From 199662071a5b44cbc5806c90cf8d74b3db66b896 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Mon, 24 Jun 2024 07:32:07 -0700 Subject: [PATCH 001/405] Make std::random_device use getentropy() --- third_party/libcxx/__config_site | 1 + 1 file changed, 1 insertion(+) diff --git a/third_party/libcxx/__config_site b/third_party/libcxx/__config_site index d99f4580e..82b354a8f 100644 --- a/third_party/libcxx/__config_site +++ b/third_party/libcxx/__config_site @@ -28,6 +28,7 @@ __static_yoink("__demangle"); #define _LIBCPP_NO_ABI_TAG #define _LIBCPP_ABI_VERSION 2 #define _LIBCPP_ABI_NAMESPACE __2 +#define _LIBCPP_USING_GETENTROPY #define _LIBCPP_DISABLE_AVAILABILITY #define _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS #define _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS From 054da021d03e078c85b716f008c586cfaa86d686 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steven=20Dee=20=28J=C5=8Dshin=29?= Date: Wed, 26 Jun 2024 18:30:05 -0700 Subject: [PATCH 002/405] ctl::string benchmarking code (#1200) --- test/ctl/BUILD.mk | 2 + test/ctl/string_bench.cc | 146 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 test/ctl/string_bench.cc diff --git a/test/ctl/BUILD.mk b/test/ctl/BUILD.mk index 0a57a98cf..250e941d5 100644 --- a/test/ctl/BUILD.mk +++ b/test/ctl/BUILD.mk @@ -13,6 +13,8 @@ TEST_CTL_TESTS = $(TEST_CTL_COMS:%=%.ok) TEST_CTL_DIRECTDEPS = \ CTL \ + LIBC_CALLS \ + LIBC_STDIO \ LIBC_INTRIN \ LIBC_MEM \ diff --git a/test/ctl/string_bench.cc b/test/ctl/string_bench.cc new file mode 100644 index 000000000..c59695dd1 --- /dev/null +++ b/test/ctl/string_bench.cc @@ -0,0 +1,146 @@ +// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +// +// Copyright 2024 Justine Alexandra Roberts Tunney +// +// Permission to use, copy, modify, and/or distribute this software for +// any purpose with or without fee is hereby granted, provided that the +// above copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include "ctl/string.h" + +#include <__utility/move.h> + +#include "libc/calls/struct/timespec.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" + +#define BENCH(ITERATIONS, WORK_PER_RUN, CODE) \ + do { \ + struct timespec start = timespec_real(); \ + for (int __i = 0; __i < ITERATIONS; ++__i) { \ + asm volatile("" ::: "memory"); \ + CODE; \ + } \ + long long work = (WORK_PER_RUN) * (ITERATIONS); \ + double nanos = \ + (timespec_tonanos(timespec_sub(timespec_real(), start)) + work - \ + 1) / \ + (double)work; \ + printf("%10g ns %2dx %s\n", nanos, (ITERATIONS), #CODE); \ + } while (0) + +const char* big_c = "aaaaaaaaaaaaaaaaaaaaaaaa"; +const char* small_c = "aaaaaaaaaaaaaaaaaaaaaaa"; + +int +main() +{ + const ctl::string_view big(big_c), small(small_c); + + BENCH(10000000, 1, { + ctl::string s; + s.append("hello "); + s.append("world"); + }); + + BENCH(1000000, 8, { + ctl::string s; + for (int i = 0; i < 8; ++i) { + s.append('a'); + } + }); + + BENCH(1000000, 16, { + ctl::string s; + for (int i = 0; i < 16; ++i) { + s.append('a'); + } + }); + + BENCH(1000000, 23, { + ctl::string s; + for (int i = 0; i < 23; ++i) { + s.append('a'); + } + }); + + BENCH(1000000, 24, { + ctl::string s; + for (int i = 0; i < 24; ++i) { + s.append('a'); + } + }); + + BENCH(1000000, 32, { + ctl::string s; + for (int i = 0; i < 32; ++i) { + s.append('a'); + } + }); + + BENCH(1000000, 1, { ctl::string s(small_c); }); + + BENCH(1000000, 1, { ctl::string s(small); }); + + { + ctl::string small_copy("hello world"); + BENCH(1000000, 1, { ctl::string s2(small_copy); }); + } + + BENCH(1000000, 1, { + ctl::string s(small); + ctl::string s2(std::move(s)); + }); + + BENCH(1000000, 1, { + ctl::string s(small); + ctl::string s2(s); + }); + + BENCH(1000000, 1, { ctl::string s(big_c); }); + + BENCH(1000000, 1, { ctl::string s(big); }); + + { + ctl::string big_copy(big); + BENCH(1000000, 1, { ctl::string s2(big_copy); }); + } + + BENCH(1000000, 1, { + ctl::string s(big); + ctl::string s2(std::move(s)); + }); + + BENCH(1000000, 1, { + ctl::string s(big); + ctl::string s2(s); + }); + + BENCH(1000000, 1, { ctl::string s(23, 'a'); }); + + BENCH(1000000, 1, { ctl::string s(24, 'a'); }); + + { + ctl::string s(5, 'a'); + BENCH(1000000, 1, { ctl::string_view s2(s); }); + } + + { + ctl::string big_trunc(48, 'a'); + big_trunc.resize(4); + BENCH(1000000, 1, { ctl::string s(big_trunc); }); + } + + return 0; +} From 38921dc46b6b54cb0b57453db68f9307e2fc97c5 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Thu, 27 Jun 2024 22:18:55 -0700 Subject: [PATCH 003/405] Introduce more CTL content This change introduces accumulate, addressof, advance, all_of, distance, array, enable_if, allocator_traits, back_inserter, bad_alloc, is_signed, any_of, copy, exception, fill, fill_n, is_same, is_same_v, out_of_range, lexicographical_compare, is_integral, uninitialized_fill_n, is_unsigned, numeric_limits, uninitialized_fill, iterator_traits, move_backward, min, max, iterator_tag, move_iterator, reverse_iterator, uninitialized_move_n This change experiments with rewriting the ctl::vector class to make the CTL design more similar to the STL. So far it has not slowed things down to have 42 #include lines rather than 2, since it's still almost nothing compared to LLVM's code. In fact the closer we can flirt with being just like libcxx, the better chance we might have of discovering exactly what makes it so slow to compile. It would be an enormous discovery if we can find one simple trick to solving the issue there instead. This also fixes a bug in `ctl::string(const string &s)` when `s` is big. --- ctl/BUILD.mk | 1 + ctl/accumulate.h | 28 ++ ctl/addressof.h | 29 ++ ctl/advance.h | 24 ++ ctl/all_of.h | 22 ++ ctl/allocator.h | 94 +++++ ctl/allocator_traits.h | 72 ++++ ctl/any_of.h | 22 ++ ctl/array.h | 243 +++++++++++++ ctl/back_inserter.h | 64 ++++ ctl/bad_alloc.h | 23 ++ ctl/copy.h | 22 ++ ctl/distance.h | 37 ++ ctl/enable_if.h | 21 ++ ctl/exception.h | 22 ++ ctl/fill.h | 18 + ctl/fill_n.h | 19 + ctl/iterator.h | 28 ++ ctl/iterator_traits.h | 31 ++ ctl/lexicographical_compare.h | 43 +++ ctl/map.h | 5 +- ctl/max.h | 17 + ctl/min.h | 17 + ctl/move_backward.h | 20 ++ ctl/move_iterator.h | 173 +++++++++ ctl/new.cc | 52 ++- ctl/new.h | 26 +- ctl/numeric_limits.h | 122 +++++++ ctl/out_of_range.h | 23 ++ ctl/reverse_iterator.h | 183 ++++++++++ ctl/string.cc | 15 +- ctl/string.h | 59 ++- ctl/type_traits.h | 123 +++++++ ctl/uninitialized_fill.h | 29 ++ ctl/uninitialized_fill_n.h | 52 +++ ctl/uninitialized_move_n.h | 52 +++ ctl/vector.h | 635 +++++++++++++++++++++++++-------- test/ctl/BUILD.mk | 8 + test/ctl/accumulate_test.cc | 51 +++ test/ctl/advance_test.cc | 56 +++ test/ctl/all_of_test.cc | 52 +++ test/ctl/any_of_test.cc | 51 +++ test/ctl/array_test.cc | 267 ++++++++++++++ test/ctl/back_inserter_test.cc | 61 ++++ test/ctl/copy_test.cc | 66 ++++ test/ctl/string_test.cc | 8 +- test/ctl/unique_ptr_test.cc | 9 +- test/ctl/vector_test.cc | 46 ++- test/libc/runtime/zipos_test.c | 1 - test/libc/stdio/lemur64_test.c | 25 ++ tool/emacs/cosmo-c-builtins.el | 2 + tool/emacs/cosmo-stuff.el | 4 +- 52 files changed, 2980 insertions(+), 193 deletions(-) create mode 100644 ctl/accumulate.h create mode 100644 ctl/addressof.h create mode 100644 ctl/advance.h create mode 100644 ctl/all_of.h create mode 100644 ctl/allocator.h create mode 100644 ctl/allocator_traits.h create mode 100644 ctl/any_of.h create mode 100644 ctl/array.h create mode 100644 ctl/back_inserter.h create mode 100644 ctl/bad_alloc.h create mode 100644 ctl/copy.h create mode 100644 ctl/distance.h create mode 100644 ctl/enable_if.h create mode 100644 ctl/exception.h create mode 100644 ctl/fill.h create mode 100644 ctl/fill_n.h create mode 100644 ctl/iterator.h create mode 100644 ctl/iterator_traits.h create mode 100644 ctl/lexicographical_compare.h create mode 100644 ctl/max.h create mode 100644 ctl/min.h create mode 100644 ctl/move_backward.h create mode 100644 ctl/move_iterator.h create mode 100644 ctl/numeric_limits.h create mode 100644 ctl/out_of_range.h create mode 100644 ctl/reverse_iterator.h create mode 100644 ctl/type_traits.h create mode 100644 ctl/uninitialized_fill.h create mode 100644 ctl/uninitialized_fill_n.h create mode 100644 ctl/uninitialized_move_n.h create mode 100644 test/ctl/accumulate_test.cc create mode 100644 test/ctl/advance_test.cc create mode 100644 test/ctl/all_of_test.cc create mode 100644 test/ctl/any_of_test.cc create mode 100644 test/ctl/array_test.cc create mode 100644 test/ctl/back_inserter_test.cc create mode 100644 test/ctl/copy_test.cc create mode 100644 test/libc/stdio/lemur64_test.c diff --git a/ctl/BUILD.mk b/ctl/BUILD.mk index ac613db1e..66527b46b 100644 --- a/ctl/BUILD.mk +++ b/ctl/BUILD.mk @@ -36,6 +36,7 @@ $(CTL_A_OBJS): private \ -Walloca-larger-than=4096 \ -ffunction-sections \ -fdata-sections \ + -fexceptions \ CTL_LIBS = $(foreach x,$(CTL_ARTIFACTS),$($(x))) CTL_SRCS = $(foreach x,$(CTL_ARTIFACTS),$($(x)_SRCS)) diff --git a/ctl/accumulate.h b/ctl/accumulate.h new file mode 100644 index 000000000..786e10321 --- /dev/null +++ b/ctl/accumulate.h @@ -0,0 +1,28 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_ACCUMULATE_H_ +#define CTL_ACCUMULATE_H_ + +namespace ctl { + +template +constexpr T +accumulate(InputIt first, InputIt last, T init) +{ + for (; first != last; ++first) + init = init + *first; + return init; +} + +template +constexpr T +accumulate(InputIt first, InputIt last, T init, BinaryOperation op) +{ + for (; first != last; ++first) + init = op(init, *first); + return init; +} + +} // namespace ctl + +#endif // CTL_ACCUMULATE_H_ diff --git a/ctl/addressof.h b/ctl/addressof.h new file mode 100644 index 000000000..713598bf8 --- /dev/null +++ b/ctl/addressof.h @@ -0,0 +1,29 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_ADDRESSOF_H_ +#define CTL_ADDRESSOF_H_ + +namespace ctl { + +template +T* +addressof(T& arg) noexcept +{ + return reinterpret_cast( + &const_cast(reinterpret_cast(arg))); +} + +template +R (*addressof(R (*&arg)(Args...)) noexcept) +(Args...) +{ + return arg; +} + +template +T* +addressof(T&&) = delete; + +} // namespace ctl + +#endif // CTL_ADDRESSOF_H_ diff --git a/ctl/advance.h b/ctl/advance.h new file mode 100644 index 000000000..e0408c680 --- /dev/null +++ b/ctl/advance.h @@ -0,0 +1,24 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_ADVANCE_H_ +#define CTL_ADVANCE_H_ + +namespace ctl { + +template +constexpr void +advance(InputIt& it, Distance n) +{ + while (n > 0) { + --n; + ++it; + } + while (n < 0) { + ++n; + --it; + } +} + +} // namespace ctl + +#endif // CTL_ADVANCE_H_ diff --git a/ctl/all_of.h b/ctl/all_of.h new file mode 100644 index 000000000..8934668a2 --- /dev/null +++ b/ctl/all_of.h @@ -0,0 +1,22 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_ALL_OF_H_ +#define CTL_ALL_OF_H_ + +namespace ctl { + +template +constexpr bool +all_of(InputIt first, InputIt last, UnaryPredicate p) +{ + for (; first != last; ++first) { + if (!p(*first)) { + return false; + } + } + return true; +} + +} // namespace ctl + +#endif // CTL_ALL_OF_H_ diff --git a/ctl/allocator.h b/ctl/allocator.h new file mode 100644 index 000000000..b084f10e9 --- /dev/null +++ b/ctl/allocator.h @@ -0,0 +1,94 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_ALLOCATOR_H_ +#define CTL_ALLOCATOR_H_ +#include "bad_alloc.h" +#include "new.h" +#include "type_traits.h" +#include "utility.h" + +namespace ctl { + +template +class allocator +{ + public: + using value_type = T; + using size_type = size_t; + using difference_type = ptrdiff_t; + using propagate_on_container_move_assignment = ctl::true_type; + using is_always_equal = ctl::true_type; + using pointer = T*; + using const_pointer = const T*; + using reference = T&; + using const_reference = const T&; + + constexpr allocator() noexcept = default; + + constexpr allocator(const allocator&) noexcept = default; + + template + constexpr allocator(const allocator&) noexcept + { + } + + constexpr ~allocator() = default; + + [[nodiscard]] T* allocate(size_type n) + { + if (n > __SIZE_MAX__ / sizeof(T)) + throw ctl::bad_alloc(); + if (auto p = static_cast(::operator new( + n * sizeof(T), ctl::align_val_t(alignof(T)), ctl::nothrow))) + return p; + throw ctl::bad_alloc(); + } + + void deallocate(T* p, size_type n) noexcept + { + ::operator delete(p, n * sizeof(T), ctl::align_val_t(alignof(T))); + } + + template + void construct(U* p, Args&&... args) + { + ::new (static_cast(p)) U(ctl::forward(args)...); + } + + template + void destroy(U* p) + { + p->~U(); + } + + size_type max_size() const noexcept + { + return __SIZE_MAX__ / sizeof(T); + } + + allocator& operator=(const allocator&) = default; + + template + struct rebind + { + using other = allocator; + }; +}; + +template +bool +operator==(const allocator&, const allocator&) noexcept +{ + return true; +} + +template +bool +operator!=(const allocator&, const allocator&) noexcept +{ + return false; +} + +} // namespace ctl + +#endif // CTL_ALLOCATOR_H_ diff --git a/ctl/allocator_traits.h b/ctl/allocator_traits.h new file mode 100644 index 000000000..42d43d84d --- /dev/null +++ b/ctl/allocator_traits.h @@ -0,0 +1,72 @@ +#ifndef CTL_ALLOCATOR_TRAITS_H_ +#define CTL_ALLOCATOR_TRAITS_H_ +#include "type_traits.h" + +namespace ctl { + +template +struct allocator_traits +{ + using allocator_type = Alloc; + using value_type = typename Alloc::value_type; + using pointer = typename Alloc::pointer; + using const_pointer = typename Alloc::const_pointer; + using void_pointer = void*; + using const_void_pointer = const void*; + using difference_type = typename Alloc::difference_type; + using size_type = typename Alloc::size_type; + + using propagate_on_container_copy_assignment = false_type; + using propagate_on_container_move_assignment = true_type; + using propagate_on_container_swap = false_type; + using is_always_equal = true_type; + + template + using rebind_alloc = typename Alloc::template rebind::other; + + template + using rebind_traits = allocator_traits>; + + __attribute__((__always_inline__)) static pointer allocate(Alloc& a, + size_type n) + { + return a.allocate(n); + } + + __attribute__((__always_inline__)) static void deallocate(Alloc& a, + pointer p, + size_type n) + { + a.deallocate(p, n); + } + + template + __attribute__((__always_inline__)) static void construct(Alloc& a, + T* p, + Args&&... args) + { + ::new ((void*)p) T(static_cast(args)...); + } + + template + __attribute__((__always_inline__)) static void destroy(Alloc& a, T* p) + { + p->~T(); + } + + __attribute__((__always_inline__)) static size_type max_size( + const Alloc& a) noexcept + { + return __PTRDIFF_MAX__ / sizeof(value_type); + } + + __attribute__((__always_inline__)) static Alloc + select_on_container_copy_construction(const Alloc& a) + { + return a; + } +}; + +} // namespace ctl + +#endif // CTL_ALLOCATOR_TRAITS_H_ diff --git a/ctl/any_of.h b/ctl/any_of.h new file mode 100644 index 000000000..7eec80605 --- /dev/null +++ b/ctl/any_of.h @@ -0,0 +1,22 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_ANY_OF_H_ +#define CTL_ANY_OF_H_ + +namespace ctl { + +template +constexpr bool +any_of(InputIt first, InputIt last, UnaryPredicate p) +{ + for (; first != last; ++first) { + if (p(*first)) { + return true; + } + } + return false; +} + +} // namespace ctl + +#endif // CTL_ANY_OF_H_ diff --git a/ctl/array.h b/ctl/array.h new file mode 100644 index 000000000..fda2ddd04 --- /dev/null +++ b/ctl/array.h @@ -0,0 +1,243 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_ARRAY_H_ +#define CTL_ARRAY_H_ +#include "initializer_list.h" +#include "reverse_iterator.h" + +namespace ctl { + +template +struct array +{ + using value_type = T; + using size_type = size_t; + using difference_type = ptrdiff_t; + using reference = value_type&; + using const_reference = const value_type&; + using pointer = value_type*; + using const_pointer = const value_type*; + using iterator = value_type*; + using const_iterator = const value_type*; + using reverse_iterator = ctl::reverse_iterator; + using const_reverse_iterator = ctl::reverse_iterator; + + T elems[N]; + + constexpr array() = default; + constexpr array(std::initializer_list init) + { + auto it = init.begin(); + for (size_t i = 0; i < N && it != init.end(); ++i, ++it) { + elems[i] = *it; + } + } + + constexpr reference at(size_type pos) + { + if (pos >= N) + __builtin_trap(); + return elems[pos]; + } + + constexpr const_reference at(size_type pos) const + { + if (pos >= N) + __builtin_trap(); + return elems[pos]; + } + + constexpr reference operator[](size_type pos) + { + return elems[pos]; + } + + constexpr const_reference operator[](size_type pos) const + { + return elems[pos]; + } + + constexpr reference front() + { + return elems[0]; + } + + constexpr const_reference front() const + { + return elems[0]; + } + + constexpr reference back() + { + return elems[N - 1]; + } + + constexpr const_reference back() const + { + return elems[N - 1]; + } + + constexpr T* data() noexcept + { + return elems; + } + + constexpr const T* data() const noexcept + { + return elems; + } + + constexpr iterator begin() noexcept + { + return elems; + } + + constexpr const_iterator begin() const noexcept + { + return elems; + } + + constexpr iterator end() noexcept + { + return elems + N; + } + + constexpr const_iterator end() const noexcept + { + return elems + N; + } + + constexpr reverse_iterator rbegin() noexcept + { + return reverse_iterator(end()); + } + + constexpr const_reverse_iterator rbegin() const noexcept + { + return const_reverse_iterator(end()); + } + + constexpr reverse_iterator rend() noexcept + { + return reverse_iterator(begin()); + } + + constexpr const_reverse_iterator rend() const noexcept + { + return const_reverse_iterator(begin()); + } + + constexpr const_iterator cbegin() const noexcept + { + return begin(); + } + + constexpr const_iterator cend() const noexcept + { + return end(); + } + + constexpr const_reverse_iterator crbegin() const noexcept + { + return rbegin(); + } + + constexpr const_reverse_iterator crend() const noexcept + { + return rend(); + } + + constexpr bool empty() const noexcept + { + return N == 0; + } + + constexpr size_type size() const noexcept + { + return N; + } + + constexpr size_type max_size() const noexcept + { + return N; + } + + void fill(const T& value) + { + for (size_type i = 0; i < N; ++i) { + elems[i] = value; + } + } + + void swap(array& other) noexcept + { + for (size_type i = 0; i < N; ++i) { + T temp = elems[i]; + elems[i] = other.elems[i]; + other.elems[i] = temp; + } + } +}; + +template +bool +operator==(const array& lhs, const array& rhs) +{ + for (size_t i = 0; i < N; ++i) { + if (!(lhs[i] == rhs[i])) + return false; + } + return true; +} + +template +bool +operator!=(const array& lhs, const array& rhs) +{ + return !(lhs == rhs); +} + +template +bool +operator<(const array& lhs, const array& rhs) +{ + for (size_t i = 0; i < N; ++i) { + if (lhs[i] < rhs[i]) + return true; + if (rhs[i] < lhs[i]) + return false; + } + return false; +} + +template +bool +operator<=(const array& lhs, const array& rhs) +{ + return !(rhs < lhs); +} + +template +bool +operator>(const array& lhs, const array& rhs) +{ + return rhs < lhs; +} + +template +bool +operator>=(const array& lhs, const array& rhs) +{ + return !(lhs < rhs); +} + +template +void +swap(array& lhs, array& rhs) noexcept +{ + lhs.swap(rhs); +} + +} // namespace ctl + +#endif // CTL_ARRAY_H_ diff --git a/ctl/back_inserter.h b/ctl/back_inserter.h new file mode 100644 index 000000000..667f95924 --- /dev/null +++ b/ctl/back_inserter.h @@ -0,0 +1,64 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_BACK_INSERTER_H_ +#define CTL_BACK_INSERTER_H_ +#include "iterator.h" +#include "utility.h" + +namespace ctl { + +template +class back_insert_iterator +{ + protected: + Container* container; + + public: + using iterator_category = ctl::output_iterator_tag; + using value_type = void; + using difference_type = void; + using pointer = void; + using reference = void; + + explicit back_insert_iterator(Container& c) : container(&c) + { + } + + back_insert_iterator& operator=(const typename Container::value_type& value) + { + container->push_back(value); + return *this; + } + + back_insert_iterator& operator=(typename Container::value_type&& value) + { + container->push_back(ctl::move(value)); + return *this; + } + + back_insert_iterator& operator*() + { + return *this; + } + + back_insert_iterator& operator++() + { + return *this; + } + + back_insert_iterator operator++(int) + { + return *this; + } +}; + +template +back_insert_iterator +back_inserter(Container& c) +{ + return back_insert_iterator(c); +} + +} // namespace ctl + +#endif // CTL_BACK_INSERTER_H_ diff --git a/ctl/bad_alloc.h b/ctl/bad_alloc.h new file mode 100644 index 000000000..2f92578fe --- /dev/null +++ b/ctl/bad_alloc.h @@ -0,0 +1,23 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_BAD_ALLOC_H_ +#define CTL_BAD_ALLOC_H_ +#include "exception.h" + +namespace ctl { + +class bad_alloc : public exception +{ + public: + bad_alloc() noexcept = default; + ~bad_alloc() override = default; + + const char* what() const noexcept override + { + return "ctl::bad_alloc"; + } +}; + +} // namespace ctl + +#endif // CTL_BAD_ALLOC_H_ diff --git a/ctl/copy.h b/ctl/copy.h new file mode 100644 index 000000000..dd546bce8 --- /dev/null +++ b/ctl/copy.h @@ -0,0 +1,22 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_COPY_H_ +#define CTL_COPY_H_ + +namespace ctl { + +template +OutputIt +copy(InputIt first, InputIt last, OutputIt d_first) +{ + while (first != last) { + *d_first = *first; + ++d_first; + ++first; + } + return d_first; +} + +} // namespace ctl + +#endif // CTL_COPY_H_ diff --git a/ctl/distance.h b/ctl/distance.h new file mode 100644 index 000000000..83bac2a77 --- /dev/null +++ b/ctl/distance.h @@ -0,0 +1,37 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_DISTANCE_H_ +#define CTL_DISTANCE_H_ +#include "iterator.h" +#include "iterator_traits.h" + +namespace ctl { + +template +constexpr typename iterator_traits::difference_type +distance_impl(InputIter first, InputIter last, input_iterator_tag) +{ + typename iterator_traits::difference_type res(0); + for (; first != last; ++first) + ++res; + return res; +} + +template +constexpr typename iterator_traits::difference_type +distance_impl(RandIter first, RandIter last, random_access_iterator_tag) +{ + return last - first; +} + +template +constexpr typename iterator_traits::difference_type +distance(InputIter first, InputIter last) +{ + return distance_impl( + first, last, typename iterator_traits::iterator_category()); +} + +} // namespace ctl + +#endif // CTL_DISTANCE_H_ diff --git a/ctl/enable_if.h b/ctl/enable_if.h new file mode 100644 index 000000000..70cb862a3 --- /dev/null +++ b/ctl/enable_if.h @@ -0,0 +1,21 @@ +#ifndef CTL_ENABLE_IF_H_ +#define CTL_ENABLE_IF_H_ + +namespace ctl { + +template +struct enable_if +{}; + +template +struct enable_if +{ + typedef T type; +}; + +template +using enable_if_t = typename enable_if::type; + +} // namespace ctl + +#endif // CTL_ENABLE_IF_H_ diff --git a/ctl/exception.h b/ctl/exception.h new file mode 100644 index 000000000..9c36374e5 --- /dev/null +++ b/ctl/exception.h @@ -0,0 +1,22 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_EXCEPTION_H_ +#define CTL_EXCEPTION_H_ + +namespace ctl { + +class exception +{ + public: + exception() noexcept = default; + virtual ~exception() = default; + + virtual const char* what() const noexcept + { + return "ctl::exception"; + } +}; + +} // namespace ctl + +#endif // CTL_EXCEPTION_H_ diff --git a/ctl/fill.h b/ctl/fill.h new file mode 100644 index 000000000..9d87de776 --- /dev/null +++ b/ctl/fill.h @@ -0,0 +1,18 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_FILL_H_ +#define CTL_FILL_H_ + +namespace ctl { + +template +void +fill(ForwardIt first, ForwardIt last, const T& value) +{ + for (; first != last; ++first) + *first = value; +} + +} // namespace ctl + +#endif // CTL_FILL_H_ diff --git a/ctl/fill_n.h b/ctl/fill_n.h new file mode 100644 index 000000000..b2dd61b24 --- /dev/null +++ b/ctl/fill_n.h @@ -0,0 +1,19 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_FILL_N_H_ +#define CTL_FILL_N_H_ + +namespace ctl { + +template +OutputIt +fill_n(OutputIt first, Size count, const T& value) +{ + for (; count > 0; --count, ++first) + *first = value; + return first; +} + +} // namespace ctl + +#endif // CTL_FILL_N_H_ diff --git a/ctl/iterator.h b/ctl/iterator.h new file mode 100644 index 000000000..7b9398b22 --- /dev/null +++ b/ctl/iterator.h @@ -0,0 +1,28 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_OUTPUT_ITERATOR_TAG_H_ +#define CTL_OUTPUT_ITERATOR_TAG_H_ + +namespace ctl { + +struct input_iterator_tag +{}; + +struct output_iterator_tag +{}; + +struct forward_iterator_tag : public input_iterator_tag +{}; + +struct bidirectional_iterator_tag : public forward_iterator_tag +{}; + +struct random_access_iterator_tag : public bidirectional_iterator_tag +{}; + +struct contiguous_iterator_tag : public random_access_iterator_tag +{}; + +} // namespace ctl + +#endif // CTL_OUTPUT_ITERATOR_TAG_H_ diff --git a/ctl/iterator_traits.h b/ctl/iterator_traits.h new file mode 100644 index 000000000..c08217c76 --- /dev/null +++ b/ctl/iterator_traits.h @@ -0,0 +1,31 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_ITERATOR_TRAITS_H_ +#define CTL_ITERATOR_TRAITS_H_ +#include "utility.h" + +namespace ctl { + +template +struct iterator_traits +{ + using iterator_category = typename Iterator::iterator_category; + using value_type = typename Iterator::value_type; + using difference_type = typename Iterator::difference_type; + using pointer = typename Iterator::pointer; + using reference = typename Iterator::reference; +}; + +template +struct iterator_traits +{ + using iterator_category = void*; // We don't actually use this + using value_type = T; + using difference_type = ptrdiff_t; + using pointer = T*; + using reference = T&; +}; + +} // namespace ctl + +#endif // CTL_ITERATOR_TRAITS_H_ diff --git a/ctl/lexicographical_compare.h b/ctl/lexicographical_compare.h new file mode 100644 index 000000000..e1644ecc4 --- /dev/null +++ b/ctl/lexicographical_compare.h @@ -0,0 +1,43 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_LEXICOGRAPHICAL_COMPARE_H_ +#define CTL_LEXICOGRAPHICAL_COMPARE_H_ + +namespace ctl { + +template +bool +lexicographical_compare(InputIt1 first1, + InputIt1 last1, + InputIt2 first2, + InputIt2 last2) +{ + for (; (first1 != last1) && (first2 != last2); ++first1, ++first2) { + if (*first1 < *first2) + return true; + if (*first2 < *first1) + return false; + } + return (first1 == last1) && (first2 != last2); +} + +template +bool +lexicographical_compare(InputIt1 first1, + InputIt1 last1, + InputIt2 first2, + InputIt2 last2, + Compare comp) +{ + for (; (first1 != last1) && (first2 != last2); ++first1, ++first2) { + if (comp(*first1, *first2)) + return true; + if (comp(*first2, *first1)) + return false; + } + return (first1 == last1) && (first2 != last2); +} + +} // namespace ctl + +#endif /* CTL_LEXICOGRAPHICAL_COMPARE_H_ */ diff --git a/ctl/map.h b/ctl/map.h index ce564793c..a9a6510bb 100644 --- a/ctl/map.h +++ b/ctl/map.h @@ -2,6 +2,7 @@ // vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi #ifndef CTL_MAP_H_ #define CTL_MAP_H_ +#include "out_of_range.h" #include "set.h" namespace ctl { @@ -164,7 +165,7 @@ class map { auto it = find(key); if (it == end()) - __builtin_trap(); + throw ctl::out_of_range("out of range"); return it->second; } @@ -172,7 +173,7 @@ class map { auto it = find(key); if (it == end()) - __builtin_trap(); + throw ctl::out_of_range("out of range"); return it->second; } diff --git a/ctl/max.h b/ctl/max.h new file mode 100644 index 000000000..63a0cb5bd --- /dev/null +++ b/ctl/max.h @@ -0,0 +1,17 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_MAX_H_ +#define CTL_MAX_H_ + +namespace ctl { + +template +inline constexpr const T& +max(const T& a, const T& b) +{ + return a < b ? b : a; +} + +} // namespace ctl + +#endif /* CTL_MAX_H_ */ diff --git a/ctl/min.h b/ctl/min.h new file mode 100644 index 000000000..7adfe137f --- /dev/null +++ b/ctl/min.h @@ -0,0 +1,17 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_MIN_H_ +#define CTL_MIN_H_ + +namespace ctl { + +template +inline constexpr const T& +min(const T& a, const T& b) +{ + return b < a ? b : a; +} + +} // namespace ctl + +#endif /* CTL_MIN_H_ */ diff --git a/ctl/move_backward.h b/ctl/move_backward.h new file mode 100644 index 000000000..b4d3f2124 --- /dev/null +++ b/ctl/move_backward.h @@ -0,0 +1,20 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_MOVE_BACKWARD_H_ +#define CTL_MOVE_BACKWARD_H_ +#include "utility.h" + +namespace ctl { + +template +BidirIt2 +move_backward(BidirIt1 first, BidirIt1 last, BidirIt2 d_last) +{ + while (first != last) + *(--d_last) = ctl::move(*(--last)); + return d_last; +} + +} // namespace ctl + +#endif // CTL_MOVE_BACKWARD_H_ diff --git a/ctl/move_iterator.h b/ctl/move_iterator.h new file mode 100644 index 000000000..8ce1ed05b --- /dev/null +++ b/ctl/move_iterator.h @@ -0,0 +1,173 @@ +#ifndef CTL_MOVE_ITERATOR_H_ +#define CTL_MOVE_ITERATOR_H_ +#include "iterator_traits.h" +#include "type_traits.h" + +namespace ctl { + +template +class move_iterator +{ + public: + using iterator_type = Iterator; + using iterator_category = + typename ctl::iterator_traits::iterator_category; + using value_type = typename ctl::iterator_traits::value_type; + using difference_type = + typename ctl::iterator_traits::difference_type; + using pointer = Iterator; + using reference = value_type&&; + + constexpr move_iterator() : current() + { + } + + explicit constexpr move_iterator(Iterator i) : current(i) + { + } + + template + constexpr move_iterator(const move_iterator& u) : current(u.base()) + { + } + + constexpr Iterator base() const + { + return current; + } + + constexpr reference operator*() const + { + return static_cast(*current); + } + + constexpr pointer operator->() const + { + return current; + } + + constexpr move_iterator& operator++() + { + ++current; + return *this; + } + + constexpr move_iterator operator++(int) + { + move_iterator tmp = *this; + ++current; + return tmp; + } + + constexpr move_iterator& operator--() + { + --current; + return *this; + } + + constexpr move_iterator operator--(int) + { + move_iterator tmp = *this; + --current; + return tmp; + } + + constexpr move_iterator operator+(difference_type n) const + { + return move_iterator(current + n); + } + + constexpr move_iterator& operator+=(difference_type n) + { + current += n; + return *this; + } + + constexpr move_iterator operator-(difference_type n) const + { + return move_iterator(current - n); + } + + constexpr move_iterator& operator-=(difference_type n) + { + current -= n; + return *this; + } + + constexpr reference operator[](difference_type n) const + { + return ctl::move(current[n]); + } + + private: + Iterator current; +}; + +template +__attribute__((__always_inline__)) constexpr move_iterator +make_move_iterator(Iterator i) +{ + return move_iterator(i); +} + +template +constexpr bool +operator==(const move_iterator& x, const move_iterator& y) +{ + return x.base() == y.base(); +} + +template +constexpr bool +operator!=(const move_iterator& x, const move_iterator& y) +{ + return !(x == y); +} + +template +constexpr bool +operator<(const move_iterator& x, const move_iterator& y) +{ + return x.base() < y.base(); +} + +template +constexpr bool +operator<=(const move_iterator& x, const move_iterator& y) +{ + return !(y < x); +} + +template +constexpr bool +operator>(const move_iterator& x, const move_iterator& y) +{ + return y < x; +} + +template +constexpr bool +operator>=(const move_iterator& x, const move_iterator& y) +{ + return !(x < y); +} + +template +constexpr move_iterator +operator+(typename move_iterator::difference_type n, + const move_iterator& x) +{ + return x + n; +} + +template +constexpr auto +operator-(const move_iterator& x, + const move_iterator& y) -> decltype(x.base() - y.base()) +{ + return x.base() - y.base(); +} + +} // namespace ctl + +#endif // CTL_MOVE_ITERATOR_H_ diff --git a/ctl/new.cc b/ctl/new.cc index 638f820a7..044fe4050 100644 --- a/ctl/new.cc +++ b/ctl/new.cc @@ -23,7 +23,7 @@ COSMOPOLITAN_C_START_ static void* -_ctl_alloc(size_t n, size_t a) +_ctl_alloc(size_t n, size_t a) noexcept { void* p; if (!(p = memalign(a, n))) @@ -32,7 +32,16 @@ _ctl_alloc(size_t n, size_t a) } static void* -_ctl_alloc1(size_t n) +_ctl_alloc_nothrow(size_t n, size_t a, const ctl::nothrow_t&) +{ + void* p; + if (!(p = memalign(a, n))) + __builtin_trap(); + return p; +} + +static void* +_ctl_alloc1(size_t n) noexcept { void* p; if (!(p = malloc(n))) @@ -41,19 +50,28 @@ _ctl_alloc1(size_t n) } static void* -_ctl_ret(size_t, void* p) +_ctl_alloc1_nothrow(size_t n, const ctl::nothrow_t&) noexcept +{ + void* p; + if (!(p = malloc(n))) + __builtin_trap(); + return p; +} + +static void* +_ctl_ret(size_t, void* p) noexcept { return p; } static void -_ctl_free(void* p) +_ctl_free(void* p) noexcept { free(p); } static void -_ctl_nop(void*, void*) +_ctl_nop(void*, void*) noexcept { } @@ -75,23 +93,43 @@ __weak_reference(void* operator new(size_t, ctl::align_val_t), _ctl_alloc); +__weak_reference(void* + operator new(size_t, + ctl::align_val_t, + const ctl::nothrow_t&) noexcept, + _ctl_alloc_nothrow); + __weak_reference(void* operator new[](size_t, ctl::align_val_t), _ctl_alloc); +__weak_reference(void* + operator new[](size_t, + ctl::align_val_t, + const ctl::nothrow_t&) noexcept, + _ctl_alloc_nothrow); + __weak_reference(void* operator new(size_t), _ctl_alloc1); +__weak_reference(void* + operator new(size_t, const ctl::nothrow_t&) noexcept, + _ctl_alloc1_nothrow); + __weak_reference(void* operator new[](size_t), _ctl_alloc1); +__weak_reference(void* + operator new[](size_t, const ctl::nothrow_t&) noexcept, + _ctl_alloc1_nothrow); + // XXX clang-format currently mutilates these for some reason. // clang-format off -__weak_reference(void* operator new(size_t, void*), _ctl_ret); -__weak_reference(void* operator new[](size_t, void*), _ctl_ret); +__weak_reference(void* operator new(size_t, void*) noexcept, _ctl_ret); +__weak_reference(void* operator new[](size_t, void*) noexcept, _ctl_ret); __weak_reference(void operator delete(void*) noexcept, _ctl_free); __weak_reference(void operator delete[](void*) noexcept, _ctl_free); diff --git a/ctl/new.h b/ctl/new.h index 9993a02f8..d9dd36e95 100644 --- a/ctl/new.h +++ b/ctl/new.h @@ -13,18 +13,30 @@ enum class align_val_t : size_t { }; -} // namespace ctl +struct nothrow_t +{ + explicit nothrow_t() = default; +}; -void* operator new(size_t); -void* operator new[](size_t); -void* operator new(size_t, ctl::align_val_t); -void* operator new[](size_t, ctl::align_val_t); +inline constexpr nothrow_t nothrow{}; + +} // namespace ctl // XXX clang-format currently mutilates these for some reason. // clang-format off -void* operator new(size_t, void*); -void* operator new[](size_t, void*); +void* operator new(size_t); +void* operator new(size_t, const ctl::nothrow_t&) noexcept; +void* operator new(size_t, ctl::align_val_t); +void* operator new(size_t, ctl::align_val_t, const ctl::nothrow_t&) noexcept; + +void* operator new[](size_t); +void* operator new[](size_t, const ctl::nothrow_t&) noexcept; +void* operator new[](size_t, ctl::align_val_t); +void* operator new[](size_t, ctl::align_val_t, const ctl::nothrow_t&) noexcept; + +void* operator new(size_t, void*) noexcept; +void* operator new[](size_t, void*) noexcept; void operator delete(void*) noexcept; void operator delete[](void*) noexcept; diff --git a/ctl/numeric_limits.h b/ctl/numeric_limits.h new file mode 100644 index 000000000..5693a62e2 --- /dev/null +++ b/ctl/numeric_limits.h @@ -0,0 +1,122 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_NUMERIC_LIMITS_H_ +#define CTL_NUMERIC_LIMITS_H_ +#include "type_traits.h" + +namespace ctl { + +template +class numeric_limits +{ + static constexpr T max_signed() + { + return T(((uintmax_t)1 << (sizeof(T) * 8 - 1)) - 1); + } + + static constexpr T max_unsigned() + { + return T(~T(0)); + } + + public: + static constexpr bool is_specialized = ctl::is_integral::value; + static constexpr bool is_signed = !ctl::is_unsigned::value; + static constexpr bool is_integer = ctl::is_integral::value; + static constexpr bool is_exact = ctl::is_integral::value; + static constexpr int digits = sizeof(T) * 8 - (is_signed ? 1 : 0); + + static constexpr T min() noexcept + { + return is_signed ? T(-max_signed() - 1) : T(0); + } + + static constexpr T max() noexcept + { + return is_signed ? max_signed() : max_unsigned(); + } + + static constexpr T lowest() noexcept + { + return min(); + } +}; + +template<> +struct numeric_limits +{ + static constexpr bool is_specialized = true; + static constexpr bool is_signed = false; + static constexpr bool is_integer = true; + static constexpr bool is_exact = true; + static constexpr int digits = 1; + + static constexpr bool min() noexcept + { + return false; + } + + static constexpr bool max() noexcept + { + return true; + } + + static constexpr bool lowest() noexcept + { + return false; + } +}; + +template<> +struct numeric_limits +{ + static constexpr bool is_specialized = true; + static constexpr bool is_signed = true; + static constexpr bool is_integer = false; + static constexpr bool is_exact = false; + static constexpr int digits = 24; + + static constexpr float min() noexcept + { + return __FLT_MIN__; + } + + static constexpr float max() noexcept + { + return __FLT_MAX__; + } + + static constexpr float lowest() noexcept + { + return -max(); + } +}; + +template<> +struct numeric_limits +{ + static constexpr bool is_specialized = true; + static constexpr bool is_signed = true; + static constexpr bool is_integer = false; + static constexpr bool is_exact = false; + static constexpr int digits = 53; + + static constexpr double min() noexcept + { + return __DBL_MIN__; + } + + static constexpr double max() noexcept + { + return __DBL_MAX__; + } + + static constexpr double lowest() noexcept + { + return -max(); + } +}; + +} // namespace ctl + +#endif // CTL_NUMERIC_LIMITS_H_ diff --git a/ctl/out_of_range.h b/ctl/out_of_range.h new file mode 100644 index 000000000..08c65fc18 --- /dev/null +++ b/ctl/out_of_range.h @@ -0,0 +1,23 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_OUT_OF_RANGE_H_ +#define CTL_OUT_OF_RANGE_H_ +#include "exception.h" + +namespace ctl { + +class out_of_range : public exception +{ + public: + out_of_range() noexcept = default; + ~out_of_range() override = default; + + const char* what() const noexcept override + { + return "ctl::out_of_range"; + } +}; + +} // namespace ctl + +#endif // CTL_OUT_OF_RANGE_H_ diff --git a/ctl/reverse_iterator.h b/ctl/reverse_iterator.h new file mode 100644 index 000000000..b7d0245cd --- /dev/null +++ b/ctl/reverse_iterator.h @@ -0,0 +1,183 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_REVERSE_ITERATOR_H_ +#define CTL_REVERSE_ITERATOR_H_ +#include "iterator_traits.h" +#include "utility.h" + +namespace ctl { + +template +class reverse_iterator +{ + public: + using iterator_type = Iterator; + using iterator_category = + typename iterator_traits::iterator_category; + using value_type = typename iterator_traits::value_type; + using difference_type = typename iterator_traits::difference_type; + using pointer = typename iterator_traits::pointer; + using reference = typename iterator_traits::reference; + + constexpr reverse_iterator() : current() + { + } + + constexpr explicit reverse_iterator(Iterator x) : current(x) + { + } + + template + constexpr reverse_iterator(const reverse_iterator& other) + : current(other.base()) + { + } + + template + constexpr reverse_iterator& operator=(const reverse_iterator& other) + { + current = other.base(); + return *this; + } + + constexpr Iterator base() const + { + return current; + } + + constexpr reference operator*() const + { + Iterator tmp = current; + return *--tmp; + } + + constexpr pointer operator->() const + { + return &(operator*()); + } + + constexpr reverse_iterator& operator++() + { + --current; + return *this; + } + + constexpr reverse_iterator operator++(int) + { + reverse_iterator tmp = *this; + --current; + return tmp; + } + + constexpr reverse_iterator& operator--() + { + ++current; + return *this; + } + + constexpr reverse_iterator operator--(int) + { + reverse_iterator tmp = *this; + ++current; + return tmp; + } + + constexpr reverse_iterator operator+(difference_type n) const + { + return reverse_iterator(current - n); + } + + constexpr reverse_iterator& operator+=(difference_type n) + { + current -= n; + return *this; + } + + constexpr reverse_iterator operator-(difference_type n) const + { + return reverse_iterator(current + n); + } + + constexpr reverse_iterator& operator-=(difference_type n) + { + current += n; + return *this; + } + + constexpr reference operator[](difference_type n) const + { + return *(*this + n); + } + + protected: + Iterator current; +}; + +template +constexpr bool +operator==(const reverse_iterator& lhs, + const reverse_iterator& rhs) +{ + return lhs.base() == rhs.base(); +} + +template +constexpr bool +operator!=(const reverse_iterator& lhs, + const reverse_iterator& rhs) +{ + return lhs.base() != rhs.base(); +} + +template +constexpr bool +operator<(const reverse_iterator& lhs, + const reverse_iterator& rhs) +{ + return rhs.base() < lhs.base(); +} + +template +constexpr bool +operator<=(const reverse_iterator& lhs, + const reverse_iterator& rhs) +{ + return !(rhs < lhs); +} + +template +constexpr bool +operator>(const reverse_iterator& lhs, + const reverse_iterator& rhs) +{ + return rhs < lhs; +} + +template +constexpr bool +operator>=(const reverse_iterator& lhs, + const reverse_iterator& rhs) +{ + return !(lhs < rhs); +} + +template +constexpr reverse_iterator +operator+(typename reverse_iterator::difference_type n, + const reverse_iterator& it) +{ + return reverse_iterator(it.base() - n); +} + +template +constexpr auto +operator-(const reverse_iterator& lhs, + const reverse_iterator& rhs) -> decltype(rhs.base() - + lhs.base()) +{ + return rhs.base() - lhs.base(); +} + +} // namespace ctl + +#endif // CTL_REVERSE_ITERATOR_H_ diff --git a/ctl/string.cc b/ctl/string.cc index 4e292a188..08ee1e65d 100644 --- a/ctl/string.cc +++ b/ctl/string.cc @@ -41,25 +41,14 @@ string::destroy_big() noexcept void string::init_big(const string& s) noexcept { - char* p2; -#ifndef NDEBUG - if (!s.isbig()) - __builtin_trap(); -#endif - if (s.size() >= s.capacity() >> 1) { - if (!(p2 = (char*)malloc(s.capacity()))) - __builtin_trap(); - set_big_string(p2, s.size(), s.capacity()); - } else { - init_big(string_view(s)); - } + init_big(string_view(s)); } void string::init_big(const string_view s) noexcept { - size_t need; char* p2; + size_t need; if (ckd_add(&need, s.n, 1 /* nul */ + 15)) __builtin_trap(); need &= -16; diff --git a/ctl/string.h b/ctl/string.h index 6b6935424..69a9cf1b7 100644 --- a/ctl/string.h +++ b/ctl/string.h @@ -2,6 +2,7 @@ // vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi #ifndef CTL_STRING_H_ #define CTL_STRING_H_ +#include "reverse_iterator.h" #include "string_view.h" namespace ctl { @@ -44,8 +45,18 @@ struct big_string class string { public: - using iterator = char*; - using const_iterator = const char*; + using value_type = char; + using size_type = size_t; + using difference_type = ptrdiff_t; + using pointer = value_type*; + using const_pointer = const value_type*; + using reference = value_type&; + using const_reference = const value_type&; + using iterator = pointer; + using const_iterator = const_pointer; + using reverse_iterator = ctl::reverse_iterator; + using const_reverse_iterator = ctl::reverse_iterator; + static constexpr size_t npos = -1; string() noexcept @@ -189,9 +200,9 @@ class string return data(); } - iterator end() noexcept + const_iterator begin() const noexcept { - return data() + size(); + return data(); } const_iterator cbegin() const noexcept @@ -199,11 +210,51 @@ class string return data(); } + reverse_iterator rbegin() noexcept + { + return reverse_iterator(end()); + } + + const_reverse_iterator rbegin() const noexcept + { + return const_reverse_iterator(end()); + } + + const_reverse_iterator crbegin() const noexcept + { + return const_reverse_iterator(end()); + } + + iterator end() noexcept + { + return data() + size(); + } + + const_iterator end() const noexcept + { + return data() + size(); + } + const_iterator cend() const noexcept { return data() + size(); } + reverse_iterator rend() noexcept + { + return reverse_iterator(begin()); + } + + const_reverse_iterator rend() const noexcept + { + return const_reverse_iterator(cbegin()); + } + + const_reverse_iterator crend() const noexcept + { + return const_reverse_iterator(cbegin()); + } + char& front() { if (!size()) diff --git a/ctl/type_traits.h b/ctl/type_traits.h new file mode 100644 index 000000000..c9dea8584 --- /dev/null +++ b/ctl/type_traits.h @@ -0,0 +1,123 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_TYPE_TRAITS_H_ +#define CTL_TYPE_TRAITS_H_ + +namespace ctl { + +template +struct integral_constant +{ + static constexpr T value = v; + using value_type = T; + using type = integral_constant; + constexpr operator value_type() const noexcept + { + return value; + } + constexpr value_type operator()() const noexcept + { + return value; + } +}; + +using true_type = integral_constant; +using false_type = integral_constant; + +template +struct is_integral : false_type +{}; + +template<> +struct is_integral : true_type +{}; + +template<> +struct is_integral : true_type +{}; + +template<> +struct is_integral : true_type +{}; + +template<> +struct is_integral : true_type +{}; + +template<> +struct is_integral : true_type +{}; + +template<> +struct is_integral : true_type +{}; + +template<> +struct is_integral : true_type +{}; + +template<> +struct is_integral : true_type +{}; + +template<> +struct is_integral : true_type +{}; + +template<> +struct is_integral : true_type +{}; + +template<> +struct is_integral : true_type +{}; + +template<> +struct is_integral : true_type +{}; + +template<> +struct is_integral : true_type +{}; + +template<> +struct is_integral : true_type +{}; + +template<> +struct is_integral : true_type +{}; + +template +inline constexpr bool is_integral_v = is_integral::value; + +template +struct is_signed +{ + static constexpr bool value = T(0) > T(-1); +}; + +template +struct is_unsigned +{ + static constexpr bool value = T(0) < T(-1); +}; + +template +struct is_same +{ + static constexpr bool value = false; +}; + +template +struct is_same +{ + static constexpr bool value = true; +}; + +template +inline constexpr bool is_same_v = is_same::value; + +} // namespace ctl + +#endif // CTL_TYPE_TRAITS_H_ diff --git a/ctl/uninitialized_fill.h b/ctl/uninitialized_fill.h new file mode 100644 index 000000000..966d948cc --- /dev/null +++ b/ctl/uninitialized_fill.h @@ -0,0 +1,29 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_UNINITIALIZED_FILL_H_ +#define CTL_UNINITIALIZED_FILL_H_ +#include "addressof.h" +#include "iterator_traits.h" + +namespace ctl { + +template +void +uninitialized_fill(ForwardIt first, ForwardIt last, const T& value) +{ + using ValueType = typename ctl::iterator_traits::value_type; + ForwardIt current = first; + try { + for (; current != last; ++current) + ::new (static_cast(ctl::addressof(*current))) + ValueType(value); + } catch (...) { + for (; first != current; ++first) + first->~ValueType(); + throw; + } +} + +} // namespace ctl + +#endif // CTL_UNINITIALIZED_FILL_H_ diff --git a/ctl/uninitialized_fill_n.h b/ctl/uninitialized_fill_n.h new file mode 100644 index 000000000..c0b6102a8 --- /dev/null +++ b/ctl/uninitialized_fill_n.h @@ -0,0 +1,52 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_UNINITIALIZED_FILL_N_H_ +#define CTL_UNINITIALIZED_FILL_N_H_ +#include "addressof.h" +#include "allocator_traits.h" +#include "iterator_traits.h" + +namespace ctl { + +template +ForwardIt +uninitialized_fill_n(ForwardIt first, Size n, const T& value) +{ + using ValueType = typename ctl::iterator_traits::value_type; + ForwardIt current = first; + try { + for (; n > 0; ++current, --n) { + ::new (static_cast(ctl::addressof(*current))) + ValueType(value); + } + return current; + } catch (...) { + for (; first != current; ++first) { + first->~ValueType(); + } + throw; + } +} + +template +ForwardIt +uninitialized_fill_n(ForwardIt first, Size n, const T& value, Alloc& alloc) +{ + using AllocTraits = ctl::allocator_traits; + ForwardIt current = first; + try { + for (; n > 0; ++current, --n) { + AllocTraits::construct(alloc, ctl::addressof(*current), value); + } + return current; + } catch (...) { + for (; first != current; ++first) { + AllocTraits::destroy(alloc, ctl::addressof(*first)); + } + throw; + } +} + +} // namespace ctl + +#endif // CTL_UNINITIALIZED_FILL_N_H_ diff --git a/ctl/uninitialized_move_n.h b/ctl/uninitialized_move_n.h new file mode 100644 index 000000000..108cc0e11 --- /dev/null +++ b/ctl/uninitialized_move_n.h @@ -0,0 +1,52 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_UNINITIALIZED_MOVE_N_H_ +#define CTL_UNINITIALIZED_MOVE_N_H_ +#include "addressof.h" +#include "allocator_traits.h" +#include "iterator_traits.h" +#include "utility.h" + +namespace ctl { + +template +ForwardIt +uninitialized_move_n(InputIt first, Size n, ForwardIt d_first) +{ + using T = typename ctl::iterator_traits::value_type; + ForwardIt current = d_first; + try { + for (; n > 0; ++first, (void)++current, --n) { + ::new (static_cast(ctl::addressof(*current))) + T(ctl::move(*first)); + } + } catch (...) { + for (; d_first != current; ++d_first) { + d_first->~T(); + } + throw; + } + return current; +} + +template +ForwardIt +uninitialized_move_n(InputIt first, Size n, ForwardIt d_first, Alloc& alloc) +{ + using AllocTraits = ctl::allocator_traits; + ForwardIt current = d_first; + try { + for (; n > 0; ++first, (void)++current, --n) + AllocTraits::construct( + alloc, ctl::addressof(*current), ctl::move(*first)); + } catch (...) { + for (; d_first != current; ++d_first) + AllocTraits::destroy(alloc, ctl::addressof(*d_first)); + throw; + } + return current; +} + +} // namespace ctl + +#endif // CTL_UNINITIALIZED_MOVE_N_H_ diff --git a/ctl/vector.h b/ctl/vector.h index e86e0d503..b5837614c 100644 --- a/ctl/vector.h +++ b/ctl/vector.h @@ -1,245 +1,594 @@ // -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- // vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi -#ifndef COSMOPOLITAN_CTL_OPTIONAL_H_ -#define COSMOPOLITAN_CTL_OPTIONAL_H_ -#include "new.h" -#include "utility.h" +#ifndef CTL_VECTOR_H_ +#define CTL_VECTOR_H_ +#include "allocator.h" +#include "allocator_traits.h" +#include "copy.h" +#include "distance.h" +#include "equal.h" +#include "fill_n.h" +#include "initializer_list.h" +#include "iterator_traits.h" +#include "lexicographical_compare.h" +#include "max.h" +#include "move_backward.h" +#include "move_iterator.h" +#include "out_of_range.h" +#include "reverse_iterator.h" +#include "uninitialized_fill.h" +#include "uninitialized_fill_n.h" +#include "uninitialized_move_n.h" namespace ctl { -template -struct vector +template> +class vector { - size_t n = 0; - size_t c = 0; - T* p = nullptr; + public: + using value_type = T; + using allocator_type = Allocator; + using size_type = size_t; + using difference_type = ptrdiff_t; + using reference = value_type&; + using const_reference = const value_type&; + using pointer = typename ctl::allocator_traits::pointer; + using const_pointer = + typename ctl::allocator_traits::const_pointer; + using iterator = pointer; + using const_iterator = const_pointer; + using reverse_iterator = ctl::reverse_iterator; + using const_reverse_iterator = ctl::reverse_iterator; - using iterator = T*; - using const_iterator = const T*; - - vector() = default; - - ~vector() + public: + vector() noexcept(noexcept(Allocator())) + : alloc_(), data_(nullptr), size_(0), capacity_(0) { - delete[] p; + } + + explicit vector(const Allocator& alloc) noexcept + : alloc_(alloc), data_(nullptr), size_(0), capacity_(0) + { + } + + vector(size_type count, + const T& value, + const Allocator& alloc = Allocator()) + : alloc_(alloc), data_(nullptr), size_(0), capacity_(0) + { + assign(count, value); + } + + explicit vector(size_type count, const Allocator& alloc = Allocator()) + : alloc_(alloc), data_(nullptr), size_(0), capacity_(0) + { + resize(count); + } + + template + vector(InputIt first, InputIt last, const Allocator& alloc = Allocator()) + : alloc_(alloc), data_(nullptr), size_(0), capacity_(0) + { + assign(first, last); } vector(const vector& other) + : alloc_(ctl::allocator_traits< + Allocator>::select_on_container_copy_construction(other.alloc_)) + , data_(nullptr) + , size_(0) + , capacity_(0) { - n = other.n; - c = other.c; - p = new T[c]; - for (size_t i = 0; i < n; ++i) - new (&p[i]) T(other.p[i]); + assign(other.begin(), other.end()); + } + + vector(const vector& other, const Allocator& alloc) + : alloc_(alloc), data_(nullptr), size_(0), capacity_(0) + { + assign(other.begin(), other.end()); } vector(vector&& other) noexcept + : alloc_(ctl::move(other.alloc_)) + , data_(other.data_) + , size_(other.size_) + , capacity_(other.capacity_) { - n = other.n; - c = other.c; - p = other.p; - other.n = 0; - other.c = 0; - other.p = nullptr; + other.data_ = nullptr; + other.size_ = 0; + other.capacity_ = 0; } - explicit vector(size_t count, const T& value = T()) + vector(vector&& other, const Allocator& alloc) + : alloc_(alloc), data_(nullptr), size_(0), capacity_(0) { - n = count; - c = count; - p = new T[c]; - for (size_t i = 0; i < n; ++i) - new (&p[i]) T(value); + if (alloc_ == other.alloc_) { + data_ = other.data_; + size_ = other.size_; + capacity_ = other.capacity_; + other.data_ = nullptr; + other.size_ = 0; + other.capacity_ = 0; + } else { + assign(ctl::make_move_iterator(other.begin()), + ctl::make_move_iterator(other.end())); + } + } + + vector(std::initializer_list init, const Allocator& alloc = Allocator()) + : alloc_(alloc), data_(nullptr), size_(0), capacity_(0) + { + assign(init.begin(), init.end()); + } + + ~vector() + { + clear(); + ctl::allocator_traits::deallocate(alloc_, data_, capacity_); } vector& operator=(const vector& other) { if (this != &other) { - T* newData = new T[other.c]; - for (size_t i = 0; i < other.n; ++i) { - newData[i] = other.p[i]; - } - delete[] p; - p = newData; - n = other.n; - c = other.c; + if (ctl::allocator_traits< + Allocator>::propagate_on_container_copy_assignment::value) + alloc_ = other.alloc_; + assign(other.begin(), other.end()); } return *this; } - vector& operator=(vector&& other) noexcept + vector& operator=(vector&& other) noexcept( + ctl::allocator_traits::is_always_equal::value) { if (this != &other) { - delete[] p; - p = other.p; - n = other.n; - c = other.c; - other.p = nullptr; - other.n = 0; - other.c = 0; + clear(); + ctl::allocator_traits::deallocate( + alloc_, data_, capacity_); + if (ctl::allocator_traits< + Allocator>::propagate_on_container_move_assignment::value) + alloc_ = ctl::move(other.alloc_); + data_ = other.data_; + size_ = other.size_; + capacity_ = other.capacity_; + other.data_ = nullptr; + other.size_ = 0; + other.capacity_ = 0; } return *this; } - bool empty() const + vector& operator=(std::initializer_list ilist) { - return !n; + assign(ilist.begin(), ilist.end()); + return *this; } - size_t size() const + void assign(size_type count, const T& value) { - return n; + clear(); + if (count > capacity_) + reallocate(count); + ctl::uninitialized_fill_n(data_, count, value); + size_ = count; } - size_t capacity() const + template + void assign(InputIt first, InputIt last) { - return c; + clear(); + for (; first != last; ++first) + push_back(*first); } - T& operator[](size_t i) + void assign(std::initializer_list ilist) { - if (i >= n) - __builtin_trap(); - return p[i]; + assign(ilist.begin(), ilist.end()); } - const T& operator[](size_t i) const + reference at(size_type pos) { - if (i >= n) - __builtin_trap(); - return p[i]; + if (pos >= size_) + throw ctl::out_of_range("out of range"); + return data_[pos]; } - iterator begin() + const_reference at(size_type pos) const { - return p; + if (pos >= size_) + throw ctl::out_of_range("out of range"); + return data_[pos]; } - iterator end() + reference operator[](size_type pos) { - return p + n; + return data_[pos]; } - const_iterator cbegin() const + const_reference operator[](size_type pos) const { - return p; + return data_[pos]; } - const_iterator cend() const + reference front() { - return p + n; + return data_[0]; } - T& front() + const_reference front() const { - if (!n) - __builtin_trap(); - return p[0]; + return data_[0]; } - const T& front() const + reference back() { - if (!n) - __builtin_trap(); - return p[0]; + return data_[size_ - 1]; } - T& back() + const_reference back() const { - if (!n) - __builtin_trap(); - return p[n - 1]; + return data_[size_ - 1]; } - const T& back() const + T* data() noexcept { - if (!n) - __builtin_trap(); - return p[n - 1]; + return data_; } - void clear() + const T* data() const noexcept { - for (size_t i = 0; i < n; ++i) - p[i].~T(); - n = 0; + return data_; } - void reserve(size_t c2) + iterator begin() noexcept { - if (c2 <= c) - return; - T* newP = new T[c2]; - for (size_t i = 0; i < n; ++i) - newP[i] = ctl::move(p[i]); - delete[] p; - p = newP; - c = c2; + return data_; } - void push_back(const T& e) + const_iterator begin() const noexcept { - if (n == c) { - size_t c2 = c + 1; - c2 += c2 >> 1; - reserve(c2); - } - new (&p[n]) T(e); - ++n; + return data_; } - void push_back(T&& e) + const_iterator cbegin() const noexcept { - if (n == c) { - size_t c2 = c + 1; - c2 += c2 >> 1; - reserve(c2); - } - new (&p[n]) T(ctl::forward(e)); - ++n; + return data_; } - template - void emplace_back(Args&&... args) + iterator end() noexcept { - if (n == c) { - size_t c2 = c + 1; - c2 += c2 >> 1; - reserve(c2); - } - new (&p[n]) T(ctl::forward(args)...); - ++n; + return data_ + size_; + } + + const_iterator end() const noexcept + { + return data_ + size_; + } + + const_iterator cend() const noexcept + { + return data_ + size_; + } + + reverse_iterator rbegin() noexcept + { + return reverse_iterator(end()); + } + + const_reverse_iterator rbegin() const noexcept + { + return const_reverse_iterator(end()); + } + + const_reverse_iterator crbegin() const noexcept + { + return const_reverse_iterator(end()); + } + + reverse_iterator rend() noexcept + { + return reverse_iterator(begin()); + } + + const_reverse_iterator rend() const noexcept + { + return const_reverse_iterator(begin()); + } + + const_reverse_iterator crend() const noexcept + { + return const_reverse_iterator(begin()); + } + + bool empty() const noexcept + { + return size_ == 0; + } + + size_type size() const noexcept + { + return size_; + } + + size_type max_size() const noexcept + { + return __PTRDIFF_MAX__; + } + + size_type capacity() const noexcept + { + return capacity_; + } + + void reserve(size_type new_cap) + { + if (new_cap > capacity_) + reallocate(new_cap); + } + + void shrink_to_fit() + { + if (size_ < capacity_) + reallocate(size_); + } + + void clear() noexcept + { + for (size_type i = 0; i < size_; ++i) + ctl::allocator_traits::destroy(alloc_, data_ + i); + size_ = 0; + } + + iterator insert(const_iterator pos, const T& value) + { + return insert(pos, 1, value); + } + + iterator insert(const_iterator pos, T&& value) + { + difference_type index = pos - begin(); + if (size_ == capacity_) + grow(); + iterator it = begin() + index; + ctl::move_backward(it, end(), end() + 1); + *it = ctl::move(value); + ++size_; + return it; + } + + iterator insert(const_iterator pos, size_type count, const T& value) + { + difference_type index = pos - begin(); + if (size_ + count > capacity_) + reallocate(ctl::max(size_ + count, capacity_ * 2)); + iterator it = begin() + index; + ctl::move_backward(it, end(), end() + count); + ctl::fill_n(it, count, value); + size_ += count; + return it; + } + + template + iterator insert(const_iterator pos, InputIt first, InputIt last) + { + difference_type count = ctl::distance(first, last); + difference_type index = pos - begin(); + if (size_ + count > capacity_) + reallocate(ctl::max(size_ + count, capacity_ * 2)); + iterator it = begin() + index; + ctl::move_backward(it, end(), end() + count); + ctl::copy(first, last, it); + size_ += count; + return it; + } + + iterator insert(const_iterator pos, std::initializer_list ilist) + { + return insert(pos, ilist.begin(), ilist.end()); + } + + template + iterator emplace(const_iterator pos, Args&&... args) + { + difference_type index = pos - begin(); + if (size_ == capacity_) + grow(); + iterator it = begin() + index; + ctl::move_backward(it, end(), end() + 1); + ctl::allocator_traits::construct( + alloc_, it, ctl::forward(args)...); + ++size_; + return it; + } + + iterator erase(const_iterator pos) + { + return erase(pos, pos + 1); + } + + iterator erase(const_iterator first, const_iterator last) + { + difference_type index = first - begin(); + difference_type count = last - first; + iterator it = begin() + index; + ctl::move(it + count, end(), it); + for (difference_type i = 0; i < count; ++i) + ctl::allocator_traits::destroy(alloc_, end() - i - 1); + size_ -= count; + return it; + } + + void push_back(const T& value) + { + if (size_ == capacity_) + grow(); + ctl::allocator_traits::construct( + alloc_, data_ + size_, value); + ++size_; + } + + void push_back(T&& value) + { + if (size_ == capacity_) + grow(); + ctl::allocator_traits::construct( + alloc_, data_ + size_, ctl::move(value)); + ++size_; + } + + template + reference emplace_back(Args&&... args) + { + if (size_ == capacity_) + grow(); + ctl::allocator_traits::construct( + alloc_, data_ + size_, ctl::forward(args)...); + return data_[size_++]; } void pop_back() { - if (n > 0) { - --n; - p[n].~T(); + if (!empty()) { + ctl::allocator_traits::destroy(alloc_, + data_ + size_ - 1); + --size_; } } - void resize(size_t n2) + void resize(size_type count) { - if (n2 > n) { - reserve(n2); - for (size_t i = n; i < n2; ++i) - new (&p[i]) T(); - } else if (n2 < n) { - for (size_t i = n2; i < n; ++i) - p[i].~T(); - } - n = n2; + resize(count, T()); } - void swap(vector& other) noexcept + void resize(size_type count, const value_type& value) { - ctl::swap(n, other.n); - ctl::swap(c, other.c); - ctl::swap(p, other.p); + if (count > size_) { + if (count > capacity_) + reallocate(count); + ctl::uninitialized_fill(data_ + size_, data_ + count, value); + } else if (count < size_) { + for (size_type i = count; i < size_; ++i) + ctl::allocator_traits::destroy(alloc_, data_ + i); + } + size_ = count; } + + void swap(vector& other) noexcept( + ctl::allocator_traits::is_always_equal::value) + { + using ctl::swap; + swap(alloc_, other.alloc_); + swap(data_, other.data_); + swap(size_, other.size_); + swap(capacity_, other.capacity_); + } + + allocator_type get_allocator() const noexcept + { + return alloc_; + } + + private: + void grow() + { + size_type c2; + c2 = capacity_; + if (c2 < 4) + c2 = 4; + c2 += c2 >> 1; + reallocate(c2); + } + + void reallocate(size_type new_capacity) + { + pointer new_data = + ctl::allocator_traits::allocate(alloc_, new_capacity); + size_type new_size = size_ < new_capacity ? size_ : new_capacity; + try { + ctl::uninitialized_move_n(data_, new_size, new_data); + } catch (...) { + ctl::allocator_traits::deallocate( + alloc_, new_data, new_capacity); + throw; + } + for (size_type i = 0; i < size_; ++i) + ctl::allocator_traits::destroy(alloc_, data_ + i); + ctl::allocator_traits::deallocate(alloc_, data_, capacity_); + data_ = new_data; + size_ = new_size; + capacity_ = new_capacity; + } + + Allocator alloc_; + pointer data_; + size_type size_; + size_type capacity_; }; +template +bool +operator==(const vector& lhs, const vector& rhs) +{ + return lhs.size() == rhs.size() && + ctl::equal(lhs.begin(), lhs.end(), rhs.begin()); +} + +template +bool +operator!=(const vector& lhs, const vector& rhs) +{ + return !(lhs == rhs); +} + +template +bool +operator<(const vector& lhs, const vector& rhs) +{ + return ctl::lexicographical_compare( + lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); +} + +template +bool +operator<=(const vector& lhs, const vector& rhs) +{ + return !(rhs < lhs); +} + +template +bool +operator>(const vector& lhs, const vector& rhs) +{ + return rhs < lhs; +} + +template +bool +operator>=(const vector& lhs, const vector& rhs) +{ + return !(lhs < rhs); +} + +template +void +swap(vector& lhs, + vector& rhs) noexcept(noexcept(lhs.swap(rhs))) +{ + lhs.swap(rhs); +} + +template::value_type>> +vector(InputIt, InputIt, Alloc = Alloc()) + -> vector::value_type, Alloc>; + +template +vector(size_t, + const typename ctl::allocator_traits::value_type&, + Alloc = Alloc()) + -> vector::value_type, Alloc>; + } // namespace ctl -#endif // COSMOPOLITAN_CTL_OPTIONAL_H_ +#endif // CTL_VECTOR_H_ diff --git a/test/ctl/BUILD.mk b/test/ctl/BUILD.mk index 250e941d5..439d7e786 100644 --- a/test/ctl/BUILD.mk +++ b/test/ctl/BUILD.mk @@ -17,6 +17,10 @@ TEST_CTL_DIRECTDEPS = \ LIBC_STDIO \ LIBC_INTRIN \ LIBC_MEM \ + LIBC_STDIO \ + THIRD_PARTY_LIBCXX \ + THIRD_PARTY_LIBCXXABI \ + THIRD_PARTY_LIBUNWIND \ TEST_CTL_DEPS := \ $(call uniq,$(foreach x,$(TEST_CTL_DIRECTDEPS),$($(x)))) @@ -33,6 +37,10 @@ o/$(MODE)/test/ctl/%.dbg: \ $(APE_NO_MODIFY_SELF) @$(APELINK) +$(TEST_CTL_OBJS): private \ + OVERRIDE_CXXFLAGS += \ + -fexceptions \ + .PHONY: o/$(MODE)/test/ctl o/$(MODE)/test/ctl: \ $(TEST_CTL_BINS) \ diff --git a/test/ctl/accumulate_test.cc b/test/ctl/accumulate_test.cc new file mode 100644 index 000000000..ff29e278e --- /dev/null +++ b/test/ctl/accumulate_test.cc @@ -0,0 +1,51 @@ +// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +// +// Copyright 2024 Justine Alexandra Roberts Tunney +// +// Permission to use, copy, modify, and/or distribute this software for +// any purpose with or without fee is hereby granted, provided that the +// above copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include "ctl/accumulate.h" +#include "ctl/array.h" + +// #include +// #include +// #define ctl std + +int +main() +{ + ctl::array arr = { 1, 2, 3, 4, 5 }; + + // Test basic accumulation with addition + if (ctl::accumulate(arr.begin(), arr.end(), 0) != 15) + return 1; + + // Test accumulation with initial value + if (ctl::accumulate(arr.begin(), arr.end(), 10) != 25) + return 2; + + // Test accumulation with custom operation (multiplication) + if (ctl::accumulate( + arr.begin(), arr.end(), 1, [](int a, int b) { return a * b; }) != 120) + return 3; + + // Test accumulation with empty range + if (ctl::accumulate(arr.end(), arr.end(), 0) != 0) + return 4; + + // Test accumulation with single element + if (ctl::accumulate(arr.begin(), arr.begin() + 1, 0) != 1) + return 5; +} diff --git a/test/ctl/advance_test.cc b/test/ctl/advance_test.cc new file mode 100644 index 000000000..90b381bd5 --- /dev/null +++ b/test/ctl/advance_test.cc @@ -0,0 +1,56 @@ +// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +// +// Copyright 2024 Justine Alexandra Roberts Tunney +// +// Permission to use, copy, modify, and/or distribute this software for +// any purpose with or without fee is hereby granted, provided that the +// above copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include "ctl/advance.h" +#include "ctl/array.h" + +// #include +// #include +// #define ctl std + +int +main() +{ + ctl::array arr = { 1, 2, 3, 4, 5 }; + + // Test advancing forward + auto it = arr.begin(); + ctl::advance(it, 2); + if (*it != 3) + return 1; + + // Test advancing to the end + ctl::advance(it, 2); + if (it != arr.end() - 1) + return 2; + + // Test advancing backward + ctl::advance(it, -2); + if (*it != 3) + return 3; + + // Test advancing by zero + ctl::advance(it, 0); + if (*it != 3) + return 4; + + // Test advancing to the beginning + ctl::advance(it, -2); + if (it != arr.begin()) + return 5; +} diff --git a/test/ctl/all_of_test.cc b/test/ctl/all_of_test.cc new file mode 100644 index 000000000..5f38e441b --- /dev/null +++ b/test/ctl/all_of_test.cc @@ -0,0 +1,52 @@ +// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +// +// Copyright 2024 Justine Alexandra Roberts Tunney +// +// Permission to use, copy, modify, and/or distribute this software for +// any purpose with or without fee is hereby granted, provided that the +// above copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include "ctl/all_of.h" +#include "ctl/array.h" + +#include +#include +#define ctl std + +int +main() +{ + ctl::array arr1 = { 2, 4, 6, 8, 10 }; + ctl::array arr2 = { 2, 4, 5, 8, 10 }; + + // Test when all elements satisfy the condition + if (!ctl::all_of( + arr1.begin(), arr1.end(), [](int n) { return n % 2 == 0; })) + return 1; + + // Test when not all elements satisfy the condition + if (ctl::all_of(arr2.begin(), arr2.end(), [](int n) { return n % 2 == 0; })) + return 2; + + // Test with empty range + if (!ctl::all_of(arr1.end(), arr1.end(), [](int n) { return false; })) + return 3; + + // Test with all elements satisfying a different condition + if (!ctl::all_of(arr1.begin(), arr1.end(), [](int n) { return n > 0; })) + return 4; + + // Test with no elements satisfying the condition + if (ctl::all_of(arr1.begin(), arr1.end(), [](int n) { return n > 10; })) + return 5; +} diff --git a/test/ctl/any_of_test.cc b/test/ctl/any_of_test.cc new file mode 100644 index 000000000..02ba6928d --- /dev/null +++ b/test/ctl/any_of_test.cc @@ -0,0 +1,51 @@ +// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +// +// Copyright 2024 Justine Alexandra Roberts Tunney +// +// Permission to use, copy, modify, and/or distribute this software for +// any purpose with or without fee is hereby granted, provided that the +// above copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include "ctl/any_of.h" +#include "ctl/array.h" + +// #include +// #include +// #define ctl std + +int +main() +{ + ctl::array arr1 = { 1, 3, 5, 7, 9 }; + ctl::array arr2 = { 2, 4, 6, 8, 10 }; + + // Test when at least one element satisfies the condition + if (!ctl::any_of(arr1.begin(), arr1.end(), [](int n) { return n == 7; })) + return 1; + + // Test when no elements satisfy the condition + if (ctl::any_of(arr1.begin(), arr1.end(), [](int n) { return n == 11; })) + return 2; + + // Test with empty range + if (ctl::any_of(arr1.end(), arr1.end(), [](int n) { return true; })) + return 3; + + // Test when all elements satisfy the condition + if (!ctl::any_of(arr2.begin(), arr2.end(), [](int n) { return true; })) + return 4; + + // Test with a different condition + if (!ctl::any_of(arr1.begin(), arr1.end(), [](int n) { return n > 5; })) + return 5; +} diff --git a/test/ctl/array_test.cc b/test/ctl/array_test.cc new file mode 100644 index 000000000..5fd8dbe54 --- /dev/null +++ b/test/ctl/array_test.cc @@ -0,0 +1,267 @@ +// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +// +// Copyright 2024 Justine Alexandra Roberts Tunney +// +// Permission to use, copy, modify, and/or distribute this software for +// any purpose with or without fee is hereby granted, provided that the +// above copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include "ctl/array.h" + +// #include +// #define ctl std + +int +main() +{ + + // Test construction and basic properties + { + ctl::array arr = { 1, 2, 3, 4, 5 }; + if (arr.size() != 5) + return 2; + if (arr.max_size() != 5) + return 3; + if (arr.empty()) + return 4; + } + + // Test element access + { + ctl::array arr = { 10, 20, 30 }; + if (arr[0] != 10 || arr[1] != 20 || arr[2] != 30) + return 5; + if (arr.front() != 10) + return 6; + if (arr.back() != 30) + return 7; + } + + // Test data() method + { + ctl::array arr = { 1, 2, 3 }; + int* data = arr.data(); + if (data[0] != 1 || data[1] != 2 || data[2] != 3) + return 9; + } + + // Test iterators + { + ctl::array arr = { 1, 2, 3 }; + int sum = 0; + for (auto it = arr.begin(); it != arr.end(); ++it) { + sum += *it; + } + if (sum != 6) + return 10; + + sum = 0; + for (auto it = arr.rbegin(); it != arr.rend(); ++it) { + sum += *it; + } + if (sum != 6) + return 11; + } + + // Test const iterators + { + const ctl::array arr = { 1, 2, 3 }; + int sum = 0; + for (auto it = arr.cbegin(); it != arr.cend(); ++it) { + sum += *it; + } + if (sum != 6) + return 12; + + sum = 0; + for (auto it = arr.crbegin(); it != arr.crend(); ++it) { + sum += *it; + } + if (sum != 6) + return 13; + } + + // Test fill method + { + ctl::array arr; + arr.fill(42); + for (int i = 0; i < 5; ++i) { + if (arr[i] != 42) + return 14; + } + } + + // Test swap method + { + ctl::array arr1 = { 1, 2, 3 }; + ctl::array arr2 = { 4, 5, 6 }; + arr1.swap(arr2); + if (arr1[0] != 4 || arr1[1] != 5 || arr1[2] != 6) + return 15; + if (arr2[0] != 1 || arr2[1] != 2 || arr2[2] != 3) + return 16; + } + + // Test comparison operators + { + ctl::array arr1 = { 1, 2, 3 }; + ctl::array arr2 = { 1, 2, 3 }; + ctl::array arr3 = { 1, 2, 4 }; + + if (!(arr1 == arr2)) + return 17; + if (arr1 != arr2) + return 18; + if (!(arr1 < arr3)) + return 19; + if (arr3 <= arr1) + return 20; + if (!(arr3 > arr1)) + return 21; + if (arr1 >= arr3) + return 22; + } + + // Test non-member swap function + { + ctl::array arr1 = { 1, 2, 3 }; + ctl::array arr2 = { 4, 5, 6 }; + swap(arr1, arr2); + if (arr1[0] != 4 || arr1[1] != 5 || arr1[2] != 6) + return 23; + if (arr2[0] != 1 || arr2[1] != 2 || arr2[2] != 3) + return 24; + } + + // Test with non-trivial type + { + struct NonTrivial + { + int value; + + NonTrivial(int v = 0) : value(v) + { + } + + bool operator==(const NonTrivial& other) const + { + return value == other.value; + } + }; + + ctl::array arr = { 1, 2, 3 }; + if (arr[0].value != 1 || arr[1].value != 2 || arr[2].value != 3) + return 25; + } + + // Test empty array + { + ctl::array arr; + if (!arr.empty()) + return 26; + if (arr.size() != 0) + return 27; + if (arr.begin() != arr.end()) + return 28; + } + + // Test basic array functionality + { + ctl::array arr = { 1, 2, 3, 4, 5 }; + if (arr.size() != 5) + return 2; + if (arr[0] != 1 || arr[4] != 5) + return 3; + } + + // Test reverse iterator basics + { + ctl::array arr = { 1, 2, 3, 4, 5 }; + auto rit = arr.rbegin(); + if (*rit != 5) + return 4; + ++rit; + if (*rit != 4) + return 5; + if (*(arr.rbegin() + 2) != 3) + return 6; + } + + // Test reverse iterator traversal + { + ctl::array arr = { 1, 2, 3, 4, 5 }; + int expected = 5; + for (auto rit = arr.rbegin(); rit != arr.rend(); ++rit) { + if (*rit != expected) + return 7; + --expected; + } + } + + // Test const reverse iterator + { + const ctl::array arr = { 1, 2, 3, 4, 5 }; + auto crit = arr.crbegin(); + if (*crit != 5) + return 8; + ++crit; + if (*crit != 4) + return 9; + } + + // Test reverse iterator arithmetic + { + ctl::array arr = { 1, 2, 3, 4, 5 }; + auto rit = arr.rbegin(); + rit += 2; + if (*rit != 3) + return 10; + rit -= 1; + if (*rit != 4) + return 11; + if (*(rit + 2) != 2) + return 12; + if (*(rit - 1) != 5) + return 13; + } + + // Test reverse iterator comparison + { + ctl::array arr = { 1, 2, 3, 4, 5 }; + auto rit1 = arr.rbegin(); + auto rit2 = arr.rbegin() + 2; + if (rit1 >= rit2) + return 14; + if (!(rit1 < rit2)) + return 15; + if (rit1 == rit2) + return 16; + } + + // Test it seems legit + { + ctl::array arr = { 1, 2, 3 }; + auto rit = arr.rbegin(); + if (*rit != 3) + return 1; + ++rit; + if (*rit != 2) + return 2; + ++rit; + if (*rit != 1) + return 3; + ++rit; + if (rit != arr.rend()) + return 4; + } +} diff --git a/test/ctl/back_inserter_test.cc b/test/ctl/back_inserter_test.cc new file mode 100644 index 000000000..38659b10e --- /dev/null +++ b/test/ctl/back_inserter_test.cc @@ -0,0 +1,61 @@ +// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +// +// Copyright 2024 Justine Alexandra Roberts Tunney +// +// Permission to use, copy, modify, and/or distribute this software for +// any purpose with or without fee is hereby granted, provided that the +// above copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include "ctl/array.h" +#include "ctl/back_inserter.h" +#include "ctl/copy.h" +#include "ctl/vector.h" + +// #include +// #include +// #include +// #define ctl std + +int +main() +{ + ctl::vector vec = { 1, 2, 3 }; + ctl::array arr = { 4, 5, 6 }; + + // Use back_inserter to append elements from arr to vec + ctl::copy(arr.begin(), arr.end(), ctl::back_inserter(vec)); + + // Check if vec now contains all elements + if (vec.size() != 6) + return 1; + if (vec[0] != 1 || vec[1] != 2 || vec[2] != 3 || vec[3] != 4 || + vec[4] != 5 || vec[5] != 6) + return 2; + + // Use back_inserter with a single element + ctl::back_inserter(vec) = 7; + + // Check if the new element was added + if (vec.size() != 7) + return 3; + if (vec[6] != 7) + return 4; + + // Test with an empty source range + ctl::array empty_arr; + ctl::copy(empty_arr.begin(), empty_arr.end(), ctl::back_inserter(vec)); + + // Check that no elements were added + if (vec.size() != 7) + return 5; +} diff --git a/test/ctl/copy_test.cc b/test/ctl/copy_test.cc new file mode 100644 index 000000000..868bbee97 --- /dev/null +++ b/test/ctl/copy_test.cc @@ -0,0 +1,66 @@ +// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +// +// Copyright 2024 Justine Alexandra Roberts Tunney +// +// Permission to use, copy, modify, and/or distribute this software for +// any purpose with or without fee is hereby granted, provided that the +// above copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include "ctl/array.h" +#include "ctl/copy.h" + +// #include +// #include +// #define ctl std + +int +main() +{ + ctl::array src = { 1, 2, 3, 4, 5 }; + ctl::array dest = { 0, 0, 0, 0, 0 }; + + // Test basic copy + ctl::copy(src.begin(), src.end(), dest.begin()); + for (size_t i = 0; i < 5; ++i) { + if (dest[i] != src[i]) + return 1; + } + + // Test partial copy + ctl::array dest2 = { 0, 0, 0, 0, 0 }; + ctl::copy(src.begin(), src.begin() + 3, dest2.begin()); + if (dest2[0] != 1 || dest2[1] != 2 || dest2[2] != 3 || dest2[3] != 0 || + dest2[4] != 0) + return 2; + + // Test copy to middle of destination + ctl::array dest3 = { 0, 0, 0, 0, 0, 0, 0 }; + ctl::copy(src.begin(), src.end(), dest3.begin() + 1); + if (dest3[0] != 0 || dest3[1] != 1 || dest3[2] != 2 || dest3[3] != 3 || + dest3[4] != 4 || dest3[5] != 5 || dest3[6] != 0) + return 3; + + // Test copy with empty range + ctl::array dest4 = { 0, 0, 0, 0, 0 }; + ctl::copy(src.begin(), src.begin(), dest4.begin()); + for (size_t i = 0; i < 5; ++i) { + if (dest4[i] != 0) + return 4; + } + + // Test copy return value + ctl::array dest5 = { 0, 0, 0, 0, 0 }; + auto result = ctl::copy(src.begin(), src.end(), dest5.begin()); + if (result != dest5.end()) + return 5; +} diff --git a/test/ctl/string_test.cc b/test/ctl/string_test.cc index 7e7cb3f32..a3fd1f461 100644 --- a/test/ctl/string_test.cc +++ b/test/ctl/string_test.cc @@ -17,10 +17,9 @@ // PERFORMANCE OF THIS SOFTWARE. #include "ctl/string.h" +#include "ctl/type_traits.h" #include "libc/mem/leaks.h" -#include <__type_traits/is_same.h> - #include "libc/str/str.h" // #include @@ -366,7 +365,7 @@ main() { String s; - if constexpr (std::is_same_v) { + if constexpr (ctl::is_same_v) { // tests the small-string optimization on ctl::string for (int i = 0; i < 23; ++i) { s.append("a"); @@ -397,7 +396,7 @@ main() s.resize(4); if (s != "arst") return 105; - if constexpr (std::is_same_v) { + if constexpr (ctl::is_same_v) { String r(s); if (issmall(s) || !issmall(r)) return 106; @@ -405,5 +404,4 @@ main() } CheckForMemoryLeaks(); - return 0; } diff --git a/test/ctl/unique_ptr_test.cc b/test/ctl/unique_ptr_test.cc index 4f83de945..87e4f30f2 100644 --- a/test/ctl/unique_ptr_test.cc +++ b/test/ctl/unique_ptr_test.cc @@ -16,11 +16,12 @@ // TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. +#include "ctl/type_traits.h" #include "ctl/unique_ptr.h" - -#include <__type_traits/is_same.h> +#include "libc/mem/leaks.h" // #include +// #include // #define ctl std template> @@ -70,7 +71,7 @@ struct FinalDeleter final static_assert(sizeof(Ptr) == sizeof(int*)); // not everyone uses [[no_unique_address]]... -static_assert(!std::is_same_v, ctl::unique_ptr> || +static_assert(!ctl::is_same_v, ctl::unique_ptr> || sizeof(Ptr) == sizeof(int*)); struct SetsGCtor @@ -227,6 +228,4 @@ main() // TODO(mrdomino): Fix memory leaks reported by MODE=dbg // CheckForMemoryLeaks(); - - return 0; } diff --git a/test/ctl/vector_test.cc b/test/ctl/vector_test.cc index aa70cb21d..9e65333c3 100644 --- a/test/ctl/vector_test.cc +++ b/test/ctl/vector_test.cc @@ -16,13 +16,10 @@ // TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. +#include "ctl/string.h" #include "ctl/vector.h" #include "libc/mem/leaks.h" -#include - -#include "ctl/string.h" - // #include // #include // #define ctl std @@ -315,6 +312,45 @@ main() return 69; } + { + ctl::vector A = { 1, 2, 3 }; + if (A[1] != 2) + return 70; + A = { 4, 5, 6 }; + if (A[1] != 5) + return 71; + } + + { + ctl::vector arr = { 1, 2, 3 }; + auto rit = arr.rbegin(); + if (*rit != 3) + return 72; + ++rit; + if (*rit != 2) + return 73; + ++rit; + if (*rit != 1) + return 74; + ++rit; + if (rit != arr.rend()) + return 75; + } + + { + ctl::vector A = { "hi", "theretheretheretherethere" }; + if (A.size() != 2) + return 76; + if (A[0] != "hi") + return 77; + if (A[1] != "theretheretheretherethere") + return 78; + A = { "theretheretheretherethere", "hi" }; + if (A[0] != "theretheretheretherethere") + return 79; + if (A[1] != "hi") + return 80; + } + CheckForMemoryLeaks(); - return 0; } diff --git a/test/libc/runtime/zipos_test.c b/test/libc/runtime/zipos_test.c index c77614a85..147920b45 100644 --- a/test/libc/runtime/zipos_test.c +++ b/test/libc/runtime/zipos_test.c @@ -144,7 +144,6 @@ static void *pthread_main(void *ptr) { struct State *s = ptr; struct State children[2]; int fd, rc; - fd = s->fd; if (s->id < 8) { for (int i = 0; i < 2; ++i) { diff --git a/test/libc/stdio/lemur64_test.c b/test/libc/stdio/lemur64_test.c new file mode 100644 index 000000000..fb6af0b2e --- /dev/null +++ b/test/libc/stdio/lemur64_test.c @@ -0,0 +1,25 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-β”‚ +β”‚ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi β”‚ +β•žβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•‘ +β”‚ Copyright 2024 Justine Alexandra Roberts Tunney β”‚ +β”‚ β”‚ +β”‚ Permission to use, copy, modify, and/or distribute this software for β”‚ +β”‚ any purpose with or without fee is hereby granted, provided that the β”‚ +β”‚ above copyright notice and this permission notice appear in all copies. β”‚ +β”‚ β”‚ +β”‚ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL β”‚ +β”‚ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED β”‚ +β”‚ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE β”‚ +β”‚ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL β”‚ +β”‚ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR β”‚ +β”‚ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER β”‚ +β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ +β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ +β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/stdio/rand.h" +#include "libc/testlib/testlib.h" + +TEST(lemur64, test) { + EXPECT_EQ(1819718037028923529, lemur64()); + EXPECT_EQ(-3120132252617434764, lemur64()); +} diff --git a/tool/emacs/cosmo-c-builtins.el b/tool/emacs/cosmo-c-builtins.el index ef7bfb4a4..bdb777018 100644 --- a/tool/emacs/cosmo-c-builtins.el +++ b/tool/emacs/cosmo-c-builtins.el @@ -46,6 +46,8 @@ (gcc-builtin-functions '("__builtin_strlen" + "__builtin_memcpy" + "__builtin_memmove" "__builtin_setjmp" "__builtin_longjmp" "__builtin_va_start" diff --git a/tool/emacs/cosmo-stuff.el b/tool/emacs/cosmo-stuff.el index 1ca81f45a..f7c712b2d 100644 --- a/tool/emacs/cosmo-stuff.el +++ b/tool/emacs/cosmo-stuff.el @@ -771,7 +771,9 @@ dots (cosmo-file-name-sans-extensions name)))) (if (file-exists-p cc-version) cc-version - c-version)) + (if (eq major-mode 'c++-mode) + cc-version + c-version))) )))) (when buddy (find-file buddy)))))) From 021c53ba321c8339d8da5c3e38198f4789613fee Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Fri, 28 Jun 2024 19:07:35 -0700 Subject: [PATCH 004/405] Add more CTL content --- ctl/add_lvalue_reference.h | 55 +++++++++ ctl/add_pointer.h | 43 +++++++ ctl/all_of.h | 6 +- ctl/allocator.h | 2 +- ctl/allocator_traits.h | 4 +- ctl/any_of.h | 6 +- ctl/array.h | 9 +- ctl/conditional.h | 22 ++++ ctl/decay.h | 35 ++++++ ctl/default_delete.h | 44 ++++++++ ctl/enable_if.h | 2 + ctl/integral_constant.h | 29 +++++ ctl/is_array.h | 26 +++++ ctl/is_convertible.h | 54 +++++++++ ctl/is_function.h | 120 ++++++++++++++++++++ ctl/{type_traits.h => is_integral.h} | 53 +-------- ctl/is_reference.h | 35 ++++++ ctl/is_same.h | 25 +++++ ctl/is_signed.h | 16 +++ ctl/is_sorted.h | 25 +++++ ctl/is_unsigned.h | 16 +++ ctl/move_iterator.h | 1 - ctl/mutex.h | 47 ++++++++ ctl/numeric_limits.h | 3 +- ctl/partition.h | 29 +++++ ctl/remove_cv.h | 49 ++++++++ ctl/remove_extent.h | 31 ++++++ ctl/remove_reference.h | 31 ++++++ ctl/runtime_error.h | 33 ++++++ ctl/sort.h | 44 ++++++++ ctl/strcat.cc | 4 +- ctl/string.cc | 39 ++++--- ctl/string.h | 52 ++------- ctl/tuple.h | 138 +++++++++++++++++++++++ ctl/unique_lock.h | 147 ++++++++++++++++++++++++ ctl/unique_ptr.cc | 19 ---- ctl/unique_ptr.h | 105 ++++++++--------- ctl/utility.cc | 19 ---- ctl/utility.h | 12 +- ctl/void_t.h | 13 +++ libc/{runtime => intrin}/dsohandle.S | 0 test/ctl/BUILD.mk | 1 + test/ctl/accumulate_test.cc | 3 + test/ctl/advance_test.cc | 3 + test/ctl/all_of_test.cc | 3 + test/ctl/any_of_test.cc | 3 + test/ctl/array_test.cc | 20 ++++ test/ctl/back_inserter_test.cc | 52 +++++---- test/ctl/copy_test.cc | 77 +++++++------ test/ctl/mutex_test.cc | 114 +++++++++++++++++++ test/ctl/sort_test.cc | 130 +++++++++++++++++++++ test/ctl/string_bench.cc | 10 +- test/ctl/string_test.cc | 3 +- test/ctl/string_view_test.cc | 1 - test/ctl/tuple_test.cc | 161 +++++++++++++++++++++++++++ test/ctl/unique_ptr_test.cc | 21 ++-- 56 files changed, 1747 insertions(+), 298 deletions(-) create mode 100644 ctl/add_lvalue_reference.h create mode 100644 ctl/add_pointer.h create mode 100644 ctl/conditional.h create mode 100644 ctl/decay.h create mode 100644 ctl/default_delete.h create mode 100644 ctl/integral_constant.h create mode 100644 ctl/is_array.h create mode 100644 ctl/is_convertible.h create mode 100644 ctl/is_function.h rename ctl/{type_traits.h => is_integral.h} (55%) create mode 100644 ctl/is_reference.h create mode 100644 ctl/is_same.h create mode 100644 ctl/is_signed.h create mode 100644 ctl/is_sorted.h create mode 100644 ctl/is_unsigned.h create mode 100644 ctl/mutex.h create mode 100644 ctl/partition.h create mode 100644 ctl/remove_cv.h create mode 100644 ctl/remove_extent.h create mode 100644 ctl/remove_reference.h create mode 100644 ctl/runtime_error.h create mode 100644 ctl/sort.h create mode 100644 ctl/tuple.h create mode 100644 ctl/unique_lock.h delete mode 100644 ctl/unique_ptr.cc delete mode 100644 ctl/utility.cc create mode 100644 ctl/void_t.h rename libc/{runtime => intrin}/dsohandle.S (100%) create mode 100644 test/ctl/mutex_test.cc create mode 100644 test/ctl/sort_test.cc create mode 100644 test/ctl/tuple_test.cc diff --git a/ctl/add_lvalue_reference.h b/ctl/add_lvalue_reference.h new file mode 100644 index 000000000..9d0c48b1d --- /dev/null +++ b/ctl/add_lvalue_reference.h @@ -0,0 +1,55 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_ADD_LVALUE_REFERENCE_H_ +#define CTL_ADD_LVALUE_REFERENCE_H_ + +namespace ctl { + +template +struct add_lvalue_reference +{ + typedef T& type; +}; + +template +struct add_lvalue_reference +{ + typedef T& type; +}; + +template +struct add_lvalue_reference +{ + typedef T& type; +}; + +template<> +struct add_lvalue_reference +{ + typedef void type; +}; + +template<> +struct add_lvalue_reference +{ + typedef const void type; +}; + +template<> +struct add_lvalue_reference +{ + typedef volatile void type; +}; + +template<> +struct add_lvalue_reference +{ + typedef const volatile void type; +}; + +template +using add_lvalue_reference_t = typename add_lvalue_reference::type; + +} // namespace ctl + +#endif // CTL_ADD_LVALUE_REFERENCE_H_ diff --git a/ctl/add_pointer.h b/ctl/add_pointer.h new file mode 100644 index 000000000..005a4a09a --- /dev/null +++ b/ctl/add_pointer.h @@ -0,0 +1,43 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_ADD_POINTER_H_ +#define CTL_ADD_POINTER_H_ +#include "remove_reference.h" + +namespace ctl { + +// Primary template +template +struct add_pointer +{ + typedef typename remove_reference::type* type; +}; + +// Specialization for functions +template +struct add_pointer +{ + typedef R (*type)(Args...); +}; + +// Specialization for function references +template +struct add_pointer +{ + typedef R (*type)(Args...); +}; + +// Specialization for rvalue references to functions +template +struct add_pointer +{ + typedef R (*type)(Args...); +}; + +// Helper alias template (C++14 and later) +template +using add_pointer_t = typename add_pointer::type; + +} // namespace ctl + +#endif // CTL_ADD_POINTER_H_ diff --git a/ctl/all_of.h b/ctl/all_of.h index 8934668a2..0c258bc4a 100644 --- a/ctl/all_of.h +++ b/ctl/all_of.h @@ -9,11 +9,9 @@ template constexpr bool all_of(InputIt first, InputIt last, UnaryPredicate p) { - for (; first != last; ++first) { - if (!p(*first)) { + for (; first != last; ++first) + if (!p(*first)) return false; - } - } return true; } diff --git a/ctl/allocator.h b/ctl/allocator.h index b084f10e9..3a593d363 100644 --- a/ctl/allocator.h +++ b/ctl/allocator.h @@ -3,8 +3,8 @@ #ifndef CTL_ALLOCATOR_H_ #define CTL_ALLOCATOR_H_ #include "bad_alloc.h" +#include "integral_constant.h" #include "new.h" -#include "type_traits.h" #include "utility.h" namespace ctl { diff --git a/ctl/allocator_traits.h b/ctl/allocator_traits.h index 42d43d84d..ebdf03424 100644 --- a/ctl/allocator_traits.h +++ b/ctl/allocator_traits.h @@ -1,6 +1,8 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi #ifndef CTL_ALLOCATOR_TRAITS_H_ #define CTL_ALLOCATOR_TRAITS_H_ -#include "type_traits.h" +#include "integral_constant.h" namespace ctl { diff --git a/ctl/any_of.h b/ctl/any_of.h index 7eec80605..09c9bcfbd 100644 --- a/ctl/any_of.h +++ b/ctl/any_of.h @@ -9,11 +9,9 @@ template constexpr bool any_of(InputIt first, InputIt last, UnaryPredicate p) { - for (; first != last; ++first) { - if (p(*first)) { + for (; first != last; ++first) + if (p(*first)) return true; - } - } return false; } diff --git a/ctl/array.h b/ctl/array.h index fda2ddd04..a2b5925b5 100644 --- a/ctl/array.h +++ b/ctl/array.h @@ -3,6 +3,7 @@ #ifndef CTL_ARRAY_H_ #define CTL_ARRAY_H_ #include "initializer_list.h" +#include "out_of_range.h" #include "reverse_iterator.h" namespace ctl { @@ -25,25 +26,25 @@ struct array T elems[N]; constexpr array() = default; + constexpr array(std::initializer_list init) { auto it = init.begin(); - for (size_t i = 0; i < N && it != init.end(); ++i, ++it) { + for (size_t i = 0; i < N && it != init.end(); ++i, ++it) elems[i] = *it; - } } constexpr reference at(size_type pos) { if (pos >= N) - __builtin_trap(); + throw ctl::out_of_range("out of range"); return elems[pos]; } constexpr const_reference at(size_type pos) const { if (pos >= N) - __builtin_trap(); + throw ctl::out_of_range("out of range"); return elems[pos]; } diff --git a/ctl/conditional.h b/ctl/conditional.h new file mode 100644 index 000000000..976143a1d --- /dev/null +++ b/ctl/conditional.h @@ -0,0 +1,22 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_CONDITIONAL_H_ +#define CTL_CONDITIONAL_H_ + +namespace ctl { + +template +struct conditional +{ + typedef T type; +}; + +template +struct conditional +{ + typedef F type; +}; + +} // namespace ctl + +#endif // CTL_CONDITIONAL_H_ diff --git a/ctl/decay.h b/ctl/decay.h new file mode 100644 index 000000000..6c4fe6f2a --- /dev/null +++ b/ctl/decay.h @@ -0,0 +1,35 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_DECAY_H_ +#define CTL_DECAY_H_ +#include "add_pointer.h" +#include "conditional.h" +#include "is_array.h" +#include "is_function.h" +#include "remove_cv.h" +#include "remove_extent.h" +#include "remove_reference.h" + +namespace ctl { + +template +struct decay +{ + private: + typedef typename remove_reference::type U; + + public: + typedef typename conditional< + is_array::value, + typename remove_extent::type*, + typename conditional::value, + typename add_pointer::type, + typename remove_cv::type>::type>::type type; +}; + +template +using decay_t = typename decay::type; + +} // namespace ctl + +#endif // CTL_DECAY_H_ diff --git a/ctl/default_delete.h b/ctl/default_delete.h new file mode 100644 index 000000000..4a3458369 --- /dev/null +++ b/ctl/default_delete.h @@ -0,0 +1,44 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_DEFAULT_DELETE_H_ +#define CTL_DEFAULT_DELETE_H_ +#include "enable_if.h" +#include "is_convertible.h" + +namespace ctl { + +template +struct default_delete +{ + constexpr default_delete() noexcept = default; + template::value>::type> + constexpr default_delete(const default_delete&) noexcept + { + } + constexpr void operator()(T* const p) const noexcept + { + delete p; + } +}; + +template +struct default_delete +{ + constexpr default_delete() noexcept = default; + template::value>::type> + constexpr default_delete(const default_delete&) noexcept + { + } + constexpr void operator()(T* const p) const noexcept + { + delete[] p; + } +}; + +} // namespace ctl + +#endif // CTL_DEFAULT_DELETE_H_ diff --git a/ctl/enable_if.h b/ctl/enable_if.h index 70cb862a3..9c61957a4 100644 --- a/ctl/enable_if.h +++ b/ctl/enable_if.h @@ -1,3 +1,5 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi #ifndef CTL_ENABLE_IF_H_ #define CTL_ENABLE_IF_H_ diff --git a/ctl/integral_constant.h b/ctl/integral_constant.h new file mode 100644 index 000000000..df5a0a688 --- /dev/null +++ b/ctl/integral_constant.h @@ -0,0 +1,29 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_INTEGRAL_CONSTANT_H_ +#define CTL_INTEGRAL_CONSTANT_H_ + +namespace ctl { + +template +struct integral_constant +{ + static constexpr T value = v; + typedef T value_type; + typedef integral_constant type; + constexpr operator value_type() const noexcept + { + return value; + } + constexpr value_type operator()() const noexcept + { + return value; + } +}; + +typedef integral_constant true_type; +typedef integral_constant false_type; + +} // namespace ctl + +#endif // CTL_INTEGRAL_CONSTANT_H_ diff --git a/ctl/is_array.h b/ctl/is_array.h new file mode 100644 index 000000000..946d152ea --- /dev/null +++ b/ctl/is_array.h @@ -0,0 +1,26 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_IS_ARRAY_H_ +#define CTL_IS_ARRAY_H_ +#include "integral_constant.h" + +namespace ctl { + +template +struct is_array : false_type +{}; + +template +struct is_array : true_type +{}; + +template +struct is_array : true_type +{}; + +template +inline constexpr bool is_array_v = is_array::value; + +} // namespace ctl + +#endif // CTL_IS_ARRAY_H_ diff --git a/ctl/is_convertible.h b/ctl/is_convertible.h new file mode 100644 index 000000000..9b81747e8 --- /dev/null +++ b/ctl/is_convertible.h @@ -0,0 +1,54 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_IS_CONVERTIBLE_H_ +#define CTL_IS_CONVERTIBLE_H_ + +#include "ctl/integral_constant.h" +#include "ctl/void_t.h" + +namespace ctl { + +// Declaration of declval +template +T&& +declval() noexcept; + +namespace detail { + +template +struct is_convertible_impl : false_type +{}; + +template +struct is_convertible_impl(declval()))>> + : true_type +{}; + +// Handle void types separately +template<> +struct is_convertible_impl : true_type +{}; + +template +struct is_convertible_impl : false_type +{}; + +template +struct is_convertible_impl : false_type +{}; + +} // namespace detail + +template +struct is_convertible : detail::is_convertible_impl +{}; + +// Helper variable template (C++17 and later) +template +inline constexpr bool is_convertible_v = is_convertible::value; + +} // namespace ctl + +#endif // CTL_IS_CONVERTIBLE_H_ diff --git a/ctl/is_function.h b/ctl/is_function.h new file mode 100644 index 000000000..667a1e8eb --- /dev/null +++ b/ctl/is_function.h @@ -0,0 +1,120 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_IS_FUNCTION_H_ +#define CTL_IS_FUNCTION_H_ +#include "integral_constant.h" + +namespace ctl { + +// Primary template +template +struct is_function : false_type +{}; + +// Specializations for various function types + +// Regular functions +template +struct is_function : true_type +{}; + +// Functions with cv-qualifiers +template +struct is_function : true_type +{}; + +template +struct is_function : true_type +{}; + +template +struct is_function : true_type +{}; + +// Functions with ref-qualifiers +template +struct is_function : true_type +{}; + +template +struct is_function : true_type +{}; + +template +struct is_function : true_type +{}; + +template +struct is_function : true_type +{}; + +template +struct is_function : true_type +{}; + +template +struct is_function : true_type +{}; + +template +struct is_function : true_type +{}; + +template +struct is_function : true_type +{}; + +// Variadic functions +template +struct is_function : true_type +{}; + +// Variadic functions with cv-qualifiers +template +struct is_function : true_type +{}; + +template +struct is_function : true_type +{}; + +template +struct is_function : true_type +{}; + +// Variadic functions with ref-qualifiers +template +struct is_function : true_type +{}; + +template +struct is_function : true_type +{}; + +template +struct is_function : true_type +{}; + +template +struct is_function : true_type +{}; + +template +struct is_function : true_type +{}; + +template +struct is_function : true_type +{}; + +template +struct is_function : true_type +{}; + +template +struct is_function : true_type +{}; + +} // namespace ctl + +#endif // CTL_IS_FUNCTION_H_ diff --git a/ctl/type_traits.h b/ctl/is_integral.h similarity index 55% rename from ctl/type_traits.h rename to ctl/is_integral.h index c9dea8584..384985a38 100644 --- a/ctl/type_traits.h +++ b/ctl/is_integral.h @@ -1,29 +1,11 @@ // -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- // vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi -#ifndef CTL_TYPE_TRAITS_H_ -#define CTL_TYPE_TRAITS_H_ +#ifndef CTL_IS_INTEGRAL_H_ +#define CTL_IS_INTEGRAL_H_ +#include "integral_constant.h" namespace ctl { -template -struct integral_constant -{ - static constexpr T value = v; - using value_type = T; - using type = integral_constant; - constexpr operator value_type() const noexcept - { - return value; - } - constexpr value_type operator()() const noexcept - { - return value; - } -}; - -using true_type = integral_constant; -using false_type = integral_constant; - template struct is_integral : false_type {}; @@ -91,33 +73,6 @@ struct is_integral : true_type template inline constexpr bool is_integral_v = is_integral::value; -template -struct is_signed -{ - static constexpr bool value = T(0) > T(-1); -}; - -template -struct is_unsigned -{ - static constexpr bool value = T(0) < T(-1); -}; - -template -struct is_same -{ - static constexpr bool value = false; -}; - -template -struct is_same -{ - static constexpr bool value = true; -}; - -template -inline constexpr bool is_same_v = is_same::value; - } // namespace ctl -#endif // CTL_TYPE_TRAITS_H_ +#endif // CTL_IS_INTEGRAL_H_ diff --git a/ctl/is_reference.h b/ctl/is_reference.h new file mode 100644 index 000000000..66ae107b6 --- /dev/null +++ b/ctl/is_reference.h @@ -0,0 +1,35 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_IS_REFERENCE_H_ +#define CTL_IS_REFERENCE_H_ + +namespace ctl { + +// Primary template +template +struct is_reference +{ + static constexpr bool value = false; +}; + +// Specialization for lvalue reference +template +struct is_reference +{ + static constexpr bool value = true; +}; + +// Specialization for rvalue reference +template +struct is_reference +{ + static constexpr bool value = true; +}; + +// Helper variable template (C++14 and later) +template +inline constexpr bool is_reference_v = is_reference::value; + +} // namespace ctl + +#endif // CTL_IS_REFERENCE_H_ diff --git a/ctl/is_same.h b/ctl/is_same.h new file mode 100644 index 000000000..44c09761b --- /dev/null +++ b/ctl/is_same.h @@ -0,0 +1,25 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_IS_SAME_H_ +#define CTL_IS_SAME_H_ + +namespace ctl { + +template +struct is_same +{ + static constexpr bool value = false; +}; + +template +struct is_same +{ + static constexpr bool value = true; +}; + +template +inline constexpr bool is_same_v = is_same::value; + +} // namespace ctl + +#endif // CTL_IS_SAME_H_ diff --git a/ctl/is_signed.h b/ctl/is_signed.h new file mode 100644 index 000000000..2c911ee4c --- /dev/null +++ b/ctl/is_signed.h @@ -0,0 +1,16 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_IS_SIGNED_H_ +#define CTL_IS_SIGNED_H_ + +namespace ctl { + +template +struct is_signed +{ + static constexpr bool value = T(0) > T(-1); +}; + +} // namespace ctl + +#endif // CTL_IS_SIGNED_H_ diff --git a/ctl/is_sorted.h b/ctl/is_sorted.h new file mode 100644 index 000000000..551cce9da --- /dev/null +++ b/ctl/is_sorted.h @@ -0,0 +1,25 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_IS_SORTED_H_ +#define CTL_IS_SORTED_H_ + +namespace ctl { + +template +bool +is_sorted(It first, It last, Compare comp) +{ + if (first == last) + return true; + It next = first; + while (++next != last) { + if (comp(*next, *first)) + return false; + first = next; + } + return true; +} + +} // namespace ctl + +#endif // CTL_IS_SORTED_H_ diff --git a/ctl/is_unsigned.h b/ctl/is_unsigned.h new file mode 100644 index 000000000..02f276a7c --- /dev/null +++ b/ctl/is_unsigned.h @@ -0,0 +1,16 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_IS_UNSIGNED_H_ +#define CTL_IS_UNSIGNED_H_ + +namespace ctl { + +template +struct is_unsigned +{ + static constexpr bool value = T(0) < T(-1); +}; + +} // namespace ctl + +#endif // CTL_IS_UNSIGNED_H_ diff --git a/ctl/move_iterator.h b/ctl/move_iterator.h index 8ce1ed05b..2527eca3b 100644 --- a/ctl/move_iterator.h +++ b/ctl/move_iterator.h @@ -1,7 +1,6 @@ #ifndef CTL_MOVE_ITERATOR_H_ #define CTL_MOVE_ITERATOR_H_ #include "iterator_traits.h" -#include "type_traits.h" namespace ctl { diff --git a/ctl/mutex.h b/ctl/mutex.h new file mode 100644 index 000000000..28a21e2e7 --- /dev/null +++ b/ctl/mutex.h @@ -0,0 +1,47 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_MUTEX_H_ +#define CTL_MUTEX_H_ +#include "libc/thread/thread.h" + +namespace ctl { + +class mutex +{ + public: + mutex() + { + pthread_mutex_init(&m_, nullptr); + } + + ~mutex() + { + pthread_mutex_destroy(&m_); + } + + void lock() + { + pthread_mutex_lock(&m_); + } + + bool try_lock() + { + return pthread_mutex_trylock(&m_) == 0; + } + + void unlock() + { + pthread_mutex_unlock(&m_); + } + + // Delete copy constructor and assignment operator + mutex(const mutex&) = delete; + mutex& operator=(const mutex&) = delete; + + private: + pthread_mutex_t m_; +}; + +} // namespace ctl + +#endif // CTL_MUTEX_H_ diff --git a/ctl/numeric_limits.h b/ctl/numeric_limits.h index 5693a62e2..41aea3ae2 100644 --- a/ctl/numeric_limits.h +++ b/ctl/numeric_limits.h @@ -2,7 +2,8 @@ // vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi #ifndef CTL_NUMERIC_LIMITS_H_ #define CTL_NUMERIC_LIMITS_H_ -#include "type_traits.h" +#include "is_integral.h" +#include "is_unsigned.h" namespace ctl { diff --git a/ctl/partition.h b/ctl/partition.h new file mode 100644 index 000000000..a1db21fb2 --- /dev/null +++ b/ctl/partition.h @@ -0,0 +1,29 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_PARTITION_H_ +#define CTL_PARTITION_H_ +#include "utility.h" + +namespace ctl { + +template +RandomIt +partition(RandomIt first, RandomIt last, Compare comp) +{ + auto pivot = *ctl::move(last - 1); + auto i = first - 1; + + for (auto j = first; j < last - 1; ++j) { + if (comp(*j, pivot)) { + ++i; + ctl::swap(*i, *j); + } + } + + ctl::swap(*(i + 1), *(last - 1)); + return i + 1; +} + +} // namespace ctl + +#endif // CTL_PARTITION_H_ diff --git a/ctl/remove_cv.h b/ctl/remove_cv.h new file mode 100644 index 000000000..2801f7d80 --- /dev/null +++ b/ctl/remove_cv.h @@ -0,0 +1,49 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_REMOVE_CV_H_ +#define CTL_REMOVE_CV_H_ + +namespace ctl { + +template +struct remove_const +{ + typedef T type; +}; + +template +struct remove_const +{ + typedef T type; +}; + +template +struct remove_volatile +{ + typedef T type; +}; + +template +struct remove_volatile +{ + typedef T type; +}; + +template +struct remove_cv +{ + typedef typename remove_volatile::type>::type type; +}; + +template +using remove_const_t = typename remove_const::type; + +template +using remove_volatile_t = typename remove_volatile::type; + +template +using remove_cv_t = typename remove_cv::type; + +} // namespace ctl + +#endif // CTL_REMOVE_CV_H_ diff --git a/ctl/remove_extent.h b/ctl/remove_extent.h new file mode 100644 index 000000000..7aef1d20a --- /dev/null +++ b/ctl/remove_extent.h @@ -0,0 +1,31 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_REMOVE_EXTENT_H_ +#define CTL_REMOVE_EXTENT_H_ + +namespace ctl { + +template +struct remove_extent +{ + typedef T type; +}; + +template +struct remove_extent +{ + typedef T type; +}; + +template +struct remove_extent +{ + typedef T type; +}; + +template +using remove_extent_t = typename remove_extent::type; + +} // namespace ctl + +#endif // CTL_REMOVE_EXTENT_H_ diff --git a/ctl/remove_reference.h b/ctl/remove_reference.h new file mode 100644 index 000000000..3e773e0ce --- /dev/null +++ b/ctl/remove_reference.h @@ -0,0 +1,31 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_REMOVE_REFERENCE_H_ +#define CTL_REMOVE_REFERENCE_H_ + +namespace ctl { + +template +struct remove_reference +{ + typedef T type; +}; + +template +struct remove_reference +{ + typedef T type; +}; + +template +struct remove_reference +{ + typedef T type; +}; + +template +using remove_reference_t = typename remove_reference::type; + +} // namespace ctl + +#endif // CTL_REMOVE_REFERENCE_H_ diff --git a/ctl/runtime_error.h b/ctl/runtime_error.h new file mode 100644 index 000000000..29cc5f301 --- /dev/null +++ b/ctl/runtime_error.h @@ -0,0 +1,33 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_RUNTIME_ERROR_H_ +#define CTL_RUNTIME_ERROR_H_ +#include "ctl/string.h" + +namespace ctl { + +class runtime_error +{ + public: + explicit runtime_error(const string& what_arg) : msg_(what_arg) + { + } + + explicit runtime_error(const char* what_arg) : msg_(what_arg) + { + } + + virtual ~runtime_error() noexcept = default; + + virtual const char* what() const noexcept + { + return msg_.c_str(); + } + + private: + string msg_; +}; + +} // namespace ctl + +#endif // CTL_RUNTIME_ERROR_H_ diff --git a/ctl/sort.h b/ctl/sort.h new file mode 100644 index 000000000..fb5a3d6c2 --- /dev/null +++ b/ctl/sort.h @@ -0,0 +1,44 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_SORT_H_ +#define CTL_SORT_H_ +#include "iterator_traits.h" +#include "less.h" +#include "partition.h" + +namespace ctl { + +namespace detail { + +template +void +quicksort(RandomIt first, RandomIt last, Compare comp) +{ + if (first < last) { + auto pivot = ctl::partition(first, last, comp); + quicksort(first, pivot, comp); + quicksort(pivot + 1, last, comp); + } +} + +} // namespace detail + +template +void +sort(RandomIt first, RandomIt last, Compare comp) +{ + detail::quicksort(first, last, comp); +} + +template +void +sort(RandomIt first, RandomIt last) +{ + sort(first, + last, + ctl::less::value_type>()); +} + +} // namespace ctl + +#endif // CTL_SORT_H_ diff --git a/ctl/strcat.cc b/ctl/strcat.cc index 0e7c49070..a00cf0e59 100644 --- a/ctl/strcat.cc +++ b/ctl/strcat.cc @@ -38,9 +38,9 @@ strcat(const string_view lhs, const string_view rhs) noexcept if (rhs.n) memcpy(res.data() + lhs.n, rhs.p, rhs.n); if (res.isbig()) { - res.big()->n = lhs.n + rhs.n; + res.__b.n = lhs.n + rhs.n; } else { - res.small()->rem = __::sso_max - lhs.n - rhs.n; + res.__s.rem = __::sso_max - lhs.n - rhs.n; } res.data()[res.size()] = 0; return res; diff --git a/ctl/string.cc b/ctl/string.cc index 08ee1e65d..064882178 100644 --- a/ctl/string.cc +++ b/ctl/string.cc @@ -26,7 +26,7 @@ namespace ctl { void string::destroy_big() noexcept { - auto* b = big(); + auto* b = &__b; if (b->n) { if (b->n >= b->c) __builtin_trap(); @@ -41,7 +41,14 @@ string::destroy_big() noexcept void string::init_big(const string& s) noexcept { - init_big(string_view(s)); + char* p2; + size_t size = s.size(); + size_t need = size + 1; + size_t capacity = need; + if (!(p2 = (char*)malloc(capacity))) + __builtin_trap(); + memcpy(p2, s.data(), need); + set_big_string(p2, size, capacity); } void @@ -103,7 +110,7 @@ string::reserve(size_t c2) noexcept __builtin_trap(); memcpy(p2, data(), __::string_size); } else { - if (!(p2 = (char*)realloc(big()->p, c2))) + if (!(p2 = (char*)realloc(__b.p, c2))) __builtin_trap(); } std::atomic_signal_fence(std::memory_order_seq_cst); @@ -120,7 +127,7 @@ string::resize(const size_t n2, const char ch) noexcept if (n2 > size()) memset(data() + size(), ch, n2 - size()); if (isbig()) { - big()->p[big()->n = n2] = 0; + __b.p[__b.n = n2] = 0; } else { set_small_size(n2); data()[size()] = 0; @@ -141,9 +148,9 @@ string::append(const char ch) noexcept } data()[size()] = ch; if (isbig()) { - ++big()->n; + ++__b.n; } else { - --small()->rem; + --__s.rem; } data()[size()] = 0; } @@ -174,9 +181,9 @@ string::append(const char ch, const size_t size) noexcept if (size) memset(data() + this->size(), ch, size); if (isbig()) { - big()->n += size; + __b.n += size; } else { - small()->rem -= size; + __s.rem -= size; } data()[this->size()] = 0; } @@ -188,9 +195,9 @@ string::append(const void* data, const size_t size) noexcept if (size) memcpy(this->data() + this->size(), data, size); if (isbig()) { - big()->n += size; + __b.n += size; } else { - small()->rem -= size; + __s.rem -= size; } this->data()[this->size()] = 0; } @@ -201,9 +208,9 @@ string::pop_back() noexcept if (!size()) __builtin_trap(); if (isbig()) { - --big()->n; + --__b.n; } else { - ++small()->rem; + ++__s.rem; } data()[size()] = 0; } @@ -322,7 +329,7 @@ string::replace(const size_t pos, memmove(data() + pos + s.n, data() + last, extra); memcpy(data() + pos, s.p, s.n); if (isbig()) { - big()->p[big()->n = need] = 0; + __b.p[__b.n = need] = 0; } else { set_small_size(need); data()[size()] = 0; @@ -346,9 +353,9 @@ string::insert(const size_t i, const string_view s) noexcept memmove(data() + i + s.n, data() + i, extra); memcpy(data() + i, s.p, s.n); if (isbig()) { - big()->n += s.n; + __b.n += s.n; } else { - small()->rem -= s.n; + __s.rem -= s.n; } data()[size()] = 0; return *this; @@ -365,7 +372,7 @@ string::erase(const size_t pos, size_t count) noexcept if (extra) memmove(data() + pos, data() + pos + count, extra); if (isbig()) { - big()->n = pos + extra; + __b.n = pos + extra; } else { set_small_size(pos + extra); } diff --git a/ctl/string.h b/ctl/string.h index 69a9cf1b7..ba0ee6223 100644 --- a/ctl/string.h +++ b/ctl/string.h @@ -151,7 +151,7 @@ class string void clear() noexcept { if (isbig()) { - big()->n = 0; + __b.n = 0; } else { set_small_size(0); } @@ -159,26 +159,26 @@ class string bool empty() const noexcept { - return isbig() ? !big()->n : small()->rem >= __::sso_max; + return isbig() ? !__b.n : __s.rem >= __::sso_max; } - char* data() noexcept + __attribute__((__always_inline__)) char* data() noexcept { - return isbig() ? big()->p : small()->buf; + return isbig() ? __b.p : __s.buf; } - const char* data() const noexcept + __attribute__((__always_inline__)) const char* data() const noexcept { - return isbig() ? big()->p : small()->buf; + return isbig() ? __b.p : __s.buf; } - size_t size() const noexcept + __attribute__((__always_inline__)) size_t size() const noexcept { #if 0 - if (!isbig() && small()->rem > __::sso_max) + if (!isbig() && __s.rem > __::sso_max) __builtin_trap(); #endif - return isbig() ? big()->n : __::sso_max - small()->rem; + return isbig() ? __b.n : __::sso_max - __s.rem; } size_t length() const noexcept @@ -189,10 +189,10 @@ class string size_t capacity() const noexcept { #if 0 - if (isbig() && big()->c <= __::sso_max) + if (isbig() && __b.c <= __::sso_max) __builtin_trap(); #endif - return isbig() ? __::big_mask & big()->c : __::string_size; + return isbig() ? __::big_mask & __b.c : __::string_size; } iterator begin() noexcept @@ -374,7 +374,7 @@ class string void init_big(string_view) noexcept; void init_big(size_t, char) noexcept; - bool isbig() const noexcept + __attribute__((__always_inline__)) bool isbig() const noexcept { return *(blob + __::sso_max) & 0x80; } @@ -395,34 +395,6 @@ class string __b.c = c2 | ~__::big_mask; } - __::small_string* small() noexcept - { - if (isbig()) - __builtin_trap(); - return &__s; - } - - const __::small_string* small() const noexcept - { - if (isbig()) - __builtin_trap(); - return &__s; - } - - __::big_string* big() noexcept - { - if (!isbig()) - __builtin_trap(); - return &__b; - } - - const __::big_string* big() const noexcept - { - if (!isbig()) - __builtin_trap(); - return &__b; - } - friend string strcat(string_view, string_view) noexcept; union diff --git a/ctl/tuple.h b/ctl/tuple.h new file mode 100644 index 000000000..dcea0f15f --- /dev/null +++ b/ctl/tuple.h @@ -0,0 +1,138 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_TUPLE_H_ +#define CTL_TUPLE_H_ +#include "decay.h" +#include "enable_if.h" +#include "is_same.h" +#include "utility.h" + +namespace ctl { + +// Forward declaration +template +class tuple; + +// Base case for tuple +template<> +class tuple<> +{}; + +// Recursive case for tuple +template +class tuple : public tuple +{ + using Base = tuple; + + public: + Head head; + + constexpr tuple() : Base(), head() + { + } + + template::type, tuple>::value>::type> + constexpr tuple(H&& h, T&&... t) + : Base(ctl::forward(t)...), head(ctl::forward(h)) + { + } + + template + constexpr tuple(const tuple& other) + : Base(static_cast&>(other)), head(other.head) + { + } + + template + constexpr tuple(tuple&& other) + : Base(static_cast&&>(other)) + , head(ctl::forward(other.head)) + { + } + + tuple(const tuple&) = default; + tuple(tuple&&) = default; + tuple& operator=(const tuple&) = default; + tuple& operator=(tuple&&) = default; +}; + +// Helper struct for getting element type +template +struct tuple_element; + +template +struct tuple_element> + : tuple_element> +{}; + +template +struct tuple_element<0, tuple> +{ + using type = Head; +}; + +// Helper function to get element +template +constexpr typename tuple_element>::type& +get(tuple& t) +{ + if constexpr (I == 0) { + return t.head; + } else { + return get(static_cast&>(t)); + } +} + +template +constexpr const typename tuple_element>::type& +get(const tuple& t) +{ + if constexpr (I == 0) { + return t.head; + } else { + return get(static_cast&>(t)); + } +} + +// Helper function to create a tuple +template +constexpr tuple::type...> +make_tuple(Types&&... args) +{ + return tuple::type...>( + ctl::forward(args)...); +} + +// Helper function for tuple comparison +template +constexpr bool +tuple_equals(const tuple& t, const tuple& u) +{ + if constexpr (I == sizeof...(TTypes)) { + return true; + } else { + return get(t) == get(u) && tuple_equals(t, u); + } +} + +// Equality comparison +template +constexpr bool +operator==(const tuple& t, const tuple& u) +{ + return tuple_equals(t, u); +} + +template +constexpr bool +operator!=(const tuple& t, const tuple& u) +{ + return !(t == u); +} + +} // namespace ctl + +#endif // CTL_TUPLE_H_ diff --git a/ctl/unique_lock.h b/ctl/unique_lock.h new file mode 100644 index 000000000..6568a408e --- /dev/null +++ b/ctl/unique_lock.h @@ -0,0 +1,147 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_UNIQUE_LOCK_H_ +#define CTL_UNIQUE_LOCK_H_ +#include "mutex.h" +#include "utility.h" + +namespace ctl { + +struct defer_lock_t +{ + explicit defer_lock_t() = default; +}; + +struct try_to_lock_t +{ + explicit try_to_lock_t() = default; +}; + +struct adopt_lock_t +{ + explicit adopt_lock_t() = default; +}; + +inline constexpr defer_lock_t defer_lock{}; +inline constexpr try_to_lock_t try_to_lock{}; +inline constexpr adopt_lock_t adopt_lock{}; + +class unique_lock +{ + public: + unique_lock() noexcept : mutex_(nullptr), owns_lock_(false) + { + } + + explicit unique_lock(ctl::mutex& m) : mutex_(&m), owns_lock_(false) + { + lock(); + } + + unique_lock(ctl::mutex& m, defer_lock_t) noexcept + : mutex_(&m), owns_lock_(false) + { + } + + unique_lock(ctl::mutex& m, try_to_lock_t) + : mutex_(&m), owns_lock_(mutex_->try_lock()) + { + } + + unique_lock(ctl::mutex& m, adopt_lock_t) : mutex_(&m), owns_lock_(true) + { + } + + ~unique_lock() + { + if (owns_lock_) + mutex_->unlock(); + } + + unique_lock(const unique_lock&) = delete; + unique_lock& operator=(const unique_lock&) = delete; + + unique_lock(unique_lock&& other) noexcept + : mutex_(other.mutex_), owns_lock_(other.owns_lock_) + { + other.mutex_ = nullptr; + other.owns_lock_ = false; + } + + unique_lock& operator=(unique_lock&& other) noexcept + { + if (owns_lock_) + mutex_->unlock(); + mutex_ = other.mutex_; + owns_lock_ = other.owns_lock_; + other.mutex_ = nullptr; + other.owns_lock_ = false; + return *this; + } + + void lock() + { + if (!mutex_) + __builtin_trap(); + if (owns_lock_) + __builtin_trap(); + mutex_->lock(); + owns_lock_ = true; + } + + bool try_lock() + { + if (!mutex_) + __builtin_trap(); + if (owns_lock_) + __builtin_trap(); + owns_lock_ = mutex_->try_lock(); + return owns_lock_; + } + + void unlock() + { + if (!owns_lock_) + __builtin_trap(); + mutex_->unlock(); + owns_lock_ = false; + } + + void swap(unique_lock& other) noexcept + { + using ctl::swap; + swap(mutex_, other.mutex_); + swap(owns_lock_, other.owns_lock_); + } + + ctl::mutex* release() noexcept + { + ctl::mutex* result = mutex_; + mutex_ = nullptr; + owns_lock_ = false; + return result; + } + + bool owns_lock() const noexcept + { + return owns_lock_; + } + + explicit operator bool() const noexcept + { + return owns_lock_; + } + + ctl::mutex* mutex() const noexcept + { + return mutex_; + } + + private: + ctl::mutex* mutex_; + bool owns_lock_; +}; + +} // namespace ctl + +#endif // CTL_UNIQUE_LOCK_H_ diff --git a/ctl/unique_ptr.cc b/ctl/unique_ptr.cc deleted file mode 100644 index daeda3b1b..000000000 --- a/ctl/unique_ptr.cc +++ /dev/null @@ -1,19 +0,0 @@ -// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*- -// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi -// -// Copyright 2024 Justine Alexandra Roberts Tunney -// -// Permission to use, copy, modify, and/or distribute this software for -// any purpose with or without fee is hereby granted, provided that the -// above copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL -// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -// PERFORMANCE OF THIS SOFTWARE. - -#include "unique_ptr.h" diff --git a/ctl/unique_ptr.h b/ctl/unique_ptr.h index c2ebae7ba..5027d5ec1 100644 --- a/ctl/unique_ptr.h +++ b/ctl/unique_ptr.h @@ -1,41 +1,17 @@ // -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- // vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi -#ifndef COSMOPOLITAN_CTL_UNIQUE_PTR_H_ -#define COSMOPOLITAN_CTL_UNIQUE_PTR_H_ +#ifndef CTL_UNIQUE_PTR_H_ +#define CTL_UNIQUE_PTR_H_ +#include "add_lvalue_reference.h" +#include "default_delete.h" +#include "is_convertible.h" +#include "is_reference.h" +#include "is_same.h" #include "utility.h" -#include <__type_traits/is_convertible.h> namespace ctl { -template -struct default_delete -{ - constexpr default_delete() noexcept = default; - template - constexpr default_delete(default_delete&&) noexcept - { - } - constexpr void operator()(T* const p) const noexcept - { - delete p; - } -}; - -template -struct default_delete -{ - constexpr default_delete() noexcept = default; - template - constexpr default_delete(default_delete&&) noexcept - { - } - constexpr void operator()(T* const p) const noexcept - { - delete[] p; - } -}; - -template> +template> struct unique_ptr { using pointer = T*; @@ -49,26 +25,34 @@ struct unique_ptr { } - constexpr unique_ptr(const pointer p) noexcept : p(p), d() + constexpr explicit unique_ptr(pointer p) noexcept : p(p), d() { } - constexpr unique_ptr(const pointer p, auto&& d) noexcept - : p(p), d(ctl::forward(d)) + constexpr unique_ptr(pointer p, const D& d) noexcept : p(p), d(d) + { + } + + constexpr unique_ptr(pointer p, D&& d) noexcept : p(p), d(ctl::move(d)) { } template - requires std::is_convertible_v && std::is_convertible_v constexpr unique_ptr(unique_ptr&& u) noexcept - : p(u.p), d(ctl::move(u.d)) + : p(u.release()), d(ctl::forward(u.get_deleter())) { - u.p = nullptr; + static_assert(ctl::is_convertible::pointer, + pointer>::value, + "U* must be implicitly convertible to T*"); + static_assert( + (ctl::is_reference::value && ctl::is_same::value) || + (!ctl::is_reference::value && ctl::is_convertible::value), + "The deleter must be convertible to the target deleter type"); } unique_ptr(const unique_ptr&) = delete; - constexpr ~unique_ptr() /* noexcept */ + constexpr ~unique_ptr() noexcept { if (p) d(p); @@ -80,6 +64,20 @@ struct unique_ptr return *this; } + template + constexpr unique_ptr& operator=(unique_ptr&& r) noexcept + { + reset(r.release()); + d = ctl::forward(r.get_deleter()); + return *this; + } + + constexpr unique_ptr& operator=(nullptr_t) noexcept + { + reset(); + return *this; + } + constexpr pointer release() noexcept { pointer r = p; @@ -87,12 +85,12 @@ struct unique_ptr return r; } - constexpr void reset(const pointer p2 = pointer()) noexcept + constexpr void reset(pointer p2 = pointer()) noexcept { - const pointer r = p; + pointer old = p; p = p2; - if (r) - d(r); + if (old) + d(old); } constexpr void swap(unique_ptr& r) noexcept @@ -119,20 +117,16 @@ struct unique_ptr constexpr explicit operator bool() const noexcept { - return p; + return p != nullptr; } - element_type& operator*() const noexcept(noexcept(*ctl::declval())) + constexpr typename ctl::add_lvalue_reference::type operator*() const { - if (!p) - __builtin_trap(); return *p; } - pointer operator->() const noexcept + constexpr pointer operator->() const noexcept { - if (!p) - __builtin_trap(); return p; } }; @@ -148,16 +142,9 @@ template constexpr unique_ptr make_unique_for_overwrite() { -#if 0 - // You'd think that it'd work like this, but std::unique_ptr does not. - return unique_ptr( - static_cast(::operator new(sizeof(T), align_val_t(alignof(T))))); -#else return unique_ptr(new T); -#endif } -// TODO(mrdomino): specializations for T[] - } // namespace ctl -#endif // COSMOPOLITAN_CTL_UNIQUE_PTR_H_ + +#endif // CTL_UNIQUE_PTR_H_ diff --git a/ctl/utility.cc b/ctl/utility.cc deleted file mode 100644 index a4c2a2008..000000000 --- a/ctl/utility.cc +++ /dev/null @@ -1,19 +0,0 @@ -// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*- -// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi -// -// Copyright 2024 Justine Alexandra Roberts Tunney -// -// Permission to use, copy, modify, and/or distribute this software for -// any purpose with or without fee is hereby granted, provided that the -// above copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL -// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -// PERFORMANCE OF THIS SOFTWARE. - -#include "utility.h" diff --git a/ctl/utility.h b/ctl/utility.h index 62036ca04..464e04f64 100644 --- a/ctl/utility.h +++ b/ctl/utility.h @@ -2,6 +2,7 @@ // vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi #ifndef COSMOPOLITAN_CTL_UTILITY_H_ #define COSMOPOLITAN_CTL_UTILITY_H_ +#include "remove_reference.h" namespace ctl { @@ -18,6 +19,14 @@ using no_infer = typename no_infer_::type; } // namespace __ +template +constexpr T&& +move(T&& t) noexcept +{ + typedef remove_reference_t U; + return static_cast(t); +} + template constexpr T&& move(T& t) noexcept @@ -47,9 +56,8 @@ template constexpr void swap(T (&a)[N], T (&b)[N]) noexcept { - for (size_t i = 0; i < N; ++i) { + for (size_t i = 0; i < N; ++i) swap(a[i], b[i]); - } } template diff --git a/ctl/void_t.h b/ctl/void_t.h new file mode 100644 index 000000000..c4573260e --- /dev/null +++ b/ctl/void_t.h @@ -0,0 +1,13 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_VOID_T_H_ +#define CTL_VOID_T_H_ + +namespace ctl { + +template +using void_t = void; + +} // namespace ctl + +#endif // CTL_VOID_T_H_ diff --git a/libc/runtime/dsohandle.S b/libc/intrin/dsohandle.S similarity index 100% rename from libc/runtime/dsohandle.S rename to libc/intrin/dsohandle.S diff --git a/test/ctl/BUILD.mk b/test/ctl/BUILD.mk index 439d7e786..2bdcf5381 100644 --- a/test/ctl/BUILD.mk +++ b/test/ctl/BUILD.mk @@ -18,6 +18,7 @@ TEST_CTL_DIRECTDEPS = \ LIBC_INTRIN \ LIBC_MEM \ LIBC_STDIO \ + LIBC_THREAD \ THIRD_PARTY_LIBCXX \ THIRD_PARTY_LIBCXXABI \ THIRD_PARTY_LIBUNWIND \ diff --git a/test/ctl/accumulate_test.cc b/test/ctl/accumulate_test.cc index ff29e278e..3145e18e2 100644 --- a/test/ctl/accumulate_test.cc +++ b/test/ctl/accumulate_test.cc @@ -18,6 +18,7 @@ #include "ctl/accumulate.h" #include "ctl/array.h" +#include "libc/mem/leaks.h" // #include // #include @@ -48,4 +49,6 @@ main() // Test accumulation with single element if (ctl::accumulate(arr.begin(), arr.begin() + 1, 0) != 1) return 5; + + CheckForMemoryLeaks(); } diff --git a/test/ctl/advance_test.cc b/test/ctl/advance_test.cc index 90b381bd5..e0782ba35 100644 --- a/test/ctl/advance_test.cc +++ b/test/ctl/advance_test.cc @@ -18,6 +18,7 @@ #include "ctl/advance.h" #include "ctl/array.h" +#include "libc/mem/leaks.h" // #include // #include @@ -53,4 +54,6 @@ main() ctl::advance(it, -2); if (it != arr.begin()) return 5; + + CheckForMemoryLeaks(); } diff --git a/test/ctl/all_of_test.cc b/test/ctl/all_of_test.cc index 5f38e441b..4bc090b67 100644 --- a/test/ctl/all_of_test.cc +++ b/test/ctl/all_of_test.cc @@ -18,6 +18,7 @@ #include "ctl/all_of.h" #include "ctl/array.h" +#include "libc/mem/leaks.h" #include #include @@ -49,4 +50,6 @@ main() // Test with no elements satisfying the condition if (ctl::all_of(arr1.begin(), arr1.end(), [](int n) { return n > 10; })) return 5; + + CheckForMemoryLeaks(); } diff --git a/test/ctl/any_of_test.cc b/test/ctl/any_of_test.cc index 02ba6928d..ee08afd3e 100644 --- a/test/ctl/any_of_test.cc +++ b/test/ctl/any_of_test.cc @@ -18,6 +18,7 @@ #include "ctl/any_of.h" #include "ctl/array.h" +#include "libc/mem/leaks.h" // #include // #include @@ -48,4 +49,6 @@ main() // Test with a different condition if (!ctl::any_of(arr1.begin(), arr1.end(), [](int n) { return n > 5; })) return 5; + + CheckForMemoryLeaks(); } diff --git a/test/ctl/array_test.cc b/test/ctl/array_test.cc index 5fd8dbe54..40f774173 100644 --- a/test/ctl/array_test.cc +++ b/test/ctl/array_test.cc @@ -17,8 +17,11 @@ // PERFORMANCE OF THIS SOFTWARE. #include "ctl/array.h" +#include "ctl/string.h" +#include "libc/mem/leaks.h" // #include +// #include // #define ctl std int @@ -264,4 +267,21 @@ main() if (rit != arr.rend()) return 4; } + + { + ctl::array A = { "hi", "theretheretheretherethere" }; + if (A.size() != 2) + return 76; + if (A[0] != "hi") + return 77; + if (A[1] != "theretheretheretherethere") + return 78; + A = { "theretheretheretherethere", "hi" }; + if (A[0] != "theretheretheretherethere") + return 79; + if (A[1] != "hi") + return 80; + } + + CheckForMemoryLeaks(); } diff --git a/test/ctl/back_inserter_test.cc b/test/ctl/back_inserter_test.cc index 38659b10e..122493952 100644 --- a/test/ctl/back_inserter_test.cc +++ b/test/ctl/back_inserter_test.cc @@ -20,6 +20,7 @@ #include "ctl/back_inserter.h" #include "ctl/copy.h" #include "ctl/vector.h" +#include "libc/mem/leaks.h" // #include // #include @@ -29,33 +30,38 @@ int main() { - ctl::vector vec = { 1, 2, 3 }; - ctl::array arr = { 4, 5, 6 }; - // Use back_inserter to append elements from arr to vec - ctl::copy(arr.begin(), arr.end(), ctl::back_inserter(vec)); + { + ctl::vector vec = { 1, 2, 3 }; + ctl::array arr = { 4, 5, 6 }; - // Check if vec now contains all elements - if (vec.size() != 6) - return 1; - if (vec[0] != 1 || vec[1] != 2 || vec[2] != 3 || vec[3] != 4 || - vec[4] != 5 || vec[5] != 6) - return 2; + // Use back_inserter to append elements from arr to vec + ctl::copy(arr.begin(), arr.end(), ctl::back_inserter(vec)); - // Use back_inserter with a single element - ctl::back_inserter(vec) = 7; + // Check if vec now contains all elements + if (vec.size() != 6) + return 1; + if (vec[0] != 1 || vec[1] != 2 || vec[2] != 3 || vec[3] != 4 || + vec[4] != 5 || vec[5] != 6) + return 2; - // Check if the new element was added - if (vec.size() != 7) - return 3; - if (vec[6] != 7) - return 4; + // Use back_inserter with a single element + ctl::back_inserter(vec) = 7; - // Test with an empty source range - ctl::array empty_arr; - ctl::copy(empty_arr.begin(), empty_arr.end(), ctl::back_inserter(vec)); + // Check if the new element was added + if (vec.size() != 7) + return 3; + if (vec[6] != 7) + return 4; - // Check that no elements were added - if (vec.size() != 7) - return 5; + // Test with an empty source range + ctl::array empty_arr; + ctl::copy(empty_arr.begin(), empty_arr.end(), ctl::back_inserter(vec)); + + // Check that no elements were added + if (vec.size() != 7) + return 5; + } + + CheckForMemoryLeaks(); } diff --git a/test/ctl/copy_test.cc b/test/ctl/copy_test.cc index 868bbee97..2c417186a 100644 --- a/test/ctl/copy_test.cc +++ b/test/ctl/copy_test.cc @@ -18,49 +18,56 @@ #include "ctl/array.h" #include "ctl/copy.h" +#include "libc/mem/leaks.h" -// #include +// #include // #include +// #include // #define ctl std int main() { - ctl::array src = { 1, 2, 3, 4, 5 }; - ctl::array dest = { 0, 0, 0, 0, 0 }; - // Test basic copy - ctl::copy(src.begin(), src.end(), dest.begin()); - for (size_t i = 0; i < 5; ++i) { - if (dest[i] != src[i]) - return 1; + { + ctl::array src = { 1, 2, 3, 4, 5 }; + ctl::array dest = { 0, 0, 0, 0, 0 }; + + // Test basic copy + ctl::copy(src.begin(), src.end(), dest.begin()); + for (size_t i = 0; i < 5; ++i) { + if (dest[i] != src[i]) + return 1; + } + + // Test partial copy + ctl::array dest2 = { 0, 0, 0, 0, 0 }; + ctl::copy(src.begin(), src.begin() + 3, dest2.begin()); + if (dest2[0] != 1 || dest2[1] != 2 || dest2[2] != 3 || dest2[3] != 0 || + dest2[4] != 0) + return 2; + + // Test copy to middle of destination + ctl::array dest3 = { 0, 0, 0, 0, 0, 0, 0 }; + ctl::copy(src.begin(), src.end(), dest3.begin() + 1); + if (dest3[0] != 0 || dest3[1] != 1 || dest3[2] != 2 || dest3[3] != 3 || + dest3[4] != 4 || dest3[5] != 5 || dest3[6] != 0) + return 3; + + // Test copy with empty range + ctl::array dest4 = { 0, 0, 0, 0, 0 }; + ctl::copy(src.begin(), src.begin(), dest4.begin()); + for (size_t i = 0; i < 5; ++i) { + if (dest4[i] != 0) + return 4; + } + + // Test copy return value + ctl::array dest5 = { 0, 0, 0, 0, 0 }; + auto result = ctl::copy(src.begin(), src.end(), dest5.begin()); + if (result != dest5.end()) + return 5; } - // Test partial copy - ctl::array dest2 = { 0, 0, 0, 0, 0 }; - ctl::copy(src.begin(), src.begin() + 3, dest2.begin()); - if (dest2[0] != 1 || dest2[1] != 2 || dest2[2] != 3 || dest2[3] != 0 || - dest2[4] != 0) - return 2; - - // Test copy to middle of destination - ctl::array dest3 = { 0, 0, 0, 0, 0, 0, 0 }; - ctl::copy(src.begin(), src.end(), dest3.begin() + 1); - if (dest3[0] != 0 || dest3[1] != 1 || dest3[2] != 2 || dest3[3] != 3 || - dest3[4] != 4 || dest3[5] != 5 || dest3[6] != 0) - return 3; - - // Test copy with empty range - ctl::array dest4 = { 0, 0, 0, 0, 0 }; - ctl::copy(src.begin(), src.begin(), dest4.begin()); - for (size_t i = 0; i < 5; ++i) { - if (dest4[i] != 0) - return 4; - } - - // Test copy return value - ctl::array dest5 = { 0, 0, 0, 0, 0 }; - auto result = ctl::copy(src.begin(), src.end(), dest5.begin()); - if (result != dest5.end()) - return 5; + CheckForMemoryLeaks(); } diff --git a/test/ctl/mutex_test.cc b/test/ctl/mutex_test.cc new file mode 100644 index 000000000..9c03d08c8 --- /dev/null +++ b/test/ctl/mutex_test.cc @@ -0,0 +1,114 @@ +// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +// +// Copyright 2024 Justine Alexandra Roberts Tunney +// +// Permission to use, copy, modify, and/or distribute this software for +// any purpose with or without fee is hereby granted, provided that the +// above copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include "ctl/mutex.h" +#include "libc/mem/leaks.h" + +// #include +// #define ctl std + +ctl::mutex mtx; +int shared_resource = 0; +const int NUM_THREADS = 5; +const int ITERATIONS = 100000; + +void* +increment_resource(void* arg) +{ + for (int i = 0; i < ITERATIONS; ++i) { + mtx.lock(); + ++shared_resource; + mtx.unlock(); + } + return nullptr; +} + +void* +decrement_resource(void* arg) +{ + for (int i = 0; i < ITERATIONS; ++i) { + mtx.lock(); + --shared_resource; + mtx.unlock(); + } + return nullptr; +} + +int +test_basic_locking() +{ + shared_resource = 0; + pthread_t threads[NUM_THREADS]; + for (int i = 0; i < NUM_THREADS; ++i) + if (pthread_create(&threads[i], 0, increment_resource, 0) != 0) + return 1; + for (int i = 0; i < NUM_THREADS; ++i) + if (pthread_join(threads[i], 0) != 0) + return 2; + return (shared_resource == NUM_THREADS * ITERATIONS) ? 0 : 3; +} + +int +test_lock_contention() +{ + shared_resource = 0; + pthread_t threads[NUM_THREADS * 2]; + for (int i = 0; i < NUM_THREADS; ++i) + if (pthread_create(&threads[i], 0, increment_resource, 0) != 0 || + pthread_create(&threads[i + NUM_THREADS], + nullptr, + decrement_resource, + nullptr) != 0) + return 4; + for (int i = 0; i < NUM_THREADS * 2; ++i) + if (pthread_join(threads[i], 0) != 0) + return 5; + return (shared_resource == 0) ? 0 : 6; +} + +int +test_try_lock() +{ + ctl::mutex try_mtx; + if (!try_mtx.try_lock()) + return 7; + if (try_mtx.try_lock()) + return 8; + try_mtx.unlock(); + return 0; +} + +int +main() +{ + int result; + + result = test_basic_locking(); + if (result != 0) + return result; + + result = test_lock_contention(); + if (result != 0) + return result; + + result = test_try_lock(); + if (result != 0) + return result; + + CheckForMemoryLeaks(); +} diff --git a/test/ctl/sort_test.cc b/test/ctl/sort_test.cc new file mode 100644 index 000000000..2acc59917 --- /dev/null +++ b/test/ctl/sort_test.cc @@ -0,0 +1,130 @@ +// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +// +// Copyright 2024 Justine Alexandra Roberts Tunney +// +// Permission to use, copy, modify, and/or distribute this software for +// any purpose with or without fee is hereby granted, provided that the +// above copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include "ctl/is_sorted.h" +#include "ctl/sort.h" +#include "ctl/string.h" +#include "ctl/vector.h" +#include "libc/mem/leaks.h" +#include "libc/stdio/rand.h" + +// #include +// #include +// #include +// #define ctl std + +// Test sorting integers +int +test_sort_integers() +{ + ctl::vector v = { 5, 2, 8, 1, 9, 3, 7, 6, 4 }; + ctl::sort(v.begin(), v.end()); + if (!ctl::is_sorted(v.begin(), v.end(), ctl::less())) + return 1; + return 0; +} + +// Test sorting with custom comparator +int +test_sort_custom_compare() +{ + ctl::vector v = { 5, 2, 8, 1, 9, 3, 7, 6, 4 }; + ctl::sort(v.begin(), v.end(), [](int a, int b) { return a > b; }); + if (!ctl::is_sorted(v.begin(), v.end(), [](int a, int b) { return a > b; })) + return 2; + return 0; +} + +// Test sorting strings +int +test_sort_strings() +{ + ctl::vector v = { "banana", "apple", "cherry", "date" }; + ctl::sort(v.begin(), v.end()); + if (!ctl::is_sorted(v.begin(), v.end(), ctl::less())) + return 3; + return 0; +} + +// Test sorting with large number of elements +int +test_sort_large() +{ + const int SIZE = 10000; + ctl::vector v(SIZE); + for (int i = 0; i < SIZE; ++i) + v[i] = rand() % SIZE; + ctl::sort(v.begin(), v.end()); + if (!is_sorted(v.begin(), v.end(), ctl::less())) + return 4; + return 0; +} + +// Test sorting already sorted vector +int +test_sort_sorted() +{ + ctl::vector v = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + ctl::sort(v.begin(), v.end()); + if (!is_sorted(v.begin(), v.end(), ctl::less())) + return 5; + return 0; +} + +// Test sorting reverse sorted vector +int +test_sort_reverse() +{ + ctl::vector v = { 9, 8, 7, 6, 5, 4, 3, 2, 1 }; + ctl::sort(v.begin(), v.end()); + if (!is_sorted(v.begin(), v.end(), ctl::less())) + return 6; + return 0; +} + +int +main() +{ + int result; + + result = test_sort_integers(); + if (result != 0) + return result; + + result = test_sort_custom_compare(); + if (result != 0) + return result; + + result = test_sort_strings(); + if (result != 0) + return result; + + result = test_sort_large(); + if (result != 0) + return result; + + result = test_sort_sorted(); + if (result != 0) + return result; + + result = test_sort_reverse(); + if (result != 0) + return result; + + CheckForMemoryLeaks(); +} diff --git a/test/ctl/string_bench.cc b/test/ctl/string_bench.cc index c59695dd1..b7b30c935 100644 --- a/test/ctl/string_bench.cc +++ b/test/ctl/string_bench.cc @@ -17,8 +17,8 @@ // PERFORMANCE OF THIS SOFTWARE. #include "ctl/string.h" - -#include <__utility/move.h> +#include "ctl/utility.h" +#include "libc/mem/leaks.h" #include "libc/calls/struct/timespec.h" #include "libc/runtime/runtime.h" @@ -100,7 +100,7 @@ main() BENCH(1000000, 1, { ctl::string s(small); - ctl::string s2(std::move(s)); + ctl::string s2(ctl::move(s)); }); BENCH(1000000, 1, { @@ -119,7 +119,7 @@ main() BENCH(1000000, 1, { ctl::string s(big); - ctl::string s2(std::move(s)); + ctl::string s2(ctl::move(s)); }); BENCH(1000000, 1, { @@ -142,5 +142,5 @@ main() BENCH(1000000, 1, { ctl::string s(big_trunc); }); } - return 0; + CheckForMemoryLeaks(); } diff --git a/test/ctl/string_test.cc b/test/ctl/string_test.cc index a3fd1f461..90b19e9c8 100644 --- a/test/ctl/string_test.cc +++ b/test/ctl/string_test.cc @@ -16,13 +16,14 @@ // TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. +#include "ctl/is_same.h" #include "ctl/string.h" -#include "ctl/type_traits.h" #include "libc/mem/leaks.h" #include "libc/str/str.h" // #include +// #include // #define ctl std using String = ctl::string; diff --git a/test/ctl/string_view_test.cc b/test/ctl/string_view_test.cc index 8ca1f8bee..a82743e15 100644 --- a/test/ctl/string_view_test.cc +++ b/test/ctl/string_view_test.cc @@ -173,5 +173,4 @@ main(int argc, char* argv[]) } CheckForMemoryLeaks(); - return 0; } diff --git a/test/ctl/tuple_test.cc b/test/ctl/tuple_test.cc new file mode 100644 index 000000000..0a3da6c6f --- /dev/null +++ b/test/ctl/tuple_test.cc @@ -0,0 +1,161 @@ +// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +// +// Copyright 2024 Justine Alexandra Roberts Tunney +// +// Permission to use, copy, modify, and/or distribute this software for +// any purpose with or without fee is hereby granted, provided that the +// above copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include "ctl/string.h" +#include "ctl/tuple.h" +#include "libc/mem/leaks.h" + +// #include +// #include +// #define ctl std + +int +test_tuple_creation() +{ + ctl::tuple t(1, 2.5, "hello"); + if (ctl::get<0>(t) != 1 || ctl::get<1>(t) != 2.5 || + ctl::get<2>(t) != "hello") { + return 1; + } + return 0; +} + +int +test_make_tuple() +{ + auto t = ctl::make_tuple(1, 2.5, ctl::string("hello")); + if (ctl::get<0>(t) != 1 || ctl::get<1>(t) != 2.5 || + ctl::get<2>(t) != "hello") { + return 2; + } + return 0; +} + +int +test_tuple_get() +{ + ctl::tuple t(1, 2.5, "hello"); + if (ctl::get<0>(t) != 1) + return 3; + if (ctl::get<1>(t) != 2.5) + return 4; + if (ctl::get<2>(t) != "hello") + return 5; + return 0; +} + +int +test_tuple_comparison() +{ + auto t1 = ctl::make_tuple(1, 2.5, "hello"); + auto t2 = ctl::make_tuple(1, 2.5, "hello"); + auto t3 = ctl::make_tuple(2, 3.5, "world"); + + if (!(t1 == t2)) + return 6; + if (t1 != t2) + return 7; + if (t1 == t3) + return 8; + if (!(t1 != t3)) + return 9; + + return 0; +} + +int +test_tuple_assignment() +{ + ctl::tuple t1(1, 2.5, "hello"); + ctl::tuple t2; + t2 = t1; + if (!(t1 == t2)) + return 10; + return 0; +} + +int +test_tuple_move() +{ + ctl::tuple t1(1, 2.5, "hello"); + ctl::tuple t2(ctl::move(t1)); + if (ctl::get<0>(t2) != 1 || ctl::get<1>(t2) != 2.5 || + ctl::get<2>(t2) != "hello") { + return 11; + } + return 0; +} + +int +test_empty_tuple() +{ + ctl::tuple<> t; + ctl::tuple<> t2; + if (!(t == t2)) + return 12; + return 0; +} + +int +test_single_element_tuple() +{ + ctl::tuple t(42); + if (ctl::get<0>(t) != 42) + return 13; + return 0; +} + +int +main() +{ + int result; + + result = test_tuple_creation(); + if (result != 0) + return result; + + result = test_make_tuple(); + if (result != 0) + return result; + + result = test_tuple_get(); + if (result != 0) + return result; + + result = test_tuple_comparison(); + if (result != 0) + return result; + + result = test_tuple_assignment(); + if (result != 0) + return result; + + result = test_tuple_move(); + if (result != 0) + return result; + + result = test_empty_tuple(); + if (result != 0) + return result; + + result = test_single_element_tuple(); + if (result != 0) + return result; + + CheckForMemoryLeaks(); +} diff --git a/test/ctl/unique_ptr_test.cc b/test/ctl/unique_ptr_test.cc index 87e4f30f2..75ed674ba 100644 --- a/test/ctl/unique_ptr_test.cc +++ b/test/ctl/unique_ptr_test.cc @@ -16,7 +16,7 @@ // TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. -#include "ctl/type_traits.h" +#include "ctl/is_same.h" #include "ctl/unique_ptr.h" #include "libc/mem/leaks.h" @@ -41,29 +41,30 @@ MkRaw() return ctl::make_unique_for_overwrite(); } -#undef ctl +// #undef ctl static int g = 0; struct SetsGDeleter { - void operator()(auto*) const noexcept + void operator()(auto* x) const noexcept { ++g; + delete x; } }; struct StatefulDeleter { char state; - void operator()(auto*) const noexcept + void operator()(auto* x) const noexcept { } }; struct FinalDeleter final { - void operator()(auto*) const noexcept + void operator()(auto* x) const noexcept { } }; @@ -99,6 +100,7 @@ struct Derived : Base int main() { + { Ptr x(new int(5)); } @@ -186,9 +188,9 @@ main() g = 0; { auto x = Mk(); - x.release(); + delete x.release(); } - if (g) + if (g != 1) return 13; } @@ -224,8 +226,5 @@ main() Ptr z(ctl::move(y)); } - // next is 18 - - // TODO(mrdomino): Fix memory leaks reported by MODE=dbg - // CheckForMemoryLeaks(); + CheckForMemoryLeaks(); } From a16eb76f5e9e5c08cd2643544a4a3ef8c42acf7a Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sat, 29 Jun 2024 04:34:27 -0700 Subject: [PATCH 005/405] Fix build break --- libc/intrin/BUILD.mk | 2 ++ libc/runtime/BUILD.mk | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libc/intrin/BUILD.mk b/libc/intrin/BUILD.mk index 3cc80c6b6..a8052956e 100644 --- a/libc/intrin/BUILD.mk +++ b/libc/intrin/BUILD.mk @@ -137,6 +137,8 @@ o/$(MODE)/libc/intrin/kweekdaynameshort.o: libc/intrin/kweekdaynameshort.S @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $< o/$(MODE)/libc/intrin/sched_yield.o: libc/intrin/sched_yield.S @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $< +o/$(MODE)/libc/intrin/dsohandle.o: libc/intrin/dsohandle.S + @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $< LIBC_INTRIN_LIBS = $(foreach x,$(LIBC_INTRIN_ARTIFACTS),$($(x))) LIBC_INTRIN_HDRS = $(foreach x,$(LIBC_INTRIN_ARTIFACTS),$($(x)_HDRS)) diff --git a/libc/runtime/BUILD.mk b/libc/runtime/BUILD.mk index 35843d5ff..f2f770cdc 100644 --- a/libc/runtime/BUILD.mk +++ b/libc/runtime/BUILD.mk @@ -107,8 +107,6 @@ o/$(MODE)/libc/runtime/clone-linux.o: libc/runtime/clone-linux.S @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $< o/$(MODE)/libc/runtime/ftrace-hook.o: libc/runtime/ftrace-hook.S @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $< -o/$(MODE)/libc/runtime/dsohandle.o: libc/runtime/dsohandle.S - @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $< o/$(MODE)/libc/runtime/zipos.o: libc/runtime/zipos.S @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $< o/$(MODE)/libc/runtime/switchstacks.o: libc/runtime/switchstacks.S From 6de12c10320b8cfe5de71b8534dc3a568577d9a1 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sat, 29 Jun 2024 05:07:25 -0700 Subject: [PATCH 006/405] Upgrade to superconfigure z0.0.44 --- tool/cosmocc/package.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tool/cosmocc/package.sh b/tool/cosmocc/package.sh index a2bb170a1..5f57c23ca 100755 --- a/tool/cosmocc/package.sh +++ b/tool/cosmocc/package.sh @@ -90,10 +90,10 @@ fetch() { OLD=$PWD cd "$OUTDIR/" if [ ! -x bin/x86_64-linux-cosmo-gcc ]; then - fetch https://github.com/ahgamut/superconfigure/releases/download/z0.0.43/aarch64-gcc.zip + fetch https://github.com/ahgamut/superconfigure/releases/download/z0.0.44/aarch64-gcc.zip unzip aarch64-gcc.zip rm -f aarch64-gcc.zip - fetch https://github.com/ahgamut/superconfigure/releases/download/z0.0.43/x86_64-gcc.zip + fetch https://github.com/ahgamut/superconfigure/releases/download/z0.0.44/x86_64-gcc.zip unzip x86_64-gcc.zip rm -f x86_64-gcc.zip fi From 464858dbb43fa7c1b0bd3fcbc99b05789f329944 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sat, 29 Jun 2024 05:10:15 -0700 Subject: [PATCH 007/405] Fix bugs with new memory manager This fixes a regression in mmap(MAP_FIXED) on Windows caused by a recent revision. This change also fixes ZipOS so it no longer needs a MAP_FIXED mapping to open files from the PKZIP store. The memory mapping mutex was implemented incorrectly earlier which meant that ftrace and strace could cause cause crashes. This lock and other recursive mutexes are rewritten so that it should be provable that recursive mutexes in cosmopolitan are asynchronous signal safe. --- libc/calls/struct/sigset.internal.h | 15 ++- libc/intrin/fds_lock_obj.c | 2 +- libc/intrin/maps.c | 19 ++- libc/intrin/maps.h | 26 +++-- libc/intrin/mmap.c | 58 +++++++--- libc/intrin/mprotect.c | 11 +- libc/intrin/pthread_mutex_init.c | 5 +- libc/intrin/pthread_mutex_lock.c | 69 ++++++----- libc/intrin/pthread_mutex_trylock.c | 74 +++++++----- libc/intrin/pthread_mutex_unlock.c | 57 +++++---- libc/intrin/pthread_mutexattr_getpshared.c | 3 +- libc/intrin/pthread_mutexattr_gettype.c | 3 +- libc/intrin/pthread_mutexattr_setpshared.c | 3 +- libc/intrin/pthread_mutexattr_settype.c | 3 +- libc/intrin/randaddr.c | 25 ++++ libc/proc/fork-nt.c | 18 +-- libc/proc/fork.c | 6 +- libc/runtime/memtrack.internal.h | 20 ++-- libc/runtime/zipos-get.c | 9 +- libc/runtime/zipos-open.c | 128 +++++---------------- libc/runtime/zipos-read.c | 6 +- libc/runtime/zipos.internal.h | 1 - libc/stdio/fflush_unlocked.c | 14 +-- libc/stdio/stderr.c | 2 +- libc/stdio/stdin.c | 2 +- libc/stdio/stdout.c | 2 +- libc/thread/lock.h | 23 ++++ libc/thread/pthread_cond_timedwait.c | 7 +- libc/thread/thread.h | 25 ++-- libc/thread/tls.h | 4 +- test/libc/calls/pledge_test.c | 3 +- test/libc/intrin/mmap_test.c | 9 ++ test/libc/runtime/zipos_test.c | 6 +- tool/cosmocc/package.sh | 8 +- 34 files changed, 353 insertions(+), 313 deletions(-) create mode 100644 libc/intrin/randaddr.c create mode 100644 libc/thread/lock.h diff --git a/libc/calls/struct/sigset.internal.h b/libc/calls/struct/sigset.internal.h index 567ea1728..ad4fe0a78 100644 --- a/libc/calls/struct/sigset.internal.h +++ b/libc/calls/struct/sigset.internal.h @@ -2,17 +2,30 @@ #define COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGSET_INTERNAL_H_ #include "libc/calls/struct/sigset.h" #include "libc/mem/alloca.h" +#include "libc/sysv/consts/sig.h" COSMOPOLITAN_C_START_ +#ifndef MODE_DBG +/* block sigs because theoretical edge cases */ #define BLOCK_SIGNALS \ do { \ sigset_t _SigMask; \ _SigMask = __sig_block() - #define ALLOW_SIGNALS \ __sig_unblock(_SigMask); \ } \ while (0) +#else +/* doesn't block signals so we can get a crash + report, when a core runtime library crashes */ +#define BLOCK_SIGNALS \ + do { \ + sigset_t _SigMask; \ + sigprocmask(SIG_SETMASK, 0, &_SigMask) +#define ALLOW_SIGNALS \ + } \ + while (0) +#endif sigset_t __sig_block(void); void __sig_unblock(sigset_t); diff --git a/libc/intrin/fds_lock_obj.c b/libc/intrin/fds_lock_obj.c index 954531a0f..89733cab9 100644 --- a/libc/intrin/fds_lock_obj.c +++ b/libc/intrin/fds_lock_obj.c @@ -19,4 +19,4 @@ #include "libc/calls/state.internal.h" #include "libc/thread/thread.h" -pthread_mutex_t __fds_lock_obj = {._type = PTHREAD_MUTEX_RECURSIVE}; +pthread_mutex_t __fds_lock_obj = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; diff --git a/libc/intrin/maps.c b/libc/intrin/maps.c index dd55f2526..a6618f19d 100644 --- a/libc/intrin/maps.c +++ b/libc/intrin/maps.c @@ -20,14 +20,10 @@ #include "ape/sections.internal.h" #include "libc/dce.h" #include "libc/intrin/dll.h" -#include "libc/intrin/kprintf.h" -#include "libc/intrin/strace.internal.h" #include "libc/runtime/runtime.h" #include "libc/runtime/stack.h" #include "libc/sysv/consts/auxv.h" #include "libc/sysv/consts/prot.h" -#include "libc/thread/thread.h" -#include "libc/thread/tls.h" #ifdef __x86_64__ __static_yoink("_init_maps"); @@ -73,7 +69,7 @@ privileged void __maps_lock(void) { if (!__tls_enabled) return; tib = __get_tls_privileged(); - if (tib->tib_flags & TIB_FLAG_MAPLOCK) + if (tib->tib_relock_maps++) return; while (atomic_exchange_explicit(&__maps.lock, 1, memory_order_acquire)) { #if defined(__GNUC__) && defined(__aarch64__) @@ -82,14 +78,15 @@ privileged void __maps_lock(void) { __asm__ volatile("pause"); #endif } - tib->tib_flags |= TIB_FLAG_MAPLOCK; } privileged void __maps_unlock(void) { struct CosmoTib *tib; - atomic_store_explicit(&__maps.lock, 0, memory_order_release); - if (__tls_enabled) { - tib = __get_tls_privileged(); - tib->tib_flags &= ~TIB_FLAG_MAPLOCK; - } + if (!__threaded) + return; + if (!__tls_enabled) + return; + tib = __get_tls_privileged(); + if (!--tib->tib_relock_maps) + atomic_store_explicit(&__maps.lock, 0, memory_order_release); } diff --git a/libc/intrin/maps.h b/libc/intrin/maps.h index bd03e2266..ca0d013ff 100644 --- a/libc/intrin/maps.h +++ b/libc/intrin/maps.h @@ -8,21 +8,23 @@ COSMOPOLITAN_C_START_ #define MAP_CONTAINER(e) DLL_CONTAINER(struct Map, elem, e) struct Map { - _Atomic(struct Map *) next; /* for __maps.maps */ - char *addr; /* granule aligned */ - size_t size; /* must be nonzero */ - struct Dll elem; /* for __maps.free */ - int64_t off; /* -1 if anonymous */ - int prot; /* memory protects */ - int flags; /* memory map flag */ - bool iscow; /* windows nt only */ - bool readonlyfile; /* windows nt only */ - intptr_t h; /* windows nt only */ + struct Map *next; /* for __maps.maps */ + char *addr; /* granule aligned */ + size_t size; /* must be nonzero */ + struct Dll elem; /* for __maps.free */ + int64_t off; /* -1 if anonymous */ + int prot; /* memory protects */ + int flags; /* memory map flag */ + bool iscow; /* windows nt only */ + bool readonlyfile; /* windows nt only */ + unsigned visited; /* used for checks */ + intptr_t h; /* windows nt only */ }; struct Maps { + unsigned mono; atomic_int lock; - _Atomic(struct Map *) maps; + struct Map *maps; struct Dll *free; struct Map stack; struct Dll *used; @@ -37,6 +39,7 @@ struct AddrSize { extern struct Maps __maps; +void *randaddr(void); void __maps_init(void); void __maps_lock(void); void __maps_check(void); @@ -44,6 +47,7 @@ void __maps_unlock(void); struct Map *__maps_alloc(void); void __maps_free(struct Map *); void __maps_insert(struct Map *); +int __munmap(char *, size_t, bool); void *__mmap(char *, size_t, int, int, int, int64_t); struct AddrSize __get_main_stack(void); diff --git a/libc/intrin/mmap.c b/libc/intrin/mmap.c index 8011618a0..1f9befd7f 100644 --- a/libc/intrin/mmap.c +++ b/libc/intrin/mmap.c @@ -18,6 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "ape/sections.internal.h" #include "libc/atomic.h" +#include "libc/calls/blockcancel.internal.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" #include "libc/calls/struct/sigset.internal.h" @@ -86,14 +87,23 @@ void __maps_check(void) { size_t maps = 0; size_t pages = 0; int granularity = getauxval(AT_PAGESZ); + unsigned id = __maps.mono++; for (struct Map *map = __maps.maps; map; map = map->next) { ASSERT(map->addr != MAP_FAILED); + ASSERT(map->visited != id); ASSERT(map->size); + map->visited = id; pages += PGUP(map->size) / granularity; maps += 1; } ASSERT(maps = __maps.count); ASSERT(pages == __maps.pages); + for (struct Dll *e = dll_first(__maps.used); e; + e = dll_next(__maps.used, e)) { + ASSERT(MAP_CONTAINER(e)->visited == id); + --maps; + } + ASSERT(maps == 0); for (struct Map *m1 = __maps.maps; m1; m1 = m1->next) for (struct Map *m2 = m1->next; m2; m2 = m2->next) ASSERT(MAX(m1->addr, m2->addr) >= @@ -168,11 +178,7 @@ struct Map *__maps_alloc(void) { return map; } -static int __munmap_chunk(void *addr, size_t size) { - return sys_munmap(addr, size); -} - -static int __munmap(char *addr, size_t size, bool untrack_only) { +int __munmap(char *addr, size_t size, bool untrack_only) { // validate arguments int pagesz = getauxval(AT_PAGESZ); @@ -186,7 +192,7 @@ static int __munmap(char *addr, size_t size, bool untrack_only) { __maps_lock(); StartOver:; struct Map *map = __maps.maps; - _Atomic(struct Map *) *prev = &__maps.maps; + struct Map **prev = &__maps.maps; while (map) { char *map_addr = map->addr; size_t map_size = map->size; @@ -207,7 +213,7 @@ StartOver:; if (!IsWindows()) { ASSERT(addr <= map_addr); ASSERT(map_addr + PGUP(map_size) <= addr + PGUP(size)); - if (__munmap_chunk(map_addr, map_size)) + if (sys_munmap(map_addr, map_size)) rc = -1; } else { if (!UnmapViewOfFile(map_addr)) @@ -236,7 +242,7 @@ StartOver:; ASSERT(left > 0); map->addr += left; map->size = right; - if (map->off != -1) + if (!(map->flags & MAP_ANONYMOUS)) map->off += left; __maps.pages -= (left + pagesz - 1) / pagesz; __maps_check(); @@ -244,7 +250,7 @@ StartOver:; __maps_unlock(); ASSERT(addr <= map_addr); ASSERT(map_addr + PGUP(left) <= addr + PGUP(size)); - if (__munmap_chunk(map_addr, left) == -1) + if (sys_munmap(map_addr, left) == -1) rc = -1; __maps_lock(); goto StartOver; @@ -259,7 +265,7 @@ StartOver:; if (!untrack_only) { __maps_unlock(); ASSERT(PGUP(right) <= PGUP(size)); - if (__munmap_chunk(addr, right) == -1) + if (sys_munmap(addr, right) == -1) rc = -1; __maps_lock(); goto StartOver; @@ -279,7 +285,7 @@ StartOver:; leftmap->flags = map->flags; map->addr += left + middle; map->size = right; - if (map->off != -1) + if (!(map->flags & MAP_ANONYMOUS)) map->off += left + middle; dll_make_first(&__maps.used, &leftmap->elem); *prev = leftmap; @@ -288,7 +294,7 @@ StartOver:; __maps_check(); if (!untrack_only) { __maps_unlock(); - if (__munmap_chunk(addr, size) == -1) + if (sys_munmap(addr, size) == -1) rc = -1; __maps_lock(); goto StartOver; @@ -339,6 +345,11 @@ static void *__mmap_chunk(void *addr, size_t size, int prot, int flags, int fd, if (!map) return MAP_FAILED; + // remove mapping we blew away + if (IsWindows() && should_untrack) + if (__munmap(addr, size, false)) + return MAP_FAILED; + // obtain mapping from operating system int olderr = errno; struct DirectMap res; @@ -349,9 +360,7 @@ TryAgain: if (noreplace) { errno = EEXIST; } else if (should_untrack) { - sys_munmap(res.addr, size); - errno = olderr; - goto TryAgain; + errno = ENOMEM; } else { addr += granularity; errno = olderr; @@ -368,7 +377,12 @@ TryAgain: // we assume non-linux gives us addr if it's free // that's what linux (e.g. rhel7) did before noreplace if (noreplace && res.addr != addr) { - sys_munmap(res.addr, size); + if (!IsWindows()) { + sys_munmap(res.addr, size); + } else { + UnmapViewOfFile(res.addr); + CloseHandle(res.maphandle); + } __maps_lock(); __maps_free(map); __maps_unlock(); @@ -376,7 +390,7 @@ TryAgain: } // untrack mapping we blew away - if (should_untrack) + if (!IsWindows() && should_untrack) __munmap(res.addr, size, true); // track Map object @@ -425,7 +439,7 @@ static void *__mmap_impl(char *addr, size_t size, int prot, int flags, int fd, if (size <= granularity || size > 100 * 1024 * 1024) return __mmap_chunk(addr, size, prot, flags, fd, off, granularity); - // so we create an separate map for each granule in the mapping + // so we create a separate map for each granule in the mapping if (!(flags & MAP_FIXED)) { while (overlaps_existing_map(addr, size)) { if (flags & MAP_FIXED_NOREPLACE) @@ -486,7 +500,11 @@ void *__mmap(char *addr, size_t size, int prot, int flags, int fd, void *mmap(void *addr, size_t size, int prot, int flags, int fd, int64_t off) { void *res; + BLOCK_SIGNALS; + BLOCK_CANCELATION; res = __mmap(addr, size, prot, flags, fd, off); + ALLOW_CANCELATION; + ALLOW_SIGNALS; STRACE("mmap(%p, %'zu, %s, %s, %d, %'ld) β†’ %p% m", addr, size, DescribeProtFlags(prot), DescribeMapFlags(flags), fd, off, res); return res; @@ -494,7 +512,11 @@ void *mmap(void *addr, size_t size, int prot, int flags, int fd, int64_t off) { int munmap(void *addr, size_t size) { int rc; + BLOCK_SIGNALS; + BLOCK_CANCELATION; rc = __munmap(addr, size, false); + ALLOW_CANCELATION; + ALLOW_SIGNALS; STRACE("munmap(%p, %'zu) β†’ %d% m", addr, size, rc); return rc; } diff --git a/libc/intrin/mprotect.c b/libc/intrin/mprotect.c index b1af88552..c02eb0769 100644 --- a/libc/intrin/mprotect.c +++ b/libc/intrin/mprotect.c @@ -30,6 +30,7 @@ #include "libc/runtime/runtime.h" #include "libc/stdio/sysparam.h" #include "libc/sysv/consts/auxv.h" +#include "libc/sysv/consts/map.h" #include "libc/sysv/consts/prot.h" #include "libc/sysv/errfuns.h" @@ -67,7 +68,7 @@ int __mprotect(char *addr, size_t size, int prot) { __maps_lock(); bool found = false; struct Map *map = __maps.maps; - _Atomic(struct Map *) *prev = &__maps.maps; + struct Map **prev = &__maps.maps; while (map) { char *map_addr = map->addr; size_t map_size = map->size; @@ -104,7 +105,7 @@ int __mprotect(char *addr, size_t size, int prot) { leftmap->flags = map->flags; map->addr += left; map->size = right; - if (map->off != -1) + if (!(map->flags & MAP_ANONYMOUS)) map->off += left; dll_make_first(&__maps.used, &leftmap->elem); *prev = leftmap; @@ -133,7 +134,7 @@ int __mprotect(char *addr, size_t size, int prot) { map->addr += left; map->size = right; map->prot = prot; - if (map->off != -1) + if (!(map->flags & MAP_ANONYMOUS)) map->off += left; dll_make_first(&__maps.used, &leftmap->elem); *prev = leftmap; @@ -165,12 +166,12 @@ int __mprotect(char *addr, size_t size, int prot) { midlmap->next = map; midlmap->addr = map_addr + left; midlmap->size = middle; - midlmap->off = map->off == -1 ? -1 : map->off + left; + midlmap->off = (map->flags & MAP_ANONYMOUS) ? 0 : map->off + left; midlmap->prot = prot; midlmap->flags = map->flags; map->addr += left + middle; map->size = right; - if (map->off != -1) + if (!(map->flags & MAP_ANONYMOUS)) map->off += left + middle; dll_make_first(&__maps.used, &leftmap->elem); dll_make_first(&__maps.used, &midlmap->elem); diff --git a/libc/intrin/pthread_mutex_init.c b/libc/intrin/pthread_mutex_init.c index 7aa536aad..8801f2372 100644 --- a/libc/intrin/pthread_mutex_init.c +++ b/libc/intrin/pthread_mutex_init.c @@ -35,9 +35,6 @@ */ int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) { - *mutex = (pthread_mutex_t){ - ._type = attr ? attr->_type : 0, - ._pshared = attr ? attr->_pshared : 0, - }; + *mutex = (pthread_mutex_t){._word = attr ? attr->_word : 0}; return 0; } diff --git a/libc/intrin/pthread_mutex_lock.c b/libc/intrin/pthread_mutex_lock.c index c3cea69bd..0138974e6 100644 --- a/libc/intrin/pthread_mutex_lock.c +++ b/libc/intrin/pthread_mutex_lock.c @@ -23,6 +23,7 @@ #include "libc/intrin/strace.internal.h" #include "libc/intrin/weaken.h" #include "libc/runtime/internal.h" +#include "libc/thread/lock.h" #include "libc/thread/thread.h" #include "libc/thread/tls.h" #include "third_party/nsync/mu.h" @@ -65,49 +66,65 @@ * @vforksafe */ errno_t pthread_mutex_lock(pthread_mutex_t *mutex) { - int t; + int me; + uint64_t word, lock; LOCKTRACE("pthread_mutex_lock(%t)", mutex); - if (__vforked) { + if (__vforked) return 0; - } - if (mutex->_type == PTHREAD_MUTEX_NORMAL && // - mutex->_pshared == PTHREAD_PROCESS_PRIVATE && // + // get current state of lock + word = atomic_load_explicit(&mutex->_word, memory_order_relaxed); + + // use fancy nsync mutex if possible + if (MUTEX_TYPE(word) == PTHREAD_MUTEX_NORMAL && // + MUTEX_PSHARED(word) == PTHREAD_PROCESS_PRIVATE && // _weaken(nsync_mu_lock)) { _weaken(nsync_mu_lock)((nsync_mu *)mutex); return 0; } - if (mutex->_type == PTHREAD_MUTEX_NORMAL) { - while (atomic_exchange_explicit(&mutex->_lock, 1, memory_order_acquire)) { + // implement barebones normal mutexes + if (MUTEX_TYPE(word) == PTHREAD_MUTEX_NORMAL) { + for (;;) { + word = MUTEX_UNLOCK(word); + lock = MUTEX_LOCK(word); + if (atomic_compare_exchange_weak_explicit(&mutex->_word, &word, lock, + memory_order_acquire, + memory_order_relaxed)) + return 0; pthread_pause_np(); } - return 0; } - t = gettid(); - if (mutex->_owner == t) { - if (mutex->_type != PTHREAD_MUTEX_ERRORCHECK) { - if (mutex->_depth < 63) { - ++mutex->_depth; - return 0; + // implement recursive mutexes + me = gettid(); + for (;;) { + if (MUTEX_OWNER(word) == me) { + if (MUTEX_TYPE(word) != PTHREAD_MUTEX_ERRORCHECK) { + if (MUTEX_DEPTH(word) < MUTEX_DEPTH_MAX) { + if (atomic_compare_exchange_weak_explicit( + &mutex->_word, &word, MUTEX_INC_DEPTH(word), + memory_order_relaxed, memory_order_relaxed)) + return 0; + continue; + } else { + return EAGAIN; + } } else { - return EAGAIN; + return EDEADLK; } - } else { - return EDEADLK; } - } - - while (atomic_exchange_explicit(&mutex->_lock, 1, memory_order_acquire)) { + word = MUTEX_UNLOCK(word); + lock = MUTEX_LOCK(word); + lock = MUTEX_SET_OWNER(lock, me); + if (atomic_compare_exchange_weak_explicit(&mutex->_word, &word, lock, + memory_order_acquire, + memory_order_relaxed)) { + mutex->_pid = __pid; + return 0; + } pthread_pause_np(); } - - mutex->_depth = 0; - mutex->_owner = t; - mutex->_pid = __pid; - - return 0; } diff --git a/libc/intrin/pthread_mutex_trylock.c b/libc/intrin/pthread_mutex_trylock.c index ff0734a54..f4e0dde6a 100644 --- a/libc/intrin/pthread_mutex_trylock.c +++ b/libc/intrin/pthread_mutex_trylock.c @@ -21,6 +21,7 @@ #include "libc/intrin/atomic.h" #include "libc/intrin/weaken.h" #include "libc/runtime/internal.h" +#include "libc/thread/lock.h" #include "libc/thread/thread.h" #include "third_party/nsync/mu.h" @@ -38,11 +39,15 @@ * current thread already holds this mutex */ errno_t pthread_mutex_trylock(pthread_mutex_t *mutex) { - int t; + int me; + uint64_t word, lock; + + // get current state of lock + word = atomic_load_explicit(&mutex->_word, memory_order_relaxed); // delegate to *NSYNC if possible - if (mutex->_type == PTHREAD_MUTEX_NORMAL && - mutex->_pshared == PTHREAD_PROCESS_PRIVATE && // + if (MUTEX_TYPE(word) == PTHREAD_MUTEX_NORMAL && + MUTEX_PSHARED(word) == PTHREAD_PROCESS_PRIVATE && // _weaken(nsync_mu_trylock)) { if (_weaken(nsync_mu_trylock)((nsync_mu *)mutex)) { return 0; @@ -52,36 +57,43 @@ errno_t pthread_mutex_trylock(pthread_mutex_t *mutex) { } // handle normal mutexes - if (mutex->_type == PTHREAD_MUTEX_NORMAL) { - if (!atomic_exchange_explicit(&mutex->_lock, 1, memory_order_acquire)) { + if (MUTEX_TYPE(word) == PTHREAD_MUTEX_NORMAL) { + word = MUTEX_UNLOCK(word); + lock = MUTEX_LOCK(word); + if (atomic_compare_exchange_weak_explicit(&mutex->_word, &word, lock, + memory_order_acquire, + memory_order_relaxed)) return 0; - } else { - return EBUSY; - } - } - - // handle recursive and error check mutexes - t = gettid(); - if (mutex->_owner == t) { - if (mutex->_type != PTHREAD_MUTEX_ERRORCHECK) { - if (mutex->_depth < 63) { - ++mutex->_depth; - return 0; - } else { - return EAGAIN; - } - } else { - return EDEADLK; - } - } - - if (atomic_exchange_explicit(&mutex->_lock, 1, memory_order_acquire)) { return EBUSY; } - mutex->_depth = 0; - mutex->_owner = t; - mutex->_pid = __pid; - - return 0; + // handle recursive and error check mutexes + me = gettid(); + for (;;) { + if (MUTEX_OWNER(word) == me) { + if (MUTEX_TYPE(word) != PTHREAD_MUTEX_ERRORCHECK) { + if (MUTEX_DEPTH(word) < MUTEX_DEPTH_MAX) { + if (atomic_compare_exchange_weak_explicit( + &mutex->_word, &word, MUTEX_INC_DEPTH(word), + memory_order_relaxed, memory_order_relaxed)) + return 0; + continue; + } else { + return EAGAIN; + } + } else { + return EDEADLK; + } + } + word = MUTEX_UNLOCK(word); + lock = MUTEX_LOCK(word); + lock = MUTEX_SET_OWNER(lock, me); + if (atomic_compare_exchange_weak_explicit(&mutex->_word, &word, lock, + memory_order_acquire, + memory_order_relaxed)) { + mutex->_pid = __pid; + return 0; + } + return EBUSY; + } } diff --git a/libc/intrin/pthread_mutex_unlock.c b/libc/intrin/pthread_mutex_unlock.c index 9ca401ec4..c6fc274b1 100644 --- a/libc/intrin/pthread_mutex_unlock.c +++ b/libc/intrin/pthread_mutex_unlock.c @@ -22,6 +22,7 @@ #include "libc/intrin/strace.internal.h" #include "libc/intrin/weaken.h" #include "libc/runtime/internal.h" +#include "libc/thread/lock.h" #include "libc/thread/thread.h" #include "third_party/nsync/mu.h" @@ -35,38 +36,52 @@ * @vforksafe */ errno_t pthread_mutex_unlock(pthread_mutex_t *mutex) { - int t; + int me; + uint64_t word, lock; LOCKTRACE("pthread_mutex_unlock(%t)", mutex); - if (mutex->_type == PTHREAD_MUTEX_NORMAL && // - mutex->_pshared == PTHREAD_PROCESS_PRIVATE && // + // get current state of lock + word = atomic_load_explicit(&mutex->_word, memory_order_relaxed); + + // use fancy nsync mutex if possible + if (MUTEX_TYPE(word) == PTHREAD_MUTEX_NORMAL && // + MUTEX_PSHARED(word) == PTHREAD_PROCESS_PRIVATE && // _weaken(nsync_mu_unlock)) { _weaken(nsync_mu_unlock)((nsync_mu *)mutex); return 0; } - if (mutex->_type == PTHREAD_MUTEX_NORMAL) { - atomic_store_explicit(&mutex->_lock, 0, memory_order_release); + // implement barebones normal mutexes + if (MUTEX_TYPE(word) == PTHREAD_MUTEX_NORMAL) { + lock = MUTEX_UNLOCK(word); + atomic_store_explicit(&mutex->_word, lock, memory_order_release); return 0; } - t = gettid(); + // implement recursive mutex unlocking + me = gettid(); + for (;;) { - // we allow unlocking an initialized lock that wasn't locked, but we - // don't allow unlocking a lock held by another thread, or unlocking - // recursive locks from a forked child, since it should be re-init'd - if (mutex->_owner && (mutex->_owner != t || mutex->_pid != __pid)) { - return EPERM; + // we allow unlocking an initialized lock that wasn't locked, but we + // don't allow unlocking a lock held by another thread, or unlocking + // recursive locks from a forked child, since it should be re-init'd + if (MUTEX_OWNER(word) && (MUTEX_OWNER(word) != me || mutex->_pid != __pid)) + return EPERM; + + // check if this is a nested lock with signal safety + if (MUTEX_DEPTH(word)) { + if (atomic_compare_exchange_weak_explicit( + &mutex->_word, &word, MUTEX_DEC_DEPTH(word), memory_order_relaxed, + memory_order_relaxed)) + return 0; + continue; + } + + // actually unlock the mutex + if (atomic_compare_exchange_weak_explicit( + &mutex->_word, &word, MUTEX_UNLOCK(word), memory_order_release, + memory_order_relaxed)) + return 0; } - - if (mutex->_depth) { - --mutex->_depth; - return 0; - } - - mutex->_owner = 0; - atomic_store_explicit(&mutex->_lock, 0, memory_order_release); - - return 0; } diff --git a/libc/intrin/pthread_mutexattr_getpshared.c b/libc/intrin/pthread_mutexattr_getpshared.c index 14897885e..0da7c3bc1 100644 --- a/libc/intrin/pthread_mutexattr_getpshared.c +++ b/libc/intrin/pthread_mutexattr_getpshared.c @@ -16,6 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/thread/lock.h" #include "libc/thread/thread.h" /** @@ -28,6 +29,6 @@ */ errno_t pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr, int *pshared) { - *pshared = attr->_pshared; + *pshared = MUTEX_PSHARED(attr->_word); return 0; } diff --git a/libc/intrin/pthread_mutexattr_gettype.c b/libc/intrin/pthread_mutexattr_gettype.c index 5b40f9df1..9b85dca0d 100644 --- a/libc/intrin/pthread_mutexattr_gettype.c +++ b/libc/intrin/pthread_mutexattr_gettype.c @@ -16,6 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/thread/lock.h" #include "libc/thread/thread.h" /** @@ -28,6 +29,6 @@ * @return 0 on success, or error on failure */ errno_t pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type) { - *type = attr->_type; + *type = MUTEX_TYPE(attr->_word); return 0; } diff --git a/libc/intrin/pthread_mutexattr_setpshared.c b/libc/intrin/pthread_mutexattr_setpshared.c index 5cb009562..088552b6e 100644 --- a/libc/intrin/pthread_mutexattr_setpshared.c +++ b/libc/intrin/pthread_mutexattr_setpshared.c @@ -17,6 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/errno.h" +#include "libc/thread/lock.h" #include "libc/thread/thread.h" /** @@ -32,7 +33,7 @@ errno_t pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared) { switch (pshared) { case PTHREAD_PROCESS_SHARED: case PTHREAD_PROCESS_PRIVATE: - attr->_pshared = pshared; + attr->_word = MUTEX_SET_PSHARED(attr->_word, pshared); return 0; default: return EINVAL; diff --git a/libc/intrin/pthread_mutexattr_settype.c b/libc/intrin/pthread_mutexattr_settype.c index 7a8e78a8f..96dc080de 100644 --- a/libc/intrin/pthread_mutexattr_settype.c +++ b/libc/intrin/pthread_mutexattr_settype.c @@ -17,6 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/errno.h" +#include "libc/thread/lock.h" #include "libc/thread/thread.h" /** @@ -35,7 +36,7 @@ errno_t pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type) { case PTHREAD_MUTEX_NORMAL: case PTHREAD_MUTEX_RECURSIVE: case PTHREAD_MUTEX_ERRORCHECK: - attr->_type = type; + attr->_word = MUTEX_SET_TYPE(attr->_word, type); return 0; default: return EINVAL; diff --git a/libc/intrin/randaddr.c b/libc/intrin/randaddr.c new file mode 100644 index 000000000..5be079696 --- /dev/null +++ b/libc/intrin/randaddr.c @@ -0,0 +1,25 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-β”‚ +β”‚ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi β”‚ +β•žβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•‘ +β”‚ Copyright 2024 Justine Alexandra Roberts Tunney β”‚ +β”‚ β”‚ +β”‚ Permission to use, copy, modify, and/or distribute this software for β”‚ +β”‚ any purpose with or without fee is hereby granted, provided that the β”‚ +β”‚ above copyright notice and this permission notice appear in all copies. β”‚ +β”‚ β”‚ +β”‚ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL β”‚ +β”‚ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED β”‚ +β”‚ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE β”‚ +β”‚ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL β”‚ +β”‚ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR β”‚ +β”‚ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER β”‚ +β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ +β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ +β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ + +void *randaddr(void) { + static unsigned long lcg = 1; + lcg *= 6364136223846793005; + lcg += 1442695040888963407; + return (void *)(lcg >> 48 << 28); +} diff --git a/libc/proc/fork-nt.c b/libc/proc/fork-nt.c index 7e8f89cac..c4b14b60e 100644 --- a/libc/proc/fork-nt.c +++ b/libc/proc/fork-nt.c @@ -95,11 +95,9 @@ static inline textwindows ssize_t ForkIo(int64_t h, char *p, size_t n, struct NtOverlapped *)) { size_t i; uint32_t x; - for (i = 0; i < n; i += x) { - if (!f(h, p + i, n - i, &x, NULL)) { + for (i = 0; i < n; i += x) + if (!f(h, p + i, n - i, &x, NULL)) return __winerr(); - } - } return i; } @@ -153,9 +151,8 @@ static textwindows dontinline void ReadOrDie(int64_t h, void *buf, size_t n) { static textwindows int64_t MapOrDie(uint32_t prot, uint64_t size) { int64_t h; for (;;) { - if ((h = CreateFileMapping(-1, 0, prot, size >> 32, size, 0))) { + if ((h = CreateFileMapping(-1, 0, prot, size >> 32, size, 0))) return h; - } if (GetLastError() == kNtErrorAccessDenied) { switch (prot) { case kNtPageExecuteWritecopy: @@ -273,16 +270,14 @@ textwindows void WinMainForked(void) { __maps.pages += (map->size + 4095) / 4096; dll_make_last(&__maps.used, &map->elem); if (!VirtualProtect(map->addr, map->size, __prot2nt(map->prot, map->iscow), - &oldprot)) { + &oldprot)) AbortFork("VirtualProtect"); - } } __maps_init(); // mitosis complete - if (!CloseHandle(reader)) { + if (!CloseHandle(reader)) AbortFork("CloseHandle"); - } // rewrap the stdin named pipe hack // since the handles closed on fork @@ -428,9 +423,8 @@ textwindows int sys_fork_nt(uint32_t dwCreationFlags) { atomic_store_explicit(&_pthread_static.ptid, GetCurrentThreadId(), memory_order_release); } - if (rc == -1) { + if (rc == -1) dll_make_first(&__proc.free, &proc->elem); - } ftrace_enabled(+1); strace_enabled(+1); return rc; diff --git a/libc/proc/fork.c b/libc/proc/fork.c index d814902c9..8bbdc8963 100644 --- a/libc/proc/fork.c +++ b/libc/proc/fork.c @@ -74,10 +74,10 @@ static void _onfork_child(void) { atomic_store_explicit(&free_waiters_mu, 0, memory_order_relaxed); pthread_mutexattr_destroy(&attr); _pthread_init(); - __maps_unlock(); - if (_weaken(_pthread_onfork_child)) { + atomic_store_explicit(&__maps.lock, 0, memory_order_relaxed); + atomic_store_explicit(&__get_tls()->tib_relock_maps, 0, memory_order_relaxed); + if (_weaken(_pthread_onfork_child)) _weaken(_pthread_onfork_child)(); - } } int _fork(uint32_t dwCreationFlags) { diff --git a/libc/runtime/memtrack.internal.h b/libc/runtime/memtrack.internal.h index 14abf4eed..7841fad40 100644 --- a/libc/runtime/memtrack.internal.h +++ b/libc/runtime/memtrack.internal.h @@ -3,19 +3,15 @@ COSMOPOLITAN_C_START_ #ifndef __SANITIZE_ADDRESS__ -#define kFixedmapStart 0x300000000 -#define kFixedmapSize (0x400000000 - kFixedmapStart) -#define kMemtrackFdsStart 0x6fe000000 -#define kMemtrackFdsSize (0x6ff000000 - kMemtrackFdsStart) -#define kMemtrackZiposStart 0x6fd000000 -#define kMemtrackZiposSize (0xafe000000 - kMemtrackZiposStart) +#define kFixedmapStart 0x300000000 +#define kFixedmapSize (0x400000000 - kFixedmapStart) +#define kMemtrackFdsStart 0x6fe000000 +#define kMemtrackFdsSize (0x6ff000000 - kMemtrackFdsStart) #else -#define kFixedmapStart 0x300000040000 -#define kFixedmapSize (0x400000040000 - kFixedmapStart) -#define kMemtrackFdsStart 0x6fe000040000 -#define kMemtrackFdsSize (0x6feffffc0000 - kMemtrackFdsStart) -#define kMemtrackZiposStart 0x6fd000040000 -#define kMemtrackZiposSize (0x6fdffffc0000 - kMemtrackZiposStart) +#define kFixedmapStart 0x300000040000 +#define kFixedmapSize (0x400000040000 - kFixedmapStart) +#define kMemtrackFdsStart 0x6fe000040000 +#define kMemtrackFdsSize (0x6feffffc0000 - kMemtrackFdsStart) #endif COSMOPOLITAN_C_END_ diff --git a/libc/runtime/zipos-get.c b/libc/runtime/zipos-get.c index a0ae6cc7e..7fea23495 100644 --- a/libc/runtime/zipos-get.c +++ b/libc/runtime/zipos-get.c @@ -69,9 +69,8 @@ static void __zipos_dismiss(uint8_t *map, const uint8_t *cdir, long pg) { // this is supposed to reduce our rss usage but does it really? lo = ROUNDDOWN(lo, pg); hi = MIN(ROUNDUP(hi, pg), ROUNDDOWN(c, pg)); - if (hi > lo) { + if (hi > lo) posix_madvise(map + lo, hi - lo, POSIX_MADV_DONTNEED); - } } static int __zipos_compare_names(const void *a, const void *b, void *c) { @@ -96,9 +95,8 @@ static void __zipos_generate_index(struct Zipos *zipos) { zipos->records = GetZipCdirRecords(zipos->cdir); zipos->index = _mapanon(zipos->records * sizeof(size_t)); for (i = 0, c = GetZipCdirOffset(zipos->cdir); i < zipos->records; - ++i, c += ZIP_CFILE_HDRSIZE(zipos->map + c)) { + ++i, c += ZIP_CFILE_HDRSIZE(zipos->map + c)) zipos->index[i] = c; - } // smoothsort() isn't the fastest algorithm, but it guarantees // o(nlogn) won't smash the stack and doesn't depend on malloc smoothsort_r(zipos->index, zipos->records, sizeof(size_t), @@ -122,9 +120,8 @@ static void __zipos_init(void) { } if (fd != -1 || PLEDGED(RPATH)) { if (fd == -1) { - if (!progpath) { + if (!progpath) progpath = GetProgramExecutableName(); - } fd = open(progpath, O_RDONLY); } if (fd != -1) { diff --git a/libc/runtime/zipos-open.c b/libc/runtime/zipos-open.c index 4a181ed51..37ace7fb3 100644 --- a/libc/runtime/zipos-open.c +++ b/libc/runtime/zipos-open.c @@ -16,112 +16,50 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/assert.h" -#include "libc/calls/calls.h" +#include "libc/calls/blockcancel.internal.h" #include "libc/calls/internal.h" #include "libc/calls/state.internal.h" -#include "libc/calls/struct/sigset.h" +#include "libc/calls/struct/fd.internal.h" #include "libc/calls/struct/sigset.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/calls/syscall_support-sysv.internal.h" -#include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/atomic.h" -#include "libc/intrin/cmpxchg.h" -#include "libc/intrin/directmap.internal.h" -#include "libc/intrin/extend.internal.h" -#include "libc/intrin/likely.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/maps.h" #include "libc/intrin/weaken.h" -#include "libc/limits.h" #include "libc/runtime/internal.h" -#include "libc/runtime/memtrack.internal.h" +#include "libc/runtime/runtime.h" #include "libc/runtime/zipos.internal.h" #include "libc/str/str.h" #include "libc/sysv/consts/f.h" -#include "libc/sysv/consts/fd.h" #include "libc/sysv/consts/map.h" #include "libc/sysv/consts/o.h" #include "libc/sysv/consts/prot.h" #include "libc/sysv/consts/s.h" -#include "libc/sysv/consts/sig.h" #include "libc/sysv/errfuns.h" -#include "libc/thread/thread.h" -#include "libc/thread/tls.h" #include "libc/zip.internal.h" -#define MAX_REFS SSIZE_MAX - -static char *__zipos_mapend; -static size_t __zipos_maptotal; -static pthread_mutex_t __zipos_lock_obj; - -static void __zipos_wipe(void) { - pthread_mutex_init(&__zipos_lock_obj, 0); -} - -static void __zipos_lock(void) { - pthread_mutex_lock(&__zipos_lock_obj); -} - -static void __zipos_unlock(void) { - pthread_mutex_unlock(&__zipos_lock_obj); -} - -static void *__zipos_mmap_space(size_t mapsize) { - char *start; - size_t offset; - unassert(mapsize); - offset = __zipos_maptotal; - __zipos_maptotal += mapsize; - start = (char *)kMemtrackZiposStart; - if (!__zipos_mapend) - __zipos_mapend = start; - __zipos_mapend = _extend(start, __zipos_maptotal, __zipos_mapend, MAP_PRIVATE, - kMemtrackZiposStart + kMemtrackZiposSize); - return start + offset; -} - struct ZiposHandle *__zipos_keep(struct ZiposHandle *h) { - size_t refs = atomic_fetch_add_explicit(&h->refs, 1, memory_order_relaxed); - unassert(!VERY_UNLIKELY(refs > MAX_REFS)); + atomic_fetch_add_explicit(&h->refs, 1, memory_order_relaxed); return h; } void __zipos_drop(struct ZiposHandle *h) { - if (atomic_fetch_sub_explicit(&h->refs, 1, memory_order_release)) { + if (atomic_fetch_sub_explicit(&h->refs, 1, memory_order_release)) return; - } atomic_thread_fence(memory_order_acquire); - __zipos_lock(); - do - h->next = h->zipos->freelist; - while (!_cmpxchg(&h->zipos->freelist, h->next, h)); - __zipos_unlock(); + __munmap((char *)h, h->mapsize, false); } static struct ZiposHandle *__zipos_alloc(struct Zipos *zipos, size_t size) { size_t mapsize; - struct ZiposHandle *h, **ph; - __zipos_lock(); + int granularity; + struct ZiposHandle *h; + granularity = __granularity(); mapsize = sizeof(struct ZiposHandle) + size; - mapsize = ROUNDUP(mapsize, 4096); -StartOver: - ph = &zipos->freelist; - while ((h = *ph)) { - if (h->mapsize >= mapsize) { - if (!_cmpxchg(ph, h, h->next)) - goto StartOver; - break; - } - ph = &h->next; - } - if (!h) { - h = __zipos_mmap_space(mapsize); - } - __zipos_unlock(); - if (h) { - atomic_store_explicit(&h->refs, 0, memory_order_relaxed); + mapsize = (mapsize + granularity - 1) & -granularity; + if ((h = __mmap(randaddr(), mapsize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) != MAP_FAILED) { h->size = size; h->zipos = zipos; h->mapsize = mapsize; @@ -158,6 +96,7 @@ static int __zipos_load(struct Zipos *zipos, size_t cf, int flags, size_t size; int fd, minfd; struct ZiposHandle *h; + if (cf == ZIPOS_SYNTHETIC_DIRECTORY) { size = name->len; if (!(h = __zipos_alloc(zipos, size + 1))) @@ -168,7 +107,6 @@ static int __zipos_load(struct Zipos *zipos, size_t cf, int flags, h->mem = h->data; } else { lf = GetZipCfileOffset(zipos->map + cf); - npassert((ZIP_LFILE_MAGIC(zipos->map + lf) == kZipLfileHdrMagic)); size = GetZipLfileUncompressedSize(zipos->map + lf); switch (ZIP_LFILE_COMPRESSIONMETHOD(zipos->map + lf)) { case kZipCompressionNone: @@ -191,18 +129,17 @@ static int __zipos_load(struct Zipos *zipos, size_t cf, int flags, return eio(); } } + atomic_store_explicit(&h->pos, 0, memory_order_relaxed); h->cfile = cf; - unassert(size < SIZE_MAX); h->size = size; if (h->mem) { minfd = 3; __fds_lock(); TryAgain: if (IsWindows() || IsMetal()) { - if ((fd = __reservefd_unlocked(-1)) != -1) { + if ((fd = __reservefd_unlocked(-1)) != -1) return __zipos_setfd(fd, h, flags); - } } else if ((fd = __zipos_mkfd(minfd)) != -1) { if (__ensurefds_unlocked(fd) != -1) { if (g_fds.p[fd].kind) { @@ -221,16 +158,15 @@ static int __zipos_load(struct Zipos *zipos, size_t cf, int flags, } void __zipos_postdup(int oldfd, int newfd) { - if (oldfd == newfd) { + if (oldfd == newfd) return; - } BLOCK_SIGNALS; + BLOCK_CANCELATION; __fds_lock(); if (__isfdkind(newfd, kFdZip)) { __zipos_drop((struct ZiposHandle *)(intptr_t)g_fds.p[newfd].handle); - if (!__isfdkind(oldfd, kFdZip)) { + if (!__isfdkind(oldfd, kFdZip)) bzero(g_fds.p + newfd, sizeof(*g_fds.p)); - } } if (__isfdkind(oldfd, kFdZip)) { __zipos_keep((struct ZiposHandle *)(intptr_t)g_fds.p[oldfd].handle); @@ -238,6 +174,7 @@ void __zipos_postdup(int oldfd, int newfd) { g_fds.p[newfd] = g_fds.p[oldfd]; } __fds_unlock(); + ALLOW_CANCELATION; ALLOW_SIGNALS; } @@ -260,45 +197,36 @@ int __zipos_open(struct ZiposUri *name, int flags) { // validate api usage if ((flags & O_CREAT) || // (flags & O_TRUNC) || // - (flags & O_ACCMODE) != O_RDONLY) { + (flags & O_ACCMODE) != O_RDONLY) return erofs(); - } // get the zipos global singleton struct Zipos *zipos; - if (!(zipos = __zipos_get())) { + if (!(zipos = __zipos_get())) return enoexec(); - } // most open() calls are due to languages path searching assets. the // majority of these calls will return ENOENT or ENOTDIR. we need to // perform two extremely costly sigprocmask() calls below. thanks to // zipos being a read-only filesystem, we can avoid it in many cases ssize_t cf; - if ((cf = __zipos_find(zipos, name)) == -1) { + if ((cf = __zipos_find(zipos, name)) == -1) return -1; - } - if (flags & O_EXCL) { + if (flags & O_EXCL) return eexist(); - } if (cf != ZIPOS_SYNTHETIC_DIRECTORY) { int mode = GetZipCfileMode(zipos->map + cf); - if ((flags & O_DIRECTORY) && !S_ISDIR(mode)) { + if ((flags & O_DIRECTORY) && !S_ISDIR(mode)) return enotdir(); - } - if (!(mode & 0444)) { + if (!(mode & 0444)) return eacces(); - } } // now do the heavy lifting BLOCK_SIGNALS; + BLOCK_CANCELATION; rc = __zipos_load(zipos, cf, flags, name); + ALLOW_CANCELATION; ALLOW_SIGNALS; return rc; } - -__attribute__((__constructor__(60))) static textstartup void zipos_ctor(void) { - __zipos_wipe(); - pthread_atfork(__zipos_lock, __zipos_unlock, __zipos_wipe); -} diff --git a/libc/runtime/zipos-read.c b/libc/runtime/zipos-read.c index 7bb1ce215..8fae44da4 100644 --- a/libc/runtime/zipos-read.c +++ b/libc/runtime/zipos-read.c @@ -34,16 +34,14 @@ static ssize_t __zipos_read_impl(struct ZiposHandle *h, const struct iovec *iov, int i; int64_t b, x, y, start_pos; if (h->cfile == ZIPOS_SYNTHETIC_DIRECTORY || - S_ISDIR(GetZipCfileMode(h->zipos->map + h->cfile))) { + S_ISDIR(GetZipCfileMode(h->zipos->map + h->cfile))) return eisdir(); - } if (opt_offset == -1) { Restart: start_pos = atomic_load_explicit(&h->pos, memory_order_relaxed); do { - if (UNLIKELY(start_pos == SIZE_MAX)) { + if (UNLIKELY(start_pos == SIZE_MAX)) goto Restart; - } } while (!LIKELY(atomic_compare_exchange_weak_explicit( &h->pos, &start_pos, SIZE_MAX, memory_order_acquire, memory_order_relaxed))); diff --git a/libc/runtime/zipos.internal.h b/libc/runtime/zipos.internal.h index b7549fc9f..0891e16a7 100644 --- a/libc/runtime/zipos.internal.h +++ b/libc/runtime/zipos.internal.h @@ -34,7 +34,6 @@ struct Zipos { uint64_t dev; size_t *index; size_t records; - struct ZiposHandle *freelist; }; int __zipos_close(int); diff --git a/libc/stdio/fflush_unlocked.c b/libc/stdio/fflush_unlocked.c index fd8887d79..dac00a5e4 100644 --- a/libc/stdio/fflush_unlocked.c +++ b/libc/stdio/fflush_unlocked.c @@ -41,20 +41,16 @@ void(__fflush_unlock)(void) { static void __stdio_fork_prepare(void) { FILE *f; __fflush_lock(); - for (int i = 0; i < __fflush.handles.i; ++i) { - if ((f = __fflush.handles.p[i])) { + for (int i = 0; i < __fflush.handles.i; ++i) + if ((f = __fflush.handles.p[i])) pthread_mutex_lock(&f->lock); - } - } } static void __stdio_fork_parent(void) { FILE *f; - for (int i = __fflush.handles.i; i--;) { - if ((f = __fflush.handles.p[i])) { + for (int i = __fflush.handles.i; i--;) + if ((f = __fflush.handles.p[i])) pthread_mutex_unlock(&f->lock); - } - } __fflush_unlock(); } @@ -63,7 +59,7 @@ static void __stdio_fork_child(void) { for (int i = __fflush.handles.i; i--;) { if ((f = __fflush.handles.p[i])) { bzero(&f->lock, sizeof(f->lock)); - f->lock._type = PTHREAD_MUTEX_RECURSIVE; + f->lock._word = PTHREAD_MUTEX_RECURSIVE; } } pthread_mutex_init(&__fflush_lock_obj, 0); diff --git a/libc/stdio/stderr.c b/libc/stdio/stderr.c index 444a3ed0c..4f80d4223 100644 --- a/libc/stdio/stderr.c +++ b/libc/stdio/stderr.c @@ -37,6 +37,6 @@ __attribute__((__constructor__(60))) static textstartup void errinit(void) { stderr->iomode = O_WRONLY; stderr->buf = stderr->mem; stderr->size = sizeof(stderr->mem); - stderr->lock._type = PTHREAD_MUTEX_RECURSIVE; + stderr->lock._word = PTHREAD_MUTEX_RECURSIVE; __fflush_register(stderr); } diff --git a/libc/stdio/stdin.c b/libc/stdio/stdin.c index e90b18012..8f87e47ed 100644 --- a/libc/stdio/stdin.c +++ b/libc/stdio/stdin.c @@ -39,7 +39,7 @@ __attribute__((__constructor__(60))) static textstartup void initin(void) { stdin->iomode = O_RDONLY; stdin->buf = stdin->mem; stdin->size = sizeof(stdin->mem); - stdin->lock._type = PTHREAD_MUTEX_RECURSIVE; + stdin->lock._word = PTHREAD_MUTEX_RECURSIVE; if (fstat(STDIN_FILENO, &st) || !S_ISREG(st.st_mode)) stdin->bufmode = _IONBF; __fflush_register(stdin); diff --git a/libc/stdio/stdout.c b/libc/stdio/stdout.c index 06eee4475..c00e5d3fa 100644 --- a/libc/stdio/stdout.c +++ b/libc/stdio/stdout.c @@ -38,7 +38,7 @@ __attribute__((__constructor__(60))) static textstartup void outinit(void) { stdout->iomode = O_WRONLY; stdout->buf = stdout->mem; stdout->size = sizeof(stdout->mem); - stdout->lock._type = PTHREAD_MUTEX_RECURSIVE; + stdout->lock._word = PTHREAD_MUTEX_RECURSIVE; /* * Unlike other C libraries we don't bother calling fstat() to check diff --git a/libc/thread/lock.h b/libc/thread/lock.h new file mode 100644 index 000000000..5a095679f --- /dev/null +++ b/libc/thread/lock.h @@ -0,0 +1,23 @@ +#ifndef COSMOPOLITAN_LIBC_THREAD_LOCK_H_ +#define COSMOPOLITAN_LIBC_THREAD_LOCK_H_ +COSMOPOLITAN_C_START_ + +#define MUTEX_DEPTH_MIN 0x00000010ull +#define MUTEX_DEPTH_MAX 0x000003f0ull + +#define MUTEX_TYPE(word) ((word) & 3) +#define MUTEX_PSHARED(word) ((word) & 4) +#define MUTEX_LOCKED(word) ((word) & 8) +#define MUTEX_DEPTH(word) ((word) & MUTEX_DEPTH_MAX) +#define MUTEX_OWNER(word) ((word) >> 32) + +#define MUTEX_LOCK(word) (((word) & 7) | 8) +#define MUTEX_UNLOCK(word) ((word) & 7) +#define MUTEX_SET_TYPE(word, type) (((word) & ~3ull) | (type)) +#define MUTEX_SET_PSHARED(word, pshared) (((word) & ~4ull) | (pshared)) +#define MUTEX_INC_DEPTH(word) ((word) + MUTEX_DEPTH_MIN) +#define MUTEX_DEC_DEPTH(word) ((word) - MUTEX_DEPTH_MIN) +#define MUTEX_SET_OWNER(word, tid) ((uint64_t)(tid) << 32 | (uint32_t)(word)) + +COSMOPOLITAN_C_END_ +#endif /* COSMOPOLITAN_LIBC_THREAD_LOCK_H_ */ diff --git a/libc/thread/pthread_cond_timedwait.c b/libc/thread/pthread_cond_timedwait.c index 593bd6bfe..6d964449b 100644 --- a/libc/thread/pthread_cond_timedwait.c +++ b/libc/thread/pthread_cond_timedwait.c @@ -17,6 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/errno.h" +#include "libc/thread/lock.h" #include "libc/thread/thread.h" #include "libc/thread/thread2.h" #include "third_party/nsync/common.internal.h" @@ -48,12 +49,10 @@ */ errno_t pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime) { - if (abstime && !(0 <= abstime->tv_nsec && abstime->tv_nsec < 1000000000)) { + if (abstime && !(0 <= abstime->tv_nsec && abstime->tv_nsec < 1000000000)) return EINVAL; - } - if (mutex->_type != PTHREAD_MUTEX_NORMAL) { + if (MUTEX_TYPE(mutex->_word) != PTHREAD_MUTEX_NORMAL) nsync_panic_("pthread cond needs normal mutex\n"); - } return nsync_cv_wait_with_deadline( (nsync_cv *)cond, (nsync_mu *)mutex, abstime ? *abstime : nsync_time_no_deadline, 0); diff --git a/libc/thread/thread.h b/libc/thread/thread.h index 374cafce5..76f372b49 100644 --- a/libc/thread/thread.h +++ b/libc/thread/thread.h @@ -15,7 +15,7 @@ #define PTHREAD_MUTEX_ROBUST 1 #define PTHREAD_PROCESS_PRIVATE 0 -#define PTHREAD_PROCESS_SHARED 1 +#define PTHREAD_PROCESS_SHARED 4 #define PTHREAD_CREATE_JOINABLE 0 #define PTHREAD_CREATE_DETACHED 1 @@ -40,13 +40,12 @@ #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -#define PTHREAD_ONCE_INIT _PTHREAD_INIT -#define PTHREAD_COND_INITIALIZER _PTHREAD_INIT -#define PTHREAD_RWLOCK_INITIALIZER _PTHREAD_INIT -#define PTHREAD_MUTEX_INITIALIZER _PTHREAD_INIT +#define PTHREAD_ONCE_INIT {0} +#define PTHREAD_COND_INITIALIZER {0} +#define PTHREAD_RWLOCK_INITIALIZER {0} +#define PTHREAD_MUTEX_INITIALIZER {0} -#define _PTHREAD_INIT \ - { 0 } +#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP {0, 0, PTHREAD_MUTEX_RECURSIVE} typedef uintptr_t pthread_t; typedef int pthread_id_np_t; @@ -65,17 +64,13 @@ typedef struct pthread_spinlock_s { } pthread_spinlock_t; typedef struct pthread_mutex_s { - _Atomic(int32_t) _lock; - unsigned _type : 2; - unsigned _pshared : 1; - unsigned _depth : 6; - unsigned _owner : 23; - long _pid; + uint32_t _nsync; + int32_t _pid; + _Atomic(uint64_t) _word; } pthread_mutex_t; typedef struct pthread_mutexattr_s { - char _type; - char _pshared; + unsigned _word; } pthread_mutexattr_t; typedef struct pthread_cond_s { diff --git a/libc/thread/tls.h b/libc/thread/tls.h index 61952f8d1..788013afb 100644 --- a/libc/thread/tls.h +++ b/libc/thread/tls.h @@ -4,7 +4,6 @@ #define TLS_ALIGNMENT 64 #define TIB_FLAG_VFORKED 1 -#define TIB_FLAG_MAPLOCK 2 #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ @@ -38,8 +37,9 @@ struct CosmoTib { char *tib_sigstack_addr; uint32_t tib_sigstack_size; uint32_t tib_sigstack_flags; + _Atomic(int) tib_relock_maps; void *tib_nsync; - void *tib_keys[48]; + void *tib_keys[47]; } __attribute__((__aligned__(64))); extern int __threaded; diff --git a/test/libc/calls/pledge_test.c b/test/libc/calls/pledge_test.c index b0cf090aa..53c5c8a19 100644 --- a/test/libc/calls/pledge_test.c +++ b/test/libc/calls/pledge_test.c @@ -56,6 +56,7 @@ #include "libc/testlib/ezbench.h" #include "libc/testlib/subprocess.h" #include "libc/testlib/testlib.h" +#include "libc/thread/lock.h" #include "libc/thread/posixthread.internal.h" #include "libc/thread/thread.h" #include "libc/time.h" @@ -652,7 +653,7 @@ TEST(pledge_openbsd, bigSyscalls) { void *LockWorker(void *arg) { flockfile(stdout); - ASSERT_EQ(gettid(), stdout->lock._owner); + ASSERT_EQ(gettid(), MUTEX_OWNER(stdout->lock._word)); funlockfile(stdout); return 0; } diff --git a/test/libc/intrin/mmap_test.c b/test/libc/intrin/mmap_test.c index d28f5c80b..9868819ab 100644 --- a/test/libc/intrin/mmap_test.c +++ b/test/libc/intrin/mmap_test.c @@ -98,6 +98,15 @@ TEST(mmap, noreplaceExistingMap) { EXPECT_SYS(0, 0, munmap(p, granularity)); } +TEST(mmap, fixedTaken) { + char *p; + ASSERT_NE(MAP_FAILED, (p = mmap(0, granularity, PROT_READ, + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0))); + ASSERT_NE(MAP_FAILED, mmap(p, granularity, PROT_READ, + MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)); + EXPECT_SYS(0, 0, munmap(p, granularity)); +} + TEST(mmap, hint) { char *p, *q; diff --git a/test/libc/runtime/zipos_test.c b/test/libc/runtime/zipos_test.c index 147920b45..a5fd58742 100644 --- a/test/libc/runtime/zipos_test.c +++ b/test/libc/runtime/zipos_test.c @@ -54,12 +54,10 @@ void *Worker(void *arg) { TEST(zipos, test) { int i, n = 16; pthread_t *t = gc(malloc(sizeof(pthread_t) * n)); - for (i = 0; i < n; ++i) { + for (i = 0; i < n; ++i) ASSERT_SYS(0, 0, pthread_create(t + i, 0, Worker, 0)); - } - for (i = 0; i < n; ++i) { + for (i = 0; i < n; ++i) EXPECT_SYS(0, 0, pthread_join(t[i], 0)); - } } TEST(zipos, erofs) { diff --git a/tool/cosmocc/package.sh b/tool/cosmocc/package.sh index 5f57c23ca..8abb3132e 100755 --- a/tool/cosmocc/package.sh +++ b/tool/cosmocc/package.sh @@ -114,10 +114,10 @@ for arch in aarch64 x86_64; do ln -sf $arch-linux-cosmo-objdump bin/$arch-unknown-cosmo-objdump ln -sf $arch-linux-cosmo-readelf bin/$arch-unknown-cosmo-readelf ln -sf $arch-linux-cosmo-strip bin/$arch-unknown-cosmo-strip - cmp -s libexec/gcc/$arch-linux-cosmo/$GCCVER/ld.bfd libexec/gcc/$arch-linux-cosmo/$GCCVER/ld - ln -sf ld.bfd libexec/gcc/$arch-linux-cosmo/$GCCVER/ld - cmp -s libexec/gcc/$arch-linux-cosmo/$GCCVER/ld.bfd bin/$arch-linux-cosmo-ld - ln -sf ../libexec/gcc/$arch-linux-cosmo/$GCCVER/ld.bfd bin/$arch-linux-cosmo-ld + # cmp -s libexec/gcc/$arch-linux-cosmo/$GCCVER/ld.bfd libexec/gcc/$arch-linux-cosmo/$GCCVER/ld + # ln -sf ld.bfd libexec/gcc/$arch-linux-cosmo/$GCCVER/ld + # cmp -s libexec/gcc/$arch-linux-cosmo/$GCCVER/ld.bfd bin/$arch-linux-cosmo-ld + # ln -sf ../libexec/gcc/$arch-linux-cosmo/$GCCVER/ld.bfd bin/$arch-linux-cosmo-ld cmp -s libexec/gcc/$arch-linux-cosmo/$GCCVER/as bin/$arch-linux-cosmo-as ln -sf ../libexec/gcc/$arch-linux-cosmo/$GCCVER/as bin/$arch-linux-cosmo-as cmp -s libexec/gcc/$arch-linux-cosmo/$GCCVER/ld.bfd bin/$arch-linux-cosmo-ld.bfd From 617ddfee93c212e9506b24acbc36327b96e80834 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sat, 29 Jun 2024 10:58:47 -0700 Subject: [PATCH 008/405] Release Cosmopolitan v3.5.2 --- libc/integral/normalize.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libc/integral/normalize.inc b/libc/integral/normalize.inc index 04aecb03a..9fcbc05fc 100644 --- a/libc/integral/normalize.inc +++ b/libc/integral/normalize.inc @@ -4,7 +4,7 @@ #define __COSMOPOLITAN_MAJOR__ 3 #define __COSMOPOLITAN_MINOR__ 5 -#define __COSMOPOLITAN_PATCH__ 1 +#define __COSMOPOLITAN_PATCH__ 2 #define __COSMOPOLITAN__ \ (100000000 * __COSMOPOLITAN_MAJOR__ + 1000000 * __COSMOPOLITAN_MINOR__ + \ __COSMOPOLITAN_PATCH__) From 98e684622b2536b4e1eee21a5769cc45e71cfb3d Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sat, 29 Jun 2024 15:45:09 -0700 Subject: [PATCH 009/405] Add iostream to CTL --- Makefile | 2 +- ctl/BUILD.mk | 4 + ctl/ios.cc | 39 ++++++ ctl/ios.h | 27 ++++ ctl/ios_base.cc | 118 ++++++++++++++++ ctl/ios_base.h | 86 ++++++++++++ ctl/is_convertible.h | 1 - ctl/istream.cc | 237 +++++++++++++++++++++++++++++++++ ctl/istream.h | 53 ++++++++ ctl/istringstream.cc | 221 ++++++++++++++++++++++++++++++ ctl/istringstream.h | 41 ++++++ ctl/ostream.cc | 166 +++++++++++++++++++++++ ctl/ostream.h | 53 ++++++++ ctl/ostringstream.cc | 140 +++++++++++++++++++ ctl/ostringstream.h | 36 +++++ ctl/utility.h | 6 +- libc/intrin/strace.internal.h | 2 +- test/ctl/BUILD.mk | 3 +- test/ctl/istringstream_test.cc | 163 +++++++++++++++++++++++ test/ctl/ostringstream_test.cc | 140 +++++++++++++++++++ 20 files changed, 1531 insertions(+), 7 deletions(-) create mode 100644 ctl/ios.cc create mode 100644 ctl/ios.h create mode 100644 ctl/ios_base.cc create mode 100644 ctl/ios_base.h create mode 100644 ctl/istream.cc create mode 100644 ctl/istream.h create mode 100644 ctl/istringstream.cc create mode 100644 ctl/istringstream.h create mode 100644 ctl/ostream.cc create mode 100644 ctl/ostream.h create mode 100644 ctl/ostringstream.cc create mode 100644 ctl/ostringstream.h create mode 100644 test/ctl/istringstream_test.cc create mode 100644 test/ctl/ostringstream_test.cc diff --git a/Makefile b/Makefile index 692df3a00..73e49877c 100644 --- a/Makefile +++ b/Makefile @@ -256,7 +256,6 @@ include third_party/nsync/mem/BUILD.mk # β”‚ You can now use stdio include libc/proc/BUILD.mk # β”‚ You can now use threads include libc/dlopen/BUILD.mk # β”‚ You can now use processes include libc/thread/BUILD.mk # β”‚ You can finally call malloc() -include ctl/BUILD.mk # β”‚ include third_party/zlib/BUILD.mk # β”‚ include libc/stdio/BUILD.mk # β”‚ include tool/hello/BUILD.mk # β”‚ @@ -285,6 +284,7 @@ include third_party/ncurses/BUILD.mk # β”‚ include third_party/readline/BUILD.mk # β”‚ include third_party/libunwind/BUILD.mk # | include third_party/libcxxabi/BUILD.mk # | +include ctl/BUILD.mk # β”‚ include third_party/libcxx/BUILD.mk # β”‚ include third_party/openmp/BUILD.mk # β”‚ include third_party/double-conversion/BUILD.mk # β”‚ diff --git a/ctl/BUILD.mk b/ctl/BUILD.mk index 66527b46b..f30a3c8bc 100644 --- a/ctl/BUILD.mk +++ b/ctl/BUILD.mk @@ -18,7 +18,11 @@ CTL_A_CHECKS = \ CTL_A_DIRECTDEPS = \ LIBC_INTRIN \ LIBC_MEM \ + LIBC_STDIO \ LIBC_STR \ + THIRD_PARTY_GDTOA \ + THIRD_PARTY_LIBCXXABI \ + THIRD_PARTY_LIBUNWIND \ CTL_A_DEPS := $(call uniq,$(foreach x,$(CTL_A_DIRECTDEPS),$($(x)))) diff --git a/ctl/ios.cc b/ctl/ios.cc new file mode 100644 index 000000000..37547aecb --- /dev/null +++ b/ctl/ios.cc @@ -0,0 +1,39 @@ +// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +// +// Copyright 2024 Justine Alexandra Roberts Tunney +// +// Permission to use, copy, modify, and/or distribute this software for +// any purpose with or without fee is hereby granted, provided that the +// above copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include "ios.h" + +namespace ctl { + +ios::ios(FILE* file) : file_(file) +{ +} + +ios::~ios() = default; + +ios& +ios::operator=(ios&& other) noexcept +{ + if (this != &other) { + file_ = other.file_; + other.file_ = nullptr; + } + return *this; +} + +} // namespace ctl diff --git a/ctl/ios.h b/ctl/ios.h new file mode 100644 index 000000000..31e82e258 --- /dev/null +++ b/ctl/ios.h @@ -0,0 +1,27 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_IOS_H_ +#define CTL_IOS_H_ +#include "ios_base.h" + +struct FILE; + +namespace ctl { + +class ios : public ios_base +{ + public: + explicit ios(FILE*); + virtual ~ios(); + + protected: + ios& operator=(ios&&) noexcept; + FILE* file_; + + private: + ios(const ios&) = delete; +}; + +} // namespace ctl + +#endif // CTL_IOS_H_ diff --git a/ctl/ios_base.cc b/ctl/ios_base.cc new file mode 100644 index 000000000..8ff97b669 --- /dev/null +++ b/ctl/ios_base.cc @@ -0,0 +1,118 @@ +// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +// +// Copyright 2024 Justine Alexandra Roberts Tunney +// +// Permission to use, copy, modify, and/or distribute this software for +// any purpose with or without fee is hereby granted, provided that the +// above copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include "ios_base.h" + +namespace ctl { + +ios_base::ios_base() : state_(goodbit), flags_(skipws | dec) +{ +} + +ios_base::~ios_base() = default; + +ios_base::fmtflags +ios_base::flags() const +{ + return static_cast(flags_); +} + +ios_base::fmtflags +ios_base::flags(fmtflags fmtfl) +{ + int old = flags_; + flags_ = fmtfl; + return static_cast(old); +} + +ios_base::fmtflags +ios_base::setf(fmtflags fmtfl) +{ + int old = flags_; + flags_ |= fmtfl; + return static_cast(old); +} + +ios_base::fmtflags +ios_base::setf(fmtflags fmtfl, fmtflags mask) +{ + int old = flags_; + flags_ = (flags_ & ~mask) | (fmtfl & mask); + return static_cast(old); +} + +void +ios_base::unsetf(fmtflags mask) +{ + flags_ &= ~mask; +} + +ios_base::iostate +ios_base::rdstate() const +{ + return static_cast(state_); +} + +void +ios_base::clear(int state) +{ + state_ = state; +} + +void +ios_base::setstate(int state) +{ + state_ |= state; +} + +bool +ios_base::good() const +{ + return state_ == goodbit; +} + +bool +ios_base::eof() const +{ + return (state_ & eofbit) != 0; +} + +bool +ios_base::fail() const +{ + return (state_ & (failbit | badbit)) != 0; +} + +bool +ios_base::bad() const +{ + return (state_ & badbit) != 0; +} + +bool +ios_base::operator!() const +{ + return fail(); +} + +ios_base::operator bool() const +{ + return !fail(); +} + +} // namespace ctl diff --git a/ctl/ios_base.h b/ctl/ios_base.h new file mode 100644 index 000000000..e52114959 --- /dev/null +++ b/ctl/ios_base.h @@ -0,0 +1,86 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_IOS_BASE_H_ +#define CTL_IOS_BASE_H_ + +namespace ctl { + +class ios_base +{ + public: + typedef size_t streamsize; + + enum iostate + { + goodbit = 0, + badbit = 1, + failbit = 2, + eofbit = 4 + }; + + enum fmtflags + { + boolalpha = 1 << 0, + dec = 1 << 1, + fixed = 1 << 2, + hex = 1 << 3, + internal = 1 << 4, + left = 1 << 5, + oct = 1 << 6, + right = 1 << 7, + scientific = 1 << 8, + showbase = 1 << 9, + showpoint = 1 << 10, + showpos = 1 << 11, + skipws = 1 << 12, + unitbuf = 1 << 13, + uppercase = 1 << 14, + adjustfield = left | right | internal, + basefield = dec | oct | hex, + floatfield = scientific | fixed + }; + + enum openmode + { + app = 1 << 0, + binary = 1 << 1, + in = 1 << 2, + out = 1 << 3, + trunc = 1 << 4, + ate = 1 << 5 + }; + + protected: + ios_base(); + virtual ~ios_base(); + + int state_; + int flags_; + + public: + fmtflags flags() const; + fmtflags flags(fmtflags); + fmtflags setf(fmtflags); + fmtflags setf(fmtflags, fmtflags); + void unsetf(fmtflags); + + iostate rdstate() const; + void clear(int = goodbit); + void setstate(int); + + bool good() const; + bool eof() const; + bool fail() const; + bool bad() const; + + bool operator!() const; + explicit operator bool() const; + + private: + ios_base(const ios_base&) = delete; + ios_base& operator=(const ios_base&) = delete; +}; + +} // namespace ctl + +#endif // CTL_IOS_BASE_H_ diff --git a/ctl/is_convertible.h b/ctl/is_convertible.h index 9b81747e8..69a105ad3 100644 --- a/ctl/is_convertible.h +++ b/ctl/is_convertible.h @@ -2,7 +2,6 @@ // vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi #ifndef CTL_IS_CONVERTIBLE_H_ #define CTL_IS_CONVERTIBLE_H_ - #include "ctl/integral_constant.h" #include "ctl/void_t.h" diff --git a/ctl/istream.cc b/ctl/istream.cc new file mode 100644 index 000000000..bb2837a0b --- /dev/null +++ b/ctl/istream.cc @@ -0,0 +1,237 @@ +// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +// +// Copyright 2024 Justine Alexandra Roberts Tunney +// +// Permission to use, copy, modify, and/or distribute this software for +// any purpose with or without fee is hereby granted, provided that the +// above copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include "istream.h" +#include "libc/fmt/conv.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "numeric_limits.h" +#include "string.h" +#include "utility.h" + +namespace ctl { + +istream cin(stdin); + +istream::~istream() = default; + +istream::istream(FILE* file) : ios(file), gcount_(0) +{ +} + +istream::istream(istream&& other) noexcept + : ios(other.file_), gcount_(other.gcount_) +{ + other.file_ = nullptr; + other.gcount_ = 0; +} + +istream& +istream::operator=(istream&& other) noexcept +{ + if (this != &other) { + ios::operator=(ctl::move(other)); + gcount_ = other.gcount_; + other.gcount_ = 0; + } + return *this; +} + +istream& +istream::operator>>(char& c) +{ + gcount_ = 0; + int ch = fgetc(file_); + if (ch == EOF) { + setstate(eofbit | failbit); + } else { + c = static_cast(ch); + gcount_ = 1; + } + return *this; +} + +istream& +istream::operator>>(int& n) +{ + if (fscanf(file_, "%d", &n) != 1) + setstate(failbit); + return *this; +} + +istream& +istream::operator>>(long& n) +{ + if (fscanf(file_, "%ld", &n) != 1) + setstate(failbit); + return *this; +} + +istream& +istream::operator>>(double& d) +{ + if (fscanf(file_, "%f", &d) != 1) + setstate(failbit); + return *this; +} + +istream& +istream::operator>>(ctl::string& s) +{ + char buffer[1024]; + if (fscanf(file_, "%1023s", buffer) == 1) { + s = buffer; + } else { + setstate(failbit); + } + return *this; +} + +istream& +istream::operator>>(bool& b) +{ + char buffer[6]; + if (fscanf(file_, "%5s", buffer) == 1) { + if (strcmp(buffer, "true") == 0 || strcmp(buffer, "1") == 0) { + b = true; + } else if (strcmp(buffer, "false") == 0 || strcmp(buffer, "0") == 0) { + b = false; + } else { + setstate(failbit); + } + } else { + setstate(failbit); + } + return *this; +} + +istream& +istream::operator>>(istream& (*manip)(istream&)) +{ + return manip(*this); +} + +int +istream::get() +{ + gcount_ = 0; + int ch = fgetc(file_); + if (ch == EOF) { + setstate(eofbit); + } else { + gcount_ = 1; + } + return ch; +} + +istream& +istream::get(char& c) +{ + int ch = get(); + if (ch != EOF) + c = static_cast(ch); + return *this; +} + +istream& +istream::getline(char* s, streamsize n) +{ + return getline(s, n, '\n'); +} + +istream& +istream::getline(char* s, streamsize n, char delim) +{ + gcount_ = 0; + if (n <= 0) { + setstate(failbit); + return *this; + } + while (gcount_ < n - 1) { + int ch = fgetc(file_); + if (ch == EOF) { + setstate(eofbit); + break; + } + if (ch == delim) + break; + s[gcount_++] = static_cast(ch); + } + s[gcount_] = '\0'; + if (gcount_ == 0) + setstate(failbit); + return *this; +} + +istream& +istream::read(char* s, streamsize n) +{ + gcount_ = fread(s, 1, n, file_); + if (gcount_ < n) { + setstate(eofbit); + if (gcount_ == 0) + setstate(failbit); + } + return *this; +} + +istream::streamsize +istream::gcount() const +{ + return gcount_; +} + +int +istream::peek() +{ + int ch = fgetc(file_); + if (ch != EOF) { + ungetc(ch, file_); + } else { + setstate(eofbit); + } + return ch; +} + +istream& +istream::ignore(streamsize n, int delim) +{ + gcount_ = 0; + while (gcount_ < n) { + int ch = fgetc(file_); + if (ch == EOF) { + setstate(eofbit); + break; + } + ++gcount_; + if (ch == delim) + break; + } + return *this; +} + +istream& +ws(istream& is) +{ + int ch; + while ((ch = is.peek()) != EOF && isspace(ch)) + is.get(); + return is; +} + +} // namespace ctl diff --git a/ctl/istream.h b/ctl/istream.h new file mode 100644 index 000000000..2ec23284d --- /dev/null +++ b/ctl/istream.h @@ -0,0 +1,53 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_ISTREAM_H_ +#define CTL_ISTREAM_H_ +#include "ios.h" + +namespace ctl { + +struct string; + +class istream : public ios +{ + public: + istream() = delete; + explicit istream(FILE*); + virtual ~istream(); + + istream& operator>>(char&); + istream& operator>>(int&); + istream& operator>>(long&); + istream& operator>>(double&); + istream& operator>>(bool&); + istream& operator>>(string&); + istream& operator>>(istream& (*)(istream&)); + + int get(); + istream& get(char&); + istream& getline(char*, streamsize); + istream& getline(char*, streamsize, char); + istream& read(char*, streamsize); + streamsize gcount() const; + + int peek(); + istream& ignore(streamsize = 1, int = -1); + + istream(istream&&) noexcept; + istream& operator=(istream&&) noexcept; + + private: + streamsize gcount_; + + istream(const istream&) = delete; + istream& operator=(const istream&) = delete; +}; + +extern istream cin; + +istream& +ws(istream& is); + +} // namespace ctl + +#endif // CTL_ISTREAM_H_ diff --git a/ctl/istringstream.cc b/ctl/istringstream.cc new file mode 100644 index 000000000..5674c620a --- /dev/null +++ b/ctl/istringstream.cc @@ -0,0 +1,221 @@ +// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +// +// Copyright 2024 Justine Alexandra Roberts Tunney +// +// Permission to use, copy, modify, and/or distribute this software for +// any purpose with or without fee is hereby granted, provided that the +// above copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include "istringstream.h" +#include "libc/fmt/conv.h" +#include "libc/str/str.h" + +namespace ctl { + +istringstream::istringstream() : buffer_(), read_pos_(0) +{ +} + +istringstream::istringstream(const string_view& str) + : buffer_(str), read_pos_(0) +{ +} + +string +istringstream::str() const +{ + return buffer_; +} + +void +istringstream::str(const string& s) +{ + buffer_ = s; + read_pos_ = 0; + clear(); +} + +istringstream& +istringstream::operator>>(char& c) +{ + if (good() && read_pos_ < buffer_.size()) { + c = buffer_[read_pos_++]; + } else { + setstate(ios_base::failbit); + } + return *this; +} + +istringstream& +istringstream::operator>>(char* s) +{ + if (!good()) + return *this; + + while (read_pos_ < buffer_.size() && isspace(buffer_[read_pos_])) + ++read_pos_; + + size_t start = read_pos_; + while (read_pos_ < buffer_.size() && !isspace(buffer_[read_pos_])) { + s[read_pos_ - start] = buffer_[read_pos_]; + ++read_pos_; + } + s[read_pos_ - start] = '\0'; + + if (start == read_pos_) { + setstate(ios_base::failbit); + } else if (read_pos_ == buffer_.size()) { + setstate(ios_base::eofbit); + } + + return *this; +} + +istringstream& +istringstream::operator>>(string& s) +{ + if (!good()) + return *this; + + s.clear(); + while (read_pos_ < buffer_.size() && isspace(buffer_[read_pos_])) + ++read_pos_; + + while (read_pos_ < buffer_.size() && !isspace(buffer_[read_pos_])) { + s.push_back(buffer_[read_pos_]); + ++read_pos_; + } + + if (s.empty()) { + setstate(ios_base::failbit); + } else if (read_pos_ == buffer_.size()) { + setstate(ios_base::eofbit); + } + + return *this; +} + +template +istringstream& +istringstream::read_numeric(T& value) +{ + if (!good()) + return *this; + + while (read_pos_ < buffer_.size() && isspace(buffer_[read_pos_])) + ++read_pos_; + + // size_t start = read_pos_; + bool is_negative = false; + if (read_pos_ < buffer_.size() && + (buffer_[read_pos_] == '-' || buffer_[read_pos_] == '+')) { + is_negative = (buffer_[read_pos_] == '-'); + ++read_pos_; + } + + T result = 0; + bool valid = false; + while (read_pos_ < buffer_.size() && isdigit(buffer_[read_pos_])) { + result = result * 10 + (buffer_[read_pos_] - '0'); + ++read_pos_; + valid = true; + } + + if (valid) { + value = is_negative ? -result : result; + if (read_pos_ == buffer_.size()) + setstate(ios_base::eofbit); + } else { + setstate(ios_base::failbit); + } + + return *this; +} + +istringstream& +istringstream::operator>>(short& n) +{ + return read_numeric(n); +} + +istringstream& +istringstream::operator>>(unsigned short& n) +{ + return read_numeric(n); +} + +istringstream& +istringstream::operator>>(int& n) +{ + return read_numeric(n); +} + +istringstream& +istringstream::operator>>(unsigned int& n) +{ + return read_numeric(n); +} + +istringstream& +istringstream::operator>>(long& n) +{ + return read_numeric(n); +} + +istringstream& +istringstream::operator>>(unsigned long& n) +{ + return read_numeric(n); +} + +istringstream& +istringstream::operator>>(float& f) +{ + if (!good()) + return *this; + + char* end; + f = strtof(buffer_.c_str() + read_pos_, &end); + + if (end == buffer_.c_str() + read_pos_) { + setstate(ios_base::failbit); + } else { + read_pos_ = end - buffer_.c_str(); + if (read_pos_ == buffer_.size()) + setstate(ios_base::eofbit); + } + + return *this; +} + +istringstream& +istringstream::operator>>(double& d) +{ + if (!good()) + return *this; + + char* end; + d = strtod(buffer_.c_str() + read_pos_, &end); + + if (end == buffer_.c_str() + read_pos_) { + setstate(ios_base::failbit); + } else { + read_pos_ = end - buffer_.c_str(); + if (read_pos_ == buffer_.size()) + setstate(ios_base::eofbit); + } + + return *this; +} + +} // namespace ctl diff --git a/ctl/istringstream.h b/ctl/istringstream.h new file mode 100644 index 000000000..b3c95e3d7 --- /dev/null +++ b/ctl/istringstream.h @@ -0,0 +1,41 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_ISTRINGSTREAM_H_ +#define CTL_ISTRINGSTREAM_H_ +#include "ios_base.h" +#include "string.h" + +namespace ctl { + +class istringstream : public ios_base +{ + public: + istringstream(); + explicit istringstream(const string_view&); + + string str() const; + void str(const string&); + + istringstream& operator>>(char&); + istringstream& operator>>(char*); + istringstream& operator>>(string&); + istringstream& operator>>(short&); + istringstream& operator>>(unsigned short&); + istringstream& operator>>(int&); + istringstream& operator>>(unsigned int&); + istringstream& operator>>(long&); + istringstream& operator>>(unsigned long&); + istringstream& operator>>(float&); + istringstream& operator>>(double&); + + private: + string buffer_; + size_t read_pos_; + + template + istringstream& read_numeric(T&); +}; + +} // namespace ctl + +#endif // CTL_ISTRINGSTREAM_H_ diff --git a/ctl/ostream.cc b/ctl/ostream.cc new file mode 100644 index 000000000..d57e11906 --- /dev/null +++ b/ctl/ostream.cc @@ -0,0 +1,166 @@ +// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +// +// Copyright 2024 Justine Alexandra Roberts Tunney +// +// Permission to use, copy, modify, and/or distribute this software for +// any purpose with or without fee is hereby granted, provided that the +// above copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include "ostream.h" +#include "libc/stdio/stdio.h" +#include "string_view.h" + +namespace ctl { + +ostream cout(stdout); +ostream cerr(stderr); + +ostream::~ostream() = default; + +ostream::ostream(FILE* file) : ios(file) +{ +} + +ostream::ostream(ostream&& other) noexcept : ios(other.file_) +{ + other.file_ = nullptr; +} + +ostream& +ostream::operator=(ostream&& other) noexcept +{ + if (this != &other) { + file_ = other.file_; + other.file_ = nullptr; + } + return *this; +} + +ostream& +ostream::operator<<(const char* str) +{ + if (good() && str) + if (fprintf(file_, "%s", str) < 0) + setstate(badbit); + return *this; +} + +ostream& +ostream::operator<<(char c) +{ + if (good()) + if (fputc(c, file_) == EOF) + setstate(badbit); + return *this; +} + +ostream& +ostream::operator<<(int n) +{ + if (good()) + if (fprintf(file_, "%d", n) < 0) + setstate(badbit); + return *this; +} + +ostream& +ostream::operator<<(long n) +{ + if (good()) + if (fprintf(file_, "%ld", n) < 0) + setstate(badbit); + return *this; +} + +ostream& +ostream::operator<<(double d) +{ + if (good()) + if (fprintf(file_, "%f", d) < 0) + setstate(badbit); + return *this; +} + +ostream& +ostream::operator<<(const string_view& s) +{ + if (good()) + if (fprintf(file_, "%.*s", (int)s.size(), s.data()) < 0) + setstate(badbit); + return *this; +} + +ostream& +ostream::operator<<(bool b) +{ + if (good()) { + const char* value = + (flags() & boolalpha) ? (b ? "true" : "false") : (b ? "1" : "0"); + if (fprintf(file_, "%s", value) < 0) + setstate(badbit); + } + return *this; +} + +ostream& +ostream::operator<<(ostream& (*manip)(ostream&)) +{ + return manip(*this); +} + +ostream& +ostream::put(char c) +{ + if (good()) + if (fputc(c, file_) == EOF) + setstate(badbit); + return *this; +} + +ostream& +ostream::write(const char* s, streamsize n) +{ + if (good()) + if (fwrite(s, 1, n, file_) != static_cast(n)) + setstate(badbit); + return *this; +} + +ostream& +ostream::flush() +{ + if (good()) + if (fflush(file_) != 0) + setstate(badbit); + return *this; +} + +ostream& +endl(ostream& os) +{ + return os.put('\n').flush(); +} + +ostream& +ends(ostream& os) +{ + return os.put('\0'); +} + +ostream& +flush(ostream& os) +{ + return os.flush(); +} + +} // namespace ctl diff --git a/ctl/ostream.h b/ctl/ostream.h new file mode 100644 index 000000000..3b30421a1 --- /dev/null +++ b/ctl/ostream.h @@ -0,0 +1,53 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_OSTREAM_H_ +#define CTL_OSTREAM_H_ +#include "ios.h" + +namespace ctl { + +struct string_view; + +class ostream : public ios +{ + public: + ostream() = delete; + explicit ostream(FILE*); + virtual ~ostream(); + + ostream& operator<<(const char*); + ostream& operator<<(char); + ostream& operator<<(int); + ostream& operator<<(long); + ostream& operator<<(double); + ostream& operator<<(const string_view&); + ostream& operator<<(bool); + ostream& operator<<(ostream& (*)(ostream&)); + + ostream& put(char); + ostream& write(const char*, streamsize); + ostream& flush(); + + ostream(ostream&&) noexcept; + ostream& operator=(ostream&&) noexcept; + + private: + ostream(const ostream&) = delete; + ostream& operator=(const ostream&) = delete; +}; + +extern ostream cout; +extern ostream cerr; + +ostream& +endl(ostream&); + +ostream& +ends(ostream&); + +ostream& +flush(ostream&); + +} // namespace ctl + +#endif // CTL_OSTREAM_H_ diff --git a/ctl/ostringstream.cc b/ctl/ostringstream.cc new file mode 100644 index 000000000..b322c01e8 --- /dev/null +++ b/ctl/ostringstream.cc @@ -0,0 +1,140 @@ +// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +// +// Copyright 2024 Justine Alexandra Roberts Tunney +// +// Permission to use, copy, modify, and/or distribute this software for +// any purpose with or without fee is hereby granted, provided that the +// above copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include "ostringstream.h" +#include "libc/fmt/itoa.h" +#include "libc/stdio/stdio.h" + +namespace ctl { + +ostringstream::ostringstream() : buffer_(), write_pos_(0) +{ +} + +ostringstream::ostringstream(const string_view& str) + : buffer_(str), write_pos_(0) +{ +} + +string +ostringstream::str() const +{ + return buffer_; +} + +void +ostringstream::str(const string& s) +{ + buffer_ = s; + write_pos_ = 0; +} + +void +ostringstream::clear() +{ + ios_base::clear(); +} + +ostringstream& +ostringstream::operator<<(char c) +{ + if (good()) { + if (write_pos_ < buffer_.size()) { + buffer_[write_pos_++] = c; + } else { + buffer_.push_back(c); + ++write_pos_; + } + } + return *this; +} + +ostringstream& +ostringstream::operator<<(const string_view& s) +{ + if (good()) { + if (write_pos_ + s.size() <= buffer_.size()) { + buffer_.replace(write_pos_, s.size(), s); + } else { + buffer_.replace(write_pos_, buffer_.size() - write_pos_, s); + buffer_.append(s.substr(buffer_.size() - write_pos_)); + } + write_pos_ += s.size(); + } + return *this; +} + +ostringstream& +ostringstream::operator<<(int n) +{ + char temp[12]; + if (good()) + *this << string_view(temp, FormatInt32(temp, n) - temp); + return *this; +} + +ostringstream& +ostringstream::operator<<(unsigned int n) +{ + char temp[12]; + if (good()) + *this << string_view(temp, FormatUint32(temp, n) - temp); + return *this; +} + +ostringstream& +ostringstream::operator<<(long n) +{ + char temp[21]; + if (good()) + *this << string_view(temp, FormatInt64(temp, n) - temp); + return *this; +} + +ostringstream& +ostringstream::operator<<(unsigned long n) +{ + char temp[21]; + if (good()) + *this << string_view(temp, FormatUint64(temp, n) - temp); + return *this; +} + +ostringstream& +ostringstream::operator<<(float f) +{ + if (good()) { + char temp[32]; + int len = snprintf(temp, sizeof(temp), "%g", f); + *this << string_view(temp, len); + } + return *this; +} + +ostringstream& +ostringstream::operator<<(double d) +{ + if (good()) { + char temp[32]; + int len = snprintf(temp, sizeof(temp), "%g", d); + *this << string_view(temp, len); + } + return *this; +} + +} // namespace ctl diff --git a/ctl/ostringstream.h b/ctl/ostringstream.h new file mode 100644 index 000000000..09face624 --- /dev/null +++ b/ctl/ostringstream.h @@ -0,0 +1,36 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_OSTRINGSTREAM_H_ +#define CTL_OSTRINGSTREAM_H_ +#include "ios_base.h" +#include "string.h" + +namespace ctl { + +class ostringstream : public ios_base +{ + public: + ostringstream(); + explicit ostringstream(const string_view&); + + string str() const; + void str(const string& s); + void clear(); + + ostringstream& operator<<(char); + ostringstream& operator<<(const string_view&); + ostringstream& operator<<(int); + ostringstream& operator<<(unsigned int); + ostringstream& operator<<(long); + ostringstream& operator<<(unsigned long); + ostringstream& operator<<(float); + ostringstream& operator<<(double); + + private: + string buffer_; + size_t write_pos_; +}; + +} // namespace ctl + +#endif // CTL_OSTRINGSTREAM_H_ diff --git a/ctl/utility.h b/ctl/utility.h index 464e04f64..547580f81 100644 --- a/ctl/utility.h +++ b/ctl/utility.h @@ -1,7 +1,7 @@ // -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- // vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi -#ifndef COSMOPOLITAN_CTL_UTILITY_H_ -#define COSMOPOLITAN_CTL_UTILITY_H_ +#ifndef CTL_UTILITY_H_ +#define CTL_UTILITY_H_ #include "remove_reference.h" namespace ctl { @@ -66,4 +66,4 @@ declval() noexcept; } // namespace ctl -#endif // COSMOPOLITAN_CTL_UTILITY_H_ +#endif // CTL_UTILITY_H_ diff --git a/libc/intrin/strace.internal.h b/libc/intrin/strace.internal.h index 3c521857f..adda49caa 100644 --- a/libc/intrin/strace.internal.h +++ b/libc/intrin/strace.internal.h @@ -5,7 +5,7 @@ #define SYSDEBUG 0 #endif -#define _NTTRACE 0 /* not configurable w/ flag yet */ +#define _NTTRACE 1 /* not configurable w/ flag yet */ #define _POLLTRACE 0 /* not configurable w/ flag yet */ #define _DATATRACE 1 /* not configurable w/ flag yet */ #define _LOCKTRACE 0 /* not configurable w/ flag yet */ diff --git a/test/ctl/BUILD.mk b/test/ctl/BUILD.mk index 2bdcf5381..f644eb2cb 100644 --- a/test/ctl/BUILD.mk +++ b/test/ctl/BUILD.mk @@ -14,10 +14,11 @@ TEST_CTL_TESTS = $(TEST_CTL_COMS:%=%.ok) TEST_CTL_DIRECTDEPS = \ CTL \ LIBC_CALLS \ - LIBC_STDIO \ LIBC_INTRIN \ + LIBC_LOG \ LIBC_MEM \ LIBC_STDIO \ + LIBC_STDIO \ LIBC_THREAD \ THIRD_PARTY_LIBCXX \ THIRD_PARTY_LIBCXXABI \ diff --git a/test/ctl/istringstream_test.cc b/test/ctl/istringstream_test.cc new file mode 100644 index 000000000..08019c93c --- /dev/null +++ b/test/ctl/istringstream_test.cc @@ -0,0 +1,163 @@ +// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +// +// Copyright 2024 Justine Alexandra Roberts Tunney +// +// Permission to use, copy, modify, and/or distribute this software for +// any purpose with or without fee is hereby granted, provided that the +// above copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include "ctl/istringstream.h" +#include "libc/mem/leaks.h" + +// #include +// #define ctl std + +int +main() +{ + + // Test default constructor + { + ctl::istringstream iss; + if (iss.eof()) + return 1; + if (!iss.good()) + return 1; + } + + // Test constructor with initial string + { + ctl::istringstream iss("Hello, world!"); + if (iss.str() != "Hello, world!") + return 2; + } + + // Test reading a char + { + ctl::istringstream iss("A"); + char c; + iss >> c; + if (c != 'A' || !iss.good()) + return 3; + } + + // Test reading a string + { + ctl::istringstream iss("Hello World"); + ctl::string s; + iss >> s; + if (s != "Hello" || !iss.good()) + return 4; + } + + // Test reading multiple strings + { + ctl::istringstream iss("One Two Three"); + ctl::string s1, s2, s3; + iss >> s1 >> s2 >> s3; + if (s1 != "One" || s2 != "Two" || s3 != "Three" || iss.good() || + !iss.eof()) + return 5; + } + + // Test reading integers + { + ctl::istringstream iss("123 -456 789"); + int a, b, c; + iss >> a >> b >> c; + if (a != 123 || b != -456 || c != 789 || iss.good() || !iss.eof()) + return 6; + } + + // Test reading floating-point numbers + { + ctl::istringstream iss("3.14 -2.718"); + float f; + double d; + iss >> f >> d; + if (f != 3.14f || d != -2.718 || iss.good() || !iss.eof()) + return 7; + } + + // Test reading past the end of the stream + { + ctl::istringstream iss("42"); + int n; + iss >> n; + if (n != 42 || iss.good() || !iss.eof()) + return 8; + iss >> n; + if (iss.good()) + return 9; + if (!iss.eof()) + return 10; + } + + // Test reading invalid data + { + ctl::istringstream iss("not_a_number"); + int n; + iss >> n; + if (iss.good() || !iss.fail()) + return 11; + } + + // Test str() setter + { + ctl::istringstream iss; + iss.str("New content"); + if (iss.str() != "New content" || !iss.good()) + return 12; + } + + // Test reading after setting a new string + { + ctl::istringstream iss("Old content"); + iss.str("New content"); + ctl::string s; + iss >> s; + if (s != "New" || !iss.good()) + return 13; + } + + // Test reading a mixture of types + { + ctl::istringstream iss("42 3.14 Hello"); + int i; + double d; + ctl::string s; + iss >> i >> d >> s; + if (i != 42 || d != 3.14 || s != "Hello" || iss.good() || !iss.eof()) + return 14; + } + + // Test reading with leading whitespace + { + ctl::istringstream iss(" 42"); + int n; + iss >> n; + if (n != 42 || iss.good() || !iss.eof()) + return 15; + } + + // Test clear() only affects error state, not content + { + ctl::istringstream iss("Test"); + iss.setstate(ctl::ios_base::failbit); + iss.clear(); + if (!iss.good() || iss.str() != "Test") + return 16; + } + + CheckForMemoryLeaks(); +} diff --git a/test/ctl/ostringstream_test.cc b/test/ctl/ostringstream_test.cc new file mode 100644 index 000000000..da45a6a03 --- /dev/null +++ b/test/ctl/ostringstream_test.cc @@ -0,0 +1,140 @@ +// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +// +// Copyright 2024 Justine Alexandra Roberts Tunney +// +// Permission to use, copy, modify, and/or distribute this software for +// any purpose with or without fee is hereby granted, provided that the +// above copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include "ctl/ostringstream.h" +#include "libc/mem/leaks.h" + +// #include +// #define ctl std + +int +main() +{ + + // Test default constructor and basic string insertion + { + ctl::ostringstream oss; + oss << "Hello, world!"; + if (oss.str() != "Hello, world!") + return 1; + } + + // Test constructor with initial string (overwrite mode) + { + ctl::ostringstream oss("Initial content"); + oss << "New"; + if (oss.str() != "Newtial content") + return 2; + } + + // Test overwrite and append behavior + { + ctl::ostringstream oss("Hello, world!"); + oss << "Hi"; + if (oss.str() != "Hillo, world!") + return 3; + oss << " Earth"; + if (oss.str() != "Hi Earthorld!") + return 4; + } + + // Test multiple insertions of different types + { + ctl::ostringstream oss; + oss << "Int: " << 42 << ", Float: " << 3.14f << ", Double: " << 2.718; + if (oss.str() != "Int: 42, Float: 3.14, Double: 2.718") + return 5; + } + + // Test char insertion + { + ctl::ostringstream oss("ABCDEF"); + oss << 'X' << 'Y' << 'Z'; + if (oss.str() != "XYZDEF") + return 6; + } + + // Test unsigned types + { + ctl::ostringstream oss("Numbers: "); + unsigned int ui = 12345; + unsigned long ul = 67890UL; + oss << ui << " " << ul; + if (oss.str() != "12345 67890") + return 7; + } + + // Test long type + { + ctl::ostringstream oss("Long: "); + long l = -9876543210L; + oss << l; + if (oss.str() != "-9876543210") + return 8; + } + + // Test clear() method + { + ctl::ostringstream oss("not that kind of clear"); + oss.clear(); + if (!oss.good() || oss.str() != "not that kind of clear") + return 9; + } + + // Test str() setter method + { + ctl::ostringstream oss; + oss.str("New content"); + oss << "Old"; + if (oss.str() != "Old content") + return 10; + } + + // Test chaining of insertion operators + { + ctl::ostringstream oss("Start: "); + oss << "Chain " << 1 << " " << 2.0 << " " << 'Z'; + if (oss.str() != "Chain 1 2 Z") + return 11; + } + + // Test insertion when stream is not in good state + { + ctl::ostringstream oss("Original"); + oss.setstate(ctl::ios_base::failbit); + oss << "This should not be inserted"; + if (oss.str() != "Original") + return 12; + } + + // Test with larger amounts of data + { + ctl::ostringstream oss("Prefix: "); + for (int i = 0; i < 1000; ++i) { + oss << "Line " << i << "\n"; + } + ctl::string result = oss.str(); + if (result.substr(0, 14) != "Line 0\nLine 1\n") + return 13; + if (result.substr(result.length() - 8) != "ine 999\n") + return 14; + } + + CheckForMemoryLeaks(); + return 0; +} From 1bf2d8e308121ae03d065837ccdaf66ab05da512 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sat, 29 Jun 2024 17:12:25 -0700 Subject: [PATCH 010/405] Further improve mmap() locking story The way to use double linked lists, is to remove all the things you want to work on, insert them into a new list on the stack. Then once you have all the work items, you release the lock, do your work, and then lock it again, to add the shelled out items back to a global freelist. --- ctl/BUILD.mk | 1 + libc/intrin/maps.h | 1 - libc/intrin/mmap.c | 145 ++++++++++++++++++++------------------ libc/intrin/randaddr.c | 25 ------- libc/intrin/reservefd.c | 6 +- libc/runtime/zipos-open.c | 2 +- test/ctl/BUILD.mk | 1 + tool/cosmocc/package.sh | 4 +- 8 files changed, 84 insertions(+), 101 deletions(-) delete mode 100644 libc/intrin/randaddr.c diff --git a/ctl/BUILD.mk b/ctl/BUILD.mk index f30a3c8bc..73cf29766 100644 --- a/ctl/BUILD.mk +++ b/ctl/BUILD.mk @@ -18,6 +18,7 @@ CTL_A_CHECKS = \ CTL_A_DIRECTDEPS = \ LIBC_INTRIN \ LIBC_MEM \ + LIBC_NEXGEN32E \ LIBC_STDIO \ LIBC_STR \ THIRD_PARTY_GDTOA \ diff --git a/libc/intrin/maps.h b/libc/intrin/maps.h index ca0d013ff..97d160fbd 100644 --- a/libc/intrin/maps.h +++ b/libc/intrin/maps.h @@ -39,7 +39,6 @@ struct AddrSize { extern struct Maps __maps; -void *randaddr(void); void __maps_init(void); void __maps_lock(void); void __maps_check(void); diff --git a/libc/intrin/mmap.c b/libc/intrin/mmap.c index 1f9befd7f..e71fb2b1e 100644 --- a/libc/intrin/mmap.c +++ b/libc/intrin/mmap.c @@ -21,6 +21,7 @@ #include "libc/calls/blockcancel.internal.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/state.internal.h" #include "libc/calls/struct/sigset.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" @@ -187,10 +188,10 @@ int __munmap(char *addr, size_t size, bool untrack_only) { !size || (uintptr_t)addr + size < size) return einval(); - // untrack and delete mapping + // untrack mappings int rc = 0; + struct Dll *delete = 0; __maps_lock(); -StartOver:; struct Map *map = __maps.maps; struct Map **prev = &__maps.maps; while (map) { @@ -202,30 +203,10 @@ StartOver:; if (addr <= map_addr && addr + PGUP(size) >= map_addr + PGUP(map_size)) { // remove mapping completely dll_remove(&__maps.used, &map->elem); + dll_make_first(&delete, &map->elem); *prev = next; __maps.pages -= (map_size + pagesz - 1) / pagesz; __maps.count -= 1; - if (untrack_only) { - __maps_free(map); - __maps_check(); - } else { - __maps_unlock(); - if (!IsWindows()) { - ASSERT(addr <= map_addr); - ASSERT(map_addr + PGUP(map_size) <= addr + PGUP(size)); - if (sys_munmap(map_addr, map_size)) - rc = -1; - } else { - if (!UnmapViewOfFile(map_addr)) - rc = -1; - if (!CloseHandle(map->h)) - rc = -1; - } - __maps_lock(); - __maps_free(map); - __maps_check(); - goto StartOver; - } map = next; continue; } else if (IsWindows()) { @@ -240,35 +221,34 @@ StartOver:; size_t right = map_size - left; ASSERT(right > 0); ASSERT(left > 0); - map->addr += left; - map->size = right; - if (!(map->flags & MAP_ANONYMOUS)) - map->off += left; - __maps.pages -= (left + pagesz - 1) / pagesz; - __maps_check(); - if (!untrack_only) { - __maps_unlock(); - ASSERT(addr <= map_addr); - ASSERT(map_addr + PGUP(left) <= addr + PGUP(size)); - if (sys_munmap(map_addr, left) == -1) - rc = -1; - __maps_lock(); - goto StartOver; + struct Map *leftmap; + if ((leftmap = __maps_alloc())) { + map->addr += left; + map->size = right; + if (!(map->flags & MAP_ANONYMOUS)) + map->off += left; + __maps.pages -= (left + pagesz - 1) / pagesz; + __maps_check(); + leftmap->addr = map_addr; + leftmap->size = left; + dll_make_first(&delete, &leftmap->elem); + } else { + rc = -1; } } else if (addr + PGUP(size) >= map_addr + PGUP(map_size)) { // shave off righthand side of mapping size_t left = addr - map_addr; size_t right = map_addr + map_size - addr; - map->size = left; - __maps.pages -= (right + pagesz - 1) / pagesz; - __maps_check(); - if (!untrack_only) { - __maps_unlock(); - ASSERT(PGUP(right) <= PGUP(size)); - if (sys_munmap(addr, right) == -1) - rc = -1; - __maps_lock(); - goto StartOver; + struct Map *rightmap; + if ((rightmap = __maps_alloc())) { + map->size = left; + __maps.pages -= (right + pagesz - 1) / pagesz; + __maps_check(); + rightmap->addr = addr; + rightmap->size = right; + dll_make_first(&delete, &rightmap->elem); + } else { + rc = -1; } } else { // punch hole in mapping @@ -277,27 +257,28 @@ StartOver:; size_t right = map_size - middle - left; struct Map *leftmap; if ((leftmap = __maps_alloc())) { - leftmap->next = map; - leftmap->addr = map_addr; - leftmap->size = left; - leftmap->off = map->off; - leftmap->prot = map->prot; - leftmap->flags = map->flags; - map->addr += left + middle; - map->size = right; - if (!(map->flags & MAP_ANONYMOUS)) - map->off += left + middle; - dll_make_first(&__maps.used, &leftmap->elem); - *prev = leftmap; - __maps.pages -= (middle + pagesz - 1) / pagesz; - __maps.count += 1; - __maps_check(); - if (!untrack_only) { - __maps_unlock(); - if (sys_munmap(addr, size) == -1) - rc = -1; - __maps_lock(); - goto StartOver; + struct Map *middlemap; + if ((middlemap = __maps_alloc())) { + leftmap->next = map; + leftmap->addr = map_addr; + leftmap->size = left; + leftmap->off = map->off; + leftmap->prot = map->prot; + leftmap->flags = map->flags; + map->addr += left + middle; + map->size = right; + if (!(map->flags & MAP_ANONYMOUS)) + map->off += left + middle; + dll_make_first(&__maps.used, &leftmap->elem); + *prev = leftmap; + __maps.pages -= (middle + pagesz - 1) / pagesz; + __maps.count += 1; + __maps_check(); + middlemap->addr = addr; + middlemap->size = size; + dll_make_first(&delete, &middlemap->elem); + } else { + rc = -1; } } else { rc = -1; @@ -309,6 +290,34 @@ StartOver:; } __maps_unlock(); + // delete mappings + for (struct Dll *e = dll_first(delete); e; e = dll_next(delete, e)) { + map = MAP_CONTAINER(e); + if (!untrack_only) { + if (!IsWindows()) { + if (sys_munmap(map->addr, map->size)) + rc = -1; + } else { + if (!UnmapViewOfFile(map->addr)) + rc = -1; + if (!CloseHandle(map->h)) + rc = -1; + } + } + } + + // free mappings + if (!dll_is_empty(delete)) { + __maps_lock(); + struct Dll *e; + while ((e = dll_first(delete))) { + dll_remove(&delete, e); + __maps_free(MAP_CONTAINER(e)); + } + __maps_check(); + __maps_unlock(); + } + return rc; } diff --git a/libc/intrin/randaddr.c b/libc/intrin/randaddr.c deleted file mode 100644 index 5be079696..000000000 --- a/libc/intrin/randaddr.c +++ /dev/null @@ -1,25 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-β”‚ -β”‚ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi β”‚ -β•žβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•‘ -β”‚ Copyright 2024 Justine Alexandra Roberts Tunney β”‚ -β”‚ β”‚ -β”‚ Permission to use, copy, modify, and/or distribute this software for β”‚ -β”‚ any purpose with or without fee is hereby granted, provided that the β”‚ -β”‚ above copyright notice and this permission notice appear in all copies. β”‚ -β”‚ β”‚ -β”‚ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL β”‚ -β”‚ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED β”‚ -β”‚ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE β”‚ -β”‚ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL β”‚ -β”‚ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR β”‚ -β”‚ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER β”‚ -β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ -β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ -β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ - -void *randaddr(void) { - static unsigned long lcg = 1; - lcg *= 6364136223846793005; - lcg += 1442695040888963407; - return (void *)(lcg >> 48 << 28); -} diff --git a/libc/intrin/reservefd.c b/libc/intrin/reservefd.c index 1be7e4b4f..a8d47a477 100644 --- a/libc/intrin/reservefd.c +++ b/libc/intrin/reservefd.c @@ -64,11 +64,9 @@ int __reservefd_unlocked(int start) { int fd, f1, f2; for (;;) { f1 = atomic_load_explicit(&g_fds.f, memory_order_acquire); - for (fd = MAX(start, f1); fd < g_fds.n; ++fd) { - if (!g_fds.p[fd].kind) { + for (fd = MAX(start, f1); fd < g_fds.n; ++fd) + if (!g_fds.p[fd].kind) break; - } - } fd = __ensurefds_unlocked(fd); bzero(g_fds.p + fd, sizeof(*g_fds.p)); if (_cmpxchg(&g_fds.p[fd].kind, kFdEmpty, kFdReserved)) { diff --git a/libc/runtime/zipos-open.c b/libc/runtime/zipos-open.c index 37ace7fb3..1bd8e568a 100644 --- a/libc/runtime/zipos-open.c +++ b/libc/runtime/zipos-open.c @@ -58,7 +58,7 @@ static struct ZiposHandle *__zipos_alloc(struct Zipos *zipos, size_t size) { granularity = __granularity(); mapsize = sizeof(struct ZiposHandle) + size; mapsize = (mapsize + granularity - 1) & -granularity; - if ((h = __mmap(randaddr(), mapsize, PROT_READ | PROT_WRITE, + if ((h = __mmap(0, mapsize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) != MAP_FAILED) { h->size = size; h->zipos = zipos; diff --git a/test/ctl/BUILD.mk b/test/ctl/BUILD.mk index f644eb2cb..97562343e 100644 --- a/test/ctl/BUILD.mk +++ b/test/ctl/BUILD.mk @@ -17,6 +17,7 @@ TEST_CTL_DIRECTDEPS = \ LIBC_INTRIN \ LIBC_LOG \ LIBC_MEM \ + LIBC_NEXGEN32E \ LIBC_STDIO \ LIBC_STDIO \ LIBC_THREAD \ diff --git a/tool/cosmocc/package.sh b/tool/cosmocc/package.sh index 8abb3132e..70e76328c 100755 --- a/tool/cosmocc/package.sh +++ b/tool/cosmocc/package.sh @@ -90,10 +90,10 @@ fetch() { OLD=$PWD cd "$OUTDIR/" if [ ! -x bin/x86_64-linux-cosmo-gcc ]; then - fetch https://github.com/ahgamut/superconfigure/releases/download/z0.0.44/aarch64-gcc.zip + fetch https://github.com/ahgamut/superconfigure/releases/download/z0.0.45/aarch64-gcc.zip unzip aarch64-gcc.zip rm -f aarch64-gcc.zip - fetch https://github.com/ahgamut/superconfigure/releases/download/z0.0.44/x86_64-gcc.zip + fetch https://github.com/ahgamut/superconfigure/releases/download/z0.0.45/x86_64-gcc.zip unzip x86_64-gcc.zip rm -f x86_64-gcc.zip fi From 4cb5e21ba809672b635d18c3750c2e1c4ee599a9 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sun, 30 Jun 2024 02:26:06 -0700 Subject: [PATCH 011/405] Introduce pthread_decimate_np() api This is useful with CheckForMemoryLeaks(). --- libc/thread/pthread_decimate_np.c | 37 +++++++++++++++++++++++++++++++ libc/thread/thread.h | 1 + 2 files changed, 38 insertions(+) create mode 100644 libc/thread/pthread_decimate_np.c diff --git a/libc/thread/pthread_decimate_np.c b/libc/thread/pthread_decimate_np.c new file mode 100644 index 000000000..a6bc591cf --- /dev/null +++ b/libc/thread/pthread_decimate_np.c @@ -0,0 +1,37 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-β”‚ +β”‚ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi β”‚ +β•žβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•‘ +β”‚ Copyright 2024 Justine Alexandra Roberts Tunney β”‚ +β”‚ β”‚ +β”‚ Permission to use, copy, modify, and/or distribute this software for β”‚ +β”‚ any purpose with or without fee is hereby granted, provided that the β”‚ +β”‚ above copyright notice and this permission notice appear in all copies. β”‚ +β”‚ β”‚ +β”‚ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL β”‚ +β”‚ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED β”‚ +β”‚ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE β”‚ +β”‚ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL β”‚ +β”‚ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR β”‚ +β”‚ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER β”‚ +β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ +β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ +β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/thread/posixthread.internal.h" +#include "libc/thread/thread.h" + +/** + * Garbage collects POSIX threads runtime. + * + * Let's say you want to run a memory leak detector. You can say: + * + * while (!pthread_orphan_np()) + * pthread_decimate_np(); + * + * To wait until all threads have exited. + * + * @return 0 on success, or errno on error + */ +int pthread_decimate_np(void) { + _pthread_decimate(); + return 0; +} diff --git a/libc/thread/thread.h b/libc/thread/thread.h index 76f372b49..a0eaf0167 100644 --- a/libc/thread/thread.h +++ b/libc/thread/thread.h @@ -166,6 +166,7 @@ int pthread_mutexattr_setpshared(pthread_mutexattr_t *, int) libcesque paramsnon int pthread_mutexattr_settype(pthread_mutexattr_t *, int) libcesque paramsnonnull(); int pthread_once(pthread_once_t *, void (*)(void)) paramsnonnull(); int pthread_orphan_np(void) libcesque; +int pthread_decimate_np(void) libcesque; int pthread_rwlock_destroy(pthread_rwlock_t *) libcesque paramsnonnull(); int pthread_rwlock_init(pthread_rwlock_t *, const pthread_rwlockattr_t *) libcesque paramsnonnull((1)); int pthread_rwlock_rdlock(pthread_rwlock_t *) libcesque paramsnonnull(); From 387310c659817632a4a4a4aeee313575e39696b7 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sun, 30 Jun 2024 02:26:38 -0700 Subject: [PATCH 012/405] Fix issue with ctl::vector constructor --- ctl/array.h | 8 ++++-- ctl/iterator_traits.h | 33 ++++++++++++++++-------- ctl/map.h | 4 +-- ctl/require_input_iterator.h | 19 ++++++++++++++ ctl/vector.h | 15 +++++++---- libc/intrin/describebacktrace.internal.h | 6 ++--- libc/mem/malloc.c | 1 - test/ctl/vector_test.cc | 8 ++++++ 8 files changed, 70 insertions(+), 24 deletions(-) create mode 100644 ctl/require_input_iterator.h diff --git a/ctl/array.h b/ctl/array.h index a2b5925b5..5e532392f 100644 --- a/ctl/array.h +++ b/ctl/array.h @@ -37,24 +37,28 @@ struct array constexpr reference at(size_type pos) { if (pos >= N) - throw ctl::out_of_range("out of range"); + throw ctl::out_of_range(); return elems[pos]; } constexpr const_reference at(size_type pos) const { if (pos >= N) - throw ctl::out_of_range("out of range"); + throw ctl::out_of_range(); return elems[pos]; } constexpr reference operator[](size_type pos) { + if (pos >= N) + __builtin_trap(); return elems[pos]; } constexpr const_reference operator[](size_type pos) const { + if (pos >= N) + __builtin_trap(); return elems[pos]; } diff --git a/ctl/iterator_traits.h b/ctl/iterator_traits.h index c08217c76..ecc0fffe0 100644 --- a/ctl/iterator_traits.h +++ b/ctl/iterator_traits.h @@ -2,12 +2,33 @@ // vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi #ifndef CTL_ITERATOR_TRAITS_H_ #define CTL_ITERATOR_TRAITS_H_ +#include "iterator.h" #include "utility.h" +#include "void_t.h" namespace ctl { -template +template struct iterator_traits +{}; + +template +struct iterator_traits +{ + using difference_type = ptrdiff_t; + using value_type = T; + using pointer = T*; + using reference = T&; + using iterator_category = ctl::random_access_iterator_tag; +}; + +template +struct iterator_traits> { using iterator_category = typename Iterator::iterator_category; using value_type = typename Iterator::value_type; @@ -16,16 +37,6 @@ struct iterator_traits using reference = typename Iterator::reference; }; -template -struct iterator_traits -{ - using iterator_category = void*; // We don't actually use this - using value_type = T; - using difference_type = ptrdiff_t; - using pointer = T*; - using reference = T&; -}; - } // namespace ctl #endif // CTL_ITERATOR_TRAITS_H_ diff --git a/ctl/map.h b/ctl/map.h index a9a6510bb..e3978545e 100644 --- a/ctl/map.h +++ b/ctl/map.h @@ -165,7 +165,7 @@ class map { auto it = find(key); if (it == end()) - throw ctl::out_of_range("out of range"); + throw ctl::out_of_range(); return it->second; } @@ -173,7 +173,7 @@ class map { auto it = find(key); if (it == end()) - throw ctl::out_of_range("out of range"); + throw ctl::out_of_range(); return it->second; } diff --git a/ctl/require_input_iterator.h b/ctl/require_input_iterator.h new file mode 100644 index 000000000..221e06a74 --- /dev/null +++ b/ctl/require_input_iterator.h @@ -0,0 +1,19 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_REQUIRE_INPUT_ITERATOR_H_ +#define CTL_REQUIRE_INPUT_ITERATOR_H_ +#include "enable_if.h" +#include "is_convertible.h" +#include "iterator.h" +#include "iterator_traits.h" + +namespace ctl { + +template +using require_input_iterator = typename ctl::enable_if< + ctl::is_convertible::iterator_category, + ctl::input_iterator_tag>::value>::type; + +} // namespace ctl + +#endif /* CTL_REQUIRE_INPUT_ITERATOR_H_ */ diff --git a/ctl/vector.h b/ctl/vector.h index b5837614c..30861e27d 100644 --- a/ctl/vector.h +++ b/ctl/vector.h @@ -15,6 +15,7 @@ #include "move_backward.h" #include "move_iterator.h" #include "out_of_range.h" +#include "require_input_iterator.h" #include "reverse_iterator.h" #include "uninitialized_fill.h" #include "uninitialized_fill_n.h" @@ -65,7 +66,7 @@ class vector resize(count); } - template + template> vector(InputIt first, InputIt last, const Allocator& alloc = Allocator()) : alloc_(alloc), data_(nullptr), size_(0), capacity_(0) { @@ -173,7 +174,7 @@ class vector size_ = count; } - template + template> void assign(InputIt first, InputIt last) { clear(); @@ -189,24 +190,28 @@ class vector reference at(size_type pos) { if (pos >= size_) - throw ctl::out_of_range("out of range"); + throw ctl::out_of_range(); return data_[pos]; } const_reference at(size_type pos) const { if (pos >= size_) - throw ctl::out_of_range("out of range"); + throw ctl::out_of_range(); return data_[pos]; } reference operator[](size_type pos) { + if (pos >= size_) + __builtin_trap(); return data_[pos]; } const_reference operator[](size_type pos) const { + if (pos >= size_) + __builtin_trap(); return data_[pos]; } @@ -368,7 +373,7 @@ class vector return it; } - template + template> iterator insert(const_iterator pos, InputIt first, InputIt last) { difference_type count = ctl::distance(first, last); diff --git a/libc/intrin/describebacktrace.internal.h b/libc/intrin/describebacktrace.internal.h index 9c116cd25..c9e600d66 100644 --- a/libc/intrin/describebacktrace.internal.h +++ b/libc/intrin/describebacktrace.internal.h @@ -1,5 +1,5 @@ -#ifndef COSMOPOLITAN_LIBC_INTRIN_DESCRIBEBACKTRACE_INTERNAL_H_ -#define COSMOPOLITAN_LIBC_INTRIN_DESCRIBEBACKTRACE_INTERNAL_H_ +#ifndef COSMOPOLITAN_LIBC_INTRIN_DESCRIBEBACKTRACE_H_ +#define COSMOPOLITAN_LIBC_INTRIN_DESCRIBEBACKTRACE_H_ #include "libc/mem/alloca.h" #include "libc/nexgen32e/stackframe.h" COSMOPOLITAN_C_START_ @@ -8,4 +8,4 @@ const char *DescribeBacktrace(char[160], const struct StackFrame *) libcesque; #define DescribeBacktrace(x) DescribeBacktrace(alloca(160), x) COSMOPOLITAN_C_END_ -#endif /* COSMOPOLITAN_LIBC_INTRIN_DESCRIBEBACKTRACE_INTERNAL_H_ */ +#endif /* COSMOPOLITAN_LIBC_INTRIN_DESCRIBEBACKTRACE_H_ */ diff --git a/libc/mem/malloc.c b/libc/mem/malloc.c index c843f2fc8..043a41aac 100644 --- a/libc/mem/malloc.c +++ b/libc/mem/malloc.c @@ -42,4 +42,3 @@ void *malloc(size_t n) { return dlmalloc(n); } - diff --git a/test/ctl/vector_test.cc b/test/ctl/vector_test.cc index 9e65333c3..84469b2c0 100644 --- a/test/ctl/vector_test.cc +++ b/test/ctl/vector_test.cc @@ -352,5 +352,13 @@ main() return 80; } + { + ctl::vector dog(8, 0); + if (dog.size() != 8) + return 81; + if (dog[0] != 0) + return 82; + } + CheckForMemoryLeaks(); } From 76957983cfa147f4b84c1f0001427abc9f38b163 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sun, 30 Jun 2024 15:38:59 -0700 Subject: [PATCH 013/405] Make POSIX threads improvements - Ensure SIGTHR isn't blocked in newly created threads - Use TIB rather than thread_local for thread atexits - Make POSIX thread keys atomic within thread - Don't bother logging prctl() to --strace - Log thread destructor names to --strace --- libc/calls/prctl.c | 10 ---- libc/intrin/describeflags.internal.h | 4 -- libc/runtime/cxa_thread_atexit.c | 47 ++++++++++--------- libc/thread/pthread_cancel.c | 5 +- libc/thread/pthread_create.c | 1 + libc/thread/pthread_key_create.c | 6 +-- libc/thread/pthread_key_delete.c | 9 ++-- libc/thread/thread.h | 2 +- libc/thread/tls.h | 3 +- test/ctl/all_of_test.cc | 6 +-- .../libc/thread/pthread_getunique_np_test.c | 35 ++++++-------- 11 files changed, 57 insertions(+), 71 deletions(-) rename libc/intrin/describeprctloperation.c => test/libc/thread/pthread_getunique_np_test.c (75%) diff --git a/libc/calls/prctl.c b/libc/calls/prctl.c index bd31a8c75..456df4cee 100644 --- a/libc/calls/prctl.c +++ b/libc/calls/prctl.c @@ -53,15 +53,5 @@ int prctl(int operation, ...) { rc = enosys(); } -#if SYSDEBUG - if (operation == PR_CAPBSET_READ || operation == PR_CAPBSET_DROP) { - STRACE("prctl(%s, %s) β†’ %d% m", DescribePrctlOperation(operation), - DescribeCapability(a), rc); - } else { - STRACE("prctl(%s, %p, %p, %p, %p) β†’ %d% m", - DescribePrctlOperation(operation), a, b, c, d, rc); - } -#endif - return rc; } diff --git a/libc/intrin/describeflags.internal.h b/libc/intrin/describeflags.internal.h index 28d0a635a..8c7ee2686 100644 --- a/libc/intrin/describeflags.internal.h +++ b/libc/intrin/describeflags.internal.h @@ -13,7 +13,6 @@ const char *DescribeFlags(char *, size_t, const struct DescribeFlags *, size_t, const char *DescribeArchPrctlCode(char[12], int) libcesque; const char *DescribeCancelState(char[12], int, int *) libcesque; -const char *DescribeCapability(char[32], int) libcesque; const char *DescribeClockName(char[32], int) libcesque; const char *DescribeControlKeyState(char[64], uint32_t) libcesque; const char *DescribeDirfd(char[12], int) libcesque; @@ -47,7 +46,6 @@ const char *DescribeOpenFlags(char[128], int) libcesque; const char *DescribeOpenMode(char[15], int, int) libcesque; const char *DescribePersonalityFlags(char[128], int) libcesque; const char *DescribePollFlags(char[64], int) libcesque; -const char *DescribePrctlOperation(int) libcesque; const char *DescribeProtFlags(char[48], int) libcesque; const char *DescribePtrace(char[12], int) libcesque; const char *DescribePtraceEvent(char[32], int) libcesque; @@ -69,9 +67,7 @@ const char *DescribeVirtualKeyCode(char[32], uint32_t) libcesque; const char *DescribeWhence(char[12], int) libcesque; const char *DescribeWhichPrio(char[12], int) libcesque; -#define DescribeArchPrctlCode(x) DescribeArchPrctlCode(alloca(12), x) #define DescribeCancelState(x, y) DescribeCancelState(alloca(12), x, y) -#define DescribeCapability(x) DescribeCapability(alloca(32), x) #define DescribeClockName(x) DescribeClockName(alloca(32), x) #define DescribeControlKeyState(x) DescribeControlKeyState(alloca(64), x) #define DescribeDirfd(x) DescribeDirfd(alloca(12), x) diff --git a/libc/runtime/cxa_thread_atexit.c b/libc/runtime/cxa_thread_atexit.c index 9d8eaa3f1..cce24949f 100644 --- a/libc/runtime/cxa_thread_atexit.c +++ b/libc/runtime/cxa_thread_atexit.c @@ -17,6 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/intrin/cxaatexit.internal.h" +#include "libc/intrin/strace.internal.h" #include "libc/intrin/weaken.h" #include "libc/mem/mem.h" #include "libc/nexgen32e/gc.internal.h" @@ -30,8 +31,6 @@ struct Dtor { struct Dtor *next; }; -static _Thread_local struct Dtor *__cxa_thread_atexit_list; - static void _pthread_unwind(struct CosmoTib *tib) { struct PosixThread *pt; struct _pthread_cleanup_buffer *cb; @@ -42,24 +41,24 @@ static void _pthread_unwind(struct CosmoTib *tib) { } } -static void __cxa_thread_unkey(struct CosmoTib *tib) { - void *val; - int i, j, gotsome; - pthread_key_dtor dtor; - for (j = 0; j < PTHREAD_DESTRUCTOR_ITERATIONS; ++j) { - for (gotsome = i = 0; i < PTHREAD_KEYS_MAX; ++i) { - if ((val = tib->tib_keys[i]) && - (dtor = atomic_load_explicit(_pthread_key_dtor + i, - memory_order_relaxed)) && - dtor != (pthread_key_dtor)-1) { - gotsome = 1; - tib->tib_keys[i] = 0; +static void _pthread_unkey(struct CosmoTib *tib) { + for (int j = 0; j < PTHREAD_DESTRUCTOR_ITERATIONS; ++j) { + bool gotsome = false; + for (int i = 0; i < PTHREAD_KEYS_MAX; ++i) { + void *val; + pthread_key_dtor dtor; + if ((dtor = atomic_load_explicit(&_pthread_key_dtor[i], + memory_order_acquire)) && + dtor != (pthread_key_dtor)-1 && + (val = atomic_exchange_explicit(&tib->tib_keys[i], 0, + memory_order_relaxed))) { + STRACE("_pthread_unkey(%t, %p)", dtor, val); + gotsome = true; dtor(val); } } - if (!gotsome) { + if (!gotsome) break; - } } } @@ -67,9 +66,8 @@ static void _pthread_ungarbage(struct CosmoTib *tib) { struct Garbages *g; while ((g = tib->tib_garbages)) { tib->tib_garbages = 0; - while (g->i--) { + while (g->i--) ((void (*)(intptr_t))g->p[g->i].fn)(g->p[g->i].arg); - } _weaken(free)(g->p); _weaken(free)(g); } @@ -82,10 +80,11 @@ void __cxa_thread_finalize(void) { _pthread_unwind(tib); if (tib->tib_nsync) _weaken(nsync_waiter_destroy)(tib->tib_nsync); - __cxa_thread_unkey(tib); + _pthread_unkey(tib); _pthread_ungarbage(tib); - while ((dtor = __cxa_thread_atexit_list)) { - __cxa_thread_atexit_list = dtor->next; + while ((dtor = tib->tib_atexit)) { + STRACE("__cxa_finalize(%t, %p)", dtor->fun, dtor->arg); + tib->tib_atexit = dtor->next; ((void (*)(void *))dtor->fun)(dtor->arg); _weaken(free)(dtor); } @@ -97,9 +96,11 @@ int __cxa_thread_atexit_impl(void *fun, void *arg, void *dso_symbol) { return -1; if (!(dtor = _weaken(malloc)(sizeof(struct Dtor)))) return -1; + struct CosmoTib *tib; + tib = __get_tls(); dtor->fun = fun; dtor->arg = arg; - dtor->next = __cxa_thread_atexit_list; - __cxa_thread_atexit_list = dtor; + dtor->next = tib->tib_atexit; + tib->tib_atexit = dtor; return 0; } diff --git a/libc/thread/pthread_cancel.c b/libc/thread/pthread_cancel.c index bc9dfd79e..14b0ce8b8 100644 --- a/libc/thread/pthread_cancel.c +++ b/libc/thread/pthread_cancel.c @@ -54,9 +54,8 @@ long _pthread_cancel_ack(void) { pthread_exit(PTHREAD_CANCELED); } pt->pt_flags |= PT_NOCANCEL; - if (IsOpenbsd()) { + if (IsOpenbsd()) pt->pt_flags |= PT_OPENBSD_KLUDGE; - } return ecanceled(); } @@ -351,6 +350,7 @@ static errno_t _pthread_cancel_everyone(void) { * @param thread may be 0 to cancel all threads except self * @return 0 on success, or errno on error * @raise ESRCH if system thread wasn't alive or we lost a race + * @cancelationpoint */ errno_t pthread_cancel(pthread_t thread) { struct PosixThread *arg; @@ -401,6 +401,7 @@ void pthread_testcancel(void) { * * @return 0 if not cancelled or cancelation is blocked or `ECANCELED` * in masked mode when the calling thread has been cancelled + * @cancelationpoint */ errno_t pthread_testcancel_np(void) { struct PosixThread *pt; diff --git a/libc/thread/pthread_create.c b/libc/thread/pthread_create.c index 4312c114d..9e01f26f6 100644 --- a/libc/thread/pthread_create.c +++ b/libc/thread/pthread_create.c @@ -117,6 +117,7 @@ static int PosixThread(void *arg, int tid) { } // set long jump handler so pthread_exit can bring control back here if (!setjmp(pt->pt_exiter)) { + sigdelset(&pt->pt_attr.__sigmask, SIGTHR); if (IsWindows()) { atomic_store_explicit(&__get_tls()->tib_sigmask, pt->pt_attr.__sigmask, memory_order_release); diff --git a/libc/thread/pthread_key_create.c b/libc/thread/pthread_key_create.c index 1f04da7a8..bc749a2be 100644 --- a/libc/thread/pthread_key_create.c +++ b/libc/thread/pthread_key_create.c @@ -48,9 +48,9 @@ int pthread_key_create(pthread_key_t *key, pthread_key_dtor dtor) { if (!dtor) dtor = (pthread_key_dtor)-1; for (i = 0; i < PTHREAD_KEYS_MAX; ++i) { - if (!(expect = atomic_load_explicit(_pthread_key_dtor + i, - memory_order_acquire)) && - atomic_compare_exchange_strong_explicit(_pthread_key_dtor + i, &expect, + if (!(expect = atomic_load_explicit(&_pthread_key_dtor[i], + memory_order_relaxed)) && + atomic_compare_exchange_strong_explicit(&_pthread_key_dtor[i], &expect, dtor, memory_order_release, memory_order_relaxed)) { *key = i; diff --git a/libc/thread/pthread_key_delete.c b/libc/thread/pthread_key_delete.c index a22239d13..b0b649c84 100644 --- a/libc/thread/pthread_key_delete.c +++ b/libc/thread/pthread_key_delete.c @@ -16,7 +16,6 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/assert.h" #include "libc/errno.h" #include "libc/intrin/atomic.h" #include "libc/thread/posixthread.internal.h" @@ -32,10 +31,12 @@ * * @param key was created by pthread_key_create() * @return 0 on success, or errno on error + * @raise EINVAL if `key` is invalid */ int pthread_key_delete(pthread_key_t k) { - unassert(0 <= k && k < PTHREAD_KEYS_MAX); - unassert(atomic_load_explicit(_pthread_key_dtor + k, memory_order_acquire)); - atomic_store_explicit(_pthread_key_dtor + k, 0, memory_order_release); + if (!(0 <= k && k < PTHREAD_KEYS_MAX)) + return EINVAL; // corrupt key identifier + if (!atomic_exchange_explicit(&_pthread_key_dtor[k], 0, memory_order_acq_rel)) + return EINVAL; // delete called twice return 0; } diff --git a/libc/thread/thread.h b/libc/thread/thread.h index a0eaf0167..7fd38f42c 100644 --- a/libc/thread/thread.h +++ b/libc/thread/thread.h @@ -1,7 +1,7 @@ #ifndef COSMOPOLITAN_LIBC_THREAD_THREAD_H_ #define COSMOPOLITAN_LIBC_THREAD_THREAD_H_ -#define PTHREAD_KEYS_MAX 48 +#define PTHREAD_KEYS_MAX 46 #define PTHREAD_STACK_MIN 65536 #define PTHREAD_DESTRUCTOR_ITERATIONS 4 diff --git a/libc/thread/tls.h b/libc/thread/tls.h index 788013afb..8880e1e8a 100644 --- a/libc/thread/tls.h +++ b/libc/thread/tls.h @@ -39,7 +39,8 @@ struct CosmoTib { uint32_t tib_sigstack_flags; _Atomic(int) tib_relock_maps; void *tib_nsync; - void *tib_keys[47]; + void *tib_atexit; + _Atomic(void *) tib_keys[46]; } __attribute__((__aligned__(64))); extern int __threaded; diff --git a/test/ctl/all_of_test.cc b/test/ctl/all_of_test.cc index 4bc090b67..bf8aa4bcd 100644 --- a/test/ctl/all_of_test.cc +++ b/test/ctl/all_of_test.cc @@ -20,9 +20,9 @@ #include "ctl/array.h" #include "libc/mem/leaks.h" -#include -#include -#define ctl std +// #include +// #include +// #define ctl std int main() diff --git a/libc/intrin/describeprctloperation.c b/test/libc/thread/pthread_getunique_np_test.c similarity index 75% rename from libc/intrin/describeprctloperation.c rename to test/libc/thread/pthread_getunique_np_test.c index fc0d3c085..f41c78975 100644 --- a/libc/intrin/describeprctloperation.c +++ b/test/libc/thread/pthread_getunique_np_test.c @@ -1,7 +1,7 @@ /*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-β”‚ β”‚ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi β”‚ β•žβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•‘ -β”‚ Copyright 2022 Justine Alexandra Roberts Tunney β”‚ +β”‚ Copyright 2024 Justine Alexandra Roberts Tunney β”‚ β”‚ β”‚ β”‚ Permission to use, copy, modify, and/or distribute this software for β”‚ β”‚ any purpose with or without fee is hereby granted, provided that the β”‚ @@ -16,24 +16,19 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" -#include "libc/sysv/consts/pr.h" +#include "libc/calls/calls.h" +#include "libc/testlib/testlib.h" +#include "libc/thread/thread.h" -const char *DescribePrctlOperation(int x) { - switch (x) { - case PR_GET_NAME: - return "PR_GET_NAME"; - case PR_SET_NO_NEW_PRIVS: - return "PR_SET_NO_NEW_PRIVS"; - case PR_SET_SECCOMP: - return "PR_SET_SECCOMP"; - case PR_GET_SECCOMP: - return "PR_GET_SECCOMP"; - case PR_CAPBSET_READ: - return "PR_CAPBSET_READ"; - case PR_CAPBSET_DROP: - return "PR_CAPBSET_DROP"; - default: - return "PRCTL_???"; - } +void *wut(void *arg) { + pthread_id_np_t tid; + pthread_getunique_np(pthread_self(), &tid); + ASSERT_EQ(gettid(), tid); + return 0; +} + +TEST(pthread_getunique_np, test) { + pthread_t id; + ASSERT_EQ(0, pthread_create(&id, 0, wut, (void *)1)); + ASSERT_EQ(0, pthread_join(id, 0)); } From e437bed00671579c0abf5a44710a37105b51d4a3 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sun, 30 Jun 2024 20:53:43 -0700 Subject: [PATCH 014/405] Fix crash caused when Windows needs a lot of TLS --- libc/runtime/enable_tls.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libc/runtime/enable_tls.c b/libc/runtime/enable_tls.c index ccc662568..3b3c098ff 100644 --- a/libc/runtime/enable_tls.c +++ b/libc/runtime/enable_tls.c @@ -24,6 +24,7 @@ #include "libc/intrin/dll.h" #include "libc/intrin/getenv.internal.h" #include "libc/intrin/kprintf.h" +#include "libc/intrin/maps.h" #include "libc/intrin/weaken.h" #include "libc/macros.internal.h" #include "libc/nt/files.h" @@ -37,6 +38,8 @@ #include "libc/stdalign.internal.h" #include "libc/str/locale.h" #include "libc/str/str.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/prot.h" #include "libc/thread/posixthread.internal.h" #include "libc/thread/thread.h" #include "libc/thread/tls.h" @@ -168,7 +171,8 @@ textstartup void __enable_tls(void) { if (I(_tls_align) <= TLS_ALIGNMENT && size <= sizeof(__static_tls)) { mem = __static_tls; } else { - mem = _weaken(_mapanon)(size); + mem = __mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, + -1, 0); } struct CosmoTib *tib = From 44191b3f50a7c30f00c3ec982f78c09bdce2ae76 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sun, 30 Jun 2024 20:59:38 -0700 Subject: [PATCH 015/405] Add more type traits to CTL --- ctl/integral_constant.h | 2 + ctl/is_abstract.h | 18 +++++++ ctl/is_base_of.h | 18 +++++++ ctl/is_class.h | 18 +++++++ ctl/is_constructible.h | 19 +++++++ ctl/is_empty.h | 18 +++++++ ctl/is_enum.h | 18 +++++++ ctl/is_polymorphic.h | 18 +++++++ ctl/is_standard_layout.h | 19 +++++++ ctl/is_trivial.h | 18 +++++++ ctl/is_union.h | 18 +++++++ test/ctl/is_base_of_test.cc | 102 ++++++++++++++++++++++++++++++++++++ 12 files changed, 286 insertions(+) create mode 100644 ctl/is_abstract.h create mode 100644 ctl/is_base_of.h create mode 100644 ctl/is_class.h create mode 100644 ctl/is_constructible.h create mode 100644 ctl/is_empty.h create mode 100644 ctl/is_enum.h create mode 100644 ctl/is_polymorphic.h create mode 100644 ctl/is_standard_layout.h create mode 100644 ctl/is_trivial.h create mode 100644 ctl/is_union.h create mode 100644 test/ctl/is_base_of_test.cc diff --git a/ctl/integral_constant.h b/ctl/integral_constant.h index df5a0a688..047b27354 100644 --- a/ctl/integral_constant.h +++ b/ctl/integral_constant.h @@ -11,10 +11,12 @@ struct integral_constant static constexpr T value = v; typedef T value_type; typedef integral_constant type; + constexpr operator value_type() const noexcept { return value; } + constexpr value_type operator()() const noexcept { return value; diff --git a/ctl/is_abstract.h b/ctl/is_abstract.h new file mode 100644 index 000000000..ccd26c123 --- /dev/null +++ b/ctl/is_abstract.h @@ -0,0 +1,18 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_IS_ABSTRACT_H_ +#define CTL_IS_ABSTRACT_H_ +#include "integral_constant.h" + +namespace ctl { + +template +struct is_abstract : public integral_constant +{}; + +template +inline constexpr bool is_abstract_v = __is_abstract(T); + +} // namespace ctl + +#endif // CTL_IS_ABSTRACT_H_ diff --git a/ctl/is_base_of.h b/ctl/is_base_of.h new file mode 100644 index 000000000..a37456f26 --- /dev/null +++ b/ctl/is_base_of.h @@ -0,0 +1,18 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_IS_BASE_OF_H_ +#define CTL_IS_BASE_OF_H_ +#include "integral_constant.h" + +namespace ctl { + +template +struct is_base_of : public integral_constant +{}; + +template +inline constexpr bool is_base_of_v = __is_base_of(Base, Derived); + +} // namespace ctl + +#endif // CTL_IS_BASE_OF_H_ diff --git a/ctl/is_class.h b/ctl/is_class.h new file mode 100644 index 000000000..3c958bd17 --- /dev/null +++ b/ctl/is_class.h @@ -0,0 +1,18 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_IS_CLASS_H_ +#define CTL_IS_CLASS_H_ +#include "integral_constant.h" + +namespace ctl { + +template +struct is_class : public integral_constant +{}; + +template +inline constexpr bool is_class_v = __is_class(T); + +} // namespace ctl + +#endif // CTL_IS_CLASS_H_ diff --git a/ctl/is_constructible.h b/ctl/is_constructible.h new file mode 100644 index 000000000..4d202bdc5 --- /dev/null +++ b/ctl/is_constructible.h @@ -0,0 +1,19 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_IS_CONSTRUCTIBLE_H_ +#define CTL_IS_CONSTRUCTIBLE_H_ +#include "integral_constant.h" + +namespace ctl { + +template +struct is_constructible + : public integral_constant +{}; + +template +inline constexpr bool is_constructible_v = __is_constructible(_Tp, _Args...); + +} // namespace ctl + +#endif // CTL_IS_CONSTRUCTIBLE_H_ diff --git a/ctl/is_empty.h b/ctl/is_empty.h new file mode 100644 index 000000000..a1cf31675 --- /dev/null +++ b/ctl/is_empty.h @@ -0,0 +1,18 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_IS_EMPTY_H_ +#define CTL_IS_EMPTY_H_ +#include "integral_constant.h" + +namespace ctl { + +template +struct is_empty : public integral_constant +{}; + +template +inline constexpr bool is_empty_v = __is_empty(T); + +} // namespace ctl + +#endif // CTL_IS_EMPTY_H_ diff --git a/ctl/is_enum.h b/ctl/is_enum.h new file mode 100644 index 000000000..7d2cd5b78 --- /dev/null +++ b/ctl/is_enum.h @@ -0,0 +1,18 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_IS_ENUM_H_ +#define CTL_IS_ENUM_H_ +#include "integral_constant.h" + +namespace ctl { + +template +struct is_enum : public integral_constant +{}; + +template +inline constexpr bool is_enum_v = __is_enum(T); + +} // namespace ctl + +#endif // CTL_IS_ENUM_H_ diff --git a/ctl/is_polymorphic.h b/ctl/is_polymorphic.h new file mode 100644 index 000000000..152b7af0b --- /dev/null +++ b/ctl/is_polymorphic.h @@ -0,0 +1,18 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_IS_POLYMORPHIC_H_ +#define CTL_IS_POLYMORPHIC_H_ +#include "integral_constant.h" + +namespace ctl { + +template +struct is_polymorphic : public integral_constant +{}; + +template +inline constexpr bool is_polymorphic_v = __is_polymorphic(T); + +} // namespace ctl + +#endif // CTL_IS_POLYMORPHIC_H_ diff --git a/ctl/is_standard_layout.h b/ctl/is_standard_layout.h new file mode 100644 index 000000000..59ae380c8 --- /dev/null +++ b/ctl/is_standard_layout.h @@ -0,0 +1,19 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_IS_STANDARD_LAYOUT_H_ +#define CTL_IS_STANDARD_LAYOUT_H_ +#include "integral_constant.h" + +namespace ctl { + +template +struct is_standard_layout + : public integral_constant +{}; + +template +inline constexpr bool is_standard_layout_v = __is_standard_layout(T); + +} // namespace ctl + +#endif // CTL_IS_STANDARD_LAYOUT_H_ diff --git a/ctl/is_trivial.h b/ctl/is_trivial.h new file mode 100644 index 000000000..c69c18f08 --- /dev/null +++ b/ctl/is_trivial.h @@ -0,0 +1,18 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_IS_TRIVIAL_H_ +#define CTL_IS_TRIVIAL_H_ +#include "integral_constant.h" + +namespace ctl { + +template +struct is_trivial : public integral_constant +{}; + +template +inline constexpr bool is_trivial_v = __is_trivial(T); + +} // namespace ctl + +#endif // CTL_IS_TRIVIAL_H_ diff --git a/ctl/is_union.h b/ctl/is_union.h new file mode 100644 index 000000000..773c52e3b --- /dev/null +++ b/ctl/is_union.h @@ -0,0 +1,18 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_IS_UNION_H_ +#define CTL_IS_UNION_H_ +#include "integral_constant.h" + +namespace ctl { + +template +struct is_union : public integral_constant +{}; + +template +inline constexpr bool is_union_v = __is_union(T); + +} // namespace ctl + +#endif // CTL_IS_UNION_H_ diff --git a/test/ctl/is_base_of_test.cc b/test/ctl/is_base_of_test.cc new file mode 100644 index 000000000..8e64a75af --- /dev/null +++ b/test/ctl/is_base_of_test.cc @@ -0,0 +1,102 @@ +// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +// +// Copyright 2024 Justine Alexandra Roberts Tunney +// +// Permission to use, copy, modify, and/or distribute this software for +// any purpose with or without fee is hereby granted, provided that the +// above copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include "ctl/is_base_of.h" + +// #include +// #define ctl std + +// Test classes +class A +{}; +class B : public A +{}; +class C : public B +{}; +class D +{}; + +struct Empty +{}; + +template +class TemplateClass +{}; + +class VirtualBase +{}; +class VirtualDerived : virtual public VirtualBase +{}; + +int +main() +{ + // Test basic inheritance + if (!ctl::is_base_of_v) + return 1; + if (!ctl::is_base_of_v) + return 2; + if (ctl::is_base_of_v) + return 3; + if (ctl::is_base_of_v) + return 4; + if (ctl::is_base_of_v) + return 5; + + // Test with same type + if (!ctl::is_base_of_v) + return 6; + if (!ctl::is_base_of_v) + return 7; + + // Test with void + if (ctl::is_base_of_v) + return 8; + if (ctl::is_base_of_v) + return 9; + if (ctl::is_base_of_v) + return 10; + + // Test with fundamental types + if (ctl::is_base_of_v) + return 11; + if (ctl::is_base_of_v) + return 12; + if (ctl::is_base_of_v) + return 13; + + // Test with empty class + if (ctl::is_base_of_v) + return 14; + if (ctl::is_base_of_v) + return 15; + + // Test with template class + if (ctl::is_base_of_v, A>) + return 16; + if (ctl::is_base_of_v>) + return 17; + + // Test with virtual inheritance + if (!ctl::is_base_of_v) + return 18; + if (ctl::is_base_of_v) + return 19; + + return 0; // All tests passed +} From 78d3b86ec74012e0a2b5e2d2778077b0ab44e4f8 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Mon, 1 Jul 2024 01:06:47 -0700 Subject: [PATCH 016/405] Fix Android support Thanks to @aj47 (techfren.net) the new Cosmo memory manager is confirmed to be working on Android!! The only issue turned out to be forgetting to update the program address in the linker script. We now know w/ absolute certainty that APE binaries as complex as llamafile, now work correctly. --- ape/aarch64.lds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ape/aarch64.lds b/ape/aarch64.lds index c63ce4295..356ff3ae7 100644 --- a/ape/aarch64.lds +++ b/ape/aarch64.lds @@ -12,7 +12,7 @@ OUTPUT_FORMAT("elf64-littleaarch64", SECTIONS { - . = SEGMENT_START("text-segment", 0x010000000000); + . = SEGMENT_START("text-segment", 0x000800000000); __executable_start = .; . += SIZEOF_HEADERS; From ca4cf67eb859947c2ee5217b36a29869133b8a7a Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Mon, 1 Jul 2024 01:32:25 -0700 Subject: [PATCH 017/405] Include more programs in cosmocc The Cosmopolitan Compiler Collection now includes the following programs - `ar.ape` is a faster alternative to `ar rcsD` for creating determistic static archives. It's ~10x faster than GNU because it isn't quadratic. It'll even outperform LLVM ar by 2x, thanks to writev/copy_file_range. - `sha256sum.ape` is a faster alternative to the `sha256sum` command. It goes 2x faster since it leverages vectorized assembly implementations. - `resymbol` is a brand new program we invented, like objcopy, that lets you rename all the global symbols in a .o file to have a new suffix or prefix. In the future, this will be used by cosmocc automatically when building -O3 math kernels, that need to be vectorized for all hardware - `gzip.ape` is a faster version of the `gzip` command, that is included by most Linux distros. It gains better performance using Chromium Zlib which, once again, includes highly optimized assembly, that Mark Adler won't merge into the official MS-DOS compatible zlib codebase. - `cocmd` is the cosmopolitan shell. It can function as a faster `sh -c` alternative than bash and dash as the `SHELL = /opt/cosmocc/bin/cocmd` at the top of your Makefile. Please note you should be using the cosmo fork of GNU make (already included), since normal make won't recognize this as a bourne-compatible shell and remove the execve() optimization which makes things slower. In some ways that's true. This doesn't have a complete POSIX shell implementation. However it's enough for cosmo's mono repo. It also implements faster behaviors in some respects. The following programs are also introduced, which aren't as interesting. The main reason why they're here is so Cosmopolitan's mono repo shall be able to remove build/bootstrap/ in future editions. That way we can keep build utilities better up to date, without bloating the git history much - `chmod.ape` for hermeticity - `cp.ape` for hermeticity - `echo.ape` for hermeticity - `objbincopy` is an objcopy-like tool that's used to build ape loader - `package.ape` is used for strict dependency checking of object graph - `rm.ape` for hermeticity - `touch.ape` for hermeticity --- build/bootstrap/rollup | Bin 246415 -> 0 bytes third_party/make/job.c | 1 + tool/build/rollup.c | 177 ---------------------------------------- tool/cosmocc/package.sh | 35 +++++++- 4 files changed, 35 insertions(+), 178 deletions(-) delete mode 100755 build/bootstrap/rollup delete mode 100644 tool/build/rollup.c diff --git a/build/bootstrap/rollup b/build/bootstrap/rollup deleted file mode 100755 index 47d2d505c54631b15df6a83c321e64989d296b2c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 246415 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 n && memcmp(p, s, n) == 0; -} - -void Process(const char *p, const char *pe, const char *path, bool isheader) { - int level; - bool noformat; - const char *p2, *dq, *name; - for (noformat = false, level = 0; p < pe; p = p2) { - p2 = memchr(p, '\n', pe - p); - p2 = p2 ? p2 + 1 : pe; - if (LOOKINGAT(p, pe, "#if")) { - if (isheader && !level++) - continue; - } - if (LOOKINGAT(p, pe, "#endif")) { - if (isheader && !--level) - continue; - } - if (LOOKINGAT(p, pe, "/* clang-format off */")) { - noformat = true; - } else if (LOOKINGAT(p, pe, "/* clang-format on */")) { - noformat = false; - } - if (LOOKINGAT(p, pe, "#include \"")) { - name = p + strlen("#include \""); - dq = memchr(name, '"', pe - name); - if (dq) { - Visit(strndup(name, dq - name)); - continue; - } - } - Appendd(&output, p, p2 - p); - } - if (noformat) { - Appends(&output, "/* clang-format on */\n"); - } -} - -void Visit(const char *path) { - int fd; - char *map; - size_t size; - bool isheader; - if (!endswith(path, ".h") && !endswith(path, ".inc")) - return; - if (endswith(path, ".internal.h")) - return; - if (endswith(path, "/internal.h")) - return; - if (endswith(path, ".internal.inc")) - return; - if (endswith(path, "/internal.inc")) - return; - if (startswith(path, "libc/isystem/")) - return; - isheader = endswith(path, ".h"); - if (isheader && isinterned(visited, path)) - return; - Appends(&output, "\n\f\n/*!BEGIN "); - Appends(&output, path); - Appends(&output, " */\n\n"); - intern(visited, path); - if ((fd = open(path, O_RDONLY)) == -1) - DieSys(path); - if ((size = GetFdSize(fd))) { - map = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0); - if (map == MAP_FAILED) - DieSys(path); - Process(map, map + size, path, isheader); - if (munmap(map, size)) - DieSys(path); - } - if (close(fd)) - DieSys(path); -} - -int main(int argc, char *argv[]) { - size_t bytes; - const char *src; - struct GetArgs ga; - prog = argv[0]; - if (!prog) - prog = "rollup"; - visited = newinterner(); - Appends(&output, "#ifndef COSMOPOLITAN_H_\n"); - Appends(&output, "#define COSMOPOLITAN_H_\n"); - getargs_init(&ga, argv + 1); - while ((src = getargs_next(&ga))) { - Visit(src); - } - getargs_destroy(&ga); - Appends(&output, "\n"); - Appends(&output, "#endif /* COSMOPOLITAN_H_ */\n"); - bytes = appendz(output).i; - if (write(1, output, bytes) != bytes) { - DieSys(prog); - } - freeinterner(visited); - return 0; -} diff --git a/tool/cosmocc/package.sh b/tool/cosmocc/package.sh index 70e76328c..0ad1fc091 100755 --- a/tool/cosmocc/package.sh +++ b/tool/cosmocc/package.sh @@ -44,6 +44,19 @@ make -j64 m=$AMD64 \ o/$AMD64/tool/build/zipobj.dbg \ o/$AMD64/tool/build/apelink.dbg \ o/$AMD64/tool/build/pecheck.dbg \ + o/$AMD64/tool/build/ar.dbg \ + o/$AMD64/tool/build/chmod.dbg \ + o/$AMD64/tool/build/cocmd.dbg \ + o/$AMD64/tool/build/compile.dbg \ + o/$AMD64/tool/build/cp.dbg \ + o/$AMD64/tool/build/echo.dbg \ + o/$AMD64/tool/build/gzip.dbg \ + o/$AMD64/tool/build/objbincopy.dbg \ + o/$AMD64/tool/build/package.dbg \ + o/$AMD64/tool/build/rm.dbg \ + o/$AMD64/tool/build/touch.dbg \ + o/$AMD64/tool/build/sha256sum.dbg \ + o/$AMD64/tool/build/resymbol.dbg \ o/$AMD64/third_party/make/make.dbg \ o/$AMD64/third_party/ctags/ctags.dbg @@ -64,6 +77,19 @@ make -j64 m=$ARM64 \ o/$ARM64/tool/build/zipobj.dbg \ o/$ARM64/tool/build/apelink.dbg \ o/$ARM64/tool/build/pecheck.dbg \ + o/$ARM64/tool/build/ar.dbg \ + o/$ARM64/tool/build/chmod.dbg \ + o/$ARM64/tool/build/cocmd.dbg \ + o/$ARM64/tool/build/compile.dbg \ + o/$ARM64/tool/build/cp.dbg \ + o/$ARM64/tool/build/echo.dbg \ + o/$ARM64/tool/build/gzip.dbg \ + o/$ARM64/tool/build/objbincopy.dbg \ + o/$ARM64/tool/build/package.dbg \ + o/$ARM64/tool/build/rm.dbg \ + o/$ARM64/tool/build/touch.dbg \ + o/$ARM64/tool/build/sha256sum.dbg \ + o/$ARM64/tool/build/resymbol.dbg \ o/$ARM64/third_party/make/make.dbg \ o/$ARM64/third_party/ctags/ctags.dbg @@ -146,7 +172,9 @@ cp -af tool/cosmocc/bin/* "$OUTDIR/bin/" cp -f o/$AMD64/ape/ape.elf "$OUTDIR/bin/ape-x86_64.elf" cp -f o/$AMD64/ape/ape.macho "$OUTDIR/bin/ape-x86_64.macho" cp -f o/$ARM64/ape/ape.elf "$OUTDIR/bin/ape-aarch64.elf" -for x in assimilate march-native mktemper fixupobj zipcopy apelink pecheck mkdeps zipobj; do + +for x in assimilate march-native mktemper fixupobj zipcopy apelink pecheck mkdeps zipobj \ + ar chmod cocmd cp echo gzip objbincopy package rm touch sha256sum resymbol; do ape $APELINK \ -l o/$AMD64/ape/ape.elf \ -l o/$ARM64/ape/ape.elf \ @@ -155,6 +183,11 @@ for x in assimilate march-native mktemper fixupobj zipcopy apelink pecheck mkdep o/$AMD64/tool/build/$x.dbg \ o/$ARM64/tool/build/$x.dbg done + +for x in ar chmod cp echo gzip package rm touch sha256sum; do + mv "$OUTDIR/bin/$x" "$OUTDIR/bin/$x.ape" +done + for x in make ctags; do ape $APELINK \ -l o/$AMD64/ape/ape.elf \ From 239f8ce76e64820b64f0533028d87319266c4270 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Mon, 1 Jul 2024 01:17:24 -0700 Subject: [PATCH 018/405] Release Cosmopolitan v3.5.3 --- libc/integral/normalize.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libc/integral/normalize.inc b/libc/integral/normalize.inc index 9fcbc05fc..7d24c2763 100644 --- a/libc/integral/normalize.inc +++ b/libc/integral/normalize.inc @@ -4,7 +4,7 @@ #define __COSMOPOLITAN_MAJOR__ 3 #define __COSMOPOLITAN_MINOR__ 5 -#define __COSMOPOLITAN_PATCH__ 2 +#define __COSMOPOLITAN_PATCH__ 3 #define __COSMOPOLITAN__ \ (100000000 * __COSMOPOLITAN_MAJOR__ + 1000000 * __COSMOPOLITAN_MINOR__ + \ __COSMOPOLITAN_PATCH__) From acbabedf2753422821c4dddb204b8026173ece1e Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Mon, 1 Jul 2024 03:48:28 -0700 Subject: [PATCH 019/405] Make CTL definitions less ambiguous --- ctl/allocator_traits.h | 27 ++++++++-------------- ctl/bad_alloc.h | 2 +- ctl/decay.h | 15 ++++++------ ctl/distance.h | 12 ++++++---- ctl/is_abstract.h | 2 +- ctl/is_array.h | 6 ++--- ctl/is_base_of.h | 3 ++- ctl/is_class.h | 2 +- ctl/is_constructible.h | 2 +- ctl/is_convertible.h | 8 +++---- ctl/is_empty.h | 2 +- ctl/is_enum.h | 2 +- ctl/is_function.h | 50 ++++++++++++++++++++-------------------- ctl/is_integral.h | 32 ++++++++++++------------- ctl/is_polymorphic.h | 2 +- ctl/is_standard_layout.h | 2 +- ctl/is_trivial.h | 2 +- ctl/is_union.h | 2 +- ctl/istream.h | 2 +- ctl/istringstream.cc | 8 +++---- ctl/istringstream.h | 6 ++--- ctl/map.h | 24 +++++++++---------- ctl/mutex.h | 12 ++++++---- ctl/ostream.h | 2 +- ctl/ostringstream.cc | 20 ++++++++-------- ctl/ostringstream.h | 10 ++++---- ctl/out_of_range.h | 2 +- ctl/reverse_iterator.h | 11 +++++---- ctl/set.h | 29 ++++++++++++----------- ctl/string.h | 50 ++++++++++++++++++++-------------------- 30 files changed, 176 insertions(+), 173 deletions(-) diff --git a/ctl/allocator_traits.h b/ctl/allocator_traits.h index ebdf03424..4873899f4 100644 --- a/ctl/allocator_traits.h +++ b/ctl/allocator_traits.h @@ -18,10 +18,10 @@ struct allocator_traits using difference_type = typename Alloc::difference_type; using size_type = typename Alloc::size_type; - using propagate_on_container_copy_assignment = false_type; - using propagate_on_container_move_assignment = true_type; - using propagate_on_container_swap = false_type; - using is_always_equal = true_type; + using propagate_on_container_copy_assignment = ctl::false_type; + using propagate_on_container_move_assignment = ctl::true_type; + using propagate_on_container_swap = ctl::false_type; + using is_always_equal = ctl::true_type; template using rebind_alloc = typename Alloc::template rebind::other; @@ -29,41 +29,34 @@ struct allocator_traits template using rebind_traits = allocator_traits>; - __attribute__((__always_inline__)) static pointer allocate(Alloc& a, - size_type n) + static pointer allocate(Alloc& a, size_type n) { return a.allocate(n); } - __attribute__((__always_inline__)) static void deallocate(Alloc& a, - pointer p, - size_type n) + static void deallocate(Alloc& a, pointer p, size_type n) { a.deallocate(p, n); } template - __attribute__((__always_inline__)) static void construct(Alloc& a, - T* p, - Args&&... args) + static void construct(Alloc& a, T* p, Args&&... args) { ::new ((void*)p) T(static_cast(args)...); } template - __attribute__((__always_inline__)) static void destroy(Alloc& a, T* p) + static void destroy(Alloc& a, T* p) { p->~T(); } - __attribute__((__always_inline__)) static size_type max_size( - const Alloc& a) noexcept + static size_type max_size(const Alloc& a) noexcept { return __PTRDIFF_MAX__ / sizeof(value_type); } - __attribute__((__always_inline__)) static Alloc - select_on_container_copy_construction(const Alloc& a) + static Alloc select_on_container_copy_construction(const Alloc& a) { return a; } diff --git a/ctl/bad_alloc.h b/ctl/bad_alloc.h index 2f92578fe..99bcda0be 100644 --- a/ctl/bad_alloc.h +++ b/ctl/bad_alloc.h @@ -6,7 +6,7 @@ namespace ctl { -class bad_alloc : public exception +class bad_alloc : public ctl::exception { public: bad_alloc() noexcept = default; diff --git a/ctl/decay.h b/ctl/decay.h index 6c4fe6f2a..3944eeba0 100644 --- a/ctl/decay.h +++ b/ctl/decay.h @@ -16,15 +16,16 @@ template struct decay { private: - typedef typename remove_reference::type U; + typedef typename ctl::remove_reference::type U; public: - typedef typename conditional< - is_array::value, - typename remove_extent::type*, - typename conditional::value, - typename add_pointer::type, - typename remove_cv::type>::type>::type type; + typedef typename ctl::conditional< + ctl::is_array::value, + typename ctl::remove_extent::type*, + typename ctl::conditional::value, + typename ctl::add_pointer::type, + typename ctl::remove_cv::type>::type>::type + type; }; template diff --git a/ctl/distance.h b/ctl/distance.h index 83bac2a77..ab06867d9 100644 --- a/ctl/distance.h +++ b/ctl/distance.h @@ -8,28 +8,30 @@ namespace ctl { template -constexpr typename iterator_traits::difference_type +constexpr typename ctl::iterator_traits::difference_type distance_impl(InputIter first, InputIter last, input_iterator_tag) { - typename iterator_traits::difference_type res(0); + typename ctl::iterator_traits::difference_type res(0); for (; first != last; ++first) ++res; return res; } template -constexpr typename iterator_traits::difference_type +constexpr typename ctl::iterator_traits::difference_type distance_impl(RandIter first, RandIter last, random_access_iterator_tag) { return last - first; } template -constexpr typename iterator_traits::difference_type +constexpr typename ctl::iterator_traits::difference_type distance(InputIter first, InputIter last) { return distance_impl( - first, last, typename iterator_traits::iterator_category()); + first, + last, + typename ctl::iterator_traits::iterator_category()); } } // namespace ctl diff --git a/ctl/is_abstract.h b/ctl/is_abstract.h index ccd26c123..95360a5f4 100644 --- a/ctl/is_abstract.h +++ b/ctl/is_abstract.h @@ -7,7 +7,7 @@ namespace ctl { template -struct is_abstract : public integral_constant +struct is_abstract : public ctl::integral_constant {}; template diff --git a/ctl/is_array.h b/ctl/is_array.h index 946d152ea..4888b87a7 100644 --- a/ctl/is_array.h +++ b/ctl/is_array.h @@ -7,15 +7,15 @@ namespace ctl { template -struct is_array : false_type +struct is_array : ctl::false_type {}; template -struct is_array : true_type +struct is_array : ctl::true_type {}; template -struct is_array : true_type +struct is_array : ctl::true_type {}; template diff --git a/ctl/is_base_of.h b/ctl/is_base_of.h index a37456f26..82c9961c1 100644 --- a/ctl/is_base_of.h +++ b/ctl/is_base_of.h @@ -7,7 +7,8 @@ namespace ctl { template -struct is_base_of : public integral_constant +struct is_base_of + : public ctl::integral_constant {}; template diff --git a/ctl/is_class.h b/ctl/is_class.h index 3c958bd17..f5f78958e 100644 --- a/ctl/is_class.h +++ b/ctl/is_class.h @@ -7,7 +7,7 @@ namespace ctl { template -struct is_class : public integral_constant +struct is_class : public ctl::integral_constant {}; template diff --git a/ctl/is_constructible.h b/ctl/is_constructible.h index 4d202bdc5..0f3c3fce8 100644 --- a/ctl/is_constructible.h +++ b/ctl/is_constructible.h @@ -8,7 +8,7 @@ namespace ctl { template struct is_constructible - : public integral_constant + : public ctl::integral_constant {}; template diff --git a/ctl/is_convertible.h b/ctl/is_convertible.h index 69a105ad3..b485f5769 100644 --- a/ctl/is_convertible.h +++ b/ctl/is_convertible.h @@ -15,7 +15,7 @@ declval() noexcept; namespace detail { template -struct is_convertible_impl : false_type +struct is_convertible_impl : ctl::false_type {}; template @@ -27,15 +27,15 @@ struct is_convertible_impl -struct is_convertible_impl : true_type +struct is_convertible_impl : ctl::true_type {}; template -struct is_convertible_impl : false_type +struct is_convertible_impl : ctl::false_type {}; template -struct is_convertible_impl : false_type +struct is_convertible_impl : ctl::false_type {}; } // namespace detail diff --git a/ctl/is_empty.h b/ctl/is_empty.h index a1cf31675..095c069ea 100644 --- a/ctl/is_empty.h +++ b/ctl/is_empty.h @@ -7,7 +7,7 @@ namespace ctl { template -struct is_empty : public integral_constant +struct is_empty : public ctl::integral_constant {}; template diff --git a/ctl/is_enum.h b/ctl/is_enum.h index 7d2cd5b78..19adcd8c3 100644 --- a/ctl/is_enum.h +++ b/ctl/is_enum.h @@ -7,7 +7,7 @@ namespace ctl { template -struct is_enum : public integral_constant +struct is_enum : public ctl::integral_constant {}; template diff --git a/ctl/is_function.h b/ctl/is_function.h index 667a1e8eb..bee4f85f8 100644 --- a/ctl/is_function.h +++ b/ctl/is_function.h @@ -8,111 +8,111 @@ namespace ctl { // Primary template template -struct is_function : false_type +struct is_function : ctl::false_type {}; // Specializations for various function types // Regular functions template -struct is_function : true_type +struct is_function : ctl::true_type {}; // Functions with cv-qualifiers template -struct is_function : true_type +struct is_function : ctl::true_type {}; template -struct is_function : true_type +struct is_function : ctl::true_type {}; template -struct is_function : true_type +struct is_function : ctl::true_type {}; // Functions with ref-qualifiers template -struct is_function : true_type +struct is_function : ctl::true_type {}; template -struct is_function : true_type +struct is_function : ctl::true_type {}; template -struct is_function : true_type +struct is_function : ctl::true_type {}; template -struct is_function : true_type +struct is_function : ctl::true_type {}; template -struct is_function : true_type +struct is_function : ctl::true_type {}; template -struct is_function : true_type +struct is_function : ctl::true_type {}; template -struct is_function : true_type +struct is_function : ctl::true_type {}; template -struct is_function : true_type +struct is_function : ctl::true_type {}; // Variadic functions template -struct is_function : true_type +struct is_function : ctl::true_type {}; // Variadic functions with cv-qualifiers template -struct is_function : true_type +struct is_function : ctl::true_type {}; template -struct is_function : true_type +struct is_function : ctl::true_type {}; template -struct is_function : true_type +struct is_function : ctl::true_type {}; // Variadic functions with ref-qualifiers template -struct is_function : true_type +struct is_function : ctl::true_type {}; template -struct is_function : true_type +struct is_function : ctl::true_type {}; template -struct is_function : true_type +struct is_function : ctl::true_type {}; template -struct is_function : true_type +struct is_function : ctl::true_type {}; template -struct is_function : true_type +struct is_function : ctl::true_type {}; template -struct is_function : true_type +struct is_function : ctl::true_type {}; template -struct is_function : true_type +struct is_function : ctl::true_type {}; template -struct is_function : true_type +struct is_function : ctl::true_type {}; } // namespace ctl diff --git a/ctl/is_integral.h b/ctl/is_integral.h index 384985a38..a68344119 100644 --- a/ctl/is_integral.h +++ b/ctl/is_integral.h @@ -7,67 +7,67 @@ namespace ctl { template -struct is_integral : false_type +struct is_integral : ctl::false_type {}; template<> -struct is_integral : true_type +struct is_integral : ctl::true_type {}; template<> -struct is_integral : true_type +struct is_integral : ctl::true_type {}; template<> -struct is_integral : true_type +struct is_integral : ctl::true_type {}; template<> -struct is_integral : true_type +struct is_integral : ctl::true_type {}; template<> -struct is_integral : true_type +struct is_integral : ctl::true_type {}; template<> -struct is_integral : true_type +struct is_integral : ctl::true_type {}; template<> -struct is_integral : true_type +struct is_integral : ctl::true_type {}; template<> -struct is_integral : true_type +struct is_integral : ctl::true_type {}; template<> -struct is_integral : true_type +struct is_integral : ctl::true_type {}; template<> -struct is_integral : true_type +struct is_integral : ctl::true_type {}; template<> -struct is_integral : true_type +struct is_integral : ctl::true_type {}; template<> -struct is_integral : true_type +struct is_integral : ctl::true_type {}; template<> -struct is_integral : true_type +struct is_integral : ctl::true_type {}; template<> -struct is_integral : true_type +struct is_integral : ctl::true_type {}; template<> -struct is_integral : true_type +struct is_integral : ctl::true_type {}; template diff --git a/ctl/is_polymorphic.h b/ctl/is_polymorphic.h index 152b7af0b..499862d1d 100644 --- a/ctl/is_polymorphic.h +++ b/ctl/is_polymorphic.h @@ -7,7 +7,7 @@ namespace ctl { template -struct is_polymorphic : public integral_constant +struct is_polymorphic : public ctl::integral_constant {}; template diff --git a/ctl/is_standard_layout.h b/ctl/is_standard_layout.h index 59ae380c8..0eabab88f 100644 --- a/ctl/is_standard_layout.h +++ b/ctl/is_standard_layout.h @@ -8,7 +8,7 @@ namespace ctl { template struct is_standard_layout - : public integral_constant + : public ctl::integral_constant {}; template diff --git a/ctl/is_trivial.h b/ctl/is_trivial.h index c69c18f08..f2e996bcf 100644 --- a/ctl/is_trivial.h +++ b/ctl/is_trivial.h @@ -7,7 +7,7 @@ namespace ctl { template -struct is_trivial : public integral_constant +struct is_trivial : public ctl::integral_constant {}; template diff --git a/ctl/is_union.h b/ctl/is_union.h index 773c52e3b..ebae27125 100644 --- a/ctl/is_union.h +++ b/ctl/is_union.h @@ -7,7 +7,7 @@ namespace ctl { template -struct is_union : public integral_constant +struct is_union : public ctl::integral_constant {}; template diff --git a/ctl/istream.h b/ctl/istream.h index 2ec23284d..f80bc5bf0 100644 --- a/ctl/istream.h +++ b/ctl/istream.h @@ -20,7 +20,7 @@ class istream : public ios istream& operator>>(long&); istream& operator>>(double&); istream& operator>>(bool&); - istream& operator>>(string&); + istream& operator>>(ctl::string&); istream& operator>>(istream& (*)(istream&)); int get(); diff --git a/ctl/istringstream.cc b/ctl/istringstream.cc index 5674c620a..bfaed7a37 100644 --- a/ctl/istringstream.cc +++ b/ctl/istringstream.cc @@ -26,19 +26,19 @@ istringstream::istringstream() : buffer_(), read_pos_(0) { } -istringstream::istringstream(const string_view& str) +istringstream::istringstream(const ctl::string_view& str) : buffer_(str), read_pos_(0) { } -string +ctl::string istringstream::str() const { return buffer_; } void -istringstream::str(const string& s) +istringstream::str(const ctl::string& s) { buffer_ = s; read_pos_ = 0; @@ -82,7 +82,7 @@ istringstream::operator>>(char* s) } istringstream& -istringstream::operator>>(string& s) +istringstream::operator>>(ctl::string& s) { if (!good()) return *this; diff --git a/ctl/istringstream.h b/ctl/istringstream.h index b3c95e3d7..0ced67333 100644 --- a/ctl/istringstream.h +++ b/ctl/istringstream.h @@ -11,14 +11,14 @@ class istringstream : public ios_base { public: istringstream(); - explicit istringstream(const string_view&); + explicit istringstream(const ctl::string_view&); string str() const; void str(const string&); istringstream& operator>>(char&); istringstream& operator>>(char*); - istringstream& operator>>(string&); + istringstream& operator>>(ctl::string&); istringstream& operator>>(short&); istringstream& operator>>(unsigned short&); istringstream& operator>>(int&); @@ -29,7 +29,7 @@ class istringstream : public ios_base istringstream& operator>>(double&); private: - string buffer_; + ctl::string buffer_; size_t read_pos_; template diff --git a/ctl/map.h b/ctl/map.h index e3978545e..32c98d5e1 100644 --- a/ctl/map.h +++ b/ctl/map.h @@ -152,12 +152,12 @@ class map Value& operator[](const Key& key) { - return ((data_.insert(make_pair(key, Value()))).first)->second; + return ((data_.insert(ctl::make_pair(key, Value()))).first)->second; } Value& operator[](Key&& key) { - return ((data_.insert(make_pair(ctl::move(key), Value()))).first) + return ((data_.insert(ctl::make_pair(ctl::move(key), Value()))).first) ->second; } @@ -244,7 +244,7 @@ class map size_type erase(const Key& key) { - return data_.erase(make_pair(key, Value())); + return data_.erase(ctl::make_pair(key, Value())); } void swap(map& other) noexcept @@ -259,47 +259,47 @@ class map iterator find(const Key& key) { - return data_.find(make_pair(key, Value())); + return data_.find(ctl::make_pair(key, Value())); } const_iterator find(const Key& key) const { - return data_.find(make_pair(key, Value())); + return data_.find(ctl::make_pair(key, Value())); } size_type count(const Key& key) const { - return data_.count(make_pair(key, Value())); + return data_.count(ctl::make_pair(key, Value())); } iterator lower_bound(const Key& key) { - return data_.lower_bound(make_pair(key, Value())); + return data_.lower_bound(ctl::make_pair(key, Value())); } const_iterator lower_bound(const Key& key) const { - return data_.lower_bound(make_pair(key, Value())); + return data_.lower_bound(ctl::make_pair(key, Value())); } iterator upper_bound(const Key& key) { - return data_.upper_bound(make_pair(key, Value())); + return data_.upper_bound(ctl::make_pair(key, Value())); } const_iterator upper_bound(const Key& key) const { - return data_.upper_bound(make_pair(key, Value())); + return data_.upper_bound(ctl::make_pair(key, Value())); } ctl::pair equal_range(const Key& key) { - return data_.equal_range(make_pair(key, Value())); + return data_.equal_range(ctl::make_pair(key, Value())); } ctl::pair equal_range(const Key& key) const { - return data_.equal_range(make_pair(key, Value())); + return data_.equal_range(ctl::make_pair(key, Value())); } key_compare key_comp() const diff --git a/ctl/mutex.h b/ctl/mutex.h index 28a21e2e7..19f67a82a 100644 --- a/ctl/mutex.h +++ b/ctl/mutex.h @@ -11,17 +11,20 @@ class mutex public: mutex() { - pthread_mutex_init(&m_, nullptr); + if (pthread_mutex_init(&m_, nullptr)) + __builtin_trap(); } ~mutex() { - pthread_mutex_destroy(&m_); + if (pthread_mutex_destroy(&m_)) + __builtin_trap(); } void lock() { - pthread_mutex_lock(&m_); + if (pthread_mutex_lock(&m_)) + __builtin_trap(); } bool try_lock() @@ -31,7 +34,8 @@ class mutex void unlock() { - pthread_mutex_unlock(&m_); + if (pthread_mutex_unlock(&m_)) + __builtin_trap(); } // Delete copy constructor and assignment operator diff --git a/ctl/ostream.h b/ctl/ostream.h index 3b30421a1..6529db5b9 100644 --- a/ctl/ostream.h +++ b/ctl/ostream.h @@ -20,7 +20,7 @@ class ostream : public ios ostream& operator<<(int); ostream& operator<<(long); ostream& operator<<(double); - ostream& operator<<(const string_view&); + ostream& operator<<(const ctl::string_view&); ostream& operator<<(bool); ostream& operator<<(ostream& (*)(ostream&)); diff --git a/ctl/ostringstream.cc b/ctl/ostringstream.cc index b322c01e8..eb7fa51cc 100644 --- a/ctl/ostringstream.cc +++ b/ctl/ostringstream.cc @@ -26,19 +26,19 @@ ostringstream::ostringstream() : buffer_(), write_pos_(0) { } -ostringstream::ostringstream(const string_view& str) +ostringstream::ostringstream(const ctl::string_view& str) : buffer_(str), write_pos_(0) { } -string +ctl::string ostringstream::str() const { return buffer_; } void -ostringstream::str(const string& s) +ostringstream::str(const ctl::string& s) { buffer_ = s; write_pos_ = 0; @@ -65,7 +65,7 @@ ostringstream::operator<<(char c) } ostringstream& -ostringstream::operator<<(const string_view& s) +ostringstream::operator<<(const ctl::string_view& s) { if (good()) { if (write_pos_ + s.size() <= buffer_.size()) { @@ -84,7 +84,7 @@ ostringstream::operator<<(int n) { char temp[12]; if (good()) - *this << string_view(temp, FormatInt32(temp, n) - temp); + *this << ctl::string_view(temp, FormatInt32(temp, n) - temp); return *this; } @@ -93,7 +93,7 @@ ostringstream::operator<<(unsigned int n) { char temp[12]; if (good()) - *this << string_view(temp, FormatUint32(temp, n) - temp); + *this << ctl::string_view(temp, FormatUint32(temp, n) - temp); return *this; } @@ -102,7 +102,7 @@ ostringstream::operator<<(long n) { char temp[21]; if (good()) - *this << string_view(temp, FormatInt64(temp, n) - temp); + *this << ctl::string_view(temp, FormatInt64(temp, n) - temp); return *this; } @@ -111,7 +111,7 @@ ostringstream::operator<<(unsigned long n) { char temp[21]; if (good()) - *this << string_view(temp, FormatUint64(temp, n) - temp); + *this << ctl::string_view(temp, FormatUint64(temp, n) - temp); return *this; } @@ -121,7 +121,7 @@ ostringstream::operator<<(float f) if (good()) { char temp[32]; int len = snprintf(temp, sizeof(temp), "%g", f); - *this << string_view(temp, len); + *this << ctl::string_view(temp, len); } return *this; } @@ -132,7 +132,7 @@ ostringstream::operator<<(double d) if (good()) { char temp[32]; int len = snprintf(temp, sizeof(temp), "%g", d); - *this << string_view(temp, len); + *this << ctl::string_view(temp, len); } return *this; } diff --git a/ctl/ostringstream.h b/ctl/ostringstream.h index 09face624..46ca777fe 100644 --- a/ctl/ostringstream.h +++ b/ctl/ostringstream.h @@ -11,14 +11,14 @@ class ostringstream : public ios_base { public: ostringstream(); - explicit ostringstream(const string_view&); + explicit ostringstream(const ctl::string_view&); - string str() const; - void str(const string& s); + ctl::string str() const; + void str(const ctl::string& s); void clear(); ostringstream& operator<<(char); - ostringstream& operator<<(const string_view&); + ostringstream& operator<<(const ctl::string_view&); ostringstream& operator<<(int); ostringstream& operator<<(unsigned int); ostringstream& operator<<(long); @@ -27,7 +27,7 @@ class ostringstream : public ios_base ostringstream& operator<<(double); private: - string buffer_; + ctl::string buffer_; size_t write_pos_; }; diff --git a/ctl/out_of_range.h b/ctl/out_of_range.h index 08c65fc18..27b76e82d 100644 --- a/ctl/out_of_range.h +++ b/ctl/out_of_range.h @@ -6,7 +6,7 @@ namespace ctl { -class out_of_range : public exception +class out_of_range : public ctl::exception { public: out_of_range() noexcept = default; diff --git a/ctl/reverse_iterator.h b/ctl/reverse_iterator.h index b7d0245cd..67d5c23ea 100644 --- a/ctl/reverse_iterator.h +++ b/ctl/reverse_iterator.h @@ -13,11 +13,12 @@ class reverse_iterator public: using iterator_type = Iterator; using iterator_category = - typename iterator_traits::iterator_category; - using value_type = typename iterator_traits::value_type; - using difference_type = typename iterator_traits::difference_type; - using pointer = typename iterator_traits::pointer; - using reference = typename iterator_traits::reference; + typename ctl::iterator_traits::iterator_category; + using value_type = typename ctl::iterator_traits::value_type; + using difference_type = + typename ctl::iterator_traits::difference_type; + using pointer = typename ctl::iterator_traits::pointer; + using reference = typename ctl::iterator_traits::reference; constexpr reverse_iterator() : current() { diff --git a/ctl/set.h b/ctl/set.h index 94644d267..ef7ee74bf 100644 --- a/ctl/set.h +++ b/ctl/set.h @@ -8,7 +8,7 @@ namespace ctl { -template> +template> class set { struct rbtree @@ -381,12 +381,12 @@ class set size_ = 0; } - pair insert(value_type&& value) + ctl::pair insert(value_type&& value) { return insert_node(new node_type(ctl::move(value))); } - pair insert(const value_type& value) + ctl::pair insert(const value_type& value) { return insert_node(new node_type(value)); } @@ -415,7 +415,7 @@ class set } template - pair emplace(Args&&... args) + ctl::pair emplace(Args&&... args) { value_type value(ctl::forward(args)...); return insert(ctl::move(value)); @@ -451,12 +451,13 @@ class set ctl::swap(size_, other.size_); } - pair equal_range(const key_type& key) + ctl::pair equal_range(const key_type& key) { return { iterator(get_floor(key)), iterator(get_ceiling(key)) }; } - pair equal_range(const key_type& key) const + ctl::pair equal_range( + const key_type& key) const { return { const_iterator(get_floor(key)), const_iterator(get_ceiling(key)) }; @@ -613,7 +614,7 @@ class set return result; } - pair insert_node(node_type* node) + ctl::pair insert_node(node_type* node) { if (root_ == nullptr) { root_ = node; @@ -878,7 +879,7 @@ class set Compare comp_; }; -template> +template> bool operator==(const set& lhs, const set& rhs) { @@ -893,7 +894,7 @@ operator==(const set& lhs, const set& rhs) return true; } -template> +template> bool operator<(const set& lhs, const set& rhs) { @@ -908,35 +909,35 @@ operator<(const set& lhs, const set& rhs) return i == lhs.end() && j != rhs.end(); } -template> +template> bool operator!=(const set& lhs, const set& rhs) { return !(lhs == rhs); } -template> +template> bool operator<=(const set& lhs, const set& rhs) { return !(rhs < lhs); } -template> +template> bool operator>(const set& lhs, const set& rhs) { return rhs < lhs; } -template> +template> bool operator>=(const set& lhs, const set& rhs) { return !(lhs < rhs); } -template> +template> void swap(set& lhs, set& rhs) noexcept; diff --git a/ctl/string.h b/ctl/string.h index ba0ee6223..0509f3839 100644 --- a/ctl/string.h +++ b/ctl/string.h @@ -9,7 +9,7 @@ namespace ctl { class string; -string strcat(string_view, string_view) noexcept __wur; +ctl::string strcat(ctl::string_view, ctl::string_view) noexcept __wur; namespace __ { @@ -66,7 +66,7 @@ class string *(((size_t*)blob) + 2) = __::sso_max << (sizeof(size_t) - 1) * 8; } - string(const string_view s) noexcept + string(const ctl::string_view s) noexcept { if (s.n <= __::sso_max) { __builtin_memcpy(blob, s.p, s.n); @@ -89,7 +89,7 @@ class string } string(const char* const p) noexcept - : string(string_view(p, __builtin_strlen(p))) + : string(ctl::string_view(p, __builtin_strlen(p))) { } @@ -104,7 +104,7 @@ class string } string(const char* const p, const size_t n) noexcept - : string(string_view(p, n)) + : string(ctl::string_view(p, n)) { } @@ -125,17 +125,17 @@ class string void append(char, size_t) noexcept; void append(unsigned long) noexcept; void append(const void*, size_t) noexcept; - string& insert(size_t, string_view) noexcept; + string& insert(size_t, ctl::string_view) noexcept; string& erase(size_t = 0, size_t = npos) noexcept; string substr(size_t = 0, size_t = npos) const noexcept; - string& replace(size_t, size_t, string_view) noexcept; - bool operator==(string_view) const noexcept; - bool operator!=(string_view) const noexcept; - bool contains(string_view) const noexcept; - bool ends_with(string_view) const noexcept; - bool starts_with(string_view) const noexcept; + string& replace(size_t, size_t, ctl::string_view) noexcept; + bool operator==(ctl::string_view) const noexcept; + bool operator!=(ctl::string_view) const noexcept; + bool contains(ctl::string_view) const noexcept; + bool ends_with(ctl::string_view) const noexcept; + bool starts_with(ctl::string_view) const noexcept; size_t find(char, size_t = 0) const noexcept; - size_t find(string_view, size_t = 0) const noexcept; + size_t find(ctl::string_view, size_t = 0) const noexcept; void swap(string& s) noexcept { @@ -302,14 +302,14 @@ class string append(ch); } - void append(const string_view s) noexcept + void append(const ctl::string_view s) noexcept { append(s.p, s.n); } - operator string_view() const noexcept + operator ctl::string_view() const noexcept { - return string_view(data(), size()); + return ctl::string_view(data(), size()); } string& operator=(const char* s) noexcept @@ -319,7 +319,7 @@ class string return *this; } - string& operator=(const string_view s) noexcept + string& operator=(const ctl::string_view s) noexcept { clear(); append(s); @@ -332,38 +332,38 @@ class string return *this; } - string& operator+=(const string_view s) noexcept + string& operator+=(const ctl::string_view s) noexcept { append(s); return *this; } - string operator+(const string_view s) const noexcept + string operator+(const ctl::string_view s) const noexcept { return strcat(*this, s); } - int compare(const string_view s) const noexcept + int compare(const ctl::string_view s) const noexcept { return strcmp(*this, s); } - bool operator<(const string_view s) const noexcept + bool operator<(const ctl::string_view s) const noexcept { return compare(s) < 0; } - bool operator<=(const string_view s) const noexcept + bool operator<=(const ctl::string_view s) const noexcept { return compare(s) <= 0; } - bool operator>(const string_view s) const noexcept + bool operator>(const ctl::string_view s) const noexcept { return compare(s) > 0; } - bool operator>=(const string_view s) const noexcept + bool operator>=(const ctl::string_view s) const noexcept { return compare(s) >= 0; } @@ -371,7 +371,7 @@ class string private: void destroy_big() noexcept; void init_big(const string&) noexcept; - void init_big(string_view) noexcept; + void init_big(ctl::string_view) noexcept; void init_big(size_t, char) noexcept; __attribute__((__always_inline__)) bool isbig() const noexcept @@ -395,7 +395,7 @@ class string __b.c = c2 | ~__::big_mask; } - friend string strcat(string_view, string_view) noexcept; + friend string strcat(ctl::string_view, ctl::string_view) noexcept; union { From e627bfa3591971cda7d4f8ed8f24d12baae08caf Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Mon, 1 Jul 2024 05:40:38 -0700 Subject: [PATCH 020/405] Introduce ctl::to_string() --- Makefile | 2 +- ctl/BUILD.mk | 1 + ctl/dubble.cc | 35 ++++++++++ ctl/dubble.h | 13 ++++ ctl/ostream.cc | 73 ++++++++++++++++++--- ctl/ostream.h | 5 +- ctl/ostringstream.cc | 58 ++++++++++------- ctl/string.h | 43 +++++++++++++ ctl/to_string.cc | 109 +++++++++++++++++++++++++++++++ test/ctl/copy_test.cc | 6 +- test/ctl/to_string_test.cc | 127 +++++++++++++++++++++++++++++++++++++ 11 files changed, 432 insertions(+), 40 deletions(-) create mode 100644 ctl/dubble.cc create mode 100644 ctl/dubble.h create mode 100644 ctl/to_string.cc create mode 100644 test/ctl/to_string_test.cc diff --git a/Makefile b/Makefile index 73e49877c..b6d080060 100644 --- a/Makefile +++ b/Makefile @@ -284,10 +284,10 @@ include third_party/ncurses/BUILD.mk # β”‚ include third_party/readline/BUILD.mk # β”‚ include third_party/libunwind/BUILD.mk # | include third_party/libcxxabi/BUILD.mk # | +include third_party/double-conversion/BUILD.mk # β”‚ include ctl/BUILD.mk # β”‚ include third_party/libcxx/BUILD.mk # β”‚ include third_party/openmp/BUILD.mk # β”‚ -include third_party/double-conversion/BUILD.mk # β”‚ include third_party/pcre/BUILD.mk # β”‚ include third_party/less/BUILD.mk # β”‚ include net/https/BUILD.mk # β”‚ diff --git a/ctl/BUILD.mk b/ctl/BUILD.mk index 73cf29766..3db733319 100644 --- a/ctl/BUILD.mk +++ b/ctl/BUILD.mk @@ -21,6 +21,7 @@ CTL_A_DIRECTDEPS = \ LIBC_NEXGEN32E \ LIBC_STDIO \ LIBC_STR \ + THIRD_PARTY_DOUBLECONVERSION \ THIRD_PARTY_GDTOA \ THIRD_PARTY_LIBCXXABI \ THIRD_PARTY_LIBUNWIND \ diff --git a/ctl/dubble.cc b/ctl/dubble.cc new file mode 100644 index 000000000..c80ab6718 --- /dev/null +++ b/ctl/dubble.cc @@ -0,0 +1,35 @@ +// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +// +// Copyright 2024 Justine Alexandra Roberts Tunney +// +// Permission to use, copy, modify, and/or distribute this software for +// any purpose with or without fee is hereby granted, provided that the +// above copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include "dubble.h" + +namespace ctl { + +const double_conversion::DoubleToStringConverter kDoubleToPrintfG( + double_conversion::DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN | + double_conversion::DoubleToStringConverter::NO_TRAILING_ZERO, + "inf", + "nan", + 'e', + -6, + 10, // let 32-bit ints be represented without exponent + 6, + 0, + 0); + +} // namespace ctl diff --git a/ctl/dubble.h b/ctl/dubble.h new file mode 100644 index 000000000..88a2f0924 --- /dev/null +++ b/ctl/dubble.h @@ -0,0 +1,13 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef COSMOPOLITAN_CTL_DUBBLE_H_ +#define COSMOPOLITAN_CTL_DUBBLE_H_ +#include "third_party/double-conversion/double-to-string.h" + +namespace ctl { + +extern const double_conversion::DoubleToStringConverter kDoubleToPrintfG; + +} // namespace ctl + +#endif // COSMOPOLITAN_CTL_DUBBLE_H_ diff --git a/ctl/ostream.cc b/ctl/ostream.cc index d57e11906..f2ab0b302 100644 --- a/ctl/ostream.cc +++ b/ctl/ostream.cc @@ -17,11 +17,15 @@ // PERFORMANCE OF THIS SOFTWARE. #include "ostream.h" +#include "dubble.h" +#include "libc/fmt/itoa.h" #include "libc/stdio/stdio.h" #include "string_view.h" namespace ctl { +extern const double_conversion::DoubleToStringConverter kDoubleToPrintfG; + ostream cout(stdout); ostream cerr(stderr); @@ -50,7 +54,7 @@ ostream& ostream::operator<<(const char* str) { if (good() && str) - if (fprintf(file_, "%s", str) < 0) + if (fputs(str, file_) < 0) setstate(badbit); return *this; } @@ -67,35 +71,84 @@ ostream::operator<<(char c) ostream& ostream::operator<<(int n) { - if (good()) - if (fprintf(file_, "%d", n) < 0) + if (good()) { + char buf[12]; + FormatInt32(buf, n); + if (fputs(buf, file_) < 0) setstate(badbit); + } + return *this; +} + +ostream& +ostream::operator<<(unsigned n) +{ + if (good()) { + char buf[12]; + FormatUint32(buf, n); + if (fputs(buf, file_) < 0) + setstate(badbit); + } return *this; } ostream& ostream::operator<<(long n) { - if (good()) - if (fprintf(file_, "%ld", n) < 0) + if (good()) { + char buf[21]; + FormatInt64(buf, n); + if (fputs(buf, file_) < 0) setstate(badbit); + } + return *this; +} + +ostream& +ostream::operator<<(unsigned long n) +{ + if (good()) { + char buf[21]; + FormatUint64(buf, n); + if (fputs(buf, file_) < 0) + setstate(badbit); + } + return *this; +} + +ostream& +ostream::operator<<(float f) +{ + if (good()) { + char buf[128]; + double_conversion::StringBuilder b(buf, sizeof(buf)); + kDoubleToPrintfG.ToShortestSingle(f, &b); + b.Finalize(); + if (fputs(buf, file_) < 0) + setstate(badbit); + } return *this; } ostream& ostream::operator<<(double d) { - if (good()) - if (fprintf(file_, "%f", d) < 0) + if (good()) { + char buf[128]; + double_conversion::StringBuilder b(buf, sizeof(buf)); + kDoubleToPrintfG.ToShortest(d, &b); + b.Finalize(); + if (fputs(buf, file_) < 0) setstate(badbit); + } return *this; } ostream& ostream::operator<<(const string_view& s) { - if (good()) - if (fprintf(file_, "%.*s", (int)s.size(), s.data()) < 0) + if (good() && s.size()) + if (!fwrite(s.data(), s.size(), 1, file_)) setstate(badbit); return *this; } @@ -106,7 +159,7 @@ ostream::operator<<(bool b) if (good()) { const char* value = (flags() & boolalpha) ? (b ? "true" : "false") : (b ? "1" : "0"); - if (fprintf(file_, "%s", value) < 0) + if (fputs(value, file_) < 0) setstate(badbit); } return *this; diff --git a/ctl/ostream.h b/ctl/ostream.h index 6529db5b9..c13d5c133 100644 --- a/ctl/ostream.h +++ b/ctl/ostream.h @@ -16,12 +16,15 @@ class ostream : public ios virtual ~ostream(); ostream& operator<<(const char*); + ostream& operator<<(bool); ostream& operator<<(char); ostream& operator<<(int); + ostream& operator<<(unsigned); ostream& operator<<(long); + ostream& operator<<(unsigned long); + ostream& operator<<(float); ostream& operator<<(double); ostream& operator<<(const ctl::string_view&); - ostream& operator<<(bool); ostream& operator<<(ostream& (*)(ostream&)); ostream& put(char); diff --git a/ctl/ostringstream.cc b/ctl/ostringstream.cc index eb7fa51cc..dcf01ff6f 100644 --- a/ctl/ostringstream.cc +++ b/ctl/ostringstream.cc @@ -17,28 +17,30 @@ // PERFORMANCE OF THIS SOFTWARE. #include "ostringstream.h" +#include "dubble.h" #include "libc/fmt/itoa.h" -#include "libc/stdio/stdio.h" namespace ctl { +extern const double_conversion::DoubleToStringConverter kDoubleToPrintfG; + ostringstream::ostringstream() : buffer_(), write_pos_(0) { } -ostringstream::ostringstream(const ctl::string_view& str) +ostringstream::ostringstream(const string_view& str) : buffer_(str), write_pos_(0) { } -ctl::string +string ostringstream::str() const { return buffer_; } void -ostringstream::str(const ctl::string& s) +ostringstream::str(const string& s) { buffer_ = s; write_pos_ = 0; @@ -65,7 +67,7 @@ ostringstream::operator<<(char c) } ostringstream& -ostringstream::operator<<(const ctl::string_view& s) +ostringstream::operator<<(const string_view& s) { if (good()) { if (write_pos_ + s.size() <= buffer_.size()) { @@ -82,36 +84,40 @@ ostringstream::operator<<(const ctl::string_view& s) ostringstream& ostringstream::operator<<(int n) { - char temp[12]; - if (good()) - *this << ctl::string_view(temp, FormatInt32(temp, n) - temp); + if (good()) { + char buf[12]; + *this << string_view(buf, FormatInt32(buf, n) - buf); + } return *this; } ostringstream& -ostringstream::operator<<(unsigned int n) +ostringstream::operator<<(unsigned n) { - char temp[12]; - if (good()) - *this << ctl::string_view(temp, FormatUint32(temp, n) - temp); + if (good()) { + char buf[12]; + *this << string_view(buf, FormatUint32(buf, n) - buf); + } return *this; } ostringstream& ostringstream::operator<<(long n) { - char temp[21]; - if (good()) - *this << ctl::string_view(temp, FormatInt64(temp, n) - temp); + if (good()) { + char buf[21]; + *this << string_view(buf, FormatInt64(buf, n) - buf); + } return *this; } ostringstream& ostringstream::operator<<(unsigned long n) { - char temp[21]; - if (good()) - *this << ctl::string_view(temp, FormatUint64(temp, n) - temp); + if (good()) { + char buf[21]; + *this << string_view(buf, FormatUint64(buf, n) - buf); + } return *this; } @@ -119,9 +125,11 @@ ostringstream& ostringstream::operator<<(float f) { if (good()) { - char temp[32]; - int len = snprintf(temp, sizeof(temp), "%g", f); - *this << ctl::string_view(temp, len); + char buf[128]; + double_conversion::StringBuilder b(buf, sizeof(buf)); + kDoubleToPrintfG.ToShortestSingle(f, &b); + b.Finalize(); + *this << string_view(buf); } return *this; } @@ -130,9 +138,11 @@ ostringstream& ostringstream::operator<<(double d) { if (good()) { - char temp[32]; - int len = snprintf(temp, sizeof(temp), "%g", d); - *this << ctl::string_view(temp, len); + char buf[128]; + double_conversion::StringBuilder b(buf, sizeof(buf)); + kDoubleToPrintfG.ToShortest(d, &b); + b.Finalize(); + *this << string_view(buf); } return *this; } diff --git a/ctl/string.h b/ctl/string.h index 0509f3839..a3488cd7a 100644 --- a/ctl/string.h +++ b/ctl/string.h @@ -338,11 +338,27 @@ class string return *this; } + string operator+(const char c) const noexcept + { + char s[2] = { c }; + return strcat(*this, s); + } + + string operator+(const string& s) const noexcept + { + return strcat(*this, s); + } + string operator+(const ctl::string_view s) const noexcept { return strcat(*this, s); } + string operator+(const char* s) const noexcept + { + return strcat(*this, s); + } + int compare(const ctl::string_view s) const noexcept { return strcmp(*this, s); @@ -409,6 +425,33 @@ static_assert(sizeof(string) == __::string_size); static_assert(sizeof(__::small_string) == __::string_size); static_assert(sizeof(__::big_string) == __::string_size); +ctl::string +to_string(int); + +ctl::string +to_string(long); + +ctl::string +to_string(long long); + +ctl::string +to_string(unsigned); + +ctl::string +to_string(unsigned long); + +ctl::string +to_string(unsigned long long); + +ctl::string +to_string(float); + +ctl::string +to_string(double); + +ctl::string +to_string(long double); + } // namespace ctl #pragma GCC diagnostic push diff --git a/ctl/to_string.cc b/ctl/to_string.cc new file mode 100644 index 000000000..fb54968e9 --- /dev/null +++ b/ctl/to_string.cc @@ -0,0 +1,109 @@ +// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +// +// Copyright 2024 Justine Alexandra Roberts Tunney +// +// Permission to use, copy, modify, and/or distribute this software for +// any purpose with or without fee is hereby granted, provided that the +// above copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include "dubble.h" +#include "libc/fmt/itoa.h" +#include "libc/math.h" +#include "string.h" +#include "third_party/gdtoa/gdtoa.h" + +namespace ctl { + +extern const double_conversion::DoubleToStringConverter kDoubleToPrintfG; + +string +to_string(int value) +{ + char buf[12]; + return { buf, FormatInt32(buf, value) - buf }; +} + +string +to_string(unsigned value) +{ + char buf[12]; + return { buf, FormatUint32(buf, value) - buf }; +} + +string +to_string(long value) +{ + char buf[21]; + return { buf, FormatInt64(buf, value) - buf }; +} + +string +to_string(unsigned long value) +{ + char buf[21]; + return { buf, FormatUint64(buf, value) - buf }; +} + +string +to_string(long long value) +{ + char buf[21]; + return { buf, FormatInt64(buf, value) - buf }; +} + +string +to_string(unsigned long long value) +{ + char buf[21]; + return { buf, FormatUint64(buf, value) - buf }; +} + +string +to_string(float value) +{ + char buf[128]; + double_conversion::StringBuilder b(buf, sizeof(buf)); + kDoubleToPrintfG.ToShortestSingle(value, &b); + b.Finalize(); + return string(buf); +} + +string +to_string(double value) +{ + char buf[128]; + double_conversion::StringBuilder b(buf, sizeof(buf)); + kDoubleToPrintfG.ToShortest(value, &b); + b.Finalize(); + return string(buf); +} + +string +to_string(long double value) +{ +#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 + return to_string((double)value); +#else + char buf[128]; +#if LDBL_MANT_DIG == 113 + g_Qfmt_p(buf, &value, 16, 128, NIK(2, 0, 0)); +#elif LDBL_MANT_DIG == 64 + g_xfmt_p(buf, &value, 16, 128, NIK(2, 0, 0)); +#else +#error "unsupported long double" +#endif + return string(buf); +#endif +} + +} // namespace ctl diff --git a/test/ctl/copy_test.cc b/test/ctl/copy_test.cc index 2c417186a..0c73ed7c8 100644 --- a/test/ctl/copy_test.cc +++ b/test/ctl/copy_test.cc @@ -35,10 +35,9 @@ main() // Test basic copy ctl::copy(src.begin(), src.end(), dest.begin()); - for (size_t i = 0; i < 5; ++i) { + for (size_t i = 0; i < 5; ++i) if (dest[i] != src[i]) return 1; - } // Test partial copy ctl::array dest2 = { 0, 0, 0, 0, 0 }; @@ -57,10 +56,9 @@ main() // Test copy with empty range ctl::array dest4 = { 0, 0, 0, 0, 0 }; ctl::copy(src.begin(), src.begin(), dest4.begin()); - for (size_t i = 0; i < 5; ++i) { + for (size_t i = 0; i < 5; ++i) if (dest4[i] != 0) return 4; - } // Test copy return value ctl::array dest5 = { 0, 0, 0, 0, 0 }; diff --git a/test/ctl/to_string_test.cc b/test/ctl/to_string_test.cc new file mode 100644 index 000000000..8cba51e60 --- /dev/null +++ b/test/ctl/to_string_test.cc @@ -0,0 +1,127 @@ +// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +// +// Copyright 2024 Justine Alexandra Roberts Tunney +// +// Permission to use, copy, modify, and/or distribute this software for +// any purpose with or without fee is hereby granted, provided that the +// above copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include "ctl/string.h" +#include "libc/intrin/kprintf.h" +#include "libc/limits.h" +#include "libc/math.h" +#include "libc/mem/leaks.h" + +int +main() +{ + + // test integer conversion + { + if (ctl::to_string(0) != "0") + return 1; + if (ctl::to_string(3) != "3") + return 1; + if (ctl::to_string(INT32_MAX) != "2147483647") + return 2; + if (ctl::to_string(INT32_MIN) != "-2147483648") + return 3; + if (ctl::to_string(UINT32_MAX) != "4294967295") + return 4; + if (ctl::to_string(INT64_MAX) != "9223372036854775807") + return 5; + if (ctl::to_string(INT64_MIN) != "-9223372036854775808") + return 6; + if (ctl::to_string(UINT64_MAX) != "18446744073709551615") + return 7; + } + + // test float conversion + // we diverge from std::to_string(float) because it's garbage + { + if (ctl::to_string(0.f) != "0") // 0.000000 + return 8; + if (ctl::to_string(-0.f) != "-0") // 0.000000 + return 9; + if (ctl::to_string(3.f) != "3") // 3.000000 + return 10; + if (ctl::to_string(3.14f) != "3.14") // 3.140000 + return 11; + if (ctl::to_string(3.140001f) != "3.140001") + return 12; + if (ctl::to_string(1000000000.f) != "1000000000") // 1000000000.000000 + return 12; + if (ctl::to_string(10000000000.f) != "1e+10") // 10000000000.000000 + return 12; + if (ctl::to_string(NAN) != "nan") + return 13; + if (ctl::to_string(INFINITY) != "inf") + return 14; + if (ctl::to_string(-INFINITY) != "-inf") + return 15; + if (ctl::to_string(FLT_MIN) != "1.1754944e-38") // 0.000000 lool + return 16; + if (ctl::to_string(-FLT_MIN) != "-1.1754944e-38") + return 17; + if (ctl::to_string(FLT_MAX) != "3.4028235e+38") + return 18; + if (ctl::to_string(-FLT_MAX) != "-3.4028235e+38") + return 19; + } + + // test double conversion + { + if (ctl::to_string(0.) != "0") + return 20; + if (ctl::to_string(-0.) != "-0") + return 21; + if (ctl::to_string(3.) != "3") + return 22; + if (ctl::to_string(2147483647.) != "2147483647") + return 23; + if (ctl::to_string(-2147483648.) != "-2147483648") + return 23; + if (ctl::to_string(10000000000.) != "1e+10") + return 23; + if (ctl::to_string(3.14) != "3.14") + return 23; + if (ctl::to_string(3.140001) != "3.140001") + return 24; + if (ctl::to_string(DBL_MIN) != "2.2250738585072014e-308") + return 25; + if (ctl::to_string(-DBL_MIN) != "-2.2250738585072014e-308") + return 26; + if (ctl::to_string(DBL_MAX) != "1.7976931348623157e+308") + return 27; + if (ctl::to_string(-DBL_MAX) != "-1.7976931348623157e+308") + return 28; + } + + // test long double conversion + { + if (ctl::to_string(0.L) != "0") + return 29; + if (ctl::to_string(-0.L) != "-0") + return 30; + if (ctl::to_string(3.L) != "3") + return 31; + if (ctl::to_string(3.14L) != "3.14") + return 32; + if (ctl::to_string(LDBL_MAX) != "1.189731495357232e+4932") + return 33; + if (ctl::to_string(-LDBL_MAX) != "-1.189731495357232e+4932") + return 34; + } + + CheckForMemoryLeaks(); +} From c1f8d0678cd32ad5fbeac6fdbcd39c786e4999ee Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Mon, 1 Jul 2024 05:54:22 -0700 Subject: [PATCH 021/405] Mark ctl::to_string() noexcept --- ctl/string.h | 18 +++++++++--------- ctl/to_string.cc | 18 +++++++++--------- test/ctl/to_string_test.cc | 1 - 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/ctl/string.h b/ctl/string.h index a3488cd7a..b2941588d 100644 --- a/ctl/string.h +++ b/ctl/string.h @@ -426,31 +426,31 @@ static_assert(sizeof(__::small_string) == __::string_size); static_assert(sizeof(__::big_string) == __::string_size); ctl::string -to_string(int); +to_string(int) noexcept; ctl::string -to_string(long); +to_string(long) noexcept; ctl::string -to_string(long long); +to_string(long long) noexcept; ctl::string -to_string(unsigned); +to_string(unsigned) noexcept; ctl::string -to_string(unsigned long); +to_string(unsigned long) noexcept; ctl::string -to_string(unsigned long long); +to_string(unsigned long long) noexcept; ctl::string -to_string(float); +to_string(float) noexcept; ctl::string -to_string(double); +to_string(double) noexcept; ctl::string -to_string(long double); +to_string(long double) noexcept; } // namespace ctl diff --git a/ctl/to_string.cc b/ctl/to_string.cc index fb54968e9..a66bb7031 100644 --- a/ctl/to_string.cc +++ b/ctl/to_string.cc @@ -27,49 +27,49 @@ namespace ctl { extern const double_conversion::DoubleToStringConverter kDoubleToPrintfG; string -to_string(int value) +to_string(int value) noexcept { char buf[12]; return { buf, FormatInt32(buf, value) - buf }; } string -to_string(unsigned value) +to_string(unsigned value) noexcept { char buf[12]; return { buf, FormatUint32(buf, value) - buf }; } string -to_string(long value) +to_string(long value) noexcept { char buf[21]; return { buf, FormatInt64(buf, value) - buf }; } string -to_string(unsigned long value) +to_string(unsigned long value) noexcept { char buf[21]; return { buf, FormatUint64(buf, value) - buf }; } string -to_string(long long value) +to_string(long long value) noexcept { char buf[21]; return { buf, FormatInt64(buf, value) - buf }; } string -to_string(unsigned long long value) +to_string(unsigned long long value) noexcept { char buf[21]; return { buf, FormatUint64(buf, value) - buf }; } string -to_string(float value) +to_string(float value) noexcept { char buf[128]; double_conversion::StringBuilder b(buf, sizeof(buf)); @@ -79,7 +79,7 @@ to_string(float value) } string -to_string(double value) +to_string(double value) noexcept { char buf[128]; double_conversion::StringBuilder b(buf, sizeof(buf)); @@ -89,7 +89,7 @@ to_string(double value) } string -to_string(long double value) +to_string(long double value) noexcept { #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 return to_string((double)value); diff --git a/test/ctl/to_string_test.cc b/test/ctl/to_string_test.cc index 8cba51e60..69841c7ad 100644 --- a/test/ctl/to_string_test.cc +++ b/test/ctl/to_string_test.cc @@ -17,7 +17,6 @@ // PERFORMANCE OF THIS SOFTWARE. #include "ctl/string.h" -#include "libc/intrin/kprintf.h" #include "libc/limits.h" #include "libc/math.h" #include "libc/mem/leaks.h" From 72511ff0ac2d6b7bbf46d53861abed62080efba5 Mon Sep 17 00:00:00 2001 From: Terror Date: Tue, 2 Jul 2024 01:06:56 +1200 Subject: [PATCH 022/405] [Redbean] Add UuidV7 method (#1213) To Complete #1140 add UUID version 7 to Redbean --- test/tool/net/uuidv7_test.lua | 25 +++++++++++++ tool/net/definitions.lua | 4 +++ tool/net/help.txt | 5 ++- tool/net/lfuncs.c | 68 +++++++++++++++++++++++++++++++++++ tool/net/lfuncs.h | 1 + tool/net/redbean.c | 1 + 6 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 test/tool/net/uuidv7_test.lua diff --git a/test/tool/net/uuidv7_test.lua b/test/tool/net/uuidv7_test.lua new file mode 100644 index 000000000..063a9da94 --- /dev/null +++ b/test/tool/net/uuidv7_test.lua @@ -0,0 +1,25 @@ +-- Copyright 2024 Justine Alexandra Roberts Tunney +-- +-- Permission to use, copy, modify, and/or distribute this software for +-- any purpose with or without fee is hereby granted, provided that the +-- above copyright notice and this permission notice appear in all copies. +-- +-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +-- WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +-- WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +-- AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +-- DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +-- PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +-- TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +-- PERFORMANCE OF THIS SOFTWARE. +for _ = 1, 1000 do + local uuid = UuidV7() + assert(#uuid == 36) + assert(string.sub(uuid, 9, 9) == "-") + assert(string.sub(uuid, 14, 14) == "-") + assert(string.sub(uuid, 15, 15) == "7") + assert(string.sub(uuid, 19, 19) == "-") + local y = string.sub(uuid, 20, 20) + assert(y == "8" or y == "9" or y == "a" or y == "b") + assert(string.sub(uuid, 24, 24) == "-") +end diff --git a/tool/net/definitions.lua b/tool/net/definitions.lua index f6fecffda..2424f9241 100644 --- a/tool/net/definitions.lua +++ b/tool/net/definitions.lua @@ -1981,6 +1981,10 @@ function Underlong(str) end --- @return string function UuidV4() end +--- Generate a uuid_v7 +--- @return string +function UuidV7() end + ---@param x integer ---@return integer # position of first bit set. --- Passing `0` will raise an error. Same as the Intel x86 instruction BSF. diff --git a/tool/net/help.txt b/tool/net/help.txt index 4ea0be1f8..f031a83ae 100644 --- a/tool/net/help.txt +++ b/tool/net/help.txt @@ -1063,7 +1063,10 @@ FUNCTIONS This function is not available in unsecure mode. UuidV4() -> str - Returns an uuid v4 string. + Returns a uuid v4 string. + + UuidV7() -> str + Returns a uuid v7 string. Fetch(url:str[,body:str|{method=value:str,body=value:str,headers=table,...}]) β”œβ”€β†’ status:int, {header:str=value:str,...}, body:str diff --git a/tool/net/lfuncs.c b/tool/net/lfuncs.c index e8d566d94..798099c7d 100644 --- a/tool/net/lfuncs.c +++ b/tool/net/lfuncs.c @@ -858,6 +858,74 @@ int LuaUuidV4(lua_State *L) { return 1; } +int LuaUuidV7(lua_State *L) { + //See https://www.rfc-editor.org/rfc/rfc9562.html + char bin[16], uuid_str[37]; + struct timespec ts = timespec_real(); + uint64_t unix_ts_ms = (uint64_t)((ts.tv_sec * 1000) + (ts.tv_nsec / 1000000)); + int fractional_ms = (int)floor((double)((double)(ts.tv_nsec - (ts.tv_nsec / 1000000) * 1000000)/1000000) * 4096) <<4; + uint64_t rand_b = _rand64(); + int rand_a = fractional_ms | (rand_b & 0x000000000000000f); //use the last 4 bits of rand_b + + bin[0] = unix_ts_ms >> 050; + bin[1] = unix_ts_ms >> 040; + bin[2] = unix_ts_ms >> 030; + bin[3] = unix_ts_ms >> 020; + bin[4] = unix_ts_ms >> 010; + bin[5] = unix_ts_ms >> 000; + bin[6] = rand_a >> 010; + bin[7] = rand_a >> 000; + bin[8] = rand_b >> 070; + bin[9] = rand_b >> 060; + bin[10] = rand_b >> 050; + bin[11] = rand_b >> 040; + bin[12] = rand_b >> 030; + bin[13] = rand_b >> 020; + bin[14] = rand_b >> 010; + bin[15] = rand_b >> 000; + + uuid_str[0] = "0123456789abcdef"[(bin[0] & 0xf0) >>4]; + uuid_str[1] = "0123456789abcdef"[(bin[0] & 0x0f)]; + uuid_str[2] = "0123456789abcdef"[(bin[1] & 0xf0) >>4]; + uuid_str[3] = "0123456789abcdef"[(bin[1] & 0x0f)]; + uuid_str[4] = "0123456789abcdef"[(bin[2] & 0xf0) >>4]; + uuid_str[5] = "0123456789abcdef"[(bin[2] & 0x0f)]; + uuid_str[6] = "0123456789abcdef"[(bin[3] & 0xf0) >>4]; + uuid_str[7] = "0123456789abcdef"[(bin[3] & 0x0f)]; + uuid_str[8] = '-'; + uuid_str[9] = "0123456789abcdef"[(bin[4] & 0xf0) >>4]; + uuid_str[10] = "0123456789abcdef"[(bin[4] & 0x0f)]; + uuid_str[11] = "0123456789abcdef"[(bin[5] & 0xf0) >>4]; + uuid_str[12] = "0123456789abcdef"[(bin[5] & 0x0f)]; + uuid_str[13] = '-'; + uuid_str[14] = '7'; + uuid_str[15] = "0123456789abcdef"[(bin[6] & 0xf0) >>4]; + uuid_str[16] = "0123456789abcdef"[(bin[6] & 0x0f)]; + uuid_str[17] = "0123456789abcdef"[(bin[7] & 0xf0) >>4]; + uuid_str[18] = '-'; + uuid_str[19] = "0123456789abcdef"[(0x8 | ((bin[7] & 0x0f) >>2))]; + uuid_str[20] = "0123456789abcdef"[(bin[7] & 0x03) | (bin[8] & 0xf0) >>6]; //See https://www.rfc-editor.org/rfc/rfc9562.html#version_field + uuid_str[21] = "0123456789abcdef"[(bin[8] & 0x0f)]; + uuid_str[22] = "0123456789abcdef"[(bin[9] & 0xf0) >>4]; + uuid_str[23] = '-'; + uuid_str[24] = "0123456789abcdef"[(bin[9] & 0x0f)]; + uuid_str[25] = "0123456789abcdef"[(bin[10] & 0xf0) >>4]; + uuid_str[26] = "0123456789abcdef"[(bin[10] & 0x0f)]; + uuid_str[27] = "0123456789abcdef"[(bin[11] & 0xf0) >>4]; + uuid_str[28] = "0123456789abcdef"[(bin[11] & 0x0f)]; + uuid_str[29] = "0123456789abcdef"[(bin[12] & 0xf0) >>4]; + uuid_str[30] = "0123456789abcdef"[(bin[12] & 0x0f)]; + uuid_str[31] = "0123456789abcdef"[(bin[13] & 0xf0) >>4]; + uuid_str[32] = "0123456789abcdef"[(bin[13] & 0x0f)]; + uuid_str[33] = "0123456789abcdef"[(bin[14] & 0xf0) >>4]; + uuid_str[34] = "0123456789abcdef"[(bin[14] & 0x0f)]; + uuid_str[35] = "0123456789abcdef"[(bin[15] & 0xf0) >>4]; + uuid_str[36] = '\0'; + + lua_pushfstring(L, uuid_str); + return 1; +} + static dontinline int LuaHasherImpl(lua_State *L, size_t k, int H(const void *, size_t, uint8_t *)) { size_t n; diff --git a/tool/net/lfuncs.h b/tool/net/lfuncs.h index ab82c4e95..7bc3fc748 100644 --- a/tool/net/lfuncs.h +++ b/tool/net/lfuncs.h @@ -91,6 +91,7 @@ int LuaSlurp(lua_State *); int LuaUncompress(lua_State *); int LuaUnderlong(lua_State *); int LuaUuidV4(lua_State *); +int LuaUuidV7(lua_State *); int LuaVisualizeControlCodes(lua_State *); void LuaPushUrlView(lua_State *, struct UrlView *); diff --git a/tool/net/redbean.c b/tool/net/redbean.c index 8696121e9..c87122c49 100644 --- a/tool/net/redbean.c +++ b/tool/net/redbean.c @@ -5364,6 +5364,7 @@ static const luaL_Reg kLuaFuncs[] = { {"Uncompress", LuaUncompress}, // {"Underlong", LuaUnderlong}, // {"UuidV4", LuaUuidV4}, // + {"UuidV7", LuaUuidV7}, // {"VisualizeControlCodes", LuaVisualizeControlCodes}, // {"Write", LuaWrite}, // {"bin", LuaBin}, // From 61370983e1977225f3e1d9a3e00990d34f388718 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Mon, 1 Jul 2024 06:42:35 -0700 Subject: [PATCH 023/405] Complete the Windows TLS fix made in e437bed00 --- libc/runtime/enable_tls.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/libc/runtime/enable_tls.c b/libc/runtime/enable_tls.c index 3b3c098ff..d2ec8d9de 100644 --- a/libc/runtime/enable_tls.c +++ b/libc/runtime/enable_tls.c @@ -141,24 +141,23 @@ textstartup void __enable_tls(void) { size_t siz = ROUNDUP(I(_tls_size) + sizeof(struct CosmoTib), TLS_ALIGNMENT); if (siz <= sizeof(__static_tls)) { // if tls requirement is small then use the static tls block - // which helps avoid a system call for appes with little tls + // which helps avoid a system call for apes with little tls. // this is crucial to keeping life.com 16 kilobytes in size! mem = __static_tls; } else { - // if this binary needs a hefty tls block then we'll bank on - // malloc() being linked, which links _mapanon(). otherwise - // if you exceed this, you need to __static_yoink("_mapanon"). - // please note that it's probably too early to call calloc() - mem = _weaken(_mapanon)(siz); + // if a binary needs this much thread_local storage, then it + // surely must have linked the mmap() function at some point + // we can't call mmap() because it's too early for sig block + mem = _weaken(__mmap)(0, siz, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); } struct CosmoTib *tib = (struct CosmoTib *)(mem + siz - sizeof(*tib)); char *tls = mem + siz - sizeof(*tib) - I(_tls_size); // copy in initialized data section - if (I(_tdata_size)) { + if (I(_tdata_size)) memcpy(tls, _tdata_start, I(_tdata_size)); - } #elif defined(__aarch64__) @@ -169,10 +168,16 @@ textstartup void __enable_tls(void) { char *mem; if (I(_tls_align) <= TLS_ALIGNMENT && size <= sizeof(__static_tls)) { + // if tls requirement is small then use the static tls block + // which helps avoid a system call for apes with little tls. + // this is crucial to keeping life.com 16 kilobytes in size! mem = __static_tls; } else { - mem = __mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, - -1, 0); + // if a binary needs this much thread_local storage, then it + // surely must have linked the mmap() function at some point + // we can't call mmap() because it's too early for sig block + mem = _weaken(__mmap)(0, size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); } struct CosmoTib *tib = @@ -184,9 +189,8 @@ textstartup void __enable_tls(void) { size_t dtv_size = sizeof(uintptr_t) * 2; char *tdata = (char *)dtv + ROUNDUP(dtv_size, I(_tdata_align)); - if (I(_tdata_size)) { + if (I(_tdata_size)) memmove(tdata, _tdata_start, I(_tdata_size)); - } // Set the DTV. // @@ -251,9 +255,8 @@ textstartup void __enable_tls(void) { #ifdef __x86_64__ // rewrite the executable tls opcodes in memory - if (IsWindows() || IsOpenbsd() || IsNetbsd()) { + if (IsWindows() || IsOpenbsd() || IsNetbsd()) __morph_tls(); - } #endif // we are now allowed to use tls From d0cd7193754dea38c8a8a4f2586904001c99b13c Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Mon, 1 Jul 2024 07:10:35 -0700 Subject: [PATCH 024/405] Make more CTL fixes --- ctl/allocator_traits.h | 17 ++++---- ctl/string.h | 22 +++++++--- ctl/vector.h | 7 ++-- test/ctl/vector_test.cc | 91 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 122 insertions(+), 15 deletions(-) diff --git a/ctl/allocator_traits.h b/ctl/allocator_traits.h index 4873899f4..155a71bcf 100644 --- a/ctl/allocator_traits.h +++ b/ctl/allocator_traits.h @@ -11,12 +11,12 @@ struct allocator_traits { using allocator_type = Alloc; using value_type = typename Alloc::value_type; - using pointer = typename Alloc::pointer; - using const_pointer = typename Alloc::const_pointer; + using pointer = typename Alloc::value_type*; + using const_pointer = const typename Alloc::value_type*; using void_pointer = void*; using const_void_pointer = const void*; - using difference_type = typename Alloc::difference_type; - using size_type = typename Alloc::size_type; + using difference_type = ptrdiff_t; + using size_type = size_t; using propagate_on_container_copy_assignment = ctl::false_type; using propagate_on_container_move_assignment = ctl::true_type; @@ -24,10 +24,13 @@ struct allocator_traits using is_always_equal = ctl::true_type; template - using rebind_alloc = typename Alloc::template rebind::other; + struct rebind_alloc + { + using other = typename Alloc::template rebind::other; + }; template - using rebind_traits = allocator_traits>; + using rebind_traits = allocator_traits::other>; static pointer allocate(Alloc& a, size_type n) { @@ -53,7 +56,7 @@ struct allocator_traits static size_type max_size(const Alloc& a) noexcept { - return __PTRDIFF_MAX__ / sizeof(value_type); + return a.max_size(); } static Alloc select_on_container_copy_construction(const Alloc& a) diff --git a/ctl/string.h b/ctl/string.h index b2941588d..6c92d8f9f 100644 --- a/ctl/string.h +++ b/ctl/string.h @@ -332,6 +332,18 @@ class string return *this; } + string& operator+=(const char* s) noexcept + { + append(s); + return *this; + } + + string& operator+=(const ctl::string s) noexcept + { + append(s); + return *this; + } + string& operator+=(const ctl::string_view s) noexcept { append(s); @@ -344,6 +356,11 @@ class string return strcat(*this, s); } + string operator+(const char* s) const noexcept + { + return strcat(*this, s); + } + string operator+(const string& s) const noexcept { return strcat(*this, s); @@ -354,11 +371,6 @@ class string return strcat(*this, s); } - string operator+(const char* s) const noexcept - { - return strcat(*this, s); - } - int compare(const ctl::string_view s) const noexcept { return strcmp(*this, s); diff --git a/ctl/vector.h b/ctl/vector.h index 30861e27d..ce0cd5831 100644 --- a/ctl/vector.h +++ b/ctl/vector.h @@ -411,16 +411,17 @@ class vector return erase(pos, pos + 1); } - iterator erase(const_iterator first, const_iterator last) + constexpr iterator erase(const_iterator first, const_iterator last) { difference_type index = first - begin(); difference_type count = last - first; iterator it = begin() + index; - ctl::move(it + count, end(), it); + for (iterator move_it = it + count; move_it != end(); ++move_it, ++it) + *it = ctl::move(*move_it); for (difference_type i = 0; i < count; ++i) ctl::allocator_traits::destroy(alloc_, end() - i - 1); size_ -= count; - return it; + return begin() + index; } void push_back(const T& value) diff --git a/test/ctl/vector_test.cc b/test/ctl/vector_test.cc index 84469b2c0..d114c5445 100644 --- a/test/ctl/vector_test.cc +++ b/test/ctl/vector_test.cc @@ -24,6 +24,46 @@ // #include // #define ctl std +static int counter; + +// Test with non-trivial type +struct NonTrivial +{ + int value; + + NonTrivial(int v) : value(v) + { + ++counter; + } + + NonTrivial(const NonTrivial& other) : value(other.value) + { + ++counter; + } + + NonTrivial(NonTrivial&& other) noexcept : value(other.value) + { + ++counter; + } + + ~NonTrivial() + { + --counter; + } + + NonTrivial& operator=(const NonTrivial& other) + { + value = other.value; + return *this; + } + + NonTrivial& operator=(NonTrivial&& other) noexcept + { + value = other.value; + return *this; + } +}; + int main() { @@ -360,5 +400,56 @@ main() return 82; } + // Test erase(const_iterator first, const_iterator last) + { + ctl::vector v = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + + // Test erasing from the middle + auto it = v.erase(v.begin() + 3, v.begin() + 7); + if (v.size() != 6 || v != ctl::vector{ 1, 2, 3, 8, 9, 10 } || + it != v.begin() + 3) + return 83; + + // Test erasing from the beginning + it = v.erase(v.begin(), v.begin() + 2); + if (v.size() != 4 || v != ctl::vector{ 3, 8, 9, 10 } || + it != v.begin()) + return 84; + + // Test erasing to the end + it = v.erase(v.begin() + 2, v.end()); + if (v.size() != 2 || v != ctl::vector{ 3, 8 } || it != v.end()) + return 85; + + // Test erasing all elements + it = v.erase(v.begin(), v.end()); + if (!v.empty() || it != v.end()) + return 86; + + // Test erasing empty range + v = { 1, 2, 3, 4, 5 }; + it = v.erase(v.begin() + 2, v.begin() + 2); + if (v.size() != 5 || v != ctl::vector{ 1, 2, 3, 4, 5 } || + it != v.begin() + 2) + return 87; + + counter = 0; + + { + ctl::vector v2; + for (int i = 0; i < 10; ++i) + v2.emplace_back(i); + v2.erase(v2.begin() + 3, v2.begin() + 7); + if (v2.size() != 6 || counter != 6) + return 89; + for (int i = 0; i < (int)v2.size(); ++i) + if (v2[i].value != (i < 3 ? i : i + 4)) + return 90; + } + + if (counter != 0) + return 91; + } + CheckForMemoryLeaks(); } From 70f77aad3317b5b95f967733409be43e1ad54d37 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Mon, 1 Jul 2024 07:11:26 -0700 Subject: [PATCH 025/405] Release Cosmopolitan v3.5.4 --- libc/integral/normalize.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libc/integral/normalize.inc b/libc/integral/normalize.inc index 7d24c2763..176f35a6d 100644 --- a/libc/integral/normalize.inc +++ b/libc/integral/normalize.inc @@ -4,7 +4,7 @@ #define __COSMOPOLITAN_MAJOR__ 3 #define __COSMOPOLITAN_MINOR__ 5 -#define __COSMOPOLITAN_PATCH__ 3 +#define __COSMOPOLITAN_PATCH__ 4 #define __COSMOPOLITAN__ \ (100000000 * __COSMOPOLITAN_MAJOR__ + 1000000 * __COSMOPOLITAN_MINOR__ + \ __COSMOPOLITAN_PATCH__) From 6dbc3fba18fa0602bdc0a8cbb355aadd7001a815 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Thu, 4 Jul 2024 02:45:45 -0700 Subject: [PATCH 026/405] Add AMD cache sizes to o//tool/viz/cpuid --- tool/viz/cpuid.c | 99 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 88 insertions(+), 11 deletions(-) diff --git a/tool/viz/cpuid.c b/tool/viz/cpuid.c index 0384d4f30..a77cc7bdd 100644 --- a/tool/viz/cpuid.c +++ b/tool/viz/cpuid.c @@ -35,6 +35,15 @@ #define CANIUSE(FEATURE) caniuse(#FEATURE, X86_HAVE(FEATURE)) #define SHOW(CONSTANT) show(#CONSTANT, CONSTANT) +static void cpuid(unsigned leaf, unsigned subleaf, unsigned *eax, unsigned *ebx, + unsigned *ecx, unsigned *edx) { + asm("movq\t%%rbx,%%rsi\n\t" + "cpuid\n\t" + "xchgq\t%%rbx,%%rsi" + : "=a"(*eax), "=S"(*ebx), "=c"(*ecx), "=d"(*edx) + : "0"(leaf), "2"(subleaf)); +} + static void caniuse(const char *feature, bool present) { printf("%-20s%s%s%s\n", feature, present ? GREEN : RED, present ? "present" : "unavailable", RESET); @@ -70,7 +79,7 @@ static void showstrata(void) { } } -void showcachesizes(void) { +void showcachesizes_intel(void) { unsigned i; CPUID4_ITERATE(i, { printf("%-19s%s%s %2u-way %,9u byte cache w/%s %,6u sets of %u byte lines " @@ -90,6 +99,81 @@ void showcachesizes(void) { }); } +static const char *const kAmdAssociativityStr[16] = { + "Disabled", // + "1 way (direct mapped)", // + "2 way", // + "4 way", // + "8 way", // + "16 way", // + "32 way", // + "48 way", // + "64 way", // + "96 way", // + "128 way", // + "Fully Associative", // +}; + +void showcachesizes_amd() { + unsigned eax, ebx, ecx, edx; + + cpuid(0x80000005, 0, &eax, &ebx, &ecx, &edx); + + unsigned L1_dataCache_size = (ecx >> 24) & 0xff; + unsigned L1_dataCache_associativity = (ecx >> 16) & 0xff; + unsigned L1_dataCache_linesPerTag = (ecx >> 8) & 0xff; + unsigned L1_dataCache_lineSize = (ecx >> 0) & 0xff; + + unsigned L1_instrCache_size = (ecx >> 24) & 0xff; + unsigned L1_instrCache_associativity = (ecx >> 16) & 0xff; + unsigned L1_instrCache_linesPerTag = (ecx >> 8) & 0xff; + unsigned L1_instrCache_lineSize = (ecx >> 0) & 0xff; + + cpuid(0x80000006, 0, &eax, &ebx, &ecx, &edx); + + unsigned L2_size = (ecx >> 16) & 0xffff; + unsigned L2_associativity = (ecx >> 12) & 0xf; + unsigned L2_linesPerTag = (ecx >> 8) & 0xf; + unsigned L2_lineSize = (ecx >> 0) & 0xff; + + unsigned L3_size = (edx >> 18) & 0x3fff; + unsigned L3_associativity = (edx >> 12) & 0xf; + unsigned L3_linesPerTag = (edx >> 8) & 0xf; + unsigned L3_lineSize = (edx >> 0) & 0xff; + + printf("L1 Data Cache:\n" + "\tSize: %d KB\n" + "\tAssociativity: %d way\n" + "\tLines per Tag: %d\n" + "\tLine Size: %d B\n" + "\n" + "L1 Instruction Cache:\n" + "\tSize: %d KB\n" + "\tAssociativity: %d way\n" + "\tLines per Tag: %d\n" + "\tLine Size: %d B\n", + L1_dataCache_size, L1_dataCache_associativity, + L1_dataCache_linesPerTag, L1_dataCache_lineSize, L1_instrCache_size, + L1_instrCache_associativity, L1_instrCache_linesPerTag, + L1_instrCache_lineSize); + + printf("L2 Cache:\n" + "\tSize: %d KB\n" + "\tAssociativity: %s\n" + "\tLines per Tag: %d\n" + "\tLine Size: %d B\n" + "\n" + "L3 Cache:\n" + "\tSize: %d KB\n" + "\tAssociativity: %s\n" + "\tLines per Tag: %d\n" + "\tLine Size: %d B\n", + L2_size, kAmdAssociativityStr[L2_associativity & 15], L2_linesPerTag, + L2_lineSize, L3_size * 512, + kAmdAssociativityStr[L3_associativity & 15], L3_linesPerTag, + L3_lineSize); +} + int main(int argc, char *argv[]) { int x; long tsc_aux; @@ -146,7 +230,8 @@ int main(int argc, char *argv[]) { printf("\n"); printf("Caches\n"); printf("──────\n"); - showcachesizes(); + showcachesizes_intel(); + showcachesizes_amd(); printf("\n"); printf("Features\n"); @@ -163,15 +248,7 @@ int main(int argc, char *argv[]) { X86_HAVE(AVX2) ? "present" : "unavailable", RESET, (!X86_HAVE(AVX2) && ({ unsigned eax, ebx, ecx, edx; - asm("push\t%%rbx\n\t" - "cpuid\n\t" - "mov\t%%ebx,%1\n\t" - "pop\t%%rbx" - : "=a"(eax), "=rm"(ebx), "=c"(ecx), "=d"(edx) - : "0"(7), "2"(0)); - (void)eax; - (void)ecx; - (void)edx; + cpuid(7, 0, &eax, &ebx, &ecx, &edx); !!(ebx & (1u << 5)); })) ? " (disabled by operating system)" From 135d538b1da0463619da417763a2c00f5869e82d Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Thu, 4 Jul 2024 02:46:27 -0700 Subject: [PATCH 027/405] Make ctl::set use 30% less memory than libcxx --- ctl/set.h | 244 +++++++++++++++++++++++------------------- test/ctl/BUILD.mk | 1 + test/ctl/set_bench.cc | 92 ++++++++++++++++ 3 files changed, 225 insertions(+), 112 deletions(-) create mode 100644 test/ctl/set_bench.cc diff --git a/ctl/set.h b/ctl/set.h index ef7ee74bf..cc951b98c 100644 --- a/ctl/set.h +++ b/ctl/set.h @@ -13,18 +13,34 @@ class set { struct rbtree { - rbtree* left; + uintptr_t left_; rbtree* right; rbtree* parent; - bool is_red; Key value; + rbtree* left() const + { + return (rbtree*)(left_ & -2); + } + + void left(rbtree* val) + { + left_ = (uintptr_t)val | (left_ & 1); + } + + bool is_red() const + { + return left_ & 1; + } + + void is_red(bool val) + { + left_ &= -2; + left_ |= val; + } + rbtree(const Key& val) - : left(nullptr) - , right(nullptr) - , parent(nullptr) - , is_red(true) - , value(val) + : left_(1), right(nullptr), parent(nullptr), value(val) { } }; @@ -85,14 +101,14 @@ class set { if (node_ == nullptr) __builtin_trap(); - if (node_->left) { - node_ = rightmost(node_->left); + if (node_->left()) { + node_ = rightmost(node_->left()); } else { node_type* parent = node_->parent; for (;;) { if (parent == nullptr) break; - if (node_ == parent->left) { + if (node_ == parent->left()) { node_ = parent; parent = parent->parent; } else { @@ -161,11 +177,11 @@ class set reverse_iterator& operator++() { - if (node_->left) { - node_ = rightmost(node_->left); + if (node_->left()) { + node_ = rightmost(node_->left()); } else { node_type* parent = node_->parent; - while (parent && node_ == parent->left) { + while (parent && node_ == parent->left()) { node_ = parent; parent = parent->parent; } @@ -508,7 +524,7 @@ class set { size_type count = 0; if (root_ != nullptr) { - if (root_->is_red) + if (root_->is_red()) // ILLEGAL TREE: root node must be black __builtin_trap(); int black_height = -1; @@ -523,8 +539,8 @@ class set private: static node_type* leftmost(node_type* node) noexcept { - while (node && node->left) - node = node->left; + while (node && node->left()) + node = node->left(); return node; } @@ -535,35 +551,35 @@ class set return node; } - static void clearer(node_type* node) noexcept + static optimizesize void clearer(node_type* node) noexcept { node_type* right; for (; node; node = right) { right = node->right; - clearer(node->left); + clearer(node->left()); delete node; } } - static node_type* copier(const node_type* node) + static optimizesize node_type* copier(const node_type* node) { if (node == nullptr) return nullptr; node_type* new_node = new node_type(node->value); - new_node->left = copier(node->left); + new_node->left(copier(node->left())); new_node->right = copier(node->right); - if (new_node->left) - new_node->left->parent = new_node; + if (new_node->left()) + new_node->left()->parent = new_node; if (new_node->right) new_node->right->parent = new_node; return new_node; } - static size_type tally(const node_type* node) + static optimizesize size_type tally(const node_type* node) { if (node == nullptr) return 0; - return 1 + tally(node->left) + tally(node->right); + return 1 + tally(node->left()) + tally(node->right); } template @@ -572,7 +588,7 @@ class set node_type* current = root_; while (current != nullptr) { if (comp_(key, current->value)) { - current = current->left; + current = current->left(); } else if (comp_(current->value, key)) { current = current->right; } else { @@ -590,7 +606,7 @@ class set while (current != nullptr) { if (!comp_(current->value, key)) { result = current; - current = current->left; + current = current->left(); } else { current = current->right; } @@ -606,7 +622,7 @@ class set while (current != nullptr) { if (comp_(key, current->value)) { result = current; - current = current->left; + current = current->left(); } else { current = current->right; } @@ -614,11 +630,11 @@ class set return result; } - ctl::pair insert_node(node_type* node) + optimizesize ctl::pair insert_node(node_type* node) { if (root_ == nullptr) { root_ = node; - root_->is_red = false; + root_->is_red(false); size_++; return { iterator(root_), true }; } @@ -627,7 +643,7 @@ class set while (current != nullptr) { parent = current; if (comp_(node->value, current->value)) { - current = current->left; + current = current->left(); } else if (comp_(current->value, node->value)) { current = current->right; } else { @@ -636,7 +652,7 @@ class set } } if (comp_(node->value, parent->value)) { - parent->left = node; + parent->left(node); } else { parent->right = node; } @@ -646,23 +662,23 @@ class set return { iterator(node), true }; } - void erase_node(node_type* node) + optimizesize void erase_node(node_type* node) { node_type* y = node; node_type* x = nullptr; node_type* x_parent = nullptr; - bool y_original_color = y->is_red; - if (node->left == nullptr) { + bool y_original_color = y->is_red(); + if (node->left() == nullptr) { x = node->right; transplant(node, node->right); x_parent = node->parent; } else if (node->right == nullptr) { - x = node->left; - transplant(node, node->left); + x = node->left(); + transplant(node, node->left()); x_parent = node->parent; } else { y = leftmost(node->right); - y_original_color = y->is_red; + y_original_color = y->is_red(); x = y->right; if (y->parent == node) { if (x) @@ -675,9 +691,9 @@ class set x_parent = y->parent; } transplant(node, y); - y->left = node->left; - y->left->parent = y; - y->is_red = node->is_red; + y->left(node->left()); + y->left()->parent = y; + y->is_red(node->is_red()); } if (!y_original_color) rebalance_after_erase(x, x_parent); @@ -685,28 +701,28 @@ class set --size_; } - void left_rotate(node_type* x) + optimizesize void left_rotate(node_type* x) { node_type* y = x->right; - x->right = y->left; - if (y->left != nullptr) - y->left->parent = x; + x->right = y->left(); + if (y->left() != nullptr) + y->left()->parent = x; y->parent = x->parent; if (x->parent == nullptr) { root_ = y; - } else if (x == x->parent->left) { - x->parent->left = y; + } else if (x == x->parent->left()) { + x->parent->left(y); } else { x->parent->right = y; } - y->left = x; + y->left(x); x->parent = y; } - void right_rotate(node_type* y) + optimizesize void right_rotate(node_type* y) { - node_type* x = y->left; - y->left = x->right; + node_type* x = y->left(); + y->left(x->right); if (x->right != nullptr) x->right->parent = y; x->parent = y->parent; @@ -715,18 +731,18 @@ class set } else if (y == y->parent->right) { y->parent->right = x; } else { - y->parent->left = x; + y->parent->left(x); } x->right = y; y->parent = x; } - void transplant(node_type* u, node_type* v) + optimizesize void transplant(node_type* u, node_type* v) { if (u->parent == nullptr) { root_ = v; - } else if (u == u->parent->left) { - u->parent->left = v; + } else if (u == u->parent->left()) { + u->parent->left(v); } else { u->parent->right = v; } @@ -734,10 +750,10 @@ class set v->parent = u->parent; } - void checker(const node_type* node, - const node_type* parent, - int black_count, - int& black_height) const + optimizesize void checker(const node_type* node, + const node_type* parent, + int black_count, + int& black_height) const { if (node == nullptr) { // Leaf nodes are considered black @@ -753,117 +769,121 @@ class set // ILLEGAL TREE: Parent link is incorrect __builtin_trap(); if (parent) { - if (parent->left == node && !comp_(node->value, parent->value)) + if (parent->left() == node && !comp_(node->value, parent->value)) // ILLEGAL TREE: Binary search property violated on left child __builtin_trap(); if (parent->right == node && !comp_(parent->value, node->value)) // ILLEGAL TREE: Binary search property violated on right child __builtin_trap(); } - if (!node->is_red) { + if (!node->is_red()) { black_count++; - } else if (parent != nullptr && parent->is_red) { + } else if (parent != nullptr && parent->is_red()) { // ILLEGAL TREE: Red node has red child __builtin_trap(); } - checker(node->left, node, black_count, black_height); + checker(node->left(), node, black_count, black_height); checker(node->right, node, black_count, black_height); } - void rebalance_after_insert(node_type* node) + optimizesize void rebalance_after_insert(node_type* node) { - node->is_red = true; - while (node != root_ && node->parent->is_red) { - if (node->parent == node->parent->parent->left) { + node->is_red(true); + while (node != root_ && node->parent->is_red()) { + if (node->parent == node->parent->parent->left()) { node_type* uncle = node->parent->parent->right; - if (uncle && uncle->is_red) { - node->parent->is_red = false; - uncle->is_red = false; - node->parent->parent->is_red = true; + if (uncle && uncle->is_red()) { + node->parent->is_red(false); + uncle->is_red(false); + node->parent->parent->is_red(true); node = node->parent->parent; } else { if (node == node->parent->right) { node = node->parent; left_rotate(node); } - node->parent->is_red = false; - node->parent->parent->is_red = true; + node->parent->is_red(false); + node->parent->parent->is_red(true); right_rotate(node->parent->parent); } } else { - node_type* uncle = node->parent->parent->left; - if (uncle && uncle->is_red) { - node->parent->is_red = false; - uncle->is_red = false; - node->parent->parent->is_red = true; + node_type* uncle = node->parent->parent->left(); + if (uncle && uncle->is_red()) { + node->parent->is_red(false); + uncle->is_red(false); + node->parent->parent->is_red(true); node = node->parent->parent; } else { - if (node == node->parent->left) { + if (node == node->parent->left()) { node = node->parent; right_rotate(node); } - node->parent->is_red = false; - node->parent->parent->is_red = true; + node->parent->is_red(false); + node->parent->parent->is_red(true); left_rotate(node->parent->parent); } } } - root_->is_red = false; + root_->is_red(false); } - void rebalance_after_erase(node_type* node, node_type* parent) + optimizesize void rebalance_after_erase(node_type* node, node_type* parent) { - while (node != root_ && (node == nullptr || !node->is_red)) { - if (node == parent->left) { + while (node != root_ && (node == nullptr || !node->is_red())) { + if (node == parent->left()) { node_type* sibling = parent->right; - if (sibling->is_red) { - sibling->is_red = false; - parent->is_red = true; + if (sibling->is_red()) { + sibling->is_red(false); + parent->is_red(true); left_rotate(parent); sibling = parent->right; } - if ((sibling->left == nullptr || !sibling->left->is_red) && - (sibling->right == nullptr || !sibling->right->is_red)) { - sibling->is_red = true; + if ((sibling->left() == nullptr || + !sibling->left()->is_red()) && + (sibling->right == nullptr || !sibling->right->is_red())) { + sibling->is_red(true); node = parent; parent = node->parent; } else { - if (sibling->right == nullptr || !sibling->right->is_red) { - sibling->left->is_red = false; - sibling->is_red = true; + if (sibling->right == nullptr || + !sibling->right->is_red()) { + sibling->left()->is_red(false); + sibling->is_red(true); right_rotate(sibling); sibling = parent->right; } - sibling->is_red = parent->is_red; - parent->is_red = false; - sibling->right->is_red = false; + sibling->is_red(parent->is_red()); + parent->is_red(false); + sibling->right->is_red(false); left_rotate(parent); node = root_; break; } } else { - node_type* sibling = parent->left; - if (sibling->is_red) { - sibling->is_red = false; - parent->is_red = true; + node_type* sibling = parent->left(); + if (sibling->is_red()) { + sibling->is_red(false); + parent->is_red(true); right_rotate(parent); - sibling = parent->left; + sibling = parent->left(); } - if ((sibling->right == nullptr || !sibling->right->is_red) && - (sibling->left == nullptr || !sibling->left->is_red)) { - sibling->is_red = true; + if ((sibling->right == nullptr || !sibling->right->is_red()) && + (sibling->left() == nullptr || + !sibling->left()->is_red())) { + sibling->is_red(true); node = parent; parent = node->parent; } else { - if (sibling->left == nullptr || !sibling->left->is_red) { - sibling->right->is_red = false; - sibling->is_red = true; + if (sibling->left() == nullptr || + !sibling->left()->is_red()) { + sibling->right->is_red(false); + sibling->is_red(true); left_rotate(sibling); - sibling = parent->left; + sibling = parent->left(); } - sibling->is_red = parent->is_red; - parent->is_red = false; - sibling->left->is_red = false; + sibling->is_red(parent->is_red()); + parent->is_red(false); + sibling->left()->is_red(false); right_rotate(parent); node = root_; break; @@ -871,7 +891,7 @@ class set } } if (node != nullptr) - node->is_red = false; + node->is_red(false); } node_type* root_; diff --git a/test/ctl/BUILD.mk b/test/ctl/BUILD.mk index 97562343e..6b36e766d 100644 --- a/test/ctl/BUILD.mk +++ b/test/ctl/BUILD.mk @@ -18,6 +18,7 @@ TEST_CTL_DIRECTDEPS = \ LIBC_LOG \ LIBC_MEM \ LIBC_NEXGEN32E \ + LIBC_PROC \ LIBC_STDIO \ LIBC_STDIO \ LIBC_THREAD \ diff --git a/test/ctl/set_bench.cc b/test/ctl/set_bench.cc new file mode 100644 index 000000000..4c565848e --- /dev/null +++ b/test/ctl/set_bench.cc @@ -0,0 +1,92 @@ +// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +// +// Copyright 2024 Justine Alexandra Roberts Tunney +// +// Permission to use, copy, modify, and/or distribute this software for +// any purpose with or without fee is hereby granted, provided that the +// above copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include "ctl/set.h" +#include "libc/calls/struct/rusage.h" +#include "libc/calls/struct/timespec.h" +#include "libc/mem/leaks.h" +#include "libc/stdio/stdio.h" +#include "libc/sysv/consts/rusage.h" + +// #include +// #define ctl std +// #define check() size() + +#define BENCH(ITERATIONS, WORK_PER_RUN, CODE) \ + do { \ + struct timespec start = timespec_real(); \ + for (int __i = 0; __i < ITERATIONS; ++__i) { \ + asm volatile("" ::: "memory"); \ + CODE; \ + } \ + long long work = (WORK_PER_RUN) * (ITERATIONS); \ + double nanos = \ + (timespec_tonanos(timespec_sub(timespec_real(), start)) + work - \ + 1) / \ + (double)work; \ + printf("%10g ns %2dx %s\n", nanos, (ITERATIONS), #CODE); \ + } while (0) + +int +rand32(void) +{ + /* Knuth, D.E., "The Art of Computer Programming," Vol 2, + Seminumerical Algorithms, Third Edition, Addison-Wesley, 1998, + p. 106 (line 26) & p. 108 */ + static unsigned long long lcg = 1; + lcg *= 6364136223846793005; + lcg += 1442695040888963407; + return lcg >> 32; +} + +void +eat(int x) +{ +} + +void (*pEat)(int) = eat; + +int +main() +{ + + { + long x = 0; + ctl::set s; + BENCH(1000000, 1, s.insert(rand32() % 1000000)); + // s.check(); + BENCH(1000000, 1, { + auto i = s.find(rand32() % 1000000); + if (i != s.end()) + x += *i; + }); + BENCH(1000000, 1, { + auto i = s.lower_bound(rand32() % 1000000); + if (i != s.end()) + x += *i; + }); + BENCH(1000000, 1, s.erase(rand32() % 1000000)); + eat(x); + } + + struct rusage ru; + getrusage(RUSAGE_SELF, &ru); + printf("%,10d kb peak rss\n", ru.ru_maxrss); + + CheckForMemoryLeaks(); +} From fdab49b30ed53a698767ae3d4d9f0f95c26c2f30 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Thu, 4 Jul 2024 02:46:54 -0700 Subject: [PATCH 028/405] Demonstrate signal safety of recursive mutexes --- test/posix/exit_async_signal_safety_test.c | 30 ++++++++ test/posix/mutex_async_signal_safety_test.c | 82 +++++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 test/posix/exit_async_signal_safety_test.c create mode 100644 test/posix/mutex_async_signal_safety_test.c diff --git a/test/posix/exit_async_signal_safety_test.c b/test/posix/exit_async_signal_safety_test.c new file mode 100644 index 000000000..2eaa65192 --- /dev/null +++ b/test/posix/exit_async_signal_safety_test.c @@ -0,0 +1,30 @@ +#include +#include +#include +#include + +atomic_bool ready; + +void* work(void* arg) { + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0); + ready = true; + pthread_exit(0); +} + +int main() { + + for (int i = 0; i < 1000; ++i) { + pthread_t th; + if (pthread_create(&th, 0, work, 0)) + _Exit(1); + for (;;) + if (ready) + break; + pthread_cancel(th); + if (pthread_join(th, 0)) + _Exit(3); + } + + while (!pthread_orphan_np()) + pthread_decimate_np(); +} diff --git a/test/posix/mutex_async_signal_safety_test.c b/test/posix/mutex_async_signal_safety_test.c new file mode 100644 index 000000000..d9da7b6bc --- /dev/null +++ b/test/posix/mutex_async_signal_safety_test.c @@ -0,0 +1,82 @@ +#include +#include +#include +#include +#include +#include + +// tests that recursive mutexes are implemented atomically +// +// glibc fails this test + +atomic_bool done; +atomic_bool ready; +pthread_mutex_t lock; + +void hand(int sig) { + if (pthread_mutex_lock(&lock)) + _Exit(50); + if (pthread_mutex_unlock(&lock)) + _Exit(51); +} + +void* work(void* arg) { + ready = true; + while (!done) { + if (pthread_mutex_lock(&lock)) + _Exit(60); + if (pthread_mutex_unlock(&lock)) + _Exit(61); + } + return 0; +} + +int main() { + + struct sigaction sa; + sa.sa_handler = hand; + sa.sa_flags = SA_NODEFER; + sigemptyset(&sa.sa_mask); + if (sigaction(SIGUSR1, &sa, 0)) + _Exit(1); + + pthread_mutexattr_t attr; + if (pthread_mutexattr_init(&attr)) + _Exit(2); + if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) + _Exit(3); + if (pthread_mutex_init(&lock, &attr)) + _Exit(4); + if (pthread_mutexattr_destroy(&attr)) + _Exit(5); + + pthread_t th; + pthread_attr_t tattr; + if (pthread_attr_init(&tattr)) + _Exit(6); + if (pthread_attr_setstacksize(&tattr, 8 * 1024 * 1024)) + _Exit(7); + if (pthread_attr_setguardsize(&tattr, 64 * 1024)) + _Exit(8); + if (pthread_create(&th, &tattr, work, 0)) + _Exit(9); + if (pthread_attr_destroy(&tattr)) + _Exit(10); + for (;;) + if (ready) + break; + + for (int i = 0; i < 1000; ++i) { + if (pthread_kill(th, SIGUSR1)) + _Exit(11); + if (pthread_kill(th, SIGUSR1)) + _Exit(12); + usleep(1); + } + + done = true; + if (pthread_join(th, 0)) + _Exit(13); + if (pthread_mutex_destroy(&lock)) + _Exit(14); +} From 15ea0524b386cee14a6f27f79927cb912fa5cdd1 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Thu, 4 Jul 2024 02:50:20 -0700 Subject: [PATCH 029/405] Reduce code size of mandatory runtime This change reduces o/tiny/examples/life from 44kb to 24kb in size since it avoids linking mmap() when unnecessary. This is important, to helping cosmo not completely lose touch with its roots. --- libc/calls/sig.c | 7 +- libc/calls/sig.internal.h | 3 +- libc/calls/sigcrashsig.c | 159 +++++++++++++++-------------- libc/intrin/__getauxval.c | 6 +- libc/intrin/g_fds.c | 3 +- libc/intrin/gettid.c | 3 +- libc/intrin/maps.c | 36 +++++-- libc/intrin/maps.h | 2 + libc/intrin/mmap.c | 5 +- libc/intrin/pthreadlock.c | 10 +- libc/proc/BUILD.mk | 2 +- libc/proc/fork-nt.c | 1 - libc/proc/fork.c | 21 ++-- libc/runtime/winmain.greg.c | 21 ++-- libc/thread/posixthread.internal.h | 1 - libc/thread/pthread_exit.c | 33 +++--- third_party/nsync/common.c | 14 +-- 17 files changed, 164 insertions(+), 163 deletions(-) diff --git a/libc/calls/sig.c b/libc/calls/sig.c index c1ce797fb..21f321223 100644 --- a/libc/calls/sig.c +++ b/libc/calls/sig.c @@ -81,14 +81,11 @@ textwindows void __sig_delete(int sig) { struct Dll *e; atomic_fetch_and_explicit(&__sig.pending, ~(1ull << (sig - 1)), memory_order_relaxed); - BLOCK_SIGNALS; _pthread_lock(); - for (e = dll_last(_pthread_list); e; e = dll_prev(_pthread_list, e)) { + for (e = dll_last(_pthread_list); e; e = dll_prev(_pthread_list, e)) atomic_fetch_and_explicit(&POSIXTHREAD_CONTAINER(e)->tib->tib_sigpending, ~(1ull << (sig - 1)), memory_order_relaxed); - } _pthread_unlock(); - ALLOW_SIGNALS; } static textwindows int __sig_getter(atomic_ulong *sigs, sigset_t masked) { @@ -559,7 +556,7 @@ void __stack_call(struct NtExceptionPointers *, int, int, struct CosmoTib *, __msabi dontinstrument unsigned __sig_crash(struct NtExceptionPointers *ep) { // translate win32 to unix si_signo and si_code - int code, sig = __sig_crash_sig(ep, &code); + int code, sig = __sig_crash_sig(ep->ExceptionRecord->ExceptionCode, &code); // advance the instruction pointer to skip over debugger breakpoints // this behavior is consistent with how unix kernels are implemented diff --git a/libc/calls/sig.internal.h b/libc/calls/sig.internal.h index 4175194f0..48566f303 100644 --- a/libc/calls/sig.internal.h +++ b/libc/calls/sig.internal.h @@ -1,7 +1,6 @@ #ifndef COSMOPOLITAN_LIBC_CALLS_SIGNALS_INTERNAL_H_ #define COSMOPOLITAN_LIBC_CALLS_SIGNALS_INTERNAL_H_ #include "libc/calls/struct/sigset.h" -#include "libc/nt/struct/ntexceptionpointers.h" #include "libc/thread/posixthread.internal.h" #define SIG_HANDLED_NO_RESTART 1 @@ -18,7 +17,7 @@ extern struct Signals __sig; bool __sig_ignored(int); int __sig_check(void); -int __sig_crash_sig(struct NtExceptionPointers *, int *); +int __sig_crash_sig(unsigned, int *); int __sig_get(sigset_t); int __sig_kill(struct PosixThread *, int, int); int __sig_mask(int, const sigset_t *, sigset_t *); diff --git a/libc/calls/sigcrashsig.c b/libc/calls/sigcrashsig.c index 27d710a5d..e48eeab3f 100644 --- a/libc/calls/sigcrashsig.c +++ b/libc/calls/sigcrashsig.c @@ -18,6 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/sig.internal.h" #include "libc/intrin/pushpop.internal.h" +#include "libc/macros.internal.h" #include "libc/nt/enum/signal.h" #include "libc/nt/enum/status.h" #include "libc/nt/struct/ntexceptionpointers.h" @@ -26,82 +27,90 @@ // so, we trade away maintanibility for tininess // see libc/sysv/consts.sh for canonical magnums -#define SIGILL_ pushpop(4) -#define SIGTRAP_ pushpop(5) -#define SIGABRT_ pushpop(6) -#define SIGFPE_ pushpop(8) -#define SIGSEGV_ pushpop(11) -#define SIGSYS_ pushpop(31) +#define SIGILL_ 4 +#define SIGTRAP_ 5 +#define SIGABRT_ 6 +#define SIGFPE_ 8 +#define SIGSEGV_ 11 +#define SIGSYS_ 31 -#define TRAP_BRKPT_ pushpop(1) -#define ILL_ILLOPC_ pushpop(1) -#define ILL_PRVOPC_ pushpop(5) -#define SEGV_MAPERR_ pushpop(1) -#define SEGV_ACCERR_ pushpop(2) -#define SI_USER_ pushpop(0) -#define FPE_FLTDIV_ pushpop(3) -#define FPE_FLTOVF_ pushpop(4) -#define FPE_INTOVF_ pushpop(2) -#define FPE_FLTUND_ pushpop(5) -#define FPE_FLTRES_ pushpop(6) -#define FPE_FLTINV_ pushpop(7) -#define SI_KERNEL_ 0x80 +#define TRAP_BRKPT_ 1 +#define ILL_ILLOPC_ 1 +#define ILL_PRVOPC_ 5 +#define SEGV_MAPERR_ 1 +#define SEGV_ACCERR_ 2 +#define SI_USER_ 0 +#define FPE_FLTDIV_ 3 +#define FPE_FLTOVF_ 4 +#define FPE_INTOVF_ 2 +#define FPE_FLTUND_ 5 +#define FPE_FLTRES_ 6 +#define FPE_FLTINV_ 7 +#define SI_KERNEL_ 128 -textwindows int __sig_crash_sig(struct NtExceptionPointers *ep, int *code) { - switch (ep->ExceptionRecord->ExceptionCode) { - case kNtSignalBreakpoint: - *code = TRAP_BRKPT_; - return SIGTRAP_; - case kNtSignalIllegalInstruction: - *code = ILL_ILLOPC_; - return SIGILL_; - case kNtSignalPrivInstruction: - *code = ILL_PRVOPC_; - return SIGILL_; - case kNtSignalInPageError: - case kNtStatusStackOverflow: - *code = SEGV_MAPERR_; - return SIGSEGV_; - case kNtSignalGuardPage: - case kNtSignalAccessViolation: - *code = SEGV_ACCERR_; - return SIGSEGV_; - case kNtSignalInvalidHandle: - case kNtSignalInvalidParameter: - case kNtSignalAssertionFailure: - *code = SI_USER_; - return SIGABRT_; - case kNtStatusIntegerOverflow: - *code = FPE_INTOVF_; - return SIGFPE_; - case kNtSignalFltDivideByZero: - *code = FPE_FLTDIV_; - return SIGFPE_; - case kNtSignalFltOverflow: - *code = FPE_FLTOVF_; - return SIGFPE_; - case kNtSignalFltUnderflow: - *code = FPE_FLTUND_; - return SIGFPE_; - case kNtSignalFltInexactResult: - *code = FPE_FLTRES_; - return SIGFPE_; - case kNtSignalFltDenormalOperand: - case kNtSignalFltInvalidOperation: - case kNtSignalFltStackCheck: - case kNtSignalIntegerDivideByZero: - case kNtSignalFloatMultipleFaults: - case kNtSignalFloatMultipleTraps: - *code = FPE_FLTINV_; - return SIGFPE_; - case kNtSignalDllNotFound: - case kNtSignalOrdinalNotFound: - case kNtSignalEntrypointNotFound: - case kNtSignalDllInitFailed: - *code = SI_KERNEL_; - return SIGSYS_; - default: - *code = ep->ExceptionRecord->ExceptionCode; - return SIGSEGV_; +#define LO(x) (x & 255) +#define HI(x) ((x >> 24) / !(x & 0x00ffff00u)) +#define ROW(x, sic, sig) \ + { \ + { \ + { \ + LO(x), HI(x), sic / !(sic & 0xffffff00), sig / !(sig & 0xffffff00) \ + } \ + } \ } + +struct CrashSig { + union { + struct { + unsigned char lo; + unsigned char hi; + unsigned char sic; + unsigned char sig; + }; + unsigned word; + }; +}; + +static const struct CrashSig kNtCrashSigs[] = { + ROW(kNtSignalBreakpoint, TRAP_BRKPT_, SIGTRAP_), // + ROW(kNtSignalIllegalInstruction, ILL_ILLOPC_, SIGILL_), // + ROW(kNtSignalPrivInstruction, ILL_PRVOPC_, SIGILL_), // + ROW(kNtSignalInPageError, SEGV_MAPERR_, SIGSEGV_), // + ROW(kNtStatusStackOverflow, SEGV_MAPERR_, SIGSEGV_), // + ROW(kNtSignalGuardPage, SEGV_ACCERR_, SIGSEGV_), // + ROW(kNtSignalAccessViolation, SEGV_ACCERR_, SIGSEGV_), // + ROW(kNtSignalInvalidHandle, SI_USER_, SIGABRT_), // + ROW(kNtSignalInvalidParameter, SI_USER_, SIGABRT_), // + ROW(kNtStatusIntegerOverflow, FPE_INTOVF_, SIGFPE_), // + ROW(kNtSignalFltDivideByZero, FPE_FLTDIV_, SIGFPE_), // + ROW(kNtSignalFltOverflow, FPE_FLTOVF_, SIGFPE_), // + ROW(kNtSignalFltUnderflow, FPE_FLTUND_, SIGFPE_), // + ROW(kNtSignalFltInexactResult, FPE_FLTRES_, SIGFPE_), // + ROW(kNtSignalFltDenormalOperand, FPE_FLTINV_, SIGFPE_), // + ROW(kNtSignalFltInvalidOperation, FPE_FLTINV_, SIGFPE_), // + ROW(kNtSignalFltStackCheck, FPE_FLTINV_, SIGFPE_), // + ROW(kNtSignalIntegerDivideByZero, FPE_FLTINV_, SIGFPE_), // + // ROW(kNtSignalAssertionFailure, SI_USER_, SIGABRT_), + // ROW(kNtSignalFloatMultipleTraps, FPE_FLTINV_, SIGFPE_), + // ROW(kNtSignalFloatMultipleFaults, FPE_FLTINV_, SIGFPE_), + // ROW(kNtSignalDllNotFound, SI_KERNEL_, SIGSYS_), + // ROW(kNtSignalOrdinalNotFound, SI_KERNEL_, SIGSYS_), + // ROW(kNtSignalEntrypointNotFound, SI_KERNEL_, SIGSYS_), + // ROW(kNtSignalDllInitFailed, SI_KERNEL_, SIGSYS_), +}; + +textwindows dontinstrument int __sig_crash_sig(unsigned exception, int *code) { + for (int i = 0; i < ARRAYLEN(kNtCrashSigs); ++i) { + struct CrashSig cs; + cs.word = kNtCrashSigs[i].word; + unsigned lo = cs.lo; + unsigned hi = cs.hi; + unsigned ec = lo | hi << 24; + if (ec == exception) { + *code = cs.sic; + return cs.sig; + } + } + *code = exception; + return SIGSEGV_; } diff --git a/libc/intrin/__getauxval.c b/libc/intrin/__getauxval.c index 58447b7ee..277cd1142 100644 --- a/libc/intrin/__getauxval.c +++ b/libc/intrin/__getauxval.c @@ -30,10 +30,8 @@ */ struct AuxiliaryValue __getauxval(unsigned long at) { unsigned long *ap; - for (ap = __auxv; ap[0]; ap += 2) { - if (at == ap[0]) { + for (ap = __auxv; ap && ap[0]; ap += 2) + if (at == ap[0]) return (struct AuxiliaryValue){ap[1], true}; - } - } return (struct AuxiliaryValue){0, false}; } diff --git a/libc/intrin/g_fds.c b/libc/intrin/g_fds.c index b9f54a491..addae54ad 100644 --- a/libc/intrin/g_fds.c +++ b/libc/intrin/g_fds.c @@ -143,7 +143,8 @@ textstartup void __init_fds(int argc, char **argv, char **envp) { break; if (!TokAtoi(&fdspec, &protocol)) break; - __ensurefds_unlocked(fd); + if (_weaken(__ensurefds_unlocked)) + _weaken(__ensurefds_unlocked)(fd); struct Fd *f = fds->p + fd; if (f->handle && f->handle != -1 && f->handle != handle) { CloseHandle(f->handle); diff --git a/libc/intrin/gettid.c b/libc/intrin/gettid.c index 91b37737f..6c5b0c9de 100644 --- a/libc/intrin/gettid.c +++ b/libc/intrin/gettid.c @@ -40,9 +40,8 @@ int gettid(void) { int tid; if (VERY_LIKELY(__tls_enabled && !__vforked)) { tid = atomic_load_explicit(&__get_tls()->tib_tid, memory_order_acquire); - if (VERY_LIKELY(tid > 0)) { + if (VERY_LIKELY(tid > 0)) return tid; - } } if (IsXnuSilicon()) { return enosys(); // can only happen if we can't access thread local storage diff --git a/libc/intrin/maps.c b/libc/intrin/maps.c index a6618f19d..7803f8cb9 100644 --- a/libc/intrin/maps.c +++ b/libc/intrin/maps.c @@ -31,35 +31,51 @@ __static_yoink("_init_maps"); struct Maps __maps; +void __maps_add(struct Map *map) { + dll_init(&map->elem); + dll_make_first(&__maps.used, &map->elem); + map->next = __maps.maps; + __maps.maps = map; + ++__maps.count; +} + +static void __maps_adder(struct Map *map, int pagesz) { + __maps.pages += ((map->size + pagesz - 1) & -pagesz) / pagesz; + __maps_add(map); +} + +void __maps_stack(void *stackaddr, int pagesz, size_t stacksize, int stackprot, + intptr_t stackhand) { + __maps.stack.addr = stackaddr; + __maps.stack.size = stacksize; + __maps.stack.prot = stackprot; + __maps.stack.h = stackhand; + __maps_adder(&__maps.stack, pagesz); +} + void __maps_init(void) { + int pagesz = getauxval(AT_PAGESZ); // record _start() stack mapping if (!IsWindows()) { struct AddrSize stack; stack = __get_main_stack(); - dll_init(&__maps.stack.elem); - __maps.stack.addr = stack.addr; - __maps.stack.size = stack.size; - __maps.stack.prot = (uintptr_t)ape_stack_prot; - __maps_insert(&__maps.stack); + __maps_stack(stack.addr, pagesz, stack.size, (uintptr_t)ape_stack_prot, 0); } // record .text and .data mappings static struct Map text, data; - dll_init(&text.elem); text.addr = (char *)__executable_start; text.size = _etext - __executable_start; text.prot = PROT_READ | PROT_EXEC; - int pagesz = getauxval(AT_PAGESZ); uintptr_t ds = ((uintptr_t)_etext + pagesz - 1) & -pagesz; if (ds < (uintptr_t)_end) { - dll_init(&data.elem); data.addr = (char *)ds; data.size = (uintptr_t)_end - ds; data.prot = PROT_READ | PROT_WRITE; - __maps_insert(&data); + __maps_adder(&data, pagesz); } - __maps_insert(&text); + __maps_adder(&text, pagesz); } privileged void __maps_lock(void) { diff --git a/libc/intrin/maps.h b/libc/intrin/maps.h index 97d160fbd..8527825ea 100644 --- a/libc/intrin/maps.h +++ b/libc/intrin/maps.h @@ -43,11 +43,13 @@ void __maps_init(void); void __maps_lock(void); void __maps_check(void); void __maps_unlock(void); +void __maps_add(struct Map *); struct Map *__maps_alloc(void); void __maps_free(struct Map *); void __maps_insert(struct Map *); int __munmap(char *, size_t, bool); void *__mmap(char *, size_t, int, int, int, int64_t); +void __maps_stack(void *, int, size_t, int, intptr_t); struct AddrSize __get_main_stack(void); COSMOPOLITAN_C_END_ diff --git a/libc/intrin/mmap.c b/libc/intrin/mmap.c index e71fb2b1e..cd2ddb69f 100644 --- a/libc/intrin/mmap.c +++ b/libc/intrin/mmap.c @@ -144,10 +144,7 @@ void __maps_insert(struct Map *map) { dll_make_first(&__maps.used, &last->elem); __maps_free(map); } else { - dll_make_first(&__maps.used, &map->elem); - map->next = __maps.maps; - __maps.maps = map; - ++__maps.count; + __maps_add(map); } __maps_check(); } diff --git a/libc/intrin/pthreadlock.c b/libc/intrin/pthreadlock.c index 3fd1d564a..dccad6479 100644 --- a/libc/intrin/pthreadlock.c +++ b/libc/intrin/pthreadlock.c @@ -18,16 +18,12 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/thread/posixthread.internal.h" -pthread_spinlock_t _pthread_lock_obj; - -void _pthread_init(void) { - (void)pthread_spin_init(&_pthread_lock_obj, 0); -} +pthread_mutex_t _pthread_lock_obj = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; void _pthread_lock(void) { - pthread_spin_lock(&_pthread_lock_obj); + pthread_mutex_lock(&_pthread_lock_obj); } void _pthread_unlock(void) { - pthread_spin_unlock(&_pthread_lock_obj); + pthread_mutex_unlock(&_pthread_lock_obj); } diff --git a/libc/proc/BUILD.mk b/libc/proc/BUILD.mk index 5c50271d5..1ddefad2b 100644 --- a/libc/proc/BUILD.mk +++ b/libc/proc/BUILD.mk @@ -35,7 +35,7 @@ LIBC_PROC_A_DIRECTDEPS = \ LIBC_STR \ LIBC_SYSV \ LIBC_SYSV_CALLS \ - THIRD_PARTY_NSYNC + THIRD_PARTY_NSYNC \ LIBC_PROC_A_DEPS := \ $(call uniq,$(foreach x,$(LIBC_PROC_A_DIRECTDEPS),$($(x)))) diff --git a/libc/proc/fork-nt.c b/libc/proc/fork-nt.c index c4b14b60e..149711409 100644 --- a/libc/proc/fork-nt.c +++ b/libc/proc/fork-nt.c @@ -67,7 +67,6 @@ #ifdef __x86_64__ extern long __klog_handle; -extern atomic_uint free_waiters_mu; void WipeKeystrokes(void); __msabi extern typeof(GetCurrentProcessId) *const __imp_GetCurrentProcessId; diff --git a/libc/proc/fork.c b/libc/proc/fork.c index 8bbdc8963..05431bcb5 100644 --- a/libc/proc/fork.c +++ b/libc/proc/fork.c @@ -45,7 +45,8 @@ #include "libc/thread/posixthread.internal.h" #include "libc/thread/tls.h" -extern atomic_uint free_waiters_mu; +extern pthread_mutex_t nsync_waiters_mu; +extern pthread_mutex_t _pthread_lock_obj; static void _onfork_prepare(void) { if (_weaken(_pthread_onfork_prepare)) @@ -53,12 +54,11 @@ static void _onfork_prepare(void) { _pthread_lock(); __maps_lock(); __fds_lock(); - while (atomic_exchange_explicit(&free_waiters_mu, 1, memory_order_acquire)) { - } + pthread_mutex_lock(&nsync_waiters_mu); } static void _onfork_parent(void) { - atomic_store_explicit(&free_waiters_mu, 0, memory_order_release); + pthread_mutex_unlock(&nsync_waiters_mu); __fds_unlock(); __maps_unlock(); _pthread_unlock(); @@ -67,13 +67,9 @@ static void _onfork_parent(void) { } static void _onfork_child(void) { - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&__fds_lock_obj, &attr); - atomic_store_explicit(&free_waiters_mu, 0, memory_order_relaxed); - pthread_mutexattr_destroy(&attr); - _pthread_init(); + __fds_lock_obj = (pthread_mutex_t)PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; + nsync_waiters_mu = (pthread_mutex_t)PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; + _pthread_lock_obj = (pthread_mutex_t)PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; atomic_store_explicit(&__maps.lock, 0, memory_order_relaxed); atomic_store_explicit(&__get_tls()->tib_relock_maps, 0, memory_order_relaxed); if (_weaken(_pthread_onfork_child)) @@ -138,9 +134,8 @@ int _fork(uint32_t dwCreationFlags) { atomic_store_explicit(&pt->pt_canceled, false, memory_order_relaxed); // run user fork callbacks - if (__threaded) { + if (__threaded) _onfork_child(); - } STRACE("fork() β†’ 0 (child of %d)", parent); } else { // this is the parent process diff --git a/libc/runtime/winmain.greg.c b/libc/runtime/winmain.greg.c index 1d92f976a..f803162e2 100644 --- a/libc/runtime/winmain.greg.c +++ b/libc/runtime/winmain.greg.c @@ -159,7 +159,7 @@ static bool32 HasEnvironmentVariable(const char16_t *name) { } static abi unsigned OnWinCrash(struct NtExceptionPointers *ep) { - int code, sig = __sig_crash_sig(ep, &code); + int code, sig = __sig_crash_sig(ep->ExceptionRecord->ExceptionCode, &code); TerminateThisProcess(sig); } @@ -194,28 +194,23 @@ static abi wontreturn void WinInit(const char16_t *cmdline) { __imp_AddVectoredExceptionHandler(true, (void *)OnWinCrash); // allocate memory for stack and argument block + intptr_t stackhand; char *stackaddr = (char *)GetStaticStackAddr(0); size_t stacksize = GetStaticStackSize(); __imp_MapViewOfFileEx( - (__maps.stack.h = __imp_CreateFileMappingW( - -1, 0, kNtPageExecuteReadwrite, stacksize >> 32, stacksize, NULL)), + (stackhand = __imp_CreateFileMappingW(-1, 0, kNtPageExecuteReadwrite, + stacksize >> 32, stacksize, NULL)), kNtFileMapWrite | kNtFileMapExecute, 0, 0, stacksize, stackaddr); - int prot = (intptr_t)ape_stack_prot; - if (~prot & PROT_EXEC) { + int stackprot = (intptr_t)ape_stack_prot; + if (~stackprot & PROT_EXEC) { uint32_t old; __imp_VirtualProtect(stackaddr, stacksize, kNtPageReadwrite, &old); } uint32_t oldattr; __imp_VirtualProtect(stackaddr, GetGuardSize(), kNtPageReadwrite | kNtPageGuard, &oldattr); - __maps.stack.addr = stackaddr; - __maps.stack.size = stacksize; - __maps.stack.prot = prot; - __maps.maps = &__maps.stack; - __maps.pages = (stacksize + 4095) / 4096; - __maps.count = 1; - dll_init(&__maps.stack.elem); - dll_make_first(&__maps.used, &__maps.stack.elem); + if (_weaken(__maps_stack)) + _weaken(__maps_stack)(stackaddr, 4096, stacksize, stackprot, stackhand); struct WinArgs *wa = (struct WinArgs *)(stackaddr + (stacksize - sizeof(struct WinArgs))); diff --git a/libc/thread/posixthread.internal.h b/libc/thread/posixthread.internal.h index cc9389d8c..bd1fd5d04 100644 --- a/libc/thread/posixthread.internal.h +++ b/libc/thread/posixthread.internal.h @@ -105,7 +105,6 @@ intptr_t _pthread_syshand(struct PosixThread *) libcesque; long _pthread_cancel_ack(void) libcesque; void _pthread_decimate(void) libcesque; void _pthread_free(struct PosixThread *, bool) libcesque; -void _pthread_init(void) libcesque; void _pthread_lock(void) libcesque; void _pthread_onfork_child(void) libcesque; void _pthread_onfork_parent(void) libcesque; diff --git a/libc/thread/pthread_exit.c b/libc/thread/pthread_exit.c index 60524f5e7..0ce26c4d3 100644 --- a/libc/thread/pthread_exit.c +++ b/libc/thread/pthread_exit.c @@ -85,39 +85,38 @@ wontreturn void pthread_exit(void *rc) { _pthread_decimate(); // run atexit handlers if orphaned thread - if (pthread_orphan_np()) { - if (_weaken(__cxa_finalize)) { + if (pthread_orphan_np()) + if (_weaken(__cxa_finalize)) _weaken(__cxa_finalize)(NULL); - } - } // transition the thread to a terminated state status = atomic_load_explicit(&pt->pt_status, memory_order_acquire); do { - switch (status) { - case kPosixThreadJoinable: - transition = kPosixThreadTerminated; - break; - case kPosixThreadDetached: - transition = kPosixThreadZombie; - break; - default: - __builtin_unreachable(); + if (status == kPosixThreadZombie) { + transition = kPosixThreadZombie; + break; + } else if (status == kPosixThreadTerminated) { + transition = kPosixThreadTerminated; + break; + } else if (status == kPosixThreadJoinable) { + transition = kPosixThreadTerminated; + } else if (status == kPosixThreadDetached) { + transition = kPosixThreadZombie; + } else { + __builtin_trap(); } } while (!atomic_compare_exchange_weak_explicit( &pt->pt_status, &status, transition, memory_order_release, memory_order_relaxed)); // make this thread a zombie if it was detached - if (transition == kPosixThreadZombie) { + if (transition == kPosixThreadZombie) _pthread_zombify(pt); - } // check if this is the last survivor if (pthread_orphan_np()) { - for (const uintptr_t *p = __fini_array_end; p > __fini_array_start;) { + for (const uintptr_t *p = __fini_array_end; p > __fini_array_start;) ((void (*)(void))(*--p))(); - } _Exit(0); } diff --git a/third_party/nsync/common.c b/third_party/nsync/common.c index 479ade601..4c77e7d4e 100644 --- a/third_party/nsync/common.c +++ b/third_party/nsync/common.c @@ -181,7 +181,7 @@ static void *nsync_malloc (size_t size) { static struct Dll *free_waiters = NULL; /* free_waiters points to a doubly-linked list of free waiter structs. */ -nsync_atomic_uint32_ free_waiters_mu; /* spinlock; protects free_waiters */ +pthread_mutex_t nsync_waiters_mu = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; #define waiter_for_thread __get_tls()->tib_nsync @@ -196,9 +196,9 @@ void nsync_waiter_destroy (void *v) { IGNORE_RACES_START (); ASSERT ((w->flags & (WAITER_RESERVED|WAITER_IN_USE)) == WAITER_RESERVED); w->flags &= ~WAITER_RESERVED; - nsync_spin_test_and_set_ (&free_waiters_mu, 1, 1, 0); + pthread_mutex_lock (&nsync_waiters_mu); dll_make_first (&free_waiters, &w->nw.q); - ATM_STORE_REL (&free_waiters_mu, 0); /* release store */ + pthread_mutex_unlock (&nsync_waiters_mu); IGNORE_RACES_END (); } @@ -212,13 +212,13 @@ waiter *nsync_waiter_new_ (void) { w = tw; if (w == NULL || (w->flags & (WAITER_RESERVED|WAITER_IN_USE)) != WAITER_RESERVED) { w = NULL; - nsync_spin_test_and_set_ (&free_waiters_mu, 1, 1, 0); + pthread_mutex_lock (&nsync_waiters_mu); q = dll_first (free_waiters); if (q != NULL) { /* If free list is non-empty, dequeue an item. */ dll_remove (&free_waiters, q); w = DLL_WAITER (q); } - ATM_STORE_REL (&free_waiters_mu, 0); /* release store */ + pthread_mutex_unlock (&nsync_waiters_mu); if (w == NULL) { /* If free list was empty, allocate an item. */ w = (waiter *) nsync_malloc (sizeof (*w)); w->tag = WAITER_TAG; @@ -246,9 +246,9 @@ void nsync_waiter_free_ (waiter *w) { ASSERT ((w->flags & WAITER_IN_USE) != 0); w->flags &= ~WAITER_IN_USE; if ((w->flags & WAITER_RESERVED) == 0) { - nsync_spin_test_and_set_ (&free_waiters_mu, 1, 1, 0); + pthread_mutex_lock (&nsync_waiters_mu); dll_make_first (&free_waiters, &w->nw.q); - ATM_STORE_REL (&free_waiters_mu, 0); /* release store */ + pthread_mutex_unlock (&nsync_waiters_mu); if (w == waiter_for_thread) waiter_for_thread = 0; } From bd6d9ff99a9d134d40b7ce01edaec5d6b5a31599 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Thu, 4 Jul 2024 03:44:17 -0700 Subject: [PATCH 030/405] Get deathstar demo working again on metal --- libc/calls/ucontext.c | 6 +++--- libc/intrin/mman.greg.c | 8 ++++---- libc/intrin/pthread_mutex_lock.c | 1 - libc/intrin/sig.c | 19 ++++++++++++------- libc/runtime/set_tls.c | 2 +- libc/thread/pthread_create.c | 2 +- 6 files changed, 21 insertions(+), 17 deletions(-) diff --git a/libc/calls/ucontext.c b/libc/calls/ucontext.c index a6227663b..d5ba75a94 100644 --- a/libc/calls/ucontext.c +++ b/libc/calls/ucontext.c @@ -34,7 +34,7 @@ int __tailcontext(const ucontext_t *); * @see getcontext() */ int setcontext(const ucontext_t *uc) { - if (IsWindows()) { + if (IsWindows() || IsMetal()) { atomic_store_explicit(&__get_tls()->tib_sigmask, uc->uc_sigmask, memory_order_release); } else { @@ -44,7 +44,7 @@ int setcontext(const ucontext_t *uc) { } int __getcontextsig(ucontext_t *uc) { - if (IsWindows()) { + if (IsWindows() || IsMetal()) { uc->uc_sigmask = atomic_load_explicit(&__get_tls()->tib_sigmask, memory_order_acquire); return 0; @@ -54,7 +54,7 @@ int __getcontextsig(ucontext_t *uc) { } int __swapcontextsig(ucontext_t *x, const ucontext_t *y) { - if (IsWindows()) { + if (IsWindows() || IsMetal()) { x->uc_sigmask = atomic_exchange_explicit( &__get_tls()->tib_sigmask, y->uc_sigmask, memory_order_acquire); return 0; diff --git a/libc/intrin/mman.greg.c b/libc/intrin/mman.greg.c index cb9274a1b..8d7f17449 100644 --- a/libc/intrin/mman.greg.c +++ b/libc/intrin/mman.greg.c @@ -45,7 +45,7 @@ #ifdef __x86_64__ #define INVERT(x) (BANE + PHYSICAL((uintptr_t)(x))) -#define NOPAGE ((uint64_t) - 1) +#define NOPAGE ((uint64_t)-1) #define APE_STACK_VADDR \ ({ \ @@ -69,9 +69,9 @@ texthead uint64_t __new_page(struct mman *mm) { if (p != NOPAGE) { uint64_t q; struct ReclaimedPage *rp = (struct ReclaimedPage *)(BANE + p); - unassert(p == (p & PAGE_TA)); + /* unassert(p == (p & PAGE_TA)); */ q = rp->next; - unassert(q == (q & PAGE_TA) || q == NOPAGE); + /* unassert(q == (q & PAGE_TA) || q == NOPAGE); */ mm->frp = q; return p; } @@ -200,7 +200,7 @@ void __ref_pages(struct mman *mm, uint64_t *pml4t, uint64_t ps, uint64_t size) { */ static void __reclaim_page(struct mman *mm, uint64_t p) { struct ReclaimedPage *rp = (struct ReclaimedPage *)(BANE + p); - unassert(p == (p & PAGE_TA)); + /* unassert(p == (p & PAGE_TA)); */ rp->next = mm->frp; mm->frp = p; } diff --git a/libc/intrin/pthread_mutex_lock.c b/libc/intrin/pthread_mutex_lock.c index 0138974e6..6fd2c6bfb 100644 --- a/libc/intrin/pthread_mutex_lock.c +++ b/libc/intrin/pthread_mutex_lock.c @@ -25,7 +25,6 @@ #include "libc/runtime/internal.h" #include "libc/thread/lock.h" #include "libc/thread/thread.h" -#include "libc/thread/tls.h" #include "third_party/nsync/mu.h" /** diff --git a/libc/intrin/sig.c b/libc/intrin/sig.c index 2bffeeb7b..8679b811d 100644 --- a/libc/intrin/sig.c +++ b/libc/intrin/sig.c @@ -27,9 +27,12 @@ struct Signals __sig; sigset_t __sig_block(void) { - if (IsWindows()) { - return atomic_exchange_explicit(&__get_tls()->tib_sigmask, -1, - memory_order_acquire); + if (IsWindows() || IsMetal()) { + if (__tls_enabled) + return atomic_exchange_explicit(&__get_tls()->tib_sigmask, -1, + memory_order_acquire); + else + return 0; } else { sigset_t res, neu = -1; sys_sigprocmask(SIG_SETMASK, &neu, &res); @@ -38,10 +41,12 @@ sigset_t __sig_block(void) { } void __sig_unblock(sigset_t m) { - if (IsWindows()) { - atomic_store_explicit(&__get_tls()->tib_sigmask, m, memory_order_release); - if (_weaken(__sig_check)) { - _weaken(__sig_check)(); + if (IsWindows() || IsMetal()) { + if (__tls_enabled) { + atomic_store_explicit(&__get_tls()->tib_sigmask, m, memory_order_release); + if (_weaken(__sig_check)) { + _weaken(__sig_check)(); + } } } else { sys_sigprocmask(SIG_SETMASK, &m, 0); diff --git a/libc/runtime/set_tls.c b/libc/runtime/set_tls.c index 0f54e8d12..a1d497896 100644 --- a/libc/runtime/set_tls.c +++ b/libc/runtime/set_tls.c @@ -57,7 +57,7 @@ dontinstrument textstartup void __set_tls(struct CosmoTib *tib) { uint64_t val = (uint64_t)tib; asm volatile("wrmsr" : /* no outputs */ - : "c"(MSR_IA32_FS_BASE), "a"((uint32_t)val), + : "c"(MSR_IA32_GS_BASE), "a"((uint32_t)val), "d"((uint32_t)(val >> 32))); } #elif defined(__aarch64__) diff --git a/libc/thread/pthread_create.c b/libc/thread/pthread_create.c index 9e01f26f6..740d43cef 100644 --- a/libc/thread/pthread_create.c +++ b/libc/thread/pthread_create.c @@ -118,7 +118,7 @@ static int PosixThread(void *arg, int tid) { // set long jump handler so pthread_exit can bring control back here if (!setjmp(pt->pt_exiter)) { sigdelset(&pt->pt_attr.__sigmask, SIGTHR); - if (IsWindows()) { + if (IsWindows() || IsMetal()) { atomic_store_explicit(&__get_tls()->tib_sigmask, pt->pt_attr.__sigmask, memory_order_release); } else { From 5a9a08d1cf817aea9400787de1dbb62fd920db6b Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Thu, 4 Jul 2024 04:02:20 -0700 Subject: [PATCH 031/405] Fix regression in elf2pe program --- libc/mem/tinymalloc.inc | 30 +++++++++++++++++++++++------- tool/build/elf2pe.c | 11 ++++++++++- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/libc/mem/tinymalloc.inc b/libc/mem/tinymalloc.inc index 019a4ec3f..0e70013cd 100644 --- a/libc/mem/tinymalloc.inc +++ b/libc/mem/tinymalloc.inc @@ -16,6 +16,7 @@ #include "libc/assert.h" #include "libc/dce.h" #include "libc/errno.h" +#include "libc/intrin/kprintf.h" #include "libc/mem/mem.h" #include "libc/stdalign.internal.h" #include "libc/stdckdint.h" @@ -26,15 +27,29 @@ #endif #ifndef TINYMALLOC_MAX_ALIGN -#define TINYMALLOC_MAX_ALIGN 4096 +#define TINYMALLOC_MAX_ALIGN sizeof(max_align_t) #endif -alignas(TINYMALLOC_MAX_ALIGN) static struct { - char memory[TINYMALLOC_MAX_BYTES]; - size_t used, last, free; +static struct { + alignas(max_align_t) char bits[TINYMALLOC_MAX_BYTES]; + char *memory; + int once; + size_t size, used, last, free; } heap; -static inline bool isheap(char *mem) { +static void tinymalloc_init(void) { + int align; + if (heap.once) + return; + align = TINYMALLOC_MAX_ALIGN; + heap.memory = (char *)(((uintptr_t)heap.bits + align - 1) & -align); + heap.size = sizeof(heap.bits) - (heap.memory - heap.bits); + kprintf("heap.memory = %p\n", heap.memory); + kprintf("heap.size = %p\n", heap.size); + heap.once = 1; +} + +static inline int isheap(char *mem) { return heap.memory <= mem && mem < heap.memory + heap.used; } @@ -59,6 +74,7 @@ size_t malloc_usable_size(void *ptr) { void *memalign(size_t align, size_t need) { char *res; size_t next, next2, base, toto, *link, *link2; + tinymalloc_init(); // normalize arguments while (align & (align - 1)) @@ -95,7 +111,7 @@ void *memalign(size_t align, size_t need) { base &= -align; if (ckd_add(&toto, base, need)) goto OutOfMemory; - if (toto > TINYMALLOC_MAX_BYTES) + if (toto > heap.size) goto OutOfMemory; res = heap.memory + base; ((size_t *)res)[-1] = need; @@ -148,7 +164,7 @@ void *realloc(void *ptr, size_t need) { need &= -sizeof(size_t); if (ckd_add(&toto, base, need)) goto OutOfMemory; - if (toto > TINYMALLOC_MAX_BYTES) + if (toto > heap.size) goto OutOfMemory; ((size_t *)mem)[-1] = need; heap.used = toto; diff --git a/tool/build/elf2pe.c b/tool/build/elf2pe.c index 9403b0bef..f438383ae 100644 --- a/tool/build/elf2pe.c +++ b/tool/build/elf2pe.c @@ -27,6 +27,7 @@ #include "libc/fmt/itoa.h" #include "libc/intrin/describeflags.internal.h" #include "libc/intrin/dll.h" +#include "libc/intrin/kprintf.h" #include "libc/limits.h" #include "libc/macros.internal.h" #include "libc/mem/mem.h" @@ -158,6 +159,7 @@ static const char *stubpath; static long FLAG_SizeOfStackCommit = 64 * 1024; static long FLAG_SizeOfStackReserve = 8 * 1024 * 1024; +#define TINYMALLOC_MAX_ALIGN MAX_ALIGN #include "libc/mem/tinymalloc.inc" static wontreturn void Die(const char *thing, const char *reason) { @@ -186,6 +188,13 @@ static void *Calloc(size_t n) { return p; } +static void *Memalign(size_t a, size_t n) { + void *p; + if (!(p = memalign(a, n))) + DieOom(); + return p; +} + static void *Realloc(void *p, size_t n) { if (!(p = realloc(p, n))) DieOom(); @@ -1106,7 +1115,7 @@ int main(int argc, char *argv[]) { GetOpts(argc, argv); // translate executable struct Elf *elf = OpenElf(argv[optind]); - char *buf = memalign(MAX_ALIGN, 134217728); + char *buf = Memalign(MAX_ALIGN, 134217728); struct ImagePointer ip = GeneratePe(elf, buf, 0x00400000); if (creat(outpath, 0755) == -1) DieSys(elf->path); From 01587de761da8554452f47587b54ef7683be2925 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Thu, 4 Jul 2024 10:52:16 -0700 Subject: [PATCH 032/405] Simplify memory manager --- ctl/is_void.h | 24 +++ ctl/vector.h | 2 +- examples/greenbean.c | 4 +- libc/calls/madvise.c | 2 +- libc/calls/posix_madvise.c | 2 +- libc/calls/setrlimit.c | 14 +- libc/dlopen/dlopen.c | 2 +- libc/intrin/getauxval.c | 13 +- libc/intrin/getmainstack.c | 2 +- libc/{runtime => intrin}/getpagesize.c | 3 +- libc/intrin/granularity.c | 15 +- libc/intrin/kprintf.greg.c | 23 +-- libc/intrin/maps.c | 33 ++-- libc/intrin/maps.h | 14 +- libc/intrin/mmap.c | 158 +++++++++---------- libc/intrin/mprotect.c | 63 ++++---- libc/intrin/msync-nt.c | 6 +- libc/intrin/printmaps.c | 10 +- libc/intrin/strace.internal.h | 2 +- libc/mem/tinymalloc.inc | 3 - libc/proc/fork-nt.c | 207 +++++++++++++++++-------- libc/runtime/isstackoverflow.c | 2 +- libc/runtime/opensymboltable.greg.c | 2 +- libc/runtime/runtime.h | 2 +- libc/runtime/sysconf.c | 4 +- libc/runtime/winmain.greg.c | 11 +- libc/runtime/zipos-get.c | 2 +- libc/thread/pthread_attr_init.c | 2 +- libc/thread/pthread_create.c | 4 +- test/libc/calls/cachestat_test.c | 2 +- test/libc/calls/madvise_test.c | 4 +- test/libc/calls/setrlimit_test.c | 24 ++- test/libc/calls/sigbus_test.c | 2 +- test/libc/intrin/kprintf_test.c | 4 +- test/libc/intrin/mmap_test.c | 44 ++++-- test/libc/intrin/mprotect_test.c | 35 ++--- third_party/dlmalloc/init.inc | 3 +- tool/net/winbench.c | 2 +- tool/viz/cpuid.c | 1 + tool/viz/life.c | 10 +- 40 files changed, 451 insertions(+), 311 deletions(-) create mode 100644 ctl/is_void.h rename libc/{runtime => intrin}/getpagesize.c (96%) diff --git a/ctl/is_void.h b/ctl/is_void.h new file mode 100644 index 000000000..04c33145c --- /dev/null +++ b/ctl/is_void.h @@ -0,0 +1,24 @@ +// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- +// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi +#ifndef CTL_IS_VOID_H_ +#define CTL_IS_VOID_H_ +#include "integral_constant.h" +#include "remove_cv.h" + +namespace ctl { + +template +struct is_void_ : public ctl::false_type +{}; + +template<> +struct is_void_ : public ctl::true_type +{}; + +template +struct is_void : public is_void_::type>::type +{}; + +} // namespace ctl + +#endif // CTL_IS_VOID_H_ diff --git a/ctl/vector.h b/ctl/vector.h index ce0cd5831..8fa55bafa 100644 --- a/ctl/vector.h +++ b/ctl/vector.h @@ -525,7 +525,7 @@ class vector capacity_ = new_capacity; } - Allocator alloc_; + [[no_unique_address]] Allocator alloc_; pointer data_; size_type size_; size_type capacity_; diff --git a/examples/greenbean.c b/examples/greenbean.c index 969051e82..9f2aae6c1 100644 --- a/examples/greenbean.c +++ b/examples/greenbean.c @@ -24,6 +24,7 @@ #include #include #include "libc/mem/leaks.h" +#include "libc/runtime/runtime.h" /** * @fileoverview greenbean lightweight threaded web server @@ -336,10 +337,9 @@ int main(int argc, char *argv[]) { sigaddset(&block, SIGHUP); sigaddset(&block, SIGQUIT); pthread_attr_t attr; - int pagesz = getauxval(AT_PAGESZ); unassert(!pthread_attr_init(&attr)); unassert(!pthread_attr_setstacksize(&attr, 65536)); - unassert(!pthread_attr_setguardsize(&attr, pagesz)); + unassert(!pthread_attr_setguardsize(&attr, getpagesize())); unassert(!pthread_attr_setsigmask_np(&attr, &block)); unassert(!pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0)); pthread_t *th = gc(calloc(threads, sizeof(pthread_t))); diff --git a/libc/calls/madvise.c b/libc/calls/madvise.c index 27ea1c7cf..c4a351c06 100644 --- a/libc/calls/madvise.c +++ b/libc/calls/madvise.c @@ -30,7 +30,7 @@ * @return 0 on success, or -1 w/ errno * @raise EINVAL if `advice` isn't valid or supported by system * @raise EINVAL on Linux if addr/length isn't page size aligned with - * respect to `getauxval(AT_PAGESZ)` + * respect to `getpagesize()` * @raise ENOMEM on Linux if addr/length overlaps unmapped regions * @see libc/sysv/consts.sh * @see fadvise() diff --git a/libc/calls/posix_madvise.c b/libc/calls/posix_madvise.c index 9503cd7a4..b6d816372 100644 --- a/libc/calls/posix_madvise.c +++ b/libc/calls/posix_madvise.c @@ -25,7 +25,7 @@ * @return 0 on success, or errno on error * @raise EINVAL if `advice` isn't valid or supported by system * @raise EINVAL on Linux if addr/length isn't page size aligned with - * respect to `getauxval(AT_PAGESZ)` + * respect to `getpagesize()` * @raise ENOMEM on Linux if addr/length overlaps unmapped regions * @returnserrno */ diff --git a/libc/calls/setrlimit.c b/libc/calls/setrlimit.c index 96112a096..45a8c532c 100644 --- a/libc/calls/setrlimit.c +++ b/libc/calls/setrlimit.c @@ -21,6 +21,7 @@ #include "libc/calls/struct/rlimit.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" +#include "libc/errno.h" #include "libc/intrin/describeflags.internal.h" #include "libc/intrin/strace.internal.h" #include "libc/macros.internal.h" @@ -77,6 +78,7 @@ */ int setrlimit(int resource, const struct rlimit *rlim) { int rc; + int olde = errno; if (resource == 127) { rc = einval(); } else if (!rlim) { @@ -85,18 +87,16 @@ int setrlimit(int resource, const struct rlimit *rlim) { rc = _sysret(__syslib->__setrlimit(resource, rlim)); } else if (!IsWindows()) { rc = sys_setrlimit(resource, rlim); - if (IsXnu() && !rc && resource == RLIMIT_AS) { - // TODO(jart): What's up with XNU and NetBSD? - __virtualmax = rlim->rlim_cur; - } } else if (resource == RLIMIT_STACK) { rc = enotsup(); - } else if (resource == RLIMIT_AS) { - __virtualmax = rlim->rlim_cur; - rc = 0; } else { rc = einval(); } + if (resource == RLIMIT_AS) { + __virtualmax = rlim->rlim_cur; + errno = olde; + rc = 0; + } STRACE("setrlimit(%s, %s) β†’ %d% m", DescribeRlimitName(resource), DescribeRlimit(0, rlim), rc); return rc; diff --git a/libc/dlopen/dlopen.c b/libc/dlopen/dlopen.c index c5cb457ba..41e0111fa 100644 --- a/libc/dlopen/dlopen.c +++ b/libc/dlopen/dlopen.c @@ -303,7 +303,7 @@ static wontreturn dontinstrument void foreign_helper(void **p) { static dontinline void elf_exec(const char *file, char **envp) { // get microprocessor page size - long pagesz = getauxval(AT_PAGESZ); + long pagesz = getpagesize(); // load helper executable into address space struct Loaded prog; diff --git a/libc/intrin/getauxval.c b/libc/intrin/getauxval.c index 93391e98a..3cbeeb560 100644 --- a/libc/intrin/getauxval.c +++ b/libc/intrin/getauxval.c @@ -16,8 +16,11 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/getauxval.internal.h" +#include "libc/nt/struct/systeminfo.h" +#include "libc/nt/systeminfo.h" #include "libc/runtime/runtime.h" #include "libc/sysv/consts/auxv.h" @@ -35,11 +38,17 @@ unsigned long getauxval(unsigned long key) { x = __getauxval(key); if (key == AT_PAGESZ) { if (!x.isfound) { + if (!IsWindows()) { #ifdef __aarch64__ - x.value = 16384; + x.value = 16384; #else - x.value = 4096; + x.value = 4096; #endif + } else { + struct NtSystemInfo si; + GetSystemInfo(&si); + x.value = si.dwPageSize; + } } x.isfound = true; } diff --git a/libc/intrin/getmainstack.c b/libc/intrin/getmainstack.c index dc9dbc3fa..e619949c1 100644 --- a/libc/intrin/getmainstack.c +++ b/libc/intrin/getmainstack.c @@ -105,7 +105,7 @@ static size_t __get_stack_size(int pagesz, uintptr_t start, uintptr_t top) { * This function works on every OS except Windows. */ struct AddrSize __get_main_stack(void) { - int pagesz = getauxval(AT_PAGESZ); + int pagesz = getpagesize(); uintptr_t start = (uintptr_t)__argv; uintptr_t top = __get_main_top(pagesz); uintptr_t bot = top - __get_stack_size(pagesz, start, top); diff --git a/libc/runtime/getpagesize.c b/libc/intrin/getpagesize.c similarity index 96% rename from libc/runtime/getpagesize.c rename to libc/intrin/getpagesize.c index 81375c246..9f4149758 100644 --- a/libc/runtime/getpagesize.c +++ b/libc/intrin/getpagesize.c @@ -17,11 +17,12 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/runtime/runtime.h" +#include "libc/sysv/consts/auxv.h" /** * Returns granularity of memory manager. * @see sysconf(_SC_PAGE_SIZE) which is portable */ int getpagesize(void) { - return __granularity(); + return getauxval(AT_PAGESZ); } diff --git a/libc/intrin/granularity.c b/libc/intrin/granularity.c index 279b8d628..5a3edf700 100644 --- a/libc/intrin/granularity.c +++ b/libc/intrin/granularity.c @@ -17,14 +17,21 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/dce.h" +#include "libc/nt/struct/systeminfo.h" +#include "libc/nt/systeminfo.h" #include "libc/runtime/runtime.h" #include "libc/sysv/consts/auxv.h" int __granularity(void) { - if (IsWindows()) - return 65536; static int res; - if (!res) - res = getauxval(AT_PAGESZ); + if (!res) { + if (!IsWindows()) { + res = getpagesize(); + } else { + struct NtSystemInfo si; + GetSystemInfo(&si); + res = si.dwAllocationGranularity; + } + } return res; } diff --git a/libc/intrin/kprintf.greg.c b/libc/intrin/kprintf.greg.c index 8c4907cc4..2bd649244 100644 --- a/libc/intrin/kprintf.greg.c +++ b/libc/intrin/kprintf.greg.c @@ -155,17 +155,20 @@ __funline bool kischarmisaligned(const char *p, signed char t) { } privileged static bool32 kisdangerous_unlocked(const char *addr) { - struct Dll *e, *e2; - for (e = dll_first(__maps.used); e; e = e2) { - e2 = dll_next(__maps.used, e); - struct Map *map = MAP_CONTAINER(e); - if (map->addr <= addr && addr < map->addr + map->size) { - dll_remove(&__maps.used, e); - dll_make_first(&__maps.used, e); - return !(map->prot & PROT_READ); - } + struct Dll *e; + if ((e = dll_first(__maps.used))) { + do { + struct Map *map = MAP_CONTAINER(e); + if (map->addr <= addr && addr < map->addr + map->size) { + dll_remove(&__maps.used, e); + dll_make_first(&__maps.used, e); + return !(map->prot & PROT_READ); + } + } while ((e = dll_next(__maps.used, e))); + return true; + } else { + return false; } - return true; } privileged bool32 kisdangerous(const void *addr) { diff --git a/libc/intrin/maps.c b/libc/intrin/maps.c index 7803f8cb9..e2786ee75 100644 --- a/libc/intrin/maps.c +++ b/libc/intrin/maps.c @@ -34,8 +34,6 @@ struct Maps __maps; void __maps_add(struct Map *map) { dll_init(&map->elem); dll_make_first(&__maps.used, &map->elem); - map->next = __maps.maps; - __maps.maps = map; ++__maps.count; } @@ -44,23 +42,31 @@ static void __maps_adder(struct Map *map, int pagesz) { __maps_add(map); } -void __maps_stack(void *stackaddr, int pagesz, size_t stacksize, int stackprot, - intptr_t stackhand) { - __maps.stack.addr = stackaddr; - __maps.stack.size = stacksize; +void __maps_stack(char *stackaddr, int pagesz, int guardsize, size_t stacksize, + int stackprot, intptr_t stackhand) { + __maps.stack.addr = stackaddr + guardsize; + __maps.stack.size = stacksize - guardsize; __maps.stack.prot = stackprot; - __maps.stack.h = stackhand; + __maps.stack.hand = -1; __maps_adder(&__maps.stack, pagesz); + if (guardsize) { + __maps.guard.addr = stackaddr; + __maps.guard.size = guardsize; + __maps.guard.prot = PROT_NONE; + __maps.guard.hand = stackhand; + __maps_adder(&__maps.guard, pagesz); + } } void __maps_init(void) { - int pagesz = getauxval(AT_PAGESZ); + int pagesz = getpagesize(); // record _start() stack mapping if (!IsWindows()) { struct AddrSize stack; stack = __get_main_stack(); - __maps_stack(stack.addr, pagesz, stack.size, (uintptr_t)ape_stack_prot, 0); + __maps_stack(stack.addr, pagesz, 0, stack.size, (uintptr_t)ape_stack_prot, + 0); } // record .text and .data mappings @@ -78,15 +84,15 @@ void __maps_init(void) { __maps_adder(&text, pagesz); } -privileged void __maps_lock(void) { +privileged bool __maps_lock(void) { struct CosmoTib *tib; if (!__threaded) - return; + return false; if (!__tls_enabled) - return; + return false; tib = __get_tls_privileged(); if (tib->tib_relock_maps++) - return; + return true; while (atomic_exchange_explicit(&__maps.lock, 1, memory_order_acquire)) { #if defined(__GNUC__) && defined(__aarch64__) __asm__ volatile("yield"); @@ -94,6 +100,7 @@ privileged void __maps_lock(void) { __asm__ volatile("pause"); #endif } + return false; } privileged void __maps_unlock(void) { diff --git a/libc/intrin/maps.h b/libc/intrin/maps.h index 8527825ea..e6a56b28d 100644 --- a/libc/intrin/maps.h +++ b/libc/intrin/maps.h @@ -8,7 +8,6 @@ COSMOPOLITAN_C_START_ #define MAP_CONTAINER(e) DLL_CONTAINER(struct Map, elem, e) struct Map { - struct Map *next; /* for __maps.maps */ char *addr; /* granule aligned */ size_t size; /* must be nonzero */ struct Dll elem; /* for __maps.free */ @@ -18,18 +17,20 @@ struct Map { bool iscow; /* windows nt only */ bool readonlyfile; /* windows nt only */ unsigned visited; /* used for checks */ - intptr_t h; /* windows nt only */ + intptr_t hand; /* windows nt only */ }; struct Maps { unsigned mono; atomic_int lock; - struct Map *maps; struct Dll *free; - struct Map stack; struct Dll *used; size_t count; size_t pages; + struct Map stack; + struct Map guard; + bool once; + atomic_ulong rollo; }; struct AddrSize { @@ -40,16 +41,15 @@ struct AddrSize { extern struct Maps __maps; void __maps_init(void); -void __maps_lock(void); +bool __maps_lock(void); void __maps_check(void); void __maps_unlock(void); void __maps_add(struct Map *); struct Map *__maps_alloc(void); void __maps_free(struct Map *); -void __maps_insert(struct Map *); int __munmap(char *, size_t, bool); void *__mmap(char *, size_t, int, int, int, int64_t); -void __maps_stack(void *, int, size_t, int, intptr_t); +void __maps_stack(char *, int, int, size_t, int, intptr_t); struct AddrSize __get_main_stack(void); COSMOPOLITAN_C_END_ diff --git a/libc/intrin/mmap.c b/libc/intrin/mmap.c index cd2ddb69f..af9f016c8 100644 --- a/libc/intrin/mmap.c +++ b/libc/intrin/mmap.c @@ -24,6 +24,7 @@ #include "libc/calls/state.internal.h" #include "libc/calls/struct/sigset.internal.h" #include "libc/calls/syscall-sysv.internal.h" +#include "libc/cosmo.h" #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/atomic.h" @@ -54,9 +55,9 @@ #define MAP_FIXED_NOREPLACE_linux 0x100000 -#define PGUP(x) (((x) + granularity - 1) & -granularity) +#define PGUP(x) (((x) + pagesz - 1) & -pagesz) -#if MMDEBUG +#if !MMDEBUG #define ASSERT(x) (void)0 #else #define ASSERT(x) \ @@ -72,14 +73,14 @@ } while (0) #endif -static atomic_ulong rollo; - -static bool overlaps_existing_map(const char *addr, size_t size) { - int granularity = __granularity(); - for (struct Map *map = __maps.maps; map; map = map->next) +static bool overlaps_existing_map(const char *addr, size_t size, int pagesz) { + for (struct Dll *e = dll_first(__maps.used); e; + e = dll_next(__maps.used, e)) { + struct Map *map = MAP_CONTAINER(e); if (MAX(addr, map->addr) < MIN(addr + PGUP(size), map->addr + PGUP(map->size))) return true; + } return false; } @@ -87,43 +88,44 @@ void __maps_check(void) { #if MMDEBUG size_t maps = 0; size_t pages = 0; - int granularity = getauxval(AT_PAGESZ); - unsigned id = __maps.mono++; - for (struct Map *map = __maps.maps; map; map = map->next) { + int pagesz = getpagesize(); + unsigned id = ++__maps.mono; + for (struct Dll *e = dll_first(__maps.used); e; + e = dll_next(__maps.used, e)) { + struct Map *map = MAP_CONTAINER(e); ASSERT(map->addr != MAP_FAILED); ASSERT(map->visited != id); ASSERT(map->size); map->visited = id; - pages += PGUP(map->size) / granularity; + pages += (map->size + getpagesize() - 1) / getpagesize(); maps += 1; } ASSERT(maps = __maps.count); ASSERT(pages == __maps.pages); for (struct Dll *e = dll_first(__maps.used); e; e = dll_next(__maps.used, e)) { - ASSERT(MAP_CONTAINER(e)->visited == id); - --maps; - } - ASSERT(maps == 0); - for (struct Map *m1 = __maps.maps; m1; m1 = m1->next) - for (struct Map *m2 = m1->next; m2; m2 = m2->next) + struct Map *m1 = MAP_CONTAINER(e); + for (struct Dll *f = dll_next(__maps.used, e); f; + f = dll_next(__maps.used, f)) { + struct Map *m2 = MAP_CONTAINER(f); ASSERT(MAX(m1->addr, m2->addr) >= MIN(m1->addr + PGUP(m1->size), m2->addr + PGUP(m2->size))); + } + } #endif } void __maps_free(struct Map *map) { - map->next = 0; map->size = 0; map->addr = MAP_FAILED; ASSERT(dll_is_alone(&map->elem)); dll_make_last(&__maps.free, &map->elem); } -void __maps_insert(struct Map *map) { - struct Map *last = __maps.maps; - int granularity = getauxval(AT_PAGESZ); - __maps.pages += PGUP(map->size) / granularity; +static void __maps_insert(struct Map *map) { + struct Dll *e = dll_first(__maps.used); + struct Map *last = e ? MAP_CONTAINER(e) : 0; + __maps.pages += (map->size + getpagesize() - 1) / getpagesize(); if (last && !IsWindows() && // map->addr == last->addr + last->size && // (map->flags & MAP_ANONYMOUS) && // @@ -155,7 +157,6 @@ struct Map *__maps_alloc(void) { if ((e = dll_first(__maps.free))) { dll_remove(&__maps.free, e); map = MAP_CONTAINER(e); - map->next = 0; return map; } int granularity = __granularity(); @@ -172,40 +173,43 @@ struct Map *__maps_alloc(void) { dll_init(&map[i].elem); __maps_free(map + i); } - map->next = 0; return map; } int __munmap(char *addr, size_t size, bool untrack_only) { // validate arguments - int pagesz = getauxval(AT_PAGESZ); + int pagesz = getpagesize(); int granularity = __granularity(); if (((uintptr_t)addr & (granularity - 1)) || // !size || (uintptr_t)addr + size < size) return einval(); + // normalize size + size = (size + granularity - 1) & -granularity; + // untrack mappings int rc = 0; + struct Dll *cur; + struct Dll *next; struct Dll *delete = 0; - __maps_lock(); - struct Map *map = __maps.maps; - struct Map **prev = &__maps.maps; - while (map) { + if (__maps_lock()) { + __maps_unlock(); + return edeadlk(); + } + for (cur = dll_first(__maps.used); cur; cur = next) { + next = dll_next(__maps.used, cur); + struct Map *map = MAP_CONTAINER(cur); char *map_addr = map->addr; size_t map_size = map->size; - struct Map *next = map->next; - if (MAX(addr, map_addr) < - MIN(addr + PGUP(size), map_addr + PGUP(map_size))) { - if (addr <= map_addr && addr + PGUP(size) >= map_addr + PGUP(map_size)) { + if (MAX(addr, map_addr) < MIN(addr + size, map_addr + PGUP(map_size))) { + if (addr <= map_addr && addr + size >= map_addr + PGUP(map_size)) { // remove mapping completely - dll_remove(&__maps.used, &map->elem); - dll_make_first(&delete, &map->elem); - *prev = next; + dll_remove(&__maps.used, cur); + dll_make_first(&delete, cur); __maps.pages -= (map_size + pagesz - 1) / pagesz; __maps.count -= 1; - map = next; - continue; + __maps_check(); } else if (IsWindows()) { // you can't carve up memory maps on windows. our mmap() makes // this not a problem (for non-enormous memory maps) by making @@ -225,14 +229,14 @@ int __munmap(char *addr, size_t size, bool untrack_only) { if (!(map->flags & MAP_ANONYMOUS)) map->off += left; __maps.pages -= (left + pagesz - 1) / pagesz; - __maps_check(); leftmap->addr = map_addr; leftmap->size = left; dll_make_first(&delete, &leftmap->elem); + __maps_check(); } else { rc = -1; } - } else if (addr + PGUP(size) >= map_addr + PGUP(map_size)) { + } else if (addr + size >= map_addr + PGUP(map_size)) { // shave off righthand side of mapping size_t left = addr - map_addr; size_t right = map_addr + map_size - addr; @@ -240,23 +244,22 @@ int __munmap(char *addr, size_t size, bool untrack_only) { if ((rightmap = __maps_alloc())) { map->size = left; __maps.pages -= (right + pagesz - 1) / pagesz; - __maps_check(); rightmap->addr = addr; rightmap->size = right; dll_make_first(&delete, &rightmap->elem); + __maps_check(); } else { rc = -1; } } else { // punch hole in mapping size_t left = addr - map_addr; - size_t middle = PGUP(size); + size_t middle = size; size_t right = map_size - middle - left; struct Map *leftmap; if ((leftmap = __maps_alloc())) { struct Map *middlemap; if ((middlemap = __maps_alloc())) { - leftmap->next = map; leftmap->addr = map_addr; leftmap->size = left; leftmap->off = map->off; @@ -267,13 +270,12 @@ int __munmap(char *addr, size_t size, bool untrack_only) { if (!(map->flags & MAP_ANONYMOUS)) map->off += left + middle; dll_make_first(&__maps.used, &leftmap->elem); - *prev = leftmap; __maps.pages -= (middle + pagesz - 1) / pagesz; __maps.count += 1; - __maps_check(); middlemap->addr = addr; middlemap->size = size; dll_make_first(&delete, &middlemap->elem); + __maps_check(); } else { rc = -1; } @@ -282,22 +284,21 @@ int __munmap(char *addr, size_t size, bool untrack_only) { } } } - prev = &map->next; - map = next; } __maps_unlock(); // delete mappings for (struct Dll *e = dll_first(delete); e; e = dll_next(delete, e)) { - map = MAP_CONTAINER(e); + struct Map *map = MAP_CONTAINER(e); if (!untrack_only) { if (!IsWindows()) { if (sys_munmap(map->addr, map->size)) rc = -1; - } else { + } else if (map->hand != -1) { + ASSERT(!((uintptr_t)map->addr & (granularity - 1))); if (!UnmapViewOfFile(map->addr)) rc = -1; - if (!CloseHandle(map->h)) + if (!CloseHandle(map->hand)) rc = -1; } } @@ -319,7 +320,7 @@ int __munmap(char *addr, size_t size, bool untrack_only) { } static void *__mmap_chunk(void *addr, size_t size, int prot, int flags, int fd, - int64_t off, int granularity) { + int64_t off, int pagesz, int granularity) { // polyfill nuances of fixed mappings int sysflags = flags; @@ -334,7 +335,7 @@ static void *__mmap_chunk(void *addr, size_t size, int prot, int flags, int fd, sysflags |= MAP_FIXED_NOREPLACE_linux; } else if (IsFreebsd() || IsNetbsd()) { sysflags |= MAP_FIXED; - if (overlaps_existing_map(addr, size)) + if (overlaps_existing_map(addr, size, pagesz)) return (void *)eexist(); } else { noreplace = true; @@ -345,7 +346,10 @@ static void *__mmap_chunk(void *addr, size_t size, int prot, int flags, int fd, // allocate Map object struct Map *map; - __maps_lock(); + if (__maps_lock()) { + __maps_unlock(); + return (void *)edeadlk(); + } map = __maps_alloc(); __maps_unlock(); if (!map) @@ -405,7 +409,7 @@ TryAgain: map->off = off; map->prot = prot; map->flags = flags; - map->h = res.maphandle; + map->hand = res.maphandle; if (IsWindows()) { map->iscow = (flags & MAP_TYPE) != MAP_SHARED && fd != -1; map->readonlyfile = (flags & MAP_TYPE) == MAP_SHARED && fd != -1 && @@ -419,10 +423,10 @@ TryAgain: } static void *__mmap_impl(char *addr, size_t size, int prot, int flags, int fd, - int64_t off, int granularity) { + int64_t off, int pagesz, int granularity) { // validate file map args - if (fd != -1) { + if (!(flags & MAP_ANONYMOUS)) { if (off & (granularity - 1)) return (void *)einval(); if (IsWindows()) { @@ -435,19 +439,21 @@ static void *__mmap_impl(char *addr, size_t size, int prot, int flags, int fd, // mmap works fine on unix if (!IsWindows()) - return __mmap_chunk(addr, size, prot, flags, fd, off, granularity); + return __mmap_chunk(addr, size, prot, flags, fd, off, pagesz, granularity); - // if the concept of granularity wasn't exciting enough - if (!addr && !(flags & (MAP_FIXED | MAP_FIXED_NOREPLACE))) - addr = (char *)(WINBASE + atomic_fetch_add(&rollo, PGUP(size)) % WINMAXX); + // if the concept of pagesz wasn't exciting enough + if (!addr && !(flags & (MAP_FIXED | MAP_FIXED_NOREPLACE))) { + size_t slab = (size + granularity - 1) & -granularity; + addr = (char *)(WINBASE + atomic_fetch_add(&__maps.rollo, slab) % WINMAXX); + } // windows forbids unmapping a subset of a map once it's made if (size <= granularity || size > 100 * 1024 * 1024) - return __mmap_chunk(addr, size, prot, flags, fd, off, granularity); + return __mmap_chunk(addr, size, prot, flags, fd, off, pagesz, granularity); // so we create a separate map for each granule in the mapping if (!(flags & MAP_FIXED)) { - while (overlaps_existing_map(addr, size)) { + while (overlaps_existing_map(addr, size, pagesz)) { if (flags & MAP_FIXED_NOREPLACE) return (void *)eexist(); addr += granularity; @@ -457,7 +463,7 @@ static void *__mmap_impl(char *addr, size_t size, int prot, int flags, int fd, while (size) { char *got; size_t amt = MIN(size, granularity); - got = __mmap_chunk(addr, amt, prot, flags, fd, off, granularity); + got = __mmap_chunk(addr, amt, prot, flags, fd, off, pagesz, granularity); if (got != addr) { if (got != MAP_FAILED) __munmap(got, amt, false); @@ -476,6 +482,7 @@ static void *__mmap_impl(char *addr, size_t size, int prot, int flags, int fd, void *__mmap(char *addr, size_t size, int prot, int flags, int fd, int64_t off) { char *res; + int pagesz = getpagesize(); int granularity = __granularity(); // validate arguments @@ -484,17 +491,12 @@ void *__mmap(char *addr, size_t size, int prot, int flags, int fd, return (void *)einval(); if (size > 0x100000000000) return (void *)enomem(); - - // normalize arguments - if (flags & MAP_ANONYMOUS) { - fd = -1; - off = 0; - size = PGUP(size); - } + if (__maps.count * pagesz + size > __virtualmax) + return (void *)enomem(); // create memory mappping if (!__isfdkind(fd, kFdZip)) { - res = __mmap_impl(addr, size, prot, flags, fd, off, granularity); + res = __mmap_impl(addr, size, prot, flags, fd, off, pagesz, granularity); } else { res = _weaken(__zipos_mmap)( addr, size, prot, flags, @@ -505,24 +507,14 @@ void *__mmap(char *addr, size_t size, int prot, int flags, int fd, } void *mmap(void *addr, size_t size, int prot, int flags, int fd, int64_t off) { - void *res; - BLOCK_SIGNALS; - BLOCK_CANCELATION; - res = __mmap(addr, size, prot, flags, fd, off); - ALLOW_CANCELATION; - ALLOW_SIGNALS; + void *res = __mmap(addr, size, prot, flags, fd, off); STRACE("mmap(%p, %'zu, %s, %s, %d, %'ld) β†’ %p% m", addr, size, DescribeProtFlags(prot), DescribeMapFlags(flags), fd, off, res); return res; } int munmap(void *addr, size_t size) { - int rc; - BLOCK_SIGNALS; - BLOCK_CANCELATION; - rc = __munmap(addr, size, false); - ALLOW_CANCELATION; - ALLOW_SIGNALS; + int rc = __munmap(addr, size, false); STRACE("munmap(%p, %'zu) β†’ %d% m", addr, size, rc); return rc; } diff --git a/libc/intrin/mprotect.c b/libc/intrin/mprotect.c index c02eb0769..83dc39926 100644 --- a/libc/intrin/mprotect.c +++ b/libc/intrin/mprotect.c @@ -59,56 +59,57 @@ int __mprotect(char *addr, size_t size, int prot) { return 0; // unix checks prot before checking size - int pagesz = getauxval(AT_PAGESZ); - if ((intptr_t)addr & (pagesz - 1)) + int pagesz = getpagesize(); + if (((intptr_t)addr & (pagesz - 1)) || (uintptr_t)addr + size < size) return einval(); + // normalize size + size = (size + pagesz - 1) & -pagesz; + // change mappings int rc = 0; - __maps_lock(); + struct Dll *cur; bool found = false; - struct Map *map = __maps.maps; - struct Map **prev = &__maps.maps; - while (map) { + if (__maps_lock()) { + __maps_unlock(); + return edeadlk(); + } + for (cur = dll_first(__maps.used); cur; cur = dll_next(__maps.used, cur)) { + struct Map *map = MAP_CONTAINER(cur); char *map_addr = map->addr; size_t map_size = map->size; - struct Map *next = map->next; char *beg = MAX(addr, map_addr); - char *end = MIN(addr + PGUP(size), map_addr + PGUP(map_size)); + char *end = MIN(addr + size, map_addr + PGUP(map_size)); if (beg < end) { found = true; - if (addr <= map_addr && addr + PGUP(size) >= map_addr + PGUP(map_size)) { + if (addr <= map_addr && addr + size >= map_addr + PGUP(map_size)) { // change protection of entire mapping if (!__mprotect_chunk(map_addr, map_size, prot, map->iscow)) { map->prot = prot; } else { rc = -1; } - } else if (IsWindows()) { - // windows does allow changing protection at 4096 byte chunks - // however we currently don't have data structures that track - // this within the 64 kb map granules that can't be broken up - if (__mprotect_chunk(beg, end - beg, prot, map->iscow) == -1) - rc = -1; } else if (addr <= map_addr) { - // cleave lefthand side of mapping + // change lefthand side of mapping size_t left = PGUP(addr + size - map_addr); size_t right = map_size - left; struct Map *leftmap; if ((leftmap = __maps_alloc())) { if (!__mprotect_chunk(map_addr, left, prot, false)) { - leftmap->next = map; leftmap->addr = map_addr; leftmap->size = left; leftmap->prot = prot; leftmap->off = map->off; leftmap->flags = map->flags; + leftmap->iscow = map->iscow; + leftmap->readonlyfile = map->readonlyfile; + leftmap->hand = map->hand; map->addr += left; map->size = right; + map->hand = -1; if (!(map->flags & MAP_ANONYMOUS)) map->off += left; dll_make_first(&__maps.used, &leftmap->elem); - *prev = leftmap; __maps.count += 1; __maps_check(); } else { @@ -118,26 +119,28 @@ int __mprotect(char *addr, size_t size, int prot) { } else { rc = -1; } - } else if (addr + PGUP(size) >= map_addr + PGUP(map_size)) { - // cleave righthand side of mapping + } else if (addr + size >= map_addr + PGUP(map_size)) { + // change righthand side of mapping size_t left = addr - map_addr; size_t right = map_addr + map_size - addr; struct Map *leftmap; if ((leftmap = __maps_alloc())) { if (!__mprotect_chunk(map_addr + left, right, prot, false)) { - leftmap->next = map; leftmap->addr = map_addr; leftmap->size = left; leftmap->off = map->off; leftmap->prot = map->prot; leftmap->flags = map->flags; + leftmap->iscow = map->iscow; + leftmap->readonlyfile = map->readonlyfile; + leftmap->hand = map->hand; map->addr += left; map->size = right; map->prot = prot; + map->hand = -1; if (!(map->flags & MAP_ANONYMOUS)) map->off += left; dll_make_first(&__maps.used, &leftmap->elem); - *prev = leftmap; __maps.count += 1; __maps_check(); } else { @@ -148,34 +151,36 @@ int __mprotect(char *addr, size_t size, int prot) { rc = -1; } } else { - // punch hole in mapping + // change middle of mapping size_t left = addr - map_addr; - size_t middle = PGUP(size); + size_t middle = size; size_t right = map_size - middle - left; struct Map *leftmap; if ((leftmap = __maps_alloc())) { struct Map *midlmap; if ((midlmap = __maps_alloc())) { if (!__mprotect_chunk(map_addr + left, middle, prot, false)) { - leftmap->next = midlmap; leftmap->addr = map_addr; leftmap->size = left; leftmap->off = map->off; leftmap->prot = map->prot; leftmap->flags = map->flags; - midlmap->next = map; + leftmap->iscow = map->iscow; + leftmap->readonlyfile = map->readonlyfile; + leftmap->hand = map->hand; midlmap->addr = map_addr + left; midlmap->size = middle; midlmap->off = (map->flags & MAP_ANONYMOUS) ? 0 : map->off + left; midlmap->prot = prot; midlmap->flags = map->flags; + midlmap->hand = -1; map->addr += left + middle; map->size = right; + map->hand = -1; if (!(map->flags & MAP_ANONYMOUS)) map->off += left + middle; - dll_make_first(&__maps.used, &leftmap->elem); dll_make_first(&__maps.used, &midlmap->elem); - *prev = leftmap; + dll_make_first(&__maps.used, &leftmap->elem); __maps.count += 2; __maps_check(); } else { @@ -192,8 +197,6 @@ int __mprotect(char *addr, size_t size, int prot) { } } } - prev = &map->next; - map = next; } // allow user to change mappings unknown to cosmo runtime diff --git a/libc/intrin/msync-nt.c b/libc/intrin/msync-nt.c index 78cbd5444..3ff6524ed 100644 --- a/libc/intrin/msync-nt.c +++ b/libc/intrin/msync-nt.c @@ -27,7 +27,7 @@ textwindows int sys_msync_nt(char *addr, size_t size, int flags) { - int pagesz = getauxval(AT_PAGESZ); + int pagesz = getpagesize(); size = (size + pagesz - 1) & -pagesz; if ((uintptr_t)addr & (pagesz - 1)) @@ -35,7 +35,9 @@ textwindows int sys_msync_nt(char *addr, size_t size, int flags) { int rc = 0; __maps_lock(); - for (struct Map *map = __maps.maps; map; map = map->next) { + for (struct Dll *e = dll_first(__maps.used); e; + e = dll_next(__maps.used, e)) { + struct Map *map = MAP_CONTAINER(e); char *beg = MAX(addr, map->addr); char *end = MIN(addr + size, map->addr + map->size); if (beg < end) diff --git a/libc/intrin/printmaps.c b/libc/intrin/printmaps.c index 468c0f928..b84a1cc25 100644 --- a/libc/intrin/printmaps.c +++ b/libc/intrin/printmaps.c @@ -30,7 +30,7 @@ * Prints memory mappings. */ void __print_maps(void) { - int limit = 13; + int limit = 15; long maptally = 0; char mappingbuf[8], sb[16]; __maps_lock(); @@ -43,8 +43,8 @@ void __print_maps(void) { (DescribeMapping)(mappingbuf, map->prot, map->flags)); sizefmt(sb, map->size, 1024); kprintf(" %!sb", sb); - if (map->h && map->h != -1) - kprintf(" h=%ld", map->h); + if (map->hand && map->hand != -1) + kprintf(" hand=%ld", map->hand); if (map->iscow) kprintf(" cow"); if (map->readonlyfile) @@ -53,7 +53,7 @@ void __print_maps(void) { if (!--limit) break; } - kprintf("# %'zu bytes in %'zu mappings\n", - __maps.pages * getauxval(AT_PAGESZ), __maps.count); + kprintf("# %'zu bytes in %'zu mappings\n", __maps.pages * getpagesize(), + __maps.count); __maps_unlock(); } diff --git a/libc/intrin/strace.internal.h b/libc/intrin/strace.internal.h index adda49caa..3c521857f 100644 --- a/libc/intrin/strace.internal.h +++ b/libc/intrin/strace.internal.h @@ -5,7 +5,7 @@ #define SYSDEBUG 0 #endif -#define _NTTRACE 1 /* not configurable w/ flag yet */ +#define _NTTRACE 0 /* not configurable w/ flag yet */ #define _POLLTRACE 0 /* not configurable w/ flag yet */ #define _DATATRACE 1 /* not configurable w/ flag yet */ #define _LOCKTRACE 0 /* not configurable w/ flag yet */ diff --git a/libc/mem/tinymalloc.inc b/libc/mem/tinymalloc.inc index 0e70013cd..1a4527c6b 100644 --- a/libc/mem/tinymalloc.inc +++ b/libc/mem/tinymalloc.inc @@ -16,7 +16,6 @@ #include "libc/assert.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/kprintf.h" #include "libc/mem/mem.h" #include "libc/stdalign.internal.h" #include "libc/stdckdint.h" @@ -44,8 +43,6 @@ static void tinymalloc_init(void) { align = TINYMALLOC_MAX_ALIGN; heap.memory = (char *)(((uintptr_t)heap.bits + align - 1) & -align); heap.size = sizeof(heap.bits) - (heap.memory - heap.bits); - kprintf("heap.memory = %p\n", heap.memory); - kprintf("heap.size = %p\n", heap.size); heap.once = 1; } diff --git a/libc/proc/fork-nt.c b/libc/proc/fork-nt.c index 149711409..6dc06bf3f 100644 --- a/libc/proc/fork-nt.c +++ b/libc/proc/fork-nt.c @@ -72,7 +72,7 @@ __msabi extern typeof(GetCurrentProcessId) *const __imp_GetCurrentProcessId; static textwindows wontreturn void AbortFork(const char *func) { #if SYSDEBUG - kprintf("fork() %s() failed with win32 error %d\n", func, GetLastError()); + kprintf("fork() %!s() failed with win32 error %u\n", func, GetLastError()); #endif TerminateThisProcess(SIGSTKFLT); } @@ -94,57 +94,45 @@ static inline textwindows ssize_t ForkIo(int64_t h, char *p, size_t n, struct NtOverlapped *)) { size_t i; uint32_t x; - for (i = 0; i < n; i += x) + for (i = 0; i < n; i += x) { if (!f(h, p + i, n - i, &x, NULL)) return __winerr(); + if (!x) + break; + } return i; } -static dontinline textwindows bool ForkIo2(int64_t h, void *buf, size_t n, - bool32 (*fn)(int64_t, void *, - uint32_t, uint32_t *, - struct NtOverlapped *), - const char *sf, bool ischild) { +static dontinline textwindows ssize_t ForkIo2( + int64_t h, void *buf, size_t n, + bool32 (*fn)(int64_t, void *, uint32_t, uint32_t *, struct NtOverlapped *), + const char *sf, bool ischild) { ssize_t rc = ForkIo(h, buf, n, fn); if (ischild) { __tls_enabled_set(false); // prevent tls crash in kprintf __pid = __imp_GetCurrentProcessId(); __klog_handle = 0; + __maps.used = 0; } NTTRACE("%s(%ld, %p, %'zu) β†’ %'zd% m", sf, h, buf, n, rc); - return rc != -1; + return rc; } static dontinline textwindows bool WriteAll(int64_t h, void *buf, size_t n) { bool ok; - ok = ForkIo2(h, buf, n, (void *)WriteFile, "WriteFile", false); -#ifndef NDEBUG - if (ok) - ok = ForkIo2(h, &n, sizeof(n), (void *)WriteFile, "WriteFile", false); -#endif -#if SYSDEBUG - if (!ok) { - kprintf("failed to write %zu bytes to forked child: %d\n", n, - GetLastError()); - } -#endif + ok = ForkIo2(h, buf, n, (void *)WriteFile, "WriteFile", false) != -1; + if (!ok) + AbortFork("WriteAll"); // Sleep(10); return ok; } static textwindows dontinline void ReadOrDie(int64_t h, void *buf, size_t n) { - if (!ForkIo2(h, buf, n, ReadFile, "ReadFile", true)) { + ssize_t got; + if ((got = ForkIo2(h, buf, n, ReadFile, "ReadFile", true)) == -1) AbortFork("ReadFile1"); - } -#ifndef NDEBUG - size_t got; - if (!ForkIo2(h, &got, sizeof(got), ReadFile, "ReadFile", true)) { + if (got != n) AbortFork("ReadFile2"); - } - if (got != n) { - AbortFork("ReadFile_SIZE_CHECK"); - } -#endif } static textwindows int64_t MapOrDie(uint32_t prot, uint64_t size) { @@ -197,12 +185,35 @@ static textwindows void *Malloc(size_t size) { return HeapAlloc(GetProcessHeap(), 0, size); } +static textwindows void Free(void *addr) { + HeapFree(GetProcessHeap(), 0, addr); +} + +static int CountMaps(struct Dll *maps) { + int count = 0; + for (struct Dll *e = dll_first(maps); e; e = dll_next(maps, e)) + ++count; + return count; +} + +static struct Map **SortMaps(struct Dll *maps, int count) { + int j, i = 0; + struct Map **sorted = Malloc(count * sizeof(struct Map *)); + for (struct Dll *e = dll_first(maps); e; e = dll_next(maps, e)) { + struct Map *map = MAP_CONTAINER(e); + for (j = i; j > 0 && sorted[j - 1]->addr > map->addr; --j) + sorted[j] = sorted[j - 1]; + sorted[j] = map; + ++i; + } + return sorted; +} + textwindows void WinMainForked(void) { jmp_buf jb; int64_t reader; int64_t savetsc; - struct Map *map; - uint32_t varlen, oldprot; + uint32_t varlen; char16_t fvar[21 + 1 + 21 + 1]; struct Fds *fds = __veil("r", &g_fds); @@ -222,29 +233,55 @@ textwindows void WinMainForked(void) { ReadOrDie(reader, jb, sizeof(jb)); // read memory mappings from parent process - struct Map *maps = __maps.maps; + int n = 0; + struct Dll *maps = 0; for (;;) { - map = Malloc(sizeof(*map)); - ReadOrDie(reader, map, sizeof(*map)); + struct Map *map = Malloc(sizeof(struct Map)); + ReadOrDie(reader, map, sizeof(struct Map)); + if (map->addr == MAP_FAILED) { + Free(map); + break; + } + dll_init(&map->elem); + dll_make_first(&maps, &map->elem); + ++n; + } + + // created sorted array of maps + struct Map **sorted = SortMaps(maps, n); + + // map memory into process + int granularity = __granularity(); + for (int i = 0; i < n; ++i) { + struct Map *map = sorted[i]; + if ((uintptr_t)map->addr & (granularity - 1)) + continue; + size_t size = map->size; + // get true length in case mprotect() chopped up actual win32 map + for (int j = i + 1; + j < n && sorted[j]->hand == -1 && map->addr + size == sorted[j]->addr; + ++j) { + size += sorted[j]->size; + } + // obtain the most permissive access possible + unsigned prot, access; + if (map->readonlyfile) { + prot = kNtPageExecuteRead; + access = kNtFileMapRead | kNtFileMapExecute; + } else { + prot = kNtPageExecuteReadwrite; + access = kNtFileMapWrite | kNtFileMapExecute; + } if ((map->flags & MAP_TYPE) != MAP_SHARED) { // we don't need to close the map handle because sys_mmap_nt // doesn't mark it inheritable across fork() for MAP_PRIVATE - ViewOrDie((map->h = MapOrDie(kNtPageExecuteReadwrite, map->size)), - kNtFileMapWrite | kNtFileMapExecute, 0, map->size, map->addr); - ReadOrDie(reader, map->addr, map->size); + map->hand = MapOrDie(prot, size); + ViewOrDie(map->hand, access, 0, size, map->addr); + ReadOrDie(reader, map->addr, size); } else { // we can however safely inherit MAP_SHARED with zero copy - ViewOrDie(map->h, - map->readonlyfile ? kNtFileMapRead | kNtFileMapExecute - : kNtFileMapWrite | kNtFileMapExecute, - map->off, map->size, map->addr); + ViewOrDie(map->hand, access, map->off, size, map->addr); } - dll_init(&map->elem); - bool isdone = !map->next; - map->next = maps; - maps = map; - if (isdone) - break; } // read the .data and .bss program image sections @@ -259,19 +296,19 @@ textwindows void WinMainForked(void) { // fixup memory manager __maps.free = 0; __maps.used = 0; - __maps.maps = maps; __maps.count = 0; __maps.pages = 0; - dll_init(&__maps.stack.elem); - dll_make_first(&__maps.used, &__maps.stack.elem); - for (struct Map *map = maps; map; map = map->next) { + for (int i = 0; i < n; ++i) { + struct Map *map = sorted[i]; __maps.count += 1; - __maps.pages += (map->size + 4095) / 4096; - dll_make_last(&__maps.used, &map->elem); + __maps.pages += (map->size + getpagesize() - 1) / getpagesize(); + unsigned old_protect; if (!VirtualProtect(map->addr, map->size, __prot2nt(map->prot, map->iscow), - &oldprot)) + &old_protect)) AbortFork("VirtualProtect"); } + Free(sorted); + __maps.used = maps; __maps_init(); // mitosis complete @@ -288,9 +325,8 @@ textwindows void WinMainForked(void) { #if SYSDEBUG RemoveVectoredExceptionHandler(oncrash); #endif - if (_weaken(__sig_init)) { + if (_weaken(__sig_init)) _weaken(__sig_init)(); - } // jump back into function below longjmp(jb, 1); @@ -299,7 +335,6 @@ textwindows void WinMainForked(void) { textwindows int sys_fork_nt(uint32_t dwCreationFlags) { char ok; jmp_buf jb; - uint32_t op; char **args; int rc = -1; struct Proc *proc; @@ -358,18 +393,62 @@ textwindows int sys_fork_nt(uint32_t dwCreationFlags) { if (spawnrc != -1) { CloseHandle(procinfo.hThread); ok = WriteAll(writer, jb, sizeof(jb)); - for (struct Map *map = __maps.maps; ok && map; map = map->next) { + int count = 0; + // this list will be populated with the maps we're transferring + struct Dll *e2, *maps = 0; + for (struct Dll *e = dll_first(__maps.used); ok && e; e = e2) { + e2 = dll_next(__maps.used, e); + struct Map *map = MAP_CONTAINER(e); if (MAX((char *)__executable_start, map->addr) < MIN((char *)_end, map->addr + map->size)) continue; // executable image is loaded by windows + dll_remove(&__maps.used, e); + dll_make_last(&maps, e); ok = WriteAll(writer, map, sizeof(*map)); - if (ok && (map->flags & MAP_TYPE) != MAP_SHARED) { - // XXX: forking destroys thread guard pages currently - VirtualProtect(map->addr, map->size, - __prot2nt(map->prot | PROT_READ, map->iscow), &op); - ok = WriteAll(writer, map->addr, map->size); - } + ++count; } + // send a terminating Map struct to child + if (ok) { + struct Map map; + map.addr = MAP_FAILED; + ok = WriteAll(writer, &map, sizeof(map)); + } + // now write content of each map to child + int granularity = __granularity(); + struct Map **sorted = SortMaps(maps, count); + uint32_t *old_protect = Malloc(count * 4); + for (int i = 0; ok && i < count; ++i) { + struct Map *map = sorted[i]; + // we only need to worry about the base mapping + if ((uintptr_t)map->addr & (granularity - 1)) + continue; + // shared mappings don't need to be copied + if ((map->flags & MAP_TYPE) == MAP_SHARED) + continue; + // get true length in case mprotect() chopped up actual win32 map + int j; + size_t size = map->size; + for (j = i + 1; j < count && sorted[j]->hand == -1 && + map->addr + size == sorted[j]->addr; + ++j) { + size += sorted[j]->size; + } + for (int k = i; ok && k < j; ++k) + if (!(sorted[k]->prot & PROT_READ)) + ok = VirtualProtect( + sorted[k]->addr, sorted[k]->size, + __prot2nt(sorted[k]->prot | PROT_READ, map->iscow), + &old_protect[k]); + if (ok) + ok = WriteAll(writer, map->addr, size); + for (int k = i; ok && k < j; ++k) + if (!(sorted[k]->prot & PROT_READ)) + ok = VirtualProtect(sorted[k]->addr, sorted[k]->size, + old_protect[k], &old_protect[k]); + } + Free(old_protect); + Free(sorted); + dll_make_first(&__maps.used, maps); if (ok) ok = WriteAll(writer, __data_start, __data_end - __data_start); if (ok) diff --git a/libc/runtime/isstackoverflow.c b/libc/runtime/isstackoverflow.c index efe0d0696..5d19014c6 100644 --- a/libc/runtime/isstackoverflow.c +++ b/libc/runtime/isstackoverflow.c @@ -35,5 +35,5 @@ char __is_stack_overflow(siginfo_t *si, void *arg) { return false; intptr_t sp = uc->uc_mcontext.SP; intptr_t fp = (intptr_t)si->si_addr; - return ABS(fp - sp) < getauxval(AT_PAGESZ); + return ABS(fp - sp) < getpagesize(); } diff --git a/libc/runtime/opensymboltable.greg.c b/libc/runtime/opensymboltable.greg.c index bbb32adcb..433890d9d 100644 --- a/libc/runtime/opensymboltable.greg.c +++ b/libc/runtime/opensymboltable.greg.c @@ -49,7 +49,7 @@ static struct SymbolTable *OpenSymbolTableImpl(const char *filename) { size_t n, m, tsz, size; const Elf64_Sym *symtab, *sym; ptrdiff_t names_offset, name_base_offset, stp_offset; - long pagesz = getauxval(AT_PAGESZ); + long pagesz = getpagesize(); map = MAP_FAILED; if ((fd = open(filename, O_RDONLY | O_CLOEXEC)) == -1) return 0; diff --git a/libc/runtime/runtime.h b/libc/runtime/runtime.h index 9450bf435..236a06f2d 100644 --- a/libc/runtime/runtime.h +++ b/libc/runtime/runtime.h @@ -53,7 +53,7 @@ int sethostid(long) libcesque; char *getlogin(void) libcesque; int getlogin_r(char *, size_t) libcesque; int login_tty(int) libcesque; -int getpagesize(void) libcesque; +int getpagesize(void) pureconst libcesque; int syncfs(int) dontthrow libcesque; int vhangup(void) libcesque; int getdtablesize(void) libcesque; diff --git a/libc/runtime/sysconf.c b/libc/runtime/sysconf.c index a99596458..5adac2b08 100644 --- a/libc/runtime/sysconf.c +++ b/libc/runtime/sysconf.c @@ -22,10 +22,10 @@ #include "libc/calls/struct/sysinfo.h" #include "libc/calls/struct/sysinfo.internal.h" #include "libc/dce.h" +#include "libc/intrin/maps.h" #include "libc/limits.h" #include "libc/macros.internal.h" #include "libc/runtime/clktck.h" -#include "libc/intrin/maps.h" #include "libc/runtime/runtime.h" #include "libc/runtime/sysconf.h" #include "libc/sysv/consts/_posix.h" @@ -60,7 +60,7 @@ long sysconf(int name) { case _SC_CLK_TCK: return CLK_TCK; case _SC_PAGESIZE: - return __granularity(); + return getpagesize(); case _SC_ARG_MAX: return __get_arg_max(); case _SC_SIGSTKSZ: diff --git a/libc/runtime/winmain.greg.c b/libc/runtime/winmain.greg.c index f803162e2..eb75a1700 100644 --- a/libc/runtime/winmain.greg.c +++ b/libc/runtime/winmain.greg.c @@ -38,6 +38,8 @@ #include "libc/nt/process.h" #include "libc/nt/runtime.h" #include "libc/nt/signals.h" +#include "libc/nt/struct/systeminfo.h" +#include "libc/nt/systeminfo.h" #include "libc/nt/thunk/msabi.h" #include "libc/runtime/internal.h" #include "libc/runtime/memtrack.internal.h" @@ -64,6 +66,7 @@ __msabi extern typeof(GetEnvironmentStrings) *const __imp_GetEnvironmentStringsW __msabi extern typeof(GetEnvironmentVariable) *const __imp_GetEnvironmentVariableW; __msabi extern typeof(GetFileAttributes) *const __imp_GetFileAttributesW; __msabi extern typeof(GetStdHandle) *const __imp_GetStdHandle; +__msabi extern typeof(GetSystemInfo) *const __imp_GetSystemInfo; __msabi extern typeof(GetUserName) *const __imp_GetUserNameW; __msabi extern typeof(MapViewOfFileEx) *const __imp_MapViewOfFileEx; __msabi extern typeof(SetConsoleCP) *const __imp_SetConsoleCP; @@ -209,8 +212,12 @@ static abi wontreturn void WinInit(const char16_t *cmdline) { uint32_t oldattr; __imp_VirtualProtect(stackaddr, GetGuardSize(), kNtPageReadwrite | kNtPageGuard, &oldattr); - if (_weaken(__maps_stack)) - _weaken(__maps_stack)(stackaddr, 4096, stacksize, stackprot, stackhand); + if (_weaken(__maps_stack)) { + struct NtSystemInfo si; + __imp_GetSystemInfo(&si); + _weaken(__maps_stack)(stackaddr, si.dwPageSize, GetGuardSize(), stacksize, + stackprot, stackhand); + } struct WinArgs *wa = (struct WinArgs *)(stackaddr + (stacksize - sizeof(struct WinArgs))); diff --git a/libc/runtime/zipos-get.c b/libc/runtime/zipos-get.c index 7fea23495..bc7c9365b 100644 --- a/libc/runtime/zipos-get.c +++ b/libc/runtime/zipos-get.c @@ -128,7 +128,7 @@ static void __zipos_init(void) { if (!fstat(fd, &st) && (map = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0)) != MAP_FAILED) { if ((cdir = GetZipEocd(map, st.st_size, &err))) { - long pagesz = getauxval(AT_PAGESZ); + long pagesz = getpagesize(); __zipos_dismiss(map, cdir, pagesz); __zipos.map = map; __zipos.cdir = cdir; diff --git a/libc/thread/pthread_attr_init.c b/libc/thread/pthread_attr_init.c index 9db001b24..9f23d2595 100644 --- a/libc/thread/pthread_attr_init.c +++ b/libc/thread/pthread_attr_init.c @@ -38,7 +38,7 @@ errno_t pthread_attr_init(pthread_attr_t *attr) { *attr = (pthread_attr_t){ .__stacksize = GetStackSize(), - .__guardsize = getauxval(AT_PAGESZ), + .__guardsize = getpagesize(), }; return 0; } diff --git a/libc/thread/pthread_create.c b/libc/thread/pthread_create.c index 740d43cef..b9515272e 100644 --- a/libc/thread/pthread_create.c +++ b/libc/thread/pthread_create.c @@ -144,7 +144,7 @@ static int FixupCustomStackOnOpenbsd(pthread_attr_t *attr) { size_t n; uintptr_t x, y; int e, rc, pagesz; - pagesz = getauxval(AT_PAGESZ); + pagesz = getpagesize(); n = attr->__stacksize; x = (uintptr_t)attr->__stackaddr; y = ROUNDUP(x, pagesz); @@ -210,7 +210,7 @@ static errno_t pthread_create_impl(pthread_t *thread, } } else { // cosmo is managing the stack - int pagesize = getauxval(AT_PAGESZ); + int pagesize = getpagesize(); pt->pt_attr.__guardsize = ROUNDUP(pt->pt_attr.__guardsize, pagesize); pt->pt_attr.__stacksize = pt->pt_attr.__stacksize; if (pt->pt_attr.__guardsize + pagesize > pt->pt_attr.__stacksize) { diff --git a/test/libc/calls/cachestat_test.c b/test/libc/calls/cachestat_test.c index a24b6e490..63c3e8088 100644 --- a/test/libc/calls/cachestat_test.c +++ b/test/libc/calls/cachestat_test.c @@ -46,7 +46,7 @@ void SetUpOnce(void) { exit(0); } testlib_enable_tmp_setup_teardown(); - pagesize = (size_t)getauxval(AT_PAGESZ); + pagesize = (size_t)getpagesize(); // ASSERT_SYS(0, 0, pledge("stdio rpath wpath cpath", 0)); } diff --git a/test/libc/calls/madvise_test.c b/test/libc/calls/madvise_test.c index bdcdbc49a..6ddc1a13c 100644 --- a/test/libc/calls/madvise_test.c +++ b/test/libc/calls/madvise_test.c @@ -65,8 +65,8 @@ TEST(madvise, subPages) { ASSERT_NE(MAP_FAILED, (p = mmap(0, __granularity(), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); ASSERT_SYS(0, 0, - madvise(p + getauxval(AT_PAGESZ), - __granularity() - getauxval(AT_PAGESZ), MADV_WILLNEED)); + madvise(p + getpagesize(), __granularity() - getpagesize(), + MADV_WILLNEED)); ASSERT_SYS(0, 0, munmap(p, __granularity())); } diff --git a/test/libc/calls/setrlimit_test.c b/test/libc/calls/setrlimit_test.c index 2b7629ee6..bc40f8542 100644 --- a/test/libc/calls/setrlimit_test.c +++ b/test/libc/calls/setrlimit_test.c @@ -136,8 +136,8 @@ TEST(setrlimit, testMemoryLimit) { ASSERT_NE(-1, (wstatus = xspawn(0))); if (wstatus == -2) { ASSERT_EQ(0, SetKernelEnforcedMemoryLimit(MEM)); - for (gotsome = false, i = 0; i < (MEM * 2) / getauxval(AT_PAGESZ); ++i) { - p = mmap(0, getauxval(AT_PAGESZ), PROT_READ | PROT_WRITE, + for (gotsome = false, i = 0; i < (MEM * 2) / __granularity(); ++i) { + p = mmap(0, __granularity(), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_POPULATE, -1, 0); if (p != MAP_FAILED) { gotsome = true; @@ -149,7 +149,7 @@ TEST(setrlimit, testMemoryLimit) { ASSERT_EQ(ENOMEM, errno); _Exit(0); } - rngset(p, getauxval(AT_PAGESZ), _rand64, -1); + rngset(p, __granularity(), _rand64, -1); } _Exit(1); } @@ -162,24 +162,18 @@ TEST(setrlimit, testMemoryLimit) { TEST(setrlimit, testVirtualMemoryLimit) { char *p; int i, wstatus; - if (IsXnu()) - return; /* doesn't work on darwin */ - if (IsOpenbsd()) - return; /* unavailable on openbsd */ - if (IsWindows()) - return; /* of course it doesn't work on windows */ ASSERT_NE(-1, (wstatus = xspawn(0))); if (wstatus == -2) { ASSERT_EQ(0, setrlimit(RLIMIT_AS, &(struct rlimit){MEM, MEM})); - for (i = 0; i < (MEM * 2) / getauxval(AT_PAGESZ); ++i) { - p = sys_mmap(0, getauxval(AT_PAGESZ), PROT_READ | PROT_WRITE, + for (i = 0; i < (MEM * 2) / __granularity(); ++i) { + p = sys_mmap(0, __granularity(), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_POPULATE, -1, 0) .addr; if (p == MAP_FAILED) { ASSERT_EQ(ENOMEM, errno); _Exit(0); } - rngset(p, getauxval(AT_PAGESZ), _rand64, -1); + rngset(p, __granularity(), _rand64, -1); } _Exit(1); } @@ -205,15 +199,15 @@ TEST(setrlimit, testDataMemoryLimit) { ASSERT_NE(-1, (wstatus = xspawn(0))); if (wstatus == -2) { ASSERT_EQ(0, setrlimit(RLIMIT_DATA, &(struct rlimit){MEM, MEM})); - for (i = 0; i < (MEM * 2) / getauxval(AT_PAGESZ); ++i) { - p = sys_mmap(0, getauxval(AT_PAGESZ), PROT_READ | PROT_WRITE, + for (i = 0; i < (MEM * 2) / __granularity(); ++i) { + p = sys_mmap(0, __granularity(), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_POPULATE, -1, 0) .addr; if (p == MAP_FAILED) { ASSERT_EQ(ENOMEM, errno); _Exit(0); } - rngset(p, getauxval(AT_PAGESZ), _rand64, -1); + rngset(p, __granularity(), _rand64, -1); } _Exit(1); } diff --git a/test/libc/calls/sigbus_test.c b/test/libc/calls/sigbus_test.c index f67fac42e..e76983933 100644 --- a/test/libc/calls/sigbus_test.c +++ b/test/libc/calls/sigbus_test.c @@ -75,7 +75,7 @@ TEST(sigbus, test) { // map two pages of the file into memory char *map; - long pagesz = getauxval(AT_PAGESZ); + long pagesz = getpagesize(); ASSERT_NE(MAP_FAILED, (map = mmap(0, pagesz * 2, PROT_READ, MAP_PRIVATE, 3, 0))); diff --git a/test/libc/intrin/kprintf_test.c b/test/libc/intrin/kprintf_test.c index 0ba13e7e1..d4d911784 100644 --- a/test/libc/intrin/kprintf_test.c +++ b/test/libc/intrin/kprintf_test.c @@ -228,7 +228,7 @@ TEST(ksnprintf, fuzzTheUnbreakable) { char *f, b[32]; _Alignas(65536) static const char weasel[65535]; f = (void *)__veil("r", weasel); - EXPECT_SYS(0, 0, mprotect(f, __granularity(), PROT_READ | PROT_WRITE)); + EXPECT_SYS(0, 0, mprotect(f, getpagesize(), PROT_READ | PROT_WRITE)); strcpy(f, "hello %s\n"); EXPECT_EQ(12, ksnprintf(b, sizeof(b), f, "world")); EXPECT_STREQ("hello world\n", b); @@ -240,7 +240,7 @@ TEST(ksnprintf, fuzzTheUnbreakable) { f[Rando() & 15] = '%'; ksnprintf(b, sizeof(b), f, lemur64(), lemur64(), lemur64()); } - EXPECT_SYS(0, 0, mprotect(f, __granularity(), PROT_READ)); + EXPECT_SYS(0, 0, mprotect(f, getpagesize(), PROT_READ)); } TEST(kprintf, testFailure_wontClobberErrnoAndBypassesSystemCallSupport) { diff --git a/test/libc/intrin/mmap_test.c b/test/libc/intrin/mmap_test.c index 9868819ab..44e9216ca 100644 --- a/test/libc/intrin/mmap_test.c +++ b/test/libc/intrin/mmap_test.c @@ -60,9 +60,11 @@ __static_yoink("zipos"); +int pagesz; int granularity; void SetUpOnce(void) { + pagesz = getpagesize(); granularity = __granularity(); testlib_enable_tmp_setup_teardown(); // ASSERT_SYS(0, 0, pledge("stdio rpath wpath cpath proc", 0)); @@ -84,27 +86,41 @@ TEST(mmap, overflow) { TEST(mmap, noreplaceImage) { ASSERT_SYS(EEXIST, MAP_FAILED, - mmap(__executable_start, granularity, PROT_READ, + mmap(__executable_start, 1, PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED_NOREPLACE, -1, 0)); } TEST(mmap, noreplaceExistingMap) { char *p; - ASSERT_NE(MAP_FAILED, (p = mmap(0, granularity, PROT_READ, - MAP_ANONYMOUS | MAP_PRIVATE, -1, 0))); + ASSERT_NE(MAP_FAILED, + (p = mmap(0, 1, PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0))); ASSERT_SYS(EEXIST, MAP_FAILED, - mmap(p, granularity, PROT_READ, + mmap(p, 1, PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED_NOREPLACE, -1, 0)); - EXPECT_SYS(0, 0, munmap(p, granularity)); + EXPECT_SYS(0, 0, munmap(p, 1)); +} + +TEST(mmap, pageBeyondGone) { + int pagesz = getpagesize(); + char *p = mmap(0, pagesz * 2, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + ASSERT_EQ(0, munmap(p, pagesz * 2)); + p = mmap(p, 1, PROT_READ | PROT_WRITE, + MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + ASSERT_NE(MAP_FAILED, p); + EXPECT_TRUE(testlib_memoryexists(p)); + EXPECT_TRUE(testlib_memoryexists(p + pagesz - 1)); + EXPECT_FALSE(testlib_memoryexists(p + pagesz)); + ASSERT_EQ(0, munmap(p, 1)); } TEST(mmap, fixedTaken) { char *p; - ASSERT_NE(MAP_FAILED, (p = mmap(0, granularity, PROT_READ, - MAP_ANONYMOUS | MAP_PRIVATE, -1, 0))); - ASSERT_NE(MAP_FAILED, mmap(p, granularity, PROT_READ, + ASSERT_NE(MAP_FAILED, + (p = mmap(0, 1, PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0))); + ASSERT_NE(MAP_FAILED, mmap(p, 1, PROT_READ, MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)); - EXPECT_SYS(0, 0, munmap(p, granularity)); + EXPECT_SYS(0, 0, munmap(p, 1)); } TEST(mmap, hint) { @@ -181,7 +197,7 @@ TEST(mmap, testMapFile_fdGetsClosed_makesNoDifference) { EXPECT_NE(-1, close(fd)); EXPECT_STREQN("hello", p, 5); p[1] = 'a'; - EXPECT_NE(-1, msync(p, getauxval(AT_PAGESZ), MS_SYNC)); + EXPECT_NE(-1, msync(p, getpagesize(), MS_SYNC)); ASSERT_NE(-1, (fd = open(path, O_RDONLY))); EXPECT_EQ(5, read(fd, buf, 5)); EXPECT_STREQN("hallo", buf, 5); @@ -193,7 +209,7 @@ TEST(mmap, testMapFile_fdGetsClosed_makesNoDifference) { TEST(mmap, fileOffset) { int fd; char *map; - int offset_align = IsWindows() ? granularity : getauxval(AT_PAGESZ); + int offset_align = IsWindows() ? granularity : getpagesize(); ASSERT_NE(-1, (fd = open("foo", O_CREAT | O_RDWR, 0644))); EXPECT_NE(-1, ftruncate(fd, offset_align * 2)); EXPECT_NE(-1, pwrite(fd, "hello", 5, offset_align * 0)); @@ -433,15 +449,15 @@ void *ptrs[N]; void BenchMmapPrivate(void) { void *p; - p = mmap(0, granularity, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, - -1, 0); + p = mmap(0, granularity * 10, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); if (p == MAP_FAILED) __builtin_trap(); ptrs[count++] = p; } void BenchUnmap(void) { - if (munmap(ptrs[--count], granularity)) + if (munmap(ptrs[--count], granularity * 10)) __builtin_trap(); } diff --git a/test/libc/intrin/mprotect_test.c b/test/libc/intrin/mprotect_test.c index 2271336c1..6a2e23b1f 100644 --- a/test/libc/intrin/mprotect_test.c +++ b/test/libc/intrin/mprotect_test.c @@ -120,9 +120,9 @@ void TearDown(void) { } TEST(mprotect, testOkMemory) { - char *p = gc(memalign(getauxval(AT_PAGESZ), getauxval(AT_PAGESZ))); + char *p = gc(memalign(getpagesize(), getpagesize())); p[0] = 0; - ASSERT_NE(-1, mprotect(p, getauxval(AT_PAGESZ), PROT_READ | PROT_WRITE)); + ASSERT_NE(-1, mprotect(p, getpagesize(), PROT_READ | PROT_WRITE)); p[0] = 1; EXPECT_EQ(1, p[0]); EXPECT_FALSE(gotsegv); @@ -131,20 +131,19 @@ TEST(mprotect, testOkMemory) { TEST(mprotect, testSegfault_writeToReadOnlyAnonymous) { volatile char *p; - p = gc(memalign(getauxval(AT_PAGESZ), getauxval(AT_PAGESZ))); + p = gc(memalign(getpagesize(), getpagesize())); EXPECT_FALSE(gotsegv); p[0] = 1; EXPECT_FALSE(gotsegv); EXPECT_FALSE(gotbusted); - EXPECT_NE(-1, mprotect((void *)p, getauxval(AT_PAGESZ), PROT_READ)); + EXPECT_NE(-1, mprotect((void *)p, getpagesize(), PROT_READ)); __expropriate(p[0]); EXPECT_FALSE(gotsegv); EXPECT_FALSE(gotbusted); p[0] = 2; EXPECT_TRUE(gotsegv | gotbusted); EXPECT_EQ(1, p[0]); - EXPECT_NE(-1, - mprotect((void *)p, getauxval(AT_PAGESZ), PROT_READ | PROT_WRITE)); + EXPECT_NE(-1, mprotect((void *)p, getpagesize(), PROT_READ | PROT_WRITE)); } TEST(mprotect, testExecOnly_canExecute) { @@ -164,22 +163,21 @@ TEST(mprotect, testExecOnly_canExecute) { TEST(mprotect, testProtNone_cantEvenRead) { volatile char *p; - p = gc(memalign(getauxval(AT_PAGESZ), getauxval(AT_PAGESZ))); - EXPECT_NE(-1, mprotect((void *)p, getauxval(AT_PAGESZ), PROT_NONE)); + p = gc(memalign(getpagesize(), getpagesize())); + EXPECT_NE(-1, mprotect((void *)p, getpagesize(), PROT_NONE)); __expropriate(p[0]); EXPECT_TRUE(gotsegv | gotbusted); - EXPECT_NE(-1, - mprotect((void *)p, getauxval(AT_PAGESZ), PROT_READ | PROT_WRITE)); + EXPECT_NE(-1, mprotect((void *)p, getpagesize(), PROT_READ | PROT_WRITE)); } TEST(mprotect, testExecJit_actuallyWorks) { - int (*p)(void) = gc(memalign(getauxval(AT_PAGESZ), getauxval(AT_PAGESZ))); + int (*p)(void) = gc(memalign(getpagesize(), getpagesize())); memcpy(p, kRet31337, sizeof(kRet31337)); - EXPECT_NE(-1, mprotect(p, getauxval(AT_PAGESZ), PROT_EXEC)); + EXPECT_NE(-1, mprotect(p, getpagesize(), PROT_EXEC)); EXPECT_EQ(31337, p()); EXPECT_FALSE(gotsegv); EXPECT_FALSE(gotbusted); - EXPECT_NE(-1, mprotect(p, getauxval(AT_PAGESZ), PROT_READ | PROT_WRITE)); + EXPECT_NE(-1, mprotect(p, getpagesize(), PROT_READ | PROT_WRITE)); } TEST(mprotect, testRwxMap_vonNeumannRules) { @@ -187,14 +185,13 @@ TEST(mprotect, testRwxMap_vonNeumannRules) { return; // boo if (IsXnuSilicon()) return; // boo - int (*p)(void) = gc(memalign(getauxval(AT_PAGESZ), getauxval(AT_PAGESZ))); + int (*p)(void) = gc(memalign(getpagesize(), getpagesize())); memcpy(p, kRet31337, sizeof(kRet31337)); - EXPECT_NE(-1, mprotect(p, getauxval(AT_PAGESZ), - PROT_READ | PROT_WRITE | PROT_EXEC)); + EXPECT_NE(-1, mprotect(p, getpagesize(), PROT_READ | PROT_WRITE | PROT_EXEC)); EXPECT_EQ(31337, p()); EXPECT_FALSE(gotsegv); EXPECT_FALSE(gotbusted); - EXPECT_NE(-1, mprotect(p, getauxval(AT_PAGESZ), PROT_READ | PROT_WRITE)); + EXPECT_NE(-1, mprotect(p, getpagesize(), PROT_READ | PROT_WRITE)); } TEST(mprotect, testExecuteFlatFileMapOpenedAsReadonly) { @@ -231,13 +228,13 @@ TEST(mprotect, testFileMap_canChangeToExecWhileOpenInRdwrMode) { } TEST(mprotect, testBadProt_failsEinval) { - volatile char *p = gc(memalign(getauxval(AT_PAGESZ), getauxval(AT_PAGESZ))); + volatile char *p = gc(memalign(getpagesize(), getpagesize())); EXPECT_EQ(-1, mprotect((void *)p, 9999, -1)); EXPECT_EQ(EINVAL, errno); } TEST(mprotect, testZeroSize_doesNothing) { - volatile char *p = gc(memalign(getauxval(AT_PAGESZ), getauxval(AT_PAGESZ))); + volatile char *p = gc(memalign(getpagesize(), getpagesize())); EXPECT_NE(-1, mprotect((void *)p, 0, PROT_READ)); p[0] = 1; EXPECT_FALSE(gotsegv); diff --git a/third_party/dlmalloc/init.inc b/third_party/dlmalloc/init.inc index 970bad026..682b50408 100644 --- a/third_party/dlmalloc/init.inc +++ b/third_party/dlmalloc/init.inc @@ -1,5 +1,6 @@ #include "libc/sysv/consts/auxv.h" #include "libc/runtime/runtime.h" +#include "libc/runtime/runtime.h" /* ---------------------------- setting mparams -------------------------- */ @@ -48,7 +49,7 @@ __attribute__((__constructor__(49))) int init_mparams(void) { size_t gsize; #if defined(__COSMOPOLITAN__) - psize = getauxval(AT_PAGESZ); + psize = getpagesize(); gsize = DEFAULT_GRANULARITY ? DEFAULT_GRANULARITY : psize; #elif !defined(WIN32) psize = malloc_getpagesize; diff --git a/tool/net/winbench.c b/tool/net/winbench.c index 5fad9df33..ea8063709 100644 --- a/tool/net/winbench.c +++ b/tool/net/winbench.c @@ -244,7 +244,7 @@ int main(int argc, char *argv[]) { sigset_t block; sigfillset(&block); pthread_attr_t attr; - int pagesz = getauxval(AT_PAGESZ); + int pagesz = getpagesize(); pthread_t *threads = calloc(nthreads, sizeof(pthread_t)); unassert(!pthread_attr_init(&attr)); unassert(!pthread_attr_setstacksize(&attr, 65536)); diff --git a/tool/viz/cpuid.c b/tool/viz/cpuid.c index a77cc7bdd..1e3e44a97 100644 --- a/tool/viz/cpuid.c +++ b/tool/viz/cpuid.c @@ -364,6 +364,7 @@ int main(int argc, char *argv[]) { CANIUSE(TM2); CANIUSE(TME); CANIUSE(TSC); + CANIUSE(INVTSC); CANIUSE(TSC_ADJUST); CANIUSE(TSC_DEADLINE_TIMER); CANIUSE(TSX_FORCE_ABORT); diff --git a/tool/viz/life.c b/tool/viz/life.c index 896e19034..8e223f894 100644 --- a/tool/viz/life.c +++ b/tool/viz/life.c @@ -497,18 +497,18 @@ static void *NewBoard(size_t *out_size) { char *p; size_t s, n, k; s = (byn * bxn) >> 3; - k = getauxval(AT_PAGESZ) + ROUNDUP(s, getauxval(AT_PAGESZ)); - n = ROUNDUP(k + getauxval(AT_PAGESZ), sysconf(_SC_PAGESIZE)); + k = getpagesize() + ROUNDUP(s, getpagesize()); + n = ROUNDUP(k + getpagesize(), sysconf(_SC_PAGESIZE)); p = _mapanon(n); - mprotect(p, getauxval(AT_PAGESZ), 0); + mprotect(p, getpagesize(), 0); mprotect(p + k, n - k, 0); if (out_size) *out_size = n; - return p + getauxval(AT_PAGESZ); + return p + getpagesize(); } static void FreeBoard(void *p, size_t n) { - munmap((char *)p - getauxval(AT_PAGESZ), n); + munmap((char *)p - getpagesize(), n); } static void AllocateBoardsWithHardwareAcceleratedMemorySafety(void) { From fc6542266017cee03545e614a3304d78661af376 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Fri, 5 Jul 2024 12:55:46 -0700 Subject: [PATCH 033/405] Remove __mmap() and __munmap() --- libc/intrin/maps.h | 2 -- libc/intrin/mmap.c | 6 +++--- libc/runtime/enable_tls.c | 8 ++++---- libc/runtime/zipos-mmap.c | 2 +- libc/runtime/zipos-open.c | 9 +++------ 5 files changed, 11 insertions(+), 16 deletions(-) diff --git a/libc/intrin/maps.h b/libc/intrin/maps.h index e6a56b28d..5b5aba76a 100644 --- a/libc/intrin/maps.h +++ b/libc/intrin/maps.h @@ -47,8 +47,6 @@ void __maps_unlock(void); void __maps_add(struct Map *); struct Map *__maps_alloc(void); void __maps_free(struct Map *); -int __munmap(char *, size_t, bool); -void *__mmap(char *, size_t, int, int, int, int64_t); void __maps_stack(char *, int, int, size_t, int, intptr_t); struct AddrSize __get_main_stack(void); diff --git a/libc/intrin/mmap.c b/libc/intrin/mmap.c index af9f016c8..c4229924e 100644 --- a/libc/intrin/mmap.c +++ b/libc/intrin/mmap.c @@ -176,7 +176,7 @@ struct Map *__maps_alloc(void) { return map; } -int __munmap(char *addr, size_t size, bool untrack_only) { +static int __munmap(char *addr, size_t size, bool untrack_only) { // validate arguments int pagesz = getpagesize(); @@ -479,8 +479,8 @@ static void *__mmap_impl(char *addr, size_t size, int prot, int flags, int fd, return res; } -void *__mmap(char *addr, size_t size, int prot, int flags, int fd, - int64_t off) { +static void *__mmap(char *addr, size_t size, int prot, int flags, int fd, + int64_t off) { char *res; int pagesz = getpagesize(); int granularity = __granularity(); diff --git a/libc/runtime/enable_tls.c b/libc/runtime/enable_tls.c index d2ec8d9de..92807978e 100644 --- a/libc/runtime/enable_tls.c +++ b/libc/runtime/enable_tls.c @@ -148,8 +148,8 @@ textstartup void __enable_tls(void) { // if a binary needs this much thread_local storage, then it // surely must have linked the mmap() function at some point // we can't call mmap() because it's too early for sig block - mem = _weaken(__mmap)(0, siz, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + mem = _weaken(mmap)(0, siz, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); } struct CosmoTib *tib = (struct CosmoTib *)(mem + siz - sizeof(*tib)); @@ -176,8 +176,8 @@ textstartup void __enable_tls(void) { // if a binary needs this much thread_local storage, then it // surely must have linked the mmap() function at some point // we can't call mmap() because it's too early for sig block - mem = _weaken(__mmap)(0, size, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + mem = _weaken(mmap)(0, size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); } struct CosmoTib *tib = diff --git a/libc/runtime/zipos-mmap.c b/libc/runtime/zipos-mmap.c index 237b9d16a..ae3559494 100644 --- a/libc/runtime/zipos-mmap.c +++ b/libc/runtime/zipos-mmap.c @@ -77,7 +77,7 @@ void *__zipos_mmap(void *addr, size_t size, int prot, int flags, flags |= MAP_PRIVATE | MAP_ANONYMOUS; const int tempProt = !IsXnu() ? prot | PROT_WRITE : PROT_WRITE; - void *outAddr = __mmap(addr, size, tempProt, flags, -1, 0); + void *outAddr = mmap(addr, size, tempProt, flags, -1, 0); if (outAddr == MAP_FAILED) { return MAP_FAILED; } diff --git a/libc/runtime/zipos-open.c b/libc/runtime/zipos-open.c index 1bd8e568a..5dfda7ea5 100644 --- a/libc/runtime/zipos-open.c +++ b/libc/runtime/zipos-open.c @@ -48,18 +48,15 @@ void __zipos_drop(struct ZiposHandle *h) { if (atomic_fetch_sub_explicit(&h->refs, 1, memory_order_release)) return; atomic_thread_fence(memory_order_acquire); - __munmap((char *)h, h->mapsize, false); + munmap((char *)h, h->mapsize); } static struct ZiposHandle *__zipos_alloc(struct Zipos *zipos, size_t size) { size_t mapsize; - int granularity; struct ZiposHandle *h; - granularity = __granularity(); mapsize = sizeof(struct ZiposHandle) + size; - mapsize = (mapsize + granularity - 1) & -granularity; - if ((h = __mmap(0, mapsize, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) != MAP_FAILED) { + if ((h = mmap(0, mapsize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, + -1, 0)) != MAP_FAILED) { h->size = size; h->zipos = zipos; h->mapsize = mapsize; From 3756870635d3a4b5a12dff0f266a8b073c830dc2 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Fri, 5 Jul 2024 12:56:03 -0700 Subject: [PATCH 034/405] Implement new red-black tree --- libc/intrin/rbtree.c | 312 +++++++++++++++++++++++++++++++++ libc/intrin/rbtree.h | 57 ++++++ test/libc/intrin/rbtree_test.c | 125 +++++++++++++ 3 files changed, 494 insertions(+) create mode 100644 libc/intrin/rbtree.c create mode 100644 libc/intrin/rbtree.h create mode 100644 test/libc/intrin/rbtree_test.c diff --git a/libc/intrin/rbtree.c b/libc/intrin/rbtree.c new file mode 100644 index 000000000..3fc3ae5cc --- /dev/null +++ b/libc/intrin/rbtree.c @@ -0,0 +1,312 @@ +// Copyright 2024 Justine Alexandra Roberts Tunney +// +// Permission to use, copy, modify, and/or distribute this software for +// any purpose with or without fee is hereby granted, provided that the +// above copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include "rbtree.h" +#include "libc/dce.h" +#include "libc/str/str.h" + +#define RBTREE_DEBUG + +struct rbtree *rbtree_next(struct rbtree *node) { + if (!node) + return 0; + if (node->right) + return rbtree_first(node->right); + struct rbtree *parent = node->parent; + while (parent && node == parent->right) { + node = parent; + parent = parent->parent; + } + return parent; +} + +struct rbtree *rbtree_prev(struct rbtree *node) { + if (!node) + return 0; + if (rbtree_get_left(node)) + return rbtree_last(rbtree_get_left(node)); + struct rbtree *parent = node->parent; + while (parent && node == rbtree_get_left(parent)) { + node = parent; + parent = parent->parent; + } + return parent; +} + +struct rbtree *rbtree_first(struct rbtree *node) { + while (node && rbtree_get_left(node)) + node = rbtree_get_left(node); + return node; +} + +struct rbtree *rbtree_last(struct rbtree *node) { + while (node && node->right) + node = node->right; + return node; +} + +static void rbtree_rotate_left(struct rbtree **root, struct rbtree *x) { + struct rbtree *y = x->right; + x->right = rbtree_get_left(y); + if (rbtree_get_left(y)) + rbtree_get_left(y)->parent = x; + y->parent = x->parent; + if (!x->parent) { + *root = y; + } else if (x == rbtree_get_left(x->parent)) { + rbtree_set_left(x->parent, y); + } else { + x->parent->right = y; + } + rbtree_set_left(y, x); + x->parent = y; +} + +static void rbtree_rotate_right(struct rbtree **root, struct rbtree *y) { + struct rbtree *x = rbtree_get_left(y); + rbtree_set_left(y, x->right); + if (x->right) + x->right->parent = y; + x->parent = y->parent; + if (!y->parent) { + *root = x; + } else if (y == y->parent->right) { + y->parent->right = x; + } else { + rbtree_set_left(y->parent, x); + } + x->right = y; + y->parent = x; +} + +static void rbtree_insert_fixup(struct rbtree **root, struct rbtree *node) { + rbtree_set_red(node, 1); + while (node != *root && rbtree_get_red(node->parent)) { + if (node->parent == rbtree_get_left(node->parent->parent)) { + struct rbtree *uncle = node->parent->parent->right; + if (uncle && rbtree_get_red(uncle)) { + rbtree_set_red(node->parent, 0); + rbtree_set_red(uncle, 0); + rbtree_set_red(node->parent->parent, 1); + node = node->parent->parent; + } else { + if (node == node->parent->right) { + node = node->parent; + rbtree_rotate_left(root, node); + } + rbtree_set_red(node->parent, 0); + rbtree_set_red(node->parent->parent, 1); + rbtree_rotate_right(root, node->parent->parent); + } + } else { + struct rbtree *uncle = rbtree_get_left(node->parent->parent); + if (uncle && rbtree_get_red(uncle)) { + rbtree_set_red(node->parent, 0); + rbtree_set_red(uncle, 0); + rbtree_set_red(node->parent->parent, 1); + node = node->parent->parent; + } else { + if (node == rbtree_get_left(node->parent)) { + node = node->parent; + rbtree_rotate_right(root, node); + } + rbtree_set_red(node->parent, 0); + rbtree_set_red(node->parent->parent, 1); + rbtree_rotate_left(root, node->parent->parent); + } + } + } + rbtree_set_red(*root, 0); +} + +void rbtree_insert(struct rbtree **root, struct rbtree *node, + rbtree_cmp_f *cmp) { + bzero(node, sizeof(*node)); + if (!*root) { + *root = node; + } else { + struct rbtree *search = *root; + struct rbtree *parent = 0; + do { + parent = search; + if (cmp(node, search) < 0) { + search = rbtree_get_left(search); + } else { + search = search->right; + } + } while (search); + if (cmp(node, parent) < 0) { + rbtree_set_left(parent, node); + } else { + parent->right = node; + } + node->parent = parent; + rbtree_insert_fixup(root, node); + } +} + +static void rbtree_transplant(struct rbtree **root, struct rbtree *u, + struct rbtree *v) { + if (!u->parent) { + *root = v; + } else if (u == rbtree_get_left(u->parent)) { + rbtree_set_left(u->parent, v); + } else { + u->parent->right = v; + } + if (v) + v->parent = u->parent; +} + +static void rbtree_remove_fixup(struct rbtree **root, struct rbtree *node, + struct rbtree *parent) { + while (node != *root && (!node || !rbtree_get_red(node))) { + if (node == rbtree_get_left(parent)) { + struct rbtree *sibling = parent->right; + if (rbtree_get_red(sibling)) { + rbtree_set_red(sibling, 0); + rbtree_set_red(parent, 1); + rbtree_rotate_left(root, parent); + sibling = parent->right; + } + if ((!rbtree_get_left(sibling) || + !rbtree_get_red(rbtree_get_left(sibling))) && + (!sibling->right || !rbtree_get_red(sibling->right))) { + rbtree_set_red(sibling, 1); + node = parent; + parent = node->parent; + } else { + if (!sibling->right || !rbtree_get_red(sibling->right)) { + rbtree_set_red(rbtree_get_left(sibling), 0); + rbtree_set_red(sibling, 1); + rbtree_rotate_right(root, sibling); + sibling = parent->right; + } + rbtree_set_red(sibling, rbtree_get_red(parent)); + rbtree_set_red(parent, 0); + rbtree_set_red(sibling->right, 0); + rbtree_rotate_left(root, parent); + node = *root; + break; + } + } else { + struct rbtree *sibling = rbtree_get_left(parent); + if (rbtree_get_red(sibling)) { + rbtree_set_red(sibling, 0); + rbtree_set_red(parent, 1); + rbtree_rotate_right(root, parent); + sibling = rbtree_get_left(parent); + } + if ((!sibling->right || !rbtree_get_red(sibling->right)) && + (!rbtree_get_left(sibling) || + !rbtree_get_red(rbtree_get_left(sibling)))) { + rbtree_set_red(sibling, 1); + node = parent; + parent = node->parent; + } else { + if (!rbtree_get_left(sibling) || + !rbtree_get_red(rbtree_get_left(sibling))) { + rbtree_set_red(sibling->right, 0); + rbtree_set_red(sibling, 1); + rbtree_rotate_left(root, sibling); + sibling = rbtree_get_left(parent); + } + rbtree_set_red(sibling, rbtree_get_red(parent)); + rbtree_set_red(parent, 0); + rbtree_set_red(rbtree_get_left(sibling), 0); + rbtree_rotate_right(root, parent); + node = *root; + break; + } + } + } + if (node) + rbtree_set_red(node, 0); +} + +void rbtree_remove(struct rbtree **root, struct rbtree *node) { + struct rbtree *y = node; + struct rbtree *x = 0; + struct rbtree *x_parent = 0; + int y_original_color = rbtree_get_red(y); + if (!rbtree_get_left(node)) { + x = node->right; + rbtree_transplant(root, node, node->right); + x_parent = node->parent; + } else if (!node->right) { + x = rbtree_get_left(node); + rbtree_transplant(root, node, rbtree_get_left(node)); + x_parent = node->parent; + } else { + y = rbtree_first(node->right); + y_original_color = rbtree_get_red(y); + x = y->right; + if (y->parent == node) { + if (x) + x->parent = y; + x_parent = y; + } else { + rbtree_transplant(root, y, y->right); + y->right = node->right; + y->right->parent = y; + x_parent = y->parent; + } + rbtree_transplant(root, node, y); + rbtree_set_left(y, rbtree_get_left(node)); + rbtree_get_left(y)->parent = y; + rbtree_set_red(y, rbtree_get_red(node)); + } + if (!y_original_color) + rbtree_remove_fixup(root, x, x_parent); +} + +struct rbtree *rbtree_get(const struct rbtree *node, const struct rbtree *key, + rbtree_cmp_f *cmp) { + while (node) { + int c = cmp(key, node); + if (c < 0) { + node = rbtree_get_left(node); + } else if (c > 0) { + node = node->right; + } else { + return (struct rbtree *)node; + } + } + return 0; +} + +struct rbtree *rbtree_floor(const struct rbtree *node, const struct rbtree *key, + rbtree_cmp_f *cmp) { + while (node) { + if (cmp(key, node) < 0) { + node = rbtree_get_left(node); + } else { + node = node->right; + } + } + return (struct rbtree *)node; +} + +struct rbtree *rbtree_ceil(const struct rbtree *node, const struct rbtree *key, + rbtree_cmp_f *cmp) { + while (node) { + if (cmp(node, key) < 0) { + node = rbtree_get_left(node); + } else { + node = node->right; + } + } + return (struct rbtree *)node; +} diff --git a/libc/intrin/rbtree.h b/libc/intrin/rbtree.h new file mode 100644 index 000000000..0c63f67dd --- /dev/null +++ b/libc/intrin/rbtree.h @@ -0,0 +1,57 @@ +#ifdef _COSMO_SOURCE +#ifndef COSMOPOLITAN_RBTREE_H_ +#define COSMOPOLITAN_RBTREE_H_ +#define rbtree_ceil __rbtree_ceil +#define rbtree_first __rbtree_first +#define rbtree_floor __rbtree_floor +#define rbtree_get __rbtree_get +#define rbtree_insert __rbtree_insert +#define rbtree_last __rbtree_last +#define rbtree_next __rbtree_next +#define rbtree_prev __rbtree_prev +#define rbtree_remove __rbtree_remove +COSMOPOLITAN_C_START_ + +#define RBTREE_CONTAINER(t, f, p) ((t *)(((char *)(p)) - offsetof(t, f))) + +struct rbtree { + uintptr_t word; + struct rbtree *right; + struct rbtree *parent; +}; + +typedef int rbtree_cmp_f(const struct rbtree *, const struct rbtree *); + +static inline struct rbtree *rbtree_get_left(const struct rbtree *node) { + return (struct rbtree *)(node->word & -2); +} + +static inline void rbtree_set_left(struct rbtree *node, struct rbtree *left) { + node->word = (uintptr_t)left | (node->word & 1); +} + +static inline int rbtree_get_red(const struct rbtree *node) { + return node->word & 1; +} + +static inline void rbtree_set_red(struct rbtree *node, int red) { + node->word &= -2; + node->word |= red; +} + +struct rbtree *rbtree_next(struct rbtree *) libcesque; +struct rbtree *rbtree_prev(struct rbtree *) libcesque; +struct rbtree *rbtree_first(struct rbtree *) libcesque; +struct rbtree *rbtree_last(struct rbtree *) libcesque; +void rbtree_remove(struct rbtree **, struct rbtree *) libcesque; +void rbtree_insert(struct rbtree **, struct rbtree *, rbtree_cmp_f *) libcesque; +struct rbtree *rbtree_get(const struct rbtree *, const struct rbtree *, + rbtree_cmp_f *) libcesque; +struct rbtree *rbtree_ceil(const struct rbtree *, const struct rbtree *, + rbtree_cmp_f *) libcesque; +struct rbtree *rbtree_floor(const struct rbtree *, const struct rbtree *, + rbtree_cmp_f *) libcesque; + +COSMOPOLITAN_C_END_ +#endif /* COSMOPOLITAN_RBTREE_H_ */ +#endif /* _COSMO_SOURCE */ diff --git a/test/libc/intrin/rbtree_test.c b/test/libc/intrin/rbtree_test.c new file mode 100644 index 000000000..5bcea721c --- /dev/null +++ b/test/libc/intrin/rbtree_test.c @@ -0,0 +1,125 @@ +// Copyright 2024 Justine Alexandra Roberts Tunney +// +// Permission to use, copy, modify, and/or distribute this software for +// any purpose with or without fee is hereby granted, provided that the +// above copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include "libc/intrin/rbtree.h" +#include "libc/intrin/kprintf.h" +#include "libc/macros.internal.h" +#include "libc/runtime/runtime.h" +#include "libc/stdio/rand.h" + +#define NUMBER_CONTAINER(e) RBTREE_CONTAINER(struct number, elem, e) + +void rbtree_checker(const struct rbtree *node, const struct rbtree *parent, + int black_count, int *black_height, rbtree_cmp_f *cmp) { + if (!node) { + // Leaf nodes are considered black + if (*black_height == -1) { + *black_height = black_count; + } else if (black_count != *black_height) { + // ILLEGAL TREE: Black height mismatch + __builtin_trap(); + } + return; + } + if (node->parent != parent) + // ILLEGAL TREE: Parent link is incorrect + __builtin_trap(); + if (parent) { + if (rbtree_get_left(parent) == node && cmp(parent, node) < 0) + // ILLEGAL TREE: Binary search property violated on left child + __builtin_trap(); + if (parent->right == node && cmp(node, parent) < 0) + // ILLEGAL TREE: Binary search property violated on right child + __builtin_trap(); + } + if (!rbtree_get_red(node)) { + black_count++; + } else if (parent && rbtree_get_red(parent)) { + // ILLEGAL TREE: Red node has red child + __builtin_trap(); + } + rbtree_checker(rbtree_get_left(node), node, black_count, black_height, cmp); + rbtree_checker(node->right, node, black_count, black_height, cmp); +} + +void rbtree_check(struct rbtree *root, rbtree_cmp_f *cmp) { + if (root) { + if (rbtree_get_red(root)) + // ILLEGAL TREE: root node must be black + __builtin_trap(); + int black_height = -1; + rbtree_checker(root, 0, 0, &black_height, cmp); + } +} + +struct number { + int number; + struct rbtree elem; +}; + +int number_compare(const struct rbtree *ra, const struct rbtree *rb) { + const struct number *a = NUMBER_CONTAINER(ra); + const struct number *b = NUMBER_CONTAINER(rb); + return (a->number > b->number) - (a->number < b->number); +} + +struct number *number_new(int number) { + static int used; + static struct number heap[8192]; + if (used == ARRAYLEN(heap)) + return 0; + struct number *res = &heap[used++]; + res->number = number; + return res; +} + +struct rbtree *tree = 0; + +void print(void) { + for (struct rbtree *e = rbtree_first(tree); e; e = rbtree_next(e)) + kprintf("%3d", NUMBER_CONTAINER(e)->number); + kprintf("\n"); +} + +void print_reversed(void) { + for (struct rbtree *e = rbtree_last(tree); e; e = rbtree_prev(e)) + kprintf("%3d", NUMBER_CONTAINER(e)->number); + kprintf("\n"); +} + +void simple_test(void) { + static const int kNumba[] = {74, 53, 96, 70, 34, 95, 30, 2, 89, 46, + 23, 2, 52, 0, 34, 12, 90, 95, 32, 65}; + for (int i = 0; i < 20; ++i) { + int number = kNumba[i]; + kprintf("%3d", number); + rbtree_insert(&tree, &number_new(number)->elem, number_compare); + rbtree_check(tree, number_compare); + } + kprintf("\n"); + print(); + print_reversed(); + for (int i = 0; i < 20; ++i) { + rbtree_remove(&tree, rbtree_get(tree, &(&(struct number){kNumba[i]})->elem, + number_compare)); + rbtree_check(tree, number_compare); + print(); + } +} + +int main() { + ShowCrashReports(); + simple_test(); +} From 8c645fa1ee6fe95e52ae76360d061fe9b5c3ce81 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Fri, 5 Jul 2024 23:13:20 -0700 Subject: [PATCH 035/405] Make mmap() scalable It's now possible to create thousands of thousands of sparse independent memory mappings, without any slowdown. The memory manager is better with tracking memory protection now, particularly on Windows in a precise way that can be restored during fork(). You now have the highest quality mem manager possible. It's even better than some OSes like XNU, where mmap() is implemented as an O(n) operation which means sadly things aren't much improved over there. With this change the llamafile HTTP server endpoint at /tokenize with a prompt of 50 tokens is now able to handle 2.6m r/sec --- libc/calls/setrlimit.c | 2 +- libc/intrin/BUILD.mk | 4 + libc/intrin/describemapping.c | 4 +- libc/intrin/describeprotflags.c | 12 +- libc/intrin/describerlimit.c | 16 +- libc/intrin/directmap-nt.c | 3 +- libc/intrin/dll.c | 8 +- libc/intrin/kprintf.greg.c | 30 +- libc/intrin/maps.c | 4 +- libc/intrin/maps.h | 54 ++- libc/intrin/mmap.c | 260 +++++++-------- libc/intrin/mprotect.c | 189 ++++++----- libc/intrin/msync-nt.c | 21 +- libc/intrin/printmaps.c | 11 +- libc/intrin/prot2nt.greg.c | 2 + libc/intrin/pthread_delay_np.c | 40 +++ libc/intrin/pthread_mutex_lock.c | 125 +++---- libc/intrin/pthread_mutex_trylock.c | 1 + libc/intrin/pthread_mutex_unlock.c | 1 + libc/intrin/pthread_syshand.c | 2 +- libc/intrin/pthread_tid.c | 2 +- libc/{calls => intrin}/pthread_yield_np.c | 0 libc/intrin/rbtree.c | 312 ------------------ libc/intrin/rbtree.h | 57 ---- libc/intrin/tree.c | 271 +++++++++++++++ libc/intrin/tree.h | 91 +++++ libc/log/oncrash_amd64.c | 10 +- libc/proc/fork-nt.c | 142 ++++---- libc/proc/fork.c | 17 +- libc/proc/posix_spawn.c | 57 ++-- libc/runtime/mapstack.c | 5 +- libc/runtime/runtime.h | 2 +- libc/stdio/printargs.c | 2 +- libc/sysv/consts.sh | 1 + libc/sysv/consts/PROT_GUARD.S | 2 + libc/sysv/consts/prot.h | 5 +- libc/thread/pthread_create.c | 18 +- libc/thread/thread.h | 1 + test/ctl/set_test.cc | 16 +- test/libc/calls/raise_test.c | 1 - test/libc/calls/setrlimit_test.c | 24 +- test/libc/intrin/mmap_scalability_test.c | 76 +++++ test/libc/intrin/mmap_test.c | 16 + .../intrin/{rbtree_test.c => tree_test.c} | 76 +++-- test/libc/thread/pthread_atfork_test.c | 17 +- third_party/nsync/common.c | 146 ++++---- third_party/nsync/common.internal.h | 11 +- third_party/nsync/mem/nsync_cv.c | 14 +- third_party/nsync/mem/nsync_debug.c | 4 +- third_party/nsync/mem/nsync_mu_wait.c | 7 +- third_party/nsync/mem/nsync_once.c | 3 +- third_party/nsync/mu.c | 7 +- third_party/nsync/mu_semaphore.c | 2 +- third_party/nsync/mu_semaphore.h | 2 +- third_party/nsync/mu_semaphore.internal.h | 6 +- third_party/nsync/mu_semaphore_futex.c | 3 +- third_party/nsync/mu_semaphore_gcd.c | 4 +- third_party/nsync/mu_semaphore_sem.c | 31 +- tool/build/runitd.c | 55 ++- 59 files changed, 1238 insertions(+), 1067 deletions(-) create mode 100644 libc/intrin/pthread_delay_np.c rename libc/{calls => intrin}/pthread_yield_np.c (100%) delete mode 100644 libc/intrin/rbtree.c delete mode 100644 libc/intrin/rbtree.h create mode 100644 libc/intrin/tree.c create mode 100644 libc/intrin/tree.h create mode 100644 libc/sysv/consts/PROT_GUARD.S create mode 100644 test/libc/intrin/mmap_scalability_test.c rename test/libc/intrin/{rbtree_test.c => tree_test.c} (55%) diff --git a/libc/calls/setrlimit.c b/libc/calls/setrlimit.c index 45a8c532c..de7b5adc9 100644 --- a/libc/calls/setrlimit.c +++ b/libc/calls/setrlimit.c @@ -85,7 +85,7 @@ int setrlimit(int resource, const struct rlimit *rlim) { rc = efault(); } else if (IsXnuSilicon()) { rc = _sysret(__syslib->__setrlimit(resource, rlim)); - } else if (!IsWindows()) { + } else if (!IsWindows() && !(IsNetbsd() && resource == RLIMIT_AS)) { rc = sys_setrlimit(resource, rlim); } else if (resource == RLIMIT_STACK) { rc = enotsup(); diff --git a/libc/intrin/BUILD.mk b/libc/intrin/BUILD.mk index a8052956e..5f05cfc5e 100644 --- a/libc/intrin/BUILD.mk +++ b/libc/intrin/BUILD.mk @@ -62,6 +62,10 @@ o/$(MODE)/libc/intrin/kprintf.o: private \ -Wframe-larger-than=128 \ -Walloca-larger-than=128 +o/$(MODE)/libc/intrin/tree.o: private \ + CFLAGS += \ + -ffunction-sections + o//libc/intrin/memmove.o: private \ CFLAGS += \ -fno-toplevel-reorder diff --git a/libc/intrin/describemapping.c b/libc/intrin/describemapping.c index 258e9a4ab..d4c54ef49 100644 --- a/libc/intrin/describemapping.c +++ b/libc/intrin/describemapping.c @@ -24,7 +24,7 @@ static char DescribeMapType(int flags) { switch (flags & MAP_TYPE) { case MAP_FILE: - return 'f'; + return '-'; case MAP_PRIVATE: return 'p'; case MAP_SHARED: @@ -47,7 +47,7 @@ const char *(DescribeMapping)(char p[8], int prot, int flags) { DescribeProt(p, prot); p[3] = DescribeMapType(flags); p[4] = (flags & MAP_ANONYMOUS) ? 'a' : '-'; - p[5] = (flags & MAP_FIXED) ? 'F' : '-'; + p[5] = (flags & MAP_FIXED) ? 'f' : '-'; p[6] = 0; return p; } diff --git a/libc/intrin/describeprotflags.c b/libc/intrin/describeprotflags.c index f281dffc2..5761ac0fe 100644 --- a/libc/intrin/describeprotflags.c +++ b/libc/intrin/describeprotflags.c @@ -20,12 +20,12 @@ #include "libc/macros.internal.h" #include "libc/sysv/consts/prot.h" -static const struct DescribeFlags kProtFlags[] = { - {PROT_READ, "READ"}, // - {PROT_WRITE, "WRITE"}, // - {PROT_EXEC, "EXEC"}, // -}; - const char *(DescribeProtFlags)(char buf[48], int x) { + const struct DescribeFlags kProtFlags[] = { + {PROT_READ, "READ"}, // + {PROT_WRITE, "WRITE"}, // + {PROT_EXEC, "EXEC"}, // + {PROT_GUARD, "GUARD"}, // + }; return DescribeFlags(buf, 48, kProtFlags, ARRAYLEN(kProtFlags), "PROT_", x); } diff --git a/libc/intrin/describerlimit.c b/libc/intrin/describerlimit.c index 79d9a7d46..9d211a6c4 100644 --- a/libc/intrin/describerlimit.c +++ b/libc/intrin/describerlimit.c @@ -18,8 +18,11 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/struct/rlimit.h" #include "libc/dce.h" +#include "libc/fmt/itoa.h" #include "libc/intrin/kprintf.h" #include "libc/intrin/strace.internal.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/rlim.h" const char *DescribeRlimit(char buf[64], int rc, const struct rlimit *rlim) { if (rc == -1) @@ -29,7 +32,18 @@ const char *DescribeRlimit(char buf[64], int rc, const struct rlimit *rlim) { if (kisdangerous(rlim)) { ksnprintf(buf, 64, "%p", rlim); } else { - ksnprintf(buf, 64, "{%'ld, %'ld}", rlim->rlim_cur, rlim->rlim_max); + char str[2][21]; + if (rlim->rlim_cur == RLIM_INFINITY) { + strcpy(str[0], "RLIM_INFINITY"); + } else { + FormatInt64(str[0], rlim->rlim_cur); + } + if (rlim->rlim_max == RLIM_INFINITY) { + strcpy(str[1], "RLIM_INFINITY"); + } else { + FormatInt64(str[1], rlim->rlim_max); + } + ksnprintf(buf, 64, "{%s, %s}", str[0], str[1]); } return buf; } diff --git a/libc/intrin/directmap-nt.c b/libc/intrin/directmap-nt.c index a6fd1d2f1..00b93463d 100644 --- a/libc/intrin/directmap-nt.c +++ b/libc/intrin/directmap-nt.c @@ -86,9 +86,8 @@ TryAgain: if ((dm.addr = MapViewOfFileEx(dm.maphandle, fl.flags2, off >> 32, off, size, addr))) { uint32_t oldprot; - if (VirtualProtect(dm.addr, size, __prot2nt(prot, iscow), &oldprot)) { + if (VirtualProtect(dm.addr, size, __prot2nt(prot, iscow), &oldprot)) return dm; - } UnmapViewOfFile(dm.addr); } CloseHandle(dm.maphandle); diff --git a/libc/intrin/dll.c b/libc/intrin/dll.c index b94cfd7b2..b6337273d 100644 --- a/libc/intrin/dll.c +++ b/libc/intrin/dll.c @@ -28,7 +28,7 @@ * * It's required that `elem` and `succ` aren't part of the same list. */ -privileged void dll_splice_after(struct Dll *elem, struct Dll *succ) { +void dll_splice_after(struct Dll *elem, struct Dll *succ) { struct Dll *tmp1, *tmp2; tmp1 = elem->next; tmp2 = succ->prev; @@ -43,7 +43,7 @@ privileged void dll_splice_after(struct Dll *elem, struct Dll *succ) { * * @param list is a doubly-linked list, where `!*list` means empty */ -privileged void dll_remove(struct Dll **list, struct Dll *elem) { +void dll_remove(struct Dll **list, struct Dll *elem) { if (*list == elem) { if ((*list)->prev == *list) { *list = 0; @@ -66,7 +66,7 @@ privileged void dll_remove(struct Dll **list, struct Dll *elem) { * @param list is a doubly-linked list, where `!*list` means empty * @param elem must not be a member of `list`, or null for no-op */ -privileged void dll_make_first(struct Dll **list, struct Dll *elem) { +void dll_make_first(struct Dll **list, struct Dll *elem) { if (elem) { if (!*list) { *list = elem->prev; @@ -85,7 +85,7 @@ privileged void dll_make_first(struct Dll **list, struct Dll *elem) { * @param list is a doubly-linked list, where `!*list` means empty * @param elem must not be a member of `list`, or null for no-op */ -privileged void dll_make_last(struct Dll **list, struct Dll *elem) { +void dll_make_last(struct Dll **list, struct Dll *elem) { if (elem) { dll_make_first(list, elem->next); *list = elem; diff --git a/libc/intrin/kprintf.greg.c b/libc/intrin/kprintf.greg.c index 2bd649244..d32c52c64 100644 --- a/libc/intrin/kprintf.greg.c +++ b/libc/intrin/kprintf.greg.c @@ -25,7 +25,6 @@ #include "libc/fmt/magnumstrs.internal.h" #include "libc/intrin/asmflag.h" #include "libc/intrin/atomic.h" -#include "libc/intrin/dll.h" #include "libc/intrin/getenv.internal.h" #include "libc/intrin/kprintf.h" #include "libc/intrin/likely.h" @@ -154,27 +153,18 @@ __funline bool kischarmisaligned(const char *p, signed char t) { return false; } -privileged static bool32 kisdangerous_unlocked(const char *addr) { - struct Dll *e; - if ((e = dll_first(__maps.used))) { - do { - struct Map *map = MAP_CONTAINER(e); - if (map->addr <= addr && addr < map->addr + map->size) { - dll_remove(&__maps.used, e); - dll_make_first(&__maps.used, e); - return !(map->prot & PROT_READ); - } - } while ((e = dll_next(__maps.used, e))); - return true; - } else { - return false; - } -} - privileged bool32 kisdangerous(const void *addr) { - bool32 res; + bool32 res = true; __maps_lock(); - res = kisdangerous_unlocked(addr); + if (__maps.maps) { + struct Map *map; + if ((map = __maps_floor(addr))) + if ((const char *)addr >= map->addr && + (const char *)addr < map->addr + map->size) + res = false; + } else { + res = false; + } __maps_unlock(); return res; } diff --git a/libc/intrin/maps.c b/libc/intrin/maps.c index e2786ee75..e845679e5 100644 --- a/libc/intrin/maps.c +++ b/libc/intrin/maps.c @@ -20,6 +20,7 @@ #include "ape/sections.internal.h" #include "libc/dce.h" #include "libc/intrin/dll.h" +#include "libc/intrin/maps.h" #include "libc/runtime/runtime.h" #include "libc/runtime/stack.h" #include "libc/sysv/consts/auxv.h" @@ -32,8 +33,7 @@ __static_yoink("_init_maps"); struct Maps __maps; void __maps_add(struct Map *map) { - dll_init(&map->elem); - dll_make_first(&__maps.used, &map->elem); + tree_insert(&__maps.maps, &map->tree, __maps_compare); ++__maps.count; } diff --git a/libc/intrin/maps.h b/libc/intrin/maps.h index 5b5aba76a..387975b41 100644 --- a/libc/intrin/maps.h +++ b/libc/intrin/maps.h @@ -1,36 +1,41 @@ -#ifndef COSMOPOLITAN_LIBC_RUNTIME_MAPS_H_ -#define COSMOPOLITAN_LIBC_RUNTIME_MAPS_H_ +#ifndef COSMOPOLITAN_MAPS_H_ +#define COSMOPOLITAN_MAPS_H_ #include "libc/intrin/atomic.h" #include "libc/intrin/dll.h" +#include "libc/intrin/tree.h" +#include "libc/runtime/runtime.h" #include "libc/thread/tls2.internal.h" COSMOPOLITAN_C_START_ -#define MAP_CONTAINER(e) DLL_CONTAINER(struct Map, elem, e) +#define MAP_TREE_CONTAINER(e) TREE_CONTAINER(struct Map, tree, e) +#define MAP_FREE_CONTAINER(e) DLL_CONTAINER(struct Map, free, e) struct Map { char *addr; /* granule aligned */ size_t size; /* must be nonzero */ - struct Dll elem; /* for __maps.free */ - int64_t off; /* -1 if anonymous */ + int64_t off; /* ignore for anon */ int prot; /* memory protects */ int flags; /* memory map flag */ bool iscow; /* windows nt only */ bool readonlyfile; /* windows nt only */ unsigned visited; /* used for checks */ + unsigned oldprot; /* in windows fork */ intptr_t hand; /* windows nt only */ + union { + struct Tree tree; + struct Dll free; + }; }; struct Maps { - unsigned mono; atomic_int lock; + struct Tree *maps; struct Dll *free; - struct Dll *used; size_t count; size_t pages; + atomic_ulong rollo; struct Map stack; struct Map guard; - bool once; - atomic_ulong rollo; }; struct AddrSize { @@ -45,10 +50,37 @@ bool __maps_lock(void); void __maps_check(void); void __maps_unlock(void); void __maps_add(struct Map *); -struct Map *__maps_alloc(void); void __maps_free(struct Map *); +struct Map *__maps_alloc(void); +struct Map *__maps_floor(const char *); void __maps_stack(char *, int, int, size_t, int, intptr_t); +int __maps_compare(const struct Tree *, const struct Tree *); struct AddrSize __get_main_stack(void); +forceinline optimizespeed int __maps_search(const void *key, + const struct Tree *node) { + const char *addr = (const char *)key; + const struct Map *map = (const struct Map *)MAP_TREE_CONTAINER(node); + if (addr < map->addr) + return +1; + if (addr >= map->addr + map->size) + return -1; + return 0; +} + +static struct Map *__maps_next(struct Map *map) { + struct Tree *node; + if ((node = tree_next(&map->tree))) + return MAP_TREE_CONTAINER(node); + return 0; +} + +static struct Map *__maps_first(void) { + struct Tree *node; + if ((node = tree_first(__maps.maps))) + return MAP_TREE_CONTAINER(node); + return 0; +} + COSMOPOLITAN_C_END_ -#endif /* COSMOPOLITAN_LIBC_RUNTIME_MAPS_H_ */ +#endif /* COSMOPOLITAN_MAPS_H_ */ diff --git a/libc/intrin/mmap.c b/libc/intrin/mmap.c index c4229924e..02ef9614e 100644 --- a/libc/intrin/mmap.c +++ b/libc/intrin/mmap.c @@ -67,20 +67,31 @@ struct StackFrame *bp = __builtin_frame_address(0); \ kprintf("%!s:%d: assertion failed: %!s\n", __FILE__, __LINE__, #x); \ kprintf("bt %!s\n", (DescribeBacktrace)(bt, bp)); \ - __print_maps(); \ - _Exit(99); \ + __print_maps(0); \ + __builtin_trap(); \ } \ } while (0) #endif +int __maps_compare(const struct Tree *ra, const struct Tree *rb) { + const struct Map *a = (const struct Map *)MAP_TREE_CONTAINER(ra); + const struct Map *b = (const struct Map *)MAP_TREE_CONTAINER(rb); + return (a->addr > b->addr) - (a->addr < b->addr); +} + +privileged optimizespeed struct Map *__maps_floor(const char *addr) { + struct Tree *node; + if ((node = tree_floor(__maps.maps, addr, __maps_search))) + return MAP_TREE_CONTAINER(node); + return 0; +} + static bool overlaps_existing_map(const char *addr, size_t size, int pagesz) { - for (struct Dll *e = dll_first(__maps.used); e; - e = dll_next(__maps.used, e)) { - struct Map *map = MAP_CONTAINER(e); + struct Map *map; + if ((map = __maps_floor(addr))) if (MAX(addr, map->addr) < MIN(addr + PGUP(size), map->addr + PGUP(map->size))) return true; - } return false; } @@ -89,66 +100,51 @@ void __maps_check(void) { size_t maps = 0; size_t pages = 0; int pagesz = getpagesize(); - unsigned id = ++__maps.mono; - for (struct Dll *e = dll_first(__maps.used); e; - e = dll_next(__maps.used, e)) { - struct Map *map = MAP_CONTAINER(e); + static unsigned mono; + unsigned id = ++mono; + for (struct Map *map = __maps_first(); map; map = __maps_next(map)) { ASSERT(map->addr != MAP_FAILED); ASSERT(map->visited != id); ASSERT(map->size); map->visited = id; pages += (map->size + getpagesize() - 1) / getpagesize(); maps += 1; + struct Map *next; + if ((next = __maps_next(map))) { + ASSERT(map->addr < next->addr); + ASSERT( + !(MAX(map->addr, next->addr) < + MIN(map->addr + PGUP(map->size), next->addr + PGUP(next->size)))); + } } ASSERT(maps = __maps.count); ASSERT(pages == __maps.pages); - for (struct Dll *e = dll_first(__maps.used); e; - e = dll_next(__maps.used, e)) { - struct Map *m1 = MAP_CONTAINER(e); - for (struct Dll *f = dll_next(__maps.used, e); f; - f = dll_next(__maps.used, f)) { - struct Map *m2 = MAP_CONTAINER(f); - ASSERT(MAX(m1->addr, m2->addr) >= - MIN(m1->addr + PGUP(m1->size), m2->addr + PGUP(m2->size))); - } - } #endif } void __maps_free(struct Map *map) { map->size = 0; map->addr = MAP_FAILED; - ASSERT(dll_is_alone(&map->elem)); - dll_make_last(&__maps.free, &map->elem); + dll_init(&map->free); + dll_make_first(&__maps.free, &map->free); } static void __maps_insert(struct Map *map) { - struct Dll *e = dll_first(__maps.used); - struct Map *last = e ? MAP_CONTAINER(e) : 0; __maps.pages += (map->size + getpagesize() - 1) / getpagesize(); - if (last && !IsWindows() && // - map->addr == last->addr + last->size && // + struct Map *floor = __maps_floor(map->addr); + if (floor && !IsWindows() && // + map->addr + map->size == floor->addr && // (map->flags & MAP_ANONYMOUS) && // - map->flags == last->flags && // - map->prot == last->prot) { - last->size += map->size; - dll_remove(&__maps.used, &last->elem); - dll_make_first(&__maps.used, &last->elem); - __maps_free(map); - } else if (last && !IsWindows() && // - map->addr + map->size == last->addr && // - (map->flags & MAP_ANONYMOUS) && // - map->flags == last->flags && // - map->prot == last->prot) { - last->addr -= map->size; - last->size += map->size; - dll_remove(&__maps.used, &last->elem); - dll_make_first(&__maps.used, &last->elem); + map->flags == floor->flags && // + map->prot == floor->prot) { + floor->addr -= map->size; + floor->size += map->size; __maps_free(map); + __maps_check(); } else { __maps_add(map); + __maps_check(); } - __maps_check(); } struct Map *__maps_alloc(void) { @@ -156,7 +152,7 @@ struct Map *__maps_alloc(void) { struct Map *map; if ((e = dll_first(__maps.free))) { dll_remove(&__maps.free, e); - map = MAP_CONTAINER(e); + map = MAP_FREE_CONTAINER(e); return map; } int granularity = __granularity(); @@ -168,11 +164,8 @@ struct Map *__maps_alloc(void) { CloseHandle(sys.maphandle); map = sys.addr; map->addr = MAP_FAILED; - dll_init(&map->elem); - for (int i = 1; i < granularity / sizeof(struct Map); ++i) { - dll_init(&map[i].elem); + for (int i = 1; i < granularity / sizeof(struct Map); ++i) __maps_free(map + i); - } return map; } @@ -190,106 +183,106 @@ static int __munmap(char *addr, size_t size, bool untrack_only) { // untrack mappings int rc = 0; - struct Dll *cur; - struct Dll *next; - struct Dll *delete = 0; + struct Map *map; + struct Map *next; + struct Dll *deleted = 0; if (__maps_lock()) { __maps_unlock(); return edeadlk(); } - for (cur = dll_first(__maps.used); cur; cur = next) { - next = dll_next(__maps.used, cur); - struct Map *map = MAP_CONTAINER(cur); + for (map = __maps_floor(addr); map; map = next) { + next = __maps_next(map); char *map_addr = map->addr; size_t map_size = map->size; - if (MAX(addr, map_addr) < MIN(addr + size, map_addr + PGUP(map_size))) { - if (addr <= map_addr && addr + size >= map_addr + PGUP(map_size)) { - // remove mapping completely - dll_remove(&__maps.used, cur); - dll_make_first(&delete, cur); - __maps.pages -= (map_size + pagesz - 1) / pagesz; - __maps.count -= 1; - __maps_check(); - } else if (IsWindows()) { - // you can't carve up memory maps on windows. our mmap() makes - // this not a problem (for non-enormous memory maps) by making - // independent mappings for each 64 kb granule, under the hood - rc = einval(); - } else if (addr <= map_addr) { - // shave off lefthand side of mapping - ASSERT(addr + size < map_addr + PGUP(map_size)); - size_t left = PGUP(addr + size - map_addr); - size_t right = map_size - left; - ASSERT(right > 0); - ASSERT(left > 0); - struct Map *leftmap; - if ((leftmap = __maps_alloc())) { - map->addr += left; - map->size = right; - if (!(map->flags & MAP_ANONYMOUS)) - map->off += left; - __maps.pages -= (left + pagesz - 1) / pagesz; + if (!(MAX(addr, map_addr) < MIN(addr + size, map_addr + PGUP(map_size)))) + break; + if (addr <= map_addr && addr + size >= map_addr + PGUP(map_size)) { + // remove mapping completely + tree_remove(&__maps.maps, &map->tree); + dll_init(&map->free); + dll_make_first(&deleted, &map->free); + __maps.pages -= (map_size + pagesz - 1) / pagesz; + __maps.count -= 1; + } else if (IsWindows()) { + // you can't carve up memory maps on windows. our mmap() makes + // this not a problem (for non-enormous memory maps) by making + // independent mappings for each 64 kb granule, under the hood + rc = einval(); + } else if (addr <= map_addr) { + // shave off lefthand side of mapping + ASSERT(addr + size < map_addr + PGUP(map_size)); + size_t left = PGUP(addr + size - map_addr); + size_t right = map_size - left; + ASSERT(right > 0); + ASSERT(left > 0); + struct Map *leftmap; + if ((leftmap = __maps_alloc())) { + map->addr += left; + map->size = right; + if (!(map->flags & MAP_ANONYMOUS)) + map->off += left; + __maps.pages -= (left + pagesz - 1) / pagesz; + leftmap->addr = map_addr; + leftmap->size = left; + dll_init(&leftmap->free); + dll_make_first(&deleted, &leftmap->free); + } else { + rc = -1; + } + } else if (addr + size >= map_addr + PGUP(map_size)) { + // shave off righthand side of mapping + size_t left = addr - map_addr; + size_t right = map_addr + map_size - addr; + struct Map *rightmap; + if ((rightmap = __maps_alloc())) { + map->size = left; + __maps.pages -= (right + pagesz - 1) / pagesz; + rightmap->addr = addr; + rightmap->size = right; + dll_init(&rightmap->free); + dll_make_first(&deleted, &rightmap->free); + } else { + rc = -1; + } + } else { + // punch hole in mapping + size_t left = addr - map_addr; + size_t middle = size; + size_t right = map_size - middle - left; + struct Map *leftmap; + if ((leftmap = __maps_alloc())) { + struct Map *middlemap; + if ((middlemap = __maps_alloc())) { leftmap->addr = map_addr; leftmap->size = left; - dll_make_first(&delete, &leftmap->elem); - __maps_check(); - } else { - rc = -1; - } - } else if (addr + size >= map_addr + PGUP(map_size)) { - // shave off righthand side of mapping - size_t left = addr - map_addr; - size_t right = map_addr + map_size - addr; - struct Map *rightmap; - if ((rightmap = __maps_alloc())) { - map->size = left; - __maps.pages -= (right + pagesz - 1) / pagesz; - rightmap->addr = addr; - rightmap->size = right; - dll_make_first(&delete, &rightmap->elem); - __maps_check(); + leftmap->off = map->off; + leftmap->prot = map->prot; + leftmap->flags = map->flags; + map->addr += left + middle; + map->size = right; + if (!(map->flags & MAP_ANONYMOUS)) + map->off += left + middle; + tree_insert(&__maps.maps, &leftmap->tree, __maps_compare); + __maps.pages -= (middle + pagesz - 1) / pagesz; + __maps.count += 1; + middlemap->addr = addr; + middlemap->size = size; + dll_init(&middlemap->free); + dll_make_first(&deleted, &middlemap->free); } else { rc = -1; } } else { - // punch hole in mapping - size_t left = addr - map_addr; - size_t middle = size; - size_t right = map_size - middle - left; - struct Map *leftmap; - if ((leftmap = __maps_alloc())) { - struct Map *middlemap; - if ((middlemap = __maps_alloc())) { - leftmap->addr = map_addr; - leftmap->size = left; - leftmap->off = map->off; - leftmap->prot = map->prot; - leftmap->flags = map->flags; - map->addr += left + middle; - map->size = right; - if (!(map->flags & MAP_ANONYMOUS)) - map->off += left + middle; - dll_make_first(&__maps.used, &leftmap->elem); - __maps.pages -= (middle + pagesz - 1) / pagesz; - __maps.count += 1; - middlemap->addr = addr; - middlemap->size = size; - dll_make_first(&delete, &middlemap->elem); - __maps_check(); - } else { - rc = -1; - } - } else { - rc = -1; - } + rc = -1; } } + __maps_check(); } __maps_unlock(); // delete mappings - for (struct Dll *e = dll_first(delete); e; e = dll_next(delete, e)) { - struct Map *map = MAP_CONTAINER(e); + for (struct Dll *e = dll_first(deleted); e; e = dll_next(deleted, e)) { + struct Map *map = MAP_FREE_CONTAINER(e); if (!untrack_only) { if (!IsWindows()) { if (sys_munmap(map->addr, map->size)) @@ -305,12 +298,12 @@ static int __munmap(char *addr, size_t size, bool untrack_only) { } // free mappings - if (!dll_is_empty(delete)) { + if (!dll_is_empty(deleted)) { __maps_lock(); struct Dll *e; - while ((e = dll_first(delete))) { - dll_remove(&delete, e); - __maps_free(MAP_CONTAINER(e)); + while ((e = dll_first(deleted))) { + dll_remove(&deleted, e); + __maps_free(MAP_FREE_CONTAINER(e)); } __maps_check(); __maps_unlock(); @@ -350,6 +343,7 @@ static void *__mmap_chunk(void *addr, size_t size, int prot, int flags, int fd, __maps_unlock(); return (void *)edeadlk(); } + __maps_check(); map = __maps_alloc(); __maps_unlock(); if (!map) diff --git a/libc/intrin/mprotect.c b/libc/intrin/mprotect.c index 83dc39926..76a40175e 100644 --- a/libc/intrin/mprotect.c +++ b/libc/intrin/mprotect.c @@ -25,6 +25,7 @@ #include "libc/intrin/kprintf.h" #include "libc/intrin/maps.h" #include "libc/intrin/strace.internal.h" +#include "libc/intrin/tree.h" #include "libc/nt/memory.h" #include "libc/runtime/internal.h" #include "libc/runtime/runtime.h" @@ -51,7 +52,7 @@ static int __mprotect_chunk(char *addr, size_t size, int prot, bool iscow) { int __mprotect(char *addr, size_t size, int prot) { // unix checks prot before checking size - if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC)) + if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_GUARD)) return einval(); // make new technology consistent with unix @@ -68,64 +69,97 @@ int __mprotect(char *addr, size_t size, int prot) { // change mappings int rc = 0; - struct Dll *cur; bool found = false; if (__maps_lock()) { __maps_unlock(); return edeadlk(); } - for (cur = dll_first(__maps.used); cur; cur = dll_next(__maps.used, cur)) { - struct Map *map = MAP_CONTAINER(cur); + for (struct Map *map = __maps_floor(addr); map; map = __maps_next(map)) { char *map_addr = map->addr; size_t map_size = map->size; char *beg = MAX(addr, map_addr); char *end = MIN(addr + size, map_addr + PGUP(map_size)); - if (beg < end) { - found = true; - if (addr <= map_addr && addr + size >= map_addr + PGUP(map_size)) { - // change protection of entire mapping - if (!__mprotect_chunk(map_addr, map_size, prot, map->iscow)) { + if (beg >= end) + break; + found = true; + if (addr <= map_addr && addr + size >= map_addr + PGUP(map_size)) { + // change protection of entire mapping + if (!__mprotect_chunk(map_addr, map_size, prot, map->iscow)) { + map->prot = prot; + } else { + rc = -1; + } + } else if (addr <= map_addr) { + // change lefthand side of mapping + size_t left = PGUP(addr + size - map_addr); + size_t right = map_size - left; + struct Map *leftmap; + if ((leftmap = __maps_alloc())) { + if (!__mprotect_chunk(map_addr, left, prot, false)) { + leftmap->addr = map_addr; + leftmap->size = left; + leftmap->prot = prot; + leftmap->off = map->off; + leftmap->flags = map->flags; + leftmap->iscow = map->iscow; + leftmap->readonlyfile = map->readonlyfile; + leftmap->hand = map->hand; + map->addr += left; + map->size = right; + map->hand = -1; + if (!(map->flags & MAP_ANONYMOUS)) + map->off += left; + tree_insert(&__maps.maps, &leftmap->tree, __maps_compare); + __maps.count += 1; + __maps_check(); + } else { + __maps_free(leftmap); + rc = -1; + } + } else { + rc = -1; + } + } else if (addr + size >= map_addr + PGUP(map_size)) { + // change righthand side of mapping + size_t left = addr - map_addr; + size_t right = map_addr + map_size - addr; + struct Map *leftmap; + if ((leftmap = __maps_alloc())) { + if (!__mprotect_chunk(map_addr + left, right, prot, false)) { + leftmap->addr = map_addr; + leftmap->size = left; + leftmap->off = map->off; + leftmap->prot = map->prot; + leftmap->flags = map->flags; + leftmap->iscow = map->iscow; + leftmap->readonlyfile = map->readonlyfile; + leftmap->hand = map->hand; + map->addr += left; + map->size = right; map->prot = prot; + map->hand = -1; + if (!(map->flags & MAP_ANONYMOUS)) + map->off += left; + tree_insert(&__maps.maps, &leftmap->tree, __maps_compare); + __maps.count += 1; + __maps_check(); } else { + __maps_free(leftmap); rc = -1; } - } else if (addr <= map_addr) { - // change lefthand side of mapping - size_t left = PGUP(addr + size - map_addr); - size_t right = map_size - left; - struct Map *leftmap; - if ((leftmap = __maps_alloc())) { - if (!__mprotect_chunk(map_addr, left, prot, false)) { - leftmap->addr = map_addr; - leftmap->size = left; - leftmap->prot = prot; - leftmap->off = map->off; - leftmap->flags = map->flags; - leftmap->iscow = map->iscow; - leftmap->readonlyfile = map->readonlyfile; - leftmap->hand = map->hand; - map->addr += left; - map->size = right; - map->hand = -1; - if (!(map->flags & MAP_ANONYMOUS)) - map->off += left; - dll_make_first(&__maps.used, &leftmap->elem); - __maps.count += 1; - __maps_check(); - } else { - __maps_free(leftmap); - rc = -1; - } - } else { - rc = -1; - } - } else if (addr + size >= map_addr + PGUP(map_size)) { - // change righthand side of mapping - size_t left = addr - map_addr; - size_t right = map_addr + map_size - addr; - struct Map *leftmap; - if ((leftmap = __maps_alloc())) { - if (!__mprotect_chunk(map_addr + left, right, prot, false)) { + } else { + rc = -1; + } + } else { + // change middle of mapping + size_t left = addr - map_addr; + size_t middle = size; + size_t right = map_size - middle - left; + struct Map *leftmap; + if ((leftmap = __maps_alloc())) { + struct Map *midlmap; + if ((midlmap = __maps_alloc())) { + if (!__mprotect_chunk(map_addr + left, middle, prot, false)) { leftmap->addr = map_addr; leftmap->size = left; leftmap->off = map->off; @@ -134,67 +168,32 @@ int __mprotect(char *addr, size_t size, int prot) { leftmap->iscow = map->iscow; leftmap->readonlyfile = map->readonlyfile; leftmap->hand = map->hand; - map->addr += left; + midlmap->addr = map_addr + left; + midlmap->size = middle; + midlmap->off = (map->flags & MAP_ANONYMOUS) ? 0 : map->off + left; + midlmap->prot = prot; + midlmap->flags = map->flags; + midlmap->hand = -1; + map->addr += left + middle; map->size = right; - map->prot = prot; map->hand = -1; if (!(map->flags & MAP_ANONYMOUS)) - map->off += left; - dll_make_first(&__maps.used, &leftmap->elem); - __maps.count += 1; + map->off += left + middle; + tree_insert(&__maps.maps, &leftmap->tree, __maps_compare); + tree_insert(&__maps.maps, &midlmap->tree, __maps_compare); + __maps.count += 2; __maps_check(); } else { + __maps_free(midlmap); __maps_free(leftmap); rc = -1; } } else { + __maps_free(leftmap); rc = -1; } } else { - // change middle of mapping - size_t left = addr - map_addr; - size_t middle = size; - size_t right = map_size - middle - left; - struct Map *leftmap; - if ((leftmap = __maps_alloc())) { - struct Map *midlmap; - if ((midlmap = __maps_alloc())) { - if (!__mprotect_chunk(map_addr + left, middle, prot, false)) { - leftmap->addr = map_addr; - leftmap->size = left; - leftmap->off = map->off; - leftmap->prot = map->prot; - leftmap->flags = map->flags; - leftmap->iscow = map->iscow; - leftmap->readonlyfile = map->readonlyfile; - leftmap->hand = map->hand; - midlmap->addr = map_addr + left; - midlmap->size = middle; - midlmap->off = (map->flags & MAP_ANONYMOUS) ? 0 : map->off + left; - midlmap->prot = prot; - midlmap->flags = map->flags; - midlmap->hand = -1; - map->addr += left + middle; - map->size = right; - map->hand = -1; - if (!(map->flags & MAP_ANONYMOUS)) - map->off += left + middle; - dll_make_first(&__maps.used, &midlmap->elem); - dll_make_first(&__maps.used, &leftmap->elem); - __maps.count += 2; - __maps_check(); - } else { - __maps_free(midlmap); - __maps_free(leftmap); - rc = -1; - } - } else { - __maps_free(leftmap); - rc = -1; - } - } else { - rc = -1; - } + rc = -1; } } } diff --git a/libc/intrin/msync-nt.c b/libc/intrin/msync-nt.c index 3ff6524ed..883a11c06 100644 --- a/libc/intrin/msync-nt.c +++ b/libc/intrin/msync-nt.c @@ -34,16 +34,17 @@ textwindows int sys_msync_nt(char *addr, size_t size, int flags) { return einval(); int rc = 0; - __maps_lock(); - for (struct Dll *e = dll_first(__maps.used); e; - e = dll_next(__maps.used, e)) { - struct Map *map = MAP_CONTAINER(e); - char *beg = MAX(addr, map->addr); - char *end = MIN(addr + size, map->addr + map->size); - if (beg < end) - if (!FlushViewOfFile(beg, end - beg)) - rc = -1; - // TODO(jart): FlushFileBuffers too on g_fds handle if MS_SYNC? + if (__maps_lock()) { + rc = edeadlk(); + } else { + for (struct Map *map = __maps_floor(addr); map; map = __maps_next(map)) { + char *beg = MAX(addr, map->addr); + char *end = MIN(addr + size, map->addr + map->size); + if (beg < end) + if (!FlushViewOfFile(beg, end - beg)) + rc = -1; + // TODO(jart): FlushFileBuffers too on g_fds handle if MS_SYNC? + } } __maps_unlock(); diff --git a/libc/intrin/printmaps.c b/libc/intrin/printmaps.c index b84a1cc25..18c02812e 100644 --- a/libc/intrin/printmaps.c +++ b/libc/intrin/printmaps.c @@ -29,16 +29,11 @@ /** * Prints memory mappings. */ -void __print_maps(void) { - int limit = 15; - long maptally = 0; +void __print_maps(size_t limit) { char mappingbuf[8], sb[16]; __maps_lock(); - struct Dll *e, *e2; - for (e = dll_first(__maps.used); e; e = e2) { - e2 = dll_next(__maps.used, e); - struct Map *map = MAP_CONTAINER(e); - maptally += map->size; + for (struct Tree *e = tree_first(__maps.maps); e; e = tree_next(e)) { + struct Map *map = MAP_TREE_CONTAINER(e); kprintf("%012lx-%012lx %!s", map->addr, map->addr + map->size, (DescribeMapping)(mappingbuf, map->prot, map->flags)); sizefmt(sb, map->size, 1024); diff --git a/libc/intrin/prot2nt.greg.c b/libc/intrin/prot2nt.greg.c index 67a59430b..59dd01491 100644 --- a/libc/intrin/prot2nt.greg.c +++ b/libc/intrin/prot2nt.greg.c @@ -42,6 +42,8 @@ privileged int __prot2nt(int prot, int iscow) { return kNtPageExecuteReadwrite; } default: + if (prot & PROT_GUARD) + return kNtPageReadwrite | kNtPageGuard; return kNtPageNoaccess; } } diff --git a/libc/intrin/pthread_delay_np.c b/libc/intrin/pthread_delay_np.c new file mode 100644 index 000000000..3a7c98024 --- /dev/null +++ b/libc/intrin/pthread_delay_np.c @@ -0,0 +1,40 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-β”‚ +β”‚ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi β”‚ +β•žβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•‘ +β”‚ Copyright 2024 Justine Alexandra Roberts Tunney β”‚ +β”‚ β”‚ +β”‚ Permission to use, copy, modify, and/or distribute this software for β”‚ +β”‚ any purpose with or without fee is hereby granted, provided that the β”‚ +β”‚ above copyright notice and this permission notice appear in all copies. β”‚ +β”‚ β”‚ +β”‚ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL β”‚ +β”‚ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED β”‚ +β”‚ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE β”‚ +β”‚ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL β”‚ +β”‚ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR β”‚ +β”‚ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER β”‚ +β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ +β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ +β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/intrin/strace.internal.h" +#include "libc/thread/thread.h" + +/** + * Delays execution for brief moment. + * + * @param symbol may be used to strace names of static locks + * @param backoff should start at zero and be feed back in + * @return new value for backoff + */ +int pthread_delay_np(const void *symbol, int backoff) { + if (backoff < 7) { + volatile int i; + for (i = 0; i != 1 << backoff; i++) { + } + backoff++; + } else { + STRACE("pthread_delay_np(%t)", symbol); + pthread_yield_np(); + } + return backoff; +} diff --git a/libc/intrin/pthread_mutex_lock.c b/libc/intrin/pthread_mutex_lock.c index 6fd2c6bfb..509af6e04 100644 --- a/libc/intrin/pthread_mutex_lock.c +++ b/libc/intrin/pthread_mutex_lock.c @@ -18,8 +18,10 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" #include "libc/calls/state.internal.h" +#include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/atomic.h" +#include "libc/intrin/describeflags.internal.h" #include "libc/intrin/strace.internal.h" #include "libc/intrin/weaken.h" #include "libc/runtime/internal.h" @@ -27,6 +29,66 @@ #include "libc/thread/thread.h" #include "third_party/nsync/mu.h" +static errno_t pthread_mutex_lock_impl(pthread_mutex_t *mutex) { + int me; + int backoff = 0; + uint64_t word, lock; + + // get current state of lock + word = atomic_load_explicit(&mutex->_word, memory_order_relaxed); + + // use fancy nsync mutex if possible + if (MUTEX_TYPE(word) == PTHREAD_MUTEX_NORMAL && // + MUTEX_PSHARED(word) == PTHREAD_PROCESS_PRIVATE && // + _weaken(nsync_mu_lock)) { + _weaken(nsync_mu_lock)((nsync_mu *)mutex); + return 0; + } + + // implement barebones normal mutexes + if (MUTEX_TYPE(word) == PTHREAD_MUTEX_NORMAL) { + for (;;) { + word = MUTEX_UNLOCK(word); + lock = MUTEX_LOCK(word); + if (atomic_compare_exchange_weak_explicit(&mutex->_word, &word, lock, + memory_order_acquire, + memory_order_relaxed)) + return 0; + backoff = pthread_delay_np(mutex, backoff); + } + } + + // implement recursive mutexes + me = gettid(); + for (;;) { + if (MUTEX_OWNER(word) == me) { + if (MUTEX_TYPE(word) != PTHREAD_MUTEX_ERRORCHECK) { + if (MUTEX_DEPTH(word) < MUTEX_DEPTH_MAX) { + if (atomic_compare_exchange_weak_explicit( + &mutex->_word, &word, MUTEX_INC_DEPTH(word), + memory_order_relaxed, memory_order_relaxed)) + return 0; + continue; + } else { + return EAGAIN; + } + } else { + return EDEADLK; + } + } + word = MUTEX_UNLOCK(word); + lock = MUTEX_LOCK(word); + lock = MUTEX_SET_OWNER(lock, me); + if (atomic_compare_exchange_weak_explicit(&mutex->_word, &word, lock, + memory_order_acquire, + memory_order_relaxed)) { + mutex->_pid = __pid; + return 0; + } + backoff = pthread_delay_np(mutex, backoff); + } +} + /** * Locks mutex. * @@ -65,65 +127,10 @@ * @vforksafe */ errno_t pthread_mutex_lock(pthread_mutex_t *mutex) { - int me; - uint64_t word, lock; - - LOCKTRACE("pthread_mutex_lock(%t)", mutex); - if (__vforked) return 0; - - // get current state of lock - word = atomic_load_explicit(&mutex->_word, memory_order_relaxed); - - // use fancy nsync mutex if possible - if (MUTEX_TYPE(word) == PTHREAD_MUTEX_NORMAL && // - MUTEX_PSHARED(word) == PTHREAD_PROCESS_PRIVATE && // - _weaken(nsync_mu_lock)) { - _weaken(nsync_mu_lock)((nsync_mu *)mutex); - return 0; - } - - // implement barebones normal mutexes - if (MUTEX_TYPE(word) == PTHREAD_MUTEX_NORMAL) { - for (;;) { - word = MUTEX_UNLOCK(word); - lock = MUTEX_LOCK(word); - if (atomic_compare_exchange_weak_explicit(&mutex->_word, &word, lock, - memory_order_acquire, - memory_order_relaxed)) - return 0; - pthread_pause_np(); - } - } - - // implement recursive mutexes - me = gettid(); - for (;;) { - if (MUTEX_OWNER(word) == me) { - if (MUTEX_TYPE(word) != PTHREAD_MUTEX_ERRORCHECK) { - if (MUTEX_DEPTH(word) < MUTEX_DEPTH_MAX) { - if (atomic_compare_exchange_weak_explicit( - &mutex->_word, &word, MUTEX_INC_DEPTH(word), - memory_order_relaxed, memory_order_relaxed)) - return 0; - continue; - } else { - return EAGAIN; - } - } else { - return EDEADLK; - } - } - word = MUTEX_UNLOCK(word); - lock = MUTEX_LOCK(word); - lock = MUTEX_SET_OWNER(lock, me); - if (atomic_compare_exchange_weak_explicit(&mutex->_word, &word, lock, - memory_order_acquire, - memory_order_relaxed)) { - mutex->_pid = __pid; - return 0; - } - pthread_pause_np(); - } + LOCKTRACE("acquiring %t...", mutex); + errno_t err = pthread_mutex_lock_impl(mutex); + LOCKTRACE("pthread_mutex_lock(%t) β†’ %s", mutex, DescribeErrno(err)); + return err; } diff --git a/libc/intrin/pthread_mutex_trylock.c b/libc/intrin/pthread_mutex_trylock.c index f4e0dde6a..21513656a 100644 --- a/libc/intrin/pthread_mutex_trylock.c +++ b/libc/intrin/pthread_mutex_trylock.c @@ -17,6 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" +#include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/atomic.h" #include "libc/intrin/weaken.h" diff --git a/libc/intrin/pthread_mutex_unlock.c b/libc/intrin/pthread_mutex_unlock.c index c6fc274b1..dc8d0fb1f 100644 --- a/libc/intrin/pthread_mutex_unlock.c +++ b/libc/intrin/pthread_mutex_unlock.c @@ -17,6 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" +#include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/atomic.h" #include "libc/intrin/strace.internal.h" diff --git a/libc/intrin/pthread_syshand.c b/libc/intrin/pthread_syshand.c index 856ce3323..b15460580 100644 --- a/libc/intrin/pthread_syshand.c +++ b/libc/intrin/pthread_syshand.c @@ -29,6 +29,6 @@ intptr_t _pthread_syshand(struct PosixThread *pt) { syshand = atomic_load_explicit(&pt->tib->tib_syshand, memory_order_acquire); if (syshand) return syshand; - pthread_pause_np(); + pthread_yield_np(); } } diff --git a/libc/intrin/pthread_tid.c b/libc/intrin/pthread_tid.c index 27e3ee5a1..4f7553e9a 100644 --- a/libc/intrin/pthread_tid.c +++ b/libc/intrin/pthread_tid.c @@ -24,6 +24,6 @@ int _pthread_tid(struct PosixThread *pt) { int tid = 0; while (pt && !(tid = atomic_load_explicit(&pt->ptid, memory_order_acquire))) - pthread_pause_np(); + pthread_yield_np(); return tid; } diff --git a/libc/calls/pthread_yield_np.c b/libc/intrin/pthread_yield_np.c similarity index 100% rename from libc/calls/pthread_yield_np.c rename to libc/intrin/pthread_yield_np.c diff --git a/libc/intrin/rbtree.c b/libc/intrin/rbtree.c deleted file mode 100644 index 3fc3ae5cc..000000000 --- a/libc/intrin/rbtree.c +++ /dev/null @@ -1,312 +0,0 @@ -// Copyright 2024 Justine Alexandra Roberts Tunney -// -// Permission to use, copy, modify, and/or distribute this software for -// any purpose with or without fee is hereby granted, provided that the -// above copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE -// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL -// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -// PERFORMANCE OF THIS SOFTWARE. - -#include "rbtree.h" -#include "libc/dce.h" -#include "libc/str/str.h" - -#define RBTREE_DEBUG - -struct rbtree *rbtree_next(struct rbtree *node) { - if (!node) - return 0; - if (node->right) - return rbtree_first(node->right); - struct rbtree *parent = node->parent; - while (parent && node == parent->right) { - node = parent; - parent = parent->parent; - } - return parent; -} - -struct rbtree *rbtree_prev(struct rbtree *node) { - if (!node) - return 0; - if (rbtree_get_left(node)) - return rbtree_last(rbtree_get_left(node)); - struct rbtree *parent = node->parent; - while (parent && node == rbtree_get_left(parent)) { - node = parent; - parent = parent->parent; - } - return parent; -} - -struct rbtree *rbtree_first(struct rbtree *node) { - while (node && rbtree_get_left(node)) - node = rbtree_get_left(node); - return node; -} - -struct rbtree *rbtree_last(struct rbtree *node) { - while (node && node->right) - node = node->right; - return node; -} - -static void rbtree_rotate_left(struct rbtree **root, struct rbtree *x) { - struct rbtree *y = x->right; - x->right = rbtree_get_left(y); - if (rbtree_get_left(y)) - rbtree_get_left(y)->parent = x; - y->parent = x->parent; - if (!x->parent) { - *root = y; - } else if (x == rbtree_get_left(x->parent)) { - rbtree_set_left(x->parent, y); - } else { - x->parent->right = y; - } - rbtree_set_left(y, x); - x->parent = y; -} - -static void rbtree_rotate_right(struct rbtree **root, struct rbtree *y) { - struct rbtree *x = rbtree_get_left(y); - rbtree_set_left(y, x->right); - if (x->right) - x->right->parent = y; - x->parent = y->parent; - if (!y->parent) { - *root = x; - } else if (y == y->parent->right) { - y->parent->right = x; - } else { - rbtree_set_left(y->parent, x); - } - x->right = y; - y->parent = x; -} - -static void rbtree_insert_fixup(struct rbtree **root, struct rbtree *node) { - rbtree_set_red(node, 1); - while (node != *root && rbtree_get_red(node->parent)) { - if (node->parent == rbtree_get_left(node->parent->parent)) { - struct rbtree *uncle = node->parent->parent->right; - if (uncle && rbtree_get_red(uncle)) { - rbtree_set_red(node->parent, 0); - rbtree_set_red(uncle, 0); - rbtree_set_red(node->parent->parent, 1); - node = node->parent->parent; - } else { - if (node == node->parent->right) { - node = node->parent; - rbtree_rotate_left(root, node); - } - rbtree_set_red(node->parent, 0); - rbtree_set_red(node->parent->parent, 1); - rbtree_rotate_right(root, node->parent->parent); - } - } else { - struct rbtree *uncle = rbtree_get_left(node->parent->parent); - if (uncle && rbtree_get_red(uncle)) { - rbtree_set_red(node->parent, 0); - rbtree_set_red(uncle, 0); - rbtree_set_red(node->parent->parent, 1); - node = node->parent->parent; - } else { - if (node == rbtree_get_left(node->parent)) { - node = node->parent; - rbtree_rotate_right(root, node); - } - rbtree_set_red(node->parent, 0); - rbtree_set_red(node->parent->parent, 1); - rbtree_rotate_left(root, node->parent->parent); - } - } - } - rbtree_set_red(*root, 0); -} - -void rbtree_insert(struct rbtree **root, struct rbtree *node, - rbtree_cmp_f *cmp) { - bzero(node, sizeof(*node)); - if (!*root) { - *root = node; - } else { - struct rbtree *search = *root; - struct rbtree *parent = 0; - do { - parent = search; - if (cmp(node, search) < 0) { - search = rbtree_get_left(search); - } else { - search = search->right; - } - } while (search); - if (cmp(node, parent) < 0) { - rbtree_set_left(parent, node); - } else { - parent->right = node; - } - node->parent = parent; - rbtree_insert_fixup(root, node); - } -} - -static void rbtree_transplant(struct rbtree **root, struct rbtree *u, - struct rbtree *v) { - if (!u->parent) { - *root = v; - } else if (u == rbtree_get_left(u->parent)) { - rbtree_set_left(u->parent, v); - } else { - u->parent->right = v; - } - if (v) - v->parent = u->parent; -} - -static void rbtree_remove_fixup(struct rbtree **root, struct rbtree *node, - struct rbtree *parent) { - while (node != *root && (!node || !rbtree_get_red(node))) { - if (node == rbtree_get_left(parent)) { - struct rbtree *sibling = parent->right; - if (rbtree_get_red(sibling)) { - rbtree_set_red(sibling, 0); - rbtree_set_red(parent, 1); - rbtree_rotate_left(root, parent); - sibling = parent->right; - } - if ((!rbtree_get_left(sibling) || - !rbtree_get_red(rbtree_get_left(sibling))) && - (!sibling->right || !rbtree_get_red(sibling->right))) { - rbtree_set_red(sibling, 1); - node = parent; - parent = node->parent; - } else { - if (!sibling->right || !rbtree_get_red(sibling->right)) { - rbtree_set_red(rbtree_get_left(sibling), 0); - rbtree_set_red(sibling, 1); - rbtree_rotate_right(root, sibling); - sibling = parent->right; - } - rbtree_set_red(sibling, rbtree_get_red(parent)); - rbtree_set_red(parent, 0); - rbtree_set_red(sibling->right, 0); - rbtree_rotate_left(root, parent); - node = *root; - break; - } - } else { - struct rbtree *sibling = rbtree_get_left(parent); - if (rbtree_get_red(sibling)) { - rbtree_set_red(sibling, 0); - rbtree_set_red(parent, 1); - rbtree_rotate_right(root, parent); - sibling = rbtree_get_left(parent); - } - if ((!sibling->right || !rbtree_get_red(sibling->right)) && - (!rbtree_get_left(sibling) || - !rbtree_get_red(rbtree_get_left(sibling)))) { - rbtree_set_red(sibling, 1); - node = parent; - parent = node->parent; - } else { - if (!rbtree_get_left(sibling) || - !rbtree_get_red(rbtree_get_left(sibling))) { - rbtree_set_red(sibling->right, 0); - rbtree_set_red(sibling, 1); - rbtree_rotate_left(root, sibling); - sibling = rbtree_get_left(parent); - } - rbtree_set_red(sibling, rbtree_get_red(parent)); - rbtree_set_red(parent, 0); - rbtree_set_red(rbtree_get_left(sibling), 0); - rbtree_rotate_right(root, parent); - node = *root; - break; - } - } - } - if (node) - rbtree_set_red(node, 0); -} - -void rbtree_remove(struct rbtree **root, struct rbtree *node) { - struct rbtree *y = node; - struct rbtree *x = 0; - struct rbtree *x_parent = 0; - int y_original_color = rbtree_get_red(y); - if (!rbtree_get_left(node)) { - x = node->right; - rbtree_transplant(root, node, node->right); - x_parent = node->parent; - } else if (!node->right) { - x = rbtree_get_left(node); - rbtree_transplant(root, node, rbtree_get_left(node)); - x_parent = node->parent; - } else { - y = rbtree_first(node->right); - y_original_color = rbtree_get_red(y); - x = y->right; - if (y->parent == node) { - if (x) - x->parent = y; - x_parent = y; - } else { - rbtree_transplant(root, y, y->right); - y->right = node->right; - y->right->parent = y; - x_parent = y->parent; - } - rbtree_transplant(root, node, y); - rbtree_set_left(y, rbtree_get_left(node)); - rbtree_get_left(y)->parent = y; - rbtree_set_red(y, rbtree_get_red(node)); - } - if (!y_original_color) - rbtree_remove_fixup(root, x, x_parent); -} - -struct rbtree *rbtree_get(const struct rbtree *node, const struct rbtree *key, - rbtree_cmp_f *cmp) { - while (node) { - int c = cmp(key, node); - if (c < 0) { - node = rbtree_get_left(node); - } else if (c > 0) { - node = node->right; - } else { - return (struct rbtree *)node; - } - } - return 0; -} - -struct rbtree *rbtree_floor(const struct rbtree *node, const struct rbtree *key, - rbtree_cmp_f *cmp) { - while (node) { - if (cmp(key, node) < 0) { - node = rbtree_get_left(node); - } else { - node = node->right; - } - } - return (struct rbtree *)node; -} - -struct rbtree *rbtree_ceil(const struct rbtree *node, const struct rbtree *key, - rbtree_cmp_f *cmp) { - while (node) { - if (cmp(node, key) < 0) { - node = rbtree_get_left(node); - } else { - node = node->right; - } - } - return (struct rbtree *)node; -} diff --git a/libc/intrin/rbtree.h b/libc/intrin/rbtree.h deleted file mode 100644 index 0c63f67dd..000000000 --- a/libc/intrin/rbtree.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifdef _COSMO_SOURCE -#ifndef COSMOPOLITAN_RBTREE_H_ -#define COSMOPOLITAN_RBTREE_H_ -#define rbtree_ceil __rbtree_ceil -#define rbtree_first __rbtree_first -#define rbtree_floor __rbtree_floor -#define rbtree_get __rbtree_get -#define rbtree_insert __rbtree_insert -#define rbtree_last __rbtree_last -#define rbtree_next __rbtree_next -#define rbtree_prev __rbtree_prev -#define rbtree_remove __rbtree_remove -COSMOPOLITAN_C_START_ - -#define RBTREE_CONTAINER(t, f, p) ((t *)(((char *)(p)) - offsetof(t, f))) - -struct rbtree { - uintptr_t word; - struct rbtree *right; - struct rbtree *parent; -}; - -typedef int rbtree_cmp_f(const struct rbtree *, const struct rbtree *); - -static inline struct rbtree *rbtree_get_left(const struct rbtree *node) { - return (struct rbtree *)(node->word & -2); -} - -static inline void rbtree_set_left(struct rbtree *node, struct rbtree *left) { - node->word = (uintptr_t)left | (node->word & 1); -} - -static inline int rbtree_get_red(const struct rbtree *node) { - return node->word & 1; -} - -static inline void rbtree_set_red(struct rbtree *node, int red) { - node->word &= -2; - node->word |= red; -} - -struct rbtree *rbtree_next(struct rbtree *) libcesque; -struct rbtree *rbtree_prev(struct rbtree *) libcesque; -struct rbtree *rbtree_first(struct rbtree *) libcesque; -struct rbtree *rbtree_last(struct rbtree *) libcesque; -void rbtree_remove(struct rbtree **, struct rbtree *) libcesque; -void rbtree_insert(struct rbtree **, struct rbtree *, rbtree_cmp_f *) libcesque; -struct rbtree *rbtree_get(const struct rbtree *, const struct rbtree *, - rbtree_cmp_f *) libcesque; -struct rbtree *rbtree_ceil(const struct rbtree *, const struct rbtree *, - rbtree_cmp_f *) libcesque; -struct rbtree *rbtree_floor(const struct rbtree *, const struct rbtree *, - rbtree_cmp_f *) libcesque; - -COSMOPOLITAN_C_END_ -#endif /* COSMOPOLITAN_RBTREE_H_ */ -#endif /* _COSMO_SOURCE */ diff --git a/libc/intrin/tree.c b/libc/intrin/tree.c new file mode 100644 index 000000000..23e25f7f5 --- /dev/null +++ b/libc/intrin/tree.c @@ -0,0 +1,271 @@ +// Copyright 2024 Justine Alexandra Roberts Tunney +// +// Permission to use, copy, modify, and/or distribute this software for +// any purpose with or without fee is hereby granted, provided that the +// above copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include "tree.h" + +struct Tree *tree_last(struct Tree *node) { + while (node && node->right) + node = node->right; + return node; +} + +struct Tree *tree_first(struct Tree *node) { + while (node && tree_get_left(node)) + node = tree_get_left(node); + return node; +} + +struct Tree *tree_next(struct Tree *node) { + if (!node) + return 0; + if (node->right) + return tree_first(node->right); + struct Tree *parent = node->parent; + while (parent && node == parent->right) { + node = parent; + parent = parent->parent; + } + return parent; +} + +struct Tree *tree_prev(struct Tree *node) { + struct Tree *parent; + if (!node) + return 0; + if (tree_get_left(node)) + return tree_last(tree_get_left(node)); + parent = node->parent; + while (parent && node == tree_get_left(parent)) { + node = parent; + parent = parent->parent; + } + return parent; +} + +static void tree_rotate_left(struct Tree **root, struct Tree *x) { + struct Tree *y = x->right; + x->right = tree_get_left(y); + if (tree_get_left(y)) + tree_get_left(y)->parent = x; + y->parent = x->parent; + if (!x->parent) { + *root = y; + } else if (x == tree_get_left(x->parent)) { + tree_set_left(x->parent, y); + } else { + x->parent->right = y; + } + tree_set_left(y, x); + x->parent = y; +} + +static void tree_rotate_right(struct Tree **root, struct Tree *y) { + struct Tree *x = tree_get_left(y); + tree_set_left(y, x->right); + if (x->right) + x->right->parent = y; + x->parent = y->parent; + if (!y->parent) { + *root = x; + } else if (y == y->parent->right) { + y->parent->right = x; + } else { + tree_set_left(y->parent, x); + } + y->parent = x; + x->right = y; +} + +static void tree_rebalance_insert(struct Tree **root, struct Tree *node) { + struct Tree *uncle; + tree_set_red(node, 1); + while (node != *root && tree_get_red(node->parent)) { + if (node->parent == tree_get_left(node->parent->parent)) { + uncle = node->parent->parent->right; + if (uncle && tree_get_red(uncle)) { + tree_set_red(node->parent, 0); + tree_set_red(uncle, 0); + tree_set_red(node->parent->parent, 1); + node = node->parent->parent; + } else { + if (node == node->parent->right) { + node = node->parent; + tree_rotate_left(root, node); + } + tree_set_red(node->parent, 0); + tree_set_red(node->parent->parent, 1); + tree_rotate_right(root, node->parent->parent); + } + } else { + uncle = tree_get_left(node->parent->parent); + if (uncle && tree_get_red(uncle)) { + tree_set_red(node->parent, 0); + tree_set_red(uncle, 0); + tree_set_red(node->parent->parent, 1); + node = node->parent->parent; + } else { + if (node == tree_get_left(node->parent)) { + node = node->parent; + tree_rotate_right(root, node); + } + tree_set_red(node->parent, 0); + tree_set_red(node->parent->parent, 1); + tree_rotate_left(root, node->parent->parent); + } + } + } + tree_set_red(*root, 0); +} + +void tree_insert(struct Tree **root, struct Tree *node, tree_cmp_f *cmp) { + struct Tree *search, *parent; + node->word = 0; + node->right = 0; + node->parent = 0; + if (!*root) { + *root = node; + } else { + search = *root; + parent = 0; + do { + parent = search; + if (cmp(node, search) < 0) { + search = tree_get_left(search); + } else { + search = search->right; + } + } while (search); + if (cmp(node, parent) < 0) { + tree_set_left(parent, node); + } else { + parent->right = node; + } + node->parent = parent; + tree_rebalance_insert(root, node); + } +} + +static void tree_transplant(struct Tree **root, struct Tree *u, + struct Tree *v) { + if (!u->parent) { + *root = v; + } else if (u == tree_get_left(u->parent)) { + tree_set_left(u->parent, v); + } else { + u->parent->right = v; + } + if (v) + v->parent = u->parent; +} + +static void tree_rebalance_remove(struct Tree **root, struct Tree *node, + struct Tree *parent) { + struct Tree *sibling; + while (node != *root && (!node || !tree_get_red(node))) { + if (node == tree_get_left(parent)) { + sibling = parent->right; + if (tree_get_red(sibling)) { + tree_set_red(sibling, 0); + tree_set_red(parent, 1); + tree_rotate_left(root, parent); + sibling = parent->right; + } + if ((!tree_get_left(sibling) || !tree_get_red(tree_get_left(sibling))) && + (!sibling->right || !tree_get_red(sibling->right))) { + tree_set_red(sibling, 1); + node = parent; + parent = node->parent; + } else { + if (!sibling->right || !tree_get_red(sibling->right)) { + tree_set_red(tree_get_left(sibling), 0); + tree_set_red(sibling, 1); + tree_rotate_right(root, sibling); + sibling = parent->right; + } + tree_set_red(sibling, tree_get_red(parent)); + tree_set_red(parent, 0); + tree_set_red(sibling->right, 0); + tree_rotate_left(root, parent); + node = *root; + break; + } + } else { + sibling = tree_get_left(parent); + if (tree_get_red(sibling)) { + tree_set_red(sibling, 0); + tree_set_red(parent, 1); + tree_rotate_right(root, parent); + sibling = tree_get_left(parent); + } + if ((!sibling->right || !tree_get_red(sibling->right)) && + (!tree_get_left(sibling) || !tree_get_red(tree_get_left(sibling)))) { + tree_set_red(sibling, 1); + node = parent; + parent = node->parent; + } else { + if (!tree_get_left(sibling) || !tree_get_red(tree_get_left(sibling))) { + tree_set_red(sibling->right, 0); + tree_set_red(sibling, 1); + tree_rotate_left(root, sibling); + sibling = tree_get_left(parent); + } + tree_set_red(sibling, tree_get_red(parent)); + tree_set_red(parent, 0); + tree_set_red(tree_get_left(sibling), 0); + tree_rotate_right(root, parent); + node = *root; + break; + } + } + } + if (node) + tree_set_red(node, 0); +} + +void tree_remove(struct Tree **root, struct Tree *node) { + struct Tree *x = 0; + struct Tree *y = node; + struct Tree *x_parent = 0; + int y_original_color = tree_get_red(y); + if (!tree_get_left(node)) { + x = node->right; + tree_transplant(root, node, node->right); + x_parent = node->parent; + } else if (!node->right) { + x = tree_get_left(node); + tree_transplant(root, node, tree_get_left(node)); + x_parent = node->parent; + } else { + y = tree_first(node->right); + y_original_color = tree_get_red(y); + x = y->right; + if (y->parent == node) { + if (x) + x->parent = y; + x_parent = y; + } else { + tree_transplant(root, y, y->right); + y->right = node->right; + y->right->parent = y; + x_parent = y->parent; + } + tree_transplant(root, node, y); + tree_set_left(y, tree_get_left(node)); + tree_get_left(y)->parent = y; + tree_set_red(y, tree_get_red(node)); + } + if (!y_original_color) + tree_rebalance_remove(root, x, x_parent); +} diff --git a/libc/intrin/tree.h b/libc/intrin/tree.h new file mode 100644 index 000000000..fae2e08cb --- /dev/null +++ b/libc/intrin/tree.h @@ -0,0 +1,91 @@ +#ifndef COSMOPOLITAN_TREE_H_ +#define COSMOPOLITAN_TREE_H_ +#define tree_first __tree_first +#define tree_insert __tree_insert +#define tree_last __tree_last +#define tree_next __tree_next +#define tree_prev __tree_prev +#define tree_remove __tree_remove +COSMOPOLITAN_C_START_ + +#define TREE_CONTAINER(t, f, p) ((t *)(((char *)(p)) - offsetof(t, f))) + +struct Tree { + uintptr_t word; + struct Tree *right; + struct Tree *parent; +}; + +typedef int tree_search_f(const void *, const struct Tree *); +typedef int tree_cmp_f(const struct Tree *, const struct Tree *); + +forceinline struct Tree *tree_get_left(const struct Tree *node) { + return (struct Tree *)(node->word & -2); +} + +static inline void tree_set_left(struct Tree *node, struct Tree *left) { + node->word = (uintptr_t)left | (node->word & 1); +} + +static inline int tree_get_red(const struct Tree *node) { + return node->word & 1; +} + +static inline void tree_set_red(struct Tree *node, int red) { + node->word &= -2; + node->word |= red; +} + +forceinline optimizespeed struct Tree *tree_floor(const struct Tree *node, + const void *key, + tree_search_f *cmp) { + struct Tree *left = 0; + while (node) { + if (cmp(key, node) >= 0) { + left = (struct Tree *)node; + node = tree_get_left(node); + } else { + node = node->right; + } + } + return left; +} + +static inline struct Tree *tree_ceil(const struct Tree *node, const void *key, + tree_search_f *cmp) { + struct Tree *right = 0; + while (node) { + if (cmp(key, node) < 0) { + right = (struct Tree *)node; + node = tree_get_left(node); + } else { + node = node->right; + } + } + return right; +} + +static inline struct Tree *tree_get(const struct Tree *node, const void *key, + tree_search_f *cmp) { + while (node) { + int c = cmp(key, node); + if (c < 0) { + node = tree_get_left(node); + } else if (c > 0) { + node = node->right; + } else { + return (struct Tree *)node; + } + } + return 0; +} + +struct Tree *tree_next(struct Tree *) libcesque; +struct Tree *tree_prev(struct Tree *) libcesque; +struct Tree *tree_first(struct Tree *) libcesque; +struct Tree *tree_last(struct Tree *) libcesque; +void tree_remove(struct Tree **, struct Tree *) libcesque; +void tree_insert(struct Tree **, struct Tree *, tree_cmp_f *) libcesque; + +COSMOPOLITAN_C_END_ +#endif /* COSMOPOLITAN_TREE_H_ */ diff --git a/libc/log/oncrash_amd64.c b/libc/log/oncrash_amd64.c index 914e2aa44..f9df5f99b 100644 --- a/libc/log/oncrash_amd64.c +++ b/libc/log/oncrash_amd64.c @@ -241,14 +241,10 @@ static relegated void ShowCrashReport(int err, int sig, siginfo_t *si, klog(buf, p - buf); } kprintf("\n"); - if (!IsWindows()) { - __print_maps(); - } - if (__argv) { - for (i = 0; i < __argc; ++i) { + __print_maps(15); + if (__argv) + for (i = 0; i < __argc; ++i) kprintf("%s ", __argv[i]); - } - } kprintf("\n"); } diff --git a/libc/proc/fork-nt.c b/libc/proc/fork-nt.c index 6dc06bf3f..7e58445b6 100644 --- a/libc/proc/fork-nt.c +++ b/libc/proc/fork-nt.c @@ -30,6 +30,7 @@ #include "libc/intrin/kprintf.h" #include "libc/intrin/maps.h" #include "libc/intrin/strace.internal.h" +#include "libc/intrin/tree.h" #include "libc/intrin/weaken.h" #include "libc/macros.internal.h" #include "libc/nt/createfile.h" @@ -95,7 +96,7 @@ static inline textwindows ssize_t ForkIo(int64_t h, char *p, size_t n, size_t i; uint32_t x; for (i = 0; i < n; i += x) { - if (!f(h, p + i, n - i, &x, NULL)) + if (!f(h, p + i, n - i, &x, 0)) return __winerr(); if (!x) break; @@ -109,10 +110,11 @@ static dontinline textwindows ssize_t ForkIo2( const char *sf, bool ischild) { ssize_t rc = ForkIo(h, buf, n, fn); if (ischild) { - __tls_enabled_set(false); // prevent tls crash in kprintf + // prevent crashes + __tls_enabled_set(false); __pid = __imp_GetCurrentProcessId(); __klog_handle = 0; - __maps.used = 0; + __maps.maps = 0; } NTTRACE("%s(%ld, %p, %'zu) β†’ %'zd% m", sf, h, buf, n, rc); return rc; @@ -121,9 +123,11 @@ static dontinline textwindows ssize_t ForkIo2( static dontinline textwindows bool WriteAll(int64_t h, void *buf, size_t n) { bool ok; ok = ForkIo2(h, buf, n, (void *)WriteFile, "WriteFile", false) != -1; - if (!ok) - AbortFork("WriteAll"); - // Sleep(10); + if (!ok) { + STRACE("fork() failed in parent due to WriteAll(%ld, %p, %'zu) β†’ %u", h, + buf, n, GetLastError()); + __print_maps(0); + } return ok; } @@ -185,30 +189,6 @@ static textwindows void *Malloc(size_t size) { return HeapAlloc(GetProcessHeap(), 0, size); } -static textwindows void Free(void *addr) { - HeapFree(GetProcessHeap(), 0, addr); -} - -static int CountMaps(struct Dll *maps) { - int count = 0; - for (struct Dll *e = dll_first(maps); e; e = dll_next(maps, e)) - ++count; - return count; -} - -static struct Map **SortMaps(struct Dll *maps, int count) { - int j, i = 0; - struct Map **sorted = Malloc(count * sizeof(struct Map *)); - for (struct Dll *e = dll_first(maps); e; e = dll_next(maps, e)) { - struct Map *map = MAP_CONTAINER(e); - for (j = i; j > 0 && sorted[j - 1]->addr > map->addr; --j) - sorted[j] = sorted[j - 1]; - sorted[j] = map; - ++i; - } - return sorted; -} - textwindows void WinMainForked(void) { jmp_buf jb; int64_t reader; @@ -233,35 +213,30 @@ textwindows void WinMainForked(void) { ReadOrDie(reader, jb, sizeof(jb)); // read memory mappings from parent process - int n = 0; - struct Dll *maps = 0; + struct Tree *maps = 0; for (;;) { struct Map *map = Malloc(sizeof(struct Map)); ReadOrDie(reader, map, sizeof(struct Map)); - if (map->addr == MAP_FAILED) { - Free(map); + if (map->addr == MAP_FAILED) break; - } - dll_init(&map->elem); - dll_make_first(&maps, &map->elem); - ++n; + tree_insert(&maps, &map->tree, __maps_compare); } - // created sorted array of maps - struct Map **sorted = SortMaps(maps, n); - // map memory into process int granularity = __granularity(); - for (int i = 0; i < n; ++i) { - struct Map *map = sorted[i]; + for (struct Tree *e = tree_first(maps); e; e = tree_next(e)) { + struct Map *map = MAP_TREE_CONTAINER(e); if ((uintptr_t)map->addr & (granularity - 1)) continue; - size_t size = map->size; // get true length in case mprotect() chopped up actual win32 map - for (int j = i + 1; - j < n && sorted[j]->hand == -1 && map->addr + size == sorted[j]->addr; - ++j) { - size += sorted[j]->size; + size_t size = map->size; + for (struct Tree *e2 = tree_next(e); e2; e2 = tree_next(e2)) { + struct Map *map2 = MAP_TREE_CONTAINER(e2); + if (map2->hand == -1 && map->addr + size == map2->addr) { + size += map2->size; + } else { + break; + } } // obtain the most permissive access possible unsigned prot, access; @@ -295,11 +270,11 @@ textwindows void WinMainForked(void) { // fixup memory manager __maps.free = 0; - __maps.used = 0; + __maps.maps = 0; __maps.count = 0; __maps.pages = 0; - for (int i = 0; i < n; ++i) { - struct Map *map = sorted[i]; + for (struct Tree *e = tree_first(maps); e; e = tree_next(e)) { + struct Map *map = MAP_TREE_CONTAINER(e); __maps.count += 1; __maps.pages += (map->size + getpagesize() - 1) / getpagesize(); unsigned old_protect; @@ -307,8 +282,7 @@ textwindows void WinMainForked(void) { &old_protect)) AbortFork("VirtualProtect"); } - Free(sorted); - __maps.used = maps; + __maps.maps = maps; __maps_init(); // mitosis complete @@ -393,19 +367,13 @@ textwindows int sys_fork_nt(uint32_t dwCreationFlags) { if (spawnrc != -1) { CloseHandle(procinfo.hThread); ok = WriteAll(writer, jb, sizeof(jb)); - int count = 0; // this list will be populated with the maps we're transferring - struct Dll *e2, *maps = 0; - for (struct Dll *e = dll_first(__maps.used); ok && e; e = e2) { - e2 = dll_next(__maps.used, e); - struct Map *map = MAP_CONTAINER(e); + for (struct Map *map = __maps_first(); ok && map; + map = __maps_next(map)) { if (MAX((char *)__executable_start, map->addr) < MIN((char *)_end, map->addr + map->size)) continue; // executable image is loaded by windows - dll_remove(&__maps.used, e); - dll_make_last(&maps, e); ok = WriteAll(writer, map, sizeof(*map)); - ++count; } // send a terminating Map struct to child if (ok) { @@ -415,40 +383,44 @@ textwindows int sys_fork_nt(uint32_t dwCreationFlags) { } // now write content of each map to child int granularity = __granularity(); - struct Map **sorted = SortMaps(maps, count); - uint32_t *old_protect = Malloc(count * 4); - for (int i = 0; ok && i < count; ++i) { - struct Map *map = sorted[i]; + for (struct Map *map = __maps_first(); ok && map; + map = __maps_next(map)) { // we only need to worry about the base mapping if ((uintptr_t)map->addr & (granularity - 1)) continue; + if (MAX((char *)__executable_start, map->addr) < + MIN((char *)_end, map->addr + map->size)) + continue; // executable image is loaded by windows // shared mappings don't need to be copied if ((map->flags & MAP_TYPE) == MAP_SHARED) continue; // get true length in case mprotect() chopped up actual win32 map - int j; size_t size = map->size; - for (j = i + 1; j < count && sorted[j]->hand == -1 && - map->addr + size == sorted[j]->addr; - ++j) { - size += sorted[j]->size; + for (struct Map *map2 = __maps_next(map); map2; + map2 = __maps_next(map2)) { + if (map2->hand == -1 && map->addr + size == map2->addr) { + size += map2->size; + } else { + break; + } + } + for (struct Map *map2 = map; ok && map2; map2 = __maps_next(map2)) { + if (!(map2->prot & PROT_READ)) + if (map->addr >= map2->addr && map->addr < map->addr + size) + ok = VirtualProtect( + map2->addr, map2->size, + __prot2nt(map2->prot | PROT_READ, map2->iscow), + &map2->oldprot); } - for (int k = i; ok && k < j; ++k) - if (!(sorted[k]->prot & PROT_READ)) - ok = VirtualProtect( - sorted[k]->addr, sorted[k]->size, - __prot2nt(sorted[k]->prot | PROT_READ, map->iscow), - &old_protect[k]); if (ok) ok = WriteAll(writer, map->addr, size); - for (int k = i; ok && k < j; ++k) - if (!(sorted[k]->prot & PROT_READ)) - ok = VirtualProtect(sorted[k]->addr, sorted[k]->size, - old_protect[k], &old_protect[k]); + for (struct Map *map2 = map; ok && map2; map2 = __maps_next(map2)) { + if (!(map2->prot & PROT_READ)) + if (map->addr >= map2->addr && map->addr < map->addr + size) + ok = VirtualProtect(map2->addr, map2->size, map2->oldprot, + &map2->oldprot); + } } - Free(old_protect); - Free(sorted); - dll_make_first(&__maps.used, maps); if (ok) ok = WriteAll(writer, __data_start, __data_end - __data_start); if (ok) @@ -466,6 +438,7 @@ textwindows int sys_fork_nt(uint32_t dwCreationFlags) { } else { TerminateProcess(procinfo.hProcess, SIGKILL); CloseHandle(procinfo.hProcess); + rc = -1; } } } @@ -473,9 +446,8 @@ textwindows int sys_fork_nt(uint32_t dwCreationFlags) { CloseHandle(reader); if (writer != -1) CloseHandle(writer); - if (rc == -1 && errno != ENOMEM) { + if (rc == -1 && errno != ENOMEM) eagain(); // posix fork() only specifies two errors - } } else { rc = 0; // re-apply code morphing for thread-local storage diff --git a/libc/proc/fork.c b/libc/proc/fork.c index 05431bcb5..3a48db798 100644 --- a/libc/proc/fork.c +++ b/libc/proc/fork.c @@ -22,6 +22,7 @@ #include "libc/calls/state.internal.h" #include "libc/calls/struct/sigset.h" #include "libc/calls/struct/sigset.internal.h" +#include "libc/calls/struct/timespec.h" #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" @@ -45,7 +46,6 @@ #include "libc/thread/posixthread.internal.h" #include "libc/thread/tls.h" -extern pthread_mutex_t nsync_waiters_mu; extern pthread_mutex_t _pthread_lock_obj; static void _onfork_prepare(void) { @@ -54,11 +54,10 @@ static void _onfork_prepare(void) { _pthread_lock(); __maps_lock(); __fds_lock(); - pthread_mutex_lock(&nsync_waiters_mu); + LOCKTRACE("READY TO ROCK AND ROLL"); } static void _onfork_parent(void) { - pthread_mutex_unlock(&nsync_waiters_mu); __fds_unlock(); __maps_unlock(); _pthread_unlock(); @@ -68,7 +67,6 @@ static void _onfork_parent(void) { static void _onfork_child(void) { __fds_lock_obj = (pthread_mutex_t)PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; - nsync_waiters_mu = (pthread_mutex_t)PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; _pthread_lock_obj = (pthread_mutex_t)PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; atomic_store_explicit(&__maps.lock, 0, memory_order_relaxed); atomic_store_explicit(&__get_tls()->tib_relock_maps, 0, memory_order_relaxed); @@ -77,7 +75,9 @@ static void _onfork_child(void) { } int _fork(uint32_t dwCreationFlags) { + long micros; struct Dll *e; + struct timespec started; int ax, dx, tid, parent; parent = __pid; BLOCK_SIGNALS; @@ -85,11 +85,13 @@ int _fork(uint32_t dwCreationFlags) { __proc_lock(); if (__threaded) _onfork_prepare(); + started = timespec_real(); if (!IsWindows()) { ax = sys_fork(); } else { ax = sys_fork_nt(dwCreationFlags); } + micros = timespec_tomicros(timespec_sub(timespec_real(), started)); if (!ax) { // get new process id @@ -136,15 +138,14 @@ int _fork(uint32_t dwCreationFlags) { // run user fork callbacks if (__threaded) _onfork_child(); - STRACE("fork() β†’ 0 (child of %d)", parent); + STRACE("fork() β†’ 0 (child of %d; took %ld us)", parent, micros); } else { // this is the parent process - if (__threaded) { + if (__threaded) _onfork_parent(); - } if (IsWindows()) __proc_unlock(); - STRACE("fork() β†’ %d% m", ax); + STRACE("fork() β†’ %d% m (took %ld us)", ax, micros); } ALLOW_SIGNALS; return ax; diff --git a/libc/proc/posix_spawn.c b/libc/proc/posix_spawn.c index 4e85e49b4..967392ad8 100644 --- a/libc/proc/posix_spawn.c +++ b/libc/proc/posix_spawn.c @@ -482,9 +482,8 @@ errno_t posix_spawn(int *pid, const char *path, const posix_spawn_file_actions_t *file_actions, const posix_spawnattr_t *attrp, char *const argv[], char *const envp[]) { - if (IsWindows()) { + if (IsWindows()) return posix_spawn_nt(pid, path, file_actions, attrp, argv, envp); - } int pfds[2]; bool use_pipe; volatile int status = 0; @@ -516,66 +515,55 @@ errno_t posix_spawn(int *pid, const char *path, sigaction(sig, &dfl, 0); } } - if (flags & POSIX_SPAWN_SETSID) { + if (flags & POSIX_SPAWN_SETSID) setsid(); - } - if ((flags & POSIX_SPAWN_SETPGROUP) && setpgid(0, (*attrp)->pgroup)) { + if ((flags & POSIX_SPAWN_SETPGROUP) && setpgid(0, (*attrp)->pgroup)) goto ChildFailed; - } - if ((flags & POSIX_SPAWN_RESETIDS) && setgid(getgid())) { + if ((flags & POSIX_SPAWN_RESETIDS) && setgid(getgid())) goto ChildFailed; - } - if ((flags & POSIX_SPAWN_RESETIDS) && setuid(getuid())) { + if ((flags & POSIX_SPAWN_RESETIDS) && setuid(getuid())) goto ChildFailed; - } if (file_actions) { struct _posix_faction *a; for (a = *file_actions; a; a = a->next) { if (use_pipe && pfds[1] == a->fildes) { int p2; - if ((p2 = dup(pfds[1])) == -1) { + if ((p2 = dup(pfds[1])) == -1) goto ChildFailed; - } lost_cloexec = true; close(pfds[1]); pfds[1] = p2; } switch (a->action) { case _POSIX_SPAWN_CLOSE: - if (close(a->fildes)) { + if (close(a->fildes)) goto ChildFailed; - } break; case _POSIX_SPAWN_DUP2: - if (dup2(a->fildes, a->newfildes) == -1) { + if (dup2(a->fildes, a->newfildes) == -1) goto ChildFailed; - } break; case _POSIX_SPAWN_OPEN: { int t; - if ((t = openat(AT_FDCWD, a->path, a->oflag, a->mode)) == -1) { + if ((t = openat(AT_FDCWD, a->path, a->oflag, a->mode)) == -1) goto ChildFailed; - } if (t != a->fildes) { if (dup2(t, a->fildes) == -1) { close(t); goto ChildFailed; } - if (close(t)) { + if (close(t)) goto ChildFailed; - } } break; } case _POSIX_SPAWN_CHDIR: - if (chdir(a->path) == -1) { + if (chdir(a->path) == -1) goto ChildFailed; - } break; case _POSIX_SPAWN_FCHDIR: - if (fchdir(a->fildes) == -1) { + if (fchdir(a->fildes) == -1) goto ChildFailed; - } break; default: __builtin_unreachable(); @@ -583,17 +571,13 @@ errno_t posix_spawn(int *pid, const char *path, } } if (IsLinux() || IsFreebsd() || IsNetbsd()) { - if (flags & POSIX_SPAWN_SETSCHEDULER) { + if (flags & POSIX_SPAWN_SETSCHEDULER) if (sched_setscheduler(0, (*attrp)->schedpolicy, - &(*attrp)->schedparam) == -1) { + &(*attrp)->schedparam) == -1) goto ChildFailed; - } - } - if (flags & POSIX_SPAWN_SETSCHEDPARAM) { - if (sched_setparam(0, &(*attrp)->schedparam)) { + if (flags & POSIX_SPAWN_SETSCHEDPARAM) + if (sched_setparam(0, &(*attrp)->schedparam)) goto ChildFailed; - } - } } if (flags & POSIX_SPAWN_SETRLIMIT) { int rlimset = (*attrp)->rlimset; @@ -608,9 +592,8 @@ errno_t posix_spawn(int *pid, const char *path, } } } - if (lost_cloexec) { + if (lost_cloexec) fcntl(pfds[1], F_SETFD, FD_CLOEXEC); - } if (flags & POSIX_SPAWN_SETSIGMASK) { childmask = (*attrp)->sigmask; } else { @@ -636,9 +619,8 @@ errno_t posix_spawn(int *pid, const char *path, if (!use_pipe) { res = status; } else { - if (can_clobber) { + if (can_clobber) atomic_store_explicit(&has_vfork, true, memory_order_release); - } res = 0; read(pfds[0], &res, sizeof(res)); } @@ -651,9 +633,8 @@ errno_t posix_spawn(int *pid, const char *path, } else { res = errno; } - if (use_pipe) { + if (use_pipe) close(pfds[0]); - } ParentFailed: sigprocmask(SIG_SETMASK, &oldmask, 0); pthread_setcancelstate(cs, 0); diff --git a/libc/runtime/mapstack.c b/libc/runtime/mapstack.c index 3bec5d639..eccd5cefc 100644 --- a/libc/runtime/mapstack.c +++ b/libc/runtime/mapstack.c @@ -50,9 +50,10 @@ void *NewCosmoStack(void) { if (IsOpenbsd() && __sys_mmap(p, n, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED | MAP_ANON_OPENBSD | MAP_STACK_OPENBSD, - -1, 0, 0) != p) { + -1, 0, 0) != p) + notpossible; + if (mprotect(p, GetGuardSize(), PROT_NONE | PROT_GUARD)) notpossible; - } return p; } else { return 0; diff --git a/libc/runtime/runtime.h b/libc/runtime/runtime.h index 236a06f2d..295f0fe02 100644 --- a/libc/runtime/runtime.h +++ b/libc/runtime/runtime.h @@ -91,7 +91,7 @@ void ShowCrashReports(void) libcesque; int ftrace_install(void) libcesque; int ftrace_enabled(int) libcesque; int strace_enabled(int) libcesque; -void __print_maps(void) libcesque; +void __print_maps(size_t) libcesque; void __printargs(const char *) libcesque; /* builtin sh-like system/popen dsl */ int _cocmd(int, char **, char **) libcesque; diff --git a/libc/stdio/printargs.c b/libc/stdio/printargs.c index 2b549cbdf..5d2a61c2f 100644 --- a/libc/stdio/printargs.c +++ b/libc/stdio/printargs.c @@ -468,7 +468,7 @@ textstartup void __printargs(const char *prologue) { PRINT(""); PRINT("MEMTRACK"); - __print_maps(); + __print_maps(0); PRINT(""); PRINT("TERMIOS"); diff --git a/libc/sysv/consts.sh b/libc/sysv/consts.sh index 233c11edc..22cd4c998 100755 --- a/libc/sysv/consts.sh +++ b/libc/sysv/consts.sh @@ -292,6 +292,7 @@ syscon mprot PROT_NONE 0 0 0 0 0 0 0 0 # mmap, mprotect, unix syscon mprot PROT_READ 1 1 1 1 1 1 1 1 # mmap, mprotect, unix consensus syscon mprot PROT_WRITE 2 2 2 2 2 2 2 2 # mmap, mprotect, unix consensus syscon mprot PROT_EXEC 4 4 4 4 4 4 4 4 # mmap, mprotect, unix consensus +syscon mprot PROT_GUARD 0 0 0 0 0 0 0 0x100 # mmap, mprotect, unix consensus # mremap() flags # the revolutionary praxis of realloc() diff --git a/libc/sysv/consts/PROT_GUARD.S b/libc/sysv/consts/PROT_GUARD.S new file mode 100644 index 000000000..e04cb73ee --- /dev/null +++ b/libc/sysv/consts/PROT_GUARD.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon mprot,PROT_GUARD,0,0,0,0,0,0,0,0x100 diff --git a/libc/sysv/consts/prot.h b/libc/sysv/consts/prot.h index 032a6b1a7..ea026f869 100644 --- a/libc/sysv/consts/prot.h +++ b/libc/sysv/consts/prot.h @@ -3,10 +3,7 @@ #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -extern const int PROT_NONE; -extern const int PROT_READ; -extern const int PROT_WRITE; -extern const int PROT_EXEC; +extern const int PROT_GUARD; COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/thread/pthread_create.c b/libc/thread/pthread_create.c index b9515272e..55db00ef4 100644 --- a/libc/thread/pthread_create.c +++ b/libc/thread/pthread_create.c @@ -229,20 +229,10 @@ static errno_t pthread_create_impl(pthread_t *thread, -1, 0, 0) != pt->pt_attr.__stackaddr) { notpossible; } - if (pt->pt_attr.__guardsize) { - if (!IsWindows()) { - if (mprotect(pt->pt_attr.__stackaddr, pt->pt_attr.__guardsize, - PROT_NONE)) { - notpossible; - } - } else { - uint32_t oldattr; - if (!VirtualProtect(pt->pt_attr.__stackaddr, pt->pt_attr.__guardsize, - kNtPageReadwrite | kNtPageGuard, &oldattr)) { - notpossible; - } - } - } + if (pt->pt_attr.__guardsize) + if (mprotect(pt->pt_attr.__stackaddr, pt->pt_attr.__guardsize, + PROT_NONE | PROT_GUARD)) + notpossible; } if (!pt->pt_attr.__stackaddr || pt->pt_attr.__stackaddr == MAP_FAILED) { rc = errno; diff --git a/libc/thread/thread.h b/libc/thread/thread.h index 7fd38f42c..872fdcc37 100644 --- a/libc/thread/thread.h +++ b/libc/thread/thread.h @@ -190,6 +190,7 @@ int pthread_spin_trylock(pthread_spinlock_t *) libcesque paramsnonnull(); int pthread_spin_unlock(pthread_spinlock_t *) libcesque paramsnonnull(); int pthread_testcancel_np(void) libcesque; int pthread_tryjoin_np(pthread_t, void **) libcesque; +int pthread_delay_np(const void *, int) libcesque; int pthread_yield_np(void) libcesque; int pthread_yield(void) libcesque; pthread_id_np_t pthread_getthreadid_np(void) libcesque; diff --git a/test/ctl/set_test.cc b/test/ctl/set_test.cc index 5eecca5e2..c435533db 100644 --- a/test/ctl/set_test.cc +++ b/test/ctl/set_test.cc @@ -19,9 +19,9 @@ #include "ctl/set.h" #include "libc/mem/leaks.h" -// #include -// #define ctl std -// #define check() size() +#include +#define ctl std +#define check() size() int rand32(void) @@ -148,6 +148,16 @@ main() s.check(); } + { + // Test lower_bound and upper_bound + ctl::set s{ 1, 3, 4, 5, 7, 9 }; + auto lower = s.lower_bound(4); + auto upper = s.upper_bound(4); + if (*lower != 4 || *upper != 5) + return 18; + s.check(); + } + { // Test emplace ctl::set> s; diff --git a/test/libc/calls/raise_test.c b/test/libc/calls/raise_test.c index 5f764fa38..5ebb8189a 100644 --- a/test/libc/calls/raise_test.c +++ b/test/libc/calls/raise_test.c @@ -20,7 +20,6 @@ #include "libc/calls/struct/sigaction.h" #include "libc/calls/struct/siginfo.h" #include "libc/dce.h" -#include "libc/intrin/kprintf.h" #include "libc/runtime/runtime.h" #include "libc/sysv/consts/sa.h" #include "libc/sysv/consts/sicode.h" diff --git a/test/libc/calls/setrlimit_test.c b/test/libc/calls/setrlimit_test.c index bc40f8542..59ad24782 100644 --- a/test/libc/calls/setrlimit_test.c +++ b/test/libc/calls/setrlimit_test.c @@ -118,10 +118,11 @@ TEST(setrlimit, testFileSizeLimit) { EXPECT_EQ(0, WTERMSIG(wstatus)); } -int SetKernelEnforcedMemoryLimit(size_t n) { - struct rlimit rlim; +int SetMemoryLimit(size_t n) { + struct rlimit rlim = {0}; getrlimit(RLIMIT_AS, &rlim); rlim.rlim_cur = n; + rlim.rlim_max = n; return setrlimit(RLIMIT_AS, &rlim); } @@ -129,27 +130,20 @@ TEST(setrlimit, testMemoryLimit) { char *p; bool gotsome; int i, wstatus; - if (IsXnu()) - return; - if (IsOpenbsd()) - return; // simply too slow until mmap() becomes O(logn) ASSERT_NE(-1, (wstatus = xspawn(0))); if (wstatus == -2) { - ASSERT_EQ(0, SetKernelEnforcedMemoryLimit(MEM)); - for (gotsome = false, i = 0; i < (MEM * 2) / __granularity(); ++i) { - p = mmap(0, __granularity(), PROT_READ | PROT_WRITE, - MAP_ANONYMOUS | MAP_PRIVATE | MAP_POPULATE, -1, 0); + ASSERT_EQ(0, SetMemoryLimit(MEM)); + for (gotsome = false, i = 0; i < (MEM * 2) / getpagesize(); ++i) { + p = mmap(0, getpagesize(), PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); if (p != MAP_FAILED) { gotsome = true; } else { - if (!IsNetbsd()) { - // TODO(jart): what's going on with NetBSD? - ASSERT_TRUE(gotsome); - } + ASSERT_TRUE(gotsome); ASSERT_EQ(ENOMEM, errno); _Exit(0); } - rngset(p, __granularity(), _rand64, -1); + rngset(p, getpagesize(), _rand64, -1); } _Exit(1); } diff --git a/test/libc/intrin/mmap_scalability_test.c b/test/libc/intrin/mmap_scalability_test.c new file mode 100644 index 000000000..26982fbbe --- /dev/null +++ b/test/libc/intrin/mmap_scalability_test.c @@ -0,0 +1,76 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-β”‚ +β”‚ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi β”‚ +β•žβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•‘ +β”‚ Copyright 2024 Justine Alexandra Roberts Tunney β”‚ +β”‚ β”‚ +β”‚ Permission to use, copy, modify, and/or distribute this software for β”‚ +β”‚ any purpose with or without fee is hereby granted, provided that the β”‚ +β”‚ above copyright notice and this permission notice appear in all copies. β”‚ +β”‚ β”‚ +β”‚ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL β”‚ +β”‚ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED β”‚ +β”‚ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE β”‚ +β”‚ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL β”‚ +β”‚ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR β”‚ +β”‚ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER β”‚ +β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ +β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ +β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/calls/calls.h" +#include "libc/calls/struct/timespec.h" +#include "libc/dce.h" +#include "libc/intrin/kprintf.h" +#include "libc/runtime/runtime.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/prot.h" + +#define BENCH(ITERATIONS, WORK_PER_RUN, CODE) \ + do { \ + struct timespec start = timespec_real(); \ + for (int __i = 0; __i < ITERATIONS; ++__i) { \ + asm volatile("" ::: "memory"); \ + CODE; \ + } \ + long long work = (WORK_PER_RUN) * (ITERATIONS); \ + double nanos = \ + (timespec_tonanos(timespec_sub(timespec_real(), start)) + work - 1) / \ + (double)work; \ + kprintf("%'20ld ns %2dx %s\n", (long)nanos, (ITERATIONS), #CODE); \ + } while (0) + +void *randaddr(void) { + static unsigned long lcg = 1; + lcg *= 6364136223846793005; + lcg += 1442695040888963407; + return (void *)(lcg >> 48 << 28); +} + +void map_unmap_one_page(void) { + void *p; + if ((p = mmap(randaddr(), 1, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) == MAP_FAILED) + __builtin_trap(); + if (munmap(p, 1)) + __builtin_trap(); +} + +int main() { + kprintf("\n"); + BENCH(1000, 1, map_unmap_one_page()); + + // macos doesn't scale + if (IsXnu()) + return 0; + + // create lots of sparse mappings to put + // weight on __maps.maps. red-black tree + int n = 10000; + kprintf("%20s creating %d sparse maps...\n", "", n); + for (int i = 0; i < n; ++i) { + if (mmap(randaddr(), 1, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, + -1, 0) == MAP_FAILED) + __builtin_trap(); + } + + BENCH(1000, 1, map_unmap_one_page()); +} diff --git a/test/libc/intrin/mmap_test.c b/test/libc/intrin/mmap_test.c index 44e9216ca..bf9eee74a 100644 --- a/test/libc/intrin/mmap_test.c +++ b/test/libc/intrin/mmap_test.c @@ -461,7 +461,23 @@ void BenchUnmap(void) { __builtin_trap(); } +void BenchBigMmap(void) { + void *p; + p = mmap(0, 101 * 1024 * 1024, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + if (p == MAP_FAILED) + __builtin_trap(); + ptrs[count++] = p; +} + +void BenchBigMunmap(void) { + if (munmap(ptrs[--count], 101 * 1024 * 1024)) + __builtin_trap(); +} + BENCH(mmap, bench) { EZBENCH2("mmap", donothing, BenchMmapPrivate()); EZBENCH2("munmap", donothing, BenchUnmap()); + // EZBENCH2("big mmap", donothing, BenchBigMmap()); + // EZBENCH2("big munmap", donothing, BenchBigMunmap()); } diff --git a/test/libc/intrin/rbtree_test.c b/test/libc/intrin/tree_test.c similarity index 55% rename from test/libc/intrin/rbtree_test.c rename to test/libc/intrin/tree_test.c index 5bcea721c..09a8c807e 100644 --- a/test/libc/intrin/rbtree_test.c +++ b/test/libc/intrin/tree_test.c @@ -13,16 +13,18 @@ // TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. -#include "libc/intrin/rbtree.h" +#include "libc/intrin/tree.h" #include "libc/intrin/kprintf.h" +#include "libc/intrin/maps.h" #include "libc/macros.internal.h" +#include "libc/mem/mem.h" #include "libc/runtime/runtime.h" #include "libc/stdio/rand.h" -#define NUMBER_CONTAINER(e) RBTREE_CONTAINER(struct number, elem, e) +#define NUMBER_CONTAINER(e) TREE_CONTAINER(struct number, elem, e) -void rbtree_checker(const struct rbtree *node, const struct rbtree *parent, - int black_count, int *black_height, rbtree_cmp_f *cmp) { +void tree_checker(const struct Tree *node, const struct Tree *parent, + int black_count, int *black_height, tree_cmp_f *cmp) { if (!node) { // Leaf nodes are considered black if (*black_height == -1) { @@ -37,89 +39,101 @@ void rbtree_checker(const struct rbtree *node, const struct rbtree *parent, // ILLEGAL TREE: Parent link is incorrect __builtin_trap(); if (parent) { - if (rbtree_get_left(parent) == node && cmp(parent, node) < 0) + if (tree_get_left(parent) == node && cmp(parent, node) < 0) // ILLEGAL TREE: Binary search property violated on left child __builtin_trap(); if (parent->right == node && cmp(node, parent) < 0) // ILLEGAL TREE: Binary search property violated on right child __builtin_trap(); } - if (!rbtree_get_red(node)) { + if (!tree_get_red(node)) { black_count++; - } else if (parent && rbtree_get_red(parent)) { + } else if (parent && tree_get_red(parent)) { // ILLEGAL TREE: Red node has red child __builtin_trap(); } - rbtree_checker(rbtree_get_left(node), node, black_count, black_height, cmp); - rbtree_checker(node->right, node, black_count, black_height, cmp); + tree_checker(tree_get_left(node), node, black_count, black_height, cmp); + tree_checker(node->right, node, black_count, black_height, cmp); } -void rbtree_check(struct rbtree *root, rbtree_cmp_f *cmp) { +void tree_check(struct Tree *root, tree_cmp_f *cmp) { if (root) { - if (rbtree_get_red(root)) + if (tree_get_red(root)) // ILLEGAL TREE: root node must be black __builtin_trap(); int black_height = -1; - rbtree_checker(root, 0, 0, &black_height, cmp); + tree_checker(root, 0, 0, &black_height, cmp); } } struct number { - int number; - struct rbtree elem; + long number; + struct Tree elem; }; -int number_compare(const struct rbtree *ra, const struct rbtree *rb) { +int number_search(const void *ra, const struct Tree *rb) { + long a = (long)ra; + const struct number *b = NUMBER_CONTAINER(rb); + return (a > b->number) - (a < b->number); +} + +int number_compare(const struct Tree *ra, const struct Tree *rb) { const struct number *a = NUMBER_CONTAINER(ra); const struct number *b = NUMBER_CONTAINER(rb); return (a->number > b->number) - (a->number < b->number); } struct number *number_new(int number) { - static int used; - static struct number heap[8192]; - if (used == ARRAYLEN(heap)) - return 0; - struct number *res = &heap[used++]; - res->number = number; + struct number *res; + if ((res = malloc(sizeof(struct number)))) + res->number = number; return res; } -struct rbtree *tree = 0; +struct Tree *tree = 0; void print(void) { - for (struct rbtree *e = rbtree_first(tree); e; e = rbtree_next(e)) + for (struct Tree *e = tree_first(tree); e; e = tree_next(e)) kprintf("%3d", NUMBER_CONTAINER(e)->number); kprintf("\n"); } void print_reversed(void) { - for (struct rbtree *e = rbtree_last(tree); e; e = rbtree_prev(e)) + for (struct Tree *e = tree_last(tree); e; e = tree_prev(e)) kprintf("%3d", NUMBER_CONTAINER(e)->number); kprintf("\n"); } void simple_test(void) { - static const int kNumba[] = {74, 53, 96, 70, 34, 95, 30, 2, 89, 46, - 23, 2, 52, 0, 34, 12, 90, 95, 32, 65}; + static const long kNumba[] = {74, 53, 96, 70, 34, 95, 30, 2, 96, 46, + 23, 2, 52, 0, 34, 94, 90, 95, 32, 65}; for (int i = 0; i < 20; ++i) { int number = kNumba[i]; kprintf("%3d", number); - rbtree_insert(&tree, &number_new(number)->elem, number_compare); - rbtree_check(tree, number_compare); + tree_insert(&tree, &number_new(number)->elem, number_compare); + tree_check(tree, number_compare); } kprintf("\n"); print(); print_reversed(); for (int i = 0; i < 20; ++i) { - rbtree_remove(&tree, rbtree_get(tree, &(&(struct number){kNumba[i]})->elem, - number_compare)); - rbtree_check(tree, number_compare); + tree_remove(&tree, tree_get(tree, (void *)kNumba[i], number_search)); + tree_check(tree, number_compare); print(); } } int main() { ShowCrashReports(); + tree_check(__maps.maps, __maps_compare); + kprintf("\n"); + __print_maps(15); + kprintf("\n"); simple_test(); + tree_check(__maps.maps, __maps_compare); + for (int i = 0; i < 100000; ++i) + tree_insert(&tree, &number_new(rand())->elem, number_compare); + tree_check(tree, number_compare); + tree_check(__maps.maps, __maps_compare); + __print_maps(15); } diff --git a/test/libc/thread/pthread_atfork_test.c b/test/libc/thread/pthread_atfork_test.c index dc977b9aa..f1e44139b 100644 --- a/test/libc/thread/pthread_atfork_test.c +++ b/test/libc/thread/pthread_atfork_test.c @@ -16,8 +16,11 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/atomic.h" #include "libc/calls/calls.h" #include "libc/dce.h" +#include "libc/intrin/atomic.h" +#include "libc/intrin/kprintf.h" #include "libc/mem/gc.h" #include "libc/mem/mem.h" #include "libc/runtime/internal.h" @@ -66,7 +69,7 @@ TEST(pthread_atfork, test) { EXITS(0); } -pthread_mutex_t mu; +pthread_mutex_t mu = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; void mu_lock(void) { pthread_mutex_lock(&mu); @@ -80,8 +83,12 @@ void mu_wipe(void) { pthread_mutex_init(&mu, 0); } +static atomic_bool once; + void *Worker(void *arg) { for (int i = 0; i < 20; ++i) { + if (!atomic_exchange(&once, true)) + __print_maps(0); mu_lock(); usleep(20); mu_unlock(); @@ -99,14 +106,14 @@ void *Worker(void *arg) { } TEST(pthread_atfork, fork_exit_torture) { + if (!IsFreebsd()) + return; mu_wipe(); pthread_atfork(mu_lock, mu_unlock, mu_wipe); int i, n = 4; pthread_t *t = gc(malloc(sizeof(pthread_t) * n)); - for (i = 0; i < n; ++i) { + for (i = 0; i < n; ++i) ASSERT_EQ(0, pthread_create(t + i, 0, Worker, 0)); - } - for (i = 0; i < n; ++i) { + for (i = 0; i < n; ++i) ASSERT_EQ(0, pthread_join(t[i], 0)); - } } diff --git a/third_party/nsync/common.c b/third_party/nsync/common.c index 4c77e7d4e..3a20bcdbb 100644 --- a/third_party/nsync/common.c +++ b/third_party/nsync/common.c @@ -18,6 +18,7 @@ #include "libc/calls/calls.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" +#include "libc/intrin/directmap.internal.h" #include "libc/intrin/dll.h" #include "libc/intrin/extend.internal.h" #include "libc/nt/enum/filemapflags.h" @@ -25,21 +26,17 @@ #include "libc/nt/memory.h" #include "libc/nt/runtime.h" #include "libc/runtime/memtrack.internal.h" +#include "libc/runtime/runtime.h" +#include "libc/stdalign.internal.h" +#include "libc/stdalign.internal.h" #include "libc/sysv/consts/map.h" #include "libc/sysv/consts/prot.h" +#include "libc/thread/thread.h" #include "libc/thread/tls.h" #include "third_party/nsync/atomic.h" #include "third_party/nsync/atomic.internal.h" #include "third_party/nsync/common.internal.h" #include "third_party/nsync/mu_semaphore.h" -#include "third_party/nsync/races.internal.h" -#include "libc/runtime/runtime.h" -#include "libc/runtime/runtime.h" -#include "libc/sysv/consts/map.h" -#include "libc/nt/runtime.h" -#include "libc/intrin/directmap.internal.h" -#include "libc/thread/thread.h" -#include "libc/dce.h" #include "third_party/nsync/wait_s.internal.h" __static_yoink("nsync_notice"); @@ -97,33 +94,15 @@ __static_yoink("nsync_notice"); distinct wakeup conditions were high. So clients are advised to resort to condition variables if they have many distinct wakeup conditions. */ -/* Used in spinloops to delay resumption of the loop. - Usage: - unsigned attempts = 0; - while (try_something) { - attempts = nsync_spin_delay_ (attempts); - } */ -unsigned nsync_spin_delay_ (unsigned attempts) { - if (attempts < 7) { - volatile int i; - for (i = 0; i != 1 << attempts; i++) { - } - attempts++; - } else { - nsync_yield_ (); - } - return (attempts); -} - /* Spin until (*w & test) == 0, then atomically perform *w = ((*w | set) & ~clear), perform an acquire barrier, and return the previous value of *w. */ uint32_t nsync_spin_test_and_set_ (nsync_atomic_uint32_ *w, uint32_t test, - uint32_t set, uint32_t clear) { + uint32_t set, uint32_t clear, void *symbol) { unsigned attempts = 0; /* CV_SPINLOCK retry count */ uint32_t old = ATM_LOAD (w); while ((old & test) != 0 || !ATM_CAS_ACQ (w, old, (old | set) & ~clear)) { - attempts = nsync_spin_delay_ (attempts); + attempts = pthread_delay_np (symbol, attempts); old = ATM_LOAD (w); } return (old); @@ -156,33 +135,69 @@ waiter *nsync_dll_waiter_samecond_ (struct Dll *e) { /* -------------------------------- */ -static void *nsync_malloc (size_t size) { - void *res; - if (!IsWindows ()) { - // too much of a performance hit to track - res = __sys_mmap ((void *)0x7110000000, size, - PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, - -1, 0, 0); +static _Atomic(waiter *) free_waiters; + +static void free_waiters_push (waiter *w) { + int backoff = 0; + w->next_free = atomic_load_explicit (&free_waiters, memory_order_relaxed); + while (!atomic_compare_exchange_weak_explicit (&free_waiters, &w->next_free, w, + memory_order_acq_rel, memory_order_relaxed)) + backoff = pthread_delay_np(free_waiters, backoff); +} + +static void free_waiters_populate (void) { + int n; + if (IsNetbsd () || IsXnuSilicon ()) { + // netbsd needs one file descriptor per semaphore (!!) + // tim cook wants us to use his grand central dispatch + n = 1; } else { - // must be tracked for fork() resurrection - res = mmap (0, size, - PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, - -1, 0); + n = getpagesize() / sizeof(waiter); } - if (res == MAP_FAILED) + waiter *waiters = mmap (0, n * sizeof(waiter), + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, + -1, 0); + if (waiters == MAP_FAILED) nsync_panic_ ("out of memory\n"); - return res; + for (size_t i = 0; i < n; ++i) { + waiter *w = &waiters[i]; + w->tag = WAITER_TAG; + w->nw.tag = NSYNC_WAITER_TAG; + if (!nsync_mu_semaphore_init (&w->sem)) { + if (!i) + nsync_panic_ ("out of semaphores\n"); + break; + } + w->nw.sem = &w->sem; + dll_init (&w->nw.q); + NSYNC_ATOMIC_UINT32_STORE_ (&w->nw.waiting, 0); + w->nw.flags = NSYNC_WAITER_FLAG_MUCV; + ATM_STORE (&w->remove_count, 0); + dll_init (&w->same_condition); + w->flags = 0; + free_waiters_push (w); + } +} + +static waiter *free_waiters_pop (void) { + waiter *w; + int backoff = 0; + for (;;) { + if ((w = atomic_load_explicit (&free_waiters, memory_order_relaxed))) { + if (atomic_compare_exchange_weak_explicit (&free_waiters, &w, w->next_free, + memory_order_acq_rel, memory_order_relaxed)) + return w; + backoff = pthread_delay_np(free_waiters, backoff); + } else { + free_waiters_populate (); + } + } + return w; } /* -------------------------------- */ -static struct Dll *free_waiters = NULL; - -/* free_waiters points to a doubly-linked list of free waiter structs. */ -pthread_mutex_t nsync_waiters_mu = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; - #define waiter_for_thread __get_tls()->tib_nsync void nsync_waiter_destroy (void *v) { @@ -193,45 +208,20 @@ void nsync_waiter_destroy (void *v) { of thread-local variables can be arbitrary in some platform e.g. POSIX. */ waiter_for_thread = NULL; - IGNORE_RACES_START (); ASSERT ((w->flags & (WAITER_RESERVED|WAITER_IN_USE)) == WAITER_RESERVED); w->flags &= ~WAITER_RESERVED; - pthread_mutex_lock (&nsync_waiters_mu); - dll_make_first (&free_waiters, &w->nw.q); - pthread_mutex_unlock (&nsync_waiters_mu); - IGNORE_RACES_END (); + free_waiters_push (w); } /* Return a pointer to an unused waiter struct. Ensures that the enclosed timer is stopped and its channel drained. */ waiter *nsync_waiter_new_ (void) { - struct Dll *q; - waiter *tw; waiter *w; + waiter *tw; tw = waiter_for_thread; w = tw; if (w == NULL || (w->flags & (WAITER_RESERVED|WAITER_IN_USE)) != WAITER_RESERVED) { - w = NULL; - pthread_mutex_lock (&nsync_waiters_mu); - q = dll_first (free_waiters); - if (q != NULL) { /* If free list is non-empty, dequeue an item. */ - dll_remove (&free_waiters, q); - w = DLL_WAITER (q); - } - pthread_mutex_unlock (&nsync_waiters_mu); - if (w == NULL) { /* If free list was empty, allocate an item. */ - w = (waiter *) nsync_malloc (sizeof (*w)); - w->tag = WAITER_TAG; - w->nw.tag = NSYNC_WAITER_TAG; - nsync_mu_semaphore_init (&w->sem); - w->nw.sem = &w->sem; - dll_init (&w->nw.q); - NSYNC_ATOMIC_UINT32_STORE_ (&w->nw.waiting, 0); - w->nw.flags = NSYNC_WAITER_FLAG_MUCV; - ATM_STORE (&w->remove_count, 0); - dll_init (&w->same_condition); - w->flags = 0; - } + w = free_waiters_pop (); if (tw == NULL) { w->flags |= WAITER_RESERVED; waiter_for_thread = w; @@ -246,9 +236,7 @@ void nsync_waiter_free_ (waiter *w) { ASSERT ((w->flags & WAITER_IN_USE) != 0); w->flags &= ~WAITER_IN_USE; if ((w->flags & WAITER_RESERVED) == 0) { - pthread_mutex_lock (&nsync_waiters_mu); - dll_make_first (&free_waiters, &w->nw.q); - pthread_mutex_unlock (&nsync_waiters_mu); + free_waiters_push (w); if (w == waiter_for_thread) waiter_for_thread = 0; } diff --git a/third_party/nsync/common.internal.h b/third_party/nsync/common.internal.h index 90205e102..a0b2c0ffe 100644 --- a/third_party/nsync/common.internal.h +++ b/third_party/nsync/common.internal.h @@ -24,19 +24,11 @@ void nsync_yield_(void); /* Retrieve the per-thread cache of the waiter object. Platform specific. */ void *nsync_per_thread_waiter_(void (*dest)(void *)); -/* Used in spinloops to delay resumption of the loop. - Usage: - unsigned attempts = 0; - while (try_something) { - attempts = nsync_spin_delay_ (attempts); - } */ -unsigned nsync_spin_delay_(unsigned attempts); - /* Spin until (*w & test) == 0, then atomically perform *w = ((*w | set) & ~clear), perform an acquire barrier, and return the previous value of *w. */ uint32_t nsync_spin_test_and_set_(nsync_atomic_uint32_ *w, uint32_t test, - uint32_t set, uint32_t clear); + uint32_t set, uint32_t clear, void *symbol); /* Abort after printing the nul-temrinated string s[]. */ void nsync_panic_(const char *s) wontreturn; @@ -210,6 +202,7 @@ typedef struct waiter_s { struct wait_condition_s cond; /* A condition on which to acquire a mu. */ struct Dll same_condition; /* Links neighbours in nw.q with same non-nil condition. */ + struct waiter_s * next_free; } waiter; static const uint32_t WAITER_TAG = 0x0590239f; static const uint32_t NSYNC_WAITER_TAG = 0x726d2ba9; diff --git a/third_party/nsync/mem/nsync_cv.c b/third_party/nsync/mem/nsync_cv.c index 926379340..8e363f77c 100644 --- a/third_party/nsync/mem/nsync_cv.c +++ b/third_party/nsync/mem/nsync_cv.c @@ -193,7 +193,7 @@ static int nsync_cv_wait_with_deadline_impl_ (struct nsync_cv_wait_with_deadline /* A timeout or cancellation occurred, and no wakeup. Acquire *pcv's spinlock, and confirm. */ c->old_word = nsync_spin_test_and_set_ (&c->pcv->word, CV_SPINLOCK, - CV_SPINLOCK, 0); + CV_SPINLOCK, 0, c->cv_mu); /* Check that w wasn't removed from the queue after we checked above, but before we acquired the spinlock. The test of remove_count confirms that the waiter *w @@ -226,7 +226,7 @@ static int nsync_cv_wait_with_deadline_impl_ (struct nsync_cv_wait_with_deadline has not yet set the waiting field to zero; a cancellation or timeout may prevent this thread from blocking above on the semaphore. */ - attempts = nsync_spin_delay_ (attempts); + attempts = pthread_delay_np (c->cv_mu, attempts); } } if (c->cv_mu != NULL && c->w->cv_mu == NULL) { /* waiter was moved to *pmu's queue, and woken. */ @@ -323,7 +323,7 @@ int nsync_cv_wait_with_deadline_generic (nsync_cv *pcv, void *pmu, } /* acquire spinlock, set non-empty */ - c.old_word = nsync_spin_test_and_set_ (&pcv->word, CV_SPINLOCK, CV_SPINLOCK|CV_NON_EMPTY, 0); + c.old_word = nsync_spin_test_and_set_ (&pcv->word, CV_SPINLOCK, CV_SPINLOCK|CV_NON_EMPTY, 0, pmu); dll_make_last (&pcv->waiters, &c.w->nw.q); c.remove_count = ATM_LOAD (&c.w->remove_count); /* Release the spin lock. */ @@ -355,7 +355,7 @@ void nsync_cv_signal (nsync_cv *pcv) { int all_readers = 0; /* acquire spinlock */ uint32_t old_word = nsync_spin_test_and_set_ (&pcv->word, CV_SPINLOCK, - CV_SPINLOCK, 0); + CV_SPINLOCK, 0, pcv); if (!dll_is_empty (pcv->waiters)) { /* Point to first waiter that enqueued itself, and detach it from all others. */ @@ -438,7 +438,7 @@ void nsync_cv_broadcast (nsync_cv *pcv) { int all_readers; struct Dll *to_wake_list = NULL; /* waiters that we will wake */ /* acquire spinlock */ - nsync_spin_test_and_set_ (&pcv->word, CV_SPINLOCK, CV_SPINLOCK, 0); + nsync_spin_test_and_set_ (&pcv->word, CV_SPINLOCK, CV_SPINLOCK, 0, pcv); p = NULL; next = NULL; all_readers = 1; @@ -497,7 +497,7 @@ static nsync_time cv_ready_time (void *v, struct nsync_waiter_s *nw) { static int cv_enqueue (void *v, struct nsync_waiter_s *nw) { nsync_cv *pcv = (nsync_cv *) v; /* acquire spinlock */ - uint32_t old_word = nsync_spin_test_and_set_ (&pcv->word, CV_SPINLOCK, CV_SPINLOCK, 0); + uint32_t old_word = nsync_spin_test_and_set_ (&pcv->word, CV_SPINLOCK, CV_SPINLOCK, 0, pcv); dll_make_last (&pcv->waiters, &nw->q); ATM_STORE (&nw->waiting, 1); /* Release spinlock. */ @@ -509,7 +509,7 @@ static int cv_dequeue (void *v, struct nsync_waiter_s *nw) { nsync_cv *pcv = (nsync_cv *) v; int was_queued = 0; /* acquire spinlock */ - uint32_t old_word = nsync_spin_test_and_set_ (&pcv->word, CV_SPINLOCK, CV_SPINLOCK, 0); + uint32_t old_word = nsync_spin_test_and_set_ (&pcv->word, CV_SPINLOCK, CV_SPINLOCK, 0, pcv); if (ATM_LOAD_ACQ (&nw->waiting) != 0) { dll_remove (&pcv->waiters, &nw->q); ATM_STORE (&nw->waiting, 0); diff --git a/third_party/nsync/mem/nsync_debug.c b/third_party/nsync/mem/nsync_debug.c index 1b72c1175..a3d847286 100644 --- a/third_party/nsync/mem/nsync_debug.c +++ b/third_party/nsync/mem/nsync_debug.c @@ -197,7 +197,7 @@ static char *emit_mu_state (struct emit_buf *b, nsync_mu *mu, word = ATM_LOAD (&mu->word); if ((word & MU_WAITING) != 0 && print_waiters && /* can benefit from lock */ (blocking || (word & MU_SPINLOCK) == 0)) { /* willing, or no need to wait */ - word = nsync_spin_test_and_set_ (&mu->word, MU_SPINLOCK, MU_SPINLOCK, 0); + word = nsync_spin_test_and_set_ (&mu->word, MU_SPINLOCK, MU_SPINLOCK, 0, mu); acquired = 1; } readers = word / MU_RLOCK; @@ -234,7 +234,7 @@ static char *emit_cv_state (struct emit_buf *b, nsync_cv *cv, word = ATM_LOAD (&cv->word); if ((word & CV_NON_EMPTY) != 0 && print_waiters && /* can benefit from lock */ (blocking || (word & CV_SPINLOCK) == 0)) { /* willing, or no need to wait */ - word = nsync_spin_test_and_set_ (&cv->word, CV_SPINLOCK, CV_SPINLOCK, 0); + word = nsync_spin_test_and_set_ (&cv->word, CV_SPINLOCK, CV_SPINLOCK, 0, cv); acquired = 1; } emit_print (b, "cv 0x%i -> 0x%i = {", (uintptr_t) cv, word); diff --git a/third_party/nsync/mem/nsync_mu_wait.c b/third_party/nsync/mem/nsync_mu_wait.c index 3c48ea599..e46492aa9 100644 --- a/third_party/nsync/mem/nsync_mu_wait.c +++ b/third_party/nsync/mem/nsync_mu_wait.c @@ -21,6 +21,7 @@ #include "third_party/nsync/common.internal.h" #include "third_party/nsync/mu_semaphore.h" #include "third_party/nsync/races.internal.h" +#include "libc/thread/thread.h" #include "third_party/nsync/wait_s.internal.h" __static_yoink("nsync_notice"); @@ -84,7 +85,7 @@ static int mu_try_acquire_after_timeout_or_cancel (nsync_mu *mu, lock_type *l_ty ATM_CAS_RELACQ (&mu->word, old_word, old_word|MU_WRITER_WAITING); } - spin_attempts = nsync_spin_delay_ (spin_attempts); + spin_attempts = pthread_delay_np (mu, spin_attempts); old_word = ATM_LOAD (&mu->word); } /* Check that w wasn't removed from the queue after our caller checked, @@ -194,7 +195,7 @@ int nsync_mu_wait_with_deadline (nsync_mu *mu, /* Acquire spinlock. */ old_word = nsync_spin_test_and_set_ (&mu->word, MU_SPINLOCK, - MU_SPINLOCK|MU_WAITING|has_condition, MU_ALL_FALSE); + MU_SPINLOCK|MU_WAITING|has_condition, MU_ALL_FALSE, mu); had_waiters = ((old_word & (MU_DESIG_WAKER | MU_WAITING)) == MU_WAITING); /* Queue the waiter. */ if (first_wait) { @@ -244,7 +245,7 @@ int nsync_mu_wait_with_deadline (nsync_mu *mu, } if (ATM_LOAD (&w->nw.waiting) != 0) { - attempts = nsync_spin_delay_ (attempts); /* will ultimately yield */ + attempts = pthread_delay_np (mu, attempts); /* will ultimately yield */ } } diff --git a/third_party/nsync/mem/nsync_once.c b/third_party/nsync/mem/nsync_once.c index 163923359..873766b99 100644 --- a/third_party/nsync/mem/nsync_once.c +++ b/third_party/nsync/mem/nsync_once.c @@ -21,6 +21,7 @@ #include "third_party/nsync/mu_semaphore.h" #include "third_party/nsync/once.h" #include "third_party/nsync/races.internal.h" +#include "libc/thread/thread.h" #include "third_party/nsync/wait_s.internal.h" __static_yoink("nsync_notice"); @@ -92,7 +93,7 @@ static void nsync_run_once_impl (nsync_once *once, struct once_sync_s *s, deadline = nsync_time_add (nsync_time_now (), nsync_time_ms (attempts)); nsync_cv_wait_with_deadline (&s->once_cv, &s->once_mu, deadline, NULL); } else { - attempts = nsync_spin_delay_ (attempts); + attempts = pthread_delay_np (once, attempts); } } if (s != NULL) { diff --git a/third_party/nsync/mu.c b/third_party/nsync/mu.c index 4cae68328..20eac1e68 100644 --- a/third_party/nsync/mu.c +++ b/third_party/nsync/mu.c @@ -22,6 +22,7 @@ #include "third_party/nsync/common.internal.h" #include "third_party/nsync/mu_semaphore.h" #include "third_party/nsync/races.internal.h" +#include "libc/thread/thread.h" #include "third_party/nsync/wait_s.internal.h" __static_yoink("nsync_notice"); @@ -120,7 +121,7 @@ void nsync_mu_lock_slow_ (nsync_mu *mu, waiter *w, uint32_t clear, lock_type *l_ about waiting writers or long waiters. */ zero_to_acquire &= ~(MU_WRITER_WAITING | MU_LONG_WAIT); } - attempts = nsync_spin_delay_ (attempts); + attempts = pthread_delay_np (mu, attempts); } ALLOW_CANCELATION; } @@ -393,7 +394,7 @@ void nsync_mu_unlock_slow_ (nsync_mu *mu, lock_type *l_type) { released above. */ if (testing_conditions) { nsync_spin_test_and_set_ (&mu->word, MU_SPINLOCK, - MU_SPINLOCK, 0); + MU_SPINLOCK, 0, mu); } /* add the new_waiters to the last of the waiters. */ @@ -444,7 +445,7 @@ void nsync_mu_unlock_slow_ (nsync_mu *mu, lock_type *l_type) { } return; } - attempts = nsync_spin_delay_ (attempts); + attempts = pthread_delay_np (mu, attempts); } } diff --git a/third_party/nsync/mu_semaphore.c b/third_party/nsync/mu_semaphore.c index 493efa2c4..fd9d855ce 100644 --- a/third_party/nsync/mu_semaphore.c +++ b/third_party/nsync/mu_semaphore.c @@ -27,7 +27,7 @@ __static_yoink("nsync_notice"); #define PREFER_GCD_OVER_ULOCK 1 /* Initialize *s; the initial value is 0. */ -void nsync_mu_semaphore_init (nsync_semaphore *s) { +bool nsync_mu_semaphore_init (nsync_semaphore *s) { if (PREFER_GCD_OVER_ULOCK && IsXnuSilicon ()) { return nsync_mu_semaphore_init_gcd (s); } else if (IsNetbsd ()) { diff --git a/third_party/nsync/mu_semaphore.h b/third_party/nsync/mu_semaphore.h index 64c7d563d..992d4849f 100644 --- a/third_party/nsync/mu_semaphore.h +++ b/third_party/nsync/mu_semaphore.h @@ -8,7 +8,7 @@ typedef struct nsync_semaphore_s_ { } nsync_semaphore; /* Initialize *s; the initial value is 0. */ -void nsync_mu_semaphore_init(nsync_semaphore *s); +bool nsync_mu_semaphore_init(nsync_semaphore *s); /* Wait until the count of *s exceeds 0, and decrement it. */ errno_t nsync_mu_semaphore_p(nsync_semaphore *s); diff --git a/third_party/nsync/mu_semaphore.internal.h b/third_party/nsync/mu_semaphore.internal.h index ce3181fc3..31b51975d 100755 --- a/third_party/nsync/mu_semaphore.internal.h +++ b/third_party/nsync/mu_semaphore.internal.h @@ -4,17 +4,17 @@ #include "third_party/nsync/time.h" COSMOPOLITAN_C_START_ -void nsync_mu_semaphore_init_futex(nsync_semaphore *); +bool nsync_mu_semaphore_init_futex(nsync_semaphore *); errno_t nsync_mu_semaphore_p_futex(nsync_semaphore *); errno_t nsync_mu_semaphore_p_with_deadline_futex(nsync_semaphore *, nsync_time); void nsync_mu_semaphore_v_futex(nsync_semaphore *); -void nsync_mu_semaphore_init_sem(nsync_semaphore *); +bool nsync_mu_semaphore_init_sem(nsync_semaphore *); errno_t nsync_mu_semaphore_p_sem(nsync_semaphore *); errno_t nsync_mu_semaphore_p_with_deadline_sem(nsync_semaphore *, nsync_time); void nsync_mu_semaphore_v_sem(nsync_semaphore *); -void nsync_mu_semaphore_init_gcd(nsync_semaphore *); +bool nsync_mu_semaphore_init_gcd(nsync_semaphore *); errno_t nsync_mu_semaphore_p_gcd(nsync_semaphore *); errno_t nsync_mu_semaphore_p_with_deadline_gcd(nsync_semaphore *, nsync_time); void nsync_mu_semaphore_v_gcd(nsync_semaphore *); diff --git a/third_party/nsync/mu_semaphore_futex.c b/third_party/nsync/mu_semaphore_futex.c index 14d0ec20e..12964e7c8 100644 --- a/third_party/nsync/mu_semaphore_futex.c +++ b/third_party/nsync/mu_semaphore_futex.c @@ -43,9 +43,10 @@ static nsync_semaphore *sem_big_enough_for_futex = (nsync_semaphore *) (uintptr_ (sizeof (struct futex) <= sizeof (*sem_big_enough_for_futex))); /* Initialize *s; the initial value is 0. */ -void nsync_mu_semaphore_init_futex (nsync_semaphore *s) { +bool nsync_mu_semaphore_init_futex (nsync_semaphore *s) { struct futex *f = (struct futex *) s; f->i = 0; + return true; } /* Wait until the count of *s exceeds 0, and decrement it. If POSIX cancellations diff --git a/third_party/nsync/mu_semaphore_gcd.c b/third_party/nsync/mu_semaphore_gcd.c index fd36135de..1f88d5e0d 100644 --- a/third_party/nsync/mu_semaphore_gcd.c +++ b/third_party/nsync/mu_semaphore_gcd.c @@ -85,8 +85,8 @@ static errno_t nsync_dispatch_semaphore_wait (nsync_semaphore *s, } /* Initialize *s; the initial value is 0. */ -void nsync_mu_semaphore_init_gcd (nsync_semaphore *s) { - *(dispatch_semaphore_t *)s = dispatch_semaphore_create (0); +bool nsync_mu_semaphore_init_gcd (nsync_semaphore *s) { + return !!(*(dispatch_semaphore_t *)s = dispatch_semaphore_create (0)); } /* Wait until the count of *s exceeds 0, and decrement it. If POSIX cancellations diff --git a/third_party/nsync/mu_semaphore_sem.c b/third_party/nsync/mu_semaphore_sem.c index d2c6377ac..3eb8a22f6 100644 --- a/third_party/nsync/mu_semaphore_sem.c +++ b/third_party/nsync/mu_semaphore_sem.c @@ -54,14 +54,22 @@ static struct { static nsync_semaphore *sem_big_enough_for_sem = (nsync_semaphore *) (uintptr_t)(1 / (sizeof (struct sem) <= sizeof (*sem_big_enough_for_sem))); -static void nsync_mu_semaphore_sem_create (struct sem *f) { +static bool nsync_mu_semaphore_sem_create (struct sem *f) { + int rc; int lol; f->id = 0; - ASSERT (!sys_sem_init (0, &f->id)); - if ((lol = __sys_fcntl (f->id, F_DUPFD_CLOEXEC, 50)) >= 50) { - sys_close (f->id); + rc = sys_sem_init (0, &f->id); + STRACE ("sem_init(0, [%ld]) β†’ %d", f->id, rc); + if (rc != 0) + return false; + lol = __sys_fcntl (f->id, F_DUPFD_CLOEXEC, 50); + STRACE ("fcntl(%ld, F_DUPFD_CLOEXEC, 50) β†’ %d", f->id, lol); + if (lol >= 50) { + rc = sys_close (f->id); + STRACE ("close(%ld) β†’ %d", f->id, rc); f->id = lol; } + return true; } static void nsync_mu_semaphore_sem_fork_child (void) { @@ -69,8 +77,12 @@ static void nsync_mu_semaphore_sem_fork_child (void) { struct sem *f; for (e = dll_first (g_sems.list); e; e = dll_next (g_sems.list, e)) { f = SEM_CONTAINER (e); - sys_close (f->id); - nsync_mu_semaphore_sem_create (f); + int rc = sys_close (f->id); + STRACE ("close(%ld) β†’ %d", f->id, rc); + } + for (e = dll_first (g_sems.list); e; e = dll_next (g_sems.list, e)) { + f = SEM_CONTAINER (e); + ASSERT (nsync_mu_semaphore_sem_create (f)); } (void) pthread_spin_init (&g_sems.lock, 0); } @@ -80,15 +92,16 @@ static void nsync_mu_semaphore_sem_init (void) { } /* Initialize *s; the initial value is 0. */ -void nsync_mu_semaphore_init_sem (nsync_semaphore *s) { +bool nsync_mu_semaphore_init_sem (nsync_semaphore *s) { struct sem *f = (struct sem *) s; - nsync_mu_semaphore_sem_create (f); + if (!nsync_mu_semaphore_sem_create (f)) + return false; cosmo_once (&g_sems.once, nsync_mu_semaphore_sem_init); pthread_spin_lock (&g_sems.lock); dll_init (&f->list); dll_make_first (&g_sems.list, &f->list); pthread_spin_unlock (&g_sems.lock); - STRACE ("sem_init(0, [%ld]) β†’ 0", f->id); + return true; } /* Wait until the count of *s exceeds 0, and decrement it. If POSIX cancellations diff --git a/tool/build/runitd.c b/tool/build/runitd.c index d1b0f375f..577876772 100644 --- a/tool/build/runitd.c +++ b/tool/build/runitd.c @@ -134,12 +134,12 @@ #define INFOF(FMT, ...) LOGF(INFO, FMT, ##__VA_ARGS__) #define WARNF(FMT, ...) LOGF(WARN, FMT, ##__VA_ARGS__) -#define LOGF(LVL, FMT, ...) \ - do { \ - if (g_log_level >= LOG_LEVEL_##LVL) { \ - kprintf("%r" #LVL " %6P %'18T %s:%d " FMT "\n", __FILE__, __LINE__, \ - ##__VA_ARGS__); \ - } \ +#define LOGF(LVL, FMT, ...) \ + do { \ + if (g_log_level >= LOG_LEVEL_##LVL) { \ + kprintf("%r" #LVL " %6P %6H %'18T %s:%d " FMT "\n", __FILE__, __LINE__, \ + ##__VA_ARGS__); \ + } \ } while (0) struct Client { @@ -443,12 +443,18 @@ void FreeClient(struct Client *client) { void *ClientWorker(void *arg) { uint32_t crc; sigset_t sigmask; + struct timespec ts0; + struct timespec ts1; + struct timespec ts2; int events, wstatus; struct Client *client = arg; uint32_t namesize, filesize; char *addrstr, *origname; unsigned char msg[4 + 1 + 4 + 4 + 4]; + ts0 = timespec_real(); + ts1 = timespec_real(); + SetupPresharedKeySsl(MBEDTLS_SSL_IS_SERVER, g_psk); defer(FreeClient, client); @@ -458,9 +464,15 @@ void *ClientWorker(void *arg) { EzHandshake(); addrstr = DescribeAddress(&client->addr); DEBUF("%s %s %s", DescribeAddress(&g_servaddr), "accepted", addrstr); + DEBUF("it took %'zu us to handshake client", + timespec_tomicros(timespec_sub(timespec_real(), ts1))); // get the executable + ts1 = timespec_real(); + ts2 = timespec_real(); Recv(client, msg, sizeof(msg)); + DEBUF("it took %'zu us to receive #1", + timespec_tomicros(timespec_sub(timespec_real(), ts2))); if (READ32BE(msg) != RUNITD_MAGIC) { WARNF("%s magic mismatch!", addrstr); pthread_exit(0); @@ -473,11 +485,19 @@ void *ClientWorker(void *arg) { filesize = READ32BE(msg + 9); crc = READ32BE(msg + 13); origname = gc(calloc(1, namesize + 1)); + ts2 = timespec_real(); Recv(client, origname, namesize); + DEBUF("it took %'zu us to receive #2", + timespec_tomicros(timespec_sub(timespec_real(), ts2))); VERBF("%s sent %#s (%'u bytes @ %#s)", addrstr, origname, filesize, client->tmpexepath); char *exedata = gc(malloc(filesize)); + ts2 = timespec_real(); Recv(client, exedata, filesize); + DEBUF("it took %'zu us to receive #3", + timespec_tomicros(timespec_sub(timespec_real(), ts2))); + DEBUF("it took %'zu us to receive executable from network", + timespec_tomicros(timespec_sub(timespec_real(), ts1))); if (crc32_z(0, exedata, filesize) != crc) { WARNF("%s crc mismatch! %#s", addrstr, origname); pthread_exit(0); @@ -488,6 +508,7 @@ void *ClientWorker(void *arg) { // condition can happen, where etxtbsy is raised by our execve // we're using o_cloexec so it's guaranteed to fix itself fast // thus we use an optimistic approach to avoid expensive locks + ts1 = timespec_real(); sprintf(client->tmpexepath, "o/%s.XXXXXX", basename(stripext(gc(strdup(origname))))); int exefd = openatemp(AT_FDCWD, client->tmpexepath, 0, O_CLOEXEC, 0700); @@ -510,6 +531,8 @@ void *ClientWorker(void *arg) { WARNF("%s failed to close %#s due to %m", addrstr, origname); pthread_exit(0); } + DEBUF("it took %'zu us to write executable to disk", + timespec_tomicros(timespec_sub(timespec_real(), ts1))); // do the args int i = 0; @@ -560,8 +583,11 @@ RetryOnEtxtbsyRaceCondition: posix_spawn_file_actions_adddup2(&spawnfila, g_bogusfd, 0); posix_spawn_file_actions_adddup2(&spawnfila, client->pipe[1], 1); posix_spawn_file_actions_adddup2(&spawnfila, client->pipe[1], 2); + ts1 = timespec_real(); err = posix_spawn(&client->pid, client->tmpexepath, &spawnfila, &spawnattr, args, environ); + DEBUF("it took %'zu us to call posix_spawn", + timespec_tomicros(timespec_sub(timespec_real(), ts1))); if (err) { if (err == ETXTBSY) { goto RetryOnEtxtbsyRaceCondition; @@ -599,8 +625,11 @@ RetryOnEtxtbsyRaceCondition: fds[0].events = POLLIN; fds[1].fd = client->pipe[0]; fds[1].events = POLLIN; + ts1 = timespec_real(); events = poll(fds, ARRAYLEN(fds), timespec_tomillis(timespec_sub(deadline, now))); + DEBUF("it took %'zu us to call poll", + timespec_tomicros(timespec_sub(timespec_real(), ts1))); if (events == -1) { if (errno == EINTR) { INFOF("poll interrupted"); @@ -615,7 +644,10 @@ RetryOnEtxtbsyRaceCondition: if (fds[0].revents) { int received; char buf[512]; + ts1 = timespec_real(); received = mbedtls_ssl_read(&ezssl, buf, sizeof(buf)); + DEBUF("it took %'zu us to call mbedtls_ssl_read", + timespec_tomicros(timespec_sub(timespec_real(), ts1))); if (!received) { WARNF("%s client disconnected so killing worker %d", origname, client->pid); @@ -640,7 +672,10 @@ RetryOnEtxtbsyRaceCondition: } if (fds[1].revents) { char buf[512]; + ts1 = timespec_real(); ssize_t got = read(client->pipe[0], buf, sizeof(buf)); + DEBUF("it took %'zu us to call read", + timespec_tomicros(timespec_sub(timespec_real(), ts1))); if (got == -1) { WARNF("got %s reading %s output", strerror(errno), origname); goto HangupClientAndTerminateJob; @@ -658,7 +693,10 @@ RetryOnEtxtbsyRaceCondition: WaitAgain: DEBUF("waitpid"); struct rusage rusage; + ts1 = timespec_real(); int wrc = wait4(client->pid, &wstatus, 0, &rusage); + DEBUF("it took %'zu us to call wait4", + timespec_tomicros(timespec_sub(timespec_real(), ts1))); if (wrc == -1) { if (errno == EINTR) { WARNF("waitpid interrupted; killing %s pid %d", origname, client->pid); @@ -711,13 +749,18 @@ WaitAgain: AppendResourceReport(&client->output, &rusage, "\n"); PrintProgramOutput(client); } + ts1 = timespec_real(); SendProgramOutput(client); SendExitMessage(exitcode); mbedtls_ssl_close_notify(&ezssl); + DEBUF("it took %'zu us to send result to client", + timespec_tomicros(timespec_sub(timespec_real(), ts1))); if (etxtbsy_tries > 1) { WARNF("encountered %d ETXTBSY race conditions spawning %s", etxtbsy_tries - 1, origname); } + DEBUF("it took %'zu us TO DO EVERYTHING", + timespec_tomicros(timespec_sub(timespec_real(), ts0))); pthread_exit(0); } From 6be030cd7c58a94138f413b00c5c2d4ac952e310 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sat, 6 Jul 2024 01:39:15 -0700 Subject: [PATCH 036/405] Fix MODE=tinylinux build --- .../pthread_atfork_actual.c} | 0 libc/proc/fork.c | 2 + libc/stdio/fflush_unlocked.c | 47 ------------------- libc/stdio/flockfile.c | 38 +++++++++++++++ libc/stdio/stderr.c | 22 ++++----- libc/stdio/stdin.c | 21 ++++----- libc/stdio/stdout.c | 41 +++++++--------- test/libc/thread/pthread_atfork_test.c | 4 -- 8 files changed, 77 insertions(+), 98 deletions(-) rename libc/{thread/pthread_atfork.c => intrin/pthread_atfork_actual.c} (100%) diff --git a/libc/thread/pthread_atfork.c b/libc/intrin/pthread_atfork_actual.c similarity index 100% rename from libc/thread/pthread_atfork.c rename to libc/intrin/pthread_atfork_actual.c diff --git a/libc/proc/fork.c b/libc/proc/fork.c index 3a48db798..f1f138231 100644 --- a/libc/proc/fork.c +++ b/libc/proc/fork.c @@ -46,6 +46,8 @@ #include "libc/thread/posixthread.internal.h" #include "libc/thread/tls.h" +__static_yoink("_pthread_atfork"); + extern pthread_mutex_t _pthread_lock_obj; static void _onfork_prepare(void) { diff --git a/libc/stdio/fflush_unlocked.c b/libc/stdio/fflush_unlocked.c index dac00a5e4..579bc3676 100644 --- a/libc/stdio/fflush_unlocked.c +++ b/libc/stdio/fflush_unlocked.c @@ -16,58 +16,11 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/calls/calls.h" #include "libc/cxxabi.h" -#include "libc/errno.h" #include "libc/intrin/pushpop.internal.h" -#include "libc/macros.internal.h" #include "libc/mem/arraylist.internal.h" -#include "libc/mem/mem.h" -#include "libc/runtime/runtime.h" #include "libc/stdio/fflush.internal.h" #include "libc/stdio/internal.h" -#include "libc/stdio/stdio.h" -#include "libc/sysv/consts/o.h" -#include "libc/thread/thread.h" - -void(__fflush_lock)(void) { - pthread_mutex_lock(&__fflush_lock_obj); -} - -void(__fflush_unlock)(void) { - pthread_mutex_unlock(&__fflush_lock_obj); -} - -static void __stdio_fork_prepare(void) { - FILE *f; - __fflush_lock(); - for (int i = 0; i < __fflush.handles.i; ++i) - if ((f = __fflush.handles.p[i])) - pthread_mutex_lock(&f->lock); -} - -static void __stdio_fork_parent(void) { - FILE *f; - for (int i = __fflush.handles.i; i--;) - if ((f = __fflush.handles.p[i])) - pthread_mutex_unlock(&f->lock); - __fflush_unlock(); -} - -static void __stdio_fork_child(void) { - FILE *f; - for (int i = __fflush.handles.i; i--;) { - if ((f = __fflush.handles.p[i])) { - bzero(&f->lock, sizeof(f->lock)); - f->lock._word = PTHREAD_MUTEX_RECURSIVE; - } - } - pthread_mutex_init(&__fflush_lock_obj, 0); -} - -__attribute__((__constructor__(60))) static textstartup void stdioinit(void) { - pthread_atfork(__stdio_fork_prepare, __stdio_fork_parent, __stdio_fork_child); -} /** * Blocks until data from stream buffer is written out. diff --git a/libc/stdio/flockfile.c b/libc/stdio/flockfile.c index 556f86b63..2c381295f 100644 --- a/libc/stdio/flockfile.c +++ b/libc/stdio/flockfile.c @@ -16,8 +16,10 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/stdio/fflush.internal.h" #include "libc/stdio/internal.h" #include "libc/stdio/stdio.h" +#include "libc/str/str.h" #include "libc/thread/thread.h" /** @@ -26,3 +28,39 @@ void flockfile(FILE *f) { pthread_mutex_lock(&f->lock); } + +void(__fflush_lock)(void) { + pthread_mutex_lock(&__fflush_lock_obj); +} + +void(__fflush_unlock)(void) { + pthread_mutex_unlock(&__fflush_lock_obj); +} + +static void __stdio_fork_prepare(void) { + FILE *f; + __fflush_lock(); + for (int i = 0; i < __fflush.handles.i; ++i) + if ((f = __fflush.handles.p[i])) + pthread_mutex_lock(&f->lock); +} + +static void __stdio_fork_parent(void) { + FILE *f; + for (int i = __fflush.handles.i; i--;) + if ((f = __fflush.handles.p[i])) + pthread_mutex_unlock(&f->lock); + __fflush_unlock(); +} + +static void __stdio_fork_child(void) { + FILE *f; + for (int i = __fflush.handles.i; i--;) + if ((f = __fflush.handles.p[i])) + f->lock = (pthread_mutex_t)PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; + pthread_mutex_init(&__fflush_lock_obj, 0); +} + +__attribute__((__constructor__(60))) static textstartup void stdioinit(void) { + pthread_atfork(__stdio_fork_prepare, __stdio_fork_parent, __stdio_fork_child); +} diff --git a/libc/stdio/stderr.c b/libc/stdio/stderr.c index 4f80d4223..de694ed62 100644 --- a/libc/stdio/stderr.c +++ b/libc/stdio/stderr.c @@ -16,27 +16,25 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/calls/calls.h" #include "libc/stdio/internal.h" -#include "libc/stdio/stdio.h" #include "libc/sysv/consts/fileno.h" #include "libc/sysv/consts/o.h" #include "libc/thread/thread.h" +static FILE __stderr = { + .fd = STDERR_FILENO, + .bufmode = _IONBF, + .iomode = O_WRONLY, + .buf = __stderr.mem, + .size = sizeof(stderr->mem), + .lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, +}; + /** * Pointer to standard error stream. */ -FILE *stderr; - -static FILE __stderr; +FILE *stderr = &__stderr; __attribute__((__constructor__(60))) static textstartup void errinit(void) { - stderr = &__stderr; - stderr->fd = STDERR_FILENO; - stderr->bufmode = _IONBF; - stderr->iomode = O_WRONLY; - stderr->buf = stderr->mem; - stderr->size = sizeof(stderr->mem); - stderr->lock._word = PTHREAD_MUTEX_RECURSIVE; __fflush_register(stderr); } diff --git a/libc/stdio/stdin.c b/libc/stdio/stdin.c index 8f87e47ed..c5c3f6c2e 100644 --- a/libc/stdio/stdin.c +++ b/libc/stdio/stdin.c @@ -16,30 +16,29 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/calls/calls.h" #include "libc/calls/struct/stat.h" #include "libc/stdio/internal.h" -#include "libc/stdio/stdio.h" #include "libc/sysv/consts/fileno.h" #include "libc/sysv/consts/o.h" #include "libc/sysv/consts/s.h" #include "libc/thread/thread.h" +static FILE __stdin = { + .fd = STDIN_FILENO, + .iomode = O_RDONLY, + .bufmode = _IOFBF, + .buf = __stdin.mem, + .size = sizeof(stdin->mem), + .lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, +}; + /** * Pointer to standard input stream. */ -FILE *stdin; - -static FILE __stdin; +FILE *stdin = &__stdin; __attribute__((__constructor__(60))) static textstartup void initin(void) { struct stat st; - stdin = &__stdin; - stdin->fd = STDIN_FILENO; - stdin->iomode = O_RDONLY; - stdin->buf = stdin->mem; - stdin->size = sizeof(stdin->mem); - stdin->lock._word = PTHREAD_MUTEX_RECURSIVE; if (fstat(STDIN_FILENO, &st) || !S_ISREG(st.st_mode)) stdin->bufmode = _IONBF; __fflush_register(stdin); diff --git a/libc/stdio/stdout.c b/libc/stdio/stdout.c index c00e5d3fa..4c6b9b2d6 100644 --- a/libc/stdio/stdout.c +++ b/libc/stdio/stdout.c @@ -16,39 +16,32 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/calls/calls.h" -#include "libc/dce.h" #include "libc/stdio/internal.h" -#include "libc/stdio/stdio.h" #include "libc/sysv/consts/fileno.h" #include "libc/sysv/consts/o.h" #include "libc/thread/thread.h" +static FILE __stdout = { + .fd = STDOUT_FILENO, + .iomode = O_WRONLY, + .buf = __stdout.mem, + .size = sizeof(stdout->mem), + .lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, + + // Unlike other C libraries we don't bother calling fstat() to check + // if stdio is a character device and we instead choose to always + // line buffer it. We need it because there's no way to use the + // unbuffer command on a statically linked binary. This still goes + // fast. We value latency more than throughput, and stdio isn't the + // best api when the goal is throughput. + .bufmode = _IOLBF, +}; + /** * Pointer to standard output stream. */ -FILE *stdout; - -static FILE __stdout; +FILE *stdout = &__stdout; __attribute__((__constructor__(60))) static textstartup void outinit(void) { - stdout = &__stdout; - - stdout->fd = STDOUT_FILENO; - stdout->iomode = O_WRONLY; - stdout->buf = stdout->mem; - stdout->size = sizeof(stdout->mem); - stdout->lock._word = PTHREAD_MUTEX_RECURSIVE; - - /* - * Unlike other C libraries we don't bother calling fstat() to check - * if stdio is a character device and we instead choose to always line - * buffer it. We need it because there's no way to use the unbuffer - * command on a statically linked binary. This still goes fast. We - * value latency more than throughput, and stdio isn't the best api - * when the goal is throughput. - */ - stdout->bufmode = _IOLBF; - __fflush_register(stdout); } diff --git a/test/libc/thread/pthread_atfork_test.c b/test/libc/thread/pthread_atfork_test.c index f1e44139b..00a19cec5 100644 --- a/test/libc/thread/pthread_atfork_test.c +++ b/test/libc/thread/pthread_atfork_test.c @@ -83,12 +83,8 @@ void mu_wipe(void) { pthread_mutex_init(&mu, 0); } -static atomic_bool once; - void *Worker(void *arg) { for (int i = 0; i < 20; ++i) { - if (!atomic_exchange(&once, true)) - __print_maps(0); mu_lock(); usleep(20); mu_unlock(); From 196942084bf7bcaaca5c5c9e0c3d984bcb1133cb Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sat, 6 Jul 2024 19:57:47 -0700 Subject: [PATCH 037/405] Recomment out accidental code --- test/ctl/set_test.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/ctl/set_test.cc b/test/ctl/set_test.cc index c435533db..2f68bb0e0 100644 --- a/test/ctl/set_test.cc +++ b/test/ctl/set_test.cc @@ -19,9 +19,9 @@ #include "ctl/set.h" #include "libc/mem/leaks.h" -#include -#define ctl std -#define check() size() +// #include +// #define ctl std +// #define check() size() int rand32(void) From f7780de24bf23d8b35857b3c18e39cc74432ac1d Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sun, 7 Jul 2024 12:24:25 -0700 Subject: [PATCH 038/405] Make realloc() go 100x faster on Linux/NetBSD Cosmopolitan now supports mremap(), which is only supported on Linux and NetBSD. First, it allows memory mappings to be relocated without copying them; this can dramatically speed up data structures like std::vector if the array size grows larger than 256kb. The mremap() system call is also 10x faster than munmap() when shrinking large memory mappings. There's now two functions, getpagesize() and getgransize() which help to write portable code that uses mmap(MAP_FIXED). Alternative sysconf() may be called with our new _SC_GRANSIZE. The madvise() system call now has a better wrapper with improved documentation. --- libc/calls/madvise-nt.c | 56 +- libc/calls/madvise.c | 42 +- libc/calls/mremap-sysv.greg.c | 77 --- libc/calls/syscall-sysv.internal.h | 3 +- libc/intrin/BUILD.mk | 1 + libc/intrin/describeflags.internal.h | 4 +- libc/intrin/describemapping.c | 8 +- ...riberemapflags.c => describemremapflags.c} | 8 +- libc/intrin/extend.c | 2 +- libc/intrin/{granularity.c => getgransize.c} | 2 +- libc/intrin/maps.c | 4 - libc/intrin/maps.h | 13 +- libc/intrin/mmap.c | 524 +++++++++++++----- libc/intrin/mprotect.c | 7 +- libc/intrin/msync-nt.c | 5 +- libc/intrin/randaddr.c | 26 + libc/intrin/tree.h | 101 +++- libc/mem/leaks.c | 2 +- libc/mem/pvalloc.c | 4 +- libc/mem/valloc.c | 2 +- libc/nt/memory.h | 6 + libc/proc/fork-nt.c | 31 +- libc/runtime/getavphyspages.c | 2 +- libc/runtime/getphyspages.c | 2 +- libc/runtime/getsymboltable.c | 9 +- libc/runtime/runtime.h | 3 +- libc/runtime/sysconf.c | 5 +- libc/runtime/sysconf.h | 2 + libc/runtime/zipos-get.c | 2 +- libc/runtime/zipos-stat-impl.c | 2 +- libc/sysv/calls/__sys_mremap.S | 2 - libc/sysv/calls/sys_mremap.S | 2 + libc/sysv/consts.sh | 8 +- libc/sysv/consts/MAP_NOFORK.S | 2 + libc/sysv/consts/MREMAP_FIXED.S | 2 - libc/sysv/consts/MREMAP_MAYMOVE.S | 2 - libc/sysv/consts/map.h | 1 + libc/sysv/syscalls.sh | 2 +- libc/testlib/memoryexists.c | 23 +- libc/testlib/testlib.h | 1 + net/https/finishcertificate.c | 2 +- test/libc/calls/madvise_test.c | 89 ++- test/libc/calls/pledge_test.c | 24 +- test/libc/calls/setrlimit_test.c | 12 +- test/libc/calls/unveil_test.c | 4 +- test/libc/intrin/kprintf_test.c | 2 +- test/libc/intrin/lockipc_test.c | 4 +- test/libc/intrin/mmap_scalability_test.c | 8 +- test/libc/intrin/mmap_test.c | 122 ++-- test/libc/intrin/mprotect_test.c | 46 +- test/libc/intrin/mremap_test.c | 178 ++++++ test/libc/intrin/munmap_test.c | 163 +++--- test/libc/intrin/tree_test.c | 183 +++++- test/libc/mem/malloc_test.c | 20 +- test/libc/nexgen32e/lz4decode_test.c | 2 +- test/libc/proc/fork_test.c | 16 +- test/libc/runtime/exit_test.c | 4 +- test/libc/str/memcpy_test.c | 2 +- test/libc/thread/sem_timedwait_test.c | 4 +- third_party/dlmalloc/directmap.inc | 2 +- third_party/dlmalloc/dlmalloc.c | 11 +- third_party/dlmalloc/platform.inc | 2 +- third_party/zip/zipup.c | 3 - tool/build/lib/elfwriter.c | 4 +- tool/lambda/lib/calloc.c | 8 +- tool/net/redbean.c | 4 +- tool/plinko/lib/plinko.c | 4 +- tool/viz/derasterize.c | 9 +- tool/viz/lib/sobel.c | 3 +- tool/viz/memzoom.c | 4 +- tool/viz/printvideo.c | 2 +- 71 files changed, 1301 insertions(+), 640 deletions(-) delete mode 100644 libc/calls/mremap-sysv.greg.c rename libc/intrin/{describeremapflags.c => describemremapflags.c} (88%) rename libc/intrin/{granularity.c => getgransize.c} (98%) create mode 100644 libc/intrin/randaddr.c delete mode 100644 libc/sysv/calls/__sys_mremap.S create mode 100644 libc/sysv/calls/sys_mremap.S create mode 100644 libc/sysv/consts/MAP_NOFORK.S delete mode 100644 libc/sysv/consts/MREMAP_FIXED.S delete mode 100644 libc/sysv/consts/MREMAP_MAYMOVE.S create mode 100644 test/libc/intrin/mremap_test.c diff --git a/libc/calls/madvise-nt.c b/libc/calls/madvise-nt.c index 77ad7351c..16bb589dc 100644 --- a/libc/calls/madvise-nt.c +++ b/libc/calls/madvise-nt.c @@ -16,61 +16,31 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall_support-nt.internal.h" #include "libc/nt/enum/offerpriority.h" +#include "libc/nt/memory.h" #include "libc/nt/runtime.h" -#include "libc/nt/struct/memoryrangeentry.h" #include "libc/sysv/consts/madv.h" #include "libc/sysv/errfuns.h" -typedef bool32 (*__msabi PrefetchVirtualMemoryPtr)( - int64_t hProcess, uintptr_t NumberOfEntries, - struct NtMemoryRangeEntry *VirtualAddresses, uint32_t reserved_Flags); - -textwindows static PrefetchVirtualMemoryPtr GetPrefetchVirtualMemory(void) { - static PrefetchVirtualMemoryPtr PrefetchVirtualMemory_; - if (!PrefetchVirtualMemory_) { - PrefetchVirtualMemory_ = /* win8.1+ */ - GetProcAddressModule("Kernel32.dll", "PrefetchVirtualMemory"); - } - return PrefetchVirtualMemory_; -} - -typedef bool32 (*__msabi OfferVirtualMemoryPtr)(void *inout_VirtualAddress, - size_t Size, int Priority); - -textwindows static OfferVirtualMemoryPtr GetOfferVirtualMemory(void) { - static OfferVirtualMemoryPtr OfferVirtualMemory_; - if (!OfferVirtualMemory_) { - OfferVirtualMemory_ = /* win8.1+ */ - GetProcAddressModule("Kernel32.dll", "OfferVirtualMemory"); - } - return OfferVirtualMemory_; -} - textwindows int sys_madvise_nt(void *addr, size_t length, int advice) { if (advice == MADV_WILLNEED || advice == MADV_SEQUENTIAL) { - PrefetchVirtualMemoryPtr fn = GetPrefetchVirtualMemory(); - if (fn) { - if (fn(GetCurrentProcess(), 1, &(struct NtMemoryRangeEntry){addr, length}, - 0)) { - return 0; - } else { - return __winerr(); - } + if (!length) + return 0; + if (PrefetchVirtualMemory(GetCurrentProcess(), 1, + &(struct NtMemoryRangeEntry){addr, length}, 0)) { + return 0; } else { - return enosys(); + return __winerr(); } } else if (advice == MADV_FREE) { - OfferVirtualMemoryPtr fn = GetOfferVirtualMemory(); - if (fn) { - if (fn(addr, length, kNtVmOfferPriorityNormal)) { - return 0; - } else { - return __winerr(); - } + if (!length) + return 0; + if (OfferVirtualMemory(addr, length, kNtVmOfferPriorityNormal)) { + return 0; } else { - return enosys(); + return __winerr(); } } else { return einval(); diff --git a/libc/calls/madvise.c b/libc/calls/madvise.c index c4a351c06..f1b2da64e 100644 --- a/libc/calls/madvise.c +++ b/libc/calls/madvise.c @@ -21,27 +21,49 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" #include "libc/intrin/strace.internal.h" +#include "libc/runtime/runtime.h" #include "libc/sysv/errfuns.h" +static int __madvise(void *addr, size_t length, int advice) { + + // simulate linux behavior of validating alignment + if ((uintptr_t)addr & (getpagesize() - 1)) + return einval(); + + // simulate linux behavior of checking for negative length + if ((ssize_t)length < 0) + return einval(); + + // madvise(0, 0, advice) may be used to validate advice + if (!length && (IsFreebsd() || IsNetbsd())) + addr = (void *)65536l; + + if (!IsWindows()) + return sys_madvise(addr, length, advice); + return sys_madvise_nt(addr, length, advice); +} + /** - * Drops hints to O/S about intended access patterns of mmap()'d memory. + * Declares intent to OS on how memory region will be used. + * + * `madvise(0, 0, advice)` is recommended for validating `advise` and it + * will always be the case that a `length` of zero is a no-op otherwise. + * + * Having the interval overlap unmapped pages has undefined behavior. On + * Linux, this can be counted upon to raise ENOMEM. Other OSes vary much + * in behavior here; they'll might ignore unmapped regions or they might + * raise EINVAL, EFAULT, or ENOMEM. * * @param advice can be MADV_WILLNEED, MADV_SEQUENTIAL, MADV_FREE, etc. * @return 0 on success, or -1 w/ errno * @raise EINVAL if `advice` isn't valid or supported by system - * @raise EINVAL on Linux if addr/length isn't page size aligned with - * respect to `getpagesize()` - * @raise ENOMEM on Linux if addr/length overlaps unmapped regions + * @raise EINVAL if `addr` isn't getpagesize() aligned + * @raise EINVAL if `length` is negative * @see libc/sysv/consts.sh * @see fadvise() */ int madvise(void *addr, size_t length, int advice) { - int rc; - if (!IsWindows()) { - rc = sys_madvise(addr, length, advice); - } else { - rc = sys_madvise_nt(addr, length, advice); - } + int rc = __madvise(addr, length, advice); STRACE("madvise(%p, %'zu, %d) β†’ %d% m", addr, length, advice, rc); return rc; } diff --git a/libc/calls/mremap-sysv.greg.c b/libc/calls/mremap-sysv.greg.c deleted file mode 100644 index e65d9af0a..000000000 --- a/libc/calls/mremap-sysv.greg.c +++ /dev/null @@ -1,77 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-β”‚ -β”‚ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi β”‚ -β•žβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•‘ -β”‚ Copyright 2021 Justine Alexandra Roberts Tunney β”‚ -β”‚ β”‚ -β”‚ Permission to use, copy, modify, and/or distribute this software for β”‚ -β”‚ any purpose with or without fee is hereby granted, provided that the β”‚ -β”‚ above copyright notice and this permission notice appear in all copies. β”‚ -β”‚ β”‚ -β”‚ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL β”‚ -β”‚ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED β”‚ -β”‚ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE β”‚ -β”‚ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL β”‚ -β”‚ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR β”‚ -β”‚ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER β”‚ -β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ -β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ -β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/calls/calls.h" -#include "libc/calls/syscall-sysv.internal.h" -#include "libc/dce.h" -#include "libc/errno.h" -#include "libc/intrin/asmflag.h" -#include "libc/intrin/strace.internal.h" -#include "libc/sysv/consts/map.h" -#include "libc/sysv/consts/mremap.h" -#include "libc/sysv/errfuns.h" - -/** - * Relocates memory. - * - * This function lets you move to to different addresses witohut copying - * it. This system call is currently supported on Linux and NetBSD. Your - * C library runtime won't have any awareness of this memory, so certain - * features like ASAN memory safety and kprintf() won't work as well. - */ -void *sys_mremap(void *p, size_t n, size_t m, int f, void *q) { -#ifdef __x86_64__ - bool cf; - uintptr_t res, rdx; - register uintptr_t r8 asm("r8"); - register uintptr_t r10 asm("r10"); - if (IsLinux()) { - r10 = f; - r8 = (uintptr_t)q; - asm("syscall" - : "=a"(res) - : "0"(0x019), "D"(p), "S"(n), "d"(m), "r"(r10), "r"(r8) - : "rcx", "r11", "memory", "cc"); - if (res > -4096ul) - errno = -res, res = -1; - } else if (IsNetbsd()) { - if (f & MREMAP_MAYMOVE) { - res = 0x19B; - r10 = m; - r8 = (f & MREMAP_FIXED) ? MAP_FIXED : 0; - asm(CFLAG_ASM("syscall") - : CFLAG_CONSTRAINT(cf), "+a"(res), "=d"(rdx) - : "D"(p), "S"(n), "2"(q), "r"(r10), "r"(r8) - : "rcx", "r9", "r11", "memory", "cc"); - if (cf) - errno = res, res = -1; - } else { - res = einval(); - } - } else { - res = enosys(); - } -#elif defined(__aarch64__) - void *res; - res = __sys_mremap(p, n, m, f, q); -#else -#error "arch unsupported" -#endif - KERNTRACE("sys_mremap(%p, %'zu, %'zu, %#b, %p) β†’ %p% m", p, n, m, f, q, res); - return (void *)res; -} diff --git a/libc/calls/syscall-sysv.internal.h b/libc/calls/syscall-sysv.internal.h index e976e42ed..551f3e4a5 100644 --- a/libc/calls/syscall-sysv.internal.h +++ b/libc/calls/syscall-sysv.internal.h @@ -136,8 +136,7 @@ u32 sys_getuid(void); u32 sys_umask(u32); unsigned long _sysret(unsigned long); void *__sys_mmap(void *, u64, u32, u32, i64, i64, i64); -void *__sys_mremap(void *, u64, u64, i32, void *); -void *sys_mremap(void *, u64, u64, i32, void *); +void *sys_mremap(void *, u64, u64, u64, u64); void sys_exit(i32); #undef i32 diff --git a/libc/intrin/BUILD.mk b/libc/intrin/BUILD.mk index 5f05cfc5e..47f52776c 100644 --- a/libc/intrin/BUILD.mk +++ b/libc/intrin/BUILD.mk @@ -62,6 +62,7 @@ o/$(MODE)/libc/intrin/kprintf.o: private \ -Wframe-larger-than=128 \ -Walloca-larger-than=128 +o/$(MODE)/libc/intrin/mmap.o \ o/$(MODE)/libc/intrin/tree.o: private \ CFLAGS += \ -ffunction-sections diff --git a/libc/intrin/describeflags.internal.h b/libc/intrin/describeflags.internal.h index 8c7ee2686..dc38a93e5 100644 --- a/libc/intrin/describeflags.internal.h +++ b/libc/intrin/describeflags.internal.h @@ -26,6 +26,7 @@ const char *DescribeInOutInt64(char[23], ssize_t, int64_t *) libcesque; const char *DescribeItimer(char[12], int) libcesque; const char *DescribeMapFlags(char[64], int) libcesque; const char *DescribeMapping(char[8], int, int) libcesque; +const char *DescribeMremapFlags(char[30], int) libcesque; const char *DescribeNtConsoleInFlags(char[256], uint32_t) libcesque; const char *DescribeNtConsoleOutFlags(char[128], uint32_t) libcesque; const char *DescribeNtCreationDisposition(uint32_t) libcesque; @@ -49,7 +50,6 @@ const char *DescribePollFlags(char[64], int) libcesque; const char *DescribeProtFlags(char[48], int) libcesque; const char *DescribePtrace(char[12], int) libcesque; const char *DescribePtraceEvent(char[32], int) libcesque; -const char *DescribeRemapFlags(char[48], int) libcesque; const char *DescribeRlimitName(char[20], int) libcesque; const char *DescribeSchedPolicy(char[48], int) libcesque; const char *DescribeSeccompOperation(int) libcesque; @@ -81,6 +81,7 @@ const char *DescribeWhichPrio(char[12], int) libcesque; #define DescribeItimer(x) DescribeItimer(alloca(12), x) #define DescribeMapFlags(x) DescribeMapFlags(alloca(64), x) #define DescribeMapping(x, y) DescribeMapping(alloca(8), x, y) +#define DescribeMremapFlags(x) DescribeMremapFlags(alloca(30), x) #define DescribeNtConsoleInFlags(x) DescribeNtConsoleInFlags(alloca(256), x) #define DescribeNtConsoleOutFlags(x) DescribeNtConsoleOutFlags(alloca(128), x) #define DescribeNtFileAccessFlags(x) DescribeNtFileAccessFlags(alloca(512), x) @@ -103,7 +104,6 @@ const char *DescribeWhichPrio(char[12], int) libcesque; #define DescribeProtFlags(x) DescribeProtFlags(alloca(48), x) #define DescribePtrace(i) DescribePtrace(alloca(12), i) #define DescribePtraceEvent(x) DescribePtraceEvent(alloca(32), x) -#define DescribeRemapFlags(x) DescribeRemapFlags(alloca(48), x) #define DescribeRlimitName(rl) DescribeRlimitName(alloca(20), rl) #define DescribeSchedPolicy(x) DescribeSchedPolicy(alloca(48), x) #define DescribeSiCode(x, y) DescribeSiCode(alloca(20), x, y) diff --git a/libc/intrin/describemapping.c b/libc/intrin/describemapping.c index d4c54ef49..792c510a7 100644 --- a/libc/intrin/describemapping.c +++ b/libc/intrin/describemapping.c @@ -26,7 +26,10 @@ static char DescribeMapType(int flags) { case MAP_FILE: return '-'; case MAP_PRIVATE: - return 'p'; + if (flags & MAP_NOFORK) + return 'P'; + else + return 'p'; case MAP_SHARED: return 's'; default: @@ -47,7 +50,6 @@ const char *(DescribeMapping)(char p[8], int prot, int flags) { DescribeProt(p, prot); p[3] = DescribeMapType(flags); p[4] = (flags & MAP_ANONYMOUS) ? 'a' : '-'; - p[5] = (flags & MAP_FIXED) ? 'f' : '-'; - p[6] = 0; + p[5] = 0; return p; } diff --git a/libc/intrin/describeremapflags.c b/libc/intrin/describemremapflags.c similarity index 88% rename from libc/intrin/describeremapflags.c rename to libc/intrin/describemremapflags.c index 01f7bdb35..53f976b20 100644 --- a/libc/intrin/describeremapflags.c +++ b/libc/intrin/describemremapflags.c @@ -1,7 +1,7 @@ /*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-β”‚ β”‚ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi β”‚ β•žβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•‘ -β”‚ Copyright 2022 Justine Alexandra Roberts Tunney β”‚ +β”‚ Copyright 2024 Justine Alexandra Roberts Tunney β”‚ β”‚ β”‚ β”‚ Permission to use, copy, modify, and/or distribute this software for β”‚ β”‚ any purpose with or without fee is hereby granted, provided that the β”‚ @@ -20,12 +20,12 @@ #include "libc/macros.internal.h" #include "libc/sysv/consts/mremap.h" -static const struct DescribeFlags kRemapFlags[] = { +static const struct DescribeFlags kMremapFlags[] = { {MREMAP_MAYMOVE, "MAYMOVE"}, // {MREMAP_FIXED, "FIXED"}, // }; -const char *(DescribeRemapFlags)(char buf[48], int x) { - return DescribeFlags(buf, 48, kRemapFlags, ARRAYLEN(kRemapFlags), "MREMAP_", +const char *(DescribeMremapFlags)(char buf[30], int x) { + return DescribeFlags(buf, 30, kMremapFlags, ARRAYLEN(kMremapFlags), "MREMAP_", x); } diff --git a/libc/intrin/extend.c b/libc/intrin/extend.c index 20a557fef..1452d026b 100644 --- a/libc/intrin/extend.c +++ b/libc/intrin/extend.c @@ -22,7 +22,7 @@ #include "libc/sysv/consts/map.h" #include "libc/sysv/consts/prot.h" -#define G __granularity() +#define G getgransize() /** * Extends static allocation. diff --git a/libc/intrin/granularity.c b/libc/intrin/getgransize.c similarity index 98% rename from libc/intrin/granularity.c rename to libc/intrin/getgransize.c index 5a3edf700..805191a01 100644 --- a/libc/intrin/granularity.c +++ b/libc/intrin/getgransize.c @@ -22,7 +22,7 @@ #include "libc/runtime/runtime.h" #include "libc/sysv/consts/auxv.h" -int __granularity(void) { +int getgransize(void) { static int res; if (!res) { if (!IsWindows()) { diff --git a/libc/intrin/maps.c b/libc/intrin/maps.c index e845679e5..af394f12b 100644 --- a/libc/intrin/maps.c +++ b/libc/intrin/maps.c @@ -86,8 +86,6 @@ void __maps_init(void) { privileged bool __maps_lock(void) { struct CosmoTib *tib; - if (!__threaded) - return false; if (!__tls_enabled) return false; tib = __get_tls_privileged(); @@ -105,8 +103,6 @@ privileged bool __maps_lock(void) { privileged void __maps_unlock(void) { struct CosmoTib *tib; - if (!__threaded) - return; if (!__tls_enabled) return; tib = __get_tls_privileged(); diff --git a/libc/intrin/maps.h b/libc/intrin/maps.h index 387975b41..eea3142a6 100644 --- a/libc/intrin/maps.h +++ b/libc/intrin/maps.h @@ -18,8 +18,7 @@ struct Map { int flags; /* memory map flag */ bool iscow; /* windows nt only */ bool readonlyfile; /* windows nt only */ - unsigned visited; /* used for checks */ - unsigned oldprot; /* in windows fork */ + unsigned visited; /* checks and fork */ intptr_t hand; /* windows nt only */ union { struct Tree tree; @@ -33,7 +32,7 @@ struct Maps { struct Dll *free; size_t count; size_t pages; - atomic_ulong rollo; + atomic_size_t rollo; struct Map stack; struct Map guard; }; @@ -45,6 +44,7 @@ struct AddrSize { extern struct Maps __maps; +void *randaddr(void); void __maps_init(void); bool __maps_lock(void); void __maps_check(void); @@ -52,6 +52,7 @@ void __maps_unlock(void); void __maps_add(struct Map *); void __maps_free(struct Map *); struct Map *__maps_alloc(void); +struct Map *__maps_ceil(const char *); struct Map *__maps_floor(const char *); void __maps_stack(char *, int, int, size_t, int, intptr_t); int __maps_compare(const struct Tree *, const struct Tree *); @@ -61,11 +62,7 @@ forceinline optimizespeed int __maps_search(const void *key, const struct Tree *node) { const char *addr = (const char *)key; const struct Map *map = (const struct Map *)MAP_TREE_CONTAINER(node); - if (addr < map->addr) - return +1; - if (addr >= map->addr + map->size) - return -1; - return 0; + return (addr > map->addr) - (addr < map->addr); } static struct Map *__maps_next(struct Map *map) { diff --git a/libc/intrin/mmap.c b/libc/intrin/mmap.c index 02ef9614e..ff0a5d3a4 100644 --- a/libc/intrin/mmap.c +++ b/libc/intrin/mmap.c @@ -44,14 +44,16 @@ #include "libc/stdio/sysparam.h" #include "libc/sysv/consts/auxv.h" #include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/mremap.h" #include "libc/sysv/consts/o.h" #include "libc/sysv/consts/prot.h" #include "libc/sysv/errfuns.h" #include "libc/thread/thread.h" +#include "libc/thread/tls.h" -#define MMDEBUG 0 // this code is too slow for openbsd/windows -#define WINBASE 0x100080040000 // TODO: Can we support Windows Vista again? -#define WINMAXX 0x200080000000 +#define MMDEBUG IsModeDbg() +#define WINBASE (1ul << 35) // 34 gb +#define WINMAXX ((1ul << 44) - WINBASE) // 17 tb #define MAP_FIXED_NOREPLACE_linux 0x100000 @@ -86,9 +88,19 @@ privileged optimizespeed struct Map *__maps_floor(const char *addr) { return 0; } -static bool overlaps_existing_map(const char *addr, size_t size, int pagesz) { - struct Map *map; - if ((map = __maps_floor(addr))) +struct Map *__maps_ceil(const char *addr) { + struct Tree *node; + if ((node = tree_ceil(__maps.maps, addr, __maps_search))) + return MAP_TREE_CONTAINER(node); + return 0; +} + +static bool __maps_overlaps(const char *addr, size_t size, int pagesz) { + ASSERT(!((uintptr_t)addr & (getgransize() - 1)) && size); + struct Map *map, *ceil, *floor; + floor = __maps_floor(addr); + ceil = __maps_ceil(addr + size); + for (map = floor; map && map != ceil; map = __maps_next(map)) if (MAX(addr, map->addr) < MIN(addr + PGUP(size), map->addr + PGUP(map->size))) return true; @@ -107,14 +119,13 @@ void __maps_check(void) { ASSERT(map->visited != id); ASSERT(map->size); map->visited = id; - pages += (map->size + getpagesize() - 1) / getpagesize(); + pages += (map->size + pagesz - 1) / pagesz; maps += 1; struct Map *next; if ((next = __maps_next(map))) { ASSERT(map->addr < next->addr); - ASSERT( - !(MAX(map->addr, next->addr) < - MIN(map->addr + PGUP(map->size), next->addr + PGUP(next->size)))); + ASSERT(MAX(map->addr, next->addr) >= + MIN(map->addr + PGUP(map->size), next->addr + PGUP(next->size))); } } ASSERT(maps = __maps.count); @@ -122,87 +133,30 @@ void __maps_check(void) { #endif } -void __maps_free(struct Map *map) { - map->size = 0; - map->addr = MAP_FAILED; - dll_init(&map->free); - dll_make_first(&__maps.free, &map->free); -} - -static void __maps_insert(struct Map *map) { - __maps.pages += (map->size + getpagesize() - 1) / getpagesize(); - struct Map *floor = __maps_floor(map->addr); - if (floor && !IsWindows() && // - map->addr + map->size == floor->addr && // - (map->flags & MAP_ANONYMOUS) && // - map->flags == floor->flags && // - map->prot == floor->prot) { - floor->addr -= map->size; - floor->size += map->size; - __maps_free(map); - __maps_check(); - } else { - __maps_add(map); - __maps_check(); - } -} - -struct Map *__maps_alloc(void) { - struct Dll *e; - struct Map *map; - if ((e = dll_first(__maps.free))) { - dll_remove(&__maps.free, e); - map = MAP_FREE_CONTAINER(e); - return map; - } - int granularity = __granularity(); - struct DirectMap sys = sys_mmap(0, granularity, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if (sys.addr == MAP_FAILED) - return 0; - if (IsWindows()) - CloseHandle(sys.maphandle); - map = sys.addr; - map->addr = MAP_FAILED; - for (int i = 1; i < granularity / sizeof(struct Map); ++i) - __maps_free(map + i); - return map; -} - -static int __munmap(char *addr, size_t size, bool untrack_only) { - - // validate arguments - int pagesz = getpagesize(); - int granularity = __granularity(); - if (((uintptr_t)addr & (granularity - 1)) || // - !size || (uintptr_t)addr + size < size) - return einval(); - - // normalize size - size = (size + granularity - 1) & -granularity; - - // untrack mappings +static int __muntrack(char *addr, size_t size, int pagesz, + struct Dll **deleted) { int rc = 0; struct Map *map; struct Map *next; - struct Dll *deleted = 0; - if (__maps_lock()) { - __maps_unlock(); - return edeadlk(); - } - for (map = __maps_floor(addr); map; map = next) { + struct Map *ceil; + struct Map *floor; + floor = __maps_floor(addr); + ceil = __maps_ceil(addr + size); + for (map = floor; map && map != ceil; map = next) { next = __maps_next(map); char *map_addr = map->addr; size_t map_size = map->size; - if (!(MAX(addr, map_addr) < MIN(addr + size, map_addr + PGUP(map_size)))) - break; - if (addr <= map_addr && addr + size >= map_addr + PGUP(map_size)) { + if (!(MAX(addr, map_addr) < + MIN(addr + PGUP(size), map_addr + PGUP(map_size)))) + continue; + if (addr <= map_addr && addr + PGUP(size) >= map_addr + PGUP(map_size)) { // remove mapping completely tree_remove(&__maps.maps, &map->tree); dll_init(&map->free); - dll_make_first(&deleted, &map->free); + dll_make_first(deleted, &map->free); __maps.pages -= (map_size + pagesz - 1) / pagesz; __maps.count -= 1; + __maps_check(); } else if (IsWindows()) { // you can't carve up memory maps on windows. our mmap() makes // this not a problem (for non-enormous memory maps) by making @@ -210,8 +164,8 @@ static int __munmap(char *addr, size_t size, bool untrack_only) { rc = einval(); } else if (addr <= map_addr) { // shave off lefthand side of mapping - ASSERT(addr + size < map_addr + PGUP(map_size)); - size_t left = PGUP(addr + size - map_addr); + ASSERT(addr + PGUP(size) < map_addr + PGUP(map_size)); + size_t left = addr + PGUP(size) - map_addr; size_t right = map_size - left; ASSERT(right > 0); ASSERT(left > 0); @@ -225,11 +179,12 @@ static int __munmap(char *addr, size_t size, bool untrack_only) { leftmap->addr = map_addr; leftmap->size = left; dll_init(&leftmap->free); - dll_make_first(&deleted, &leftmap->free); + dll_make_first(deleted, &leftmap->free); + __maps_check(); } else { rc = -1; } - } else if (addr + size >= map_addr + PGUP(map_size)) { + } else if (addr + PGUP(size) >= map_addr + PGUP(map_size)) { // shave off righthand side of mapping size_t left = addr - map_addr; size_t right = map_addr + map_size - addr; @@ -240,14 +195,15 @@ static int __munmap(char *addr, size_t size, bool untrack_only) { rightmap->addr = addr; rightmap->size = right; dll_init(&rightmap->free); - dll_make_first(&deleted, &rightmap->free); + dll_make_first(deleted, &rightmap->free); + __maps_check(); } else { rc = -1; } } else { // punch hole in mapping size_t left = addr - map_addr; - size_t middle = size; + size_t middle = PGUP(size); size_t right = map_size - middle - left; struct Map *leftmap; if ((leftmap = __maps_alloc())) { @@ -268,7 +224,8 @@ static int __munmap(char *addr, size_t size, bool untrack_only) { middlemap->addr = addr; middlemap->size = size; dll_init(&middlemap->free); - dll_make_first(&deleted, &middlemap->free); + dll_make_first(deleted, &middlemap->free); + __maps_check(); } else { rc = -1; } @@ -276,36 +233,146 @@ static int __munmap(char *addr, size_t size, bool untrack_only) { rc = -1; } } - __maps_check(); } + return rc; +} + +void __maps_free(struct Map *map) { + map->size = 0; + map->addr = MAP_FAILED; + dll_init(&map->free); + dll_make_first(&__maps.free, &map->free); +} + +static void __maps_insert(struct Map *map) { + map->flags &= MAP_TYPE | MAP_ANONYMOUS | MAP_NOFORK; + + // coalesce adjacent mappings + if (!IsWindows() && (map->flags & MAP_ANONYMOUS)) { + int prot = map->prot & ~(MAP_FIXED | MAP_FIXED_NOREPLACE); + int flags = map->flags; + bool coalesced = false; + struct Map *floor, *ceil, *other, *last = 0; + floor = __maps_floor(map->addr); + ceil = __maps_ceil(map->addr + map->size); + for (other = floor; other; last = other, other = __maps_next(other)) { + if (prot == other->prot && flags == other->flags) { + if (!coalesced) { + if (map->addr == other->addr + other->size) { + __maps.pages += (map->size + getpagesize() - 1) / getpagesize(); + other->size += map->size; + __maps_free(map); + __maps_check(); + coalesced = true; + } else if (map->addr + map->size == other->addr) { + __maps.pages += (map->size + getpagesize() - 1) / getpagesize(); + other->addr -= map->size; + other->size += map->size; + __maps_free(map); + __maps_check(); + coalesced = true; + } + } + if (last && other->addr == last->addr + last->size) { + other->addr -= last->size; + other->size += last->size; + tree_remove(&__maps.maps, &last->tree); + __maps.count -= 1; + __maps_free(last); + __maps_check(); + } + } + if (other == ceil) + break; + } + if (coalesced) + return; + } + + // otherwise insert new mapping + __maps.pages += (map->size + getpagesize() - 1) / getpagesize(); + __maps_add(map); + __maps_check(); +} + +struct Map *__maps_alloc(void) { + struct Dll *e; + struct Map *map; + if ((e = dll_first(__maps.free))) { + dll_remove(&__maps.free, e); + map = MAP_FREE_CONTAINER(e); + return map; + } + int gransz = getgransize(); + struct DirectMap sys = sys_mmap(0, gransz, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (sys.addr == MAP_FAILED) + return 0; + map = sys.addr; + map->addr = sys.addr; + map->size = gransz; + map->prot = PROT_READ | PROT_WRITE; + map->flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NOFORK; + map->hand = sys.maphandle; + __maps_insert(map++); + map->addr = MAP_FAILED; + for (int i = 1; i < gransz / sizeof(struct Map) - 1; ++i) + __maps_free(map + i); + return map; +} + +static int __munmap(char *addr, size_t size) { + + // validate arguments + int pagesz = getpagesize(); + int gransz = getgransize(); + if (((uintptr_t)addr & (gransz - 1)) || // + !size || (uintptr_t)addr + size < size) + return einval(); + + // lock the memory manager + // abort on reentry due to signal handler + if (__maps_lock()) { + __maps_unlock(); + return edeadlk(); + } + __maps_check(); + + // normalize size + // abort if size doesn't include all pages in granule + size_t pgup_size = (size + pagesz - 1) & -pagesz; + size_t grup_size = (size + gransz - 1) & -gransz; + if (grup_size > pgup_size) + if (__maps_overlaps(addr + pgup_size, grup_size - pgup_size, pagesz)) { + __maps_unlock(); + return einval(); + } + + // untrack mappings + struct Dll *deleted = 0; + __muntrack(addr, pgup_size, pagesz, &deleted); __maps_unlock(); // delete mappings + int rc = 0; for (struct Dll *e = dll_first(deleted); e; e = dll_next(deleted, e)) { struct Map *map = MAP_FREE_CONTAINER(e); - if (!untrack_only) { - if (!IsWindows()) { - if (sys_munmap(map->addr, map->size)) - rc = -1; - } else if (map->hand != -1) { - ASSERT(!((uintptr_t)map->addr & (granularity - 1))); - if (!UnmapViewOfFile(map->addr)) - rc = -1; - if (!CloseHandle(map->hand)) - rc = -1; - } + if (!IsWindows()) { + if (sys_munmap(map->addr, map->size)) + rc = -1; + } else if (map->hand != -1) { + ASSERT(!((uintptr_t)map->addr & (gransz - 1))); + if (!UnmapViewOfFile(map->addr)) + rc = -1; + if (!CloseHandle(map->hand)) + rc = -1; } } // free mappings if (!dll_is_empty(deleted)) { __maps_lock(); - struct Dll *e; - while ((e = dll_first(deleted))) { - dll_remove(&deleted, e); - __maps_free(MAP_FREE_CONTAINER(e)); - } - __maps_check(); + dll_make_first(&__maps.free, deleted); __maps_unlock(); } @@ -313,7 +380,7 @@ static int __munmap(char *addr, size_t size, bool untrack_only) { } static void *__mmap_chunk(void *addr, size_t size, int prot, int flags, int fd, - int64_t off, int pagesz, int granularity) { + int64_t off, int pagesz, int gransz) { // polyfill nuances of fixed mappings int sysflags = flags; @@ -328,7 +395,7 @@ static void *__mmap_chunk(void *addr, size_t size, int prot, int flags, int fd, sysflags |= MAP_FIXED_NOREPLACE_linux; } else if (IsFreebsd() || IsNetbsd()) { sysflags |= MAP_FIXED; - if (overlaps_existing_map(addr, size, pagesz)) + if (__maps_overlaps(addr, size, pagesz)) return (void *)eexist(); } else { noreplace = true; @@ -351,7 +418,7 @@ static void *__mmap_chunk(void *addr, size_t size, int prot, int flags, int fd, // remove mapping we blew away if (IsWindows() && should_untrack) - if (__munmap(addr, size, false)) + if (__munmap(addr, size)) return MAP_FAILED; // obtain mapping from operating system @@ -366,7 +433,7 @@ TryAgain: } else if (should_untrack) { errno = ENOMEM; } else { - addr += granularity; + addr += gransz; errno = olderr; goto TryAgain; } @@ -394,10 +461,17 @@ TryAgain: } // untrack mapping we blew away - if (!IsWindows() && should_untrack) - __munmap(res.addr, size, true); + if (!IsWindows() && should_untrack) { + struct Dll *deleted = 0; + __muntrack(res.addr, size, pagesz, &deleted); + if (!dll_is_empty(deleted)) { + __maps_lock(); + dll_make_first(&__maps.free, deleted); + __maps_unlock(); + } + } - // track Map object + // track map object map->addr = res.addr; map->size = size; map->off = off; @@ -417,11 +491,11 @@ TryAgain: } static void *__mmap_impl(char *addr, size_t size, int prot, int flags, int fd, - int64_t off, int pagesz, int granularity) { + int64_t off, int pagesz, int gransz) { // validate file map args if (!(flags & MAP_ANONYMOUS)) { - if (off & (granularity - 1)) + if (off & (gransz - 1)) return (void *)einval(); if (IsWindows()) { if (!__isfdkind(fd, kFdFile)) @@ -433,36 +507,48 @@ static void *__mmap_impl(char *addr, size_t size, int prot, int flags, int fd, // mmap works fine on unix if (!IsWindows()) - return __mmap_chunk(addr, size, prot, flags, fd, off, pagesz, granularity); + return __mmap_chunk(addr, size, prot, flags, fd, off, pagesz, gransz); // if the concept of pagesz wasn't exciting enough if (!addr && !(flags & (MAP_FIXED | MAP_FIXED_NOREPLACE))) { - size_t slab = (size + granularity - 1) & -granularity; - addr = (char *)(WINBASE + atomic_fetch_add(&__maps.rollo, slab) % WINMAXX); + size_t rollo, rollo2, slab = (size + gransz - 1) & -gransz; + rollo = atomic_load_explicit(&__maps.rollo, memory_order_relaxed); + for (;;) { + if ((rollo2 = rollo + slab) > WINMAXX) { + rollo = 0; + rollo2 = slab; + } + if (atomic_compare_exchange_weak_explicit(&__maps.rollo, &rollo, rollo2, + memory_order_acq_rel, + memory_order_relaxed)) { + addr = (char *)WINBASE + rollo; + break; + } + } } // windows forbids unmapping a subset of a map once it's made - if (size <= granularity || size > 100 * 1024 * 1024) - return __mmap_chunk(addr, size, prot, flags, fd, off, pagesz, granularity); + if (size <= gransz || size > 100 * 1024 * 1024) + return __mmap_chunk(addr, size, prot, flags, fd, off, pagesz, gransz); // so we create a separate map for each granule in the mapping if (!(flags & MAP_FIXED)) { - while (overlaps_existing_map(addr, size, pagesz)) { + while (__maps_overlaps(addr, size, pagesz)) { if (flags & MAP_FIXED_NOREPLACE) return (void *)eexist(); - addr += granularity; + addr += gransz; } } char *res = addr; while (size) { char *got; - size_t amt = MIN(size, granularity); - got = __mmap_chunk(addr, amt, prot, flags, fd, off, pagesz, granularity); + size_t amt = MIN(size, gransz); + got = __mmap_chunk(addr, amt, prot, flags, fd, off, pagesz, gransz); if (got != addr) { if (got != MAP_FAILED) - __munmap(got, amt, false); + __munmap(got, amt); if (addr > res) - __munmap(res, addr - res, false); + __munmap(res, addr - res); errno = EAGAIN; return MAP_FAILED; } @@ -477,20 +563,20 @@ static void *__mmap(char *addr, size_t size, int prot, int flags, int fd, int64_t off) { char *res; int pagesz = getpagesize(); - int granularity = __granularity(); + int gransz = getgransize(); // validate arguments - if (((uintptr_t)addr & (granularity - 1)) || // + if (((uintptr_t)addr & (gransz - 1)) || // !size || (uintptr_t)addr + size < size) return (void *)einval(); - if (size > 0x100000000000) + if (size > WINMAXX) return (void *)enomem(); if (__maps.count * pagesz + size > __virtualmax) return (void *)enomem(); // create memory mappping if (!__isfdkind(fd, kFdZip)) { - res = __mmap_impl(addr, size, prot, flags, fd, off, pagesz, granularity); + res = __mmap_impl(addr, size, prot, flags, fd, off, pagesz, gransz); } else { res = _weaken(__zipos_mmap)( addr, size, prot, flags, @@ -500,6 +586,170 @@ static void *__mmap(char *addr, size_t size, int prot, int flags, int fd, return res; } +static void *__mremap_impl(char *old_addr, size_t old_size, size_t new_size, + int flags, char *new_addr, int pagesz, int gransz) { + + // normalize and validate old size + // abort if size doesn't include all pages in granule + size_t pgup_old_size = (old_size + pagesz - 1) & -pagesz; + size_t grup_old_size = (old_size + gransz - 1) & -gransz; + if (grup_old_size > pgup_old_size) + if (__maps_overlaps(old_addr + pgup_old_size, grup_old_size - pgup_old_size, + pagesz)) + return (void *)einval(); + old_size = pgup_old_size; + + // validate new size + // abort if size doesn't include all pages in granule + if (flags & MREMAP_FIXED) { + size_t pgup_new_size = (new_size + pagesz - 1) & -pagesz; + size_t grup_new_size = (new_size + gransz - 1) & -gransz; + if (grup_new_size > pgup_new_size) + if (__maps_overlaps(new_addr + pgup_new_size, + grup_new_size - pgup_new_size, pagesz)) + return (void *)einval(); + } + + // check old interval is fully contained within one mapping + struct Map *old_map; + if (!(old_map = __maps_floor(old_addr)) || + old_addr + old_size > old_map->addr + PGUP(old_map->size) || + old_addr < old_map->addr) + return (void *)efault(); + + // save old properties + int old_off = old_map->off; + int old_prot = old_map->prot; + int old_flags = old_map->flags; + + // allocate object for tracking new mapping + struct Map *map; + if (!(map = __maps_alloc())) + return (void *)enomem(); + + // netbsd mremap fixed returns enoent rather than unmapping old pages + if (IsNetbsd() && (flags & MREMAP_FIXED)) + if (__munmap(new_addr, new_size)) { + __maps_free(map); + return MAP_FAILED; + } + + // release lock before system call if possible + if (!flags) + __maps_unlock(); + + // the time has come + char *res; + if (IsNetbsd()) { + int sysfl = (flags & MREMAP_FIXED) ? MAP_FIXED : 0; + res = sys_mremap(old_addr, old_size, (uintptr_t)new_addr, new_size, sysfl); + } else { + res = sys_mremap(old_addr, old_size, new_size, flags, (uintptr_t)new_addr); + } + + // re-acquire lock if needed + if (!flags) + __maps_lock(); + + // check result + if (res == MAP_FAILED) { + __maps_free(map); + return MAP_FAILED; + } + + if (!(flags & MREMAP_MAYMOVE)) + ASSERT(res == old_addr); + + // untrack old mapping + struct Dll *deleted = 0; + __muntrack(old_addr, old_size, pagesz, &deleted); + dll_make_first(&__maps.free, deleted); + deleted = 0; + + // track map object + map->addr = res; + map->size = new_size; + map->off = old_off; + map->prot = old_prot; + map->flags = old_flags; + __maps_insert(map); + + return res; +} + +static void *__mremap(char *old_addr, size_t old_size, size_t new_size, + int flags, char *new_addr) { + + int pagesz = getpagesize(); + int gransz = getgransize(); + + // demand kernel support + if (!IsLinux() && !IsNetbsd()) + return (void *)enosys(); + + // we support these flags + if (flags & ~(MREMAP_MAYMOVE | MREMAP_FIXED)) + return (void *)einval(); + if (IsNetbsd() && !(flags & MREMAP_MAYMOVE) && + ((new_size + pagesz - 1) & -pagesz) > old_size) + return (void *)enotsup(); + if ((flags & MREMAP_FIXED) && !(flags & MREMAP_MAYMOVE)) + return (void *)einval(); + + // addresses must be granularity aligned + if ((uintptr_t)old_addr & (gransz - 1)) + return (void *)einval(); + if (flags & MREMAP_FIXED) + if ((uintptr_t)new_addr & (gransz - 1)) + return (void *)einval(); + + // sizes must not be zero + if (!old_size) + return (void *)einval(); + if (!new_size) + return (void *)einval(); + + // check for big size + if (old_size > WINMAXX) + return (void *)enomem(); + if (new_size > WINMAXX) + return (void *)enomem(); + + // check for overflow + if ((uintptr_t)old_addr + old_size < old_size) + return (void *)enomem(); + if (flags & MREMAP_FIXED) + if ((uintptr_t)new_addr + new_size < new_size) + return (void *)enomem(); + + // old and new intervals must not overlap + if (flags & MREMAP_FIXED) + if (MAX(old_addr, new_addr) < + MIN(old_addr + old_size, new_addr + PGUP(new_size))) + return (void *)einval(); + + // memory increase must not exceed RLIMIT_AS + if (PGUP(new_size) > old_size) + if (__maps.count * pagesz - old_size + PGUP(new_size) > __virtualmax) + return (void *)enomem(); + + // lock the memory manager + // abort on reentry due to signal handler + if (__maps_lock()) { + __maps_unlock(); + return (void *)edeadlk(); + } + __maps_check(); + + // perform operation + char *res = __mremap_impl(old_addr, old_size, new_size, flags, new_addr, + pagesz, gransz); + + // return result + __maps_unlock(); + return res; +} + void *mmap(void *addr, size_t size, int prot, int flags, int fd, int64_t off) { void *res = __mmap(addr, size, prot, flags, fd, off); STRACE("mmap(%p, %'zu, %s, %s, %d, %'ld) β†’ %p% m", addr, size, @@ -507,8 +757,22 @@ void *mmap(void *addr, size_t size, int prot, int flags, int fd, int64_t off) { return res; } +void *mremap(void *old_addr, size_t old_size, size_t new_size, int flags, ...) { + va_list ap; + void *new_addr = 0; + if (flags & MREMAP_FIXED) { + va_start(ap, flags); + new_addr = va_arg(ap, void *); + va_end(ap); + } + void *res = __mremap(old_addr, old_size, new_size, flags, new_addr); + STRACE("mremap(%p, %'zu, %'zu, %s, %p) β†’ %p% m", old_addr, old_size, new_size, + DescribeMremapFlags(flags), new_addr, res); + return res; +} + int munmap(void *addr, size_t size) { - int rc = __munmap(addr, size, false); + int rc = __munmap(addr, size); STRACE("munmap(%p, %'zu) β†’ %d% m", addr, size, rc); return rc; } diff --git a/libc/intrin/mprotect.c b/libc/intrin/mprotect.c index 76a40175e..a5bb5f554 100644 --- a/libc/intrin/mprotect.c +++ b/libc/intrin/mprotect.c @@ -74,13 +74,16 @@ int __mprotect(char *addr, size_t size, int prot) { __maps_unlock(); return edeadlk(); } - for (struct Map *map = __maps_floor(addr); map; map = __maps_next(map)) { + struct Map *map, *ceil, *floor; + floor = __maps_floor(addr); + ceil = __maps_ceil(addr + size); + for (map = floor; map && map != ceil; map = __maps_next(map)) { char *map_addr = map->addr; size_t map_size = map->size; char *beg = MAX(addr, map_addr); char *end = MIN(addr + size, map_addr + PGUP(map_size)); if (beg >= end) - break; + continue; found = true; if (addr <= map_addr && addr + size >= map_addr + PGUP(map_size)) { // change protection of entire mapping diff --git a/libc/intrin/msync-nt.c b/libc/intrin/msync-nt.c index 883a11c06..35f540827 100644 --- a/libc/intrin/msync-nt.c +++ b/libc/intrin/msync-nt.c @@ -37,7 +37,10 @@ textwindows int sys_msync_nt(char *addr, size_t size, int flags) { if (__maps_lock()) { rc = edeadlk(); } else { - for (struct Map *map = __maps_floor(addr); map; map = __maps_next(map)) { + struct Map *map, *ceil, *floor; + floor = __maps_floor(addr); + ceil = __maps_ceil(addr + size); + for (map = floor; map && map != ceil; map = __maps_next(map)) { char *beg = MAX(addr, map->addr); char *end = MIN(addr + size, map->addr + map->size); if (beg < end) diff --git a/libc/intrin/randaddr.c b/libc/intrin/randaddr.c new file mode 100644 index 000000000..672d909e6 --- /dev/null +++ b/libc/intrin/randaddr.c @@ -0,0 +1,26 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-β”‚ +β”‚ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi β”‚ +β•žβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•‘ +β”‚ Copyright 2024 Justine Alexandra Roberts Tunney β”‚ +β”‚ β”‚ +β”‚ Permission to use, copy, modify, and/or distribute this software for β”‚ +β”‚ any purpose with or without fee is hereby granted, provided that the β”‚ +β”‚ above copyright notice and this permission notice appear in all copies. β”‚ +β”‚ β”‚ +β”‚ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL β”‚ +β”‚ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED β”‚ +β”‚ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE β”‚ +β”‚ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL β”‚ +β”‚ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR β”‚ +β”‚ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER β”‚ +β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ +β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ +β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/intrin/maps.h" + +void *randaddr(void) { + static unsigned long lcg = 1; + lcg *= 6364136223846793005; + lcg += 1442695040888963407; + return (void *)(lcg >> 48 << 28); +} diff --git a/libc/intrin/tree.h b/libc/intrin/tree.h index fae2e08cb..601eaa927 100644 --- a/libc/intrin/tree.h +++ b/libc/intrin/tree.h @@ -36,35 +36,12 @@ static inline void tree_set_red(struct Tree *node, int red) { node->word |= red; } -forceinline optimizespeed struct Tree *tree_floor(const struct Tree *node, - const void *key, - tree_search_f *cmp) { - struct Tree *left = 0; - while (node) { - if (cmp(key, node) >= 0) { - left = (struct Tree *)node; - node = tree_get_left(node); - } else { - node = node->right; - } - } - return left; -} - -static inline struct Tree *tree_ceil(const struct Tree *node, const void *key, - tree_search_f *cmp) { - struct Tree *right = 0; - while (node) { - if (cmp(key, node) < 0) { - right = (struct Tree *)node; - node = tree_get_left(node); - } else { - node = node->right; - } - } - return right; -} - +// Returns node equal to given key. +// +// [1 3 5 7] [1 3 5 7] [1 3 5 7] +// NULL ↑ NULL +// 4 3 8 +// static inline struct Tree *tree_get(const struct Tree *node, const void *key, tree_search_f *cmp) { while (node) { @@ -80,6 +57,72 @@ static inline struct Tree *tree_get(const struct Tree *node, const void *key, return 0; } +// Returns last node less than or equal to given key. +// +// [1 3 5 7] [1 3 5 7] [1 3 5 7] +// ↑ ↑ ↑ +// 4 3 8 +// +forceinline optimizespeed struct Tree *tree_floor(const struct Tree *node, + const void *key, + tree_search_f *cmp) { + struct Tree *left = 0; + while (node) { + int c = cmp(key, node); + if (c < 0) { + node = tree_get_left(node); + } else if (c > 0) { + left = (struct Tree *)node; + node = node->right; + } else { + return (struct Tree *)node; + } + } + return left; +} + +// Returns first node not less than given key. +// +// [1 3 5 7] [1 3 5 7] [1 3 5 7] +// ↑ ↑ NULL +// 4 3 8 +// +static inline struct Tree *tree_lower(const struct Tree *node, const void *key, + tree_search_f *cmp) { + struct Tree *left = 0; + while (node) { + int c = cmp(key, node); + if (c <= 0) { + left = (struct Tree *)node; + node = tree_get_left(node); + } else { + node = node->right; + } + } + return left; +} + +// Returns first node greater than than given key. +// +// [1 3 5 7] [1 3 5 7] [1 3 5 7] +// ↑ ↑ NULL +// 4 3 8 +// +static inline struct Tree *tree_ceil(const struct Tree *node, const void *key, + tree_search_f *cmp) { + struct Tree *left = 0; + while (node) { + int c = cmp(key, node); + if (c < 0) { + left = (struct Tree *)node; + node = tree_get_left(node); + } else { + node = node->right; + } + } + return left; +} + struct Tree *tree_next(struct Tree *) libcesque; struct Tree *tree_prev(struct Tree *) libcesque; struct Tree *tree_first(struct Tree *) libcesque; diff --git a/libc/mem/leaks.c b/libc/mem/leaks.c index bb70e05d6..aae79fcfb 100644 --- a/libc/mem/leaks.c +++ b/libc/mem/leaks.c @@ -44,7 +44,7 @@ void __may_leak(void *alloc) { return; pthread_mutex_lock(&lock); if (dll_is_empty(freaks)) { - int g = __granularity(); + int g = getgransize(); struct Leak *p = _mapanon(g); int n = g / sizeof(struct Leak); for (int i = 0; i < n; ++i) { diff --git a/libc/mem/pvalloc.c b/libc/mem/pvalloc.c index 19479a0da..95fee37c7 100644 --- a/libc/mem/pvalloc.c +++ b/libc/mem/pvalloc.c @@ -32,9 +32,9 @@ * @see valloc() */ void *pvalloc(size_t n) { - if (ckd_add(&n, n, __granularity() - 1)) { + if (ckd_add(&n, n, getpagesize() - 1)) { errno = ENOMEM; return 0; } - return memalign(__granularity(), n & -__granularity()); + return memalign(getpagesize(), n & -getpagesize()); } diff --git a/libc/mem/valloc.c b/libc/mem/valloc.c index cc91f5f3e..71fe70275 100644 --- a/libc/mem/valloc.c +++ b/libc/mem/valloc.c @@ -29,5 +29,5 @@ * @see pvalloc() */ void *valloc(size_t n) { - return memalign(__granularity(), n); + return memalign(getpagesize(), n); } diff --git a/libc/nt/memory.h b/libc/nt/memory.h index bfd662e2d..376f0fb16 100644 --- a/libc/nt/memory.h +++ b/libc/nt/memory.h @@ -102,6 +102,12 @@ void *VirtualAlloc2( struct NtMemExtendedParameter *in_out_opt_ExtendedParameters, unsigned ParameterCount); +bool32 PrefetchVirtualMemory(int64_t hProcess, uintptr_t NumberOfEntries, + struct NtMemoryRangeEntry *VirtualAddresses, + uint32_t reserved_Flags); +bool32 OfferVirtualMemory(void *inout_VirtualAddress, size_t Size, + int Priority); + #if ShouldUseMsabiAttribute() #include "libc/nt/thunk/memory.inc" #endif /* ShouldUseMsabiAttribute() */ diff --git a/libc/proc/fork-nt.c b/libc/proc/fork-nt.c index 7e58445b6..e5e009d52 100644 --- a/libc/proc/fork-nt.c +++ b/libc/proc/fork-nt.c @@ -71,9 +71,10 @@ extern long __klog_handle; void WipeKeystrokes(void); __msabi extern typeof(GetCurrentProcessId) *const __imp_GetCurrentProcessId; -static textwindows wontreturn void AbortFork(const char *func) { +static textwindows wontreturn void AbortFork(const char *func, void *addr) { #if SYSDEBUG - kprintf("fork() %!s() failed with win32 error %u\n", func, GetLastError()); + kprintf("fork() %!s(%lx) failed with win32 error %u\n", func, addr, + GetLastError()); #endif TerminateThisProcess(SIGSTKFLT); } @@ -134,9 +135,9 @@ static dontinline textwindows bool WriteAll(int64_t h, void *buf, size_t n) { static textwindows dontinline void ReadOrDie(int64_t h, void *buf, size_t n) { ssize_t got; if ((got = ForkIo2(h, buf, n, ReadFile, "ReadFile", true)) == -1) - AbortFork("ReadFile1"); + AbortFork("ReadFile1", buf); if (got != n) - AbortFork("ReadFile2"); + AbortFork("ReadFile2", buf); } static textwindows int64_t MapOrDie(uint32_t prot, uint64_t size) { @@ -159,7 +160,7 @@ static textwindows int64_t MapOrDie(uint32_t prot, uint64_t size) { break; } } - AbortFork("MapOrDie"); + AbortFork("MapOrDie", (void *)size); } } @@ -172,7 +173,7 @@ TryAgain: access &= ~kNtFileMapExecute; goto TryAgain; } - AbortFork("ViewOrDie"); + AbortFork("ViewOrDie", base); } } @@ -223,7 +224,7 @@ textwindows void WinMainForked(void) { } // map memory into process - int granularity = __granularity(); + int granularity = getgransize(); for (struct Tree *e = tree_first(maps); e; e = tree_next(e)) { struct Map *map = MAP_TREE_CONTAINER(e); if ((uintptr_t)map->addr & (granularity - 1)) @@ -280,14 +281,14 @@ textwindows void WinMainForked(void) { unsigned old_protect; if (!VirtualProtect(map->addr, map->size, __prot2nt(map->prot, map->iscow), &old_protect)) - AbortFork("VirtualProtect"); + AbortFork("VirtualProtect", map->addr); } __maps.maps = maps; __maps_init(); // mitosis complete if (!CloseHandle(reader)) - AbortFork("CloseHandle"); + AbortFork("CloseHandle", (void *)reader); // rewrap the stdin named pipe hack // since the handles closed on fork @@ -370,6 +371,8 @@ textwindows int sys_fork_nt(uint32_t dwCreationFlags) { // this list will be populated with the maps we're transferring for (struct Map *map = __maps_first(); ok && map; map = __maps_next(map)) { + if (map->flags & MAP_NOFORK) + continue; if (MAX((char *)__executable_start, map->addr) < MIN((char *)_end, map->addr + map->size)) continue; // executable image is loaded by windows @@ -382,9 +385,11 @@ textwindows int sys_fork_nt(uint32_t dwCreationFlags) { ok = WriteAll(writer, &map, sizeof(map)); } // now write content of each map to child - int granularity = __granularity(); + int granularity = getgransize(); for (struct Map *map = __maps_first(); ok && map; map = __maps_next(map)) { + if (map->flags & MAP_NOFORK) + continue; // we only need to worry about the base mapping if ((uintptr_t)map->addr & (granularity - 1)) continue; @@ -410,15 +415,15 @@ textwindows int sys_fork_nt(uint32_t dwCreationFlags) { ok = VirtualProtect( map2->addr, map2->size, __prot2nt(map2->prot | PROT_READ, map2->iscow), - &map2->oldprot); + &map2->visited); } if (ok) ok = WriteAll(writer, map->addr, size); for (struct Map *map2 = map; ok && map2; map2 = __maps_next(map2)) { if (!(map2->prot & PROT_READ)) if (map->addr >= map2->addr && map->addr < map->addr + size) - ok = VirtualProtect(map2->addr, map2->size, map2->oldprot, - &map2->oldprot); + ok = VirtualProtect(map2->addr, map2->size, map2->visited, + &map2->visited); } } if (ok) diff --git a/libc/runtime/getavphyspages.c b/libc/runtime/getavphyspages.c index 326666fa5..4ed40d3ed 100644 --- a/libc/runtime/getavphyspages.c +++ b/libc/runtime/getavphyspages.c @@ -23,5 +23,5 @@ long __get_avphys_pages(void) { struct sysinfo si; if (sysinfo(&si) == -1) return -1; - return (((int64_t)si.freeram + si.bufferram) * si.mem_unit) / __granularity(); + return (((int64_t)si.freeram + si.bufferram) * si.mem_unit) / getpagesize(); } diff --git a/libc/runtime/getphyspages.c b/libc/runtime/getphyspages.c index 9f6dd35ea..1e553894b 100644 --- a/libc/runtime/getphyspages.c +++ b/libc/runtime/getphyspages.c @@ -23,5 +23,5 @@ long __get_phys_pages(void) { struct sysinfo si; if (sysinfo(&si) == -1) return -1; - return ((int64_t)si.totalram * si.mem_unit) / __granularity(); + return ((int64_t)si.totalram * si.mem_unit) / getpagesize(); } diff --git a/libc/runtime/getsymboltable.c b/libc/runtime/getsymboltable.c index 9010c9a37..0c8fad9d6 100644 --- a/libc/runtime/getsymboltable.c +++ b/libc/runtime/getsymboltable.c @@ -56,15 +56,14 @@ static ssize_t GetZipFile(struct Zipos *zipos, const char *name) { * @note This code can't depend on dlmalloc() */ static struct SymbolTable *GetSymbolTableFromZip(struct Zipos *zipos) { + size_t size; ssize_t cf, lf; - size_t size, size2; struct SymbolTable *res = 0; if ((cf = GetZipFile(zipos, ".symtab." _ARCH_NAME)) != -1 || (cf = GetZipFile(zipos, ".symtab")) != -1) { lf = GetZipCfileOffset(zipos->map + cf); size = GetZipLfileUncompressedSize(zipos->map + lf); - size2 = ROUNDUP(size, __granularity()); - if ((res = _mapanon(size2))) { + if ((res = _mapanon(size))) { switch (ZIP_LFILE_COMPRESSIONMETHOD(zipos->map + lf)) { case kZipCompressionNone: memcpy(res, (void *)ZIP_LFILE_CONTENT(zipos->map + lf), size); @@ -73,12 +72,12 @@ static struct SymbolTable *GetSymbolTableFromZip(struct Zipos *zipos) { if (__inflate((void *)res, size, (void *)ZIP_LFILE_CONTENT(zipos->map + lf), GetZipLfileCompressedSize(zipos->map + lf))) { - munmap(res, size2); + munmap(res, size); res = 0; } break; default: - munmap(res, size2); + munmap(res, size); res = 0; break; } diff --git a/libc/runtime/runtime.h b/libc/runtime/runtime.h index 295f0fe02..26f857536 100644 --- a/libc/runtime/runtime.h +++ b/libc/runtime/runtime.h @@ -43,6 +43,7 @@ int unsetenv(const char *) libcesque; int clearenv(void) libcesque; void fpreset(void) libcesque; void *mmap(void *, uint64_t, int32_t, int32_t, int32_t, int64_t) libcesque; +void *mremap(void *, size_t, size_t, int, ...) libcesque; int munmap(void *, uint64_t) libcesque; int mprotect(void *, uint64_t, int) libcesque; int msync(void *, size_t, int) libcesque; @@ -54,6 +55,7 @@ char *getlogin(void) libcesque; int getlogin_r(char *, size_t) libcesque; int login_tty(int) libcesque; int getpagesize(void) pureconst libcesque; +int getgransize(void) pureconst libcesque; int syncfs(int) dontthrow libcesque; int vhangup(void) libcesque; int getdtablesize(void) libcesque; @@ -127,7 +129,6 @@ void GetCpuidBrand(char[13], uint32_t) libcesque; long __get_rlimit(int) libcesque; const char *__describe_os(void) libcesque; long __get_sysctl(int, int) libcesque; -int __granularity(void) pureconst libcesque; int __get_arg_max(void) pureconst libcesque; int __get_cpu_count(void) pureconst libcesque; long __get_avphys_pages(void) pureconst libcesque; diff --git a/libc/runtime/sysconf.c b/libc/runtime/sysconf.c index 5adac2b08..2603ca453 100644 --- a/libc/runtime/sysconf.c +++ b/libc/runtime/sysconf.c @@ -41,11 +41,12 @@ * * The following parameters are supported: * + * - `_SC_PAGESIZE` returns page size for mmap() + * - `_SC_GRANSIZE` returns addr alignment for mmap() * - `_SC_CLK_TCK` returns number of clock ticks per second * - `_SC_ARG_MAX` will perform expensive rlimit calculations * - `_SC_SIGSTKSZ` returns host platform's preferred SIGSTKSZ * - `_SC_MINSIGSTKSZ` returns host platform's required MINSIGSTKSZ - * - `_SC_PAGESIZE` currently always returns 65536 due to Windows * - `_SC_AVPHYS_PAGES` returns average physical memory pages * - `_SC_PHYS_PAGES` returns physical memory pages available * - `_SC_NPROCESSORS_ONLN` returns number of effective CPUs @@ -61,6 +62,8 @@ long sysconf(int name) { return CLK_TCK; case _SC_PAGESIZE: return getpagesize(); + case _SC_GRANSIZE: + return getgransize(); case _SC_ARG_MAX: return __get_arg_max(); case _SC_SIGSTKSZ: diff --git a/libc/runtime/sysconf.h b/libc/runtime/sysconf.h index c44138c09..f3fd5bbd1 100644 --- a/libc/runtime/sysconf.h +++ b/libc/runtime/sysconf.h @@ -33,6 +33,8 @@ #define _SC_VERSION 29 #define _SC_PAGE_SIZE 30 #define _SC_PAGESIZE 30 /* !! */ +#define _SC_GRAN_SIZE 3000 +#define _SC_GRANSIZE 3000 #define _SC_RTSIG_MAX 31 #define _SC_SEM_NSEMS_MAX 32 #define _SC_SEM_VALUE_MAX 33 diff --git a/libc/runtime/zipos-get.c b/libc/runtime/zipos-get.c index bc7c9365b..352b7e4db 100644 --- a/libc/runtime/zipos-get.c +++ b/libc/runtime/zipos-get.c @@ -62,7 +62,7 @@ static void __zipos_dismiss(uint8_t *map, const uint8_t *cdir, long pg) { } // unmap the executable portion beneath the local files - mo = ROUNDDOWN(lo, __granularity()); + mo = ROUNDDOWN(lo, getgransize()); if (mo) munmap(map, mo); diff --git a/libc/runtime/zipos-stat-impl.c b/libc/runtime/zipos-stat-impl.c index 8c1e387f7..5644a1bb0 100644 --- a/libc/runtime/zipos-stat-impl.c +++ b/libc/runtime/zipos-stat-impl.c @@ -31,7 +31,7 @@ int __zipos_stat_impl(struct Zipos *zipos, size_t cf, struct stat *st) { bzero(st, sizeof(*st)); st->st_nlink = 1; st->st_dev = zipos->dev; - st->st_blksize = __granularity(); + st->st_blksize = getpagesize(); if (cf == ZIPOS_SYNTHETIC_DIRECTORY) { st->st_mode = S_IFDIR | (0555 & ~atomic_load_explicit( &__umask, memory_order_acquire)); diff --git a/libc/sysv/calls/__sys_mremap.S b/libc/sysv/calls/__sys_mremap.S deleted file mode 100644 index 97fc160d0..000000000 --- a/libc/sysv/calls/__sys_mremap.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/macros.internal.h" -.scall __sys_mremap,0x19bffffffffff019,216,4095,4095,globl,hidden diff --git a/libc/sysv/calls/sys_mremap.S b/libc/sysv/calls/sys_mremap.S new file mode 100644 index 000000000..87e3e314c --- /dev/null +++ b/libc/sysv/calls/sys_mremap.S @@ -0,0 +1,2 @@ +#include "libc/sysv/macros.internal.h" +.scall sys_mremap,0x19bffffffffff019,216,4095,4095,globl,hidden diff --git a/libc/sysv/consts.sh b/libc/sysv/consts.sh index 22cd4c998..74f00632f 100755 --- a/libc/sysv/consts.sh +++ b/libc/sysv/consts.sh @@ -228,6 +228,7 @@ syscon mmap MAP_LOCKED 0x00002000 0x00002000 0 0 0 0 0 0 syscon mmap MAP_NORESERVE 0x00004000 0x00004000 0x00000040 0x00000040 0 0 0x00000040 0 # Linux calls it "reserve"; NT calls it "commit"? which is default? syscon mmap MAP_POPULATE 0x00008000 0x00008000 0 0 0x00040000 0 0 0 # MAP_PREFAULT_READ on FreeBSD; can avoid madvise(MADV_WILLNEED) on private file mapping syscon mmap MAP_NONBLOCK 0x00010000 0x00010000 0 0 0 0 0 0 +syscon mmap MAP_NOFORK 0 0 0 0 0 0 0 0x10000000 # used on pages internal to our mmap() implemention on windows syscon mmap MAP_SYNC 0x00080000 0x00080000 0 0 0 0 0 0 # perform synchronous page faults for mapping (Linux 4.15+) syscon mmap MAP_HUGETLB 0x00040000 -1 -1 -1 -1 -1 -1 -1 # make it inherit across execve() syscon mmap MAP_INHERIT -1 -1 -1 -1 -1 -1 0x00000080 -1 # make it inherit across execve() @@ -294,13 +295,6 @@ syscon mprot PROT_WRITE 2 2 2 2 2 2 2 2 # mmap, mprotect, uni syscon mprot PROT_EXEC 4 4 4 4 4 4 4 4 # mmap, mprotect, unix consensus syscon mprot PROT_GUARD 0 0 0 0 0 0 0 0x100 # mmap, mprotect, unix consensus -# mremap() flags -# the revolutionary praxis of realloc() -# -# group name GNU/Systemd GNU/Systemd (Aarch64) XNU's Not UNIX! MacOS (Arm64) FreeBSD OpenBSD NetBSD The New Technology Commentary -syscon mremap MREMAP_MAYMOVE 1 1 1 1 1 1 1 1 # faked non-linux (b/c linux only) -syscon mremap MREMAP_FIXED 2 2 2 2 2 2 2 2 # faked non-linux (b/c linux only) - # sigprocmask() flags # # group name GNU/Systemd GNU/Systemd (Aarch64) XNU's Not UNIX! MacOS (Arm64) FreeBSD OpenBSD NetBSD The New Technology Commentary diff --git a/libc/sysv/consts/MAP_NOFORK.S b/libc/sysv/consts/MAP_NOFORK.S new file mode 100644 index 000000000..04b0363b6 --- /dev/null +++ b/libc/sysv/consts/MAP_NOFORK.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon mmap,MAP_NOFORK,0,0,0,0,0,0,0,0x10000000 diff --git a/libc/sysv/consts/MREMAP_FIXED.S b/libc/sysv/consts/MREMAP_FIXED.S deleted file mode 100644 index ac6a13656..000000000 --- a/libc/sysv/consts/MREMAP_FIXED.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon mremap,MREMAP_FIXED,2,2,2,2,2,2,2,2 diff --git a/libc/sysv/consts/MREMAP_MAYMOVE.S b/libc/sysv/consts/MREMAP_MAYMOVE.S deleted file mode 100644 index 7e65b360a..000000000 --- a/libc/sysv/consts/MREMAP_MAYMOVE.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon mremap,MREMAP_MAYMOVE,1,1,1,1,1,1,1,1 diff --git a/libc/sysv/consts/map.h b/libc/sysv/consts/map.h index 20ed8bf51..ae719ea0b 100644 --- a/libc/sysv/consts/map.h +++ b/libc/sysv/consts/map.h @@ -19,6 +19,7 @@ extern const int MAP_JIT; extern const int MAP_LOCKED; extern const int MAP_NOCACHE; extern const int MAP_NOEXTEND; +extern const int MAP_NOFORK; extern const int MAP_NONBLOCK; extern const int MAP_NORESERVE; extern const int MAP_NOSYNC; diff --git a/libc/sysv/syscalls.sh b/libc/sysv/syscalls.sh index d497dbaf7..1887b7049 100755 --- a/libc/sysv/syscalls.sh +++ b/libc/sysv/syscalls.sh @@ -59,7 +59,7 @@ scall __sys_pipe 0x02a10721e202a016 0x03b globl hidden # NOTE: pipe2() on FreeB scall sys_select 0x9a184785d285d817 0xfff globl hidden scall sys_pselect 0x9b486ea0a298a90e 0x848 globl hidden # pselect6() on gnu/systemd scall sys_sched_yield 0x15e12a14bf25d018 0x07c globl hidden # select() on XNU (previously swtch() but removed in 12.4) -scall __sys_mremap 0x19bffffffffff019 0x0d8 globl hidden +scall sys_mremap 0x19bffffffffff019 0x0d8 globl hidden scall sys_mincore 0x04e04e04e204e01b 0x0e8 globl hidden scall sys_madvise 0x04b04b04b204b01c 0x0e9 globl hidden scall sys_shmget 0x0e71210e7210901d 0x0c2 globl # no wrapper diff --git a/libc/testlib/memoryexists.c b/libc/testlib/memoryexists.c index d18c173ba..014497658 100644 --- a/libc/testlib/memoryexists.c +++ b/libc/testlib/memoryexists.c @@ -22,6 +22,7 @@ #include "libc/calls/struct/siginfo.h" #include "libc/calls/ucontext.h" #include "libc/intrin/atomic.h" +#include "libc/intrin/kprintf.h" #include "libc/sysv/consts/sa.h" #include "libc/sysv/consts/sig.h" #include "libc/testlib/testlib.h" @@ -44,14 +45,7 @@ static void ContinueOnError(int sig, siginfo_t *si, void *vctx) { #endif /* __x86_64__ */ } -/** - * Returns true if byte at address `p` is readable. - * - * This function temporarily catches `SIGSEGV` and `SIGBUS` to recover - * on error. It then attempts a volatile read and if it faults, then - * this function shall return false. The value at `p` isn't considered. - */ -bool testlib_memoryexists(const void *p) { +bool testlib_pokememory(const void *p) { volatile char c; const atomic_char *mem = p; struct sigaction old[2]; @@ -68,3 +62,16 @@ bool testlib_memoryexists(const void *p) { npassert(!sigaction(SIGSEGV, old + 0, 0)); return !gotsignal; } + +/** + * Returns true if byte at address `p` is readable. + * + * This function temporarily catches `SIGSEGV` and `SIGBUS` to recover + * on error. It then attempts a volatile read and if it faults, then + * this function shall return false. The value at `p` isn't considered. + */ +bool testlib_memoryexists(const void *p) { + if (kisdangerous(p)) + return false; + return testlib_pokememory(p); +} diff --git a/libc/testlib/testlib.h b/libc/testlib/testlib.h index 8ff94e2da..398c50004 100644 --- a/libc/testlib/testlib.h +++ b/libc/testlib/testlib.h @@ -372,6 +372,7 @@ void testlib_seterrno(int); void testlib_runalltests(void); const char *testlib_strerror(void); void testlib_runallbenchmarks(void); +bool testlib_pokememory(const void *); bool testlib_memoryexists(const void *); void testlib_runtestcases(const testfn_t *, const testfn_t *, testfn_t); void testlib_runfixtures(const testfn_t *, const testfn_t *, diff --git a/net/https/finishcertificate.c b/net/https/finishcertificate.c index 13aaf28b6..2d56078f1 100644 --- a/net/https/finishcertificate.c +++ b/net/https/finishcertificate.c @@ -27,7 +27,7 @@ struct Cert FinishCertificate(struct Cert *ca, mbedtls_x509write_cert *wcert, int i, n, rc; unsigned char *p; mbedtls_x509_crt *cert; - p = malloc((n = __granularity())); + p = malloc((n = getgransize())); i = mbedtls_x509write_crt_der(wcert, p, n, GenerateHardRandom, 0); if (i < 0) FATALF("write key (grep -0x%04x)", -i); diff --git a/test/libc/calls/madvise_test.c b/test/libc/calls/madvise_test.c index 6ddc1a13c..a3ae232ad 100644 --- a/test/libc/calls/madvise_test.c +++ b/test/libc/calls/madvise_test.c @@ -33,63 +33,100 @@ void SetUpOnce(void) { TEST(madvise, anon) { char *p; - ASSERT_NE(MAP_FAILED, (p = mmap(0, __granularity(), PROT_READ | PROT_WRITE, + ASSERT_NE(MAP_FAILED, (p = mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); - ASSERT_SYS(0, 0, madvise(p, __granularity(), MADV_WILLNEED)); - ASSERT_SYS(0, 0, munmap(p, __granularity())); + ASSERT_SYS(0, 0, madvise(p, getpagesize(), MADV_WILLNEED)); + ASSERT_SYS(0, 0, munmap(p, getpagesize())); } TEST(madvise, file) { char *p; ASSERT_SYS(0, 3, creat("foo.dat", 0644)); - ASSERT_SYS(0, 0, ftruncate(3, __granularity())); + ASSERT_SYS(0, 0, ftruncate(3, getpagesize())); ASSERT_SYS(0, 0, close(3)); ASSERT_SYS(0, 3, open("foo.dat", O_RDWR)); - ASSERT_NE(MAP_FAILED, (p = mmap(0, __granularity(), PROT_READ | PROT_WRITE, + ASSERT_NE(MAP_FAILED, (p = mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_PRIVATE, 3, 0))); - ASSERT_SYS(0, 0, madvise(p, __granularity(), MADV_WILLNEED)); - ASSERT_SYS(0, 0, munmap(p, __granularity())); + ASSERT_SYS(0, 0, madvise(p, getpagesize(), MADV_WILLNEED)); + ASSERT_SYS(0, 0, munmap(p, getpagesize())); ASSERT_SYS(0, 0, close(3)); } TEST(madvise, short) { char *p; - ASSERT_NE(MAP_FAILED, (p = mmap(0, __granularity(), PROT_READ | PROT_WRITE, + ASSERT_NE(MAP_FAILED, (p = mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); - ASSERT_SYS(0, 0, madvise(p, __granularity() - 1, MADV_WILLNEED)); - ASSERT_SYS(0, 0, munmap(p, __granularity())); + ASSERT_SYS(0, 0, madvise(p, getpagesize() - 1, MADV_WILLNEED)); + ASSERT_SYS(0, 0, munmap(p, getpagesize())); +} + +TEST(madvise, zero) { + char *p; + ASSERT_NE(MAP_FAILED, (p = mmap(0, getpagesize(), PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); + ASSERT_SYS(0, 0, madvise(p, 0, MADV_WILLNEED)); + ASSERT_SYS(0, 0, madvise(0, 0, MADV_WILLNEED)); + ASSERT_SYS(EINVAL, -1, madvise(p, 0, 666)); + ASSERT_SYS(EINVAL, -1, madvise(0, 0, 666)); + ASSERT_SYS(0, 0, munmap(p, getpagesize())); } TEST(madvise, subPages) { char *p; - ASSERT_NE(MAP_FAILED, (p = mmap(0, __granularity(), PROT_READ | PROT_WRITE, + ASSERT_NE(MAP_FAILED, (p = mmap(0, getpagesize() * 2, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); - ASSERT_SYS(0, 0, - madvise(p + getpagesize(), __granularity() - getpagesize(), - MADV_WILLNEED)); - ASSERT_SYS(0, 0, munmap(p, __granularity())); + ASSERT_SYS(0, 0, madvise(p + getpagesize(), getpagesize(), MADV_WILLNEED)); + ASSERT_SYS(0, 0, munmap(p, getpagesize() * 2)); +} + +TEST(madvise, madvWillNeed_unmappedRegion) { + char *p; + ASSERT_NE(MAP_FAILED, (p = mmap(0, getgransize() * 3, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); + ASSERT_SYS(0, 0, munmap(p + getgransize(), getgransize())); + if (IsXnu()) + ASSERT_SYS(EINVAL, -1, madvise(p, getgransize() * 3, MADV_WILLNEED)); + else if (IsBsd() || IsWindows()) + ASSERT_SYS(0, 0, madvise(p, getgransize() * 3, MADV_WILLNEED)); + else + ASSERT_SYS(ENOMEM, -1, madvise(p, getgransize() * 3, MADV_WILLNEED)); + ASSERT_SYS(0, 0, munmap(p, getgransize() * 3)); +} + +TEST(madvise, madvFree_unmappedRegion) { + char *p; + ASSERT_NE(MAP_FAILED, (p = mmap(0, getgransize() * 3, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); + ASSERT_SYS(0, 0, munmap(p + getgransize(), getgransize())); + if (IsXnu()) + ASSERT_SYS(EINVAL, -1, madvise(p, getgransize() * 3, MADV_FREE)); + else if (IsNetbsd() || IsOpenbsd()) + ASSERT_SYS(EFAULT, -1, madvise(p, getgransize() * 3, MADV_FREE)); + else if (IsFreebsd() || IsWindows()) + ASSERT_SYS(0, 0, madvise(p, getgransize() * 3, MADV_FREE)); + else + ASSERT_SYS(ENOMEM, -1, madvise(p, getgransize() * 3, MADV_FREE)); + ASSERT_SYS(0, 0, munmap(p, getgransize() * 3)); } TEST(madvise, misalign) { char *p; - if (!IsLinux()) - return; // most platforms don't care - if (IsQemuUser()) - return; // qemu claims to be linux but doesn't care - ASSERT_NE(MAP_FAILED, (p = mmap(0, __granularity(), PROT_READ | PROT_WRITE, + ASSERT_NE(MAP_FAILED, (p = mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); - ASSERT_SYS(EINVAL, -1, madvise(p + 1, __granularity() - 1, MADV_WILLNEED)); - ASSERT_SYS(0, 0, munmap(p, __granularity())); + ASSERT_SYS(EINVAL, -1, madvise(p + 1, getpagesize(), MADV_WILLNEED)); + ASSERT_SYS(0, 0, madvise(p, 1, MADV_WILLNEED)); + ASSERT_SYS(EINVAL, -1, madvise(p, -1, MADV_WILLNEED)); + ASSERT_SYS(0, 0, munmap(p, getpagesize())); } TEST(madvise, badAdvice) { char *p; if (IsAarch64() && IsQemuUser()) return; // qemu doesn't validate advice - ASSERT_NE(MAP_FAILED, (p = mmap(0, __granularity(), PROT_READ | PROT_WRITE, + ASSERT_NE(MAP_FAILED, (p = mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); - ASSERT_SYS(EINVAL, -1, madvise(p, __granularity(), 127)); - ASSERT_SYS(0, 0, munmap(p, __granularity())); + ASSERT_SYS(EINVAL, -1, madvise(p, getpagesize(), 127)); + ASSERT_SYS(0, 0, munmap(p, getpagesize())); } TEST(madvise, missingMemory) { @@ -98,5 +135,5 @@ TEST(madvise, missingMemory) { if (IsQemuUser()) return; // qemu claims to be linux but doesn't care ASSERT_SYS(ENOMEM, -1, - madvise((char *)0x83483838000, __granularity(), MADV_WILLNEED)); + madvise((char *)0x83483838000, getpagesize(), MADV_WILLNEED)); } diff --git a/test/libc/calls/pledge_test.c b/test/libc/calls/pledge_test.c index 53c5c8a19..c710147f1 100644 --- a/test/libc/calls/pledge_test.c +++ b/test/libc/calls/pledge_test.c @@ -86,7 +86,7 @@ TEST(pledge, default_allowsExit) { int *job; int ws, pid; // create small shared memory region - ASSERT_NE(-1, (job = mmap(0, __granularity(), PROT_READ | PROT_WRITE, + ASSERT_NE(-1, (job = mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0))); job[0] = 2; // create workload job[1] = 2; @@ -100,7 +100,7 @@ TEST(pledge, default_allowsExit) { EXPECT_TRUE(WIFEXITED(ws)); EXPECT_EQ(0, WEXITSTATUS(ws)); EXPECT_EQ(4, job[0]); // check result - EXPECT_SYS(0, 0, munmap(job, __granularity())); + EXPECT_SYS(0, 0, munmap(job, getpagesize())); } TEST(pledge, execpromises_notok) { @@ -298,7 +298,7 @@ TEST(pledge, stdioTty_sendtoRestricted_requiresNullAddr) { errno = 0; // set lower 32-bit word of pointer to zero lool struct sockaddr_in *sin = - mmap((void *)0x300000000000, __granularity(), PROT_READ | PROT_WRITE, + mmap((void *)0x300000000000, getpagesize(), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); sin->sin_family = AF_INET; ASSERT_SYS( @@ -334,7 +334,7 @@ TEST(pledge, unix_forbidsInetSockets) { TEST(pledge, wpath_doesNotImplyRpath) { int ws, pid; bool *gotsome; - ASSERT_NE(-1, (gotsome = _mapshared(__granularity()))); + ASSERT_NE(-1, (gotsome = _mapshared(getpagesize()))); ASSERT_SYS(0, 0, touch("foo", 0644)); ASSERT_NE(-1, (pid = fork())); if (!pid) { @@ -412,13 +412,13 @@ TEST(pledge, mmap) { ASSERT_NE(-1, (pid = fork())); if (!pid) { ASSERT_SYS(0, 0, pledge("stdio", 0)); - ASSERT_NE(MAP_FAILED, (p = mmap(0, __granularity(), PROT_READ | PROT_WRITE, + ASSERT_NE(MAP_FAILED, (p = mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0))); - ASSERT_SYS(0, 0, mprotect(p, __granularity(), PROT_READ)); + ASSERT_SYS(0, 0, mprotect(p, getpagesize(), PROT_READ)); ASSERT_SYS(EPERM, MAP_FAILED, - mprotect(p, __granularity(), PROT_READ | PROT_EXEC)); + mprotect(p, getpagesize(), PROT_READ | PROT_EXEC)); ASSERT_SYS(EPERM, MAP_FAILED, - mmap(0, __granularity(), PROT_EXEC | PROT_READ, + mmap(0, getpagesize(), PROT_EXEC | PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)); _Exit(0); } @@ -434,11 +434,11 @@ TEST(pledge, mmapProtExec) { ASSERT_NE(-1, (pid = fork())); if (!pid) { ASSERT_SYS(0, 0, pledge("stdio prot_exec", 0)); - ASSERT_NE(MAP_FAILED, (p = mmap(0, __granularity(), PROT_READ | PROT_WRITE, + ASSERT_NE(MAP_FAILED, (p = mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0))); - ASSERT_SYS(0, 0, mprotect(p, __granularity(), PROT_READ)); - ASSERT_SYS(0, 0, mprotect(p, __granularity(), PROT_READ | PROT_EXEC)); - ASSERT_NE(MAP_FAILED, mmap(0, __granularity(), PROT_EXEC | PROT_READ, + ASSERT_SYS(0, 0, mprotect(p, getpagesize(), PROT_READ)); + ASSERT_SYS(0, 0, mprotect(p, getpagesize(), PROT_READ | PROT_EXEC)); + ASSERT_NE(MAP_FAILED, mmap(0, getpagesize(), PROT_EXEC | PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)); _Exit(0); } diff --git a/test/libc/calls/setrlimit_test.c b/test/libc/calls/setrlimit_test.c index 59ad24782..041d6f606 100644 --- a/test/libc/calls/setrlimit_test.c +++ b/test/libc/calls/setrlimit_test.c @@ -159,15 +159,15 @@ TEST(setrlimit, testVirtualMemoryLimit) { ASSERT_NE(-1, (wstatus = xspawn(0))); if (wstatus == -2) { ASSERT_EQ(0, setrlimit(RLIMIT_AS, &(struct rlimit){MEM, MEM})); - for (i = 0; i < (MEM * 2) / __granularity(); ++i) { - p = sys_mmap(0, __granularity(), PROT_READ | PROT_WRITE, + for (i = 0; i < (MEM * 2) / getpagesize(); ++i) { + p = sys_mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_POPULATE, -1, 0) .addr; if (p == MAP_FAILED) { ASSERT_EQ(ENOMEM, errno); _Exit(0); } - rngset(p, __granularity(), _rand64, -1); + rngset(p, getpagesize(), _rand64, -1); } _Exit(1); } @@ -193,15 +193,15 @@ TEST(setrlimit, testDataMemoryLimit) { ASSERT_NE(-1, (wstatus = xspawn(0))); if (wstatus == -2) { ASSERT_EQ(0, setrlimit(RLIMIT_DATA, &(struct rlimit){MEM, MEM})); - for (i = 0; i < (MEM * 2) / __granularity(); ++i) { - p = sys_mmap(0, __granularity(), PROT_READ | PROT_WRITE, + for (i = 0; i < (MEM * 2) / getpagesize(); ++i) { + p = sys_mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_POPULATE, -1, 0) .addr; if (p == MAP_FAILED) { ASSERT_EQ(ENOMEM, errno); _Exit(0); } - rngset(p, __granularity(), _rand64, -1); + rngset(p, getpagesize(), _rand64, -1); } _Exit(1); } diff --git a/test/libc/calls/unveil_test.c b/test/libc/calls/unveil_test.c index 2e3c97a4f..f0f361cb2 100644 --- a/test/libc/calls/unveil_test.c +++ b/test/libc/calls/unveil_test.c @@ -335,7 +335,7 @@ TEST(unveil, isThreadSpecificOnLinux_isProcessWideOnOpenbsd) { TEST(unveil, usedTwice_forbidden_worksWithPledge) { int ws, pid; bool *gotsome; - ASSERT_NE(-1, (gotsome = _mapshared(__granularity()))); + ASSERT_NE(-1, (gotsome = _mapshared(getpagesize()))); ASSERT_NE(-1, (pid = fork())); if (!pid) { __pledge_mode = PLEDGE_PENALTY_KILL_PROCESS; @@ -359,7 +359,7 @@ TEST(unveil, usedTwice_forbidden_worksWithPledge) { ASSERT_TRUE(*gotsome); ASSERT_TRUE(WIFSIGNALED(ws)); ASSERT_EQ(IsOpenbsd() ? SIGABRT : SIGSYS, WTERMSIG(ws)); - EXPECT_SYS(0, 0, munmap(gotsome, __granularity())); + EXPECT_SYS(0, 0, munmap(gotsome, getpagesize())); } TEST(unveil, lotsOfPaths) { diff --git a/test/libc/intrin/kprintf_test.c b/test/libc/intrin/kprintf_test.c index d4d911784..1ec8889ff 100644 --- a/test/libc/intrin/kprintf_test.c +++ b/test/libc/intrin/kprintf_test.c @@ -277,7 +277,7 @@ TEST(ksnprintf, testMisalignedPointer_wontFormat) { TEST(ksnprintf, testUnterminatedOverrun_truncatesAtPageBoundary) { char *m; char b[32]; - int gran = __granularity(); + int gran = getgransize(); m = memset(_mapanon(gran * 2), 1, gran); EXPECT_SYS(0, 0, munmap(m + gran, gran)); EXPECT_EQ(12, ksnprintf(b, 32, "%'s", m + gran - 3)); diff --git a/test/libc/intrin/lockipc_test.c b/test/libc/intrin/lockipc_test.c index 1dd48d41b..6e9b84d52 100644 --- a/test/libc/intrin/lockipc_test.c +++ b/test/libc/intrin/lockipc_test.c @@ -47,7 +47,7 @@ TEST(lockipc, mutex) { int e, rc, ws, pid; // create shared memory - shm = _mapshared(__granularity()); + shm = _mapshared(getpagesize()); // create shared mutex pthread_mutexattr_t mattr; @@ -86,5 +86,5 @@ TEST(lockipc, mutex) { EXPECT_EQ(PROCESSES * ITERATIONS, shm->x); ASSERT_EQ(0, pthread_mutex_destroy(&shm->mutex)); - ASSERT_SYS(0, 0, munmap(shm, __granularity())); + ASSERT_SYS(0, 0, munmap(shm, getpagesize())); } diff --git a/test/libc/intrin/mmap_scalability_test.c b/test/libc/intrin/mmap_scalability_test.c index 26982fbbe..46928abff 100644 --- a/test/libc/intrin/mmap_scalability_test.c +++ b/test/libc/intrin/mmap_scalability_test.c @@ -20,6 +20,7 @@ #include "libc/calls/struct/timespec.h" #include "libc/dce.h" #include "libc/intrin/kprintf.h" +#include "libc/intrin/maps.h" #include "libc/runtime/runtime.h" #include "libc/sysv/consts/map.h" #include "libc/sysv/consts/prot.h" @@ -38,13 +39,6 @@ kprintf("%'20ld ns %2dx %s\n", (long)nanos, (ITERATIONS), #CODE); \ } while (0) -void *randaddr(void) { - static unsigned long lcg = 1; - lcg *= 6364136223846793005; - lcg += 1442695040888963407; - return (void *)(lcg >> 48 << 28); -} - void map_unmap_one_page(void) { void *p; if ((p = mmap(randaddr(), 1, PROT_READ | PROT_WRITE, diff --git a/test/libc/intrin/mmap_test.c b/test/libc/intrin/mmap_test.c index bf9eee74a..80ca31c7e 100644 --- a/test/libc/intrin/mmap_test.c +++ b/test/libc/intrin/mmap_test.c @@ -18,37 +18,22 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "ape/sections.internal.h" #include "libc/calls/calls.h" -#include "libc/calls/syscall-sysv.internal.h" -#include "libc/calls/ucontext.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/atomic.h" -#include "libc/intrin/kprintf.h" -#include "libc/intrin/safemacros.internal.h" -#include "libc/intrin/xchg.internal.h" +#include "libc/intrin/maps.h" #include "libc/limits.h" -#include "libc/log/log.h" -#include "libc/macros.internal.h" -#include "libc/mem/gc.h" -#include "libc/mem/mem.h" -#include "libc/runtime/memtrack.internal.h" #include "libc/runtime/runtime.h" -#include "libc/runtime/stack.h" #include "libc/runtime/sysconf.h" #include "libc/stdio/rand.h" #include "libc/stdio/stdio.h" #include "libc/str/str.h" -#include "libc/sysv/consts/auxv.h" #include "libc/sysv/consts/map.h" #include "libc/sysv/consts/msync.h" #include "libc/sysv/consts/o.h" #include "libc/sysv/consts/prot.h" -#include "libc/sysv/consts/sa.h" -#include "libc/sysv/consts/sig.h" #include "libc/testlib/ezbench.h" #include "libc/testlib/testlib.h" #include "libc/x/xspawn.h" -#include "third_party/xed/x86.h" // this is also a good torture test for mmap // @@ -61,11 +46,11 @@ __static_yoink("zipos"); int pagesz; -int granularity; +int gransz; void SetUpOnce(void) { pagesz = getpagesize(); - granularity = __granularity(); + gransz = getgransize(); testlib_enable_tmp_setup_teardown(); // ASSERT_SYS(0, 0, pledge("stdio rpath wpath cpath proc", 0)); } @@ -109,7 +94,7 @@ TEST(mmap, pageBeyondGone) { MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); ASSERT_NE(MAP_FAILED, p); EXPECT_TRUE(testlib_memoryexists(p)); - EXPECT_TRUE(testlib_memoryexists(p + pagesz - 1)); + EXPECT_FALSE(testlib_memoryexists(p + 1)); // b/c kisdangerous EXPECT_FALSE(testlib_memoryexists(p + pagesz)); ASSERT_EQ(0, munmap(p, 1)); } @@ -124,47 +109,76 @@ TEST(mmap, fixedTaken) { } TEST(mmap, hint) { - char *p, *q; + char *p; // obtain four pages - EXPECT_NE(MAP_FAILED, (p = mmap(NULL, granularity * 4, PROT_READ, + ASSERT_NE(MAP_FAILED, (p = mmap(randaddr(), gransz * 4, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); // unmap two of those pages - EXPECT_SYS(0, 0, munmap(p + granularity, granularity)); - EXPECT_SYS(0, 0, munmap(p + granularity * 3, granularity)); + EXPECT_SYS(0, 0, munmap(p + gransz, gransz)); + EXPECT_SYS(0, 0, munmap(p + gransz * 3, gransz)); // test AVAILABLE nonfixed nonzero addr is granted // - posix doesn't mandate this behavior (but should) // - freebsd always chooses for you (which has no acceptable workaround) // - netbsd manual claims it'll be like freebsd, but is actually like openbsd if (!IsFreebsd()) - EXPECT_EQ(p + granularity, mmap(p + granularity, granularity, PROT_READ, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)); + ASSERT_EQ(p + gransz, mmap(p + gransz, gransz, PROT_READ, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)); // test UNAVAILABLE nonfixed nonzero addr picks something nearby // - posix actually does require this, but doesn't say how close // - xnu / linux / openbsd always choose nearest on the right // - freebsd goes about 16mb to the right // - qemu-user is off the wall - if (!IsQemuUser()) { - q = mmap(p + granularity * 2, granularity, PROT_READ, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - EXPECT_LE(ABS(q - (p + granularity * 2)), 64 * 1024 * 1024); - EXPECT_SYS(0, 0, munmap(q, granularity)); - } + /*if (!IsQemuUser()) { + q = mmap(p + gransz * 2, gransz, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, + 0); + EXPECT_LE(ABS(q - (p + gransz * 2)), 128 * 1024 * 1024); + EXPECT_SYS(0, 0, munmap(q, gransz)); + }*/ // clean up - EXPECT_SYS(0, 0, munmap(p, granularity * 4)); + EXPECT_SYS(0, 0, munmap(p, gransz * 4)); +} + +TEST(mprotect, punchHoleAndFillHole) { + char *p; + int count = __maps.count; + int gransz = getgransize(); + + // obtain memory + ASSERT_NE(MAP_FAILED, + (p = mmap(randaddr(), gransz * 3, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); + ASSERT_EQ((count += IsWindows() ? 3 : 1), __maps.count); + + // if munmap punches a hole... + // the number of mappings may increase + // this is why it's possible for munmap() to ENOMEM lool + EXPECT_SYS(0, 0, munmap(p + gransz, gransz)); + ASSERT_EQ((count += IsWindows() ? -1 : +1), __maps.count); + + // now if we fill that hole + // the memory manager will coalesce the mappings + ASSERT_NE(MAP_FAILED, + (p = mmap(p + gransz, gransz, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0))); + ASSERT_EQ((count += IsWindows() ? +1 : -1), __maps.count); + + // clean up + EXPECT_SYS(0, 0, munmap(p, gransz * 3)); } TEST(mmap, smallerThanPage_mapsRemainder) { long pagesz = sysconf(_SC_PAGESIZE); char *map = - mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + mmap(0, 1, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); ASSERT_NE(MAP_FAILED, map); EXPECT_TRUE(testlib_memoryexists(map)); - EXPECT_TRUE(testlib_memoryexists(map + (pagesz - 1))); + EXPECT_TRUE(testlib_pokememory(map + (pagesz - 1))); + EXPECT_TRUE(!testlib_memoryexists(map + (pagesz - 1))); EXPECT_SYS(0, 0, munmap(map, 1)); EXPECT_FALSE(testlib_memoryexists(map)); EXPECT_FALSE(testlib_memoryexists(map + (pagesz - 1))); @@ -178,7 +192,7 @@ TEST(mmap, testMapFile) { ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644))); EXPECT_EQ(5, write(fd, "hello", 5)); EXPECT_NE(-1, fdatasync(fd)); - EXPECT_NE(MAP_FAILED, (p = mmap(NULL, 5, PROT_READ, MAP_PRIVATE, fd, 0))); + ASSERT_NE(MAP_FAILED, (p = mmap(NULL, 5, PROT_READ, MAP_PRIVATE, fd, 0))); EXPECT_STREQN("hello", p, 5); EXPECT_NE(-1, munmap(p, 5)); EXPECT_NE(-1, close(fd)); @@ -192,7 +206,7 @@ TEST(mmap, testMapFile_fdGetsClosed_makesNoDifference) { ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644))); EXPECT_EQ(5, write(fd, "hello", 5)); EXPECT_NE(-1, fdatasync(fd)); - EXPECT_NE(MAP_FAILED, + ASSERT_NE(MAP_FAILED, (p = mmap(NULL, 5, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0))); EXPECT_NE(-1, close(fd)); EXPECT_STREQN("hello", p, 5); @@ -209,7 +223,7 @@ TEST(mmap, testMapFile_fdGetsClosed_makesNoDifference) { TEST(mmap, fileOffset) { int fd; char *map; - int offset_align = IsWindows() ? granularity : getpagesize(); + int offset_align = IsWindows() ? gransz : getpagesize(); ASSERT_NE(-1, (fd = open("foo", O_CREAT | O_RDWR, 0644))); EXPECT_NE(-1, ftruncate(fd, offset_align * 2)); EXPECT_NE(-1, pwrite(fd, "hello", 5, offset_align * 0)); @@ -226,13 +240,13 @@ TEST(mmap, mapPrivate_writesDontChangeFile) { int fd; char *map, buf[6]; ASSERT_NE(-1, (fd = open("bar", O_CREAT | O_RDWR, 0644))); - EXPECT_NE(-1, ftruncate(fd, granularity)); + EXPECT_NE(-1, ftruncate(fd, gransz)); EXPECT_NE(-1, pwrite(fd, "hello", 5, 0)); - ASSERT_NE(MAP_FAILED, (map = mmap(NULL, granularity, PROT_READ | PROT_WRITE, + ASSERT_NE(MAP_FAILED, (map = mmap(NULL, gransz, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0))); memcpy(map, "there", 5); - EXPECT_NE(-1, msync(map, granularity, MS_SYNC)); - EXPECT_NE(-1, munmap(map, granularity)); + EXPECT_NE(-1, msync(map, gransz, MS_SYNC)); + EXPECT_NE(-1, munmap(map, gransz)); EXPECT_NE(-1, pread(fd, buf, 6, 0)); EXPECT_EQ(0, memcmp(buf, "hello", 5), "%#.*s", 5, buf); EXPECT_NE(-1, close(fd)); @@ -245,7 +259,7 @@ TEST(mmap, ziposCannotBeShared) { void *p; ASSERT_NE(-1, (fd = open(ziposLifePath, O_RDONLY), "%s", ziposLifePath)); EXPECT_SYS(EINVAL, MAP_FAILED, - (p = mmap(NULL, granularity, PROT_READ, MAP_SHARED, fd, 0))); + (p = mmap(NULL, gransz, PROT_READ, MAP_SHARED, fd, 0))); close(fd); } @@ -257,9 +271,9 @@ TEST(mmap, ziposCow) { void *p; ASSERT_NE(-1, (fd = open(ziposLifePath, O_RDONLY), "%s", ziposLifePath)); EXPECT_NE(MAP_FAILED, - (p = mmap(NULL, granularity, PROT_READ, MAP_PRIVATE, fd, 0))); + (p = mmap(NULL, gransz, PROT_READ, MAP_PRIVATE, fd, 0))); EXPECT_STREQN("\177ELF", ((const char *)p), 4); - EXPECT_NE(-1, munmap(p, granularity)); + EXPECT_NE(-1, munmap(p, gransz)); EXPECT_NE(-1, close(fd)); } @@ -270,7 +284,7 @@ TEST(mmap, ziposCowFileMapReadonlyFork) { int fd, ws; void *p; ASSERT_NE(-1, (fd = open(ziposLifePath, O_RDONLY), "%s", ziposLifePath)); - EXPECT_NE(MAP_FAILED, (p = mmap(NULL, 4, PROT_READ, MAP_PRIVATE, fd, 0))); + ASSERT_NE(MAP_FAILED, (p = mmap(NULL, 4, PROT_READ, MAP_PRIVATE, fd, 0))); EXPECT_STREQN("ELF", ((const char *)p) + 1, 3); ASSERT_NE(-1, (ws = xspawn(0))); if (ws == -2) { @@ -291,7 +305,7 @@ TEST(mmap, ziposCowFileMapFork) { void *p; char lol[4]; ASSERT_NE(-1, (fd = open(ziposLifePath, O_RDONLY), "%s", ziposLifePath)); - EXPECT_NE(MAP_FAILED, + ASSERT_NE(MAP_FAILED, (p = mmap(NULL, 6, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0))); memcpy(p, "parnt", 6); ASSERT_NE(-1, (ws = xspawn(0))); @@ -321,7 +335,7 @@ TEST(mmap, cow) { path); EXPECT_EQ(5, write(fd, "hello", 5)); EXPECT_NE(-1, fdatasync(fd)); - EXPECT_NE(MAP_FAILED, (p = mmap(NULL, 5, PROT_READ, MAP_PRIVATE, fd, 0))); + ASSERT_NE(MAP_FAILED, (p = mmap(NULL, 5, PROT_READ, MAP_PRIVATE, fd, 0))); EXPECT_STREQN("hello", p, 5); EXPECT_NE(-1, munmap(p, 5)); EXPECT_NE(-1, close(fd)); @@ -340,7 +354,7 @@ TEST(mmap, cowFileMapReadonlyFork) { EXPECT_EQ(6, write(fd, "hello", 6)); EXPECT_NE(-1, close(fd)); ASSERT_NE(-1, (fd = open(path, O_RDONLY))); - EXPECT_NE(MAP_FAILED, (p = mmap(NULL, 6, PROT_READ, MAP_PRIVATE, fd, 0))); + ASSERT_NE(MAP_FAILED, (p = mmap(NULL, 6, PROT_READ, MAP_PRIVATE, fd, 0))); EXPECT_STREQN("hello", p, 5); ASSERT_NE(-1, (ws = xspawn(0))); if (ws == -2) { @@ -365,7 +379,7 @@ TEST(mmap, cowFileMapFork) { ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644))); EXPECT_EQ(6, write(fd, "parnt", 6)); EXPECT_NE(-1, fdatasync(fd)); - EXPECT_NE(MAP_FAILED, + ASSERT_NE(MAP_FAILED, (p = mmap(NULL, 6, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0))); EXPECT_STREQN("parnt", p, 5); ASSERT_NE(-1, (ws = xspawn(0))); @@ -390,7 +404,7 @@ TEST(mmap, cowFileMapFork) { TEST(mmap, sharedAnonMapFork) { int ws; char *p; - EXPECT_NE(MAP_FAILED, (p = mmap(NULL, 6, PROT_READ | PROT_WRITE, + ASSERT_NE(MAP_FAILED, (p = mmap(NULL, 6, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0))); strcpy(p, "parnt"); EXPECT_STREQN("parnt", p, 5); @@ -417,7 +431,7 @@ TEST(mmap, sharedFileMapFork) { ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644))); EXPECT_EQ(6, write(fd, "parnt", 6)); EXPECT_NE(-1, fdatasync(fd)); - EXPECT_NE(MAP_FAILED, + ASSERT_NE(MAP_FAILED, (p = mmap(NULL, 6, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0))); EXPECT_STREQN("parnt", p, 5); ASSERT_NE(-1, (ws = xspawn(0))); @@ -449,15 +463,15 @@ void *ptrs[N]; void BenchMmapPrivate(void) { void *p; - p = mmap(0, granularity * 10, PROT_READ | PROT_WRITE, - MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + p = mmap(0, gransz * 10, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, + -1, 0); if (p == MAP_FAILED) __builtin_trap(); ptrs[count++] = p; } void BenchUnmap(void) { - if (munmap(ptrs[--count], granularity * 10)) + if (munmap(ptrs[--count], gransz * 10)) __builtin_trap(); } diff --git a/test/libc/intrin/mprotect_test.c b/test/libc/intrin/mprotect_test.c index 6a2e23b1f..8466d665b 100644 --- a/test/libc/intrin/mprotect_test.c +++ b/test/libc/intrin/mprotect_test.c @@ -147,18 +147,18 @@ TEST(mprotect, testSegfault_writeToReadOnlyAnonymous) { } TEST(mprotect, testExecOnly_canExecute) { - char *p = _mapanon(__granularity()); + char *p = _mapanon(getpagesize()); void (*f)(void) = (void *)p; memcpy(p, kRet31337, sizeof(kRet31337)); - ASSERT_SYS(0, 0, mprotect(p, __granularity(), PROT_EXEC | PROT_READ)); + ASSERT_SYS(0, 0, mprotect(p, getpagesize(), PROT_EXEC | PROT_READ)); f(); // On all supported platforms, PROT_EXEC implies PROT_READ. There is // one exception to this rule: Chromebook's fork of the Linux kernel // which has been reported, to have the ability to prevent a program // from reading its own code. - ASSERT_SYS(0, 0, mprotect(p, __granularity(), PROT_EXEC)); + ASSERT_SYS(0, 0, mprotect(p, getpagesize(), PROT_EXEC)); f(); - munmap(p, __granularity()); + munmap(p, getpagesize()); } TEST(mprotect, testProtNone_cantEvenRead) { @@ -249,3 +249,41 @@ TEST(mprotect, image) { EXPECT_SYS(0, 0, mprotect(p, 16384, PROT_READ | PROT_WRITE)); EXPECT_EQ(2, ++p[0]); } + +TEST(mprotect, weirdSize) { + char *p; + EXPECT_NE(MAP_FAILED, (p = mmap(0, 1, PROT_READ | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); + EXPECT_SYS(0, 0, mprotect(p, 2, PROT_NONE)); + EXPECT_SYS(0, 0, munmap(p, 1)); +} + +TEST(mprotect, outerOverlap) { + char *p; + int gransz = getgransize(); + EXPECT_NE(MAP_FAILED, (p = mmap(0, gransz * 3, PROT_READ | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); + EXPECT_TRUE(testlib_memoryexists(p + gransz * 0)); + EXPECT_TRUE(testlib_memoryexists(p + gransz * 1)); + EXPECT_TRUE(testlib_memoryexists(p + gransz * 2)); + EXPECT_SYS(0, 0, munmap(p, gransz)); + EXPECT_FALSE(testlib_memoryexists(p + gransz * 0)); + EXPECT_TRUE(testlib_memoryexists(p + gransz * 1)); + EXPECT_TRUE(testlib_memoryexists(p + gransz * 2)); + EXPECT_SYS(0, 0, munmap(p + gransz * 2, gransz)); + EXPECT_FALSE(testlib_memoryexists(p + gransz * 0)); + EXPECT_TRUE(testlib_memoryexists(p + gransz * 1)); + EXPECT_FALSE(testlib_memoryexists(p + gransz * 2)); + EXPECT_SYS(0, 0, mprotect(p, gransz * 3, PROT_NONE)); + EXPECT_FALSE(testlib_memoryexists(p + gransz * 0)); + EXPECT_FALSE(testlib_memoryexists(p + gransz * 1)); + EXPECT_FALSE(testlib_memoryexists(p + gransz * 2)); + EXPECT_SYS(0, 0, mprotect(p + gransz, gransz, PROT_READ)); + EXPECT_FALSE(testlib_memoryexists(p + gransz * 0)); + EXPECT_TRUE(testlib_memoryexists(p + gransz * 1)); + EXPECT_FALSE(testlib_memoryexists(p + gransz * 2)); + EXPECT_SYS(0, 0, munmap(p, gransz * 3)); + EXPECT_FALSE(testlib_memoryexists(p + gransz * 0)); + EXPECT_FALSE(testlib_memoryexists(p + gransz * 1)); + EXPECT_FALSE(testlib_memoryexists(p + gransz * 2)); +} diff --git a/test/libc/intrin/mremap_test.c b/test/libc/intrin/mremap_test.c new file mode 100644 index 000000000..4a6e704d7 --- /dev/null +++ b/test/libc/intrin/mremap_test.c @@ -0,0 +1,178 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-β”‚ +β”‚ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi β”‚ +β•žβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•‘ +β”‚ Copyright 2024 Justine Alexandra Roberts Tunney β”‚ +β”‚ β”‚ +β”‚ Permission to use, copy, modify, and/or distribute this software for β”‚ +β”‚ any purpose with or without fee is hereby granted, provided that the β”‚ +β”‚ above copyright notice and this permission notice appear in all copies. β”‚ +β”‚ β”‚ +β”‚ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL β”‚ +β”‚ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED β”‚ +β”‚ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE β”‚ +β”‚ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL β”‚ +β”‚ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR β”‚ +β”‚ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER β”‚ +β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ +β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ +β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/sysv/consts/mremap.h" +#include "libc/calls/calls.h" +#include "libc/calls/struct/timespec.h" +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/intrin/kprintf.h" +#include "libc/intrin/maps.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/mremap.h" +#include "libc/sysv/consts/prot.h" +#include "libc/testlib/testlib.h" + +void SetUpOnce(void) { + if (!IsLinux() && !IsNetbsd()) { + tinyprint(2, "warning: skipping mremap() tests on this os\n", NULL); + exit(0); + } +} + +TEST(mremap, dontMove_hasRoom_itMoves) { + if (IsNetbsd()) + return; // NetBSD requires MREMAP_MAYMOVE + char *p; + int pagesz = getpagesize(); + ASSERT_NE(MAP_FAILED, (p = mmap(randaddr(), pagesz, PROT_READ | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); + EXPECT_TRUE(testlib_memoryexists(p)); + EXPECT_FALSE(testlib_memoryexists(p + pagesz)); + ASSERT_SYS(0, p, mremap(p, pagesz, pagesz * 2, 0)); + EXPECT_TRUE(testlib_memoryexists(p)); + EXPECT_TRUE(testlib_memoryexists(p + pagesz)); + ASSERT_SYS(0, 0, munmap(p, pagesz * 2)); + EXPECT_FALSE(testlib_memoryexists(p)); + EXPECT_FALSE(testlib_memoryexists(p + pagesz)); +} + +TEST(mremap, dontMove_noRoom_itFailsWithEnomem) { + if (IsNetbsd()) + return; // NetBSD requires MREMAP_MAYMOVE + char *p; + int pagesz = getpagesize(); + ASSERT_NE(MAP_FAILED, (p = mmap(randaddr(), pagesz * 2, PROT_READ | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); + EXPECT_TRUE(testlib_memoryexists(p + pagesz * 0)); + EXPECT_TRUE(testlib_memoryexists(p + pagesz * 1)); + EXPECT_FALSE(testlib_memoryexists(p + pagesz * 2)); + ASSERT_SYS(ENOMEM, MAP_FAILED, mremap(p, pagesz, pagesz * 3, 0)); + EXPECT_TRUE(testlib_memoryexists(p + pagesz * 0)); + EXPECT_TRUE(testlib_memoryexists(p + pagesz * 1)); + EXPECT_FALSE(testlib_memoryexists(p + pagesz * 2)); + ASSERT_SYS(0, 0, munmap(p, pagesz * 2)); + EXPECT_FALSE(testlib_memoryexists(p + pagesz * 0)); + EXPECT_FALSE(testlib_memoryexists(p + pagesz * 1)); + EXPECT_FALSE(testlib_memoryexists(p + pagesz * 2)); +} + +TEST(mremap, mayMove_noRoom_itRelocates) { + char *p, *p2; + int pagesz = getpagesize(); + ASSERT_NE(MAP_FAILED, (p = mmap(randaddr(), pagesz * 2, PROT_READ | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); + EXPECT_TRUE(testlib_memoryexists(p + pagesz * 0)); + EXPECT_TRUE(testlib_memoryexists(p + pagesz * 1)); + EXPECT_FALSE(testlib_memoryexists(p + pagesz * 2)); + ASSERT_NE(MAP_FAILED, (p2 = mremap(p, pagesz, pagesz * 3, MREMAP_MAYMOVE))); + ASSERT_NE(p, p2); + EXPECT_FALSE(testlib_memoryexists(p + pagesz * 0)); + EXPECT_TRUE(testlib_memoryexists(p + pagesz * 1)); + EXPECT_FALSE(testlib_memoryexists(p + pagesz * 2)); + EXPECT_TRUE(testlib_memoryexists(p2 + pagesz * 0)); + EXPECT_TRUE(testlib_memoryexists(p2 + pagesz * 1)); + EXPECT_TRUE(testlib_memoryexists(p2 + pagesz * 2)); + ASSERT_SYS(0, 0, munmap(p + pagesz, pagesz)); + ASSERT_SYS(0, 0, munmap(p2, pagesz * 3)); + EXPECT_FALSE(testlib_memoryexists(p + pagesz * 0)); + EXPECT_FALSE(testlib_memoryexists(p + pagesz * 1)); + EXPECT_FALSE(testlib_memoryexists(p + pagesz * 2)); + EXPECT_FALSE(testlib_memoryexists(p2 + pagesz * 0)); + EXPECT_FALSE(testlib_memoryexists(p2 + pagesz * 1)); + EXPECT_FALSE(testlib_memoryexists(p2 + pagesz * 2)); +} + +// demonstrate value of mremap() system call +// +// mmap(1'048'576) took 1'130 ns +// mremap(1'048'576 -> 2'097'152) took 3'117 ns +// mremap(2'097'152 -> 1'048'576) took 3'596 ns +// mremap(1'048'576 -> 2'097'152) took 796'381 ns [simulated] +// munmap(2'097'152) took 50'020 ns +// + +TEST(mremap, bench) { +#define N 10 + long size = 1024 * 1024; + char *rollo = randaddr(); + char *addr[N]; + + // create mappings + struct timespec ts1 = timespec_real(); + for (long i = 0; i < N; ++i) + if ((addr[i] = mmap((rollo += size), size, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)) == MAP_FAILED) { + kprintf("first mmap failed: %m\n"); + exit(1); + } + kprintf("mmap(%'zu) took %'ld ns\n", size, + timespec_tonanos(timespec_sub(timespec_real(), ts1)) / N); + + // use mremap to grow mappings + ts1 = timespec_real(); + for (long i = 0; i < N; ++i) + if ((addr[i] = mremap(addr[i], size, size * 2, MREMAP_MAYMOVE)) == + MAP_FAILED) { + kprintf("grow mremap failed: %m\n"); + exit(1); + } + kprintf("mremap(%'zu -> %'zu) took %'ld ns\n", size, size * 2, + timespec_tonanos(timespec_sub(timespec_real(), ts1)) / N); + + // use mremap to shrink mappings + ts1 = timespec_real(); + for (long i = 0; i < N; ++i) + if (mremap(addr[i], size * 2, size, 0) != addr[i]) { + kprintf("shrink mremap failed: %m\n"); + exit(1); + } + kprintf("mremap(%'zu -> %'zu) took %'ld ns\n", size * 2, size, + timespec_tonanos(timespec_sub(timespec_real(), ts1)) / N); + + // do the thing that mremap is trying to optimize + ts1 = timespec_real(); + for (long i = 0; i < N; ++i) { + char *addr2; + if ((addr2 = mmap(0, size * 2, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)) == MAP_FAILED) { + kprintf("simulated mmap failed: %m\n"); + exit(1); + } + memmove(addr2, addr[i], size); + if (munmap(addr[i], size)) { + kprintf("simulated munmap failed: %m\n"); + exit(1); + } + addr[i] = addr2; + } + kprintf("mremap(%'zu -> %'zu) took %'ld ns [simulated]\n", size, size * 2, + timespec_tonanos(timespec_sub(timespec_real(), ts1)) / N); + + // unmap mappings + ts1 = timespec_real(); + for (long i = 0; i < N; ++i) + if (munmap(addr[i], size * 2)) { + kprintf("munmap failed: %m\n"); + exit(1); + } + kprintf("munmap(%'zu) took %'ld ns\n", size * 2, + timespec_tonanos(timespec_sub(timespec_real(), ts1)) / N); +} diff --git a/test/libc/intrin/munmap_test.c b/test/libc/intrin/munmap_test.c index a420ad659..8ae6fb635 100644 --- a/test/libc/intrin/munmap_test.c +++ b/test/libc/intrin/munmap_test.c @@ -19,6 +19,7 @@ #include "libc/calls/calls.h" #include "libc/dce.h" #include "libc/errno.h" +#include "libc/intrin/maps.h" #include "libc/log/log.h" #include "libc/runtime/runtime.h" #include "libc/sysv/consts/map.h" @@ -26,116 +27,116 @@ #include "libc/sysv/consts/prot.h" #include "libc/testlib/testlib.h" -int granularity; +int gransz; void SetUpOnce(void) { - granularity = __granularity(); + gransz = getgransize(); testlib_enable_tmp_setup_teardown(); } TEST(munmap, doesntExist_doesntCare) { - EXPECT_SYS(0, 0, munmap(0, granularity * 8)); + EXPECT_SYS(0, 0, munmap(0, gransz * 8)); } TEST(munmap, invalidParams) { EXPECT_SYS(EINVAL, -1, munmap(0, 0)); EXPECT_SYS(EINVAL, -1, munmap((void *)0x100080000000, 0)); - EXPECT_SYS(EINVAL, -1, munmap((void *)0x100080000001, granularity)); + EXPECT_SYS(EINVAL, -1, munmap((void *)0x100080000001, gransz)); } TEST(munmap, test) { char *p; - ASSERT_NE(MAP_FAILED, (p = mmap(0, granularity, PROT_READ | PROT_WRITE, + ASSERT_NE(MAP_FAILED, (p = mmap(0, gransz, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0))); EXPECT_TRUE(testlib_memoryexists(p)); - EXPECT_SYS(0, 0, munmap(p, granularity)); + EXPECT_SYS(0, 0, munmap(p, gransz)); EXPECT_FALSE(testlib_memoryexists(p)); } TEST(munmap, punchHoleInMemory) { char *p; - ASSERT_NE(MAP_FAILED, (p = mmap(0, granularity * 3, PROT_READ | PROT_WRITE, + ASSERT_NE(MAP_FAILED, (p = mmap(0, gransz * 3, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0))); - EXPECT_TRUE(testlib_memoryexists(p + granularity * 0)); - EXPECT_TRUE(testlib_memoryexists(p + granularity * 1)); - EXPECT_TRUE(testlib_memoryexists(p + granularity * 2)); - EXPECT_SYS(0, 0, munmap(p + granularity, granularity)); - EXPECT_TRUE(testlib_memoryexists(p + granularity * 0)); - EXPECT_FALSE(testlib_memoryexists(p + granularity * 1)); - EXPECT_TRUE(testlib_memoryexists(p + granularity * 2)); - EXPECT_SYS(0, 0, munmap(p, granularity)); - EXPECT_SYS(0, 0, munmap(p + granularity * 2, granularity)); - EXPECT_FALSE(testlib_memoryexists(p + granularity * 0)); - EXPECT_FALSE(testlib_memoryexists(p + granularity * 1)); - EXPECT_FALSE(testlib_memoryexists(p + granularity * 2)); + EXPECT_TRUE(testlib_memoryexists(p + gransz * 0)); + EXPECT_TRUE(testlib_memoryexists(p + gransz * 1)); + EXPECT_TRUE(testlib_memoryexists(p + gransz * 2)); + EXPECT_SYS(0, 0, munmap(p + gransz, gransz)); + EXPECT_TRUE(testlib_memoryexists(p + gransz * 0)); + EXPECT_FALSE(testlib_memoryexists(p + gransz * 1)); + EXPECT_TRUE(testlib_memoryexists(p + gransz * 2)); + EXPECT_SYS(0, 0, munmap(p, gransz)); + EXPECT_SYS(0, 0, munmap(p + gransz * 2, gransz)); + EXPECT_FALSE(testlib_memoryexists(p + gransz * 0)); + EXPECT_FALSE(testlib_memoryexists(p + gransz * 1)); + EXPECT_FALSE(testlib_memoryexists(p + gransz * 2)); } TEST(munmap, memoryHasHole) { char *p; - ASSERT_NE(MAP_FAILED, (p = mmap(0, granularity * 3, PROT_READ | PROT_WRITE, + ASSERT_NE(MAP_FAILED, (p = mmap(0, gransz * 3, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0))); - EXPECT_SYS(0, 0, munmap(p + granularity, granularity)); - EXPECT_TRUE(testlib_memoryexists(p + granularity * 0)); - EXPECT_FALSE(testlib_memoryexists(p + granularity * 1)); - EXPECT_TRUE(testlib_memoryexists(p + granularity * 2)); - EXPECT_SYS(0, 0, munmap(p, granularity * 3)); - EXPECT_FALSE(testlib_memoryexists(p + granularity * 0)); - EXPECT_FALSE(testlib_memoryexists(p + granularity * 1)); - EXPECT_FALSE(testlib_memoryexists(p + granularity * 2)); + EXPECT_SYS(0, 0, munmap(p + gransz, gransz)); + EXPECT_TRUE(testlib_memoryexists(p + gransz * 0)); + EXPECT_FALSE(testlib_memoryexists(p + gransz * 1)); + EXPECT_TRUE(testlib_memoryexists(p + gransz * 2)); + EXPECT_SYS(0, 0, munmap(p, gransz * 3)); + EXPECT_FALSE(testlib_memoryexists(p + gransz * 0)); + EXPECT_FALSE(testlib_memoryexists(p + gransz * 1)); + EXPECT_FALSE(testlib_memoryexists(p + gransz * 2)); } TEST(munmap, blanketFree) { char *p; - ASSERT_NE(MAP_FAILED, (p = mmap(0, granularity * 3, PROT_READ | PROT_WRITE, + ASSERT_NE(MAP_FAILED, (p = mmap(0, gransz * 3, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0))); - EXPECT_TRUE(testlib_memoryexists(p + granularity * 0)); - EXPECT_TRUE(testlib_memoryexists(p + granularity * 1)); - EXPECT_TRUE(testlib_memoryexists(p + granularity * 2)); - EXPECT_SYS(0, 0, munmap(p + granularity * 0, granularity)); - EXPECT_SYS(0, 0, munmap(p + granularity * 2, granularity)); - EXPECT_FALSE(testlib_memoryexists(p + granularity * 0)); - EXPECT_TRUE(testlib_memoryexists(p + granularity * 1)); - EXPECT_FALSE(testlib_memoryexists(p + granularity * 2)); - EXPECT_SYS(0, 0, munmap(p, granularity * 3)); - EXPECT_FALSE(testlib_memoryexists(p + granularity * 0)); - EXPECT_FALSE(testlib_memoryexists(p + granularity * 1)); - EXPECT_FALSE(testlib_memoryexists(p + granularity * 2)); + EXPECT_TRUE(testlib_memoryexists(p + gransz * 0)); + EXPECT_TRUE(testlib_memoryexists(p + gransz * 1)); + EXPECT_TRUE(testlib_memoryexists(p + gransz * 2)); + EXPECT_SYS(0, 0, munmap(p + gransz * 0, gransz)); + EXPECT_SYS(0, 0, munmap(p + gransz * 2, gransz)); + EXPECT_FALSE(testlib_memoryexists(p + gransz * 0)); + EXPECT_TRUE(testlib_memoryexists(p + gransz * 1)); + EXPECT_FALSE(testlib_memoryexists(p + gransz * 2)); + EXPECT_SYS(0, 0, munmap(p, gransz * 3)); + EXPECT_FALSE(testlib_memoryexists(p + gransz * 0)); + EXPECT_FALSE(testlib_memoryexists(p + gransz * 1)); + EXPECT_FALSE(testlib_memoryexists(p + gransz * 2)); } TEST(munmap, trimLeft) { char *p; - ASSERT_NE(MAP_FAILED, (p = mmap(0, granularity * 2, PROT_READ | PROT_WRITE, + ASSERT_NE(MAP_FAILED, (p = mmap(0, gransz * 2, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0))); - EXPECT_TRUE(testlib_memoryexists(p + granularity * 0)); - EXPECT_TRUE(testlib_memoryexists(p + granularity * 1)); - EXPECT_SYS(0, 0, munmap(p, granularity)); - EXPECT_FALSE(testlib_memoryexists(p + granularity * 0)); - EXPECT_TRUE(testlib_memoryexists(p + granularity * 1)); - EXPECT_SYS(0, 0, munmap(p, granularity * 2)); - EXPECT_FALSE(testlib_memoryexists(p + granularity * 0)); - EXPECT_FALSE(testlib_memoryexists(p + granularity * 1)); + EXPECT_TRUE(testlib_memoryexists(p + gransz * 0)); + EXPECT_TRUE(testlib_memoryexists(p + gransz * 1)); + EXPECT_SYS(0, 0, munmap(p, gransz)); + EXPECT_FALSE(testlib_memoryexists(p + gransz * 0)); + EXPECT_TRUE(testlib_memoryexists(p + gransz * 1)); + EXPECT_SYS(0, 0, munmap(p, gransz * 2)); + EXPECT_FALSE(testlib_memoryexists(p + gransz * 0)); + EXPECT_FALSE(testlib_memoryexists(p + gransz * 1)); } TEST(munmap, trimRight) { char *p; - ASSERT_NE(MAP_FAILED, (p = mmap(0, granularity * 2, PROT_READ | PROT_WRITE, + ASSERT_NE(MAP_FAILED, (p = mmap(0, gransz * 2, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0))); - EXPECT_TRUE(testlib_memoryexists(p + granularity * 0)); - EXPECT_TRUE(testlib_memoryexists(p + granularity * 1)); - EXPECT_SYS(0, 0, munmap(p + granularity, granularity)); - EXPECT_TRUE(testlib_memoryexists(p + granularity * 0)); - EXPECT_FALSE(testlib_memoryexists(p + granularity * 1)); - EXPECT_SYS(0, 0, munmap(p, granularity * 2)); - EXPECT_FALSE(testlib_memoryexists(p + granularity * 0)); - EXPECT_FALSE(testlib_memoryexists(p + granularity * 1)); + EXPECT_TRUE(testlib_memoryexists(p + gransz * 0)); + EXPECT_TRUE(testlib_memoryexists(p + gransz * 1)); + EXPECT_SYS(0, 0, munmap(p + gransz, gransz)); + EXPECT_TRUE(testlib_memoryexists(p + gransz * 0)); + EXPECT_FALSE(testlib_memoryexists(p + gransz * 1)); + EXPECT_SYS(0, 0, munmap(p, gransz * 2)); + EXPECT_FALSE(testlib_memoryexists(p + gransz * 0)); + EXPECT_FALSE(testlib_memoryexists(p + gransz * 1)); } TEST(munmap, memoryGone) { char *p; - ASSERT_NE(MAP_FAILED, (p = mmap(0, granularity, PROT_READ | PROT_WRITE, + ASSERT_NE(MAP_FAILED, (p = mmap(0, gransz, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0))); - EXPECT_SYS(0, 0, munmap(p, granularity)); - EXPECT_SYS(0, 0, munmap(p, granularity)); + EXPECT_SYS(0, 0, munmap(p, gransz)); + EXPECT_SYS(0, 0, munmap(p, gransz)); } TEST(munmap, tinyFile_roundupUnmapSize) { @@ -147,7 +148,7 @@ TEST(munmap, tinyFile_roundupUnmapSize) { ASSERT_NE(MAP_FAILED, (p = mmap(0, 5, PROT_READ, MAP_PRIVATE, 3, 0))); ASSERT_SYS(0, 0, close(3)); EXPECT_TRUE(testlib_memoryexists(p)); - EXPECT_SYS(0, 0, munmap(p, granularity)); + EXPECT_SYS(0, 0, munmap(p, gransz)); EXPECT_FALSE(testlib_memoryexists(p)); EXPECT_FALSE(testlib_memoryexists(p + 5)); } @@ -171,22 +172,22 @@ TEST(munmap, tinyFile_preciseUnmapSize) { } // clang-format off -/* TEST(munmap, tinyFile_mapThriceUnmapOnce) { */ -/* char *p = (char *)0x000063d646e20000; */ -/* ASSERT_SYS(0, 3, open("doge", O_RDWR | O_CREAT | O_TRUNC, 0644)); */ -/* ASSERT_SYS (0, 5, write(3, "hello", 5)); */ -/* ASSERT_EQ(p+granularity*0, mmap(p+granularity*0, granularity, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0)); */ -/* ASSERT_EQ(p+granularity*1, mmap(p+granularity*1, 5, PROT_READ, MAP_PRIVATE|MAP_FIXED, 3, 0)); */ -/* ASSERT_EQ(p+granularity*3, mmap(p+granularity*3, 5, PROT_READ, MAP_PRIVATE|MAP_FIXED, 3, 0)); */ -/* ASSERT_SYS(0, 0, close(3)); */ -/* EXPECT_TRUE(testlib_memoryexists(p+granularity*0)); */ -/* EXPECT_TRUE(testlib_memoryexists(p+granularity*1)); */ -/* EXPECT_FALSE(testlib_memoryexists(p+granularity*2)); */ -/* EXPECT_TRUE(testlib_memoryexists(p+granularity*3)); */ -/* EXPECT_SYS(0, 0, munmap(p, granularity*5)); */ -/* EXPECT_FALSE(testlib_memoryexists(p+granularity*0)); */ -/* EXPECT_FALSE(testlib_memoryexists(p+granularity*1)); */ -/* EXPECT_FALSE(testlib_memoryexists(p+granularity*2)); */ -/* EXPECT_FALSE(testlib_memoryexists(p+granularity*3)); */ -/* } */ +TEST(munmap, tinyFile_mapThriceUnmapOnce) { + char *p = randaddr(); + ASSERT_SYS(0, 3, open("doge", O_RDWR | O_CREAT | O_TRUNC, 0644)); + ASSERT_SYS (0, 5, write(3, "hello", 5)); + ASSERT_EQ(p+gransz*0, mmap(p+gransz*0, gransz, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0)); + ASSERT_EQ(p+gransz*1, mmap(p+gransz*1, 5, PROT_READ, MAP_PRIVATE|MAP_FIXED, 3, 0)); + ASSERT_EQ(p+gransz*3, mmap(p+gransz*3, 5, PROT_READ, MAP_PRIVATE|MAP_FIXED, 3, 0)); + ASSERT_SYS(0, 0, close(3)); + EXPECT_TRUE(testlib_memoryexists(p+gransz*0)); + EXPECT_TRUE(testlib_memoryexists(p+gransz*1)); + EXPECT_FALSE(testlib_memoryexists(p+gransz*2)); + EXPECT_TRUE(testlib_memoryexists(p+gransz*3)); + EXPECT_SYS(0, 0, munmap(p, gransz*5)); + EXPECT_FALSE(testlib_memoryexists(p+gransz*0)); + EXPECT_FALSE(testlib_memoryexists(p+gransz*1)); + EXPECT_FALSE(testlib_memoryexists(p+gransz*2)); + EXPECT_FALSE(testlib_memoryexists(p+gransz*3)); +} // clang-format on diff --git a/test/libc/intrin/tree_test.c b/test/libc/intrin/tree_test.c index 09a8c807e..0f9d3f04d 100644 --- a/test/libc/intrin/tree_test.c +++ b/test/libc/intrin/tree_test.c @@ -16,6 +16,7 @@ #include "libc/intrin/tree.h" #include "libc/intrin/kprintf.h" #include "libc/intrin/maps.h" +#include "libc/intrin/tree.h" #include "libc/macros.internal.h" #include "libc/mem/mem.h" #include "libc/runtime/runtime.h" @@ -71,12 +72,6 @@ struct number { struct Tree elem; }; -int number_search(const void *ra, const struct Tree *rb) { - long a = (long)ra; - const struct number *b = NUMBER_CONTAINER(rb); - return (a > b->number) - (a < b->number); -} - int number_compare(const struct Tree *ra, const struct Tree *rb) { const struct number *a = NUMBER_CONTAINER(ra); const struct number *b = NUMBER_CONTAINER(rb); @@ -90,23 +85,32 @@ struct number *number_new(int number) { return res; } -struct Tree *tree = 0; - -void print(void) { +void print(struct Tree *tree) { for (struct Tree *e = tree_first(tree); e; e = tree_next(e)) kprintf("%3d", NUMBER_CONTAINER(e)->number); kprintf("\n"); } -void print_reversed(void) { +void print_reversed(struct Tree *tree) { for (struct Tree *e = tree_last(tree); e; e = tree_prev(e)) kprintf("%3d", NUMBER_CONTAINER(e)->number); kprintf("\n"); } +int number_search(const void *ra, const struct Tree *rb) { + long a = (long)ra; + const struct number *b = NUMBER_CONTAINER(rb); + return (a > b->number) - (a < b->number); +} + void simple_test(void) { + // 0 2 2 23 30 32 34 34 46 52 53 65 70 74 90 94 95 95 96 96 + // 96 96 95 95 94 90 74 70 65 53 52 46 34 34 32 30 23 2 2 0 static const long kNumba[] = {74, 53, 96, 70, 34, 95, 30, 2, 96, 46, 23, 2, 52, 0, 34, 94, 90, 95, 32, 65}; + + // test insertion works + struct Tree *tree = 0; for (int i = 0; i < 20; ++i) { int number = kNumba[i]; kprintf("%3d", number); @@ -114,26 +118,159 @@ void simple_test(void) { tree_check(tree, number_compare); } kprintf("\n"); - print(); - print_reversed(); + + // test iteration works + print(tree); + + // test reverse iteration works + print_reversed(tree); + + // test removal works for (int i = 0; i < 20; ++i) { tree_remove(&tree, tree_get(tree, (void *)kNumba[i], number_search)); tree_check(tree, number_compare); - print(); + print(tree); } -} -int main() { - ShowCrashReports(); - tree_check(__maps.maps, __maps_compare); - kprintf("\n"); - __print_maps(15); - kprintf("\n"); - simple_test(); - tree_check(__maps.maps, __maps_compare); + // use up a bunch of memory for (int i = 0; i < 100000; ++i) tree_insert(&tree, &number_new(rand())->elem, number_compare); tree_check(tree, number_compare); tree_check(__maps.maps, __maps_compare); - __print_maps(15); + + // visually verify maps get coalesced + __print_maps(0); +} + +void search_test(void) { + struct Tree *x, *tree = 0; + tree_insert(&tree, &number_new(1)->elem, number_compare); + tree_insert(&tree, &number_new(3)->elem, number_compare); + tree_insert(&tree, &number_new(5)->elem, number_compare); + tree_insert(&tree, &number_new(7)->elem, number_compare); + + // Test tree_get() + // + // Returns node equal to given key. + // + // [1 3 5 7] [1 3 5 7] [1 3 5 7] + // NULL ↑ NULL + // 4 3 8 + // + x = tree_get(tree, (void *)4l, number_search); + if (x) + exit(1); + x = tree_get(tree, (void *)3l, number_search); + if (!x) + exit(2); + if (NUMBER_CONTAINER(x)->number != 3) + exit(3); + if (!tree_get(tree, (void *)7l, number_search)) + exit(27); + if (tree_get(tree, (void *)8l, number_search)) + exit(28); + + // Test tree_floor() + // + // Returns last node less than or equal to given key. + // + // [1 3 5 7] [1 3 5 7] [1 3 5 7] + // ↑ ↑ ↑ + // 4 3 8 + // + x = tree_floor(tree, (void *)4l, number_search); + if (!x) + exit(4); + if (NUMBER_CONTAINER(x)->number != 3) + exit(5); + x = tree_floor(tree, (void *)3l, number_search); + if (!x) + exit(6); + if (NUMBER_CONTAINER(x)->number != 3) + exit(7); + if (!tree_floor(tree, (void *)7l, number_search)) + exit(24); + x = tree_floor(tree, (void *)8l, number_search); + if (!x) + exit(25); + if (NUMBER_CONTAINER(x)->number != 7) + exit(30); + if (tree_floor(tree, (void *)0l, number_search)) + exit(31); + + // Test tree_lower() + // + // Returns first node not less than given key. + // + // [1 3 5 7] [1 3 5 7] [1 3 5 7] + // ↑ ↑ NULL + // 4 3 8 + // + x = tree_lower(tree, (void *)4l, number_search); + if (!x) + exit(4); + if (NUMBER_CONTAINER(x)->number != 5) + exit(8); + x = tree_lower(tree, (void *)3l, number_search); + if (!x) + exit(9); + if (NUMBER_CONTAINER(x)->number != 3) + exit(10); + if (!tree_lower(tree, (void *)7l, number_search)) + exit(22); + if (tree_lower(tree, (void *)8l, number_search)) + exit(23); + + // Test tree_ceil() + // + // Returns first node greater than than given key. + // + // [1 3 5 7] [1 3 5 7] [1 3 5 7] + // ↑ ↑ NULL + // 4 3 8 + // + x = tree_ceil(tree, (void *)4l, number_search); + if (!x) + exit(11); + if (NUMBER_CONTAINER(x)->number != 5) + exit(12); + x = tree_ceil(tree, (void *)3l, number_search); + if (!x) + exit(13); + if (NUMBER_CONTAINER(x)->number != 5) + exit(14); + if (tree_ceil(tree, (void *)7l, number_search)) + exit(21); + + // Test tree_first() + if (tree_first(NULL)) + exit(15); + x = tree_first(tree); + if (!x) + exit(16); + if (NUMBER_CONTAINER(x)->number != 1) + exit(17); + + // Test tree_last() + if (tree_last(NULL)) + exit(18); + x = tree_last(tree); + if (!x) + exit(19); + if (NUMBER_CONTAINER(x)->number != 7) + exit(20); +} + +int main() { + ShowCrashReports(); + + // show memory maps at startup + tree_check(__maps.maps, __maps_compare); + kprintf("\n"); + __print_maps(0); + kprintf("\n"); + + // run tests + simple_test(); + search_test(); } diff --git a/test/libc/mem/malloc_test.c b/test/libc/mem/malloc_test.c index 0fceb4649..6ce7d23dc 100644 --- a/test/libc/mem/malloc_test.c +++ b/test/libc/mem/malloc_test.c @@ -188,20 +188,22 @@ BENCH(bulk_free, bench) { EZBENCH2("free(malloc(16)) MT", donothing, MallocFree()); } -#define ITERATIONS 10000 +#define ITERATIONS 1000 +#define THREADS 10 +#define SIZE (256 * 1024) void *Worker(void *arg) { - /* for (int i = 0; i < ITERATIONS; ++i) { */ - /* char *p; */ - /* ASSERT_NE(NULL, (p = malloc(lemur64() % 128))); */ - /* ASSERT_NE(NULL, (p = realloc(p, max(lemur64() % 128, 1)))); */ - /* free(p); */ - /* } */ + for (int i = 0; i < ITERATIONS; ++i) { + char *p; + ASSERT_NE(NULL, (p = malloc(lemur64() % SIZE))); + ASSERT_NE(NULL, (p = realloc(p, max(lemur64() % SIZE, 1)))); + free(p); + } return 0; } -BENCH(malloc, torture) { - int i, n = __get_cpu_count(); +TEST(malloc, torture) { + int i, n = THREADS; pthread_t *t = gc(malloc(sizeof(pthread_t) * n)); if (!n) return; diff --git a/test/libc/nexgen32e/lz4decode_test.c b/test/libc/nexgen32e/lz4decode_test.c index 2f6fc2ef5..ce289468f 100644 --- a/test/libc/nexgen32e/lz4decode_test.c +++ b/test/libc/nexgen32e/lz4decode_test.c @@ -85,7 +85,7 @@ TEST(lz4, zoneFileGmt) { (mapsize = roundup( LZ4_FRAME_BLOCKCONTENTSIZE(lz4check(dict)) + (gmtsize = LZ4_FRAME_BLOCKCONTENTSIZE(lz4check(gmt))), - __granularity())))), + getpagesize())))), dict)), gmt); ASSERT_BINEQ( diff --git a/test/libc/proc/fork_test.c b/test/libc/proc/fork_test.c index 76c95ce98..641909045 100644 --- a/test/libc/proc/fork_test.c +++ b/test/libc/proc/fork_test.c @@ -63,10 +63,10 @@ TEST(fork, testSharedMemory) { int *sharedvar; int *privatevar; EXPECT_NE(MAP_FAILED, - (sharedvar = mmap(NULL, __granularity(), PROT_READ | PROT_WRITE, + (sharedvar = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0))); EXPECT_NE(MAP_FAILED, - (privatevar = mmap(NULL, __granularity(), PROT_READ | PROT_WRITE, + (privatevar = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); stackvar = 1; *sharedvar = 1; @@ -77,18 +77,18 @@ TEST(fork, testSharedMemory) { ++stackvar; ++*sharedvar; ++*privatevar; - msync((void *)ROUNDDOWN((intptr_t)&stackvar, __granularity()), - __granularity(), MS_SYNC); - EXPECT_NE(-1, msync(privatevar, __granularity(), MS_SYNC)); - EXPECT_NE(-1, msync(sharedvar, __granularity(), MS_SYNC)); + msync((void *)ROUNDDOWN((intptr_t)&stackvar, getpagesize()), getpagesize(), + MS_SYNC); + EXPECT_NE(-1, msync(privatevar, getpagesize(), MS_SYNC)); + EXPECT_NE(-1, msync(sharedvar, getpagesize(), MS_SYNC)); _exit(0); } EXPECT_NE(-1, waitpid(pid, &ws, 0)); EXPECT_EQ(1, stackvar); EXPECT_EQ(2, *sharedvar); EXPECT_EQ(1, *privatevar); - EXPECT_NE(-1, munmap(sharedvar, __granularity())); - EXPECT_NE(-1, munmap(privatevar, __granularity())); + EXPECT_NE(-1, munmap(sharedvar, getpagesize())); + EXPECT_NE(-1, munmap(privatevar, getpagesize())); } static volatile bool gotsigusr1; diff --git a/test/libc/runtime/exit_test.c b/test/libc/runtime/exit_test.c index 004ecfd89..7acaef336 100644 --- a/test/libc/runtime/exit_test.c +++ b/test/libc/runtime/exit_test.c @@ -28,11 +28,11 @@ int i, *p; void SetUp(void) { - p = _mapshared(__granularity()); + p = _mapshared(getpagesize()); } void TearDown(void) { - munmap(p, __granularity()); + munmap(p, getpagesize()); } void AtExit3(void) { diff --git a/test/libc/str/memcpy_test.c b/test/libc/str/memcpy_test.c index d2fd7e294..59d63f813 100644 --- a/test/libc/str/memcpy_test.c +++ b/test/libc/str/memcpy_test.c @@ -169,5 +169,5 @@ BENCH(memcpy, bench) { BB(1023); BB(1024); BB(4096); - BB(__granularity()); + BB(getpagesize()); } diff --git a/test/libc/thread/sem_timedwait_test.c b/test/libc/thread/sem_timedwait_test.c index d1fedb251..8ba2393f0 100644 --- a/test/libc/thread/sem_timedwait_test.c +++ b/test/libc/thread/sem_timedwait_test.c @@ -129,7 +129,7 @@ TEST(sem_timedwait, threads) { TEST(sem_timedwait, processes) { int i, r, rc, n = 4, pshared = 1; - sem_t *sm = _mapshared(__granularity()), *s[2] = {sm, sm + 1}; + sem_t *sm = _mapshared(getpagesize()), *s[2] = {sm, sm + 1}; ASSERT_SYS(0, 0, sem_init(s[0], pshared, 0)); ASSERT_SYS(0, 0, sem_init(s[1], pshared, 0)); for (i = 0; i < n; ++i) { @@ -163,5 +163,5 @@ TEST(sem_timedwait, processes) { ASSERT_EQ(0, r); ASSERT_SYS(0, 0, sem_destroy(s[1])); ASSERT_SYS(0, 0, sem_destroy(s[0])); - ASSERT_SYS(0, 0, munmap(sm, __granularity())); + ASSERT_SYS(0, 0, munmap(sm, getpagesize())); } diff --git a/third_party/dlmalloc/directmap.inc b/third_party/dlmalloc/directmap.inc index 2e313e31e..e83348cea 100644 --- a/third_party/dlmalloc/directmap.inc +++ b/third_party/dlmalloc/directmap.inc @@ -57,7 +57,7 @@ static mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb, int flags) { size_t newmmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); char* cp = (char*)CALL_MREMAP((char*)oldp - offset, oldmmsize, newmmsize, flags); - if (cp != CMFAIL) { + if (cp != MAP_FAILED) { mchunkptr newp = (mchunkptr)(cp + offset); size_t psize = newmmsize - offset - MMAP_FOOT_PAD; newp->head = psize; diff --git a/third_party/dlmalloc/dlmalloc.c b/third_party/dlmalloc/dlmalloc.c index 4ec0983d3..fa546f8cc 100644 --- a/third_party/dlmalloc/dlmalloc.c +++ b/third_party/dlmalloc/dlmalloc.c @@ -24,8 +24,7 @@ #include "libc/thread/tls.h" #include "third_party/dlmalloc/vespene.internal.h" #include "libc/thread/tls.h" -#include "libc/intrin/kprintf.h" -#include "libc/intrin/kprintf.h" +#include "libc/sysv/consts/mremap.h" #include "third_party/nsync/mu.h" #if !IsTiny() @@ -41,7 +40,7 @@ #endif #define HAVE_MMAP 1 -#define HAVE_MREMAP 0 +#define HAVE_MREMAP 1 #define HAVE_MORECORE 0 #define USE_LOCKS 2 #define USE_SPIN_LOCKS 1 @@ -197,7 +196,7 @@ static void* sys_alloc(mstate m, size_t nb) { } if (HAVE_MMAP && tbase == CMFAIL) { /* Try MMAP */ - char* mp = (char*)(dlmalloc_requires_more_vespene_gas(asize)); + char* mp = dlmalloc_requires_more_vespene_gas(asize); if (mp != CMFAIL) { tbase = mp; tsize = asize; @@ -368,7 +367,7 @@ static int sys_trim(mstate m, size_t pad) { size_t newsize = sp->size - extra; (void)newsize; /* placate people compiling -Wunused-variable */ /* Prefer mremap, fall back to munmap */ - if (CALL_MREMAP(sp->base, sp->size, newsize, 0) != MFAIL || + if (CALL_MREMAP(sp->base, sp->size, newsize, 0) != MAP_FAILED || (!extra || !CALL_MUNMAP(sp->base + newsize, extra))) { released = extra; } @@ -1263,7 +1262,7 @@ void* dlrealloc_single(void* oldmem, size_t bytes) { } #endif /* FOOTERS */ if (!PREACTION(m)) { - mchunkptr newp = try_realloc_chunk(m, oldp, nb, 1); + mchunkptr newp = try_realloc_chunk(m, oldp, nb, MREMAP_MAYMOVE); POSTACTION(m); if (newp != 0) { check_inuse_chunk(m, newp); diff --git a/third_party/dlmalloc/platform.inc b/third_party/dlmalloc/platform.inc index 25c80f416..e21769099 100644 --- a/third_party/dlmalloc/platform.inc +++ b/third_party/dlmalloc/platform.inc @@ -511,7 +511,7 @@ FORCEINLINE int win32munmap(void* ptr, size_t size) { #define CALL_MREMAP(addr, osz, nsz, mv) MREMAP_DEFAULT((addr), (osz), (nsz), (mv)) #endif /* MREMAP */ #else /* HAVE_MMAP && HAVE_MREMAP */ - #define CALL_MREMAP(addr, osz, nsz, mv) MFAIL + #define CALL_MREMAP(addr, osz, nsz, mv) MAP_FAILED #endif /* HAVE_MMAP && HAVE_MREMAP */ /* mstate bit set if continguous morecore disabled or failed */ diff --git a/third_party/zip/zipup.c b/third_party/zip/zipup.c index fe531952f..182a3ed5a 100644 --- a/third_party/zip/zipup.c +++ b/third_party/zip/zipup.c @@ -47,9 +47,6 @@ // MISSING #include "os2/os2zip.h" #endif -#undef PAGESIZE -#define PAGESIZE __granularity() - #if defined(MMAP) #include "libc/calls/calls.h" #include "libc/calls/weirdtypes.h" diff --git a/tool/build/lib/elfwriter.c b/tool/build/lib/elfwriter.c index 0008815a7..46cdd0341 100644 --- a/tool/build/lib/elfwriter.c +++ b/tool/build/lib/elfwriter.c @@ -163,7 +163,7 @@ struct ElfWriter *elfwriter_open(const char *path, int mode, int arch) { CHECK_NOTNULL((elf = calloc(1, sizeof(struct ElfWriter)))); CHECK_NOTNULL((elf->path = strdup(path))); CHECK_NE(-1, (elf->fd = open(elf->path, O_CREAT | O_TRUNC | O_RDWR, mode))); - CHECK_NE(-1, ftruncate(elf->fd, (elf->mapsize = __granularity()))); + CHECK_NE(-1, ftruncate(elf->fd, (elf->mapsize = getgransize()))); CHECK_NE(MAP_FAILED, (elf->map = mmap((void *)(intptr_t)kFixedmapStart, elf->mapsize, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, elf->fd, 0))); @@ -234,7 +234,7 @@ void *elfwriter_reserve(struct ElfWriter *elf, size_t size) { do { greed = greed + (greed >> 1); } while (need > greed); - greed = ROUNDUP(greed, __granularity()); + greed = ROUNDUP(greed, getgransize()); CHECK_NE(-1, ftruncate(elf->fd, greed)); CHECK_NE(MAP_FAILED, mmap((char *)elf->map + elf->mapsize, greed - elf->mapsize, PROT_READ | PROT_WRITE, diff --git a/tool/lambda/lib/calloc.c b/tool/lambda/lib/calloc.c index c09ddd3c5..185c91d33 100644 --- a/tool/lambda/lib/calloc.c +++ b/tool/lambda/lib/calloc.c @@ -28,14 +28,14 @@ void *Calloc(size_t a, size_t b) { static size_t n; z = a * b; if (!p) { - n = __granularity(); - p = mmap((void *)0x300000000000, __granularity(), PROT_READ | PROT_WRITE, + n = getgransize(); + p = mmap((void *)0x300000000000, getgransize(), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0); } if (i + z > n) { - mmap(p + i, __granularity(), PROT_READ | PROT_WRITE, + mmap(p + i, getgransize(), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0); - n += __granularity(); + n += getgransize(); } r = p + i; i += z; diff --git a/tool/net/redbean.c b/tool/net/redbean.c index c87122c49..64a599028 100644 --- a/tool/net/redbean.c +++ b/tool/net/redbean.c @@ -5019,7 +5019,7 @@ static int LuaProgramTokenBucket(lua_State *L) { VERBOSEF("(token) please run the blackholed program; see our website!"); } } - tokenbucket.b = _mapshared(ROUNDUP(1ul << cidr, __granularity())); + tokenbucket.b = _mapshared(ROUNDUP(1ul << cidr, getgransize())); memset(tokenbucket.b, 127, 1ul << cidr); tokenbucket.cidr = cidr; tokenbucket.reject = reject; @@ -7339,7 +7339,7 @@ void RedBean(int argc, char *argv[]) { heartbeatinterval.tv_sec = 5; CHECK_GT(CLK_TCK, 0); CHECK_NE(MAP_FAILED, - (shared = mmap(NULL, ROUNDUP(sizeof(struct Shared), __granularity()), + (shared = mmap(NULL, ROUNDUP(sizeof(struct Shared), getgransize()), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0))); if (daemonize) { diff --git a/tool/plinko/lib/plinko.c b/tool/plinko/lib/plinko.c index 26f9db1c6..3def139a0 100644 --- a/tool/plinko/lib/plinko.c +++ b/tool/plinko/lib/plinko.c @@ -970,7 +970,7 @@ int Plinko(int argc, char *argv[]) { } if (mmap((void *)0x200000000000, - ROUNDUP((TERM + 1) * sizeof(g_mem[0]), __granularity()), + ROUNDUP((TERM + 1) * sizeof(g_mem[0]), getgransize()), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0) == MAP_FAILED || mmap((void *)(0x200000000000 + @@ -979,7 +979,7 @@ int Plinko(int argc, char *argv[]) { PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0) == MAP_FAILED || mmap((void *)0x400000000000, - ROUNDUP((TERM + 1) * sizeof(g_mem[0]), __granularity()), + ROUNDUP((TERM + 1) * sizeof(g_mem[0]), getgransize()), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0) == MAP_FAILED || mmap((void *)(0x400000000000 + diff --git a/tool/viz/derasterize.c b/tool/viz/derasterize.c index 5beaada39..478ec1dc8 100644 --- a/tool/viz/derasterize.c +++ b/tool/viz/derasterize.c @@ -452,7 +452,6 @@ static void PrintImage(unsigned yn, unsigned xn, size_t size; char *v, *vt; size = yn * (xn * (32 + (2 + (1 + 3) * 3) * 2 + 1 + 3)) * 1 + 5 + 1; - size = ROUNDUP(size, __granularity()); CHECK_NOTNULL((vt = _mapanon(size))); v = RenderImage(vt, yn, xn, rgb); *v++ = '\r'; @@ -550,8 +549,8 @@ static void LoadFile(const char *path, size_t yn, size_t xn, void *rgb) { stbir_resize_uint8(data, gotx, goty, 0, rgb, xn * XS, yn * YS, 0, CN); #else CHECK_EQ(CN, 3); - data2size = ROUNDUP(sizeof(float) * goty * gotx * CN, __granularity()); - data3size = ROUNDUP(sizeof(float) * yn * YS * xn * XS * CN, __granularity()); + data2size = sizeof(float) * goty * gotx * CN; + data3size = sizeof(float) * yn * YS * xn * XS * CN; CHECK_NOTNULL((data2 = _mapanon(data2size))); CHECK_NOTNULL((data3 = _mapanon(data3size))); rgb2lin(goty * gotx * CN, data2, data); @@ -625,7 +624,7 @@ int main(int argc, char *argv[]) { // FIXME: on the conversion stage should do 2Y because of halfblocks // printf( "filename >%s<\tx >%d<\ty >%d<\n\n", filename, x_, y_); size = y_ * YS * x_ * XS * CN; - CHECK_NOTNULL((rgb = _mapanon(ROUNDUP(size, __granularity())))); + CHECK_NOTNULL((rgb = _mapanon(size))); for (i = optind; i < argc; ++i) { if (!argv[i]) continue; @@ -636,7 +635,7 @@ int main(int argc, char *argv[]) { } PrintImage(y_, x_, rgb); } - munmap(rgb, ROUNDUP(size, __granularity())); + munmap(rgb, size); return 0; } diff --git a/tool/viz/lib/sobel.c b/tool/viz/lib/sobel.c index b26ad3113..a6acf15b0 100644 --- a/tool/viz/lib/sobel.c +++ b/tool/viz/lib/sobel.c @@ -37,8 +37,7 @@ forceinline void ConvolveGradient(unsigned yn, unsigned xn, size_t size; unsigned y, x, i, j, k; float py[4], px[4], (*tmp)[yn][xn][4]; - tmp = - _mapanon((size = ROUNDUP(sizeof(float) * 4 * xn * yn, __granularity()))); + tmp = _mapanon((size = ROUNDUP(sizeof(float) * 4 * xn * yn, getgransize()))); for (y = 0; y < yn - KW + 1; ++y) { for (x = 0; x < xn - KW + 1; ++x) { for (k = 0; k < 4; ++k) diff --git a/tool/viz/memzoom.c b/tool/viz/memzoom.c index 21fbbd0d1..7793fd853 100644 --- a/tool/viz/memzoom.c +++ b/tool/viz/memzoom.c @@ -281,8 +281,8 @@ static void SetupCanvas(void) { munmap(buffer, buffersize); } displaysize = ROUNDUP(ROUNDUP((tyn * txn) << zoom, 16), 1ul << zoom); - canvassize = ROUNDUP(displaysize, __granularity()); - buffersize = ROUNDUP(tyn * txn * 16 + 4096, __granularity()); + canvassize = ROUNDUP(displaysize, getgransize()); + buffersize = ROUNDUP(tyn * txn * 16 + 4096, getgransize()); canvas = Allocate(canvassize); buffer = Allocate(buffersize); } diff --git a/tool/viz/printvideo.c b/tool/viz/printvideo.c index b348fabe5..ccaf445a8 100644 --- a/tool/viz/printvideo.c +++ b/tool/viz/printvideo.c @@ -785,7 +785,7 @@ static void RasterIt(void) { static bool once; static void *buf; if (!once) { - buf = _mapanon(ROUNDUP(fb0_.size, __granularity())); + buf = _mapanon(ROUNDUP(fb0_.size, getgransize())); once = true; } WriteToFrameBuffer(fb0_.vscreen.yres_virtual, fb0_.vscreen.xres_virtual, buf, From f590e96abdc76ae03d1bb277c34a4816bcd02061 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sun, 7 Jul 2024 15:42:46 -0700 Subject: [PATCH 039/405] Work around QEMU bugs --- test/libc/calls/madvise_test.c | 6 ++++-- test/libc/intrin/BUILD.mk | 5 +++++ test/libc/mem/malloc_test.c | 2 +- third_party/nsync/common.c | 5 ++--- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/test/libc/calls/madvise_test.c b/test/libc/calls/madvise_test.c index a3ae232ad..e36cdb449 100644 --- a/test/libc/calls/madvise_test.c +++ b/test/libc/calls/madvise_test.c @@ -61,6 +61,8 @@ TEST(madvise, short) { } TEST(madvise, zero) { + if (IsQemuUser()) + return; // doesn't validate flags char *p; ASSERT_NE(MAP_FAILED, (p = mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); @@ -86,7 +88,7 @@ TEST(madvise, madvWillNeed_unmappedRegion) { ASSERT_SYS(0, 0, munmap(p + getgransize(), getgransize())); if (IsXnu()) ASSERT_SYS(EINVAL, -1, madvise(p, getgransize() * 3, MADV_WILLNEED)); - else if (IsBsd() || IsWindows()) + else if (IsBsd() || IsWindows() || IsQemuUser()) ASSERT_SYS(0, 0, madvise(p, getgransize() * 3, MADV_WILLNEED)); else ASSERT_SYS(ENOMEM, -1, madvise(p, getgransize() * 3, MADV_WILLNEED)); @@ -102,7 +104,7 @@ TEST(madvise, madvFree_unmappedRegion) { ASSERT_SYS(EINVAL, -1, madvise(p, getgransize() * 3, MADV_FREE)); else if (IsNetbsd() || IsOpenbsd()) ASSERT_SYS(EFAULT, -1, madvise(p, getgransize() * 3, MADV_FREE)); - else if (IsFreebsd() || IsWindows()) + else if (IsFreebsd() || IsWindows() || IsQemuUser()) ASSERT_SYS(0, 0, madvise(p, getgransize() * 3, MADV_FREE)); else ASSERT_SYS(ENOMEM, -1, madvise(p, getgransize() * 3, MADV_FREE)); diff --git a/test/libc/intrin/BUILD.mk b/test/libc/intrin/BUILD.mk index 5ca755af0..dcde4ae37 100644 --- a/test/libc/intrin/BUILD.mk +++ b/test/libc/intrin/BUILD.mk @@ -44,6 +44,7 @@ TEST_LIBC_INTRIN_DIRECTDEPS = \ TOOL_VIZ_LIB \ THIRD_PARTY_COMPILER_RT \ THIRD_PARTY_NSYNC \ + THIRD_PARTY_OPENMP \ THIRD_PARTY_XED TEST_LIBC_INTRIN_DEPS := \ @@ -76,6 +77,10 @@ $(TEST_LIBC_INTRIN_OBJS): private \ CFLAGS += \ -fno-builtin +$(TEST_LIBC_INTRIN_OBJS): private \ + CXXFLAGS += \ + -fopenmp + .PHONY: o/$(MODE)/test/libc/intrin o/$(MODE)/test/libc/intrin: \ $(TEST_LIBC_INTRIN_BINS) \ diff --git a/test/libc/mem/malloc_test.c b/test/libc/mem/malloc_test.c index 6ce7d23dc..b5336ed12 100644 --- a/test/libc/mem/malloc_test.c +++ b/test/libc/mem/malloc_test.c @@ -190,7 +190,7 @@ BENCH(bulk_free, bench) { #define ITERATIONS 1000 #define THREADS 10 -#define SIZE (256 * 1024) +#define SIZE (2 * 1024 * 1024) void *Worker(void *arg) { for (int i = 0; i < ITERATIONS; ++i) { diff --git a/third_party/nsync/common.c b/third_party/nsync/common.c index 3a20bcdbb..4b4b13d98 100644 --- a/third_party/nsync/common.c +++ b/third_party/nsync/common.c @@ -142,7 +142,7 @@ static void free_waiters_push (waiter *w) { w->next_free = atomic_load_explicit (&free_waiters, memory_order_relaxed); while (!atomic_compare_exchange_weak_explicit (&free_waiters, &w->next_free, w, memory_order_acq_rel, memory_order_relaxed)) - backoff = pthread_delay_np(free_waiters, backoff); + backoff = pthread_delay_np (free_waiters, backoff); } static void free_waiters_populate (void) { @@ -188,12 +188,11 @@ static waiter *free_waiters_pop (void) { if (atomic_compare_exchange_weak_explicit (&free_waiters, &w, w->next_free, memory_order_acq_rel, memory_order_relaxed)) return w; - backoff = pthread_delay_np(free_waiters, backoff); + backoff = pthread_delay_np (free_waiters, backoff); } else { free_waiters_populate (); } } - return w; } /* -------------------------------- */ From 3f2a1b696e91d854555e75dd0554d9c3d1621b02 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sun, 7 Jul 2024 15:55:55 -0700 Subject: [PATCH 040/405] Fix greenbean example The memory leak detector was crashing. When using gc() you shouldn't use the CheckForMemoryLeaks() function from inside the same function, due to how it runs the atexit handlers. --- examples/greenbean.c | 6 ++++-- libc/mem/gc.c | 22 ---------------------- libc/runtime/cxa_thread_atexit.c | 6 ++++-- libc/thread/pthread_attr_setguardsize.c | 4 ---- 4 files changed, 8 insertions(+), 30 deletions(-) diff --git a/examples/greenbean.c b/examples/greenbean.c index 9f2aae6c1..8ffc51622 100644 --- a/examples/greenbean.c +++ b/examples/greenbean.c @@ -289,10 +289,11 @@ int main(int argc, char *argv[]) { // print all the ips that 0.0.0.0 would bind // Cosmo's GetHostIps() API is much easier than ioctl(SIOCGIFCONF) uint32_t *hostips; - for (hostips = gc(GetHostIps()), i = 0; hostips[i]; ++i) { + for (hostips = GetHostIps(), i = 0; hostips[i]; ++i) { kprintf("listening on http://%hhu.%hhu.%hhu.%hhu:%hu\n", hostips[i] >> 24, hostips[i] >> 16, hostips[i] >> 8, hostips[i], PORT); } + free(hostips); // secure the server // @@ -342,7 +343,7 @@ int main(int argc, char *argv[]) { unassert(!pthread_attr_setguardsize(&attr, getpagesize())); unassert(!pthread_attr_setsigmask_np(&attr, &block)); unassert(!pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0)); - pthread_t *th = gc(calloc(threads, sizeof(pthread_t))); + pthread_t *th = calloc(threads, sizeof(pthread_t)); for (i = 0; i < threads; ++i) { int rc; ++a_workers; @@ -399,6 +400,7 @@ int main(int argc, char *argv[]) { for (i = 0; i < threads; ++i) { unassert(!pthread_join(th[i], 0)); } + free(th); // close the server socket if (!IsWindows()) diff --git a/libc/mem/gc.c b/libc/mem/gc.c index 1ef55198c..7f34d9db5 100644 --- a/libc/mem/gc.c +++ b/libc/mem/gc.c @@ -33,28 +33,6 @@ forceinline bool PointerNotOwnedByParentStackFrame(struct StackFrame *frame, ((intptr_t)ptr < (intptr_t)parent)); } -static void TeardownGc(void) { - struct Garbages *g; - struct CosmoTib *t; - if (__tls_enabled) { - t = __get_tls(); - if ((g = t->tib_garbages)) { - // exit() currently doesn't use gclongjmp() like pthread_exit() - // so we need to run the deferred functions manually. - while (g->i) { - --g->i; - ((void (*)(intptr_t))g->p[g->i].fn)(g->p[g->i].arg); - } - free(g->p); - free(g); - } - } -} - -__attribute__((__constructor__(51))) static textstartup void InitGc(void) { - atexit(TeardownGc); -} - // add item to garbage shadow stack. // then rewrite caller's return address on stack. static void DeferFunction(struct StackFrame *frame, void *fn, void *arg) { diff --git a/libc/runtime/cxa_thread_atexit.c b/libc/runtime/cxa_thread_atexit.c index cce24949f..143727024 100644 --- a/libc/runtime/cxa_thread_atexit.c +++ b/libc/runtime/cxa_thread_atexit.c @@ -68,8 +68,10 @@ static void _pthread_ungarbage(struct CosmoTib *tib) { tib->tib_garbages = 0; while (g->i--) ((void (*)(intptr_t))g->p[g->i].fn)(g->p[g->i].arg); - _weaken(free)(g->p); - _weaken(free)(g); + if (_weaken(free)) { + _weaken(free)(g->p); + _weaken(free)(g); + } } } diff --git a/libc/thread/pthread_attr_setguardsize.c b/libc/thread/pthread_attr_setguardsize.c index 2905a7605..2e03607b2 100644 --- a/libc/thread/pthread_attr_setguardsize.c +++ b/libc/thread/pthread_attr_setguardsize.c @@ -16,7 +16,6 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/errno.h" #include "libc/thread/thread.h" /** @@ -33,11 +32,8 @@ * * @param guardsize contains guard size in bytes * @return 0 on success, or errno on error - * @raise EINVAL if `guardsize` is zero */ errno_t pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize) { - if (!guardsize) - return EINVAL; attr->__guardsize = guardsize; return 0; } From 63065cdd7021412fb85d73dcdbfa5f8a0a2df776 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sun, 7 Jul 2024 19:35:09 -0700 Subject: [PATCH 041/405] Make a test less intensive by default --- test/libc/mem/malloc_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/libc/mem/malloc_test.c b/test/libc/mem/malloc_test.c index b5336ed12..228594367 100644 --- a/test/libc/mem/malloc_test.c +++ b/test/libc/mem/malloc_test.c @@ -190,7 +190,7 @@ BENCH(bulk_free, bench) { #define ITERATIONS 1000 #define THREADS 10 -#define SIZE (2 * 1024 * 1024) +#define SIZE 1024 void *Worker(void *arg) { for (int i = 0; i < ITERATIONS; ++i) { From 76cea6c68705a2e77fb0ed59c8a1b6c28ef6e4f6 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Mon, 8 Jul 2024 03:08:42 -0700 Subject: [PATCH 042/405] Squeeze more performance out of memory manager --- libc/intrin/maps.h | 1 - libc/intrin/mmap.c | 36 ++++++++++++++---------------------- libc/intrin/mprotect.c | 5 ++--- libc/intrin/msync-nt.c | 5 ++--- 4 files changed, 18 insertions(+), 29 deletions(-) diff --git a/libc/intrin/maps.h b/libc/intrin/maps.h index eea3142a6..499530a4e 100644 --- a/libc/intrin/maps.h +++ b/libc/intrin/maps.h @@ -52,7 +52,6 @@ void __maps_unlock(void); void __maps_add(struct Map *); void __maps_free(struct Map *); struct Map *__maps_alloc(void); -struct Map *__maps_ceil(const char *); struct Map *__maps_floor(const char *); void __maps_stack(char *, int, int, size_t, int, intptr_t); int __maps_compare(const struct Tree *, const struct Tree *); diff --git a/libc/intrin/mmap.c b/libc/intrin/mmap.c index ff0a5d3a4..8cbb7feb8 100644 --- a/libc/intrin/mmap.c +++ b/libc/intrin/mmap.c @@ -88,19 +88,9 @@ privileged optimizespeed struct Map *__maps_floor(const char *addr) { return 0; } -struct Map *__maps_ceil(const char *addr) { - struct Tree *node; - if ((node = tree_ceil(__maps.maps, addr, __maps_search))) - return MAP_TREE_CONTAINER(node); - return 0; -} - static bool __maps_overlaps(const char *addr, size_t size, int pagesz) { - ASSERT(!((uintptr_t)addr & (getgransize() - 1)) && size); - struct Map *map, *ceil, *floor; - floor = __maps_floor(addr); - ceil = __maps_ceil(addr + size); - for (map = floor; map && map != ceil; map = __maps_next(map)) + struct Map *map, *floor = __maps_floor(addr); + for (map = floor; map && map->addr <= addr + size; map = __maps_next(map)) if (MAX(addr, map->addr) < MIN(addr + PGUP(size), map->addr + PGUP(map->size))) return true; @@ -138,11 +128,9 @@ static int __muntrack(char *addr, size_t size, int pagesz, int rc = 0; struct Map *map; struct Map *next; - struct Map *ceil; struct Map *floor; floor = __maps_floor(addr); - ceil = __maps_ceil(addr + size); - for (map = floor; map && map != ceil; map = next) { + for (map = floor; map && map->addr <= addr + size; map = next) { next = __maps_next(map); char *map_addr = map->addr; size_t map_size = map->size; @@ -252,10 +240,10 @@ static void __maps_insert(struct Map *map) { int prot = map->prot & ~(MAP_FIXED | MAP_FIXED_NOREPLACE); int flags = map->flags; bool coalesced = false; - struct Map *floor, *ceil, *other, *last = 0; - floor = __maps_floor(map->addr); - ceil = __maps_ceil(map->addr + map->size); - for (other = floor; other; last = other, other = __maps_next(other)) { + struct Map *floor, *other, *last = 0; + for (other = floor = __maps_floor(map->addr); + other && other->addr <= map->addr + map->size; + last = other, other = __maps_next(other)) { if (prot == other->prot && flags == other->flags) { if (!coalesced) { if (map->addr == other->addr + other->size) { @@ -282,8 +270,6 @@ static void __maps_insert(struct Map *map) { __maps_check(); } } - if (other == ceil) - break; } if (coalesced) return; @@ -683,10 +669,16 @@ static void *__mremap(char *old_addr, size_t old_size, size_t new_size, int pagesz = getpagesize(); int gransz = getgransize(); - // demand kernel support + // kernel support if (!IsLinux() && !IsNetbsd()) return (void *)enosys(); + // it is not needed + if (new_size <= old_size) + if (!(flags & MREMAP_FIXED)) + if (flags & MREMAP_MAYMOVE) + flags &= ~MREMAP_MAYMOVE; + // we support these flags if (flags & ~(MREMAP_MAYMOVE | MREMAP_FIXED)) return (void *)einval(); diff --git a/libc/intrin/mprotect.c b/libc/intrin/mprotect.c index a5bb5f554..cd0586fef 100644 --- a/libc/intrin/mprotect.c +++ b/libc/intrin/mprotect.c @@ -74,10 +74,9 @@ int __mprotect(char *addr, size_t size, int prot) { __maps_unlock(); return edeadlk(); } - struct Map *map, *ceil, *floor; + struct Map *map, *floor; floor = __maps_floor(addr); - ceil = __maps_ceil(addr + size); - for (map = floor; map && map != ceil; map = __maps_next(map)) { + for (map = floor; map && map->addr <= addr + size; map = __maps_next(map)) { char *map_addr = map->addr; size_t map_size = map->size; char *beg = MAX(addr, map_addr); diff --git a/libc/intrin/msync-nt.c b/libc/intrin/msync-nt.c index 35f540827..72ce53b0c 100644 --- a/libc/intrin/msync-nt.c +++ b/libc/intrin/msync-nt.c @@ -37,10 +37,9 @@ textwindows int sys_msync_nt(char *addr, size_t size, int flags) { if (__maps_lock()) { rc = edeadlk(); } else { - struct Map *map, *ceil, *floor; + struct Map *map, *floor; floor = __maps_floor(addr); - ceil = __maps_ceil(addr + size); - for (map = floor; map && map != ceil; map = __maps_next(map)) { + for (map = floor; map && map->addr <= addr + size; map = __maps_next(map)) { char *beg = MAX(addr, map->addr); char *end = MIN(addr + size, map->addr + map->size); if (beg < end) From 23dfb79d3349ea26105fa44b339f0021427182a2 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Thu, 18 Jul 2024 19:19:51 -0700 Subject: [PATCH 043/405] Fix minor suboptimalities in memory manager --- libc/intrin/maps.c | 5 ++- libc/intrin/maps.h | 10 ++--- libc/intrin/mmap.c | 94 +++++++++++++++++++++------------------------- 3 files changed, 49 insertions(+), 60 deletions(-) diff --git a/libc/intrin/maps.c b/libc/intrin/maps.c index af394f12b..5ca9861ee 100644 --- a/libc/intrin/maps.c +++ b/libc/intrin/maps.c @@ -89,7 +89,7 @@ privileged bool __maps_lock(void) { if (!__tls_enabled) return false; tib = __get_tls_privileged(); - if (tib->tib_relock_maps++) + if (atomic_fetch_add_explicit(&tib->tib_relock_maps, 1, memory_order_relaxed)) return true; while (atomic_exchange_explicit(&__maps.lock, 1, memory_order_acquire)) { #if defined(__GNUC__) && defined(__aarch64__) @@ -106,6 +106,7 @@ privileged void __maps_unlock(void) { if (!__tls_enabled) return; tib = __get_tls_privileged(); - if (!--tib->tib_relock_maps) + if (atomic_fetch_sub_explicit(&tib->tib_relock_maps, 1, + memory_order_relaxed) == 1) atomic_store_explicit(&__maps.lock, 0, memory_order_release); } diff --git a/libc/intrin/maps.h b/libc/intrin/maps.h index 499530a4e..06b8a813e 100644 --- a/libc/intrin/maps.h +++ b/libc/intrin/maps.h @@ -1,14 +1,12 @@ #ifndef COSMOPOLITAN_MAPS_H_ #define COSMOPOLITAN_MAPS_H_ #include "libc/intrin/atomic.h" -#include "libc/intrin/dll.h" #include "libc/intrin/tree.h" #include "libc/runtime/runtime.h" #include "libc/thread/tls2.internal.h" COSMOPOLITAN_C_START_ #define MAP_TREE_CONTAINER(e) TREE_CONTAINER(struct Map, tree, e) -#define MAP_FREE_CONTAINER(e) DLL_CONTAINER(struct Map, free, e) struct Map { char *addr; /* granule aligned */ @@ -22,14 +20,14 @@ struct Map { intptr_t hand; /* windows nt only */ union { struct Tree tree; - struct Dll free; + struct Map *free; }; }; struct Maps { atomic_int lock; struct Tree *maps; - struct Dll *free; + _Atomic(struct Map *) free; size_t count; size_t pages; atomic_size_t rollo; @@ -64,14 +62,14 @@ forceinline optimizespeed int __maps_search(const void *key, return (addr > map->addr) - (addr < map->addr); } -static struct Map *__maps_next(struct Map *map) { +static inline struct Map *__maps_next(struct Map *map) { struct Tree *node; if ((node = tree_next(&map->tree))) return MAP_TREE_CONTAINER(node); return 0; } -static struct Map *__maps_first(void) { +static inline struct Map *__maps_first(void) { struct Tree *node; if ((node = tree_first(__maps.maps))) return MAP_TREE_CONTAINER(node); diff --git a/libc/intrin/mmap.c b/libc/intrin/mmap.c index 8cbb7feb8..25b2ead83 100644 --- a/libc/intrin/mmap.c +++ b/libc/intrin/mmap.c @@ -31,7 +31,6 @@ #include "libc/intrin/describebacktrace.internal.h" #include "libc/intrin/describeflags.internal.h" #include "libc/intrin/directmap.internal.h" -#include "libc/intrin/dll.h" #include "libc/intrin/kprintf.h" #include "libc/intrin/maps.h" #include "libc/intrin/strace.internal.h" @@ -124,7 +123,7 @@ void __maps_check(void) { } static int __muntrack(char *addr, size_t size, int pagesz, - struct Dll **deleted) { + struct Map **deleted) { int rc = 0; struct Map *map; struct Map *next; @@ -140,8 +139,8 @@ static int __muntrack(char *addr, size_t size, int pagesz, if (addr <= map_addr && addr + PGUP(size) >= map_addr + PGUP(map_size)) { // remove mapping completely tree_remove(&__maps.maps, &map->tree); - dll_init(&map->free); - dll_make_first(deleted, &map->free); + map->free = *deleted; + *deleted = map; __maps.pages -= (map_size + pagesz - 1) / pagesz; __maps.count -= 1; __maps_check(); @@ -166,8 +165,8 @@ static int __muntrack(char *addr, size_t size, int pagesz, __maps.pages -= (left + pagesz - 1) / pagesz; leftmap->addr = map_addr; leftmap->size = left; - dll_init(&leftmap->free); - dll_make_first(deleted, &leftmap->free); + leftmap->free = *deleted; + *deleted = leftmap; __maps_check(); } else { rc = -1; @@ -182,8 +181,8 @@ static int __muntrack(char *addr, size_t size, int pagesz, __maps.pages -= (right + pagesz - 1) / pagesz; rightmap->addr = addr; rightmap->size = right; - dll_init(&rightmap->free); - dll_make_first(deleted, &rightmap->free); + rightmap->free = *deleted; + *deleted = rightmap; __maps_check(); } else { rc = -1; @@ -211,8 +210,8 @@ static int __muntrack(char *addr, size_t size, int pagesz, __maps.count += 1; middlemap->addr = addr; middlemap->size = size; - dll_init(&middlemap->free); - dll_make_first(deleted, &middlemap->free); + middlemap->free = *deleted; + *deleted = middlemap; __maps_check(); } else { rc = -1; @@ -228,8 +227,21 @@ static int __muntrack(char *addr, size_t size, int pagesz, void __maps_free(struct Map *map) { map->size = 0; map->addr = MAP_FAILED; - dll_init(&map->free); - dll_make_first(&__maps.free, &map->free); + map->free = atomic_load_explicit(&__maps.free, memory_order_relaxed); + for (;;) { + if (atomic_compare_exchange_weak_explicit(&__maps.free, &map->free, map, + memory_order_release, + memory_order_relaxed)) + break; + } +} + +static void __maps_free_all(struct Map *list) { + struct Map *next; + for (struct Map *map = list; map; map = next) { + next = map->free; + __maps_free(map); + } } static void __maps_insert(struct Map *map) { @@ -282,12 +294,13 @@ static void __maps_insert(struct Map *map) { } struct Map *__maps_alloc(void) { - struct Dll *e; struct Map *map; - if ((e = dll_first(__maps.free))) { - dll_remove(&__maps.free, e); - map = MAP_FREE_CONTAINER(e); - return map; + map = atomic_load_explicit(&__maps.free, memory_order_relaxed); + while (map) { + if (atomic_compare_exchange_weak_explicit(&__maps.free, &map, map->free, + memory_order_acquire, + memory_order_relaxed)) + return map; } int gransz = getgransize(); struct DirectMap sys = sys_mmap(0, gransz, PROT_READ | PROT_WRITE, @@ -335,14 +348,13 @@ static int __munmap(char *addr, size_t size) { } // untrack mappings - struct Dll *deleted = 0; + struct Map *deleted = 0; __muntrack(addr, pgup_size, pagesz, &deleted); __maps_unlock(); // delete mappings int rc = 0; - for (struct Dll *e = dll_first(deleted); e; e = dll_next(deleted, e)) { - struct Map *map = MAP_FREE_CONTAINER(e); + for (struct Map *map = deleted; map; map = map->free) { if (!IsWindows()) { if (sys_munmap(map->addr, map->size)) rc = -1; @@ -356,11 +368,7 @@ static int __munmap(char *addr, size_t size) { } // free mappings - if (!dll_is_empty(deleted)) { - __maps_lock(); - dll_make_first(&__maps.free, deleted); - __maps_unlock(); - } + __maps_free_all(deleted); return rc; } @@ -392,20 +400,12 @@ static void *__mmap_chunk(void *addr, size_t size, int prot, int flags, int fd, // allocate Map object struct Map *map; - if (__maps_lock()) { - __maps_unlock(); - return (void *)edeadlk(); - } - __maps_check(); - map = __maps_alloc(); - __maps_unlock(); - if (!map) + if (!(map = __maps_alloc())) return MAP_FAILED; // remove mapping we blew away if (IsWindows() && should_untrack) - if (__munmap(addr, size)) - return MAP_FAILED; + __munmap(addr, size); // obtain mapping from operating system int olderr = errno; @@ -424,9 +424,7 @@ TryAgain: goto TryAgain; } } - __maps_lock(); __maps_free(map); - __maps_unlock(); return MAP_FAILED; } @@ -440,21 +438,15 @@ TryAgain: UnmapViewOfFile(res.addr); CloseHandle(res.maphandle); } - __maps_lock(); __maps_free(map); - __maps_unlock(); return (void *)eexist(); } // untrack mapping we blew away if (!IsWindows() && should_untrack) { - struct Dll *deleted = 0; + struct Map *deleted = 0; __muntrack(res.addr, size, pagesz, &deleted); - if (!dll_is_empty(deleted)) { - __maps_lock(); - dll_make_first(&__maps.free, deleted); - __maps_unlock(); - } + __maps_free_all(deleted); } // track map object @@ -632,25 +624,23 @@ static void *__mremap_impl(char *old_addr, size_t old_size, size_t new_size, } else { res = sys_mremap(old_addr, old_size, new_size, flags, (uintptr_t)new_addr); } + if (res == MAP_FAILED) + __maps_free(map); // re-acquire lock if needed if (!flags) __maps_lock(); - // check result - if (res == MAP_FAILED) { - __maps_free(map); + if (res == MAP_FAILED) return MAP_FAILED; - } if (!(flags & MREMAP_MAYMOVE)) ASSERT(res == old_addr); // untrack old mapping - struct Dll *deleted = 0; + struct Map *deleted = 0; __muntrack(old_addr, old_size, pagesz, &deleted); - dll_make_first(&__maps.free, deleted); - deleted = 0; + __maps_free_all(deleted); // track map object map->addr = res; From 567d8fe32d7411a0431fa1b5b451309af83142cd Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Thu, 18 Jul 2024 21:02:59 -0700 Subject: [PATCH 044/405] Create variables for page size --- libc/calls/madvise.c | 2 +- libc/dlopen/dlopen.c | 2 +- libc/intrin/BUILD.mk | 2 ++ libc/intrin/extend.c | 2 +- libc/intrin/getauxval.c | 20 ------------ libc/intrin/getgransize.c | 19 +++-------- libc/intrin/getmainstack.c | 2 +- libc/intrin/getpagesize.c | 7 ++-- libc/intrin/maps.c | 2 +- libc/intrin/mmap.c | 22 ++++++------- libc/intrin/mprotect.c | 2 +- libc/intrin/msync-nt.c | 2 +- libc/intrin/pagesize.c | 47 +++++++++++++++++++++++++++ libc/intrin/pagesize_init.S | 28 ++++++++++++++++ libc/intrin/printmaps.c | 2 +- libc/mem/leaks.c | 2 +- libc/mem/pvalloc.c | 4 +-- libc/mem/valloc.c | 2 +- libc/nexgen32e/auxv.S | 6 ++-- libc/proc/fork-nt.c | 6 ++-- libc/runtime/cosmo2.c | 10 ++---- libc/runtime/getavphyspages.c | 2 +- libc/runtime/getphyspages.c | 2 +- libc/runtime/isstackoverflow.c | 2 +- libc/runtime/opensymboltable.greg.c | 2 +- libc/runtime/runtime.h | 2 ++ libc/runtime/sysconf.c | 4 +-- libc/runtime/winmain.greg.c | 18 ++++------ libc/runtime/zipos-get.c | 4 +-- libc/runtime/zipos-stat-impl.c | 2 +- libc/sysv/calls/getpagesize_freebsd.S | 2 -- libc/sysv/syscalls.sh | 1 - libc/thread/pthread_attr_init.c | 2 +- libc/thread/pthread_create.c | 4 +-- 34 files changed, 137 insertions(+), 101 deletions(-) create mode 100644 libc/intrin/pagesize.c create mode 100644 libc/intrin/pagesize_init.S delete mode 100644 libc/sysv/calls/getpagesize_freebsd.S diff --git a/libc/calls/madvise.c b/libc/calls/madvise.c index f1b2da64e..885e727f3 100644 --- a/libc/calls/madvise.c +++ b/libc/calls/madvise.c @@ -27,7 +27,7 @@ static int __madvise(void *addr, size_t length, int advice) { // simulate linux behavior of validating alignment - if ((uintptr_t)addr & (getpagesize() - 1)) + if ((uintptr_t)addr & (__pagesize - 1)) return einval(); // simulate linux behavior of checking for negative length diff --git a/libc/dlopen/dlopen.c b/libc/dlopen/dlopen.c index 41e0111fa..a39921b54 100644 --- a/libc/dlopen/dlopen.c +++ b/libc/dlopen/dlopen.c @@ -303,7 +303,7 @@ static wontreturn dontinstrument void foreign_helper(void **p) { static dontinline void elf_exec(const char *file, char **envp) { // get microprocessor page size - long pagesz = getpagesize(); + long pagesz = __pagesize; // load helper executable into address space struct Loaded prog; diff --git a/libc/intrin/BUILD.mk b/libc/intrin/BUILD.mk index 47f52776c..300e0631f 100644 --- a/libc/intrin/BUILD.mk +++ b/libc/intrin/BUILD.mk @@ -144,6 +144,8 @@ o/$(MODE)/libc/intrin/sched_yield.o: libc/intrin/sched_yield.S @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $< o/$(MODE)/libc/intrin/dsohandle.o: libc/intrin/dsohandle.S @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $< +o/$(MODE)/libc/intrin/getpagesize_freebsd.o: libc/intrin/getpagesize_freebsd.S + @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $< LIBC_INTRIN_LIBS = $(foreach x,$(LIBC_INTRIN_ARTIFACTS),$($(x))) LIBC_INTRIN_HDRS = $(foreach x,$(LIBC_INTRIN_ARTIFACTS),$($(x)_HDRS)) diff --git a/libc/intrin/extend.c b/libc/intrin/extend.c index 1452d026b..f4bf9383b 100644 --- a/libc/intrin/extend.c +++ b/libc/intrin/extend.c @@ -22,7 +22,7 @@ #include "libc/sysv/consts/map.h" #include "libc/sysv/consts/prot.h" -#define G getgransize() +#define G __gransize /** * Extends static allocation. diff --git a/libc/intrin/getauxval.c b/libc/intrin/getauxval.c index 3cbeeb560..54bc4a7e5 100644 --- a/libc/intrin/getauxval.c +++ b/libc/intrin/getauxval.c @@ -16,13 +16,9 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/getauxval.internal.h" -#include "libc/nt/struct/systeminfo.h" -#include "libc/nt/systeminfo.h" #include "libc/runtime/runtime.h" -#include "libc/sysv/consts/auxv.h" /** * Returns auxiliary value. @@ -36,22 +32,6 @@ unsigned long getauxval(unsigned long key) { struct AuxiliaryValue x; x = __getauxval(key); - if (key == AT_PAGESZ) { - if (!x.isfound) { - if (!IsWindows()) { -#ifdef __aarch64__ - x.value = 16384; -#else - x.value = 4096; -#endif - } else { - struct NtSystemInfo si; - GetSystemInfo(&si); - x.value = si.dwPageSize; - } - } - x.isfound = true; - } if (x.isfound) { return x.value; } else { diff --git a/libc/intrin/getgransize.c b/libc/intrin/getgransize.c index 805191a01..0b8e30418 100644 --- a/libc/intrin/getgransize.c +++ b/libc/intrin/getgransize.c @@ -16,22 +16,11 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/dce.h" -#include "libc/nt/struct/systeminfo.h" -#include "libc/nt/systeminfo.h" #include "libc/runtime/runtime.h" -#include "libc/sysv/consts/auxv.h" +/** + * Returns granularity of mmap() allocations. + */ int getgransize(void) { - static int res; - if (!res) { - if (!IsWindows()) { - res = getpagesize(); - } else { - struct NtSystemInfo si; - GetSystemInfo(&si); - res = si.dwAllocationGranularity; - } - } - return res; + return __gransize; } diff --git a/libc/intrin/getmainstack.c b/libc/intrin/getmainstack.c index e619949c1..3638898d9 100644 --- a/libc/intrin/getmainstack.c +++ b/libc/intrin/getmainstack.c @@ -105,7 +105,7 @@ static size_t __get_stack_size(int pagesz, uintptr_t start, uintptr_t top) { * This function works on every OS except Windows. */ struct AddrSize __get_main_stack(void) { - int pagesz = getpagesize(); + int pagesz = __pagesize; uintptr_t start = (uintptr_t)__argv; uintptr_t top = __get_main_top(pagesz); uintptr_t bot = top - __get_stack_size(pagesz, start, top); diff --git a/libc/intrin/getpagesize.c b/libc/intrin/getpagesize.c index 9f4149758..acfe9f298 100644 --- a/libc/intrin/getpagesize.c +++ b/libc/intrin/getpagesize.c @@ -1,7 +1,7 @@ /*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-β”‚ β”‚ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi β”‚ β•žβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•‘ -β”‚ Copyright 2023 Justine Alexandra Roberts Tunney β”‚ +β”‚ Copyright 2024 Justine Alexandra Roberts Tunney β”‚ β”‚ β”‚ β”‚ Permission to use, copy, modify, and/or distribute this software for β”‚ β”‚ any purpose with or without fee is hereby granted, provided that the β”‚ @@ -17,12 +17,11 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/runtime/runtime.h" -#include "libc/sysv/consts/auxv.h" /** - * Returns granularity of memory manager. + * Returns system page size. * @see sysconf(_SC_PAGE_SIZE) which is portable */ int getpagesize(void) { - return getauxval(AT_PAGESZ); + return __pagesize; } diff --git a/libc/intrin/maps.c b/libc/intrin/maps.c index 5ca9861ee..e7d913206 100644 --- a/libc/intrin/maps.c +++ b/libc/intrin/maps.c @@ -59,7 +59,7 @@ void __maps_stack(char *stackaddr, int pagesz, int guardsize, size_t stacksize, } void __maps_init(void) { - int pagesz = getpagesize(); + int pagesz = __pagesize; // record _start() stack mapping if (!IsWindows()) { diff --git a/libc/intrin/mmap.c b/libc/intrin/mmap.c index 25b2ead83..b54d7f900 100644 --- a/libc/intrin/mmap.c +++ b/libc/intrin/mmap.c @@ -100,7 +100,7 @@ void __maps_check(void) { #if MMDEBUG size_t maps = 0; size_t pages = 0; - int pagesz = getpagesize(); + int pagesz = __pagesize; static unsigned mono; unsigned id = ++mono; for (struct Map *map = __maps_first(); map; map = __maps_next(map)) { @@ -259,13 +259,13 @@ static void __maps_insert(struct Map *map) { if (prot == other->prot && flags == other->flags) { if (!coalesced) { if (map->addr == other->addr + other->size) { - __maps.pages += (map->size + getpagesize() - 1) / getpagesize(); + __maps.pages += (map->size + __pagesize - 1) / __pagesize; other->size += map->size; __maps_free(map); __maps_check(); coalesced = true; } else if (map->addr + map->size == other->addr) { - __maps.pages += (map->size + getpagesize() - 1) / getpagesize(); + __maps.pages += (map->size + __pagesize - 1) / __pagesize; other->addr -= map->size; other->size += map->size; __maps_free(map); @@ -288,7 +288,7 @@ static void __maps_insert(struct Map *map) { } // otherwise insert new mapping - __maps.pages += (map->size + getpagesize() - 1) / getpagesize(); + __maps.pages += (map->size + __pagesize - 1) / __pagesize; __maps_add(map); __maps_check(); } @@ -302,7 +302,7 @@ struct Map *__maps_alloc(void) { memory_order_relaxed)) return map; } - int gransz = getgransize(); + int gransz = __gransize; struct DirectMap sys = sys_mmap(0, gransz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (sys.addr == MAP_FAILED) @@ -323,8 +323,8 @@ struct Map *__maps_alloc(void) { static int __munmap(char *addr, size_t size) { // validate arguments - int pagesz = getpagesize(); - int gransz = getgransize(); + int pagesz = __pagesize; + int gransz = __gransize; if (((uintptr_t)addr & (gransz - 1)) || // !size || (uintptr_t)addr + size < size) return einval(); @@ -540,8 +540,8 @@ static void *__mmap_impl(char *addr, size_t size, int prot, int flags, int fd, static void *__mmap(char *addr, size_t size, int prot, int flags, int fd, int64_t off) { char *res; - int pagesz = getpagesize(); - int gransz = getgransize(); + int pagesz = __pagesize; + int gransz = __gransize; // validate arguments if (((uintptr_t)addr & (gransz - 1)) || // @@ -656,8 +656,8 @@ static void *__mremap_impl(char *old_addr, size_t old_size, size_t new_size, static void *__mremap(char *old_addr, size_t old_size, size_t new_size, int flags, char *new_addr) { - int pagesz = getpagesize(); - int gransz = getgransize(); + int pagesz = __pagesize; + int gransz = __gransize; // kernel support if (!IsLinux() && !IsNetbsd()) diff --git a/libc/intrin/mprotect.c b/libc/intrin/mprotect.c index cd0586fef..a3c38744a 100644 --- a/libc/intrin/mprotect.c +++ b/libc/intrin/mprotect.c @@ -60,7 +60,7 @@ int __mprotect(char *addr, size_t size, int prot) { return 0; // unix checks prot before checking size - int pagesz = getpagesize(); + int pagesz = __pagesize; if (((intptr_t)addr & (pagesz - 1)) || (uintptr_t)addr + size < size) return einval(); diff --git a/libc/intrin/msync-nt.c b/libc/intrin/msync-nt.c index 72ce53b0c..73f6ed95a 100644 --- a/libc/intrin/msync-nt.c +++ b/libc/intrin/msync-nt.c @@ -27,7 +27,7 @@ textwindows int sys_msync_nt(char *addr, size_t size, int flags) { - int pagesz = getpagesize(); + int pagesz = __pagesize; size = (size + pagesz - 1) & -pagesz; if ((uintptr_t)addr & (pagesz - 1)) diff --git a/libc/intrin/pagesize.c b/libc/intrin/pagesize.c new file mode 100644 index 000000000..a15149123 --- /dev/null +++ b/libc/intrin/pagesize.c @@ -0,0 +1,47 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-β”‚ +β”‚ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi β”‚ +β•žβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•‘ +β”‚ Copyright 2023 Justine Alexandra Roberts Tunney β”‚ +β”‚ β”‚ +β”‚ Permission to use, copy, modify, and/or distribute this software for β”‚ +β”‚ any purpose with or without fee is hereby granted, provided that the β”‚ +β”‚ above copyright notice and this permission notice appear in all copies. β”‚ +β”‚ β”‚ +β”‚ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL β”‚ +β”‚ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED β”‚ +β”‚ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE β”‚ +β”‚ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL β”‚ +β”‚ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR β”‚ +β”‚ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER β”‚ +β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ +β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ +β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/dce.h" +#include "libc/intrin/kprintf.h" +#include "libc/nt/struct/systeminfo.h" +#include "libc/nt/systeminfo.h" +#include "libc/runtime/runtime.h" +#include "libc/sysv/consts/auxv.h" + +#ifdef __x86_64__ +__static_yoink("_init_pagesize"); +#endif + +int __pagesize; +int __gransize; + +textstartup static int __pagesize_get(unsigned long *auxv) { + for (; auxv && auxv[0]; auxv += 2) + if (auxv[0] == AT_PAGESZ) + return auxv[1]; +#ifdef __aarch64__ + return 16384; +#else + return 4096; +#endif +} + +textstartup dontinstrument void __pagesize_init(unsigned long *auxv) { + if (!__pagesize) + __gransize = __pagesize = __pagesize_get(auxv); +} diff --git a/libc/intrin/pagesize_init.S b/libc/intrin/pagesize_init.S new file mode 100644 index 000000000..5c1cda3fa --- /dev/null +++ b/libc/intrin/pagesize_init.S @@ -0,0 +1,28 @@ +/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-β”‚ +β”‚ vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi β”‚ +β•žβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•‘ +β”‚ Copyright 2024 Justine Alexandra Roberts Tunney β”‚ +β”‚ β”‚ +β”‚ Permission to use, copy, modify, and/or distribute this software for β”‚ +β”‚ any purpose with or without fee is hereby granted, provided that the β”‚ +β”‚ above copyright notice and this permission notice appear in all copies. β”‚ +β”‚ β”‚ +β”‚ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL β”‚ +β”‚ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED β”‚ +β”‚ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE β”‚ +β”‚ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL β”‚ +β”‚ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR β”‚ +β”‚ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER β”‚ +β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ +β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ +β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/macros.internal.h" + + .init.start 251,_init_pagesize + push %rdi + push %rsi + mov %r15,%rdi + call __pagesize_init + pop %rsi + pop %rdi + .init.end 251,_init_pagesize diff --git a/libc/intrin/printmaps.c b/libc/intrin/printmaps.c index 18c02812e..0a67103b3 100644 --- a/libc/intrin/printmaps.c +++ b/libc/intrin/printmaps.c @@ -48,7 +48,7 @@ void __print_maps(size_t limit) { if (!--limit) break; } - kprintf("# %'zu bytes in %'zu mappings\n", __maps.pages * getpagesize(), + kprintf("# %'zu bytes in %'zu mappings\n", __maps.pages * __pagesize, __maps.count); __maps_unlock(); } diff --git a/libc/mem/leaks.c b/libc/mem/leaks.c index aae79fcfb..be64764aa 100644 --- a/libc/mem/leaks.c +++ b/libc/mem/leaks.c @@ -44,7 +44,7 @@ void __may_leak(void *alloc) { return; pthread_mutex_lock(&lock); if (dll_is_empty(freaks)) { - int g = getgransize(); + int g = __gransize; struct Leak *p = _mapanon(g); int n = g / sizeof(struct Leak); for (int i = 0; i < n; ++i) { diff --git a/libc/mem/pvalloc.c b/libc/mem/pvalloc.c index 95fee37c7..21346ab29 100644 --- a/libc/mem/pvalloc.c +++ b/libc/mem/pvalloc.c @@ -32,9 +32,9 @@ * @see valloc() */ void *pvalloc(size_t n) { - if (ckd_add(&n, n, getpagesize() - 1)) { + if (ckd_add(&n, n, __pagesize - 1)) { errno = ENOMEM; return 0; } - return memalign(getpagesize(), n & -getpagesize()); + return memalign(__pagesize, n & -__pagesize); } diff --git a/libc/mem/valloc.c b/libc/mem/valloc.c index 71fe70275..f8f9e90bf 100644 --- a/libc/mem/valloc.c +++ b/libc/mem/valloc.c @@ -29,5 +29,5 @@ * @see pvalloc() */ void *valloc(size_t n) { - return memalign(getpagesize(), n); + return memalign(__pagesize, n); } diff --git a/libc/nexgen32e/auxv.S b/libc/nexgen32e/auxv.S index 0c921df7c..e750b74fe 100644 --- a/libc/nexgen32e/auxv.S +++ b/libc/nexgen32e/auxv.S @@ -18,13 +18,13 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/macros.internal.h" - .initbss 300,_init_auxv + .initbss 250,_init_auxv // Global variable holding _start(auxv) parameter. __auxv: .quad 0 .endobj __auxv,globl .previous - .init.start 300,_init_auxv + .init.start 250,_init_auxv mov %r15,%rax stosq - .init.end 300,_init_auxv + .init.end 250,_init_auxv diff --git a/libc/proc/fork-nt.c b/libc/proc/fork-nt.c index e5e009d52..0c670b9c0 100644 --- a/libc/proc/fork-nt.c +++ b/libc/proc/fork-nt.c @@ -224,7 +224,7 @@ textwindows void WinMainForked(void) { } // map memory into process - int granularity = getgransize(); + int granularity = __gransize; for (struct Tree *e = tree_first(maps); e; e = tree_next(e)) { struct Map *map = MAP_TREE_CONTAINER(e); if ((uintptr_t)map->addr & (granularity - 1)) @@ -277,7 +277,7 @@ textwindows void WinMainForked(void) { for (struct Tree *e = tree_first(maps); e; e = tree_next(e)) { struct Map *map = MAP_TREE_CONTAINER(e); __maps.count += 1; - __maps.pages += (map->size + getpagesize() - 1) / getpagesize(); + __maps.pages += (map->size + __pagesize - 1) / __pagesize; unsigned old_protect; if (!VirtualProtect(map->addr, map->size, __prot2nt(map->prot, map->iscow), &old_protect)) @@ -385,7 +385,7 @@ textwindows int sys_fork_nt(uint32_t dwCreationFlags) { ok = WriteAll(writer, &map, sizeof(map)); } // now write content of each map to child - int granularity = getgransize(); + int granularity = __gransize; for (struct Map *map = __maps_first(); ok && map; map = __maps_next(map)) { if (map->flags & MAP_NOFORK) diff --git a/libc/runtime/cosmo2.c b/libc/runtime/cosmo2.c index 8d962a9a6..e102b8fee 100644 --- a/libc/runtime/cosmo2.c +++ b/libc/runtime/cosmo2.c @@ -66,6 +66,8 @@ extern char ape_stack_prot[] __attribute__((__weak__)); extern pthread_mutex_t __mmi_lock_obj; extern int hostos asm("__hostos"); +void __pagesize_init(unsigned long *auxv); + static const char *DecodeMagnum(const char *p, long *r) { int k = 0; unsigned long c, x = 0; @@ -164,6 +166,7 @@ wontreturn textstartup void cosmo(long *sp, struct Syslib *m1, char *exename, __pid = sys_getpid().ax; // initialize file system + __pagesize_init(auxv); __maps_init(); __init_fds(argc, argv, envp); @@ -172,13 +175,6 @@ wontreturn textstartup void cosmo(long *sp, struct Syslib *m1, char *exename, __enable_tls(); -#if 0 -#if IsAsan() - // TODO(jart): Figure out ASAN data model on AARCH64. - __asan_init(argc, argv, envp, auxv); -#endif -#endif - _init(); // initialize program #if SYSDEBUG diff --git a/libc/runtime/getavphyspages.c b/libc/runtime/getavphyspages.c index 4ed40d3ed..fc88bfa15 100644 --- a/libc/runtime/getavphyspages.c +++ b/libc/runtime/getavphyspages.c @@ -23,5 +23,5 @@ long __get_avphys_pages(void) { struct sysinfo si; if (sysinfo(&si) == -1) return -1; - return (((int64_t)si.freeram + si.bufferram) * si.mem_unit) / getpagesize(); + return (((int64_t)si.freeram + si.bufferram) * si.mem_unit) / __pagesize; } diff --git a/libc/runtime/getphyspages.c b/libc/runtime/getphyspages.c index 1e553894b..e732eafca 100644 --- a/libc/runtime/getphyspages.c +++ b/libc/runtime/getphyspages.c @@ -23,5 +23,5 @@ long __get_phys_pages(void) { struct sysinfo si; if (sysinfo(&si) == -1) return -1; - return ((int64_t)si.totalram * si.mem_unit) / getpagesize(); + return ((int64_t)si.totalram * si.mem_unit) / __pagesize; } diff --git a/libc/runtime/isstackoverflow.c b/libc/runtime/isstackoverflow.c index 5d19014c6..cb1068a9c 100644 --- a/libc/runtime/isstackoverflow.c +++ b/libc/runtime/isstackoverflow.c @@ -35,5 +35,5 @@ char __is_stack_overflow(siginfo_t *si, void *arg) { return false; intptr_t sp = uc->uc_mcontext.SP; intptr_t fp = (intptr_t)si->si_addr; - return ABS(fp - sp) < getpagesize(); + return ABS(fp - sp) < __pagesize; } diff --git a/libc/runtime/opensymboltable.greg.c b/libc/runtime/opensymboltable.greg.c index 433890d9d..7cd2c8d7a 100644 --- a/libc/runtime/opensymboltable.greg.c +++ b/libc/runtime/opensymboltable.greg.c @@ -49,7 +49,7 @@ static struct SymbolTable *OpenSymbolTableImpl(const char *filename) { size_t n, m, tsz, size; const Elf64_Sym *symtab, *sym; ptrdiff_t names_offset, name_base_offset, stp_offset; - long pagesz = getpagesize(); + long pagesz = __pagesize; map = MAP_FAILED; if ((fd = open(filename, O_RDONLY | O_CLOEXEC)) == -1) return 0; diff --git a/libc/runtime/runtime.h b/libc/runtime/runtime.h index 26f857536..2492fc95a 100644 --- a/libc/runtime/runtime.h +++ b/libc/runtime/runtime.h @@ -71,6 +71,8 @@ char *secure_getenv(const char *) paramsnonnull() __wur nosideeffect libcesque; extern int __argc; extern char **__argv; extern char **__envp; +extern int __pagesize; +extern int __gransize; extern unsigned long *__auxv; extern intptr_t __oldstack; extern char *__program_executable_name; diff --git a/libc/runtime/sysconf.c b/libc/runtime/sysconf.c index 2603ca453..f0c32dd90 100644 --- a/libc/runtime/sysconf.c +++ b/libc/runtime/sysconf.c @@ -61,9 +61,9 @@ long sysconf(int name) { case _SC_CLK_TCK: return CLK_TCK; case _SC_PAGESIZE: - return getpagesize(); + return __pagesize; case _SC_GRANSIZE: - return getgransize(); + return __gransize; case _SC_ARG_MAX: return __get_arg_max(); case _SC_SIGSTKSZ: diff --git a/libc/runtime/winmain.greg.c b/libc/runtime/winmain.greg.c index eb75a1700..9dda29289 100644 --- a/libc/runtime/winmain.greg.c +++ b/libc/runtime/winmain.greg.c @@ -59,6 +59,7 @@ __msabi extern typeof(AddVectoredExceptionHandler) *const __imp_AddVectoredExcep __msabi extern typeof(CreateFileMapping) *const __imp_CreateFileMappingW; __msabi extern typeof(DuplicateHandle) *const __imp_DuplicateHandle; __msabi extern typeof(FreeEnvironmentStrings) *const __imp_FreeEnvironmentStringsW; +__msabi extern typeof(GetCommandLine) *const __imp_GetCommandLineW; __msabi extern typeof(GetConsoleMode) *const __imp_GetConsoleMode; __msabi extern typeof(GetCurrentDirectory) *const __imp_GetCurrentDirectoryW; __msabi extern typeof(GetCurrentProcessId) *const __imp_GetCurrentProcessId; @@ -67,6 +68,7 @@ __msabi extern typeof(GetEnvironmentVariable) *const __imp_GetEnvironmentVariabl __msabi extern typeof(GetFileAttributes) *const __imp_GetFileAttributesW; __msabi extern typeof(GetStdHandle) *const __imp_GetStdHandle; __msabi extern typeof(GetSystemInfo) *const __imp_GetSystemInfo; +__msabi extern typeof(GetSystemInfo) *const __imp_GetSystemInfo; __msabi extern typeof(GetUserName) *const __imp_GetUserNameW; __msabi extern typeof(MapViewOfFileEx) *const __imp_MapViewOfFileEx; __msabi extern typeof(SetConsoleCP) *const __imp_SetConsoleCP; @@ -87,16 +89,6 @@ __funline int IsAlpha(int c) { return ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z'); } -// https://nullprogram.com/blog/2022/02/18/ -__funline char16_t *MyCommandLine(void) { - void *cmd; - asm("mov\t%%gs:(0x60),%0\n" - "mov\t0x20(%0),%0\n" - "mov\t0x78(%0),%0\n" - : "=r"(cmd)); - return cmd; -} - static abi char16_t *StrStr(const char16_t *haystack, const char16_t *needle) { size_t i; for (;;) { @@ -318,9 +310,13 @@ abi int64_t WinMain(int64_t hInstance, int64_t hPrevInstance, "sudo sh -c 'echo -1 > /proc/sys/fs/binfmt_misc/WSLInterop'\n"); return 77 << 8; // exit(77) } + struct NtSystemInfo si; + __imp_GetSystemInfo(&si); + __pagesize = si.dwPageSize; + __gransize = si.dwAllocationGranularity; __umask = 077; __pid = __imp_GetCurrentProcessId(); - cmdline = MyCommandLine(); + cmdline = __imp_GetCommandLineW(); #if SYSDEBUG // sloppy flag-only check for early initialization if (StrStr(cmdline, u"--strace")) diff --git a/libc/runtime/zipos-get.c b/libc/runtime/zipos-get.c index 352b7e4db..e2067a400 100644 --- a/libc/runtime/zipos-get.c +++ b/libc/runtime/zipos-get.c @@ -62,7 +62,7 @@ static void __zipos_dismiss(uint8_t *map, const uint8_t *cdir, long pg) { } // unmap the executable portion beneath the local files - mo = ROUNDDOWN(lo, getgransize()); + mo = ROUNDDOWN(lo, __gransize); if (mo) munmap(map, mo); @@ -128,7 +128,7 @@ static void __zipos_init(void) { if (!fstat(fd, &st) && (map = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0)) != MAP_FAILED) { if ((cdir = GetZipEocd(map, st.st_size, &err))) { - long pagesz = getpagesize(); + long pagesz = __pagesize; __zipos_dismiss(map, cdir, pagesz); __zipos.map = map; __zipos.cdir = cdir; diff --git a/libc/runtime/zipos-stat-impl.c b/libc/runtime/zipos-stat-impl.c index 5644a1bb0..93109bbc7 100644 --- a/libc/runtime/zipos-stat-impl.c +++ b/libc/runtime/zipos-stat-impl.c @@ -31,7 +31,7 @@ int __zipos_stat_impl(struct Zipos *zipos, size_t cf, struct stat *st) { bzero(st, sizeof(*st)); st->st_nlink = 1; st->st_dev = zipos->dev; - st->st_blksize = getpagesize(); + st->st_blksize = __pagesize; if (cf == ZIPOS_SYNTHETIC_DIRECTORY) { st->st_mode = S_IFDIR | (0555 & ~atomic_load_explicit( &__umask, memory_order_acquire)); diff --git a/libc/sysv/calls/getpagesize_freebsd.S b/libc/sysv/calls/getpagesize_freebsd.S deleted file mode 100644 index 23eb9eae1..000000000 --- a/libc/sysv/calls/getpagesize_freebsd.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/macros.internal.h" -.scall getpagesize_freebsd,0xffffff040fffffff,4095,4095,64,globl,hidden diff --git a/libc/sysv/syscalls.sh b/libc/sysv/syscalls.sh index 1887b7049..930516052 100755 --- a/libc/sysv/syscalls.sh +++ b/libc/sysv/syscalls.sh @@ -679,7 +679,6 @@ scall sys_getcontext 0x133fff1a5fffffff 0xfff globl hidden #scall gethostname 0xffff0057ffffffff 0xfff globl #scall getkerninfo 0xffffff03ffffffff 0xfff globl #scall getloginclass 0xffffff20bfffffff 0xfff globl -scall getpagesize_freebsd 0xffffff040fffffff 0xfff globl hidden #scall gssd_syscall 0xffffff1f9fffffff 0xfff globl #scall jail 0xffffff152fffffff 0xfff globl #scall jail_attach 0xffffff1b4fffffff 0xfff globl diff --git a/libc/thread/pthread_attr_init.c b/libc/thread/pthread_attr_init.c index 9f23d2595..b4c82204e 100644 --- a/libc/thread/pthread_attr_init.c +++ b/libc/thread/pthread_attr_init.c @@ -38,7 +38,7 @@ errno_t pthread_attr_init(pthread_attr_t *attr) { *attr = (pthread_attr_t){ .__stacksize = GetStackSize(), - .__guardsize = getpagesize(), + .__guardsize = __pagesize, }; return 0; } diff --git a/libc/thread/pthread_create.c b/libc/thread/pthread_create.c index 55db00ef4..c0933e50a 100644 --- a/libc/thread/pthread_create.c +++ b/libc/thread/pthread_create.c @@ -144,7 +144,7 @@ static int FixupCustomStackOnOpenbsd(pthread_attr_t *attr) { size_t n; uintptr_t x, y; int e, rc, pagesz; - pagesz = getpagesize(); + pagesz = __pagesize; n = attr->__stacksize; x = (uintptr_t)attr->__stackaddr; y = ROUNDUP(x, pagesz); @@ -210,7 +210,7 @@ static errno_t pthread_create_impl(pthread_t *thread, } } else { // cosmo is managing the stack - int pagesize = getpagesize(); + int pagesize = __pagesize; pt->pt_attr.__guardsize = ROUNDUP(pt->pt_attr.__guardsize, pagesize); pt->pt_attr.__stacksize = pt->pt_attr.__stacksize; if (pt->pt_attr.__guardsize + pagesize > pt->pt_attr.__stacksize) { From 1ff037df3cb5a969b791e7874af9d7609253aef1 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Fri, 19 Jul 2024 02:53:07 -0700 Subject: [PATCH 045/405] Add some documentation --- libc/intrin/mmap.c | 112 ++++++++++++++++++++++++++++-- libc/sysv/consts.sh | 1 - libc/sysv/consts/MAP_GROWSDOWN.S | 2 - test/libc/intrin/mmap_test.c | 78 ++++++++++++++++++--- third_party/dlmalloc/platform.inc | 6 +- 5 files changed, 177 insertions(+), 22 deletions(-) delete mode 100644 libc/sysv/consts/MAP_GROWSDOWN.S diff --git a/libc/intrin/mmap.c b/libc/intrin/mmap.c index b54d7f900..887d4de34 100644 --- a/libc/intrin/mmap.c +++ b/libc/intrin/mmap.c @@ -544,8 +544,13 @@ static void *__mmap(char *addr, size_t size, int prot, int flags, int fd, int gransz = __gransize; // validate arguments - if (((uintptr_t)addr & (gransz - 1)) || // - !size || (uintptr_t)addr + size < size) + if ((uintptr_t)addr & (gransz - 1)) + addr = NULL; + if (!addr && (flags & (MAP_FIXED | MAP_FIXED_NOREPLACE))) + return (void *)eperm(); + if ((intptr_t)addr < 0) + return (void *)enomem(); + if (!size || (uintptr_t)addr + size < size) return (void *)einval(); if (size > WINMAXX) return (void *)enomem(); @@ -732,13 +737,100 @@ static void *__mremap(char *old_addr, size_t old_size, size_t new_size, return res; } +/** + * Creates memory mapping. + * + * The mmap() function is used by Cosmopolitan's malloc() implementation + * to obtain new memory from the operating system. This function is also + * useful for establishing a mapping between a file on disk and a memory + * address, which avoids most need to call read() and write(). It is how + * executables are loaded into memory, for instance, in which case pages + * are loaded lazily from disk by the operating system. + * + * The `addr` parameter may be zero. This lets the implementation choose + * an available address in memory. OSes normally pick something randomly + * assigned, for security. Most OSes try to make sure subsequent mapping + * requests will be adjacent to one another. More paranoid OSes may have + * different mappings be sparse, with unmapped content between them. You + * may not use the `MAP_FIXED` parameter to create a memory map at NULL. + * + * The `addr` parameter may be non-zero, in which case Cosmopolitan will + * give you a mapping at that specific address if it's available. When a + * mapping already exists at the requested address then another one will + * be chosen automatically. On most OSes the newly selected address will + * be as close-by as possible, but that's not guaranteed. If `MAP_FIXED` + * is also supplied in `flags` then this hint is taken as mandatory, and + * existing mappings at the requested interval shall be auto-unmapped. + * + * The `size` parameter is implicitly rounded up to the system page size + * reported by getpagesize() and sysconf(_SC_PAGESIZE). Your extra bytes + * will be zero-initialized. + * + * The returned address will always be aligned, on the system allocation + * granularity. This value may be obtained from getgransize() or calling + * sysconf(_SC_GRANSIZE). Granularity is always greater than or equal to + * the page size. On some platforms, i.e. Windows, it may be larger than + * the page size. + * + * The `prot` value specifies the memory protection of the mapping. This + * may be `PROT_NONE` to disallow all access otherwise it's a bitwise or + * of the following constants: + * + * - `PROT_READ` allows read access + * - `PROT_WRITE` allows write access + * - `PROT_EXEC` allows execute access + * + * Some OSes (i.e. OpenBSD) will raise an error if both `PROT_WRITE` and + * `PROT_EXEC` are requested. You may still modify executable memory but + * you must use mprotect() to transition between the two states. On some + * OSes like MacOS ARM64, you need to pass the `MAP_JIT` flag to get RWX + * memory, which is considered zero on other OSes. + * + * The lower bits of the `flags` parameter specify the `MAP_TYPE`, which + * may be: + * + * - `MAP_PRIVATE` for non-shared and copy-on-write mappings + * - `MAP_SHARED` for memory that may be shared between processes + * + * Your `fd` argument specifies the file descriptor of the open file you + * want to map. This parameter is ignored when `MAP_ANONYMOUS` is passed + * via `flags`. + * + * Your `off` argument specifies the offset into a, file at which mapped + * memory shall begin. It must be aligned to the allocation granularity, + * which may be obtained from getgransize() or sysconf(_SC_GRANSIZE). + * + * The `MAP_FIXED_NOREPLACE` flag may be passed in `flags` which has the + * same behavior as `MAP_FIXED` except it raises `EEXIST` when a mapping + * already exists on the requested interval. + * + * The `MAP_CONCEAL` flag may be passed to prevent a memory mapping from + * appearing in core dumps. This is currently supported on BSD OSes, and + * is ignored on everything else. + */ void *mmap(void *addr, size_t size, int prot, int flags, int fd, int64_t off) { void *res = __mmap(addr, size, prot, flags, fd, off); - STRACE("mmap(%p, %'zu, %s, %s, %d, %'ld) β†’ %p% m", addr, size, - DescribeProtFlags(prot), DescribeMapFlags(flags), fd, off, res); + STRACE("mmap(%p, %'zu, %s, %s, %d, %'ld) β†’ %p% m (%'zu bytes total)", addr, + size, DescribeProtFlags(prot), DescribeMapFlags(flags), fd, off, res, + __maps.pages * __pagesize); return res; } +/** + * Changes memory mapping. + * + * This system call lets you move memory without copying it. It can also + * be used to shrink memory mappings. + * + * This system call is supported on Linux and NetBSD. It's used by Cosmo + * Libc's realloc() implementation under the hood. + * + * The `flags` parameter may have: + * + * - `MREMAP_MAYMOVE` to allow relocation + * - `MREMAP_FIXED` in which case an additional parameter is taken + * + */ void *mremap(void *old_addr, size_t old_size, size_t new_size, int flags, ...) { va_list ap; void *new_addr = 0; @@ -748,11 +840,19 @@ void *mremap(void *old_addr, size_t old_size, size_t new_size, int flags, ...) { va_end(ap); } void *res = __mremap(old_addr, old_size, new_size, flags, new_addr); - STRACE("mremap(%p, %'zu, %'zu, %s, %p) β†’ %p% m", old_addr, old_size, new_size, - DescribeMremapFlags(flags), new_addr, res); + STRACE("mremap(%p, %'zu, %'zu, %s, %p) β†’ %p% m (%'zu bytes total)", old_addr, + old_size, new_size, DescribeMremapFlags(flags), new_addr, res, + __maps.pages * __pagesize); return res; } +/** + * Removes memory mapping. + * + * The `size` parameter is implicitly rounded up to the page size. + * + * @return 0 on success, or -1 w/ errno. + */ int munmap(void *addr, size_t size) { int rc = __munmap(addr, size); STRACE("munmap(%p, %'zu) β†’ %d% m", addr, size, rc); diff --git a/libc/sysv/consts.sh b/libc/sysv/consts.sh index 74f00632f..b6ff0405a 100755 --- a/libc/sysv/consts.sh +++ b/libc/sysv/consts.sh @@ -223,7 +223,6 @@ syscon mmap MAP_TYPE 15 15 15 15 15 15 15 15 # mask for type syscon mmap MAP_FIXED 0x00000010 0x00000010 0x00000010 0x00000010 0x00000010 0x00000010 0x00000010 0x00000010 # unix consensus; openbsd appears to forbid; faked nt syscon mmap MAP_FIXED_NOREPLACE 0x08000000 0x08000000 0x00004000 0x00004000 0x08000000 0x08000000 0x08000000 0x08000000 # handled and defined by cosmo runtime; 0x100000 on linux 4.7+; MAP_FIXED|MAP_EXCL on FreeBSD syscon mmap MAP_ANONYMOUS 0x00000020 0x00000020 0x00001000 0x00001000 0x00001000 0x00001000 0x00001000 0x00000020 # bsd consensus; faked nt -syscon mmap MAP_GROWSDOWN 0x00000100 0x00000100 0 0 0 0 0 0 # use MAP_STACK; abstracted by MAP_STACK; may be passed to __sys_mmap() for low-level Linux fiddling syscon mmap MAP_LOCKED 0x00002000 0x00002000 0 0 0 0 0 0 syscon mmap MAP_NORESERVE 0x00004000 0x00004000 0x00000040 0x00000040 0 0 0x00000040 0 # Linux calls it "reserve"; NT calls it "commit"? which is default? syscon mmap MAP_POPULATE 0x00008000 0x00008000 0 0 0x00040000 0 0 0 # MAP_PREFAULT_READ on FreeBSD; can avoid madvise(MADV_WILLNEED) on private file mapping diff --git a/libc/sysv/consts/MAP_GROWSDOWN.S b/libc/sysv/consts/MAP_GROWSDOWN.S deleted file mode 100644 index 62bed1141..000000000 --- a/libc/sysv/consts/MAP_GROWSDOWN.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/consts/syscon.internal.h" -.syscon mmap,MAP_GROWSDOWN,0x00000100,0x00000100,0,0,0,0,0,0 diff --git a/test/libc/intrin/mmap_test.c b/test/libc/intrin/mmap_test.c index 80ca31c7e..7f765666f 100644 --- a/test/libc/intrin/mmap_test.c +++ b/test/libc/intrin/mmap_test.c @@ -22,6 +22,7 @@ #include "libc/errno.h" #include "libc/intrin/maps.h" #include "libc/limits.h" +#include "libc/literal.h" #include "libc/runtime/runtime.h" #include "libc/runtime/sysconf.h" #include "libc/stdio/rand.h" @@ -146,7 +147,6 @@ TEST(mmap, hint) { TEST(mprotect, punchHoleAndFillHole) { char *p; int count = __maps.count; - int gransz = getgransize(); // obtain memory ASSERT_NE(MAP_FAILED, @@ -223,16 +223,17 @@ TEST(mmap, testMapFile_fdGetsClosed_makesNoDifference) { TEST(mmap, fileOffset) { int fd; char *map; - int offset_align = IsWindows() ? gransz : getpagesize(); ASSERT_NE(-1, (fd = open("foo", O_CREAT | O_RDWR, 0644))); - EXPECT_NE(-1, ftruncate(fd, offset_align * 2)); - EXPECT_NE(-1, pwrite(fd, "hello", 5, offset_align * 0)); - EXPECT_NE(-1, pwrite(fd, "there", 5, offset_align * 1)); + EXPECT_NE(-1, ftruncate(fd, gransz * 2)); + EXPECT_NE(-1, pwrite(fd, "hello", 5, gransz * 0)); + EXPECT_NE(-1, pwrite(fd, "there", 5, gransz * 1)); EXPECT_NE(-1, fdatasync(fd)); - ASSERT_NE(MAP_FAILED, (map = mmap(NULL, offset_align, PROT_READ, MAP_PRIVATE, - fd, offset_align))); + ASSERT_SYS(EINVAL, MAP_FAILED, + mmap(NULL, gransz, PROT_READ, MAP_PRIVATE, fd, gransz - 1)); + ASSERT_NE(MAP_FAILED, + (map = mmap(NULL, gransz, PROT_READ, MAP_PRIVATE, fd, gransz))); EXPECT_EQ(0, memcmp(map, "there", 5), "%#.*s", 5, map); - EXPECT_NE(-1, munmap(map, offset_align)); + EXPECT_NE(-1, munmap(map, gransz)); EXPECT_NE(-1, close(fd)); } @@ -263,6 +264,67 @@ TEST(mmap, ziposCannotBeShared) { close(fd); } +TEST(mmap, misalignedAddr_justIgnoresIt) { + char *p; + ASSERT_NE(MAP_FAILED, (p = mmap((void *)1, 1, PROT_READ, + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0))); + munmap(p, 1); +} + +TEST(mmap, nullFixed_isNotAllowed) { + ASSERT_SYS( + EPERM, MAP_FAILED, + mmap(0, 1, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0)); + ASSERT_SYS(EPERM, MAP_FAILED, + mmap(0, 1, PROT_NONE, + MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED_NOREPLACE, -1, 0)); +} + +static int GetBitsInAddressSpace(void) { + int i; + void *ptr; + uint64_t want; + for (i = 0; i < 40; ++i) { + want = UINT64_C(0x8123000000000000) >> i; + if (want > UINTPTR_MAX) + continue; + if (msync((void *)(uintptr_t)want, 1, MS_ASYNC) == 0 || errno == EBUSY) + return 64 - i; + ptr = mmap((void *)(uintptr_t)want, 1, PROT_READ, + MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0); + if (ptr != MAP_FAILED) { + munmap(ptr, 1); + return 64 - i; + } + } + abort(); +} + +TEST(mmap, negative_isNotAllowed) { + ASSERT_SYS(ENOMEM, MAP_FAILED, + mmap((void *)-(70 * 1024 * 1024), 1, PROT_NONE, + MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0)); +} + +TEST(mmap, pml5t) { + switch (GetBitsInAddressSpace()) { + case 56: + ASSERT_EQ((void *)0x00fff2749119c000, + mmap((void *)0x00fff2749119c000, 1, PROT_NONE, + MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0)); + munmap((void *)0x00fff2749119c000, 1); + break; + case 48: + ASSERT_EQ((void *)0x0000f2749119c000, + mmap((void *)0x0000f2749119c000, 1, PROT_NONE, + MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0)); + munmap((void *)0x0000f2749119c000, 1); + break; + default: + break; + } +} + //////////////////////////////////////////////////////////////////////////////// // zipos NON-SHARED READ-ONLY FILE MEMORY diff --git a/third_party/dlmalloc/platform.inc b/third_party/dlmalloc/platform.inc index e21769099..8fab2e29e 100644 --- a/third_party/dlmalloc/platform.inc +++ b/third_party/dlmalloc/platform.inc @@ -505,11 +505,7 @@ FORCEINLINE int win32munmap(void* ptr, size_t size) { * Define CALL_MREMAP */ #if HAVE_MMAP && HAVE_MREMAP - #ifdef MREMAP - #define CALL_MREMAP(addr, osz, nsz, mv) MREMAP((addr), (osz), (nsz), (mv)) - #else /* MREMAP */ - #define CALL_MREMAP(addr, osz, nsz, mv) MREMAP_DEFAULT((addr), (osz), (nsz), (mv)) - #endif /* MREMAP */ + #define CALL_MREMAP(addr, osz, nsz, mv) ({ int olderr = errno; void *res = mremap((addr), (osz), (nsz), (mv)); if (res == MAP_FAILED) errno = olderr; res; }) #else /* HAVE_MMAP && HAVE_MREMAP */ #define CALL_MREMAP(addr, osz, nsz, mv) MAP_FAILED #endif /* HAVE_MMAP && HAVE_MREMAP */ From c697133a2db2aeb52e6c4a4b0315e72d6b392ebb Mon Sep 17 00:00:00 2001 From: Ikko Eltociear Ashimine Date: Fri, 19 Jul 2024 21:46:29 +0900 Subject: [PATCH 046/405] Fix typo in accept4-sysv.c (#1235) --- libc/sock/accept4-sysv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libc/sock/accept4-sysv.c b/libc/sock/accept4-sysv.c index 20ed11c37..86065680e 100644 --- a/libc/sock/accept4-sysv.c +++ b/libc/sock/accept4-sysv.c @@ -40,7 +40,7 @@ int sys_accept4(int server, struct sockaddr_storage *addr, int flags) { if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) return einval(); if ((client = __sys_accept(server, addr, &size, 0)) != -1) { - // __sys_accept() has inconsistent flag inheritence across platforms + // __sys_accept() has inconsistent flag inheritance across platforms // this is one of the issues that accept4() was invented for solving unassert((file_mode = __sys_fcntl(client, F_GETFD)) != -1); unassert(!__sys_fcntl(client, F_SETFD, From 1029dcc59719f7c73abb20fe36fb39e23ffbc00f Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Fri, 19 Jul 2024 14:14:08 -0700 Subject: [PATCH 047/405] Reduce default stack size from 256kb to 81kb This is the same as Musl Libc. Please note it only applies to threads. --- ctl/string_view.h | 6 +++--- libc/runtime/stack.h | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/ctl/string_view.h b/ctl/string_view.h index f4807c62c..64a895799 100644 --- a/ctl/string_view.h +++ b/ctl/string_view.h @@ -1,7 +1,7 @@ // -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*- // vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi -#ifndef COSMOPOLITAN_CTL_STRINGVIEW_H_ -#define COSMOPOLITAN_CTL_STRINGVIEW_H_ +#ifndef CTL_STRINGVIEW_H_ +#define CTL_STRINGVIEW_H_ #include "utility.h" namespace ctl { @@ -157,4 +157,4 @@ struct string_view } // namespace ctl -#endif // COSMOPOLITAN_CTL_STRINGVIEW_H_ +#endif // CTL_STRINGVIEW_H_ diff --git a/libc/runtime/stack.h b/libc/runtime/stack.h index a09fe61d8..8a8c5d934 100644 --- a/libc/runtime/stack.h +++ b/libc/runtime/stack.h @@ -1,18 +1,19 @@ #ifdef _COSMO_SOURCE #ifndef COSMOPOLITAN_LIBC_RUNTIME_STACK_H_ #define COSMOPOLITAN_LIBC_RUNTIME_STACK_H_ +#include "libc/runtime/runtime.h" /** * Returns preferred size and alignment of thread stack. */ -#define GetStackSize() 262144 +#define GetStackSize() 81920 /** * Returns preferred stack guard size. * * This is the max cpu page size of supported architectures. */ -#define GetGuardSize() 16384 +#define GetGuardSize() __pagesize /** * Makes program stack executable if declared, e.g. From 0ed916ad5c52b1739880791ccd6d33c4552a3de1 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Fri, 19 Jul 2024 19:11:28 -0700 Subject: [PATCH 048/405] Fix a bug in example code --- examples/crashreport2.cc | 5 ++--- libc/log/showcrashreports.c | 1 + 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/crashreport2.cc b/examples/crashreport2.cc index d57f3bdea..094a9e21b 100644 --- a/examples/crashreport2.cc +++ b/examples/crashreport2.cc @@ -7,9 +7,8 @@ β”‚ β€’ http://creativecommons.org/publicdomain/zero/1.0/ β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #endif -#include "libc/calls/calls.h" -#include "libc/math.h" -#include "libc/runtime/runtime.h" +#include +#include void crash(long x0, long x1, long x2, // double v0, double v1, double v2) { diff --git a/libc/log/showcrashreports.c b/libc/log/showcrashreports.c index bd68fe1b5..ff7ea1132 100644 --- a/libc/log/showcrashreports.c +++ b/libc/log/showcrashreports.c @@ -33,6 +33,7 @@ __static_yoink("__die"); // for backtracing __static_yoink("ShowBacktrace"); // for backtracing __static_yoink("GetSymbolTable"); // for backtracing __static_yoink("PrintBacktraceUsingSymbols"); // for backtracing +__static_yoink("__demangle"); // for pretty c++ symbols __static_yoink("malloc_inspect_all"); // for asan memory origin __static_yoink("GetSymbolByAddr"); // for asan memory origin #endif From 86d884cce24d773e298a2714c1e3d91ecab9be45 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Fri, 19 Jul 2024 19:36:25 -0700 Subject: [PATCH 049/405] Get rid of .internal.h convention in LIBC_INTRIN --- dsp/core/scalevolume.c | 2 +- dsp/tty/ident.c | 2 +- dsp/tty/ttymove.c | 2 +- dsp/tty/ttyraster.c | 2 +- examples/nesemu1.cc | 2 +- examples/unbourne.c | 2 +- libc/calls/assertfail.c | 2 +- libc/calls/cachestat.c | 2 +- libc/calls/chdir.c | 2 +- libc/calls/chroot.c | 2 +- libc/calls/clktck.c | 2 +- libc/calls/clock_getres.c | 4 ++-- libc/calls/clock_gettime.c | 4 ++-- libc/calls/clock_nanosleep-sys.c | 4 ++-- libc/calls/clock_settime.c | 4 ++-- libc/calls/close-nt.c | 2 +- libc/calls/close.c | 4 ++-- libc/calls/close_range.c | 2 +- libc/calls/closefrom.c | 2 +- libc/calls/commandv.c | 2 +- libc/calls/copy_file_range.c | 4 ++-- libc/calls/dup.c | 2 +- libc/calls/dup2.c | 2 +- libc/calls/dup3-sysv.c | 2 +- libc/calls/dup3.c | 2 +- libc/calls/faccessat.c | 4 ++-- libc/calls/fadvise.c | 2 +- libc/calls/fchdir.c | 2 +- libc/calls/fchmod-nt.c | 2 +- libc/calls/fchmod.c | 2 +- libc/calls/fchmodat.c | 4 ++-- libc/calls/fchown.c | 2 +- libc/calls/fchownat.c | 4 ++-- libc/calls/fcntl-nt.c | 2 +- libc/calls/fcntl.c | 4 ++-- libc/calls/fdatasync.c | 2 +- libc/calls/fdexists.c | 2 +- libc/calls/fileexists.c | 2 +- libc/calls/finddebugbinary.c | 2 +- libc/calls/flock-nt.c | 2 +- libc/calls/flock.c | 2 +- libc/calls/fstat-nt.c | 4 ++-- libc/calls/fstat.c | 4 ++-- libc/calls/fstatat-nt.c | 2 +- libc/calls/fstatat.c | 4 ++-- libc/calls/fstatfs.c | 4 ++-- libc/calls/fsync.c | 2 +- libc/calls/ftruncate.c | 2 +- libc/calls/futimens.c | 2 +- libc/calls/futimes.c | 2 +- libc/calls/getcwd.greg.c | 2 +- libc/calls/getdomainname.c | 2 +- libc/calls/getegid.c | 2 +- libc/calls/geteuid.c | 2 +- libc/calls/getgroups.c | 4 ++-- libc/calls/gethostname.c | 2 +- libc/calls/getloadavg.c | 2 +- libc/calls/getpgid.c | 2 +- libc/calls/getpgrp.c | 2 +- libc/calls/getppid.c | 2 +- libc/calls/getprogramexecutablename.greg.c | 4 ++-- libc/calls/getrandom.c | 2 +- libc/calls/getresgid.c | 2 +- libc/calls/getresuid.c | 2 +- libc/calls/getrlimit.c | 4 ++-- libc/calls/getsid.c | 2 +- libc/calls/getuid.c | 2 +- libc/calls/grantpt.c | 4 ++-- libc/calls/internal.h | 2 +- libc/calls/ioctl.c | 4 ++-- libc/calls/isatty-nt.c | 2 +- libc/calls/isatty.c | 2 +- libc/calls/isdirectory.c | 2 +- libc/calls/isregularfile.c | 2 +- libc/calls/issetugid.c | 4 ++-- libc/calls/issymlink.c | 2 +- libc/calls/kemptyfd.c | 2 +- libc/calls/landlock_add_rule.c | 2 +- libc/calls/landlock_create_ruleset.c | 2 +- libc/calls/landlock_restrict_self.c | 2 +- libc/calls/linkat.c | 4 ++-- libc/calls/lseek.c | 4 ++-- libc/calls/madvise.c | 2 +- libc/calls/memfd_create.c | 2 +- libc/calls/metalfile.c | 2 +- libc/calls/mincore.c | 2 +- libc/calls/mkdirat.c | 4 ++-- libc/calls/mknod.c | 2 +- libc/calls/mkntenvblock.c | 2 +- libc/calls/mkntpath.c | 2 +- libc/calls/mkntpathat.c | 2 +- libc/calls/ntaccesscheck.c | 2 +- libc/calls/ntspawn.c | 2 +- libc/calls/openat-metal.c | 2 +- libc/calls/openat.c | 4 ++-- libc/calls/pause.c | 2 +- libc/calls/pipe.c | 2 +- libc/calls/pipe2.c | 2 +- libc/calls/pivot_root.c | 2 +- libc/calls/pledge-linux.c | 2 +- libc/calls/pledge.c | 4 ++-- libc/calls/pledge.internal.h | 2 +- libc/calls/poll-metal.c | 2 +- libc/calls/poll-nt.c | 2 +- libc/calls/poll.c | 2 +- libc/calls/posix_fadvise.c | 4 ++-- libc/calls/posix_openpt.c | 4 ++-- libc/calls/ppoll.c | 2 +- libc/calls/prctl.c | 4 ++-- libc/calls/pread.c | 2 +- libc/calls/preadv.c | 2 +- libc/calls/printfds.c | 4 ++-- libc/calls/pselect.c | 4 ++-- libc/calls/ptrace.c | 4 ++-- libc/calls/ptsname.c | 4 ++-- libc/calls/pwrite.c | 4 ++-- libc/calls/pwritev.c | 2 +- libc/calls/raise.c | 2 +- libc/calls/read-nt.c | 8 ++++---- libc/calls/read.c | 2 +- libc/calls/readlinkat-nt.c | 2 +- libc/calls/readlinkat.c | 4 ++-- libc/calls/readv-metal.c | 2 +- libc/calls/readv-serial.c | 2 +- libc/calls/readv.c | 4 ++-- libc/calls/readwrite-nt.c | 2 +- libc/calls/renameat.c | 4 ++-- libc/calls/sched_get_priority_max.c | 4 ++-- libc/calls/sched_get_priority_min.c | 4 ++-- libc/calls/sched_getparam.c | 2 +- libc/calls/sched_getscheduler.c | 4 ++-- libc/calls/sched_rr_get_interval.c | 4 ++-- libc/calls/sched_setparam.c | 2 +- libc/calls/sched_setscheduler.c | 4 ++-- libc/calls/seccomp.c | 4 ++-- libc/calls/sedebug.c | 2 +- libc/calls/select.c | 4 ++-- libc/calls/setegid.c | 2 +- libc/calls/seteuid.c | 2 +- libc/calls/setfl.c | 2 +- libc/calls/setfsgid.c | 2 +- libc/calls/setfsuid.c | 2 +- libc/calls/setgid.c | 2 +- libc/calls/setgroups.c | 4 ++-- libc/calls/setpgid.c | 2 +- libc/calls/setregid.c | 2 +- libc/calls/setresgid.c | 2 +- libc/calls/setresuid.c | 2 +- libc/calls/setreuid.c | 2 +- libc/calls/setrlimit.c | 4 ++-- libc/calls/setsid.c | 2 +- libc/calls/settimeofday.c | 2 +- libc/calls/setuid.c | 2 +- libc/calls/sig.c | 4 ++-- libc/calls/sigaction.c | 4 ++-- libc/calls/sigaltstack.c | 4 ++-- libc/calls/sigcrashsig.c | 2 +- libc/calls/sigpending.c | 4 ++-- libc/calls/sigsuspend.c | 2 +- libc/calls/sigtimedwait.c | 2 +- libc/calls/splice.c | 4 ++-- libc/calls/statfs.c | 2 +- libc/calls/struct/iovec.internal.h | 2 +- libc/calls/struct/winsize.internal.h | 2 +- libc/calls/symlinkat.c | 4 ++-- libc/calls/sync.c | 2 +- libc/calls/sys_ptrace.c | 4 ++-- libc/calls/sysinfo.c | 2 +- libc/calls/tcdrain.c | 4 ++-- libc/calls/tcflow.c | 4 ++-- libc/calls/tcflush.c | 4 ++-- libc/calls/tcgetattr-nt.c | 4 ++-- libc/calls/tcgetattr.c | 2 +- libc/calls/tcgetpgrp.c | 2 +- libc/calls/tcgetsid.c | 2 +- libc/calls/tcgetwinsize.c | 2 +- libc/calls/tcsendbreak.c | 2 +- libc/calls/tcsetattr-nt.c | 4 ++-- libc/calls/tcsetattr.c | 2 +- libc/calls/tcsetpgrp.c | 2 +- libc/calls/tcsetsid.c | 2 +- libc/calls/tcsetwinsize.c | 2 +- libc/calls/truncate.c | 2 +- libc/calls/ttyname_r.c | 4 ++-- libc/calls/umask.c | 2 +- libc/calls/uname.c | 2 +- libc/calls/unassert.c | 2 +- libc/calls/unlinkat.c | 4 ++-- libc/calls/unlockpt.c | 4 ++-- libc/calls/unmount.c | 2 +- libc/calls/unveil.c | 2 +- libc/calls/utimens.c | 4 ++-- libc/calls/utimensat.c | 4 ++-- libc/calls/utimes.c | 2 +- libc/calls/vdsofunc.greg.c | 4 ++-- libc/calls/write-nt.c | 4 ++-- libc/calls/write.c | 2 +- libc/calls/writev-metal.c | 2 +- libc/calls/writev-serial.c | 2 +- libc/calls/writev.c | 4 ++-- libc/dlopen/dlopen.c | 2 +- libc/intrin/BUILD.mk | 2 +- libc/intrin/__getauxval.c | 2 +- libc/intrin/__getenv.c | 2 +- libc/intrin/aarch64/{asmdefs.internal.h => asmdefs.h} | 0 libc/intrin/aarch64/memchr.S | 2 +- libc/intrin/aarch64/memcpy.S | 2 +- libc/intrin/aarch64/memrchr.S | 2 +- libc/intrin/aarch64/memset.S | 2 +- libc/intrin/aarch64/stpcpy.S | 2 +- libc/intrin/aarch64/strchr.S | 2 +- libc/intrin/aarch64/strchrnul.S | 2 +- libc/intrin/aarch64/strcmp.S | 2 +- libc/intrin/aarch64/strcpy.S | 2 +- libc/intrin/aarch64/strlen.S | 2 +- libc/intrin/aarch64/strncmp.S | 2 +- libc/intrin/aarch64/strnlen.S | 2 +- libc/intrin/aarch64/strrchr.S | 2 +- libc/intrin/clearenv.c | 2 +- libc/intrin/createdirectory.c | 4 ++-- libc/intrin/createfile.c | 4 ++-- libc/intrin/createfilemapping.c | 4 ++-- libc/intrin/createfilemappingnuma.c | 4 ++-- libc/intrin/createnamedpipe.c | 4 ++-- libc/intrin/createpipe.c | 4 ++-- libc/intrin/createprocess.c | 4 ++-- libc/intrin/createsymboliclink.c | 4 ++-- libc/intrin/createthread.c | 4 ++-- libc/intrin/cxaatexit.c | 4 ++-- libc/intrin/{cxaatexit.internal.h => cxaatexit.h} | 0 libc/intrin/cxablocks.c | 2 +- libc/intrin/cxafinalize.c | 4 ++-- libc/intrin/cxalock.c | 2 +- libc/intrin/deletefile.c | 2 +- libc/intrin/describearchprctlcode.c | 2 +- libc/intrin/describebacktrace.c | 4 ++-- ...escribebacktrace.internal.h => describebacktrace.h} | 0 libc/intrin/describecancelstate.c | 2 +- libc/intrin/describecapability.c | 2 +- libc/intrin/describeclockname.c | 2 +- libc/intrin/describecontrolkeystate.c | 2 +- libc/intrin/describedirfd.c | 2 +- libc/intrin/describednotify.c | 2 +- libc/intrin/describeerrnoresult.c | 2 +- libc/intrin/describefcntlcmd.c | 2 +- libc/intrin/describeflags.c | 2 +- .../{describeflags.internal.h => describeflags.h} | 0 libc/intrin/describeflock.c | 2 +- libc/intrin/describefutexop.c | 2 +- libc/intrin/describehow.c | 2 +- libc/intrin/describeinoutint64.c | 2 +- libc/intrin/describeiovnt.c | 2 +- libc/intrin/describeitimer.c | 2 +- libc/intrin/describeitimerval.c | 2 +- libc/intrin/describemapflags.c | 2 +- libc/intrin/describemapping.c | 2 +- libc/intrin/describemremapflags.c | 2 +- libc/intrin/describentconsolemodeinputflags.c | 2 +- libc/intrin/describentconsolemodeoutputflags.c | 2 +- libc/intrin/describentcreationdisposition.c | 2 +- libc/intrin/describentfileaccessflags.c | 2 +- libc/intrin/describentfileflagattr.c | 2 +- libc/intrin/describentfilemapflags.c | 2 +- libc/intrin/describentfileshareflags.c | 2 +- libc/intrin/describentfiletypeflags.c | 2 +- libc/intrin/describentlockfileflags.c | 2 +- libc/intrin/describentmovfileinpflags.c | 2 +- libc/intrin/describentoverlapped.c | 2 +- ...entoverlapped.internal.h => describentoverlapped.h} | 0 libc/intrin/describentpageflags.c | 2 +- libc/intrin/describentpipemodeflags.c | 2 +- libc/intrin/describentpipeopenflags.c | 2 +- libc/intrin/describentprocaccessflags.c | 2 +- libc/intrin/describentsecurityattributes.c | 2 +- libc/intrin/describentstartflags.c | 2 +- libc/intrin/describentsymlinkflags.c | 2 +- libc/intrin/describeopenflags.c | 2 +- libc/intrin/describeopenmode.c | 2 +- libc/intrin/describepersonalityflags.c | 2 +- libc/intrin/describepollfds.c | 2 +- libc/intrin/describepollflags.c | 2 +- libc/intrin/describeprotflags.c | 2 +- libc/intrin/describeptrace.c | 2 +- libc/intrin/describeptraceevent.c | 2 +- libc/intrin/describerlimit.c | 2 +- libc/intrin/describerlimitname.c | 2 +- libc/intrin/describeschedparam.c | 2 +- libc/intrin/describeschedpolicy.c | 2 +- libc/intrin/describeseccompoperation.c | 2 +- libc/intrin/describesigaction.c | 2 +- libc/intrin/describesigaltstack.c | 2 +- libc/intrin/describesiginfo.c | 2 +- libc/intrin/describesleepflags.c | 2 +- libc/intrin/describesocketfamily.c | 2 +- libc/intrin/describesocketprotocol.c | 2 +- libc/intrin/describesockettype.c | 2 +- libc/intrin/describesocklevel.c | 2 +- libc/intrin/describesockoptname.c | 2 +- libc/intrin/describestdiostate.c | 2 +- libc/intrin/describestringlist.c | 2 +- libc/intrin/describetermios.c | 2 +- libc/intrin/describethreadcreationflags.c | 2 +- libc/intrin/describetimespec.c | 2 +- libc/intrin/describetimeval.c | 2 +- libc/intrin/describewhence.c | 2 +- libc/intrin/describewhichprio.c | 2 +- libc/intrin/describewinsize.c | 2 +- libc/intrin/deviceiocontrol.c | 4 ++-- libc/intrin/directmap-metal.c | 2 +- libc/intrin/directmap-nt.c | 2 +- libc/intrin/directmap.c | 6 +++--- libc/intrin/{directmap.internal.h => directmap.h} | 0 libc/intrin/dos2errno.c | 2 +- libc/intrin/{dos2errno.internal.h => dos2errno.h} | 0 libc/intrin/exit.c | 4 ++-- libc/intrin/{extend.internal.h => extend.h} | 0 libc/intrin/{g_fds.c => fds.c} | 10 +++++----- libc/{calls/struct/fd.internal.h => intrin/fds.h} | 0 libc/intrin/{g_fds_init.S => fds_init.S} | 4 ++-- libc/intrin/findclose.c | 2 +- libc/intrin/findfirstfile.c | 4 ++-- libc/intrin/findnextfile.c | 4 ++-- libc/intrin/flushfilebuffers.c | 2 +- libc/intrin/flushviewoffile.c | 2 +- libc/intrin/generateconsolectrlevent.c | 2 +- libc/intrin/getauxval.c | 2 +- libc/intrin/{getauxval.internal.h => getauxval.h} | 0 libc/intrin/getenv.c | 4 ++-- libc/intrin/{getenv.internal.h => getenv.h} | 0 libc/intrin/getexitcodeprocess.c | 2 +- libc/intrin/getfileattributes.c | 4 ++-- libc/intrin/getmainstack.c | 2 +- libc/intrin/getminsigstksz.c | 2 +- libc/intrin/iscall.c | 2 +- libc/intrin/{iscall.internal.h => iscall.h} | 0 libc/intrin/isdebuggerpresent.c | 4 ++-- libc/intrin/kprintf.greg.c | 4 ++-- libc/intrin/lockfileex.c | 6 +++--- libc/intrin/mapviewoffileex.c | 4 ++-- libc/intrin/mapviewoffileexnuma.c | 4 ++-- libc/intrin/mmap.c | 8 ++++---- libc/intrin/movefileex.c | 4 ++-- libc/intrin/mprotect.c | 6 +++--- libc/intrin/msync.c | 2 +- libc/intrin/munmap-metal.c | 2 +- libc/intrin/munmap-sysv.c | 6 +++--- libc/intrin/nomultics.c | 2 +- libc/intrin/{nomultics.internal.h => nomultics.h} | 0 libc/intrin/openprocess.c | 4 ++-- libc/intrin/printmaps.c | 2 +- libc/intrin/promises.c | 2 +- libc/intrin/{promises.internal.h => promises.h} | 0 libc/intrin/prot2nt.greg.c | 2 +- libc/intrin/pthread_atfork_actual.c | 2 +- libc/intrin/pthread_delay_np.c | 2 +- libc/intrin/pthread_mutex_lock.c | 4 ++-- libc/intrin/pthread_mutex_unlock.c | 2 +- libc/intrin/pthread_setcancelstate.c | 4 ++-- libc/intrin/{pushpop.internal.h => pushpop.h} | 0 libc/intrin/rand64.c | 2 +- libc/intrin/removedirectory.c | 2 +- libc/intrin/reopenfile.c | 4 ++-- libc/intrin/reservefd.c | 4 ++-- libc/intrin/{safemacros.internal.h => safemacros.h} | 0 libc/intrin/setcurrentdirectory.c | 2 +- libc/intrin/{setjmp.internal.h => setjmp.h} | 0 libc/intrin/sigprocmask.c | 4 ++-- libc/intrin/{strace.internal.h => strace.h} | 0 libc/intrin/stracef.greg.c | 4 ++-- libc/intrin/terminateprocess.c | 2 +- libc/intrin/ubsan.c | 4 ++-- libc/intrin/ulock.c | 4 ++-- libc/intrin/unlockfileex.c | 6 +++--- libc/intrin/unmapviewoffile.c | 2 +- libc/intrin/unsetenv.c | 2 +- libc/intrin/virtualprotect.c | 4 ++-- libc/intrin/waitformultipleobjects.c | 2 +- libc/intrin/waitforsingleobject.c | 2 +- libc/intrin/wsagetoverlappedresult.c | 4 ++-- libc/intrin/wsarecv.c | 6 +++--- libc/intrin/wsarecvfrom.c | 6 +++--- libc/intrin/wsawaitformultipleevents.c | 4 ++-- libc/intrin/{xchg.internal.h => xchg.h} | 0 libc/irq/acpi-xsdt.c | 2 +- libc/log/attachdebugger.c | 2 +- libc/log/backtrace2.c | 6 +++--- libc/log/backtrace3.c | 2 +- libc/log/checkfail.c | 4 ++-- libc/log/commandvenv.c | 2 +- libc/log/cxaprintexits.c | 2 +- libc/log/die.c | 2 +- libc/log/gdbexec.c | 2 +- libc/log/minicrash.c | 2 +- libc/log/oncrash_amd64.c | 6 +++--- libc/log/oncrash_arm64.c | 4 ++-- libc/log/printwindowsmemory.c | 2 +- libc/log/startfatal.c | 2 +- libc/log/vflogf.c | 4 ++-- libc/mem/leaks.c | 2 +- libc/mem/putenv.c | 4 ++-- libc/mem/realpath.c | 2 +- libc/mem/reverse.internal.h | 2 +- libc/mem/setenv.c | 2 +- libc/mem/shuffle.internal.h | 2 +- libc/proc/cocmd.c | 2 +- libc/proc/describefds.c | 4 ++-- libc/proc/describefds.internal.h | 2 +- libc/proc/execve-nt.greg.c | 2 +- libc/proc/execve-sysv.c | 6 +++--- libc/proc/execve.c | 6 +++--- libc/proc/fexecve.c | 6 +++--- libc/proc/fork-nt.c | 4 ++-- libc/proc/fork.c | 2 +- libc/proc/getpriority-nt.c | 2 +- libc/proc/getpriority.c | 4 ++-- libc/proc/getrusage.c | 2 +- libc/proc/kill-nt.c | 2 +- libc/proc/kill.c | 2 +- libc/proc/posix_spawn.c | 6 +++--- libc/proc/proc.c | 2 +- libc/proc/sched_getaffinity.c | 2 +- libc/proc/sched_setaffinity.c | 2 +- libc/proc/setpriority-nt.c | 2 +- libc/proc/setpriority.c | 4 ++-- libc/proc/vfork.S | 2 +- libc/proc/wait4-nt.c | 2 +- libc/proc/wait4.c | 2 +- libc/runtime/clone.c | 2 +- libc/runtime/cosmo.S | 2 +- libc/runtime/cosmo2.c | 2 +- libc/runtime/cxa_thread_atexit.c | 4 ++-- libc/runtime/enable_tls.c | 2 +- libc/runtime/exit.c | 4 ++-- libc/runtime/getlogin.c | 2 +- libc/runtime/getlogin_r.c | 2 +- libc/runtime/getsymboltable.c | 4 ++-- libc/runtime/inflate.c | 2 +- libc/runtime/login_tty.c | 2 +- libc/runtime/opensymboltable.greg.c | 2 +- libc/runtime/straceinit.greg.c | 4 ++-- libc/runtime/winmain.greg.c | 2 +- libc/runtime/zipos-get.c | 4 ++-- libc/runtime/zipos-mmap.c | 2 +- libc/runtime/zipos-open.c | 2 +- libc/runtime/zipos-stat-impl.c | 2 +- libc/sock/accept-nt.c | 2 +- libc/sock/accept4.c | 2 +- libc/sock/bind.c | 4 ++-- libc/sock/connect-nt.c | 2 +- libc/sock/connect.c | 4 ++-- libc/sock/epoll.c | 2 +- libc/sock/getsockname.c | 4 ++-- libc/sock/getsockopt.c | 6 +++--- libc/sock/kntwsadata.c | 2 +- libc/sock/listen.c | 4 ++-- libc/sock/recv-nt.c | 2 +- libc/sock/recv.c | 2 +- libc/sock/recvfrom-nt.c | 2 +- libc/sock/recvfrom.c | 2 +- libc/sock/recvmsg.c | 4 ++-- libc/sock/send-nt.c | 2 +- libc/sock/send.c | 2 +- libc/sock/sendfile.c | 4 ++-- libc/sock/sendmsg.c | 6 +++--- libc/sock/sendto-nt.c | 2 +- libc/sock/sendto.c | 2 +- libc/sock/setsockopt-nt.c | 2 +- libc/sock/setsockopt.c | 6 +++--- libc/sock/shutdown.c | 4 ++-- libc/sock/sockatmark.c | 4 ++-- libc/sock/sockdebug.c | 2 +- libc/sock/socket.c | 4 ++-- libc/sock/syscall_fd.internal.h | 2 +- libc/sock/syslog.c | 2 +- libc/stdio/dirstream.c | 2 +- libc/stdio/fflush_unlocked.c | 2 +- libc/stdio/fmt.c | 4 ++-- libc/stdio/fread.c | 4 ++-- libc/stdio/fseek.c | 4 ++-- libc/stdio/fwrite.c | 4 ++-- libc/stdio/getentropy.c | 2 +- libc/stdio/printargs.c | 6 +++--- libc/stdio/scanf.c | 2 +- libc/str/intsort.c | 2 +- libc/str/longsort.c | 2 +- libc/str/lz4cpy.c | 2 +- libc/str/lz4len.c | 2 +- libc/str/setlocale.c | 4 ++-- libc/str/strnwidth16.c | 2 +- libc/str/strwidth16.c | 2 +- libc/testlib/ezbenchreport.c | 2 +- libc/testlib/showerror.c | 2 +- libc/testlib/testmain.c | 6 +++--- libc/testlib/testrunner.c | 4 ++-- libc/thread/getitimer.c | 4 ++-- libc/thread/itimer.c | 2 +- libc/thread/pthread_cancel.c | 4 ++-- libc/thread/pthread_create.c | 4 ++-- libc/thread/pthread_detach.c | 4 ++-- libc/thread/pthread_exit.c | 4 ++-- libc/thread/pthread_getaffinity_np.c | 4 ++-- libc/thread/pthread_kill.c | 4 ++-- libc/thread/pthread_setaffinity_np.c | 4 ++-- libc/thread/pthread_setcanceltype.c | 4 ++-- libc/thread/pthread_setname_np.c | 4 ++-- libc/thread/pthread_timedjoin_np.c | 4 ++-- libc/thread/sem_open.c | 2 +- libc/thread/setitimer.c | 4 ++-- libc/vga/readv-vga.c | 2 +- libc/vga/tty.greg.c | 4 ++-- libc/vga/writev-vga.c | 2 +- libc/x/paginate.c | 2 +- libc/x/xjoinpaths.c | 2 +- net/turfwar/blackholed.c | 2 +- net/turfwar/turfwar.c | 2 +- test/libc/calls/clock_nanosleep_test.c | 4 ++-- test/libc/calls/commandv_test.c | 2 +- test/libc/calls/devfd_test.c | 2 +- test/libc/calls/ftruncate_test.c | 2 +- test/libc/calls/pledge2_test.c | 2 +- test/libc/calls/setrlimit_test.c | 4 ++-- test/libc/intrin/describeflags_test.c | 2 +- test/libc/intrin/describegidlist_test.c | 2 +- test/libc/intrin/describesigset_test.c | 2 +- test/libc/intrin/dos2errno_test.c | 2 +- test/libc/intrin/mprotect_test.c | 2 +- test/libc/intrin/pthread_mutex_lock_test.c | 2 +- test/libc/mem/malloc_test.c | 4 ++-- test/libc/mem/realpath_test.c | 2 +- test/libc/nexgen32e/lz4decode_test.c | 2 +- test/libc/proc/posix_spawn_test.c | 2 +- test/libc/proc/sched_getaffinity_test.c | 2 +- test/libc/sock/inet_pton_test.c | 2 +- test/libc/sock/nonblock_test.c | 2 +- test/libc/sock/socket_test.c | 2 +- test/libc/stdio/palandprintf_test.c | 4 ++-- test/libc/stdio/sprintf_s_test.c | 2 +- test/libc/thread/pthread_detach_test.c | 2 +- test/libc/thread/pthread_exit_test.c | 2 +- third_party/dlmalloc/dlmalloc_abort.c | 2 +- third_party/dlmalloc/threaded.inc | 2 +- third_party/linenoise/linenoise.c | 4 ++-- third_party/lua/lrepl.c | 2 +- third_party/lua/lunix.c | 2 +- third_party/mbedtls/ecp.c | 2 +- third_party/mbedtls/profile.h | 2 +- third_party/mbedtls/rsa.c | 2 +- third_party/mbedtls/test/lib.c | 4 ++-- third_party/mbedtls/test/test_suite_ssl.c | 2 +- third_party/nsync/common.c | 4 ++-- third_party/nsync/futex.c | 4 ++-- third_party/nsync/mu_semaphore_gcd.c | 2 +- third_party/nsync/mu_semaphore_sem.c | 2 +- third_party/nsync/panic.c | 2 +- third_party/nsync/yield.c | 2 +- third_party/python/Python/pystate.c | 2 +- third_party/python/runpythonmodule.c | 2 +- third_party/regex/regerror.c | 2 +- tool/build/compile.c | 2 +- tool/build/dso/sandbox.c | 2 +- tool/build/elf2pe.c | 2 +- tool/build/helpop.c | 2 +- tool/build/lib/demangle.c | 2 +- tool/build/lib/eztls.c | 2 +- tool/build/lib/interner.c | 2 +- tool/build/lib/panel.c | 2 +- tool/build/pledge.c | 4 ++-- tool/build/runit.c | 2 +- tool/decode/elf.c | 2 +- tool/decode/lib/asmcodegen.c | 2 +- tool/decode/macho.c | 2 +- tool/decode/pe2.c | 2 +- tool/decode/zip.c | 2 +- tool/net/redbean.c | 4 ++-- tool/plinko/lib/plinko.c | 2 +- tool/plinko/lib/printf.c | 2 +- tool/plinko/lib/read.c | 2 +- tool/viz/deathstar.c | 2 +- tool/viz/fixconsole.c | 2 +- tool/viz/fold.c | 2 +- tool/viz/lib/formatstringtable-assembly.c | 2 +- tool/viz/lib/formatstringtable-code.c | 2 +- tool/viz/lib/formatstringtable.c | 2 +- tool/viz/life.c | 4 ++-- tool/viz/memzoom.c | 2 +- tool/viz/printansi.c | 2 +- tool/viz/printdos2errno.c | 2 +- tool/viz/printvideo.c | 4 ++-- tool/viz/rlimit.c | 4 ++-- tool/viz/tailf.c | 2 +- tool/viz/virtualquery.c | 2 +- 591 files changed, 773 insertions(+), 773 deletions(-) rename libc/intrin/aarch64/{asmdefs.internal.h => asmdefs.h} (100%) rename libc/intrin/{cxaatexit.internal.h => cxaatexit.h} (100%) rename libc/intrin/{describebacktrace.internal.h => describebacktrace.h} (100%) rename libc/intrin/{describeflags.internal.h => describeflags.h} (100%) rename libc/intrin/{describentoverlapped.internal.h => describentoverlapped.h} (100%) rename libc/intrin/{directmap.internal.h => directmap.h} (100%) rename libc/intrin/{dos2errno.internal.h => dos2errno.h} (100%) rename libc/intrin/{extend.internal.h => extend.h} (100%) rename libc/intrin/{g_fds.c => fds.c} (96%) rename libc/{calls/struct/fd.internal.h => intrin/fds.h} (100%) rename libc/intrin/{g_fds_init.S => fds_init.S} (97%) rename libc/intrin/{getauxval.internal.h => getauxval.h} (100%) rename libc/intrin/{getenv.internal.h => getenv.h} (100%) rename libc/intrin/{iscall.internal.h => iscall.h} (100%) rename libc/intrin/{nomultics.internal.h => nomultics.h} (100%) rename libc/intrin/{promises.internal.h => promises.h} (100%) rename libc/intrin/{pushpop.internal.h => pushpop.h} (100%) rename libc/intrin/{safemacros.internal.h => safemacros.h} (100%) rename libc/intrin/{setjmp.internal.h => setjmp.h} (100%) rename libc/intrin/{strace.internal.h => strace.h} (100%) rename libc/intrin/{xchg.internal.h => xchg.h} (100%) diff --git a/dsp/core/scalevolume.c b/dsp/core/scalevolume.c index 4586aeb22..2ca6e479f 100644 --- a/dsp/core/scalevolume.c +++ b/dsp/core/scalevolume.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "dsp/core/core.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/limits.h" /** diff --git a/dsp/tty/ident.c b/dsp/tty/ident.c index 9e28c817d..da830cab7 100644 --- a/dsp/tty/ident.c +++ b/dsp/tty/ident.c @@ -21,7 +21,7 @@ #include "libc/calls/termios.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/intrin/weaken.h" #include "libc/mem/mem.h" #include "libc/runtime/runtime.h" diff --git a/dsp/tty/ttymove.c b/dsp/tty/ttymove.c index 48d6696e4..838259f7e 100644 --- a/dsp/tty/ttymove.c +++ b/dsp/tty/ttymove.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "dsp/tty/itoa8.h" #include "dsp/tty/tty.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/limits.h" #include "libc/log/check.h" diff --git a/dsp/tty/ttyraster.c b/dsp/tty/ttyraster.c index 1ced9e374..a4e5e98fd 100644 --- a/dsp/tty/ttyraster.c +++ b/dsp/tty/ttyraster.c @@ -22,7 +22,7 @@ #include "dsp/tty/ttyrgb.h" #include "dsp/tty/windex.h" #include "libc/assert.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/limits.h" #include "libc/log/check.h" #include "libc/log/log.h" diff --git a/examples/nesemu1.cc b/examples/nesemu1.cc index 0104fd100..a7799bff0 100644 --- a/examples/nesemu1.cc +++ b/examples/nesemu1.cc @@ -19,7 +19,7 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/conv.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/inttypes.h" #include "libc/log/check.h" #include "libc/log/log.h" diff --git a/examples/unbourne.c b/examples/unbourne.c index c8fe70c0f..0500f1088 100644 --- a/examples/unbourne.c +++ b/examples/unbourne.c @@ -122,7 +122,7 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/conv.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/limits.h" #include "libc/log/log.h" #include "libc/macros.internal.h" diff --git a/libc/calls/assertfail.c b/libc/calls/assertfail.c index 9a15d2e8c..dc69fca5c 100644 --- a/libc/calls/assertfail.c +++ b/libc/calls/assertfail.c @@ -21,7 +21,7 @@ #include "libc/calls/struct/sigset.internal.h" #include "libc/errno.h" #include "libc/fmt/itoa.h" -#include "libc/intrin/describebacktrace.internal.h" +#include "libc/intrin/describebacktrace.h" #include "libc/runtime/runtime.h" #include "libc/runtime/symbols.internal.h" diff --git a/libc/calls/cachestat.c b/libc/calls/cachestat.c index 0163aeed7..6ab48a757 100644 --- a/libc/calls/cachestat.c +++ b/libc/calls/cachestat.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/cachestat.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" int sys_cachestat(int, struct cachestat_range *, struct cachestat *, uint32_t); diff --git a/libc/calls/chdir.c b/libc/calls/chdir.c index b37eaf655..876dedb60 100644 --- a/libc/calls/chdir.c +++ b/libc/calls/chdir.c @@ -20,7 +20,7 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/log/log.h" #include "libc/runtime/runtime.h" diff --git a/libc/calls/chroot.c b/libc/calls/chroot.c index c5256fd1a..e18ed88c0 100644 --- a/libc/calls/chroot.c +++ b/libc/calls/chroot.c @@ -19,7 +19,7 @@ #include "libc/calls/calls.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sysv/errfuns.h" /** diff --git a/libc/calls/clktck.c b/libc/calls/clktck.c index b59a73711..3e39b4e3f 100644 --- a/libc/calls/clktck.c +++ b/libc/calls/clktck.c @@ -20,7 +20,7 @@ #include "libc/calls/calls.h" #include "libc/dce.h" #include "libc/fmt/wintime.internal.h" -#include "libc/intrin/getauxval.internal.h" +#include "libc/intrin/getauxval.h" #include "libc/runtime/runtime.h" #include "libc/sysv/consts/auxv.h" diff --git a/libc/calls/clock_getres.c b/libc/calls/clock_getres.c index e400e0569..fae7959c4 100644 --- a/libc/calls/clock_getres.c +++ b/libc/calls/clock_getres.c @@ -18,8 +18,8 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/struct/timespec.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/sysv/consts/clock.h" #include "libc/sysv/errfuns.h" #include "libc/time.h" diff --git a/libc/calls/clock_gettime.c b/libc/calls/clock_gettime.c index c5f72fdd9..2aac56c98 100644 --- a/libc/calls/clock_gettime.c +++ b/libc/calls/clock_gettime.c @@ -21,8 +21,8 @@ #include "libc/calls/syscall_support-sysv.internal.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/runtime/syslib.internal.h" #ifdef __aarch64__ diff --git a/libc/calls/clock_nanosleep-sys.c b/libc/calls/clock_nanosleep-sys.c index 3d0e5cef8..d33d9454c 100644 --- a/libc/calls/clock_nanosleep-sys.c +++ b/libc/calls/clock_nanosleep-sys.c @@ -22,8 +22,8 @@ #include "libc/calls/struct/timespec.internal.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/sysv/errfuns.h" #include "libc/thread/thread.h" diff --git a/libc/calls/clock_settime.c b/libc/calls/clock_settime.c index e738d35df..b618cbdec 100644 --- a/libc/calls/clock_settime.c +++ b/libc/calls/clock_settime.c @@ -21,8 +21,8 @@ #include "libc/calls/struct/timeval.h" #include "libc/calls/struct/timeval.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/sysv/consts/clock.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/close-nt.c b/libc/calls/close-nt.c index 5d5b49645..74475c8d3 100644 --- a/libc/calls/close-nt.c +++ b/libc/calls/close-nt.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall_support-nt.internal.h" #include "libc/intrin/weaken.h" diff --git a/libc/calls/close.c b/libc/calls/close.c index d054f8199..979d24937 100644 --- a/libc/calls/close.c +++ b/libc/calls/close.c @@ -20,14 +20,14 @@ #include "libc/calls/calls.h" #include "libc/calls/internal.h" #include "libc/calls/state.internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/sigset.internal.h" #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/runtime/zipos.internal.h" #include "libc/sock/syscall_fd.internal.h" diff --git a/libc/calls/close_range.c b/libc/calls/close_range.c index adf2049e5..3ee22d119 100644 --- a/libc/calls/close_range.c +++ b/libc/calls/close_range.c @@ -19,7 +19,7 @@ #include "libc/calls/calls.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sysv/errfuns.h" /** diff --git a/libc/calls/closefrom.c b/libc/calls/closefrom.c index f102259cf..fe30a4672 100644 --- a/libc/calls/closefrom.c +++ b/libc/calls/closefrom.c @@ -21,7 +21,7 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/limits.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/commandv.c b/libc/calls/commandv.c index a603e4373..925ffbe1c 100644 --- a/libc/calls/commandv.c +++ b/libc/calls/commandv.c @@ -19,7 +19,7 @@ #include "libc/calls/calls.h" #include "libc/calls/struct/stat.h" #include "libc/errno.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/paths.h" #include "libc/runtime/runtime.h" #include "libc/str/str.h" diff --git a/libc/calls/copy_file_range.c b/libc/calls/copy_file_range.c index d35fcbc9a..af90ab52d 100644 --- a/libc/calls/copy_file_range.c +++ b/libc/calls/copy_file_range.c @@ -27,8 +27,8 @@ #include "libc/cosmo.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/sysv/consts/sig.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/dup.c b/libc/calls/dup.c index caab149ee..e502622fb 100644 --- a/libc/calls/dup.c +++ b/libc/calls/dup.c @@ -21,7 +21,7 @@ #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/runtime/zipos.internal.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/dup2.c b/libc/calls/dup2.c index 34d42dd12..3d5178259 100644 --- a/libc/calls/dup2.c +++ b/libc/calls/dup2.c @@ -23,7 +23,7 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/runtime/zipos.internal.h" #include "libc/str/str.h" diff --git a/libc/calls/dup3-sysv.c b/libc/calls/dup3-sysv.c index 5f7889091..93cf8a732 100644 --- a/libc/calls/dup3-sysv.c +++ b/libc/calls/dup3-sysv.c @@ -22,7 +22,7 @@ #include "libc/cosmo.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sysv/consts/o.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/dup3.c b/libc/calls/dup3.c index 368942c61..4d2f327cc 100644 --- a/libc/calls/dup3.c +++ b/libc/calls/dup3.c @@ -23,7 +23,7 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/runtime/zipos.internal.h" #include "libc/str/str.h" diff --git a/libc/calls/faccessat.c b/libc/calls/faccessat.c index 7493e5e90..f9df7a9c0 100644 --- a/libc/calls/faccessat.c +++ b/libc/calls/faccessat.c @@ -22,8 +22,8 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/runtime/zipos.internal.h" #include "libc/sysv/consts/at.h" diff --git a/libc/calls/fadvise.c b/libc/calls/fadvise.c index fb191ff34..36078bbcd 100644 --- a/libc/calls/fadvise.c +++ b/libc/calls/fadvise.c @@ -22,7 +22,7 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/str/str.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/fchdir.c b/libc/calls/fchdir.c index cfa17b725..509d078f3 100644 --- a/libc/calls/fchdir.c +++ b/libc/calls/fchdir.c @@ -21,7 +21,7 @@ #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sysv/errfuns.h" /** diff --git a/libc/calls/fchmod-nt.c b/libc/calls/fchmod-nt.c index 5b31226c0..bd3249070 100644 --- a/libc/calls/fchmod-nt.c +++ b/libc/calls/fchmod-nt.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall_support-nt.internal.h" #include "libc/nt/enum/fileflagandattributes.h" diff --git a/libc/calls/fchmod.c b/libc/calls/fchmod.c index a4070cb02..88a0221d9 100644 --- a/libc/calls/fchmod.c +++ b/libc/calls/fchmod.c @@ -21,7 +21,7 @@ #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sysv/errfuns.h" /** diff --git a/libc/calls/fchmodat.c b/libc/calls/fchmodat.c index e5bbc9bdf..744ad5bdb 100644 --- a/libc/calls/fchmodat.c +++ b/libc/calls/fchmodat.c @@ -22,8 +22,8 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/runtime/zipos.internal.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/fchown.c b/libc/calls/fchown.c index e105e7bb6..2418873b8 100644 --- a/libc/calls/fchown.c +++ b/libc/calls/fchown.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" #include "libc/calls/syscall-sysv.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sysv/consts/at.h" /** diff --git a/libc/calls/fchownat.c b/libc/calls/fchownat.c index 132cacac5..235f403ff 100644 --- a/libc/calls/fchownat.c +++ b/libc/calls/fchownat.c @@ -19,8 +19,8 @@ #include "libc/calls/calls.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/runtime/zipos.internal.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/fcntl-nt.c b/libc/calls/fcntl-nt.c index 73584e48d..a94130412 100644 --- a/libc/calls/fcntl-nt.c +++ b/libc/calls/fcntl-nt.c @@ -20,7 +20,7 @@ #include "libc/calls/calls.h" #include "libc/calls/createfileflags.internal.h" #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/flock.h" #include "libc/calls/struct/sigset.internal.h" #include "libc/calls/syscall-nt.internal.h" diff --git a/libc/calls/fcntl.c b/libc/calls/fcntl.c index 497ff2ccb..5193c291e 100644 --- a/libc/calls/fcntl.c +++ b/libc/calls/fcntl.c @@ -24,8 +24,8 @@ #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/runtime/zipos.internal.h" #include "libc/str/str.h" diff --git a/libc/calls/fdatasync.c b/libc/calls/fdatasync.c index a452e6bdf..0bf8c3453 100644 --- a/libc/calls/fdatasync.c +++ b/libc/calls/fdatasync.c @@ -22,7 +22,7 @@ #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/runtime/runtime.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/fdexists.c b/libc/calls/fdexists.c index fd5b9b71b..0965ec528 100644 --- a/libc/calls/fdexists.c +++ b/libc/calls/fdexists.c @@ -21,7 +21,7 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sysv/consts/f.h" /** diff --git a/libc/calls/fileexists.c b/libc/calls/fileexists.c index 03d3a9b80..56d58474d 100644 --- a/libc/calls/fileexists.c +++ b/libc/calls/fileexists.c @@ -23,7 +23,7 @@ #include "libc/calls/syscall_support-nt.internal.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/nt/files.h" #include "libc/runtime/zipos.internal.h" diff --git a/libc/calls/finddebugbinary.c b/libc/calls/finddebugbinary.c index b4bae854e..e8afd3935 100644 --- a/libc/calls/finddebugbinary.c +++ b/libc/calls/finddebugbinary.c @@ -26,7 +26,7 @@ #include "libc/elf/def.h" #include "libc/elf/tinyelf.internal.h" #include "libc/errno.h" -#include "libc/intrin/directmap.internal.h" +#include "libc/intrin/directmap.h" #include "libc/nt/memory.h" #include "libc/nt/runtime.h" #include "libc/runtime/runtime.h" diff --git a/libc/calls/flock-nt.c b/libc/calls/flock-nt.c index 734362ffa..1f23a0e69 100644 --- a/libc/calls/flock-nt.c +++ b/libc/calls/flock-nt.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall_support-nt.internal.h" #include "libc/nt/enum/filelockflags.h" diff --git a/libc/calls/flock.c b/libc/calls/flock.c index 080e2f1f7..2935e1e65 100644 --- a/libc/calls/flock.c +++ b/libc/calls/flock.c @@ -21,7 +21,7 @@ #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" /** * Acquires lock on file. diff --git a/libc/calls/fstat-nt.c b/libc/calls/fstat-nt.c index 97a941b1c..3c6b8c1cd 100644 --- a/libc/calls/fstat-nt.c +++ b/libc/calls/fstat-nt.c @@ -19,14 +19,14 @@ #include "libc/assert.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/stat.h" #include "libc/calls/struct/stat.internal.h" #include "libc/calls/syscall_support-nt.internal.h" #include "libc/fmt/wintime.internal.h" #include "libc/intrin/atomic.h" #include "libc/intrin/bsr.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/macros.internal.h" #include "libc/mem/alloca.h" #include "libc/nt/enum/fileflagandattributes.h" diff --git a/libc/calls/fstat.c b/libc/calls/fstat.c index bec74978d..094ae5347 100644 --- a/libc/calls/fstat.c +++ b/libc/calls/fstat.c @@ -20,8 +20,8 @@ #include "libc/calls/internal.h" #include "libc/calls/struct/stat.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/runtime/zipos.internal.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/fstatat-nt.c b/libc/calls/fstatat-nt.c index b8b75e8f8..1415cb84c 100644 --- a/libc/calls/fstatat-nt.c +++ b/libc/calls/fstatat-nt.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/sigset.internal.h" #include "libc/calls/struct/stat.internal.h" #include "libc/calls/syscall_support-nt.internal.h" diff --git a/libc/calls/fstatat.c b/libc/calls/fstatat.c index 9e4247067..0d4946f95 100644 --- a/libc/calls/fstatat.c +++ b/libc/calls/fstatat.c @@ -23,8 +23,8 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/itoa.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/log/log.h" #include "libc/mem/alloca.h" diff --git a/libc/calls/fstatfs.c b/libc/calls/fstatfs.c index 607acb621..fee2e5039 100644 --- a/libc/calls/fstatfs.c +++ b/libc/calls/fstatfs.c @@ -19,11 +19,11 @@ #include "libc/calls/calls.h" #include "libc/calls/cp.internal.h" #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/statfs-meta.internal.h" #include "libc/calls/struct/statfs.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/runtime/stack.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/fsync.c b/libc/calls/fsync.c index 95a28e45e..72c2bd823 100644 --- a/libc/calls/fsync.c +++ b/libc/calls/fsync.c @@ -22,7 +22,7 @@ #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/runtime/runtime.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/ftruncate.c b/libc/calls/ftruncate.c index e441d4617..0b76efa4c 100644 --- a/libc/calls/ftruncate.c +++ b/libc/calls/ftruncate.c @@ -23,7 +23,7 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sysv/errfuns.h" /** diff --git a/libc/calls/futimens.c b/libc/calls/futimens.c index 5a45ef505..e2c2332db 100644 --- a/libc/calls/futimens.c +++ b/libc/calls/futimens.c @@ -19,7 +19,7 @@ #include "libc/calls/internal.h" #include "libc/calls/struct/timespec.h" #include "libc/calls/struct/timespec.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sysv/errfuns.h" /** diff --git a/libc/calls/futimes.c b/libc/calls/futimes.c index 50f814c14..0bb6572cf 100644 --- a/libc/calls/futimes.c +++ b/libc/calls/futimes.c @@ -21,7 +21,7 @@ #include "libc/calls/struct/timeval.h" #include "libc/calls/struct/timeval.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sysv/errfuns.h" /** diff --git a/libc/calls/getcwd.greg.c b/libc/calls/getcwd.greg.c index edabb8af1..81dde1559 100644 --- a/libc/calls/getcwd.greg.c +++ b/libc/calls/getcwd.greg.c @@ -22,7 +22,7 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/limits.h" #include "libc/nt/files.h" #include "libc/stdio/sysparam.h" diff --git a/libc/calls/getdomainname.c b/libc/calls/getdomainname.c index b188ff066..9cfb722f6 100644 --- a/libc/calls/getdomainname.c +++ b/libc/calls/getdomainname.c @@ -19,7 +19,7 @@ #include "libc/calls/calls.h" #include "libc/calls/syscall_support-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/macros.internal.h" #include "libc/nt/enum/computernameformat.h" #include "libc/str/str.h" diff --git a/libc/calls/getegid.c b/libc/calls/getegid.c index 09d8cec0d..c48ab96cc 100644 --- a/libc/calls/getegid.c +++ b/libc/calls/getegid.c @@ -19,7 +19,7 @@ #include "libc/calls/calls.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/runtime/runtime.h" /** diff --git a/libc/calls/geteuid.c b/libc/calls/geteuid.c index aa618ddcc..eedafcd9c 100644 --- a/libc/calls/geteuid.c +++ b/libc/calls/geteuid.c @@ -19,7 +19,7 @@ #include "libc/calls/calls.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" /** * Returns effective user ID of calling process. diff --git a/libc/calls/getgroups.c b/libc/calls/getgroups.c index 72d49a49a..d4c8fe1a9 100644 --- a/libc/calls/getgroups.c +++ b/libc/calls/getgroups.c @@ -19,8 +19,8 @@ #include "libc/calls/calls.h" #include "libc/calls/groups.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/stdckdint.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/gethostname.c b/libc/calls/gethostname.c index 6419fbae2..10a3cb12c 100644 --- a/libc/calls/gethostname.c +++ b/libc/calls/gethostname.c @@ -19,7 +19,7 @@ #include "libc/calls/calls.h" #include "libc/calls/syscall_support-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nt/enum/computernameformat.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/getloadavg.c b/libc/calls/getloadavg.c index eb28d34c4..ad13a8610 100644 --- a/libc/calls/getloadavg.c +++ b/libc/calls/getloadavg.c @@ -21,7 +21,7 @@ #include "libc/calls/struct/sysinfo.internal.h" #include "libc/calls/syscall-nt.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sysv/errfuns.h" #define CTL_VM 2 diff --git a/libc/calls/getpgid.c b/libc/calls/getpgid.c index 3b6760ddd..ba353cd7d 100644 --- a/libc/calls/getpgid.c +++ b/libc/calls/getpgid.c @@ -19,7 +19,7 @@ #include "libc/calls/calls.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" /** * Returns process group id. diff --git a/libc/calls/getpgrp.c b/libc/calls/getpgrp.c index 6ba24c23c..718b7b8a5 100644 --- a/libc/calls/getpgrp.c +++ b/libc/calls/getpgrp.c @@ -19,7 +19,7 @@ #include "libc/calls/calls.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" /** * Returns process group id of calling process. diff --git a/libc/calls/getppid.c b/libc/calls/getppid.c index 075d610a7..e1f80863a 100644 --- a/libc/calls/getppid.c +++ b/libc/calls/getppid.c @@ -20,7 +20,7 @@ #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" /** * Returns parent process id. diff --git a/libc/calls/getprogramexecutablename.greg.c b/libc/calls/getprogramexecutablename.greg.c index 067e7a0a3..12f02933c 100644 --- a/libc/calls/getprogramexecutablename.greg.c +++ b/libc/calls/getprogramexecutablename.greg.c @@ -24,8 +24,8 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/libgen.h" -#include "libc/intrin/getenv.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/getenv.h" +#include "libc/intrin/strace.h" #include "libc/limits.h" #include "libc/macros.internal.h" #include "libc/nt/runtime.h" diff --git a/libc/calls/getrandom.c b/libc/calls/getrandom.c index b15abf069..957c7bc18 100644 --- a/libc/calls/getrandom.c +++ b/libc/calls/getrandom.c @@ -30,7 +30,7 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/asmflag.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/macros.internal.h" #include "libc/nexgen32e/kcpuids.h" diff --git a/libc/calls/getresgid.c b/libc/calls/getresgid.c index 53edea9f1..584d9f1c0 100644 --- a/libc/calls/getresgid.c +++ b/libc/calls/getresgid.c @@ -19,7 +19,7 @@ #include "libc/calls/calls.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" /** * Gets real, effective, and "saved" group ids. diff --git a/libc/calls/getresuid.c b/libc/calls/getresuid.c index 7234882e1..c7e1257b8 100644 --- a/libc/calls/getresuid.c +++ b/libc/calls/getresuid.c @@ -19,7 +19,7 @@ #include "libc/calls/calls.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" /** * Gets real, effective, and "saved" user ids. diff --git a/libc/calls/getrlimit.c b/libc/calls/getrlimit.c index f02ac5226..de7df079e 100644 --- a/libc/calls/getrlimit.c +++ b/libc/calls/getrlimit.c @@ -20,8 +20,8 @@ #include "libc/calls/struct/rlimit.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/runtime/runtime.h" #include "libc/runtime/stack.h" #include "libc/runtime/syslib.internal.h" diff --git a/libc/calls/getsid.c b/libc/calls/getsid.c index 7c76e9b76..6c71174d0 100644 --- a/libc/calls/getsid.c +++ b/libc/calls/getsid.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" #include "libc/calls/syscall-sysv.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" /** * Creates session and sets the process group id. diff --git a/libc/calls/getuid.c b/libc/calls/getuid.c index bebd5cee8..483be9c15 100644 --- a/libc/calls/getuid.c +++ b/libc/calls/getuid.c @@ -23,7 +23,7 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" #include "libc/intrin/atomic.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/limits.h" #include "libc/macros.internal.h" #include "libc/runtime/runtime.h" diff --git a/libc/calls/grantpt.c b/libc/calls/grantpt.c index ee8c14ed5..476b82f86 100644 --- a/libc/calls/grantpt.c +++ b/libc/calls/grantpt.c @@ -17,12 +17,12 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/calls/syscall_support-sysv.internal.h" #include "libc/calls/termios.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sysv/errfuns.h" #define TIOCPTYGRANT 0x20007454 diff --git a/libc/calls/internal.h b/libc/calls/internal.h index 5640aa719..8a9b54819 100644 --- a/libc/calls/internal.h +++ b/libc/calls/internal.h @@ -1,7 +1,7 @@ #ifndef COSMOPOLITAN_LIBC_CALLS_INTERNAL_H_ #define COSMOPOLITAN_LIBC_CALLS_INTERNAL_H_ #include "libc/atomic.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/sigval.h" #include "libc/dce.h" #include "libc/macros.internal.h" diff --git a/libc/calls/ioctl.c b/libc/calls/ioctl.c index 87ea17031..bd0c0642d 100644 --- a/libc/calls/ioctl.c +++ b/libc/calls/ioctl.c @@ -18,14 +18,14 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/assert.h" #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/calls/syscall_support-nt.internal.h" #include "libc/calls/termios.h" #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/cmpxchg.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/macros.internal.h" #include "libc/mem/alloca.h" diff --git a/libc/calls/isatty-nt.c b/libc/calls/isatty-nt.c index 7098291a5..72342c683 100644 --- a/libc/calls/isatty-nt.c +++ b/libc/calls/isatty-nt.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/syscall-nt.internal.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/isatty.c b/libc/calls/isatty.c index f5bd51491..9462d31a9 100644 --- a/libc/calls/isatty.c +++ b/libc/calls/isatty.c @@ -23,7 +23,7 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/calls/syscall_support-sysv.internal.h" #include "libc/errno.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sysv/consts/termios.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/isdirectory.c b/libc/calls/isdirectory.c index c5847f7b9..9299fbf23 100644 --- a/libc/calls/isdirectory.c +++ b/libc/calls/isdirectory.c @@ -23,7 +23,7 @@ #include "libc/calls/syscall_support-nt.internal.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/nt/files.h" #include "libc/runtime/zipos.internal.h" diff --git a/libc/calls/isregularfile.c b/libc/calls/isregularfile.c index 5dd12bd97..8baa68b21 100644 --- a/libc/calls/isregularfile.c +++ b/libc/calls/isregularfile.c @@ -22,7 +22,7 @@ #include "libc/calls/syscall_support-nt.internal.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/runtime/zipos.internal.h" #include "libc/sysv/consts/at.h" diff --git a/libc/calls/issetugid.c b/libc/calls/issetugid.c index 7dd7aa5b4..8a8a700f5 100644 --- a/libc/calls/issetugid.c +++ b/libc/calls/issetugid.c @@ -19,8 +19,8 @@ #include "libc/calls/calls.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/getauxval.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/getauxval.h" +#include "libc/intrin/strace.h" #include "libc/sysv/consts/auxv.h" /** diff --git a/libc/calls/issymlink.c b/libc/calls/issymlink.c index f030b20b6..8a6fe4c25 100644 --- a/libc/calls/issymlink.c +++ b/libc/calls/issymlink.c @@ -23,7 +23,7 @@ #include "libc/calls/syscall_support-nt.internal.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/nt/files.h" #include "libc/runtime/zipos.internal.h" diff --git a/libc/calls/kemptyfd.c b/libc/calls/kemptyfd.c index 138980eba..17f646919 100644 --- a/libc/calls/kemptyfd.c +++ b/libc/calls/kemptyfd.c @@ -17,6 +17,6 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" const struct Fd kEmptyFd; diff --git a/libc/calls/landlock_add_rule.c b/libc/calls/landlock_add_rule.c index 34cb1d1bb..b87c22081 100644 --- a/libc/calls/landlock_add_rule.c +++ b/libc/calls/landlock_add_rule.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/landlock.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" int sys_landlock_add_rule(int, enum landlock_rule_type, const void *, uint32_t); diff --git a/libc/calls/landlock_create_ruleset.c b/libc/calls/landlock_create_ruleset.c index baee3b920..a8dec3f99 100644 --- a/libc/calls/landlock_create_ruleset.c +++ b/libc/calls/landlock_create_ruleset.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/landlock.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" int sys_landlock_create_ruleset(const struct landlock_ruleset_attr *, size_t, uint32_t); diff --git a/libc/calls/landlock_restrict_self.c b/libc/calls/landlock_restrict_self.c index 2bf173c1e..96a36e8fd 100644 --- a/libc/calls/landlock_restrict_self.c +++ b/libc/calls/landlock_restrict_self.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/landlock.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" int sys_landlock_restrict_self(int, uint32_t); diff --git a/libc/calls/linkat.c b/libc/calls/linkat.c index 2b3d466d3..09c2153b7 100644 --- a/libc/calls/linkat.c +++ b/libc/calls/linkat.c @@ -20,8 +20,8 @@ #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/runtime/zipos.internal.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/lseek.c b/libc/calls/lseek.c index 696889f2b..2cf78a674 100644 --- a/libc/calls/lseek.c +++ b/libc/calls/lseek.c @@ -21,8 +21,8 @@ #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/log/backtrace.internal.h" #include "libc/runtime/zipos.internal.h" diff --git a/libc/calls/madvise.c b/libc/calls/madvise.c index 885e727f3..8bf52c515 100644 --- a/libc/calls/madvise.c +++ b/libc/calls/madvise.c @@ -20,7 +20,7 @@ #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/runtime/runtime.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/memfd_create.c b/libc/calls/memfd_create.c index fa0950ab1..9215b7736 100644 --- a/libc/calls/memfd_create.c +++ b/libc/calls/memfd_create.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" #include "libc/calls/syscall-sysv.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" /** * Creates anonymous file. diff --git a/libc/calls/metalfile.c b/libc/calls/metalfile.c index 0832d52f5..cdfb6bc5f 100644 --- a/libc/calls/metalfile.c +++ b/libc/calls/metalfile.c @@ -29,7 +29,7 @@ #include "libc/assert.h" #include "libc/calls/internal.h" #include "libc/calls/metalfile.internal.h" -#include "libc/intrin/directmap.internal.h" +#include "libc/intrin/directmap.h" #include "libc/intrin/kprintf.h" #include "libc/intrin/weaken.h" #include "libc/macros.internal.h" diff --git a/libc/calls/mincore.c b/libc/calls/mincore.c index 40187d2c0..62c6a0eee 100644 --- a/libc/calls/mincore.c +++ b/libc/calls/mincore.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" #include "libc/calls/syscall-sysv.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" /** * Tells you which pages are resident in memory. diff --git a/libc/calls/mkdirat.c b/libc/calls/mkdirat.c index 3dd07d8b3..64ad9ea2d 100644 --- a/libc/calls/mkdirat.c +++ b/libc/calls/mkdirat.c @@ -20,8 +20,8 @@ #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/runtime/zipos.internal.h" #include "libc/sysv/consts/at.h" diff --git a/libc/calls/mknod.c b/libc/calls/mknod.c index 33ee93d32..2c1fa90b9 100644 --- a/libc/calls/mknod.c +++ b/libc/calls/mknod.c @@ -20,7 +20,7 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sysv/consts/at.h" #include "libc/sysv/consts/s.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/mkntenvblock.c b/libc/calls/mkntenvblock.c index 9ea54b03e..ad47b28d2 100644 --- a/libc/calls/mkntenvblock.c +++ b/libc/calls/mkntenvblock.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/assert.h" -#include "libc/intrin/getenv.internal.h" +#include "libc/intrin/getenv.h" #include "libc/mem/alloca.h" #include "libc/proc/ntspawn.h" #include "libc/runtime/runtime.h" diff --git a/libc/calls/mkntpath.c b/libc/calls/mkntpath.c index 32477d412..f1ca7d153 100644 --- a/libc/calls/mkntpath.c +++ b/libc/calls/mkntpath.c @@ -19,7 +19,7 @@ #include "libc/calls/syscall_support-nt.internal.h" #include "libc/dce.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/macros.internal.h" #include "libc/nt/systeminfo.h" #include "libc/str/str.h" diff --git a/libc/calls/mkntpathat.c b/libc/calls/mkntpathat.c index 8eec12b4c..e1e845b55 100644 --- a/libc/calls/mkntpathat.c +++ b/libc/calls/mkntpathat.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/internal.h" #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/macros.internal.h" #include "libc/nt/enum/fileflagandattributes.h" #include "libc/nt/files.h" diff --git a/libc/calls/ntaccesscheck.c b/libc/calls/ntaccesscheck.c index 708238736..695d5480b 100644 --- a/libc/calls/ntaccesscheck.c +++ b/libc/calls/ntaccesscheck.c @@ -24,7 +24,7 @@ #include "libc/calls/syscall_support-nt.internal.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/mem/mem.h" #include "libc/nt/createfile.h" diff --git a/libc/calls/ntspawn.c b/libc/calls/ntspawn.c index 3cd4c8ae0..392531915 100644 --- a/libc/calls/ntspawn.c +++ b/libc/calls/ntspawn.c @@ -19,7 +19,7 @@ #include "libc/proc/ntspawn.h" #include "libc/calls/struct/sigset.internal.h" #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nt/createfile.h" #include "libc/nt/enum/accessmask.h" #include "libc/nt/enum/creationdisposition.h" diff --git a/libc/calls/openat-metal.c b/libc/calls/openat-metal.c index 34d4d799d..ec958f4c0 100644 --- a/libc/calls/openat-metal.c +++ b/libc/calls/openat-metal.c @@ -21,7 +21,7 @@ #include "libc/assert.h" #include "libc/calls/internal.h" #include "libc/calls/metalfile.internal.h" -#include "libc/intrin/directmap.internal.h" +#include "libc/intrin/directmap.h" #include "libc/intrin/weaken.h" #include "libc/macros.internal.h" #include "libc/mem/mem.h" diff --git a/libc/calls/openat.c b/libc/calls/openat.c index 94e4452bc..327867ba3 100644 --- a/libc/calls/openat.c +++ b/libc/calls/openat.c @@ -26,8 +26,8 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/itoa.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/log/log.h" #include "libc/runtime/zipos.internal.h" diff --git a/libc/calls/pause.c b/libc/calls/pause.c index 7d24dd2d9..d73537081 100644 --- a/libc/calls/pause.c +++ b/libc/calls/pause.c @@ -20,7 +20,7 @@ #include "libc/calls/cp.internal.h" #include "libc/calls/syscall_support-nt.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sock/internal.h" /** diff --git a/libc/calls/pipe.c b/libc/calls/pipe.c index 2f668c31d..1071cfaf8 100644 --- a/libc/calls/pipe.c +++ b/libc/calls/pipe.c @@ -20,7 +20,7 @@ #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sysv/errfuns.h" /** diff --git a/libc/calls/pipe2.c b/libc/calls/pipe2.c index 36593d76c..caab1cb42 100644 --- a/libc/calls/pipe2.c +++ b/libc/calls/pipe2.c @@ -19,7 +19,7 @@ #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sysv/consts/o.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/pivot_root.c b/libc/calls/pivot_root.c index aec7fe4bf..53c6af00c 100644 --- a/libc/calls/pivot_root.c +++ b/libc/calls/pivot_root.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" #include "libc/calls/syscall-sysv.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" /** * Changes root mount. diff --git a/libc/calls/pledge-linux.c b/libc/calls/pledge-linux.c index d36684bfd..fbafd3d1e 100644 --- a/libc/calls/pledge-linux.c +++ b/libc/calls/pledge-linux.c @@ -28,7 +28,7 @@ #include "libc/calls/ucontext.h" #include "libc/intrin/bsr.h" #include "libc/intrin/likely.h" -#include "libc/intrin/promises.internal.h" +#include "libc/intrin/promises.h" #include "libc/macros.internal.h" #include "libc/runtime/runtime.h" #include "libc/runtime/stack.h" diff --git a/libc/calls/pledge.c b/libc/calls/pledge.c index f56af95fa..b5a6dbb63 100644 --- a/libc/calls/pledge.c +++ b/libc/calls/pledge.c @@ -24,8 +24,8 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/promises.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/promises.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/nexgen32e/vendor.internal.h" #include "libc/runtime/runtime.h" diff --git a/libc/calls/pledge.internal.h b/libc/calls/pledge.internal.h index a133cc904..773d38b55 100644 --- a/libc/calls/pledge.internal.h +++ b/libc/calls/pledge.internal.h @@ -1,7 +1,7 @@ #ifndef COSMOPOLITAN_LIBC_CALLS_PLEDGE_INTERNAL_H_ #define COSMOPOLITAN_LIBC_CALLS_PLEDGE_INTERNAL_H_ #include "libc/calls/pledge.h" -#include "libc/intrin/promises.internal.h" +#include "libc/intrin/promises.h" COSMOPOLITAN_C_START_ struct Pledges { diff --git a/libc/calls/poll-metal.c b/libc/calls/poll-metal.c index 613d4d415..d81af2658 100644 --- a/libc/calls/poll-metal.c +++ b/libc/calls/poll-metal.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/internal.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/nexgen32e/rdtsc.h" #include "libc/nexgen32e/uart.internal.h" #include "libc/runtime/pc.internal.h" diff --git a/libc/calls/poll-nt.c b/libc/calls/poll-nt.c index f2b16e91d..ac1e64c7e 100644 --- a/libc/calls/poll-nt.c +++ b/libc/calls/poll-nt.c @@ -27,7 +27,7 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/atomic.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/macros.internal.h" #include "libc/mem/mem.h" #include "libc/nt/console.h" diff --git a/libc/calls/poll.c b/libc/calls/poll.c index 0108475bb..5e13677a5 100644 --- a/libc/calls/poll.c +++ b/libc/calls/poll.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/cp.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sock/struct/pollfd.h" #include "libc/sock/struct/pollfd.internal.h" #include "libc/stdckdint.h" diff --git a/libc/calls/posix_fadvise.c b/libc/calls/posix_fadvise.c index 2aea15d7b..f7ba74c91 100644 --- a/libc/calls/posix_fadvise.c +++ b/libc/calls/posix_fadvise.c @@ -19,13 +19,13 @@ #include "libc/assert.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/magnumstrs.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/str/str.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/posix_openpt.c b/libc/calls/posix_openpt.c index ae36362fb..2868bba77 100644 --- a/libc/calls/posix_openpt.c +++ b/libc/calls/posix_openpt.c @@ -20,8 +20,8 @@ #include "libc/calls/termios.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/sysv/consts/at.h" #include "libc/sysv/consts/o.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/ppoll.c b/libc/calls/ppoll.c index 8c2d6d38f..a50cfc5e0 100644 --- a/libc/calls/ppoll.c +++ b/libc/calls/ppoll.c @@ -23,7 +23,7 @@ #include "libc/calls/struct/timespec.internal.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sock/struct/pollfd.h" #include "libc/sock/struct/pollfd.internal.h" #include "libc/stdckdint.h" diff --git a/libc/calls/prctl.c b/libc/calls/prctl.c index 456df4cee..4d5119cf8 100644 --- a/libc/calls/prctl.c +++ b/libc/calls/prctl.c @@ -21,8 +21,8 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/sysv/consts/pr.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/pread.c b/libc/calls/pread.c index 4aa7b0c53..0064397cb 100644 --- a/libc/calls/pread.c +++ b/libc/calls/pread.c @@ -24,7 +24,7 @@ #include "libc/calls/struct/iovec.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/macros.internal.h" #include "libc/runtime/runtime.h" diff --git a/libc/calls/preadv.c b/libc/calls/preadv.c index 586141b80..83a6f2a86 100644 --- a/libc/calls/preadv.c +++ b/libc/calls/preadv.c @@ -25,7 +25,7 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/likely.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/limits.h" #include "libc/mem/alloca.h" diff --git a/libc/calls/printfds.c b/libc/calls/printfds.c index 9e3ad0e55..36cb548d7 100644 --- a/libc/calls/printfds.c +++ b/libc/calls/printfds.c @@ -18,8 +18,8 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/internal.h" #include "libc/calls/state.internal.h" -#include "libc/calls/struct/fd.internal.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/fds.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/kprintf.h" static const char *__fdkind2str(int x) { diff --git a/libc/calls/pselect.c b/libc/calls/pselect.c index 391d94f53..9d3036a4c 100644 --- a/libc/calls/pselect.c +++ b/libc/calls/pselect.c @@ -23,8 +23,8 @@ #include "libc/calls/struct/timespec.internal.h" #include "libc/calls/struct/timeval.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/sock/internal.h" #include "libc/sock/select.h" #include "libc/sock/select.internal.h" diff --git a/libc/calls/ptrace.c b/libc/calls/ptrace.c index 8acb3c8de..a48d0cc0a 100644 --- a/libc/calls/ptrace.c +++ b/libc/calls/ptrace.c @@ -19,8 +19,8 @@ #include "libc/sysv/consts/ptrace.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/sysv/errfuns.h" /** diff --git a/libc/calls/ptsname.c b/libc/calls/ptsname.c index 67fc87abc..abf6b9f90 100644 --- a/libc/calls/ptsname.c +++ b/libc/calls/ptsname.c @@ -17,11 +17,11 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/syscall_support-sysv.internal.h" #include "libc/calls/termios.h" #include "libc/errno.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sysv/errfuns.h" static char g_ptsname[16]; diff --git a/libc/calls/pwrite.c b/libc/calls/pwrite.c index f22f52f52..e1f030def 100644 --- a/libc/calls/pwrite.c +++ b/libc/calls/pwrite.c @@ -20,12 +20,12 @@ #include "libc/calls/calls.h" #include "libc/calls/cp.internal.h" #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/iovec.h" #include "libc/calls/struct/iovec.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/macros.internal.h" #include "libc/stdio/sysparam.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/pwritev.c b/libc/calls/pwritev.c index 651b320aa..d2d8cd043 100644 --- a/libc/calls/pwritev.c +++ b/libc/calls/pwritev.c @@ -25,7 +25,7 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/likely.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/limits.h" #include "libc/mem/alloca.h" diff --git a/libc/calls/raise.c b/libc/calls/raise.c index 8ba3e67ff..096f9bea0 100644 --- a/libc/calls/raise.c +++ b/libc/calls/raise.c @@ -20,7 +20,7 @@ #include "libc/calls/sig.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/runtime/syslib.internal.h" #include "libc/sysv/consts/sicode.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/read-nt.c b/libc/calls/read-nt.c index 931e9b1f9..e49d6b3d7 100644 --- a/libc/calls/read-nt.c +++ b/libc/calls/read-nt.c @@ -20,17 +20,17 @@ #include "libc/calls/internal.h" #include "libc/calls/sig.internal.h" #include "libc/calls/state.internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/iovec.h" #include "libc/calls/struct/sigset.internal.h" #include "libc/calls/syscall_support-nt.internal.h" #include "libc/cosmo.h" #include "libc/errno.h" #include "libc/fmt/itoa.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/dll.h" -#include "libc/intrin/nomultics.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/nomultics.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/macros.internal.h" #include "libc/nt/console.h" diff --git a/libc/calls/read.c b/libc/calls/read.c index af9461971..69b593652 100644 --- a/libc/calls/read.c +++ b/libc/calls/read.c @@ -23,7 +23,7 @@ #include "libc/calls/struct/iovec.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/runtime/zipos.internal.h" #include "libc/sock/internal.h" diff --git a/libc/calls/readlinkat-nt.c b/libc/calls/readlinkat-nt.c index ff9a6eca2..9a82c9845 100644 --- a/libc/calls/readlinkat-nt.c +++ b/libc/calls/readlinkat-nt.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/struct/sigset.internal.h" #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/mem/alloca.h" #include "libc/nt/createfile.h" #include "libc/nt/enum/accessmask.h" diff --git a/libc/calls/readlinkat.c b/libc/calls/readlinkat.c index 0312fae73..dc5041c21 100644 --- a/libc/calls/readlinkat.c +++ b/libc/calls/readlinkat.c @@ -19,8 +19,8 @@ #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/runtime/runtime.h" #include "libc/runtime/zipos.internal.h" diff --git a/libc/calls/readv-metal.c b/libc/calls/readv-metal.c index 6e43f431a..5de8ace91 100644 --- a/libc/calls/readv-metal.c +++ b/libc/calls/readv-metal.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/internal.h" #include "libc/calls/metalfile.internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/iovec.h" #include "libc/calls/struct/iovec.internal.h" #include "libc/intrin/weaken.h" diff --git a/libc/calls/readv-serial.c b/libc/calls/readv-serial.c index 677e3481b..5b7976dc2 100644 --- a/libc/calls/readv-serial.c +++ b/libc/calls/readv-serial.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/iovec.internal.h" #include "libc/nexgen32e/uart.internal.h" #include "libc/runtime/pc.internal.h" diff --git a/libc/calls/readv.c b/libc/calls/readv.c index e885ca6de..b48ca2ff6 100644 --- a/libc/calls/readv.c +++ b/libc/calls/readv.c @@ -23,9 +23,9 @@ #include "libc/calls/struct/iovec.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/errno.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/likely.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/limits.h" #include "libc/mem/alloca.h" diff --git a/libc/calls/readwrite-nt.c b/libc/calls/readwrite-nt.c index 530880f4b..6fbfc1075 100644 --- a/libc/calls/readwrite-nt.c +++ b/libc/calls/readwrite-nt.c @@ -19,7 +19,7 @@ #include "libc/calls/createfileflags.internal.h" #include "libc/calls/internal.h" #include "libc/calls/sig.internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/sigset.h" #include "libc/calls/syscall_support-nt.internal.h" #include "libc/intrin/weaken.h" diff --git a/libc/calls/renameat.c b/libc/calls/renameat.c index 4c329abe6..80f2a230c 100644 --- a/libc/calls/renameat.c +++ b/libc/calls/renameat.c @@ -20,8 +20,8 @@ #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/runtime/zipos.internal.h" #include "libc/sysv/consts/at.h" diff --git a/libc/calls/sched_get_priority_max.c b/libc/calls/sched_get_priority_max.c index 247fea944..89fff487f 100644 --- a/libc/calls/sched_get_priority_max.c +++ b/libc/calls/sched_get_priority_max.c @@ -19,8 +19,8 @@ #include "libc/calls/calls.h" #include "libc/calls/sched-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/sysv/consts/sched.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/sched_get_priority_min.c b/libc/calls/sched_get_priority_min.c index 80059e8d1..7d9552ec1 100644 --- a/libc/calls/sched_get_priority_min.c +++ b/libc/calls/sched_get_priority_min.c @@ -19,8 +19,8 @@ #include "libc/calls/calls.h" #include "libc/calls/sched-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/sysv/consts/sched.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/sched_getparam.c b/libc/calls/sched_getparam.c index 0b5a9705f..98699211d 100644 --- a/libc/calls/sched_getparam.c +++ b/libc/calls/sched_getparam.c @@ -20,7 +20,7 @@ #include "libc/calls/struct/sched_param.h" #include "libc/calls/struct/sched_param.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sysv/errfuns.h" /** diff --git a/libc/calls/sched_getscheduler.c b/libc/calls/sched_getscheduler.c index fe6e39f25..d7a15554f 100644 --- a/libc/calls/sched_getscheduler.c +++ b/libc/calls/sched_getscheduler.c @@ -19,8 +19,8 @@ #include "libc/calls/sched-sysv.internal.h" #include "libc/calls/struct/sched_param.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" /** * Gets scheduler policy for `pid`. diff --git a/libc/calls/sched_rr_get_interval.c b/libc/calls/sched_rr_get_interval.c index 6e1c43001..15881ceab 100644 --- a/libc/calls/sched_rr_get_interval.c +++ b/libc/calls/sched_rr_get_interval.c @@ -18,8 +18,8 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" #include "libc/calls/struct/timespec.internal.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" int sys_sched_rr_get_interval(int, struct timespec *); diff --git a/libc/calls/sched_setparam.c b/libc/calls/sched_setparam.c index 4fae3cbbd..10b64bd66 100644 --- a/libc/calls/sched_setparam.c +++ b/libc/calls/sched_setparam.c @@ -20,7 +20,7 @@ #include "libc/calls/struct/sched_param.h" #include "libc/calls/struct/sched_param.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sysv/errfuns.h" /** diff --git a/libc/calls/sched_setscheduler.c b/libc/calls/sched_setscheduler.c index 80a48e95a..576ecadfa 100644 --- a/libc/calls/sched_setscheduler.c +++ b/libc/calls/sched_setscheduler.c @@ -20,8 +20,8 @@ #include "libc/calls/struct/sched_param.h" #include "libc/calls/struct/sched_param.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/str/str.h" #include "libc/sysv/errfuns.h" #include "libc/thread/tls.h" diff --git a/libc/calls/seccomp.c b/libc/calls/seccomp.c index eaa1e4708..3048745d0 100644 --- a/libc/calls/seccomp.c +++ b/libc/calls/seccomp.c @@ -21,8 +21,8 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/sysv/consts/pr.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/sedebug.c b/libc/calls/sedebug.c index 64c4ac52d..eed940e25 100644 --- a/libc/calls/sedebug.c +++ b/libc/calls/sedebug.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nt/enum/accessmask.h" #include "libc/nt/enum/securityimpersonationlevel.h" #include "libc/nt/errors.h" diff --git a/libc/calls/select.c b/libc/calls/select.c index d517eb4ea..9c234f601 100644 --- a/libc/calls/select.c +++ b/libc/calls/select.c @@ -23,8 +23,8 @@ #include "libc/calls/struct/timeval.h" #include "libc/calls/struct/timeval.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/sock/internal.h" #include "libc/sock/select.h" #include "libc/sock/select.internal.h" diff --git a/libc/calls/setegid.c b/libc/calls/setegid.c index 3d6edd902..fd6dba78e 100644 --- a/libc/calls/setegid.c +++ b/libc/calls/setegid.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" /** * Sets effective group ID. diff --git a/libc/calls/seteuid.c b/libc/calls/seteuid.c index 995c7cccb..7bbb79ffb 100644 --- a/libc/calls/seteuid.c +++ b/libc/calls/seteuid.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" /** * Sets effective user ID. diff --git a/libc/calls/setfl.c b/libc/calls/setfl.c index 553179598..e96137862 100644 --- a/libc/calls/setfl.c +++ b/libc/calls/setfl.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/createfileflags.internal.h" #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/syscall_support-nt.internal.h" #include "libc/nt/createfile.h" #include "libc/nt/enum/fileflagandattributes.h" diff --git a/libc/calls/setfsgid.c b/libc/calls/setfsgid.c index 5deee2daa..f69a32187 100644 --- a/libc/calls/setfsgid.c +++ b/libc/calls/setfsgid.c @@ -19,7 +19,7 @@ #include "libc/calls/calls.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" /** * Sets user id of current process for file system ops. diff --git a/libc/calls/setfsuid.c b/libc/calls/setfsuid.c index 62b7c6c79..d992e53e2 100644 --- a/libc/calls/setfsuid.c +++ b/libc/calls/setfsuid.c @@ -19,7 +19,7 @@ #include "libc/calls/calls.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" /** * Sets user id of current process for file system ops. diff --git a/libc/calls/setgid.c b/libc/calls/setgid.c index 44a55c5ad..5a1208a83 100644 --- a/libc/calls/setgid.c +++ b/libc/calls/setgid.c @@ -19,7 +19,7 @@ #include "libc/calls/calls.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" /** * Sets group id of current process. diff --git a/libc/calls/setgroups.c b/libc/calls/setgroups.c index 0c12a106b..d030239bb 100644 --- a/libc/calls/setgroups.c +++ b/libc/calls/setgroups.c @@ -19,8 +19,8 @@ #include "libc/calls/calls.h" #include "libc/calls/groups.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/stdckdint.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/setpgid.c b/libc/calls/setpgid.c index c883c2e6a..26980b4f9 100644 --- a/libc/calls/setpgid.c +++ b/libc/calls/setpgid.c @@ -19,7 +19,7 @@ #include "libc/calls/calls.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" /** * Changes process group for process. diff --git a/libc/calls/setregid.c b/libc/calls/setregid.c index 03367acb1..859db8bea 100644 --- a/libc/calls/setregid.c +++ b/libc/calls/setregid.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" #include "libc/calls/syscall-sysv.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" /** * Sets real and/or effective group ids. diff --git a/libc/calls/setresgid.c b/libc/calls/setresgid.c index e8310cc1a..bf27e7f9b 100644 --- a/libc/calls/setresgid.c +++ b/libc/calls/setresgid.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" #include "libc/calls/syscall-sysv.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" /** * Sets real, effective, and "saved" group ids. diff --git a/libc/calls/setresuid.c b/libc/calls/setresuid.c index eaa95f1a9..c6ae50caa 100644 --- a/libc/calls/setresuid.c +++ b/libc/calls/setresuid.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" #include "libc/calls/syscall-sysv.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" /** * Sets real, effective, and "saved" user ids. diff --git a/libc/calls/setreuid.c b/libc/calls/setreuid.c index f01680988..0b7149ba7 100644 --- a/libc/calls/setreuid.c +++ b/libc/calls/setreuid.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" #include "libc/calls/syscall-sysv.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" /** * Sets real and/or effective user ids. diff --git a/libc/calls/setrlimit.c b/libc/calls/setrlimit.c index de7b5adc9..7cfaeccc6 100644 --- a/libc/calls/setrlimit.c +++ b/libc/calls/setrlimit.c @@ -22,8 +22,8 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/macros.internal.h" #include "libc/runtime/runtime.h" #include "libc/runtime/syslib.internal.h" diff --git a/libc/calls/setsid.c b/libc/calls/setsid.c index 026f97b3c..efd10aef7 100644 --- a/libc/calls/setsid.c +++ b/libc/calls/setsid.c @@ -19,7 +19,7 @@ #include "libc/calls/calls.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" /** * Creates session and sets the process group id. diff --git a/libc/calls/settimeofday.c b/libc/calls/settimeofday.c index f0774746d..e35ba6e01 100644 --- a/libc/calls/settimeofday.c +++ b/libc/calls/settimeofday.c @@ -19,7 +19,7 @@ #include "libc/calls/struct/timeval.h" #include "libc/calls/struct/timeval.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sysv/errfuns.h" #include "libc/time.h" diff --git a/libc/calls/setuid.c b/libc/calls/setuid.c index f9e922906..5d22f24ef 100644 --- a/libc/calls/setuid.c +++ b/libc/calls/setuid.c @@ -19,7 +19,7 @@ #include "libc/calls/calls.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" /** * Sets user id of current process. diff --git a/libc/calls/sig.c b/libc/calls/sig.c index 21f321223..c97e41d2a 100644 --- a/libc/calls/sig.c +++ b/libc/calls/sig.c @@ -30,10 +30,10 @@ #include "libc/errno.h" #include "libc/intrin/atomic.h" #include "libc/intrin/bsf.h" -#include "libc/intrin/describebacktrace.internal.h" +#include "libc/intrin/describebacktrace.h" #include "libc/intrin/dll.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/nt/console.h" #include "libc/nt/enum/context.h" diff --git a/libc/calls/sigaction.c b/libc/calls/sigaction.c index 8def7b1dd..d3f46e71b 100644 --- a/libc/calls/sigaction.c +++ b/libc/calls/sigaction.c @@ -30,9 +30,9 @@ #include "libc/calls/syscall_support-sysv.internal.h" #include "libc/calls/ucontext.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/dll.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/limits.h" #include "libc/log/backtrace.internal.h" #include "libc/log/log.h" diff --git a/libc/calls/sigaltstack.c b/libc/calls/sigaltstack.c index 7cfb961e4..1fb21189f 100644 --- a/libc/calls/sigaltstack.c +++ b/libc/calls/sigaltstack.c @@ -21,8 +21,8 @@ #include "libc/calls/struct/sigaltstack.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/macros.internal.h" #include "libc/runtime/runtime.h" #include "libc/runtime/syslib.internal.h" diff --git a/libc/calls/sigcrashsig.c b/libc/calls/sigcrashsig.c index e48eeab3f..21e0d0203 100644 --- a/libc/calls/sigcrashsig.c +++ b/libc/calls/sigcrashsig.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/sig.internal.h" -#include "libc/intrin/pushpop.internal.h" +#include "libc/intrin/pushpop.h" #include "libc/macros.internal.h" #include "libc/nt/enum/signal.h" #include "libc/nt/enum/status.h" diff --git a/libc/calls/sigpending.c b/libc/calls/sigpending.c index 648a6d223..e11e194c0 100644 --- a/libc/calls/sigpending.c +++ b/libc/calls/sigpending.c @@ -21,8 +21,8 @@ #include "libc/calls/struct/sigset.internal.h" #include "libc/dce.h" #include "libc/intrin/atomic.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/sysv/errfuns.h" #include "libc/thread/tls.h" diff --git a/libc/calls/sigsuspend.c b/libc/calls/sigsuspend.c index 8c4c5d69e..134eda44c 100644 --- a/libc/calls/sigsuspend.c +++ b/libc/calls/sigsuspend.c @@ -24,7 +24,7 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/atomic.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nt/synchronization.h" #include "libc/sysv/consts/sig.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/sigtimedwait.c b/libc/calls/sigtimedwait.c index d68958113..20579e199 100644 --- a/libc/calls/sigtimedwait.c +++ b/libc/calls/sigtimedwait.c @@ -23,7 +23,7 @@ #include "libc/calls/struct/sigset.internal.h" #include "libc/calls/struct/timespec.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/str/str.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/splice.c b/libc/calls/splice.c index ce936f6ff..6460d0c79 100644 --- a/libc/calls/splice.c +++ b/libc/calls/splice.c @@ -23,8 +23,8 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/itoa.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/mem/alloca.h" #include "libc/str/str.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/statfs.c b/libc/calls/statfs.c index c8d573a06..6068760d7 100644 --- a/libc/calls/statfs.c +++ b/libc/calls/statfs.c @@ -24,7 +24,7 @@ #include "libc/calls/struct/statfs.internal.h" #include "libc/calls/syscall_support-nt.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/runtime/stack.h" #include "libc/runtime/zipos.internal.h" diff --git a/libc/calls/struct/iovec.internal.h b/libc/calls/struct/iovec.internal.h index 34fd4e07d..cfa58b479 100644 --- a/libc/calls/struct/iovec.internal.h +++ b/libc/calls/struct/iovec.internal.h @@ -1,6 +1,6 @@ #ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_IOVEC_INTERNAL_H_ #define COSMOPOLITAN_LIBC_CALLS_STRUCT_IOVEC_INTERNAL_H_ -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/iovec.h" #include "libc/mem/alloca.h" COSMOPOLITAN_C_START_ diff --git a/libc/calls/struct/winsize.internal.h b/libc/calls/struct/winsize.internal.h index 8e1d5dbec..642b995d8 100644 --- a/libc/calls/struct/winsize.internal.h +++ b/libc/calls/struct/winsize.internal.h @@ -1,6 +1,6 @@ #ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_WINSIZE_INTERNAL_H_ #define COSMOPOLITAN_LIBC_CALLS_STRUCT_WINSIZE_INTERNAL_H_ -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/winsize.h" #include "libc/mem/alloca.h" COSMOPOLITAN_C_START_ diff --git a/libc/calls/symlinkat.c b/libc/calls/symlinkat.c index 3af90f91d..c4aa3e726 100644 --- a/libc/calls/symlinkat.c +++ b/libc/calls/symlinkat.c @@ -20,8 +20,8 @@ #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/sysv/consts/at.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/sync.c b/libc/calls/sync.c index bdf2c7592..ca6cd1b84 100644 --- a/libc/calls/sync.c +++ b/libc/calls/sync.c @@ -20,7 +20,7 @@ #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/runtime/runtime.h" /** diff --git a/libc/calls/sys_ptrace.c b/libc/calls/sys_ptrace.c index 21cfda437..3121e0bc3 100644 --- a/libc/calls/sys_ptrace.c +++ b/libc/calls/sys_ptrace.c @@ -19,9 +19,9 @@ #include "libc/calls/calls.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/likely.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/runtime/runtime.h" #define IsPeek(request) (IsLinux() && (request) - 1u < 3) diff --git a/libc/calls/sysinfo.c b/libc/calls/sysinfo.c index 5f5fc832f..cf7ce29d3 100644 --- a/libc/calls/sysinfo.c +++ b/libc/calls/sysinfo.c @@ -22,7 +22,7 @@ #include "libc/calls/struct/timespec.h" #include "libc/calls/struct/timeval.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/macros.internal.h" #include "libc/str/str.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/tcdrain.c b/libc/calls/tcdrain.c index c172d4027..1e4dc4522 100644 --- a/libc/calls/tcdrain.c +++ b/libc/calls/tcdrain.c @@ -18,13 +18,13 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/cp.internal.h" #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/calls/syscall_support-nt.internal.h" #include "libc/calls/termios.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nt/files.h" #include "libc/sysv/consts/termios.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/tcflow.c b/libc/calls/tcflow.c index 6543319c3..512de21bd 100644 --- a/libc/calls/tcflow.c +++ b/libc/calls/tcflow.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/metatermios.internal.h" #include "libc/calls/struct/termios.h" #include "libc/calls/syscall-sysv.internal.h" @@ -25,7 +25,7 @@ #include "libc/calls/termios.h" #include "libc/dce.h" #include "libc/fmt/itoa.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/mem/alloca.h" #include "libc/nt/comms.h" #include "libc/sysv/consts/termios.h" diff --git a/libc/calls/tcflush.c b/libc/calls/tcflush.c index cfa4bd9a1..3802897b6 100644 --- a/libc/calls/tcflush.c +++ b/libc/calls/tcflush.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/calls/syscall_support-nt.internal.h" @@ -25,7 +25,7 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/itoa.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/mem/alloca.h" #include "libc/nt/comms.h" #include "libc/nt/console.h" diff --git a/libc/calls/tcgetattr-nt.c b/libc/calls/tcgetattr-nt.c index bf4262ebf..00950d3c0 100644 --- a/libc/calls/tcgetattr-nt.c +++ b/libc/calls/tcgetattr-nt.c @@ -18,10 +18,10 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/assert.h" #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/termios.h" #include "libc/calls/syscall-nt.internal.h" -#include "libc/intrin/nomultics.internal.h" +#include "libc/intrin/nomultics.h" #include "libc/nt/console.h" #include "libc/nt/enum/consolemodeflags.h" #include "libc/str/str.h" diff --git a/libc/calls/tcgetattr.c b/libc/calls/tcgetattr.c index e22e0c780..4c2f116eb 100644 --- a/libc/calls/tcgetattr.c +++ b/libc/calls/tcgetattr.c @@ -24,7 +24,7 @@ #include "libc/calls/termios.internal.h" #include "libc/calls/ttydefaults.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/str/str.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/tcgetpgrp.c b/libc/calls/tcgetpgrp.c index f6a6ade21..2f996c9d6 100644 --- a/libc/calls/tcgetpgrp.c +++ b/libc/calls/tcgetpgrp.c @@ -22,7 +22,7 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/calls/termios.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nt/console.h" #include "libc/sysv/consts/termios.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/tcgetsid.c b/libc/calls/tcgetsid.c index 147cfacde..77c9617f5 100644 --- a/libc/calls/tcgetsid.c +++ b/libc/calls/tcgetsid.c @@ -20,7 +20,7 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/calls/termios.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sysv/errfuns.h" #define TIOCGSID (IsLinux() ? 0x5429 : 0x40047463) diff --git a/libc/calls/tcgetwinsize.c b/libc/calls/tcgetwinsize.c index 6ed585a47..ad1bd76e6 100644 --- a/libc/calls/tcgetwinsize.c +++ b/libc/calls/tcgetwinsize.c @@ -22,7 +22,7 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/calls/termios.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sysv/consts/termios.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/tcsendbreak.c b/libc/calls/tcsendbreak.c index 9e6e3b55b..f00ef83db 100644 --- a/libc/calls/tcsendbreak.c +++ b/libc/calls/tcsendbreak.c @@ -21,7 +21,7 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/calls/syscall_support-nt.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nt/comms.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/tcsetattr-nt.c b/libc/calls/tcsetattr-nt.c index b0f49e803..4a5484ad3 100644 --- a/libc/calls/tcsetattr-nt.c +++ b/libc/calls/tcsetattr-nt.c @@ -18,11 +18,11 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/assert.h" #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/termios.h" #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/ttydefaults.h" -#include "libc/intrin/nomultics.internal.h" +#include "libc/intrin/nomultics.h" #include "libc/nt/console.h" #include "libc/nt/enum/consolemodeflags.h" #include "libc/str/str.h" diff --git a/libc/calls/tcsetattr.c b/libc/calls/tcsetattr.c index db59486db..030e42790 100644 --- a/libc/calls/tcsetattr.c +++ b/libc/calls/tcsetattr.c @@ -24,7 +24,7 @@ #include "libc/calls/termios.internal.h" #include "libc/dce.h" #include "libc/fmt/itoa.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/mem/alloca.h" #include "libc/sysv/consts/termios.h" diff --git a/libc/calls/tcsetpgrp.c b/libc/calls/tcsetpgrp.c index eafe3ab2b..ba88f1422 100644 --- a/libc/calls/tcsetpgrp.c +++ b/libc/calls/tcsetpgrp.c @@ -22,7 +22,7 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/calls/termios.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nt/console.h" #include "libc/sysv/consts/termios.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/tcsetsid.c b/libc/calls/tcsetsid.c index de7e241ef..59f6052a5 100644 --- a/libc/calls/tcsetsid.c +++ b/libc/calls/tcsetsid.c @@ -20,7 +20,7 @@ #include "libc/calls/internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sysv/consts/termios.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/tcsetwinsize.c b/libc/calls/tcsetwinsize.c index a8503ca68..7c0e6bd2c 100644 --- a/libc/calls/tcsetwinsize.c +++ b/libc/calls/tcsetwinsize.c @@ -22,7 +22,7 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/calls/termios.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sysv/consts/termios.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/truncate.c b/libc/calls/truncate.c index 956fd81fc..756353a13 100644 --- a/libc/calls/truncate.c +++ b/libc/calls/truncate.c @@ -22,7 +22,7 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/runtime/zipos.internal.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/ttyname_r.c b/libc/calls/ttyname_r.c index c87d4a99a..4d700a51d 100644 --- a/libc/calls/ttyname_r.c +++ b/libc/calls/ttyname_r.c @@ -19,14 +19,14 @@ #include "libc/assert.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/stat.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/itoa.h" #include "libc/fmt/magnumstrs.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/log/log.h" #include "libc/nt/console.h" #include "libc/nt/enum/consolemodeflags.h" diff --git a/libc/calls/umask.c b/libc/calls/umask.c index 79f0ea314..29b10e8e3 100644 --- a/libc/calls/umask.c +++ b/libc/calls/umask.c @@ -21,7 +21,7 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" #include "libc/intrin/atomic.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sysv/consts/nr.h" /** diff --git a/libc/calls/uname.c b/libc/calls/uname.c index e61181f20..8569c7839 100644 --- a/libc/calls/uname.c +++ b/libc/calls/uname.c @@ -25,7 +25,7 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/itoa.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/log/log.h" #include "libc/macros.internal.h" #include "libc/nt/enum/computernameformat.h" diff --git a/libc/calls/unassert.c b/libc/calls/unassert.c index d7a8ce42d..b44f8a1d8 100644 --- a/libc/calls/unassert.c +++ b/libc/calls/unassert.c @@ -21,7 +21,7 @@ #include "libc/calls/struct/sigset.internal.h" #include "libc/errno.h" #include "libc/fmt/itoa.h" -#include "libc/intrin/describebacktrace.internal.h" +#include "libc/intrin/describebacktrace.h" #include "libc/runtime/runtime.h" #include "libc/runtime/symbols.internal.h" diff --git a/libc/calls/unlinkat.c b/libc/calls/unlinkat.c index 75ecfdcb9..33bd2f572 100644 --- a/libc/calls/unlinkat.c +++ b/libc/calls/unlinkat.c @@ -22,8 +22,8 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/runtime/zipos.internal.h" #include "libc/sysv/consts/s.h" diff --git a/libc/calls/unlockpt.c b/libc/calls/unlockpt.c index 181115065..438a4b955 100644 --- a/libc/calls/unlockpt.c +++ b/libc/calls/unlockpt.c @@ -18,12 +18,12 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/calls/syscall_support-sysv.internal.h" #include "libc/calls/termios.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sysv/consts/pty.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/unmount.c b/libc/calls/unmount.c index db84e4670..e78172bef 100644 --- a/libc/calls/unmount.c +++ b/libc/calls/unmount.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/mount.h" #include "libc/calls/syscall-sysv.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" /** * Unmounts file system. diff --git a/libc/calls/unveil.c b/libc/calls/unveil.c index 57f4cfc28..8112fc721 100644 --- a/libc/calls/unveil.c +++ b/libc/calls/unveil.c @@ -31,7 +31,7 @@ #include "libc/errno.h" #include "libc/fmt/conv.h" #include "libc/fmt/libgen.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/limits.h" #include "libc/macros.internal.h" #include "libc/nexgen32e/vendor.internal.h" diff --git a/libc/calls/utimens.c b/libc/calls/utimens.c index 333b49432..c768d5235 100644 --- a/libc/calls/utimens.c +++ b/libc/calls/utimens.c @@ -23,8 +23,8 @@ #include "libc/calls/struct/timeval.internal.h" #include "libc/calls/syscall_support-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/runtime/zipos.internal.h" #include "libc/sysv/consts/at.h" diff --git a/libc/calls/utimensat.c b/libc/calls/utimensat.c index adac0714e..a8065a1a1 100644 --- a/libc/calls/utimensat.c +++ b/libc/calls/utimensat.c @@ -18,8 +18,8 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/struct/timespec.h" #include "libc/calls/struct/timespec.internal.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/sysv/errfuns.h" /** diff --git a/libc/calls/utimes.c b/libc/calls/utimes.c index 7f863fd3e..a5dd2f66c 100644 --- a/libc/calls/utimes.c +++ b/libc/calls/utimes.c @@ -20,7 +20,7 @@ #include "libc/calls/struct/timespec.internal.h" #include "libc/calls/struct/timeval.h" #include "libc/calls/struct/timeval.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sysv/consts/at.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/vdsofunc.greg.c b/libc/calls/vdsofunc.greg.c index 69b2f774d..a063c41a1 100644 --- a/libc/calls/vdsofunc.greg.c +++ b/libc/calls/vdsofunc.greg.c @@ -26,8 +26,8 @@ #include "libc/elf/struct/sym.h" #include "libc/elf/struct/verdaux.h" #include "libc/elf/struct/verdef.h" -#include "libc/intrin/getauxval.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/getauxval.h" +#include "libc/intrin/strace.h" #include "libc/runtime/runtime.h" #include "libc/str/str.h" #include "libc/sysv/consts/auxv.h" diff --git a/libc/calls/write-nt.c b/libc/calls/write-nt.c index edea79f9f..3e5eb0163 100644 --- a/libc/calls/write-nt.c +++ b/libc/calls/write-nt.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/internal.h" #include "libc/calls/sig.internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/iovec.h" #include "libc/calls/struct/sigset.h" #include "libc/calls/struct/sigset.internal.h" @@ -26,7 +26,7 @@ #include "libc/calls/syscall_support-nt.internal.h" #include "libc/errno.h" #include "libc/intrin/atomic.h" -#include "libc/intrin/nomultics.internal.h" +#include "libc/intrin/nomultics.h" #include "libc/intrin/weaken.h" #include "libc/nt/console.h" #include "libc/nt/enum/consolemodeflags.h" diff --git a/libc/calls/write.c b/libc/calls/write.c index 258386df3..bf1d4fa19 100644 --- a/libc/calls/write.c +++ b/libc/calls/write.c @@ -22,7 +22,7 @@ #include "libc/calls/struct/iovec.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/runtime/zipos.internal.h" #include "libc/sock/sock.h" diff --git a/libc/calls/writev-metal.c b/libc/calls/writev-metal.c index a3e87c6cd..d028e5f83 100644 --- a/libc/calls/writev-metal.c +++ b/libc/calls/writev-metal.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/iovec.h" #include "libc/calls/struct/iovec.internal.h" #include "libc/intrin/weaken.h" diff --git a/libc/calls/writev-serial.c b/libc/calls/writev-serial.c index c896fec31..9c5822d7b 100644 --- a/libc/calls/writev-serial.c +++ b/libc/calls/writev-serial.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/iovec.h" #include "libc/calls/struct/iovec.internal.h" #include "libc/nexgen32e/uart.internal.h" diff --git a/libc/calls/writev.c b/libc/calls/writev.c index 42d141461..7c476d3e5 100644 --- a/libc/calls/writev.c +++ b/libc/calls/writev.c @@ -22,9 +22,9 @@ #include "libc/calls/struct/iovec.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/errno.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/likely.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/limits.h" #include "libc/runtime/stack.h" diff --git a/libc/dlopen/dlopen.c b/libc/dlopen/dlopen.c index a39921b54..99c648776 100644 --- a/libc/dlopen/dlopen.c +++ b/libc/dlopen/dlopen.c @@ -38,7 +38,7 @@ #include "libc/fmt/itoa.h" #include "libc/intrin/atomic.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/limits.h" #include "libc/nt/dll.h" #include "libc/nt/enum/filemapflags.h" diff --git a/libc/intrin/BUILD.mk b/libc/intrin/BUILD.mk index 300e0631f..fa18d9b46 100644 --- a/libc/intrin/BUILD.mk +++ b/libc/intrin/BUILD.mk @@ -16,7 +16,7 @@ LIBC_INTRIN_A_CHECKS = $(LIBC_INTRIN_A).pkg ifeq ($(ARCH), aarch64) LIBC_INTRIN_A_SRCS_S += $(wildcard libc/intrin/aarch64/*.S) -LIBC_INTRIN_A_HDRS += libc/intrin/aarch64/asmdefs.internal.h +LIBC_INTRIN_A_HDRS += libc/intrin/aarch64/asmdefs.h endif LIBC_INTRIN_A_OBJS = \ diff --git a/libc/intrin/__getauxval.c b/libc/intrin/__getauxval.c index 277cd1142..db75a12ff 100644 --- a/libc/intrin/__getauxval.c +++ b/libc/intrin/__getauxval.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/getauxval.internal.h" +#include "libc/intrin/getauxval.h" #include "libc/runtime/runtime.h" /** diff --git a/libc/intrin/__getenv.c b/libc/intrin/__getenv.c index b94d09798..b387b458d 100644 --- a/libc/intrin/__getenv.c +++ b/libc/intrin/__getenv.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/dce.h" -#include "libc/intrin/getenv.internal.h" +#include "libc/intrin/getenv.h" #include "libc/intrin/kprintf.h" privileged struct Env __getenv(char **p, const char *k) { diff --git a/libc/intrin/aarch64/asmdefs.internal.h b/libc/intrin/aarch64/asmdefs.h similarity index 100% rename from libc/intrin/aarch64/asmdefs.internal.h rename to libc/intrin/aarch64/asmdefs.h diff --git a/libc/intrin/aarch64/memchr.S b/libc/intrin/aarch64/memchr.S index 7242bfc86..22361b26d 100644 --- a/libc/intrin/aarch64/memchr.S +++ b/libc/intrin/aarch64/memchr.S @@ -25,7 +25,7 @@ β”‚ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. β”‚ β”‚ β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/aarch64/asmdefs.internal.h" +#include "libc/intrin/aarch64/asmdefs.h" .yoink arm_optimized_routines_notice #define __memchr_aarch64 memchr diff --git a/libc/intrin/aarch64/memcpy.S b/libc/intrin/aarch64/memcpy.S index 65b58d75a..d9294db9d 100644 --- a/libc/intrin/aarch64/memcpy.S +++ b/libc/intrin/aarch64/memcpy.S @@ -25,7 +25,7 @@ β”‚ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. β”‚ β”‚ β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/aarch64/asmdefs.internal.h" +#include "libc/intrin/aarch64/asmdefs.h" .yoink arm_optimized_routines_notice #define __memcpy_aarch64_simd memcpy diff --git a/libc/intrin/aarch64/memrchr.S b/libc/intrin/aarch64/memrchr.S index 3041eeab7..57e6c4354 100644 --- a/libc/intrin/aarch64/memrchr.S +++ b/libc/intrin/aarch64/memrchr.S @@ -25,7 +25,7 @@ β”‚ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. β”‚ β”‚ β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/aarch64/asmdefs.internal.h" +#include "libc/intrin/aarch64/asmdefs.h" .yoink arm_optimized_routines_notice #define __memrchr_aarch64 memrchr diff --git a/libc/intrin/aarch64/memset.S b/libc/intrin/aarch64/memset.S index cef8edd9c..c9e2d3dd7 100644 --- a/libc/intrin/aarch64/memset.S +++ b/libc/intrin/aarch64/memset.S @@ -25,7 +25,7 @@ β”‚ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. β”‚ β”‚ β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/aarch64/asmdefs.internal.h" +#include "libc/intrin/aarch64/asmdefs.h" .yoink arm_optimized_routines_notice #define __memset_aarch64 memset diff --git a/libc/intrin/aarch64/stpcpy.S b/libc/intrin/aarch64/stpcpy.S index a34f1aa8f..3bf49d8cb 100644 --- a/libc/intrin/aarch64/stpcpy.S +++ b/libc/intrin/aarch64/stpcpy.S @@ -25,7 +25,7 @@ β”‚ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. β”‚ β”‚ β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/aarch64/asmdefs.internal.h" +#include "libc/intrin/aarch64/asmdefs.h" .yoink arm_optimized_routines_notice #define __stpcpy_aarch64 stpcpy diff --git a/libc/intrin/aarch64/strchr.S b/libc/intrin/aarch64/strchr.S index 462d94806..20a7e8dab 100644 --- a/libc/intrin/aarch64/strchr.S +++ b/libc/intrin/aarch64/strchr.S @@ -25,7 +25,7 @@ β”‚ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. β”‚ β”‚ β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/aarch64/asmdefs.internal.h" +#include "libc/intrin/aarch64/asmdefs.h" .yoink arm_optimized_routines_notice #define __strchr_aarch64 strchr diff --git a/libc/intrin/aarch64/strchrnul.S b/libc/intrin/aarch64/strchrnul.S index 184305b22..a86383f62 100644 --- a/libc/intrin/aarch64/strchrnul.S +++ b/libc/intrin/aarch64/strchrnul.S @@ -25,7 +25,7 @@ β”‚ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. β”‚ β”‚ β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/aarch64/asmdefs.internal.h" +#include "libc/intrin/aarch64/asmdefs.h" .yoink arm_optimized_routines_notice #define __strchrnul_aarch64 strchrnul diff --git a/libc/intrin/aarch64/strcmp.S b/libc/intrin/aarch64/strcmp.S index 98f26d486..190fd77e3 100644 --- a/libc/intrin/aarch64/strcmp.S +++ b/libc/intrin/aarch64/strcmp.S @@ -25,7 +25,7 @@ β”‚ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. β”‚ β”‚ β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/aarch64/asmdefs.internal.h" +#include "libc/intrin/aarch64/asmdefs.h" .yoink arm_optimized_routines_notice #define __strcmp_aarch64 strcmp diff --git a/libc/intrin/aarch64/strcpy.S b/libc/intrin/aarch64/strcpy.S index 93cb85fec..dc53c8f50 100644 --- a/libc/intrin/aarch64/strcpy.S +++ b/libc/intrin/aarch64/strcpy.S @@ -25,7 +25,7 @@ β”‚ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. β”‚ β”‚ β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/aarch64/asmdefs.internal.h" +#include "libc/intrin/aarch64/asmdefs.h" .yoink arm_optimized_routines_notice #define __strcpy_aarch64 strcpy diff --git a/libc/intrin/aarch64/strlen.S b/libc/intrin/aarch64/strlen.S index 7464eafc9..600640cf3 100644 --- a/libc/intrin/aarch64/strlen.S +++ b/libc/intrin/aarch64/strlen.S @@ -25,7 +25,7 @@ β”‚ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. β”‚ β”‚ β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/aarch64/asmdefs.internal.h" +#include "libc/intrin/aarch64/asmdefs.h" .yoink arm_optimized_routines_notice #define __strlen_aarch64 strlen diff --git a/libc/intrin/aarch64/strncmp.S b/libc/intrin/aarch64/strncmp.S index 8a0b75397..4734185bc 100644 --- a/libc/intrin/aarch64/strncmp.S +++ b/libc/intrin/aarch64/strncmp.S @@ -25,7 +25,7 @@ β”‚ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. β”‚ β”‚ β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/aarch64/asmdefs.internal.h" +#include "libc/intrin/aarch64/asmdefs.h" .yoink arm_optimized_routines_notice #define __strncmp_aarch64 strncmp diff --git a/libc/intrin/aarch64/strnlen.S b/libc/intrin/aarch64/strnlen.S index 988c15f63..750b1de48 100644 --- a/libc/intrin/aarch64/strnlen.S +++ b/libc/intrin/aarch64/strnlen.S @@ -25,7 +25,7 @@ β”‚ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. β”‚ β”‚ β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/aarch64/asmdefs.internal.h" +#include "libc/intrin/aarch64/asmdefs.h" .yoink arm_optimized_routines_notice #define __strnlen_aarch64 strnlen diff --git a/libc/intrin/aarch64/strrchr.S b/libc/intrin/aarch64/strrchr.S index 5199254ff..0ad8f7b3b 100644 --- a/libc/intrin/aarch64/strrchr.S +++ b/libc/intrin/aarch64/strrchr.S @@ -25,7 +25,7 @@ β”‚ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. β”‚ β”‚ β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/aarch64/asmdefs.internal.h" +#include "libc/intrin/aarch64/asmdefs.h" .yoink arm_optimized_routines_notice #define __strrchr_aarch64 strrchr diff --git a/libc/intrin/clearenv.c b/libc/intrin/clearenv.c index 35dcda617..14ed915f8 100644 --- a/libc/intrin/clearenv.c +++ b/libc/intrin/clearenv.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/runtime/runtime.h" /** diff --git a/libc/intrin/createdirectory.c b/libc/intrin/createdirectory.c index e0e787859..af41e4ba5 100644 --- a/libc/intrin/createdirectory.c +++ b/libc/intrin/createdirectory.c @@ -17,8 +17,8 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/nt/files.h" #include "libc/nt/thunk/msabi.h" diff --git a/libc/intrin/createfile.c b/libc/intrin/createfile.c index 594329c64..265675a1b 100644 --- a/libc/intrin/createfile.c +++ b/libc/intrin/createfile.c @@ -19,8 +19,8 @@ #include "libc/nt/createfile.h" #include "libc/calls/sig.internal.h" #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/nt/enum/accessmask.h" #include "libc/nt/enum/creationdisposition.h" #include "libc/nt/errors.h" diff --git a/libc/intrin/createfilemapping.c b/libc/intrin/createfilemapping.c index 147793ec7..7d6912967 100644 --- a/libc/intrin/createfilemapping.c +++ b/libc/intrin/createfilemapping.c @@ -17,8 +17,8 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/nt/memory.h" #include "libc/nt/struct/securityattributes.h" #include "libc/nt/thunk/msabi.h" diff --git a/libc/intrin/createfilemappingnuma.c b/libc/intrin/createfilemappingnuma.c index a99653617..50ee5f7c4 100644 --- a/libc/intrin/createfilemappingnuma.c +++ b/libc/intrin/createfilemappingnuma.c @@ -18,8 +18,8 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall_support-nt.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/nt/memory.h" #include "libc/nt/struct/securityattributes.h" diff --git a/libc/intrin/createnamedpipe.c b/libc/intrin/createnamedpipe.c index 2bb67417a..b62a4e482 100644 --- a/libc/intrin/createnamedpipe.c +++ b/libc/intrin/createnamedpipe.c @@ -18,8 +18,8 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/sig.internal.h" #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/nt/errors.h" #include "libc/nt/ipc.h" #include "libc/nt/runtime.h" diff --git a/libc/intrin/createpipe.c b/libc/intrin/createpipe.c index 7d6e9df1e..bde3623e1 100644 --- a/libc/intrin/createpipe.c +++ b/libc/intrin/createpipe.c @@ -17,8 +17,8 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/nt/ipc.h" #include "libc/nt/struct/securityattributes.h" #include "libc/nt/thunk/msabi.h" diff --git a/libc/intrin/createprocess.c b/libc/intrin/createprocess.c index 4205b5bcd..232c2d17b 100644 --- a/libc/intrin/createprocess.c +++ b/libc/intrin/createprocess.c @@ -17,8 +17,8 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/nt/process.h" #include "libc/nt/runtime.h" #include "libc/nt/thunk/msabi.h" diff --git a/libc/intrin/createsymboliclink.c b/libc/intrin/createsymboliclink.c index 663753b13..cd6be90c7 100644 --- a/libc/intrin/createsymboliclink.c +++ b/libc/intrin/createsymboliclink.c @@ -17,8 +17,8 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/nt/files.h" __msabi extern typeof(CreateSymbolicLink) *const __imp_CreateSymbolicLinkW; diff --git a/libc/intrin/createthread.c b/libc/intrin/createthread.c index 8a4bc7a64..a910e629f 100644 --- a/libc/intrin/createthread.c +++ b/libc/intrin/createthread.c @@ -17,8 +17,8 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/nt/runtime.h" #include "libc/nt/struct/securityattributes.h" #include "libc/nt/thread.h" diff --git a/libc/intrin/cxaatexit.c b/libc/intrin/cxaatexit.c index a5b001162..7f13261bf 100644 --- a/libc/intrin/cxaatexit.c +++ b/libc/intrin/cxaatexit.c @@ -17,8 +17,8 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/intrin/bsr.h" -#include "libc/intrin/cxaatexit.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/cxaatexit.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/macros.internal.h" #include "libc/mem/mem.h" diff --git a/libc/intrin/cxaatexit.internal.h b/libc/intrin/cxaatexit.h similarity index 100% rename from libc/intrin/cxaatexit.internal.h rename to libc/intrin/cxaatexit.h diff --git a/libc/intrin/cxablocks.c b/libc/intrin/cxablocks.c index 86b4965da..af74fdf9a 100644 --- a/libc/intrin/cxablocks.c +++ b/libc/intrin/cxablocks.c @@ -16,6 +16,6 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/cxaatexit.internal.h" +#include "libc/intrin/cxaatexit.h" struct CxaAtexitBlocks __cxa_blocks; diff --git a/libc/intrin/cxafinalize.c b/libc/intrin/cxafinalize.c index 119bebdd4..da9b30441 100644 --- a/libc/intrin/cxafinalize.c +++ b/libc/intrin/cxafinalize.c @@ -17,8 +17,8 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/intrin/bsf.h" -#include "libc/intrin/cxaatexit.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/cxaatexit.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/mem/mem.h" #include "libc/runtime/runtime.h" diff --git a/libc/intrin/cxalock.c b/libc/intrin/cxalock.c index 4e6de59d0..e0d43f534 100644 --- a/libc/intrin/cxalock.c +++ b/libc/intrin/cxalock.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/cxaatexit.internal.h" +#include "libc/intrin/cxaatexit.h" #include "libc/thread/thread.h" static pthread_mutex_t __cxa_lock_obj; diff --git a/libc/intrin/deletefile.c b/libc/intrin/deletefile.c index 1fd3b54ed..6161b816b 100644 --- a/libc/intrin/deletefile.c +++ b/libc/intrin/deletefile.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nt/files.h" #include "libc/nt/thunk/msabi.h" diff --git a/libc/intrin/describearchprctlcode.c b/libc/intrin/describearchprctlcode.c index 57ad37830..9c1fea1f9 100644 --- a/libc/intrin/describearchprctlcode.c +++ b/libc/intrin/describearchprctlcode.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" #include "libc/fmt/itoa.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/sysv/consts/arch.h" const char *(DescribeArchPrctlCode)(char buf[12], int x) { diff --git a/libc/intrin/describebacktrace.c b/libc/intrin/describebacktrace.c index d6bd8f8e0..113854ff6 100644 --- a/libc/intrin/describebacktrace.c +++ b/libc/intrin/describebacktrace.c @@ -16,8 +16,8 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describebacktrace.internal.h" -#include "libc/intrin/iscall.internal.h" +#include "libc/intrin/describebacktrace.h" +#include "libc/intrin/iscall.h" #include "libc/intrin/kprintf.h" #include "libc/intrin/weaken.h" #include "libc/nexgen32e/stackframe.h" diff --git a/libc/intrin/describebacktrace.internal.h b/libc/intrin/describebacktrace.h similarity index 100% rename from libc/intrin/describebacktrace.internal.h rename to libc/intrin/describebacktrace.h diff --git a/libc/intrin/describecancelstate.c b/libc/intrin/describecancelstate.c index b6ef58702..4b5856666 100644 --- a/libc/intrin/describecancelstate.c +++ b/libc/intrin/describecancelstate.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/fmt/itoa.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/thread/thread.h" const char *(DescribeCancelState)(char buf[12], int err, int *state) { diff --git a/libc/intrin/describecapability.c b/libc/intrin/describecapability.c index f38ed5b8b..6e072f4dd 100644 --- a/libc/intrin/describecapability.c +++ b/libc/intrin/describecapability.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/fmt/itoa.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/macros.internal.h" #include "libc/str/str.h" #include "libc/sysv/consts/cap.h" diff --git a/libc/intrin/describeclockname.c b/libc/intrin/describeclockname.c index b5640c620..c8e704ca5 100644 --- a/libc/intrin/describeclockname.c +++ b/libc/intrin/describeclockname.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/fmt/magnumstrs.internal.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" /** * Describes clock_gettime() clock argument. diff --git a/libc/intrin/describecontrolkeystate.c b/libc/intrin/describecontrolkeystate.c index 93f685cad..c46d859a2 100644 --- a/libc/intrin/describecontrolkeystate.c +++ b/libc/intrin/describecontrolkeystate.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/macros.internal.h" #include "libc/nt/struct/inputrecord.h" diff --git a/libc/intrin/describedirfd.c b/libc/intrin/describedirfd.c index a769f1225..6b33d8ebf 100644 --- a/libc/intrin/describedirfd.c +++ b/libc/intrin/describedirfd.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/fmt/itoa.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/sysv/consts/at.h" const char *(DescribeDirfd)(char buf[12], int dirfd) { diff --git a/libc/intrin/describednotify.c b/libc/intrin/describednotify.c index c6693dbb9..b4b719940 100644 --- a/libc/intrin/describednotify.c +++ b/libc/intrin/describednotify.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/macros.internal.h" #include "libc/nt/enum/processaccess.h" #include "libc/sysv/consts/dn.h" diff --git a/libc/intrin/describeerrnoresult.c b/libc/intrin/describeerrnoresult.c index 672665edb..0deed696e 100644 --- a/libc/intrin/describeerrnoresult.c +++ b/libc/intrin/describeerrnoresult.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/fmt/itoa.h" #include "libc/fmt/magnumstrs.internal.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/log/libfatal.internal.h" #include "libc/str/str.h" diff --git a/libc/intrin/describefcntlcmd.c b/libc/intrin/describefcntlcmd.c index 338b476a6..bcebd1b19 100644 --- a/libc/intrin/describefcntlcmd.c +++ b/libc/intrin/describefcntlcmd.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/fmt/itoa.h" #include "libc/fmt/magnumstrs.internal.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/str/str.h" const char *(DescribeFcntlCmd)(char buf[20], int x) { diff --git a/libc/intrin/describeflags.c b/libc/intrin/describeflags.c index cb316b244..10aa0ea1c 100644 --- a/libc/intrin/describeflags.c +++ b/libc/intrin/describeflags.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" const char *DescribeFlags(char *p, size_t n, const struct DescribeFlags *d, size_t m, const char *prefix, unsigned x) { diff --git a/libc/intrin/describeflags.internal.h b/libc/intrin/describeflags.h similarity index 100% rename from libc/intrin/describeflags.internal.h rename to libc/intrin/describeflags.h diff --git a/libc/intrin/describeflock.c b/libc/intrin/describeflock.c index c2399e583..ea7b744bd 100644 --- a/libc/intrin/describeflock.c +++ b/libc/intrin/describeflock.c @@ -19,7 +19,7 @@ #include "libc/calls/struct/flock.h" #include "libc/calls/struct/flock.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/kprintf.h" #include "libc/sysv/consts/f.h" diff --git a/libc/intrin/describefutexop.c b/libc/intrin/describefutexop.c index 9dead5932..7a4b0c783 100644 --- a/libc/intrin/describefutexop.c +++ b/libc/intrin/describefutexop.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/fmt/itoa.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/str/str.h" #include "libc/sysv/consts/futex.h" diff --git a/libc/intrin/describehow.c b/libc/intrin/describehow.c index a4c447025..f4fc6798d 100644 --- a/libc/intrin/describehow.c +++ b/libc/intrin/describehow.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/fmt/itoa.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/sysv/consts/sig.h" const char *(DescribeHow)(char buf[12], int how) { diff --git a/libc/intrin/describeinoutint64.c b/libc/intrin/describeinoutint64.c index 977c32a15..49fe1015b 100644 --- a/libc/intrin/describeinoutint64.c +++ b/libc/intrin/describeinoutint64.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/errno.h" #include "libc/fmt/itoa.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" const char *(DescribeInOutInt64)(char buf[23], ssize_t rc, int64_t *x) { if (!x) diff --git a/libc/intrin/describeiovnt.c b/libc/intrin/describeiovnt.c index 1f94bc5d2..8229301d2 100644 --- a/libc/intrin/describeiovnt.c +++ b/libc/intrin/describeiovnt.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/kprintf.h" #include "libc/macros.internal.h" #include "libc/nt/winsock.h" diff --git a/libc/intrin/describeitimer.c b/libc/intrin/describeitimer.c index d1e83a28d..98c4e2a8c 100644 --- a/libc/intrin/describeitimer.c +++ b/libc/intrin/describeitimer.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/fmt/itoa.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/sysv/consts/itimer.h" const char *(DescribeItimer)(char buf[12], int which) { diff --git a/libc/intrin/describeitimerval.c b/libc/intrin/describeitimerval.c index 9ea8ff455..1e5661f50 100644 --- a/libc/intrin/describeitimerval.c +++ b/libc/intrin/describeitimerval.c @@ -20,7 +20,7 @@ #include "libc/calls/struct/timeval.h" #include "libc/calls/struct/timeval.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/kprintf.h" #define N 90 diff --git a/libc/intrin/describemapflags.c b/libc/intrin/describemapflags.c index fa1514435..770798ac0 100644 --- a/libc/intrin/describemapflags.c +++ b/libc/intrin/describemapflags.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/macros.internal.h" #include "libc/nt/enum/consolemodeflags.h" #include "libc/sysv/consts/map.h" diff --git a/libc/intrin/describemapping.c b/libc/intrin/describemapping.c index 792c510a7..79f1cf706 100644 --- a/libc/intrin/describemapping.c +++ b/libc/intrin/describemapping.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/runtime/memtrack.internal.h" #include "libc/sysv/consts/map.h" #include "libc/sysv/consts/prot.h" diff --git a/libc/intrin/describemremapflags.c b/libc/intrin/describemremapflags.c index 53f976b20..185206e3c 100644 --- a/libc/intrin/describemremapflags.c +++ b/libc/intrin/describemremapflags.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/macros.internal.h" #include "libc/sysv/consts/mremap.h" diff --git a/libc/intrin/describentconsolemodeinputflags.c b/libc/intrin/describentconsolemodeinputflags.c index 8083e49a3..caeeae037 100644 --- a/libc/intrin/describentconsolemodeinputflags.c +++ b/libc/intrin/describentconsolemodeinputflags.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/macros.internal.h" #include "libc/nt/enum/consolemodeflags.h" diff --git a/libc/intrin/describentconsolemodeoutputflags.c b/libc/intrin/describentconsolemodeoutputflags.c index 93b9adf78..68ab4c2c1 100644 --- a/libc/intrin/describentconsolemodeoutputflags.c +++ b/libc/intrin/describentconsolemodeoutputflags.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/macros.internal.h" #include "libc/nt/enum/consolemodeflags.h" diff --git a/libc/intrin/describentcreationdisposition.c b/libc/intrin/describentcreationdisposition.c index 33ee9015f..136a8119f 100644 --- a/libc/intrin/describentcreationdisposition.c +++ b/libc/intrin/describentcreationdisposition.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/nt/enum/creationdisposition.h" const char *DescribeNtCreationDisposition(uint32_t x) { diff --git a/libc/intrin/describentfileaccessflags.c b/libc/intrin/describentfileaccessflags.c index 6bcfe0ed2..996c9f36b 100644 --- a/libc/intrin/describentfileaccessflags.c +++ b/libc/intrin/describentfileaccessflags.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/macros.internal.h" #include "libc/nt/enum/accessmask.h" #include "libc/nt/enum/filesharemode.h" diff --git a/libc/intrin/describentfileflagattr.c b/libc/intrin/describentfileflagattr.c index 36762db5a..a27024fbd 100644 --- a/libc/intrin/describentfileflagattr.c +++ b/libc/intrin/describentfileflagattr.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/macros.internal.h" #include "libc/nt/enum/fileflagandattributes.h" #include "libc/runtime/runtime.h" diff --git a/libc/intrin/describentfilemapflags.c b/libc/intrin/describentfilemapflags.c index 6d1848b3f..11d28d561 100644 --- a/libc/intrin/describentfilemapflags.c +++ b/libc/intrin/describentfilemapflags.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/macros.internal.h" #include "libc/nt/enum/filemapflags.h" diff --git a/libc/intrin/describentfileshareflags.c b/libc/intrin/describentfileshareflags.c index 5878b1140..865cda1d7 100644 --- a/libc/intrin/describentfileshareflags.c +++ b/libc/intrin/describentfileshareflags.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/macros.internal.h" #include "libc/nt/enum/filesharemode.h" diff --git a/libc/intrin/describentfiletypeflags.c b/libc/intrin/describentfiletypeflags.c index 4ba2ffe00..8e720f302 100644 --- a/libc/intrin/describentfiletypeflags.c +++ b/libc/intrin/describentfiletypeflags.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/macros.internal.h" #include "libc/nt/enum/filetype.h" #include "libc/sysv/consts/mremap.h" diff --git a/libc/intrin/describentlockfileflags.c b/libc/intrin/describentlockfileflags.c index af02f1d9f..69f0875bc 100644 --- a/libc/intrin/describentlockfileflags.c +++ b/libc/intrin/describentlockfileflags.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/macros.internal.h" #include "libc/nt/enum/filelockflags.h" diff --git a/libc/intrin/describentmovfileinpflags.c b/libc/intrin/describentmovfileinpflags.c index 7cb601066..1b301cd6a 100644 --- a/libc/intrin/describentmovfileinpflags.c +++ b/libc/intrin/describentmovfileinpflags.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/macros.internal.h" #include "libc/nt/enum/movefileexflags.h" diff --git a/libc/intrin/describentoverlapped.c b/libc/intrin/describentoverlapped.c index a4f3e1e07..d6727424d 100644 --- a/libc/intrin/describentoverlapped.c +++ b/libc/intrin/describentoverlapped.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describentoverlapped.internal.h" +#include "libc/intrin/describentoverlapped.h" #include "libc/intrin/kprintf.h" #include "libc/macros.internal.h" diff --git a/libc/intrin/describentoverlapped.internal.h b/libc/intrin/describentoverlapped.h similarity index 100% rename from libc/intrin/describentoverlapped.internal.h rename to libc/intrin/describentoverlapped.h diff --git a/libc/intrin/describentpageflags.c b/libc/intrin/describentpageflags.c index 543f630f2..30acb62bc 100644 --- a/libc/intrin/describentpageflags.c +++ b/libc/intrin/describentpageflags.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/macros.internal.h" #include "libc/nt/enum/pageflags.h" diff --git a/libc/intrin/describentpipemodeflags.c b/libc/intrin/describentpipemodeflags.c index 490bdb037..4bab699f4 100644 --- a/libc/intrin/describentpipemodeflags.c +++ b/libc/intrin/describentpipemodeflags.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/macros.internal.h" #include "libc/nt/enum/filemapflags.h" #include "libc/nt/ipc.h" diff --git a/libc/intrin/describentpipeopenflags.c b/libc/intrin/describentpipeopenflags.c index ec3a0c5c6..bc8134229 100644 --- a/libc/intrin/describentpipeopenflags.c +++ b/libc/intrin/describentpipeopenflags.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/macros.internal.h" #include "libc/nt/enum/accessmask.h" #include "libc/nt/enum/fileflagandattributes.h" diff --git a/libc/intrin/describentprocaccessflags.c b/libc/intrin/describentprocaccessflags.c index b8d18202e..a7f5db917 100644 --- a/libc/intrin/describentprocaccessflags.c +++ b/libc/intrin/describentprocaccessflags.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/macros.internal.h" #include "libc/nt/enum/processaccess.h" diff --git a/libc/intrin/describentsecurityattributes.c b/libc/intrin/describentsecurityattributes.c index 3031b3c3a..058c2a49f 100644 --- a/libc/intrin/describentsecurityattributes.c +++ b/libc/intrin/describentsecurityattributes.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/state.internal.h" #include "libc/fmt/itoa.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/nt/struct/securityattributes.h" const char *( diff --git a/libc/intrin/describentstartflags.c b/libc/intrin/describentstartflags.c index 02aaec9ee..6a46b736c 100644 --- a/libc/intrin/describentstartflags.c +++ b/libc/intrin/describentstartflags.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/macros.internal.h" #include "libc/nt/enum/startf.h" #include "libc/sysv/consts/prot.h" diff --git a/libc/intrin/describentsymlinkflags.c b/libc/intrin/describentsymlinkflags.c index 4cc66d262..85e5d5896 100644 --- a/libc/intrin/describentsymlinkflags.c +++ b/libc/intrin/describentsymlinkflags.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/macros.internal.h" #include "libc/nt/enum/symboliclink.h" diff --git a/libc/intrin/describeopenflags.c b/libc/intrin/describeopenflags.c index b57fc9219..984ecd76e 100644 --- a/libc/intrin/describeopenflags.c +++ b/libc/intrin/describeopenflags.c @@ -19,7 +19,7 @@ #include "libc/assert.h" #include "libc/fmt/itoa.h" #include "libc/fmt/magnumstrs.internal.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/macros.internal.h" #include "libc/str/str.h" #include "libc/sysv/consts/o.h" diff --git a/libc/intrin/describeopenmode.c b/libc/intrin/describeopenmode.c index 692427508..bbfa86e8e 100644 --- a/libc/intrin/describeopenmode.c +++ b/libc/intrin/describeopenmode.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/dce.h" #include "libc/fmt/itoa.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/sysv/consts/o.h" #define O_TMPFILE_LINUX 0x00410000 diff --git a/libc/intrin/describepersonalityflags.c b/libc/intrin/describepersonalityflags.c index d92bc2c0d..86d5563cf 100644 --- a/libc/intrin/describepersonalityflags.c +++ b/libc/intrin/describepersonalityflags.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/macros.internal.h" #include "libc/nt/enum/accessmask.h" #include "libc/nt/enum/filesharemode.h" diff --git a/libc/intrin/describepollfds.c b/libc/intrin/describepollfds.c index 941fa09e2..dd1b8a19a 100644 --- a/libc/intrin/describepollfds.c +++ b/libc/intrin/describepollfds.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/kprintf.h" #include "libc/limits.h" #include "libc/macros.internal.h" diff --git a/libc/intrin/describepollflags.c b/libc/intrin/describepollflags.c index 6556e4f16..e902914a3 100644 --- a/libc/intrin/describepollflags.c +++ b/libc/intrin/describepollflags.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/macros.internal.h" #include "libc/nt/enum/filemapflags.h" #include "libc/sysv/consts/poll.h" diff --git a/libc/intrin/describeprotflags.c b/libc/intrin/describeprotflags.c index 5761ac0fe..33baf5fcf 100644 --- a/libc/intrin/describeprotflags.c +++ b/libc/intrin/describeprotflags.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/macros.internal.h" #include "libc/sysv/consts/prot.h" diff --git a/libc/intrin/describeptrace.c b/libc/intrin/describeptrace.c index 7b9969fce..d4c6f4fec 100644 --- a/libc/intrin/describeptrace.c +++ b/libc/intrin/describeptrace.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/fmt/itoa.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/sysv/consts/ptrace.h" const char *(DescribePtrace)(char buf[12], int x) { diff --git a/libc/intrin/describeptraceevent.c b/libc/intrin/describeptraceevent.c index f8e8e49ed..b3ba1ee18 100644 --- a/libc/intrin/describeptraceevent.c +++ b/libc/intrin/describeptraceevent.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/fmt/itoa.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/sysv/consts/ptrace.h" const char *(DescribePtraceEvent)(char buf[32], int x) { diff --git a/libc/intrin/describerlimit.c b/libc/intrin/describerlimit.c index 9d211a6c4..feb7574ee 100644 --- a/libc/intrin/describerlimit.c +++ b/libc/intrin/describerlimit.c @@ -20,7 +20,7 @@ #include "libc/dce.h" #include "libc/fmt/itoa.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/str/str.h" #include "libc/sysv/consts/rlim.h" diff --git a/libc/intrin/describerlimitname.c b/libc/intrin/describerlimitname.c index d7b578853..15ee5a7b9 100644 --- a/libc/intrin/describerlimitname.c +++ b/libc/intrin/describerlimitname.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/fmt/magnumstrs.internal.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" /** * Describes setrlimit() / getrlimit() argument. diff --git a/libc/intrin/describeschedparam.c b/libc/intrin/describeschedparam.c index 059d66088..369f52d93 100644 --- a/libc/intrin/describeschedparam.c +++ b/libc/intrin/describeschedparam.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/struct/sched_param.h" #include "libc/fmt/itoa.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/str/str.h" /** diff --git a/libc/intrin/describeschedpolicy.c b/libc/intrin/describeschedpolicy.c index 626a8efe0..687636ae3 100644 --- a/libc/intrin/describeschedpolicy.c +++ b/libc/intrin/describeschedpolicy.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/fmt/itoa.h" #include "libc/fmt/magnumstrs.internal.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/macros.internal.h" #include "libc/str/str.h" #include "libc/sysv/consts/sched.h" diff --git a/libc/intrin/describeseccompoperation.c b/libc/intrin/describeseccompoperation.c index 74a379f9e..a18b18d6f 100644 --- a/libc/intrin/describeseccompoperation.c +++ b/libc/intrin/describeseccompoperation.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/struct/seccomp.internal.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" const char *DescribeSeccompOperation(int x) { switch (x) { diff --git a/libc/intrin/describesigaction.c b/libc/intrin/describesigaction.c index 968ce057c..a9b1fb8d6 100644 --- a/libc/intrin/describesigaction.c +++ b/libc/intrin/describesigaction.c @@ -21,7 +21,7 @@ #include "libc/calls/struct/sigset.h" #include "libc/calls/struct/sigset.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/kprintf.h" #include "libc/macros.internal.h" #include "libc/mem/alloca.h" diff --git a/libc/intrin/describesigaltstack.c b/libc/intrin/describesigaltstack.c index 5121a93e5..90770f3a6 100644 --- a/libc/intrin/describesigaltstack.c +++ b/libc/intrin/describesigaltstack.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/struct/sigaltstack.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/kprintf.h" const char *(DescribeSigaltstk)(char buf[128], int rc, diff --git a/libc/intrin/describesiginfo.c b/libc/intrin/describesiginfo.c index d1bc5508d..8235b078b 100644 --- a/libc/intrin/describesiginfo.c +++ b/libc/intrin/describesiginfo.c @@ -19,7 +19,7 @@ #include "libc/calls/struct/siginfo.h" #include "libc/calls/struct/siginfo.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/kprintf.h" #include "libc/intrin/weaken.h" #include "libc/str/str.h" diff --git a/libc/intrin/describesleepflags.c b/libc/intrin/describesleepflags.c index 8b37755fd..858a254f6 100644 --- a/libc/intrin/describesleepflags.c +++ b/libc/intrin/describesleepflags.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/fmt/itoa.h" #include "libc/fmt/magnumstrs.internal.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/sysv/consts/timer.h" /** diff --git a/libc/intrin/describesocketfamily.c b/libc/intrin/describesocketfamily.c index 7f1b32ade..e4bacb527 100644 --- a/libc/intrin/describesocketfamily.c +++ b/libc/intrin/describesocketfamily.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/fmt/itoa.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/sysv/consts/af.h" const char *(DescribeSocketFamily)(char buf[12], int family) { diff --git a/libc/intrin/describesocketprotocol.c b/libc/intrin/describesocketprotocol.c index 933ce7b41..39086245f 100644 --- a/libc/intrin/describesocketprotocol.c +++ b/libc/intrin/describesocketprotocol.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/fmt/itoa.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/sysv/consts/ipproto.h" const char *(DescribeSocketProtocol)(char buf[12], int family) { diff --git a/libc/intrin/describesockettype.c b/libc/intrin/describesockettype.c index 69cf9d76e..f28ffc5b8 100644 --- a/libc/intrin/describesockettype.c +++ b/libc/intrin/describesockettype.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/fmt/itoa.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/str/str.h" #include "libc/sysv/consts/sock.h" diff --git a/libc/intrin/describesocklevel.c b/libc/intrin/describesocklevel.c index dc1959ee1..8edadadc5 100644 --- a/libc/intrin/describesocklevel.c +++ b/libc/intrin/describesocklevel.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/fmt/itoa.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/sysv/consts/sol.h" /** diff --git a/libc/intrin/describesockoptname.c b/libc/intrin/describesockoptname.c index 1341008eb..baf37f81b 100644 --- a/libc/intrin/describesockoptname.c +++ b/libc/intrin/describesockoptname.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/fmt/itoa.h" #include "libc/fmt/magnumstrs.internal.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/str/str.h" #include "libc/sysv/consts/sol.h" diff --git a/libc/intrin/describestdiostate.c b/libc/intrin/describestdiostate.c index 74a934cdc..822bd2ed9 100644 --- a/libc/intrin/describestdiostate.c +++ b/libc/intrin/describestdiostate.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/fmt/itoa.h" #include "libc/fmt/magnumstrs.internal.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/str/str.h" const char *(DescribeStdioState)(char buf[12], int x) { diff --git a/libc/intrin/describestringlist.c b/libc/intrin/describestringlist.c index b998b1cea..9f0e5949f 100644 --- a/libc/intrin/describestringlist.c +++ b/libc/intrin/describestringlist.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/kprintf.h" #define N 300 diff --git a/libc/intrin/describetermios.c b/libc/intrin/describetermios.c index 825d3f0c6..6a76a2234 100644 --- a/libc/intrin/describetermios.c +++ b/libc/intrin/describetermios.c @@ -20,7 +20,7 @@ #include "libc/calls/struct/termios.internal.h" #include "libc/calls/ttydefaults.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/kprintf.h" #include "libc/macros.internal.h" #include "libc/sysv/consts/termios.h" diff --git a/libc/intrin/describethreadcreationflags.c b/libc/intrin/describethreadcreationflags.c index 54f5ec657..1b0e75b62 100644 --- a/libc/intrin/describethreadcreationflags.c +++ b/libc/intrin/describethreadcreationflags.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/macros.internal.h" #include "libc/nt/enum/processcreationflags.h" diff --git a/libc/intrin/describetimespec.c b/libc/intrin/describetimespec.c index 7b5c56d9c..a07f0c992 100644 --- a/libc/intrin/describetimespec.c +++ b/libc/intrin/describetimespec.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/struct/timespec.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/kprintf.h" #include "libc/str/str.h" diff --git a/libc/intrin/describetimeval.c b/libc/intrin/describetimeval.c index 328d95d90..896b10c3d 100644 --- a/libc/intrin/describetimeval.c +++ b/libc/intrin/describetimeval.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/struct/timeval.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/kprintf.h" const char *(DescribeTimeval)(char buf[45], int rc, const struct timeval *tv) { diff --git a/libc/intrin/describewhence.c b/libc/intrin/describewhence.c index 3de47df18..3d166fcbd 100644 --- a/libc/intrin/describewhence.c +++ b/libc/intrin/describewhence.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" #include "libc/fmt/itoa.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" const char *(DescribeWhence)(char buf[12], int whence) { if (whence == SEEK_SET) diff --git a/libc/intrin/describewhichprio.c b/libc/intrin/describewhichprio.c index 3459dc17e..c72bf5eca 100644 --- a/libc/intrin/describewhichprio.c +++ b/libc/intrin/describewhichprio.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/fmt/itoa.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/sysv/consts/prio.h" const char *(DescribeWhichPrio)(char buf[12], int x) { diff --git a/libc/intrin/describewinsize.c b/libc/intrin/describewinsize.c index abc91c867..994ade424 100644 --- a/libc/intrin/describewinsize.c +++ b/libc/intrin/describewinsize.c @@ -19,7 +19,7 @@ #include "libc/calls/struct/winsize.h" #include "libc/calls/struct/winsize.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/kprintf.h" #include "libc/limits.h" #include "libc/macros.internal.h" diff --git a/libc/intrin/deviceiocontrol.c b/libc/intrin/deviceiocontrol.c index bd164fe29..983870285 100644 --- a/libc/intrin/deviceiocontrol.c +++ b/libc/intrin/deviceiocontrol.c @@ -17,8 +17,8 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/describentoverlapped.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describentoverlapped.h" +#include "libc/intrin/strace.h" #include "libc/nt/files.h" #include "libc/nt/struct/overlapped.h" #include "libc/nt/thunk/msabi.h" diff --git a/libc/intrin/directmap-metal.c b/libc/intrin/directmap-metal.c index af0e1889c..77c0ee8b9 100644 --- a/libc/intrin/directmap-metal.c +++ b/libc/intrin/directmap-metal.c @@ -19,7 +19,7 @@ #include "libc/calls/calls.h" #include "libc/calls/internal.h" #include "libc/calls/metalfile.internal.h" -#include "libc/intrin/directmap.internal.h" +#include "libc/intrin/directmap.h" #include "libc/macros.internal.h" #include "libc/runtime/pc.internal.h" #include "libc/str/str.h" diff --git a/libc/intrin/directmap-nt.c b/libc/intrin/directmap-nt.c index 00b93463d..3cd19da78 100644 --- a/libc/intrin/directmap-nt.c +++ b/libc/intrin/directmap-nt.c @@ -20,7 +20,7 @@ #include "libc/calls/internal.h" #include "libc/calls/state.internal.h" #include "libc/errno.h" -#include "libc/intrin/directmap.internal.h" +#include "libc/intrin/directmap.h" #include "libc/nt/enum/filemapflags.h" #include "libc/nt/enum/pageflags.h" #include "libc/nt/errors.h" diff --git a/libc/intrin/directmap.c b/libc/intrin/directmap.c index edac9eb8d..b0a40ff59 100644 --- a/libc/intrin/directmap.c +++ b/libc/intrin/directmap.c @@ -20,9 +20,9 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/directmap.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/directmap.h" +#include "libc/intrin/strace.h" #include "libc/nt/runtime.h" #include "libc/runtime/memtrack.internal.h" #include "libc/runtime/runtime.h" diff --git a/libc/intrin/directmap.internal.h b/libc/intrin/directmap.h similarity index 100% rename from libc/intrin/directmap.internal.h rename to libc/intrin/directmap.h diff --git a/libc/intrin/dos2errno.c b/libc/intrin/dos2errno.c index 4e88bd67b..2cbca8f1e 100644 --- a/libc/intrin/dos2errno.c +++ b/libc/intrin/dos2errno.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/errno.h" -#include "libc/intrin/dos2errno.internal.h" +#include "libc/intrin/dos2errno.h" #include "libc/nt/errors.h" #include "libc/sock/sock.h" diff --git a/libc/intrin/dos2errno.internal.h b/libc/intrin/dos2errno.h similarity index 100% rename from libc/intrin/dos2errno.internal.h rename to libc/intrin/dos2errno.h diff --git a/libc/intrin/exit.c b/libc/intrin/exit.c index 8d1a92f6c..1338e1846 100644 --- a/libc/intrin/exit.c +++ b/libc/intrin/exit.c @@ -17,8 +17,8 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/dce.h" -#include "libc/intrin/promises.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/promises.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/nexgen32e/vendor.internal.h" #include "libc/nt/enum/status.h" diff --git a/libc/intrin/extend.internal.h b/libc/intrin/extend.h similarity index 100% rename from libc/intrin/extend.internal.h rename to libc/intrin/extend.h diff --git a/libc/intrin/g_fds.c b/libc/intrin/fds.c similarity index 96% rename from libc/intrin/g_fds.c rename to libc/intrin/fds.c index addae54ad..f70abfb92 100644 --- a/libc/intrin/g_fds.c +++ b/libc/intrin/fds.c @@ -18,14 +18,14 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/internal.h" #include "libc/calls/state.internal.h" -#include "libc/calls/struct/fd.internal.h" #include "libc/calls/ttydefaults.h" #include "libc/dce.h" #include "libc/intrin/atomic.h" -#include "libc/intrin/extend.internal.h" +#include "libc/intrin/extend.h" +#include "libc/intrin/fds.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/nomultics.internal.h" -#include "libc/intrin/pushpop.internal.h" +#include "libc/intrin/nomultics.h" +#include "libc/intrin/pushpop.h" #include "libc/intrin/weaken.h" #include "libc/nt/console.h" #include "libc/nt/createfile.h" @@ -45,7 +45,7 @@ #define OPEN_MAX 16 #ifdef __x86_64__ -__static_yoink("_init_g_fds"); +__static_yoink("_init_fds"); #endif struct Fds g_fds; diff --git a/libc/calls/struct/fd.internal.h b/libc/intrin/fds.h similarity index 100% rename from libc/calls/struct/fd.internal.h rename to libc/intrin/fds.h diff --git a/libc/intrin/g_fds_init.S b/libc/intrin/fds_init.S similarity index 97% rename from libc/intrin/g_fds_init.S rename to libc/intrin/fds_init.S index c39f63767..d0fa0b96d 100644 --- a/libc/intrin/g_fds_init.S +++ b/libc/intrin/fds_init.S @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/macros.internal.h" - .init.start 305,_init_g_fds + .init.start 305,_init_fds push %rdi push %rsi mov %r12d,%edi // argc @@ -27,4 +27,4 @@ call __init_fds pop %rsi pop %rdi - .init.end 305,_init_g_fds + .init.end 305,_init_fds diff --git a/libc/intrin/findclose.c b/libc/intrin/findclose.c index eccb3dff0..7f208ac21 100644 --- a/libc/intrin/findclose.c +++ b/libc/intrin/findclose.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nt/files.h" #include "libc/nt/thunk/msabi.h" diff --git a/libc/intrin/findfirstfile.c b/libc/intrin/findfirstfile.c index 661de9c3d..f43759706 100644 --- a/libc/intrin/findfirstfile.c +++ b/libc/intrin/findfirstfile.c @@ -17,8 +17,8 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/nt/files.h" #include "libc/nt/memory.h" #include "libc/nt/struct/win32finddata.h" diff --git a/libc/intrin/findnextfile.c b/libc/intrin/findnextfile.c index 5bb42cc87..e1cb288e6 100644 --- a/libc/intrin/findnextfile.c +++ b/libc/intrin/findnextfile.c @@ -17,8 +17,8 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/nt/errors.h" #include "libc/nt/files.h" #include "libc/nt/memory.h" diff --git a/libc/intrin/flushfilebuffers.c b/libc/intrin/flushfilebuffers.c index 1105d8dd1..4c03a89ae 100644 --- a/libc/intrin/flushfilebuffers.c +++ b/libc/intrin/flushfilebuffers.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nt/files.h" #include "libc/nt/runtime.h" diff --git a/libc/intrin/flushviewoffile.c b/libc/intrin/flushviewoffile.c index 049a9c0e1..1f977481c 100644 --- a/libc/intrin/flushviewoffile.c +++ b/libc/intrin/flushviewoffile.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nt/memory.h" __msabi extern typeof(FlushViewOfFile) *const __imp_FlushViewOfFile; diff --git a/libc/intrin/generateconsolectrlevent.c b/libc/intrin/generateconsolectrlevent.c index a9b24dd0e..8a2c673cd 100644 --- a/libc/intrin/generateconsolectrlevent.c +++ b/libc/intrin/generateconsolectrlevent.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nt/console.h" #include "libc/nt/thunk/msabi.h" diff --git a/libc/intrin/getauxval.c b/libc/intrin/getauxval.c index 54bc4a7e5..503be8f26 100644 --- a/libc/intrin/getauxval.c +++ b/libc/intrin/getauxval.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/errno.h" -#include "libc/intrin/getauxval.internal.h" +#include "libc/intrin/getauxval.h" #include "libc/runtime/runtime.h" /** diff --git a/libc/intrin/getauxval.internal.h b/libc/intrin/getauxval.h similarity index 100% rename from libc/intrin/getauxval.internal.h rename to libc/intrin/getauxval.h diff --git a/libc/intrin/getenv.c b/libc/intrin/getenv.c index e272d3ed1..29a003d71 100644 --- a/libc/intrin/getenv.c +++ b/libc/intrin/getenv.c @@ -16,8 +16,8 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/getenv.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/getenv.h" +#include "libc/intrin/strace.h" #include "libc/runtime/runtime.h" /** diff --git a/libc/intrin/getenv.internal.h b/libc/intrin/getenv.h similarity index 100% rename from libc/intrin/getenv.internal.h rename to libc/intrin/getenv.h diff --git a/libc/intrin/getexitcodeprocess.c b/libc/intrin/getexitcodeprocess.c index 8f359803a..630cb4d77 100644 --- a/libc/intrin/getexitcodeprocess.c +++ b/libc/intrin/getexitcodeprocess.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nt/accounting.h" #include "libc/nt/thunk/msabi.h" diff --git a/libc/intrin/getfileattributes.c b/libc/intrin/getfileattributes.c index 17f520589..976d0a2e3 100644 --- a/libc/intrin/getfileattributes.c +++ b/libc/intrin/getfileattributes.c @@ -16,8 +16,8 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/nt/files.h" #include "libc/nt/thunk/msabi.h" diff --git a/libc/intrin/getmainstack.c b/libc/intrin/getmainstack.c index 3638898d9..af6e901ba 100644 --- a/libc/intrin/getmainstack.c +++ b/libc/intrin/getmainstack.c @@ -19,7 +19,7 @@ #include "libc/calls/struct/rlimit.h" #include "libc/calls/struct/rlimit.internal.h" #include "libc/dce.h" -#include "libc/intrin/getauxval.internal.h" +#include "libc/intrin/getauxval.h" #include "libc/intrin/kprintf.h" #include "libc/intrin/maps.h" #include "libc/macros.internal.h" diff --git a/libc/intrin/getminsigstksz.c b/libc/intrin/getminsigstksz.c index 95306f23b..cb87e441c 100644 --- a/libc/intrin/getminsigstksz.c +++ b/libc/intrin/getminsigstksz.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/getauxval.internal.h" +#include "libc/intrin/getauxval.h" #include "libc/macros.internal.h" #include "libc/runtime/runtime.h" #include "libc/sysv/consts/auxv.h" diff --git a/libc/intrin/iscall.c b/libc/intrin/iscall.c index 7907d8525..d97d446c1 100644 --- a/libc/intrin/iscall.c +++ b/libc/intrin/iscall.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/iscall.internal.h" +#include "libc/intrin/iscall.h" // returns true if `p` is preceded by x86 call instruction // this is actually impossible to do but we'll do our best diff --git a/libc/intrin/iscall.internal.h b/libc/intrin/iscall.h similarity index 100% rename from libc/intrin/iscall.internal.h rename to libc/intrin/iscall.h diff --git a/libc/intrin/isdebuggerpresent.c b/libc/intrin/isdebuggerpresent.c index 0e12034f3..37474326e 100644 --- a/libc/intrin/isdebuggerpresent.c +++ b/libc/intrin/isdebuggerpresent.c @@ -20,8 +20,8 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/getenv.internal.h" -#include "libc/intrin/promises.internal.h" +#include "libc/intrin/getenv.h" +#include "libc/intrin/promises.h" #include "libc/log/libfatal.internal.h" #include "libc/log/log.h" #include "libc/runtime/runtime.h" diff --git a/libc/intrin/kprintf.greg.c b/libc/intrin/kprintf.greg.c index d32c52c64..1677f8953 100644 --- a/libc/intrin/kprintf.greg.c +++ b/libc/intrin/kprintf.greg.c @@ -25,11 +25,11 @@ #include "libc/fmt/magnumstrs.internal.h" #include "libc/intrin/asmflag.h" #include "libc/intrin/atomic.h" -#include "libc/intrin/getenv.internal.h" +#include "libc/intrin/getenv.h" #include "libc/intrin/kprintf.h" #include "libc/intrin/likely.h" #include "libc/intrin/maps.h" -#include "libc/intrin/nomultics.internal.h" +#include "libc/intrin/nomultics.h" #include "libc/intrin/weaken.h" #include "libc/log/internal.h" #include "libc/nexgen32e/rdtsc.h" diff --git a/libc/intrin/lockfileex.c b/libc/intrin/lockfileex.c index e156ebe54..88f3cb9e0 100644 --- a/libc/intrin/lockfileex.c +++ b/libc/intrin/lockfileex.c @@ -17,9 +17,9 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/describentoverlapped.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/describentoverlapped.h" +#include "libc/intrin/strace.h" #include "libc/nt/enum/filelockflags.h" #include "libc/nt/files.h" diff --git a/libc/intrin/mapviewoffileex.c b/libc/intrin/mapviewoffileex.c index 3841269bf..992a1897d 100644 --- a/libc/intrin/mapviewoffileex.c +++ b/libc/intrin/mapviewoffileex.c @@ -18,8 +18,8 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/assert.h" #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/nt/enum/filemapflags.h" #include "libc/nt/memory.h" diff --git a/libc/intrin/mapviewoffileexnuma.c b/libc/intrin/mapviewoffileexnuma.c index 2ee4e40de..879ba345c 100644 --- a/libc/intrin/mapviewoffileexnuma.c +++ b/libc/intrin/mapviewoffileexnuma.c @@ -19,8 +19,8 @@ #include "libc/assert.h" #include "libc/calls/syscall_support-nt.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/nt/enum/filemapflags.h" #include "libc/nt/memory.h" diff --git a/libc/intrin/mmap.c b/libc/intrin/mmap.c index 887d4de34..6982507a6 100644 --- a/libc/intrin/mmap.c +++ b/libc/intrin/mmap.c @@ -28,12 +28,12 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/atomic.h" -#include "libc/intrin/describebacktrace.internal.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/directmap.internal.h" +#include "libc/intrin/describebacktrace.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/directmap.h" #include "libc/intrin/kprintf.h" #include "libc/intrin/maps.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/nt/memory.h" #include "libc/nt/runtime.h" diff --git a/libc/intrin/movefileex.c b/libc/intrin/movefileex.c index 66e32fe02..bd7496db2 100644 --- a/libc/intrin/movefileex.c +++ b/libc/intrin/movefileex.c @@ -17,8 +17,8 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/nt/files.h" #include "libc/nt/memory.h" #include "libc/nt/thunk/msabi.h" diff --git a/libc/intrin/mprotect.c b/libc/intrin/mprotect.c index a3c38744a..cc8a23ee9 100644 --- a/libc/intrin/mprotect.c +++ b/libc/intrin/mprotect.c @@ -19,12 +19,12 @@ #include "libc/calls/struct/sigset.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/directmap.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/directmap.h" #include "libc/intrin/dll.h" #include "libc/intrin/kprintf.h" #include "libc/intrin/maps.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/tree.h" #include "libc/nt/memory.h" #include "libc/runtime/internal.h" diff --git a/libc/intrin/msync.c b/libc/intrin/msync.c index a9b03ea8c..69bf5730b 100644 --- a/libc/intrin/msync.c +++ b/libc/intrin/msync.c @@ -23,7 +23,7 @@ #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/macros.internal.h" #include "libc/sysv/errfuns.h" diff --git a/libc/intrin/munmap-metal.c b/libc/intrin/munmap-metal.c index b022ddfc4..83f889bb6 100644 --- a/libc/intrin/munmap-metal.c +++ b/libc/intrin/munmap-metal.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/directmap.internal.h" +#include "libc/intrin/directmap.h" #include "libc/runtime/pc.internal.h" #ifdef __x86_64__ diff --git a/libc/intrin/munmap-sysv.c b/libc/intrin/munmap-sysv.c index 258782d60..0f00ddc5c 100644 --- a/libc/intrin/munmap-sysv.c +++ b/libc/intrin/munmap-sysv.c @@ -18,9 +18,9 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/directmap.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/directmap.h" +#include "libc/intrin/strace.h" #include "libc/runtime/runtime.h" #include "libc/runtime/syslib.internal.h" diff --git a/libc/intrin/nomultics.c b/libc/intrin/nomultics.c index 065eb42fc..fa38350f1 100644 --- a/libc/intrin/nomultics.c +++ b/libc/intrin/nomultics.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/ttydefaults.h" -#include "libc/intrin/nomultics.internal.h" +#include "libc/intrin/nomultics.h" struct TtyConf __ttyconf = { .vmin = 1, diff --git a/libc/intrin/nomultics.internal.h b/libc/intrin/nomultics.h similarity index 100% rename from libc/intrin/nomultics.internal.h rename to libc/intrin/nomultics.h diff --git a/libc/intrin/openprocess.c b/libc/intrin/openprocess.c index 338da91bf..3f9fed97c 100644 --- a/libc/intrin/openprocess.c +++ b/libc/intrin/openprocess.c @@ -17,8 +17,8 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/nt/memory.h" #include "libc/nt/process.h" #include "libc/nt/struct/securityattributes.h" diff --git a/libc/intrin/printmaps.c b/libc/intrin/printmaps.c index 0a67103b3..d9eaa32af 100644 --- a/libc/intrin/printmaps.c +++ b/libc/intrin/printmaps.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/fmt/conv.h" #include "libc/fmt/itoa.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/kprintf.h" #include "libc/intrin/maps.h" #include "libc/macros.internal.h" diff --git a/libc/intrin/promises.c b/libc/intrin/promises.c index a04f9cd8a..99778d9b5 100644 --- a/libc/intrin/promises.c +++ b/libc/intrin/promises.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/pledge.h" -#include "libc/intrin/promises.internal.h" +#include "libc/intrin/promises.h" // XXX: should be inherited thread local // see also sys_pledge_linux() which is 100% pure diff --git a/libc/intrin/promises.internal.h b/libc/intrin/promises.h similarity index 100% rename from libc/intrin/promises.internal.h rename to libc/intrin/promises.h diff --git a/libc/intrin/prot2nt.greg.c b/libc/intrin/prot2nt.greg.c index 59dd01491..569786b9b 100644 --- a/libc/intrin/prot2nt.greg.c +++ b/libc/intrin/prot2nt.greg.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/directmap.internal.h" +#include "libc/intrin/directmap.h" #include "libc/nt/enum/pageflags.h" #include "libc/sysv/consts/prot.h" diff --git a/libc/intrin/pthread_atfork_actual.c b/libc/intrin/pthread_atfork_actual.c index 251d9c81f..815517206 100644 --- a/libc/intrin/pthread_atfork_actual.c +++ b/libc/intrin/pthread_atfork_actual.c @@ -23,7 +23,7 @@ #include "libc/errno.h" #include "libc/intrin/atomic.h" #include "libc/intrin/dll.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/macros.internal.h" #include "libc/proc/proc.internal.h" #include "libc/runtime/runtime.h" diff --git a/libc/intrin/pthread_delay_np.c b/libc/intrin/pthread_delay_np.c index 3a7c98024..03d51f08d 100644 --- a/libc/intrin/pthread_delay_np.c +++ b/libc/intrin/pthread_delay_np.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/thread/thread.h" /** diff --git a/libc/intrin/pthread_mutex_lock.c b/libc/intrin/pthread_mutex_lock.c index 509af6e04..99d4d9ba2 100644 --- a/libc/intrin/pthread_mutex_lock.c +++ b/libc/intrin/pthread_mutex_lock.c @@ -21,8 +21,8 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/atomic.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/runtime/internal.h" #include "libc/thread/lock.h" diff --git a/libc/intrin/pthread_mutex_unlock.c b/libc/intrin/pthread_mutex_unlock.c index dc8d0fb1f..652896475 100644 --- a/libc/intrin/pthread_mutex_unlock.c +++ b/libc/intrin/pthread_mutex_unlock.c @@ -20,7 +20,7 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/atomic.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/runtime/internal.h" #include "libc/thread/lock.h" diff --git a/libc/intrin/pthread_setcancelstate.c b/libc/intrin/pthread_setcancelstate.c index ae8f9a129..9ce15824d 100644 --- a/libc/intrin/pthread_setcancelstate.c +++ b/libc/intrin/pthread_setcancelstate.c @@ -18,8 +18,8 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/thread/posixthread.internal.h" #include "libc/thread/thread.h" #include "libc/thread/tls.h" diff --git a/libc/intrin/pushpop.internal.h b/libc/intrin/pushpop.h similarity index 100% rename from libc/intrin/pushpop.internal.h rename to libc/intrin/pushpop.h diff --git a/libc/intrin/rand64.c b/libc/intrin/rand64.c index f631d109f..0014d0de9 100644 --- a/libc/intrin/rand64.c +++ b/libc/intrin/rand64.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/getauxval.internal.h" +#include "libc/intrin/getauxval.h" #include "libc/nexgen32e/rdtsc.h" #include "libc/runtime/internal.h" #include "libc/runtime/runtime.h" diff --git a/libc/intrin/removedirectory.c b/libc/intrin/removedirectory.c index 38f03d205..0e7864bf7 100644 --- a/libc/intrin/removedirectory.c +++ b/libc/intrin/removedirectory.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nt/files.h" #include "libc/nt/thunk/msabi.h" diff --git a/libc/intrin/reopenfile.c b/libc/intrin/reopenfile.c index 0c769d8be..d49b008ef 100644 --- a/libc/intrin/reopenfile.c +++ b/libc/intrin/reopenfile.c @@ -17,8 +17,8 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/nt/files.h" #include "libc/nt/runtime.h" #include "libc/nt/thunk/msabi.h" diff --git a/libc/intrin/reservefd.c b/libc/intrin/reservefd.c index a8d47a477..e751c1dd6 100644 --- a/libc/intrin/reservefd.c +++ b/libc/intrin/reservefd.c @@ -18,10 +18,10 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/internal.h" #include "libc/calls/state.internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/intrin/atomic.h" #include "libc/intrin/cmpxchg.h" -#include "libc/intrin/extend.internal.h" +#include "libc/intrin/extend.h" #include "libc/macros.internal.h" #include "libc/runtime/memtrack.internal.h" #include "libc/str/str.h" diff --git a/libc/intrin/safemacros.internal.h b/libc/intrin/safemacros.h similarity index 100% rename from libc/intrin/safemacros.internal.h rename to libc/intrin/safemacros.h diff --git a/libc/intrin/setcurrentdirectory.c b/libc/intrin/setcurrentdirectory.c index ae8b70c43..3e2398bf5 100644 --- a/libc/intrin/setcurrentdirectory.c +++ b/libc/intrin/setcurrentdirectory.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nt/files.h" #include "libc/nt/memory.h" #include "libc/nt/thunk/msabi.h" diff --git a/libc/intrin/setjmp.internal.h b/libc/intrin/setjmp.h similarity index 100% rename from libc/intrin/setjmp.internal.h rename to libc/intrin/setjmp.h diff --git a/libc/intrin/sigprocmask.c b/libc/intrin/sigprocmask.c index aa77cac8c..aa76966ab 100644 --- a/libc/intrin/sigprocmask.c +++ b/libc/intrin/sigprocmask.c @@ -23,8 +23,8 @@ #include "libc/calls/struct/sigset.internal.h" #include "libc/dce.h" #include "libc/fmt/itoa.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/str/str.h" #include "libc/sysv/consts/sig.h" #include "libc/sysv/errfuns.h" diff --git a/libc/intrin/strace.internal.h b/libc/intrin/strace.h similarity index 100% rename from libc/intrin/strace.internal.h rename to libc/intrin/strace.h diff --git a/libc/intrin/stracef.greg.c b/libc/intrin/stracef.greg.c index 3bbfe1166..04cc8a80a 100644 --- a/libc/intrin/stracef.greg.c +++ b/libc/intrin/stracef.greg.c @@ -17,9 +17,9 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/dce.h" -#include "libc/intrin/describebacktrace.internal.h" +#include "libc/intrin/describebacktrace.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/runtime/runtime.h" dontinstrument void __stracef(const char *fmt, ...) { diff --git a/libc/intrin/terminateprocess.c b/libc/intrin/terminateprocess.c index b69e68351..b03966dd6 100644 --- a/libc/intrin/terminateprocess.c +++ b/libc/intrin/terminateprocess.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nt/console.h" #include "libc/nt/runtime.h" #include "libc/nt/thunk/msabi.h" diff --git a/libc/intrin/ubsan.c b/libc/intrin/ubsan.c index 98c22d85d..e6107594a 100644 --- a/libc/intrin/ubsan.c +++ b/libc/intrin/ubsan.c @@ -19,8 +19,8 @@ #include "libc/intrin/ubsan.h" #include "libc/calls/calls.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/pushpop.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/pushpop.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/limits.h" #include "libc/log/color.internal.h" diff --git a/libc/intrin/ulock.c b/libc/intrin/ulock.c index 190d18133..906f96ecc 100644 --- a/libc/intrin/ulock.c +++ b/libc/intrin/ulock.c @@ -21,8 +21,8 @@ #include "libc/calls/calls.h" #include "libc/calls/syscall_support-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" // XNU futexes // https://opensource.apple.com/source/xnu/xnu-7195.50.7.100.1/bsd/sys/ulock.h.auto.html diff --git a/libc/intrin/unlockfileex.c b/libc/intrin/unlockfileex.c index 46cc29248..295b7ae77 100644 --- a/libc/intrin/unlockfileex.c +++ b/libc/intrin/unlockfileex.c @@ -18,9 +18,9 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall_support-nt.internal.h" #include "libc/errno.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/describentoverlapped.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/describentoverlapped.h" +#include "libc/intrin/strace.h" #include "libc/nt/files.h" #include "libc/str/str.h" diff --git a/libc/intrin/unmapviewoffile.c b/libc/intrin/unmapviewoffile.c index 853893895..7c5972082 100644 --- a/libc/intrin/unmapviewoffile.c +++ b/libc/intrin/unmapviewoffile.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nt/memory.h" __msabi extern typeof(UnmapViewOfFile) *const __imp_UnmapViewOfFile; diff --git a/libc/intrin/unsetenv.c b/libc/intrin/unsetenv.c index d96e1e4f4..e882448ff 100644 --- a/libc/intrin/unsetenv.c +++ b/libc/intrin/unsetenv.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/dce.h" -#include "libc/intrin/getenv.internal.h" +#include "libc/intrin/getenv.h" #include "libc/runtime/runtime.h" #include "libc/str/str.h" #include "libc/sysv/errfuns.h" diff --git a/libc/intrin/virtualprotect.c b/libc/intrin/virtualprotect.c index 55c97470c..4b1aaa1a0 100644 --- a/libc/intrin/virtualprotect.c +++ b/libc/intrin/virtualprotect.c @@ -17,8 +17,8 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/log/libfatal.internal.h" #include "libc/nt/memory.h" diff --git a/libc/intrin/waitformultipleobjects.c b/libc/intrin/waitformultipleobjects.c index 3ea1abba3..661f8946b 100644 --- a/libc/intrin/waitformultipleobjects.c +++ b/libc/intrin/waitformultipleobjects.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nt/runtime.h" #include "libc/nt/synchronization.h" #include "libc/nt/thunk/msabi.h" diff --git a/libc/intrin/waitforsingleobject.c b/libc/intrin/waitforsingleobject.c index 038ff2683..c42d3b5d2 100644 --- a/libc/intrin/waitforsingleobject.c +++ b/libc/intrin/waitforsingleobject.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nt/runtime.h" #include "libc/nt/synchronization.h" #include "libc/nt/thunk/msabi.h" diff --git a/libc/intrin/wsagetoverlappedresult.c b/libc/intrin/wsagetoverlappedresult.c index a9096ec8a..f1315bcef 100644 --- a/libc/intrin/wsagetoverlappedresult.c +++ b/libc/intrin/wsagetoverlappedresult.c @@ -17,9 +17,9 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/errno.h" -#include "libc/intrin/describentoverlapped.internal.h" +#include "libc/intrin/describentoverlapped.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/mem/alloca.h" #include "libc/nt/thunk/msabi.h" #include "libc/nt/winsock.h" diff --git a/libc/intrin/wsarecv.c b/libc/intrin/wsarecv.c index 89cad8a1c..e4fe65f11 100644 --- a/libc/intrin/wsarecv.c +++ b/libc/intrin/wsarecv.c @@ -18,11 +18,11 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/assert.h" #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/describentoverlapped.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/describentoverlapped.h" #include "libc/intrin/kprintf.h" #include "libc/intrin/likely.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nt/thunk/msabi.h" #include "libc/nt/winsock.h" #include "libc/runtime/runtime.h" diff --git a/libc/intrin/wsarecvfrom.c b/libc/intrin/wsarecvfrom.c index 9965974d3..170eb9977 100644 --- a/libc/intrin/wsarecvfrom.c +++ b/libc/intrin/wsarecvfrom.c @@ -17,11 +17,11 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/describentoverlapped.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/describentoverlapped.h" #include "libc/intrin/kprintf.h" #include "libc/intrin/likely.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nt/runtime.h" #include "libc/nt/thunk/msabi.h" #include "libc/nt/winsock.h" diff --git a/libc/intrin/wsawaitformultipleevents.c b/libc/intrin/wsawaitformultipleevents.c index 33f8d65c7..115d9615e 100644 --- a/libc/intrin/wsawaitformultipleevents.c +++ b/libc/intrin/wsawaitformultipleevents.c @@ -17,8 +17,8 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/nt/thunk/msabi.h" #include "libc/nt/winsock.h" diff --git a/libc/intrin/xchg.internal.h b/libc/intrin/xchg.h similarity index 100% rename from libc/intrin/xchg.internal.h rename to libc/intrin/xchg.h diff --git a/libc/irq/acpi-xsdt.c b/libc/irq/acpi-xsdt.c index e37f92a3d..94dc50a82 100644 --- a/libc/irq/acpi-xsdt.c +++ b/libc/irq/acpi-xsdt.c @@ -26,7 +26,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/dce.h" #include "libc/intrin/atomic.h" -#include "libc/intrin/directmap.internal.h" +#include "libc/intrin/directmap.h" #include "libc/intrin/kprintf.h" #include "libc/irq/acpi.internal.h" #include "libc/log/color.internal.h" diff --git a/libc/log/attachdebugger.c b/libc/log/attachdebugger.c index 337f6c4e8..6d0238c53 100644 --- a/libc/log/attachdebugger.c +++ b/libc/log/attachdebugger.c @@ -20,7 +20,7 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" #include "libc/fmt/itoa.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/log/color.internal.h" #include "libc/log/gdb.h" #include "libc/log/internal.h" diff --git a/libc/log/backtrace2.c b/libc/log/backtrace2.c index b3eeac606..34be29c7d 100644 --- a/libc/log/backtrace2.c +++ b/libc/log/backtrace2.c @@ -24,10 +24,10 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/itoa.h" -#include "libc/intrin/describebacktrace.internal.h" -#include "libc/intrin/iscall.internal.h" +#include "libc/intrin/describebacktrace.h" +#include "libc/intrin/iscall.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/promises.internal.h" +#include "libc/intrin/promises.h" #include "libc/intrin/weaken.h" #include "libc/log/backtrace.internal.h" #include "libc/log/color.internal.h" diff --git a/libc/log/backtrace3.c b/libc/log/backtrace3.c index 37d0c1462..a49240bce 100644 --- a/libc/log/backtrace3.c +++ b/libc/log/backtrace3.c @@ -20,7 +20,7 @@ #include "libc/calls/calls.h" #include "libc/cosmo.h" #include "libc/fmt/itoa.h" -#include "libc/intrin/iscall.internal.h" +#include "libc/intrin/iscall.h" #include "libc/intrin/kprintf.h" #include "libc/intrin/weaken.h" #include "libc/log/backtrace.internal.h" diff --git a/libc/log/checkfail.c b/libc/log/checkfail.c index f1b0d26eb..51cb08efb 100644 --- a/libc/log/checkfail.c +++ b/libc/log/checkfail.c @@ -19,8 +19,8 @@ #include "libc/calls/calls.h" #include "libc/errno.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/safemacros.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/safemacros.h" +#include "libc/intrin/strace.h" #include "libc/log/check.h" #include "libc/log/color.internal.h" #include "libc/log/internal.h" diff --git a/libc/log/commandvenv.c b/libc/log/commandvenv.c index e028d89db..f0e2430fc 100644 --- a/libc/log/commandvenv.c +++ b/libc/log/commandvenv.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/limits.h" #include "libc/log/log.h" #include "libc/mem/mem.h" diff --git a/libc/log/cxaprintexits.c b/libc/log/cxaprintexits.c index a7be1130c..2264a6bbe 100644 --- a/libc/log/cxaprintexits.c +++ b/libc/log/cxaprintexits.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/intrin/bsf.h" -#include "libc/intrin/cxaatexit.internal.h" +#include "libc/intrin/cxaatexit.h" #include "libc/log/log.h" #include "libc/runtime/runtime.h" #include "libc/stdio/stdio.h" diff --git a/libc/log/die.c b/libc/log/die.c index 30458102c..15f86e8e6 100644 --- a/libc/log/die.c +++ b/libc/log/die.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" #include "libc/errno.h" -#include "libc/intrin/describebacktrace.internal.h" +#include "libc/intrin/describebacktrace.h" #include "libc/intrin/kprintf.h" #include "libc/log/backtrace.internal.h" #include "libc/log/internal.h" diff --git a/libc/log/gdbexec.c b/libc/log/gdbexec.c index 0d63a9682..a29bc4f98 100644 --- a/libc/log/gdbexec.c +++ b/libc/log/gdbexec.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/log/gdb.h" #include "libc/log/log.h" #include "libc/nexgen32e/stackframe.h" diff --git a/libc/log/minicrash.c b/libc/log/minicrash.c index 6a02251ca..7197b8ce9 100644 --- a/libc/log/minicrash.c +++ b/libc/log/minicrash.c @@ -21,7 +21,7 @@ #include "libc/calls/struct/ucontext.internal.h" #include "libc/calls/ucontext.h" #include "libc/errno.h" -#include "libc/intrin/describebacktrace.internal.h" +#include "libc/intrin/describebacktrace.h" #include "libc/intrin/kprintf.h" #include "libc/log/internal.h" #include "libc/log/log.h" diff --git a/libc/log/oncrash_amd64.c b/libc/log/oncrash_amd64.c index f9df5f99b..e55cfa7e5 100644 --- a/libc/log/oncrash_amd64.c +++ b/libc/log/oncrash_amd64.c @@ -32,10 +32,10 @@ #include "libc/errno.h" #include "libc/fmt/itoa.h" #include "libc/intrin/atomic.h" -#include "libc/intrin/describebacktrace.internal.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describebacktrace.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/log/backtrace.internal.h" #include "libc/log/gdb.h" diff --git a/libc/log/oncrash_arm64.c b/libc/log/oncrash_arm64.c index 0e6530018..83a347a75 100644 --- a/libc/log/oncrash_arm64.c +++ b/libc/log/oncrash_arm64.c @@ -36,8 +36,8 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/atomic.h" -#include "libc/intrin/describebacktrace.internal.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describebacktrace.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/kprintf.h" #include "libc/log/internal.h" #include "libc/log/log.h" diff --git a/libc/log/printwindowsmemory.c b/libc/log/printwindowsmemory.c index 9ec34dd57..ed9a4a145 100644 --- a/libc/log/printwindowsmemory.c +++ b/libc/log/printwindowsmemory.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/fmt/conv.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/kprintf.h" #include "libc/log/log.h" #include "libc/macros.internal.h" diff --git a/libc/log/startfatal.c b/libc/log/startfatal.c index 197c61659..7b1bc54d8 100644 --- a/libc/log/startfatal.c +++ b/libc/log/startfatal.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/errno.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/log/internal.h" #include "libc/thread/thread.h" diff --git a/libc/log/vflogf.c b/libc/log/vflogf.c index f90b118e3..53eed5421 100644 --- a/libc/log/vflogf.c +++ b/libc/log/vflogf.c @@ -25,8 +25,8 @@ #include "libc/errno.h" #include "libc/fmt/conv.h" #include "libc/fmt/libgen.h" -#include "libc/intrin/safemacros.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/safemacros.h" +#include "libc/intrin/strace.h" #include "libc/log/internal.h" #include "libc/log/log.h" #include "libc/math.h" diff --git a/libc/mem/leaks.c b/libc/mem/leaks.c index be64764aa..570124226 100644 --- a/libc/mem/leaks.c +++ b/libc/mem/leaks.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/cxxabi.h" -#include "libc/intrin/cxaatexit.internal.h" +#include "libc/intrin/cxaatexit.h" #include "libc/intrin/dll.h" #include "libc/intrin/kprintf.h" #include "libc/intrin/weaken.h" diff --git a/libc/mem/putenv.c b/libc/mem/putenv.c index 3482f8b99..9a096673c 100644 --- a/libc/mem/putenv.c +++ b/libc/mem/putenv.c @@ -16,8 +16,8 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/getenv.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/getenv.h" +#include "libc/intrin/strace.h" #include "libc/macros.internal.h" #include "libc/mem/internal.h" #include "libc/mem/leaks.h" diff --git a/libc/mem/realpath.c b/libc/mem/realpath.c index 966921565..f74a16e05 100644 --- a/libc/mem/realpath.c +++ b/libc/mem/realpath.c @@ -29,7 +29,7 @@ #include "libc/calls/calls.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/limits.h" #include "libc/log/backtrace.internal.h" #include "libc/mem/mem.h" diff --git a/libc/mem/reverse.internal.h b/libc/mem/reverse.internal.h index 07861b0ee..cc26e6e11 100644 --- a/libc/mem/reverse.internal.h +++ b/libc/mem/reverse.internal.h @@ -1,6 +1,6 @@ #ifndef COSMOPOLITAN_LIBC_ALG_REVERSE_H_ #define COSMOPOLITAN_LIBC_ALG_REVERSE_H_ -#include "libc/intrin/xchg.internal.h" +#include "libc/intrin/xchg.h" /** * Reverses array. diff --git a/libc/mem/setenv.c b/libc/mem/setenv.c index 10135428b..971e328ec 100644 --- a/libc/mem/setenv.c +++ b/libc/mem/setenv.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/mem/internal.h" #include "libc/mem/leaks.h" #include "libc/mem/mem.h" diff --git a/libc/mem/shuffle.internal.h b/libc/mem/shuffle.internal.h index 229cc91b6..2b543a89d 100644 --- a/libc/mem/shuffle.internal.h +++ b/libc/mem/shuffle.internal.h @@ -1,6 +1,6 @@ #ifndef COSMOPOLITAN_LIBC_RAND_SHUFFLE_H_ #define COSMOPOLITAN_LIBC_RAND_SHUFFLE_H_ -#include "libc/intrin/xchg.internal.h" +#include "libc/intrin/xchg.h" /** * Fisher-Yates shuffle. diff --git a/libc/proc/cocmd.c b/libc/proc/cocmd.c index 59aba86cc..7babef174 100644 --- a/libc/proc/cocmd.c +++ b/libc/proc/cocmd.c @@ -25,7 +25,7 @@ #include "libc/fmt/conv.h" #include "libc/fmt/itoa.h" #include "libc/fmt/magnumstrs.internal.h" -#include "libc/intrin/getenv.internal.h" +#include "libc/intrin/getenv.h" #include "libc/intrin/weaken.h" #include "libc/limits.h" #include "libc/macros.internal.h" diff --git a/libc/proc/describefds.c b/libc/proc/describefds.c index 71d36c17f..d2cee918c 100644 --- a/libc/proc/describefds.c +++ b/libc/proc/describefds.c @@ -17,10 +17,10 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/assert.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/syscall_support-nt.internal.h" #include "libc/fmt/itoa.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/mem/mem.h" #include "libc/nt/files.h" #include "libc/nt/runtime.h" diff --git a/libc/proc/describefds.internal.h b/libc/proc/describefds.internal.h index 437fabdf7..dd192630a 100644 --- a/libc/proc/describefds.internal.h +++ b/libc/proc/describefds.internal.h @@ -1,6 +1,6 @@ #ifndef COSMOPOLITAN_LIBC_PROC_DESCRIBEFDS_INTERNAL_H_ #define COSMOPOLITAN_LIBC_PROC_DESCRIBEFDS_INTERNAL_H_ -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/nt/struct/startupinfo.h" COSMOPOLITAN_C_START_ diff --git a/libc/proc/execve-nt.greg.c b/libc/proc/execve-nt.greg.c index 03d8590c1..607ac1623 100644 --- a/libc/proc/execve-nt.greg.c +++ b/libc/proc/execve-nt.greg.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/assert.h" #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/sigset.internal.h" #include "libc/calls/syscall-nt.internal.h" #include "libc/errno.h" diff --git a/libc/proc/execve-sysv.c b/libc/proc/execve-sysv.c index 93c22f8c0..e0dbc53b1 100644 --- a/libc/proc/execve-sysv.c +++ b/libc/proc/execve-sysv.c @@ -27,9 +27,9 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/magnumstrs.internal.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/safemacros.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/safemacros.h" +#include "libc/intrin/strace.h" #include "libc/limits.h" #include "libc/mem/alloca.h" #include "libc/paths.h" diff --git a/libc/proc/execve.c b/libc/proc/execve.c index 2fde8ee9b..781bd3f26 100644 --- a/libc/proc/execve.c +++ b/libc/proc/execve.c @@ -22,10 +22,10 @@ #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/likely.h" -#include "libc/intrin/promises.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/promises.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/log/libfatal.internal.h" #include "libc/runtime/runtime.h" diff --git a/libc/proc/fexecve.c b/libc/proc/fexecve.c index 9ed672c8d..762865acf 100644 --- a/libc/proc/fexecve.c +++ b/libc/proc/fexecve.c @@ -27,10 +27,10 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/itoa.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/safemacros.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/safemacros.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/limits.h" #include "libc/proc/execve.internal.h" diff --git a/libc/proc/fork-nt.c b/libc/proc/fork-nt.c index 0c670b9c0..201c08595 100644 --- a/libc/proc/fork-nt.c +++ b/libc/proc/fork-nt.c @@ -26,10 +26,10 @@ #include "libc/errno.h" #include "libc/fmt/itoa.h" #include "libc/intrin/atomic.h" -#include "libc/intrin/directmap.internal.h" +#include "libc/intrin/directmap.h" #include "libc/intrin/kprintf.h" #include "libc/intrin/maps.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/tree.h" #include "libc/intrin/weaken.h" #include "libc/macros.internal.h" diff --git a/libc/proc/fork.c b/libc/proc/fork.c index f1f138231..bc7bfbf2b 100644 --- a/libc/proc/fork.c +++ b/libc/proc/fork.c @@ -30,7 +30,7 @@ #include "libc/intrin/dll.h" #include "libc/intrin/kprintf.h" #include "libc/intrin/maps.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/nt/files.h" #include "libc/nt/process.h" diff --git a/libc/proc/getpriority-nt.c b/libc/proc/getpriority-nt.c index 8cfbcc1fe..67d84363c 100644 --- a/libc/proc/getpriority-nt.c +++ b/libc/proc/getpriority-nt.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall-nt.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nt/enum/processcreationflags.h" #include "libc/nt/errors.h" #include "libc/nt/process.h" diff --git a/libc/proc/getpriority.c b/libc/proc/getpriority.c index b66cbc26a..fcaa7b756 100644 --- a/libc/proc/getpriority.c +++ b/libc/proc/getpriority.c @@ -22,8 +22,8 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/asmflag.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/limits.h" #include "libc/sysv/errfuns.h" diff --git a/libc/proc/getrusage.c b/libc/proc/getrusage.c index 95d385a50..be0cec92d 100644 --- a/libc/proc/getrusage.c +++ b/libc/proc/getrusage.c @@ -20,7 +20,7 @@ #include "libc/calls/struct/rusage.h" #include "libc/calls/struct/rusage.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sysv/errfuns.h" /** diff --git a/libc/proc/kill-nt.c b/libc/proc/kill-nt.c index 0a60bf350..afe759dcc 100644 --- a/libc/proc/kill-nt.c +++ b/libc/proc/kill-nt.c @@ -21,7 +21,7 @@ #include "libc/calls/syscall-nt.internal.h" #include "libc/errno.h" #include "libc/intrin/dll.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nt/console.h" #include "libc/nt/enum/ctrlevent.h" #include "libc/nt/enum/processaccess.h" diff --git a/libc/proc/kill.c b/libc/proc/kill.c index 34342add9..9c0e99a6e 100644 --- a/libc/proc/kill.c +++ b/libc/proc/kill.c @@ -20,7 +20,7 @@ #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/str/str.h" /** diff --git a/libc/proc/posix_spawn.c b/libc/proc/posix_spawn.c index 967392ad8..a7209abac 100644 --- a/libc/proc/posix_spawn.c +++ b/libc/proc/posix_spawn.c @@ -22,7 +22,7 @@ #include "libc/calls/calls.h" #include "libc/calls/internal.h" #include "libc/calls/state.internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/rlimit.h" #include "libc/calls/struct/rlimit.internal.h" #include "libc/calls/struct/rusage.internal.h" @@ -37,9 +37,9 @@ #include "libc/fmt/magnumstrs.internal.h" #include "libc/intrin/atomic.h" #include "libc/intrin/bsf.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/dll.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/mem/alloca.h" #include "libc/mem/mem.h" diff --git a/libc/proc/proc.c b/libc/proc/proc.c index e43262ce8..d147135b3 100644 --- a/libc/proc/proc.c +++ b/libc/proc/proc.c @@ -27,7 +27,7 @@ #include "libc/errno.h" #include "libc/fmt/wintime.internal.h" #include "libc/intrin/dll.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/mem/leaks.h" #include "libc/mem/mem.h" diff --git a/libc/proc/sched_getaffinity.c b/libc/proc/sched_getaffinity.c index 095e28c3b..5bddf33bf 100644 --- a/libc/proc/sched_getaffinity.c +++ b/libc/proc/sched_getaffinity.c @@ -20,7 +20,7 @@ #include "libc/calls/struct/cpuset.h" #include "libc/calls/syscall_support-nt.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nt/errors.h" #include "libc/nt/process.h" #include "libc/nt/runtime.h" diff --git a/libc/proc/sched_setaffinity.c b/libc/proc/sched_setaffinity.c index c7c43fefa..5e494ee98 100644 --- a/libc/proc/sched_setaffinity.c +++ b/libc/proc/sched_setaffinity.c @@ -20,7 +20,7 @@ #include "libc/calls/struct/cpuset.h" #include "libc/calls/syscall_support-nt.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nt/errors.h" #include "libc/nt/process.h" #include "libc/nt/runtime.h" diff --git a/libc/proc/setpriority-nt.c b/libc/proc/setpriority-nt.c index fc3f2fb09..837bd8743 100644 --- a/libc/proc/setpriority-nt.c +++ b/libc/proc/setpriority-nt.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nt/enum/processcreationflags.h" #include "libc/nt/errors.h" #include "libc/nt/process.h" diff --git a/libc/proc/setpriority.c b/libc/proc/setpriority.c index 07845826a..4b09a631c 100644 --- a/libc/proc/setpriority.c +++ b/libc/proc/setpriority.c @@ -20,8 +20,8 @@ #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" /** * Sets nice value of thing. diff --git a/libc/proc/vfork.S b/libc/proc/vfork.S index 482d3b23a..39d7ae6e2 100644 --- a/libc/proc/vfork.S +++ b/libc/proc/vfork.S @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/thread/tls.h" #include "libc/macros.internal.h" diff --git a/libc/proc/wait4-nt.c b/libc/proc/wait4-nt.c index d1f2bc396..5f4a4f9d4 100644 --- a/libc/proc/wait4-nt.c +++ b/libc/proc/wait4-nt.c @@ -21,7 +21,7 @@ #include "libc/calls/struct/sigset.h" #include "libc/calls/struct/sigset.internal.h" #include "libc/intrin/dll.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/nt/enum/wait.h" #include "libc/nt/events.h" diff --git a/libc/proc/wait4.c b/libc/proc/wait4.c index 7d6056aff..056e9b371 100644 --- a/libc/proc/wait4.c +++ b/libc/proc/wait4.c @@ -20,7 +20,7 @@ #include "libc/calls/cp.internal.h" #include "libc/calls/struct/rusage.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/proc/proc.internal.h" #include "libc/sysv/errfuns.h" diff --git a/libc/runtime/clone.c b/libc/runtime/clone.c index be9b73488..46347d47b 100644 --- a/libc/runtime/clone.c +++ b/libc/runtime/clone.c @@ -28,7 +28,7 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/atomic.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/ulock.h" #include "libc/intrin/weaken.h" #include "libc/limits.h" diff --git a/libc/runtime/cosmo.S b/libc/runtime/cosmo.S index fcaa2376e..eccd05cfa 100644 --- a/libc/runtime/cosmo.S +++ b/libc/runtime/cosmo.S @@ -19,7 +19,7 @@ #include "libc/macros.internal.h" #include "libc/sysv/consts/prot.h" #include "libc/sysv/consts/map.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sysv/consts/map.h" #include "libc/dce.h" #ifdef __x86_64__ diff --git a/libc/runtime/cosmo2.c b/libc/runtime/cosmo2.c index e102b8fee..ccd926192 100644 --- a/libc/runtime/cosmo2.c +++ b/libc/runtime/cosmo2.c @@ -22,7 +22,7 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/maps.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/limits.h" #include "libc/macros.internal.h" #include "libc/nexgen32e/rdtsc.h" diff --git a/libc/runtime/cxa_thread_atexit.c b/libc/runtime/cxa_thread_atexit.c index 143727024..4e8a2efff 100644 --- a/libc/runtime/cxa_thread_atexit.c +++ b/libc/runtime/cxa_thread_atexit.c @@ -16,8 +16,8 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/cxaatexit.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/cxaatexit.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/mem/mem.h" #include "libc/nexgen32e/gc.internal.h" diff --git a/libc/runtime/enable_tls.c b/libc/runtime/enable_tls.c index 92807978e..580450ef2 100644 --- a/libc/runtime/enable_tls.c +++ b/libc/runtime/enable_tls.c @@ -22,7 +22,7 @@ #include "libc/errno.h" #include "libc/intrin/atomic.h" #include "libc/intrin/dll.h" -#include "libc/intrin/getenv.internal.h" +#include "libc/intrin/getenv.h" #include "libc/intrin/kprintf.h" #include "libc/intrin/maps.h" #include "libc/intrin/weaken.h" diff --git a/libc/runtime/exit.c b/libc/runtime/exit.c index 33456c7fe..6320d4323 100644 --- a/libc/runtime/exit.c +++ b/libc/runtime/exit.c @@ -17,8 +17,8 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/cxxabi.h" -#include "libc/intrin/cxaatexit.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/cxaatexit.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/runtime/internal.h" diff --git a/libc/runtime/getlogin.c b/libc/runtime/getlogin.c index a62748cfa..73b8dec59 100644 --- a/libc/runtime/getlogin.c +++ b/libc/runtime/getlogin.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall_support-nt.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/macros.internal.h" #include "libc/nt/accounting.h" #include "libc/runtime/runtime.h" diff --git a/libc/runtime/getlogin_r.c b/libc/runtime/getlogin_r.c index 197929644..4b2311b07 100644 --- a/libc/runtime/getlogin_r.c +++ b/libc/runtime/getlogin_r.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/syscall_support-nt.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/macros.internal.h" #include "libc/nt/accounting.h" #include "libc/runtime/runtime.h" diff --git a/libc/runtime/getsymboltable.c b/libc/runtime/getsymboltable.c index 0c8fad9d6..90dcb169f 100644 --- a/libc/runtime/getsymboltable.c +++ b/libc/runtime/getsymboltable.c @@ -18,8 +18,8 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/assert.h" #include "libc/errno.h" -#include "libc/intrin/promises.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/promises.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/macros.internal.h" #include "libc/runtime/internal.h" diff --git a/libc/runtime/inflate.c b/libc/runtime/inflate.c index 9a52edce3..c7a82fa0b 100644 --- a/libc/runtime/inflate.c +++ b/libc/runtime/inflate.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/macros.internal.h" #include "libc/runtime/internal.h" diff --git a/libc/runtime/login_tty.c b/libc/runtime/login_tty.c index 14679663f..0a80916d8 100644 --- a/libc/runtime/login_tty.c +++ b/libc/runtime/login_tty.c @@ -21,7 +21,7 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/runtime/runtime.h" #include "libc/runtime/utmp.h" #include "libc/sysv/consts/termios.h" diff --git a/libc/runtime/opensymboltable.greg.c b/libc/runtime/opensymboltable.greg.c index 7cd2c8d7a..2a54eb7b6 100644 --- a/libc/runtime/opensymboltable.greg.c +++ b/libc/runtime/opensymboltable.greg.c @@ -22,7 +22,7 @@ #include "libc/dce.h" #include "libc/elf/tinyelf.internal.h" #include "libc/errno.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/limits.h" #include "libc/log/libfatal.internal.h" #include "libc/macros.internal.h" diff --git a/libc/runtime/straceinit.greg.c b/libc/runtime/straceinit.greg.c index ba2084888..151e3449a 100644 --- a/libc/runtime/straceinit.greg.c +++ b/libc/runtime/straceinit.greg.c @@ -16,8 +16,8 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/getenv.internal.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/getenv.h" +#include "libc/intrin/safemacros.h" #include "libc/log/libfatal.internal.h" #include "libc/runtime/internal.h" #include "libc/runtime/runtime.h" diff --git a/libc/runtime/winmain.greg.c b/libc/runtime/winmain.greg.c index 9dda29289..77ebd63c2 100644 --- a/libc/runtime/winmain.greg.c +++ b/libc/runtime/winmain.greg.c @@ -22,7 +22,7 @@ #include "libc/calls/syscall_support-nt.internal.h" #include "libc/intrin/dll.h" #include "libc/intrin/maps.h" -#include "libc/intrin/nomultics.internal.h" +#include "libc/intrin/nomultics.h" #include "libc/intrin/weaken.h" #include "libc/limits.h" #include "libc/macros.internal.h" diff --git a/libc/runtime/zipos-get.c b/libc/runtime/zipos-get.c index e2067a400..e3615c5f4 100644 --- a/libc/runtime/zipos-get.c +++ b/libc/runtime/zipos-get.c @@ -23,8 +23,8 @@ #include "libc/cosmo.h" #include "libc/fmt/conv.h" #include "libc/intrin/cmpxchg.h" -#include "libc/intrin/promises.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/promises.h" +#include "libc/intrin/strace.h" #include "libc/macros.internal.h" #include "libc/mem/alg.h" #include "libc/runtime/runtime.h" diff --git a/libc/runtime/zipos-mmap.c b/libc/runtime/zipos-mmap.c index ae3559494..d2551ed3d 100644 --- a/libc/runtime/zipos-mmap.c +++ b/libc/runtime/zipos-mmap.c @@ -21,7 +21,7 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/maps.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/runtime/internal.h" #include "libc/runtime/runtime.h" #include "libc/runtime/zipos.internal.h" diff --git a/libc/runtime/zipos-open.c b/libc/runtime/zipos-open.c index 5dfda7ea5..46707b179 100644 --- a/libc/runtime/zipos-open.c +++ b/libc/runtime/zipos-open.c @@ -19,7 +19,7 @@ #include "libc/calls/blockcancel.internal.h" #include "libc/calls/internal.h" #include "libc/calls/state.internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/sigset.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/calls/syscall_support-sysv.internal.h" diff --git a/libc/runtime/zipos-stat-impl.c b/libc/runtime/zipos-stat-impl.c index 93109bbc7..ff0a4b316 100644 --- a/libc/runtime/zipos-stat-impl.c +++ b/libc/runtime/zipos-stat-impl.c @@ -19,7 +19,7 @@ #include "libc/calls/internal.h" #include "libc/calls/struct/stat.h" #include "libc/intrin/atomic.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/runtime/runtime.h" #include "libc/runtime/zipos.internal.h" #include "libc/str/str.h" diff --git a/libc/sock/accept-nt.c b/libc/sock/accept-nt.c index 9aa702760..839553624 100644 --- a/libc/sock/accept-nt.c +++ b/libc/sock/accept-nt.c @@ -19,7 +19,7 @@ #include "libc/assert.h" #include "libc/atomic.h" #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/sigset.internal.h" #include "libc/cosmo.h" #include "libc/errno.h" diff --git a/libc/sock/accept4.c b/libc/sock/accept4.c index 5aee5e465..9b44071cc 100644 --- a/libc/sock/accept4.c +++ b/libc/sock/accept4.c @@ -19,7 +19,7 @@ #include "libc/calls/cp.internal.h" #include "libc/calls/internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sock/internal.h" #include "libc/sock/sock.h" #include "libc/sock/struct/sockaddr.h" diff --git a/libc/sock/bind.c b/libc/sock/bind.c index 5ff0ff37b..8401776f9 100644 --- a/libc/sock/bind.c +++ b/libc/sock/bind.c @@ -17,9 +17,9 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sock/internal.h" #include "libc/sock/sock.h" #include "libc/sock/struct/sockaddr.h" diff --git a/libc/sock/connect-nt.c b/libc/sock/connect-nt.c index ce1951452..6fbd14937 100644 --- a/libc/sock/connect-nt.c +++ b/libc/sock/connect-nt.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/assert.h" #include "libc/atomic.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/sigset.internal.h" #include "libc/cosmo.h" #include "libc/errno.h" diff --git a/libc/sock/connect.c b/libc/sock/connect.c index 9453c62d5..5f3fd2d7c 100644 --- a/libc/sock/connect.c +++ b/libc/sock/connect.c @@ -18,9 +18,9 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/cp.internal.h" #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sock/internal.h" #include "libc/sock/sock.h" #include "libc/sock/struct/sockaddr.h" diff --git a/libc/sock/epoll.c b/libc/sock/epoll.c index 1be06e4d5..818ddf19e 100644 --- a/libc/sock/epoll.c +++ b/libc/sock/epoll.c @@ -41,7 +41,7 @@ #include "libc/calls/syscall_support-sysv.internal.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/limits.h" #include "libc/macros.internal.h" #include "libc/mem/mem.h" diff --git a/libc/sock/getsockname.c b/libc/sock/getsockname.c index e04d620ad..b09543f2f 100644 --- a/libc/sock/getsockname.c +++ b/libc/sock/getsockname.c @@ -17,9 +17,9 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nt/errors.h" #include "libc/nt/thunk/msabi.h" #include "libc/nt/winsock.h" diff --git a/libc/sock/getsockopt.c b/libc/sock/getsockopt.c index 3a7106ddd..46957a415 100644 --- a/libc/sock/getsockopt.c +++ b/libc/sock/getsockopt.c @@ -17,10 +17,10 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/sock/internal.h" #include "libc/sock/sock.h" #include "libc/sock/syscall_fd.internal.h" diff --git a/libc/sock/kntwsadata.c b/libc/sock/kntwsadata.c index a3450d88c..2c08015e1 100644 --- a/libc/sock/kntwsadata.c +++ b/libc/sock/kntwsadata.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/mem/mem.h" #include "libc/nt/runtime.h" #include "libc/nt/winsock.h" diff --git a/libc/sock/listen.c b/libc/sock/listen.c index c4c51430d..b1262c51f 100644 --- a/libc/sock/listen.c +++ b/libc/sock/listen.c @@ -17,9 +17,9 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sock/internal.h" #include "libc/sock/sock.h" #include "libc/sock/syscall_fd.internal.h" diff --git a/libc/sock/recv-nt.c b/libc/sock/recv-nt.c index 7ce09a186..1652c113e 100644 --- a/libc/sock/recv-nt.c +++ b/libc/sock/recv-nt.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/iovec.h" #include "libc/calls/struct/sigset.internal.h" #include "libc/nt/struct/iovec.h" diff --git a/libc/sock/recv.c b/libc/sock/recv.c index 26b9a7436..ec85a9b48 100644 --- a/libc/sock/recv.c +++ b/libc/sock/recv.c @@ -20,7 +20,7 @@ #include "libc/calls/internal.h" #include "libc/calls/struct/iovec.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sock/internal.h" #include "libc/sock/sock.h" #include "libc/sock/syscall_fd.internal.h" diff --git a/libc/sock/recvfrom-nt.c b/libc/sock/recvfrom-nt.c index 25d571ad7..69f436d07 100644 --- a/libc/sock/recvfrom-nt.c +++ b/libc/sock/recvfrom-nt.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/iovec.h" #include "libc/calls/struct/sigset.internal.h" #include "libc/nt/struct/iovec.h" diff --git a/libc/sock/recvfrom.c b/libc/sock/recvfrom.c index b015cf2af..d5e7565cf 100644 --- a/libc/sock/recvfrom.c +++ b/libc/sock/recvfrom.c @@ -21,7 +21,7 @@ #include "libc/calls/struct/iovec.h" #include "libc/calls/struct/iovec.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nt/winsock.h" #include "libc/sock/internal.h" #include "libc/sock/sock.h" diff --git a/libc/sock/recvmsg.c b/libc/sock/recvmsg.c index 56f6d4762..c172f74c1 100644 --- a/libc/sock/recvmsg.c +++ b/libc/sock/recvmsg.c @@ -19,13 +19,13 @@ #include "libc/assert.h" #include "libc/calls/cp.internal.h" #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/iovec.h" #include "libc/calls/struct/iovec.internal.h" #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/runtime/runtime.h" #include "libc/sock/sock.h" #include "libc/sock/struct/msghdr.h" diff --git a/libc/sock/send-nt.c b/libc/sock/send-nt.c index a186159b2..63cf646cf 100644 --- a/libc/sock/send-nt.c +++ b/libc/sock/send-nt.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/iovec.h" #include "libc/calls/struct/sigset.internal.h" #include "libc/nt/struct/iovec.h" diff --git a/libc/sock/send.c b/libc/sock/send.c index b66ee698c..4d9df49ad 100644 --- a/libc/sock/send.c +++ b/libc/sock/send.c @@ -21,7 +21,7 @@ #include "libc/calls/struct/iovec.h" #include "libc/calls/struct/iovec.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/macros.internal.h" #include "libc/sock/internal.h" #include "libc/sock/sock.h" diff --git a/libc/sock/sendfile.c b/libc/sock/sendfile.c index f5b107a1b..26d7cef55 100644 --- a/libc/sock/sendfile.c +++ b/libc/sock/sendfile.c @@ -25,8 +25,8 @@ #include "libc/cosmo.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/nt/enum/wsaid.h" #include "libc/nt/errors.h" #include "libc/nt/events.h" diff --git a/libc/sock/sendmsg.c b/libc/sock/sendmsg.c index 1b1e32a1d..197e5fd8c 100644 --- a/libc/sock/sendmsg.c +++ b/libc/sock/sendmsg.c @@ -19,13 +19,13 @@ #include "libc/assert.h" #include "libc/calls/cp.internal.h" #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/iovec.h" #include "libc/calls/struct/iovec.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/runtime/runtime.h" #include "libc/sock/internal.h" #include "libc/sock/sock.h" diff --git a/libc/sock/sendto-nt.c b/libc/sock/sendto-nt.c index e6fdb1f17..2daf9badc 100644 --- a/libc/sock/sendto-nt.c +++ b/libc/sock/sendto-nt.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/iovec.h" #include "libc/calls/struct/sigset.internal.h" #include "libc/nt/struct/iovec.h" diff --git a/libc/sock/sendto.c b/libc/sock/sendto.c index 61638e132..803e48fa0 100644 --- a/libc/sock/sendto.c +++ b/libc/sock/sendto.c @@ -22,7 +22,7 @@ #include "libc/calls/struct/iovec.h" #include "libc/calls/struct/iovec.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/macros.internal.h" #include "libc/sock/internal.h" #include "libc/sock/sock.h" diff --git a/libc/sock/setsockopt-nt.c b/libc/sock/setsockopt-nt.c index c6a79b57a..f9e7a6a4d 100644 --- a/libc/sock/setsockopt-nt.c +++ b/libc/sock/setsockopt-nt.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/timeval.h" #include "libc/nt/struct/linger.h" #include "libc/nt/thunk/msabi.h" diff --git a/libc/sock/setsockopt.c b/libc/sock/setsockopt.c index c7c204eb9..5b4db5661 100644 --- a/libc/sock/setsockopt.c +++ b/libc/sock/setsockopt.c @@ -17,11 +17,11 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/nt/winsock.h" #include "libc/sock/internal.h" #include "libc/sock/sock.h" diff --git a/libc/sock/shutdown.c b/libc/sock/shutdown.c index bcf816928..1ec433181 100644 --- a/libc/sock/shutdown.c +++ b/libc/sock/shutdown.c @@ -17,9 +17,9 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sock/internal.h" #include "libc/sock/sock.h" #include "libc/sock/syscall_fd.internal.h" diff --git a/libc/sock/sockatmark.c b/libc/sock/sockatmark.c index 767305d7b..be6ed7696 100644 --- a/libc/sock/sockatmark.c +++ b/libc/sock/sockatmark.c @@ -17,10 +17,10 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nt/winsock.h" #include "libc/sock/internal.h" #include "libc/sock/sock.h" diff --git a/libc/sock/sockdebug.c b/libc/sock/sockdebug.c index 89e029fba..fd98aeb30 100644 --- a/libc/sock/sockdebug.c +++ b/libc/sock/sockdebug.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/errno.h" #include "libc/fmt/itoa.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/macros.internal.h" #include "libc/sock/sock.h" #include "libc/sock/struct/sockaddr.h" diff --git a/libc/sock/socket.c b/libc/sock/socket.c index 23f8de2e3..61b6463ac 100644 --- a/libc/sock/socket.c +++ b/libc/sock/socket.c @@ -17,8 +17,8 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/sock/internal.h" #include "libc/sock/sock.h" #include "libc/sysv/consts/af.h" diff --git a/libc/sock/syscall_fd.internal.h b/libc/sock/syscall_fd.internal.h index ef898b72e..1c51d00ff 100644 --- a/libc/sock/syscall_fd.internal.h +++ b/libc/sock/syscall_fd.internal.h @@ -1,6 +1,6 @@ #ifndef COSMOPOLITAN_LIBC_SOCK_SYSCALL_INTERNAL_H_ #define COSMOPOLITAN_LIBC_SOCK_SYSCALL_INTERNAL_H_ -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/iovec.h" #include "libc/nt/struct/overlapped.h" #include "libc/sock/struct/sockaddr.h" diff --git a/libc/sock/syslog.c b/libc/sock/syslog.c index c0ac9caf5..8c5840016 100644 --- a/libc/sock/syslog.c +++ b/libc/sock/syslog.c @@ -23,7 +23,7 @@ #include "libc/calls/weirdtypes.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/log/internal.h" #include "libc/macros.internal.h" #include "libc/nt/events.h" diff --git a/libc/stdio/dirstream.c b/libc/stdio/dirstream.c index 2f080fabe..215eb9093 100644 --- a/libc/stdio/dirstream.c +++ b/libc/stdio/dirstream.c @@ -26,7 +26,7 @@ #include "libc/calls/syscall_support-nt.internal.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/limits.h" #include "libc/macros.internal.h" diff --git a/libc/stdio/fflush_unlocked.c b/libc/stdio/fflush_unlocked.c index 579bc3676..49099d7e7 100644 --- a/libc/stdio/fflush_unlocked.c +++ b/libc/stdio/fflush_unlocked.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/cxxabi.h" -#include "libc/intrin/pushpop.internal.h" +#include "libc/intrin/pushpop.h" #include "libc/mem/arraylist.internal.h" #include "libc/stdio/fflush.internal.h" #include "libc/stdio/internal.h" diff --git a/libc/stdio/fmt.c b/libc/stdio/fmt.c index b8c31bc63..cafe4f63e 100644 --- a/libc/stdio/fmt.c +++ b/libc/stdio/fmt.c @@ -44,8 +44,8 @@ #include "libc/fmt/divmod10.internal.h" #include "libc/fmt/itoa.h" #include "libc/intrin/bsr.h" -#include "libc/intrin/nomultics.internal.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/nomultics.h" +#include "libc/intrin/safemacros.h" #include "libc/limits.h" #include "libc/macros.internal.h" #include "libc/math.h" diff --git a/libc/stdio/fread.c b/libc/stdio/fread.c index 5c47656cb..22bf3d2f5 100644 --- a/libc/stdio/fread.c +++ b/libc/stdio/fread.c @@ -16,8 +16,8 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/runtime/runtime.h" #include "libc/stdio/internal.h" diff --git a/libc/stdio/fseek.c b/libc/stdio/fseek.c index 49235a912..d8a549ac5 100644 --- a/libc/stdio/fseek.c +++ b/libc/stdio/fseek.c @@ -16,8 +16,8 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/stdio/internal.h" /** diff --git a/libc/stdio/fwrite.c b/libc/stdio/fwrite.c index 11d2445ae..41d7141d9 100644 --- a/libc/stdio/fwrite.c +++ b/libc/stdio/fwrite.c @@ -16,8 +16,8 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/stdio/internal.h" /** diff --git a/libc/stdio/getentropy.c b/libc/stdio/getentropy.c index c9cebf50b..45b5b918e 100644 --- a/libc/stdio/getentropy.c +++ b/libc/stdio/getentropy.c @@ -20,7 +20,7 @@ #include "libc/calls/struct/sigset.internal.h" #include "libc/calls/syscall_support-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/stdio/rand.h" #include "libc/sysv/errfuns.h" diff --git a/libc/stdio/printargs.c b/libc/stdio/printargs.c index 5d2a61c2f..3e2ba0bb7 100644 --- a/libc/stdio/printargs.c +++ b/libc/stdio/printargs.c @@ -27,10 +27,10 @@ #include "libc/calls/ttydefaults.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/promises.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/promises.h" +#include "libc/intrin/strace.h" #include "libc/limits.h" #include "libc/macros.internal.h" #include "libc/nexgen32e/cpuid4.internal.h" diff --git a/libc/stdio/scanf.c b/libc/stdio/scanf.c index 34f62f620..3afb23cad 100644 --- a/libc/stdio/scanf.c +++ b/libc/stdio/scanf.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/fmt/internal.h" #include "libc/stdio/stdio.h" diff --git a/libc/str/intsort.c b/libc/str/intsort.c index 335b7f98d..2b71b1c41 100644 --- a/libc/str/intsort.c +++ b/libc/str/intsort.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/runtime/runtime.h" static inline void InsertionSort(int *A, long n) { diff --git a/libc/str/longsort.c b/libc/str/longsort.c index 5ed1911cf..e5d091f7f 100644 --- a/libc/str/longsort.c +++ b/libc/str/longsort.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/runtime/runtime.h" static inline void InsertionSort(long *A, long n) { diff --git a/libc/str/lz4cpy.c b/libc/str/lz4cpy.c index 832501510..125114985 100644 --- a/libc/str/lz4cpy.c +++ b/libc/str/lz4cpy.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/pushpop.internal.h" +#include "libc/intrin/pushpop.h" #include "libc/intrin/repmovsb.h" #include "libc/nexgen32e/kompressor.h" #include "libc/serialize.h" diff --git a/libc/str/lz4len.c b/libc/str/lz4len.c index 8dd0fcf04..3b4147794 100644 --- a/libc/str/lz4len.c +++ b/libc/str/lz4len.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/pushpop.internal.h" +#include "libc/intrin/pushpop.h" #include "libc/nexgen32e/kompressor.h" #include "libc/str/str.h" diff --git a/libc/str/setlocale.c b/libc/str/setlocale.c index 409e97590..9e4ecbeed 100644 --- a/libc/str/setlocale.c +++ b/libc/str/setlocale.c @@ -16,8 +16,8 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/safemacros.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/safemacros.h" +#include "libc/intrin/strace.h" #include "libc/str/locale.h" #include "libc/str/str.h" diff --git a/libc/str/strnwidth16.c b/libc/str/strnwidth16.c index c07f5144d..afc854bc9 100644 --- a/libc/str/strnwidth16.c +++ b/libc/str/strnwidth16.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/str/str.h" #include "libc/str/unicode.h" #include "libc/str/utf16.h" diff --git a/libc/str/strwidth16.c b/libc/str/strwidth16.c index ddcab3bad..b2a2355d1 100644 --- a/libc/str/strwidth16.c +++ b/libc/str/strwidth16.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/limits.h" #include "libc/str/strwidth.h" diff --git a/libc/testlib/ezbenchreport.c b/libc/testlib/ezbenchreport.c index 04ad5facd..3af989847 100644 --- a/libc/testlib/ezbenchreport.c +++ b/libc/testlib/ezbenchreport.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/intrin/kprintf.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/math.h" #include "libc/runtime/runtime.h" diff --git a/libc/testlib/showerror.c b/libc/testlib/showerror.c index 713afbb67..2197956ca 100644 --- a/libc/testlib/showerror.c +++ b/libc/testlib/showerror.c @@ -23,7 +23,7 @@ #include "libc/fmt/itoa.h" #include "libc/intrin/atomic.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/intrin/weaken.h" #include "libc/log/color.internal.h" #include "libc/log/internal.h" diff --git a/libc/testlib/testmain.c b/libc/testlib/testmain.c index 78cacd2a4..bd6093851 100644 --- a/libc/testlib/testmain.c +++ b/libc/testlib/testmain.c @@ -26,9 +26,9 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/dll.h" -#include "libc/intrin/getenv.internal.h" -#include "libc/intrin/safemacros.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/getenv.h" +#include "libc/intrin/safemacros.h" +#include "libc/intrin/strace.h" #include "libc/intrin/ubsan.h" #include "libc/intrin/weaken.h" #include "libc/log/log.h" diff --git a/libc/testlib/testrunner.c b/libc/testlib/testrunner.c index f77738c05..efe4483e2 100644 --- a/libc/testlib/testrunner.c +++ b/libc/testlib/testrunner.c @@ -22,8 +22,8 @@ #include "libc/errno.h" #include "libc/fmt/itoa.h" #include "libc/intrin/dll.h" -#include "libc/intrin/getenv.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/getenv.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/limits.h" #include "libc/macros.internal.h" diff --git a/libc/thread/getitimer.c b/libc/thread/getitimer.c index 4e37b0d40..afa356d18 100644 --- a/libc/thread/getitimer.c +++ b/libc/thread/getitimer.c @@ -20,8 +20,8 @@ #include "libc/calls/struct/itimerval.h" #include "libc/calls/struct/itimerval.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/sysv/errfuns.h" /** diff --git a/libc/thread/itimer.c b/libc/thread/itimer.c index a4b63a0d5..91a55580a 100644 --- a/libc/thread/itimer.c +++ b/libc/thread/itimer.c @@ -24,7 +24,7 @@ #include "libc/calls/struct/sigset.internal.h" #include "libc/calls/struct/timeval.h" #include "libc/cosmo.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nt/enum/processcreationflags.h" #include "libc/nt/thread.h" #include "libc/str/str.h" diff --git a/libc/thread/pthread_cancel.c b/libc/thread/pthread_cancel.c index 14b0ce8b8..5ddbea0db 100644 --- a/libc/thread/pthread_cancel.c +++ b/libc/thread/pthread_cancel.c @@ -29,9 +29,9 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/atomic.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/str/str.h" #include "libc/sysv/consts/sa.h" #include "libc/sysv/consts/sig.h" diff --git a/libc/thread/pthread_create.c b/libc/thread/pthread_create.c index c0933e50a..8be2420c7 100644 --- a/libc/thread/pthread_create.c +++ b/libc/thread/pthread_create.c @@ -25,10 +25,10 @@ #include "libc/errno.h" #include "libc/fmt/itoa.h" #include "libc/intrin/bsr.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/dll.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/log/internal.h" #include "libc/macros.internal.h" diff --git a/libc/thread/pthread_detach.c b/libc/thread/pthread_detach.c index 16557e2f0..2a33b4988 100644 --- a/libc/thread/pthread_detach.c +++ b/libc/thread/pthread_detach.c @@ -19,8 +19,8 @@ #include "libc/assert.h" #include "libc/errno.h" #include "libc/intrin/atomic.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/macros.internal.h" #include "libc/mem/mem.h" #include "libc/thread/posixthread.internal.h" diff --git a/libc/thread/pthread_exit.c b/libc/thread/pthread_exit.c index 0ce26c4d3..7e5c941a1 100644 --- a/libc/thread/pthread_exit.c +++ b/libc/thread/pthread_exit.c @@ -21,8 +21,8 @@ #include "libc/cxxabi.h" #include "libc/dce.h" #include "libc/intrin/atomic.h" -#include "libc/intrin/cxaatexit.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/cxaatexit.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/limits.h" #include "libc/mem/gc.h" diff --git a/libc/thread/pthread_getaffinity_np.c b/libc/thread/pthread_getaffinity_np.c index 1cd9aad31..50cd3e011 100644 --- a/libc/thread/pthread_getaffinity_np.c +++ b/libc/thread/pthread_getaffinity_np.c @@ -21,8 +21,8 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/atomic.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/str/str.h" #include "libc/sysv/errfuns.h" #include "libc/thread/posixthread.internal.h" diff --git a/libc/thread/pthread_kill.c b/libc/thread/pthread_kill.c index c1a1c4fc2..472da205e 100644 --- a/libc/thread/pthread_kill.c +++ b/libc/thread/pthread_kill.c @@ -22,8 +22,8 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/atomic.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/runtime/syslib.internal.h" #include "libc/sysv/consts/sicode.h" #include "libc/thread/posixthread.internal.h" diff --git a/libc/thread/pthread_setaffinity_np.c b/libc/thread/pthread_setaffinity_np.c index 131f03a4d..4c1b3aa46 100644 --- a/libc/thread/pthread_setaffinity_np.c +++ b/libc/thread/pthread_setaffinity_np.c @@ -22,8 +22,8 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/atomic.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/nt/enum/threadaccess.h" #include "libc/nt/runtime.h" #include "libc/nt/thread.h" diff --git a/libc/thread/pthread_setcanceltype.c b/libc/thread/pthread_setcanceltype.c index 48290d5cf..f65187104 100644 --- a/libc/thread/pthread_setcanceltype.c +++ b/libc/thread/pthread_setcanceltype.c @@ -19,8 +19,8 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/itoa.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/mem/alloca.h" #include "libc/thread/posixthread.internal.h" #include "libc/thread/thread.h" diff --git a/libc/thread/pthread_setname_np.c b/libc/thread/pthread_setname_np.c index 9f2894c05..84915ac92 100644 --- a/libc/thread/pthread_setname_np.c +++ b/libc/thread/pthread_setname_np.c @@ -23,8 +23,8 @@ #include "libc/errno.h" #include "libc/fmt/itoa.h" #include "libc/intrin/atomic.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/runtime/syslib.internal.h" #include "libc/str/str.h" #include "libc/sysv/consts/at.h" diff --git a/libc/thread/pthread_timedjoin_np.c b/libc/thread/pthread_timedjoin_np.c index c79428b8d..f814e038a 100644 --- a/libc/thread/pthread_timedjoin_np.c +++ b/libc/thread/pthread_timedjoin_np.c @@ -23,9 +23,9 @@ #include "libc/errno.h" #include "libc/fmt/itoa.h" #include "libc/intrin/atomic.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/dll.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/thread/posixthread.internal.h" #include "libc/thread/thread2.h" #include "libc/thread/tls.h" diff --git a/libc/thread/sem_open.c b/libc/thread/sem_open.c index 41ab6615f..9a3e5b2ce 100644 --- a/libc/thread/sem_open.c +++ b/libc/thread/sem_open.c @@ -24,7 +24,7 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/atomic.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/limits.h" #include "libc/mem/mem.h" #include "libc/runtime/runtime.h" diff --git a/libc/thread/setitimer.c b/libc/thread/setitimer.c index 88d1c7b16..e713258f0 100644 --- a/libc/thread/setitimer.c +++ b/libc/thread/setitimer.c @@ -19,8 +19,8 @@ #include "libc/calls/struct/itimerval.h" #include "libc/calls/struct/itimerval.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/sysv/errfuns.h" #include "libc/time.h" diff --git a/libc/vga/readv-vga.c b/libc/vga/readv-vga.c index 3f746e729..5aaa4562a 100644 --- a/libc/vga/readv-vga.c +++ b/libc/vga/readv-vga.c @@ -24,7 +24,7 @@ β”‚ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR β”‚ β”‚ OTHER DEALINGS IN THE SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/iovec.h" #include "libc/calls/struct/iovec.internal.h" #include "libc/vga/vga.internal.h" diff --git a/libc/vga/tty.greg.c b/libc/vga/tty.greg.c index 4f84a240e..85ce5f74a 100644 --- a/libc/vga/tty.greg.c +++ b/libc/vga/tty.greg.c @@ -18,8 +18,8 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/fmt/bing.internal.h" #include "libc/fmt/itoa.h" -#include "libc/intrin/directmap.internal.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/directmap.h" +#include "libc/intrin/safemacros.h" #include "libc/runtime/pc.internal.h" #include "libc/str/str.h" #include "libc/str/thompike.h" diff --git a/libc/vga/writev-vga.c b/libc/vga/writev-vga.c index 1c6d35e1e..f88e053c2 100644 --- a/libc/vga/writev-vga.c +++ b/libc/vga/writev-vga.c @@ -24,7 +24,7 @@ β”‚ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR β”‚ β”‚ OTHER DEALINGS IN THE SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/calls/struct/iovec.h" #include "libc/calls/struct/iovec.internal.h" #include "libc/dce.h" diff --git a/libc/x/paginate.c b/libc/x/paginate.c index 5b86705d0..a377208bc 100644 --- a/libc/x/paginate.c +++ b/libc/x/paginate.c @@ -19,7 +19,7 @@ #include "libc/calls/calls.h" #include "libc/calls/syscall_support-nt.internal.h" #include "libc/dce.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/limits.h" #include "libc/mem/gc.h" #include "libc/runtime/runtime.h" diff --git a/libc/x/xjoinpaths.c b/libc/x/xjoinpaths.c index ce5281e43..4921d5404 100644 --- a/libc/x/xjoinpaths.c +++ b/libc/x/xjoinpaths.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/str/str.h" #include "libc/x/x.h" diff --git a/net/turfwar/blackholed.c b/net/turfwar/blackholed.c index b21bc04b4..ccbd8a5ef 100644 --- a/net/turfwar/blackholed.c +++ b/net/turfwar/blackholed.c @@ -27,7 +27,7 @@ #include "libc/fmt/conv.h" #include "libc/fmt/itoa.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/mem/mem.h" #include "libc/mem/sortedints.internal.h" #include "libc/runtime/runtime.h" diff --git a/net/turfwar/turfwar.c b/net/turfwar/turfwar.c index 5d9d2c768..41a37df79 100644 --- a/net/turfwar/turfwar.c +++ b/net/turfwar/turfwar.c @@ -35,7 +35,7 @@ #include "libc/intrin/bsr.h" #include "libc/intrin/hilbert.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/log/check.h" #include "libc/log/log.h" #include "libc/macros.internal.h" diff --git a/test/libc/calls/clock_nanosleep_test.c b/test/libc/calls/clock_nanosleep_test.c index 805dfacee..02ab5cdaa 100644 --- a/test/libc/calls/clock_nanosleep_test.c +++ b/test/libc/calls/clock_nanosleep_test.c @@ -22,8 +22,8 @@ #include "libc/calls/struct/timespec.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/runtime/runtime.h" #include "libc/sysv/consts/clock.h" #include "libc/sysv/consts/itimer.h" diff --git a/test/libc/calls/commandv_test.c b/test/libc/calls/commandv_test.c index a86aaa43c..f2681cd4c 100644 --- a/test/libc/calls/commandv_test.c +++ b/test/libc/calls/commandv_test.c @@ -19,7 +19,7 @@ #include "libc/calls/calls.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/limits.h" #include "libc/mem/mem.h" #include "libc/runtime/runtime.h" diff --git a/test/libc/calls/devfd_test.c b/test/libc/calls/devfd_test.c index c5aec28a3..b2803cd61 100644 --- a/test/libc/calls/devfd_test.c +++ b/test/libc/calls/devfd_test.c @@ -19,7 +19,7 @@ #include "libc/calls/calls.h" #include "libc/calls/struct/stat.h" #include "libc/dce.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/str/str.h" #include "libc/sysv/consts/o.h" #include "libc/testlib/testlib.h" diff --git a/test/libc/calls/ftruncate_test.c b/test/libc/calls/ftruncate_test.c index 6d740f818..6c910df7e 100644 --- a/test/libc/calls/ftruncate_test.c +++ b/test/libc/calls/ftruncate_test.c @@ -21,7 +21,7 @@ #include "libc/calls/struct/stat.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/limits.h" #include "libc/mem/gc.h" #include "libc/nexgen32e/vendor.internal.h" diff --git a/test/libc/calls/pledge2_test.c b/test/libc/calls/pledge2_test.c index e5d16dbea..17777975a 100644 --- a/test/libc/calls/pledge2_test.c +++ b/test/libc/calls/pledge2_test.c @@ -22,7 +22,7 @@ #include "libc/calls/syscall_support-sysv.internal.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/promises.internal.h" +#include "libc/intrin/promises.h" #include "libc/runtime/runtime.h" #include "libc/sock/sock.h" #include "libc/stdio/stdio.h" diff --git a/test/libc/calls/setrlimit_test.c b/test/libc/calls/setrlimit_test.c index 041d6f606..7f840519d 100644 --- a/test/libc/calls/setrlimit_test.c +++ b/test/libc/calls/setrlimit_test.c @@ -22,8 +22,8 @@ #include "libc/calls/struct/timespec.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/directmap.internal.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/directmap.h" +#include "libc/intrin/safemacros.h" #include "libc/limits.h" #include "libc/runtime/runtime.h" #include "libc/stdio/rand.h" diff --git a/test/libc/intrin/describeflags_test.c b/test/libc/intrin/describeflags_test.c index 5475cdf72..14f2892a0 100644 --- a/test/libc/intrin/describeflags_test.c +++ b/test/libc/intrin/describeflags_test.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/macros.internal.h" #include "libc/testlib/testlib.h" diff --git a/test/libc/intrin/describegidlist_test.c b/test/libc/intrin/describegidlist_test.c index 98c6a3408..f85f17f0c 100644 --- a/test/libc/intrin/describegidlist_test.c +++ b/test/libc/intrin/describegidlist_test.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/groups.internal.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/testlib/testlib.h" TEST(DescribeGidList, test) { diff --git a/test/libc/intrin/describesigset_test.c b/test/libc/intrin/describesigset_test.c index 10410fb53..fc65ef61d 100644 --- a/test/libc/intrin/describesigset_test.c +++ b/test/libc/intrin/describesigset_test.c @@ -19,7 +19,7 @@ #include "libc/calls/struct/sigset.h" #include "libc/calls/struct/sigset.internal.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/sysv/consts/sig.h" #include "libc/testlib/testlib.h" diff --git a/test/libc/intrin/dos2errno_test.c b/test/libc/intrin/dos2errno_test.c index 14f8a2579..fb4e27aef 100644 --- a/test/libc/intrin/dos2errno_test.c +++ b/test/libc/intrin/dos2errno_test.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/dos2errno.internal.h" +#include "libc/intrin/dos2errno.h" #include "libc/nt/errors.h" #include "libc/sock/internal.h" #include "libc/str/str.h" diff --git a/test/libc/intrin/mprotect_test.c b/test/libc/intrin/mprotect_test.c index 8466d665b..a3df5a4b2 100644 --- a/test/libc/intrin/mprotect_test.c +++ b/test/libc/intrin/mprotect_test.c @@ -21,7 +21,7 @@ #include "libc/calls/ucontext.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/log/log.h" #include "libc/mem/gc.h" #include "libc/mem/mem.h" diff --git a/test/libc/intrin/pthread_mutex_lock_test.c b/test/libc/intrin/pthread_mutex_lock_test.c index b45d2a20a..e2e97cda1 100644 --- a/test/libc/intrin/pthread_mutex_lock_test.c +++ b/test/libc/intrin/pthread_mutex_lock_test.c @@ -21,7 +21,7 @@ #include "libc/calls/calls.h" #include "libc/calls/state.internal.h" #include "libc/errno.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/log/check.h" #include "libc/macros.internal.h" #include "libc/math.h" diff --git a/test/libc/mem/malloc_test.c b/test/libc/mem/malloc_test.c index 228594367..18d2829ba 100644 --- a/test/libc/mem/malloc_test.c +++ b/test/libc/mem/malloc_test.c @@ -21,9 +21,9 @@ #include "libc/calls/struct/timespec.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/cxaatexit.internal.h" +#include "libc/intrin/cxaatexit.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/macros.internal.h" #include "libc/mem/gc.h" #include "libc/mem/mem.h" diff --git a/test/libc/mem/realpath_test.c b/test/libc/mem/realpath_test.c index ac1be2cae..83dc43251 100644 --- a/test/libc/mem/realpath_test.c +++ b/test/libc/mem/realpath_test.c @@ -19,7 +19,7 @@ #include "libc/calls/calls.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/limits.h" #include "libc/mem/gc.h" #include "libc/mem/mem.h" diff --git a/test/libc/nexgen32e/lz4decode_test.c b/test/libc/nexgen32e/lz4decode_test.c index ce289468f..6afd50878 100644 --- a/test/libc/nexgen32e/lz4decode_test.c +++ b/test/libc/nexgen32e/lz4decode_test.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/log/check.h" #include "libc/mem/gc.h" #include "libc/mem/mem.h" diff --git a/test/libc/proc/posix_spawn_test.c b/test/libc/proc/posix_spawn_test.c index e83abb2a8..044c24dcf 100644 --- a/test/libc/proc/posix_spawn_test.c +++ b/test/libc/proc/posix_spawn_test.c @@ -33,7 +33,7 @@ #include "libc/errno.h" #include "libc/fmt/conv.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/limits.h" #include "libc/mem/gc.h" #include "libc/mem/mem.h" diff --git a/test/libc/proc/sched_getaffinity_test.c b/test/libc/proc/sched_getaffinity_test.c index 6e2a7f65d..0ca0d8d53 100644 --- a/test/libc/proc/sched_getaffinity_test.c +++ b/test/libc/proc/sched_getaffinity_test.c @@ -22,7 +22,7 @@ #include "libc/errno.h" #include "libc/fmt/conv.h" #include "libc/intrin/popcnt.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/proc/posix_spawn.h" #include "libc/runtime/runtime.h" #include "libc/testlib/subprocess.h" diff --git a/test/libc/sock/inet_pton_test.c b/test/libc/sock/inet_pton_test.c index ffc44b22e..c6f1dd313 100644 --- a/test/libc/sock/inet_pton_test.c +++ b/test/libc/sock/inet_pton_test.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/sock/sock.h" #include "libc/sysv/consts/af.h" #include "libc/sysv/consts/inaddr.h" diff --git a/test/libc/sock/nonblock_test.c b/test/libc/sock/nonblock_test.c index 3d3259d47..117582a57 100644 --- a/test/libc/sock/nonblock_test.c +++ b/test/libc/sock/nonblock_test.c @@ -20,7 +20,7 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/runtime/runtime.h" #include "libc/runtime/syslib.internal.h" #include "libc/sock/sock.h" diff --git a/test/libc/sock/socket_test.c b/test/libc/sock/socket_test.c index b3a5e1d32..f79b0d7a7 100644 --- a/test/libc/sock/socket_test.c +++ b/test/libc/sock/socket_test.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" -#include "libc/calls/struct/fd.internal.h" +#include "libc/intrin/fds.h" #include "libc/dce.h" #include "libc/intrin/kprintf.h" #include "libc/nt/winsock.h" diff --git a/test/libc/stdio/palandprintf_test.c b/test/libc/stdio/palandprintf_test.c index 9a67f6732..a9486703e 100644 --- a/test/libc/stdio/palandprintf_test.c +++ b/test/libc/stdio/palandprintf_test.c @@ -26,8 +26,8 @@ └─────────────────────────────────────────────────────────────────────────────*/ #include "libc/errno.h" #include "libc/fmt/itoa.h" -#include "libc/intrin/pushpop.internal.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/pushpop.h" +#include "libc/intrin/safemacros.h" #include "libc/limits.h" #include "libc/math.h" #include "libc/mem/gc.h" diff --git a/test/libc/stdio/sprintf_s_test.c b/test/libc/stdio/sprintf_s_test.c index 2d38cd53f..a6a448684 100644 --- a/test/libc/stdio/sprintf_s_test.c +++ b/test/libc/stdio/sprintf_s_test.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/mem/gc.h" #include "libc/testlib/testlib.h" #include "libc/x/x.h" diff --git a/test/libc/thread/pthread_detach_test.c b/test/libc/thread/pthread_detach_test.c index bfbb9c9c5..f491a2da8 100644 --- a/test/libc/thread/pthread_detach_test.c +++ b/test/libc/thread/pthread_detach_test.c @@ -19,7 +19,7 @@ #include "libc/calls/calls.h" #include "libc/calls/struct/sigaction.h" #include "libc/errno.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/sysv/consts/sa.h" #include "libc/sysv/consts/sig.h" #include "libc/testlib/testlib.h" diff --git a/test/libc/thread/pthread_exit_test.c b/test/libc/thread/pthread_exit_test.c index 2855702ae..133a81cab 100644 --- a/test/libc/thread/pthread_exit_test.c +++ b/test/libc/thread/pthread_exit_test.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/cxxabi.h" -#include "libc/intrin/cxaatexit.internal.h" +#include "libc/intrin/cxaatexit.h" #include "libc/runtime/runtime.h" #include "libc/testlib/subprocess.h" #include "libc/testlib/testlib.h" diff --git a/third_party/dlmalloc/dlmalloc_abort.c b/third_party/dlmalloc/dlmalloc_abort.c index 0ca5135be..ef3effcb4 100644 --- a/third_party/dlmalloc/dlmalloc_abort.c +++ b/third_party/dlmalloc/dlmalloc_abort.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" #include "libc/errno.h" -#include "libc/intrin/describebacktrace.internal.h" +#include "libc/intrin/describebacktrace.h" #include "libc/runtime/runtime.h" #include "third_party/dlmalloc/dlmalloc.h" diff --git a/third_party/dlmalloc/threaded.inc b/third_party/dlmalloc/threaded.inc index 9b87934e8..83d608b9b 100644 --- a/third_party/dlmalloc/threaded.inc +++ b/third_party/dlmalloc/threaded.inc @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/dce.h" #include "libc/intrin/magicu.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/macros.internal.h" #include "libc/nexgen32e/rdtscp.h" diff --git a/third_party/linenoise/linenoise.c b/third_party/linenoise/linenoise.c index 8c7c0d144..ca9b35f87 100644 --- a/third_party/linenoise/linenoise.c +++ b/third_party/linenoise/linenoise.c @@ -140,8 +140,8 @@ #include "libc/fmt/conv.h" #include "libc/serialize.h" #include "libc/intrin/bsr.h" -#include "libc/intrin/nomultics.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/nomultics.h" +#include "libc/intrin/strace.h" #include "libc/log/check.h" #include "libc/log/log.h" #include "libc/macros.internal.h" diff --git a/third_party/lua/lrepl.c b/third_party/lua/lrepl.c index b56548a6b..3312918e9 100644 --- a/third_party/lua/lrepl.c +++ b/third_party/lua/lrepl.c @@ -30,7 +30,7 @@ #include "libc/calls/calls.h" #include "libc/calls/struct/sigaction.h" #include "libc/errno.h" -#include "libc/intrin/nomultics.internal.h" +#include "libc/intrin/nomultics.h" #include "libc/log/check.h" #include "libc/macros.internal.h" #include "libc/mem/alg.h" diff --git a/third_party/lua/lunix.c b/third_party/lua/lunix.c index 8f6c36c17..9fd10961a 100644 --- a/third_party/lua/lunix.c +++ b/third_party/lua/lunix.c @@ -46,7 +46,7 @@ #include "libc/fmt/magnumstrs.internal.h" #include "libc/intrin/atomic.h" #include "libc/serialize.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/limits.h" #include "libc/log/log.h" #include "libc/macros.internal.h" diff --git a/third_party/mbedtls/ecp.c b/third_party/mbedtls/ecp.c index 4b696ef83..60870d240 100644 --- a/third_party/mbedtls/ecp.c +++ b/third_party/mbedtls/ecp.c @@ -16,7 +16,7 @@ β”‚ limitations under the License. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "third_party/mbedtls/ecp.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/log/check.h" #include "libc/log/log.h" #include "libc/runtime/runtime.h" diff --git a/third_party/mbedtls/profile.h b/third_party/mbedtls/profile.h index 8c8553e7b..3143d73eb 100644 --- a/third_party/mbedtls/profile.h +++ b/third_party/mbedtls/profile.h @@ -1,6 +1,6 @@ #ifndef COSMOPOLITAN_THIRD_PARTY_MBEDTLS_PROFILE_H_ #define COSMOPOLITAN_THIRD_PARTY_MBEDTLS_PROFILE_H_ -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/log/log.h" #include "libc/nexgen32e/bench.h" #include "libc/nexgen32e/rdtsc.h" diff --git a/third_party/mbedtls/rsa.c b/third_party/mbedtls/rsa.c index edc6ae58f..5ecfe67bb 100644 --- a/third_party/mbedtls/rsa.c +++ b/third_party/mbedtls/rsa.c @@ -16,7 +16,7 @@ β”‚ limitations under the License. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "third_party/mbedtls/rsa.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/runtime/runtime.h" #include "libc/stdio/rand.h" #include "third_party/mbedtls/common.h" diff --git a/third_party/mbedtls/test/lib.c b/third_party/mbedtls/test/lib.c index 7e9de24be..fbe2fa9ab 100644 --- a/third_party/mbedtls/test/lib.c +++ b/third_party/mbedtls/test/lib.c @@ -22,8 +22,8 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/conv.h" -#include "libc/intrin/describebacktrace.internal.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/describebacktrace.h" +#include "libc/intrin/safemacros.h" #include "libc/limits.h" #include "libc/log/backtrace.internal.h" #include "libc/log/check.h" diff --git a/third_party/mbedtls/test/test_suite_ssl.c b/third_party/mbedtls/test/test_suite_ssl.c index 0c9f6e54c..6c3c7bb1e 100644 --- a/third_party/mbedtls/test/test_suite_ssl.c +++ b/third_party/mbedtls/test/test_suite_ssl.c @@ -20,7 +20,7 @@ #include "libc/log/log.h" #include "libc/time.h" #include "libc/stdio/rand.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "third_party/mbedtls/test/test.inc" /* * *** THIS FILE WAS MACHINE GENERATED *** diff --git a/third_party/nsync/common.c b/third_party/nsync/common.c index 4b4b13d98..2b150401c 100644 --- a/third_party/nsync/common.c +++ b/third_party/nsync/common.c @@ -18,9 +18,9 @@ #include "libc/calls/calls.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" -#include "libc/intrin/directmap.internal.h" +#include "libc/intrin/directmap.h" #include "libc/intrin/dll.h" -#include "libc/intrin/extend.internal.h" +#include "libc/intrin/extend.h" #include "libc/nt/enum/filemapflags.h" #include "libc/nt/enum/pageflags.h" #include "libc/nt/memory.h" diff --git a/third_party/nsync/futex.c b/third_party/nsync/futex.c index feb8c49ef..971501901 100644 --- a/third_party/nsync/futex.c +++ b/third_party/nsync/futex.c @@ -32,8 +32,8 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/atomic.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/intrin/ulock.h" #include "libc/intrin/weaken.h" #include "libc/limits.h" diff --git a/third_party/nsync/mu_semaphore_gcd.c b/third_party/nsync/mu_semaphore_gcd.c index 1f88d5e0d..088b50414 100644 --- a/third_party/nsync/mu_semaphore_gcd.c +++ b/third_party/nsync/mu_semaphore_gcd.c @@ -18,7 +18,7 @@ #include "libc/assert.h" #include "libc/calls/sig.internal.h" #include "libc/errno.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" #include "libc/runtime/clktck.h" #include "libc/runtime/syslib.internal.h" diff --git a/third_party/nsync/mu_semaphore_sem.c b/third_party/nsync/mu_semaphore_sem.c index 3eb8a22f6..44f8cb3c3 100644 --- a/third_party/nsync/mu_semaphore_sem.c +++ b/third_party/nsync/mu_semaphore_sem.c @@ -25,7 +25,7 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/dll.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/str/str.h" #include "libc/sysv/consts/f.h" #include "libc/sysv/consts/fd.h" diff --git a/third_party/nsync/panic.c b/third_party/nsync/panic.c index dcb09dd7b..10f9eddf8 100644 --- a/third_party/nsync/panic.c +++ b/third_party/nsync/panic.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" #include "libc/errno.h" -#include "libc/intrin/describebacktrace.internal.h" +#include "libc/intrin/describebacktrace.h" #include "libc/runtime/runtime.h" #include "third_party/nsync/common.internal.h" diff --git a/third_party/nsync/yield.c b/third_party/nsync/yield.c index f15b29f6c..588d8650d 100644 --- a/third_party/nsync/yield.c +++ b/third_party/nsync/yield.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/thread/thread.h" #include "third_party/nsync/common.internal.h" diff --git a/third_party/python/Python/pystate.c b/third_party/python/Python/pystate.c index 11dc33893..4bab4fc6e 100644 --- a/third_party/python/Python/pystate.c +++ b/third_party/python/Python/pystate.c @@ -6,7 +6,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "third_party/python/Include/pystate.h" #include "libc/errno.h" -#include "libc/intrin/pushpop.internal.h" +#include "libc/intrin/pushpop.h" #include "libc/dlopen/dlfcn.h" #include "third_party/python/Include/ceval.h" #include "third_party/python/Include/dictobject.h" diff --git a/third_party/python/runpythonmodule.c b/third_party/python/runpythonmodule.c index 1ce15f005..f3410c136 100644 --- a/third_party/python/runpythonmodule.c +++ b/third_party/python/runpythonmodule.c @@ -12,7 +12,7 @@ #include "libc/calls/ucontext.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/intrin/weaken.h" #include "libc/log/check.h" #include "libc/log/log.h" diff --git a/third_party/regex/regerror.c b/third_party/regex/regerror.c index 8564b2ed1..b922b9b59 100644 --- a/third_party/regex/regerror.c +++ b/third_party/regex/regerror.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/stdio/stdio.h" #include "libc/str/str.h" #include "third_party/regex/regex.h" diff --git a/tool/build/compile.c b/tool/build/compile.c index 8b2f35e16..68cc4c9ee 100644 --- a/tool/build/compile.c +++ b/tool/build/compile.c @@ -32,7 +32,7 @@ #include "libc/fmt/itoa.h" #include "libc/fmt/libgen.h" #include "libc/fmt/magnumstrs.internal.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/intrin/x86.h" #include "libc/limits.h" #include "libc/log/appendresourcereport.internal.h" diff --git a/tool/build/dso/sandbox.c b/tool/build/dso/sandbox.c index ee7ccc12b..01569dc46 100644 --- a/tool/build/dso/sandbox.c +++ b/tool/build/dso/sandbox.c @@ -19,7 +19,7 @@ #include "libc/calls/calls.h" #include "libc/calls/pledge.h" #include "libc/calls/pledge.internal.h" -#include "libc/intrin/promises.internal.h" +#include "libc/intrin/promises.h" #include "libc/runtime/runtime.h" // runs pledge at glibc executable load time, e.g. diff --git a/tool/build/elf2pe.c b/tool/build/elf2pe.c index f438383ae..b1508a926 100644 --- a/tool/build/elf2pe.c +++ b/tool/build/elf2pe.c @@ -25,7 +25,7 @@ #include "libc/elf/struct/shdr.h" #include "libc/fmt/conv.h" #include "libc/fmt/itoa.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/dll.h" #include "libc/intrin/kprintf.h" #include "libc/limits.h" diff --git a/tool/build/helpop.c b/tool/build/helpop.c index 399372a0f..9da096ca6 100644 --- a/tool/build/helpop.c +++ b/tool/build/helpop.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/errno.h" #include "libc/fmt/conv.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/macros.internal.h" #include "libc/runtime/runtime.h" #include "libc/stdio/stdio.h" diff --git a/tool/build/lib/demangle.c b/tool/build/lib/demangle.c index a2d11cd14..d2260fe3e 100644 --- a/tool/build/lib/demangle.c +++ b/tool/build/lib/demangle.c @@ -20,7 +20,7 @@ #include "libc/assert.h" #include "libc/calls/calls.h" #include "libc/calls/struct/iovec.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/limits.h" #include "libc/str/str.h" #include "libc/sysv/consts/o.h" diff --git a/tool/build/lib/eztls.c b/tool/build/lib/eztls.c index 5ae728387..754d1a533 100644 --- a/tool/build/lib/eztls.c +++ b/tool/build/lib/eztls.c @@ -23,7 +23,7 @@ #include "libc/errno.h" #include "libc/fmt/itoa.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/macros.internal.h" #include "libc/sysv/consts/sig.h" #include "libc/thread/thread.h" diff --git a/tool/build/lib/interner.c b/tool/build/lib/interner.c index a287b1132..a491de30c 100644 --- a/tool/build/lib/interner.c +++ b/tool/build/lib/interner.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "tool/build/lib/interner.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/mem/mem.h" #include "libc/nexgen32e/crc32.h" #include "libc/runtime/runtime.h" diff --git a/tool/build/lib/panel.c b/tool/build/lib/panel.c index 976d49aa5..072836bef 100644 --- a/tool/build/lib/panel.c +++ b/tool/build/lib/panel.c @@ -19,7 +19,7 @@ #include "tool/build/lib/panel.h" #include "libc/fmt/conv.h" #include "libc/intrin/bsr.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/mem/mem.h" #include "libc/str/str.h" #include "libc/str/unicode.h" diff --git a/tool/build/pledge.c b/tool/build/pledge.c index 874f76669..6968f7797 100644 --- a/tool/build/pledge.c +++ b/tool/build/pledge.c @@ -38,8 +38,8 @@ #include "libc/fmt/conv.h" #include "libc/fmt/itoa.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/promises.internal.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/promises.h" +#include "libc/intrin/safemacros.h" #include "libc/limits.h" #include "libc/macros.internal.h" #include "libc/math.h" diff --git a/tool/build/runit.c b/tool/build/runit.c index 3c0a55681..6c2a34fc5 100644 --- a/tool/build/runit.c +++ b/tool/build/runit.c @@ -26,7 +26,7 @@ #include "libc/errno.h" #include "libc/fmt/libgen.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/limits.h" #include "libc/log/check.h" #include "libc/log/log.h" diff --git a/tool/decode/elf.c b/tool/decode/elf.c index 741ad381f..4db9e45ab 100644 --- a/tool/decode/elf.c +++ b/tool/decode/elf.c @@ -26,7 +26,7 @@ #include "libc/errno.h" #include "libc/fmt/conv.h" #include "libc/fmt/libgen.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/log/check.h" #include "libc/log/log.h" #include "libc/macros.internal.h" diff --git a/tool/decode/lib/asmcodegen.c b/tool/decode/lib/asmcodegen.c index 1e4520a3c..e63ea97fd 100644 --- a/tool/decode/lib/asmcodegen.c +++ b/tool/decode/lib/asmcodegen.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "tool/decode/lib/asmcodegen.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/mem/gc.h" #include "libc/mem/mem.h" #include "libc/stdio/stdio.h" diff --git a/tool/decode/macho.c b/tool/decode/macho.c index 736ad4078..9f358aaef 100644 --- a/tool/decode/macho.c +++ b/tool/decode/macho.c @@ -21,7 +21,7 @@ #include "libc/calls/struct/stat.h" #include "libc/fmt/conv.h" #include "libc/fmt/libgen.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/macho.internal.h" #include "libc/mem/gc.h" #include "libc/mem/mem.h" diff --git a/tool/decode/pe2.c b/tool/decode/pe2.c index 7660aeee8..06ac8c888 100644 --- a/tool/decode/pe2.c +++ b/tool/decode/pe2.c @@ -20,7 +20,7 @@ #include "libc/calls/struct/stat.h" #include "libc/fmt/conv.h" #include "libc/fmt/libgen.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/mem/gc.h" #include "libc/mem/mem.h" #include "libc/nt/struct/imagedosheader.internal.h" diff --git a/tool/decode/zip.c b/tool/decode/zip.c index e0f8101f4..6b4cf88b2 100644 --- a/tool/decode/zip.c +++ b/tool/decode/zip.c @@ -22,7 +22,7 @@ #include "libc/fmt/libgen.h" #include "libc/fmt/wintime.internal.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/log/check.h" #include "libc/log/log.h" #include "libc/mem/gc.h" diff --git a/tool/net/redbean.c b/tool/net/redbean.c index 64a599028..e86be3ab9 100644 --- a/tool/net/redbean.c +++ b/tool/net/redbean.c @@ -40,8 +40,8 @@ #include "libc/intrin/atomic.h" #include "libc/intrin/bsr.h" #include "libc/intrin/likely.h" -#include "libc/intrin/nomultics.internal.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/nomultics.h" +#include "libc/intrin/safemacros.h" #include "libc/log/appendresourcereport.internal.h" #include "libc/log/check.h" #include "libc/log/log.h" diff --git a/tool/plinko/lib/plinko.c b/tool/plinko/lib/plinko.c index 3def139a0..181c3b838 100644 --- a/tool/plinko/lib/plinko.c +++ b/tool/plinko/lib/plinko.c @@ -22,7 +22,7 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/errno.h" #include "libc/intrin/likely.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/log/countbranch.h" #include "libc/log/countexpr.h" #include "libc/log/log.h" diff --git a/tool/plinko/lib/printf.c b/tool/plinko/lib/printf.c index 09b7da750..b7e058011 100644 --- a/tool/plinko/lib/printf.c +++ b/tool/plinko/lib/printf.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "tool/plinko/lib/printf.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/nexgen32e/rdtsc.h" #include "libc/runtime/runtime.h" #include "libc/str/str.h" diff --git a/tool/plinko/lib/read.c b/tool/plinko/lib/read.c index 04dd889a0..ad94f6370 100644 --- a/tool/plinko/lib/read.c +++ b/tool/plinko/lib/read.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" #include "libc/errno.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/strace.h" #include "libc/log/check.h" #include "libc/runtime/runtime.h" #include "libc/str/str.h" diff --git a/tool/viz/deathstar.c b/tool/viz/deathstar.c index f06a827fd..a5d0621dc 100644 --- a/tool/viz/deathstar.c +++ b/tool/viz/deathstar.c @@ -1,7 +1,7 @@ #include "libc/calls/calls.h" #include "libc/calls/struct/sigaction.h" #include "libc/calls/struct/termios.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/math.h" #include "libc/runtime/runtime.h" #include "libc/stdio/stdio.h" diff --git a/tool/viz/fixconsole.c b/tool/viz/fixconsole.c index ea656d477..8bd23e075 100644 --- a/tool/viz/fixconsole.c +++ b/tool/viz/fixconsole.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" #include "libc/dce.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/nt/console.h" #include "libc/nt/enum/consolemodeflags.h" #include "libc/nt/runtime.h" diff --git a/tool/viz/fold.c b/tool/viz/fold.c index 1663a3dfc..2fe852001 100644 --- a/tool/viz/fold.c +++ b/tool/viz/fold.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/errno.h" #include "libc/fmt/conv.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/runtime/runtime.h" #include "libc/stdio/stdio.h" #include "libc/str/str.h" diff --git a/tool/viz/lib/formatstringtable-assembly.c b/tool/viz/lib/formatstringtable-assembly.c index b126c60bc..456710dee 100644 --- a/tool/viz/lib/formatstringtable-assembly.c +++ b/tool/viz/lib/formatstringtable-assembly.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/fmt/itoa.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/mem/gc.h" #include "libc/str/str.h" #include "libc/str/strwidth.h" diff --git a/tool/viz/lib/formatstringtable-code.c b/tool/viz/lib/formatstringtable-code.c index 1034dc875..71b36360c 100644 --- a/tool/viz/lib/formatstringtable-code.c +++ b/tool/viz/lib/formatstringtable-code.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/fmt/itoa.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "tool/viz/lib/formatstringtable.h" void *FormatStringTableAsCode(long yn, long xn, const char *const T[yn][xn], diff --git a/tool/viz/lib/formatstringtable.c b/tool/viz/lib/formatstringtable.c index af74d3b3b..7c9152c1d 100644 --- a/tool/viz/lib/formatstringtable.c +++ b/tool/viz/lib/formatstringtable.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "tool/viz/lib/formatstringtable.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/mem/mem.h" #include "libc/str/strwidth.h" diff --git a/tool/viz/life.c b/tool/viz/life.c index 8e223f894..bbf7df3d3 100644 --- a/tool/viz/life.c +++ b/tool/viz/life.c @@ -26,8 +26,8 @@ #include "libc/fmt/conv.h" #include "libc/fmt/itoa.h" #include "libc/intrin/popcnt.h" -#include "libc/intrin/safemacros.internal.h" -#include "libc/intrin/xchg.internal.h" +#include "libc/intrin/safemacros.h" +#include "libc/intrin/xchg.h" #include "libc/limits.h" #include "libc/log/check.h" #include "libc/log/log.h" diff --git a/tool/viz/memzoom.c b/tool/viz/memzoom.c index 7793fd853..034ea4265 100644 --- a/tool/viz/memzoom.c +++ b/tool/viz/memzoom.c @@ -32,7 +32,7 @@ #include "libc/intrin/bsf.h" #include "libc/intrin/bsr.h" #include "libc/intrin/hilbert.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/limits.h" #include "libc/log/log.h" #include "libc/macros.internal.h" diff --git a/tool/viz/printansi.c b/tool/viz/printansi.c index dd9ebaf59..849242540 100644 --- a/tool/viz/printansi.c +++ b/tool/viz/printansi.c @@ -29,7 +29,7 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/conv.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/limits.h" #include "libc/log/check.h" #include "libc/log/log.h" diff --git a/tool/viz/printdos2errno.c b/tool/viz/printdos2errno.c index 7f06d581f..4218f6968 100644 --- a/tool/viz/printdos2errno.c +++ b/tool/viz/printdos2errno.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/fmt/magnumstrs.internal.h" -#include "libc/intrin/dos2errno.internal.h" +#include "libc/intrin/dos2errno.h" #include "libc/intrin/kprintf.h" #include "libc/str/str.h" diff --git a/tool/viz/printvideo.c b/tool/viz/printvideo.c index ccaf445a8..f412911d4 100644 --- a/tool/viz/printvideo.c +++ b/tool/viz/printvideo.c @@ -42,8 +42,8 @@ #include "libc/fmt/conv.h" #include "libc/fmt/itoa.h" #include "libc/intrin/kprintf.h" -#include "libc/intrin/safemacros.internal.h" -#include "libc/intrin/xchg.internal.h" +#include "libc/intrin/safemacros.h" +#include "libc/intrin/xchg.h" #include "libc/log/check.h" #include "libc/log/log.h" #include "libc/macros.internal.h" diff --git a/tool/viz/rlimit.c b/tool/viz/rlimit.c index 3d3b84eb5..e4b4e4ae9 100644 --- a/tool/viz/rlimit.c +++ b/tool/viz/rlimit.c @@ -10,8 +10,8 @@ #include "libc/calls/struct/rlimit.h" #include "libc/calls/calls.h" #include "libc/errno.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/intrin/strace.h" #include "libc/log/color.internal.h" #include "libc/macros.internal.h" #include "libc/runtime/runtime.h" diff --git a/tool/viz/tailf.c b/tool/viz/tailf.c index 9c97c516a..ed420d23e 100644 --- a/tool/viz/tailf.c +++ b/tool/viz/tailf.c @@ -18,7 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" #include "libc/calls/struct/stat.h" -#include "libc/intrin/safemacros.internal.h" +#include "libc/intrin/safemacros.h" #include "libc/macros.internal.h" #include "libc/runtime/runtime.h" #include "libc/stdio/stdio.h" diff --git a/tool/viz/virtualquery.c b/tool/viz/virtualquery.c index 7168c7202..e1ce16cc1 100644 --- a/tool/viz/virtualquery.c +++ b/tool/viz/virtualquery.c @@ -19,7 +19,7 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/conv.h" -#include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/describeflags.h" #include "libc/macros.internal.h" #include "libc/nt/enum/memflags.h" #include "libc/nt/memory.h" From f6ba270ff3eef773f0e0d073c2bdec9a3af86245 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Fri, 19 Jul 2024 19:38:53 -0700 Subject: [PATCH 050/405] Add last commit to .git-blame-ignore-revs --- .git-blame-ignore-revs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 6344f77fc..6436e229a 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -25,3 +25,5 @@ c0eacf2eb1e1c0b3bd4f71f12fef258f5b249c3f da8baf2aa5ce93b958aca90a0ae69f537806324b # Run clang-format on most sources 369f9740de4534c28d0e81ab2afc99decbb9a3e6 +# Get rid of .internal.h convention in LIBC_INTRIN +86d884cce24d773e298a2714c1e3d91ecab9be45 From 101fb3d9b3250759f383c9e6fe86460f10ee499c Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Fri, 19 Jul 2024 22:26:49 -0700 Subject: [PATCH 051/405] Make some new Windows 10 memory APIs available --- .../MapViewOfFile3.S | 2 +- .../VirtualAlloc2.S | 2 +- libc/nt/BUILD.mk | 21 +++++++++++++++++++ libc/nt/enum/memflags.h | 1 + libc/nt/master.sh | 8 +++++-- 5 files changed, 30 insertions(+), 4 deletions(-) rename libc/nt/{kernel32 => API-MS-Win-Core-Memory-l1-1-6}/MapViewOfFile3.S (79%) rename libc/nt/{kernel32 => API-MS-Win-Core-Memory-l1-1-6}/VirtualAlloc2.S (79%) diff --git a/libc/nt/kernel32/MapViewOfFile3.S b/libc/nt/API-MS-Win-Core-Memory-l1-1-6/MapViewOfFile3.S similarity index 79% rename from libc/nt/kernel32/MapViewOfFile3.S rename to libc/nt/API-MS-Win-Core-Memory-l1-1-6/MapViewOfFile3.S index 2b242dfd3..059fe827c 100644 --- a/libc/nt/kernel32/MapViewOfFile3.S +++ b/libc/nt/API-MS-Win-Core-Memory-l1-1-6/MapViewOfFile3.S @@ -1,5 +1,5 @@ #include "libc/nt/codegen.h" -.imp kernel32,__imp_MapViewOfFile3,MapViewOfFile3 +.imp API-MS-Win-Core-Memory-l1-1-6,__imp_MapViewOfFile3,MapViewOfFile3 .text.windows .ftrace1 diff --git a/libc/nt/kernel32/VirtualAlloc2.S b/libc/nt/API-MS-Win-Core-Memory-l1-1-6/VirtualAlloc2.S similarity index 79% rename from libc/nt/kernel32/VirtualAlloc2.S rename to libc/nt/API-MS-Win-Core-Memory-l1-1-6/VirtualAlloc2.S index 77b2af26c..755aafb20 100644 --- a/libc/nt/kernel32/VirtualAlloc2.S +++ b/libc/nt/API-MS-Win-Core-Memory-l1-1-6/VirtualAlloc2.S @@ -1,5 +1,5 @@ #include "libc/nt/codegen.h" -.imp kernel32,__imp_VirtualAlloc2,VirtualAlloc2 +.imp API-MS-Win-Core-Memory-l1-1-6,__imp_VirtualAlloc2,VirtualAlloc2 .text.windows .ftrace1 diff --git a/libc/nt/BUILD.mk b/libc/nt/BUILD.mk index feaa79e24..f6bd28be4 100644 --- a/libc/nt/BUILD.mk +++ b/libc/nt/BUILD.mk @@ -158,6 +158,27 @@ $(LIBC_NT_SYNCHRONIZATION_A).pkg: \ #─────────────────────────────────────────────────────────────────────────────── +LIBC_NT_ARTIFACTS += LIBC_NT_MEMORY_A +LIBC_NT_MEMORY = $(LIBC_NT_MEMORY_A_DEPS) $(LIBC_NT_MEMORY_A) +LIBC_NT_MEMORY_A = o/$(MODE)/libc/nt/memory.a +LIBC_NT_MEMORY_A_SRCS := $(wildcard libc/nt/API-MS-Win-Core-Memory-l1-1-6/*.S) +LIBC_NT_MEMORY_A_OBJS = $(LIBC_NT_MEMORY_A_SRCS:%.S=o/$(MODE)/%.o) +LIBC_NT_MEMORY_A_CHECKS = $(LIBC_NT_MEMORY_A).pkg +LIBC_NT_MEMORY_A_DIRECTDEPS = LIBC_NT_KERNEL32 +LIBC_NT_MEMORY_A_DEPS := \ + $(call uniq,$(foreach x,$(LIBC_NT_MEMORY_A_DIRECTDEPS),$($(x)))) + +$(LIBC_NT_MEMORY_A): \ + libc/nt/API-MS-Win-Core-Memory-l1-1-6/ \ + $(LIBC_NT_MEMORY_A).pkg \ + $(LIBC_NT_MEMORY_A_OBJS) + +$(LIBC_NT_MEMORY_A).pkg: \ + $(LIBC_NT_MEMORY_A_OBJS) \ + $(foreach x,$(LIBC_NT_MEMORY_A_DIRECTDEPS),$($(x)_A).pkg) + +#─────────────────────────────────────────────────────────────────────────────── + LIBC_NT_ARTIFACTS += LIBC_NT_USER32_A LIBC_NT_USER32 = $(LIBC_NT_USER32_A_DEPS) $(LIBC_NT_USER32_A) LIBC_NT_USER32_A = o/$(MODE)/libc/nt/user32.a diff --git a/libc/nt/enum/memflags.h b/libc/nt/enum/memflags.h index fffb09ef9..7d7f11f61 100644 --- a/libc/nt/enum/memflags.h +++ b/libc/nt/enum/memflags.h @@ -16,6 +16,7 @@ #define kNtMemLargePages 0x20000000 #define kNtMem4mbPages 0x80000000 +#define kNtMemReservePlaceholder 0x00040000 #define kNtMemReplacePlaceholder 0x00004000 #endif /* COSMOPOLITAN_LIBC_NT_ENUM_MEMFLAGS_H_ */ diff --git a/libc/nt/master.sh b/libc/nt/master.sh index 21a07cdcd..4f44cc057 100755 --- a/libc/nt/master.sh +++ b/libc/nt/master.sh @@ -205,7 +205,6 @@ imp 'LoadResource' LoadResource kernel32 2 imp 'LocalFree' LocalFree kernel32 1 imp 'LockFile' LockFile kernel32 5 imp 'LockResource' LockResource kernel32 1 -imp 'MapViewOfFile3' MapViewOfFile3 kernel32 9 imp 'MoveFile' MoveFileW kernel32 2 imp 'MultiByteToWideChar' MultiByteToWideChar kernel32 6 imp 'OfferVirtualMemory' OfferVirtualMemory kernel32 3 @@ -296,7 +295,6 @@ imp 'UnmapViewOfFile2' UnmapViewOfFile2 kernel32 2 imp 'UnmapViewOfFileEx' UnmapViewOfFileEx kernel32 3 imp 'UpdateProcThreadAttribute' UpdateProcThreadAttribute kernel32 7 imp 'VirtualAlloc' VirtualAlloc kernel32 4 -imp 'VirtualAlloc2' VirtualAlloc2 kernel32 7 imp 'VirtualAllocEx' VirtualAllocEx kernel32 5 imp 'VirtualFree' VirtualFree kernel32 3 imp 'VirtualLock' VirtualLock kernel32 2 @@ -629,6 +627,12 @@ imp 'WaitOnAddress' WaitOnAddress API-MS-Win-Core-Synch-l1-2-0 4 imp 'WakeByAddressAll' WakeByAddressAll API-MS-Win-Core-Synch-l1-2-0 1 imp 'WakeByAddressSingle' WakeByAddressSingle API-MS-Win-Core-Synch-l1-2-0 1 +# API-MS-Win-Core-Memory-l1-1-6.dll (Windows 10+) +# +# Name Actual DLL Arity +imp 'MapViewOfFile3' MapViewOfFile3 API-MS-Win-Core-Memory-l1-1-6 9 +imp 'VirtualAlloc2' VirtualAlloc2 API-MS-Win-Core-Memory-l1-1-6 7 + # NTDLL.DLL # BEYOND THE PALE # From 493ffc9b7ff4ed25e440ce24ea40f5444a0d1237 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Fri, 19 Jul 2024 22:33:17 -0700 Subject: [PATCH 052/405] Release Cosmopolitan v3.5.5 --- libc/integral/normalize.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libc/integral/normalize.inc b/libc/integral/normalize.inc index 176f35a6d..ea2cd4328 100644 --- a/libc/integral/normalize.inc +++ b/libc/integral/normalize.inc @@ -4,7 +4,7 @@ #define __COSMOPOLITAN_MAJOR__ 3 #define __COSMOPOLITAN_MINOR__ 5 -#define __COSMOPOLITAN_PATCH__ 4 +#define __COSMOPOLITAN_PATCH__ 5 #define __COSMOPOLITAN__ \ (100000000 * __COSMOPOLITAN_MAJOR__ + 1000000 * __COSMOPOLITAN_MINOR__ + \ __COSMOPOLITAN_PATCH__) From 6a5d4ed65b24ad8398f7fec408890aea9ad3d55d Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sat, 20 Jul 2024 01:00:16 -0700 Subject: [PATCH 053/405] Fix bug with disabling sigaltstack() --- libc/calls/sigaltstack.c | 3 ++- test/libc/calls/sigaltstack_test.c | 41 ++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 test/libc/calls/sigaltstack_test.c diff --git a/libc/calls/sigaltstack.c b/libc/calls/sigaltstack.c index 1fb21189f..01079570f 100644 --- a/libc/calls/sigaltstack.c +++ b/libc/calls/sigaltstack.c @@ -132,7 +132,8 @@ int sigaltstack(const struct sigaltstack *neu, struct sigaltstack *old) { if (neu && ((neu->ss_size >> 32) || // (neu->ss_flags & ~(SS_ONSTACK | SS_DISABLE)))) { rc = einval(); - } else if (neu && neu->ss_size < __get_minsigstksz()) { + } else if (neu && !(neu->ss_flags & SS_DISABLE) && + neu->ss_size < __get_minsigstksz()) { rc = enomem(); } else if (IsLinux()) { rc = sys_sigaltstack(neu, old); diff --git a/test/libc/calls/sigaltstack_test.c b/test/libc/calls/sigaltstack_test.c new file mode 100644 index 000000000..7efdc7cbd --- /dev/null +++ b/test/libc/calls/sigaltstack_test.c @@ -0,0 +1,41 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-β”‚ +β”‚ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi β”‚ +β•žβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•‘ +β”‚ Copyright 2024 Justine Alexandra Roberts Tunney β”‚ +β”‚ β”‚ +β”‚ Permission to use, copy, modify, and/or distribute this software for β”‚ +β”‚ any purpose with or without fee is hereby granted, provided that the β”‚ +β”‚ above copyright notice and this permission notice appear in all copies. β”‚ +β”‚ β”‚ +β”‚ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL β”‚ +β”‚ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED β”‚ +β”‚ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE β”‚ +β”‚ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL β”‚ +β”‚ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR β”‚ +β”‚ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER β”‚ +β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ +β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ +β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/calls/struct/sigaltstack.h" +#include "libc/calls/calls.h" +#include "libc/errno.h" +#include "libc/sysv/consts/ss.h" +#include "libc/testlib/testlib.h" + +TEST(sigaltstack, badFlag) { + struct sigaltstack ss; + ss.ss_flags = -1; + ss.ss_size = 0; + ss.ss_sp = 0; + EXPECT_SYS(EINVAL, -1, sigaltstack(&ss, 0)); +} + +TEST(sigaltstack, disable) { + struct sigaltstack ss; + ss.ss_flags = SS_DISABLE; + ss.ss_size = 0; + ss.ss_sp = 0; + EXPECT_SYS(0, 0, sigaltstack(&ss, 0)); + EXPECT_SYS(0, 0, sigaltstack(0, &ss)); + EXPECT_EQ(SS_DISABLE, ss.ss_flags); +} From 2018cac11f1b4181b1bb4afd1835789959403e2f Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sat, 20 Jul 2024 02:20:03 -0700 Subject: [PATCH 054/405] Use better memory strategy on Windows Rather than using the the rollo global to pick addresses, we select them randomly now using a conservative vaspace. --- libc/intrin/maps.h | 5 +- libc/intrin/mmap.c | 106 ++++++++++------------- libc/intrin/rand64.c | 28 +++--- libc/intrin/randaddr.c | 26 ------ libc/proc/fork.c | 4 + test/libc/calls/madvise_test.c | 4 + test/libc/intrin/kprintf_test.c | 2 + test/libc/intrin/mmap_scalability_test.c | 6 +- test/libc/intrin/mmap_test.c | 24 +++-- test/libc/intrin/mprotect_test.c | 2 + test/libc/intrin/mremap_test.c | 17 ++-- test/libc/intrin/munmap_test.c | 12 ++- test/libc/thread/pthread_create_test.c | 1 - 13 files changed, 113 insertions(+), 124 deletions(-) delete mode 100644 libc/intrin/randaddr.c diff --git a/libc/intrin/maps.h b/libc/intrin/maps.h index 06b8a813e..35bb44e97 100644 --- a/libc/intrin/maps.h +++ b/libc/intrin/maps.h @@ -30,7 +30,7 @@ struct Maps { _Atomic(struct Map *) free; size_t count; size_t pages; - atomic_size_t rollo; + _Atomic(char *) pick; struct Map stack; struct Map guard; }; @@ -42,11 +42,12 @@ struct AddrSize { extern struct Maps __maps; -void *randaddr(void); void __maps_init(void); bool __maps_lock(void); void __maps_check(void); void __maps_unlock(void); +void *__maps_randaddr(void); +void *__maps_pickaddr(size_t); void __maps_add(struct Map *); void __maps_free(struct Map *); struct Map *__maps_alloc(void); diff --git a/libc/intrin/mmap.c b/libc/intrin/mmap.c index 6982507a6..72ebda766 100644 --- a/libc/intrin/mmap.c +++ b/libc/intrin/mmap.c @@ -40,6 +40,7 @@ #include "libc/runtime/runtime.h" #include "libc/runtime/stack.h" #include "libc/runtime/zipos.internal.h" +#include "libc/stdio/rand.h" #include "libc/stdio/sysparam.h" #include "libc/sysv/consts/auxv.h" #include "libc/sysv/consts/map.h" @@ -50,9 +51,9 @@ #include "libc/thread/thread.h" #include "libc/thread/tls.h" -#define MMDEBUG IsModeDbg() -#define WINBASE (1ul << 35) // 34 gb -#define WINMAXX ((1ul << 44) - WINBASE) // 17 tb +#define MMDEBUG IsModeDbg() +#define MAX_SIZE 0x0ff800000000ul +#define MAX_TRIES 10 #define MAP_FIXED_NOREPLACE_linux 0x100000 @@ -373,6 +374,34 @@ static int __munmap(char *addr, size_t size) { return rc; } +void *__maps_randaddr(void) { + uintptr_t addr; + addr = _rand64(); + addr &= 0x007fffffffff; + addr |= 0x004000000000; + addr &= -__gransize; + return (void *)addr; +} + +void *__maps_pickaddr(size_t size) { + char *addr; + for (int try = 0; try < MAX_TRIES; ++try) { + addr = atomic_exchange_explicit(&__maps.pick, 0, memory_order_acq_rel); + if (!addr) + addr = __maps_randaddr(); + __maps_lock(); + bool overlaps = __maps_overlaps(addr, size, __pagesize); + __maps_unlock(); + if (!overlaps) { + atomic_store_explicit(&__maps.pick, + addr + ((size + __gransize - 1) & __gransize), + memory_order_release); + return addr; + } + } + return 0; +} + static void *__mmap_chunk(void *addr, size_t size, int prot, int flags, int fd, int64_t off, int pagesz, int gransz) { @@ -409,6 +438,7 @@ static void *__mmap_chunk(void *addr, size_t size, int prot, int flags, int fd, // obtain mapping from operating system int olderr = errno; + int tries = MAX_TRIES; struct DirectMap res; TryAgain: res = sys_mmap(addr, size, prot, sysflags, fd, off); @@ -418,10 +448,11 @@ TryAgain: errno = EEXIST; } else if (should_untrack) { errno = ENOMEM; - } else { - addr += gransz; + } else if (--tries && (addr = __maps_pickaddr(size))) { errno = olderr; goto TryAgain; + } else { + errno = ENOMEM; } } __maps_free(map); @@ -483,58 +514,15 @@ static void *__mmap_impl(char *addr, size_t size, int prot, int flags, int fd, } } - // mmap works fine on unix - if (!IsWindows()) - return __mmap_chunk(addr, size, prot, flags, fd, off, pagesz, gransz); + // try to pick our own addresses on windows which are higher up in the + // vaspace. this is important so that conflicts are less likely, after + // forking when resurrecting mappings, because win32 has a strong pref + // with lower memory addresses which may get assigned to who knows wut + if (IsWindows() && !addr) + if (!(addr = __maps_pickaddr(size))) + return (void *)enomem(); - // if the concept of pagesz wasn't exciting enough - if (!addr && !(flags & (MAP_FIXED | MAP_FIXED_NOREPLACE))) { - size_t rollo, rollo2, slab = (size + gransz - 1) & -gransz; - rollo = atomic_load_explicit(&__maps.rollo, memory_order_relaxed); - for (;;) { - if ((rollo2 = rollo + slab) > WINMAXX) { - rollo = 0; - rollo2 = slab; - } - if (atomic_compare_exchange_weak_explicit(&__maps.rollo, &rollo, rollo2, - memory_order_acq_rel, - memory_order_relaxed)) { - addr = (char *)WINBASE + rollo; - break; - } - } - } - - // windows forbids unmapping a subset of a map once it's made - if (size <= gransz || size > 100 * 1024 * 1024) - return __mmap_chunk(addr, size, prot, flags, fd, off, pagesz, gransz); - - // so we create a separate map for each granule in the mapping - if (!(flags & MAP_FIXED)) { - while (__maps_overlaps(addr, size, pagesz)) { - if (flags & MAP_FIXED_NOREPLACE) - return (void *)eexist(); - addr += gransz; - } - } - char *res = addr; - while (size) { - char *got; - size_t amt = MIN(size, gransz); - got = __mmap_chunk(addr, amt, prot, flags, fd, off, pagesz, gransz); - if (got != addr) { - if (got != MAP_FAILED) - __munmap(got, amt); - if (addr > res) - __munmap(res, addr - res); - errno = EAGAIN; - return MAP_FAILED; - } - size -= amt; - addr += amt; - off += amt; - } - return res; + return __mmap_chunk(addr, size, prot, flags, fd, off, pagesz, gransz); } static void *__mmap(char *addr, size_t size, int prot, int flags, int fd, @@ -552,7 +540,7 @@ static void *__mmap(char *addr, size_t size, int prot, int flags, int fd, return (void *)enomem(); if (!size || (uintptr_t)addr + size < size) return (void *)einval(); - if (size > WINMAXX) + if (size > MAX_SIZE) return (void *)enomem(); if (__maps.count * pagesz + size > __virtualmax) return (void *)enomem(); @@ -697,9 +685,9 @@ static void *__mremap(char *old_addr, size_t old_size, size_t new_size, return (void *)einval(); // check for big size - if (old_size > WINMAXX) + if (old_size > MAX_SIZE) return (void *)enomem(); - if (new_size > WINMAXX) + if (new_size > MAX_SIZE) return (void *)enomem(); // check for overflow diff --git a/libc/intrin/rand64.c b/libc/intrin/rand64.c index 0014d0de9..73308daa2 100644 --- a/libc/intrin/rand64.c +++ b/libc/intrin/rand64.c @@ -25,11 +25,9 @@ #include "libc/thread/thread.h" #include "libc/thread/tls.h" -static struct { - int thepid; - uint128_t thepool; - pthread_spinlock_t lock; -} g_rand64; +static int _rand64_pid; +static unsigned __int128 _rand64_pool; +pthread_mutex_t _rand64_lock_obj = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; /** * Returns nondeterministic random data. @@ -39,19 +37,17 @@ static struct { * the case even across forks and threads, whose sequences will differ. * * @see rdseed(), rdrand(), rand(), random(), rngset() - * @note this function takes 5 cycles (30 if `__threaded`) - * @note this function is not intended for cryptography * @note this function passes bigcrush and practrand + * @asyncsignalsafe */ uint64_t _rand64(void) { void *p; uint128_t s; - if (__threaded) - pthread_spin_lock(&g_rand64.lock); - if (__pid == g_rand64.thepid) { - s = g_rand64.thepool; // normal path + pthread_mutex_lock(&_rand64_lock_obj); + if (__pid == _rand64_pid) { + s = _rand64_pool; // normal path } else { - if (!g_rand64.thepid) { + if (!_rand64_pid) { if (AT_RANDOM && (p = (void *)__getauxval(AT_RANDOM).value)) { // linux / freebsd kernel supplied entropy memcpy(&s, p, 16); @@ -61,13 +57,13 @@ uint64_t _rand64(void) { } } else { // blend another timestamp on fork contention - s = g_rand64.thepool ^ rdtsc(); + s = _rand64_pool ^ rdtsc(); } // blend the pid on startup and fork contention s ^= __pid; - g_rand64.thepid = __pid; + _rand64_pid = __pid; } - g_rand64.thepool = (s *= 15750249268501108917ull); // lemur64 - pthread_spin_unlock(&g_rand64.lock); + _rand64_pool = (s *= 15750249268501108917ull); // lemur64 + pthread_mutex_unlock(&_rand64_lock_obj); return s >> 64; } diff --git a/libc/intrin/randaddr.c b/libc/intrin/randaddr.c deleted file mode 100644 index 672d909e6..000000000 --- a/libc/intrin/randaddr.c +++ /dev/null @@ -1,26 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-β”‚ -β”‚ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi β”‚ -β•žβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•‘ -β”‚ Copyright 2024 Justine Alexandra Roberts Tunney β”‚ -β”‚ β”‚ -β”‚ Permission to use, copy, modify, and/or distribute this software for β”‚ -β”‚ any purpose with or without fee is hereby granted, provided that the β”‚ -β”‚ above copyright notice and this permission notice appear in all copies. β”‚ -β”‚ β”‚ -β”‚ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL β”‚ -β”‚ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED β”‚ -β”‚ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE β”‚ -β”‚ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL β”‚ -β”‚ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR β”‚ -β”‚ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER β”‚ -β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ -β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ -β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/intrin/maps.h" - -void *randaddr(void) { - static unsigned long lcg = 1; - lcg *= 6364136223846793005; - lcg += 1442695040888963407; - return (void *)(lcg >> 48 << 28); -} diff --git a/libc/proc/fork.c b/libc/proc/fork.c index bc7bfbf2b..238fe281b 100644 --- a/libc/proc/fork.c +++ b/libc/proc/fork.c @@ -48,6 +48,7 @@ __static_yoink("_pthread_atfork"); +extern pthread_mutex_t _rand64_lock_obj; extern pthread_mutex_t _pthread_lock_obj; static void _onfork_prepare(void) { @@ -56,10 +57,12 @@ static void _onfork_prepare(void) { _pthread_lock(); __maps_lock(); __fds_lock(); + pthread_mutex_lock(&_rand64_lock_obj); LOCKTRACE("READY TO ROCK AND ROLL"); } static void _onfork_parent(void) { + pthread_mutex_unlock(&_rand64_lock_obj); __fds_unlock(); __maps_unlock(); _pthread_unlock(); @@ -69,6 +72,7 @@ static void _onfork_parent(void) { static void _onfork_child(void) { __fds_lock_obj = (pthread_mutex_t)PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; + _rand64_lock_obj = (pthread_mutex_t)PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; _pthread_lock_obj = (pthread_mutex_t)PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; atomic_store_explicit(&__maps.lock, 0, memory_order_relaxed); atomic_store_explicit(&__get_tls()->tib_relock_maps, 0, memory_order_relaxed); diff --git a/test/libc/calls/madvise_test.c b/test/libc/calls/madvise_test.c index e36cdb449..dc595e7ae 100644 --- a/test/libc/calls/madvise_test.c +++ b/test/libc/calls/madvise_test.c @@ -82,6 +82,8 @@ TEST(madvise, subPages) { } TEST(madvise, madvWillNeed_unmappedRegion) { + if (IsWindows()) + return; // needs carving char *p; ASSERT_NE(MAP_FAILED, (p = mmap(0, getgransize() * 3, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); @@ -96,6 +98,8 @@ TEST(madvise, madvWillNeed_unmappedRegion) { } TEST(madvise, madvFree_unmappedRegion) { + if (IsWindows()) + return; // needs carving char *p; ASSERT_NE(MAP_FAILED, (p = mmap(0, getgransize() * 3, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); diff --git a/test/libc/intrin/kprintf_test.c b/test/libc/intrin/kprintf_test.c index 1ec8889ff..e6d17b336 100644 --- a/test/libc/intrin/kprintf_test.c +++ b/test/libc/intrin/kprintf_test.c @@ -275,6 +275,8 @@ TEST(ksnprintf, testMisalignedPointer_wontFormat) { } TEST(ksnprintf, testUnterminatedOverrun_truncatesAtPageBoundary) { + if (IsWindows()) + return; // needs carving char *m; char b[32]; int gran = getgransize(); diff --git a/test/libc/intrin/mmap_scalability_test.c b/test/libc/intrin/mmap_scalability_test.c index 46928abff..9f164a6e2 100644 --- a/test/libc/intrin/mmap_scalability_test.c +++ b/test/libc/intrin/mmap_scalability_test.c @@ -41,7 +41,7 @@ void map_unmap_one_page(void) { void *p; - if ((p = mmap(randaddr(), 1, PROT_READ | PROT_WRITE, + if ((p = mmap(__maps_randaddr(), 1, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) == MAP_FAILED) __builtin_trap(); if (munmap(p, 1)) @@ -61,8 +61,8 @@ int main() { int n = 10000; kprintf("%20s creating %d sparse maps...\n", "", n); for (int i = 0; i < n; ++i) { - if (mmap(randaddr(), 1, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, - -1, 0) == MAP_FAILED) + if (mmap(__maps_randaddr(), 1, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) == MAP_FAILED) __builtin_trap(); } diff --git a/test/libc/intrin/mmap_test.c b/test/libc/intrin/mmap_test.c index 7f765666f..7f91daed7 100644 --- a/test/libc/intrin/mmap_test.c +++ b/test/libc/intrin/mmap_test.c @@ -112,20 +112,23 @@ TEST(mmap, fixedTaken) { TEST(mmap, hint) { char *p; + if (IsWindows()) + return; // needs carving + // obtain four pages - ASSERT_NE(MAP_FAILED, (p = mmap(randaddr(), gransz * 4, PROT_READ, + ASSERT_NE(MAP_FAILED, (p = mmap(__maps_randaddr(), pagesz * 4, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); // unmap two of those pages - EXPECT_SYS(0, 0, munmap(p + gransz, gransz)); - EXPECT_SYS(0, 0, munmap(p + gransz * 3, gransz)); + EXPECT_SYS(0, 0, munmap(p + pagesz, pagesz)); + EXPECT_SYS(0, 0, munmap(p + pagesz * 3, pagesz)); // test AVAILABLE nonfixed nonzero addr is granted // - posix doesn't mandate this behavior (but should) // - freebsd always chooses for you (which has no acceptable workaround) // - netbsd manual claims it'll be like freebsd, but is actually like openbsd if (!IsFreebsd()) - ASSERT_EQ(p + gransz, mmap(p + gransz, gransz, PROT_READ, + ASSERT_EQ(p + pagesz, mmap(p + pagesz, pagesz, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)); // test UNAVAILABLE nonfixed nonzero addr picks something nearby @@ -134,23 +137,26 @@ TEST(mmap, hint) { // - freebsd goes about 16mb to the right // - qemu-user is off the wall /*if (!IsQemuUser()) { - q = mmap(p + gransz * 2, gransz, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, + q = mmap(p + pagesz * 2, pagesz, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - EXPECT_LE(ABS(q - (p + gransz * 2)), 128 * 1024 * 1024); - EXPECT_SYS(0, 0, munmap(q, gransz)); + EXPECT_LE(ABS(q - (p + pagesz * 2)), 128 * 1024 * 1024); + EXPECT_SYS(0, 0, munmap(q, pagesz)); }*/ // clean up - EXPECT_SYS(0, 0, munmap(p, gransz * 4)); + EXPECT_SYS(0, 0, munmap(p, pagesz * 4)); } TEST(mprotect, punchHoleAndFillHole) { char *p; int count = __maps.count; + if (IsWindows()) + return; // needs carving + // obtain memory ASSERT_NE(MAP_FAILED, - (p = mmap(randaddr(), gransz * 3, PROT_READ | PROT_WRITE, + (p = mmap(__maps_randaddr(), gransz * 3, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); ASSERT_EQ((count += IsWindows() ? 3 : 1), __maps.count); diff --git a/test/libc/intrin/mprotect_test.c b/test/libc/intrin/mprotect_test.c index a3df5a4b2..4c2a6a5c3 100644 --- a/test/libc/intrin/mprotect_test.c +++ b/test/libc/intrin/mprotect_test.c @@ -259,6 +259,8 @@ TEST(mprotect, weirdSize) { } TEST(mprotect, outerOverlap) { + if (IsWindows()) + return; // needs carving char *p; int gransz = getgransize(); EXPECT_NE(MAP_FAILED, (p = mmap(0, gransz * 3, PROT_READ | PROT_EXEC, diff --git a/test/libc/intrin/mremap_test.c b/test/libc/intrin/mremap_test.c index 4a6e704d7..57f99d4ac 100644 --- a/test/libc/intrin/mremap_test.c +++ b/test/libc/intrin/mremap_test.c @@ -42,8 +42,9 @@ TEST(mremap, dontMove_hasRoom_itMoves) { return; // NetBSD requires MREMAP_MAYMOVE char *p; int pagesz = getpagesize(); - ASSERT_NE(MAP_FAILED, (p = mmap(randaddr(), pagesz, PROT_READ | PROT_EXEC, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); + ASSERT_NE(MAP_FAILED, + (p = mmap(__maps_randaddr(), pagesz, PROT_READ | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); EXPECT_TRUE(testlib_memoryexists(p)); EXPECT_FALSE(testlib_memoryexists(p + pagesz)); ASSERT_SYS(0, p, mremap(p, pagesz, pagesz * 2, 0)); @@ -59,8 +60,9 @@ TEST(mremap, dontMove_noRoom_itFailsWithEnomem) { return; // NetBSD requires MREMAP_MAYMOVE char *p; int pagesz = getpagesize(); - ASSERT_NE(MAP_FAILED, (p = mmap(randaddr(), pagesz * 2, PROT_READ | PROT_EXEC, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); + ASSERT_NE(MAP_FAILED, + (p = mmap(__maps_randaddr(), pagesz * 2, PROT_READ | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); EXPECT_TRUE(testlib_memoryexists(p + pagesz * 0)); EXPECT_TRUE(testlib_memoryexists(p + pagesz * 1)); EXPECT_FALSE(testlib_memoryexists(p + pagesz * 2)); @@ -77,8 +79,9 @@ TEST(mremap, dontMove_noRoom_itFailsWithEnomem) { TEST(mremap, mayMove_noRoom_itRelocates) { char *p, *p2; int pagesz = getpagesize(); - ASSERT_NE(MAP_FAILED, (p = mmap(randaddr(), pagesz * 2, PROT_READ | PROT_EXEC, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); + ASSERT_NE(MAP_FAILED, + (p = mmap(__maps_randaddr(), pagesz * 2, PROT_READ | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); EXPECT_TRUE(testlib_memoryexists(p + pagesz * 0)); EXPECT_TRUE(testlib_memoryexists(p + pagesz * 1)); EXPECT_FALSE(testlib_memoryexists(p + pagesz * 2)); @@ -112,7 +115,7 @@ TEST(mremap, mayMove_noRoom_itRelocates) { TEST(mremap, bench) { #define N 10 long size = 1024 * 1024; - char *rollo = randaddr(); + char *rollo = __maps_randaddr(); char *addr[N]; // create mappings diff --git a/test/libc/intrin/munmap_test.c b/test/libc/intrin/munmap_test.c index 8ae6fb635..716c717ee 100644 --- a/test/libc/intrin/munmap_test.c +++ b/test/libc/intrin/munmap_test.c @@ -54,6 +54,8 @@ TEST(munmap, test) { } TEST(munmap, punchHoleInMemory) { + if (IsWindows()) + return; // needs carving char *p; ASSERT_NE(MAP_FAILED, (p = mmap(0, gransz * 3, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0))); @@ -72,6 +74,8 @@ TEST(munmap, punchHoleInMemory) { } TEST(munmap, memoryHasHole) { + if (IsWindows()) + return; // needs carving char *p; ASSERT_NE(MAP_FAILED, (p = mmap(0, gransz * 3, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0))); @@ -86,6 +90,8 @@ TEST(munmap, memoryHasHole) { } TEST(munmap, blanketFree) { + if (IsWindows()) + return; // needs carving char *p; ASSERT_NE(MAP_FAILED, (p = mmap(0, gransz * 3, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0))); @@ -104,6 +110,8 @@ TEST(munmap, blanketFree) { } TEST(munmap, trimLeft) { + if (IsWindows()) + return; // needs carving char *p; ASSERT_NE(MAP_FAILED, (p = mmap(0, gransz * 2, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0))); @@ -118,6 +126,8 @@ TEST(munmap, trimLeft) { } TEST(munmap, trimRight) { + if (IsWindows()) + return; // needs carving char *p; ASSERT_NE(MAP_FAILED, (p = mmap(0, gransz * 2, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0))); @@ -173,7 +183,7 @@ TEST(munmap, tinyFile_preciseUnmapSize) { // clang-format off TEST(munmap, tinyFile_mapThriceUnmapOnce) { - char *p = randaddr(); + char *p = __maps_randaddr(); ASSERT_SYS(0, 3, open("doge", O_RDWR | O_CREAT | O_TRUNC, 0644)); ASSERT_SYS (0, 5, write(3, "hello", 5)); ASSERT_EQ(p+gransz*0, mmap(p+gransz*0, gransz, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0)); diff --git a/test/libc/thread/pthread_create_test.c b/test/libc/thread/pthread_create_test.c index ad680cd10..697b8f1f0 100644 --- a/test/libc/thread/pthread_create_test.c +++ b/test/libc/thread/pthread_create_test.c @@ -21,7 +21,6 @@ #include "libc/calls/calls.h" #include "libc/calls/struct/sched_param.h" #include "libc/calls/struct/sigaction.h" -#include "libc/calls/struct/sigaltstack.h" #include "libc/calls/struct/siginfo.h" #include "libc/dce.h" #include "libc/errno.h" From 3374cbba73fe3014cdec6abb61172266a8ed1612 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sat, 20 Jul 2024 02:28:19 -0700 Subject: [PATCH 055/405] Release Cosmopolitan v3.5.6 --- libc/integral/normalize.inc | 2 +- libc/intrin/mmap.c | 4 +--- test/libc/calls/sigaltstack_test.c | 3 +-- test/libc/intrin/munmap_test.c | 4 +++- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/libc/integral/normalize.inc b/libc/integral/normalize.inc index ea2cd4328..de1e3a5b7 100644 --- a/libc/integral/normalize.inc +++ b/libc/integral/normalize.inc @@ -4,7 +4,7 @@ #define __COSMOPOLITAN_MAJOR__ 3 #define __COSMOPOLITAN_MINOR__ 5 -#define __COSMOPOLITAN_PATCH__ 5 +#define __COSMOPOLITAN_PATCH__ 6 #define __COSMOPOLITAN__ \ (100000000 * __COSMOPOLITAN_MAJOR__ + 1000000 * __COSMOPOLITAN_MINOR__ + \ __COSMOPOLITAN_PATCH__) diff --git a/libc/intrin/mmap.c b/libc/intrin/mmap.c index 72ebda766..4f6e90556 100644 --- a/libc/intrin/mmap.c +++ b/libc/intrin/mmap.c @@ -146,9 +146,7 @@ static int __muntrack(char *addr, size_t size, int pagesz, __maps.count -= 1; __maps_check(); } else if (IsWindows()) { - // you can't carve up memory maps on windows. our mmap() makes - // this not a problem (for non-enormous memory maps) by making - // independent mappings for each 64 kb granule, under the hood + // you can't carve up memory maps on windows ;_; rc = einval(); } else if (addr <= map_addr) { // shave off lefthand side of mapping diff --git a/test/libc/calls/sigaltstack_test.c b/test/libc/calls/sigaltstack_test.c index 7efdc7cbd..c2ed85c42 100644 --- a/test/libc/calls/sigaltstack_test.c +++ b/test/libc/calls/sigaltstack_test.c @@ -32,9 +32,8 @@ TEST(sigaltstack, badFlag) { TEST(sigaltstack, disable) { struct sigaltstack ss; + EXPECT_SYS(0, 0, sigaltstack(0, &ss)); ss.ss_flags = SS_DISABLE; - ss.ss_size = 0; - ss.ss_sp = 0; EXPECT_SYS(0, 0, sigaltstack(&ss, 0)); EXPECT_SYS(0, 0, sigaltstack(0, &ss)); EXPECT_EQ(SS_DISABLE, ss.ss_flags); diff --git a/test/libc/intrin/munmap_test.c b/test/libc/intrin/munmap_test.c index 716c717ee..a664ef520 100644 --- a/test/libc/intrin/munmap_test.c +++ b/test/libc/intrin/munmap_test.c @@ -183,7 +183,9 @@ TEST(munmap, tinyFile_preciseUnmapSize) { // clang-format off TEST(munmap, tinyFile_mapThriceUnmapOnce) { - char *p = __maps_randaddr(); + char *p; + ASSERT_NE(MAP_FAILED, (p = mmap(0, gransz*4, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0))); + ASSERT_SYS(0, 0, munmap(p, gransz*4)); ASSERT_SYS(0, 3, open("doge", O_RDWR | O_CREAT | O_TRUNC, 0644)); ASSERT_SYS (0, 5, write(3, "hello", 5)); ASSERT_EQ(p+gransz*0, mmap(p+gransz*0, gransz, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0)); From 421a819d88c06c4b83de41f72c70208efb8c0708 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sat, 20 Jul 2024 03:23:37 -0700 Subject: [PATCH 056/405] Fix bug in munmap_test --- test/libc/intrin/munmap_test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/libc/intrin/munmap_test.c b/test/libc/intrin/munmap_test.c index a664ef520..9bf2ef344 100644 --- a/test/libc/intrin/munmap_test.c +++ b/test/libc/intrin/munmap_test.c @@ -184,8 +184,8 @@ TEST(munmap, tinyFile_preciseUnmapSize) { // clang-format off TEST(munmap, tinyFile_mapThriceUnmapOnce) { char *p; - ASSERT_NE(MAP_FAILED, (p = mmap(0, gransz*4, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0))); - ASSERT_SYS(0, 0, munmap(p, gransz*4)); + ASSERT_NE(MAP_FAILED, (p = mmap(0, gransz*5, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0))); + ASSERT_SYS(0, 0, munmap(p, gransz*5)); ASSERT_SYS(0, 3, open("doge", O_RDWR | O_CREAT | O_TRUNC, 0644)); ASSERT_SYS (0, 5, write(3, "hello", 5)); ASSERT_EQ(p+gransz*0, mmap(p+gransz*0, gransz, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0)); From 527aaa41eb6d4db9a1fe8e768e36c62d449b102f Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sat, 20 Jul 2024 03:34:37 -0700 Subject: [PATCH 057/405] Prevent MODE=tiny ShowCrashReports() looping --- libc/log/minicrash.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libc/log/minicrash.c b/libc/log/minicrash.c index 7197b8ce9..e6c7188b0 100644 --- a/libc/log/minicrash.c +++ b/libc/log/minicrash.c @@ -73,4 +73,5 @@ relegated dontinstrument void __minicrash(int sig, siginfo_t *si, void *arg) { ctx ? ctx->uc_mcontext.PC : 0, DescribeBacktrace(ctx ? (struct StackFrame *)ctx->uc_mcontext.BP : (struct StackFrame *)__builtin_frame_address(0))); + _Exit(1); } From 626a5d02ee4c08ef460a81c83d46ee6c18ad08e9 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sat, 20 Jul 2024 03:47:22 -0700 Subject: [PATCH 058/405] Add missing lock statement --- libc/intrin/mmap.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libc/intrin/mmap.c b/libc/intrin/mmap.c index 4f6e90556..267f16742 100644 --- a/libc/intrin/mmap.c +++ b/libc/intrin/mmap.c @@ -312,7 +312,9 @@ struct Map *__maps_alloc(void) { map->prot = PROT_READ | PROT_WRITE; map->flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NOFORK; map->hand = sys.maphandle; + __maps_lock(); __maps_insert(map++); + __maps_unlock(); map->addr = MAP_FAILED; for (int i = 1; i < gransz / sizeof(struct Map) - 1; ++i) __maps_free(map + i); From 7996bf67b5e31d624d427c6dfe48e07e5842e727 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sat, 20 Jul 2024 03:48:57 -0700 Subject: [PATCH 059/405] Release Cosmopolitan v3.5.7 --- libc/integral/normalize.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libc/integral/normalize.inc b/libc/integral/normalize.inc index de1e3a5b7..2790ddf2a 100644 --- a/libc/integral/normalize.inc +++ b/libc/integral/normalize.inc @@ -4,7 +4,7 @@ #define __COSMOPOLITAN_MAJOR__ 3 #define __COSMOPOLITAN_MINOR__ 5 -#define __COSMOPOLITAN_PATCH__ 6 +#define __COSMOPOLITAN_PATCH__ 7 #define __COSMOPOLITAN__ \ (100000000 * __COSMOPOLITAN_MAJOR__ + 1000000 * __COSMOPOLITAN_MINOR__ + \ __COSMOPOLITAN_PATCH__) From 29ce25c767d9637bdde832950172e18bbf4baecf Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sat, 20 Jul 2024 10:04:22 -0700 Subject: [PATCH 060/405] Start writing formal specification for APE --- ape/specification.md | 271 ++++++++++++++++++++++++++++++ libc/thread/pthread_cond_signal.c | 2 +- 2 files changed, 272 insertions(+), 1 deletion(-) create mode 100644 ape/specification.md diff --git a/ape/specification.md b/ape/specification.md new file mode 100644 index 000000000..95afcc12e --- /dev/null +++ b/ape/specification.md @@ -0,0 +1,271 @@ +# Actually Portable Executable Specification v0.1 + +Actually Portable Executable (APE) is an executable file format that +polyglots the Windows Portable Executable (PE) format with a UNIX Sixth +Edition style shell script that doesn't have a shebang. This makes it +possible to produce a single file binary that executes on the stock +installations of the many OSes and architectures. + +## Supported OSes and Architectures + +- AMD64 + - Linux + - MacOS + - Windows + - FreeBSD + - OpenBSD + - NetBSD + - BIOS + +- ARM64 + - Linux + - MacOS + - FreeBSD + - Windows (non-native) + +## File Header + +APE defines three separate file magics, all of which are 8 characters +long. Any file that starts with one of these magic values can be +considered an APE program. + +### (1) APE MZ Magic + +- ASCII: `MZqFpD='` +- Hex: 4d 5a 71 46 70 44 3d 27 + +This is the canonical magic used by almost all APE programs. It enables +maximum portability between OSes. When interpreted as a shell script, it +is assiging a single quoted string to an unused variable. The shell will +then ignore subsequent binary content that's placed inside the string. + +It is strongly recommended that this magic value be immediately followed +by a newline (\n or hex 0a) character. Some shells, e.g. FreeBSD SH and +Zsh impose a binary safety check before handing off files that don't +have a shebang to `/bin/sh`. That check applies to the first line, which +can't contain NUL characters. + +The letters were carefully chosen so as to be valid x86 instructions in +all operating modes. This makes it possible to store a BIOS bootloader +disk image inside an APE binary. For example, simple CLI programs built +with Cosmopolitan Libc will boot from BIOS into long mode if they're +treated as a floppy disk image. + +The letters also allow for the possibility of being treated on x86-64 as +a flat executable, where the PE / ELF / Mach-O executable structures are +ignored, and execution simply begins at the beginning of the file, +similar to how MS-DOS .COM binaries work. + +The 0x4a relative offset of the magic causes execution to jump into the +MS-DOS stub defined by Portable Executable. APE binaries built by Cosmo +Libc use tricks in the MS-DOS stub to check the operating mode and then +jump to the appropriate entrypoint, e.g. `_start()`. + +#### Decoded as i8086 + +```asm + dec %bp + pop %dx + jno 0x4a + jo 0x4a +``` + +#### Decoded as i386 + +```asm + push %ebp + pop %edx + jno 0x4a + jo 0x4a +``` + +#### Decoded as x86-64 + +```asm + rex.WRB + pop %r10 + jno 0x4a + jo 0x4a +``` + +### (2) APE UNIX-Only Magic + +- ASCII: `jartsr='` +- Hex: 6a 61 72 74 73 72 3d 27 + +Being a novel executable format that was first published in 2020, the +APE file format is less understood by industry tools compared to the PE, +ELF, and Mach-O executable file formats, which have been around for +decades. For this reason, APE programs that use the MZ magic above can +attract attention from Windows AV software, which may be unwanted by +developers who aren't interested in targeting the Windows platform. +Therefore the `jartsr='` magic is defined which enables the creation of +APE binaries that can safely target all non-Windows platforms. Even +though this magic is less common, APE interpreters and binfmt-misc +installations MUST support this. + +It is strongly recommended that this magic value be immediately followed +by a newline (\n or hex 0a) character. Some shells, e.g. FreeBSD SH and +Zsh impose a binary safety check before handing off files that don't +have a shebang to `/bin/sh`. That check applies to the first line, which +can't contain NUL characters. + +The letters were carefully chosen so as to be valid x86 instructions in +all operating modes. This makes it possible to store a BIOS bootloader +disk image inside an APE binary. For example, simple CLI programs built +with Cosmopolitan Libc will boot from BIOS into long mode if they're +treated as a floppy disk image. + +The letters also allow for the possibility of being treated on x86-64 as +a flat executable, where the PE / ELF / Mach-O executable structures are +ignored, and execution simply begins at the beginning of the file, +similar to how MS-DOS .COM binaries work. + +The 0x78 relative offset of the magic causes execution to jump into the +MS-DOS stub defined by Portable Executable. APE binaries built by Cosmo +Libc use tricks in the MS-DOS stub to check the operating mode and then +jump to the appropriate entrypoint, e.g. `_start()`. + +#### Decoded as i8086 / i386 / x86-64 + +```asm + push $0x61 + jb 0x78 + jae 0x78 +``` + +### (3) APE Debug Magic + +- ASCII: `APEDBG='` +- Hex: 41 50 45 44 42 47 3d 27 + +While APE files must be valid shell scripts, in practice, UNIX systems +will oftentimes be configured to provide a faster safer alternative to +loading an APE binary through `/bin/sh`. The Linux Kernel can be patched +to have execve() recognize the APE format and directly load its embedded +ELF header. Linux systems can also use binfmt-misc to recognize APE's MZ +and jartsr magic, and pass them to a userspace program named `ape` that +acts as an interpreter. In such environments, the need sometimes arises +to be able to test that the `/bin/sh` is working correctly, in which +case the `APEDBG='` magic is RECOMMENDED. + +APE interpreters, execve() implementations, and binfmt-misc installs +MUST ignore this magic. If necessary, steps can be taken to help files +with this magic be passed to `/bin/sh` like a normal shebang-less shell +script for execution. + +## Embedded ELF Header + +APE binaries MAY embed an ELF header inside them. Unlike conventional +executable file formats, this header is not stored at a fixed offset. +It's instead encoded as octal escape codes in a shell script `printf` +statement. For example: + +``` +printf '\177ELF\2\1\1\011\0\0\0\0\0\0\0\0\2\0\076\0\1\0\0\0\166\105\100\000\000\000\000\000\060\013\000\000\000\000\000\000\000\000\000\000\000\000\000\000\165\312\1\1\100\0\070\0\005\000\0\0\000\000\000\000' +``` + +This `printf` statement MUST appear in the first 8192 bytes of the APE +executable, so as to limit how much of the initial portion of a file an +intepreter must load. + +Multiple such `printf` statements MAY appear in hte first 8192 bytes, in +order to specify multiple architectures. For example, fat binaries built +by the `apelink` program (provided by Cosmo Libc) will have two encoded +ELF headers, for amd64 and arm64, each of which point into the proper +file offsets for their respective native code. Therefore, kernels and +interpreters which load the APE format directly MUST check the +`e_machine` field of the `Elf64_Ehdr` that's decoded from the octal +codes, before accepting a `printf` shell statement as valid. + +These printf statements MUST always use only unescaped ASCII characters +or octal escape codes. These printf statements MUST NOT use space saving +escape codes such as `\n`. For example, rather than saying `\n` it would +be valid to say `\012` instead. It's also valid to say `\12` but only if +the encoded characters that follow aren't an octal digit. + +For example, the following algorithm may be used for parsing octal: + +```c +static int ape_parse_octal(const unsigned char page[8192], int i, int *pc) +{ + int c; + if ('0' <= page[i] && page[i] <= '7') { + c = page[i++] - '0'; + if ('0' <= page[i] && page[i] <= '7') { + c *= 8; + c += page[i++] - '0'; + if ('0' <= page[i] && page[i] <= '7') { + c *= 8; + c += page[i++] - '0'; + } + } + *pc = c; + } + return i; +} +``` + +APE aware interpreters SHOULD only take `e_machine` into consideration. +It is the responsibility of the `_start()` function to detect the OS. +Therefore, multiple `printf` statements are only embedded in the shell +script for different CPU architectures. + +The OS ABI field of an APE embedded `Elf64_Ehdr` SHOULD be set to +`ELFOSABI_FREEBSD`, since it's the only UNIX OS APE supports that +actually checks the field. However different values MAY be chosen for +binaries that don't intend to have FreeBSD in their support vector. + +Counter-intuitively, the ARM64 ELF header is used on the MacOS ARM64 +platform when loading from fat binaries. + +## Embedded Mach-O Header (x86-64 only) + +APE shell scripts that support MacOS on AMD64 must use the `dd` command +in a very specific way to specify how the embedded binary Macho-O header +is copied backward to the start of the file. For example: + +``` +dd if="$o" of="$o" bs=8 skip=433 count=66 conv=notrunc +``` + +These `dd` statements have traditionally been generated by the GNU as +and ld.bfd programs by encoding ASCII into 64-bit linker relocations, +which necessitated a fixed width for integer values. It took several +iterations over APE's history before we eventually got it right: + +- `arg=" 9293"` is how we originally had ape do it +- `arg=$(( 9293))` b/c busybox sh disliked quoted space +- `arg=9293 ` is generated by modern apelink program + +Software that parses the APE file format, which needs to extract to be +able extract the Macho-O x86-64 header SHOULD support the old binaries +that use the previous encodings. To make backwards compatibility simple +the following regular expression may be used, which generalizes to all +defined formats: + +```c +regcomp(&rx, + "bs=" // dd block size arg + "(['\"] *)?" // #1 optional quote w/ space + "(\\$\\(\\( *)?" // #2 optional math w/ space + "([[:digit:]]+)" // #3 + "( *\\)\\))?" // #4 optional math w/ space + "( *['\"])?" // #5 optional quote w/ space + " +" // + "skip=" // dd skip arg + "(['\"] *)?" // #6 optional quote w/ space + "(\\$\\(\\( *)?" // #7 optional math w/ space + "([[:digit:]]+)" // #8 + "( *\\)\\))?" // #9 optional math w/ space + "( *['\"])?" // #10 optional quote w/ space + " +" // + "count=" // dd count arg + "(['\"] *)?" // #11 optional quote w/ space + "(\\$\\(\\( *)?" // #12 optional math w/ space + "([[:digit:]]+)", // #13 + REG_EXTENDED); +``` + +For further details, see the canonical implementation in +`cosmopolitan/tool/build/assimilate.c`. diff --git a/libc/thread/pthread_cond_signal.c b/libc/thread/pthread_cond_signal.c index 3e3c54f7b..e490bb402 100644 --- a/libc/thread/pthread_cond_signal.c +++ b/libc/thread/pthread_cond_signal.c @@ -26,7 +26,7 @@ * pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; * // ... * pthread_mutex_lock(&lock); - * pthread_cond_signal(&cond, &lock); + * pthread_cond_signal(&cond); * pthread_mutex_unlock(&lock); * * This function has no effect if there aren't any threads currently From d3f87f4c64adf410a5a202716eca5ca716ef7078 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sat, 20 Jul 2024 11:21:26 -0700 Subject: [PATCH 061/405] Upgrade to cosmocc v3.5.7 --- Makefile | 32 +++++++++++++++++--------------- ape/BUILD.mk | 4 ++-- build/bootstrap/ar | Bin 210927 -> 0 bytes build/bootstrap/chmod | Bin 182967 -> 0 bytes build/bootstrap/cp | Bin 264367 -> 0 bytes build/bootstrap/echo | Bin 164055 -> 0 bytes build/bootstrap/fixupobj | Bin 206822 -> 0 bytes build/bootstrap/gzip | Bin 432879 -> 0 bytes build/bootstrap/mkdeps | Bin 250663 -> 0 bytes build/bootstrap/objbincopy | Bin 191487 -> 0 bytes build/bootstrap/package | Bin 250528 -> 0 bytes build/bootstrap/pecheck | Bin 65536 -> 0 bytes build/bootstrap/rm | Bin 246151 -> 0 bytes build/bootstrap/touch | Bin 184703 -> 0 bytes build/bootstrap/zipcopy | Bin 190839 -> 0 bytes build/bootstrap/zipobj | Bin 522122 -> 0 bytes build/sanitycheck | 2 +- test/libc/mem/BUILD.mk | 4 ++-- tool/cosmocc/package.sh | 6 ++++-- 19 files changed, 26 insertions(+), 22 deletions(-) delete mode 100755 build/bootstrap/ar delete mode 100755 build/bootstrap/chmod delete mode 100755 build/bootstrap/cp delete mode 100755 build/bootstrap/echo delete mode 100755 build/bootstrap/fixupobj delete mode 100755 build/bootstrap/gzip delete mode 100755 build/bootstrap/mkdeps delete mode 100755 build/bootstrap/objbincopy delete mode 100755 build/bootstrap/package delete mode 100755 build/bootstrap/pecheck delete mode 100755 build/bootstrap/rm delete mode 100755 build/bootstrap/touch delete mode 100755 build/bootstrap/zipcopy delete mode 100755 build/bootstrap/zipobj diff --git a/Makefile b/Makefile index b6d080060..b70197109 100644 --- a/Makefile +++ b/Makefile @@ -101,19 +101,20 @@ XARGS ?= xargs -P4 -rs8000 DOT ?= dot CLANG = clang TMPDIR = o/tmp -AR = build/bootstrap/ar -CP = build/bootstrap/cp -RM = build/bootstrap/rm -f -GZIP = build/bootstrap/gzip -ECHO = build/bootstrap/echo -CHMOD = build/bootstrap/chmod -TOUCH = build/bootstrap/touch -PKG = build/bootstrap/package -MKDEPS = build/bootstrap/mkdeps -ZIPOBJ = build/bootstrap/zipobj -ZIPCOPY = build/bootstrap/zipcopy -PECHECK = build/bootstrap/pecheck -FIXUPOBJ = build/bootstrap/fixupobj +AR = $(BOOTSTRAP)/ar.ape +CP = $(BOOTSTRAP)/cp.ape +RM = $(BOOTSTRAP)/rm.ape -f +GZIP = $(BOOTSTRAP)/gzip.ape +ECHO = $(BOOTSTRAP)/echo.ape +CHMOD = $(BOOTSTRAP)/chmod.ape +TOUCH = $(BOOTSTRAP)/touch.ape +PKG = $(BOOTSTRAP)/package.ape +MKDEPS = $(BOOTSTRAP)/mkdeps +ZIPOBJ = $(BOOTSTRAP)/zipobj +ZIPCOPY = $(BOOTSTRAP)/zipcopy +PECHECK = $(BOOTSTRAP)/pecheck +FIXUPOBJ = $(BOOTSTRAP)/fixupobj +OBJBINCOPY = $(BOOTSTRAP)/objbincopy MKDIR = build/bootstrap/mkdir -p COMPILE = build/bootstrap/compile -V9 -M2048m -P8192 $(QUOTA) @@ -149,9 +150,10 @@ export MODE export SOURCE_DATE_EPOCH export TMPDIR -COSMOCC = .cosmocc/3.3.5 +COSMOCC = .cosmocc/3.5.7 +BOOTSTRAP = $(COSMOCC)/bin TOOLCHAIN = $(COSMOCC)/bin/$(ARCH)-linux-cosmo- -DOWNLOAD := $(shell build/download-cosmocc.sh $(COSMOCC) 3.3.5 db78fd8d3f8706e9dff4be72bf71d37a3f12062f212f407e1c33bc4af3780dd0) +DOWNLOAD := $(shell build/download-cosmocc.sh $(COSMOCC) 3.5.7 596876951b62ad2530c63afc40edd805d751fcb2416e544d249af04ad00bb4ed) AS = $(TOOLCHAIN)as CC = $(TOOLCHAIN)gcc diff --git a/ape/BUILD.mk b/ape/BUILD.mk index 3bbf00e60..25542e0d5 100644 --- a/ape/BUILD.mk +++ b/ape/BUILD.mk @@ -218,10 +218,10 @@ o/$(MODE)/ape/loader-xnu-clang.asm: ape/loader.c @$(COMPILE) -AOBJECTIFY.c $(CLANG) -DSUPPORT_VECTOR=8 -S -g0 $(APE_LOADER_FLAGS) o/$(MODE)/ape/ape.elf: o/$(MODE)/ape/ape.elf.dbg - @$(COMPILE) -AOBJBINCOPY -w build/bootstrap/objbincopy -f -o $@ $< + @$(COMPILE) -AOBJBINCOPY -w $(OBJBINCOPY) -f -o $@ $< o/$(MODE)/ape/ape.macho: o/$(MODE)/ape/ape.elf.dbg - @$(COMPILE) -AOBJBINCOPY -w build/bootstrap/objbincopy -fm -o $@ $< + @$(COMPILE) -AOBJBINCOPY -w $(OBJBINCOPY) -fm -o $@ $< APE_LOADER_LDFLAGS = \ -static \ diff --git a/build/bootstrap/ar b/build/bootstrap/ar deleted file mode 100755 index 0a671a3b1ab89428490781116f5bda6788605950..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 210927 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∨aK@&B^e;B) zUp6LP(1S7N7@&e3fRX8-*QSl)KCi|8gx@YOs+D-|I}ziKI~UtI2`ROuRW{> zl4^pKL5@>Kue|IDwhB%9^rY3>YBrpiso?-}<$t4Sb- zlxBrB1?`wF+EX&xq>z>L9py(MnP#D!A#tZuo$;ZYPOvj-*7m475AhxpKXmZM9okmG z?M)Pam`9xj7&AEMiG4@(^vP{UIsm_LpgQ=UfF*^V)H_Z$u{eRt6E@-LJ?B9tRCdIcTzr{`L5Jc=k*GW&raJzV#vF z*NdxnqcUTp)oE&nr-%d+!4C#IF}SD}d7L2uO30-}0i?xlR$8Uzr=kk|b~PfL`8h_P zNGj@QRl$yy$CrwfwOUkl92G88pVnqz*0{DQ7$^~@xwDZ8ldZNyWwv#tqUG0{I+?;G zP?XUyn0dF$7&^s?A{0~UMMwKE3vv+}r$=J&`s~BtREmTYkmEHPYS<9Ce(MS8!ow-+ z;NR!qX1l_cQT0fZ zTBUV!X&5nqAsqLd!J3ESBw#qEe1R@|6kkk%>UoS?N*_suHR<<`Br+R!9%u-<3@LHv zK8M-lA∋MC@cv;rED^W)ut#n7~{^HTZm%W{AWsN}SQvN^^WmyeZ!$CA5|3$Oe>F zWlzTZFH0{L7j$m?VZhOd+6iqj zjD!W-4F5Dtqm5vm!i4fa#CUybs24j3O%7+Rt#H|u(?r=`pbD0d$B~VRrCx4BH#Ajr z+f9$HUwq~J!!-8HcA(b7R{ZGAK-Ssl>{^9Voa&bC?P0mZi|`&cuqH$>hm?4dGSZep zz?D&=jSLeFEF}nR;sp*2B~#U?>)vqC&^Qh0>NdO@j>3ISG~_*2H^3$2Y=Vavs$HRt zlj4ybm|{^Oz&N6r62r8oCK}tU$vX%;mWMFEid9`=ZwV{YC4a_4?syKa2g8f}2@l)M zDY1`gNF8#up(2}=YK5+1^^wqrXE3;KVLY$cwcfOCu(GZ48g!xDA8wN7>t7F;JpOd= zATJk@2%ttCVTyyf16~MrENe}X_8bahgZxLtW_B^n14*)^yZ@BVlOm|XiBJNY%z^%1 zM5&Y+sM3;KsqByn^TI!h+!K7nBh^qanuh^r^Kb!k4h9jBY?2BWCHULRK8j#OMfn1*AvmatY1kFFl#@K%`mP9VY=tOi7SYg@FyQk~y1{D0`N zoONgrqJy@H7^)Hp`4MI)ZG99*)jv*4RkA4WM#!eY23bA0vr?S3oCYm+2rNI@bcr!Y zZ=;1xs#XIW1_N@LSIoy5ov|DdESY zA&iMhZo}z&q&6eAtY31nVzyEnOqsp*UuA9>9+StoxL&p^IJS;oc}{&Z*3MwYd&!(F zBf%3L0YodlnBRig4KtwF(0OR9aI|{up1JlQ7RVfH~Lz=5Pa;=NrJh*Z}6I4PZL$O@KDxP^Y^I(EcVsn=rex z370yXu%NpM3%Z-Ipt}hRx|^_|y9o=rn+RNY6N&3?!p!a_GS}UN~9iZ(kmy9{F7&p?y6UU^HvO}rZT zvwGpShV6?cD_m@`%`wLA$z}&G&CP#fGhZHeSU%jXMWj%;v%uIY_nOipon12`eXNBT zf#WA7yZ)v7+jA~jj2(oN@l$Li=yiDk1x||cRw9uBzi9teCe}W6o5z!1ETZD^QW(JEh1LFW_3r} z)2A$-Ztg|M8W1&Zsi;!0ED?ak3gpE%giGJgmdEFYOP?44W`f{@ni$~jn3)6txcorPpUVsB2-@q`?NG+*qMlu@fP>oTF;mDdP0vIF44q*EP|#iUb( zWn>veCCjtoz>5Ga;i)JN%lC2&qD>P#2oGu`<}Pl{koU@l6){M%p?I+MscN3O1Lk)I zl=OPpEq;Y_s3hiio-w=VPp!?1qpD;V)Tlw;9=Ns&b;ICeb!4J|XS3x=%Tke8!<6+5 zq3uz;$)J2wS)2*R6L}_1bN!|dj^ouEO>qMUU4>9k==BT%-daOYFif_q##MfG*=pHi zv#>Cex8zv7!}o0L;T>z_7pBGALR|n<4P<2s2hfe;9 zE{f0*TB5~@5AV)Svqa*)RqF>9@V*4*IcU}5Hzx3b1irOlbvrHK=L&NU zTD6aEqs@}3eeH+YY_dOtpJmo-ZL>f(OYevhofn-fO*K;7X`7`}Gra_c%+e;Os~Re< zyUo%MGHC)~qHFQ8OxyY7O(ogY+7@|uWnN;I<30~t#xg7X*HIJpc!HbyN%OrQ!Pdj*_`{n;*NF;`=V;O z;pzoymfpfUL~hvxkE;ltVVIq*oHXUs*%#O`#WppvmA$C69yAmc{DHpiCHAO*?NR}W zKG>yYC*ICrd}`%5%a-?)W&rYADh3Fi2bKP0d^B<*vCFRxW*Rxx$sGw|r5UjLjEjWR z?*Q(B5!?pJQ7%5 z8gt6Zs?VF4rBqrecl?>f7k^fURerj}L@JXEXgV$}Wrv>21UD41y~b+^l=^Oo0jZM8 z+MqsTg1gW+Z_ycsH-?}5>-gf#R2`*XH_0@ho!%&^NPqXlpi8G!!OJh7pY{p9H6;@Njqqn&a^sJoJ3cekY0>jaa>X6iWehSgr)VeGoYp* ziMuh>A$F?^)xo-+eR9v_gE(lWrULP1Qmvxi>}}~>E%K9^L7Baw-*Yf{z}W!7*Bpe@D&}$L9E3cLYyim=yY=!QaL+!UY~iwD zk`fs4`43brevU8n$q&kazgD{9gM6~`$cIOH^rQ?E>YKZIZCq=h|5ae%LAbn~Q;<(O z7G{<7zKiD`*@bvn2m2E~(jw}pc(x2}#QbH!I&C zvSi5@aK{P|o?-mIGx692MHa*B!Woh)jjtq91~$e7U^8gZugq*S6YEurU2W6JSuo)D z7!{O;3ktQQ;ekv@(DLTmT`Za+DZ3-GD7rThpJNU2lDf`e3!`HJ9hf7Iy8rDq4(}5- z4ev$BEZLT9vSN|&C1DyVF0rD^OxQZLqJ{0;F~6#TZOE42`U_=Xf*VaPwPmI6UEG=g z;7?iS058IZXWjM3Q1{Q+`E)a+?e?h4d#JH+Qm8o+fy)`UF8qMNYK zfM&TQX<$LwMT}&nEEB_ZPuV_|)I`zm6rdf&9B&Szo6gY3z!B*(cdn!^)>i8N zOnclEufLTe3BS3K-Digt&h#JyN%;c`)UJc;9~Fd(7yU&#ycF{&nmJwu`bs`3#BNa3 z=wxHUR^d{9!x*G;fm$`ecR=NeQFJw;$a{stVSzYNV??=niE?gEciC$S;&T?T#A!00 zV<3Futgs%1;@*M9p{x^Y!01aE47(Rb=^ot#nBWC=dlS5_k>Ux(kWnaTZHKG3J)XLI z^oF;VP{`}ti72ofQYQ}jb18V;_r7xL^22}o@rSb7{temVV5}dy{&86#_rHKh6QZHegq(i*0(-(^o@mty zn}XANOs>dFoOco+Qw$$FpRHq+IAC!2L9NFsB|qr(P&FH%h$2<|}mT>EU;aqXJ=}zv!fcVp|m6V?u~-i{O^)Q4Hc5;_UCG zGN{&H?Xm?LC@|H>PHIGI3+Yefm7x^FE57#~s$kwQ(+((=biHVkP4?U;`qT@K#E84z z%)QIKEvTxYO{_xE&ohJV7Hg|V-KU?>o)zoOAyGFAD?WQPJR-pce zwus4ng9E7XSPfuAFG+UL=|Bq4(0$UMl*n`Ao!yRo2VG5ndp*I=+V9h06q+dXXYFJ8 zS^JbeYj2mHr)iWN?d{1@yME}S^4OiH3;&Z2;+3~zHwrgu7JIT==*f=Rlb!WF*)e)D z?^)w88WuRplyeOY0bHV>d6FF# zYg2*Erq(L4-oF{YK0SGV+GOPRyc!QruP)Dj6_?){XD^KC26VyJuy_%>jz85g3p#kF zsk$i(r>U%gLQhpRw_St%od$|=u<-IVVIdfjk>He@#e$FsHMoU#I8=j%D<3z;l40%&JvNCt>yf7AnyR%F7 z9GY)rJtTO7NKC|u3uas@1ks;?d;tntQNRq4oh9n-+Tb8Z47aJ-VhJNe_?OY{0il~N zUAh2T$52TW`@1-J%}PX(1?U=a2v42Q6SE&)n=8-l$rEh?&$C^L!;XGHikv9IV}DMt zy2q0m3ZJz0bdSi7t{HJ#y`K6KTkYb{e|a69_O@VYs_%MOTi}ZW+BE)-0$|&nzIuZN ztn1k$Q__xEgvb3ku3{rQ3PYlabhH`blpHm17Vk;Pb~m%-a#LKX{^FQ6Q}?M(veM|Q z9T9%+2(O6$w6%4d|GW+zvD*6dX{&hrYOB44R~l?bhzfqg^Vajir*>2opda-|X1*T_ z;@QR)6jFDp(SKhBRaHD%$+ss}Z{JF8D%G8@zQN<#XBIp(Ba2FM^Dhfkp|Nx#{>bpp l3!$E+>Q_5?6r?GQ?MC@0T5P?#IX2o0{J%Fd%^)?20029HOp5>j diff --git a/build/bootstrap/chmod b/build/bootstrap/chmod deleted file mode 100755 index e42818495ed163f99f066cbdbb6f5c06bd415703..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 182967 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 m<62R_A?HM;6PoOw-wlIpbWwx`5orK5XZ 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

^=y#wl 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 z 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

f z#9RAV-}TU{L2SCSIP$n<1T4?+Jc2cG*aYPs!~Ogj8jR9{ivnexV~he?#^i)hHoBgv zlbRTYaw_%s9Y!g|{*ppJX^bIzBQ)E2;=UG4l9b&NSrly?iO=x*cu`*asDaVCfDUXL zOI>U?5Bj0*K=Nfeu-~;N z7aGKJFF@Sl0N_tp`w(xdhUY}6PN43WC{`Y8bTe+4s=O>33)eo%`zpKX{g%qnK}!i- zRHRMFQY^X&`wVE7>zNuBlwHI~3X3u^d%|6f8Pd8L_p$l3%I@8C;?wj_@7O*<#FGjVSJ4p|F@I&huz7woas6tJ5ZX zO(BHV5>`cZ=5h?fkE}J;qfp#gu#S{cm2CGKJ2&&R1^S;rOSY9v9X2CuEO>k%qYO zfGY{P`vyd+*#5+~rlJzjl!xv?UP4=sb=R8<(j3j0d5_>e_D@mm*l~}{vke~cshC*m zXU7B1SipI?ah~-NC8ym;x=~_5b0;a;ags>4cGqY%kCJe`?6L#>`eQ`*5%1NmG%8uq z#f}zn^lChy*jQ|_M$cRl#yv;TLRe^YsEcmk-(iA}ZUS#kql#RH(C0qRx=t+PV%>F< zEzvN5DK@lXE!bL!P$aJpr7&FaX>?!318zGr2ZNy3 ztamvYunz~#_91=*@%i(nb_8jj@)k7P$Aiz=ejwKr^#|y(gOWa>P61BWin@kyy-Hb$5WF@P)rc7^ARsYXAU(`lU0Ul22hFhbr)=-OR>>)_ z+0) z6rU>B4lS9D)-D!P9`L#r^g#)Qjh3obHataRhI)u84)UgS>SSTvI({eyce{zCkP$>v zaD<0|glQ1jU=PJY5ZxKb7oZ>`9A<#@I8di)f`c3}+-YXZ6^sz!*G1z2gl@XB=`!df z3`(LnXyV}2D-lJOplifAI(5WO%zk+Dtvq@s52Xn_Pn!~l8Nh%PSwVm&_bhLHhlec` zK4~%~Jt99QriEU0yXp&Lm5V?A`E_vC-GL=xa$Up50$(i9rr{4100Zgl)f+5e+^Qbv zl6JxZJh9JlNg0@d6cSC41dJh0$x#hw{;HF7gEC#a*2PWe&rfJS^nmK5({uDSiU2?3 zgEzZ>+SxhDel~_qN$q_4w39zUwbRjTID diff --git a/build/bootstrap/cp b/build/bootstrap/cp deleted file mode 100755 index de2d52a67ef3b3261071d9d7bba367ac3e61badd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 264367 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¿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 diff --git a/build/bootstrap/fixupobj b/build/bootstrap/fixupobj deleted file mode 100755 index b59b55a5b22cd89d4009079f1dacf17749ee5bd0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 206822 zcmeFa3wRVo)<4`c$t07I(8DEcKrRi2n;OU)zd6cb64+Wp@<jZ4(EngPHj42J8Ne&Zc@sEoZ*h>TBgTx6Y9+e9Vkyn0a@HAj^;-X4viaT?cChjm^$RKi@%}I zv%`L{?T?RddtzJub5AU8S>*lPtMR)S`eokSM-O)F@7Ql{wjSMXc+q&U-@W;j1Fi<9 z#H9^clf2z-7P)!5qWwU1G6z44$~VR+Vjg4|NYy7=MukEr-?U@9+8+>o|`tN zu)MUiplk(~zJ?o-mN8;%;$p6PM4EL3H$0cCPERkWswyrmE-4U;xTV~vQJlE0qKGTN zciQ+BMQg^FNhKxRglVI!6joGSRH%iGNGl%!ZnhDLV(y5vhv&QV9KzjG($gO1=eV6y z(#LJsFn%0(q+7>XGe&$(f{VHIYVZuqIYi7MF=0ZuAoCIIDoTn9s){(&-xRL8uzW>PdR0+LQK87C zrx%x1i3KGkBhX+cXl<0UQY-xy6_Y*bcI)IDD#n_TnUNW(nXj#w!herh#G4>3yjF22 zX8Kw#eGZpSg^GavWr}Z&c@OMg*OmWomgoOD3H&x9Vx1IitkJeRDZ8h$`C1XVq3!

MAa+l&g{|D#|ONFkEjO6DB9(!^A>KqOSp8 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 AivR!s diff --git a/build/bootstrap/gzip b/build/bootstrap/gzip deleted file mode 100755 index 09bd2306bd412c0e96da88e6edd55555f0a2e4a7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 432879 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 r$gq?L~W@&nSc(Ibu_*73cgUXxmpv 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∨aK@&B^e;B)Up6LP(1S7N7@&e3 zfRX8-*QSl)KCi|8gx@YOs+D-|I}ziKI~UtI2`ROuRW{>l4^pKL5@>Kue|ID zwhB%9^rY3>YBrpiso?-}<$t4Sb-lxBrB1?`wF+EX&x zq>z>L9py(MnP#D!A#tZuo$;ZYPOvj-*7m475AhxpKXmZM9okmG?M)Pam`9xj7&AEM ziG4@(^vP{UIsm_LpgQ=UfF*^V)H_Z$u{eRt6E@-LJ?B9tRCdIcTzr{`L5Jc=k*GW&raJzV#vF*NdxnqcUTp)oE&n zr-%d+!4C#IF}SD}d7L2uO30-}0i?xlR$8Uzr=kk|b~PfL`8h_PNGj@QRl$yy$Crwf zwOUkl92G88pVnqz*0{DQ7$^~@xwDZ8ldZNyWwv#tqUG0{I+?;GP?XUyn0dF$7&^s? zA{0~UMMwKE3vv+}r$=J&`s~BtREmTYkmEHPYS<9Ce(MS8!ow-+;NR!qX1l_cQT0fZTBUV!X&5nqAsqLd z!J3ESBw#qEe1R@|6kkk%>UoS?N*_suHR<<`Br+R!9%u-<3@LHvK8M-lA∋MC@cv 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 Z?MC@0T5P?#IX2o0{J%Fd%^)?2004GNUNQgx diff --git a/build/bootstrap/mkdeps b/build/bootstrap/mkdeps deleted file mode 100755 index 30b5e5f062c40941346962c8b7771c5860932e0f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 250663 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

  • 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 diff --git a/build/bootstrap/objbincopy b/build/bootstrap/objbincopy deleted file mode 100755 index 8cce21b7c6542132b86428189db2b75418b60331..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 191487 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%0DFtUmN9l%`wN9p|m~R-s2| ziBANXwDAS><^6l`<@P6BoAWKIX*l=_<76$g(DGlwJKCWYH~8s*_Tp{uLg=^UbZ|l` zbs7CAySMp9?!8gY0DW&$4i)gmIRmOc^E8EUkP1XxrviFZ@)4Jcx|2C~8|4UZxJ{cv zex)UD1fF5BYMzR%AEMnu+!WQOE0xIB*ER!g#uohaZD*`GA3NyF9M|TrA5PwUt|(=5 zpdxkiw_}}wi;E8!y!hhc%?7_|8KwdoY4;i0e|D5=dk(mq?f3k-<=4djT5zPbs`E>a z(0-HpY{?Os4=uuPl)YI~^l`V=Oq(+l$GXYG&%)2j&&JQbMbcaDG4r+L&_DXn@}e^M zUP}>uw_e|>COQwbRI32{PP1E%t2QY!4>{7}a0Z6K_wt!Taxbv937CEd&O`fkroo~6EUdj3`EKAs1K(v5oPgVfVL(7>a>Y}V^A@hWM) z0nHmnIWNP&voY6{nzs>}597xt_zC6LY(lfjkV!4qnSHt<9sVHc=o@k2GVunThx!?6 zL#gZffsc9QG5N0^-`w&aDloiTIe|r~>y3O$;4%6G%(UBuhjs&I6Svf*_!HbaCGWVA zMxA~BsZMxj_qKJ7oHn5V;rs(E~pE_WBa1(^9fkk;%3U*jBVZMy?p z!efjwSJlt5?akoIEYJN$>WTLd;2= zx+oj()tW_rK~DSA!FTukZ&Uw9#_8hXHxQ3%wf6b4!=fjunNtmYCvK7zS*Z@JwWud0 zU349lJ2l{i_ey=p^IV}Jk-=_DT$A9?n?1#-OZ{MKpw6NKbwi9f-IkB+lRDHRQ)P~~ zn}K_nsw%zg|aT_hIuRVd3ExVse%8vK?UL$P7Q2~ux$os zGG`dOslvP3qz+5N)W9>mxl~duBajnmzr-8tpQJ?6%1;Ve;pMP~B_;cn@ z)0t4ej#ICCZpGmi`*U9i4DHi)e$kGOAY-FJpM(dM?rKBlNOE0eW1T2c2J8ZNA?<|m z7Va0{{{nZfclBW{bv?bzX4o<4x{3M2ok=qH&w`h)86W2V9n$xL8&z}uaFtYmEs}4s zjv=3+FXjWkrkqI|Bh?*+H#pmT9~7QnI$U9I3^MfHd?`nnIOXkkGjk@NJo=@eQ71Zc z+uwl)`e~MW2UE|mSJ5ruUGP#P4jM|TAFj1c*{0_06j>JKO!8{#j%0MMLdthad7h=6 z4(s4VX{#OGc{Fo2|3YxvFDScqxT|f$X;ZFtSmU6P0j)aeVvh;@@TeqkdWXQKs8`_1 zAL49lq28||z1i@9#PHk~z3$@Tw~R3j!)=tOolk+K#X=uC)jTJCa6(HQu4-<==8=9P z+l(}(YOb^^wt|#Z7lT){EjC>kuN}Z8cn$Yg@VXy72%hsPAI2~C|Df>wHeitcI=>0# zN#QmeyahW2`fZP797TsF-hgSSbB)kkJ362?nEP88 zH{G|c1De)3bkZ(mh*Lw+eW^q8DYa+~a`DVYvCqiYZWY=v>!wYEFNypy=Bqh>5(O@q zKj@=@e1q?L4+~F__*wkoCLjy%bp|$Al)sFA%iPuASKfcgJ1??8{05RgxLiAQaj~}f zVha2z$70OQuY`slwnEGH#ILOpiRX%Jo6lLTiRZCF0u^>_eoNvvR$J>`nttcMU|+Oj z%PASNwXOi|Z4m-#p&s}qM{TyKftb5$^(WRri6^YrCLXsAZdJcUrV7Yk`i(k!HP=L?tZy?vX0 z2yUg^QO0YbWpI<)n;J02aJUyY6Yad48jw2F(_UljitH-aLj2-OGoQvkkm#hnB5)^h zF7Af|Q=U)vm!s=gkmG}cGoLp4yJYzK;n-dAW%=8&=_@J?*tCk%jEfUpdZ|@~;#9?b z#7Um}32D2c{hbX%1efs#Qv>%fE=#Qw=4_--UTF9G`Za`p>CpHW25ot>h3|ZPud3a1 zY37lR$PGh|+MXCP_>16O!)RysnPBb{mV2Uis-d@a;0KDc>UY+?IrE4wM)h0#c+C+R zqmDt)0d{c9VczT`}=+d43V@S&pa91tPVxn z#kZp+Zb1K!Cw~F?tiYsfBi1Y5quZHN<0CqWrwq(x>Q__15Fad}&MQ?Yri}$-6|i+qbFkk~z;^ zz^aa#bSh&K5B@VX)pj@Sh)>!VyyZ^kvdeV+4SgO$+Hq)K`Y3%5w(1zggfuz$4O zn7hi~&KMeV;=|M{WYi?`e;@owmx4bJ*V96I7|?_c@GUr)iB2o}(0BDw`X{=-$dZ-m zP&5DakQ|8(*)Lbf71D!C&3vmv`NQ_irfFt8up58fbo~%eE)X;KJX%Z&?0<)u<*gciBsS!8u2#bKY_0wXB>|qpH2T^ zoMCf_?*1o{O~~TzeGlt)Qtkw_aCO<+z@_NvVLWu#XQU5a1dHf1(vN!X)i2W9;#<<; zV_Kq$QnxvkKF7xx{4o&xxzTPn8{ucc;I=R6yAL`&hyRoLb!dY{o!*Ep$(lkJ{JhI= zt;jOry%!h%zDs`JPX4g`7QeN~>i~WZkvkUbcahmak=c>REld9*uflGnb!nSQUowQZ(kOq#;KJ;(>HTt{QmMJE^B+9sj?J5iHTNy9(^F!L}GmpslD||x9 z+)s#7abn9c&kieo@bkl^$bpa1*?=`y+Ag6#sY@c)QyxE(t?9Y4;_dO^CSKX@7d|XJ zS~<0*FO9LjY`2BSc^5VeIwgGVyXp8Cyv3B6ajo|-*M;t(zn2Af-p8DahN%Jm&!8{9 z`8=q|B7AqC@FB)7t`(*Z4)8srhqf~x`r~)UuDRnA@(QhsPKe&udLFrl{&x5?;%zm~ zMJcSqY|w{SY=#ajtUVN>!{#AFhVyKzbS~QPp_(W9T4B_4>+xMTO#vTD->^>bA$a1D z_@G^sNug{JVJi68psRU0<&$Ha$X!bl^5Dg1s6)z&d{V2gEPvwT4cTEhtk9KZp>q** zV!{-66-;hmx?sXoWWZzvChI@JBt8eB6U!3kqOkohv;sbUE^A6*dI{6VpXkSN{4eGj zuBCOjRc#B`AwHBZu|=jhNBGA8A9Ap18MMUw@joN|RQ(Ugm}>Cow`Cm>{X?mz*LC;H z=mvk87_u3>hs72W98S5Q&SVJg(V044TA5wHZ&NM!uh=N~ip2(H&8Hn5DTMEA!FPAK z^5L~Y@3NL8Wt^g~I+3R#o5(BedTq@G@M4Rhf5V5RZfIG2JF2X}(7#)VqYsH;nAfu2 z+x=PO%JTEft!}=i?)+3>5MJsN-p^bJw;OJ=7xMk;HVeRIZ|14UJMpbbd;1t4=rz%6 z{lWQsUIi<0Hu%I!BYi-t|6o zmW+;qKZ*Hf$bo~&_^^~Ot!<&E;-p{X-geuNn( zyrM2zHRr~{BP?;yMO-U<;n2_MgV>erj5Rvs10CpQ%XW=ua>6s}_m7xZFwi*>aeW80 zlXSJLaZ;D~f~2mqgo-l4)5~c~`+V3$;h8cQMbGa(Ciwlf)>#so3-J31?EAqFFmDUV zzJqoBR5ScAdjS0wUzg|@=og9Cf@3Fh!B_HB_J)2cseQ|qTCYVJc_dxRNL~l|fOlT| zpbbN=h8cLW`INk2e+aD$&BjBE@w&ytsp*$A;1f6)zt&HgJIbmi$o(PkCHaL1#^+j^ zpP_$$#D)N_I|>J?W>=hZ;uLW2V?AmwctDRc;pj%6@jmq9p{n1M1U0V_zA13%z$I(Q z0-xxz7Z<;_S@uzc#~GvXpz!Mf%t!AB$$@jM{W&Amw%@>CeKs`#x;{9NvFl%x);8ZV zaE^wJ@N{o=r!MnswWayzlzHE#?pSJZezA-7iR9P~A9Pp;wQdmDqtzXEhSGebDbm{K zAz)3C#ZetrbLS|ZiU0>9w@9P3I0@Qurw=EcQ(41Lgm ztJ2c^0e!X5rudW;q4>WgH2e;PexBQxBAZ4TzRQDQ+8IbcAGD07f8N8#N8t0&d|$NV zXUM;_VND_9rc}!pqN~e#Og%Wozr=d2*8ChguFyMkIJX|UYq8Tui@NJa;88J#{{|j? zdy>Ug4CF{UcoEzhG?Hs=W~K%@2dlN2r1|K-mJU3A_M~n7hqOReygW{jxAu#f}^fEhYzp=G-L@>mzwjlnEJUBdJ$z)6Ph@m`myDj^??w54l9!a*M!62k z>B4U+@u9JH({WsbmIoNN5_9gi&{wX=&lY5$Q8zdkrs68%;em$lgZwgHqVp_`aDK6o zdX0R@MRfZ)@yrEzzLqi48OteFbKS1ca%VI?)Ua)n2#lhmCdxeb(dMgSs{)6}XOR!T z#tsp=d~vZ8|7o|q7U=VggP{vui>)m<5*`-cITbq>{}TF-3s@yS{^-;;4W1@G`C9t^ z4580*{w^a8oT1-6JpvkC3XS$cpBMoxD)w6x4z@Ho*>mA!&jtQC`fsVQ9b7hK#FD&~ zOSvzg&j}aoD|a9_jxlZ;azy4$FeSQ+K12?j75Z4-3qQ5CS@cKI-$f>zTdp-*V$^0^ zoVNMX6fJOanilvYItscB^c2l_*fvW!@Nii8WxE|ZdKfy&Q*B>a)XN=|7ydII+LST# zB1dFhN#yHW)H4Ly>X9Cu`cFX*WC++j0=&e5S6Scb&-EE5-*I0uGF^(R9_f1DL0PqtEau z3I8ne=}khn;qv0=kjECroLYp!kV$<}8w&gjV z`4GR|+HCQqw+YRC2o7a#3vCK+JKz&Lh?8d-d&aRJIE-t*9XXF|YG;3m)2_B1+a1Zc z#3i~SyxA{>@(aAjQf$o~Mp}PE|JfQ!6Tfu_b+q?)8T-cK(Fr@KtNmY{0r2ME2u-$A zZU*|y$Gh+;GG6`h-}E8#&x zku8Ep;fY1yQtXsx*%P&eI=buWMQZS!Taam@k3EYl7oF<4aNod%(7-6*W8U-?9a4C) z?7vJ-pN4Jgq+gbb7V=4a^7g65v-suL0*B}iQ)1Pb&CDNT41Ct+w`7kA`lS))r0(t!-*zrzXmJ#y9X3DP!51-nPSHF?gq!H8U@M zZ{bCz&1}wzD|k%Tey%;6W<{VUpr7mLmQv;!%kXH?$z&e!R<ZX6WN)sK@o9(rzB;keE z!t;#h2$ggkJPJ(&Bk0=I!B)>P}<2$Rp;T;2?Z2 zHjBuayael?mqn;;BfZ{iyJb_Y9;0PhI~T8cKE{^SE7tkNeX-6p$g$jlmX9+N>eZoS zWqWbNQ+ib@zoMZdvl{r7zMhb^=k*)2_DqV(N(d}HvM1rKb$j%;)`>m72YxDLlfCLp zxZGyoE*<(DWj-~^MBuOcuDXtqFIDT+)Bp?(UUle1r0syzYt*lN9~2SyF?!OTSlNe+=Wid;)AZO2PqHV@|%QG=kwuI9Y;#^zuyxN&^(w-Rl z_?8!j-n&KeAnUsFU8A%EA8QsrzWUq|$~XDu80VV!&z7vQs%s7;t81F{2Im%d_vGPE zxwa%bEoVf3%x_Rz^oHaug-;=qpGw&hue9bOe)t8?jD~+S#67-6@_21ajXclA-Mgj5 zX2NyzH^FVo!Oy?YP6O@G#sSIqEVx=0^Z1tMjdm@DFGcXzqW*o7*Y*?Ae>Lfum|v1- z$(9DCL0j6HDB6-fO5K8sXJYO(`X+r0y~>$7bU+YQ>aK)b7eSPXd2rS;={6FPtuY3HL##t|x%g>_=zH`M; zbx3%}DEcP6BeHDd`7n-G#F#uscnIkR4M8(M3+x9PU@q5_PCMtVQ_I^XW@I z^@iaSoOS;R{%qr%Yc_bNoZ(wfxt18`W}!u)w=~AHlyJ5&t|L#stwufB66O2`d79gB z>xy*>-$ny8*M7Tqo#02sq&7)AmKYa%(!RgEGhE(kmXBbMsFe5J%DQr>4uMgF7sN;H z+@k+xc$NB%UZsAaUt>D4<+QMzdk%my{>0Tc^iDB2pKqneN!^u^QA6$|99a~@R!_2ZHrRc zem{5{#{BKWJl@HC>BE|Y6?#wLm#nKZWvcgqas#Kf{eSds_`t4>IqmD^{05ny`;M}= zlBfA(XdZt?n}XXS{oQqWF`51b!XoB#etYTxxK`CRIk3S?*Pkk((`IxV4#vGdq5BM)@ zp95QZIgtl_4utbB#b+*gcLMVkyE>CjnQ`oU7x~nOw*O&`IUw+iPT09=OZ=bK{bPW0 z&2O|@@3M`2cim{71rH4>s7=^p$Xv+FdLJ|WYqKueJS6>B*l|~np^Tpe*mu(3Fb}bX zcu0!Sn$Q7hLI=Y0^Wgzvd+4i8T}AXasWTN?Y)DnjBbCh$edd0m^gENC>QMJNEA>&= z%QC;8_o_28$CslA3}-$|8hgXHQO20hPUhv-|#ZU3b|!o;fS^N}c1^=|-L7-!$tq>Y=Y9&qbCC4AQ=| zUG(~htU2hR8FqDOj26AWLhE%pT>mHFpFPOUK3m#>pkf^;)|>}on|txwX?v3cI(#`_ zsh8oU*>cVR--KWEY;+NPnBHt`t~D}V@!;9?QJZU7<~kJm`Gt>HV#m%?=pC}|<7KYs zp}n7lm-1E?%Kpg5tt+3!Cz*$A+$nXdDepU}8^7&JXw2B>kblXn#|JHlZ7A?5?7QxI zz4#3&VE7xO=B2fb)&}4C1kZc$)9qnx&PTm>;D@F!Yr?*|Px1FP-~;euQ;H81yKyUa zMWPdX&&ucOXy;C&t@AGYYwE70z__=!_pnZxr~w<+-3nc3eDY47U6k2G+7$Gdjyt@E zqx#mbyY(hBJzs2&c1!b7)@;J}*I87Ytl>rASCD=#N5)ZqMLIYToPwMCN|cIz#+KZB z1%8RNxEIzx&zj{9d`@%7aofebwW6;>6G`;J*oz{*^k?yv==>y( zdU6}Y55&9`-A4K$eUr67smDfNJE<#qNy2*Zv*O?K3vG;4)+QUjq88Qs!cgbtCx)uc zFAQ}NYMY;Dy>>+`dmpGHh4rW+%ED(K$iqM43gN0-`9t4V{_3@E@hvFmSnT~f89z7s z55%APHEY!yShMOt=6JzN0s9aJtxRuovghZVg}uy$$~b#ckFQ4dfyrKu(7HmuLi(zy zhQlpOeP28R{@a;5m1jbGGD3R%PpZp9}tlU(3G8!ITTP zxz;jxy}%&tF^>J#zFD(I;P+xL3moGpt7FToO?Eb~jXt`LGjV}q)FbmuU>gC>#Gexh zk0|yHZxSD{o%(N7mfjhpjaV{r{V^4Bf4#D==Nws+S76a(uLiz<)$4%LWDQo<3QWI? z_*&S<$vT3@{#A3osQ6XxhQ~`E{ySd=zE9a-ktlm_$I_1YHuF++zZ1D?f#&`Kj?|K8 z)}NkX8F9*i=;mAiv|BgddEDLaI6?QMx{z_~7{VKrnYFu;}y$ zc6xt;YRO(peT5NsuczL=b&ub@K7~1+Ym+%>?VTb%;-?bUk6<0&8O52cNYz&_tJ_{e zyi=+B)!Kyh`4V4t`}S8E8-W4GNeG5GW3RllGn{s8a{d9H!5)pi(q>#FZLA)?Ug3*t zpHpD;?cLDu< z+MpG4Y-L`ZXN=Clk4*oxB~ixseV%1+Z|JNv`=;%NFYQ~_s@hmzI?0%PX^m`+uwoxX z;j?GnTfx1ZzQiwicKtKZxD$AzXm^-)ZH4SN%3w}U(XR7vME_1-&04p{_;7!pPQSDv z6&;Mx#0e&|2j7=zLA>jm#Y72#)}MecFh1b2NmLeI~Z z6>Z;Ou~snea!1hSQq{|^$^HMu-kZlm`Mv++W0!29P?jNEvXhX=PS$KC>tHapVPzlzl1Uciq$SdcEJ@&-d~D{quc%|8dv2=4{uw&huR7 zI@dY(eV>6kBT@8T*8#uXP-i4+rl})kteYrCA#(dGJOs-7pg(`@$Cd_vyZW0R9}%-d*r64+Y@36OF3aehH<_nSxT@k&aS+ z20X!Db-)i1CvF2p{qx-tzJo7!3E3;wf_ratb3IO2!Y14Z`kF<^_)Yq&QsZ+O)~nSH;@1pF?8 z+!sc8qUcd<96}u8QP2*srxmEXF%?d~?JAN^NsVH21V3pQcu;civN;aZ`PU(G=D55O z03Anj@XAB}3S`d|;elE~_NC!|)xVxEA;+8PRv`Y2Jjgc)^v}IrG7d1_5gh&l1CIa1 zVEex?z(D7F80se{ridPPKZiOr}_?Jk17?^{hEfs&>qe4SDL7y2uae;Mplzs&>;5ZCp=1(~!KP8m?cm6+l!4C!f z{`Jn>-{)J&eMot4Ba#x{pF@=jfPR07q{>6?9eq3n&&t4F!eJ;E3HQ#ZxinOqpdXNT zXE2n|_vCti-D4)V6UG=&Mg1MWd{v~)C<-yf4J}yb?S^N$6@SGK!@E2XN8UFlmxDe= z@*?+d(Qr@T4=*R^2gFA}+9ET(k@jb7M(w72jY8G~;D;8%yo{7Z`c(|}E#km$z676O z=o@;5sLn6iQJsF`a6SWsKW~ZZ+@cfJ*`We)5N_HP)tPr7sb)b&TK??8bSE%b|?>Vm*4}wJI7~;&*O)5 z$OG$GjwXa3$U6h_9zwz(R~*zY197l1#?b`zZ&85yz;{ymUEY8j>Vl5~ggvMM4@6$b zF9TtE`smI$RCMPh_#n0l?9>C~9>Opc%J9F>B0<)aRp7UafSqgP(*3Rr-_OAK0ef0H z0b^tg=GK>BU&rCOk#Xo7cesaz_{p%3*$I0eov;`FfCAPxn!ukD>Vi66k?VsoP{ZDd={nj(o=Cz5yCIXuXY$C9Uz$OBl2y7y-iNGcTn+R+ou!+DX0-FeI zBCv_TCIXuXY$C9Uz$OBl2y7y-iNGcTn+R+ou!+DX0-FeIBCv_TCIXuXY$C9Uz$OBl z2y7y-iNGcTn+R+ou!+DX0-FeIBCv_TCIXuXY$C9Uz$OBl2y7y-iNGcTn+R+ou!+DX z0{_nuK+Z8EpH&v@x-t&u4Y|O%TyQ=|C!E6p=PRJ#CtTo6H~5V=CpiCre*xvMft+tZ z4pYYGLfjC4N>^3&z)o#8swi|+RMa69iXQ$(QAb75 zN3p^OE^5Yqs^_F*a(2ONC2TQ1%o@(%j`!GYBX9z$_w(OtNrdV>w~KM{9~W|U!*b%F zdSOQKLv}nOEM6R>mg& zMZvKThzRsZy@&pR04<3}n_5|#Sy`eDOyDmAgSL)^mbrnMrGcpl0|OeZiy@NGPIzZe z7rb8xTGGN4?Tquq5JH^LBo7P;?TW_|eML!VoG%eeAfcVT@fea6QqIx?M@0J(@a_bR z4;sF@;R$FG&Ie0G2YFx#SSXD}2l(QG(cU;;FDwDc;*7=lxw|58>McRV* z^$tM?VL}kW-LU`&2@N$N%?cnwv;Id2$pX7z{Ybx>1w}kSieJdMVu?5c(r7f!#}DHI z+}zL@S676UH=cwD3=w3wks8SokQ;_}!+B#RKxj0c0PRN-eK20Y1)A)Q2?3dY3rxiL zK%;(D7l#NuUsJ1iTL#ABZJ*LvJBT2qQEB>yE?w5~ZLh zbUy(LvI8ijf9s?lmH@Fn(Cfe3@khr2SAYp=DO9d^K(tSX?CXg>@IX|1HspE7^O zfHB6!L(=qL+KJ?H`zIG3OK`!WbqpL$Ei^O@5MXr)SgfXnHUoo(xt^7=j)^5%oZmwo zDfoLB;?YD5bmA|i`=j#z3?rzAY!`l21$~B$5pTDDNdoExqr({#|361G0|Sb|%0fd= z2Y~?v;DX&C+mJw6DH#Uj8v*C;K|;&P$jPHUVE~hdbbzlfHiW^0MDio5NK3l|)&b5^ zE_felPYi)1?Sd!z;QjF4I1R^_ivWxv zxCbDLgF@Qy%aDO0A_nX~#y&Zjh;<=>5`lKWKp~RI9ZfbvXkR=DMnizFD@w`-ItGt& z!4n7pek7(6 z0azl!^mp(7ZWc1Ue$@-A^IOEf0wJRP>LNvj-wi}T$H3_H0f?d7aPSv{HrCK`G}3ak z(9uIw!x8c#_8AMqDCDoklZPwPssB|OD1j^40K1~7nHZShqGLkgyuGpRFsku>2xh2X z1csr10FD6T8btaFJqq=!mwd57V4pC4e+&l$3RMmVWTD`H@o)Mk3`NM-e}|<5hy-cq zMrq)Jl7c^yC}~%0ptPH-G)fvK9~WsNbjW`PLA!sax&#o&xe%Lya{N;Z3T5T%<%`TK zSONi0KuMvbPvGE4EfnflBK!gQ{%>7pfAi<~U4fRAm8GsEoOboUxdz#&FC$5Rd2%~`t0aXIZ1M!+b6-rSkJD`~m?+er$ z!cjm|fL;P>2lOV;0!S|estVysp#4Bw5eo5rKu<$>8t7Y~bkq92vF2094T2+|i2 z3SlZZjQJVlV*%<7VR@jX5IzFb4)WoF-U50O=mOA8psGNNftCV&3v>{s7P^pe8^UfZ76e1?mly5%`<~S^)Xs zw~$dJpih8?LHaA8=Yb9aRe<Tm_y%IUajyT^ z2;BhRe=Hj~K;BryYJ=%Cg=rh}%PfPXgMbf?gv6V`Jcc-QA&@6=6pUO48@h)DFKo;t^Wpzbq{}mD>1h)kQb`BthpmY&8 zh-~hOC@lh>NR<3t67jeHg7Pa4g2<%s4`v34SM*Pi%QI^^( zw=3QU&_|GW14a9l2jC0vCXwfM0@e>gpm2!)4ORZe6}(tiavucY1E4?gE--!k!kO$M z{M8BQaZo;Rzd=P@ya38T49=U(O8bvilB>b`_>n^Xk)0Ug;|#8i3wcFEL}S5Q3P5!A zmv+O-32_|}naN87a0?KiQ3jwXB%B)#rcwfU?}3opjDRQMUGUz&71A2x9RLmy{bI7ZagF_c_Xz4w zMvONsj9f#IWf~xh(!%(XTM1*|-Iom6FURlC&^N)7g75?{WXg#F<;6w)|gkLnQvw*55UNg8t9>5Cs0o^BWQvgN)ly@Dos z1dzyp{MA!f>cNNs)g`KcStp}P^n*bK82{5AWFLaONRn9v@O@UPkEPa~m2p|fGx3$w+)H7^M1>c1%#Bn;R@6J3j6#?b>- zyI^QcojswqklK)uOhODK*(@Vt^!M=p7f%4l1?vqWng+oV8mu*Z1->910wiL9z*Ljf z0$DyFiz{G^Bq0h8UcK)xo%-L+hkz~F$~hy8X(9<$U%;O{5rFw|A>jOAaz)zY3^NoY zgS7uYE(WcCFW|KPy#|y)AO5`t)bPdz10Vzp+8hrPDC}EU{#q3>{A+%M9)SLl0EO`j zkwE+4U2$$ep_nvz@<*0yuuekOwa{wfA6{4 zfw7s9fsXdSOPlJVjdjem^nn@d9~c=}+K?;OHLx_%v9OSWJpi;LeS`_f z#PC}tO&zq6frh4$4q6u^)G)C@TbSu+8E6xCvctIWp zZ4F~s@mipN7yT1Fs;^;bVG1>xL#r&Tj4To9bJ%vX6=6hDt5XAt-@1(a|$9(9EQ!%# zup=WWzXyiFpWP2xWu^TRXjx@tdGcQcWV;G&j&+AgoroA~WTaa8!ZsU$h$Dfs<%ZS* zPZ{*s7l%PHFqpz}+Xr_7RMQ*`6AW@9TFltM5^V(92s^U>t_k*8TKA+*o5M=%<{uacuUWOmv`mgvZh%Zmw z*eD13=R(@^7CugC8yoQZWq&U;6MX$0{#P_P{oi5!cvuj@MM?El+18K!XzDN2`g_Ym(d1n_br!C8zjc@Xf(LUHnMkQy-A`9F*06Xdhz&P z06sgktztafG>!Qz0n7Kw#Fel+!KS`grs#nT-ORw#u<&3mPM6lgzJB76lHW!c?)Vbc zo9}6(V=`Sf)x7eP{+4lOuB$ITcZc74yIp1|qL)yzZ@E`OIoPE3LEqJ<^MhwLd>Y^1 zJo?Q9^+6){E0+j=)=ji0&UZr~m|peKBdZ2+|M>EVuSb<OQ{$7dti7udZ_UOam36#OaHTga%KrAFj#x>I}qQU1q+be#9JbE`j{p{Xt1 z_Ji(*{gW#vg4v!btyVbNDu3&F&QjiXkNrT>VYOz`?KfEW(0eM58sa|B?uRW$**7f& ztn*SQbl6aLDA4)U%saAPpQrRoQ^G$yM=f`w#PLRWW%^r*1HonotU4_|b>;IencQji zQh4E&Gp{hGA}jmCD@6~rJ2P1NRsOEv#pJpi=}R2lw`nV69W+gA2>|UT7e4Y5jcHft&XDcg1 z&W-!&M30-%Y}LG@{&kz8!9q}jZXEO0eVUIF*2~FIUZcP`WKu7Z==H5}I@{g!~BRfiVGmjxWw&G%? z*)mOa=l$Dr6OXo~u3p8U-fn%jp0~IB*@gZSafTVRnO4K+vnmYL4O>z3XZyV{oOLcJ z&LBtsEp*dPKg#SbE$pkR>5(;~UD_STsbvd7rUS<8F6%R3tE zSKSi_-0e@yD)_u@2w0)i52H8g(|tfaHggT;RJC7Y4MK^j?ihAu7c&ef2a##eh0QW&FkR(m_r zzImRxARkNd^zmwy*CWieyozH|{*V&OA= zE%V(mYVU{4>RLQ*cguP(kHxWLnME!8-Q%xFzb<6Hdh6Ol!xJ&5%uq?%x(Cy;VwsN% z3M4P+#GUl-9N+Sh?Z^GkRcK9_&+U=hFjB8W;tqY6t=#pcJ0zsf`b_+rZmkQiQ%?@0 zmT=wK8*-y4>(q*>|MEW5*cF?tUAWKgX!+O6y%bcvL&9wiNynzl{2Uv@nU?$BKiH$a zaq$#ayeP)uqc1AxRPo-)It%CI2XPOdPh1*k4t;-F-$)O=`txbju^*{+@95~obmCeL zUOs)|brf#oo3I_WXw;-J(NeS1;LwD8U2Rt^ z4mOnEQ8y~v)6-6-?Kj3nEz&?8v$N!KreB2|;d3)*5C@;3P&+{XjnDER>%1Hx&{Ik@_ouHnxQO@)>toBQvv zgvS}aq-yYEvHQ~Nd@gf^*@2WG6&Nh=WLJXe^RsTDt#1-zj?5OPF~3Y;yIOp`acc*I zw2b%jmWzTLv2VZFX0)W<(U9Q?l+T?i>D5;V4jArnw~z7v<>kiy8nx8CacOYEK-_B_#SK@I)m)&Yi7xa?KJ zd_Jq0W>Gq(v&XE|vuR0u&kVEYL**`7!ga>0>;~_AUdnQQ^1I;ta8LTlb2o)*SZ+%R z5HU_^0yK_G2$1hwe7bKM2p`KUoyEH@l zIEjx5UH$57<57{+A*MoSp_n!>-;ieAJGUr3vp+ z1jRnfiDpsUIm=?tR%%#v>%Bpatz4PNSMA9M+rAd*aV?6xWq(9JSzgBIJHGqQ>HCJ= z3mh7&{kbM+_m+0mxGc_V+y?ITmtXRHKF9EuGJDX?&~)Qu@b}eTC)eh!LWQrg)Fw}D zy?rQ{-HYzVc6xk{re8CEdZDUInY+V}2POPhC`RfnoO&(CA_WLv_y@I1uk#OAoY>viuGMc_9R=Hi>P-AzEp?}Kz zNmB{wfqhIu-nRuh^c~5csrrtM^t6K8PgT=54CzH;OPo2FhZiX4@k zb3IO!=nCXrJ$c2&EZ|&ph^x3YubBSukmVv%zr||iPtlIEbx~OqH*WeVZcn%!5y50Q zUgmNrf#w%y&-daT0qOx-g$N^)0;mPHJg~$*fV!RVF$zB#Wn9a!3SrtT3C7@@a;k?^_z862L(#)(j1O#@9Yh)TkQ`uI`leR z+8M2}zWo6%N0sLBneX9h9%YZxw8yu0-gEcL&*E}n4Ygdf>-mqdE zUCvp8@X+WGH-k)q*Y257Ey~nx2?2MKg4b z4SnBLHX4|cO3#0xl-k9pSn(Yz4B%HbU1 zIk)FtZQ_|XyB{dB^ZU8@yw<1ZsN>2@xXZfby39LUhrPiiiDp(dl^JodC&Mg~)n672 zIJG%it!F*-Xp`^^q^UhDlOt1aEj%_J^lYTBb&mJ?OebL<-(LKA>a`2Y4w(8D_qsl3 zj6nM;l^D@wSHi`mX^+#E9!#`vr{waLS)Md%!S80-4cpNRMeCPJ?s(UiGZVi<>csh> z+l|}LJ4Lz_ck$n+;&x8tt>@x0IP&y^(=IawvBL^ArB$kDp5(}O9%Ht7oTGvBl#nRs zL!HZbct~(Atn0_4{1x}pi}{Kw;~%DPglyd*(VO}{D{^S5A;dZDkK|rp#mLE1c}P+2d%RGL9v37te~wP|rsSR7{GXg;1z} zb{8HUXEL)qnyNNkO}i6ELGc_Fd&c9V6ZOU$H;dz5DbdM;Vne+wVaB2FuhXVtD=iT(H}Kloz2=%;O;eLi*s`6mV$MDtfAH}b_T z+^QcEI?OoI*fH9kn!z3#prOloAR^-FGl!2NOX9p62T9HS&m8hEsS_G4_zcz8405lA z%{|T-Z+uj{ybZ0OL2=aOD-^j{y0C{z_Uld(K>t)h8!x+mCTtZj77T~;0aEHHEL z@X7IuiT$BQdtI`V1}zzu+V7ZXUAfi%0oS*8t*N^DWbRD^p%6s_4Hq$z(yrCy9pyQb z?9OvLHQbGt+&bECkD1m#y^E%)KhrOqZpv59cQkZZx9M%A+x_)@OvbC?9EYXZaaS_# zmR)IjD?Jl3P7zwPx93IUxD4}_{#p5x9rYx_7w)!5gPf|4y`>FYhG!1#UxoWWL-S=_@?RENsn|bt#Lgqk=zo+ z%Dek5rqFE-)S(AfqHiUy(%c{6>2~!!J#s+*YX;%XE*0*;fR1u4QM#Q?_^1L3fqm0K zmr6Lp(arDY1slK04kkqpCG()Nv$bM%S9Pm<9CGoc?cKZT6M7=j)~RORB~;8r6uG^m z;&Nx-AIzs(Tq1eqV(TsLQ5v}n1FrLQVHXGP_4E=Ktqc5_R;&{*QYljQ>TB&_`br;T zq|+0x#*3cLk}GuMUsCby?y!BIW1AZ(vO07qZL0(IjNHjtyN(x8HT>f*S1L-^i#HS& zb{24~Y2>QE8=S{Ie7yLQJ+oFS_2T3CJV*OSbL-m*0$K}a9XUVF>5f~-6jPTy%uu0Y zkQEW3;w^PEK2_titD)s$)TPVIUZ2Or7p`cTyAKZqr39<142uih>o3bRisr!4ln8%u zIPY$_NKcv2@iV2t={Rkr;l1|tlSQ9;d!zlMJgX3o*zd)e;_7rT!7 zlpH$MZ{Ew@?Y<=ZEF{z^^c4Tr7Kf^X{=x3Vme_C62bmf22K=KYQR-V)xHEf>v@kUe z^91kdy?^uRa@6C9sqajF8BAqirE*Pcfj!wrY42#bzk1z!qQO#*sWk_Sv1v0+8;X+X zx5hY{-2SA0{i5gltxcA9Z@-gTXzAW~x#sTGuXbcOtfCGV)$#%rnXo%q#F#b zQm?L|uFLj>NGUXq>Y=}4o@pA@eD}H@rPRIY#^dfELiw*x58Qj7wpDeT*F$;PXGu6k z51r`c*836%C=cWhuzXk8nODNts(*$5>Z48>x?_)Y8B&D}HCkvK$AYsHb60sX-R>l^ zb+A>orl_n4kiNX7WKk8lF>Nv9S*}eZt$hA5RYV=tID5-{bAjoEui#+M9pQ?&+`zQS z5cM~^lBW}%1&x#Z&xJh+pXd1AR<~ir-CobUBsXN3DQ6%@k2xczaRo3+;Q(Z=Trl_b<8+C%aPwaYd}|YkS-Bf>}|s%{{jO@G8nlOSHBz^zkAyzGvI;y^4-YcC^q}B6CS!tt8>E1riDq%Js z>1`f*TZHlLpG|#QoMfLJP6^r}tKA&Ar-g+xA$Dm=KsN+8s@^d9xcySQ)6Z8?yq~`0 z2L=o+yEi#fW;Hq=Tsma5HzPV+s(#sIZjdo#PKHWon!bjc z^w}e)D#A|JN}U_E8OyKmKQBEj=-WaqO%-EaT$tz?di_})YTboX4KK0{X5jPmfO4QCfK&NPUZHRzV>wVQ$;m`Jw zVSJL^e2!AnobJu_3kiKT)ETuG-uyVTY(5?n^zr8@^_#_+f7 zMcr+uw0lGQzRVTrWiVk!9|XU@aLjp!x%dae+;z7VjZ<%1mR54lo)q=fZX3HQxJSRC zX-+2G_{kcvW114LCRNYLO5#;3kMGM`3nPU#tkhZ?Otn2a`8qDRW zs9hGyKKjBo>61Lyyvm+nX4P}Ytsl?Scpv7wa%Sb##M6?dN*=v4l*Kf@`K32z2K3jp zc?FkmIDDuoy}>#Ay^6Ecu3%c?`Hz~Y7K(!J6jL(_V^kau98(QX(D>-t6+9MtB6975 z^}YFTxUsu5?v}gs@vpcp$e)+Vpvr0P(q0p#`zm@&U9k4?=~k-9&yDhWYl0!R_#E9D z&+TiOv0W_h<*1#XjI15a8vgl(fBeUNK@qyW`#QYN*G?bp)aUnnttL?IqMOct*y}2H z+>m;Vk#5}RN*@?Ijv3xyO5CLmCzxz8Hnn zU(mlGDp&hLiCOtvSB&v4x0ez-);fJ(XX_j=mc2~No6#oH@o=xw*8GbXcb^#>xUg?1 zq)kTfGb|ii&+O#n(~FqYy&!COH`-sMHRuISh4@WRt#JVD+WKXknP_yztKI??aJWdO z+C_eeSy=yt9(7=&v2efawm_8;(HPE>MaH0`XS+&C#h+`Z=eR57KAF$Ng$16SEoWQ1 zJn4}^8~z?U>NS&b6Eo>oBYZNqB;~VTZx(Imr_~tO5Xar$Z89bECAx@pdruh+3Nf7P zBi&^!3s^Uidl0Z~-a5tV_<~!n|FY}?Yw&~K6U;c$=) z-Qxb_t1a6{bz1G4XI^Sv#~S(vzIVnQFE!>V=XA^M(npx8pDF zjGXVQxXCP0|5Lh`z8uqU^YvLMW7`KYoVX;%>%OgtR~&rZWSQ1~$o(jLee3$Zbm>RZ zUGm&4RDtRX-K_DM&GHAa0Xgec&sjpAvkVD(R>U4iPTTroc;GB1#M(5q<@2$qt&_oa zChzGpj`288mZ)Uh$>p=IEjga?wcZn3X1d3@`biJAW%{|=;V{N&mw`m#l2zNKfO`j7 zo1az|O1tTNql%i2tm`4hWDgpb^TV9rlpgx+=?A@-FEu~MX=D2i-sM$vK31InVy6G< z)6_F++}0nWgFhdxEOFnsNcA*!p8sO~^Web9mX-r&=9Tugd{&}z@9;F;T1uR6ldCcO2#ATJdDH2!YTbuW3>kR6KK zs_EVbt*OyD72%zWsERED-F(7+IPE6%?8)ufc|TCSJH0T`nyd12;zx801qmPb9*>*3}wr=Njf6B@2UrwLydlILxeRx&wn{1j)twM%t?9;hh zOV`IwbSAVewXV+d#|DMX%@zkbIjxiw7wW8)xLMA&7ioQ%pU|;)Ihe?;ChxXdf_|g( znRXGQG=}52x^*bJqts*8!=i(&_a~i?_;JDGY&*a0JDBIuGJfaggJah&DzblNE@dn= zDwR-J@)1^4ATnY>k7Eo8_6l5w&vi>Uo?|LlVmM>G z@V2K{|3m8thy5X@H*d=`uiB-0#&jF=9liF{v%YN`$9Us==a`_9^5+2}^HeMu=M1~! zu72Haz3NkObf)g%hkCkmA{q+mEt8D-@jdGITY?o2Jl{F)b~WC6Y-eTb2mhn0K2I~t z`#zDp1ry$EY35l>mOJV)NPlF&G`>vI`f6c6)1gO&?|zobeNVYv)h}$VRB)`t>ddFU zkgoJ=yY@fv;d}7T#^LBEju*jK4kP>wr1%o3%1+w zpylgDqa7($O5gV0B~~)r%d|G^YCX#6LGhtD{*KW$o%qYMc2?34PnD%u)pM5h76c?> zvlO?97tx zw0$V&Y({PWr#uIvt0OxpSw3va;}AY&W-&*XP{(<5sp4ue@(`F<;#_j>mk< za73#(5z6NH6H6M$&|`X-QvpY{wmlBxk9cxg!S>szTtFX&YgM9pG2hIiO-Z%C+Jn<+ zLUcyq6LHD6?jcuQdiok01BIen_5)i~WOhAM9EI_$p;vb199EEb zMyYEh$>j4`Zsy9utM=NJsiKY0iAa;!We$zTr6*^pJD%^bZw;2b;8!Z1SVQe`eXcs3 zGwEl(EGDF?zgD<5#WhpKt7~wN^t1hxQV7AxyCZzm+&sNHdH=H?CB z%RyP|k$j8GTNjViPH$AR-0|4^W0_|AdYV|dh{PM?l}!I1PBX9iwX4rE*xeBmG>mSy z8lLA^S!D>Tp{&iRlNOuNVOUFH4dKU^Fs`?si>}J&>Gz~jv)~MwHlN|Qy6EBaOM=VB|dGyP^_KX@bNWbF^L^j7gIm(8*Dnnv zP#+5+OneAKWvsQj zTV^ohXtrdvnA14YBU&G6Td#h*w>|%GRETMG{t{Yzh2QjHTb#jgwkhQuW!ujhsrdLy zs@*-62g@eHgnS><;VMKT1-9e!W;#?j#ZkxIT}J49x>#b8KDP?uW?IVK7q)5JRy=nRSkg_IzF*XM?(@O>`uL-I zS9t=y-{t$7;^;7qI(}=pTx)+UN_vaJb?qklwFT@gF6uO>x& zHGjb~v)})P_CcNLqNOs3%qrVB^rLy5|HE0$$U`>4_nh-zk8`T~PS2WtDbVL%;akm6 z+){mOE%NM0=;sX#;c#UwWoy<0{kRnUmq`Ojee9*$?^X03 z3x6sL^``C+bmehBoHav+5!P$9ZL=+-C5pOLnOu)l!DfrbAcujYPj^ zzumpTGZ1qA()!oPji309`RuWw4FRdF)33#se8=}pmR0gDNxu?Wq-^`47U_2qH&u*L z`rv=1_$rolrt5^sz5CxIf84y}FdzIuIF6H6f~imLgYg*UtZ|A2o;EUiuv*5=LfXIu z|IkR;aNMCG$uD*AfULWGQ_JpvliTA{{W(N32SUGOQZTMFrJ=1d<;B#;WwQ%1_M+ z$2Qig81|rdElK0sXm>BIPmM|LVjf&L6E(&lqrqzvo+dgzZPG3^#QLx#esW&^?sxxN zM~nKNI|a|}a9AyBYisw75SDYy9@U)8eB~XcOQ-C7v#ztjl(fez zuV)#*y8q_h98Y>i?&<@z^|7^l4)(?K`P=qQ40xcnFX4Y2Q;=SJy4Pdq?iLT)jw=F+ z4_P)$eB16zJ&@@j$xrQ$PCK=K+#OGwCQ9{;sME2%I&$CXkJGwr#>tCk+;KS4*%OgILEpbkC%vitSya0*Ub`W`_I@yQ?j~pX zI^kuXp{T*3>2Gb3ik*iZ>6lEkEx*;0dY@epeeKzZ68%@9D1-0=&C4Q=Av{y|7fg79 z+DseJ7oJkKG#IiUkUTst8>a1JTr#v3 z4vmjt=djQ?V)|4^HvG#crNk5QJc+MRA}pTm$^3W1V&yTT{d1#51;p}=kA2D2K4pG< zRnG|&Uu0~B1|2KX>H1}CPPYU&5ePMeSo=NO?3VF^7u(hg6wG*sUU2?onG&8Xt!(ej zPB&4$krFGV@*{v0vBdCjF!P$z>q6J~pN(Z}l1p>Kq0tF^2LqXBLp0lkKWU7g_gkq6 zo}*T(AXz9L7w#CJs#V9xjNj_WwQWC`DjlTSn7768r%X9^(I;K0R&gTe`hFj-yhP4f zUEafCQxS@9?A1xN7x5wIri7zJlDnJ_v-zj_T&1BDrDxBczk4L;DcT^uBLR()Jxd)< z%@8gZtCII|inBL$r1bjEEu&lecq3;!XTzs%hcU8;z8oNBO57AXkGaoJm-yPdq4qwH zCY3Kc*E8R#3Z>je2fy)^!M6q>S#Q~H*sWZMnmDNAQO|RE^cGH{lcwxPS;Kn|wY<(d zY&o}-*Xj-TofOn?JUFz!NgyjVsvhmA)O@sW^5On!TbVaBd3{71Ocrh1Np^mnBSFl% zi72a`_=2uiT(44v_6}b6OE)*C6epSAbckI`ys^wYmtWu{e{=hDE9aNDGxVqH$JkwN zo3BM5InypA(xDM#Z%s!GukBjT>%#3fdoPpPe6HC%(wYNfPizVQCbZ^H`|M)cjL{R~ zZm|VQL&eh^m(TUR9EtF?6Oc2;Pegq?799PuZW~)$V_65MK@Lf}PO3Q}L6>GBg(~}L z*BH$q)i_n5yknlNPS&^aX(p-zISPR@@;6UKChxN;s8! z54(iblI6aahfCcYPT90vK2b{=d(9hyKJf5OY)uL;u5^G??lMz&N~8em#OnffH>-A2C zZ0Hf4Cmn)qDWs&IuTx`jDP*kWbq^dLUfU<}NblxPDHmS(?MKfJ%)j0%zv$dQ{q)?* z40l~kZ+j=c@f6D`cD7IVGfw=Nyv;hpxb(vf1W?Uzn?k})hXEhF6ix#XJHKpn3GpX<_m@Zc? z9vN9y{;3u{me=#ByC{f-xz~dBv)Z>v-{H;&)kCoXu6wkP!ea}R+b*995IS~;?TD>r z>HCUUUNzeunX7^3%Oc(5Y?JeXAvC>OTSChzrlL_shQoDMIeD0n`j=hRbNgYuf) z*mf*mbd*DR#{JZH1(6p~Qu-y^C7k?6#$3i{<{xBa)Hw^p^pm#FcAlpxh`63msH&!z z$+#o>QVea|JqfCA;Sw7gUGt{lk&Nknk=xX>%Eygv+q~uxcTC$fJXbqz({@e%S|gVGh*e|De8^nS!%P~-6n7=Hs&k5x zR0>_Uk5wOUyKAM486h5#Z|-wdUR}8{Z?R0gzZQTCakfm6PB1BL-(gyGjimO`WU4Ks zpxQyL0PB1#v?%4l7>$KAZG26y$b#WY=Cdw^c^T#G)B?Xf2YaYLywdwbRhl=Ux28(U zO}Zs#zPqnlS>*1H_k*e{MP9=Ecex5~Xo@cO+uhW~g|$(=YBJtg)*IJY!soSnY*o35 z@_65Y159NlT2p63o}8zO9VpD#aG;z^)^QbB_SvN@mH+Bh*Qdw@wGxMf=PS!!EPliX zgz64Ze%`~SM90+ayr>kqFHdeVg2uW3!i~>b0U>XAgDMNcT3nPz_(5RgDf>aV6nPfx?xbSb*Q1)k3)H(m(EQOrDUo_#r25vp|dC~)Z^HiXxb+Z)8(JK z_aTAq<2z+H=40XPQ>r<4yRNv}9p--6_PrqebbE?|Y?4TN3SXMPB<0I$!SS}aOnL5D zYIT&xXY2EUfyH|Y3q>APUX~Z(JOAKNHHF-|(*@<@^UO|N_KF=%8J5!xCu{OZM>>no zvD^2^erBIzXvwXRed}6TS;UOzgW(jY%(|&XNcgtr7NkMUkU&9Vt zjHl_JytqBma3hM&BB##M_~hfJVuNIw3sr%%T_h3F%DoS_7pzCqKDzL_d=7=^dq(EQ*9m(udvTv@l6-H_|TSdmZyk&Oh~n7RNz6AVSQHBWzAic z6$UW}47j+Sg?g|?U1HB$>0d91Jz&mP$)x*~V%}+?{(#$-j7f$c+=+hAJdH*2@4t?} zyLJ7E49nYI#^W^3LA5VD-fTBV-AfJGuEX@ml!C)&^@d^NC`GQ*<=Juv{)AIze$J}2 zxqV^5O&0{yRLvj0n~==Dmz_kB7d&98{|S}Tdi}(m)v6;M!r?ui3fFSb@V zmuu{Brg|T^ZP4FdI7ztf%9Wa2gS?KP-x&%UkDXjTrIq<+yF%ZY*{<4&)FXyy!;D)Q zo-!40CLXxI(EULhuy^!R*VgK6oPa<8w^_XQt}`)WCNZ8DZk+23f1@1XEy$U4QqDqH zU8hn)Jfq{$y^DV5sFN-WN7!Kv63-7ia>U&%%*5!(2jymMZE%+zV4r`uTycK;*=9a5 zB@tDsqcj*n4fkU?ypO?{! z2s56V;Mo|o5q4sJ^#29B8ARs)NRbagwyc7=4_+OX_)aosAW2D@D9-(Xp<OoCTau zfhB3y1<35ILt(s>u{hTY9h2oDa5uj9pss|3iv}TfAA=>WU>sE@%NoicN{Z9XwygNB zdaB8<&#Pv}k~MoK@-hL99{Kbq{RFc*_Sw;b{XG?@mD7fmrx%XB0O*=U^E!! zIAo>5nufNbQ%CHc`G6m6Vhw^uZU$P^?Az#?YJ#Qi)2}XCUPu+LNJ!Q&A71LYVvYI_ zk|yZAb$bLG*-l66cLzw%B==qlB3|FF>sH!c)a^#aribb+7q?eBN0K7FAf?zH2aWJ; z<)>4+-r|J#0jn}ujK`YQ_1YqdKc%Dn@w2hpIT*X$@$=>%+n+MMQ~arU$>dX-tkwb@ z;Rpv)H(aLCGEKxtu7s_{HCUzijkPeK^FjM&CIz*-TWokq8{_0t`p0(DYUU&4*Lpyc z;9=wOW_rOUtt_?xN2h2-Pj;B?2oXcD%!jh1xVU|u}!H5X%_gaqJe{O&GF? z0k0w^!$cr)Q)Y>u3JX%GhxApIl@;t z0SQ^r7#TEHFBs6ovye6$>97@6ihtJloV3*g+G<(ary@L8S1KwpD{0EI)zpeOwF14R ztj@rN&0UF9j8FM0HFtEw&ej@pFl+}>~a4rP^j-XGOg)=3Gfky1)d zJETd)Y+{rbuikW=HYA#~N}q_R-_ku5;pd|qF&6232#m)v0wf;9A<7x!x1wr&*rO`g zJ?4LDmZg^VYle-A#g(GESTm(%lR}~4vnt0rohHHG)w*qA&xuW0gT#(J!{XI53mHJl z7^senhQI5a|HT5KO@MJAtYNMsMl0$YFS2&s+K8q-@AP?iky3UYUL075gA+aBODw_ z)Xc}yZ1e9&mJ6rZj(#@^8HlnCzkbJtl-56@v!o5LkBGqNQO`Q?iC)kHRTVWhT?H7i zTFkif;&kB!P4VD76d@eiJ9R;iH)UXk4C$B0xES|mVhLwZpte~gdU%!iRff3-fx8R5 z^|OjBGq)d~D!7cBX4ZmU6-6Mtds8)u9cM*t1*&7T#F6P zU+Z8m#vfer1j|Bd37S=*>%fk{ctVQY{*A)ALGodpl}o9pwI4;W1RZ(42aRFVkSFM! zcYHs*XT$d&n7srp)=%MVSid}_*#-NsAY7P#NjQFS=E zE&Wg&2rW`(5w>IT9(vo#{q47GA8Adg9gFrHl8sujqdJm>cRZc}b1UhVZPX-4fzXx8 z{37WU1*?b`;EzzB;Z*3#>38Jbn;{S_QLBK$P@DSZEN>kuok=f=Ji#_bn-+c5h0 zrF7)lBNj$55∨aK@&B^e;B)Up6LP(1S7N7@&e3fRX8-*QSl)KCi|8gx@YOs+D-| zI}ziKI~UtI2`ROuRW{>l4^pKL5@>Kue|IDwhB%9^rY3>YBrpiso?-}<$t4Sb-lxBrB1?`wF+EX&xq>z>L9py(MnP#D!A#tZuo$;ZY zPOvj-*7m475AhxpKXmZM9okmG?M)Pam`9xj7&AEMiG4@(^vP{UIsm_LpgQ=UfF*^V z)H_Z$u{eRt6E@-LJ?B9tRCd zIcTzr{`L5Jc=k*GW&raJzV#vF*NdxnqcUTp)oE&nr-%d+!4C#IF}SD}d7L2uO30-} z0i?xlR$8Uzr=kk|b~PfL`8h_PNGj@QRl$yy$CrwfwOUkl92G88pVnqz*0{DQ7$^~@ zxwDZ8ldZNyWwv#tqUG0{I+?;GP?XUyn0dF$7&^s?A{0~UMMwKE3vv+}r$=J&`s~Bt zREmTYkmEHPYS<9Ce(MS8!ow-+;NR!qX1l_cQT0fZTBUV!X&5nqAsqLd!J3ESBw#qEe1R@|6kkk%>UoS? zN*_suHR<<`Br+R!9%u-<3@LHvK8M-lA∋MC@cv;rED^W)ut#n7~{^HTZm%W{AWs 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 F0025{%?AJg diff --git a/build/bootstrap/package b/build/bootstrap/package deleted file mode 100755 index 1c7db41316fdfe0d000b3abe9a8945276c5ecb28..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 250528 zcmeFa4R{nqwm;mHnMsBanBgNB6r_m(!)hSIX95XM!wmG`jD(M1y0uSzQ2P*gr~a&c+(&4~p`2JSbGFc%)WeS0`w44ksq55K{2VRMh{6Bn14mtc?V=HkvhgM^18C%5q&x9z>%+zm~6 z+_sQCWRIMC&VSJ%U9XPd5*iKm1DU;hn>e+cd!#+k&Tngl$0Z!E_xTKLkiH-}UW zw};*wQaPu|5VzaFy~4f5#cgY|A4Alnmn`_sXn4zi;x_-sp{|y$mWSTFF@BW2cUyaN z%E*V$KTDryMm@gkzaHE5!(9c>{cu^^QvX+eM(=$1=Xnbrdb8_5*8xk5{aB;nrMNeT z+*MFH>{4iYeA>v30~!sN+NVz)H*%vfvsY-#qf7q1h$*Alpw2EJ(vf7N#9 z-j~O!YGkGQX=LvkW7Q8M=eCEx*=^#QInxXEA*ug@B|mCDG*&fpci(mVbenv!{;)K3 z;S&3S7mbF4&)=QoKfUz%)3e;0F1E$mL%aGp1Ggm-iO?M`?0RjA|Nbujxx{PQH1VdJ zQxg-*bJNlb%gf4EZ&<@;Y~)kZGE>JTF5_!b)9k7I=v=-gBV%<{RcTr2`qfeqzk(k- zmX|hF6!EL^H*><8qKy+a_|~uIC(ayer)NbqMTP8HYFc?Js5w#-rQFoC`xkrjobH9w zGt%xC=X+h#GsbV;JYhU&WZ1{sGgJRgfy?-e8qktbwendR?Dk3_WvGU4!|JjkKBElG zTxM(>|G)!$S#C|%)Rj{wCzclT%lOfJ#u|QtP*JhIv~aalTE3x*UonH1N{TjU&$X)m zRn4zXlA2bQ$|D7%3Z_uTGBC&@SC_4sI{7k1#_P14nRp63kglkvRO0Ou?THnYr5mJT z{^sTOY13SuIm;(5x6?oS^33o2o47o4CZb{wCQY8?bX=8WiX9p3la^;@;!1yi=bxRW znZ}Z3PW^6{oB5ezrzJ+Y9-EO^T#B1giLMO1e;l0Et1Amj2#IUasVw`yj?VIlQ>R@G z(3C3>XrN7`7<;s?|13n4{|ShS)>jq%vpD?&LbPTLUs{Y_1PLmSUhk>OwewZ$N-J_F zO`JHH*FJ^iz710Dl!;ly~ z0&;!7G-kpNHj{8Oa#u0S_?tM%K6$dnk;dO-d-kL#gRB-;^;Z4?{@(jaE6_m;`I+e9 zX@R!l5&)kIi0UqU$nZah)4TP=W7bf*A!(` z6|FBSl=zH{(hXJ8>haC4G1H<6 z(!$FPhiYb2^BME`462j{_O&VgY0P7=|2Y*bX1-&?u5j9oKPDk{n=VK7|j922J{;=`F> zB+;J%e?p#%^H*<+w_FuBzoKZvtVJ+s@kzKU{*EGvMLTYJX$s{vQvybXt`7R*IG%lT zTqdQ!Cw6tPJC>Tt<}%~7h)hAd=Ec%$w_IlQ>d>ylM?3`^qv=*f^ZBFqS~8C7zKw+( z(R+Hz@~w)N_uYK9Xu?>A=ykzo(i)a8`uOi%2tWG7ur>A9?!Wu3p~`WwE5ibb-n#h3 zCDhSiM3^|Gvd@C~SnY=6Uc}$Zm3hKk*HYKQ`M9~}!(Vgvw{EV`LCf2(PNm^?xm{w9 zqU}WZYwfK)xQ5QeSYljb?HOyo%k8YCAv&=-QOq@TCTVHdcdVTp(YRRqMca$$5LU6z z4G5&*ZqQ`ty;~@ei>;7%{y4QMsjDG2n2m zOVDm&SI$8Rv?L@u4G(MRG(3!S_#eA&XQ?=@CMz0nXxD#M-ecW{aAkl0q`XH<*DpE( zIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZ zIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZ zIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZ zIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZ zIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZ zIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZ zIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZ zIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZ zIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZIs!TZ zIs!TZ|0@yjF8x1qDxA4DCvu#P>x;5z;4F@-xSh9{<8J12a&C4|vMZm0B#!%yBg}<| zZr>h`7Xzm(_QP**T-e+rJ2~zf>!^okcJJjX><6~BT-^4qeCX?eqg0N&yY_S?*Tlu; z>JB*ix$2#?9Cxn!|kCrhg8mKGQ{mRaIbK$adF$)?8gu_=_L!k zGaBCVpSaEcaj2`MtL33LZ;T&h@7>nkoHFv^^Uu=fnNg4L`me`!{cu;ob3a_xw$%TX zpV2!X{(0Vlhu-Wu&~?DlVn5bscq#79A$Jv24!abZ9-lUHg?*`MQwQ@3jQ(rGanS!e6!Bx%cI{`4&Ori*P?(5H}} zGjLlXkqCuxVOI+Oqo4fe5*>**-JF_OmYbID+pxN~b9pU_UqJ~jN3JegGj%e*Vg@gj6m3W>&rMBBFDx%B zTfJcopRo}+GgHTzbZ1e)HxD<55P2eY`!B zXk^rYnv|;5=KjR8b!$p1`HTug-Y<=r@Po~%C_Qn_8osm`f(-D)IJ-nM~rO z)K~?l<;(;}AaEs#J+Y#)bc0mP-@M#DZJNt7XZghCcKpk<2aS za(m`v{Nc&>{Y^x?ebVSam(8zL6#zTew>SxaQ10jTezC8C1H8WFvfJx;qVvA8s` zsIa7*FRH98ubd8TQCh|N^*yB$$D#|ORs+gvkId-C!-<}xF#tlg1 zin1nVa^>sS6jt~+3`eu4aUqNebGe#(1f~R;PW<6p(2ltM$*;BRk;R|6b6$&+qdT|9f#k zvD{Mp8prWmvHfUqUh&f`F1tmVP~1#d2TqTd%B+mCH)+nZu8ZsIXO7Vl0$=Hfkhf_G7Ihij+-cW)+FPASgr@@3W^ zkWz{jm!-JBD@hs{xR6{K--{%YG0>4xTz^c8uZ?gcD_^mPc3Ze_&h2X38yc(DUbuLp zJ+v((Zacb{GdJ7JW4D^~wwm(Bwwt+jQ)H|^H&W1GDj3^f9_4d1894P;uJMJ>*QjH- z#x8dGbXA_3!Zp5)n?YPbQrzdO0AJ&O;Wmy7|MJr{JL7y8+i)>R7u&vWi@z~Jy`C#> z209$8Flxjthe2>}@wsQePH4L^{-V_|tZS^54<#9_si82pmLGLvLfR!3P8ih&8>0RT zDZBXxBfok6hcD1bn(^2Rk8PbC4{F{0xDswtf?Cp-r@kC1SWs;5EyghE|7I+sewWwx zDV5N~ZQ6DeRzw6qaG3z2xFep+Gj=6#6euu;w1C6ds0A{OJG20A+^z*|6o7eB++>X7 zID4dcSFsr;5?B1|<9{x0;<^(!YwA%ji@Mx+%SbEVT|8h15?WKci+B4uE@YipJiyQo z5t*^d77s9zOa!{WMnz9<9+%FEO>#ew^kd}iwuc%s!E)EO(6;Vv>gyb5;av7lUG^_r z_Ffn2am@aO*wMk6L6QG(4_Rx$ty~2f>tHs=m23g&_ijzI8itN}C*A?VDTxk<4XlFh z;_Y#bFWkVvQn)mK!Ka^sCCbcI4C1&QgE$i`y0zTXzj2^70^QUE#V42Y94CSUd@2yC z-A9H-hY8}4z#?IPFr}9vLz|I#^Osu#_*g-tDI-aepmWREIcf(JDegai)|^M>{hpRR+lK- z#6r>HQNYeYaoqttlq@NtQL^yv?6Xz-+`;XH2am0wXF(j7gS+ukQH?~gXYoh$Vpocbet5LT_{ue_rPYYYq(4xKU88B};=up$(PVVP ztwK6m^omRD6M{N;>*5!efRzFLltU_3zq40r!3{^8h`*I9^MtvsrLKkZadXXwzvk|5 z-CUuw*j0e{wkscp7L3Vf>_PON+VN_+zd~o>e5bHjh$ZJ@a!q*9Cq^%NPjpbN%bzQB zuAu^~q9h&Bq^qL22tRy?4q+AhK!I^IEdKPaN9QFy`uV8Xm3VH#AIabk@b^Fc`N-+` zhgh(Vs$=Q4zy^&o&_JPm;<%X%zdMZF7K(9b(bs%CxGYv*iX_yo#v8XRU+fw`6d`Q~>vJ=QKU{86QA+Bw!A&J20>Kb4_3 zyB@u}*m2iG7nl5R>kpo2J4c)2Z(jb{@rC4r{sTl{Ybp7 zFHnM}W1#M~IzxG4VFcERTkc%TsSao;F|aSCEzhYePO~-H8Lf*^S_hl<6Rkbep^4T- zo+3D5&!03}t)O)PR*JVUBrH(>jImIoCHVU+zWCY$NE^3+SwbQE0hD$)mLhP;u$u<3 zJQ(P(0bQL=YjZnnr(QJ#^HHolRe)hdkS~gbmpt+#X(H}C!AH_~T*Y8r8VyYzxh~DY z?q6c}9nLfh=~R#GNlOutDGLwT%ZDgC(`@#Tb8DO!X>|d+A-OQXxa!k_+!hJVX>g9< z!^Z;`CR8WN2Lmk@kKtfAL6pA|1ML=387$Tx_U*GDK;;c$P)g(FR_l{3E^BjZ(Bn3! zgBZK}h~2h)w+t{2%HO(?IcV;@k>EJRw>#7Nb0S`KO1C76=iehD{lkeAn?d0u*nGlk zG!-ezo%X{Xxx;<_oHyt&1X?p^H7t&gkfA5Hh=Gg!s{b^r-4xH+Lt=Jc)zGa&?*NxKGa?Riih`fELCuqJ859BjqaBvS z4Xt9}q@mKX)ikWZGzim!Vz9;{W?!tdii&e)AJEUnS6^5avs*U~aBR(qcQoV}z;yU@ zn{cOFepguHmV1SKVX;>}l)p%nzXobGV&L_(M)1R-IdAo#1x4lgG#VRyNn%Hx_K0Lx z(ZXVIz{^zeNT(>9(!`shvB;O{a|*RHX=Jk2(?BfvA2b=Pb(dg^3CbK>K#eO7^ck!V z_adTL2s}7=rnUZDG(0s+8Uo5bP^Ol-B%e{Q13WJ4s~fTqUx|3vx-YVX+Ha}*Rv&XK zcks#sX}1cp>XA>1@`vi(-vG_}khS4gAnDHDZ>^_*V14zDEJC>D!5hVOU0KS|A%TlV zYu&%%S>R%v79fQFM8aWxbx9V?{|BeL*M+j&K@oD8V+`D8@TG}?E$N(Zq?rBo=0W1P zgAgZU7Ty@L)EVHiScu$_6>dR455MkFo?wtszd!#zqv#F_2I?75GhJf#;xvmj*b8{Q z>)y+n7c|`v$TC>#_aI_k@PQk$P@1*=dE6j2rIj~94T$un-FzTqnI8|EXu!!jCw}5h~s`Q&Ui^n zE#S>2%_bVFd5>{!x@X*J&n?ch6p!pk7v%~b+{cO8T~zJXc|qxh3RZ3Bx6x{o62MCm zzIv?GLjw<_*-X+nb~Q^G>}vFx-SYA@i#xE-=2mjjL>Y<1`iSrC@DOUCscs???sm%n zC;XmBX+`;cywc&t&ZB6RA_TMWYAZthH~7zTv?6abEZo8P>#)yq3V$J9V?#O<3Ae0q;v3HiqAfZ1K5)5;2<8Ui; zQqUj3dUgjJ6r9#M-R|sz9_y^P-H|pi(3;irOHxh20g>y_?dm_Z)|G&&{TOvxo6)x- z@U3A_Dq5f^4tilXwT0E$x`%Uc+!Bxcj@5ZEUkG$Y=mj0UpkIrccp(y5334BToKPUj zZE`E?sY9vD1_yK@TC6vvS?djmAma2k)Wj2ASL+^9*n!T$h$jhXnn%&jR)q5$*5>`V zE`|)v$r7`nfvkbi(8E+=3+q-i2ctMla%;=UxWI9PARpNoCz*u6@8U4&L{}3_D?*i^ zcR3(9)#x|(rW1R04>D=WNsCFKCwOb7OMV}6H!nDJ!n|P4SogSnp3xXH9w2-dqoK#0 zbZ7s;W1V~4TmPvvQ0Q&LkWQAX%j!Bp1KmxN)0~j*^}7cnQZ%%)(uqVc=X$4n*mIL; z5fH;F1v~hi4vy*dYed?el-m3p9rQ=xG%w# zeMEXNJl}2jlh<&{BdcOC&jRKuq0~_}N|(FBVUOJH4tfo43{?itI8_XE_d&&xGU6av zt!~49Z}zE;FF~M$c2|T8e@Uz@MsLq^7apOS6sViP7x7R~ACg-cAGZ)6Sr^f^U=m$W zN=vEQOkAgkw;&9&%YGmqG$7`k5vTmVX!uAyfledbB`ih#HZ4G1{*nwkNbo2_F;N4H zKuf1+1Jwfe=&x9Q@%%?#!*Ox+c}N`*`2~pFy^=@_1c@e)kXw6x4dD|bkPR^asmSVi z3%$*L0MaBDV*G$Lv>#Rm8APx$jOs3s2z+bvr4qlkwPR>v3HB7#1Z=~$qH=r~JPMY& zjd!QmnMx1?-}0i>`9PY8fk^K0$QRWNBte(2LOX|Z5vZlWWCR|kz%2+oLxEHT-lV{A z1Wr)EhJa}Z0tpD*ga9mtnq@15<-!W#Zeb;vK3`#eOt@26LIb(*I$6MrFpi7pkd~68E3$HtfK%mVQ-YW(+cXB=pql(^*NDDE6G!R(MRd+xd;SSESd6l)8 zsB<;Bl{in(amg#svh}nh0mkYrH%s}<%5usl><2KW2a~@AK5EuqAb|4cdx=iZzfggs zO&6>5|zy%B)P@a+3vg!eKIU6z9x$F$nWFzK>Zc)KtVR1B+!{=MW;UNmfM>+ieUMK zcIU7NS0CDPR#aTTamqHZ51khBC`)Z#tOlgpLtB&L>kjw^3jQ2pu5Yk6xZG$64-%#) zVJs(esT&+x!f$!yUt7R6Oeg;Xc!i{QrBL{sTYfkNu@D%Tkih{{K)t6Fn4y)e^=E;d z{V>uea}%s}$8m>u1sJTpQ!e>G$+!ap*1C^LjYmRW`DZqwl*_EX-wN#y^SH$f_kr7k zrv5;8=j^Sf{&gX1{bFQrD?g%g-9hJ|I4z6y;T4ES$Mx2u=n_g3WF*|mtHiiR_C5tg zj_ZmYUIUD0SEE{rw(}ZU4Vp%yu-(ujoY3xPB?ITiW@>(y@-Xp)w>|@2Q9^jJvL9B< zz9Ji8#SV|+eF`H;eK%5il(I%rVc!^Ba<@l5b4A<4skulGZ8a1iWuf!StseO_gi0L& zQL`V|!|^DGGWE(GX#JhUUGbNtHTwg7w^jE?%muuT+7E|cb}Pd~ z$e6f$?P{!sRp#C-HpiScm;_}Xv_8=yW`E@gCXI4fpJ;bjzVu~_yP=((v*sdo_Ce_f z!eS2u#0iU0J{j?Kf)S4#QC}qPV5AePcwbUCpcdk5u?14`DUSgbsjJB|V?|Td8}95I zto6SJU~WjZy;uGc?<__!dvnvq)z)U4Cs<$zT)bH-2wYt5o3T|i1bQ<47ZR#7t<7(5 z6`=wO;-WD(TAT4A{dI6C;*HU`M8qM936Vm>(5YgiU97!Cph*Kf^3m|)Zn-UR;kJ#F zzqcCH$e6Ts!?))2;P`aWg--yuYDm1wym^uUkhU*#xiLX{~#RV%oKg6TEmI=#dcP3630r z_w=426qffvOd;6XTE^9DI7{rkSnxQ8Wk0uk5aX|{&uXqRisz5E0apE^BcLOoBcLOo zBcLOoBcLOoBcLPj|9b@Z;?ODj_G!47e(ntu8Dn-B855u(>E}QaN9Vlq^d{W%<38tIMKUt2pL? z4BzcFT9WeO?@h%DTV2KHEnexqW3g*t9$#HjT3GVE%$I2Cz_H+U&;A<;g~iNGX3^3p z38}iAuPCoBs^p4RR>1XKsw%y&2+#QH%JL2Oa#DFYYPMn1-(;?0WieWz>OOc97Zw$* zsp2bEmKBv%-NzB<6)QKcUbCi>FWmsQ>w7DGAWzLzv9i3lxT;9v;c@L-U(R3V>6%Qp z#7Obw8;dH7*OymEA4fCO^Jv-EB&aI7w~Xq+vaMfT!EY+}Rq}YL=hv50t1&8nm8b~K z$CtzTzOstnSXwFhRJ)8j7-suy3Rh1Lgmlv*H zf8`eOTn2~6b|ohA{OUsD8Q#C-`n&p`_2>%l`S)o-t>!#%tb*e_PtNTxD}Y}Xzq zav3E>>npfCVX??jht$AMFI&Coo+4gz)4!#Ly65-_{07Ke(VB5wIUMUa>T675tIB}H z-&26wi^s=YiS!VbqjfZN4A5tEInXg6)v3#Yj)5)*bp(Ol7jz7CIf%O5>*E5PuSPjJ zZae%?F1Y2x!fQ7}ILILd&M0ne^A~n@Es}rdk-MDod*YG4G2{Xa->G&X@O6?j-+kW2 z8L$xV8(((}ek1lT!Z{xKE!BAtOR3B+ObUyEgGQ{%^Sj9p%pN-ToLkQ4#Afa+)??v0 z>%Pf{b@y;TkKyz1zb%7n6FJAMXv>F72sy^M<@4m{dP&Il1fNfgV1X5!)qX~~uVPS? zj|dCI+D|CjBfGjh*R!&xBQpa5+zp4XgK^3`DWz^9f>bXeL4Q?z!ipbvzx-;C}5gw4;x>l|1Zd zTM;6{wH;J9)dp`s_#1?<AYtU3m&vNGcxesomXa5Qa)*>1Z^4ALp z1W)kZ6!OZDKlUo67B9AK<~!xkZa7T=`rpIZIYl%ag{MHuxo1TsFGUP)rFImJdAwNr zF)=IF9%q;Ax2uwcz$Tl)H;~+NWidsFppJRGJJ6C6{sp{91y)%X96^_Of|V(dS*P6T zmCwm7Zly8>Ud-8*nN=g*!TVF(^f(a4-^mol%DHFZ!SZf6PVQtJ1uHXIv=C|Wkl*pFbNBFj*8_0i-dVM>X_c`1RyxHfgMtb46Dj$H8hX)%W!76eUJR+4W3^YX|iku?b(=_RkL2P70Ds4V=D0 zEX-WW{G9p$Iescb;PoR~XEPuI`y5x-<_)%SQ@-E{&P`e5QRds=6(P2KHbE?03Bca3 z>hH$3%-jgD-I%a!g-3SV+T2QwMR<)i(usx+PxeP{>)fw#&x7miqu9{dMy~vcaGCWD z60_f}?&prQ!bvtI+z3ZVkDQc_x{7S4Zup(H?Jruw{ozU{T3sikxEJ|`0jCzzw$x;E zzJasaUu*m~fs>8$A`^2Ime6d$#UH?LZOqeJvUhO7zT4VQA*t9(95?{g_U>2Wui@?A zYuaKJrxDZvDls$9J)_Nua`#?h>YR8=+b|Y~eH8gns<(a z!#*2h&}58sC)kFk-ZD8CnBN-Z zSL#N%SKYnxKupEU)YG&*6^r0>C!#F^kvJbV3qNRS9z9Xu)Uj}1w8P8GTDK4?9sA1D zsaFKw$b@K|+a(5{Y=m}YdZnX2ikM|rjYWIe$W!|lQ4V>off)2nb_ z1uxh75-Lx5nbLaTyK3l0-gD20^3#+fd=ujKfH*jQnX-U!%Ah81zI_SJX{bzioV|AsK;Yz#D04MM0pv;vqD}SiL%g#5}SR< z+e0{blozPoyul)aXU4Nl2v%JOFhdB;lSg1r%Cq#iCktO}{Mke56BtrTU`XlIwyDxvQt)r|A=Pe3I|l_XpZ91H z>Jw~u|9;`QF)BRFEASr{oDZs4rQ1kw0AdBOg#1wH-k=XyzFdQts?lC-_VF0Y{EQ`L zjh#97tVe#C()UclmxgMVhAQR3Amvvd)Tp=g*jNm!J4{Sr^*;o1?%VH~!I<-CJ;WOL0fs#Hx<6%!#ua{huVVBDCj&XM z60d(8_MF@S`Hji>?U&_T{Z}eao{hnwog^G7NW8=2m|(l)KCK?q!_=Agv!oXIy;|$@ zPyr^+D52*|HePB>?-?)&TIH5US=toxu}y4FMpTc3svNDE7`#25^)&TyEg`QZ98U?E zRjarfU{%VqGd)V71sf=^;{eiQMH_%{M?DD*cw$h&=5xZO{ZNp^W*^zZP;VMDu-Mfv zSv-l8&)Pf}1?=511EstK3IeJK5#1ghcNBb~lnp%)JMrdYg@;wLrV z1p)->nGox8(M*I-c$h|jx<)ur3&ZD_r9Oq!Q6(p0+twYyq|u%kL8jwwxJpc;%FQDO z3jkI)=X*38p6vjaq8wz}Gvogd1}yAR*b`{I7c}AZH9&F+C~vSBl3TRBDjBxmQ=;-D zMb49l!fGpO2;XqE0`P5zoIa(#Q^9&cS7i2NA=1%PLnU@FHHZqKCimO4CK0n)mO?XTr&}LB2{V#e&&Jt&aiAuiv(_KM!>xIy&`DF| zp#P#_V+u4@5y=g;EL2+|-g0{WizuLvl4VVdDHioKc+zTVt$Q3~)l@fj_skHDY)B#; z1|h=$!`90iK-QaHNHhGNZQ@HWUnO+$ud&tSJ;4VB@YabY4Tyw)C zU}Gn~Jo1wy1|Ds&!C3kf?$lA`M4ut*QCNby5X6F>`F;wkIi=?mVYO~wid(spr~R68 zJ&`F^X2lD}xtYasJqN+tI?L3+h=f82e2WA-t-gWo$Ug6kd($gJJ^z8mkXz*Tz{eH- z3q0Jk;r;LMU&4MT%}v|1v)lK!SDBxpU?)a3w$yDwWe%#p-%4$!>GdjTjAjL(0xmJw1%n88BdfdG4?Qu_T2Ss!|!Vw*hcvN31 zqxNUvD8d9aOX>TW8y2Ropr z$!omB=9Uc#YXLzPEM9q7PXivhgBvaG;Da_z46r@pO5sNh53B>mTHW_-j|X{U zT}FMPnvEoNZP;zJ-P(UU_GIi3u~%SspW@*55K%Q@4%NujgpN)%L=!sH zlp#&0M|nA<#Zakkc|V|F=wvfQq(Wh<%N*#o=EO<23yPP9_Dmua%;^uUpcYR@M>qYiRqh?&k(}?l}Ni9hB12A-5C0NZUUCB`d(}O zkFg!hsl1Ry*cxA;wrYNcG-VSRmZYv=3j5!eaGg_n{0Tvu^W_B+U9y3M6fG%I8H)o^`nV6hk>aC7qw$=PMWG z6^){y4N`*P=R6WWg_LM`nE6`DJ<*gdq@=-!bx{M1VkCZXS%>9VSGb9t2;e zD!}Mx#(fPQin;U*Chuv~sHY5jVvx>$O#Mp(YWWw$!APlFLOY&jJWaxD4g3=6qb9JZ zn2w4{1urT!De5NJr_eqo)-57!;ooCubHyt!6R3M4gjdto_(lt{0RV#qY%G^wG<>Mw z6}e>SWIPKd;nXvfF2brWSbDk0uc>@Zh%lS9`>-9a&p!t(jSw*rX;UB(#yso+SNkJ# z7<=Z6j@m<4O*V*u+zdAw)mjfziOX-Mfnaab(@>oq=F#*3heaSb@Jet93!2b^pW(p( zcE@ua=Kcubog5(Zmfvy9Z@rgc_z0w0&O{ zFSY^V41v4_DmG$r5!+n_;gf2A;$|*35B*3TR6>m&eW3;Hv3FV8Q1}MvB}^0rJ_{{+ zjq`yVrY_yJ-}NGyY$fGxC@*xNmEb|A4wj8{i}4c1*U*$^YGd@*v)8K zG3f0S18+st?8zi#u1+^7tSVUQRHmd}Z{T{(w}ZUFXHmsh$rf*SVc%?)t3D!46_s2E zo;7cS7^$rXA@#jb9@21ZK7yT%^HQziy57XV$xJ!|%|+@F_*K`B-s@6F5DD}a?XDLP#l1Y^CXkKH=MZBB4MZ4 zmM(j5PtDJ%H81XljE6A8({hrxX0`=#pGiT5Bzu1I1ki+-FItF+g{KfHDk(G%`NqqL zrcNzl1D7a|#EvGeVA+bcwqA1!f+lHv{+{QLJ2*C`Qa53Zdm_QW?EztKcjX2L7fC*E zVU5inpnNjRH#~o@AJZ|&qJBCN{jdQyD|${L*p}b)?6(ej5}Q&lKqJ&lMrokfVJ=3< zNZf+08KN@f9^B&vx$g!xd*E)uL4uJpu;0X%6N51wj^i~higK<8sc^}~MST-}75i^H z%(vi<4+_|V{+NL2iHtK2N@V5{E%fe>lRQmS(8K2Qlh92OqB4O`A8sY{TGP_7ajki2 zgRLRY(Xic5kCo&PC}|(EiP+JKzdTX?m+g2It^h@owAOx%AhI?qog!3gav6}KqeAF? z3kQ_o&C#$imr`H|KI)M_jwF8)ucg2YHy#cT;gq|0(U>fuoIv-t9{C;2$L4EQd(Nj#zeWHGh1Tac~ z&&b6SsqXhxgch{;0)hYdpzbK3|GpFBWgVsZi9!A&f97X>%4;5G^tvfxiBSipi!6!fy-ehSWF!S^XRjRj9o z@KzT5l!BvK@B#&C#8C#!ybeJcag+gzD2NcJ?uNw37EEKe9g3}wp(o3Kq-BY37CB|e z=cz2k#f#YIEPG#f2J`Sv;B9mlwu&v?IBp5Rx;mwP*jwA^HnfC|7#;{_T9^{#qfRVd z+_Ium@!GJVv&kLI!5hnm$iD+?Svys32PA+fylt(U3lUWEaZt;OouIV?+dZ2C$E|^{ zBi1KFSboE?4QyTw@A=~*2Ysn^A?Zf3unos)f(?j}c~B-)tHWf(zIhByk#Ib|@Ko`o z2#fH7y_b}Ru)wK!Ul;Cl8r~6>$X}_o|AF$+pRtS)3HcsS-S@DmO%y7T%rs)c!UooF z59SQj>e5VBheyueNmWpVpT*dh_7Tsp`gURvH(+;gtUR&hv`s712u7&P0nsueA?Z<% zlE2ek+scT}$nUHS#MGAL5O-tz-a_kqh>L7-XYX@cy%6wL@D*|gou&v5Q4y{4u~)eD zfx##_M5EX@Ki?Y(n`j;ck_?U1ebvZ?*2PNPXLl}v$$u87L*TG-uwQ$Mw?GQopQ4x4 zkUiwC?YjhhSe+~egOnbN;FQ0lCzxfOPQwS@LOnr9BaWwlEkmb0 za%9usLRX%yk>pg6#;Y_;`Y$8NV^BqGQx5NBy7LkY#5;R8_;Dpk>tIsh>=|o2n>9`!kxAGQR0`F4dyq}q=4KK zIf9Y#2CQm<8J{_DaCkUAaQuAWpcxyWJz(w~F@owwjJ{T(3D83;=Qr+doJ_;fPeB=P zT(&)Xa2t(Vh++iTNq&0M1QJ4%1DTvS$%k*I;nCgF!(%LsptsQS6@sS_gqR^11u2sJ z7nqyq$FT6&fifcLIBoe*Hou4DbQ~8>8A+!sJe3tm-U?nEz3tGrxmK{?8;T})UTA`d z;V4<8z}ryd-Dn)pW5?34IDFwe*e&Q)XE0c=BkGtZhRK6n=)defy_qu{6q-1cBI9lG zV>!>Xhnx)@4HY;G=(lt{Vuynti&Df62Wo+WI?RJX1Z8mQGx&BZNicr*lkvAk?Zf;F z5L@O|OlkJR^4mB^!NN%`nn0OmF!tn`Vp`$K| zZpPybe0T7rH1Lv66ukM~%i$(QdylHA`;gT?jXzv6`pssfAB=N78M^8i;_WD#d9 zvSE5TI1iTP?Usf(OetD?pObkh;!K0!EW8uMTVIU>ye1stn=ZGs^z;v0xWRWLvY4!| zF2wVJFzi3c;Er-!OLt@ABfETmA!SmMph?n_I^5 zTJj~gJlCdd?u0`HcI9K_@HVNNp{0btmK3Pn{ZhK1%uNBzJkI^IKG7QJ>t}r;WNB^4 zKO~j0e3w)&(ua@Yj2KLTBqL0R0u7_dQg`H#XWUs&b~hHO_X%{;9F9i`!R)#Z(29yT z1x}@tvkhbe$70Py z+x-ma3e*;bo#G5{XH~)-@~v&2LJW17Yq$4e4g)GxG|aZXnlq4EBY-;L;6{!ca}q%GoEX`@_f*<<1@-Aer6Z91~%^>Z5QN4>!io zZg-C1xZ8uCG3c8(KCn}|(Vvy89p~~T9n10YM}Z!}e_?oaJXFMVDcL*j#Qfm;F^2g; zX<(c?@>b7z;D?hr{1=u>X8(l=z7MIcIBw3db*7^(A`Nu-BcyxcC(!VB(y_J1AYTf6 z{!!qxfSK*#)kBG_Z=k=%IKgLeG}OekI}8)RuVZT_sxHkyq8Yxi|6n#K(TA@Yoh|3f z7^%=SnAJE$Cq}iZ^LfZOPLdh^Y0qJZg*Rv#;e?CPjO3TbVK5KiZJWcfdpN}}`L~D= z3$GUoXPNLygW(H=&7_yz*&kGzVZBx20Q0u01e`rrnGjCGrRqL6YJXn3raKrE-kdI{Oe7Ng>yGCF=B8=g<*$&{2>hFZ4?r+?I~2hcM`q z5q_C_&o~?^_?D`SV)J~1(4Fv#)ZQ}#fJ5@bIA-loL|un>GMYX*`AbxVHN({=V|MPk zB-mx7)T9yFxpQzM4b9G-iYv5gATk0PwqF^G|*Y(+CBP09Na;TxGRDoaWl(F;BkvrkqhDRU}lNhte|)*m4s*zAZh$O@rX zkLy6}ux}9YruLvit%%l`YMoEaVdR4L>1e~Vh#-wBc=>R1@F5!rxF8GryK2|4BgK? ziSbr(nZ%pS4ihw z5lVhz1Z*$7^fclkznp^aj`}owQ)>0!{CMrGrxajg0@g8(qEPi=Kq*IKrGbihG76LH zDQmdD!ZP>Vf*Jr@lZLHQkgmL}l@q)b$>2bgP8UqdnOH5Xb)TX*rJg;+Tii{_>7a?O zQurig>o7e@eS$vG7_>((O~fga|42>b8=?d$A!`}fAV<2zerUf%S&${IZCb>B=c#S( z%k!Nf%P2@SLA5iHYc~(V=XPlo#li@p6jmL%K8uBkS!%{b@Ul`gz*sAy9t0b$MBozX zidNtzb0v7wkdVxQ&bY7?igO4htdN!k0wfm?sU@bD;PJ{K4H6A66!RLN> zd0L(_<@cCgQw2az$CBn@ykF6V(^3n(Fz4*yAV(8JpIQCG za1v(o*ANqE2pJ;^X)kO28%Qk3z3LRk$A0xil!kOS+zL362vx=0755rdM?CTg1Z=1# zV0f_16RZh&X55!9;T+k{zy(9K1A#tKap#Hk??IFl5soJZq#xjwO1w$reWTAt99`;N ztUg#L`ihRgI}Q&qIxTDvV#7E%*ZgyE=(DPma1U)davpBOX0Q-`1mgiL#4}gyuAY5Q zgDb>diDD?TDFr{;O_Wc=#T@;v1pHgay-aHm)^Ts-;o`K8tEXjXT!XaqhHJhbUn{ob zt7r$l${O+I3*l>XmzoIp_Cj8`z}E(86k9mjn8GH20$<0$yDn_TgN^Y@?jAFMoALy{ z)urITnywX^&I)Cn#c55CmYg0fIh{&Qr;^jDhp!=w#P?r+h%%R6G>yFxzA{W8N8lCj9cCem=|Z*s{< z1LvP^@+h-xz6qD78Z4?~`(6ls=yD89X`JhJhOAjN4bRA*JCEtcuV5OKyowd<=(%)s z*d)#%r5>_O{qTCSS;}z6w+i^Aq(Gn9H&Jzlp}J-^S=Kq&O#F4ql+}1w**gG9)VEM6 z^#~;xsYRrq`-s;pd-VJUi(}VDMQhBet4;mGK!Zsp;}}HQ+o>*Qg6-|Z35c{%9=H(M zoTC2uB+UG$NVWs_TR1p};}A-B@Y8YdvGGz)3uk1`O+=Rn+w*k{97b56Zh8E9^ zn<|swVNAt(v)`$H$}4{p#!-(dJ9#~uX`X##4jub3vA8e&+8H!-^5|saGdCExtsIv5 zuis+2)ESP?F-fMJe!gL}T7^lMo^I+4g@^42de&~+8&TVPBADk7KD;Up-6GxLx2B8R zt?79?tmy@f*7Q{&YkEnSHNB$SnqG4jQpn*?wBaj{$5%lnzE(N#Rg#CVidFcksSty6 z^E`^kV9GygGt7)ikuH@I;=w<qjh^dma1na{Oqwxf| z2&YBT_VZJ*hNcwt9q6eGqL$q%8rP5Kmqj=MYP1xO$fe9=loj1p7D+hW7YalJrW2wvQ`?5?>K3&3mYb8sy4uYqhyuYDd92NnuhOrH62`n zzXY`u9#r80it7;VSZV3z#eO(d6yq39;XZ^O3fDzLcZHP}m~aARvf6e6#LVgsK$GH- zQi8ikVM=(Ye@2{?psv@R^U>#6zKDrzR3)+Zr$u7nd#H)6{#eZ&;*60Wroi>eg;D2E z2rvW;NBvoxG*OWM0)er?-t!(^8wa%|$nR(yHME6a^f)Z`da#H&~PwdiU9+;quX1%(c*Z z-E43;TD_f;Vo?razvt7$N>KR31_~P~dIX|9!Qcld%M+|WiVNx}e*_-?fG~`wF5==5 z_#BX5#tMvktfYj%vy|mh;0?-R_T7lJD+xZ8bO#jy0a335c>u>8?gF0}G1|F?f1xHp zsVXlMQK!O66>2}jBpy~nGwd=9xOM!3~ zS@a}&cfh{Bh^TB+nr{{+jApuIoQJK^XGEhUG_p}bc_@Z45-mn;9>4}6&Uz) zhT1V|EX0OLfqe6$D@=lXh>AO-~{{ruEdZv4W){w*X*);f_raCJ5plUfSan90n!4O5wr)ND7FmOaKPr?7a3 ziEV+++zajTCRRV@!@jox*<5n5#U*brEonw8gw}Flv3V^~1Es%!Jy4n(rSyyMQ0m8s zuxxw(^(smWSPA&)kDn%y;W@`vu(am{h&Pu<={^m*Y+`s=vo9L8RVzyKP<6`3S-&~2 zvR8+~qijL3`GIKKyOEYHr9)Q#&>V=yzW5;PUgK#c&VImOV?j&gStOj+NmCg*ILyN2Tj(>^1k8uJ%J4Omsc znb)&z?MBRYtur}g_;eM%k0lgnGrak!kCmWn_CZO8O=948c!l2_QvU@`*Q zgC&*Ze+R@EzcC4H@O8^AIQCjT*x-FM@Rh+?_mz~Wo;{AvdxQxLTz_S(mq*%tL*dv( zwh1XFEdOD-Sav(j^9qLkQ5`+n^X+)PEqewJX{`1UTM5C=f3c|Dqxw%uzr`~Xx z6&P$IF=4(P)5y>JHu*O{%1KpNVta}?+%8H97pt?7Hun=^c##XUj|u88x-oj((e%uE zhM+W+D&7A~w9@Iyl-DoN+sa9`6CP5SDNrY^)-)+idJF!~@iQjt5mJ9hWN<=yh*jts z%e5_E{<8LC&cnefjk>5@mMd6C$?s#~Q8c`-%raq-2--CA+sJJ~zc>BU4Zbb*v%lh; zTu9oeRKhL|VfE?*8W{n}AFz(1zKq7FF{MaU%#VYN;{5>Qp5prh4yjMEp-?UpFMc1W z?{A}?uMOU5NP908Nl84}C-8gN??W9Ub^&5N@|qM|I6-y(2U-uFzUCZ6I_32#SW&tB z-W64(%&y@B5wrDStnhPkABJnpk-{u%gc1j#$bwETu~oZ!r(Y>kF0^OGDhjAI}iaPZ@-Jj3jDRHOkl% z%NayY^;eV&j|S1BpJ|Vzjj%3UM}cKGS;~2yAhu}+^YI%8{Jr=_?=DU{71xGz&QZa%8|?#E=nEs$cTGN$Fv7~0OG;fl^`7R3q} zytOBC8hiUo@oM3Ruy+^9IKue|PI1P>GN!Izc$qK^Zl;~TMw=0^!q7$tTdFJwLmtBY@B=UAy?zjuTS!JZQ@;yHU_;^qxQoL% z^A;AegcE^;7E5N+z-S7dj-odT@(?dNe1gysmw;?EM}s)*WX6&16zaE(8Q_@a`FcS! ztvk_FSWXSDNSRX1BnvScUbu`Jncf@|uu<7(3tvx@HVtTWOdAiQ-_SUt-lyGJI_L*SxNv-j5xR%wSi7}N z;g}{q9DX!5{4l%3O~Vgf1w^JUPed(D`AM?Z)KpBKC@ctdpQzeCKoh+Jiu76{pH^q0 z6j++5kG1X>h-Qg0DA8lM!+O+aZn?Ft0by(m8-#8M&td5Sk7h5?!SWC(m>STuss$D; zvL~q7AQa9Qfc^yK<$dr~neW0X={y+t zsKx`XOUr#T>FoRmN8sD&vryfz{xndC9AZg2oGuhV1qG>_pnI17^;TDD-gatxl?fC$L~G$!(^YWXBk>mt$H6F zmws**XXRT1G^^$bng-9ZzM7PPUo!KVcQcv8_`h*j;KFj>pyI#-b1z{TwGJtJ9>N#N z;eA@HuQG69ysylIrEPcim(t+kIm+UMI4r5b@J!9t5i##j^qr zB*cyPO+&7@ST1LR35)qG7nbx#;K#V68?_>&bJ6QSMEcH!6N=@ex#ap3X=Ufx7k8NE zV$KrpslIsih4*4F;q2!`*c=jD0)wf%H6dp?R$X!?VE>8bZE5A!I}KOd1r}_*GY2KLd?eKB^4!P)h}fgN-3tG~;+ zVtI}Q`;xmq3aCQP@ahHlX^1rVBDjUE&a}9k37GF#?#sD~O0)=5S}`W+v2$bdK>V(h zQRr|nYOj%!faM}IUqBb^p*MQ`w#ZZ>W&p87p_!J>L2?q66L*_-?;Ar2jM36k1m?07 zhM9AQeuE0cC{uU?V@H5va?o1$9HKRg5r!_j zfd2DObia=$5++(Xrfm2%y1+iO{TO_}Zu5@2i?)iUsd-w3Ds_XGPLoy@*!Wk|RRFFhL6R$);GD0L1X5G3)`~DguyRQpA{M5Kib+#TdM&Pa)De>Ap}LlTL6VKjMV^b5X zXYDfy!P>s>AMf+>JY@FSXW!1=Yp=c5+Uw#tB_;vUNvHIp(==8#&c*@ZtJHqEJ$#A$ zrcDfwkl)_7vt-ekU(3Y_U#LeQn;k9IC!A$OO~@8S&S^k?*T=^~JP0Y>Ll_H@9+R7N z!DvtqUwpt+zs1a}XH-Gd8QV&(Z77Z1yPfrJca~?iPehnLqh4fsb`+SIwqQ@b*qDV1 zTCj?H#wxGr+gfVuQxf=KqXfRO+p3{0X0cca{opR=+1clPXiqNU$k3Rg!^}o_vZvxJ z6}-Xeb9@^Aqm+Z;sEPGSWWSIsEhV_}E&Fl&L)h-&3kQ3mH++pEZMd(nDv3{G3j`Nr zi&&bO;Eue$J?Vqr}?bxd%Cj;5~heFE@fEHn-`nYyn1v?u{>4O%fYD| z&y>oHn>WKSJSikH;lx$8NV&-_r-U-qw5alWR$ep#{~}kQBi< z$xf2@*~u!B7RZ;}YLabsvXP`1PLbP8GQ}>tmt=;WY$fTklNQOLcCw9R4oUOp(&s$m znZ@cs#?6BqlJm@;UvEDx;YT;BT3MjuF9<$Ll9A@)>&ZfGUCl)WdI0d9G6BX)(Ff7Z z$JOi@E2V9oq;cJtjK$UCbL?a}Ni`|P#h6@8Qca368D8q~6uVk8Ni`|P--q!^Q1Ne;COSR`}oWSjZ8 zjC!82Qo5gKKCY(3SSjCNJ}xuDE14f=WR{^647&kq;6Amz1k&&giu^l~olcg*BgR&a zaHq8hK_bUpQYz^&nk7u8u+BXz?R)?1N}jVSVMS9d)30>0Bs^r^@jvLs`6BPa8h*6C za#AUGNCUZ&m=rLby-4U4U!=66@HlC{{1}sT-B@^EBKx+zXvj}0G@ZxbEHGRcrVJO* zNa~akvpaCA!k3&mcSJrj2ZdK-`$gIF;xdG#Yn0kSgRhDiNrcbw6Bo(Wa{n>tm>7R9 zK@nKNanQ|%AFKjTi)boztwc#xNvuAR#yIb!ym;J+w5D=U`_4r;cDR=((r_V9=Y9}5 z*cz!Tj`#H_?W5O=`ThnUx@chhVWRdcEr$+}1tg|;w&e2n^>Y4LhgZrleQV7W(T_)q zDB!Tf{*}B{JQ=>HB-0FHY29S(19?}0(r<{SVFjrM1U=X(hUgNYGdbyjc@Qwrz-cIpuLU=NMJF4QPrgSifujHtCsQ~cfIdA+G@`f>B@TTOqS`~D7Dsg)l#kYc;8j!l`~bk zvVMOi%XGdZt^7|{D_upN>sh2picI`wkvDr5IV44fQX~=96XD`SxG)hOoe1Y8!a0fX zP)=HwvXpR?3V(n+?6ques(Z`4)=bAtig<;+Vu1>Kia5$4k+_XSKQ4J?jSc4f0QUDN zmo4`Oj8o!02GMJv;9wxPRo^AlO5lMwHo1Q;XA~ZDX^KB}S)p~3Cy@vWI~a&Q>WFVa z-#-ey{u&C2KoPgZ-#B=WiWLAISBdSPy1m`_+p%KM31C_0L7J z`#l$Oc2A_UGIXv)LmR(JUWH?Uxzp186*cOiw_WLeduX1jL9~EJmHTA0YM`i+(euOf zY!5X2?|oOOzQ?0^z44yH|Jb*@>h4=T(6>~&AB|m^5;ZwpeFr4enDpFnYgf;wu43-7 z1VehvWFS;D7Pz`OYs|lv=Ws@2S!gcIvwnA-l3gm3PMPXYRITHG6dhgJG|6jPe0`aZ zN;PeT;+xP368&Bx>@LjYW^V|Zv&#ng8*17FwM4n_nBC;h-xbGcL9IxL;w}DYT7lo) zwqUI0@{Vhpr|osV^P=E{de=NHRAc{tuaU@H2`->pDv;grR@+2uXyPJDfZBHivH z+UlYqUhUO>#8e!U4m0G5oXA;zFvdy9YSdfrxzBu#-Y_YLY_z*4k25adw zLG9dEQvwMbCB!j^#T}7yId=_!ja`Y+dY1DW>%4LFbEZ+{@8(Tp<2eE2fjj};SwXgT zrI2n!yjyVrGh2^#v1nDB7$Pwv(VO}p(Vm%M`>RvybwYunUX^pj6*&|8(19Xm`PQ+2 zhf3u%>qM4FYL)LRNY`-2#@}2cyJ!zWvQCDnAPZRfnlFay^NRgNariA-6IO8OwLZs+JmBq-M$4POO zs8v2MGe0-`O`aQ^8|1xYfV<3_-c9kk+m;sEn&eqEQscTS!g)NiakKuyv$lDP!^kp8 zMNV81zOej^$( zgtHB8rAW~~_?r@%?n-IlxA*P(mkcZ$+J>NtG2yyTzMcrbpi{BYU!8oBZ@FY_xi zk*Tloo40REiC;~XKa;6GjRrlN*w87VYa&G}rJ+!tEf3LywI5jYY?7lSJ`^L*IlQA{ zI9V~_oK5Oh2+kg)Kw{J%xc%0Rw#bRJ(4Yu@Brc1b=!ItaiPTVTK~sDJ_7=Sgn#?gz zdd;*|UL);EW6Ub9T2OHhAF1PIs#tZ6*%>g?8Use!PTd&Os9x_1TXn@xjM2PLq-A(l zrD?^h#^5MN)w67zGaEl9$y2CHwkEn?pgPZt1Q84|_rxIVFlWm!PvYIm>cv-e<#pK4 z!-B>?JOk9p1{o;^Ifa1J1T z{SYPWwC({f1dXHdry14Sl+XnMi{E#)o6%aMnb+Ph{M1{qkNIn%nL?`rD>0stIEMfX@Hto;H{T-un0<}o42P% z2WL)=j=_R}Pjnoxu4h#8U3PJJI*N+$5H}Ewl+^tTUCGg{!!PCq>rDmsIG@O|^Kejo3bBN!-_o9&=&++i=F^70~_VC;_ zbJRaM1!*`wNyaxs z#&;nDTkkh}>m~!kTE-F2l^l=R+hkPd@XWZv>yzW^u=>lm(5j19G9YH=j`ac$!TjS2 z$ZPe>X02xcjReOIxc8w=zFP(W?^Z7@BxC?@q1#5d&~=M~L3dnxe22i#_y^Z5yqX5r z6|~I8CK3RtW)y27P8qeo<6l4(pLc|2tOYUvY+Xdx0Ol9Ou{W6iVf=b&LyHJB((Izk z$VQ4QAWu8ef`XhQf&5QspLR-V+q#&xP;pcJQbqRnpbyI!T98?Em$legZ|gt=;U z{1=H)qqqUG2{NUlZEX!Rv(dYe(;v3J4}T|&C1G^&NrGqB{l{Mr;XIg4jmqZDZGwId z-1u5h8iP5FKGJzq#bSze|q!l1en%1A~x@EZE^R$=MYo)@qQ19AJATKprz7uy@mx4z_ww3L!nX_&!O z2WjC`J@KY}k!^pB_Sjm!4sGEcA2fy!N@rNBx&|o%1Y;?q46jiiwGRBXTD%GbSE&zM zV}DqqsBOib7@WRpFcd|tz>FJfP8RP(d^HN3OpvIxA7gjZ`f6!i&I}*(vlx58;A+%e zsLhwGTQ#_Mj~19C>eT{)5X8FnG9GGQJ{oWw0lDi4WrEQqV^hL7kYb3O1E@Z5!IKYS zL0w3z`~;Ynj;+(&3JFl2B^_YCVt)XACPqEqAT*o>kxqnO0ZZ$lF~V$!5k;MHxf1(` za*?8KJ&N27NAzz+sN6|?aZ52hL-Gm2%@&sU3z8}TriQ!B1=0 z3m==<-H==4=4A|ZKHz%s&;ZtgF)ojQVjj%m(RiB`7g{=a?vbIoG2IpS@+vP7)$`=; z1qJiPilMraoE$m~ip})SK-8aynl(k5!vEmgastum6l)5%`Wx6&>iUy-#3a0?UWn^m zTwP6>GCu9?HNS%WyJm_p;a&Zg(B^Pz94~qf!x}BvWi%t8mq$j&FYX@yQbZi_+x_E< zbHZp3FV4Z7+gPjyw=M3YvJ4_Lfr@#mBDi=OQ@t~CI8|8*U#Lg+17z9P(Tr}$t6ki) z1C=_-b7I#j0%2K3aeG5At#YHx%=ocaQa0>EH91RFa$cZ*vJ+qPHnQEpBBZID(hRNg zUxGs#oL}-z{*inunT+k@Rlv;N%X7fJC!9}%uSgSybDR3v#jt)WsqXO%cEw(l_9BM? zhZC~i_WE|xa@plLYh`^G4b|Np;engg`qt-;y@eKH`=x86j1^qwioGKbCf1DR4Xp2J zS>I`At?x3{cUsr_F6&y~Y0Nz93!C;|*Ov*iueaxW&1v@9-oo0BIkUDO^;p|!-?p~h zWB>J6tZklu{QPfOTMlm-qZ~QOwLNR;2BR&~9KMJtyqiX1KaiD^rNzaJn$BfZlO-O^ zm+!Kt@ub=&lavI*9GgqE=uMfKyRmN@{BAMeScySJCa|*07@H;oOS5ISCA8pSW@V3* z4vmRS)NV4v*un6ww)y(9QQ8|vH(adNVfU61{6^YG?)qW_l7f`{qwv1^?n4UqMD}+|sPrp2%XJ4XB4QKuNDVso zX*)$z0oA~UIH#g8GK)v+MlqjT?1~T5&Dnf(2~U&dizQG4uC z**@ck-*b{3d_J3THVOGha!fKAL#oLBn8f~=$^NL5{V_B7nWYNlKZ12^spEs5tBZ8>lA(buy+;e8_O~# zw}(>poyqnn1@*Oru4aDepk#DBPf&aV|Pb4W+pM&#G%yN_&8Kz+cGUlZ*&CGJ#@rt@QPlTy+#rWP98fwrVTsia=BPOW4A-(r$G|GIV+3rp2@DTwM$R-^d?NE-!LY#Xtvt=)R~8yY z#)e4>hPlf?y)t$S$9|Pq(t6xmy;`6Zb|g6W(||E*EQ5ti$m=0F5QiGk$u3;62zV;k z6biWwdU%MQ->e&1Z5>oHoV(-)BQTIhhHg54D!aA8J1(PCpwDo&@VX8HyG=HaZP1Iw zJ>^$$bgEy57nz;`t-UjLn=~-K=t{;G z_Ufr)vq&J=)FOVn4cdg${g!6<$`V@4{%5;<+}L;di4CIqL^@FUzHuztRvDbzrRf%OX=U z9BlYWyqA9@OOwf1MEW&nXSCOH+%J>|po*IUHK@5f`=Qc|UBP_3`3Pxs(mr~{w?EY& zt#*Y6Zd6BaZEp6*|4JUceq#ot)s(KIcQ&YHI;iD6K`m6|taG@vQ}m1 zeA`^dN2{e1Uq*X+f*7$?1jIN!05R6Y`W#1y;t`3xCDOP%>dtsEj5W+;F)9+vAzQVT z=uirXzlg4)5>;mLjG1!w63K`(l&VcLlNnx+Uhsj^p3%**BUmfXCOMFTh)Be;yuTRN zWCWxA5au^77!)+`8R^2iMfelUREGi?T3>PfJak<~cmtNyf9EK<8aJOpjCZu-GLFCs zFMq7N-z@uIb<823FT-@brtC*pU%TXZ_=jHk0p2hevY!7w1U&wnGOW=T+7$d;viKb-` z>`oUK#5t7kN4`Ese9PW3M2{S7GmFw?6qro10gO(pH1RCd(aZ`vYNFoEOmDQ`+f)M4 zj8PaIm%h4rgG-nX@J_g|_P3oz(bi)?SBBr1&$hV1MVuULQ;azoQzC(k3`guc>2fqV z{||-y?!8*%kG<85tq@!%BzVg1Ru8^tcJKE&n!Lu2j*q>WJ968MnvVB#Yq&PCM=|)U zQ3UBgjY4M>JHq{UALwYwJ!xc*PY&c^1~QEk?;U^shd56gQ8vJfN4lBjA@2IO?9Xge$ux7F^dkOt;m9XB|pqlG?baic$t%b$*Jb8+!^lg z&4ijdY7|vbMrg@tAcC8_kpcHs3~AJFr2%93EBwT!Fb!Ta>qn%0ax3zbQ!e@%JN9~W z8?{Z2=$YX0BwfCBX|&>!ajr00~S%qgKyp;w2HAS{vl=5-X>8B zaw;7ih>jG3sf+hZA}IK&QV`UfE(8Td0)o1V9MH$Epz+avMNs|*QF0WDuO;+=*PK%r zj6N`BiaX6lPX%}y|A);PDD)&;-;D}AaiAyB(@3B8xA(n9meHn=le*L{ee*b;hY3od8t zYAd&~1HHt&;6>Ly!#oe;9rB@Yh4+U7(>p#^)(vNfu+Ah$v3H{)zB)$apU6LnTu-7yk!HH30)oI^nxGb+$9A@VkQMlw)WX zXwetUmJE517AX_z0$@f!0Wd4-{~N%}X)C}iz|tawyba7rK?cAKALrz@LOQH(Q7#0_=mu&9$gnZIgG{|%Ng zo3-%}u;my)jqY^vY?$p=Fb8w$dz`K<74YYCVIS8U!~r zDBLtm2KTMFDYi+DV4ALpWf(i51;!@%+&t}#6G^B%?y2eqOAm);7pGeio#5$$%@ctA z#?OI-9~RoUQ_y5XiQ;vAl}u0*PdN-4UiU=!B2Q*xbox}LSBVoKs^3=l)Nn4M4Zap` zcbaLhf(_-FyS}u!UGzVMSzu?{NYK3_RG@??xDc|r-Jsd8QMB=$L8CGL9``8-2ulF_ z8==l_bj99e46?6H+$&Tz~rN-`-q#;6yey;fK9P7U$L;gtv4bJslPmv}tn0$e(y4amL4XNqg zyJ)(e51w%TP&I_Xk#m)#1gAy&NoS9!7c-~|ssl8TpS#+fe_+e>(pD_UNKydSMcB2+ z=JMF?{4wuf!1v22#t)D2q&=o&N3!MKlw8yKrffMg`*wZ;(NOC3usr@;6urc>$;=u{ zHp&nEaptT=ejzo42VYGh;6AQJR!YL?uuAGsFG;ccRNl6hi-ckF|Y;wWOCkBR~W zS6X!T{1J*rA8r*F#~HX^?x(y$O9BKfeKap{%AQ6t?OaG%>=<7HjsxSz{z-m}vCr|d zD4oQ!Bv4m&#pm!TDamiR%l-yNxbS+up@K3(>*9na`(7z8uGic(3ohha77mx;N3tlv zEgl4)ZvFCZOdhfa*8ZEeF`9P%QeRf=EjDm7f0&0`$xqW%B< z>01)9&v;-woj`N|gW&Pbb_Ltc!~86gk2)l8ppRlSp~zW!UPz6{$&h&jA2%$dU{P2y zOy@ZaVdE+h4jDx)QWtpRr@{F?e}$d`!sby_Ig2u!-<5V(L8f#Gdh|%OOHe!)9*fos zm!hcK5Y)hE&?YY3`Y|Ir!-q|MXnRdY_=@uVj!+&P(}Ifv?uJDd1RTd8arZ-PB1TfQ zlcU{w2W^?yU4pg77wzDc8t*m|>Wh%qjFZ-3=TSSciRmxnE;{fS+dYv38QO~bsJl_V zK41=u86C*vBb`=cJ>m<;f^G*{Md$tUg4VJcUWW-4W$H8_9FUp1A6b2&-s z6zUBrePwbZ)fs-AX0-*~jo9B&hzoIlkIPf~&t zGyCUA1;*FPzI;4GQ0M>3_^GB)*^Rt z0m^oGNS+}RjO?JKx=^ITi&-~HmI0bfqR7~FR05zCsBy!GD2P!69P=rGO3uGadN_mA zuuHhvMJy5#0SO8dB<|QDhqK=}>d&w7%UNKfVTrKDRtaAiNX^>(ne?5#lb?W*wVod$ zgdljCk`a4YIK1&=Um`D@Pf^n@`YTnmiPArm3?&$<`70pZ26Z`=#z(qQa>fPdG$kS!PePxl631GzW26VgT93)%Mu@CJA0 z&}q>4P~97xCA^S(Aw(PYy-?an`hqurKJ}V+79za}M(4`KK~j3brO;>pPZtN>mqPb_ zsu+a-w-*PFkNplV@tgF>JOoI|S>#zJQteA<8wPiVZW6o8|3)``dhkEeP5%c75{;Oe zFEWgy$R)34v&*LBexN-mQhoE=?+5yEKVVB$$F8D%wIhuwg&w038EBGZsyy9AF0m(T zre>aoR7&0p*rbv%Hb7lPDcv~59HZWeXtnRIm`BN0J^Ae8on9c8R^_e?j?wRK`X;f& z)xeJA)j++7RR_aME;vIh)u^o|EUhp=!q$qK`+_sX(pn1iG%N&av=zn9Xj?>lHZJCN?NN5g z!f)KJo!UQqFvo^Xp?_I;QgJ4>JwZl!$L3yM!AAG!S7r76Sh5BI4s3 z!8jTO4Wcs@_4H&qxFU<*(6vkGiN0j6ULfH$C$Uk85T(O=3{z_`=PDEBKtjAQ6y<#_|l5H;F_Ou>x>f16+?(8wa1S_24LWSK*-k5NC(WUmAnu^ zEElTIxulVwgw&7paigRZr;jeFk(L@;PbDQO;TQ%4>?OCQx(uBqhy3Su_KZ|FgBFq( zsyDN!3%aDb0JjN~2g$;c3$&kE@&zopT+65>U(mJWCH9gts{gv=jE@m={DBus?ByqCSo{unL4?Sv9DrcF6l_M zm|<)O7<=5O?n)9d4eHi3a%@EYu6%AZzf{MbBRcruxKqhRj9uo~o9V>Hm@^9nUD|5V zm8Urmld96jdt9ZKOw9z54Lh5R8GEi8;Uq=IjOij{P6`=w#3o}9pfq&dMBNO^S@acE*i;}hh7D?Vj>4~hykJvX(YaNKL z-FXZk#IM_J3i*ix%m+RKpNhylsYNP2W0cM^J%$H(ZioBz+@Ul+W1qu>fYz2nAS}|X z*i2zq=Kft6mN->Tdp6|=z(r0Y^bJJk4e>`lZ3{-1fr^((r(t5LD*fKOK2tuH+MV;% zSVq`*_~3_#@CVuHlcd4PJK=-kH;LEi-iq1s3#ap4;e>3{p;n^ub)qRHCfCsD+~3Ol zMLG!~Ud_#~(9e2)ZNPm5rMq{ngh!~O4(mkD*x;^!8$D1ut=IIaTI!J-l|x>@eu zxy|l4sH2`Y|6v4u)1phRclbLFW3@m3J5?_}Q_RLku&hTHj*z>~$e~v2i@ieEK@V4> zBMC+s$YnXD+MzYgU?XsdN)x(GI#DD<|LuLhV-Ho2{~>5h7`dLH%Cqp4VeS4EtK_s& zpG_({_4H6E!LPqsp1`XJ5vX;H);g9S)&K~?YW`ee8q{Hd(&Q1HIOB9Onyr09S&*1v zW-WMy`?jWDR$;op5JmwPSu1A$4o~&H?-I%n&}my~Y(n)GN{BGvqMvH8M|5Yb~(u znT58k&p6>F&T%Po1uMB%`9H?ABzjZt1U`p;JxK<=HHSL5rc)}KR@-oKp%U7p{Ed0L zM}M6}d%yHQMxB@%^OMS)8lSWrS|$8*d_+7_2;)r8=v4C@<^{6(xh>0&G{M+nx#GVzBWh2#^S>u2&BJMd_ zwV&3Ktv$9(n!#auWtarZRGczBy5!=7x-Y`m+^zf^<% zny>DaH3^rQ;dRHB^ij=v-6xh^h&`s)ZFT2# zE^~R@Z)?xi6tqYn+UII>x0}v;|HAwSHyL|!YmkIVAWTQju2sR8LVc`5Yam>XvS2~u zvw{|X%|Bf8@EoB%UF&hYtF7A23lE-_AKOl%qxm9PtaXt_m*J~w_ib{8#srOH{+g2r z@&>%e#A+*+Q%>RM4&ukGv5rGf6B!1*No|FoN9!5LZmaGvKy4tvtnL zFWDvIS)sXY__byMZ1s9PV)<~NTv3}!sl}Ii-P;$8q8m@gK2L6oCps(Pb+pVMlw5-4 z^fKP1{b&`J3gUtT4q;1(1zFMn+iVkL~0%L&+$37&mZ8)J?S%= zJ&xx2y}jep3YOe}(rJ7LLDN{=v7>0kYu;>^FT`d(;c?VHJUD)ZCt8AEID2$C9(V16 z^F19Od!oLCFZY<2w)#zqdb3lCP9+YHSe9-reFm(Wht73yE~|1#bd-oiuT|c{q@fkx z(Ol`A`LZaDTEi%b;(tsG!o6stV#A8Joz6((Kvvdt`rbt~+7-GUp8>C+qJ#TV*3^{v zCbFzAS)Jq5vcAMOgfsnke2cwC7oLip1B-cKEUk+1K`Ej=#a=uE59_Rp&Q%rHf#7;+ zeQE1QR&1)QN_Z{U30LZv9H>rHDw;5ghA--%Th;#^s{@V>G>6szfmRsguZ* z1R(Y!Or=78@IM|-HQ0t>gJ?p0k`1Hm37QvdzSlYr+0>nP$)v;? zv*|4OlYo9|cm(t5F;eTXTaFKszXXlzE1wG6CZB3Lhai-Ww5Bnx@J-)7V{5GXYv~>u zjT4FMB069!TIE034L33fG~5{iLt$uZJQx)mvP{T}TW_ICJg-#j9Mlrnt#6VN9iAI0 zUutze%{j@DK}mlE(cy{*L008UUrGsG5?Q)V&1|@z%tXR^j&8Z0#Nc_OC<#i|1vS)G zo)|iN=n#ocF{j#SRH^qebtqP^8=2HSAT%v~X?(Tei& z-o=;r=T?KfF0BW7ou5R>qj&%%hx^Jcyp`_WB8UG0vu1ogJ@izUdlfO*$7OQ6G3!&tWrd0`DpiMyRc!-=W%33?n#!%Abi5F< z9q=-AxZSz1MWKD`TDqd^;PZ67hG`or2fy$|y{$~ui#plVu_ii$-9+q6PHcC5S%E@0 zbb98jQ^#DiU%KwzRW=Y^>2abg!J${?Sfp*0IOja*Qf$q}QBs2~vX^uzn11 z1m<=I+(rGGILMaxAJ_?2$kKSw=MHf1UUI+3y=RGLdeYo=%d-7*PxBZa$fG{@q`OX= zRu^}oWk2^cH-%v0mAm9yufoRP#W&U*cB#*CY`5bZ2+b$d-?TP8|Fre9Y(+V;7g3Cl zJ<1t(3xtC0)V_;czY4HPLIf zvZ*))G8DwDzB=~LLa8?nWp)lZSk(*k2e$LAC?O?k`Jl@j3>j^F=nB81I{s0>fZP*h z8jK+KB&p!Q+(R=7+7o=>(>$;H`0`8qkX4DgDRU>}$j4eEHiO#8nqn@=!Aa}ZJS!g{ zkH3>#0|LdRiy;2%HtjD%!pF~$K6d-cnUo#80u@m!S3t92lFk(1oM4mq(C6`PdF1!L z#d5S1B~hYQgwi7SzV$qAWbzt(jq*wYn+d2_i)mD)?=9Tqm_ht69`k0N^z@zO za@3#vkgG6VZDSsC#~)q1sp_RahV?U%~(;;<&eV_pwvo}=tcX05lL1Ci^xu0Z z8M;obA7NS9xdy)LE`V?XYAg=V-p?pn$Ee4E*IEb=$&Q3M!+0iEOV`+Y;wwol)JAb_ z61qvXW%EJIb20Yug*YtJ8TuG~{0)WSD>1MpcTus@LH9?AL8?a|Rj%n{iwdOUNxGEo zEk-QiPkJz{%H&=-&O!fVUPi!#c?SDM@lH2WDn@6HHhbZki_!E6<8>Fef+7q+$CVx? zfgNh)hHmN{`^I|!{BtS)=ivOvy+71NeHY3KnE1luI~6?kG=J>k?@j?Lz@C}vLF9;+ zL(HsOU3i=IDdZDz_4zvhvtxX~AZ>-**T;tQM}RDwU!ykvSY&%2^|msNjDY!Q1`akA088*{P<+EA zfd}rNp57)7JsNz~^4Q?pRL+m0xTe!z(7Z$(EB_$i9y{u3sEtv=C7z?3&M%*mW6wJ> zFT}oFG7<;IeUOY=-{%mF7t;mT$t+EoPLLFF6%X$#^V@%^>Nhct>xr9tSA~85DBT;QDwuQ;>MUQ`0PbWX!#g5{=>Eya?$N}9v9 zVn589C1m>8w4X6+Cjfx*1IwkUaGVgf^~f`dL(bTD0jAi+45Z!pw`A6Hl69WSTAR#j zkgNyEY5=ixg^_>`8`b*jloWAiXr}W0SqxBMJB+Ddya@O4O#m<}vKj`(sO{J%u;I=w z`VD|H(48HoYN(Gp`&s!_glenD{Z9Dra7Ll^3Tenk%2x|M7!v+hGN6Ukzy`sFjw*N5 zZ5-EJ%xV`TV%s?1ser5!L4^!Sx5tVkXkl^J0c?(a=C>T5<2Qn>!KBs(j-J5WR!rIp zmh~~mTbYy$7#FGD0nT1lI0EeyQQH0wk`KON3`Gg#pa`()^0h#q9m5E zAjq|kLzsu~p>uwmu*Iri>@JRE)d&MCwQi!^<_~ukr);^KR;<4Htev!HdF14dF3i|+ zA5Vw|0mX$b>whlCi?k|m+a0k<$(F>*0wQVV467f57Gadv%tNGP{e{smX3b1>J3VXV zWV=kJ_lyq(b0S}3h3sN#7G-3rHDXoZ+_8$u(K+TcENR-TzvnSJU<#)q8R8PebWVLf zCFRBq6#yIhcAI~~@BJytO-LzII%5cxp_R8V=oIUd%aURpk<`iY6iM_hySTykIWKJy z2C8DMP`B>pP#=C0wa~%wFEI~+f^3vi3@nb>zLFhvAc0j>3bHyCj8(bHHcoj>FH?(%Ut>z*#f0cleXrWv}qrkqj94(@MG zN<)BxiOC8v(*wou*EVt3vPu?eKK&4jGxsgQ$)ASK3z{QGN@4)`YfCvL{6g6*yHvCW zQYa+<1beD0+OwJ~mgaH=aLlYGVi}%eAQYS;C1|A2mfs1ca0=!#og>NRTSoEY zcWl+25DZLvEArs)i-mwQP2L+{V&4WfkbjqntWH z8CQYMb_1pGU%dLdiuf@pJc+PYq00J&>}-Kc0!V|Lm)NBGLKCR?rDD}rdF3-i=E zSxz=zgY)*}r*(UUL9%X(>0AWWz8`=$hd;GVHq#Zk6m73d3-zma4kzh|{f?2f*JXtI z&ueh@ksL=1j7wHdXi&ZL1Pq1)zaadmPk6MwZh-c*^B~WmhpbX0QTVAxNZ#Q4kV@2Y zgvNPr0xZ;f66|m?0w65?(0V42l9KA2z_}3~q*qC{G|3W0X)Qjy{2-jp72>BhgeQ_m zl0DWt%SbuIfBl>;CaIewGCDSoey5n&l1b9vCe63Z2PnmUOSc{xDSY}Bv|#ww`j97O zn!_*RDf5oCA{;$eWaDDVCD`8j^#DOV+K`nNL5;C8%p6WLAl}!?{SU^^)<$`OfifoAeXMPj$o3FUFrKAr@mYi_JQmH? z9?D2znFgwl_ifTDUy@Q_mrJa2PDI2y83@=_;#th0#no_% z)+5Y>eWef$BgQyv)L2*j2^glSInax0FHvuh)$zAPV!ZQ5z=yV?2$UkG4QV6kJ3K~u zsQ;6euI-4HwIdXId{^vV|M3aISpw#a45Ff!rV<9!oB;B{T2AAyyzGFWx31wYdVisGg{n~Mh>Ng&ZE?W_#Osz z!=~o`kyV{*rOVIltYJam40rLve67TI%N^KNr>pE{^f90KAgrTAa134u} zIJ-+CKTOLAjZoL`(Fp@|$1d%sHQK99FqUPRqB4ZD*Jd%eCvYihZKunwndhE8VbK)? zK+6-olnYU+S~y&LZTfZdA}1y;%GO?M(O%vakidm|7T`cDZHQEsF2^VmN4&8P^_rMj zB1aQGc{sC{6slRU|3YkldgObq;0<-98kJnyYqPJX7IK-Toz@T3Y0ZPVv=fhRwRUv9 zD%;c4X9WB5lmaN%h}{KUU#6pEI#PG+<}4ov1h{u|$#sa6>qgxERaR9N?9@Dyqxehf`VS?!$$?@=`+B^A_i| zr(}db<>rSWd?avS{q3SH#FDH`Jc1x|ITO{@LZ~#7=oOyY1uMqVudG!RHJ5%R!Li0W zBkQ5wL_&z$Zs#%{5YvXTOy{IGz=XZSy>T_w6d!|hJLGIaYhZkn#M`9a)SmTjNY?9T zI{Vu7`o*2G9QujPyhh2!L+Qrpm=}EBCC!6^f$E-t|L}=+gC}2RAlD=Z@-H4lUVM?Y z`AVV1>aE$iazY-q&I1a{i>yt|5Ah$uglv*r0jKh!mag2q_}K1AYcDQ#NO+UO)?YdK zt#fHd&YM5bZhXkMl==~+aK>eIAqO*i_0Ksmj`q!7!!JvQZ_y$rL==iCv0uwFsreW$ z!^i!(n#XIC!{k$8Wcs=86R3fh>;YY}l&aVgSJSx$z)F7H;$J0v%KtR3)JB=iiLZLfPI^j%NK zJ76OMhQORz$C-cI|6pja9Ohv;h2*6*fJKSV6H0oBHHx&EHI4<~FwZcvhm$f~KbY2?Q~q-fL#OrXqssZd1UY2I z&h`-}d%E5Eiw!9$E-pLL!FW`-rk?<*jnhDkwysEJ(<6PXe42`_=2N*P3gxizE)vLf zJ1Zdl77a;4?h+nky@kMWg3;Qu)*F-`GvX3$`e)P zUR3tbSNxLlLPw}yd0{4_3rlNP$l0d2RXr+)+#Qy6-;)3tG!70i!FK5iIct4!dawXB zVPvGl{y0r<*AbtQD9(HSNN-mrofq%o0Z*g?=t#1OmFj$%9Cy7@t4-SjQ=Pq*$MBaR z9Af;zN2|*mktDn$foAuz&COvdhAX~z%F>PZtd=CXHZ-dtJ)J=s|DVw}T#}hX=J7w;;cSH| zNf!1RFUsqHQJKS!b@6YR4^veQTvYTs+0o`;JD#jdVn_50^o!O~sXsamF*Brp{h2_& z#969>jg;uHV_yRfKhUF3%edHO(iNzXxZI+jkl@(=yLv;YUuqETicr5xGptu-6ct-# zj(QwdP=c7GeKz}Mrfx-bhAn)&FI?HY-qQ`P=h4AAZB{|*LmyU|yNGNgxxkWPT z+KTb~#7^+ai9h*?k~s9@x48MG#QbI!(T|5~){8Q3e^Ic|}?L#HSaP zIOzVGqA~m|8Wvsk=IO-5jpyd@S-X#vAK>O1S~ewCA@#mi4awmWtCZ)z_o8NI(ck!4 zR2H9El#@og{o~*Fn%S?g!D1$bNLP{G$k(OB_)^Jul8pFeB<_^Ng(U8k#JMECFA3QB z?As)fPNIawMn;?xpJ8T4c_2^fMNT?HS@9wdMi!U|KxI>z4@$)Jzm+#lgPg|00xma z*Qm0j9(EHTPeR0p#Iu=lQ*k%`u{1QR@ly7jsn!^ecuj zTQYu$>}fW|g+@sI9o@${HdCUn6Z-^-xuL;ISXC z<}ul2sofb{zfg5Z>at~-1l7Q1Pn_lBlTqU6DF*n1&3E0yzOtVtf0Ik?g(F~1F>eL(5@Kf(EriEw4 zRRBbTbZou;f|{BP(^(1R$GOq#u%04M-D9G<`K7g|QtAB>Vwy$nfntOOc~ARQt@b>M zel7XUVZo~I9X)bzsz*PH@8J+>vwkY9o9Tn!nT7rUzP6P|vtxmLskgL`UQw&UUZL!j zzul%iZKX#PDviCYS)??kIgc`YT# zJ1VS0>wh_Z`OW(Gb{3atDf6!+^2A}8@{Kz?W*&U;f4Am{aZ%0biF(Hoz2;=Po{xjI zUGvj9OXXf$^c>Z{a`;8RC?3eaUa&DKPI*zk_OCdg? zQ>!5@`C4Bynj?FymJz}hHB_$Qv~lt6knlD=Te+4TlIww?b&?dn6)P$61lB`!AR^zY z71`@mnJEsuo+Q{F;mbFQ`Vz1!FGQ9jLN!HAq$4bb%I=F;JN%GRoctcD(DA>TQR$g@ zLuG@F#z;+uo~n8?RCatIJJKEp2Cha_CC#BRk*D|Q+;7H zQT%IKZK@-%Qd+3b1ftVeL!=wEn}jDHnPhfzxUNxch+O1ngW)B3Hj|=}82xZ);G7uO z_tgY^oV(rcKC$S!g7zuVwBEY=;fzHW`my8m7`r32&d=B7gwu|%j>CHsI&X`{a& z0A>6gqMhNU412%oc#Z5?`~>C&jOn8T#_Ym?aaVD`_^uu>9x4qOWh~?JyLDsveHiM@ z*Nul3>&EltjDb)utJKevYvhMZ2w-pJT1g`xCAm&z+o7oQi=nm%MV(J5>U=^`=igne zJ=W_UJH6 zb0Qr0|37B-{2V(*_MFk!pmMnDdNN)%%=gfwm`tRY|FSjmXPCpk`;u^ajxhV(IhV8m z4T!&ZXuM!^3b7csWb?HBMgh?K zO*2v8;6CO#CdOmDW4viSbAb}Wrdy}K&z|ff7vovhBc%CS6=JV@I}Ynk4V2KpjlTja~)qs*+Itq?J;QvWYVBt!Tz zd~Cj~bKw;PF^7B0{Km)VX7;mE(QuLanM##r_~*WpGGuetOsuURPf>~BzwC&_0*C_#6jVxvKczG?Oj-V4{A zi&v@4dgpI`&m~-Z@L5Bk)Hq6cjq&x)3iWap=qxU?qAp(&gA%Z;$uD@&u>nWV9*N)0Bv&?iEdG}bve^80d|L@rJ#C6i?%}K zO}hCoSnM@VA!f+=~68I8dcVgAtF!3moK!;>38$Td{E zR?xGfKK_=d<*&Gi2K|Ih)>hc&lFjJk6*P%vlOVDW0w!00)gh1vzLgx?{U}a{^2%KN zriDiF*NI~JzW7CWyki?Z6dFPT#^)h&PsWjsw8Vj*U2+NhF7`sM_h0^gnQIaN?!&>>tUS$tfTWO~o!}I2OB0ub% z61vl4UJV%#aC~h2nn?#M1w__-{k%zLz{iH}Y%lKR2w!Auzos;8UPoKME@|+QSfx_;h z)}_#J=c(GO$&lkkjKsusc5FV2v0IJ`lIu~K}lJ&ioT+*VBxcKUxlsFn;YnC4L{P*U$+Bg8x?KJXNJpu`GD&H%`Ltpr({$chI!m%cz-FF5mt;(<5D>2i?W= zSoO!`Byfh;$Sh?q;zuh059ZvVXL5vPKS&0IV#}j!Yi`kcX7*EIqnP zaa~9#YfcESMMH|)Lb{IOsA?O+B<(sbxo~Z9QdVynoZ%6hGgKF82+J@#QT@(9U0#jE zX?-N;qhl}ebdX4D5y5^4LEG!J@I)<-xHEM8=&@TA3b`jV@1;=FX|O1w$QNlrGipR?uaH{|TqvX?@PNHc59~PQJmj&^f!<;LI|I!t1>m zhUcbP1^<}&IxofBO}=g%S*L|d{89X{fL^&*y%zn9v;lZmMV!>kI_#RKy|>-={}eut zEC}*>+TG;dSECKMX>zMJz&p7uzBv$`VM#_ltF$}FUg}++k|TBy&^8;uwot?^3`KimJ5I4H_J2iA zB!-{1_oU43FC&Mw;wQG4#B3~HwK%b&DSQBo^H-FHuZ_P*N;uP5F#NWArB2*`RU8s# zfX&%;D>4%f<0E!zVdOAu^IMpWD+;qQd^6^n_#|6A0R8X9{ep9=1LK|3xt3Uvsf&Wp zhd{sI4i4!d*Ta=h_>kY656L|ZpQcR<-VfwA>Enad3!3%R3p(m#2%)riUBL$%gzXUn z?3(>o`5kYUA8=`vh&L7OKPV6_my-U9RvBl|*oxZ5CSg;~ut(@}1jdJ}7kUbsaQS;N z3>Zv}^(QZ%#o}M6cceIa(bu`~coUzaqI)YAm|LesUl=XzP}@(KSW@u~oFPnf_PLaj zNGoC-QzCp_hE(fj$CCYNkwXlU5H=U9jc<30f&sM0dh06b9RoT>psf&@t=M9S566V{ z5+|V)lQ*^O(Jk`%8)N_&tzakHAmGLBYxlj?3kL{U=?p$zqGvhzCC>?&Wi-bx!^f@S z`P9c&Pom9@U2L6hrohuleN_1E<@}H07`q5NFCbV}fxr z`0Pa#Wq)J`OajNFm}b9EN7&L3e^I>}!Z~vkX!nao+-KGf8NZQ!w6w? z+MPG?gf@WbT(U?ohUxsi`en@MOwOt~OrM`w+le(KGLDm)W7tToZ~QAo_9kt?&bGqu zo0UofM({1{RY!4LLnP2c$~;s?dh3z8jQC;eYp$EbVqhK2jn@pnm1JI%tSfp=Q0bn? z4mi)FinbT}$Xyq{_C7|+yN`XwQDr%GKY;Ru%TvWkz}SpqSc@;@SP~Ky6A?`J*`OhC zF7Q`v`RGibZY!ND@CNKEA7EPIsp8G^>?k^0M*oi|C3X!}?9^z0!_>f4UU$u+JfqRr z?j@aDyURj(iSyxs77Vs#yW9)XmiG2?{KVfgYT~=WYqHJ-P347G5O}?yB^tkt2=;*?4(|ZW`m*&<9x2BUaw=7vqQ6Zq1=@zN)rg zDFBBh56u0-b5qdxLKZ>Dwt)FvkoYB9I#=_Ni6>wZ`n#3 zV+21G^SdNm=fKYImRloo*|UAD1Gl1mP(?E!z7y&Hz6oj$543(m1;4_Pp`Capa+ySr zd(Y|v*apNI3)V;TdV>{9#qzIbGxR&~%zjF`3lJ{>0mor0C>K+LbswP}e{{u2*;gC# z7>Ux)5_=lm929)uAH-BBad^3+5w2pAi^xKGQ=&`q@+<>%4WQkU#DQ{nL!ZIU=AJ4>LXq)7-WAvuDwT^rT#o)%JAXt>iJ zZZei2TQKl4_YQH1xaeHWOIhh4PMWz$S%-ka?4#qP0bc<4Y0#dWO#!?I$W5Dvs+bhR z=dL&EzzlAQB^F#4(md`D7xt5}`P`Q~mi0=!2`1nP2>^ZswCD>=iPwEF`~$E1{|))dg~b$wO){!8LY0XMrnA($IK%E?+B|o(q#imvlm4^4?$18Zghh;^ImuB z8CvBlvLM>#(vd#*5v}rf^5mYMqgBcY<24#CD-4*pDw+!o-XJ^A?>?nfmh;Z|#F&%j z&2IpM%UfOr9E4^&PH+@ga6Cs^q%Y7CeBgt;L|wqKZ~S>$gP?kRNIMheCe_4r*{ zVvCOmUS!q(4<=*1#{W>C5vP*NIs7316deYuc)k zQBTOQrx5w_{*hi|LC&g@i)EG~TPfI6^zE;LbdrDNvuqlTMS9F(7c`yigul8Uom zCMEJ#83-%>=^3o^?_)}8Ga09>$;rVLfBWF_H!Iq|=Fk`&U#QSkmD|HutIl+B>kO5_ zXuqPsilwiF9RkjppPsSALYm>;r05V$&Low1S=o56~dL`bW#GTnQ_e$}kkbe?}d)OKs?gkGWVsn=w!{~m>F=T#i& zbfBRPw>F)pQR%1W5gj#wpcS4xHM4o1$DpW|^QH7+qUc2%fnlyJzg3C>wO;SOq45X_oQ=z}ot;quIZ3_HQU}ct)rkqlW8-huq zwsW`866w}3Df+okeuRG#A%ZO=wO(%DoVX+Qd;UVD5Yz#K&l-_-x7KZO{Sts)PCYyI zOHxAg$bch7&#k62j8$8o;@a<4USW5J4%c{R|L-EcK|J9c#iN$*Ym1drk}=?yxhRvD zBCs58tq@mLXyEZ3F0sFXNJ3Qm-oF^-IB3&GBx{JMJ9)t*`P$+aA`0F81P^A`JN(#^ zSa4gX2vG~zpR@2$ll_xhE(t`m`kHseQx&Y1BLJ zZR7Bj9%unF)cKH9GP39MV<}5w<(q*Ut!9tWWYCXrOH2XxyHDLrQCJDl7FPPq4?HGy zmF4BunG1@da~#TUPdBr_BX7*28~L%V_`ZCIjJd>yAx6NV-qsE!Y94;6YQT97KRqwi zWX44aeI-#oP(rt&Ot<0t%BqlOffz-L&i1^P(XCU0_2b;(yDNnJsK?<0L)gIslebfT zv|t_NzPonO0Fi~T3XGwANkMfANpG(Rh0(;AwYNqH8%kSQ4j%n z2~w38i9&)&q4?-dRVoDuge2r4(x9mje9*CHC}lmwloNfe1 z?VfI}@KEe@Py2)vg7yFHTep%x+w=IowZ3ot*Gi!7zUSO?_St8jz4zH?pL44q^~aQZ z#V*|U5E=Y;+>h8C?R}i9GhhBm3JiOg0`iNHCo%`^nN#O?{AiKpnEm@rZ*BTu(8A+# zlynINHXW+_1JRo^mw5uw4*h~|ONZu~9oi#l>CoAjvp*6SWrze!E;(b-Z8e(awTdwP zh{665U#WqtfFyiov5?H!rU+A{Au%CmW1cnerS(#68Scf4_vKaE4eLDe%ooK7-{7Ws z_ktHc7p&34;Kbe-SDAxAIDuE(j-HKK0>Z>P`F=>EX8d67>se=L8iI(wZ^{a`VS9zT zqi5uYS~_{r_-w7EX@&&T&Una?#zNTTSxvnxxnK@&z8 z(Li%S#yae+K@&az92|7#u|anbS%1I%_?hEDH0{bk6BZcDF(XJ=%W96YkrJK3?nN74 zCRH29&zRRq(2)t99~B%k=ofK=eleUgWTXE2ZscFYCu{#|e6qGzeA0+cN@%is1fv0N zUSSIN4sbVX-6!`Gn}+=-W<(BF&>>N}`U2RB(seF6dyw$NK8Y9&is_ucZ!~L^vj^kr z63!k>B>y^)kU#$HK|86Lk<=*P37z;wF_vo}_NHs!9wR@Z;+!yZ5aWE))NjHjwWA1` zE91Qser`U<5PwE_F=|2IdCs)FCGSqz8V~nB^E2|_Jk%JjU&F8K92)fU>!5jR&`TTD zG2)AZesOfuw+H?l+xYQ(yYE-NoPK;qZAX0gt-4PSbj9QF_rr$0aftV|IGJUGpq1vo|Fq$KL^O;63)DC)O9#ow9Ezu$|pK)gzIhNWvjh}NrCdP}`ZRKZ% z#&BdoUe>>L2zjg@8s{EYwV$xsK2E^KcAT${>FhLS4q6C_VKc4TEhdBCWIo&rKEA&4 z(+cL?Zp|@X4*6q~eHKUmPXCoi!F3W47?e0*gc&Y)lb6FjCKP)>!Uac-hygEi+2>3j zLEMh@cg<%K_}-V(9&<3}-u9UAxONv*@9VdCz_F`tTs$B=ZjX^p2-tSoZVlMN;{ryy z|7P3cw%pC6Hydd!^z_v2j@*9?kMkMnft!=khfP^LBs{LlNLyX1SjD3fB(`54)1Qh{sB9 z%HScR!u!bueNS$9bJ{1&RXK@;@Bm(sk#NZo8F?{_Y534^E5o`8tu@z4{na} z(viBmeDn4gXcp71dEPnl(<-&MoYh#GG_JL&+G(BI_dfOh=PTiH;xf;ZOYL=o{^hg& zgEq)_pwomn^v)}|PUwu|dgY*(+6|1$Kw10S z2tqxAa8OM3%ZD8JwX6nE$pgXo180&l`+d-PeA(ndDI3Wnq}X@Y$AdmO=+lKhd(dYI z`z&FfCG4|=eU`A#682fbK1=w2ttA|kVywf@$d+GI%sXp|QcmHPUwa;U<5^Cm@HHG4 z$mDm7eMzhfCtM-#-R}D^)2?#%m*iM&<0zcFFS>}%`O)HjoNkquNY@mT7!^&V68Ir@ zAyGB?5w-!{r&Eu1a!7@<>c?`L;(1#n{0$q4vqQC!@0MRU`#{}r-~I8C7Zd9GA6DLf zVFyTUs)~`rWIY=bOFr+YHN{LWG*4IVmj^7(4=r)* zGlGemzG#!INTi0}M_qIwJnT_B@d6_TeJQ$^I9O+(`-pIk@m_OpbUMxREgFA`Zgw|1 zS+KKimmlMcyr)!SIrqW$4si(K)}{gc(iA`B`eyBH&ba*07MsP(3b77f*Sxw>3x8zO zvVNGD#c{k8hwuEny1@&7l&NXFCde0#&&kxnwZF>ct%iSPCrD0aY&zd~B96DS>nGcN zpV;;ZU3HUf1C$VNk%v;-`;q}XM__A7dKt?8pjx$ zhOHq0EZ^qF&t6No@X=c${NXUs_dvespl@D~a;i3cpNP%bLp8O-eDmIyth!jFLUoSy z%Jpiw%6Cf)Yr5&DJpIvtuPH)gd1JiD)uzRBJ7YHu`yo%{th7X_-#oObiix>RaUR^mQ;9aYV^uwdd=EZ#g*k{9=+PT%vGe%ZjVr)wC#hvfQ3heX?6$ zR#xuSYf3BY%1c0apI0xdr4MT=^vP8#mq(t~R#slG(}cU$TcQ`Qg;?;DSq_^F#tDNa zmFm6zK)5DSuGCvzC66oh#SUkVStQDa%DURBx>~qWTPkHrzN<_(tJWIj^n0q|ox9du zT<-l|LV`-jb1cdd0y28DZxQUH9F0a8UY(FocvoKj;=uOSks)VJgyvFNYsaCCWSE-81THUQ1W7ESD741N&8)m^dcX63sTfJ7VuB)gh zt5~kDaYxW4c~kR^hH*t0vdfR>MWLs;s6)Nai7eQZ2Uzb1!{hNVNGtN>-u+%gQU)sL9pd za`)t_>azRb<8p6_TH~%37R=G>5b$MX74$5k5A?a#pvzsJpo$hO%ujbLEXvQ$F3fTk zIUVT>vx-zdHD0u#hE9usk5_ZhxhQ4^p~TyxQYAFd>!I1kcr`vj8M3OX)>N0(dX=ZV zvc?PE2_X9mlE$lR4YHz?BHblr)ii&JhR#V)ODa}Yh*lWGC-aN^^%8jFwyYc$xXbm* zDj^?HGI~+%U0nyx8W{n1_3}E=RNj8J7Aj5 zlhjmolbWGCs#2BnsphGt)azL(1LxM)xao5>tg0v}Gg@C$Dhgg#QC{g;=`Bf6?%G=K zs;XL%wu+jy6`rD1bw!b<6Rs5sqnSF2TOxyj-j`sGO1%Gzx-!zy`o<`j2n;oHmy}db zEk`i)Zepmp%W3`TXBZ zSX6XhNlj%D65&}{wA@=;Teixp7Ut$HSz0u8@(iWcS4Z$aY{K_U_@}=DtIhm_CcL4< zd*2PJwsx(;^p>ld+LE#gxzZy6$c|c8a)VMCDqrQPTs~vzRi0X+76LDymH26e^$~g& znD8nSHkj~f6CO69V{z`JMTL{@EUTE5f%%(M2wO`hmESmN>ZB=?OQ7h#`FrVXq`j+6 zm~O&C6Z%Z(H{oBR)Bejpi}lh!TMU1_km$1q+B|1BhB3l zyg+^h@Ry{0z*E4@z@Gwl0S8e2dEjHD{}p&W<^K&hm;B!V-zERgz_H}V*~q8ep};?q z9tT`Vx#_^iNM{1y1r`FI1}+EI@_Zfedg?s}oKF5WNt53Kypr@m;04m}08arw1U^Il zSHPc=wlcU$qz3`tCOr*kBYiut6<8^0@;3mTz^8#*$ln7@BK@x9lm0WXm9!-mT7ZLr z_mV#oI34;H0hwCWy}$wFuLJ%R_!RI}@|%HUfo}kR3H%8774R&u9GDmf-+>c=&j9Zb z2>)tSaf-SA8Bz6*RCcnbI`@EhPCc|M-qmJ7ff;P1$H12+QK0W-n73;0K% z{BG4)=>8gbC2%BLJxRbxK>5kWn}M0s%L6V1-UDnUzZ_UX`iH;)lz#^JF8E}t=xv@K z0sap7A#e-%p9Aj&UI1PR9D+6d9dHWpRm$B9I9US3(TTxH$w_2B+guX5L# zwbPlc3@R$>Ruy}zrF{=mAg*_W0B?YwIk1J+^f7jGQo)B!Btk5AR?ZXu<|}!d;?Xc;o8ArqZx67*7nfey=XH! zp|duttP@#{NcSq_PZn;_T;i<(5B@rgR=G$@tt=7{afw=tzhCL8EH?#`1zVj- zov>Y`6%-N2n1!6%#A9-~cx^4qF+4_DHTDo!SL3a&QHA2eF;v}3$e>kJR!pif@{z@w zT6}xM?K7noq73J=L@hEq(5*V%WUi@3lME^h+Dv5Kk44dYSa?ZxOT~`@Bm5mxkKfDoxR?Jt` zA#gQ@_V$d8^Dp=&6i54NQo~?34o|FAeKiW;Dn7TA~N;Y=EG=6rdU?I#BU5O zGbRGekEgnB|sf0zHb-M1KdNs6~KMqsg^YP_X7i@>w!L=KMX7d z{s=gM=T88qklqS>igE$qV$!>TkCOf=a2DlSB@H|P`~dg{a3t^;@F}4D9K#2c{|GpX z`lo@3z&`?m<%5`db?gFF8(yR=XmF~#QR#_Q2xeGH@mSce+$nx@?=?ib8!ji(fR94o~+(I&!W@g-Es6lD zJE`Yf>P(mV*(MQ%i=iR&_9gj3?&93VR4B;LrqxBn7icY#m6;DY1&+K0JkHE=WC|S; zzjWs3FU-#~db2P?^75Toixx{e3-j|AOL|cuPjfScDT@p8ope9{j;w<0h52`qy|6Ir zc0!tkSp_sm-NJl9LIm6C$jmG#kcZSS%)OgtjoQw;gh1k%!&(rG`7F_eUvpO>G$M0lB7D49aIGjdayv&2M5Hx@ba?kdQVa?adES(*7u zz$kZ7RM`*&-kkhGvyR+#Q{h+$Ihk-gHxFJcpk)xjKpFaitVIlnA!EikWH|CNvK9(5 zI+Il(BWVy-0MU$!#4;sK$D}Sugrf)---#U&)J!$y#;Mb$-!x<9tl92j5AL8U%E&KV zlwXvc$tk|*-^l2V2{jX*{raoRoy)2^%}Wdp|8yD-+Rk%eCL z5e^%BB}}NSMWv>(OOoKs$Q33bORvLLJGtBR4ZEQ%`dgl1|edd6~Ktax8J? zv!g4L0W-O?BIWfY_Caa z8g&+syk5`CTCgy8K^6)oZRShq1ScjTH-8CSH7Z=MI|_0OrA2gHYEuw|ViM?%U^Lh* z;{p{%`WZGLtju?xx5_p%dPNCPAILdt*V)G!wt*PqPk+)TDoDm z@%#oO)E}`Ncd~7eUtunf$hwpLtMs*I+7XEyUy@fyfAE>3f0Vp~r4B*ok}LuT#>PjE z;a1E3M8sFlt<1V#%4f)iOyr@YSU=Tzv+jeXcN$NPw0OFU*xsa-%W@@|Stn}>s&!+@ zF0ZR8l}hQx(x^r-WmkK>Srzw{vAmTnmqKH2t48WC@Yb>%si~w5_BEueQsxo4V}D9qhl#qQIm=D0bAE*3ckL%1dr;MI@?4Fe-g* zcQ>O?of3L5sLp1=U%r?iOCB+hXh{?MLU&DVmTWhgbmt?d<+5j7QeXsIA{fjL%Ti3( zM*D@eC6}~VXoTscfTKoelRL9y_mjn}c*<%nEg-m@L|KG9A<0M^jD-8O#HKFEixOaz zD)X$&knqcl=~4zsxTDOwCV!c8Z=OgILUScn;gSsW8vzU&E7U<6av@~prs z8YxHwYXQqQca68u%QkN*k{ijZVSlb?vC1bHX@0G5tE{||YTJ6b?N>ooyzOl*O zUB8!{^p*z7U&43N5i)x5s<7Pat&-LR8hj|MtD#3F-2^)&gh>dku1rW11Y%|Ln@@h*n1y!jdZ+s3yC7x3ds5|AO)}+AfO<^vWBOYf(CR|JC2f zMUm$dOgPts(K<`b^nE7WXu`)$xYLCDOnBIYADHluCXCICv@_C#lTDaz!lfpxHsNC? z+-bsg6aLDCe=y;B6DH57n(%QGK4ZdPnD7k~o-pCJCLAC?X~dsy z!YL-Sn{cTKSD4Ue!mTE3G2tsFJZ!?FCJdVJD-*_=<2cfUlY5P;(6L!A{0RXNm1 z<62-`M;O->=@JT+i6{a6M{VPg~#M z{-pIN*W)(1UNiUuu9}i-qj6nlT(21~Ilr=<;o23OSnW`MP;&j18p(Bz(z(tsuB*n& z{YvBdYugm=-!ZN~PKB z<;vaN5k2{+A~(SLku*5HAo^X-m;JI30E$IKdb%gB@o z^QTUqHe#k4YKdPopzvkO#4Ga#%}z=$x@OX-*hx;8Hd(*-x@*%Gykfa}&h=MWv**se zIXQF4VB$tT-RJY!i5_S#Shd5}q+5?zc5Cru`E0&KA2&Xq%^GKmjnQHr_SqVIwxpqI zKw_e1v)Fpb9F-cU#a&VCardw8x9HZy2NIT7mX5hA^#_poGfUO#>zp;vxnkIaktuhN zEm`IrQ8o`c#|@ZhzxT>(2CYmQ->5Au8Wme~+XhW@=?lJhPg?qttINNCm9_SkidD&X z4tY49FR(V~gc>0!@su|A6YVW+e8R|o(j-T>`!opVFG8#(#;2*lLlRR)75pckKiV*Q0h zdsa)j^+U_c7NN&-IisOnNLAm>=-3{5?@e5KDZO_&FQ+#m4|jLV!}qSa2YT=PKJ*s- zr932PmTq~t^PeqRVbZNFmN$h;+y9P8tMwY-1J zJDk@U|59GyY3-?jFKM4xKhi$bj^@3S_ejEFTWj8yygPp%|3+SurD2fmZ2Z2wU*{dn zdo}M+-Vw{|d1tge{VWHxf6@jXOI81pH(pDAGtcVR)GzX0&igR_gZP*8{@zwL;FY{p z|1k4k^V;&>p7y@95}N#0-Y@e;{lfNMUTgo>{zvk*Xz%6??vW_Y2c%s3ua`V+@acx^ zo8qLtTb%e7C3Db6skqpvIQ9E};$4>x&)xT4K0Gc%obKr!o>EcQWzI5&r=<7rcnvYi zV9(yCZ$`4A`O^))#0E4WoU(=MTYR2u^d&a>d?Q7u;(Lvk7Gtql2?_@Fl>=AJL>Dm&h_doqhGz*@xs+OQt`L9&IV^{IHn$Hei z*VUBv!}&`2JFJ6Rp0%ni{A8c;cX8eRX5M4=UtD+Kxpr&Odw;FH1H3-0pJ`|t#n;ss z_lq~Q4UgV0-Ox5PdjHghHfV{InbO#HMf84YV;f&N6UpD)*v8l9MDF)Awy{4Sx&N$D ze%m{#VW{ODU8y#9t@-PFEX}-sJ@IR+)^g5cZ4RxpHGgxR3Z=xW z)g63gP$1SGa`XCfYWzh1&(qWvyHYn@nWVM^tv0_U$#+aszJfJ8zmjLaIronR=N`O{ z-*5H}`GBMDzd84Eb+|shIeeQ61^a7lC#)k{I;_Ls=kSS+ShXd^rfzg=${FnMXp?(K zqH-E-ZMn{GfzNhu&q`5Sbl}NwctlD-TkRUCoGHK5R<~0xWwW;0K{_cvGbD5btw}90 zSF0`G&>z9a`{)sTNfZ6@EH_4NNv3Sjn%ts~QCs*9C;wNC1#fPRg@GHh=J>&7TI1Uks%mSE_2qw_#@z{5?yVbZCK| zWB+=U+HxNGftH^&z)PcV6DIn9Pniz#PgzG#jGt1Vw%UdKMsFKq`Y zpK+zy;|)? z6YU}TK)a+Tl1{gWjQe!%XPEah7(4oW3v~JTiYTKGORw|)6r5jKbDFotDt{5Y+ev%D z+w7sC_fPLSpP@p$hd!cXjKv?!u=vN&FN@|o_G6P*2jCSyv^_$`OvaWkF58j{wDaLi z_K0?5M|&)%?IVk}a);Ru3pi5eUhiMW^BuoRZ3=oU{%fcwa1QV*c;<>zdnNrY^?B!h z%N9$j-Aj)nSSiDhxS`kXX60nJjFQkbpv}k{?#7xw2$@&57|Q-pm8*1e-x*- zocpysbUwo#`U;s1(XX?V?|R)Hs<)2p)MnFH@)MEaU}L<|-hJqRwD;bSDgL40NVzbh znRW|!P48&<*DB<**h495Xy+TZDCggO8osIh+&>;`nC>fRKlkz%cGdnxun`%f4bg=y z7S$y3`sHY~ z&C(b0I%qfWpxP#Up2ly8=%p@xb;MWjp23UZErZadb0#mMGLdTN_3)MiaEQK%-hC+g zk)T4NUzh70ziU1MSu8kZ9Wn8Q)oSRTqTZ5WqBq#Q-g=78eM))8dEzq0!S%4cIT;wh z{uw$@ItiOHyk!h!$8nZn$K@jZNEXT zrK};>FWEyK`N;A8GrB@A81}90T&x<5Ob>R=P;Eb^{Qz{lFLd;>?ag6zW;f+RroA(=Fcf-@cOH8>$xHJ&`7KA*tvucww|+$+!nSB?=1T)>^y*s z9Dv`c7hK01EUMKt+#bR|>74Lo*jY@S)b%5`*_GC09bjMEsPRfwqJ6enZ!4t#x2r4F z5ScUjG5?9o8n$-i4SqZPSc=}gSFHRWLsLend!Nu$JkTCG4o&vY!mVy>AoFcY2V>!4 zUeeKBzB_P>_)Y&{u{Y15KShjz1>8PpO8xWtQlp|No)B)sal*&gzt zAI4l^@f|w_-$$GLJO$rVnKM4594}QIa}2eIM%Sxt_G$LEG&Q>E4*HTozj))Ke{h$! zw*5i+l{kE2aHe&3aGPUo%7Bs8dc1O4;**9H#oJf6BafB=+$Y&r!*gd!{Lt#uIOQBu zx^AES5qop`AbV&V{gbiMKMl8b(0(oBgX1~fPTTJdR6|m~-Oju@x=GP)iqclPVwCfv z;cB%&2Xx_-_U}OE^tbh<;Wm5QdsnL=GH0BfW}U5>@*EQ1LyaXAv z?<2kkc6@bkOsxOxp%{M%d;Q)J-`4lx?KjAGJ-kh)E^kyFJF(mzI)@EyM`txPqRCP^ zvnzO}>A@3hi?f`RX zdwOJyWUlh^Rym(QF2r9vZW-FtfiLl*1$z^# z_R74x-;&&!D)bMuuf=8+$b1q<{xamSgwNrs8~qyxO!cevJGP09m3bol%BjX2TSvN< z&)$jG`o}R}Y)P2n?_mBExqZzN({#Y1H9g0CFa(>UudC~lwx6JFyG894T05Xwe3p~= zq&C`A_t$jQkZ-vX{>9r3Jn8662Xpb?gC~eTP|rN+K^E`17#<?G|KSuLIDnN!+2Pu;cm{{Y%Xx14N> zZ4P21RtSv=YVY0PKiQPs{1tSb-33k9bSpmhdk-=QZ}Uo)JtL)Gvmk&TW+5!n#_2Cc)G|B%I>sL)$R{Slp_U+0*2zC6U-iQLvO@1FbO zf#XtM%1WL6X4wOb_lYMd`x0f*dnp^m`wPl^xn1Uu;n-#TWa?Sz_a3S1vwYrhK8)`) zY@+x`o6#}sjk+un8;XYiNFE&P$KIM{YdyG;a7AFPC~C@oWCq|u!c!* zKIh3`?UKpb#U8r2?zhI;D@6OL=q|Qyt>v=^j_U*X!7p@CY+dSCVW(cYbKl28C$`g; zGQ~eGMPy-g3$ig-WNq9Wr~WE*9ADElIXlD}wDkaU zU>aq0K54<2*`*Dh_SX}qzgLV-h?U*T`k?(>x4W8q`vW8)L^ygU!!UmLJcg{1$1pG4N10gtR7 zu4+-U?C%6B@gddI1%Z>QP0Fs;@Tah~%=e$e3#Z%*tpUb?2tp{ZKx;GZb>$BrQ-K8y zZ7QCZa~aDWl+hWVz_!1Vk8Gyk%LI^Rjru!C3r=av9S%F&rGG)2f5!rctdZM{w2JZX zK%S+~M%qPsTd%ZETJS}m+b??_AUz`TJYe9#ZczX{G zq@lAd1s`Y!K2DTBl#S5LbIm5}OJ&3Y0;3~+y5zYQc}{#KDcVM=$XT?XW*f|3*l4vn z0B)B-*Jyv>=ZZC9Pd%Z9Z=^HIDd;iqwL>%QcJqOBH*dkE_!Hh6INwMya9;5jIPp1p zxBc{0Mmg4GNzwZ4!aF_IAHZMZ>wS}UV4ng%w}*Z|2)TjI0BI$%!E(nAt=N}6kBZcs-sZa7lsV}jR zTH-UpLtnvs0~eN1=A2MXvZ2#$u3N;`@YM?Mri+fZx$?~P2WI+KGyS{tkc)MflpPk7 zXKHiZaMGvJL&K>zTpKyVz;ni^7g9OM7yWi`(ER#^?QiJl6~5RCowbWm?vD}t?i0$d zqg&YN%?{)Sy%l}loc>jM=;y>)Qa?)%?TEECI~WhiPwh$<+tnsGEEm#4J6QwBy{0m- zl}RnX5nqFOH#)anTzBZXYa)8FdFZR@pjtA^!({Ri)4;9;nUAW z(m9_~hFjkYk@N)f`4khnOxSKd5AKPSd(2EnTi9sEU9VJDzr+;VMOSAz+H}?+GCxYX zBZhd6jClZGfw^)hvLgM`@N4b#Sz;BG+cPxN#`B)JG7_VFrMZDIm-yx2!vp9J2Ol)ojFYRN&ag@cv_#3;*`Tsf+*iMF!;APnj+!*f9ugTQUemHAR=p#!)N{K7ZNj&GB)7(oe`Xn^qNAHn2edB~{{l)Yg4Hcb`hd7gjC!^m~Ms!_cuYKCPP;@wJ4GmrXi08g#tU?4hg&TNagpFRj|d1JEya zGi@Jh6P~9|xz_&z^^mKH_x*SD?}__=Mt{{*zpOwU$N9DPvAF2hPRAjK#&AMSJ>nIm%f5o57oAnQ>=K2RUK9=U*dLg#d zz=8b~yZH4`g*`*3Y!N)g__0OU&J4!nB;yooQ}2{0%aQrY+F458Ewp2|_OxRyEuK~H zQ>&lDcBi9@#l*n=jNHU1Ym!qGqVV<8srpA67Zr#sU&$?+t+7w?gl`^Ty)044yohDc5BK$d%hxmFMd3E5;N0~fng(iVxBvY zA7hM(^SOvQYzl{;Os5Rxj-472iTUEoM`P=IQi-igtd04Xn2N;Lhy6u-{q96#&CyfG zjPtn)EZB!(6IT-F{)wSGub?}O(=!hp3&cG0h44MN;J_C_d}qdOkCvGk3SfIwRZd&5 zM$L9;MjUKU>VPT!6X@J2k1}*jaa&Kgs+NCVn3iw|2AykWG|rYKcPpHv7yXJ@T9z?R=XJ+WZ1~Vw$5&- zj&Gaas#YIhTvWV$wvRXxax=J?`eJ)D($Ws`tclVV{A~G{b)V}(xb-ROZmG^`+x~}$ zzsZ_t1BiM?&+#dWV5vKFNq8$H`c zI})o3Sm?tUwc1V}T#T1`ZmPct`H_C&^BK={;R}4L7axGS>SFjN;Y+mbQ;E3pbD>O)d?W}pFAHh&~xn}^n zd!Bf8d;I{lx|Dc`*vXBqY5t8lo>|zz#F9tHHu+S_d+8U_kIQ;`-2I+?Ha;=;kJ&et zkLYU=dhU?54f>aUAtPF@i*j9*>!Mtjl&e=3qnzl9feSsi@rfxNGixlL-nb+#eQ{ln zoMMApzCs?w21eu)NDTHI>r083x$u`FYk&3{EL}5Xz7JUDzZX=U7)n$2D44=D0sHj(<`A+c5Q$T7>5p*R^%)(wETJqdT^VqElVgm=@XF3|V7a zWPej)mM5nXTT51-KS#{&y^5jReqbHSo=I}&8?1AB%UMrc;dMja8Z7ACikf{5E2iy3 zFWb&RL%nr`VR!EahuBccgecQRnJ&tN&XISHJw@U9SC*kiP7vpjd0hNGWu5 z+&@IEMh>0(i6sVs#HNVV$bMuJWk|jX+`bc}PwmYA z66ZfhpRlzNoWwT;XM2Lo4N;uZ{^*usa8Ac2oPws4_$86{h8xe$vsMUR2;U?=r{Ik( zAG+j!SB)2JZ=ccj;%eoa`e6ElEdK@=WCA zAn`nS)5ABZmjoSB zCjs8keu(x%v>&4VP|&2whp*J2A~bDepYEwpd7g!MW|Wux4~N;V3%g{D6|vKv zHj|+@sYTj7`)#CMS>HS8vyZ+v&}ZiMHstTfSMVupiR~;yu0OHZj%-k)j})o6&h(>? zY?ZZ!;Owwij>wo1M|)Ca-)T)ca?p}|BwY=qY*J_X<}KZ24;W=fw0uC>?UuMsegnw4 z-7>WE(~rZ>deX9Q-VuL%>&GHL$m3~bNakLVBWYt4eEJW@{O=QvZyhWBgip{Mg60r3 zhmMoiGbWKfM#tn~bVYbP@mxeVqPz*xW)E*7x*@!Ip%-r&;7gDX;|Y&coA4z-TjaxY z_Je4j{Lp#wq#wn>u+gtFa5q5fclD>8etbeZr)cLB=sHWk|4hvLG&WFtV)3`dC&UNa zYg3k%lf>1w$J@V11!s}2KL0UucnP0VYGd+o>V1Me_FQlrmo>(AoBfL&%qc~Q>hnh^ zlgUTy#aN*1U5ei;a~orLH2tW|8x~{U=#EF?7s@{Pr|iwi+RCt>=x;k?9wG0>Ep7P(ob5*)- zmcH`lSyHdwGTNBKWUV!aI$7VqXG=`y31m}j#NA=X@tCEfw>j<^y$v7nb4NeX`_b4F zIe!w|A{LHcn5nLY^(9rHzB=f5X= zfj-qWqhr23WW?#|@9cYqZj*9S-YAPcNLjJ%f9k@PQwRLVic4LyQdhcWrLELwxl8p~ z*lqfwjQ)h6eU8zWyTSW0bY;Q=Y4-%}AE509+7$m-+MRFu0_Wk$3$ziTe^^V$lX1;L`)Tml&xU78 zKLv;MAq^Zm!6EyYf+Om8?4&+rhWr31vWkr#fjl2geYeNQK^BRB${vlnN#riTb45H{ z5&Qn_AS3ShSD!yQP$l&)uMzXQWwc7Nu9teigv_bI`xVveM$ zn5GS^xl-t_YqWAci+{BLg7xzW?19I`JDT@PeyVcr9H2s3tlNsgX~Vt>?8Y-7KF?x} zpZQP{KBJ21RN&bJ&U)3aGst~9@%L0^Y03t7QPBGNbDT}`nz;2VdvK>I`->K07#e$^ zDb&>%(+1Lp-_}+Ccro|UGH&LFG2ojIt#61t-k(xuniMH8_2i8a!s~p{*Vjm*BBk z`g^a}SOZyGEVESGC*a&oyuNXOwdo@jx5B|3=ek}C9aeD@A7V@%Cg!4SzIid6FOmKW zO((3f56BrB=#qMZCr<4th*?1l1sn=LX)No3qV;O^MqB!A-s>HqvHGi9Hzqc0l`+d; zOmbXr6sXuH)$Yt!Q7>_2p>-e z;@f)javA$kD@Mwg$9CEo-(qlNgX17&Z)MNEcou7f37UTc?Z8VzPV~XZ#$dU(bOyN3 z9;QMc|CzGT`4(-mCTu;Js6yFtk8D|Zb}%WDu0w}nX|o?~rqHH-h3sSZwAqXgXt}J- z6lAlVa%r?F@~*J0*U)A*>tYLSzIj=j7TPpuFxwQF&!SzKS5ke%@6exU?BeH2_CtrZ zTz7>ruiO;XNA0JMP%5@u`>A$GEYHAYvp>Fnfcjj+Ul2J@{|*_KvA4qmkpqzjNpGN^ zK4@x$X3?t#c$|vvu->Cz*3KZd-Y5sXKI$4}dg+enmps2_unHZZKPS>v? zCm7qS$QL=;`B-|FB}TQL!47`Re3cd8tPXtH5DxD>Nc*qBhcxa}G!=SS>h!|3)5Ilx zJ!kj=%D{JmxXk|q-`|2S8@kt<@JZly(%b2i(4P(cwd9Gsc%kFO`S9L9{65@T%DBg3 zXJa0C;P`HPKfmbHPDAD_oeh5sI~&oZNPpi*-VZ+M^9J-S2#q2KG2pU%6W+Uta~$!1 z1((Rrfj@|E=vqB?SVP~%cD;!Vj?tB|Z(qdN9m3Dq zC4P+3j<~01W3#o+p_{jFHP(W?V!`o@yAjg@kCc_T7kdBso9M5^pghX{xLav088-Wi zsjB`(cdTODmwB2ow8U^$Kx}P{3aw#omoo~xX|tI*VeBw;L$h_-S;veOJ>gyA44S!-KBN=hnhy_hn2T?v{YS9H+k@D4e4*IEj^>Y)ty9MiyowFrdrCt>PtgPF z^Bin3{$G##EunuVtA@N5$_$ADA#B{W%~Pv~j@-wqR>tu(F6B{ZU= zF7h}>85)QDZ3Tbq74}g7QNk;1AGmDL{4o7~m44sW6>hc7wzqA>_Km&5*7OiKQnZ-P z0Od+d{`$CICbsV^Wyw2&t`p~IeHA%>n0p&zV&mDX=)9z#r_Bftv=$4rdW2?Za>VrX zzr&hCe=ndd9aLX7=Ut=1S z-}Y^IZ+~oiEPQ%({R780qO)VQ9$vZ73DM_P>Wq)Ew~d3I-TL8Vu?45pxCF+ct(0dM z*X=WWb@9*t1$n-^G0iV~YK6acgucYTzH7`tV{cLXc=jI(#FsB7{`56=`#sJ!Eam4* zUEjAi*CepVr>Pkk%>BjM$eFAij-(8*f3ant{qZEuK5yZik#AspUPG)sbPYEABm8I| zG(HihT0{8DozNn&l$+6$j&$vv4VKYOoQpT~^(130=d|XtmSp~PZWw3}J(`SfCTX5E z&~_TK<3M(vV-9PW!~P1g;~1nh(N^dq%E?@*!8^g>N@CtacG4M#h9UM)4)TF-)XJIh zP#X6Q!;SrbRtK^pX(P5W+Bfgy8r60RpS`}n+Jda-pIif9C6+k4ecma2T0KVHWPiaC z+Nee}$=MNpwd;ue1ugV7zWX%n*zvCL-jBYWzd9IhC^)dwmn^a->z>s0_9q;iRp@>8 z71E7 zpdUyMGv0iIdx9fQwfzb_u5iwA)~T%>_;4vo>%115H4=Zwf@>w3Kb1iAz4#cZsW`e=3jO2t=9MSc`?TksvzNvGpGG8a!&`oU!888a_M z^7>1j!gs`W-)6;kEj>J*2A0&{KQ!AXf4;E zd#UJN1N!Db_p*JYP2CfnPlI>&19#doZmY*XwBj2Uk2$zCJ#m}i8_Jm?2fUPZx*Oix z@eT1uj;A8SF3tzlTQ$Qsbm4m#JU~Wkkx}13t$90rcYxc1UVk5GJV*W-g(vW44tX-~ zJiI~q-{n5VX8Bne`U0N|WFGImf78l3Xbbz9A|oC62^-J{W!Lni}<~~{P z>CiD>4f{!ltT({nLm%fW)%hkgYMd7kIvePV$h5R0Q1T*ig2=v3bj=^#=g}_4&Dg8d z5zb7#vp3=JRs%j5yKTS4);WQ7wGY~hXrq)i>Vc0kk1BZUV$5zrAAD-q5m}Slm1_F? z1oi^Xhi@vTFT$5}p85Wn@rzXZ(G; znr}hU1IJwh^(GA-j^&er|DmclKZ%^$;)w&mmlT=n$s5aA|GlyH7jL5f7Uo8LzmT3Y zp(_^oKa3wE?JtKf2f?2XZkcO}2U=K5T32W_%DG!vC(1tJ>7DUy3&6dcHcqmSJ{|tM z7?YAAD#ZMg^iizkXPdCkM*rB43tZ1S6+R(*kGqgF$7D4_=BhS$Im>gSoMri3an{R{ zxa7R*&%WLQ<&?Q6z}XMAUh^~e{BS?9+MNqoU;V-nI*6V3AO}8+m9rtNXEtY?fAcmO zcg{+1*4Q_Z{ZEmT7ahbD@o)ZFGxQ=CnRCCWg*?cT8#ydy{qDI{wWcN7o3qdrStr@& zDrYKubR&=Mfx=I%6W%*r#(pGmZ0cnaQ`k8h94WzG9Y*#7aH6Nku^~X^4=d=Z(xjbPN{bSytfgr#U9a^gRjHS zaU=U>vA$z(^8COliP>nKF&8tA+hf%8*CGekVJBRNwUGCwhql(frG-+iQlGE*l@_x5 z9Ouh+TH7SvvH=pewUTJ^z(7XeQT9blK<=Ze<__l+-2Jjm{!Hx=VUBXAsJp^e} z*2_BkTJ7-Wpt2qjA69(KcAmNUWFe1?bEt^5LTMrA-jK-?=#j{LD)glib6`xww^-r+ zzOfdVC^qc`vS~#&#~_>dwasqi?NLo7EswRg{rmTofA4>;fBcbt>L!uR{Sp&LPemqE z(8FuTA|J>G@5CH&!AAv6Y3NKbyc8K1-LXTP=#S`qdoR7GZ_`~TuJBL7uMjzm+C@3b zadBN_pGevlTOc&-_+iHJs4Zy!NaBt9M1>#5JlNktUv22O=wJ*`bkKoZUBjmczPT22 zHjVye)6X=<-Dgu%b!ZYA?eJ6R7CPS-I|fbv)=zEu57uPu^vjKYi#;gICmulGL~o1H zTPt;>e}Y4NX1(;9F6rlCa0I^1IsUN~yKMR!XRej`!FK!qo4H;y=lUJj9N3ylzsE7x zyYj|0Y0S?D9I92~Is1)xPS$PDq)9C2@3tyrvL7D{dM5FkG|?;O=^U|ftU)#)UpeUW z$N1=x$D#ZRlt4^L5 zUlv(wb>U}Nxz}mmNK;1ADXcY1(`9U9n+~%EzJ@WpTrO^BOhpbvhp(YrJu*;_3`jYV zBhg8bp?2=GDSLpq&Bytl)F~Nl;y-HaUx_{E?7*=dX9mrfPZ`m#*H4G12d#0p@yoYt zfwkYQn5&e`PuTGo#(lg+eb@WE~6wf${yq;!GiJVmy-q|`g!rN4R!`7Yj7kjyP zCw)8!kH^8!W{a(90{q-Byvd62GX{PJ;HRt`zKfqh<_5*OLHOxo4vAsikY)1oIg_6O z_$jfbC_e-6Q_|bfm3|J|={0w5fHxL+V=EnN%$=`etFFN&dEw~^bM8FMx>58NJGa7} zqnsWUJ5l0DC$UcwPks%WpEc)BUPLy|A$Fpp!dICaQ(upp*=EjW8Q&c0=q1^+Q(p zkb=F=!9Ka*!zt5Vi(j#exUb0gc6^DBrOLU{@Fh5t13xVAL-vP?;YkKIdpvT1&a}n6 znlkhBp|}|`Z|*u2cBT*~DgzcLAVbK(SlV^bw+$BfEd7Sh%mK!{SVF%Y%!|d!(xgM9 z%!@K7`lzFr7wrO>3th~E`z>1Mi8J`7@FkW0OW7^pbx}T*x*BE0HvXNo_gC!x3)tB0 zvFc}>t9RPv9MGNxA^T|dws@Z)g)>~DH$RZ^ZE>)_J*?$4>$Ha7g!g`*Jn?CgyOjTK z>#!#Ad+xR-{gAoO@NqJ&R^~WcXR)4n-f}bhz??@&e@W(xb-~NNu8DDk+k?T#g=&ggH@5V z_%+!<>pKtBM$*^14$WH-w7j$a{z%#b&YYn3&bsxHbUNwWpnB&AzDRmJ>05Q>U%N4q zzV)GC-WL3~`yY*@uO+R)|22Ena(_4XRnJB4XLG;or;+=S+&`44p7-vFq|ZGZ%xjF-o-b*Qq~9ama;19S zvoDg~OZvlF^?dO!Bk3)q&zGp@-R+0w4PT<3uOZ#6YtI(|e^;(Oe{U_S^8zVBpNkZ8k=heB=6sp&HRdsyIO zYrK{m(`!$RJmMPAVa7G0zK&z8_&RY3srWkMh-=7uHlMK8ll?G!hqik5w_LMSo9t<6 z#K&C&wI{d~)WcV)jIiL2nwg+4c5hm(ml0*wXdzVK*@q5Ai{n zYkU{*`|tx|DJy4&L~oyiXX8~|lZxr_8-v(!(UzP(BWO;hON69JNa%49p5e$A27h$A{Ia4c&Yd_7hn@UxrhBy`3h` zFgSk&PIWQo_zA<`X0HMMTJX2W3SW(Qn#9)*CbPG4yX@C`h_A8tiX0wF#!of#QX~&K zJY>qD>lYYbip9SusOg=E1@n{EHfDgj&7-DDt zNZLa?X^eNeIo_63iP1f})nkr#G%hDGIUD@qJz-*YwicH;-r{r1c)P$Wbc#>tWxN9e zwC4TLwgozE#7M2gNM*d)Q$8lKc#%o@4vd-5EU^aspC*YnY_|;SjDH~P6x)&webKc+ zEcfDvr!ijY&*8lfJriyngAeZ_hO3C-imw~>;{(L(tk{+-de`|ZytnlEaO*hg1TL#H zA3vv^HFXSi4Bo*r=}VN?9{M1$%gjO!=pyo`qx{5|=vB?rlOk$<~Ew*{TIw!Ff< zN5%)AMtm*a*K2YmU`Nq;JNVw>c{6(R96sEBe7JaG^p7Mtn!~Ky+lTP(4gCBu{M?AF zD?V}56Ms*9#i%d1KgXazS@epzxIZtrakVb4|2{OD9 z8QzEt?-n`JUrjDSh9h|?lGne4yp7n>jVk80Mr3#+F=DH6zCaD}*m#cZ6d$t)+1(9a zGLT=|ThTy!oGtKs23nh_J5l;AHVJ>btr!`$BNuk$wMlpr3vY(>;!SLiZ!3M;K$()f zF-;qh$9n9M3t#CP2SZh)uuM6J09TFPj{%Cot^M%Fry8tX=UZ_a2uME)*Qrq6sCZhZv#IgR|tKCjFV zEwoX@o~6iK3~QbJ_>4Mndn;=l&llm=hoGmFHoW+iUgSz-O3tl3#2E!IYaK~*o}NAB z2oEwz3vV)^Wf$XWW&P!a&tu@ThqcWvH73CWA7zia5j+{Jy&eh3I>XxX2WuR5Gp6Oo zq<2dj*h=BYa&%@K_eJcP|C)NISs!@xHw;`dSCt7a%2`A7kFs*s*ou8P3KYLmd`g|T zn#5)815|78bI5YunAq&*uguu&aJza(&X;|O|LwzP*JI;n9+EL;95}z&kx3Q4@ljy|As zq2d*3T_5qiE)DF-Y#_ZHxd>Q_x@7O$$J(F~+{Z2Ih~TWJoR9NH25xlb(c!GOED_xH zUbuzM_uxT5))mB<+c`JxBd&8N-)YmkPmQ6tnWrhISexmhizZEJ;{QXx#L`$J8*}xg zv9v?UJ~NgUMDJw|9!j64(Kok6YZm?m;Zb)?tJj%q*~jSZGrfV#No+{;aU=2~ev`cS z5#1B&J!hqU$DBo8uQ^M*?NZ+<#_*lSn7)&1j%wSD|0MHP1O9^OyawN=q1&SGjm%ja zkx>t8JQw>hKHi&BoQd|a<_Hc{t;W$rcknAgPq%N!>5 zVJN(Rf-!In!C!&?cNkap{JUeEPmvyrjTn!O*e-I5uc}keMm-<(9_b8s$3kRm;kzN< z3V%BY9Y!pK`%~!t*gsH~yhqS^>{_c28(`yJVj*_E@4`nJNiU#HkwtJl&U*=;r*eKr zWc<72t(meV1MQ(@$wJ@I&H!@dO6Z~Qnp1qA$(%^+tB1a!op$7>-Jma0NA~_-JwaLY zM$Q2Arq6}W20MD_6WRvQ?%b~MlVZz;Vnf=|wHowY&L~+}FS|Yq-z0lTe6JOINm{60 z%F*8vQ%2U1_CeLg6RNscS>; zjB^S=Imb*)Ahdl5HkJERw6k0AV~3s~&%n)d4Lx-OT`TmidwAY~UDVMZ#k{ARe*GEz z6WP;p;hXC04~m@?U)~z%@lAd3t&u*9Z@M3ym%d57If~0=;u1a)Pcy!&N${!vAwK!8 zgIDRp(?F4zF~VQY3yuFE;?LON!!G6|4|9^}o{M&bM{@S40sV>4@mex5q>%K>hi<+I z9Wu5a_DF-^T6UcI2)Xz!TyiEh_0M6a=wfeNJ`oM^4eh*XLPYK4W*7@wcPTf5l@6%#*G-m`f7Z1~9? zJSRTWlB&hee3$s4?1yeim%0*5jl}$;?`#H$I~cb5+wk-NwtBpL{}^+qoM-ApJ_V0U z`~zemhCLB0XIJHWi#9OdY-g_UsE6>;t;Cy$a`yg-tsii{PGU*v?A=D&GR_(pw)i#U zoI$ir-}y+J9phO`@Lhx*HH$ zr-|s%9(ngsy-myw`;|hxP4d*y1%|y)^e39Pg#4s87K8%tEeLH#o=WlK7?X)Dya(v} zo1!kI=D#QJUPNU`oG@og$b?S1OOq1&E#@c6c$+tglz)(;lYSKe8!M-Mn_l6q#{ z;|X7Jrk=LhCu?m}YOmmR(?9wC6({mwv5q+6vW#fbuodm3-?fNd`3imx?4HBqdr-#o zyh|+Wo(A}l&U*^-UO~Fvu=O|ex4biQ)?N0#tGT}jYzV(_tRwvUFFL~EFN`>{wr5Dk zg#%xRP6r>^o*X&D@Jh3+SJ2lX(KDe!a{&1ln_CP$R$nIM`;K{3%G7W9jt|x^Ka+iW zkuhvvo0L`TEzDPHt&gEo;Bl4O`q{Me5Xz@@{aBQVej4JqO7*Z z|2+c=;tdfM&GH$*G&JvbO=q~MB!U5&mBtLiC%N{wQQ)cE5G$>6~?(F*1v-`$ejg@)i590R-fNXoTIJg zO!S&L=4FEKBlv=8V|NW6W2rGk@gKYFWx z-=SqY&L;lq1W*-wT!!-!pzinhWjlf&cd_oA4say&ZS|`8o4(i zsAkkMy}h%8R|jL0m^k;(-lX&l9XCVz57_l)Z+wVe${nZD?ui~xdvdi6&oZG@I4 zHT3F0`X%41*Cc%$!n^;iUE^t&29JweU<}5~*~;UCRnDFpqYj_&DQR=m`^h#zmumX9 zqn=$C*%xda=(j_)?Qw#Ac7a}6pWF{d9jUL(d z4KN$=VJa0?O&*Gj?*8s(8YeJ1%CSLz<{wG6#eoFOoi9@PJPz zIdvYpHFm7@1^xH8W9NSM9eo&3d5pGIy%MP6m#HQ3&DGkRdfJD@uUsE>csn}i6@ORX zT|=ID(I+YN$>|8}1=dOwAPfw z8@!q~tiJwo4(&{Tnti;o-%OkBw>me?TFyOK-S4LDxyE{(zJni@8Jhb|Hu`jWl4p(g z+YKuH9Am(Q&XP4(sl(u{nw$C$giIG#tdO4$afRzZKU%8C*>WoT2+oO zXH0dk&pMfnJP4Ogub!#l{MQ{La*fJQ5r>@W^crWI`-0mmj6Z2}p?)T?UU~$O^Hw7g zXtSJMJD2XP_!d3)6goi0>j|%h8)6LR3OOej5$ueQU~X8sQ{!B0t1zpVT6B&*o9E}L ziXVols|&bO;ru*v#TjIj=#q2n+x%e|wmLKvUXrpRunR;l3Gaw*GQzuZPHzTz86)Qm zKh-3D$GP-x=||Uj(?I;wt(af6ylwA>`2S>#pXuuw=gHWY!lM>&RlY7hl|ErFL1K(S zRScjW@dZ`ZbnRoFdyB9Cpv`S~C;LsMjnZ~ceS%{Gcu9N2){r(;>tk1)tELb2G0|w~ zZ8~ZW>Hi!4{jm`}<&=^i0o3aR^cEV7!bXv^ZU1e&i%u7P>)ec_;Qvy$9$B*96~0Zc z5LE+nNxB8@^q%`;mb~qX2Y3Ciwy)+FbcWcWF5Ak0ZDmAP%l#;#tLtq@K!+^za>;$G z$o=f0Zn@v{+&<_ca?mJpKS<M;| zN}E(kA2j>keLfPK*0Wdgxtf~I*pgwD@aZi2lks(^#HfB)gAaf+k2mpe0p6m^MD}{@ zQrX|#lk^__EoY}iU(4MxqNiC?*L8M{=xp{l{lYn8i672$4e}eg!yY@shOOAcC(uDh zf_oNSVeHEsLu7U&__UzT*2siP?9T1vJxM!Cxp!s<^W#u-5a<5N^Nq&zFnHf{9=$eg zJ$7eL#)A{x)XvM8evUF&Qwal?^rz`Fxf?>_3y5#0ny0g0Hq7hbvNqc6?8D*w3g}Zi z&~7%f|4R0G%6@V$&Mwa@wkY;(ayPTOR-@|!?i_?>L1EHgTh9LFJZdc)*mE{TXy~yU zw<5zmwiI{2irpQynK<|*OxonRufs_FUi4Quv^Q)Ub(sF&B=>QJ^ZW|u5osGD+qIV( zdCt9+;!8B116TcQl7sd{&h}YN{-QPP30#+&QqCGzg-Lmj5IHO|TA2-texVIw8wXFn zE5K`Z(t>%K7K~ zBi`I4Q@^Y_OI73#P*)#9J{)J%s%X|)Rg@bH4#*1bC5mswZytHP8JowA?A@TR z*9GW%iNnA-Y#np)6y@Epfc@!(H3n8)HDDZe)6e6MW=8%y+o=qqjZ}4&1<=^%drt;|t8h$-TV>UuS&H zOf^N?5!Ae(O>6GvI!T=-(u?m!#{FdG9#-b#Vmnl4nJaGN)tk25N9)gX?)0xbBDmOS zAAQi)$REp0>YPhoDBXoWsIS~&xl7fmXKKIybq`oXEsfdYje;=L}*U0%&MEC+AT z{9SlzhY`OZy4WN`c}1@Q*XUG&2WQ)a`jE zeCFb{Tlap5>=56I$e(J?7*wB9MZK}jpRXTrrM!_^?t~`NuDNq=wW+|}CgI(a?N~!& zu44-`bI-hibI0l&eVLftg?Ri!7KJ~|SdTfA>pstF(tBie5_>hxl;N@sTWoj_n##F& z&p8;Og$qBc9dDtuBv;H=n^-b@)0=E0RzIPBc zE+~Mtlqn0KS(JBcp6gGMF~ENGib%$+@V%Wj<}0JC-)^|ZC$?weR`^ZkWUNz$)llva zJSQ^-ux&=zRg16``n$xP&wj%-UWD(3uUh&$@PimoyDH05hm4=v8(b zpl3CV{jSUGQ--3h@SKM}<O-1R9uWguJ$l)ilmD1Ca^Q5 zr04|Y@w`dli~fe^5XMhF;|Cr{}yRu;nRcuR+q_|hsc*Tlws;qUeGTlu7Jq&Hw*vfq+2Fh;Ed?Ike2;ww+QF@zbzlS&e zdRHTN(145UE+_h`s>k1y)sHynIRzfa57nG{0_hulKB%|j8RUWaT1{{HR>n#C(?Fkv z)2CYqOCQkot0w4b8f3nCSJ+M3yKP#*vnB$$$6d=c^NfcA%jsWyr7Jm8^&M?HO`X!V zVaUHIerLG5@D&wS6hS@^zKn+*v=RSAGvs)ftKVJc#^k*T```rWMdm&ZKmQKAS+=_!F1|3}&ozc| z4=w92Az?B$OH|8AB17k)N9`)mPi(Ux%3IgLcI-2eVNy5e9(DU&)-OEcnEeDRQW%qB zlX~itIoxwzREck^x?)7rQUF9H0@KqR@a|LeLNjU{`&1LggGZnha zJOi8J+)3K#M3+0c$5dVU*Ci+G@p7N3)6Y_N`l{&RCSdTus)s3a}Rhk36xba|`1QZJ#y$BmbFW4Q34nTwX#qljf>* zEqkEnvM2GROMgiJTJKgB)?|a6*{ZOfG!$WvR9NTw2+g)wg=XBFitSUe%&YAc3CkUj z++wN6i7uCM9dfp~&U}~hSJ#5O|*{n!kKSK9#S87Ey`bX1fYa2B~ zALsg<-F3HMrRvy6r$Z0bUtyzJ{kZQ9KBCq(uupN->T7leRy{mUa#z9?q7iIR%PM=A z`&SY-hH@l7_EWkEzXT^3b^B6eZ#8$x(HEQPm*vS#%w-pW=Ib?mih(i*#;>tl_UP$r z-;{lgu-HLDpO(;A$B}-sa<&y8_mpYS>i3o3 zv2hsR-RXx!*EiA36|{#jphnb|@18YX`Yzxn>Q;u1dR_Xr5U?e&+w?K~6*j2YY_4x4 zaHpD=d^3k{kh%MQ5cQsx{NN~U5ZNPkmxm{%&mdKR$h=U0^Gq{%$rxa4E!jdJL)Wk| z^rQIiJbhh{J{1}mvLh=VqhCwuR};SUQlY)K>gAzNr7@__alRX3rEbMq4dZsoNGV?h z^$@y9|L+2S(S;gmc3^+&d4u$IxlUrM2;LsLc*d|5T1dGzDHq?X_^nL-axVVX88}H> z$o3ZOlK6;0DxgFQPWM6w8K;|P;2%ookW!+N{VU0on?ye5nu*?d<{2f| z)s%gdXZKyVTJ}H=VScQ%+sh1wcRYH*Ws4YHeigT$54%+7Njo~kW5eH)6T8;?GbRK- z!PBFcjkC?jl3V_!DrA;x@2PA3PV$RQw2d~M!Y-4&9deF2n6+O|8FG&bV>)bzIpo|u zv=v|aqPe0cjK*_og=Xw&5gCg;7QfhKV_Z~fS#fQ9OOrih+)3-9p{#Yg@Vqs*7u!vE zP<)#DeG%-9V7+gHmG4UNZISfzdVjDU3(lT>0iL<}Ex&8?4XbFQ@HBE^v&eK=FSLNS z*lRAjHQ&H~m=(zO%`0?$*=oZ}oZqGYd)H3$*Lslmt>oT{uYkAvmAPjPKZMlj@yRx( zucR)aweVyL^*O04SL(y3U=w>(+EGi!d&=~Nm!!}1@^t%D{PUi>O^snGj5q1$X7u+m z<`UwM5FVF$9;O~eyN&o^lC0Ry^p61=3{kDpEj&L*{Ra5n5o~A6Z z0f$`YeogWik#{HFSP);ZZ+#9tt$zzo`Ez$IGDPOI?mmr|alzPKqC_sD%bbmz@lC<8 z)X=f7%roSj$Q-qo@0;L16jT4`~@DqMf6Fz;FYSY(pONqN> zGwxjfZ9^4UJ1n}R=PCTOx6LJP&HV%i;ekq7N5HS@sn=6y17!bS>x35)yD?vuwUarl zHA;Q#eGwiGb9#-vVpXcI#NEwYVut>{#Rf@Ff4gkVTE2Zr_inAc)i-?fysgAHNdF+y zmb}a_ygahPelW5^_V1(P&>8x?X-PPClv-e^n8?{>kwtT%d$@mq>+W;69P#kDQt-ew z?iCh&R_>y^wZ1FP0v&VxR8b=5VApV0rSK+p_n~NHu;{*O_{vLo7u$aB&X7fB{LcmZ zL;BfTn)|`0z2S}ix5kIdc4r->=n8F+vc!L&$b)V_mquNN3+?)e|6Rs~tQpsqqswSR zZa@I{ef#V7)_&*%&YN`^0WER^ILC(UYC*fjc19;*YqtoS1dYwe#7f8Fc=pouuim&Z z$7xi08hI~yBrRu&bY8A*Rnq3KID=2T_+m7m$UKp$&}IqyO>f>O@4-*-p#L_^LWU~t zN0;YT*b$OmWTUBl*(?l%P5zwQl>p>gX$JKks zq}+a$tPvIX@Qps&VP<_uc;XM*UCq2ja1xq|d}@J>7U)FHM_ zbv|palrQ*s=-LuI#~5|{x$0Dip{UZpcP=|2Gj5bDO@`*IHeQl7Td|W1pbLA#n6ny+ znn=IGt5)c`6rL%qr+RJWZpVkAfr9>9siShO%rmeV&7`^&sn^X{bGTQ0 zJnt%@g`_o**2F$6Cu!Pg0sVtSK9Xk|c${Ltob+`|_>eW)4W`%S+axW+PBX7yJY4L| znDM01-=B58|H}P-B({>3eJ<_%RsRW6CwG`gJ&N(G7(33b>gwyzh;dhxkIycdb{QFG zvY#LrJ_={|e_7x@+&f^*MdUdZ72$om@hMBD?Og~zaSC2iF0lLr8@`8hts$OX=UsNjCQJV=o>0PG6%B z`vm`wZZ|N_E2;Ax*|Xq&C$ha6{U z8DS?`z*XW+<>3_uWS7k0deZi_z}t8k92GuA9e;R7jTM=~S{U_vc;_1Ze_hXa>zi+~ zAM}*EvNeb@b()E7!8Z(gqT6KtCbG*0y?uBudQ;A0Iq551r_)z5Hsl=tcE*O-Lg9=7 zJ7Xi9JNT0r7iRF6vu+}{w=>@pn-JQb3z4L(!CGPZ4;ueF}v2VLa*0bupRv+-^4Yz*O|$)i2GC) zi9b?&kwfrJZ3I`sODVT#?c(xFa^I533(7oK{Y6Qeldo|@7Ue^G^r4p?cS4UdjPTfv zI&B$;Cn8kQL1MI6qeA z&3V@EA`Dm03^QEqgH4L%;qwTH|RVyuX|AbSgEaUq0hW=spjk zr!d|_kVz%VYZCmOc-@z~t5m&nYpJUf<$31aqHlzb?ENbe9-^)BHTj0J1x@*mWkcaB z_1P`GdP_%(JabZytVPRQ3|hJ5GqMHyU<*2bN%*F=MWk6GK9~#ej`51uRgrTZU9I>I zh>0>ZekQATk=o{6bPn1Jt&s~`#NTAZSK{(zZO13O-07u1PDb#3RQ+9Z-JT!m zepg9foS=;A<`#W@2A@%)%-gG4FyHkWk;y{r}+lF@?; z(JfNvW$;d*TzRg|bI?KOw|9=$tiUhR>Qx|X1bY7qpNO4cr~hPr`?6AfVkx7x+~uyq zKAibkA@hruv2W@34N;!9!B@iL?4g$ZUCm@pBywN+Bb+_&CS)+ORQIdu`e0?a9+o}J z%fLg{28XaupYv3SdLLZzF5=#x<)!r7aUI8Zb^F63E2OXF{uo&=X(Kq(kIPwueb`F{ zEKd%0e^1D;LF^0J2k{5|A$g3OA}h8Vjk-PIY8i(6{ppdH-ojiL$&LHCrp&R*?yRi)6nL?N4-aM`Sw#_Zi`b zI>Xr%DSrrOhC4ET70>v90;Ax^?cz_OP22I|XymJxVV+Tl9tcS8H*&q_J)uaoEPf$HKO?i;e3Rnbw>Zs)Fh!E3wn zJLlW1uvq3e@*N?UZ^2vlEu0}N{t|q|{jKaH7r)Ya@U`=;@_g{L@NAZEeIsMc;4ZYQ zRBF)^lkENcu%9S9-2{E>G4C6Oef#b7l9#llKIArQl;*1*Ux;(25qg4 z%oSGlHG0Z%)GFtM&;p-`nKo+F;gQkO&vxh|d?ZlTEv){O!`QN$wM8;7*6C+eMeBH$ zaW4Bg!%HJ8UT5rB|HH?t@Zp;K8yHW2AiIRGDw*fmCRzJ==6NTOF%q9lToQA?HPBhs z_`T`F{7G6r!J!)cU`03AmQ~<=K_SNlXV0_HJ1Nxb^SSla=Jrn3s*LM%v_^(lFU}yn z(#Siufxr3E{r={q3i{YekH>@-z~{>QA0dmi%t(Irw(VmJ`Aygs8oOuP-LZQH`NoD` z=( z+Q<8Vl&hDoDv#NT6F%SLUwO>xJrotlYOol?;-ycOv`mW~|M3CS75j?CNXIc2`{S{t{oYpfahP z_=@$F?aC$INI%AMUn1}NKXoCgU&qu;ju)%`zNuaMZNPWt!B^wH#<`91H!^>@xSqP{ z>y2w04cX{<9~x-cnB+8EOyk{?ZRc!!we8@Ik_LP5X1XTIaNxMXcrJoAgn)Y&?uC+d zU@z4Kd$q|Tt!&{;1hJ5BfYqJ%!Xm9S0=c%g}0Wqd6O2(d#wpzHFgi zsd{OU)BADWzc^@ZqZddsdt;$8z*~lkzSJdcl(K~uYa0#L+a_)F(4cmoO8*JZ${p)M zmj&*AJ4u@i@Z((i$w2=Uxcg_W@|SQ$fxBNAllW0o|8VYfEU0cbUFwj2-l@7_vy}`= zX5CkDAA%E{^>;k8w{D|Tx!Nv%JuliUd6JyQi&{tXObdMfts40GEAXwzz#T$g@>$8p z{BG%7bVRr^9+GwljYIMpelBfaPurbp@XfL%o!!isGaC*`UaOkB@$b^rrpN#FS?HJI zEQt56U#^dRBV&IFW8aIh@AKrQSSM|%kq@MZ4mXg}CDmOCS!;+}{tf}4~jW$5__nKE||3MT)$*zT`(&kP~0 z7qZ~5a9X`_YYznzk#~~H;CO=A6a3<9~ia4O{IY2!!WWp>*(p0)@S`US)P=4^9}LHOhHoWsF| zjhaTP2`?3fepnm|9nFn)43c-A_!Q2@7SfMV$f-i;wazzkQ6y(GpBSVLiL5oHeyht` zL+UH~n3J@UuJC&JVQ)iFpC{U?Ln3=S&^D31KB?`mcx1y9+)p4fTVycrbs5b2a(U0X z-DcuvkY`4_)X;tsCv-AVX9PBlfiZ0Lo;%3wU3s65?>bYaw8NWytyW}#xzSEnJKXW> zIJe38Eb_F=K3g5CjjJ7d$VywRl%^$hp?P}#uz2li6pN2=Zi(iEL>kK^;yDYUU`9~UPzis5e3kBjY$XKQuj0p)b> z8(<8|IFvemXxjLI)YE|Rd{6uRjOWJx2=7*M%&r=2;O?Xi)r=pZsn`_3(BF%(9V$M5 z?$xv|u*|e-ku$A~N2~JInX7p*}1D^C^`%2m!;JmRO-xncIXYN4} z{oa_mfA(s0K=A1px?}xD)2GEhw=ge#-O#PCcl(cvI}#Q;6e`~h4rnn!dGDVDJ%kqQ z0eot|q27l5zjL=O`9n!BY2^Kr$T@kR)F|$p(CLi2_o*MqgQ31f>PezZZ_1W*uJ?^y z?|*fbMV*JF{pd)2Z^U2uKNQ>3+iiP#^pDJKJUYmXPXBK@$lkU?>?`P=Lf{_JLD-_N zV2e)K);=~&^aZ@cd}(RD_PdHZ4GxOE-_ZW4bbfyDhTxIUylANZlf@I8%`dL4o4UjE zQm&NQy;#%B?EZnPOuZb&zUV{Ig@S|BFLm3ug~U$6?uf3Z4&7t$+n;V|@PnuPZ{ev| z_>OL+chrFz#Ti!SV#3qn({VCaH>{KS1wJCBwjhhxJ0|;^jpx>g4a(fZL>zvDrIN?Q zc$58;tW_{)aK_6$Umm}eYrhEdgzN0xf?vdbm-&+uzSCGY(?~D-pOYE8R?cR;%(|24 znH^G(8gj(Ud)DR_&|mtQMyu=rqnt{3O?(}KtHNJVdwvnh{KCg+)W6wK7~?Dc$9P}% ztS4P%w_Pxha(a{jp=SjkQ@Vo5^ zWKD~<)ni=~dM)+%!oFi&sgOC@+sw&j9vT8Jq5}=+6^-*K(CBIeP;i%c>~g(7f=MUO z;q;-AH2BoZ%%qcNlef~pww5p6_bJFXbLB1t_R@ft+@-LRy5)>!5Nlgn0IG4SqGQT{A&*~4#`il8%Abu6`iOE{;Wn&=wdYu8w zjct1*(}(P}=4?u7)w8r+_Wa@JJy#(7N*sHU%WRxG|CTheHYfY6J$EpqkarMeGf(a% z=NdlLeSU2=?3Mi%+$$q{75=9?7zA&9-Y)aw>UKpK0fFGJKR4lwmh8u>kFQw9!aQsW z=$t;B_DP?>8}~anPqWrLyx|l0nxg_=UHu9^mhG%PO(G5a&`f+7vgRoMzrT)8BW;!W z1NS^#JVE*)^r1m5U@vIFZF{%YFg^?D1ATpqeR=e21^85nuc{q9=nZ~np;h?o(ACWA zs`8N;GUnUkoAKsnFI7dawl$YM*;bXk+SURzlrcBC`UH3ShzxA&U`zN)^y z>(Uk0#m~~88nQdt$Txz)VH4$5e#|!y)~YhaxlQ7)RvOi6xiis%Pse6dR}H0#`IlP6 zJ@6xBEev_NLij;+S~dQ-Ao6+YTy6|nEjUPhI)8tVy;Sgb;*SwLz5oY}`SS8`bJ23Y zqs8p+y?Roo;r24YEd-j09N?bCt0|Sii)8(_9_8Pyj18lC7c#s3>XWKI=g;b`mVJy) z!NnlwDpeHsq_GG_#zuW9hOVm9qj5v?1O$=iSw(_;yFWu|+!c=N^l|^!?(eIOt zD#kfyl$%MNfqWl{9Sp0vZ|!RJB%9v8#iUQB{v`01HA|^aaP-tCZTHl9a*~O&)h*IP ze&N1zV~Y{2g@-XNn+ZLq(cWb`uekbF`tk~W^gA*{`j_vqhe;nFA^fYCcbN43Rr-%_ zy6QgvYpg$i4F8>>Pk!<8*-+n$Ig~H!?TmZ5@1Y)TG0lE?^;&q`48H84Zr0AwI$h3; zM>D2}816W?hB?acCG0UX&_6uiuhA|;oAeX((VA3S`TfukAMwpI%}Ex+IRo$D{}J$i zyxs>LO{<0OHLCu(VEXeEbwaylYvAXXQ|;v?M$Qr=zeE?yH&qStOr814H+>EC3!%<@ z)kfb>Ntz0|7XTSnp)p3K+!J0t@L$k|VE94K*!^#OE_k4;6AjS72_8ZR+nhBz9bTqQ z?bug*0vzBW@VVn$fjsN@v`9C}vm2is;5N_LdcMgKL>62Cw(LQT*_S<$f9@yc;wD0U9G{V{ozH{!>$^*=kEmN2h!d< zur~~}w~eMMS}alhTP;`pTdq|7cT*Vnd=B8+aAKI8dep64NZWlbxBeKRxlJ%-!M zBu-?79XrXsMC{KYN8Uq^dhCx7%CZM>ry;hC*vvvtkq-sz53yl~c*34Ne+IX_k@Yay zt2o5hdP($~iE>PB`8E&byn4aaFP#NH&L*^zZ$v`BUX*RcHqD!3Sg-@V$K0&fc-B3| z?z|J6WbM(0jMlEF@ttRtUP+$b?mSc7c`EVwOPR`71q6l$%3AC}@>bp( zy;VRGc5yXj7z6JNNUHXkQYmv@d9ygT$Y8WZ)HxChAMvQgsM zGas0*W?zaRt(|j&Vh_n&!hrqG-Jm^W?FgJXFBo1S_1VzPw53A!k_sI)@(FLA$W=vO zGnQFTuJEk68?beb>gl$XNg0w(?%oqwxSa5^onHEWQ!Dcf>s(dzBJ_NYc;_W^#hPT- zIZX>~vexG=JRh$z6ZEWZ8d1hs)T_qXhSh5Jj@9^GS0{7!iajx9QbsXlczB@p*>nZZ z>FxL!-ekRL(RJ6i*5J?0)w}qm?n@qFSYO5c8P97U)#sqKq{-V%I$-D*{$lZH_ z%gG4nW``!zBP*JKcQx|FLpw=tgnqTtd(wK5_EtLg`2d}djT>t6xdRm*FfqnYfSauU zpPa}3U4yggG4f%zU-S;L41nhPJ$^PL{IA!$Ti-LP(+K$k>@&QjYYrm)E@x|MIJa0G z!rZNoE52Ip{)=F~%zHf_d@j!-XP65H$bKrp{}ePX3^bR)k5#8v7|KrDiEE{_r~2qm^pfLyU)cX6!m-jF-7I=VQXM2To%R*@L&$ z5Y$KJY*KIO7u=VJ-KFCfVmzc|zD<1_v5zF~LwCPOT90k~SNTS{x81i843EpaNzQH4 zpSqmwNIMoXe_O(j^nt#7$K?A+XH|BXvuZZsvkkb1G|E|ZaDcOFI^n%{IIGGAvPUJz zS(Qh4cw6pgBh4s&*^<7Ev+5q6yYb5)?CVodl{UDb>O%j5s#HDfBD$02=DLf=&ZWH zcRxlEUeJQ_h+D!>)}GH2U)GNIq!~_luapn|7r;MK()$)vEgVSR<^@$|c@N$T!LJ)> za1;mb1-}Npzy~|IA7Lpkx;6Ol>qR(~dp*CG_K?0CVP7dv6;v(ZC;A87^Cp9bb=2GT z%jkX<(RbV6ue*^Ad%9WlZ)eX(Ci)Qf19I;>?5O?d(lhMuJwyLbMApc7l{I;MfmN)n zy=h<`9!~j2>Y|PVdVR>r36${^<7(EWj?ESnxBGL*MaeH|_Kb}HxB4S0kuiJ8o2th4 z@x7Y2RPHI*!R;9+9ttC+9dESUfs9R=zrP)C6}3e-`cjskTQsG~p~1?nhJM}ayD)KQ?00(BIqqd*-6>L^f0 zfjSD*QJ{_jbrh(hKph3@C{Ra%IttWLppF7{6sV&>9R=zrP)C6}3e-`cjskTQsG~p~ z1?nhJM}ayD)KQ?00(BIqqd*-6>L^f0fjSD*QJ{_jbrh(hKph3@C{Ra%IttWL;Qx0D z%r~g9XSm;>hPw!dHF8$%?Z#hXu8Irpg^g9JQ%IyjKFZUyIpIX(+ z(^IbSZGbR4cffH!Miuv(aKD2(BzKu;smcAU+`rK7GT#S~`xW%CanY;99VbrirU~ax zCaW?ok~^a0&H@S7PfPB1oO}HgcO4WGmb)Z9gnFUI{bx}AO8GSI*1c;;`v&SE|IvQE z@9WdBgDI+6lRM0o_%Wg0E$j7bF*vAQ$00p>^=#EwH8=W>Y?Sc6F|2KD)Bb_sNq67d zy8gY1RznwUT&H`2hkanYYe45ay@n1NG_Xx%fHHVFHK)^QR_d(57wGhMI(?n~{P^>3 zbPJ7Uty`IV8YkOr4Racdyx;$Ezlm9?ArF~mf=2d~PKmjoF{wqzpmq<3rc7|OO1lp< z+BXU_k868()AYa&^9*B?TGvk+G1p+QYQx4q5*$AIu8c?T^vWBYIl0Y)pkdUppiZgS ze~JLj>~tFV4~#&i9bXxB{TWp2RyQfq;8FjFZllP<Eh=X8I=$bA3Z8DIxg1FPty`p({i=!oUDmCw#nLKj-0d!X^vbiFV&$< zb7W-PJ0UA)vLhwak(;Y!P0(^@Ois?qNV97>jtPz&N2cA8OA)rr6fN6kPq$5UXeo|t zM`j9dq?EKwy&!v5?&Pd&^5xkwwaHnT@|3CCmY0GPD zXt}9bQ!`R1@G*y$mPZ?=Wolir(QF-w!F^LMp+VvyOVgxkTo?gdukq3$xD?qDSwydCaGrV>9j|3pq(wxmYm@j z@8_rdVl5-11c8X!&sWzwriEPPfT3*f!EoW+GW?JS%ZL%%hq1iJWwoEk{_Q-SC^Hgfq zfRq8sk&}~^GeFDC@^m`?0$$r$VWhGA{=YL5tP=nqxvZm%}6SA_p zOitHAI}VMDOM+Pw?$IV@WF>3KIa%qB%pp<~jmXp-858>S(vs6MZ8m^?yo4iiBQ>IdCu8`W6GjXbnJtcpzqYg#+ z=zkvQ?G9@?kfP16?fPJecjFUz#w)l}wEO&=JaIZV;fk)k84?OD*d*Bs!*aLmJq)GlfFvuPDz>e;)2ljJ^ zJQtL+|bP zUyJ@Gz?-WQF}`a3yeg^yo*ctd6aL`Vr{JoS~M>-9-8Q4!C@56z+ zw<|Rc*o$x`@H$~9FqCvlfaeLn42I6z+SvR1Z)fZ z2KW{6mw~5A=f&mxiG-U1y?Ngg7)kg6;CWyca1iO{0v7{c0DesTCSVNV&m^Ak&%pD9 zjrGA7*bKOw_`bjl${h)Of%tL27~*FEPXkv1uM=Me90%MBybL@J>`cDjfa?hR`zW;y z*b(>@a18J?bj<^P27FQCfqXMhU8da6fZn7#4ZKeH8n82vdxF&<;Ba6d?`^nxaoLU>moYAH2uw~x-leEmjP9uz*t&I{mE$%-5GXg_hyY-^prSL8pE*;r#kS6! zk&Cd@?AY-tx@(-<2Jw`Igh{hIG)fZ@CV4G66EW&@MYv`m-7_busOb(nR$|U%Tb?_2 zIMP(dB6I5GWJiwFZ%0Hk6>%Zp$W@8hv$l!0v`iIOTlT3@(j06?tTU!6X*5d;^Hd%# zGKv>EQf`YVMMd635)3g}K{$D8?hG|lw1Q(g$mXhuoUGj3d)+ya#OXJQ;))|Ernt*+ z6PiV1Y1InqW$C8tE$cK93QV?T&cIT0WaCSag!;@O9%XfJRwmOfoyM*XR5y{4#^tJT z-8$E@)6f8P=9J!Rkv<5<}XgDQLCdWBcI+@8siWU}9@?m*b{#@{ByDr`X#vi@t^2)LchSu1XLagRZ(c2}zO zH;*ZhZkD*Y7Nm63Jw=UlH{j;bxryeq97d9kg^ruMu$!-Cpx+|lZPB??v$L~uWc<4^ z6O!n(z4hjHiSfV23m@h&mCu!e>4cQ*tTZMYH>;gso16ys2~xMpvbf{}PLBV4DHHf? zcaJDfLR*GdT{Fb|g0d>YmZ`Uru|H7^GN_MWx;6A;9eLBTa?)j5n!;R3)e29|q$GQ) z&R(AAl$+jPE1#YErlY~(S877Fy`=7mn8)a&qPLP`d z;Fbeu04>w0nwyPh2pZpNj~IC=A`4U^PdSL1Y#C6slTeP3MGenF+TSEQ1Djkjn6y-0 z)Y3+tM$(~l_CzR_Tk9sZB;Q6YN-*Se7yB z9{#n;gg|x&E;SW5Et58+h`OL$uoFUx0K$==v&BgGL(FdqmRG{yxY06QJoVr7p~pp) zEM5WpS^6l`6#?SMo|Bf1e@xnxjD`|-mqYQ_Z7cSMkqhL3yMSZgQEESM6XAovO2S_N zI}-jH*bjJ0An|8_!|@jX2rMW57od~yHQ;)n0b4Q~=nLG-dp=^OMiFiaya2otc!l^- z;7Y=sfoFj|B%bp71K0C@2+)`CP~dRFe9TNO0geWa1&Zz4jrVroS>Pn#70StxFz=@W zs|n`=%X$AKuoU<-(8~K|z*NG;z@wxq1uh`W_kPu0!mk6fNw*nT3ETnn=lx#bD8g01 zgTSK_4?GUc<~_c3H5_;z7(_hZ{ZJPOb8ofMfZo`=2PwZXFqQXhfKK8=fYpS%0H+fk z0Nez;AJ`H2FwhK423moWfvJ=;6F3$)U*dsFfzv6c6u1Cb26O_q05|b|JFpV?F>odE zUjWU(<3L5ZXMpR07l75kKY&MpKG@a=fz5#BD*0=odG6F(5B5sn1zCH*Mi z65xXZd7lI<1x^HxB7O=m2sj&flzfYUD+wX#wCWwj3C44gojjA)Y#|*BF9EXjgePwkQf;)RVC;k zc4%}=l!_YZ0%T7lU*g!raLGT^jYPsIaEN?hbey0&DtZ(d;^T%=>qus^)aHtcj02r` zOYAUSM@Cs91rPD(CdS3Z#Kr2ZiHVT7xWuTDqokggxVTXg9+|+~=tv>TsQ9=58+=E2NBt$)+qDCh~#Zw`96XK*0Jo<^2$jJD3c}f0+=!dCR&z<;?Ac%ihii#Tr z&iWIyA3bVRT)eb_A`)wbrPR@25;w~A#N();wccB93s5U__yp<@1ju0-V~Li|jY^D^ zE#cH3MITDQ9UmJPK3ZrQogk5dc%theVfbiwfiz>J zCHA5CC`p$XJu)gXZZsvzlc%VmAVj&t;}YC?ruRdHB{m`|Mhc@bQSs7~I#Tfv0tAK*Onjiggwx&_L=~J>=`*} z6I1iF9^HC$)9#-t)}ceQWH_dy@N#Tgd=?WVobZYG_8l|){A$gA(6H!VRzWDEvpAR1 zCIHFSRiE66J3U#~#IiJ!>#=1pZT)0Ul8wIy-?VGBi43ypB&Poahpq)vF{-i3WW@$6 ztF!3k$I_T;pck3Op&b1%fmoT5%3TdWZ^~3qR+RL`7=7aDnyGnSVR5negGOXBDLM6J zAHT%mQCdRW(8LEV@ljfIf=1VliH?kl)PgMugo8CpY@{ZMETa>L$Hi-ruvm;GdSrrT ziHY$e7lSo1Ix0bXFq*}j_^4r)c+$s_g~DzX92*fcIx;$TnB>x;M~;e#j*6_EJ8q~p zG72F^VV3adnCQfZ^ooZ@C&t2OU9{*}EjCVz8iTac5{645;N<7VDLhJxi58yHhJqnX zt|g3$iiozvbOv2mF0nKDJx`=yXdn+pQx<9bA}u2=!)Smzt0(y2a0_CB8slkI0)kPn z9~vJwQj3X8AoWm<(Lx2VELr`a8^|Vf)*c)l1#0nvv4#I5WW7*QQ)yy6!OmK2)UcT7 zVNr|_sWVPe`z11_qvJ+HRXsyz%@QA-AT=^bB{vBvP{uUPkrH)sOTU1HUO%!fE}juC zr4GHF{9TkEoKH%;k(tBY|D+qj1hxMyJwyCZQE`48fQpK z>xLQ8o&Kc_yrc5`*n*EzjF z_Wcbn|9SS^4mZ|+)}q_-ZC~cR-~0D3JNKWRng85yysfWc`P(bE z+E>oL@{Dss`--dct3xh)eq>C8^xgNKeDc?%?<(^{`rBu3_^|kgH;&Ev_=BX))8_ni zEv%&Rx%eaAd=ZRDZEFIrDcek6WhhgF~Cy?Z%k+URQ|%J08p zYp3I1XSM3_{*U=hKMC0!=ao_HHR$+_uEP(`xvPA{3mqPcy59QGmmLm$Gd^a+&L$n! zzu5Vwe_lHKd6QZ19X{QA>8a0;&+(gaXUWP_y?2JpZT8Ie72kedZ`&UW@+;59`Ngff zvHR&u0T0igJZVS4;Ji~E%+H^V8F0;ftg_=1k3D>+&bBxqFJfNR!YI(HBBiF>bn`}ctr&vc1+{^)1D624xxKJ)jx z7tZbe$M@qKw7lc$`%O0gLf`JilXu@2@a=-19_rud$h2LbW)Fz^ zYW%EM6Wey_y1rlHCv&U5Klk;{WdV;5JKFh>$+m3NkFV6cnHI99WbWt13m@A#CD2~~ zncNQ=br^m*seiXt>zD2Oe(U+bKmPgB6AQb4`$hT1n67Ka_{``v|B0!K5}(bsemkdp zRk?Tl(u41Qx<6;~@7m7|XTCCi#J8WP@9I1)+t>fsxm&aTxWCJkPCi|y-qX|hw%-dE zQ+_)1Y<$zXGa`T5vZUdK2Pzl6Hzcot&riu$_Ix_xj{%S7AL*V{de5py+g}c!bZw&b zUy(}(UJlr_{Hxc>y^Y4-j}2(`aCz?WT`9k}Uh!zJh&$fQo}Aw>_t@}9TbdibKmU^* z?{EFG{d@2IcJH#sI*eaxscd@S-ead;|3N!;qhj$NlTQwQZ(5sse)O64R{7qa3=dA~ zpZZYOlp_^YFZ!SPzWG}>=BD{CzV`1kG0!YDZAxu-$4jrgcg%Kbv8nXJPjkN5a%9sd zRpUCZ=+|VymOXF3Jx+Ui#C5-+1KymI|NfR=|7Q-qNbR`z}5B z_GiXJw)@`PJ>$!_Cj4{U%<(UsnG$$lb8?q8&F(B-<#Ou%BM5;#?Bk!^WwrAi|_2{{PVt(=S>SgY*O!x zUwXg!i{Y2QY?9phrNSu--=6bAK!dBn3v8!;GL3UQdpdScc3I(w4m;xCcysl0XIsyh@$#+~ zA#;zMPaeHu-GlzCZalv{uldo`?kC3Vcq653dU5IHrH`Kcz*64(zTIC>?$OCI;ZFbh z@!u_9*M9u>4?a2Op@-_7Y<;ioSli8IOD^wEUf?t8>&K663mi1=+o*kCcg_9BC-<+) zTsyU*e*QCM`&KTU;or9ZlvU~J>Ytzd60|;h<-a$-cmCqAP1e2hwq-Z^)YxVHsj<14 z&wrmk<)s@V=N?&IFrt3e_JuE&?Hsr&=H5;3sq=+x!rx0<(Yh?EWL5kpsyOuZCS7(I zjjQY*q@DTKwGHR`-JP*<+JNdqUdO(e@S$Pc=p9pEnEOGS+3TyKzFJbyZ=-kDu%ny) z)u>a$#h3j${rJPS;@8F}*ZbqQqCp>qrEdS%z@5eKf4;8$lKZP)Gq&x}WXjvQT{e8N z_0!9*=6tl?XaAn-QNj25%z5WX$FN7zm)AUzI5WP>_rng)ef%FMN=LkL|4+yFeN{Z- zo81n_hHjrVesI9^D}y_H@N}!MUtVd9a}xIE_2NAC5x-lRz14BQP)m8Mt`{fm3!8XZ~J86 zw69(`b0jbN{5@}6JND9pJJuB5)qU5xAwxgkU^@1X(3*djFDp)Lc=m|_pM@^neBd+t zT|b;?v%{Lu&AY|0DH&ZSjgR@x(8#gk?X2b(w6pE+n)%G8{NdvZN}IhDu(k5W!!N13 zN7$8p!`t`$*RQ94Yq#xu`}mwYwl!IGJ*3;0k1p!`s&Ua{ zR?Byb+JcSa=Ve(o_rF%TdO^FNny!B`*796Iy=IB6pZ{z~(=|TFJ|8wJ z>DoVk9^e!C`fJ%8Mo*ahL{4IP&q-T{KmX&0u|3=S|JWt2-=}YvHhbUf;~22?Vdoc5 z6}6j}8~cW;W*4gAN(19B>PkK1v+6>L?;!8W7T)L8*omr}!8vT=%F*L~Y5GosN1m9x z^RYE8N0h8Cyz#*F_@j$kRb(4GRX?5m?6M=xR`+Q9)`pK4{_J$@p5LY6F~_5G-`#(_ zed|ZwJ0E#&YqKBUc(V1c&3z|LZF6_Rps_*;7O&hiFS0An)Kj^yG>eBZ= zeYIg>^Oft{Z~XU5bLOSan$`OA2{~I<55FVK&}-$~-CGAcwx+!P)~sL0FL`D6W6_^3 zd-|zakG{Kq@X=i>r~P`P|Ngt*-hb&}r%wi#AAWk(v>k)*`JzL$^YXmDOFpemdfEK( z#XUhYbo?R@6V?G4W_I{eQa#7 z`IPfdw6R8eZQCDT^LVFaYreJ?UjO2O<<0CL1wJt9$N_E9l_B-U$A4<@4W4X&tA}== z{H^ zS^C?K#;Z2$i_AIRYwgb?jr#_@`OZhbXuDI2&rTW`?3mf)C7-etgS(%bIq=!L&Q8hp z|EzE5vBS^A?K(eT%}2kOpNtOu{kZn7?+;zC9%}UZ;HQ?p^}&ZfjeOz3?*=TJ-=Wp! zU&|7nIFfU~Z|b{W9Gzr4e7MlD>_nH3a=s5vO&ziQ+gG~&+nnC<#fM9t=&&yNldqSa z-I3hsyUXjIx@v8Z-LBDF-`$hD@Qy~$Pd5))cF(C}UDmwjc(>F#`i+H`SB(9tz&P&T z*Jez3=(|^jYzcX-#e~m)&kFz4@=fu*|D0nT+o53Uv#$@%c=5C6PX~NHWBP^s`8n-( z^}M(1dxZnb?`^to**D$`GR@piBWZ1x%XFqScR!#r)%?pvyJ9q8xzhu(83w!U}TC(rm-=oSc z0j(bD{8jNY$$r-sxA;D4)tp|>Prel2DRb?#t$_ta;|_O!WZ&fh{YFpv?cR?c_~_#9 zkE0?k_j=(*v(LKR=>F=zM-H=m+-&R^b)ehDJ|$I8wtF_t`0arzc`hesIqn%eE)%c>iF6?b_I>%j`>Dyzd`J z)YI=JU43cPz4PWxFHK(eV9!ZiI|d()`Ju&Unc6?XwylUa9j!OxzJSJ0E}uE4$&3dk zWR)I2aNwOSAKe(A^XbWeuJ**a69>*e`_Y97Z~FiK&2RS&{^zbPcl3U}Pmf_`hlXz5 zaG+`PF?WpnZ05x9+0DL~@>{op^0IvgYKiRx1aW=F}`2o=H)3f z_ZG}b?d5nXCcosy!pQfw41D(Ihpun=cV)=@Q$tR!S^dnbT^8T@RkO`qQhty5y}C!o z)B`J~Oy2J76fq#XgV&7inU6fa{^_3gbv)cZsBfqHFAo1ldg~P{o6P%l&ync!)qR{} z-g&9|1Fw|-7Y9A~!ew6C%e6g+n4avyGB3Ob1{EwPjc?C}clzKAgy~6eQ}YEsU>3fY zMdyd2b4YY%Hamx$A3D!Flid>ShwH{Z%;m={#@l!sZ{uyejkobO-p1Si zgT~kUf{lSXK3>KLqR~*8XMB+Wg5l^go~aAgh2|)HplJt?h;k+0{_~D>0;pTZwQ70ywVa0FgewfFdqdSBOs3N*!@$xZI@)zwA$V8{>5 zqAIY*+53yg>MSisf}U&bDh4hXx=C*KD;Lot#1s+bJMxS^TuR<3LCK3$rO-;TCvwox5e|hs`n?-YGNwX0ADgnR31e%qokKYlC zWhcva1VhWp)L68vG3@s>jtv1|7BFzwVqqcA`~0YLV+)T5?c31^q0k)gt64C+a~}2@ z3x-3ybD?t)Eb)gUEz#i41~9{8iym9d?^0t5y0EV?(CiDAkujqf127D{%c| z(|d`V-m7%{*U;&?>AhAVfAqYsE|I?Zqo+we`8&*WQ`%qq2#}y}2EzH96&%fUctsq1 zqw+o|kX(8B+5O)l|G)vB4xZIe%RBl0fzD^812!}h+Ami52QKP=)OA5f=vkqmtc!wB znh5*^G!2@7wixhA(B4Wf96z1vujT=>X^!M^=&wd1haw%xXD$g`>0n2)Jeb4<2Zyxs zErG(3a_TM7Q*cP*&zP6X1utNJSV-)-Sk8qno+f$lv{uGG)q|N79$G-X#w^KD#M81D z`0*8kf~KcaB)OQRuqhHbS&02f3tZ5h6B0^0KxfnY^XNJ0z(?TWmLP?}hukMvJ~?$G zspa_1hfQ>I=91*xP=LMmM>Ez0G zE_g+t(#Q+6(v(QAfo}8_4VljgeE;wZBtNgAGX&Y!bN+#K+IOKl>VeVAL%XzxZGAMm z#3>rEZqGR(si%D|jb6GHF*BVVafk*BC61it$qait@y>}nW?x8WV|I)u6Ce!2PbFvf+%ja&i`>}>0xV+(0Uc!A6o5=N2%pX;z0G>#I3 z4QpHnzD=YvfQKm&+8Ych#TCL_V_BvzH(5pM3Tc&>|`(Hp;0$v30 zGLG>)&?kU?2f`MFfD`KEwvT?k#FJH*oAS3TKwuhSM~A* z@cxxYYI~xc@-2eC<#}~({cQOx=7uw1hgj?SR)24e)<5tU_|+Ep*f}Au=OW}A6z&3# z`8`Yzs-HbB(817sZh# zI5KOpq;MxkC)%%v%K`Y7Hm_yG@`4=~T`S)bnDNqpd( zmgG*F)n8}egG_HszPE|*FY4nI`E-ZpEApL(|En@ygdH4WzNe>ABnER~7LAIm*U_jE zYy3Wu!k?H(-VYpRcYS!jf$=-&zd~OFTV_7Zbn+H-QlmEo3*omD_V?y&xe|CyuSh{V zH|xDqH0RR^yRFEO4Vdes)R%Vx_9Cwdv~vlQw342OyIIBLQ<)Jhw z+zxyP@Q=W@7w`Yayh_MXBzAV$aLzvfZTCv4m&wWD47%q@;eT5!g+JtIcOjoXLX;QK z7yqP-aAv3+b{A5@2<`h}S0O)zhkweFZ`_LHR40=B%R!3zCG&OYx}^x`eZoq0o<9eFH<*oaCmAciRUFN68vl3S5O=Mba(H2$yA_4V2Ed8~gGuv0vJ z+O6)pG+X`?;8`rzV-Li%>TK+D1-|zQ@6VHXfAtdu{_0P7DwUG4zu?ac9iZO9`=l_l z7sRNM5YvzR3H=4nkINu*u=giyEyr4ssYFDWWF1;tb;Y)z%t5F-LSr3QY*>jDiN*Z%>R zx%=D-3ctE}u7gO}fU5O68n zr|S3hZ28Bxm<{EXvUuB%SYi<}8sJOjp#$)PcIg1yY(85pg-IA+9;FXu z%g=#+4|of3sezE7>*0~-m@GS)Ekdr21d?mf=!@s}vp7Zjj&$we2!5d(3Eqg9kIW&% z&1kMfo`EfY!E9)S6g~^vJtnYPAg`1|Okr{k3E8E6*h{sUmlU3ActxJv9QkqZa};`F zbT#Nzx+3VEXp;8O%{W`D$dSJT+7N7HxM6kh zx_3?R)&ePfWmErgmW!h}ojUoNivNX9zN(Hl&yq*g@!T}|Gj)6-O&(Fl>(k{+>iAN+ zd_Ja=(VN>}4~pdPx``T-)3DsTBTqoB_T`g&@X97GnEif9;BCaSYc}Nf1`YU12p&Vu z{yA)SXQwp&bBvFnuA9U18f@wq;J7Pf9m%CpPD|$RA%>eIlGk9(I^e<2Mm4ArPG)p= z!B1Lpu%`)UdM*1%-aSdQl=))4md+eVGma-}DQu#w{zyl~83}b?nDL0ZuIK@h?@7}1 z7NI7N*oykU0vxim=#cwD$j^g9R!=YVA4!$Yj0>zL>#XKZi#VS-->v+j(7FCTo zSnt4I=uJoAf5Bcw;F;M-Cf2a>(#p!$APe@bNkr|`&9zt&?`l${mAHQ`Wx6OrUCCr) zvX(#xwU7_BWWx^ZQyYma%f$NDM4BDX^Vp3T&ozG^t>JU-10Jgz>rqc;;cOE%6yA$> z=UmZ@Ra3SeOcU_5?mv`u8#MqTutWhIq1Kq1AT+`q%6kehhO|JCJ zQOLG4T?$KDW+&PJqYDDoy$W%NpeNuNMOq=PGEGIJ*X{jqvI92S3!3J_n{CU zjj#I7p4s!ll-yPa`2Vu| z7kFXyGEbcYtd3_jGh36@%#0^LV!q1PbdHhqD- zfYlR-Ek_>=3>1BEd@Kubf!q7;7~#HX7P10IFAk5f`%rfZ{A$sj0ps3ZjaeW5U`&OF zl3_R6-2+E=9Un7ZdUpaYCbN5FLFq-ve?geja~`o{7%}7={>F{L0SHY%* z29bTpkqfobC}FKZ)E*yWz12D)wOBWu#tFW!<34i*^Q-hEGaQyLwGZzd$Ua>hnEzkD z9NYE5`(xVS;j!NX{srVk?H7$p8pY-kV|ieJ`CBqt3R)_=+n~)tOG8UX!<}US@nnG2 zSS)vBqvfFGqTPj-hnA04fX2Rie4E83zVMSvsKwd3_j2?qV%End<*phMsGs#>z17)h zuM@YHi*}F4Y-dBa=YEmuoOP~ye4@Rn7ARF4){0HmElwNVw`5VR(-#Fey$r$I z+T85+`0RDWU@kZ2%$BOnRjWm}hYi;}{xI3xt&P#u>Yc9GVh+2t&h8PnI(-h&Xslkn ze)&>tU~@QKcG1_?Y$t^`pIh_*HA>U$ac}Whn-p3v`8=&In-x39P~7!*#ER}_^@q3Q#~ry>@W8V1p$AvbfM_&ZHX7GeZF)kP@ojaB&F-ys57{lv4!g_e zbv|RqoVeBFc5NY_+YQNFZ8I|0Y^jH+-e*MnHk;jE=LMk2-sF8onS9z>SLYF(E*lo} zv|@R7Udp-Hg~H>G;XXC8{LfWJ0sa~e4^XufL!9!PLHqE+9+aox2G+N4_r@Mv)c&)n32@G zTVV=L7t{BKM~rJ?rm%6XWivH9?P61twV58-6z$`MpA?pTuzr5A!DQ|S!tc{be7|tiNtZM1K*y6V7$$6agpVA|K}a@pHJ z;_&&Jz4w=wE2w3S?#6QXU75qz)R>a;y-koT$_!jl6gO5svQB)`SiSE1ix;xrB@4^S z%6_0sFPbu4u`q@dolc=e4trxWZ8VzK)1J_$W>2cp=PLc2 zxbMA5O204edv%4faUf6!?4v{vQf_fdap*z%MKC#R~j)LhQYB%HIzR{&$Lj zyqPqe|IHb9mh1gE_`2xaXyi7%DsXZ0o&GQ2ChT!KoS(4E>2P7f9;d@K6Lvcto-kp5 z-{gM^0aklC<4$nxZT1p_C)1tfN+ClWydEuMiavb`{3p@>WKwRkzor@B+oSN?ncq7D z{y!-Ds`9G;|8&iO|B`~At5fVl2?Qq;xO(oQg8#-0>ztke{@x65n!Al2VljR-;?<@$ zug~68hGgOOAr&;2RZ!J7r;j#zkacLIosA!|H$8-mRp#`1te7`@+Nv7sNlp1=S-0U4 zlW~LPk+o|#p?EPHO&h8#w84r>!$B4cQi{dvvwD0M3*IKvLky@O*j;te=?P>qHrqGE zGG~lM#w??cA=>M#J}a>|qB3t=6IMj;^Tc|GI@;oDEkl9gpt8C)7tmt8&qHM%d!v=T zP?-;z5AW{iiVS3JLd{mT#qEp!lr=Z{{x)&2P>KC~Tz*jdtO=W*9>>*uf;%YT-s@KB zRlimHf*I&(N*qg_vcKxzYF{xeZcfsx@o|x|HXoP2)SkOzyq98Gf9Q=0VU4n|PFX8n|H)JKp8A}~kM+O(n)9DM z1AV(#voZlblIXx)cRTOem5=QnodlY~8xQU?1+h?88>=Uz=aD-3@>Q_#rE&cJ9ND zE3rwS(P%UpjYgvZ?(a5s8*J%M`LTWCcvJ4hjo6w*4NCGH_rz{YtjMt&{%jWU__%Wd z*^N7A8ZVBYpV?c-DB%0Mp<9^FJQJe|GB}Gk|9BZx(lL7DwFb-~S;lp8CN$bmohgby}S^`es6t`HjeYGq}0zk485T{p{qyB$;5BLElhxDv>(R+(z3RLR#!@J(i=nAMB z0z*dc&u_5dZ-!SF?EGp(je0-oLxsJY9v00C|L_XhH>v}gKD1_tjqJg{)0@H7B^Cyn zZiYQ1@Us8*eDJn^dD=%jR|H+s`&UCK{(dCU)LCyh7$I3#?{5(26;%V6FZ-e%>P}=P zkg5@BQraH^7cY8L{~NQ*o4-p=|MtKB{-6K;&+u<||IsgwXS=H@XD_WN0=?T@ywcJ@ zwFOpeFZR_#Cfl9ao|(kM(DThCfQel*$#o{*c-ba%p+_R8Z7Yf0<8TIT=pG z&N4&f%7e*++Vkj_DWBm?7+7;2{gt(k4xT@Kw7<)i*1fY_Eg>Cdi^%ya7xRGaM@ygC z7EDgoH_ostC4%eT&AZXy&q@PT@qK*J`^a9hcB}K0{fQ+h$COe_ijIC8oey3^*4x1; z7Tt+<*mt($?y#3H*>ik!=&^l-&l7qsC=WVkgv0j*1Nx)2XN##0dfna+S01uq9~cDh zO<+9;0`?O&;Sn%?Wyfqpne4wmVlYL;z=FABpU9V69^y=fudeUSS#=lY*>AP#t?x{0 zT58|~yjF!0pE_UkbldgqZ{sXc5DhT`#OoOo(Xw4@4 zo5~?H;MRem6UL5>LvZYPx0dTnt(a#?Eg;H<-w3GQV}usWQAt)Dhaz2ItL`eiwfdtn z^(z4in#1p%I6;sn=$qrZ8ac$%0x-}CODp;&dtLUXGY6|)keWUh73Q&LEjjT~6tx#% zLkUo&AjgR|8e`dlWW_ra4qZwLK!pmcRf~{6Q1s41eiaq0r?jHDN=%tF9qApIh+?di zia#*w=&8g6L;kkIs$kt8G+Hkj?N$v(He;!*=qz<-c@a)(4!O&%h(FAL&~hT4N_S=i z`HpAEhLEB{FG{eEr(2Z94t}b2@C(_&l9ghls;)?tuHHdPF|ND<)u==G0r#xf z7_VZ`rK(d0CxvG~m!rl8O3-p37=e}@!*pY+3^4+dOl=0x(u~OnBpr0H#4;mgf~AU{ z%0^j%*34=!gSk@g7tTCMM;^+KY`35x5aAqbV1xH+3ou z;xTrtsYYdwuHbk32+3S|sQ>shTXf~Qj`yuV2Wv2?yyf#??H!k739VU}6^HARTxfJi z#;R#dh_oys6V&KxqX72Jk?NavqjjJUGMG%KZV3ldtwvDMdYN`bj$=X*OkK$?ZF&_z zmARz+1-PCcq;NOm{>T1l zp|#Y}q0WB0EVijqT-P__^Q+!jAyiw30$ja|!Re+N0cvo0(;r@Mtg$~B6UT~be5yl{ z7ozCrFs<>;_+y#f*w&#wltFcLs9_mYN>}e@eEsfh_yAW43SB=B7eT1{-HYUl8fJz;?E z)4`V-j?~sci+yK>5FH88K?p=t4Az!l?NUT73DIh08g}$_Q^QQ!$!OBCK9g9V<;lyz z9!c1vEnp8N?BN!$PbKWrEnp3XKLERd^*LCB{|~?#Js}OvzB}tLrXji4l7eLL@v(!u zrJveIUrzK)Ftx%Ma^rQt3p19My?{P8^7vSD)fogr7A_OkMH#TVpUsLgqFe?a&s=LB z6%xc3Xv7s}1q-NrLoOJCg*nm2a?yrzz;|zYFO12w53X~45abyg6ts~T5{$*>by3c( zHJye<89`ab%yD`2*P@&yUlwOrF1(61tvodIrC7aQ&8SrwVdD!?Gs)RxHT(3u{i5?F zQ~tWJJTWTBmPgO^7lWtQR=gN-D})t6nD~xeC+4B$x@)!GalEM$!n!!$CiL#PoWxaM zDPeLp4Hg^dk534~mru&^Zc^0?_&F?yBuPc22C{oIOi(R0ed6#xsg*V!#9$Q_TCrni z8a0Z;bM6`I#HeP9ooGDkvKC^#TYxO!T6J%)#`gAz9U+fbp~tYhlWLHcfc$hB7|307 znHd(<ZUOWJ44%UpYp`mVzUoxzb-xBH<`O!usPTHz z1jqp|f1M2Q|SK?d@6r@Le3Ck;d(Xx~?C zt>I;Ox9*rQ&Lj=#os?tR=4u(eINUlU~cfK)BaM=@bX^v zCIS?UXkfKfXEb0EnVb5OJ|K5*4|v1w*&i9qrF(3rwIe9Kr__B&#rGddPVd3QYmsaa z&w#0)MG54BV|1m3)j`$p#{qF|pD+uoz6o|7P}FElQZB^|S!aDwOu}bMnrKNAOo~s6 zxE28APM&jvEa!BFA;I@R5IX0By*+G7W2a8-Ze)y!du=RGZ-9*78)J^#M*XD|7Y#IW z$yPgc1|v)AqNrvRC%Udf&?n?un@uxgsLqdf7;Y)~j&>#RICsOgb^+gSLq&&21jD`c|!RUi`%n~x!5%e=6;h0tG zOjcc?7f~1dwP7Bpuo<)p#O`jNQKSQ;08}OQ&5If;pFJqraz&SnX&;3m#Kz-lbv*Wb z!HMx0m}c_fJ~N7Ja_Y)z%QsHTehLPp;&ojil>>mbSgY;MvszA<^lY0)(W#H&57TOq z39}nSS=Edt5m-~HzL5zumF|Jj(|9EfE=qZ&MhIpgXjYyQDbjI)I4by0Dh;$PO-DG7 z=W@kxgDk`bw(ZitZ!MXRpE#)}u`5cRyU`a2DZPd4M8ff54>*TUbE6 z$M`ac*Gz;wFp>E}Pf8uzRt!i8Ncl;Lkc!#mBt_yg$t-@qY z1dRkm391RVtyRQD*wao#sBSs)IG+MbV!5e?z_Hix#=r*w$ggk$SzY0Vp@1qbww^Tj#^W3l!*5pTub@7how;XCU?$aU zRLF{ji3vPGPlwo*bpbyZiU|l>eko{PoA08(rVi$-OTRj3jv!TNrjypge0Zs5iq)!* zB~8!=n;hp`85GBxUFI}6qB|#sp-|neCapAGi@UXwodDHaHtspJk0nLPDviRzEVN8_ zmGesJcY_n+2TZMKIUXmhu2z;&_&FXOjGvC}_Tkv>jGxv2*!r9*u>4QOi6)=pXuT2W z7&QUdfBq^CR&gXod?{=ttbpn6);7X`q5?Hush#NU?&KR@(8e(O9RIOZH=6kX`IRov zBzRbRxS5W(O)K*)z|kpM(Ul!$dI!W1EOIQYDCDx*ZY9`~WjGC)Mk85_XWR@VNC*Eg zK{^r~ZjTTDzZRslng6tcH03jE<;F^qHq8iCH3ghJ%F^?L)?B!@qGfU&-9i<)jEsFc zQ3e>rTAoRaj_*}U*NzUxKXHBSNJ<|jbEvc`7tDe?a)yJoYZt{ECWD4pwjM)T&Ig0h zz!*y{VtsT35;tWQIB&2Zg%C*xPElEr4|&DKDT1>qLMrD)auJ(wIT#E zM{gmkQ*dE&mm(D-lwutjhCG&GOW-!(!WhdfP${qtm@w#a3rq@Z111^4xdk!}vRo`h zxF!v1m`?0PF7OlomdK_oE6WjJ8Qlf-6h@7f)fW9kZNi^yI^lmpS*7mi2ep-P2#0E< zl!Ajaaa1y!XywJLGabh@i6$=7CnBJ{aHBzZ=O{;vMLK!}SyC=a@azneVb`2s#XlubvXPO1;_GJ-8JHAFB!5$J(6kp}PMbZsQikie8uIu#^& z<*96mbl?*#63Q`U4+E&fPDO^0Y=NLYp*o?KrPQcunL_uodm5v_x-+L%e$O9}u?;`M z!4U=ZY=Frw|9NDY7?a)LccYNe8N2Z7ckI$6`bTt@wBeJ}M=*NSa}o_iFX(|P3#FQ_ zJq+W_XWTkrymY*}c(CsC5EgAH+MvhlGFm}K(#sQqjJq?jgwrTc`yLWKyh{8kL*IA6 z9R=QarNXWBEeGZAZ;EIr+?9}l>*@2W7yQ^ z5xV&;*Y)q%@WV%DE`js)Q;ZkZFV71%SQ{z>W+?y>9+ri8fC~bv;{i?caE1E|cl$}G z8BT61*B3{V^OPBc?HRm>-ZpZ-e^2+0Hk8^kXwM+oswI1>Bbk58!x=EQly2F^gaj!N zNu@GBPkKqgGU5gJ1JtKD6}n>jExF&O2}DEGDxfg_q`EzeYuWNi+>zL4V_$RQ_N%#7 z7<~F#IC9Mq3nQ2a|5{2oV^cx;SCjOwTazy6!N6;b+Q1ILaBa|QQ)BP4fc+7lFEP}U zckU>hb!iIuopc8F0X>C%-3i^)n1D{MYU(S%YWvb3T z(M1H<85Lts&tCX=BM+Wj!(C9M2=_@*{9zuomSD`_oF_Ig(bFgQFX<|Vr3KZ&{|GE8 z^rYT$x)aFqY#y-*kMB75QlUzADyd^>punUdPH-hVSGL%v6UKWhnW{n3liB-vcy%+r zyt?ey*+uVqd_5fe+Pmq)yn}B&$oTEz>iww57-_WYiNjNb$B0NUjhz^AQwbc-kN_p* z(xL#;LOU(3QnOQ0iGI5p5zg!!lbn3Y>t|KLULub#6)79FsOmT>T%ZLz}aC_QKL`_2iHX@{Uu^+=OirFAlCKn;a$+;IkL9tyaC;TZEJy6jPWF@^3f z!7Zgvq{8a-druOXjynf51YOG&*$bD$Y;qrmmS`e&GN+hyL`yRY1`$kPuAv%SK8sUC z;yy3V=#sAmzD3TIH%STYL`jGQN~^LbL;jbQ6N)QiQbgRrxr|D~O5AMA1cO-w_k2%p zI1X---DZji7JW+*mys84OY zgH3thk?R0%&7eQ-tZYP!)zFi&7Y`5$7uKGD>R8F(g#bE2(q z*_F{m>0Y1;mXOEXwTY!#Y(v))s_5ROF5A5L%JzqD?CI@5t%t4n#hHPuv(eyMg;Ja) zEdw?}xyT9dMnJG8L@i@>H9r@|I23N7y!;gxQ6x z>J@WWSXnRGvk!99vwz(mUSv-`n3hg~iBv)Akg+ut@vF2e^cJg*gi0L1_?p9zUbE|D z-?qkzcFQZ!i*k#&PRg%$-DmPx(4B?sTm~Yr7}bO>5&9;0F2=E_HF?@ID6~EDUl5xv zb2Jr1(TXmjRBBI3p^7L%A*?eCx_lYLQf#0~og}62kP7|wNs0m#e8i*1P%v2d9%l=G z3DXV+BrZ(R6#@>H5MHN=It_|g=TO1S@id z69S5w({)7g2++`UXQ6ogeJSbwQN+jeLn5PmOBsZ}Baf+&xMOkM; zIvLi;_QCy?{M=>LXvsrh*(s+(j6r&9g-uht{@Lbreu{L7B~Lym6m)3X9D?DjTXYH!1W&NeLQY{P=iHZ16D!-CE>Ea+?_aGh-= zuCom@JKM-yXB&3PzX7vio4TD{fM1N1lHy6?`axr+>TFX}9J=ff_?NV`Ydoki3`0JJTAdFWwv zf4dQpLSfH5ZNuEDOTTn_1Bdjq<{|}79u@5U7w&Q|xM(qU5KhKVu$7?K<=qT8Das3b zL!sTitcK<QlnFF={p8|I!oVcB$jM?%(ssBvROm4cOt0L)h)?}Q;-$!&L8 zd^X1a-e)>5({GPkJckU|DRnlI)` zN~=|wb*a!c+=~RcLk?B-n5m{PM$?~)~@WMk&cq)p+3ceVFXwwAGh=Upl zxs4k%Jn-M9Eq9jPebv1NI1vrr^9Fl94CXpFj)uiuh0)p#pKU0hB< zw*=%AdNoCW7rGD>43pimag|+NHX7#G%q`611u`b@mOPwuSe1RXY;;be7gc(?@EkAg zy3JSqDv}PYzu;bfdMZP&fA9BJq$g5>}f z@J`6@??yh07S=6~#7>IEmX005nh8jw@r2->y_S>+rxc#D%}RpW`@vn0TmKvFSU`KZ z1(R?aSAVqaP#`VY-rZ7SAP0*U=O&$B7(X=>(NabjRVpr34fDoQwZe+F3eV9tL29g# z7gddfoR^2a>>33m+9FzhE(GTxO0tfFVnVb7^Lnk_0#ti?C(4oED2V-F8D4ga7-S$* zUb%+pD?7=kmCkl*Mcg`~9y?p9md-z3wM5Qxg`<t@d76~Ge1DOo9u}084W|4fS&Hs# zO;VrbN+m81%73ovqHvBR`2}4Kk;G?-7Aro`)v;+ZaRONoHB*=UpGt3`JrF`cP?$~Vj$#Ad8Ji{( z8(R0X+2mjbKdUsSqZjC;=?9`j`*}M}Q;ifi&8F$pOeca-xXO^D8Y(WGP1B#H0t%f& zm(Qh{NsH+U+BE$|T1c$eQo%JZ(-52Mo_|M{;~Fhc+Tx^9BZA1uYDN$?@NZio|FSp4H_ilsCC2fuhuZAL?s86gb3)aEO-R`t} zgKqW2R=t{{g5T2z>%>kMuv_Xf!TTnyTmh;6^`Mh9TU`U+ z&3qn61Hpr((j|?LT23Is1=I;oEyp+lBteWc4K_I}BjJ*F4Td(UQn$EH!&aZ-VciGM z3G3in;rHkgpY3j<&=3}W)TAbnaTp4m}qMt}lXwwbueD^=%yuQY96&L49fmH?nWup+61p<39b@ z@x?$_9fe=uNj0FEUMr|5`8JP6SCUo+FTc){Eh3Z4O6i~I$rjb~Hk403(o;}A$+}Y05BF~&_^~e+rE@a)P|4Q}ggAJu!H9$ml-?W3 zdjn$mkf1+9LsMFQQJ}1PjA=lNnw%HP zw%0RtQWJwxPQf0(!@#E4UsAv*jZI{4gyud^+}+aEB`CWkvM5G55}!Br@p`@XQ3GRq z0Ug*vmbwma9{P6?oBDSm@Rtl*Hd(VkIK(iGw5C{@ruK7{TG7CE?&%-Qz&50Agya)` zVE1cHE;OX&-hsIL0l=TI_95PJ4bO>Coj~2MP^>)G=w{qERe8lU7Os7gw_JA9TQQY` zgq9$<7)hIurC4+m_8HJD*FiNbD7%P}6c%M-xDhO+61WHYTFMDEQS>{7nFk@q`_JgU zHuRNnM7qkHj;V?TU2=I`x8OQk6p!>sqX?NruO>*26|p~HcGJQY7RAlt4TnJz4vQHS zeT_FOLPByMA(dh`C|GnFGh%ChCBFa;GPpzq9^pHnv&ERX8qsM1g~DQu0Z5&9T2Hb1SCE=708H70O%g%CA9TeciFih&C!gRw-4@P{}k1Z9rwsQ5#bS^ ziixFuc0AyW1)P@~?OESaaz>7%8zmMrcaoAFCy8`xH}U~vuf_w4jl~vg^ynqQ-*Xf#goQ?jy66V}9VYnbUhw8Ls>sy{eeUCI?Zh&a z)?GK*5)BHNnnNqrBE5wOMe@>7irf{SocC1-ub2i1FLo_mP+Dh`efv=o`-|cnaNC(V z7&pCUz01*neLQHk5Akb}&!0E7gG=+2x1iZR9em051G%)QKR}lql=KO83UIns)HQ_b zB}+ET>8A3^DgyO-OqY)`jE;TFKA|_UUB};@db8R5VqAPyQ6fjTm8Jz+by2LefWS^- z_&^O{^sY#D&`CgALsKBq{}agrLk^6KqC}Q~4Kstp&y43|$<4r@0g+3TT zkR7i)kDIsBRTgm^M92I4vQ*RcT^xbUMZ9!BCvm&-j_6wMD$RUPc5*%0)_bzOxhLCN zPi8$~97e+uN11Yl;oOO)9?t0L$uZ3hmUYC5Ic~C=iK{cSUb?ageET^Xapxy#X=QxFAdTn)R*MG@)h1X2 zcx+*T=A-xoymr*dY_xVAnev?1wIC5nC~UM;wX)$U8Z$IROmUDmrGqL9>(=o@F}T}J zB!!G1nt~%dIwVYk$Od~T7J}%`K)wJ48R0Mkq=$$)O%ojCh~f4$TdrV)2!Ajd4aJnv_D z>pMK3q3}tQDd`dU2{J8ItJ_uIC97Qg`7dvRv+fQo36o16HWv75fi?|)q5v33XRqI4 z0pl+AK$o-=7T`I5j!VkG47`wNf+WBUaY~MAIP({zq#K**+O;n3Pk(+w`=|$0C!M*Y zZ&(EQ@gKYo{`1bxN%mtibg*jY^XHxXp{t$N4&G(38z3t94bMBzavz>iRe*j>KDqMq zSP;)Hwjh_fSC0PYDk!Vs!AgESDtr4;a7Ag-`Ra=_ws}m!K{GP1B)9+0P8k|QC*qHc n_`DG6S*m`u<3@3r(uYth{$PozSGUJTdv^a9C6{tYxQhS)GnHj8 diff --git a/build/bootstrap/pecheck b/build/bootstrap/pecheck deleted file mode 100755 index 6536a79bf3ae09b594bcc9777311bc2baebd1187..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65536 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 diff --git a/build/bootstrap/rm b/build/bootstrap/rm deleted file mode 100755 index 85f08d8b87247b23c2bd90a9f9c908c040c59501..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 246151 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

    J^c1?FW;!vNv08&GUaP0A(7Tjt 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 r$gq?L~W@&nSc(Ibu_*73cgU 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∨aK@&B^e;B)Up6LP(1S7N z7@&e3fRX8-*QSl)KCi|8gx@YOs+D-|I}ziKI~UtI2`ROuRW{>l4^pKL5@>K zue|IDwhB%9^rY3>YBrpiso?-}<$t4Sb-lxBrB1?`wF z+EX&xq>z>L9py(MnP#D!A#tZuo$;ZYPOvj-*7m475AhxpKXmZM9okmG?M)Pam`9xj z7&AEMiG4@(^vP{UIsm_LpgQ=UfF*^V)H_Z$u{eRt6E@-LJ?B9tRCdIcTzr{`L5Jc=k*GW&raJzV#vF*NdxnqcUTp z)oE&nr-%d+!4C#IF}SD}d7L2uO30-}0i?xlR$8Uzr=kk|b~PfL`8h_PNGj@QRl$yy z$CrwfwOUkl92G88pVnqz*0{DQ7$^~@xwDZ8ldZNyWwv#tqUG0{I+?;GP?XUyn0dF$ z7&^s?A{0~UMMwKE3vv+}r$=J&`s~BtREmTYkmEHPYS<9Ce(MS8!ow-+;NR!qX1l_cQT0fZTBUV!X&5nq zAsqLd!J3ESBw#qEe1R@|6kkk%>UoS?N*_suHR<<`Br+R!9%u-<3@LHvK8M-lA∋ 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 diff --git a/build/bootstrap/touch b/build/bootstrap/touch deleted file mode 100755 index 7b6bc4943882cb7cebc366c1791d21eef48f5fa2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 184703 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

  • (!6o`-#RDHBTvBoW+Fu~iurqe-*dczN@2 zO@PV$fr(Z5%Y14{EXC!uyRWhL4b_m|;Df<-%xBT2(%W=D0p?Q5lsKB&ioJMD6+5;< zQNYxgA}LGzp^*=K(jO#C?;zmpwgc^PrE$vQFTtk|AZFz!s`?Go&Z}5Y<~p0~!Vu|r zC3G|s7WZaB-i}m;Q&ieU<7@{`$CZG>Cw5TqlJ`(}`+~s_k(V!6eH;(eQ96k-{uypQ z_*@&6f^Pr7%)4qOM7EYwY~V#o(j9o6l2~v(gxVzZY0(Hk#RqdJXTLytsiosLcny3K z9k_zg>kDNZ#Jl_lBI=g4T)E0mq5Na%GC9%`Ugi-A)?= zho&MZ=Qyn)Rec||tyM_qNMCuei2d?i#7MR(y6DCmIAp2)QV&y(rE9${!z-rpWF}Tl$F?*yut49*e_hFTQ39VtmzS{EN)*bf3B<*(p#IjaIjG*}=7zw)wH4~$A`mK~f} zEujcu=to~EqkmkdN-ZePiyi0SDODG1I-9C|O*EdPw~S9Q_Y#XbXIZR*UDK(~aIcz_ zLPQA9%B7Vmsu7Hq#s>Zb#c|Dp*l#HINhRfc%gm)1$5AGYj@CLA)P;1q6s)BTX6@0K zNT;nl0m8KQxVcqNrwqJS6sR=AFi+lr+2bB@W5wpD7@-s^YuG<+;H5v9#J;Wof^ za4G+X$l$i0kXE6abi2kZ>1&v1`55SJk?p8!e1*0D_zS;4l}#VWGtF2Vf-qEnug>6l zy-_jMByMq>`xP#N4GA0M5@>EAELwd?0~;3J{*2`lMFc)HBw#(zvIk^j|A!d1Wbx0q z>nXvGOqoc|27eal7k_b#0(MT&B;iWvT9s$g_jdLcVw6|UK-F3#;jWLjaoq>zLs${Rm~Vy@-b@C3 z(X?W2$E8KWowyBi%>juSz=R!A1I*RTDE(#AkYkmn2ABpgfd+GU$lv&5cxwnE33VZt zkbrePFaFfR5#+);R9D4k6}TIwB^>eDRUr)2_`UkDI8hmfl68<8RDD>g7X|{3C}eoa zG^8`|SyZ4oD%}4jukJuI)*{=7mc&%P$*?r&wht>MH-=}pt)*7D(c8kka4nOit^$Om zdcv47_qv1#c0@jmw{g zAkmKnJGgo+*K|M3Hm@wGU4a<1;rSxw`cSFxrzlz?K4~#J4}7@GE*{@&T82e1O`7%0 zRm=BrX?DEhk=P{yKdXLve9uY{8W$l#2N?*SmSDcdjDVpdNP$Z2Qa(+5;fuaMRwpINC-dZGd3AF<=4!UAtzP=_aPfhT=C`v{K!$Y|@WYk7`j`+#X~=87-l1 zf=+Jx72WRxBZ8+-Ya}CCu55H>)C3S!oIUhNZ$3vETqevRiaer*^WxU@p- zpC8yXryHw(KwZCFjQH>o-B&CLTpBMH`miGFb$%@j$e%4Qj*Y^)af%Rw-xXqC*xot6 z#${7HZpih)S?bE48Q2sXHC~*8R8c*t+_7e?L2Ie75JW#R}Es6!A8`W(BhX_x6J!BoElnR_jhOg&(Zg62*vPZU_uC(Ta1v ztrq*l!N>Zw%#NFiH2KnOD=fF$PX-h&eMs2?u3}RXme9T2Hg{4~dJ1N=E5!60s6?_b zC*^aJ$LbAk?uY9|qq!E3Mh$-gjaFS%uJ#hTUx}ri*3~;*NBjrP-`Ik z>a9m?RWHF?*Lcoqn^(_&pWd5TB4MTlPfCVMi33d*#|dm*&hU@x_L-`ip+~-XeVwhRQBwVGq<_gN3ddx9n-kls-^J?DP9u={i9|1^bo78Xhif zfdaFtiJYq~5R)9LVTiU-xVz9UYJmm{$$2G$(Qwue8& z{B2n2ATBuj8<=m1y=eldp6n>Wud<2*ZPW>iv^P`>)wu-iL(l#PMSAwy+QN13-PgVK zoy%(p`lAF93OL1!wN5oYrl(L+6NIcqQCyk~j4WAjQXAc8jrB<_+nz-4M{Aq4%Erd3OEH<@(g&iJ2KqR7(bo!Tm6i>C%PRmH*H9IQQPmMky-7~%3< z7|Zx;0_`>kh$YYiYrx+$qZB67CF7dYiyeAjv}Ft8(}9CPd$hKwiaG6>C@#>Fh_@jp z0-v-88eQSuoVM9;5T#^VJbUoVgon~DKT#G=!3%wd;p#@>_h1En6#uDQX!??zO6oVMniZ@}*K?L-HbLeN`hiF(&hac!D zpMgM_@AT|4i!-^-7FI}CMk8-+6%!zw3|w&uw#qA19kJg*jBHG}&q0hk_+yj@F*qY9 zR8QO?rFLM8856Qrd}(6VwDe|n`;=Rp$t~cB3odb)UcOz?k1RYRErtL7yUZCXfPYAidMF5bK{;T#-gNw<;Ea49rz;WYx1(peE zNxBPdfzo|VCN9`@s%b69o;%bH}$`L&_W*^#`1x7;U7pY*~{hf$> zpsLx$$W|zwckwwG$KDNeRSQFKX|i?NRtge3d^z*X-pYFIB}PxQM$e6_Q9;2cb*!cW zXnAAn1LZu91vWkJd3xTLv_QUwO-^QK(0oIaMv#}2uKbkVJYBNoIk>iZuHxQT(R!c> z1W_2At>{7}wYpLLK{v7{8kw$N-*a0~k&zDyj5xN%G7k>woh=qu#D&dxKb&6=;9$`> zojk(>0~w>>V8pl<%aBO4Kt`PAg_2oD!i7aeTQ#v0pA&!SKZxKN{L%-fB)szCcNn+x z+~zcWFS_qn2&{(FfQuM#Ck;hdU)7sVa4Kw z!!3`Ri3bcnmf!(BbE<#^Ojr%8idCm0j>Lppj8QGa5h0Lq2Ywl$n5&pEwQh0~1ZQ6O z0owK#2A~XQ{vCn%P>RBE9zC$^_9=X+GJnC7km$wl^vWv^G2sbF@*zC6s(~Q)8s;91 zaBm>v4@5|atMecS& zp-G&!E!k{)VmCbb1MtNM!PK`9mcpBGy>^@Ji6;>(dtR%Hfj=&I*T&UoEtbvWc}?=X zrmO(Q=;qHOR<-5Ljo^UcyKMSF4R2)=5pD78BkH)7oi+t?1Dp3T{(fo)@I5SDBQSI*VJx%x`F=s!VexJGO!z{7U4iM zxtRIEO{3KVgawpWuWc3?QPrp;IK1l1b;fxrJX>D`g_&U$F)fzM3rTU-5mu+n(;9Za9UMj`#ur;cOZ`Y-JHn2Fk+Yv4@p z*tXIVB-2xbiQK*hl z6?Dfl8CTRZBOZ%YD*ueB(OB5V_;b)IpV^`7;x2Jp_5A=1o9Y+asx1QeS?H^2MA|?jo|)@?W{bXSzsB;ba3uSMFnJd?$=>cc2g;`6T|_i{O>} zJ|k)tfgDs%y7QXKTN5}uK)DpJbwg2tQ7x*Z^C zXmJGaiIi|p@`{paMY&#^0w)@a8(<9PWPZw{HV-1{Vi z*Bud&JRUC)$zpGx?6NE8D(Yyv_X+w#1<>r23mAMcalmf2Y&l)ZFug6G;WyA4d$Da~ z8`h9Z-|AVeq3LA;MkFcgG|Ht2*!#Mw4Jyh|;EN(CGD2{9e039T8zUX9TAt~&{1-YH z#J=)0vO?CgKSb6$0b2sM0#-kff{iUaV<=UjF++U7NeEz)s# z^RgF`*s9ev1#@3J>R5k9xA8F@(an75YHugbQ_sU~`P~W&Cf56+S8eHd6l2`|P!zC$ zd*<4DWk(9wMw{x;-nz8;9FXr)Cee5;i(P2)bIL)m95v)!@YLE7$9sVTMyvhPDqReY zVnZ-%weHB&I_?xqWN2maU6{tNJ%YN<$9bj(ROoIKii}k|=oR?0GvU9`pMIshp_=G> zs^8!e^qkLN&-00Y?dh>@=Y=g}yilvu#<@A^ELB$dK3NICYp%SBrN6*4R_PBW5C1vR z1~=@|M$9IlSmJyZb{}xLf*M9{SD@U%tOjZZPTHlz%JMN-qn-jTw8ZYFzKf1bOB67T z3x6nMA`R6Fiy0@C?FgjPs(|zpAk(UhAE7NXze}u!6UaC40nGkzbiKRm-hAhh^bN`Q z<3(d>jX#n8_U$m+tMjMk2XNz8(5P} zAH1>zV^OmjU%Pt6(T=YGQGw%OVG(IJ@#xy;RYB(H410DIKJzj#LpY(?)T(*^2)-_~ zJQxWqFuQe7E7p2f2Dldf34X5Q!)3qs|Rm{w82L+j<{zWaZd&>Hmi@=Zo8)+X_xc8**o73U%pVg`fH3Z zKF3gVMoZK8}yM5uT1L1&!vKK& z#ib4-*>K)93|(TK`4(z{q4QG<_R3JGiif`94~=(E=~)N8CP_F5NQunQSzU)T#HO#i zK18|hAwQD}pTDH}55Lhv`zx?Aj;0S@0(7wLb2PmR5Aj~u_E&^mFs}kS)#pH{yOXdJ zoHj|hLv~9zX=lWli>nu&5)lLRU3eYMcTGPI99&bskK_u3RY04&a2+J=>mY2SNdrrm z@3dXD&vAm6J78@bFnLtJUcpsy~2_`>v6Q$~3GQcK^(yPg(v&K!kv{jjds zzU;@{n1e}|HEVaF2y9wfF+9`wDQIZx+FmsD3OqzZi+d<=amI%CUPEn=j<#1;;KjCK zHJ+~N&jWG%)y{*#rOc07XMVl`rJFT(cg=8J(u1jsVL1o~v)%A973cbKCFqM3QrFF+ zXu&?bU29WXB5WNa)X9Jus<@pZwjsiPe;SIt*1pobNPGPYY&6Ddt}f=Z>m}e{UjH&j zV3VlXLUNrVU7ZhrKnkz5i{>G&b9lG+cccEKAWM)v@&w*&Vb(K}In8yH;_hEWaZ#43 zup99>_c(mGi9R;L%Ytnl#AZFCx)btuFi^GYLBJ=kX;F{eGwUW6gF9km0exg;i0flq zs&WD25?jQ*W)VYY1QBPFdRQGq+z=meM#4kH8R%Moc^les4V^QZ8i2h&-c#w1#K2N}@Kxc;SIhX6; zm!Ko)VD$AK`U(peVxR`!J!`LoB@pY^Si8QB+NNO#DK^iRQ*GmYM&!lt!2CwEOn1V( zWmjh)B@c2P@G{q>VDV0foi4?R7Thi;~O;@N?x0d z2fJ}t%LhkBP=;*-2gx3Ffp&HDs^lSmC2CaS4yG#jxh^8hS)`TKd_rya@7N7Y()7ub4#1wyS!0p>`1|K#-;1+6Q=c@)swkPdq{A3Ee?%b>Kd zYpn|Ns0{ne&uUN-u{)B58%Q3`@0L4WIOG}y0Nt_HE|nRQ{+@W(?=bxZX=kIO(p zzIqstk+d{uS!|{~8@nt|*0!lH;pDUGyNzyqRtUS3zFM!E@DJMA{slio)f$Ga$nI9I z{XiqdxgIj6kVcw$fPW^}ijgQED8Nbxj#OyGzXAJv@Y(R;qUp~au9`b%!?*_~;*uJ& z=+PdP=iehba^M?<_)eAW1TF@;O$1~M(rSbk=q8%W=-6uNDaw%%)8_gXH0i&u35!nm z9_UY+`709=kfkjLn{RE`_s4!Jfrh`Z9dk_qWuvY@*Xd7z;1F8e?(cdI?_eN&Nxz5T z4)1vzL|fqsBm6uLyDy(`eMQ-i^(1+q=PhD?6wrMDbkAJd%?GGu?veKXTNd4!{&{`7 z*wBjFBZ6xWxF?MUd?|}|p-#@QM;1~>+(~7Re3rlAi*d#;eB=FjpyHrH@SkUX8bcrj z+B)s_yGw_p1E^#(i^6gK-(ZMpVO$~R9AS@~3t+Ts|7;Gn&fJR_2BRL3h?Ayw^uPMjoAZy;B!+(e(y`WHyg0QK)?punBQ;-j9JqiiOS|k9`_2cuzx8>^E8qs}{n? z@_i7b&C(Ir7mmCBifAl3f@yv_?A;n)~L6)vUS8cVV!zO_(Ope)pw;r^wA?u$ZC46DJU z0Esjob@ICtzM?5xI6p2;+tXnJTz-(RqHEp{$=L9;P>zRmH8 z#Jq8Tl0KDi!s?XfrHvE}bAC;i18+4RE1s4Yky~-0ka%X&sb!&>_Yv>ej+hq<5QDEs zwJ(3>Cz&!e`?D1_ryWREbHj?KJHA)$e?h>DqmWxgx$n0R!e%Ll!-3C(S*=za%L3Zn zfqbUwSKj$TYloJW5wBU*sLm-w43}J&Q*_1;2 z>cD`)q}77TG6qpXNMVve2(sK?(mCF47DAC^kli3)^On~foFQBV2GfRu&gk2D>q7&u z{UB_8L|`3VQsH$Zo-n)J0URh&{d+Wg%lCZlLTjaVy!)pvFThU>?gTg~Iu)Yyj{#`4 z)-ZqKf93Em&Sh>;jmfZG+^w;s-~byK+MjV%Rn=6jCQOA3MB2hM@g3;)6X^1zH83=w zCx#&iY_(96i_oH0%|OE}r)HpT)@AqptPS&pEa6X@_tV%+xr-r$Q25@N53&rSGhV5_Kg|xq|<{&>tW$U(mo>6m--v#G4 z%Yf-Z>ir#zH?j6SQ*$a+|$DHOjY97Ul|wJ*3As`3k6Z7<~bOrtU+et9{`xGtWi}*T5AN z#XntJ*9P)AK+X4Ek9ZzyJBR41NthF^r5#sbLvsH>NGEqnMt{1B5n*cB_wfzGu{grU z^$@Dn^~2jJ^FzO?kzr@hGblfd0@$pQ(O)I!Rq=})UCAjM1aAPVhc4BGB%NR9o!MJ?ep#G@2W{8e2dwB_&oWe@&g89?o0`va);q7 zxq+^ip$IUz8l32pRo>A`yi+<4=cnXdT*fQZ^311$aPI{Al(>9#j_cwMJO<9Z9k zWsmHBmL`m{*(U>dco7*;!9bL8n~p!Ap>@#5agR=+rtBd2DR^ogeiaTBd_%KrgeD9e z!Hlv0msaEp!N_+IG~KwN<03wddMM2Omki+sKICp5K*l5QA!*ujujQYdvt-)3GjX97 z^wZiKVaw;@8Mq7+k-@l0Za{a2Z3sRvt?72pL%4F;0Q+Es-n0!t*iH8ggbB+A71{?E zBJ_5lZAc-)Z@c5jIu*S>U|k??tb+|o_1!L9&4Yy%Sf^l7n;dZKyInWI{jf)wSB)gF zhIB%;z==tB93^~}R)A{pDf&oU41(>SlZBQL3>92d6^|P&&*7@X4)eWH4mpYtPYbJA z#(&VUfq!5+NME6+uP%exjMl9E3I*Zb7T`Psmp5XmA|q*5m}U6^Z}ly@qJ)GtHffV- z)2Ggg&$;Yz!a~$gnvt$4M zUtA#=HCeVCTvU`AR0sjH3&CyUiMH(%fvXK{3%Iwftx zEUYXXRi@w^3y$u>u#bbgV^V-iRSb0dv6z~~lW--g|Co7U7k2O}Jui&2KZf;T&+52q z>VG~@rj?1hF&-)mH9_N`vW!O{(2(mfd2zXViY}>0_2NU<)cYv|7~|Csz!>KP5brTm zg^F-ax9u|28MjX4AkPO*r}628%5*Qaeo*qrI$`L+E( zEptl#8t-k-626)~Otba|vSlPahDtBv4XS>eF6o43?HPD^)|B8)9V<+=!(!)n{{3%^G?thP^&h^v~LQPLKlsl>-qH>?t-Ct8xJRhA^QNJ5KT zmWOmn6{2MfHkhQ1>4vnUPh*2#vZklSTf%i?U>r*HfuA9)2y-t$Rb+Jq)jM3XVXeeb zQ=0za1`rsm=t?EnV~HX&m4sPa3SCMSue0G2o0PEiX@_l3tJbBATu)#>7NlFZ7~g!a z6xXGUA}rP3dtyGb86uwktn+1E0^(%p8=R4lEhnr6f)+fhYcj1=#e9~L^qE=1^%fq6 zWh`5mZ^&bQaE;b(X-#OuE`D=0xa-NxnzLL}ln>u$C7m%tXne(Y75~#`&2TLT!*ZX! z!*zZN6Or8)#H?Lk?2>_#ejd0n`?-$VdTuh!fnZEnd(;w%Ye>R+3^$p!2wWy*3`2F# zwI7g3BY>jFI%k9kbK{{N@rIOGC&7(Dsj5Hm`5Y%cR5JhR#ErUL4}V zBt{wBfqm&H%{_sZBY3^w9DhVL?tjSDoC&UV1_qzvsc=4H5DKM>5b5L+mM|Q=GvuBn z`M7?T3T+(N)5btoOa1|`yLh+KypT^BKZm@c`J#P+>UtXkGcgZuy%>z|U-w7h?`6}V zn-ye+!gc};a!<0)QWZ7=^!x6BUfY)31G{Y&KFVIRNCgd-9Rh~P)_bJ=yN&JEnU^f^ znV;zC2|BArSO;RBKpU`PwLBeb6Xs!d1+FX%Iut;-b%*W_!{Qijq7odo0K1~rd7hTG z)Yv=Y4)lI*QPv&~vMK1&POA$bJIZRe^Dre&MLwWL0!ak(a- zaDaLhD@pq$;0K>$r+c|+OSkYB3{KZROny<`2_&Es<)?L;z0)l9+6{9AZPMRuM{TDx zStrRb-+%q)lO$w#@SI;oPM!yo5L(TD;foUDr)KMrf40}pJN#S&V^Pw~shmo&& zq&fL!M9RJ97o)cmx+QXf*Ff3`p#-1Y_v~m&&xd z-D5g_YJ@QVq7lN}%LqZL3%5V?^q|dWg?bD9*4qkI4@pH7&3ifW_e*KXPGv@eXuJ8E zN726+bnZFV+Au?GCQhYMyOW#mgBEaUOXjg0W zU@QZ0CbzqJFAwLNCu+Ub%ayk7cFo6!uzmYg%?EYt;S&-Jjvcn!t^W+DJ(nz5KeJ{8 zUx7dj!VQBLTDyaw4+eK<1Rs_MAhcjuMTc0E!C-IVUhbIy%{3V;lBRKit`YwM;Wr8U ze$Q8+2{?&K*IpF>n^0OCAr?}LYujl7$j{W*?oeNr?a~wMd zM}qak2u!+MAr|-o=wcK1dDlcJQrNlSdLH9bXSW>x=|su)jkfkPDAHG4$FPZn=AcRK zmZ?QFs{wyZvt8kPSa1zJ?n;!8)-Q%ehJCwf;D1C5(3^1gHq1_DkTQmq!!-nzk=>&k zS{1kf%+(If+7i&2TZxnzcONgZ&a{>TXp8#7OPJsFa0tFB;F4WRTj2G;Q(_SZXknt-4HByygstx=sD8L+u^8YBsvA zIe1=Z=lv7sg?dMpaDPaHYNzV429AqiT~Xb0hq-xnJ`dC$osfIs3P?A{cl#F{C?a&Xt%BH-%&1G4*pj^cTCEkYcI%d{{%d)sf|W_)XIXb%XYkMn9RS3p^5LGhTTui zU+W~6alo(6W;PdOC{?6(W^9-jjJ9MS&R?A@PiXeGwk)_{3X8I7zlgw73#+1Qb|J()4sPG98 zRF_fn4?56xP5pL0Eg?kM)des)@pYjC6anqIeZKG3ZyP?-fgpK;I01JO-NZf44*`12 zkB+q8UEFj2;v%UyHLB}foCrU*s{FLLcY2D$9PTlD=;t~t{zDy4!dmKjRRG;pjeAA9 zXIh5h&JrPQeOMZHp+w`Rk(ri(SsQeMfUS)!kX|$*dS>I&~~HtbYSfb zb@h13dS2B`09eLz+c1_E&2hCC6?}09p5;SoZ{t%Lwa%Nhj-YnmyQ9`+dLhV|S3)iKalTc7?#MBGOQeK_c&gFYSfryoo1;|zVA zp^r24afUw5(8me?zrzVN(Gr`JX3%EMoX8%ks4O==RAnkHe8{xI#F+R@dX{!p&U0c; zcB-h$F@%KZ(sEL>Gv^sH=jua3MA1-GTqT;z%S%OLc}1}a??oo@`Qi#OuhLvxm}fLs zjT4ItDRiZ1T2WkO9*5NAMP5@`fmqJt!~#>5xwtIPTwGoz78aM9#*3MSVp%yaiTqV^ zW^sA3xv01dd8wM>vI>itCr6=0rZPPIz*Lwj3(G5)R8bk_@bHqy16r!L++y};M1iHH zV!lZ)spgx^3q~6TKF_*F_lQOG9)DDDgE4e zIhi?BDVrv;wE6nk`ne1AOf1X;kri;2O;FfQJ>9TR_J7z>cZhSRl&%$uJ^-K=cXWl@l2=(u*_0g%Bsv52=oL? zAjedRN>bTere~S>#i1@en~&Si*-tnl2cze);x`h1|7L^iDt-P4pR4t`**>=?W6z85 z-~K6-cmJu>`0L3FgXTfG-d;iftFINl`eFOyf2rf=8`2+4{6!eP9;AAOBC%7T=kM(V z#`Y-~D;Uezr*MzM{Tgl@+-q_>pi| z!<`KG6U6J_hQgl%_Y3$J!QBP_D!9)g-^*}I5x$N52ycRGfWHmyIK-cT8v*xgxPL?V z_v9j-5}lg`zXtA2_$R@g0srH0FTpK`I~n0?;MT!?4eoJ-?}e*_{|mS;!~ajXXW>_1 z3+G302g2Qg@JHYlpx!y;NBFaFbqHSt_bl93;eLL{;6@-m z5AH|s<2z8;r-FWiI~?^Mf@^^L1KcdQQNe&4?t^g0A^mi?tKsV5*1>%S?xiv41Gulj zzaH)kq~8Ts1(#M7R0ux?Hv;b0a6dtPSKz)3_a@vdxPwB_&qzN3?#(g47u>a=+|06N zd8Ne#clcborOe2=Aj!t!B^9M6Vt?T0bNyNfmzwY_DK=BMzFe%bK)aCHcjX-s(Gx=| z8AL0~L^(d`AXcrcGMko&;QOU4^P#ySBFZa!a)8Md8@Z6kD<}Xbu43BCMPeyLJ(zvD zSXy4Th^0Y;AT?$Q#JQY11u~37QD#|^Z{npvA1Ez=^1uNwRWSo3SKgvL@XWc;yr8=+ zF)e{KWAmsv(0QP}6`0D3(JU&=UwH}yQ3)bAP(JBUz;r!80>W}jB>>L1RIOy`B*(bA zQ^is%p-DaH%gJT3A6;@7T5J~cdf_Y+Qm2=fm&MhjJCf1h7tJKxeX?0D#=Nq^#3f!O zGniJ$nq@DTIO-tKOdQV@c>uW7R0uRsqp5A|aZ9;553n0erUKv~(cR3d zD1{uyatE>=V5o6bETyu%1VB|3SD4tGJabVGU6Ia8_%0}40_@XUAqY)Q1N2!+p&I}d zl_sv}mGLICY(HKLP&e;`<>eOiXSva6sg&_tmd6zUA58$cvi<@RF_r+8%b*sKlF4*E ziVIaE>p(rQSFK!<4{gf`3PU5H)*GP{fmUVeUIO~dTLfwZ^rkA513eOmW|^QAOc9`% zq0%K#TngB{%5rnL5pxNdAfL!9wUAB%=m_mZttg_fxC})U<|rhv`yHGl&`L#GGK<(2Sq zC^&4s!g`_!Rd-N$S8$c3qN2Q##=j3TY6|bdJ27{2jQ=s5nq;obE32Y{X>L_fUJS*n zr`p22CB>jV0_sj#TA4pU|NUvCn7@*SKJO9cPncJViBiEz%pzzi#8UIhcq=jX7nO08 z0h8z+|IpWCvQu7JLW*-i`SLQ>%Wo+|NyZ{hUjE>M%JPZ|WXA-i42m-GlYEmg4>b|_ zfY425Ags{5Jg*W{HVVHhZC*Z_&QkAW<~evfOfo~uw-gqF;HvoOz0)^_pWuxk_P5ms z4La-R(-8*lr17Doie|TYg%}1u(<@?Ckp)U85YjV(K z%H;;2+ei~Z{qo$O>pilf;E%$9&*L2eU50YPhy*KwAtO!9nVW7{pv_JbGjqgw*>j)B z)TQafSZxmcv7%P56Dg5)z9D07wy4X@NzKw`&dCwASy>^-m95nqGShOz1(}8nF*|LR zHXG^ZA`1$;Q?NcYYrZa1KZ|mSnJ`FXrs;a;o|`VtNy|>nKw;XH%&bhqQ@rBzOoKix zCkIv=y{Mlnrah6SH;6eIR0v=S@xhdmCT3-7Q?k;;bU>)pKPBeOOH0kvW{m^5*=ebU zamep~LyFY7`kb`K=c6p73DIfiXlJ1TzN~)lf(%?OF&8yvqg6TcvkU}%diLBoV%FRo zq)r#-=cJ(mT)>a4A;24e%^4>y$VdZd*#xl`|5M3;N2yV%AsgOtqCRa_R_3fUeQFxj zIhRt080Kap;e23~XBa1Hvomw3#<}wilp6_AAj;6AIaDG?H}wmk;Pt0vqw#aJywvo& z(LbJrEHas4H4x)da&!+)8qMFq@Z z_k@yHXCZD3cF|Kxda0$Vh%%*cp@L&hjHOqaOlf7yilG>g-k*cvR<@{$^3O7v!N{v% z0-RG`V4}1XVyOhrH$z5~hM!q*SE!+gMD5)vGqS&;2ZXvRe}_x zGz;>I&FSTpIq3URlPnx5l#FSNd;dDVkmJAhxtDzIO`kjH z&vLxzb07A(={`5t=T`dMbw2kspZl)QJ??YQ`P`d6ci5M5`SCti=W`7{cd^fX-si6O zxv%-$CZGGE&pqyQPy5`PJ~z~dmk6I5?{la5+$^7)?{ocl+UR>3%rY)ZEQ&v~`Ev+= zM)RkZKO^~bIDg*9pCW&T^Jgr7-aneknat+ld0u!D&;2TT#;_thE7=M>*YM{Ts@-^( z7(J)+=MmLjyia2E>{K=5Ie+viJm)bdp68SBoW@q*Ih8+`jHdSz{`_3E4(})U z^Lh3v-lwqLc&75_4*uMzqL4xS-NE+a{S<$`qjuo^E&dE*^d1#R&n6!7Hh=yHf8ukG z2;alsb4Jtqi}*l=#7algvz`TAm0;Bs@jR-^#q$EAr)4xfSF#Q~vqsYs)*8QEPzdZl zVd6t0Mh3H|!sdrenK`xJ=$N#D1MZtEX|tb*Qw>%pMm`!99iRO0kK+OK$E+PM3b=`&_bAEq0mw2D@%6_vfC6e1oA z!mCwf4YT6KYE`{tRrLlT-Vl8Di@!jlV!1}vPtMi6qvS4nMROAvWaDq?% z6J(S;dpAnnSI8)_Dth6B;0gK}Xr2vw@@{CJGW;wwPxo}pbEBRCGz)$OXcqoA9rGVP zC{(`;#Q9LQL*J@Dp#OvZJw2?FO~RpItMIA*Px^y;chCp=hS!8w2Yeu$SAHXWEp+Hl z=zkq@P_<9LMZe(hL5KBrMU6&vEvQ-lxxP*RiN0NbOmRrRH(1ds{JSuqGlqSrA1w?! zqF2@n?0x;m`mcjd1%0glS5P!8;e*5|z z({B;J&<~V*7iR8g`CqTDT?671aOTz534S6E{#DphcjNNuXMYx#&-CE3h={zSVq5S#iXYKi(7kA7eSiP|#6X{ZA?r84q+k3TRmeH+#N6wr zn4CG%odkHJs}k8(jqGmnxm!Q?`F-xTcVz$OcjUY_QFi;DeHiG&KpzJBFwlpAJ`D6> zpbrCm80f=59|rm`(1(FO4D?~34+DJ|=)*uC2Kq42hk-r}^kJY61AQ3i!$2Pf`Y_Ok zf&T#m^wD&MAmFr{{HI_aVCNaGWhXCQBy#Z=#6#tGi6t^6V*0aC9*U!ecmMep#No#M zyBy_r{RL7IY}#S*zWDeD5Q6_buCK&XdA=7(b|3%NTtNB$U;n~<3C}87lT*p+hcj#E z{rEkA-wwu}6qv9cSK-xnDK$+60^5Q+w)x+!RRq(GO133hg>O?}qib}7urx+s27y_#Mf`Byc8e8d34hbK zh(T=N0R=08-w=a12|rvLKO|=L3!AGH)9S5@^SZYv1ba<@fuFpl9chMfC=}bYocPQN;=IKJeAnosK{Ar&Ayr`prvG;i13OO&%18*r9 zCbg)MKNb1&@dHje9cq*_n0daxx18M%*PlT-d4nX+r2w|YpQdDcnlynysf_`Pb}}d$f|dccVWW5~P*+!z2%T5}PlX!j8dZ?^-3j8;uX<+Jb!j zvT;g%ZiwV*M4druwzQ`Y;wRO=jxf-Z`!LZ)GpqkbA-IirSIm%B3W?In7^di_kYqQe znGGDXTG}i)V(gS|jlVC=lj`eHj)F-o3t0fCBN=y->g@<;4Jpl5);*PnO_*H&62d}I zPOd|=Q{B`K#R{rh;ZDW73iT=`ODj{Ds-H^KHrK6S1L>XG_l<(xsrUHg`YM!_TeP@2 znyK&9J8nw-5`>>;!S?G4h24p<@(1`qYa7>0wq^^7=`Dnh7{(qRPxLwMXXqI58K6a? zVWQ<*fk-!ud9K|{e?B_Cp1bM!N`nBmo~uO4d&VK5&J? zKzgV0PAi8tS$SDQ-86nVj^n4+cc8uhXPUI~OTcA)R9Z>!bfI3#XHAjIqWnpJL|N6+ zW-6!5S5DV0ub~Eco>n3+$^cFEt3e)e8E9Zjn`p;pv4>E8?8w~WaCzmi^77RBcPV_B z)RIATk0ak49)#ngz(c;v(Ki0@OiJT*V=DNQuJP8YPdU%MwW^Wx;D%`C*>NB9>>R>8 zua9OeyEM!rIj8@*;dcoC9gRDoiFH?>BpPRzR-YuEf;ukaRCv9>n5Us#sAno%?ttU} zNQ0jOKP7%D{M36WzG1qYt|5ncMD%ULTQbjWFfx>Xe-lfTPBfG=5B4W#H=JQDlxHdA zMT182M1$|<0>|`Dur@?v+<`AQ%o1AoyU6Mrwj+F2O$!Ucc)a|=$sI@|q7NIk{X+N$ z%o8mt|J?9_eIGJ9*W0scWL<{$e@NY+YYBR-K;osKFFTqdc z`Qvl%iFd$1#23%YK^v$XXDG)b!7P`nmhnn)j(+t!MoV{KfFE$S0M4a5K=Xe5I0!$! z^n!}U4&(B$;Xb)dcf|{GJoJhPf1VgV-hA!!)xp?(gQy;)F-TOlB-S_lfq7zk##qq6TQtE*R^$as?RNp&2kRy7`|R^u1Y zi1E=*zl^`e!HTmuR{Hbp95utXKyAfe#sNdG(g}w-UkQe1zcf zV7zi1H@qczRPetJI`5s=%96jNI6-75b|9@5d1F{&eGDH{f;$8F?w$Tkln?o{<<_c? z8yV6Hm)CTXzQuIuT;GbAp{$2Kd2EYu~dlV`gKFIh}Y{3)Q7qk?z@vYd+{*Se*`D8PW7t z$P1@3yvfhkZ>?(IJxU%I8^fh^&qt62{Xi?H;j(CyDE~(hcm7-{a^NMO``R?wzwS3k zgIB9o_FwkJcl+FUC<+ws@WnfQ;V=9A{u<(Z^Nrz5SxAZ7_|>r%KP=%GWB6v=5NZ?YqQ;C- zeBMAXeWw%>YEVCo<5+2yJSJ{VsQ(X)F|;!Qb3oAlfyOhCuR6j9Xu0nD3H2#>PuVxI zo^)|)pF}i+JfQLHzxK*Qa~Fyq3EKQtV3T>iy))|1q8&8|JEv4NC0`OIqQ4BdsE=frWHnf}`382Z$4} z?+5IxiS1h3*`VHam0)qsYQ5@&{y_aE=+emD%N+U^XBA5ViO6$~?g`Mvgr>7b#@k5c z7NcB0PW|ntxzMduA8{Rp=3rY;)@H@@dYWfl2OrFhm6C`rTtitupv~Y7QwT?SqgZ`z zEKAA@VV+!tatzWDpPZ5l-BMsu(vCnjCI11b#qm{scXcd-?mVPqHgJ?n`H&}qSqI_1 z_J~}h5pR2WnYjq&{jQ_8-;SBKVVDqz}LWMc^K#`siti}OY%Opw3Xyskd$N< z*pw6%8<>y$F3Jx-)zhVnN}#%&&{G#+Jm+FQ^D6RgY16lCzbMOG=#2>!KNs;VZ2@cy@n1Abs!Fs!#Zs@x#sYqn>ksr9pu@!AC(6JGu8CA=O59th7ghxFqY zHh>}i_kDnY+AH1glK$S}^mr$8SZ+?G@39Z@wzCt?Kt7N4cpqXd-f-Y75dDaL=t4M$ zX}GkBXwC`!P>90&L+Cfrv9&9l>wry8%7ZXAoDFoM3`)n?%1w}&S9U<>rgTmv(S}?$ z>f}6&WE1BvpgqW$1cK`al*NK(d2%^VwssP~pzta9MW|+Z8V1brY{y)w2<@gZ&cMs8 zzggH#a>7IHsTEG#S|v2zN(JA_QBb)}WK;Oz871ggo$!M)0Cofw=v$f4tqg4Pl&Bj$ zN=3pAjO9lJaq4d{H*!M1XBeYwi`F9n4uZiMWzGIJ7`lt3w&e8i_&J|yC11!yM+jxghM}|uv@FNjo;;@ zVE&Mb`GXGghqOktf#Zk6@S4`+xb5AyMPU1!-gi2y(e}KZ)~!~|wR0h>Ph(E3U~N~) z4!}CrY$e@mHsKs{jLIk2i55{7|2zCBdIA6ae_F=gTlXXJfe(831@NT+JhHuI=nU!V zk7Jpq26hDE1gziVsjExPzZOlhHPb_55LdO*M5zs|U5a7#n;Hes}Fnufaq8NH98d#DhG}>(%d)O~M5@dH5$fPk+z|^1PLg zx+qS8xL<;GGH^@zPNBb6!1loo>pZ*`=T`5xt+x0$zhb?mlS%*SGia+|A_LP;ryO(?mDevzPK zS1Xw>jFmiwFiJBUF6u6E9@;*Pa2eB~^Grv-R4XSh-hnn*LA$@yt{-lAhlrr@tDLs1 z*~D|cd6ZQiyglz^SK#(xr&KQui@NH4BpUU!U-24VQcMqNWy2rtTFzP`l;YH?{qs&b zLfN2IFIJqSKI$3*I#^CLAuiTl_8QtshYykzWV2%lPUPXZf}R0>)Z&a}Q!&m!-}g10 zUd14Xp^L2oPa1%6`-1od@OuU6vk4B+>0-14GZOjg5J1f=Vr(55+Iq&2F@U%C=dyg2vUhGr|6M>on*!P6e_-Kbb?D1#g}Ouu7kxf^5(^Iz5SOPA z#uj261frjdLDPY&M{gTlyr?;u1(r0?c=K-07L?)roHt*uL_141{NOeG3jH9i4%t>! zoZDO#z$T7D+p84nvFAV!n}zU@C5phYFX3H8JU)tC;>H+=0k5a|9n}H8KkyP@2t@rc z7$;-v*@+OfwG%dqgzcCY#2|eh(kTHGQ;pch9M3f~*h&Lj2uB_;m$7f2_Zq%K8JHu4 zFoc0mjr|?u&m(~C4VB#Hx^rIM=2W<+kv0cyCcCM-#M<&LY&Pqmd(n99Qub@g5~P;1 z%E*M&SZj7FQzkgt#ABzycXMIKaVIm+rCQcKCrh4-vm}oM z91<;2S*egSr1uf+KyMs`xnK5q@TKRF7h}XN{KIQF2i@UY^dtCs(;3Kns*C9D=f=YM zM`WIq4?7Uis1~rYQ!<@WpTq$FSpsXBhI+_O?(jY|Ra$e0u5X~t!w`1{v`=lMw)^WN z7#{&#)E?Nsd7GSk>@v3#eaOee-*k7$s2NEAOYkS%_WssiP6P6T0Zr}#z6l5Opl^~c z^mA<_o=bBAk|jau;1u}Z;FBX8ee;^TxBmGZWCq#6 zWqZHSbPcjZ)r#`D-Y>tQ$8&k@f&GKzjso*~lG$F8*@2K- zif}uHXW-on{tdokAbsgy8SChR4Ei#5dVM#>z7zD%c{bpQM4dyy6C4W3a{zfyqa6(| z4&BxYJvI(9D3)Z9LQ#?c+L!f^A$Q@{GlJUs>F!Aw4_31OC>14cl!3WU0$?fGfIcJr zox*`TLo^F7=>k5K9h--Vt1C{X;8%k_HNrJYQa#okFpm=K3z^cL(owrr%h<6zlF>hU zxjZ<-aTb+8{WZsrZ@<0P2aA8s>&KyAZ+sXy_Ulr=gYHgx>I9iy5~$z&b1DVuSE9e5 zo1YLqns*ZY-$8bx6uid-u?U*SVVrd`{J_sU3n2%-fzAe44OF)Y?a{3c+=l%1JDAG8 ztEiwk2Dph~s@cSciAOU@uz$z<`p%rq-_LEBzd)x1U;BAFJ`LU?%gl(Tp&0AbKG5HL zggaUTipHAJCD0eX&pgDaAig`8_z)i_4Ix!wnv1Wxi&6IDEmS~-HLg;-> z-H?0G-#RZL{OmW|vr}iVLEFXH5+(Xmu|isj{wcvCn?VsFdGevpE`&UZg>E zytTKTM5J+zxwaohnt#xH@=bOnliCSgrR$w_*)>OYSE8*YJJ3EBhIyZgEpPouh~9qUpB3F06TNIl zz4;))K=U~V@odnrzg~Zx!H~=M)`@Xz2*LOwIknwq$2o%j1)U{Wl}~o(;tF7b;Q@^A ztvo)miPHDX%X{%rO7~%}yw2N!Jg)|MWt-B+jcZ`@NMXZdo05;F2xj8j&^42yKf>G@ za7H)FxXcZZ!)V-Ag|K=<7{;q20<;p*gfV*JLzIpFo#;g0L7#iP3wqL;wh?v-7ocK^SWPQR2;7!8#aF|}s-ad#WIrr?Tv?>@+ zL-CY{(hfyBz`N8rWc#ptVFo1iy-e34kc6YaZ?_zP@J`GZ-#HbP2F2JRiOsT~F$pi{|k^rE>K2XxipY*2C> zTWSLjBRE9Bbsa9jM|$P0RUbB5efB(`t*e80XC%g`b*t8M9qV&aAlvsgc%4JVCKIg= zM&E^BPH9=D7`#}3zP`C1n<^4t4@;{5E%JP+VpFOW($zMsA*6(D|Edf8@)Fu6g|I18 zeQ^%NF~m6+=O$W%+2r??a-QDdL|YAz%Y*NY!rx_L(^sHQvh6Uq+(r$T+W_FY5$>#poEXh*h#mgE8H{#5p@>KOtes~@ z!2TdOt~xR2&%M2UQ$G3)8sAmYo5|K%1DwLn<8h`6_3uL8BzniVG}M6Z8q{c`f<5vy z@W{}Iq(?Yj($c)mlSA>q3*na2$QMcV(3m~fqS%%!#5vG@N-H33j2i6)T}OuvONt^r z0eO}Kjx(bXhxfstWs*-ZSxKO&!3paK4)Ex47!jyc}&wN(K*MfXk2TJml$u{+J8f5{-$?sM9aANG6cYTEJX_;38QS(+~vw z537&FxF9^xo*uF_QCjjd^qmC0I30Qh<>hIRkL}WWu$aX0Lh{DH7pM;9)`97C{cwMk(!eMT-)*Lyyh_9&!;*Jii8Y#-h#`&?e;C;s(UE zp^Pr*=-?Th_X7^kHSZAc){YdUOJPxud><&oMq$*Zl+{{K$_mWQSn`(-qHp}L(R|HbUZ#)!NG6b8 z4m~Gf@RR8+3)tYr67WU%CY-QD==d43jvvip7v};mzegFQQ+)w@71Hfxz8ZayM>*92($yU(m#3ST-U2;)aSX-+`G=y9MD%5{QeIojS4<6oJ<~tWNEnZGM6OR@ zoI6nG2Q+V#=THeGAKt^9fMo5hRT6BOz4k&tw?;p3{b(rWy@Vs;VKGHI%sFA}flj0a ztP~#eq^?B(Pb1s-VzhlH+@3MTbu~rP8P@&&bBN<@C*1)$?!g5|jiB+AB4gr0&^Pp1%s*7ndBdBQqCMvcXOO)k zVDIRy-#8TAj{x4iF(?yy=;je9vl?XvLvI;@G8y)1#FfiaK_zKuR8!)b{e!KK(^6X_NIpP&@9O&?8!-R)&|3lEi}@cjP!ewQ`c*S zdPOK}R7D7l=TZgF`B{SJ57336Gl9lKKqIO~%7?z`Bp&WmgSMXmZ7*ak-z(UAUC2*7 zb0WqI;nE7(23rmG6GbNAy9rx{f!@0o$0kbPfeUX2UWq}U%lb9V2L>mM@Z}>~pnMGV zP<##PHkcPUpOIS5pzoc)f9?$Mq0299a$=mB!PhbOB)nd!8f4u{^8YTHfm{O)IK2oW z8`uSyN#0*V9}rJBVqX=FC4YXh1LG#ash|Jg9a4)vF``cb&?lx|{k#Z$@(KF+Oi@8% zHToHI7z5IF6oBSOfabR|V*eL|sQwp0|C-3DST3JcRm#bW$2G)E_kG z3CDONe+>VD9;EaZ8V9YwA@LicNy2Rxc-Jn3`DqmWI0!h5a882m0eR`fz7$E#_ML7I zM88BNXalU-TYTvW-qWe7`Ys+9&ULa^d~syg?m`*Pa4q4fBnD%m3uQU~Me@M!-T|6) zBHwc8Sl_h4=7|0ZhkZ{jE3zpcd`QIDraHd|+}lttz4z`D;DPst{Ri)FJAv;P;L;u} z8k>Yi;?qXplI9(+Gd6V-%IG~_j4W#E9>`hJ5nqRX0Y1`X^S2FnCmNUw_%Ln;l3q*l zf!1A94(l-YmC!ClNdwYxS(2#ZezMyy0vx2%B!{sp*#BqXeGoLQ{u1p?LBD;&Vf>Ku zfB#sbzM}o3Sj$WpMlj2=dN1~a4cd~Q;9K_;XdatD>m4`1=O~Y2LVC*qg@W^QE7sGj zu!|Fal;_m)n7E7Y^{iDK+&wJ-x(ntEBJ^F#vr`cpLV6;Nqe+A-ADu`6%&-ORjs@(m zVE(Oz8}7rC7VUpUfpsyCAbKte;^;})ww7)`lfQ}2ITjr-G^|Z?Js%!y>o3`a0p#U z03J@Fj~M1k4(LaD(2M>05y^83&qvro=uA6MHtmg5VXRay78A+#;k@mAkMy_RG$x{t z7@NlF)c;O00P@AX8#eV3OmVE*fH^td&tMO#swlrX6?%wkgo%>*z77$6iD2r1t$!KWcv*@U6ygAyZt5$2eFBSP!F5 z7E0_&J75r*V`dHeW(M#!a|hc#gUW6LUl|2?@@wnD?f|SS|IQlSEr*9uc*{D+!e)fG z>~=&qQ@8@OroX8@iMXWomlr0+7nLOwu<#m>-2dE2OsejN1fQ|iA0YfZK) zpqbOI0<^mkw2LuvHSndqdhis37W8*UsXR8~RZ%~ZXcule+}DSnFZ%?)rNbxaH{oZ* z9@vTdAJ$`@xryA@$iGWJ@y&^4Bal`J zTE4ejDvN#;Zv@?9ESxZcW~-TWRZ^uwf01ozz1#Kw`cCanVCGRnx&xz=WR>zaxMvMLe?A zh+oRh6(=QU>apH4<^_##4Eqc=9gIU-7SLqGk7Qy1XdO1z#1Z&`?<|$VQlF0j zOwmEoRW0hJd@(3zG~fytd1UK(U^zgC6gD(Ca-Hl)=Z&0H!+p{B1l0xFn{$t1VPM;V%|6D^*BY0@26!FP@C83)SdY z;lJ0#eY!Occ$7k0XHc9!ygK|JRnh;OF&0?gMDz7ly> zMi<2;QW)VW26d(~^)UfsI#;!3hNN=Lc5CvL!{D8YP^pnE9G}g zz`D4v41!SrFNg_h-6OsoTgKiN%h;>p044BY#26LPpODqZjM&p8;hg~w4E@gI(O>xl zPf!YnhswzZk5Pcf#571*68K9D@}%GwGaN2{;zzN1_K~Qk{3`GfBV^zR?D?Yco=atc z_x~IY34ba5**=^PJL(4BqA`B^V;r|)y!6NXQVDvG!!Jc-SBhA_W5pb&s-vG-w|}J; z#$0p+OE;jC7!EOY6VlY5_l@IAsFQGO6pwFR7@Fm-gKNZi&UNaJF{{sZk13@vs3C4IHGx8|LbN{zeCT#!8$by^d@S}MX;gn=zEby66?M<& zVm#(D6(3_uzytnE+5gy{Un|b?jNI>0JquB$3T0C|IljLf|ASl>>O4X1XP9T+ z+lSPDanPMqKHbSLe`r6YUj|8#!@nehjKfFk-+=6?gL{x<5Ok?Gpi3?NXrw-YxZ77`3pKhql15n&{j2nSXoXx_sK_`J!^&>#&28Y-#2CS@M?>%7(3Y9r}pxbI83d zm*W6^(cF*VW0=47*4xQei45Gv8FVG3C0>Y{`V#yHVH-S%H9`kV{&Ey--)PGwzkTo= zY>ai7(VkrFAE=Z^~;pcjNvym?zUZ zM)fdur3>kk0lUD~Vf~=yu64&9z7;pCG!xt^z~@50rL2zIM)p|P zoZQr(Bbm~!!q3>i>fanLHNG^QHNH7q3s-1-BTVwF4a2$@%1Fh!l@WQtTOMBs8-~`` zzFzrH{8IjV*QaT|&p>-L2cHU@o3Uqr?5;mxeR(_VYhB>8)L(hnJ1`_Dy+y)4o$Cth zJn*TS884H3z`PjdEyg5NsoWGqSM+Vq6zEV(nxrR-^n;OwlhBaU)ib+;*A;%&uYT zZM1G~C0GR7Ux76O7JLk{p05+o`WKZ$_7Cj6#Cn5(J*V;>PqKAj8_#>xhX2mK0DEK; z?2rkxU-nVdL-xjnsiIqgEKz{w{sJ7a)jPL!qisJf#vTym(2`QJQDJ{9>>W)Lk%#OZ zlm~Db4q&gxY0wts9fo|)#m_fKv!Nw(5LShKw!;vf_u_}!&ftu0wIZ?v_{YA*h?1kA z2^L6p)uAQ-1>P?2xf|S+kMhC0CSs4Xp%t)*Xb)K6>^Ph;g+1-@{D5iOQ0~C07pHAY z#ke%!ya905FO}@JFUM^gfjt0H5YAr(vVmezRkI1<5@WO3mbh)X6kar``2+L~!2n~1 z4~7W7x1H*VMLjAy%Ybo?eH8<#&WJ$Nu`zZVgMG}oIFGmQW#r9A{R;vAgLtR<2u6Q> z)OLTJrx(XyFHL00i0{0Hd`0AJ*xeH_E(a1mm!rL#IjzWjOXI2=eRLf>M79|#5~z>A zgrD}~Qr~;fe>aqBZr}P5HuB?GhdPfw`A!+w6rhAo90c1w#y#!tQ==_0t6$%?6ErRX z-XPQ)EetK8Jwlln)5*ep?j6uMGd5yPTtNTe{V@^k5{8v@p^tVH9z)q!sErNT$ z-|@)7v-^NQJ<#_w_+Abk!0{9uR(;|&OqwADCVes;Cfy2ng7vBt-0n!E0fzeL+8A6% zg3lSD`?o6KGddFB>!5W9%ER5)1%BB6HWW`N461^Ac7J?u1o+Ge0sJh4Bjoq~Jd1$$ zdtHIneCRm@1yb8}$d9puzS)OWq0iKC&(cHf1Ryzxq5EWDzYOq@0C~0`zQBg!U2g{d z4aC$ER^W36D0XND6uO^|0BbRPAN3yi4c8{n=G^Z#KEK;EfzOX2o-k4vEj=eaUpUYM ztf$p5-pFd(-|H$=j!y`qwE?ls6ySkR&q8Z6MdH;2$(dvSo*mdYoSsD-)USr_V?sP& z{wm;JG5B2TuV+he`F$$YPz)jtnh;do;v#!6!$=J zB_4vr52nX#T8~lWULElqJ1D}yp|9RF955zRX zzw3d%lAwCOzY}%)vkGWq5B8EU^=e9h;}n=Pf7(HO@j=_a>;I_>Vn<-#zrO$W&oimG zF~om*7={nN3kNG_2lo9bjGzGeJm+&Hc%}yIpD%)TVc_#DLPjMSTQCmLcU=(pVC-@I zw&I@6!08F*7@(4xCx6A4kj^kXUdclhu(vq_p1+p-l|Kc(djs-t_p)*Az!*byq0f2Y z;6D8yUbbKypt%a^!n$&p_GfN}pTU0zgJO6PI~D`K47G*El^5*QV?nHY8@z+T*pQNi z_kUFl@Au>j@An7k`D5Yz$JE06`((oVu^`=XI=sI?HoU)-5!3-`P3G`^El|e*yxpMs zr^5Tsf@=}*b_Quul8Ankd_@1MbVNV6PXf~6ARXRM4fxqY^{GMspf8cL;r*5%%?rvq z!C3Tx_hqO)G2nLr@CWswb%__;Q|ROk?_WKP=r;iA>nA{akarurbwGL^I)@VvkrH^N5JC-nEw|=RjU^W$h6s-_!gT%y>`Gi2JmbHJlg=zXz)F%x(-Ue)N5=P>Z1NcnBg4TIyuHR+*sjvpMhw8Mgssh=FwVQyi>Huw>VV5OI zzhjfS!F3zB-_CZRu+{`@$`j;M|G*|eYt{cGC+}~&gB`t&5I92M2!SI6ju1FP;0S>u z1db3mLf{C2BLt2RI6~kEfg=Qt5I92M2!SI6ju1FP;0S>u1db3mLf{C2BLt2RI6~kE zfg=Qt5I92M2!SI6ju1FP;0S>u1db3mLf{C2BLt2RI6~kEfg=Qt5I92M2!SI6ju1FP z;0S>u1db3mLf{C2BLt2RI6~n6IRan6`6uAatNw@n4!d*U{2_aAP8T?@qaU2h0nS%| zy@Sr;fP>#@vjyiLux-M;l%VqsaB2Lwe2_N@@}P4?l)TiiYBZFm6_pH4ISEe^ zNu7{qWaCv3lMrV(Plr#cOKwz;&&RAsB~7nv!!5`}ENEk2vmqO!p#n2$>Vw`HVSx zAn4xHi{BUnx_3Fj%gAtRfCAlfk@G29GILY8((^>(UAAE&w$Z+dhi41du(IG# zHeq$MW+A}Jd$^x6qs7Pd4tj&S#B~f;3=hWx|9~h!1~zcC^sg5lkl_~u$E>N%{{w<6 zmj5FJ7XLut3_;*%i~kIUWE>4U{p2TYxj9^lU(VLXxEj%aUp48#Ks5;)F6Kw79@v=8=AL%`6@4Q_{o z+j}DsSfm3aD+&vDKqE08JlH=H`#GcRo#7}9XzPPPI{LW50rOu?P##Wj52W93mF=BT zzCcz_GzNpRa|?h}wRb}zJm5Z_psh0+Qp664^+N(-e@X9+v`2e8U~u|EI{h~gI8i{` z-`F9AoP^+jAJQLb?}J6yxgme6j_~-6FC>sX+5?O9z~YnxZGn28-bf76+ZX8oM#ID2 z&Bp<%hT{W<1iJn;WH|XDm=IXFJ0bulvmeqI=?w>3I6&&yxuHQB7F6JYzy%N?FgQIC z_V!2&Mu?0IXE2ay2s*?6dSRT=e!m9D8R_OpMy7UIN!LI}4XTK?a{?f4S>13BRpY3KpvPQ+6S1i9Y6<(ws(O48c!IQ5dc6iCJ?ST1BO9Y4k%EL zMFR!V08~dewBLVa17q;^@dSqWU-@W9M+_1REX@g6vM&-2%n$IBl)zPUL)#;ONkRht z2iw2$|K$rA85ZS^ggYZJz)-*i7*!unCvSuU?(!E~Hyk%lKW`Kk3BxJ&``X?OjX}cP zeLNrlz}x`>xq%r5O;5-ln~Sp0<;d$n}B`*eC|PM zP!9cAL>)-C0D2RYzXKEt=mem0pnMaeAWZ-c$1Ml-r~tJDX>mXwf%GLnbwE8dpecY} z1#||`Oh5$yEd}%updSET0`*q_RR!(wiD58iKxqKo1o`IyZ3SsvC=Kdc0$K#}g8)?p z>2yGiK{@!n9auR?gR{F~Iv_m>=rusM0o@1r)FfaWK$;g&2|!H&RRw&oP#VztfXV?{ z4yZAx{{c`3KxY881auG3o1h$=>j=vPR1;7v$VULm3}_Ib9{_y_XfWX44rn=`;J2$` zMSwCM1Ns6g2xtmuFAL}xpn8DL0BQlKF`#aM?gM%Q&`ePO5ugr$)&S}T^4|g)4Cn-) zoFIP<&?V6CKA=T_(tu#yDF&rc-Z6C49Jt9+&$fp z&|(2rKm9*G8|Py{!X1T$^7YVgj1Ta|zZN_1e;3q$N}!1i91%7#3>-saYwp?wI5~xsRJSe z5bHP~Jy1X`h}oacmBF&@3JP#S{a#BQV5 zArubdUjqpHM;J&s3{2S@?FxkQL;)|Li@-YnV^>gw2jT62b_eJ~SB}8Ye$@f+`M3d3 z3ZU>t;=&>ioXRl6Ke#%8zHwvVhxP&EiM9vs;up>y2%Nk8Z4&_8U)~;=h`lR-(ia2~ zP)G(-{m0Ei-TaCe{*fIM;BE(E6MJA`KnV~8+k*%K*y=Cqb_e!{a01o{q(@=^9}sl` zpkZ3TQb0fr!Whu0J8<(3FavKi7HtnA?_UOKig5FRJUEaJf*rC}z`_yb0a!R70Mfts z{6^U>0E>iUfTsriBmV^!gty)pm=VwiL>vDE&d{KFpgjaJxO`xX{|4*7triG{bNUW2 z-QNn}1c9c`KVtfMgCtH0oNT|D{ZkA<^)H0~k&W^3^hA3@^Z&PGkSe$#{I}#kSB(E- zKBN-X8{vV07(+V|Pc#aIDgSiqh;T;%>w|>)mzUD7^#MeS|7#)KE&!VPxDkQ$N-XHc>YX%J+L)Ed%HqmrUTl~1NK+i#{+P(cgC65 zpKJ$jw5KO%4#Is85LQC#i5=1&0eXVW2N*gM3jlM(`XRi*1_#RjkGcpupgK(D-^REW zI6aWR7Bo8_M@L|A7~JgrcWjLR7u+C;|LFQ#8ZcP@b3F)wf9w2)1Ox2_5sqLQ{12l7 z$2j|7ae(|YiM)|OFvxTH~$jVE+1GVaDLf8!R=R(1iNC3g835 z0@Fl;)&3vY!NdlwaN)2sDEP}8{ZSGOC>U%ffEeblQV+1j`MbmjivX*$p1RSmRm>UT z;Q&?#eLEL0T2OD$Oa}3_9%T8y=IHO~{})dHkUbLYOK?V+DeUD!@^}q9n09)KD2lj|S87$bf1O7Ni0G1znZ1`?hD-Y6$$EL==POay+>2U3Z4+#T(Jas(7K6NXkd;G(@zcDRv(cK(<@whop)GHCPV3F3UP zUHP@G0}Y_N2as!UMB-3#1||e%E!g@%F^2#&qP{5Lig4Ro2s|<{MZjhY>im}i09Pnf z0R8{k%Hjf(U!MF=5txw(9AY5YfLelkB4AT&tf>Y!(pNV&Q!-S8YZ<`}4E0U5RMk}B z97;wY%>h@^Q-wp7luV2@^$p>wT1F~5N?N)`a3vibGSJFUNzYhI%?NI$WvmG|RMSv0 z1oibn6Ts|W#(F9`CaPL`8c-{^7T8~Fsj2?mT3;Qmt7fR8379DvtE2%G_}%nR(o9py*hnArXb7}2GSM-Hq*pi8 z*M;lo8-d#Da1$dn(1DV%5@<>Wa09{`3Bb)X)qrS*ki<&hzY26e3aSk{H8uoE0l1!; zhK`nonx2Xp)TcgFo6K0>5L7e)sNxz3z?BTOjG!L%O^l(|pdw%hc<2FjAdWb=p>Y9H z;QCiH1j_3w;kc^*C;UP%GAAS!Y=Ysu%0{Y!;%EP|d{Jqs^8#>DX=!oXUkT_=6xh4NLwdkP#--v#KO7nBdq|Alp=93D#iSA8tVU%hj92!6x)pBGgB zCU`TZ9UhAOSNeh~m5nR^JIxjcHa_5m zPw-9J!jsM{bv)JWT0}WHr4%C7o#!r|Fx465>x9uyVn2>KUa@T=R)%SGh@Bix;_%sP zUKbe{6iCzSbsM-{;O5?K>f&Ui?c(SoqjyIZnmt4a2J%vA-g}RTt$UR3!hh9Rp>V}>D9@F z%%I?>ue%3qUhZ7j3muvGUOl%MJXo?tHqa7c7u>mQZ+ELcY@k>C)7gl*GL-OPnYEn7 z{=4nK-uDWOJv4 z2@-~R_Vu%{cX?~DAu&TKm=ui7fYOmVHLV9`VHC0v5Q##qCi}Ib=y!S|_pr3Gg{S?ulACgbZ_^Lv5m$>^EAL&` z6_grIK-5w8(B9W_QpogmBUhGtkZff2P1W-%Ry{r>Pt8E0X_>? zM6FoJgwm9*WR~Bm2;IY1YXS}LDP!7$!v=yCrhSG*q8<2TFOpJM!~B`quLZLBI`s!h zB{0k+CjfVe`D0>%q5XFSp6Bi=ZRsCC;5UhR<>lgMLFM< zT%)8@sORzFu1!aAVF>En?1q=(zG@g>N*HTAO|?>amo^&nZ_V98@|IiAlN9isaFXL;)j6*Q@P_YklT$3Gqv@K?3o8Viio&LGY-nYx)(t*xNl4coXr z=89lwvWGGF*?1izS+V_5X?c6|TwTMEsD94bj8NtIy@GGqk>}{Nmizdd485~wX{)HK zh6bzpTCDb*633ma0@ozmKeYJl6KJYU@Zm^cl&m6TRRs~>FUw_+t`l6pw*5k?BTW9i>L{`xCuHGr+ z5o&wGeQC=sF}K8{@m{^$t8=YD+%KrUEaZg`E4)=NZsmC@ZI`I-YwM5UE3SJhJf5-H zcFtcZs83wm!K11tGIY9rnOkkor@EsW|@!8i%JtLob5nnzrobU(`E$DQlI*w^h55me4LA4iDXK~ zB_sEh`iR8V1dd{Q}tc*%#H%`E9U?-X}e_+2sOy+`+7Xa`0`8o-iN)i0!F zMN?kkU{Bsui@oaAKX>di?T=^kb#P^o`Q9)ZgwVTySjF$6wWq%h1_X?l#>BlJRJrvo z_3C(P8RKLAfCnX6k-KtUJLmMHcg>Fvpyr+6;_r5b@d$<|xq7UVE-x8)+O&mG?2L>) zKdX8eAITWUgRuVW0rQJ2H8oO%xTL znl|Z6+EA{zIrFQJ)3#}LOj?Q;xRzOy&CiO-9z(&AdfHd|?;O1RbjQ>*B3NBJU6KSP zmt<{@{~h+Awl_WPYFc3(Z#9X7#~10d?^Vh@hWdI-C76uF#NoH;(yHQ#rxxnMW665P z^2ZVSa#tx-SU*Hf&mXVK(X;KXzLbC19YEqjSS(DCMm`ZrS8EvcQas~|?T&mYoh02y zmD+9{!GkfmF9P9OEelh$0Pl+#ZJP&wv42mX~XFI-&^` zQ8yw@@_KO?t!@-$FMyAe5|iwU(48>sgL#&Dtpg+ zqmbG_xg;IYKV(qu(y`5Vc9qiQh4cWicP{xoI<1fHZ$ufsc;2#maW?(xjfb2KRCz+| z7zBlTT3I8pKlM#o;gGaawny^Ok7%+^R)&YVFNU{wljKs-I@Axd+iBc>{l1K0K&D`` zMoZr#WXfKFGw&sQ;dZA2e)6}9j?Z|u?~VyL@ANe)uO^bW62EI2e3tu?eKhkYwJs-Y zhXkwgIQMN+G-(aF_QKpN#t7dnnv|i2#o8Vvn!U3h9=%yAUd^QNbaI>EFt1FL>P}KD zmzDce7o^1TL!Kq+tFsHOHNSc&^M0l^Wn5&{W%4+-X*(f-gJTQ{O`jFK)~E&K+oD)b zn(mT@w{>)cVegK-u8=R&9p-bRt2|zDL3PqtnLOYUtF-@U9oZsRV9Yp{I7$@NqEUhn1hu*oMK8_z=u*shiYpUiz!_QB0GlxH*0U;V?#v@PE( z=e=(p=FZhgeY`RxMhf-EL`e!fIY*{-?1qTUx;0w35oflkTTTxLqr*>LEl>EE!ofQ) z#*>Bj_&SvpZMk;cqfxCK3$aS>Z>o#WX}*wpsOHVtg0mUm^<_M+B5CJO?suh zv3xzaQ&+ECY!<_PCM~DtJ8zihZ;*Y!&z^A9)<3-J|9x-R)}iw_XYt!C`NhcNd5ZpY zt|SjmkfL*xJv-Ubi{b%`}5k$2^AX*`&LqCifq4q>qtzScAV}^)}ON*`Oi%kn>BFeZ& zHp!DUS*w(>G>>c=JWlxvCFcqp^W8Md!1Q7K*U0tTOJ(xvTN*6ylZ`F8)pV3$pIb#G z6fAF&z#j|#Ox3h$BPHfI5m`^#GN}=UEVF}gE{P~<3|e1;^&3B5Jwd#+z~`3Ypq0Wk zGxa0`wh=XP?Rzyp(_sW`4sM_;Y)1Bp*ZJCj>(`hm*ExDiK^83^JbL0TIXAJG_r2F+ zm7Y!W`FBa{%s1E;$ z4Yl%$l>bh)_s(H|Y1RtM>{34+PI~k7vTz5K-cO6{`mEQ|zGn51aVnL$ zh}t&XjtEY8c{2BN6z6+w$_cf-vqlbq=YGDV{WjpCFj6N~NX1LQH~u(bg-dwc_rqp4 z;rjzvA0ABp>Vx}VSpxBY7;ByHB0VkVCYVIwN)uctZ~5FfgHq{E#HkNlLR$a~l|td=08iA&yU4HAHi&S_8_2>1}8~T50E+oDb4bd>0~Y2Uj{c@f?*SNAxo0 zdx*SqWks6m+=+M6)u?GGm}hYA_;w?@`RpQbD)wx%3^C#p>5|FNjeD;j?`o2#O*|eFiMamJ*}IS`s;ukO)q@(_ zo9JU_DS``KJNLQbBEoXm=_%JQT1a%vs2XtulZ)skISafHpGCh(Y-8fek0uC}l8U1( zI8+zd5DCjHdHU?mpmE${;cjZQLC&YsQN5ocTCeH{F6hI_24*L}pRSzoO-UtXyH!qT zuTv`dk(!);tuG6{v?lmm)1T*|Do2ia)i-@IhT>uplj)#cTUR(^Q5-?e*6E$7u1KD3b@M(Nma+?8#+ksv{0zjZ4yb<8*3f4RP_ z@ftPNvYYY+9p{G%Z(gc>U=%iv4Ynuza^Uy~UX_r*OOeAc$$aDN)5gS@_h+6<(y@8k zyT8*UrEg*^NO(ehELY^Cg*Cr_S)zf7d2L2)^wnUaWQ8|Hb zcBUZyuq0L}O;yvTk|?rbIb})88KGG&c=F>&&T8CAp}?Dyd2J_d+J@Pe4zN8VV6sbO zX=Y^9y7cOk?P&uE-is0q<#lo~H94aFmnqF(<|v_D1O$pkU^g;eC~~X^5B#Vo+;zIP zRVXPl_i5!p!10p;!>OZLVUyb}0p^^T+S?hE)NVJ$Oq9n$7#N$S%CFQDpF-i` zy@o}{IDfV!JbdqH^m#*S3mhJlq&bm#eA1-6RYKrxh%|z z^jucs-reZW6@~usaXepW=G{N{`FSP!X+^NrCAYE0Za!+BrvCxcNDECgvY+bNeO??Dy9;@Y9Ay8HIP+ zybdNpi{hS9i{=4EY<)_RQ=%i7LQbeKYx|uFl0Ljs@xP+h-?D7?W-HKGsvY z`>6L5YJ`8kqrU!X{zEO!07)$+dtR*6>AmEWRXK}vcI&5Iu`zsq5n}Z(-DqQ9QpH9jz0BKY3x5th3i;UP@{ET;@xsifxtocp2MG z??cLO@~#ZJZ;Pq7F28)Je|^z8T}5S1LxnrPOtSXLd7~wGPYYp?>~6%PUEVu*x;bGeH0^+3^Wdxf}G`)TjN)sip6 z!x3KLF7*rYy6%IE>c~{WAlT&8* zrtCwM)!U^zhWN+uSjA=2S&bF=>7H)7`l z$~Gf@tmO3e-Ed%wu^2^n4iaJBqn|bzE-+?_u+hu=qL~}-GJ3qj_(|SJq0O$r!#Dd* zu4D3-rh==RP~lzeu&{(P$=teRl3v)Vh}~udB?Wcb8Vo+?9Bhd6u3@Hrc;}N`4Sb=e zD{WVtJ_WJmu8cn&O*<|}8uv9)BQ|97GJh-oa(#8se&@{Zq2)F_bU2D zNG?~XlcjQLD|Hds%=%|1=I=3QIzCRM?W3*jPLbJV$A0~QPbJ6wV8v+FrAn1ZSo-Em zg3u;{Il8Wm&LaH<4~~hU$6VF1`Mzn30SfO=C$A*5`psdzZUonaY|wx2X*x7v>TRan z7Ms-0XXhj~@;yZnTQv0UHlAznN$uuj^`sqG%!n1kM2Y=A-j9{Ow3gHieewHsB==Le zPyZZQ9TnZPxW~bOU-E;Z6Fr@O@Re8h(51_x*3jX?>|NeZTi?R#+gyVwEW30+rWyyZ z&&K9Q&y5DGvwWGK4feiEp3#55@11K(m3V6&MQD9--WKmy;!%cW7i86F`{2c7Cpn5jbEeKH zY#I&=XOyT6RY*%6R!TiR=TgT->n=>=tZ|GB-8--E-eoJ=dNIZCq^N3V*x4>BhJ@(t zZFcnl)Qm#Q;>+IKy|zE!hO>P6TIlODx#QGfgP+xAcVSymhd(1CM5uX3Z+(J1b|+OX z>x-atr%@Jt!cQW!dQOH+P@1Naqww`hk=4Q18ij7mn9mkgd)*YC;_&Dq6efr=EGRPr(Y2l{oT*yYuljI5WXEtdA@f;n#54*2mv6--$2%gGUwJa^@@b7{ zC8`$4l1OUbpY%q_55MiH_M-hvHn&J;xQ?%ENb)}SR>FumVMgPv_djBG4CkW!KL3nV zcsP}IUO6ac=i+^x$CGVf-SD5oYs#}tdpddU>w1Ys1_g5Fx&P>`%XTLX`95jqA2{wR zMSkeo-p#*$mB&N1XZ9Y)S)3O-t1sF{Hp%ObbVoQ#w$Q|lODRPkmy zWwrmE_2gq`KZ`}7_$h`OrNgb;1@1Cm(bq6s>*Q|VIm&W_@}^M3%Wv@uiNw~WTIso+ z8b!{O91kjx+>niWY-pW0r&zPkxI031LA1tjlh2BBQxBW$yK;-yV)0^H82Lw-n}eFd zt{SqBH!fg#mM9SG}z?zj@}*N z!s!j8FYG?Syq6BtS+up*b7bW2aAupeTO@rEXWWoE>rW|n!@Ych`}!<@+d5SusW`JpvuCr^T7I3UHJosweNKd<(5S&0W;eaBl`m6#=< ze{Pei9Z2M^VOjK&vxfWrEz_qP%c$8WL{7%1HPLSwZ;9U&$sow-98lfoA^FC0S%IVR z<+W~tu=zG|jeU*)3v`ZpgUgBi%;*8CQ87Zhn(2MBtf`-0+2(#cwv6Bi>I_j}AcXEVDdQe%>5>HTi`4SZ^C9X!#8-mm=)Cs(u zPn0R`=3f~S4QSc2{;Ctud`t5dk62^76s7cyfhgV6j&B4`?)Q7V%T|-s6}>~ulF`H6 z_kv&Qcwv0}nV8w}TjwSNdPF$p!N##W<`e^~M(CpYEiUaR5nkNge(fk3%(8}j+c?~z z`|ANEMkmI#*$C!yu|%ZaUVNL9OS4^r(6>#OYfO~JS7w?gilJP&Ew-59|>p|12f&=Y&^L$hI;Vsd5EaoBjTsN=4HQ)c@-6&5e}l=v$r<`HgH^B~yS;~$`n}hdPU2ODl8Q1s&y}E*_-6S{ z(zoYWKiQa3+NXRf%JoQu@<@*TB9T`AXPu3~+DY(@Cd ztdsJmeZ!Uo*AH{;kEd^rR6nE?X#OcYOj?B)Gym2aMBej>7sV$?|8C@X;$3SGM^TD{ zA7Vc$-#yAbmo8i(JRr_QMc}KjIY=Fs*(rVj>63F%_nIo;HPs}COLeqta@z6ssqyQG z08{q3DgLf`DFPd& z@ZL?OhK`@p@$m_83k81%pBM%oe@PUH^ziG-5qkMUX&K*`yt=o2A=eW=c-|7{40#pz z#4p!X+#%qkBuzcZsNcRkiERnmu7se}$k)+5_=oKo@1e8#L#LkkDh#F+W&L@5r zxF~%$N|utL`mkqE?^-)S1O1xi6Z#PnW@!t43YtN?126o=6JM`g8>xwvI5D*+wk(<^ z(kPMP5dCWX(RS`!V1GjQcK6-}TeM&B`dX>4t?h1EX|dXVnWOPqZ;8sMjRiF;`wNLo z^5TwrW$^cE^Tb;SsaX{Lz2lP+edW$;&PIK-!#_#f`L1wWp*^*H?m~fc*WBZW&oAGP zm!$hfSx#QAQ!XH}?LMP7n;g8|x$$IZq(-z1HB&RJ$Pd(6xrqN>y-;)IrJq~T&5P1CYMp2pNWtsvP5!Px~a!}&Yjas zYd6&+pY^osaS)m?u;i4na;sW@9@DWYk>zQlxnQp(^v9WvWZmpf0P~{Z}r{Jv8)lZKHNkeq~j!eYiIW zs4{M7560g6cEWVez1nQG>BXmJk{jGg66sxwNp znVkEp%&L(uST~M@_s2S!x01!o>?cSsjqAr%3Yy+49-~mKDE|1fTf#OLqlce28#D&3zt zdSA;mNj>#^!hDXFV)4dnKA!2lZB0q$?D@@M_OxB&sJBK=1+>p=-()K&6H}S z(%&MJaw}Wi1%Kd@=hJG zG)Q{f^Qm+ovSoSgL)8jDuYtivVWtU@XKirp;~JMYDH=m6r6R(ss+TOy)>mEDj;VAm zWDC{A{Im+z4-Gv?ezSSi>;3VSSa{Uq$9?#<#ZRLLnRHy|^PkO`SS-ACdoVzGk7f>y zSkAD4%h-BXuCpbUwavn3H4u?LW-2rbD9FoO`6?#_F9J zY!`S|CB9&`J(^xHHl?TU(~{vyI%Yq&fQ4l@Q^exwu4%hwXRaeTm}pyE(MsLR=D*%Po>V!Tg%_C-Dw=CZ2J}$LL;>>=YHusWhhc& z#-ZLiz%0yYIJd5Fa``;(icwogjFbM={z927)-9_GdOsUjw`!Y|^AZvsG@iV%`tSkq z9lxxDFxIV|<6D;+R}Sl`9y{~@*daP`kj7iZE%07= zrZ(tz_sD`9@EdcQgn3uh$o5mH1K7}IX-rV4`uN<3=?($7~f#1%>=HM>+) zkE`iD^3ag(KFd?VdS+vxg6cGdYd2NNl?v87d7ZYF7H;_!CsQJP#qK4pbbBPc{vvvB z%~#w{Bb@AN_a)XWRuyiQTkh_Uiegv0s+=}yR4uAs+p}-0r>s0HX}d9h;h84dOyeH2 z&-W*+-%@O>S728j?NsqjA`4%XGQ8Qz5ooRzud{3D_L#VC*mtt6-1uR6&*aSJwZoYq zQqOMB&_7TM`MAA;}1Mh8_J<(d7o{8q-D``F7%3^8`#B4@A{MfZ7K zH}Kqnkip>W!}W(BF)zDG&SxX12U)YJ{4~C?bvM?8eX5#VMvWaFd-Age^>Q|CP5-%a z%Qm%PmaIutbGX?^*$~AVydW^9V)o22oi5xR2KQ5lVwTwf}K z+(`7Fliolw6uLaUkt8)bA?4Lz%hpr3^h$lHq&v;c@w1_#6>p9GoZJ$xTLGCSCvB`M zN1|rVcBRFrU?u6}{f-OUSI<)Qn=a@io#Z0Q3R|k=*85yt>?x`3ANb)y^wMDcdEGe; z;rMaS1)`T4Z?S`c&9L{AhZ_o6O<}%sETZ9#tLW5i%T(@qA??Th1-~o*(jIo>x&zr3k4{UUy6H zA*ojf0`;Cg`yTe=;ce>;|4&@848#HyBVwO)XYto`Qv}e&VG$GcB92DFTK4D{I?~#6 z)-6e%sS~oIPU0P1XMC=nh)eaN=gu4t`kIMHen621H^~&|RhSdaE*f@UB0QTdX-*&G zH<6-`SDV}-Y^^GDY(0?HDWl`z7UbAyd?Tsa4|_g8()7@Kjp!7mCyMYGcD!#U8ydDIs3kFFITZZnA!5 zaky?KS;Lx{xz&5GZ|c+3O#U&c0XoG@ORIR|!*488BsYZwYDnVD5N>JFzyUHv5o$5SweXK6~FW3lVi@reRtUmInkHoho+ zP#KTyA~dAnaKA{RGWA(4dm+r-@B8vf()-4rC5?x3jfdjRP zD>c!OuV17R1LK$z-@>@5TzZq)9tTH@BWA|dXG)4NRfnHPlIz_oJz48sd*gi-vEZDr zsZJ*u6EVNmoDn0XLSo!nu@L!JrMcfD!sj8S%ief$$?p|hE3PjA4imjj7(z%EA{H%E@Og=0 zICZ)__tdeO<0C9#YyE2>OL@WMbU|;%v6%u7d2b?~v5_Rcb8BgQ#;i=>LC4tYu~aRU z-)8MOw>$AcD>G>zQt7h|h;Ld}tlLpZH*ha=oy~R{Y_K*Cuvv@-j46nrG?k^9=VRF2(e6a`!3u zS(%bxLK+7S3I>u%_iH5ePt+J0nD+epwB-ELZpiZ=zLXiDxV3tTxE>@1S;Id1% zt!W-QO;2t-N5Xei{9$BR5{rQOS@ow2H*~(`cG{oXxKa|+oEnG3!M_3@2&{Nh`7V=J$2?5;93H4OLmquU~>BI#(q zJj)3Dv6x4_O1}NWF*tO9VR0osgRJ!D@p6S)$AytE-M0Sj2*%7?v39MiT{?N^1P_=U z7_Ac&o+u598ch~{c$V=r?Jm>ALHF*DZ(l`*$S%H)3ZvOxACJ-{$p75G-+MdIIlo~c z;abJPm=00VD;v=*9`UX546Hd;=49!`6>Rs+`BNV`0&@CgPj;gxvo}l5elNW}CdipU z%(D`$={MAJVaX=T8u7N)^z9`f>xa}!eqtGmjeDzacYhA7Vq0qzE;JAH2v9Q2Ob3#t z!ao_w;{`Qaj^EUOCM0w{VfvkJn7{aPb`~XxGAX00Liy`n*L~@Tm^>TP@~{ic@fsk& zDTzMsa^E;MfTYj&BhRgisw**0=LzP8y}!yulP*2hpuV4Vi}bzyb!!PRJ?l)XK?RAC z5(?9jS0&lzKUD}!19$hXD_u0@DcaNNNK@0KkYV1`->KcYG`%DJQ$Aw0V5nlS#E*({ z*ob&uemTrzs{eWYWVDaNSyeOe*aAMyok$s1Zgq0$DJ>)IjBR=m&_zT8F4#`xaX+=!5~+exw*Pw z$JBJj${2SZ;hOXnojmh*%zQSpW;FwgdVPyu$vDZ&YQ<-I5MOYURkKkF^^1QgX<%NHT-E(evQJf9^p5+;so z80Oy8-pyZQ4#oE)8y+bwbB zVtc|^^gx+sYs~VYIx4t_;BANQsmkHlwlY@NGqZcr9r#y9WMwHT%T$)G2h`joh#oI4 zRI)RwA+#jI#(dJ z7)oT?#f7ytpYDEi>^6Z;bkFrgtz`Fa?&oga;1SW+w_RUp(z$=x?K5H*n zMv8^Mln*)BXfiq#u^xk|kEZ%GGn`a!IE@bflY)= z9izn)srO4xUsvpF5FT!`Cz!goCKuszFeI>X&qR8#J9J*u{GOGrn${XaSlHXk<3cZX ztWL>Xt$x?;F^3Uve@ilQkJLcyLBxPw^1JYNV&^HiLKK&KC|9E|lq!g&Yx@nG25B4o zP%H?#ePd-ZB~v~;c8Gffo`q+m5KG%Z)Vpwzq%iX7rv#GEAEg~BFNe@A$>ls5xa(kf zk?BRx_oDP`y(to+N!;lvtZ80?_;2bt=6cpM#hIcB6<|v9rZ;_kOV1V;b63>f5$9&T z`CPFcPwc?DI}*@~cHZIMmkGQWW=D z72b<<)7$m$`%2s1Hr?63VI&+L>$wy(-{?*D)gT~qa3x2acHz>(xm-d-dKqDsfIm+I zm-Ab^9GOdRG{&P0A4!!>sOgb3p*~F)>7SZiO%Eo&Mq1OJH{J3eoWv-n$yoR5%Z^g5 zWTIPjzQhAqZk}5H7bl7iB8V$)y(_yflZED0?jp9T;>WUAUWF;j9>Oc+>mz%dU)-fz zyX%q88UMn9e2uw;X_ixNXomfHhjw#T-5urAwbfctvRaIctwGMz;kW4ucE=8iqGb(P zYbn%U;ceJ%Hp@C5%UC4)!IbFP>Y~eC`0QQWlj8?9B2*uS$*&OE`8BpXzdvCJdzu<> zLXDzAACKOB?}2vP3|_wNowX`!wuDFnPdho{{E=Y)j$0gQa)vKHE(m5n%}&BA@E@J_Ep8fG*5@8-5e^#XqaE;d^JHx|%R^I%8S?gv z)JYxT&emDw^chu(%qR9W?ht=W%|Dabe!SYQO6jB>!Kg3IgqIap5?9mRyAAnT1${ri zlNGmJzPb~slKK9G#7NBAK;uH{C2hEN#-j`uk?Qvg&z;)Ue-Qid&wLp;UZ0I(XZK+; zh*Lcs6UD0+<#Ox6jsB4L(xGk~3`tkTjJOokY6bW*`YN8rd)^>Sy2BM}iPTEGIb}m1 z`>;3@p(gH^pLM*&NpzfUR))v$;t6jG zKfu0LZ6!Nnqn^ArJ~~d$9(G+y;PAOYiEsJ&wW}Z1E4p6=g_7LIB;?*`pz^OOe8B8Z zD0u4u{=l``9u{hTY9h2oDa5uj9 zpss|3iv}TfAA=>WU>sE@%NoicN{Z9XwygNBdaB8<&#Pv}k~MoK@-hL99{Kbq{RFc* z_Sw;b{XG?@mD7fmrx%XB0O*=U^E!!IAo>5nufNbQ%CHc`G6m6Vhw^uZU$P^ z?Az#?YJ#Qi)2}XCUPu+LNJ!Q&A71LYVvYI_k|yZAb$bLG*-l66cLzw%B==qlB3|FF z>sH!c)a^#aribb+7q?eBN0K7FAf?zH2aWJ;<)>4+-r|J#0jn}ujK`YQ_1YqdKc%Dn z@w2hpIT*X$@$=>%+n+MMQ~arU$>dX-tkwb@;Rpv)H(aLCGEKxtu7s_{HCUzijkPeK z^FjM&CIz*-TWokq8{_0t`p0(DYUU&4*Lpyc;9=wOW_rOUtt_?xN2h2-Pj;B?2oXcD z%!jh1xVU|u}!H5X%_gaqJe{O&GF?0k0w^!$cr)Q)Y>u3JX%GhxApIl@;t0SQ^r7#TEHFBs6ovye6$>97@6ihtJl zoV3*g+G<(ary@L8S1KwpD{0EI)zpeOwF14Rtj@rN&0UF9j8FM0HF ztEw&ej@pFl+}>~a4rP^j-XGOg)=3Gfky1)dJETd)Y+{rbuikW=HYA#~N}q_R-_ku5 z;pd|qF&6232#m)v0wf;9A<7x!x1wr&*rO`gJ?4LDmZg^VYle-A#g(GESTm(%lR}~4 zvnt0rohHHG)w*qA&xuW0gT#(J!{XI53mHJl7^senhQI5a|HT5KO@MJAtYNMsMl0$ zYFS2&s+K8q-@AP?iky3UYUL075gA+aBODw_)Xc}yZ1e9&mJ6rZj(#@^8HlnCzkbJt zl-56@v!o5LkBGqNQO`Q?iC)kHRTVWhT?H7iTFkif;&kB!P4VD76d@eiJ9R;iH)UXk z4C$B0xES|mVhLwZpte~gdU%!iRff3-fx8R5^|OjBGq)d~D! z7cBX4ZmU6-6Mtds8)u9cM*t1*&7T#F6PU+Z8m#vfer1j|Bd37S=*>%fk{ctVQY z{*A)ALGodpl}o9pwI4;W1RZ(42aRFVkSFM!cYHs*XT$d&n7srp)=%MVSid}_*#-NsAY7P#NjQFS=EE&Wg&2rW`(5w>IT9(vo#{q47GA8Adg z9gFrHl8sujqdJm>cRZc}b1UhVZPX-4fzXx8{37WU1*?b`;EzzB;Z*3#>38Jbn;{S_ zQLBK$P@DSZEN>kuok=f=Ji#_bn-+c5h0rF7)lBNj$55∨aK@&B^e;B)Up6LP z(1S7N7@&e3fRX8-*QSl)KCi|8gx@YOs+D-|I}ziKI~UtI2`ROuRW{>l4^pK zL5@>Kue|IDwhB%9^rY3>YBrpiso?-}<$t4Sb-lxBrB z1?`wF+EX&xq>z>L9py(MnP#D!A#tZuo$;ZYPOvj-*7m475AhxpKXmZM9okmG?M)Pa zm`9xj7&AEMiG4@(^vP{UIsm_LpgQ=UfF*^V)H_Z$u{eRt6E@-LJ?B9tRCdIcTzr{`L5Jc=k*GW&raJzV#vF*Ndxn zqcUTp)oE&nr-%d+!4C#IF}SD}d7L2uO30-}0i?xlR$8Uzr=kk|b~PfL`8h_PNGj@Q zRl$yy$CrwfwOUkl92G88pVnqz*0{DQ7$^~@xwDZ8ldZNyWwv#tqUG0{I+?;GP?XUy zn0dF$7&^s?A{0~UMMwKE3vv+}r$=J&`s~BtREmTYkmEHPYS<9Ce(MS8!ow-+;NR!q zX1l_cQT0fZTBUV! zX&5nqAsqLd!J3ESBw#qEe1R@|6kkk%>UoS?N*_suHR<<`Br+R!9%u-<3@LHvK8M-l zA∋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 diff --git a/build/bootstrap/zipobj b/build/bootstrap/zipobj deleted file mode 100755 index 019751ea1dfdfd392bb7c04d2b25bc30cd384d1f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 522122 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

    +xLDcFnBeguOld7iH^0X_X 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 CU*=~3 diff --git a/build/sanitycheck b/build/sanitycheck index 7808571f4..2ed283ee5 100755 --- a/build/sanitycheck +++ b/build/sanitycheck @@ -31,7 +31,7 @@ if [ ! -f /proc/sys/fs/binfmt_misc/status ]; then exit 0 fi -if ! build/bootstrap/echo.com -n; then +if ! build/bootstrap/echo -n; then cat <<'EOF' >&2 ERROR diff --git a/test/libc/mem/BUILD.mk b/test/libc/mem/BUILD.mk index 44385da00..ec48d8263 100644 --- a/test/libc/mem/BUILD.mk +++ b/test/libc/mem/BUILD.mk @@ -85,7 +85,7 @@ o/$(MODE)/test/libc/mem/prog/life.elf: \ o/$(MODE)/tool/build/assimilate \ o/$(MODE)/test/libc/mem/prog/life @$(COMPILE) -wACP -T$@ \ - build/bootstrap/cp \ + $(CP) \ o/$(MODE)/test/libc/mem/prog/life \ o/$(MODE)/test/libc/mem/prog/life.elf @$(COMPILE) -wAASSIMILATE -T$@ \ @@ -116,7 +116,7 @@ o/$(MODE)/test/libc/mem/prog/sock.elf: \ o/$(MODE)/tool/build/assimilate \ o/$(MODE)/test/libc/mem/prog/sock @$(COMPILE) -wACP -T$@ \ - build/bootstrap/cp \ + $(CP) \ o/$(MODE)/test/libc/mem/prog/sock \ o/$(MODE)/test/libc/mem/prog/sock.elf @$(COMPILE) -wAASSIMILATE -T$@ \ diff --git a/tool/cosmocc/package.sh b/tool/cosmocc/package.sh index 0ad1fc091..2b97b477c 100755 --- a/tool/cosmocc/package.sh +++ b/tool/cosmocc/package.sh @@ -88,6 +88,7 @@ make -j64 m=$ARM64 \ o/$ARM64/tool/build/package.dbg \ o/$ARM64/tool/build/rm.dbg \ o/$ARM64/tool/build/touch.dbg \ + o/$ARM64/tool/build/mkdir.dbg \ o/$ARM64/tool/build/sha256sum.dbg \ o/$ARM64/tool/build/resymbol.dbg \ o/$ARM64/third_party/make/make.dbg \ @@ -174,7 +175,8 @@ cp -f o/$AMD64/ape/ape.macho "$OUTDIR/bin/ape-x86_64.macho" cp -f o/$ARM64/ape/ape.elf "$OUTDIR/bin/ape-aarch64.elf" for x in assimilate march-native mktemper fixupobj zipcopy apelink pecheck mkdeps zipobj \ - ar chmod cocmd cp echo gzip objbincopy package rm touch sha256sum resymbol; do + ar chmod cocmd cp echo gzip objbincopy package rm touch mkdir compile sha256sum \ + resymbol; do ape $APELINK \ -l o/$AMD64/ape/ape.elf \ -l o/$ARM64/ape/ape.elf \ @@ -184,7 +186,7 @@ for x in assimilate march-native mktemper fixupobj zipcopy apelink pecheck mkdep o/$ARM64/tool/build/$x.dbg done -for x in ar chmod cp echo gzip package rm touch sha256sum; do +for x in ar chmod cp echo gzip package rm touch mkdir compile sha256sum; do mv "$OUTDIR/bin/$x" "$OUTDIR/bin/$x.ape" done From d3167126aaa7a7e5b90fe57bf0835b26bffba9db Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sat, 20 Jul 2024 16:43:48 -0700 Subject: [PATCH 062/405] Fix regression with last commit --- Makefile | 5 +++-- examples/BUILD.mk | 1 + examples/helloplus.cc | 6 ++++++ libc/intrin/mmap.c | 11 +---------- tool/cosmocc/package.sh | 1 + 5 files changed, 12 insertions(+), 12 deletions(-) create mode 100644 examples/helloplus.cc diff --git a/Makefile b/Makefile index b70197109..69e141e25 100644 --- a/Makefile +++ b/Makefile @@ -436,6 +436,9 @@ loc: o/$(MODE)/tool/build/summy # PLEASE: MAINTAIN TOPOLOGICAL ORDER # FROM HIGHEST LEVEL TO LOWEST LEVEL COSMOPOLITAN_OBJECTS = \ + CTL \ + THIRD_PARTY_DOUBLECONVERSION \ + THIRD_PARTY_OPENMP \ TOOL_ARGS \ NET_HTTP \ LIBC_SOCK \ @@ -445,7 +448,6 @@ COSMOPOLITAN_OBJECTS = \ THIRD_PARTY_GETOPT \ LIBC_LOG \ THIRD_PARTY_TZ \ - THIRD_PARTY_OPENMP \ THIRD_PARTY_MUSL \ THIRD_PARTY_ZLIB_GZ \ THIRD_PARTY_LIBCXXABI \ @@ -456,7 +458,6 @@ COSMOPOLITAN_OBJECTS = \ LIBC_THREAD \ LIBC_PROC \ THIRD_PARTY_NSYNC_MEM \ - CTL \ LIBC_MEM \ THIRD_PARTY_DLMALLOC \ LIBC_DLOPEN \ diff --git a/examples/BUILD.mk b/examples/BUILD.mk index 5ebceb991..ff8e97a79 100644 --- a/examples/BUILD.mk +++ b/examples/BUILD.mk @@ -39,6 +39,7 @@ EXAMPLES_BINS = \ $(EXAMPLES_COMS:%=%.dbg) EXAMPLES_DIRECTDEPS = \ + CTL \ DSP_CORE \ DSP_SCALE \ DSP_TTY \ diff --git a/examples/helloplus.cc b/examples/helloplus.cc new file mode 100644 index 000000000..0cae09b15 --- /dev/null +++ b/examples/helloplus.cc @@ -0,0 +1,6 @@ +#include "ctl/ostream.h" + +int main(int argc, char* argv[]) { + ctl::cout << "hello world\n"; + return 0; +} diff --git a/libc/intrin/mmap.c b/libc/intrin/mmap.c index 267f16742..ac4ceeb5a 100644 --- a/libc/intrin/mmap.c +++ b/libc/intrin/mmap.c @@ -16,15 +16,9 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "ape/sections.internal.h" -#include "libc/atomic.h" -#include "libc/calls/blockcancel.internal.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" -#include "libc/calls/state.internal.h" -#include "libc/calls/struct/sigset.internal.h" #include "libc/calls/syscall-sysv.internal.h" -#include "libc/cosmo.h" #include "libc/dce.h" #include "libc/errno.h" #include "libc/intrin/atomic.h" @@ -34,22 +28,19 @@ #include "libc/intrin/kprintf.h" #include "libc/intrin/maps.h" #include "libc/intrin/strace.h" +#include "libc/intrin/tree.h" #include "libc/intrin/weaken.h" #include "libc/nt/memory.h" #include "libc/nt/runtime.h" #include "libc/runtime/runtime.h" -#include "libc/runtime/stack.h" #include "libc/runtime/zipos.internal.h" #include "libc/stdio/rand.h" #include "libc/stdio/sysparam.h" -#include "libc/sysv/consts/auxv.h" #include "libc/sysv/consts/map.h" #include "libc/sysv/consts/mremap.h" #include "libc/sysv/consts/o.h" #include "libc/sysv/consts/prot.h" #include "libc/sysv/errfuns.h" -#include "libc/thread/thread.h" -#include "libc/thread/tls.h" #define MMDEBUG IsModeDbg() #define MAX_SIZE 0x0ff800000000ul diff --git a/tool/cosmocc/package.sh b/tool/cosmocc/package.sh index 2b97b477c..db8f36fa0 100755 --- a/tool/cosmocc/package.sh +++ b/tool/cosmocc/package.sh @@ -48,6 +48,7 @@ make -j64 m=$AMD64 \ o/$AMD64/tool/build/chmod.dbg \ o/$AMD64/tool/build/cocmd.dbg \ o/$AMD64/tool/build/compile.dbg \ + o/$AMD64/tool/build/mkdir.dbg \ o/$AMD64/tool/build/cp.dbg \ o/$AMD64/tool/build/echo.dbg \ o/$AMD64/tool/build/gzip.dbg \ From 30afd6ddbbcb15f931a934b973cae621bf2644c6 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sun, 21 Jul 2024 06:41:30 -0700 Subject: [PATCH 063/405] Improve multithreading --- libc/calls/sig.c | 2 - libc/calls/sigaltstack.c | 4 +- libc/calls/struct/sigaltstack.internal.h | 4 +- libc/intrin/describeflags.h | 4 + .../{pthread_unref.c => describemsyncflags.c} | 27 +-- libc/intrin/describesigaltstack.c | 8 +- libc/intrin/describesigaltstackflags.c | 30 +++ libc/intrin/maps.c | 13 +- libc/intrin/mmap.c | 3 +- libc/intrin/msync.c | 4 +- libc/mem/leaks.c | 2 +- libc/runtime/cxa_thread_atexit.c | 11 + libc/testlib/testmain.c | 11 +- libc/thread/posixthread.internal.h | 13 +- libc/thread/pt.internal.h | 2 + libc/thread/pthread_attr_getguardsize.c | 2 +- libc/thread/pthread_attr_getsigaltstack_np.c | 34 ++++ .../pthread_attr_getsigaltstacksize_np.c | 36 ++++ libc/thread/pthread_attr_setguardsize.c | 18 +- libc/thread/pthread_attr_setsigaltstack_np.c | 42 ++++ .../pthread_attr_setsigaltstacksize_np.c | 78 ++++++++ libc/thread/pthread_attr_setstack.c | 3 + libc/thread/pthread_attr_setstacksize.c | 3 + libc/thread/pthread_create.c | 189 ++++++++++++------ libc/thread/pthread_decimate_np.c | 2 +- libc/thread/pthread_detach.c | 4 +- libc/thread/pthread_exit.c | 27 ++- libc/thread/pthread_timedjoin_np.c | 65 +++--- libc/thread/thread.h | 8 +- test/libc/calls/stackoverflow5_test.c | 86 ++++++++ test/libc/intrin/cosmo_once_test.c | 6 +- test/libc/intrin/mmap_test.c | 13 +- .../pthread_cancel_deferred_cond_test.c | 40 ++++ .../thread/pthread_cancel_masked_cond_test.c | 43 ++++ .../thread/pthread_cancel_masked_read_test.c | 41 ++++ .../thread/pthread_create_inherit_mask_test.c | 30 +++ test/libc/thread/pthread_create_test.c | 8 +- test/libc/thread/pthread_detach_test.c | 10 +- 38 files changed, 752 insertions(+), 174 deletions(-) rename libc/intrin/{pthread_unref.c => describemsyncflags.c} (75%) create mode 100644 libc/intrin/describesigaltstackflags.c create mode 100644 libc/thread/pthread_attr_getsigaltstack_np.c create mode 100644 libc/thread/pthread_attr_getsigaltstacksize_np.c create mode 100644 libc/thread/pthread_attr_setsigaltstack_np.c create mode 100644 libc/thread/pthread_attr_setsigaltstacksize_np.c create mode 100644 test/libc/calls/stackoverflow5_test.c create mode 100644 test/libc/thread/pthread_cancel_deferred_cond_test.c create mode 100644 test/libc/thread/pthread_cancel_masked_cond_test.c create mode 100644 test/libc/thread/pthread_cancel_masked_read_test.c create mode 100644 test/libc/thread/pthread_create_inherit_mask_test.c diff --git a/libc/calls/sig.c b/libc/calls/sig.c index c97e41d2a..a52ad2bc7 100644 --- a/libc/calls/sig.c +++ b/libc/calls/sig.c @@ -396,9 +396,7 @@ static textwindows int __sig_killer(struct PosixThread *pt, int sig, int sic) { textwindows int __sig_kill(struct PosixThread *pt, int sig, int sic) { int rc; BLOCK_SIGNALS; - _pthread_ref(pt); rc = __sig_killer(pt, sig, sic); - _pthread_unref(pt); ALLOW_SIGNALS; return rc; } diff --git a/libc/calls/sigaltstack.c b/libc/calls/sigaltstack.c index 01079570f..0e246d749 100644 --- a/libc/calls/sigaltstack.c +++ b/libc/calls/sigaltstack.c @@ -146,7 +146,7 @@ int sigaltstack(const struct sigaltstack *neu, struct sigaltstack *old) { } else { rc = sigaltstack_cosmo(neu, old); } - STRACE("sigaltstack(%s, [%s]) β†’ %d% m", DescribeSigaltstk(0, neu), - DescribeSigaltstk(0, old), rc); + STRACE("sigaltstack(%s, [%s]) β†’ %d% m", DescribeSigaltstack(0, neu), + DescribeSigaltstack(0, old), rc); return rc; } diff --git a/libc/calls/struct/sigaltstack.internal.h b/libc/calls/struct/sigaltstack.internal.h index 43c21abb9..c95eea696 100644 --- a/libc/calls/struct/sigaltstack.internal.h +++ b/libc/calls/struct/sigaltstack.internal.h @@ -4,8 +4,8 @@ #include "libc/mem/alloca.h" COSMOPOLITAN_C_START_ -const char *DescribeSigaltstk(char[128], int, const struct sigaltstack *); -#define DescribeSigaltstk(rc, ss) DescribeSigaltstk(alloca(128), rc, ss) +const char *DescribeSigaltstack(char[128], int, const struct sigaltstack *); +#define DescribeSigaltstack(rc, ss) DescribeSigaltstack(alloca(128), rc, ss) COSMOPOLITAN_C_END_ #endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGALTSTACK_INTERNAL_H_ */ diff --git a/libc/intrin/describeflags.h b/libc/intrin/describeflags.h index dc38a93e5..9bcf96218 100644 --- a/libc/intrin/describeflags.h +++ b/libc/intrin/describeflags.h @@ -27,6 +27,7 @@ const char *DescribeItimer(char[12], int) libcesque; const char *DescribeMapFlags(char[64], int) libcesque; const char *DescribeMapping(char[8], int, int) libcesque; const char *DescribeMremapFlags(char[30], int) libcesque; +const char *DescribeMsyncFlags(char[48], int) libcesque; const char *DescribeNtConsoleInFlags(char[256], uint32_t) libcesque; const char *DescribeNtConsoleOutFlags(char[128], uint32_t) libcesque; const char *DescribeNtCreationDisposition(uint32_t) libcesque; @@ -54,6 +55,7 @@ const char *DescribeRlimitName(char[20], int) libcesque; const char *DescribeSchedPolicy(char[48], int) libcesque; const char *DescribeSeccompOperation(int) libcesque; const char *DescribeSiCode(char[20], int, int) libcesque; +const char *DescribeSigaltstackFlags(char[22], int) libcesque; const char *DescribeSleepFlags(char[16], int) libcesque; const char *DescribeSockLevel(char[12], int) libcesque; const char *DescribeSockOptname(char[32], int, int) libcesque; @@ -82,6 +84,7 @@ const char *DescribeWhichPrio(char[12], int) libcesque; #define DescribeMapFlags(x) DescribeMapFlags(alloca(64), x) #define DescribeMapping(x, y) DescribeMapping(alloca(8), x, y) #define DescribeMremapFlags(x) DescribeMremapFlags(alloca(30), x) +#define DescribeMsyncFlags(x) DescribeMsyncFlags(alloca(48), x) #define DescribeNtConsoleInFlags(x) DescribeNtConsoleInFlags(alloca(256), x) #define DescribeNtConsoleOutFlags(x) DescribeNtConsoleOutFlags(alloca(128), x) #define DescribeNtFileAccessFlags(x) DescribeNtFileAccessFlags(alloca(512), x) @@ -107,6 +110,7 @@ const char *DescribeWhichPrio(char[12], int) libcesque; #define DescribeRlimitName(rl) DescribeRlimitName(alloca(20), rl) #define DescribeSchedPolicy(x) DescribeSchedPolicy(alloca(48), x) #define DescribeSiCode(x, y) DescribeSiCode(alloca(20), x, y) +#define DescribeSigaltstackFlags(x) DescribeSigaltstackFlags(alloca(22), x) #define DescribeSleepFlags(x) DescribeSleepFlags(alloca(16), x) #define DescribeSockLevel(x) DescribeSockLevel(alloca(12), x) #define DescribeSockOptname(x, y) DescribeSockOptname(alloca(32), x, y) diff --git a/libc/intrin/pthread_unref.c b/libc/intrin/describemsyncflags.c similarity index 75% rename from libc/intrin/pthread_unref.c rename to libc/intrin/describemsyncflags.c index 6ff6a7a5c..481493489 100644 --- a/libc/intrin/pthread_unref.c +++ b/libc/intrin/describemsyncflags.c @@ -1,7 +1,7 @@ /*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-β”‚ β”‚ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi β”‚ β•žβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•‘ -β”‚ Copyright 2023 Justine Alexandra Roberts Tunney β”‚ +β”‚ Copyright 2022 Justine Alexandra Roberts Tunney β”‚ β”‚ β”‚ β”‚ Permission to use, copy, modify, and/or distribute this software for β”‚ β”‚ any purpose with or without fee is hereby granted, provided that the β”‚ @@ -16,20 +16,15 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/assert.h" -#include "libc/intrin/atomic.h" -#include "libc/intrin/weaken.h" -#include "libc/thread/posixthread.internal.h" +#include "libc/intrin/describeflags.h" +#include "libc/macros.internal.h" +#include "libc/sysv/consts/msync.h" -static bool _pthread_deref(struct PosixThread *pt) { - int refs = atomic_load_explicit(&pt->pt_refs, memory_order_acquire); - return !refs || !atomic_fetch_sub(&pt->pt_refs, 1); -} - -void _pthread_unref(struct PosixThread *pt) { - if (_pthread_deref(pt)) { - unassert(_weaken(_pthread_free)); - _weaken(_pthread_free)(pt, false); - _weaken(_pthread_decimate)(); - } +const char *(DescribeMsyncFlags)(char buf[48], int x) { + const struct DescribeFlags kMsyncFlags[] = { + {MS_SYNC, "SYNC"}, // + {MS_ASYNC, "ASYNC"}, // + {MS_INVALIDATE, "INVALIDATE"}, // + }; + return DescribeFlags(buf, 48, kMsyncFlags, ARRAYLEN(kMsyncFlags), "MS_", x); } diff --git a/libc/intrin/describesigaltstack.c b/libc/intrin/describesigaltstack.c index 90770f3a6..32cdb3bc2 100644 --- a/libc/intrin/describesigaltstack.c +++ b/libc/intrin/describesigaltstack.c @@ -21,8 +21,8 @@ #include "libc/intrin/describeflags.h" #include "libc/intrin/kprintf.h" -const char *(DescribeSigaltstk)(char buf[128], int rc, - const struct sigaltstack *ss) { +const char *(DescribeSigaltstack)(char buf[128], int rc, + const struct sigaltstack *ss) { if (rc == -1) return "n/a"; if (!ss) @@ -30,8 +30,8 @@ const char *(DescribeSigaltstk)(char buf[128], int rc, if (kisdangerous(ss)) { ksnprintf(buf, 128, "%p", ss); } else { - ksnprintf(buf, 128, "{.ss_sp=%p, .ss_flags=%#lx, .ss_size=%'zu}", ss->ss_sp, - ss->ss_flags, ss->ss_size); + ksnprintf(buf, 128, "{.ss_sp=%p, .ss_flags=%s, .ss_size=%'zu}", ss->ss_sp, + DescribeSigaltstackFlags(ss->ss_flags), ss->ss_size); } return buf; } diff --git a/libc/intrin/describesigaltstackflags.c b/libc/intrin/describesigaltstackflags.c new file mode 100644 index 000000000..e9c7c6e8b --- /dev/null +++ b/libc/intrin/describesigaltstackflags.c @@ -0,0 +1,30 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-β”‚ +β”‚ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi β”‚ +β•žβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•‘ +β”‚ Copyright 2022 Justine Alexandra Roberts Tunney β”‚ +β”‚ β”‚ +β”‚ Permission to use, copy, modify, and/or distribute this software for β”‚ +β”‚ any purpose with or without fee is hereby granted, provided that the β”‚ +β”‚ above copyright notice and this permission notice appear in all copies. β”‚ +β”‚ β”‚ +β”‚ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL β”‚ +β”‚ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED β”‚ +β”‚ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE β”‚ +β”‚ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL β”‚ +β”‚ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR β”‚ +β”‚ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER β”‚ +β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ +β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ +β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/intrin/describeflags.h" +#include "libc/macros.internal.h" +#include "libc/sysv/consts/ss.h" + +const char *(DescribeSigaltstackFlags)(char buf[22], int x) { + const struct DescribeFlags kSigaltstackFlags[] = { + {SS_ONSTACK, "ONSTACK"}, // + {SS_DISABLE, "DISABLE"}, // + }; + return DescribeFlags(buf, 48, kSigaltstackFlags, ARRAYLEN(kSigaltstackFlags), + "SS_", x); +} diff --git a/libc/intrin/maps.c b/libc/intrin/maps.c index e7d913206..3d042e5d2 100644 --- a/libc/intrin/maps.c +++ b/libc/intrin/maps.c @@ -91,12 +91,21 @@ privileged bool __maps_lock(void) { tib = __get_tls_privileged(); if (atomic_fetch_add_explicit(&tib->tib_relock_maps, 1, memory_order_relaxed)) return true; + int backoff = 0; while (atomic_exchange_explicit(&__maps.lock, 1, memory_order_acquire)) { + if (backoff < 7) { + volatile int i; + for (i = 0; i != 1 << backoff; i++) { + } + backoff++; + } else { + // STRACE("pthread_delay_np(__maps)"); #if defined(__GNUC__) && defined(__aarch64__) - __asm__ volatile("yield"); + __asm__ volatile("yield"); #elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) - __asm__ volatile("pause"); + __asm__ volatile("pause"); #endif + } } return false; } diff --git a/libc/intrin/mmap.c b/libc/intrin/mmap.c index ac4ceeb5a..47e102a4c 100644 --- a/libc/intrin/mmap.c +++ b/libc/intrin/mmap.c @@ -834,7 +834,8 @@ void *mremap(void *old_addr, size_t old_size, size_t new_size, int flags, ...) { */ int munmap(void *addr, size_t size) { int rc = __munmap(addr, size); - STRACE("munmap(%p, %'zu) β†’ %d% m", addr, size, rc); + STRACE("munmap(%p, %'zu) β†’ %d% m (%'zu bytes total)", addr, size, rc, + __maps.pages * __pagesize); return rc; } diff --git a/libc/intrin/msync.c b/libc/intrin/msync.c index 69bf5730b..d3e43e26d 100644 --- a/libc/intrin/msync.c +++ b/libc/intrin/msync.c @@ -23,6 +23,7 @@ #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" +#include "libc/intrin/describeflags.h" #include "libc/intrin/strace.h" #include "libc/macros.internal.h" #include "libc/sysv/errfuns.h" @@ -93,6 +94,7 @@ int msync(void *addr, size_t size, int flags) { END_CANCELATION_POINT; Finished: - STRACE("msync(%p, %'zu, %#x) β†’ %d% m", addr, size, flags, rc); + STRACE("msync(%p, %'zu, %s) β†’ %d% m", addr, size, DescribeMsyncFlags(flags), + rc); return rc; } diff --git a/libc/mem/leaks.c b/libc/mem/leaks.c index 570124226..8c7ac7f9d 100644 --- a/libc/mem/leaks.c +++ b/libc/mem/leaks.c @@ -76,7 +76,7 @@ void CheckForMemoryLeaks(void) { // validate usage of this api if (_weaken(_pthread_decimate)) - _weaken(_pthread_decimate)(); + _weaken(_pthread_decimate)(false); if (!pthread_orphan_np()) kprintf("warning: called CheckForMemoryLeaks() from non-orphaned thread\n"); diff --git a/libc/runtime/cxa_thread_atexit.c b/libc/runtime/cxa_thread_atexit.c index 4e8a2efff..76b89ec89 100644 --- a/libc/runtime/cxa_thread_atexit.c +++ b/libc/runtime/cxa_thread_atexit.c @@ -79,11 +79,22 @@ void __cxa_thread_finalize(void) { struct Dtor *dtor; struct CosmoTib *tib; tib = __get_tls(); + + // "Any cancellation cleanup handlers that have been pushed and not + // yet popped shall be popped in the reverse order that they were + // pushed and then executed." ──Quoth POSIX.1-2017 _pthread_unwind(tib); + + // "After all cancellation cleanup handlers have been executed, if the + // thread has any thread-specific data, appropriate destructor + // functions shall be called in an unspecified order." + // ──Quoth POSIX.1-2017 if (tib->tib_nsync) _weaken(nsync_waiter_destroy)(tib->tib_nsync); _pthread_unkey(tib); + _pthread_ungarbage(tib); + while ((dtor = tib->tib_atexit)) { STRACE("__cxa_finalize(%t, %p)", dtor->fun, dtor->arg); tib->tib_atexit = dtor->next; diff --git a/libc/testlib/testmain.c b/libc/testlib/testmain.c index bd6093851..e211f8564 100644 --- a/libc/testlib/testmain.c +++ b/libc/testlib/testmain.c @@ -151,23 +151,20 @@ int main(int argc, char *argv[]) { a->teardown(0); } } - if (_weaken(TearDownOnce)) { + if (_weaken(TearDownOnce)) _weaken(TearDownOnce)(); - } // make sure threads are in a good state - if (_weaken(_pthread_decimate)) { - _weaken(_pthread_decimate)(); - } + if (_weaken(_pthread_decimate)) + _weaken(_pthread_decimate)(false); if (_weaken(pthread_orphan_np) && !_weaken(pthread_orphan_np)()) { tinyprint(2, "error: tests ended with threads still active\n", NULL); _Exit(1); } // check for memory leaks - if (!g_testlib_failed) { + if (!g_testlib_failed) CheckForMemoryLeaks(); - } // we're done! int status = MIN(255, g_testlib_failed); diff --git a/libc/thread/posixthread.internal.h b/libc/thread/posixthread.internal.h index bd1fd5d04..4afebc85d 100644 --- a/libc/thread/posixthread.internal.h +++ b/libc/thread/posixthread.internal.h @@ -74,7 +74,7 @@ struct PosixThread { atomic_int pt_canceled; // 0x04: thread has bad beliefs _Atomic(enum PosixThreadStatus) pt_status; atomic_int ptid; // transitions 0 β†’ tid - atomic_int pt_refs; // negative means free + atomic_int pt_refs; // prevents decimation void *(*pt_start)(void *); // creation callback void *pt_arg; // start's parameter void *pt_rc; // start's return value @@ -103,14 +103,13 @@ int _pthread_setschedparam_freebsd(int, int, const struct sched_param *); int _pthread_tid(struct PosixThread *) libcesque; intptr_t _pthread_syshand(struct PosixThread *) libcesque; long _pthread_cancel_ack(void) libcesque; -void _pthread_decimate(void) libcesque; -void _pthread_free(struct PosixThread *, bool) libcesque; +void _pthread_decimate(bool) libcesque; +void _pthread_free(struct PosixThread *) libcesque; void _pthread_lock(void) libcesque; void _pthread_onfork_child(void) libcesque; void _pthread_onfork_parent(void) libcesque; void _pthread_onfork_prepare(void) libcesque; void _pthread_unlock(void) libcesque; -void _pthread_unref(struct PosixThread *) libcesque; void _pthread_zombify(struct PosixThread *) libcesque; forceinline pureconst struct PosixThread *_pthread_self(void) { @@ -118,7 +117,11 @@ forceinline pureconst struct PosixThread *_pthread_self(void) { } forceinline void _pthread_ref(struct PosixThread *pt) { - atomic_fetch_add_explicit(&pt->pt_refs, 1, memory_order_relaxed); + atomic_fetch_add_explicit(&pt->pt_refs, 1, memory_order_acq_rel); +} + +forceinline void _pthread_unref(struct PosixThread *pt) { + atomic_fetch_sub_explicit(&pt->pt_refs, 1, memory_order_acq_rel); } COSMOPOLITAN_C_END_ diff --git a/libc/thread/pt.internal.h b/libc/thread/pt.internal.h index d054c8bab..c211c273f 100644 --- a/libc/thread/pt.internal.h +++ b/libc/thread/pt.internal.h @@ -8,5 +8,7 @@ #define PT_MASKED 16 #define PT_INCANCEL 32 #define PT_OPENBSD_KLUDGE 64 +#define PT_EXITING 128 +#define PT_OWNSIGALTSTACK 256 #endif /* COSMOPOLITAN_LIBC_THREAD_PT_H_ */ diff --git a/libc/thread/pthread_attr_getguardsize.c b/libc/thread/pthread_attr_getguardsize.c index 3d4f394d3..fd4524efb 100644 --- a/libc/thread/pthread_attr_getguardsize.c +++ b/libc/thread/pthread_attr_getguardsize.c @@ -19,7 +19,7 @@ #include "libc/thread/thread.h" /** - * Returns size of unmapped pages at bottom of stack. + * Returns size of protected region at bottom of thread stack. * * @param guardsize will be set to guard size in bytes * @return 0 on success, or errno on error diff --git a/libc/thread/pthread_attr_getsigaltstack_np.c b/libc/thread/pthread_attr_getsigaltstack_np.c new file mode 100644 index 000000000..c261a57a4 --- /dev/null +++ b/libc/thread/pthread_attr_getsigaltstack_np.c @@ -0,0 +1,34 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-β”‚ +β”‚ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi β”‚ +β•žβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•‘ +β”‚ Copyright 2022 Justine Alexandra Roberts Tunney β”‚ +β”‚ β”‚ +β”‚ Permission to use, copy, modify, and/or distribute this software for β”‚ +β”‚ any purpose with or without fee is hereby granted, provided that the β”‚ +β”‚ above copyright notice and this permission notice appear in all copies. β”‚ +β”‚ β”‚ +β”‚ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL β”‚ +β”‚ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED β”‚ +β”‚ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE β”‚ +β”‚ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL β”‚ +β”‚ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR β”‚ +β”‚ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER β”‚ +β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ +β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ +β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/runtime/stack.h" +#include "libc/thread/thread.h" + +/** + * Returns configuration for thread signal stack. + * + * @param stackaddr will be set to signal stack address + * @return 0 on success, or errno on error + * @see pthread_attr_setsigaltstacksize_np() + */ +errno_t pthread_attr_getsigaltstack_np(const pthread_attr_t *attr, + void **stackaddr, size_t *stacksize) { + *stackaddr = attr->__sigaltstackaddr; + *stacksize = attr->__sigaltstacksize; + return 0; +} diff --git a/libc/thread/pthread_attr_getsigaltstacksize_np.c b/libc/thread/pthread_attr_getsigaltstacksize_np.c new file mode 100644 index 000000000..b6115357a --- /dev/null +++ b/libc/thread/pthread_attr_getsigaltstacksize_np.c @@ -0,0 +1,36 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-β”‚ +β”‚ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi β”‚ +β•žβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•‘ +β”‚ Copyright 2022 Justine Alexandra Roberts Tunney β”‚ +β”‚ β”‚ +β”‚ Permission to use, copy, modify, and/or distribute this software for β”‚ +β”‚ any purpose with or without fee is hereby granted, provided that the β”‚ +β”‚ above copyright notice and this permission notice appear in all copies. β”‚ +β”‚ β”‚ +β”‚ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL β”‚ +β”‚ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED β”‚ +β”‚ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE β”‚ +β”‚ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL β”‚ +β”‚ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR β”‚ +β”‚ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER β”‚ +β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ +β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ +β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/runtime/stack.h" +#include "libc/thread/thread.h" + +/** + * Returns size of thread signal stack. + * + * This defaults to zero, which means that cosmo won't allocate a + * managed signal stack for newly created threads. + * + * @param x will be set to stack size in bytes + * @return 0 on success, or errno on error + * @see pthread_attr_setsigaltstacksize_np() + */ +errno_t pthread_attr_getsigaltstacksize_np(const pthread_attr_t *a, + size_t *stacksize) { + *stacksize = a->__sigaltstacksize; + return 0; +} diff --git a/libc/thread/pthread_attr_setguardsize.c b/libc/thread/pthread_attr_setguardsize.c index 2e03607b2..e404ea04f 100644 --- a/libc/thread/pthread_attr_setguardsize.c +++ b/libc/thread/pthread_attr_setguardsize.c @@ -19,18 +19,16 @@ #include "libc/thread/thread.h" /** - * Sets size of unmapped pages at bottom of stack. + * Sets size of protected region at bottom of thread stack. * - * This value will be rounded up to the host microprocessor page size, - * which is usually 4096 or 16384. It's important to write code in such - * a way that that code can't skip over the guard area. GCC has warnings - * like `-Wframe-larger-than=4096 -Walloca-larger-than=4096` which help - * guarantee your code is safe in this regard. It should be assumed the - * guard pages exist beneath the stack pointer, rather than the bottom - * of the stack, since guard pages are also used to grow down commit, - * which can be poked using CheckLargeStackAllocation(). + * Cosmopolitan sets this value to `sysconf(_SC_PAGESIZE)` by default. * - * @param guardsize contains guard size in bytes + * You may set `guardsize` to disable the stack guard feature and gain a + * slight performance advantage by avoiding mprotect() calls. Note that + * it could make your code more prone to silent unreported corruption. + * + * @param guardsize contains guard size in bytes, which is implicitly + * rounded up to `sysconf(_SC_PAGESIZE)`, or zero to disable * @return 0 on success, or errno on error */ errno_t pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize) { diff --git a/libc/thread/pthread_attr_setsigaltstack_np.c b/libc/thread/pthread_attr_setsigaltstack_np.c new file mode 100644 index 000000000..91c08f107 --- /dev/null +++ b/libc/thread/pthread_attr_setsigaltstack_np.c @@ -0,0 +1,42 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-β”‚ +β”‚ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi β”‚ +β•žβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•‘ +β”‚ Copyright 2022 Justine Alexandra Roberts Tunney β”‚ +β”‚ β”‚ +β”‚ Permission to use, copy, modify, and/or distribute this software for β”‚ +β”‚ any purpose with or without fee is hereby granted, provided that the β”‚ +β”‚ above copyright notice and this permission notice appear in all copies. β”‚ +β”‚ β”‚ +β”‚ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL β”‚ +β”‚ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED β”‚ +β”‚ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE β”‚ +β”‚ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL β”‚ +β”‚ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR β”‚ +β”‚ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER β”‚ +β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ +β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ +β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/dce.h" +#include "libc/errno.h" +#include "libc/limits.h" +#include "libc/runtime/runtime.h" +#include "libc/thread/thread.h" + +/** + * Defines user-owned signal stack for thread. + */ +errno_t pthread_attr_setsigaltstack_np(pthread_attr_t *attr, void *stackaddr, + size_t stacksize) { + if (!stackaddr) { + attr->__sigaltstackaddr = 0; + attr->__sigaltstacksize = 0; + return 0; + } + if (stacksize > INT_MAX) + return EINVAL; + if (stacksize < __get_minsigstksz()) + return EINVAL; + attr->__sigaltstackaddr = stackaddr; + attr->__sigaltstacksize = stacksize; + return 0; +} diff --git a/libc/thread/pthread_attr_setsigaltstacksize_np.c b/libc/thread/pthread_attr_setsigaltstacksize_np.c new file mode 100644 index 000000000..73da4ad30 --- /dev/null +++ b/libc/thread/pthread_attr_setsigaltstacksize_np.c @@ -0,0 +1,78 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-β”‚ +β”‚ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi β”‚ +β•žβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•‘ +β”‚ Copyright 2022 Justine Alexandra Roberts Tunney β”‚ +β”‚ β”‚ +β”‚ Permission to use, copy, modify, and/or distribute this software for β”‚ +β”‚ any purpose with or without fee is hereby granted, provided that the β”‚ +β”‚ above copyright notice and this permission notice appear in all copies. β”‚ +β”‚ β”‚ +β”‚ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL β”‚ +β”‚ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED β”‚ +β”‚ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE β”‚ +β”‚ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL β”‚ +β”‚ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR β”‚ +β”‚ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER β”‚ +β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ +β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ +β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/errno.h" +#include "libc/limits.h" +#include "libc/runtime/runtime.h" +#include "libc/thread/thread.h" + +/** + * Defines size of cosmo-owned signal stack for thread. + * + * The sigaltstack() function is useful for writing robust programs that + * can recover from the occasional thread having a stack overflow rather + * than having the entire process crash. To use it normally, sigaltstack + * needs to be called at the start of each thread with a unique piece of + * memory. However this is challenging to do *correctly* without support + * from the POSIX threads runtime, since canceled or crashed threads may + * need to execute on the signal stack during pthread_exit() which would + * prevent a thread-local storage key destructor from free()'ing it. + * + * By default pthread_create() will not install a sigaltstack() on newly + * created threads. If this function is called, on the attributes object + * that gets passed to pthread_create(), then it'll use malloc() to make + * a stack for the thread using the size you specify here. The threading + * runtime will also free that memory safely after complete termination. + * + * pthread_t id; + * pthread_attr_t attr; + * pthread_attr_init(&attr); + * pthread_attr_setguardsize(&attr, getpagesize()); + * pthread_attr_setsigaltstacksize_np(&attr, stacksize); + * pthread_create(&id, &attr, func, 0); + * pthread_attr_destroy(&attr); + * pthread_join(id, 0); + * + * Try using a size of `sysconf(_SC_SIGSTKSZ)`. If you want the smallest + * size possible, then `sysconf(_SC_MINSIGSTKSZ) + 2048` is probably the + * smallest value that can reasonably expected to work with pthread_exit + * + * struct sigaction sa; + * sigemptyset(&sa.sa_mask); + * sa.sa_flags = SA_SIGINFO | SA_ONSTACK; + * sa.sa_sigaction = on_crash_signal; + * sigaction(SIGSEGV, &sa, 0); + * + * Please note that in order for this to work, your handlers for signals + * such as SIGSEGV and SIGBUS need to use SA_ONSTACK in your sa_flags. + * + * @param stacksize contains stack size in bytes, or 0 to disable + * @return 0 on success, or errno on error + * @raise EINVAL if `stacksize` is less than `sysconf(_SC_MINSIGSTKSZ)` + */ +errno_t pthread_attr_setsigaltstacksize_np(pthread_attr_t *a, + size_t stacksize) { + if (stacksize) { + if (stacksize > INT_MAX) + return EINVAL; + if (stacksize < __get_minsigstksz()) + return EINVAL; + } + a->__sigaltstacksize = stacksize; + return 0; +} diff --git a/libc/thread/pthread_attr_setstack.c b/libc/thread/pthread_attr_setstack.c index f82be129f..8bfaed866 100644 --- a/libc/thread/pthread_attr_setstack.c +++ b/libc/thread/pthread_attr_setstack.c @@ -18,6 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/dce.h" #include "libc/errno.h" +#include "libc/limits.h" #include "libc/thread/thread.h" /** @@ -71,6 +72,8 @@ errno_t pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, attr->__stacksize = 0; return 0; } + if (stacksize > INT_MAX) + return EINVAL; if (stacksize < PTHREAD_STACK_MIN) return EINVAL; attr->__stackaddr = stackaddr; diff --git a/libc/thread/pthread_attr_setstacksize.c b/libc/thread/pthread_attr_setstacksize.c index f2ccb0c99..58e69eb15 100644 --- a/libc/thread/pthread_attr_setstacksize.c +++ b/libc/thread/pthread_attr_setstacksize.c @@ -17,6 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/errno.h" +#include "libc/limits.h" #include "libc/thread/thread.h" /** @@ -27,6 +28,8 @@ * @raise EINVAL if `stacksize` is less than `PTHREAD_STACK_MIN` */ errno_t pthread_attr_setstacksize(pthread_attr_t *a, size_t stacksize) { + if (stacksize > INT_MAX) + return EINVAL; if (stacksize < PTHREAD_STACK_MIN) return EINVAL; a->__stacksize = stacksize; diff --git a/libc/thread/pthread_create.c b/libc/thread/pthread_create.c index 8be2420c7..42a3b45a1 100644 --- a/libc/thread/pthread_create.c +++ b/libc/thread/pthread_create.c @@ -18,6 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/assert.h" #include "libc/calls/calls.h" +#include "libc/calls/struct/sigaltstack.h" #include "libc/calls/struct/sigset.h" #include "libc/calls/struct/sigset.internal.h" #include "libc/calls/syscall-sysv.internal.h" @@ -67,54 +68,104 @@ __static_yoink("_pthread_onfork_child"); #define MAP_ANON_OPENBSD 0x1000 #define MAP_STACK_OPENBSD 0x4000 -void _pthread_free(struct PosixThread *pt, bool isfork) { +void _pthread_free(struct PosixThread *pt) { + + // thread must be removed from _pthread_list before calling unassert(dll_is_alone(&pt->list) && &pt->list != _pthread_list); + + // do nothing for the one and only magical statical posix thread if (pt->pt_flags & PT_STATIC) return; + + // unmap stack if the cosmo runtime was responsible for mapping it if (pt->pt_flags & PT_OWNSTACK) unassert(!munmap(pt->pt_attr.__stackaddr, pt->pt_attr.__stacksize)); - if (!isfork) { - uint64_t syshand = - atomic_load_explicit(&pt->tib->tib_syshand, memory_order_acquire); - if (syshand) { - if (IsWindows()) - unassert(CloseHandle(syshand)); - else if (IsXnuSilicon()) - __syslib->__pthread_join(syshand, 0); - } + + // free any additional upstream system resources + // our fork implementation wipes this handle in child automatically + uint64_t syshand = + atomic_load_explicit(&pt->tib->tib_syshand, memory_order_acquire); + if (syshand) { + if (IsWindows()) + unassert(CloseHandle(syshand)); // non-inheritable + else if (IsXnuSilicon()) + unassert(!__syslib->__pthread_join(syshand, 0)); } + + // free heap memory associated with thread + if (pt->pt_flags & PT_OWNSIGALTSTACK) + free(pt->pt_attr.__sigaltstackaddr); free(pt->pt_tls); free(pt); } -void _pthread_decimate(void) { - struct Dll *e; +void _pthread_decimate(bool annihilation_only) { struct PosixThread *pt; + struct Dll *e, *e2, *list = 0; enum PosixThreadStatus status; -StartOver: + + // acquire posix threads gil _pthread_lock(); - for (e = dll_last(_pthread_list); e; e = dll_prev(_pthread_list, e)) { + + // swiftly remove every single zombie + // that isn't being held by a killing thread + for (e = dll_last(_pthread_list); e; e = e2) { + e2 = dll_prev(_pthread_list, e); pt = POSIXTHREAD_CONTAINER(e); + if (atomic_load_explicit(&pt->pt_refs, memory_order_acquire) > 0) + continue; // pthread_kill() has a lease on this thread status = atomic_load_explicit(&pt->pt_status, memory_order_acquire); if (status != kPosixThreadZombie) - break; - if (!atomic_load_explicit(&pt->tib->tib_tid, memory_order_acquire)) { - dll_remove(&_pthread_list, e); - _pthread_unlock(); - _pthread_unref(pt); - goto StartOver; - } + break; // zombies only exist at the end of the linked list + if (atomic_load_explicit(&pt->tib->tib_tid, memory_order_acquire)) + continue; // undead thread should that'll stop existing soon + dll_remove(&_pthread_list, e); + dll_make_first(&list, e); } + + // code like pthread_exit() needs to call this in order to know if + // it's appropriate to run exit() handlers however we really don't + // want to have a thread exiting block on a bunch of __maps locks! + // therefore we only take action if we'll destroy all but the self + if (annihilation_only) + if (!(_pthread_list == _pthread_list->prev && + _pthread_list == _pthread_list->next)) { + dll_make_last(&_pthread_list, list); + list = 0; + } + + // release posix threads gil _pthread_unlock(); + + // now free our thread local batch of zombies + // because death is a release and not a punishment + // this is advantaged by not holding locks over munmap + while ((e = dll_first(list))) { + pt = POSIXTHREAD_CONTAINER(e); + dll_remove(&list, e); + _pthread_free(pt); + } } static int PosixThread(void *arg, int tid) { void *rc; struct PosixThread *pt = arg; + + // setup scheduling if (pt->pt_attr.__inheritsched == PTHREAD_EXPLICIT_SCHED) { unassert(_weaken(_pthread_reschedule)); _weaken(_pthread_reschedule)(pt); // yoinked by attribute builder } + + // setup signal stack + if (pt->pt_attr.__sigaltstacksize) { + struct sigaltstack ss; + ss.ss_sp = pt->pt_attr.__sigaltstackaddr; + ss.ss_size = pt->pt_attr.__sigaltstacksize; + ss.ss_flags = 0; + unassert(!sigaltstack(&ss, 0)); + } + // set long jump handler so pthread_exit can bring control back here if (!setjmp(pt->pt_exiter)) { sigdelset(&pt->pt_attr.__sigmask, SIGTHR); @@ -130,41 +181,45 @@ static int PosixThread(void *arg, int tid) { // calling pthread_exit() will either jump back here, or call exit pthread_exit(rc); } + // avoid signal handler being triggered after we trash our own stack __sig_block(); + // return to clone polyfill which clears tid, wakes futex, and exits return 0; } -static int FixupCustomStackOnOpenbsd(pthread_attr_t *attr) { - // OpenBSD: Only permits RSP to occupy memory that's been explicitly - // defined as stack memory. We need to squeeze the provided interval - // in order to successfully call mmap(), which will return EINVAL if - // these calculations should overflow. - size_t n; - uintptr_t x, y; - int e, rc, pagesz; - pagesz = __pagesize; - n = attr->__stacksize; - x = (uintptr_t)attr->__stackaddr; - y = ROUNDUP(x, pagesz); - n -= y - x; - n = ROUNDDOWN(n, pagesz); - e = errno; - if (__sys_mmap((void *)y, n, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_FIXED | MAP_ANON_OPENBSD | MAP_STACK_OPENBSD, - -1, 0, 0) == (void *)y) { - attr->__stackaddr = (void *)y; - attr->__stacksize = n; - return 0; - } else { - rc = errno; - errno = e; - if (rc == EOVERFLOW) { - rc = EINVAL; - } - return rc; +static bool TellOpenbsdThisIsStackMemory(void *addr, size_t size) { + return __sys_mmap( + addr, size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_FIXED | MAP_ANON_OPENBSD | MAP_STACK_OPENBSD, -1, + 0, 0) == addr; +} + +// OpenBSD only permits RSP to occupy memory that's been explicitly +// defined as stack memory, i.e. `lo <= %rsp < hi` must be the case +static errno_t FixupCustomStackOnOpenbsd(pthread_attr_t *attr) { + + // get interval + uintptr_t lo = (uintptr_t)attr->__stackaddr; + uintptr_t hi = lo + attr->__stacksize; + + // squeeze interval + lo = (lo + __pagesize - 1) & -__pagesize; + hi = hi & -__pagesize; + + // tell os it's stack memory + errno_t olderr = errno; + if (!TellOpenbsdThisIsStackMemory((void *)lo, hi - lo)) { + errno_t err = errno; + errno = olderr; + return err; } + + // update attributes with usable stack address + attr->__stackaddr = (void *)lo; + attr->__stacksize = hi - lo; + return 0; } static errno_t pthread_create_impl(pthread_t *thread, @@ -204,7 +259,7 @@ static errno_t pthread_create_impl(pthread_t *thread, // assume they know what they're doing as much as possible if (IsOpenbsd()) { if ((rc = FixupCustomStackOnOpenbsd(&pt->pt_attr))) { - _pthread_free(pt, false); + _pthread_free(pt); return rc; } } @@ -214,21 +269,17 @@ static errno_t pthread_create_impl(pthread_t *thread, pt->pt_attr.__guardsize = ROUNDUP(pt->pt_attr.__guardsize, pagesize); pt->pt_attr.__stacksize = pt->pt_attr.__stacksize; if (pt->pt_attr.__guardsize + pagesize > pt->pt_attr.__stacksize) { - _pthread_free(pt, false); + _pthread_free(pt); return EINVAL; } pt->pt_attr.__stackaddr = mmap(0, pt->pt_attr.__stacksize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (pt->pt_attr.__stackaddr != MAP_FAILED) { - if (IsOpenbsd() && - __sys_mmap( - pt->pt_attr.__stackaddr, pt->pt_attr.__stacksize, - PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_FIXED | MAP_ANON_OPENBSD | MAP_STACK_OPENBSD, - -1, 0, 0) != pt->pt_attr.__stackaddr) { - notpossible; - } + if (IsOpenbsd()) + if (!TellOpenbsdThisIsStackMemory(pt->pt_attr.__stackaddr, + pt->pt_attr.__stacksize)) + notpossible; if (pt->pt_attr.__guardsize) if (mprotect(pt->pt_attr.__stackaddr, pt->pt_attr.__guardsize, PROT_NONE | PROT_GUARD)) @@ -236,7 +287,7 @@ static errno_t pthread_create_impl(pthread_t *thread, } if (!pt->pt_attr.__stackaddr || pt->pt_attr.__stackaddr == MAP_FAILED) { rc = errno; - _pthread_free(pt, false); + _pthread_free(pt); errno = e; if (rc == EINVAL || rc == EOVERFLOW) { return EINVAL; @@ -247,6 +298,18 @@ static errno_t pthread_create_impl(pthread_t *thread, pt->pt_flags |= PT_OWNSTACK; } + // setup signal stack + if (pt->pt_attr.__sigaltstacksize) { + if (!pt->pt_attr.__sigaltstackaddr) { + if (!(pt->pt_attr.__sigaltstackaddr = + malloc(pt->pt_attr.__sigaltstacksize))) { + _pthread_free(pt); + return errno; + } + pt->pt_flags |= PT_OWNSIGALTSTACK; + } + } + // set initial status pt->tib->tib_pthread = (pthread_t)pt; atomic_store_explicit(&pt->tib->tib_sigmask, -1, memory_order_relaxed); @@ -264,7 +327,7 @@ static errno_t pthread_create_impl(pthread_t *thread, memory_order_relaxed); break; default: - _pthread_free(pt, false); + _pthread_free(pt); return EINVAL; } @@ -284,7 +347,7 @@ static errno_t pthread_create_impl(pthread_t *thread, _pthread_lock(); dll_remove(&_pthread_list, &pt->list); _pthread_unlock(); - _pthread_free(pt, false); + _pthread_free(pt); return rc; } @@ -353,7 +416,7 @@ static const char *DescribeHandle(char buf[12], errno_t err, pthread_t *th) { errno_t pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) { errno_t err; - _pthread_decimate(); + _pthread_decimate(false); BLOCK_SIGNALS; err = pthread_create_impl(thread, attr, start_routine, arg, _SigMask); ALLOW_SIGNALS; diff --git a/libc/thread/pthread_decimate_np.c b/libc/thread/pthread_decimate_np.c index a6bc591cf..3027dc7fa 100644 --- a/libc/thread/pthread_decimate_np.c +++ b/libc/thread/pthread_decimate_np.c @@ -32,6 +32,6 @@ * @return 0 on success, or errno on error */ int pthread_decimate_np(void) { - _pthread_decimate(); + _pthread_decimate(false); return 0; } diff --git a/libc/thread/pthread_detach.c b/libc/thread/pthread_detach.c index 2a33b4988..2456ec69f 100644 --- a/libc/thread/pthread_detach.c +++ b/libc/thread/pthread_detach.c @@ -40,10 +40,8 @@ static errno_t pthread_detach_impl(struct PosixThread *pt) { if (atomic_compare_exchange_weak_explicit(&pt->pt_status, &status, transition, memory_order_release, memory_order_relaxed)) { - if (transition == kPosixThreadZombie) { + if (transition == kPosixThreadZombie) _pthread_zombify(pt); - } - _pthread_decimate(); return 0; } } diff --git a/libc/thread/pthread_exit.c b/libc/thread/pthread_exit.c index 7e5c941a1..933f041a2 100644 --- a/libc/thread/pthread_exit.c +++ b/libc/thread/pthread_exit.c @@ -69,23 +69,33 @@ * @noreturn */ wontreturn void pthread_exit(void *rc) { + int orphan; struct CosmoTib *tib; struct PosixThread *pt; enum PosixThreadStatus status, transition; + STRACE("pthread_exit(%p)", rc); + + // get posix thread object tib = __get_tls(); pt = (struct PosixThread *)tib->tib_pthread; - pt->pt_flags |= PT_NOCANCEL; - pt->pt_rc = rc; - STRACE("pthread_exit(%p)", rc); + // "The behavior of pthread_exit() is undefined if called from a + // cancellation cleanup handler or destructor function that was + // invoked as a result of either an implicit or explicit call to + // pthread_exit()." ──Quoth POSIX.1-2017 + unassert(!(pt->pt_flags & PT_EXITING)); + + // set state + pt->pt_flags |= PT_NOCANCEL | PT_EXITING; + pt->pt_rc = rc; // free resources __cxa_thread_finalize(); - _pthread_decimate(); // run atexit handlers if orphaned thread - if (pthread_orphan_np()) + _pthread_decimate(true); + if ((orphan = pthread_orphan_np())) if (_weaken(__cxa_finalize)) _weaken(__cxa_finalize)(NULL); @@ -113,8 +123,11 @@ wontreturn void pthread_exit(void *rc) { if (transition == kPosixThreadZombie) _pthread_zombify(pt); - // check if this is the last survivor - if (pthread_orphan_np()) { + // "The process shall exit with an exit status of 0 after the last + // thread has been terminated. The behavior shall be as if the + // implementation called exit() with a zero argument at thread + // termination time." ──Quoth POSIX.1-2017 + if (orphan) { for (const uintptr_t *p = __fini_array_end; p > __fini_array_start;) ((void (*)(void))(*--p))(); _Exit(0); diff --git a/libc/thread/pthread_timedjoin_np.c b/libc/thread/pthread_timedjoin_np.c index f814e038a..9dcc410a0 100644 --- a/libc/thread/pthread_timedjoin_np.c +++ b/libc/thread/pthread_timedjoin_np.c @@ -55,29 +55,38 @@ static const char *DescribeReturnValue(char buf[30], int err, void **value) { * * @return 0 on success, or errno on error * @raise ECANCELED if calling thread was cancelled in masked mode + * @raise EDEADLK if `ctid` refers calling thread's own ctid futex * @raise EBUSY if `abstime` was specified and deadline expired * @cancelationpoint */ static errno_t _pthread_wait(atomic_int *ctid, struct timespec *abstime) { - int x, e, rc = 0; - unassert(ctid != &__get_tls()->tib_tid); - // "If the thread calling pthread_join() is canceled, then the target - // thread shall not be detached." ──Quoth POSIX.1-2017 - if (!(rc = pthread_testcancel_np())) { - BEGIN_CANCELATION_POINT; - while ((x = atomic_load_explicit(ctid, memory_order_acquire))) { - e = nsync_futex_wait_(ctid, x, !IsWindows() && !IsXnu(), abstime); - if (e == -ECANCELED) { - rc = ECANCELED; - break; - } else if (e == -ETIMEDOUT) { - rc = EBUSY; - break; + int x, e; + errno_t err = 0; + if (ctid == &__get_tls()->tib_tid) { + // "If an implementation detects that the value specified by the + // thread argument to pthread_join() refers to the calling thread, + // it is recommended that the function should fail and report an + // [EDEADLK] error." ──Quoth POSIX.1-2017 + err = EDEADLK; + } else { + // "If the thread calling pthread_join() is canceled, then the target + // thread shall not be detached." ──Quoth POSIX.1-2017 + if (!(err = pthread_testcancel_np())) { + BEGIN_CANCELATION_POINT; + while ((x = atomic_load_explicit(ctid, memory_order_acquire))) { + e = nsync_futex_wait_(ctid, x, !IsWindows() && !IsXnu(), abstime); + if (e == -ECANCELED) { + err = ECANCELED; + break; + } else if (e == -ETIMEDOUT) { + err = EBUSY; + break; + } } + END_CANCELATION_POINT; } - END_CANCELATION_POINT; } - return rc; + return err; } /** @@ -97,6 +106,7 @@ static errno_t _pthread_wait(atomic_int *ctid, struct timespec *abstime) { * when we'll stop waiting; if this is null we will wait forever * @return 0 on success, or errno on error * @raise ECANCELED if calling thread was cancelled in masked mode + * @raise EDEADLK if `thread` refers to calling thread * @raise EBUSY if `abstime` deadline elapsed * @cancelationpoint * @returnserrno @@ -104,26 +114,29 @@ static errno_t _pthread_wait(atomic_int *ctid, struct timespec *abstime) { errno_t pthread_timedjoin_np(pthread_t thread, void **value_ptr, struct timespec *abstime) { int tid; - errno_t err; + errno_t err = 0; struct PosixThread *pt; enum PosixThreadStatus status; pt = (struct PosixThread *)thread; - tid = _pthread_tid(pt); - unassert(_pthread_tid(pt)); - status = atomic_load_explicit(&pt->pt_status, memory_order_acquire); + // "The behavior is undefined if the value specified by the thread // argument to pthread_join() does not refer to a joinable thread." // ──Quoth POSIX.1-2017 + unassert((tid = _pthread_tid(pt))); + status = atomic_load_explicit(&pt->pt_status, memory_order_acquire); unassert(status == kPosixThreadJoinable || status == kPosixThreadTerminated); + + // "The results of multiple simultaneous calls to pthread_join() + // specifying the same target thread are undefined." + // ──Quoth POSIX.1-2017 if (!(err = _pthread_wait(&pt->tib->tib_tid, abstime))) { - _pthread_lock(); - dll_remove(&_pthread_list, &pt->list); - _pthread_unlock(); - if (value_ptr) { + atomic_store_explicit(&pt->pt_status, kPosixThreadZombie, + memory_order_release); + _pthread_zombify(pt); + if (value_ptr) *value_ptr = pt->pt_rc; - } - _pthread_unref(pt); } + STRACE("pthread_timedjoin_np(%d, %s, %s) β†’ %s", tid, DescribeReturnValue(alloca(30), err, value_ptr), DescribeTimespec(err ? -1 : 0, abstime), DescribeErrno(err)); diff --git a/libc/thread/thread.h b/libc/thread/thread.h index 872fdcc37..af8ecd60c 100644 --- a/libc/thread/thread.h +++ b/libc/thread/thread.h @@ -94,9 +94,11 @@ typedef struct pthread_attr_s { int __schedpolicy; int __contentionscope; int __guardsize; - size_t __stacksize; + int __stacksize; + int __sigaltstacksize; uint64_t __sigmask; void *__stackaddr; + void *__sigaltstackaddr; } pthread_attr_t; struct _pthread_cleanup_buffer { @@ -117,6 +119,8 @@ int pthread_attr_getschedpolicy(const pthread_attr_t *, int *) libcesque paramsn int pthread_attr_getscope(const pthread_attr_t *, int *) libcesque paramsnonnull(); int pthread_attr_getstack(const pthread_attr_t *, void **, size_t *) libcesque paramsnonnull(); int pthread_attr_getstacksize(const pthread_attr_t *, size_t *) libcesque paramsnonnull(); +int pthread_attr_getsigaltstack_np(const pthread_attr_t *, void **, size_t *) libcesque paramsnonnull(); +int pthread_attr_getsigaltstacksize_np(const pthread_attr_t *, size_t *) libcesque paramsnonnull(); int pthread_attr_init(pthread_attr_t *) libcesque paramsnonnull(); int pthread_attr_setdetachstate(pthread_attr_t *, int) libcesque paramsnonnull(); int pthread_attr_setguardsize(pthread_attr_t *, size_t) libcesque paramsnonnull(); @@ -125,6 +129,8 @@ int pthread_attr_setschedpolicy(pthread_attr_t *, int) libcesque paramsnonnull() int pthread_attr_setscope(pthread_attr_t *, int) libcesque paramsnonnull(); int pthread_attr_setstack(pthread_attr_t *, void *, size_t) libcesque paramsnonnull((1)); int pthread_attr_setstacksize(pthread_attr_t *, size_t) libcesque paramsnonnull(); +int pthread_attr_setsigaltstack_np(pthread_attr_t *, void *, size_t) libcesque paramsnonnull((1)); +int pthread_attr_setsigaltstacksize_np(pthread_attr_t *, size_t); int pthread_barrier_destroy(pthread_barrier_t *) libcesque paramsnonnull(); int pthread_barrier_init(pthread_barrier_t *, const pthread_barrierattr_t *, unsigned) libcesque paramsnonnull((1)); int pthread_barrier_wait(pthread_barrier_t *) libcesque paramsnonnull(); diff --git a/test/libc/calls/stackoverflow5_test.c b/test/libc/calls/stackoverflow5_test.c new file mode 100644 index 000000000..611604448 --- /dev/null +++ b/test/libc/calls/stackoverflow5_test.c @@ -0,0 +1,86 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-β”‚ +β”‚ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi β”‚ +β•žβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•‘ +β”‚ Copyright 2023 Justine Alexandra Roberts Tunney β”‚ +β”‚ β”‚ +β”‚ Permission to use, copy, modify, and/or distribute this software for β”‚ +β”‚ any purpose with or without fee is hereby granted, provided that the β”‚ +β”‚ above copyright notice and this permission notice appear in all copies. β”‚ +β”‚ β”‚ +β”‚ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL β”‚ +β”‚ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED β”‚ +β”‚ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE β”‚ +β”‚ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL β”‚ +β”‚ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR β”‚ +β”‚ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER β”‚ +β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ +β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ +β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include +#include +#include +#include +#include + +/** + * stack overflow recovery technique #5 + * use the cosmo posix threads extensions + */ + +sig_atomic_t smashed_stack; + +void CrashHandler(int sig) { + smashed_stack = true; + pthread_exit(0); +} + +int StackOverflow(int f(), int n) { + if (n < INT_MAX) { + return f(f, n + 1) - 1; + } else { + return INT_MAX; + } +} + +int (*pStackOverflow)(int (*)(), int) = StackOverflow; + +void *MyPosixThread(void *arg) { + exit(pStackOverflow(pStackOverflow, 0)); + return 0; +} + +int main() { + + // choose the most dangerously small size possible + size_t sigstacksize = sysconf(_SC_MINSIGSTKSZ) + 2048; + + // setup signal handler + struct sigaction sa; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_ONSTACK; + sa.sa_handler = CrashHandler; + if (sigaction(SIGBUS, &sa, 0)) + return 1; + if (sigaction(SIGSEGV, &sa, 0)) + return 2; + + // create thread with signal stack + pthread_t id; + pthread_attr_t attr; + if (pthread_attr_init(&attr)) + return 3; + if (pthread_attr_setguardsize(&attr, getpagesize())) + return 4; + if (pthread_attr_setsigaltstacksize_np(&attr, sigstacksize)) + return 5; + if (pthread_create(&id, &attr, MyPosixThread, 0)) + return 6; + if (pthread_attr_destroy(&attr)) + return 7; + if (pthread_join(id, 0)) + return 8; + if (!smashed_stack) + return 9; + + CheckForMemoryLeaks(); +} diff --git a/test/libc/intrin/cosmo_once_test.c b/test/libc/intrin/cosmo_once_test.c index c0e7d54ee..aaf8cba51 100644 --- a/test/libc/intrin/cosmo_once_test.c +++ b/test/libc/intrin/cosmo_once_test.c @@ -50,12 +50,10 @@ TEST(cosmo_once, test) { pthread_t th[N]; x = y = 0; ASSERT_EQ(0, pthread_barrier_init(&b, 0, N)); - for (i = 0; i < N; ++i) { + for (i = 0; i < N; ++i) ASSERT_EQ(0, pthread_create(th + i, 0, Worker, 0)); - } - for (i = 0; i < N; ++i) { + for (i = 0; i < N; ++i) ASSERT_EQ(0, pthread_join(th[i], 0)); - } ASSERT_EQ(N, atomic_load(&x)); ASSERT_EQ(1, atomic_load(&y)); ASSERT_EQ(0, pthread_barrier_destroy(&b)); diff --git a/test/libc/intrin/mmap_test.c b/test/libc/intrin/mmap_test.c index 7f91daed7..5044d6f96 100644 --- a/test/libc/intrin/mmap_test.c +++ b/test/libc/intrin/mmap_test.c @@ -528,18 +528,21 @@ TEST(mmap, sharedFileMapFork) { int count; void *ptrs[N]; +size_t sizes[N]; void BenchMmapPrivate(void) { void *p; - p = mmap(0, gransz * 10, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, - -1, 0); + p = mmap(0, (sizes[count] = rand() % (pagesz * 500)), PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); if (p == MAP_FAILED) __builtin_trap(); - ptrs[count++] = p; + ptrs[count] = p; + ++count; } void BenchUnmap(void) { - if (munmap(ptrs[--count], gransz * 10)) + --count; + if (munmap(ptrs[count], sizes[count])) __builtin_trap(); } @@ -557,7 +560,7 @@ void BenchBigMunmap(void) { __builtin_trap(); } -BENCH(mmap, bench) { +TEST(mmap, bench) { EZBENCH2("mmap", donothing, BenchMmapPrivate()); EZBENCH2("munmap", donothing, BenchUnmap()); // EZBENCH2("big mmap", donothing, BenchBigMmap()); diff --git a/test/libc/thread/pthread_cancel_deferred_cond_test.c b/test/libc/thread/pthread_cancel_deferred_cond_test.c new file mode 100644 index 000000000..7bf8e1045 --- /dev/null +++ b/test/libc/thread/pthread_cancel_deferred_cond_test.c @@ -0,0 +1,40 @@ +#include +#include +#include +#include + +int got_cleanup; +pthread_cond_t cv = PTHREAD_COND_INITIALIZER; +pthread_mutex_t mu = PTHREAD_MUTEX_INITIALIZER; + +void cleanup(void* arg) { + got_cleanup = 1; +} + +void* worker(void* arg) { + pthread_cleanup_push(cleanup, 0); + if (pthread_mutex_lock(&mu)) + _Exit(11); + pthread_cond_wait(&cv, &mu); + _Exit(12); + pthread_cleanup_pop(0); +} + +int main(int argc, char* argv[]) { + void* rc; + pthread_t th; + if (pthread_create(&th, 0, worker, 0)) + return 2; + if (pthread_cancel(th)) + return 3; + if (pthread_join(th, &rc)) + return 4; + if (rc != PTHREAD_CANCELED) + return 5; + if (!got_cleanup) + return 6; + if (pthread_mutex_trylock(&mu) != EBUSY) + return 7; + if (pthread_mutex_unlock(&mu)) + return 8; +} diff --git a/test/libc/thread/pthread_cancel_masked_cond_test.c b/test/libc/thread/pthread_cancel_masked_cond_test.c new file mode 100644 index 000000000..479ebf48d --- /dev/null +++ b/test/libc/thread/pthread_cancel_masked_cond_test.c @@ -0,0 +1,43 @@ +#include +#include +#include +#include + +int got_cleanup; +pthread_cond_t cv = PTHREAD_COND_INITIALIZER; +pthread_mutex_t mu = PTHREAD_MUTEX_INITIALIZER; + +void cleanup(void* arg) { + got_cleanup = 1; +} + +void* worker(void* arg) { + if (pthread_setcancelstate(PTHREAD_CANCEL_MASKED, 0)) + _Exit(10); + pthread_cleanup_push(cleanup, 0); + if (pthread_mutex_lock(&mu)) + _Exit(11); + if (pthread_cond_wait(&cv, &mu) != ECANCELED) + _Exit(12); + if (pthread_mutex_trylock(&mu) != EBUSY) + _Exit(13); + if (pthread_mutex_unlock(&mu)) + _Exit(14); + pthread_cleanup_pop(0); + return (void*)123; +} + +int main(int argc, char* argv[]) { + void* rc; + pthread_t th; + if (pthread_create(&th, 0, worker, 0)) + return 2; + if (pthread_cancel(th)) + return 3; + if (pthread_join(th, &rc)) + return 4; + if (rc != (void*)123) + return 5; + if (got_cleanup) + return 6; +} diff --git a/test/libc/thread/pthread_cancel_masked_read_test.c b/test/libc/thread/pthread_cancel_masked_read_test.c new file mode 100644 index 000000000..1608df770 --- /dev/null +++ b/test/libc/thread/pthread_cancel_masked_read_test.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include + +int pfds[2]; +int got_cleanup; + +void cleanup(void* arg) { + got_cleanup = 1; +} + +void* worker(void* arg) { + char buf[8]; + if (pthread_setcancelstate(PTHREAD_CANCEL_MASKED, 0)) + _Exit(10); + pthread_cleanup_push(cleanup, 0); + if (read(pfds[0], buf, sizeof(buf)) != -1) + _Exit(11); + if (errno != ECANCELED) + _Exit(12); + pthread_cleanup_pop(0); + return (void*)123; +} + +int main(int argc, char* argv[]) { + void* rc; + pthread_t th; + if (pipe(pfds)) + return 1; + if (pthread_create(&th, 0, worker, 0)) + return 2; + if (pthread_cancel(th)) + return 3; + if (pthread_join(th, &rc)) + return 4; + if (rc != (void*)123) + return 5; + if (got_cleanup) + return 7; +} diff --git a/test/libc/thread/pthread_create_inherit_mask_test.c b/test/libc/thread/pthread_create_inherit_mask_test.c new file mode 100644 index 000000000..58a0460f7 --- /dev/null +++ b/test/libc/thread/pthread_create_inherit_mask_test.c @@ -0,0 +1,30 @@ +#include +#include +#include +#include + +sigset_t parent_mask; +sigset_t child_mask; + +void* worker(void* arg) { + if (pthread_sigmask(SIG_SETMASK, 0, &child_mask)) + _Exit(1); + return 0; +} + +int main(int argc, char* argv[]) { + pthread_t th; + sigemptyset(&parent_mask); + sigaddset(&parent_mask, SIGSYS); + sigaddset(&parent_mask, SIGUSR2); + sigaddset(&parent_mask, SIGWINCH); + if (pthread_sigmask(SIG_SETMASK, &parent_mask, 0)) + return 1; + if (pthread_create(&th, 0, worker, 0)) + return 2; + if (pthread_join(th, 0)) + return 3; + for (int i = 1; i <= _NSIG; ++i) + if (sigismember(&parent_mask, i) != sigismember(&child_mask, i)) + return 4; +} diff --git a/test/libc/thread/pthread_create_test.c b/test/libc/thread/pthread_create_test.c index 697b8f1f0..d977dd0dc 100644 --- a/test/libc/thread/pthread_create_test.c +++ b/test/libc/thread/pthread_create_test.c @@ -34,6 +34,7 @@ #include "libc/runtime/runtime.h" #include "libc/runtime/stack.h" #include "libc/runtime/sysconf.h" +#include "libc/stdio/rand.h" #include "libc/sysv/consts/prot.h" #include "libc/sysv/consts/sa.h" #include "libc/sysv/consts/sched.h" @@ -279,11 +280,10 @@ static void CreateDetached(void) { ASSERT_EQ(0, pthread_attr_destroy(&attr)); } -BENCH(pthread_create, bench) { +TEST(pthread_create, bench) { EZBENCH2("CreateJoin", donothing, CreateJoin()); EZBENCH2("CreateDetach", donothing, CreateDetach()); EZBENCH2("CreateDetached", donothing, CreateDetached()); - while (!pthread_orphan_np()) { - _pthread_decimate(); - } + while (!pthread_orphan_np()) + pthread_decimate_np(); } diff --git a/test/libc/thread/pthread_detach_test.c b/test/libc/thread/pthread_detach_test.c index f491a2da8..d5f7d80a3 100644 --- a/test/libc/thread/pthread_detach_test.c +++ b/test/libc/thread/pthread_detach_test.c @@ -50,9 +50,8 @@ TEST(pthread_detach, testCreateReturn) { pthread_t id; ASSERT_EQ(0, pthread_create(&id, 0, Increment, 0)); ASSERT_EQ(0, pthread_detach(id)); - while (!pthread_orphan_np()) { - _pthread_decimate(); - } + while (!pthread_orphan_np()) + pthread_decimate_np(); } TEST(pthread_detach, testDetachUponCreation) { @@ -62,7 +61,6 @@ TEST(pthread_detach, testDetachUponCreation) { ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)); ASSERT_EQ(0, pthread_create(&th, &attr, Increment, 0)); ASSERT_EQ(0, pthread_attr_destroy(&attr)); - while (!pthread_orphan_np()) { - _pthread_decimate(); - } + while (!pthread_orphan_np()) + pthread_decimate_np(); } From e7be5a5e2b8b46179e7915c5bc0fa91056763ec9 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sun, 21 Jul 2024 15:30:47 -0700 Subject: [PATCH 064/405] Upgrade to latest superconfigure --- tool/cosmocc/package.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tool/cosmocc/package.sh b/tool/cosmocc/package.sh index db8f36fa0..48d2be7c6 100755 --- a/tool/cosmocc/package.sh +++ b/tool/cosmocc/package.sh @@ -118,10 +118,10 @@ fetch() { OLD=$PWD cd "$OUTDIR/" if [ ! -x bin/x86_64-linux-cosmo-gcc ]; then - fetch https://github.com/ahgamut/superconfigure/releases/download/z0.0.45/aarch64-gcc.zip + fetch https://github.com/ahgamut/superconfigure/releases/download/z0.0.46/aarch64-gcc.zip unzip aarch64-gcc.zip rm -f aarch64-gcc.zip - fetch https://github.com/ahgamut/superconfigure/releases/download/z0.0.45/x86_64-gcc.zip + fetch https://github.com/ahgamut/superconfigure/releases/download/z0.0.46/x86_64-gcc.zip unzip x86_64-gcc.zip rm -f x86_64-gcc.zip fi From 7ebaff34c68e243cff0d8a4a680292a08d0ca75b Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sun, 21 Jul 2024 15:54:17 -0700 Subject: [PATCH 065/405] Fix ctype.h and wctype.h --- ctl/istream.cc | 1 + ctl/istringstream.cc | 1 + examples/kilo.c | 1 + examples/ttyinfo.c | 1 + examples/unbourne.c | 17 +++++-- examples/whois.c | 1 + libc/calls/read-nt.c | 3 +- libc/calls/readlinkat-nt.c | 1 + libc/ctype.h | 26 ++++++++++ libc/fmt/atoi.c | 1 + libc/fmt/atol.c | 1 + libc/fmt/internal.h | 1 + libc/fmt/sizetol.c | 1 + libc/intrin/kprintf.greg.c | 1 + libc/isystem/ctype.h | 2 +- libc/isystem/wctype.h | 4 +- libc/proc/cocmd.c | 1 + libc/sock/inet_aton.c | 1 + libc/sock/inet_pton.c | 1 + libc/stdio/fmt.c | 1 + libc/stdio/readpassphrase.c | 1 + libc/stdio/stdio.h | 9 ++-- libc/str/isalnum.c | 2 +- libc/str/isalpha.c | 2 +- libc/str/isascii.c | 2 +- libc/str/isblank.c | 2 +- libc/str/iscntrl.c | 2 +- libc/str/isdigit.c | 2 +- libc/str/isgraph.c | 2 +- libc/str/islower.c | 2 +- libc/str/isprint.c | 2 +- libc/str/ispunct.c | 2 +- libc/str/isspace.c | 2 +- libc/str/isupper.c | 2 +- libc/str/iswalnum.c | 2 +- libc/str/iswalpha.c | 2 +- libc/str/iswblank.c | 2 +- libc/str/iswcntrl.c | 2 +- libc/str/iswctype.c | 2 +- libc/str/iswdigit.c | 2 +- libc/str/iswgraph.c | 2 +- libc/str/iswlower.c | 2 +- libc/str/iswprint.c | 2 +- libc/str/iswpunct.c | 2 +- libc/str/iswseparator.c | 2 +- libc/str/iswspace.c | 2 +- libc/str/iswupper.c | 2 +- libc/str/iswxdigit.c | 2 +- libc/str/isxdigit.c | 5 +- libc/str/str.h | 48 ++----------------- libc/str/strcasecmp16.c | 1 + libc/str/strncasecmp16.c | 1 + libc/str/strverscmp.c | 1 + libc/str/towctrans.c | 2 +- libc/str/wcscasecmp.c | 1 + libc/str/wcsncasecmp.c | 1 + libc/str/wctrans.c | 1 + libc/str/wctype.c | 2 +- libc/str/wcwidth.c | 2 +- libc/testlib/formatint.c | 1 + libc/testlib/formatstr.c | 1 + libc/vga/tty.greg.c | 1 + libc/wctype.h | 35 ++++++++++++++ net/http/isacceptablehost.c | 1 + net/http/parsecidr.c | 1 + net/http/parsecontentlength.c | 1 + net/http/parseforwarded.c | 1 + net/http/parsehttpmessage.c | 1 + net/http/parseip.c | 1 + net/turfwar/blackholed.c | 1 + net/turfwar/turfwar.c | 1 + test/libc/calls/getcwd_test.c | 1 + test/libc/calls/shm_open_test.c | 1 + test/libc/intrin/strcmp_test.c | 1 + test/libc/str/towupper_test.c | 1 + test/tool/build/lib/interner_test.c | 1 + third_party/chibicc/as.c | 1 + third_party/chibicc/asm.c | 1 + third_party/chibicc/tokenize.c | 1 + third_party/ctags/args.c | 1 + third_party/ctags/asm.c | 1 + third_party/ctags/asp.c | 1 + third_party/ctags/awk.c | 1 + third_party/ctags/basic.c | 1 + third_party/ctags/beta.c | 1 + third_party/ctags/eiffel.c | 1 + third_party/ctags/entry.c | 1 + third_party/ctags/erlang.c | 1 + third_party/ctags/flex.c | 2 + third_party/ctags/general.h | 1 + third_party/ctags/get.c | 1 + third_party/ctags/go.c | 1 + third_party/ctags/jscript.c | 2 + third_party/ctags/lisp.c | 1 + third_party/ctags/lregex.c | 1 + third_party/ctags/lua.c | 1 + third_party/ctags/make.c | 1 + third_party/ctags/parse.c | 1 + third_party/ctags/pascal.c | 1 + third_party/ctags/perl.c | 1 + third_party/ctags/python.c | 1 + third_party/ctags/read.c | 1 + third_party/ctags/readtags.c | 1 + third_party/ctags/routines.c | 1 + third_party/ctags/ruby.c | 1 + third_party/ctags/scheme.c | 1 + third_party/ctags/sh.c | 1 + third_party/ctags/sml.c | 1 + third_party/ctags/tcl.c | 1 + third_party/ctags/tex.c | 2 + third_party/ctags/verilog.c | 1 + third_party/ctags/vhdl.c | 1 + third_party/ctags/vim.c | 1 + third_party/ctags/vstring.c | 1 + third_party/finger/util.c | 1 + third_party/hiredis/async.c | 1 + third_party/hiredis/hiredis.c | 1 + third_party/hiredis/read.c | 1 + third_party/hiredis/sds.c | 1 + third_party/linenoise/linenoise.c | 1 + third_party/lua/lbaselib.c | 1 + third_party/lua/liolib.c | 1 + third_party/lua/lstrlib.c | 1 + third_party/lua/luac.main.c | 1 + third_party/musl/crypt_sha256.c | 1 + third_party/musl/crypt_sha512.c | 1 + third_party/musl/fnmatch.c | 1 + third_party/musl/getnameinfo.c | 1 + third_party/musl/lookup_ipliteral.c | 1 + third_party/musl/lookup_name.c | 1 + third_party/musl/lookup_serv.c | 1 + third_party/musl/resolvconf.c | 1 + third_party/musl/strfmon.c | 1 + third_party/musl/strptime.c | 1 + third_party/ncurses/read_entry.c | 1 + third_party/pcre/pcre2_compile.c | 1 + third_party/pcre/pcre2_context.c | 1 + third_party/pcre/pcre2_convert.c | 1 + third_party/pcre/pcre2_maketables.c | 1 + .../python/Modules/_decimal/_decimal.c | 1 + .../python/Modules/_decimal/libmpdec/io.c | 1 + third_party/python/Modules/_hashmbedtls.c | 1 + third_party/python/Objects/bytesobject.c | 1 + third_party/python/Parser/grammar.c | 1 + third_party/python/Parser/tokenizer.c | 1 + third_party/python/runpythonmodule.c | 1 + third_party/regex/regcomp.c | 1 + third_party/regex/tre.inc | 1 + third_party/sed/compile.c | 1 + third_party/sed/process.c | 2 + third_party/sqlite3/completion.c | 1 + third_party/sqlite3/decimal.c | 1 + third_party/sqlite3/geopoly.inc | 1 + third_party/sqlite3/shell.c | 1 + third_party/sqlite3/uint.c | 1 + third_party/tidy/attrs.c | 1 + third_party/tidy/language.c | 1 + third_party/tidy/pprint.c | 1 + third_party/tr/next.c | 1 + third_party/tree/html.c | 1 + third_party/tree/json.c | 1 + third_party/tree/tree.c | 2 + third_party/zlib/trees.c | 1 + tool/build/BUILD.mk | 2 +- tool/build/apelink.c | 1 + tool/build/killall.c | 1 + tool/build/lib/javadown.c | 1 + tool/build/pecheck.c | 1 + tool/build/pledge.c | 1 + tool/decode/ent.c | 1 + tool/decode/x86opinfo.c | 1 + tool/lambda/bru2bin.c | 1 + tool/lambda/lam2bin.c | 2 + tool/lambda/lib/debug.c | 1 + tool/lambda/lib/getbit.c | 1 + tool/net/ljson.c | 1 + tool/net/redbean.c | 1 + tool/viz/life.c | 1 + tool/viz/memzoom.c | 1 + tool/viz/printvideo.c | 1 + 180 files changed, 264 insertions(+), 92 deletions(-) create mode 100644 libc/ctype.h create mode 100644 libc/wctype.h diff --git a/ctl/istream.cc b/ctl/istream.cc index bb2837a0b..fa6d0d1db 100644 --- a/ctl/istream.cc +++ b/ctl/istream.cc @@ -17,6 +17,7 @@ // PERFORMANCE OF THIS SOFTWARE. #include "istream.h" +#include "libc/ctype.h" #include "libc/fmt/conv.h" #include "libc/stdio/stdio.h" #include "libc/str/str.h" diff --git a/ctl/istringstream.cc b/ctl/istringstream.cc index bfaed7a37..254e5d0d6 100644 --- a/ctl/istringstream.cc +++ b/ctl/istringstream.cc @@ -17,6 +17,7 @@ // PERFORMANCE OF THIS SOFTWARE. #include "istringstream.h" +#include "libc/ctype.h" #include "libc/fmt/conv.h" #include "libc/str/str.h" diff --git a/examples/kilo.c b/examples/kilo.c index 055b29853..513b3277e 100644 --- a/examples/kilo.c +++ b/examples/kilo.c @@ -60,6 +60,7 @@ Contact: antirez@gmail.com"); #include "libc/calls/calls.h" #include "libc/calls/termios.h" #include "libc/calls/weirdtypes.h" +#include "libc/ctype.h" #include "libc/errno.h" #include "libc/log/log.h" #include "libc/mem/alg.h" diff --git a/examples/ttyinfo.c b/examples/ttyinfo.c index 6f111acbe..16e3c23a8 100644 --- a/examples/ttyinfo.c +++ b/examples/ttyinfo.c @@ -14,6 +14,7 @@ #include "libc/calls/struct/sigaction.h" #include "libc/calls/struct/sigset.h" #include "libc/calls/termios.h" +#include "libc/ctype.h" #include "libc/errno.h" #include "libc/log/check.h" #include "libc/log/log.h" diff --git a/examples/unbourne.c b/examples/unbourne.c index 0500f1088..81f67fea3 100644 --- a/examples/unbourne.c +++ b/examples/unbourne.c @@ -119,6 +119,7 @@ #include "libc/calls/struct/stat.h" #include "libc/calls/struct/tms.h" #include "libc/calls/termios.h" +#include "libc/ctype.h" #include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/conv.h" @@ -11142,7 +11143,9 @@ static void exitreset() { inps4 = 0; } /* from expand.c: */ - { ifsfree(); } + { + ifsfree(); + } /* from redir.c: */ { /* @@ -11165,9 +11168,13 @@ static void forkreset() { } } /* from main.c: */ - { handler = &main_handler; } + { + handler = &main_handler; + } /* from redir.c: */ - { redirlist = NULL; } + { + redirlist = NULL; + } /* from trap.c: */ { char **tp; @@ -11198,7 +11205,9 @@ static void reset() { popallfiles(); } /* from var.c: */ - { unwindlocalvars(0); } + { + unwindlocalvars(0); + } } static void calcsize(union node *n) { diff --git a/examples/whois.c b/examples/whois.c index 95154787f..81b3e0214 100644 --- a/examples/whois.c +++ b/examples/whois.c @@ -30,6 +30,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" #include "libc/calls/weirdtypes.h" +#include "libc/ctype.h" #include "libc/errno.h" #include "libc/log/bsd.h" #include "libc/mem/mem.h" diff --git a/libc/calls/read-nt.c b/libc/calls/read-nt.c index e49d6b3d7..bd460a4f3 100644 --- a/libc/calls/read-nt.c +++ b/libc/calls/read-nt.c @@ -20,15 +20,16 @@ #include "libc/calls/internal.h" #include "libc/calls/sig.internal.h" #include "libc/calls/state.internal.h" -#include "libc/intrin/fds.h" #include "libc/calls/struct/iovec.h" #include "libc/calls/struct/sigset.internal.h" #include "libc/calls/syscall_support-nt.internal.h" #include "libc/cosmo.h" +#include "libc/ctype.h" #include "libc/errno.h" #include "libc/fmt/itoa.h" #include "libc/intrin/describeflags.h" #include "libc/intrin/dll.h" +#include "libc/intrin/fds.h" #include "libc/intrin/nomultics.h" #include "libc/intrin/strace.h" #include "libc/intrin/weaken.h" diff --git a/libc/calls/readlinkat-nt.c b/libc/calls/readlinkat-nt.c index 9a82c9845..bd2423272 100644 --- a/libc/calls/readlinkat-nt.c +++ b/libc/calls/readlinkat-nt.c @@ -18,6 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/struct/sigset.internal.h" #include "libc/calls/syscall_support-nt.internal.h" +#include "libc/ctype.h" #include "libc/intrin/strace.h" #include "libc/mem/alloca.h" #include "libc/nt/createfile.h" diff --git a/libc/ctype.h b/libc/ctype.h new file mode 100644 index 000000000..b7fabc097 --- /dev/null +++ b/libc/ctype.h @@ -0,0 +1,26 @@ +#ifndef COSMOPOLITAN_CTYPE_H_ +#define COSMOPOLITAN_CTYPE_H_ +COSMOPOLITAN_C_START_ + +#define _tolower(u) (0040 | (u)) +#define _toupper(u) (0137 & (u)) + +int isascii(int) libcesque; +int isspace(int) libcesque; +int isalpha(int) libcesque; +int isdigit(int) libcesque; +int isalnum(int) libcesque; +int isxdigit(int) libcesque; +int isprint(int) libcesque; +int islower(int) libcesque; +int isupper(int) libcesque; +int isblank(int) libcesque; +int iscntrl(int) libcesque; +int isgraph(int) libcesque; +int tolower(int) libcesque; +int ispunct(int) libcesque; +int toupper(int) libcesque; +int toascii(int) libcesque; + +COSMOPOLITAN_C_END_ +#endif /* COSMOPOLITAN_CTYPE_H_ */ diff --git a/libc/fmt/atoi.c b/libc/fmt/atoi.c index bca5be980..ac2450add 100644 --- a/libc/fmt/atoi.c +++ b/libc/fmt/atoi.c @@ -16,6 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/ctype.h" #include "libc/fmt/conv.h" #include "libc/str/str.h" diff --git a/libc/fmt/atol.c b/libc/fmt/atol.c index 5bce5bcac..c922b82d2 100644 --- a/libc/fmt/atol.c +++ b/libc/fmt/atol.c @@ -16,6 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/ctype.h" #include "libc/fmt/conv.h" #include "libc/str/str.h" diff --git a/libc/fmt/internal.h b/libc/fmt/internal.h index b05b1085b..65e80281a 100644 --- a/libc/fmt/internal.h +++ b/libc/fmt/internal.h @@ -1,5 +1,6 @@ #ifndef COSMOPOLITAN_LIBC_FMT_STRTOL_H_ #define COSMOPOLITAN_LIBC_FMT_STRTOL_H_ +#include "libc/ctype.h" #include "libc/errno.h" #include "libc/str/str.h" diff --git a/libc/fmt/sizetol.c b/libc/fmt/sizetol.c index e1828fc9d..e1d8b3107 100644 --- a/libc/fmt/sizetol.c +++ b/libc/fmt/sizetol.c @@ -16,6 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/ctype.h" #include "libc/fmt/conv.h" #include "libc/stdckdint.h" #include "libc/str/str.h" diff --git a/libc/intrin/kprintf.greg.c b/libc/intrin/kprintf.greg.c index 1677f8953..21eac26a6 100644 --- a/libc/intrin/kprintf.greg.c +++ b/libc/intrin/kprintf.greg.c @@ -65,6 +65,7 @@ #include "libc/thread/tls.h" #include "libc/thread/tls2.internal.h" #include "libc/vga/vga.internal.h" +#include "libc/wctype.h" #define STACK_ERROR "kprintf error: stack is about to overflow\n" diff --git a/libc/isystem/ctype.h b/libc/isystem/ctype.h index c375b5004..5fcf04c7a 100644 --- a/libc/isystem/ctype.h +++ b/libc/isystem/ctype.h @@ -1,4 +1,4 @@ #ifndef _CTYPE_H #define _CTYPE_H -#include "libc/str/str.h" +#include "libc/ctype.h" #endif /* _CTYPE_H */ diff --git a/libc/isystem/wctype.h b/libc/isystem/wctype.h index ba782a3bc..4de842c45 100644 --- a/libc/isystem/wctype.h +++ b/libc/isystem/wctype.h @@ -1,6 +1,4 @@ #ifndef _WCTYPE_H #define _WCTYPE_H -#include "libc/calls/calls.h" -#include "libc/fmt/conv.h" -#include "libc/str/str.h" +#include "libc/wctype.h" #endif /* _WCTYPE_H */ diff --git a/libc/proc/cocmd.c b/libc/proc/cocmd.c index 7babef174..4632ab559 100644 --- a/libc/proc/cocmd.c +++ b/libc/proc/cocmd.c @@ -20,6 +20,7 @@ #include "libc/calls/calls.h" #include "libc/calls/struct/stat.h" #include "libc/calls/struct/timespec.h" +#include "libc/ctype.h" #include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/conv.h" diff --git a/libc/sock/inet_aton.c b/libc/sock/inet_aton.c index d08e5c0d9..270033eb0 100644 --- a/libc/sock/inet_aton.c +++ b/libc/sock/inet_aton.c @@ -25,6 +25,7 @@ β”‚ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. β”‚ β”‚ β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/ctype.h" #include "libc/fmt/conv.h" #include "libc/sock/sock.h" #include "libc/sock/struct/sockaddr.h" diff --git a/libc/sock/inet_pton.c b/libc/sock/inet_pton.c index 5693977b9..dd226eaae 100644 --- a/libc/sock/inet_pton.c +++ b/libc/sock/inet_pton.c @@ -16,6 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/ctype.h" #include "libc/macros.internal.h" #include "libc/sock/internal.h" #include "libc/sock/sock.h" diff --git a/libc/stdio/fmt.c b/libc/stdio/fmt.c index cafe4f63e..69d6da94f 100644 --- a/libc/stdio/fmt.c +++ b/libc/stdio/fmt.c @@ -39,6 +39,7 @@ β”‚ THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/assert.h" +#include "libc/ctype.h" #include "libc/errno.h" #include "libc/fmt/conv.h" #include "libc/fmt/divmod10.internal.h" diff --git a/libc/stdio/readpassphrase.c b/libc/stdio/readpassphrase.c index bff7a96f3..140c2134e 100644 --- a/libc/stdio/readpassphrase.c +++ b/libc/stdio/readpassphrase.c @@ -26,6 +26,7 @@ #include "libc/calls/calls.h" #include "libc/calls/struct/sigaction.h" #include "libc/calls/termios.h" +#include "libc/ctype.h" #include "libc/errno.h" #include "libc/paths.h" #include "libc/str/str.h" diff --git a/libc/stdio/stdio.h b/libc/stdio/stdio.h index d9f560b2b..02773651b 100644 --- a/libc/stdio/stdio.h +++ b/libc/stdio/stdio.h @@ -1,11 +1,10 @@ #ifndef COSMOPOLITAN_LIBC_STDIO_H_ #define COSMOPOLITAN_LIBC_STDIO_H_ -#define EOF -1 /* end of file */ -#define WEOF -1u /* end of file (multibyte) */ -#define _IOFBF 0 /* fully buffered */ -#define _IOLBF 1 /* line buffered */ -#define _IONBF 2 /* no buffering */ +#define EOF -1 /* end of file */ +#define _IOFBF 0 /* fully buffered */ +#define _IOLBF 1 /* line buffered */ +#define _IONBF 2 /* no buffering */ #define L_tmpnam 20 #define L_ctermid 20 diff --git a/libc/str/isalnum.c b/libc/str/isalnum.c index e202f503b..910cebbe3 100644 --- a/libc/str/isalnum.c +++ b/libc/str/isalnum.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/str/str.h" +#include "libc/ctype.h" /** * Returns nonzero if c is lower, alpha, or digit. diff --git a/libc/str/isalpha.c b/libc/str/isalpha.c index 6aee95aa8..5e4823f08 100644 --- a/libc/str/isalpha.c +++ b/libc/str/isalpha.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/str/str.h" +#include "libc/ctype.h" /** * Returns nonzero if c is upper or lower. diff --git a/libc/str/isascii.c b/libc/str/isascii.c index 1a85dd308..617830d5b 100644 --- a/libc/str/isascii.c +++ b/libc/str/isascii.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/str/str.h" +#include "libc/ctype.h" /** * Returns nonzero if c is ascii. diff --git a/libc/str/isblank.c b/libc/str/isblank.c index c99897b19..71b63e3ae 100644 --- a/libc/str/isblank.c +++ b/libc/str/isblank.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/str/str.h" +#include "libc/ctype.h" /** * Returns nonzero if c is space or tab. diff --git a/libc/str/iscntrl.c b/libc/str/iscntrl.c index 7e3fef430..a98c3f754 100644 --- a/libc/str/iscntrl.c +++ b/libc/str/iscntrl.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/str/str.h" +#include "libc/ctype.h" /** * Returns nonzero if c is C0 ASCII control code or DEL. diff --git a/libc/str/isdigit.c b/libc/str/isdigit.c index b7400f4ad..da34a2f85 100644 --- a/libc/str/isdigit.c +++ b/libc/str/isdigit.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/str/str.h" +#include "libc/ctype.h" /** * Returns nonzero if c is decimal digit. diff --git a/libc/str/isgraph.c b/libc/str/isgraph.c index cd2401b50..46bc713f4 100644 --- a/libc/str/isgraph.c +++ b/libc/str/isgraph.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/str/str.h" +#include "libc/ctype.h" /** * Returns nonzero if c is printable ascii that isn't space. diff --git a/libc/str/islower.c b/libc/str/islower.c index 49ecc83b4..f9a764d81 100644 --- a/libc/str/islower.c +++ b/libc/str/islower.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/str/str.h" +#include "libc/ctype.h" /** * Returns nonzero if c is lowercase alpha ascii character. diff --git a/libc/str/isprint.c b/libc/str/isprint.c index d27c40dd2..8f3c81edb 100644 --- a/libc/str/isprint.c +++ b/libc/str/isprint.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/str/str.h" +#include "libc/ctype.h" /** * Returns nonzero if c is printable ascii including space. diff --git a/libc/str/ispunct.c b/libc/str/ispunct.c index 6928950d7..a67f9137b 100644 --- a/libc/str/ispunct.c +++ b/libc/str/ispunct.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/str/str.h" +#include "libc/ctype.h" /** * Returns nonzero if ``c ∈ !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~`` diff --git a/libc/str/isspace.c b/libc/str/isspace.c index a82c74be4..350efb337 100644 --- a/libc/str/isspace.c +++ b/libc/str/isspace.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/str/str.h" +#include "libc/ctype.h" /** * Returns nonzero if c is space, \t, \r, \n, \f, or \v. diff --git a/libc/str/isupper.c b/libc/str/isupper.c index 1666bc28b..d07bace8b 100644 --- a/libc/str/isupper.c +++ b/libc/str/isupper.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/str/str.h" +#include "libc/ctype.h" /** * Returns nonzero if c is uppercase alpha ascii character. diff --git a/libc/str/iswalnum.c b/libc/str/iswalnum.c index f08c085d7..7c979def3 100644 --- a/libc/str/iswalnum.c +++ b/libc/str/iswalnum.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/str/str.h" +#include "libc/wctype.h" /** * Returns nonzero if c is lower, alpha, or digit. diff --git a/libc/str/iswalpha.c b/libc/str/iswalpha.c index db8872b1f..573392d42 100644 --- a/libc/str/iswalpha.c +++ b/libc/str/iswalpha.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/str/str.h" +#include "libc/wctype.h" /** * Returns nonzero if c is alphabetical. diff --git a/libc/str/iswblank.c b/libc/str/iswblank.c index 07a7b9bb9..4d42bcc6d 100644 --- a/libc/str/iswblank.c +++ b/libc/str/iswblank.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/str/str.h" +#include "libc/wctype.h" /** * Returns nonzero if c is space or tab. diff --git a/libc/str/iswcntrl.c b/libc/str/iswcntrl.c index 2a103395f..b67dbf854 100644 --- a/libc/str/iswcntrl.c +++ b/libc/str/iswcntrl.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/str/str.h" +#include "libc/wctype.h" /** * Returns nonzero if c is C0 or C1 control code. diff --git a/libc/str/iswctype.c b/libc/str/iswctype.c index 9aefb7278..0c2b83fab 100644 --- a/libc/str/iswctype.c +++ b/libc/str/iswctype.c @@ -17,7 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/macros.internal.h" -#include "libc/str/str.h" +#include "libc/wctype.h" typedef int (*isw_f)(wint_t); diff --git a/libc/str/iswdigit.c b/libc/str/iswdigit.c index 6d7b0232c..16ae3d9a6 100644 --- a/libc/str/iswdigit.c +++ b/libc/str/iswdigit.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/str/str.h" +#include "libc/wctype.h" /** * Returns nonzero if c is decimal digit. diff --git a/libc/str/iswgraph.c b/libc/str/iswgraph.c index 8e420286a..def864fc0 100644 --- a/libc/str/iswgraph.c +++ b/libc/str/iswgraph.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/str/str.h" +#include "libc/wctype.h" /** * Returns nonzero if c is printable and not a space. diff --git a/libc/str/iswlower.c b/libc/str/iswlower.c index aba9180c6..546ee379f 100644 --- a/libc/str/iswlower.c +++ b/libc/str/iswlower.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/str/str.h" +#include "libc/wctype.h" /** * Returns nonzero if c is lowercase letter. diff --git a/libc/str/iswprint.c b/libc/str/iswprint.c index 95e2e6cf1..030e45d46 100644 --- a/libc/str/iswprint.c +++ b/libc/str/iswprint.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/str/str.h" +#include "libc/wctype.h" /** * Returns nonzero if c is printable. diff --git a/libc/str/iswpunct.c b/libc/str/iswpunct.c index 96c16f34b..d66779b76 100644 --- a/libc/str/iswpunct.c +++ b/libc/str/iswpunct.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/str/str.h" +#include "libc/wctype.h" /** * Returns nonzero if c is punctuation mark. diff --git a/libc/str/iswseparator.c b/libc/str/iswseparator.c index 2a3a24d86..224fec28a 100644 --- a/libc/str/iswseparator.c +++ b/libc/str/iswseparator.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/str/str.h" +#include "libc/wctype.h" static const unsigned short kCodes[][2] = { {0x00aa, 0x00aa}, /* 1x English */ diff --git a/libc/str/iswspace.c b/libc/str/iswspace.c index d97a48242..44d62af9d 100644 --- a/libc/str/iswspace.c +++ b/libc/str/iswspace.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/str/str.h" +#include "libc/wctype.h" /** * Returns nonzero if c is space character. diff --git a/libc/str/iswupper.c b/libc/str/iswupper.c index f965d51a6..aad3dd6e7 100644 --- a/libc/str/iswupper.c +++ b/libc/str/iswupper.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/str/str.h" +#include "libc/wctype.h" /** * Returns nonzero if c is uppercase letter. diff --git a/libc/str/iswxdigit.c b/libc/str/iswxdigit.c index c325efc6f..75e4347f2 100644 --- a/libc/str/iswxdigit.c +++ b/libc/str/iswxdigit.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/str/str.h" +#include "libc/wctype.h" /** * Returns nonzero if c is ascii hex digit. diff --git a/libc/str/isxdigit.c b/libc/str/isxdigit.c index e31788738..03af7c9cc 100644 --- a/libc/str/isxdigit.c +++ b/libc/str/isxdigit.c @@ -16,10 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/assert.h" -#include "libc/calls/calls.h" -#include "libc/limits.h" -#include "libc/str/str.h" +#include "libc/ctype.h" /** * Returns true if c is hexadecimal digit. diff --git a/libc/str/str.h b/libc/str/str.h index fdc97b244..ed9553633 100644 --- a/libc/str/str.h +++ b/libc/str/str.h @@ -3,9 +3,6 @@ #define INVALID_CODEPOINT 0xfffd -#define _tolower(u) (0040 | (u)) -#define _toupper(u) (0137 & (u)) - #ifdef _COSMO_SOURCE #define chomp _chomp #define chomp16 _chomp16 @@ -20,42 +17,13 @@ #define wcsstartswith _wcsstartswith #endif /* _COSMO_SOURCE */ +#ifndef WEOF +#define WEOF -1u +#endif + #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -int isascii(int) libcesque; -int isspace(int) libcesque; -int isalpha(int) libcesque; -int isdigit(int) libcesque; -int isalnum(int) libcesque; -int isxdigit(int) libcesque; -int isprint(int) libcesque; -int islower(int) libcesque; -int isupper(int) libcesque; -int isblank(int) libcesque; -int iscntrl(int) libcesque; -int isgraph(int) libcesque; -int tolower(int) libcesque; -int ispunct(int) libcesque; -int toupper(int) libcesque; -int toascii(int) libcesque; - -int iswalnum(wint_t) libcesque; -int iswalpha(wint_t) libcesque; -int iswblank(wint_t) libcesque; -int iswcntrl(wint_t) libcesque; -int iswdigit(wint_t) libcesque; -int iswgraph(wint_t) libcesque; -int iswlower(wint_t) libcesque; -int iswspace(wint_t) libcesque; -int iswupper(wint_t) libcesque; -int iswxdigit(wint_t) libcesque; -int iswpunct(wint_t) libcesque; -int iswprint(wint_t) libcesque; -int iswseparator(wint_t) libcesque; -wint_t towlower(wint_t) libcesque; -wint_t towupper(wint_t) libcesque; - void *memset(void *, int, size_t) memcpyesque; void *memmove(void *, const void *, size_t) memcpyesque; void *memcpy(void *restrict, const void *restrict, size_t) memcpyesque; @@ -157,14 +125,6 @@ int wctomb(char *, wchar_t) libcesque; int wctob(wint_t) libcesque; wint_t btowc(int) libcesque; -typedef unsigned wctype_t; -wctype_t wctype(const char *) strlenesque; -pureconst int iswctype(wint_t, wctype_t) libcesque; - -typedef const int *wctrans_t; -wctrans_t wctrans(const char *) libcesque; -wint_t towctrans(wint_t, wctrans_t) libcesque; - int getsubopt(char **, char *const *, char **) libcesque paramsnonnull(); char *strsignal(int) returnsnonnull libcesque; char *strerror(int) returnsnonnull dontthrow dontcallback; diff --git a/libc/str/strcasecmp16.c b/libc/str/strcasecmp16.c index 8420ba882..49f0d9c05 100644 --- a/libc/str/strcasecmp16.c +++ b/libc/str/strcasecmp16.c @@ -17,6 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/str/str.h" +#include "libc/wctype.h" /** * Compares NUL-terminated UCS-2 strings case-insensitively. diff --git a/libc/str/strncasecmp16.c b/libc/str/strncasecmp16.c index 4d39f6bea..8919e866a 100644 --- a/libc/str/strncasecmp16.c +++ b/libc/str/strncasecmp16.c @@ -17,6 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/str/str.h" +#include "libc/wctype.h" /** * Compares NUL-terminated UCS-2 strings case-insensitively w/ limit. diff --git a/libc/str/strverscmp.c b/libc/str/strverscmp.c index 3cc3740ef..22596fc49 100644 --- a/libc/str/strverscmp.c +++ b/libc/str/strverscmp.c @@ -25,6 +25,7 @@ β”‚ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. β”‚ β”‚ β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/ctype.h" #include "libc/str/str.h" __static_yoink("musl_libc_notice"); diff --git a/libc/str/towctrans.c b/libc/str/towctrans.c index 87f1a87bc..ed928df67 100644 --- a/libc/str/towctrans.c +++ b/libc/str/towctrans.c @@ -16,7 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/str/str.h" +#include "libc/wctype.h" wint_t towctrans(wint_t c, wctrans_t t) { if (t == (wctrans_t)1) diff --git a/libc/str/wcscasecmp.c b/libc/str/wcscasecmp.c index 8f32d77cc..288eb5da4 100644 --- a/libc/str/wcscasecmp.c +++ b/libc/str/wcscasecmp.c @@ -17,6 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/str/str.h" +#include "libc/wctype.h" /** * Compares NUL-terminated wide strings case-insensitively. diff --git a/libc/str/wcsncasecmp.c b/libc/str/wcsncasecmp.c index b98b4baaa..c91af94e9 100644 --- a/libc/str/wcsncasecmp.c +++ b/libc/str/wcsncasecmp.c @@ -17,6 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/str/str.h" +#include "libc/wctype.h" /** * Compares NUL-terminated wide strings case-insensitively w/ limit. diff --git a/libc/str/wctrans.c b/libc/str/wctrans.c index 2fa75a817..19c4fa376 100644 --- a/libc/str/wctrans.c +++ b/libc/str/wctrans.c @@ -17,6 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/str/str.h" +#include "libc/wctype.h" wctrans_t wctrans(const char *s) { if (!strcmp(s, "toupper")) diff --git a/libc/str/wctype.c b/libc/str/wctype.c index 588439a25..20516dc47 100644 --- a/libc/str/wctype.c +++ b/libc/str/wctype.c @@ -16,9 +16,9 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/wctype.h" #include "libc/macros.internal.h" #include "libc/serialize.h" -#include "libc/str/str.h" static const char kWcTypeNames[][8] = { "alnum", // diff --git a/libc/str/wcwidth.c b/libc/str/wcwidth.c index 093133c2e..66a7a9113 100644 --- a/libc/str/wcwidth.c +++ b/libc/str/wcwidth.c @@ -17,9 +17,9 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/intrin/likely.h" -#include "libc/str/str.h" #include "libc/str/unicode.h" #include "libc/str/wcwidth_osx.internal.h" +#include "libc/wctype.h" /** * Returns cell width of monospace character. diff --git a/libc/testlib/formatint.c b/libc/testlib/formatint.c index 169ab7654..cf349237b 100644 --- a/libc/testlib/formatint.c +++ b/libc/testlib/formatint.c @@ -17,6 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/atomic.h" +#include "libc/ctype.h" #include "libc/fmt/itoa.h" #include "libc/fmt/magnumstrs.internal.h" #include "libc/intrin/atomic.h" diff --git a/libc/testlib/formatstr.c b/libc/testlib/formatstr.c index be7ffc145..9775cbbaa 100644 --- a/libc/testlib/formatstr.c +++ b/libc/testlib/formatstr.c @@ -16,6 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/ctype.h" #include "libc/intrin/atomic.h" #include "libc/serialize.h" #include "libc/str/str.h" diff --git a/libc/vga/tty.greg.c b/libc/vga/tty.greg.c index 85ce5f74a..ad1f009d7 100644 --- a/libc/vga/tty.greg.c +++ b/libc/vga/tty.greg.c @@ -16,6 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/ctype.h" #include "libc/fmt/bing.internal.h" #include "libc/fmt/itoa.h" #include "libc/intrin/directmap.h" diff --git a/libc/wctype.h b/libc/wctype.h new file mode 100644 index 000000000..af1c246fe --- /dev/null +++ b/libc/wctype.h @@ -0,0 +1,35 @@ +#ifndef COSMOPOLITAN_WCTYPE_H_ +#define COSMOPOLITAN_WCTYPE_H_ +COSMOPOLITAN_C_START_ + +#ifndef WEOF +#define WEOF -1u +#endif + +typedef unsigned wctype_t; +typedef const int *wctrans_t; + +int iswalnum(wint_t) libcesque; +int iswalpha(wint_t) libcesque; +int iswblank(wint_t) libcesque; +int iswcntrl(wint_t) libcesque; +int iswdigit(wint_t) libcesque; +int iswgraph(wint_t) libcesque; +int iswlower(wint_t) libcesque; +int iswspace(wint_t) libcesque; +int iswupper(wint_t) libcesque; +int iswxdigit(wint_t) libcesque; +int iswpunct(wint_t) libcesque; +int iswprint(wint_t) libcesque; +int iswseparator(wint_t) libcesque; +wint_t towlower(wint_t) libcesque; +wint_t towupper(wint_t) libcesque; + +wctype_t wctype(const char *) strlenesque; +pureconst int iswctype(wint_t, wctype_t) libcesque; + +wctrans_t wctrans(const char *) libcesque; +wint_t towctrans(wint_t, wctrans_t) libcesque; + +COSMOPOLITAN_C_END_ +#endif /* COSMOPOLITAN_WCTYPE_H_ */ diff --git a/net/http/isacceptablehost.c b/net/http/isacceptablehost.c index f8dc7feed..1eb8ff046 100644 --- a/net/http/isacceptablehost.c +++ b/net/http/isacceptablehost.c @@ -16,6 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/ctype.h" #include "libc/str/str.h" #include "net/http/http.h" diff --git a/net/http/parsecidr.c b/net/http/parsecidr.c index 01ede3523..5fb1f6fbb 100644 --- a/net/http/parsecidr.c +++ b/net/http/parsecidr.c @@ -16,6 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/ctype.h" #include "libc/str/str.h" #include "net/http/ip.h" diff --git a/net/http/parsecontentlength.c b/net/http/parsecontentlength.c index 3755e63ff..d2bf3ae85 100644 --- a/net/http/parsecontentlength.c +++ b/net/http/parsecontentlength.c @@ -16,6 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/ctype.h" #include "libc/stdckdint.h" #include "libc/str/str.h" #include "net/http/http.h" diff --git a/net/http/parseforwarded.c b/net/http/parseforwarded.c index 0d3e746b3..f999f3f71 100644 --- a/net/http/parseforwarded.c +++ b/net/http/parseforwarded.c @@ -16,6 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/ctype.h" #include "libc/str/str.h" #include "net/http/http.h" diff --git a/net/http/parsehttpmessage.c b/net/http/parsehttpmessage.c index 91ef243b7..1a52fce57 100644 --- a/net/http/parsehttpmessage.c +++ b/net/http/parsehttpmessage.c @@ -17,6 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/assert.h" +#include "libc/ctype.h" #include "libc/limits.h" #include "libc/mem/alg.h" #include "libc/mem/arraylist.internal.h" diff --git a/net/http/parseip.c b/net/http/parseip.c index 700f49044..72df550ea 100644 --- a/net/http/parseip.c +++ b/net/http/parseip.c @@ -16,6 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/ctype.h" #include "libc/stdckdint.h" #include "libc/str/str.h" #include "net/http/ip.h" diff --git a/net/turfwar/blackholed.c b/net/turfwar/blackholed.c index ccbd8a5ef..a7175dbd7 100644 --- a/net/turfwar/blackholed.c +++ b/net/turfwar/blackholed.c @@ -22,6 +22,7 @@ #include "libc/calls/struct/sigset.h" #include "libc/calls/struct/sigset.internal.h" #include "libc/calls/struct/timespec.h" +#include "libc/ctype.h" #include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/conv.h" diff --git a/net/turfwar/turfwar.c b/net/turfwar/turfwar.c index 41a37df79..6a0b956cc 100644 --- a/net/turfwar/turfwar.c +++ b/net/turfwar/turfwar.c @@ -27,6 +27,7 @@ #include "libc/calls/struct/sysinfo.h" #include "libc/calls/struct/timespec.h" #include "libc/calls/struct/timeval.h" +#include "libc/ctype.h" #include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/conv.h" diff --git a/test/libc/calls/getcwd_test.c b/test/libc/calls/getcwd_test.c index f9e8f22e3..0cd9919a6 100644 --- a/test/libc/calls/getcwd_test.c +++ b/test/libc/calls/getcwd_test.c @@ -17,6 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" +#include "libc/ctype.h" #include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/libgen.h" diff --git a/test/libc/calls/shm_open_test.c b/test/libc/calls/shm_open_test.c index da7909fef..3a83ea298 100644 --- a/test/libc/calls/shm_open_test.c +++ b/test/libc/calls/shm_open_test.c @@ -5,6 +5,7 @@ #include "libc/atomic.h" #include "libc/calls/calls.h" #include "libc/calls/struct/sigaction.h" +#include "libc/ctype.h" #include "libc/dce.h" #include "libc/errno.h" #include "libc/runtime/runtime.h" diff --git a/test/libc/intrin/strcmp_test.c b/test/libc/intrin/strcmp_test.c index a17153f58..742dac914 100644 --- a/test/libc/intrin/strcmp_test.c +++ b/test/libc/intrin/strcmp_test.c @@ -17,6 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/assert.h" +#include "libc/ctype.h" #include "libc/dce.h" #include "libc/macros.internal.h" #include "libc/mem/gc.h" diff --git a/test/libc/str/towupper_test.c b/test/libc/str/towupper_test.c index 479e41c94..b0779d608 100644 --- a/test/libc/str/towupper_test.c +++ b/test/libc/str/towupper_test.c @@ -20,6 +20,7 @@ #include "libc/str/str.h" #include "libc/testlib/ezbench.h" #include "libc/testlib/testlib.h" +#include "libc/wctype.h" TEST(iswupper, test) { EXPECT_TRUE(iswupper(L'𝐡')); diff --git a/test/tool/build/lib/interner_test.c b/test/tool/build/lib/interner_test.c index b26709ae7..ece510d30 100644 --- a/test/tool/build/lib/interner_test.c +++ b/test/tool/build/lib/interner_test.c @@ -17,6 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "tool/build/lib/interner.h" +#include "libc/ctype.h" #include "libc/mem/gc.h" #include "libc/mem/mem.h" #include "libc/stdio/stdio.h" diff --git a/third_party/chibicc/as.c b/third_party/chibicc/as.c index e4aa4b02c..e17c68d27 100644 --- a/third_party/chibicc/as.c +++ b/third_party/chibicc/as.c @@ -38,6 +38,7 @@ #include "third_party/chibicc/file.h" #include "third_party/gdtoa/gdtoa.h" #include "libc/serialize.h" +#include "libc/ctype.h" #include "tool/build/lib/elfwriter.h" #define OSZ 0x66 diff --git a/third_party/chibicc/asm.c b/third_party/chibicc/asm.c index 7a10b8631..5dd73b871 100644 --- a/third_party/chibicc/asm.c +++ b/third_party/chibicc/asm.c @@ -18,6 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/intrin/bsf.h" #include "libc/intrin/bsr.h" +#include "libc/ctype.h" #include "third_party/chibicc/chibicc.h" #define PRECIOUS 0b1111000000101000 // bx,bp,r12-r15 diff --git a/third_party/chibicc/tokenize.c b/third_party/chibicc/tokenize.c index 15ba6c6e5..cc297966a 100644 --- a/third_party/chibicc/tokenize.c +++ b/third_party/chibicc/tokenize.c @@ -5,6 +5,7 @@ #include "libc/str/tab.internal.h" #include "third_party/chibicc/chibicc.h" #include "third_party/chibicc/file.h" +#include "libc/ctype.h" #include "third_party/chibicc/kw.h" // Input file diff --git a/third_party/ctags/args.c b/third_party/ctags/args.c index e8770d204..0dec366a6 100644 --- a/third_party/ctags/args.c +++ b/third_party/ctags/args.c @@ -13,6 +13,7 @@ #include "libc/str/str.h" #include "third_party/ctags/args.h" #include "third_party/ctags/debug.h" +#include "libc/ctype.h" #include "third_party/ctags/routines.h" /* diff --git a/third_party/ctags/asm.c b/third_party/ctags/asm.c index 3b3cc3a40..02069ca36 100644 --- a/third_party/ctags/asm.c +++ b/third_party/ctags/asm.c @@ -13,6 +13,7 @@ /* * INCLUDE FILES */ +#include "libc/ctype.h" #include "third_party/ctags/general.h" /* must always come first */ #include "libc/mem/alg.h" diff --git a/third_party/ctags/asp.c b/third_party/ctags/asp.c index fd8d1df75..8e90b4cfe 100644 --- a/third_party/ctags/asp.c +++ b/third_party/ctags/asp.c @@ -13,6 +13,7 @@ /* * INCLUDE FILES */ +#include "libc/ctype.h" #include "third_party/ctags/general.h" /* must always come first */ #include "libc/mem/alg.h" diff --git a/third_party/ctags/awk.c b/third_party/ctags/awk.c index ab4c17ca3..8a3fd2add 100644 --- a/third_party/ctags/awk.c +++ b/third_party/ctags/awk.c @@ -12,6 +12,7 @@ /* * INCLUDE FILES */ +#include "libc/ctype.h" #include "third_party/ctags/general.h" /* must always come first */ #include "libc/mem/alg.h" diff --git a/third_party/ctags/basic.c b/third_party/ctags/basic.c index b53b97b2b..89be4b8c2 100644 --- a/third_party/ctags/basic.c +++ b/third_party/ctags/basic.c @@ -15,6 +15,7 @@ /* * INCLUDE FILES */ +#include "libc/ctype.h" #include "third_party/ctags/general.h" /* must always come first */ #include "libc/mem/alg.h" diff --git a/third_party/ctags/beta.c b/third_party/ctags/beta.c index 08d1c3d4d..7fa63c2f4 100644 --- a/third_party/ctags/beta.c +++ b/third_party/ctags/beta.c @@ -15,6 +15,7 @@ /* * INCLUDE FILES */ +#include "libc/ctype.h" #include "third_party/ctags/general.h" /* must always come first */ #include "libc/mem/alg.h" diff --git a/third_party/ctags/eiffel.c b/third_party/ctags/eiffel.c index 0a4d0042e..1f2a48da8 100644 --- a/third_party/ctags/eiffel.c +++ b/third_party/ctags/eiffel.c @@ -14,6 +14,7 @@ * INCLUDE FILES */ #include "libc/fmt/conv.h" +#include "libc/ctype.h" #include "third_party/ctags/general.h" /* must always come first */ #ifdef TYPE_REFERENCE_TOOL diff --git a/third_party/ctags/entry.c b/third_party/ctags/entry.c index 13126d298..a60ab0a1c 100644 --- a/third_party/ctags/entry.c +++ b/third_party/ctags/entry.c @@ -13,6 +13,7 @@ * INCLUDE FILES */ #include "libc/runtime/runtime.h" +#include "libc/ctype.h" #include "third_party/ctags/general.h" /* must always come first */ #include "libc/mem/alg.h" diff --git a/third_party/ctags/erlang.c b/third_party/ctags/erlang.c index c4844d5a7..570e883dd 100644 --- a/third_party/ctags/erlang.c +++ b/third_party/ctags/erlang.c @@ -13,6 +13,7 @@ /* * INCLUDE FILES */ +#include "libc/ctype.h" #include "third_party/ctags/general.h" /* must always come first */ #include "libc/mem/alg.h" diff --git a/third_party/ctags/flex.c b/third_party/ctags/flex.c index dd02cd75a..3676f0758 100644 --- a/third_party/ctags/flex.c +++ b/third_party/ctags/flex.c @@ -22,6 +22,8 @@ #include "third_party/ctags/general.h" /* must always come first */ #include "libc/str/str.h" /* to define isalpha () */ #include "libc/runtime/runtime.h" +#include "libc/ctype.h" + #ifdef DEBUG #include "libc/calls/calls.h" #include "libc/stdio/dprintf.h" diff --git a/third_party/ctags/general.h b/third_party/ctags/general.h index ca8c0c515..15b9774c0 100644 --- a/third_party/ctags/general.h +++ b/third_party/ctags/general.h @@ -11,6 +11,7 @@ #ifndef _GENERAL_H #define _GENERAL_H #include "third_party/ctags/config.h" +#include "libc/ctype.h" /* Define standard error destination */ diff --git a/third_party/ctags/get.c b/third_party/ctags/get.c index 7e938c98f..f8df96aea 100644 --- a/third_party/ctags/get.c +++ b/third_party/ctags/get.c @@ -13,6 +13,7 @@ /* * INCLUDE FILES */ +#include "libc/ctype.h" #include "third_party/ctags/general.h" /* must always come first */ #include "libc/mem/alg.h" diff --git a/third_party/ctags/go.c b/third_party/ctags/go.c index 6d2de2b46..bb55f22c4 100644 --- a/third_party/ctags/go.c +++ b/third_party/ctags/go.c @@ -2,6 +2,7 @@ * INCLUDE FILES */ #include "third_party/ctags/general.h" /* must always come first */ +#include "libc/ctype.h" #include "libc/runtime/runtime.h" #include "third_party/ctags/debug.h" diff --git a/third_party/ctags/jscript.c b/third_party/ctags/jscript.c index c8bf53917..bccd0c852 100644 --- a/third_party/ctags/jscript.c +++ b/third_party/ctags/jscript.c @@ -21,6 +21,8 @@ #include "third_party/ctags/general.h" /* must always come first */ #include "libc/str/str.h" /* to define isalpha () */ #include "libc/runtime/runtime.h" +#include "libc/ctype.h" + #ifdef DEBUG #include "libc/calls/calls.h" #include "libc/stdio/dprintf.h" diff --git a/third_party/ctags/lisp.c b/third_party/ctags/lisp.c index 8a47e7b20..5041888a6 100644 --- a/third_party/ctags/lisp.c +++ b/third_party/ctags/lisp.c @@ -12,6 +12,7 @@ /* * INCLUDE FILES */ +#include "libc/ctype.h" #include "third_party/ctags/general.h" /* must always come first */ #include "third_party/ctags/parse.h" diff --git a/third_party/ctags/lregex.c b/third_party/ctags/lregex.c index 40a67907d..1f905e1e4 100644 --- a/third_party/ctags/lregex.c +++ b/third_party/ctags/lregex.c @@ -16,6 +16,7 @@ /* * INCLUDE FILES */ +#include "libc/ctype.h" #include "third_party/ctags/general.h" /* must always come first */ #include "libc/mem/alg.h" diff --git a/third_party/ctags/lua.c b/third_party/ctags/lua.c index 47c9d5893..d86ff839c 100644 --- a/third_party/ctags/lua.c +++ b/third_party/ctags/lua.c @@ -12,6 +12,7 @@ /* * INCLUDE FILES */ +#include "libc/ctype.h" #include "third_party/ctags/general.h" /* must always come first */ #include "libc/mem/alg.h" diff --git a/third_party/ctags/make.c b/third_party/ctags/make.c index 794560cbf..ec1360518 100644 --- a/third_party/ctags/make.c +++ b/third_party/ctags/make.c @@ -12,6 +12,7 @@ /* * INCLUDE FILES */ +#include "libc/ctype.h" #include "third_party/ctags/general.h" /* must always come first */ #include "libc/mem/alg.h" diff --git a/third_party/ctags/parse.c b/third_party/ctags/parse.c index 84cd8869f..d3dffd91b 100644 --- a/third_party/ctags/parse.c +++ b/third_party/ctags/parse.c @@ -13,6 +13,7 @@ /* * INCLUDE FILES */ +#include "libc/ctype.h" #include "third_party/ctags/general.h" /* must always come first */ #include "libc/mem/alg.h" diff --git a/third_party/ctags/pascal.c b/third_party/ctags/pascal.c index 9ffc2834f..d6b22e666 100644 --- a/third_party/ctags/pascal.c +++ b/third_party/ctags/pascal.c @@ -13,6 +13,7 @@ /* * INCLUDE FILES */ +#include "libc/ctype.h" #include "third_party/ctags/general.h" /* must always come first */ #include "libc/mem/alg.h" diff --git a/third_party/ctags/perl.c b/third_party/ctags/perl.c index 4fda42f3c..186cf7c8a 100644 --- a/third_party/ctags/perl.c +++ b/third_party/ctags/perl.c @@ -13,6 +13,7 @@ /* * INCLUDE FILES */ +#include "libc/ctype.h" #include "third_party/ctags/general.h" /* must always come first */ #include "libc/mem/alg.h" diff --git a/third_party/ctags/python.c b/third_party/ctags/python.c index 7bdf3baf2..cbe02d8ce 100644 --- a/third_party/ctags/python.c +++ b/third_party/ctags/python.c @@ -13,6 +13,7 @@ * INCLUDE FILES */ #include "libc/mem/mem.h" +#include "libc/ctype.h" #include "third_party/ctags/general.h" /* must always come first */ #include "libc/mem/alg.h" diff --git a/third_party/ctags/read.c b/third_party/ctags/read.c index 521413fd6..3ddf7da58 100644 --- a/third_party/ctags/read.c +++ b/third_party/ctags/read.c @@ -13,6 +13,7 @@ /* * INCLUDE FILES */ +#include "libc/ctype.h" #include "third_party/ctags/general.h" /* must always come first */ #include "libc/mem/alg.h" diff --git a/third_party/ctags/readtags.c b/third_party/ctags/readtags.c index a6c56642d..dc069e522 100644 --- a/third_party/ctags/readtags.c +++ b/third_party/ctags/readtags.c @@ -14,6 +14,7 @@ #include "libc/mem/mem.h" #include "libc/stdio/stdio.h" #include "libc/str/str.h" +#include "libc/ctype.h" #include "third_party/ctags/readtags.h" /* diff --git a/third_party/ctags/routines.c b/third_party/ctags/routines.c index f1b8cb2f3..10c39e470 100644 --- a/third_party/ctags/routines.c +++ b/third_party/ctags/routines.c @@ -19,6 +19,7 @@ #include "libc/sysv/consts/s.h" #include "third_party/ctags/config.h" #include "third_party/ctags/debug.h" +#include "libc/ctype.h" #include "third_party/ctags/routines.h" /* diff --git a/third_party/ctags/ruby.c b/third_party/ctags/ruby.c index 89569449f..956ac6dd3 100644 --- a/third_party/ctags/ruby.c +++ b/third_party/ctags/ruby.c @@ -15,6 +15,7 @@ /* * INCLUDE FILES */ +#include "libc/ctype.h" #include "third_party/ctags/general.h" /* must always come first */ #include "libc/mem/alg.h" diff --git a/third_party/ctags/scheme.c b/third_party/ctags/scheme.c index 152efcdbc..1d84e44db 100644 --- a/third_party/ctags/scheme.c +++ b/third_party/ctags/scheme.c @@ -13,6 +13,7 @@ /* * INCLUDE FILES */ +#include "libc/ctype.h" #include "third_party/ctags/general.h" /* must always come first */ #include "libc/mem/alg.h" diff --git a/third_party/ctags/sh.c b/third_party/ctags/sh.c index 130cca513..8409f62fd 100644 --- a/third_party/ctags/sh.c +++ b/third_party/ctags/sh.c @@ -13,6 +13,7 @@ /* * INCLUDE FILES */ +#include "libc/ctype.h" #include "third_party/ctags/general.h" /* must always come first */ #include "libc/mem/alg.h" diff --git a/third_party/ctags/sml.c b/third_party/ctags/sml.c index d9a460eac..b3f94d823 100644 --- a/third_party/ctags/sml.c +++ b/third_party/ctags/sml.c @@ -12,6 +12,7 @@ /* * INCLUDE FILES */ +#include "libc/ctype.h" #include "third_party/ctags/general.h" /* must always come first */ #include "libc/mem/alg.h" diff --git a/third_party/ctags/tcl.c b/third_party/ctags/tcl.c index 600a23742..d193ce2d4 100644 --- a/third_party/ctags/tcl.c +++ b/third_party/ctags/tcl.c @@ -12,6 +12,7 @@ /* * INCLUDE FILES */ +#include "libc/ctype.h" #include "third_party/ctags/general.h" /* must always come first */ #include "libc/mem/alg.h" diff --git a/third_party/ctags/tex.c b/third_party/ctags/tex.c index f881aee59..3ce844a73 100644 --- a/third_party/ctags/tex.c +++ b/third_party/ctags/tex.c @@ -18,6 +18,8 @@ #include "third_party/ctags/general.h" /* must always come first */ #include "libc/str/str.h" /* to define isalpha () */ #include "libc/runtime/runtime.h" +#include "libc/ctype.h" + #ifdef DEBUG #include "libc/calls/calls.h" #include "libc/stdio/dprintf.h" diff --git a/third_party/ctags/verilog.c b/third_party/ctags/verilog.c index 705175d2f..737fdaee6 100644 --- a/third_party/ctags/verilog.c +++ b/third_party/ctags/verilog.c @@ -19,6 +19,7 @@ /* * INCLUDE FILES */ +#include "libc/ctype.h" #include "third_party/ctags/general.h" /* must always come first */ #include "libc/mem/alg.h" diff --git a/third_party/ctags/vhdl.c b/third_party/ctags/vhdl.c index a6c8016fa..1b970ce66 100644 --- a/third_party/ctags/vhdl.c +++ b/third_party/ctags/vhdl.c @@ -12,6 +12,7 @@ /* * INCLUDE FILES */ +#include "libc/ctype.h" #include "third_party/ctags/general.h" /* must always come first */ #include "libc/str/str.h" /* to define isalpha () */ diff --git a/third_party/ctags/vim.c b/third_party/ctags/vim.c index d2c0009b1..e0cd9b0d9 100644 --- a/third_party/ctags/vim.c +++ b/third_party/ctags/vim.c @@ -15,6 +15,7 @@ /* * INCLUDE FILES */ +#include "libc/ctype.h" #include "third_party/ctags/general.h" /* must always come first */ #include "libc/mem/alg.h" diff --git a/third_party/ctags/vstring.c b/third_party/ctags/vstring.c index cc92117e6..01311d421 100644 --- a/third_party/ctags/vstring.c +++ b/third_party/ctags/vstring.c @@ -12,6 +12,7 @@ /* * INCLUDE FILES */ +#include "libc/ctype.h" #include "third_party/ctags/general.h" /* must always come first */ #include "libc/limits.h" diff --git a/third_party/finger/util.c b/third_party/finger/util.c index 14a544d64..7de3544b9 100644 --- a/third_party/finger/util.c +++ b/third_party/finger/util.c @@ -43,6 +43,7 @@ #include "libc/stdio/stdio.h" #include "libc/str/str.h" #include "libc/sysv/consts/o.h" +#include "libc/ctype.h" #include "third_party/finger/finger.h" #ifndef lint diff --git a/third_party/hiredis/async.c b/third_party/hiredis/async.c index b6c721d45..23220df77 100644 --- a/third_party/hiredis/async.c +++ b/third_party/hiredis/async.c @@ -56,6 +56,7 @@ #include "third_party/hiredis/async.h" #include "third_party/hiredis/net.h" #include "third_party/hiredis/dict.c" +#include "libc/ctype.h" #include "third_party/hiredis/sds.h" #include "third_party/hiredis/async_private.inc" diff --git a/third_party/hiredis/hiredis.c b/third_party/hiredis/hiredis.c index 372da65d9..67c2185ac 100644 --- a/third_party/hiredis/hiredis.c +++ b/third_party/hiredis/hiredis.c @@ -51,6 +51,7 @@ #include "libc/assert.h" #include "libc/errno.h" #include "libc/mem/gc.h" +#include "libc/ctype.h" #include "libc/str/str.h" #include "third_party/hiredis/hiredis.h" diff --git a/third_party/hiredis/read.c b/third_party/hiredis/read.c index a907520a5..86aa95920 100644 --- a/third_party/hiredis/read.c +++ b/third_party/hiredis/read.c @@ -73,6 +73,7 @@ #include "libc/sysv/consts/limits.h" #include "libc/sysv/consts/xopen.h" #include "libc/thread/thread.h" +#include "libc/ctype.h" #include "libc/math.h" #include "third_party/hiredis/alloc.h" diff --git a/third_party/hiredis/sds.c b/third_party/hiredis/sds.c index 1e7b108e9..75ab85089 100644 --- a/third_party/hiredis/sds.c +++ b/third_party/hiredis/sds.c @@ -62,6 +62,7 @@ #include "libc/sysv/consts/xopen.h" #include "libc/thread/thread.h" #include "third_party/hiredis/sds.h" +#include "libc/ctype.h" #include "third_party/hiredis/sdsalloc.h" #pragma GCC diagnostic ignored "-Wstringop-overflow" diff --git a/third_party/linenoise/linenoise.c b/third_party/linenoise/linenoise.c index ca9b35f87..94ecebb90 100644 --- a/third_party/linenoise/linenoise.c +++ b/third_party/linenoise/linenoise.c @@ -168,6 +168,7 @@ #include "libc/sysv/consts/termios.h" #include "libc/sysv/errfuns.h" #include "net/http/escape.h" +#include "libc/wctype.h" #include "tool/build/lib/case.h" __notice(linenoise_notice, "\ diff --git a/third_party/lua/lbaselib.c b/third_party/lua/lbaselib.c index 10a0e75f1..f8b778d33 100644 --- a/third_party/lua/lbaselib.c +++ b/third_party/lua/lbaselib.c @@ -32,6 +32,7 @@ #include "third_party/lua/lauxlib.h" #include "third_party/lua/lprefix.h" #include "third_party/lua/lua.h" +#include "libc/ctype.h" #include "third_party/lua/lualib.h" __static_yoink("lua_notice"); diff --git a/third_party/lua/liolib.c b/third_party/lua/liolib.c index a668b0c1c..18bba75a1 100644 --- a/third_party/lua/liolib.c +++ b/third_party/lua/liolib.c @@ -37,6 +37,7 @@ #include "third_party/lua/lauxlib.h" #include "third_party/lua/lprefix.h" #include "third_party/lua/lua.h" +#include "libc/ctype.h" #include "third_party/lua/lualib.h" __static_yoink("lua_notice"); diff --git a/third_party/lua/lstrlib.c b/third_party/lua/lstrlib.c index 9c8c7a1ba..7fd3a842c 100644 --- a/third_party/lua/lstrlib.c +++ b/third_party/lua/lstrlib.c @@ -34,6 +34,7 @@ #include "third_party/lua/lauxlib.h" #include "third_party/lua/lprefix.h" #include "third_party/lua/lua.h" +#include "libc/ctype.h" #include "third_party/lua/lualib.h" __static_yoink("lua_notice"); diff --git a/third_party/lua/luac.main.c b/third_party/lua/luac.main.c index 456343e2b..2898af946 100644 --- a/third_party/lua/luac.main.c +++ b/third_party/lua/luac.main.c @@ -43,6 +43,7 @@ #include "third_party/lua/lstate.h" #include "third_party/lua/lua.h" #include "third_party/lua/lualib.h" +#include "libc/ctype.h" #include "third_party/lua/lundump.h" __static_yoink("lua_notice"); diff --git a/third_party/musl/crypt_sha256.c b/third_party/musl/crypt_sha256.c index d5e2f8059..57d311911 100644 --- a/third_party/musl/crypt_sha256.c +++ b/third_party/musl/crypt_sha256.c @@ -39,6 +39,7 @@ #include "libc/str/str.h" #include "libc/sysv/consts/exit.h" #include "third_party/gdtoa/gdtoa.h" +#include "libc/ctype.h" #include "third_party/musl/crypt.internal.h" __static_yoink("musl_libc_notice"); diff --git a/third_party/musl/crypt_sha512.c b/third_party/musl/crypt_sha512.c index 7d3b4414b..a0e8bcc1a 100644 --- a/third_party/musl/crypt_sha512.c +++ b/third_party/musl/crypt_sha512.c @@ -39,6 +39,7 @@ #include "libc/str/str.h" #include "libc/sysv/consts/exit.h" #include "third_party/gdtoa/gdtoa.h" +#include "libc/ctype.h" #include "third_party/musl/crypt.internal.h" __static_yoink("musl_libc_notice"); diff --git a/third_party/musl/fnmatch.c b/third_party/musl/fnmatch.c index d2f32e259..6ccf0a2e7 100644 --- a/third_party/musl/fnmatch.c +++ b/third_party/musl/fnmatch.c @@ -27,6 +27,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/limits.h" #include "libc/str/str.h" +#include "libc/wctype.h" #include "third_party/musl/fnmatch.h" __static_yoink("musl_libc_notice"); diff --git a/third_party/musl/getnameinfo.c b/third_party/musl/getnameinfo.c index 173822278..193e6b2e3 100644 --- a/third_party/musl/getnameinfo.c +++ b/third_party/musl/getnameinfo.c @@ -36,6 +36,7 @@ #include "libc/sysv/consts/af.h" #include "third_party/musl/lookup.internal.h" #include "third_party/musl/netdb.h" +#include "libc/ctype.h" #include "third_party/musl/resolv.internal.h" __static_yoink("musl_libc_notice"); diff --git a/third_party/musl/lookup_ipliteral.c b/third_party/musl/lookup_ipliteral.c index a02b0239b..b0fc6462d 100644 --- a/third_party/musl/lookup_ipliteral.c +++ b/third_party/musl/lookup_ipliteral.c @@ -31,6 +31,7 @@ #include "libc/fmt/conv.h" #include "libc/limits.h" #include "libc/sock/sock.h" +#include "libc/ctype.h" #include "third_party/musl/lookup.internal.h" __static_yoink("musl_libc_notice"); diff --git a/third_party/musl/lookup_name.c b/third_party/musl/lookup_name.c index 291178213..1b9ca1611 100644 --- a/third_party/musl/lookup_name.c +++ b/third_party/musl/lookup_name.c @@ -39,6 +39,7 @@ #include "libc/sysv/consts/sock.h" #include "third_party/musl/lookup.internal.h" #include "third_party/musl/netdb.h" +#include "libc/ctype.h" #include "third_party/musl/resolv.internal.h" __static_yoink("musl_libc_notice"); diff --git a/third_party/musl/lookup_serv.c b/third_party/musl/lookup_serv.c index cc7fbffb2..a0fff8a23 100644 --- a/third_party/musl/lookup_serv.c +++ b/third_party/musl/lookup_serv.c @@ -32,6 +32,7 @@ #include "libc/stdio/internal.h" #include "libc/errno.h" #include "libc/calls/sysdir.internal.h" +#include "libc/ctype.h" #include "third_party/musl/lookup.internal.h" __static_yoink("musl_libc_notice"); diff --git a/third_party/musl/resolvconf.c b/third_party/musl/resolvconf.c index ddc44b363..0c766d9e1 100644 --- a/third_party/musl/resolvconf.c +++ b/third_party/musl/resolvconf.c @@ -37,6 +37,7 @@ #include "libc/str/str.h" #include "libc/sysv/consts/af.h" #include "libc/sock/sock.h" +#include "libc/ctype.h" #include "third_party/musl/lookup.internal.h" __static_yoink("musl_libc_notice"); diff --git a/third_party/musl/strfmon.c b/third_party/musl/strfmon.c index 95e590612..b80801d5f 100644 --- a/third_party/musl/strfmon.c +++ b/third_party/musl/strfmon.c @@ -29,6 +29,7 @@ #include "libc/stdio/stdio.h" #include "libc/str/locale.h" #include "libc/str/str.h" +#include "libc/ctype.h" #include "libc/thread/tls.h" __static_yoink("musl_libc_notice"); diff --git a/third_party/musl/strptime.c b/third_party/musl/strptime.c index 1c334640e..682d33d77 100644 --- a/third_party/musl/strptime.c +++ b/third_party/musl/strptime.c @@ -28,6 +28,7 @@ #include "libc/fmt/conv.h" #include "libc/macros.internal.h" #include "libc/str/str.h" +#include "libc/ctype.h" #include "libc/time.h" __static_yoink("musl_libc_notice"); diff --git a/third_party/ncurses/read_entry.c b/third_party/ncurses/read_entry.c index d481d924f..0d2b42d53 100644 --- a/third_party/ncurses/read_entry.c +++ b/third_party/ncurses/read_entry.c @@ -2853,6 +2853,7 @@ __static_yoink("usr/share/terminfo/z/ztx11"); */ #include "curses.priv.h" +#include "libc/ctype.h" #include "hashed_db.h" #include "tic.h" diff --git a/third_party/pcre/pcre2_compile.c b/third_party/pcre/pcre2_compile.c index 4fc63cd57..b5d076a9f 100644 --- a/third_party/pcre/pcre2_compile.c +++ b/third_party/pcre/pcre2_compile.c @@ -1,3 +1,4 @@ +#include "libc/ctype.h" #include "libc/str/str.h" /************************************************* diff --git a/third_party/pcre/pcre2_context.c b/third_party/pcre/pcre2_context.c index 9788a6336..d573debe9 100644 --- a/third_party/pcre/pcre2_context.c +++ b/third_party/pcre/pcre2_context.c @@ -1,4 +1,5 @@ #include "libc/mem/mem.h" +#include "libc/ctype.h" #include "libc/str/str.h" /************************************************* diff --git a/third_party/pcre/pcre2_convert.c b/third_party/pcre/pcre2_convert.c index 79d7ce86a..7a352cbb0 100644 --- a/third_party/pcre/pcre2_convert.c +++ b/third_party/pcre/pcre2_convert.c @@ -1,3 +1,4 @@ +#include "libc/ctype.h" #include "libc/str/str.h" /************************************************* diff --git a/third_party/pcre/pcre2_maketables.c b/third_party/pcre/pcre2_maketables.c index ab0aa5d6e..771396de9 100644 --- a/third_party/pcre/pcre2_maketables.c +++ b/third_party/pcre/pcre2_maketables.c @@ -2,6 +2,7 @@ * Perl-Compatible Regular Expressions * *************************************************/ #include "libc/str/str.h" +#include "libc/ctype.h" #include "libc/mem/mem.h" /* PCRE is a library of functions to support regular expressions whose syntax diff --git a/third_party/python/Modules/_decimal/_decimal.c b/third_party/python/Modules/_decimal/_decimal.c index 3940663c9..7c3a66c54 100644 --- a/third_party/python/Modules/_decimal/_decimal.c +++ b/third_party/python/Modules/_decimal/_decimal.c @@ -46,6 +46,7 @@ #include "third_party/python/Include/tupleobject.h" #include "third_party/python/Include/yoink.h" #include "third_party/python/Modules/_decimal/docstrings.h" +#include "libc/ctype.h" #include "third_party/python/Modules/_decimal/libmpdec/mpdecimal.h" PYTHON_PROVIDE("_decimal"); diff --git a/third_party/python/Modules/_decimal/libmpdec/io.c b/third_party/python/Modules/_decimal/libmpdec/io.c index 687417335..86e1ea79f 100644 --- a/third_party/python/Modules/_decimal/libmpdec/io.c +++ b/third_party/python/Modules/_decimal/libmpdec/io.c @@ -34,6 +34,7 @@ #include "third_party/python/Modules/_decimal/libmpdec/constants.h" #include "third_party/python/Modules/_decimal/libmpdec/io.h" #include "third_party/python/Modules/_decimal/libmpdec/mpdecimal.h" +#include "libc/ctype.h" #include "third_party/python/Modules/_decimal/libmpdec/typearith.h" __static_yoink("libmpdec_notice"); diff --git a/third_party/python/Modules/_hashmbedtls.c b/third_party/python/Modules/_hashmbedtls.c index d045940c8..26202c7b5 100644 --- a/third_party/python/Modules/_hashmbedtls.c +++ b/third_party/python/Modules/_hashmbedtls.c @@ -32,6 +32,7 @@ #include "third_party/python/Include/pystrhex.h" #include "third_party/python/Include/structmember.h" #include "third_party/python/Include/yoink.h" +#include "libc/ctype.h" #include "third_party/python/Modules/hashlib.h" PYTHON_PROVIDE("_hashlib"); diff --git a/third_party/python/Objects/bytesobject.c b/third_party/python/Objects/bytesobject.c index 8190e3c4d..803c2a2b1 100644 --- a/third_party/python/Objects/bytesobject.c +++ b/third_party/python/Objects/bytesobject.c @@ -26,6 +26,7 @@ #include "third_party/python/Include/pystrhex.h" #include "third_party/python/Include/pystrtod.h" #include "third_party/python/Include/sliceobject.h" +#include "libc/ctype.h" #include "third_party/python/Include/warnings.h" /*[clinic input] diff --git a/third_party/python/Parser/grammar.c b/third_party/python/Parser/grammar.c index f8e113451..b4c385dc2 100644 --- a/third_party/python/Parser/grammar.c +++ b/third_party/python/Parser/grammar.c @@ -9,6 +9,7 @@ #include "third_party/python/Include/objimpl.h" #include "third_party/python/Include/pgenheaders.h" #include "third_party/python/Include/pyerrors.h" +#include "libc/ctype.h" #include "third_party/python/Include/token.h" extern int Py_DebugFlag; diff --git a/third_party/python/Parser/tokenizer.c b/third_party/python/Parser/tokenizer.c index bdf7615a4..c87720ea9 100644 --- a/third_party/python/Parser/tokenizer.c +++ b/third_party/python/Parser/tokenizer.c @@ -23,6 +23,7 @@ #include "third_party/python/Include/pymacro.h" #include "third_party/python/Include/pymem.h" #include "third_party/python/Include/sysmodule.h" +#include "libc/ctype.h" #include "third_party/python/Include/unicodeobject.h" #endif diff --git a/third_party/python/runpythonmodule.c b/third_party/python/runpythonmodule.c index f3410c136..ba23daa13 100644 --- a/third_party/python/runpythonmodule.c +++ b/third_party/python/runpythonmodule.c @@ -49,6 +49,7 @@ #include "third_party/python/Include/unicodeobject.h" #include "third_party/python/Include/yoink.h" #include "libc/runtime/stack.h" +#include "libc/ctype.h" #include "third_party/xed/x86.h" STATIC_STACK_SIZE(0x100000); diff --git a/third_party/regex/regcomp.c b/third_party/regex/regcomp.c index fbec0a48f..f0fffdc78 100644 --- a/third_party/regex/regcomp.c +++ b/third_party/regex/regcomp.c @@ -57,6 +57,7 @@ β”‚ β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/mem/alg.h" +#include "libc/ctype.h" #include "third_party/regex/tre.inc" #define CHARCLASS_NAME_MAX 14 diff --git a/third_party/regex/tre.inc b/third_party/regex/tre.inc index 2f6e39854..a86cb46b7 100644 --- a/third_party/regex/tre.inc +++ b/third_party/regex/tre.inc @@ -60,6 +60,7 @@ #include "libc/mem/alg.h" #include "libc/mem/mem.h" #include "libc/str/str.h" +#include "libc/wctype.h" #include "third_party/regex/regex.h" #undef TRE_MBSTATE diff --git a/third_party/sed/compile.c b/third_party/sed/compile.c index 66758b242..1f86d24f1 100644 --- a/third_party/sed/compile.c +++ b/third_party/sed/compile.c @@ -47,6 +47,7 @@ #include "libc/sysv/consts/s.h" #include "libc/sysv/consts/utime.h" #include "libc/mem/gc.h" +#include "libc/ctype.h" #include "libc/time.h" #include "libc/str/str.h" diff --git a/third_party/sed/process.c b/third_party/sed/process.c index 1a50f1061..fbef8809a 100644 --- a/third_party/sed/process.c +++ b/third_party/sed/process.c @@ -47,6 +47,8 @@ #include "libc/sysv/consts/s.h" #include "libc/sysv/consts/termios.h" #include "third_party/sed/defs.h" +#include "libc/wctype.h" +#include "libc/ctype.h" #include "third_party/sed/extern.h" static SPACE HS, PS, SS, YS; diff --git a/third_party/sqlite3/completion.c b/third_party/sqlite3/completion.c index e7279f297..e47d66482 100644 --- a/third_party/sqlite3/completion.c +++ b/third_party/sqlite3/completion.c @@ -35,6 +35,7 @@ */ #include "libc/assert.h" #include "libc/str/str.h" +#include "libc/ctype.h" #include "third_party/sqlite3/sqlite3ext.h" SQLITE_EXTENSION_INIT1 diff --git a/third_party/sqlite3/decimal.c b/third_party/sqlite3/decimal.c index f6326842a..76d91ecf7 100644 --- a/third_party/sqlite3/decimal.c +++ b/third_party/sqlite3/decimal.c @@ -17,6 +17,7 @@ #include "libc/assert.h" #include "libc/mem/mem.h" #include "libc/str/str.h" +#include "libc/ctype.h" #include "third_party/sqlite3/sqlite3ext.h" SQLITE_EXTENSION_INIT1 diff --git a/third_party/sqlite3/geopoly.inc b/third_party/sqlite3/geopoly.inc index 8de1fdbee..5874571e1 100644 --- a/third_party/sqlite3/geopoly.inc +++ b/third_party/sqlite3/geopoly.inc @@ -16,6 +16,7 @@ ** This file is #include-ed onto the end of "rtree.c" so that it has ** access to all of the R-Tree internals. */ +#include "libc/ctype.h" #include "libc/fmt/conv.h" /* Enable -DGEOPOLY_ENABLE_DEBUG for debugging facilities */ diff --git a/third_party/sqlite3/shell.c b/third_party/sqlite3/shell.c index 1144c6e73..e81818669 100644 --- a/third_party/sqlite3/shell.c +++ b/third_party/sqlite3/shell.c @@ -30,6 +30,7 @@ ** This file contains code to implement the "sqlite" command line ** utility for accessing SQLite databases. */ +#include "libc/ctype.h" #include "libc/dce.h" #if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS) /* This needs to come before any includes for MSVC compiler */ diff --git a/third_party/sqlite3/uint.c b/third_party/sqlite3/uint.c index 5bbc9ed08..835f78bed 100644 --- a/third_party/sqlite3/uint.c +++ b/third_party/sqlite3/uint.c @@ -29,6 +29,7 @@ */ #include "libc/assert.h" #include "libc/str/str.h" +#include "libc/ctype.h" #include "third_party/sqlite3/sqlite3ext.h" SQLITE_EXTENSION_INIT1 diff --git a/third_party/tidy/attrs.c b/third_party/tidy/attrs.c index 3b96f361f..b85208a7c 100644 --- a/third_party/tidy/attrs.c +++ b/third_party/tidy/attrs.c @@ -10,6 +10,7 @@ #include "third_party/tidy/message.h" #include "third_party/tidy/tmbstr.h" #include "libc/assert.h" +#include "libc/ctype.h" #include "third_party/tidy/utf8.h" #if __GNUC__ >= 11 /* [jart] this one looks legit */ diff --git a/third_party/tidy/language.c b/third_party/tidy/language.c index ea80ad7a2..b540225c5 100644 --- a/third_party/tidy/language.c +++ b/third_party/tidy/language.c @@ -7,6 +7,7 @@ #include "third_party/tidy/language.h" #include "third_party/tidy/tmbstr.h" +#include "libc/ctype.h" #include "libc/assert.h" #include "third_party/tidy/language_en.inc" diff --git a/third_party/tidy/pprint.c b/third_party/tidy/pprint.c index d7a98f4cd..d77ae7844 100644 --- a/third_party/tidy/pprint.c +++ b/third_party/tidy/pprint.c @@ -14,6 +14,7 @@ #include "third_party/tidy/tmbstr.h" #include "third_party/tidy/utf8.h" #include "libc/assert.h" +#include "libc/ctype.h" #include "third_party/tidy/sprtf.h" diff --git a/third_party/tr/next.c b/third_party/tr/next.c index 802197dd7..e71c31c97 100644 --- a/third_party/tr/next.c +++ b/third_party/tr/next.c @@ -35,6 +35,7 @@ #include "libc/mem/alg.h" #include "libc/mem/mem.h" #include "libc/str/str.h" +#include "libc/ctype.h" #include "third_party/tr/extern.h" static int backslash(STR *); diff --git a/third_party/tree/html.c b/third_party/tree/html.c index 41b731d19..c6f3a941e 100644 --- a/third_party/tree/html.c +++ b/third_party/tree/html.c @@ -15,6 +15,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "libc/ctype.h" #include "third_party/tree/tree.h" extern char *version, *hversion; diff --git a/third_party/tree/json.c b/third_party/tree/json.c index e9ef424e9..414b25975 100644 --- a/third_party/tree/json.c +++ b/third_party/tree/json.c @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "libc/sysv/consts/s.h" +#include "libc/ctype.h" #include "third_party/tree/tree.h" extern bool dflag, lflag, pflag, sflag, Fflag, aflag, fflag, uflag, gflag; diff --git a/third_party/tree/tree.c b/third_party/tree/tree.c index d68e8ad96..005e6d0fc 100644 --- a/third_party/tree/tree.c +++ b/third_party/tree/tree.c @@ -29,6 +29,8 @@ #include "libc/calls/struct/stat.macros.h" #include "libc/calls/struct/dirent.h" #include "libc/mem/alg.h" +#include "libc/ctype.h" +#include "libc/wctype.h" #include "third_party/tree/tree.h" char *version = "$Version: $ tree v2.1.1 %s 1996 - 2023 by Steve Baker, Thomas Moore, Francesc Rocher, Florian Sesser, Kyosuke Tokoro $"; diff --git a/third_party/zlib/trees.c b/third_party/zlib/trees.c index 578ac9cf6..b3bcd67e5 100644 --- a/third_party/zlib/trees.c +++ b/third_party/zlib/trees.c @@ -10,6 +10,7 @@ #include "libc/stdio/stdio.h" #include "libc/temp.h" #include "libc/str/str.h" +#include "libc/ctype.h" #include "third_party/zlib/deflate.internal.h" /* diff --git a/tool/build/BUILD.mk b/tool/build/BUILD.mk index 844a0ab28..bfbb2ccb2 100644 --- a/tool/build/BUILD.mk +++ b/tool/build/BUILD.mk @@ -96,7 +96,7 @@ o/$(MODE)/tool/build/dso/sandbox.o: \ libc/calls/pledge.h \ libc/runtime/runtime.h \ libc/calls/pledge.internal.h \ - libc/intrin/promises.internal.h \ + libc/intrin/promises.h \ tool/build/BUILD.mk o/$(MODE)/tool/build/dso/sandbox-$(ARCH).so: \ diff --git a/tool/build/apelink.c b/tool/build/apelink.c index cfdcaea61..2c707ab61 100644 --- a/tool/build/apelink.c +++ b/tool/build/apelink.c @@ -19,6 +19,7 @@ #include "ape/ape.h" #include "libc/assert.h" #include "libc/calls/calls.h" +#include "libc/ctype.h" #include "libc/dce.h" #include "libc/dos.internal.h" #include "libc/elf/def.h" diff --git a/tool/build/killall.c b/tool/build/killall.c index 7a250983b..75a41e5c7 100644 --- a/tool/build/killall.c +++ b/tool/build/killall.c @@ -30,6 +30,7 @@ #include "libc/stdio/stdio.h" #include "libc/str/str.h" #include "libc/sysv/consts/sig.h" +#include "libc/wctype.h" #include "libc/x/x.h" #include "third_party/getopt/getopt.internal.h" diff --git a/tool/build/lib/javadown.c b/tool/build/lib/javadown.c index 476da98ca..313d95d0e 100644 --- a/tool/build/lib/javadown.c +++ b/tool/build/lib/javadown.c @@ -17,6 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "tool/build/lib/javadown.h" +#include "libc/ctype.h" #include "libc/mem/mem.h" #include "libc/str/str.h" diff --git a/tool/build/pecheck.c b/tool/build/pecheck.c index 3585f26e3..199cfed02 100644 --- a/tool/build/pecheck.c +++ b/tool/build/pecheck.c @@ -17,6 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" +#include "libc/ctype.h" #include "libc/limits.h" #include "libc/nt/struct/imageimportbyname.internal.h" #include "libc/nt/struct/imageimportdescriptor.internal.h" diff --git a/tool/build/pledge.c b/tool/build/pledge.c index 6968f7797..379301069 100644 --- a/tool/build/pledge.c +++ b/tool/build/pledge.c @@ -29,6 +29,7 @@ #include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/calls/syscall_support-sysv.internal.h" +#include "libc/ctype.h" #include "libc/dce.h" #include "libc/elf/def.h" #include "libc/elf/elf.h" diff --git a/tool/decode/ent.c b/tool/decode/ent.c index ff4db3982..585452a61 100644 --- a/tool/decode/ent.c +++ b/tool/decode/ent.c @@ -30,6 +30,7 @@ #include "libc/stdio/rand.h" #include "libc/stdio/stdio.h" #include "libc/str/str.h" +#include "libc/ctype.h" #include "third_party/getopt/getopt.internal.h" #define UPDATE "January 28th, 2008" diff --git a/tool/decode/x86opinfo.c b/tool/decode/x86opinfo.c index 79ac631e5..6b741c304 100644 --- a/tool/decode/x86opinfo.c +++ b/tool/decode/x86opinfo.c @@ -16,6 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/ctype.h" #include "libc/errno.h" #include "libc/macros.internal.h" #include "libc/runtime/runtime.h" diff --git a/tool/lambda/bru2bin.c b/tool/lambda/bru2bin.c index 2516ff0f9..dd317af19 100644 --- a/tool/lambda/bru2bin.c +++ b/tool/lambda/bru2bin.c @@ -23,6 +23,7 @@ #include "libc/stdio/stdio.h" #include "libc/str/locale.h" #include "libc/str/str.h" +#include "libc/wctype.h" #include "third_party/getopt/getopt.internal.h" #define USAGE \ diff --git a/tool/lambda/lam2bin.c b/tool/lambda/lam2bin.c index 9c8dd8fb5..3e0efb9a2 100644 --- a/tool/lambda/lam2bin.c +++ b/tool/lambda/lam2bin.c @@ -17,12 +17,14 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/calls/calls.h" +#include "libc/ctype.h" #include "libc/intrin/kprintf.h" #include "libc/mem/mem.h" #include "libc/runtime/runtime.h" #include "libc/stdio/stdio.h" #include "libc/str/locale.h" #include "libc/str/str.h" +#include "libc/wctype.h" #include "third_party/getopt/getopt.internal.h" #define USAGE \ diff --git a/tool/lambda/lib/debug.c b/tool/lambda/lib/debug.c index f841a1ac3..8a6ea7a43 100644 --- a/tool/lambda/lib/debug.c +++ b/tool/lambda/lib/debug.c @@ -16,6 +16,7 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/ctype.h" #include "libc/fmt/itoa.h" #include "libc/intrin/kprintf.h" #include "libc/str/str.h" diff --git a/tool/lambda/lib/getbit.c b/tool/lambda/lib/getbit.c index 8c64eff0f..db22a1a67 100644 --- a/tool/lambda/lib/getbit.c +++ b/tool/lambda/lib/getbit.c @@ -17,6 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/str/str.h" +#include "libc/wctype.h" #include "tool/lambda/lib/blc.h" char GetBit(FILE* f) { diff --git a/tool/net/ljson.c b/tool/net/ljson.c index 10a17c1f6..a3c73616c 100644 --- a/tool/net/ljson.c +++ b/tool/net/ljson.c @@ -18,6 +18,7 @@ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "tool/net/ljson.h" #include "libc/assert.h" +#include "libc/ctype.h" #include "libc/intrin/likely.h" #include "libc/log/check.h" #include "libc/log/log.h" diff --git a/tool/net/redbean.c b/tool/net/redbean.c index e86be3ab9..0eec73175 100644 --- a/tool/net/redbean.c +++ b/tool/net/redbean.c @@ -31,6 +31,7 @@ #include "libc/calls/struct/termios.h" #include "libc/calls/struct/timespec.h" #include "libc/calls/termios.h" +#include "libc/ctype.h" #include "libc/dce.h" #include "libc/dos.internal.h" #include "libc/errno.h" diff --git a/tool/viz/life.c b/tool/viz/life.c index bbf7df3d3..8ca83fb8b 100644 --- a/tool/viz/life.c +++ b/tool/viz/life.c @@ -22,6 +22,7 @@ #include "libc/calls/struct/termios.h" #include "libc/calls/struct/winsize.h" #include "libc/calls/termios.h" +#include "libc/ctype.h" #include "libc/errno.h" #include "libc/fmt/conv.h" #include "libc/fmt/itoa.h" diff --git a/tool/viz/memzoom.c b/tool/viz/memzoom.c index 034ea4265..e3f16a046 100644 --- a/tool/viz/memzoom.c +++ b/tool/viz/memzoom.c @@ -25,6 +25,7 @@ #include "libc/calls/struct/winsize.h" #include "libc/calls/termios.h" #include "libc/calls/ucontext.h" +#include "libc/ctype.h" #include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/conv.h" diff --git a/tool/viz/printvideo.c b/tool/viz/printvideo.c index f412911d4..04c7da6b6 100644 --- a/tool/viz/printvideo.c +++ b/tool/viz/printvideo.c @@ -37,6 +37,7 @@ #include "libc/calls/struct/winsize.h" #include "libc/calls/termios.h" #include "libc/calls/ucontext.h" +#include "libc/ctype.h" #include "libc/cxxabi.h" #include "libc/errno.h" #include "libc/fmt/conv.h" From e08a4cd99ee598149d6ba65d99dd90e9c9e5375d Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sun, 21 Jul 2024 17:01:33 -0700 Subject: [PATCH 066/405] Release Cosmopolitan v3.5.8 --- libc/integral/normalize.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libc/integral/normalize.inc b/libc/integral/normalize.inc index 2790ddf2a..58e4d9aeb 100644 --- a/libc/integral/normalize.inc +++ b/libc/integral/normalize.inc @@ -4,7 +4,7 @@ #define __COSMOPOLITAN_MAJOR__ 3 #define __COSMOPOLITAN_MINOR__ 5 -#define __COSMOPOLITAN_PATCH__ 7 +#define __COSMOPOLITAN_PATCH__ 8 #define __COSMOPOLITAN__ \ (100000000 * __COSMOPOLITAN_MAJOR__ + 1000000 * __COSMOPOLITAN_MINOR__ + \ __COSMOPOLITAN_PATCH__) From 5d2d9e96406db792560c3cdcf5343510ed4f9234 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sun, 21 Jul 2024 20:45:27 -0700 Subject: [PATCH 067/405] Add back missing TlsAlloc() call Cosmopolitan Libc once called this important function although somewhere along the way, possibly in a refactoring, it got removed and __tls_alloc has always been zero ever since. --- libc/proc/fork-nt.c | 12 +++++++----- libc/runtime/cosmo.S | 2 +- libc/runtime/enable_tls.c | 2 ++ libc/runtime/set_tls.c | 2 +- libc/thread/tls2.internal.h | 3 +-- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/libc/proc/fork-nt.c b/libc/proc/fork-nt.c index 201c08595..a4a938e1d 100644 --- a/libc/proc/fork-nt.c +++ b/libc/proc/fork-nt.c @@ -65,6 +65,7 @@ #include "libc/thread/itimer.internal.h" #include "libc/thread/posixthread.internal.h" #include "libc/thread/tls.h" +#include "libc/thread/tls2.internal.h" #ifdef __x86_64__ extern long __klog_handle; @@ -112,7 +113,8 @@ static dontinline textwindows ssize_t ForkIo2( ssize_t rc = ForkIo(h, buf, n, fn); if (ischild) { // prevent crashes - __tls_enabled_set(false); + __threaded = false; + __tls_enabled = false; __pid = __imp_GetCurrentProcessId(); __klog_handle = 0; __maps.maps = 0; @@ -265,9 +267,8 @@ textwindows void WinMainForked(void) { ReadOrDie(reader, __data_start, __data_end - __data_start); ReadOrDie(reader, __bss_start, __bss_end - __bss_start); kStartTsc = savetsc; + __tls_enabled = false; __threaded = false; - __tls_index = 0; - __tls_enabled_set(false); // fixup memory manager __maps.free = 0; @@ -456,9 +457,10 @@ textwindows int sys_fork_nt(uint32_t dwCreationFlags) { } else { rc = 0; // re-apply code morphing for thread-local storage - __set_tls(tib); + __tls_index = TlsAlloc(); + __set_tls_win32(tib); __morph_tls(); - __tls_enabled_set(true); + __tls_enabled = true; // the child's pending signals is initially empty atomic_store_explicit(&__sig.pending, 0, memory_order_relaxed); atomic_store_explicit(&tib->tib_sigpending, 0, memory_order_relaxed); diff --git a/libc/runtime/cosmo.S b/libc/runtime/cosmo.S index eccd05cfa..07b6c459f 100644 --- a/libc/runtime/cosmo.S +++ b/libc/runtime/cosmo.S @@ -45,7 +45,7 @@ cosmo: push %rbp #endif /* SYSDEBUG */ #ifndef NOX87 -// Windows always initializes FPU to douuble precision. +// Windows always initializes FPU to double precision. // WSL breaks Linux ABI by initializing FPU to double precision. // This code makes long double long again. // diff --git a/libc/runtime/enable_tls.c b/libc/runtime/enable_tls.c index 580450ef2..faaa704c3 100644 --- a/libc/runtime/enable_tls.c +++ b/libc/runtime/enable_tls.c @@ -251,6 +251,8 @@ textstartup void __enable_tls(void) { atomic_store_explicit(&_pthread_static.ptid, tid, memory_order_release); // ask the operating system to change the x86 segment register + if (IsWindows()) + __tls_index = TlsAlloc(); __set_tls(tib); #ifdef __x86_64__ diff --git a/libc/runtime/set_tls.c b/libc/runtime/set_tls.c index a1d497896..0ed3609d0 100644 --- a/libc/runtime/set_tls.c +++ b/libc/runtime/set_tls.c @@ -38,7 +38,7 @@ dontinstrument textstartup void __set_tls(struct CosmoTib *tib) { #ifdef __x86_64__ // ask the operating system to change the x86 segment register if (IsWindows()) { - asm("mov\t%1,%%gs:%0" : "=m"(*((long *)0x1480 + __tls_index)) : "r"(tib)); + __set_tls_win32(tib); } else if (IsLinux()) { sys_set_tls(ARCH_SET_GS, tib); } else if (IsFreebsd()) { diff --git a/libc/thread/tls2.internal.h b/libc/thread/tls2.internal.h index 383d79cc2..be2e1c02a 100644 --- a/libc/thread/tls2.internal.h +++ b/libc/thread/tls2.internal.h @@ -17,9 +17,8 @@ forceinline struct CosmoTib *__get_tls_privileged(void) { __asm__("mov\t%%fs:(%1),%0" : "=a"(tib) : "r"(lin) : "memory"); } else { __asm__("mov\t%%gs:(%1),%0" : "=a"(tib) : "r"(lin) : "memory"); - if (IsWindows()) { + if (IsWindows()) tib = *(char **)(tib + 0x1480 + __tls_index * 8); - } } return (struct CosmoTib *)tib; } From 41cc053419d57b38f8bab71004488bcaad00036f Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sun, 21 Jul 2024 20:47:24 -0700 Subject: [PATCH 068/405] Add more content to APE specification --- ape/specification.md | 408 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 408 insertions(+) diff --git a/ape/specification.md b/ape/specification.md index 95afcc12e..94e8de308 100644 --- a/ape/specification.md +++ b/ape/specification.md @@ -269,3 +269,411 @@ regcomp(&rx, For further details, see the canonical implementation in `cosmopolitan/tool/build/assimilate.c`. + +## Static Linking + +Actually Portable Executables are always statically linked. This +revision of the specification does not define any facility for storing +code in dynamic shared objects. + +Cosmopolitan Libc provides a solution that enables APE binaries have +limited access to dlopen(). By manually loading a platform-specific +executable and asking the OS-specific libc's dlopen() to load +OS-specific libraries, it becomes possible to use GPUs and GUIs. This +has worked great for AI projects like llamafile. + +There is no way for an Actually Portable Executable to interact with +OS-specific dynamic shared object extension modules to programming +languages. For example, a Lua interpreter compiled as an Actually +Portable Executable would have no way of linking extension libraries +downloaded from the Lua Rocks package manager. This is primarily because +different OSes define incompatible ABIs. + +While it was possible to polyglot PE+ELF+MachO to create multi-OS +executables, it simply isn't possible to do that same thing for +DLL+DLIB+SO. Therefore, in order to have DSOs, APE would need to either +choose one of the existing formats or invent one of its own, and then +develop its own parallel ecosystem of extension software. In the future, +the APE specification may expand to encompass this. However the focus to +date has been exclusively on executables with limited dlopen() support. + +## Application Binary Interface (ABI) + +APE binaries use the System V ABI, as defined by: + +- [System V ABI - AMD64 Architecture Processor Supplement](https://gitlab.com/x86-psABIs/x86-64-ABI) +- AARCH64 has a uniform consensus defined by ARM Limited + +There are however a few changes we've had to make. + +### Thread Local Storage + +#### aarch64 + +Here's the TLS memory layout on aarch64: + +``` + x28 + %tpidr_el0 + β”‚ + β”‚ _Thread_local + β”Œβ”€β”€β”€β”Όβ”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚tibβ”‚dtvβ”‚ .tdata β”‚ .tbss β”‚ + β”œβ”€β”€β”€β”΄β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + __get_tls() +``` + +The ARM64 code in actually portable executables use the `x28` register +to store the address of the thread information block. All aarch64 code +linked into these executables SHOULD be compiled with `-ffixed-x28` +which is supported by both Clang and GCC. + +The runtime library for an actually portable executables MAY choose to +use `tpidr_el0` instead, if OSes like MacOS aren't being targeted. For +example, if the goal is to create a Linux-only fat binary linker program +for Musl Libc, then choosing to use the existing `tpidr_el0` convention +would be friction-free alternative. + +It's not possible for an APE runtime that targets the full range of OSes +to use the `tpidr_el0` register for TLS because Apple won't allow it. On +MacOS ARM64 systems, this reigster can only be used by a runtime to +implement the `sched_getcpu()` system call. It's reserved by MacOS. + +#### x86-64 + +Here's the TLS memory layout on x86_64: + +``` + __get_tls() + β”‚ + %fs OpenBSD/NetBSD + _Thread_local β”‚ + β”Œβ”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β” + β”‚padβ”‚ .tdata β”‚ .tbss β”‚tibβ”‚ + β””β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”˜ + β”‚ + Linux/FreeBSD/Windows/Mac %gs +``` + +Quite possibly the greatest challenge in Actually Portable Executable +working, has been overcoming the incompatibilities between OSes in how +thread-local storage works on x86-64. The AMD64 architecture defines two +special segment registers. Every OS uses one of these segment registers +to implement TLS support. However not all OSes agree on which register +to use. Some OSes grant userspace the power to define either of these +registers to hold any value that is desired. Some OSes only effectively +allow a single one of them to be changed. Lastly, some OSes, e.g. +Windows, claim ownership of the memory layout these registers point +towards too. + +Here's a breakdown on how much power is granted to userspace runtimes by +each OS when it comes to changing amd64 segment registers. + +| | %fs | %gs | +|---------|--------------|--------------| +| Linux | unrestricted | unrestricted | +| MacOS | inaccessible | unrestricted | +| Windows | inaccessible | restricted | +| FreeBSD | unrestricted | unrestricted | +| NetBSD | unrestricted | broken | +| OpenBSD | unrestricted | inaccessible | + +Therefore, regardless of which register one we choose, some OSes are +going to be incompatible. + +APE binaries are always built with a Linux compiler. So another issue +arises in the fact that our Linux-flavored GCC and Clang toolchains +(which are used to produce cross-OS binaries) are also only capable of +producing TLS instructions that use the %fs convention. + +To solve these challenges, the `cosmocc` compiler will rewrite binary +objects after they've been compiled by GCC, so that `%gs` register is +used, rather than `%fs`. Morphing x86-64 binaries after they've been +compiled is normally difficult, due to the complexity of the machine +instruction language. However GCC provides `-mno-tls-direct-seg-refs` +which greatly reduces the complexity of this task. This flag forgoes +some optimizations to make the generated code simpler. Rather than doing +clever arithmetic with `%fs` prefixes, the compiler will always generate +the thread information block address load as a separate instruction. + +```c +// Change AMD code to use %gs:0x30 instead of %fs:0 +// We assume -mno-tls-direct-seg-refs has been used +static void ChangeTlsFsToGs(unsigned char *p, size_t n) { + unsigned char *e = p + n - 9; + while (p <= e) { + // we're checking for the following expression: + // 0144 == p[0] && // %fs + // 0110 == (p[1] & 0373) && // rex.w (and ignore rex.r) + // (0213 == p[2] || // mov reg/mem β†’ reg (word-sized) + // 0003 == p[2]) && // add reg/mem β†’ reg (word-sized) + // 0004 == (p[3] & 0307) && // mod/rm (4,reg,0) means sib β†’ reg + // 0045 == p[4] && // sib (5,4,0) β†’ (rbp,rsp,0) β†’ disp32 + // 0000 == p[5] && // displacement (von Neumann endian) + // 0000 == p[6] && // displacement + // 0000 == p[7] && // displacement + // 0000 == p[8] // displacement + uint64_t w = READ64LE(p) & READ64LE("\377\373\377\307\377\377\377\377"); + if ((w == READ64LE("\144\110\213\004\045\000\000\000") || + w == READ64LE("\144\110\003\004\045\000\000\000")) && + !p[8]) { + p[0] = 0145; // change %fs to %gs + p[5] = 0x30; // change 0 to 0x30 + p += 9; + } else { + ++p; + } + } +} +``` + +By favoring `%gs` we've now ensured friction-free compatibilty for the +APE runtime on MacOS, Linux, and FreeBSD which are all able to conform +easily to this convention. However additional work needs to be done at +runtime when an APE program is started on Windows, OpenBSD, and NetBSD. +On these platforms, all executable pages must be faulted and morped to +fixup the TLS instructions. + +On OpenBSD and NetBSD, this is as simple as undoing the example +operation above. Earlier at compile-time we turned `%fs` into `%gs`. +Now, at runtime, `%gs` must be turned back into `%fs`. Since the +executable is morphing itself, this is easier said than done. + +OpenBSD for example enforces a `W^X` invariant. Code that's executing +can't modify itself at the same time. The way Cosmopolitan solves this +is by defining a special part of the binary called `.text.privileged`. +This section is aligned to page boundaries. A GNU ld linker script is +used to ensure that code which morphs code is placed into this section, +through the use of a header-define cosmo-specific keyword `privileged`. +Additionally, the `fixupobj` program is used by the Cosmo build system +to ensure that compiled objects don't contain privileged functions that +call non-privileged functions. Needless to say, `mprotect()` needs to be +a privileged function, so that it can be used to disable the execute bit +on all other parts of the executable except for the privileged section, +thereby making it writable. Once this has been done, code can change. + +On Windows the diplacement bytes of the TLS instruction are changed to +use the `%gs:0x1480+i*8` ABI where `i` is a number assigned by the WIN32 +`TlsAlloc()` API. This avoids the need to call `TlsGetValue()` which is +implemented this exact same way under the hood. Even though 0x1480 isn't +explicitly documented by MSDN, this ABI is believed to be stable because +MSVC generates binaries that use this offset directly. The only caveat +is that `TlsAlloc()` must be called as early in the runtime init as +possible, to ensure an index less than 64 is returned. + +### Thread Information Block (TIB) + +The Actually Portable Exccutable Thread Information Block (TIB) is +defined by this version of the specification as follows: + +- The 64-bit TIB self-pointer is stored at offset 0x00. +- The 64-bit TIB self-pointer is stored at offset 0x30. +- The 32-bit `errno` value is stored at offset 0x3c. + +All other parts of the thread information block should be considered +unspecified and therefore reserved for future specifications. + +The APE thread information block is aligned on a 64-byte boundary. + +Cosmopolitan Libc v3.5.8 (c. 2024-07-21) currently implements a thread +information block that's 512 bytes in size. + +### Foreign Function Calls + +Even though APE programs always use the System V ABI, there arises the +occasional need to interface with foreign functions, e.g. WIN32. The +`__attribute__((__ms_abi__))` annotation introduced by GCC v6 is used +for this purpose. + +The ability to change a function's ABI on a case-by-case basis is +surprisingly enough supported by GCC, Clang, NVCC, and even the AMD HIP +compilers for both UNIX systems and Windows. All of these compilers +support both the System V ABI and the Microsoft x64 ABI. + +APE binaries will actually favor the Microsoft ABI even when running on +UNIX OSes for certain dlopen() use-cases. For example, if we control the +code to a CUDA module, which we compile on each OS separately from our +main APE binary, then any function that's inside the APE binary whose +pointer may be passed into a foreign module SHOULD be compiled to use +the Microsoft ABI. This is because in practice the OS-specific module +may need to be compiled by MSVC, where MS ABI is the *only* ABI, which +forces our UNIX programs to partially conform. Thankfully, all UNIX +compilers support doing it on a case-by-case basis. + +### Char Signedness + +Actually Portable Executable defines `char` as signed. + +Therefore conformant APE software MUST use `-fsigned-char` when building +code for aarch64, as well as any other architecture that (unlike x86-64) +would otherwise define `char` as being `unsigned char` by deafult. + +This decision was one of the cases where it made sense to offer a more +consistent runtime experience for fat multi-arch binaries. However you +SHOULD still write code to assume `char` can go either way. But if all +you care about is using APE, then you CAN assume `char` is signed. + +### Long Double + +On AMD64 platforms, APE binaries define `long double` as 80-bit. + +On ARM64 platforms, APE binaries define `long double` as 128-bit. + +We accept inconsistency in this case, because hardware acceleration is +far more valuable than stylistic consistency in the case of mathematics. + +One challenge arises on AMD64 for supporting `long double` across OSes. +Unlike UNIX systems, the Windows Executive on x86-64 initializes the x87 +FPU to have double (64-bit) precision rather than 80-bit. That's because +code compiled by MSVC treats `long double` as though it were `double` to +prefer always using the more modern SSE instructions. However System V +requires genuine 80-bit `long double` support on AMD64. + +Therefore, if an APE program detects that it's been started on a Windows +x86-64 system, then it SHOULD use the following assembly to initialize +the x87 FPU in System V ABI mode. + +```asm + fldcw 1f(%rip) + .rodata + .balign 2 +// 8087 FPU Control Word +// IM: Invalid Operation ───────────────┐ +// DM: Denormal Operand ───────────────┐│ +// ZM: Zero Divide ───────────────────┐││ +// OM: Overflow ─────────────────────┐│││ +// UM: Underflow ───────────────────┐││││ +// PM: Precision ──────────────────┐│││││ +// PC: Precision Control ───────┐ β”‚β”‚β”‚β”‚β”‚β”‚ +// {float,βˆ…,double,long double}β”‚ β”‚β”‚β”‚β”‚β”‚β”‚ +// RC: Rounding Control ──────┐ β”‚ β”‚β”‚β”‚β”‚β”‚β”‚ +// {even, β†’-∞, β†’+∞, β†’0} β”‚β”Œβ”€ β”‚β”‚β”‚β”‚β”‚β”‚ +// β”Œβ”€β”‚β”‚ β”‚β”‚β”‚β”‚β”‚β”‚ +// dβ”‚β”‚β”‚β”‚rrβ”‚β”‚β”‚β”‚β”‚β”‚ +1: .short 0b00000000000000000001101111111 + .previous +``` + +## Executable File Alignment + +Actually Portable Executable is a statically-linked flat executable file +format that is, as a thing in itself, agnostic to file alignments. For +example, the shell script payload at the beginning of the file and its +statements have no such requirements. Alignment requirements are however +imposed by the executable formats that APE wraps. + +1. ELF requires that file offsets be congruent with virtual addresses + modulo the CPU page size. So when we add a shell script to the start + of an executable, we need to round up to the page size in order to + maintain ELF's invariant. Although no such roundup is required on the + program segments once the invariant is restored. ELF loaders will + happily map program headers from arbitrary file intervals (which may + overlap) onto arbitrarily virtual intervals (which don't need to be + contiguous). in order to do that, the loaders will generally use + unix's mmap() function which needs to have both page aligned + addresses and file offsets, even though the ELF programs headers + themselves do not. Since program headers start and stop at + potentially any byte, ELF loaders tease the intervals specified by + program headers into conforming to mmap() requirements by rounding + out intervals as necessary in order to ensure that both the mmap() + size and offset parameters are page-size aligned. This means with + ELF, we never need to insert any empty space into a file when we + don't want to; we can simply allow the offset to drift apart from the + virtual offset. + +2. PE doesn't care about congruency and instead specifies a second kind + of alignment. The minimum alignment of files is 512 because that's + what MS-DOS used. Where things get hairy is with PE's SizeOfHeaders + which has complex requirements. When the PE image base needs to be + skewed, Windows imposes a separate 64kb alignment requirement on the + image base. Therefore an APE executable's `__executable_start` should + be aligned on at least a 64kb address. + +3. Apple's Mach-O format is the strictest of them all. While both ELF + and PE are defined in such a way that invites great creativity, XNU + will simply refuse to an executable that does anything creative with + alignment. All loaded segments need to both start and end on a page + aligned address. XNU also wants segments to be contiguous similar to + portable executable, except it applies to both the file and virtual + spaces, which must follow the same structure. + +Actually Portable Executables must conform to the strictest requirements +demanded by the support vector. Therefore an APE binary that has headers +for all three of the above executable formats MUST conform to the Apple +way of doing things. GNU ld linker scripts aren't very good at producing +ELF binaries that rigidly conform to this simple naive layout. There are +so many ways things can go wrong, where third party code might slip its +own custom section name in-between the linker script sections that are +explicitly defined, thereby causing ELF's powerful features to manifest +and the resulting content overlapping. The best `ld` flag that helps is +`--orphan-handling=error` which can help with explaining such mysteries. + +While Cosmopolitan was originally defined to just use stock GNU tools, +this proved intractable over time, and the project has been evolving in +the direction of building its own. Inventing the `apelink` program was +what enabled the project to achieve multi-architecture binaries whereas +previously it was only possible to do multi-OS binaries. In the future, +our hope is that a fast power linker like Mold can be adapted to produce +fat APE binaries directly from object files in one pass. + +## Position Independent Code + +APE doesn't currently support position independent executable formats. +This is because APE was originally written for the GNU linker, where PIC +and PIE were after-thoughts and never fully incorporated with the older +more powerful linker script techniques upon which APE relies. Future +iterations of this specification are intended to converge on modern +standards, as our tooling becomes developed enough to support it. + +However this only applies to the wrapped executable formats themselves. +While our convention to date has been to always load ELF programs at the +4mb mark, this is not guaranteed across OSes and architectures. Programs +should have no expectations that a program will be loaded to any given +address. For example, Cosmo currently implements APE on AARCH64 as +loading executables to a starting address of 0x000800000000. This +address occupies a sweet spot of requirements. + +## Address Space + +In order to create a single binary that supports as many platforms as +possible without needing to be recompiled, there's a very narrow range +of addresses that can be used. That range is somewhere between 32 bits +and 39 bits. + +- Embedded devices that claim to be 64-bit will oftentimes only support + a virtual address space that's 39 bits in size. + +- We can't load executable images on AARCH64 beneath 0x100000000 (4gb) + because Apple forbids doing that, possibly in an effort to enforce a + best practice for spotting 32-bit to 64-bit transition bugs. Please + note that this restriction only applies to Apple ARM64 systems. The + x86-64 version of XNU will happily load APE binaries to 0x00400000. + +- The AMD64 architecture on desktops and servers can usually be counted + upon to provide a 47-bit address space. The Linux Kernel for instance + grants each userspace program full dominion over addresses 0x00200000 + through 0x00007fffffffffff provided the hardware supports this. On + modern workstations supporting Intel and AMD's new PML5T feature which + virtualizes memory using a radix trie that's five layers deep, Linux + is able to offer userspace its choice of fixed addresses from + 0x00200000 through 0x00ffffffffffffff. The only exception to this rule + we've encountered so far is that Windows 7 and Windows Vista behaved + similar to embedded devices in reducing the number of va bits. + +## Page Size + +APE software MUST be page size agnostic. For many years the industry had +converged on a strong consensus of having a page size that's 4096 bytes. +However this convention was never guaranteed. New computers have become +extremely popular, such as Apple Silicon, that use a 16kb page size. + +In addition to being page size agnostic, APE software that cares about +working correctly on Windows needs to be aware of the concept of +allocation granularity. While the page size on Windows is generally 4kb +in size, memory mappings can only be created on addresses that aligned +to the system allocation granularity, which is generally 64kb. If you +use a function like mmap() with Cosmopolitan Libc, then the `addr` and +`offset` parameters need to be aligned to `sysconf(_SC_GRANSIZE)` or +else your software won't work on Windows. Windows has other limitations +too, such as lacking the abiilty to carve or punch holes in mappings. From 16d244614e8245f3ecedf60133f116663d1dae3e Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sun, 21 Jul 2024 21:18:12 -0700 Subject: [PATCH 069/405] Mention red zone in APE ABI specification --- ape/specification.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/ape/specification.md b/ape/specification.md index 94e8de308..b55970cba 100644 --- a/ape/specification.md +++ b/ape/specification.md @@ -306,6 +306,19 @@ APE binaries use the System V ABI, as defined by: There are however a few changes we've had to make. +### No Red Zone + +Actually Portable Executables that have Windows and/or bare metal in +their support vector MUST be compiled using `-mno-red-zone`. This is +because, on Windows, DLLs and other software lurking in the va-space +might use tricks like SetThreadContext() to take control of a thread +whereas on bare metal, it's also generally accepted that kernel-mode +code cannot assume a red zone either due to hardware interrutps that +pull the exact same kinds of stunts. + +APE software that only has truly System V ABI conformant OSes (e.g. +Linux) in their support vector MAY use the red zone optimization. + ### Thread Local Storage #### aarch64 @@ -668,6 +681,11 @@ converged on a strong consensus of having a page size that's 4096 bytes. However this convention was never guaranteed. New computers have become extremely popular, such as Apple Silicon, that use a 16kb page size. +By convention, Cosmopolitan Libc currently generates ELF headers for +x86-64 that are strictly aligned on a 4096-byte page size. On ARM64 +Cosmopolitan is currently implemented to always generate ELF headers +aligned on a 16kb page size. + In addition to being page size agnostic, APE software that cares about working correctly on Windows needs to be aware of the concept of allocation granularity. While the page size on Windows is generally 4kb From 62a97c919f0a5d6548ad009e49243debecf6201a Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Mon, 22 Jul 2024 01:41:44 -0700 Subject: [PATCH 070/405] Fix typos in APE specification Fixes #1244 --- ape/specification.md | 31 ++++++++++++++++--------------- libc/calls/sig.c | 33 +++++++++++---------------------- 2 files changed, 27 insertions(+), 37 deletions(-) diff --git a/ape/specification.md b/ape/specification.md index b55970cba..74a8720f0 100644 --- a/ape/specification.md +++ b/ape/specification.md @@ -36,8 +36,9 @@ considered an APE program. This is the canonical magic used by almost all APE programs. It enables maximum portability between OSes. When interpreted as a shell script, it -is assiging a single quoted string to an unused variable. The shell will -then ignore subsequent binary content that's placed inside the string. +is assigning a single quoted string to an unused variable. The shell +will then ignore subsequent binary content that's placed inside the +string. It is strongly recommended that this magic value be immediately followed by a newline (\n or hex 0a) character. Some shells, e.g. FreeBSD SH and @@ -167,12 +168,12 @@ printf '\177ELF\2\1\1\011\0\0\0\0\0\0\0\0\2\0\076\0\1\0\0\0\166\105\100\000\000\ This `printf` statement MUST appear in the first 8192 bytes of the APE executable, so as to limit how much of the initial portion of a file an -intepreter must load. +interpreter must load. -Multiple such `printf` statements MAY appear in hte first 8192 bytes, in +Multiple such `printf` statements MAY appear in the first 8192 bytes, in order to specify multiple architectures. For example, fat binaries built by the `apelink` program (provided by Cosmo Libc) will have two encoded -ELF headers, for amd64 and arm64, each of which point into the proper +ELF headers, for AMD64 and ARM64, each of which point into the proper file offsets for their respective native code. Therefore, kernels and interpreters which load the APE format directly MUST check the `e_machine` field of the `Elf64_Ehdr` that's decoded from the octal @@ -313,7 +314,7 @@ their support vector MUST be compiled using `-mno-red-zone`. This is because, on Windows, DLLs and other software lurking in the va-space might use tricks like SetThreadContext() to take control of a thread whereas on bare metal, it's also generally accepted that kernel-mode -code cannot assume a red zone either due to hardware interrutps that +code cannot assume a red zone either due to hardware interrupts that pull the exact same kinds of stunts. APE software that only has truly System V ABI conformant OSes (e.g. @@ -350,7 +351,7 @@ would be friction-free alternative. It's not possible for an APE runtime that targets the full range of OSes to use the `tpidr_el0` register for TLS because Apple won't allow it. On -MacOS ARM64 systems, this reigster can only be used by a runtime to +MacOS ARM64 systems, this register can only be used by a runtime to implement the `sched_getcpu()` system call. It's reserved by MacOS. #### x86-64 @@ -441,11 +442,11 @@ static void ChangeTlsFsToGs(unsigned char *p, size_t n) { } ``` -By favoring `%gs` we've now ensured friction-free compatibilty for the +By favoring `%gs` we've now ensured friction-free compatibility for the APE runtime on MacOS, Linux, and FreeBSD which are all able to conform easily to this convention. However additional work needs to be done at runtime when an APE program is started on Windows, OpenBSD, and NetBSD. -On these platforms, all executable pages must be faulted and morped to +On these platforms, all executable pages must be faulted and morphed to fixup the TLS instructions. On OpenBSD and NetBSD, this is as simple as undoing the example @@ -466,7 +467,7 @@ a privileged function, so that it can be used to disable the execute bit on all other parts of the executable except for the privileged section, thereby making it writable. Once this has been done, code can change. -On Windows the diplacement bytes of the TLS instruction are changed to +On Windows the displacement bytes of the TLS instruction are changed to use the `%gs:0x1480+i*8` ABI where `i` is a number assigned by the WIN32 `TlsAlloc()` API. This avoids the need to call `TlsGetValue()` which is implemented this exact same way under the hood. Even though 0x1480 isn't @@ -477,7 +478,7 @@ possible, to ensure an index less than 64 is returned. ### Thread Information Block (TIB) -The Actually Portable Exccutable Thread Information Block (TIB) is +The Actually Portable Executable Thread Information Block (TIB) is defined by this version of the specification as follows: - The 64-bit TIB self-pointer is stored at offset 0x00. @@ -520,7 +521,7 @@ Actually Portable Executable defines `char` as signed. Therefore conformant APE software MUST use `-fsigned-char` when building code for aarch64, as well as any other architecture that (unlike x86-64) -would otherwise define `char` as being `unsigned char` by deafult. +would otherwise define `char` as being `unsigned char` by default. This decision was one of the cases where it made sense to offer a more consistent runtime experience for fat multi-arch binaries. However you @@ -584,7 +585,7 @@ imposed by the executable formats that APE wraps. happily map program headers from arbitrary file intervals (which may overlap) onto arbitrarily virtual intervals (which don't need to be contiguous). in order to do that, the loaders will generally use - unix's mmap() function which needs to have both page aligned + UNIX's mmap() function which needs to have both page aligned addresses and file offsets, even though the ELF programs headers themselves do not. Since program headers start and stop at potentially any byte, ELF loaders tease the intervals specified by @@ -595,7 +596,7 @@ imposed by the executable formats that APE wraps. don't want to; we can simply allow the offset to drift apart from the virtual offset. -2. PE doesn't care about congruency and instead specifies a second kind +2. PE doesn't care about congruence and instead specifies a second kind of alignment. The minimum alignment of files is 512 because that's what MS-DOS used. Where things get hairy is with PE's SizeOfHeaders which has complex requirements. When the PE image base needs to be @@ -694,4 +695,4 @@ to the system allocation granularity, which is generally 64kb. If you use a function like mmap() with Cosmopolitan Libc, then the `addr` and `offset` parameters need to be aligned to `sysconf(_SC_GRANSIZE)` or else your software won't work on Windows. Windows has other limitations -too, such as lacking the abiilty to carve or punch holes in mappings. +too, such as lacking the ability to carve or punch holes in mappings. diff --git a/libc/calls/sig.c b/libc/calls/sig.c index a52ad2bc7..247c56746 100644 --- a/libc/calls/sig.c +++ b/libc/calls/sig.c @@ -96,9 +96,8 @@ static textwindows int __sig_getter(atomic_ulong *sigs, sigset_t masked) { if ((deliverable = pending & ~masked)) { sig = bsfl(deliverable) + 1; bit = 1ull << (sig - 1); - if (atomic_fetch_and_explicit(sigs, ~bit, memory_order_acq_rel) & bit) { + if (atomic_fetch_and_explicit(sigs, ~bit, memory_order_acq_rel) & bit) return sig; - } } else { return 0; } @@ -107,28 +106,23 @@ static textwindows int __sig_getter(atomic_ulong *sigs, sigset_t masked) { textwindows int __sig_get(sigset_t masked) { int sig; - if (!(sig = __sig_getter(&__get_tls()->tib_sigpending, masked))) { + if (!(sig = __sig_getter(&__get_tls()->tib_sigpending, masked))) sig = __sig_getter(&__sig.pending, masked); - } return sig; } static textwindows bool __sig_should_use_altstack(unsigned flags, struct CosmoTib *tib) { - if (!(flags & SA_ONSTACK)) { + if (!(flags & SA_ONSTACK)) return false; // signal handler didn't enable it - } - if (!tib->tib_sigstack_size) { + if (!tib->tib_sigstack_size) return false; // sigaltstack() wasn't installed on this thread - } - if (tib->tib_sigstack_flags & SS_DISABLE) { + if (tib->tib_sigstack_flags & SS_DISABLE) return false; // sigaltstack() on this thread was disabled by user - } char *bp = __builtin_frame_address(0); if (tib->tib_sigstack_addr <= bp && - bp <= tib->tib_sigstack_addr + tib->tib_sigstack_size) { + bp <= tib->tib_sigstack_addr + tib->tib_sigstack_size) return false; // we're already on the alternate stack - } return true; } @@ -282,9 +276,8 @@ static textwindows wontreturn void __sig_tramp(struct SignalFrame *sf) { // jump back into original code if there aren't any pending signals do { - if (!(sig = __sig_get(sf->ctx.uc_sigmask))) { + if (!(sig = __sig_get(sf->ctx.uc_sigmask))) __sig_restore(&sf->ctx); - } } while (!__sig_start(pt, sig, &sf->rva, &sf->flags)); // tail recurse into another signal handler @@ -459,11 +452,9 @@ textwindows void __sig_generate(int sig, int sic) { static textwindows char *__sig_stpcpy(char *d, const char *s) { size_t i; - for (i = 0;; ++i) { - if (!(d[i] = s[i])) { + for (i = 0;; ++i) + if (!(d[i] = s[i])) return d + i; - } - } } static textwindows wontreturn void __sig_death(int sig, const char *thing) { @@ -500,9 +491,8 @@ static textwindows void __sig_unmaskable(struct NtExceptionPointers *ep, // if the user didn't install a signal handler for this unmaskable // exception, then print a friendly helpful hint message to stderr unsigned rva = __sighandrvas[sig]; - if (rva == (intptr_t)SIG_DFL || rva == (intptr_t)SIG_IGN) { + if (rva == (intptr_t)SIG_DFL || rva == (intptr_t)SIG_IGN) __sig_death(sig, "uncaught "); - } // if this signal handler is configured to auto-reset to the default // then that reset needs to happen before the user handler is called @@ -560,9 +550,8 @@ __msabi dontinstrument unsigned __sig_crash(struct NtExceptionPointers *ep) { // this behavior is consistent with how unix kernels are implemented if (sig == SIGTRAP) { ep->ContextRecord->Rip++; - if (__sig_ignored(sig)) { + if (__sig_ignored(sig)) return kNtExceptionContinueExecution; - } } // win32 stack overflow detection executes INSIDE the guard page From 23611cd854795db5e8538c35d5f1c686fdc6fc0e Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Mon, 22 Jul 2024 02:10:51 -0700 Subject: [PATCH 071/405] Talk more about alignment --- ape/specification.md | 47 ++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/ape/specification.md b/ape/specification.md index 74a8720f0..b7f846d03 100644 --- a/ape/specification.md +++ b/ape/specification.md @@ -292,7 +292,7 @@ different OSes define incompatible ABIs. While it was possible to polyglot PE+ELF+MachO to create multi-OS executables, it simply isn't possible to do that same thing for -DLL+DLIB+SO. Therefore, in order to have DSOs, APE would need to either +DLL+DYLIB+SO. Therefore, in order to have DSOs, APE would need to either choose one of the existing formats or invent one of its own, and then develop its own parallel ecosystem of extension software. In the future, the APE specification may expand to encompass this. However the focus to @@ -459,7 +459,7 @@ can't modify itself at the same time. The way Cosmopolitan solves this is by defining a special part of the binary called `.text.privileged`. This section is aligned to page boundaries. A GNU ld linker script is used to ensure that code which morphs code is placed into this section, -through the use of a header-define cosmo-specific keyword `privileged`. +through the use of a header-defined cosmo-specific keyword `privileged`. Additionally, the `fixupobj` program is used by the Cosmo build system to ensure that compiled objects don't contain privileged functions that call non-privileged functions. Needless to say, `mprotect()` needs to be @@ -482,7 +482,7 @@ The Actually Portable Executable Thread Information Block (TIB) is defined by this version of the specification as follows: - The 64-bit TIB self-pointer is stored at offset 0x00. -- The 64-bit TIB self-pointer is stored at offset 0x30. +- The 64-bit TIB self-pointer is also stored at offset 0x30. - The 32-bit `errno` value is stored at offset 0x3c. All other parts of the thread information block should be considered @@ -584,25 +584,30 @@ imposed by the executable formats that APE wraps. program segments once the invariant is restored. ELF loaders will happily map program headers from arbitrary file intervals (which may overlap) onto arbitrarily virtual intervals (which don't need to be - contiguous). in order to do that, the loaders will generally use - UNIX's mmap() function which needs to have both page aligned - addresses and file offsets, even though the ELF programs headers - themselves do not. Since program headers start and stop at - potentially any byte, ELF loaders tease the intervals specified by - program headers into conforming to mmap() requirements by rounding - out intervals as necessary in order to ensure that both the mmap() - size and offset parameters are page-size aligned. This means with - ELF, we never need to insert any empty space into a file when we - don't want to; we can simply allow the offset to drift apart from the - virtual offset. + contiguous). In order to do that, the loaders will generally use + UNIX's mmap() function which is more restrictive and only accepts + addresses and offsets that are page aligned. To make it possible to + map an unaligned ELF program header that could potentially start and + stop at any byte, ELF loaders round-out the intervals, which means + adjacent unrelated data might also get mapped, which may need to be + explicitly zero'd. Thanks to the cleverness of ELF, it's possible to + have an executable file be very tiny, without needing any alignment + bytes, and it'll be loaded into a properly aligned virtual space + where segments can be as sparse as we want them to be. -2. PE doesn't care about congruence and instead specifies a second kind - of alignment. The minimum alignment of files is 512 because that's - what MS-DOS used. Where things get hairy is with PE's SizeOfHeaders - which has complex requirements. When the PE image base needs to be - skewed, Windows imposes a separate 64kb alignment requirement on the - image base. Therefore an APE executable's `__executable_start` should - be aligned on at least a 64kb address. +2. PE doesn't care about congruence and instead defines two separate + kinds of alignment. First, PE requires that the layout of segment + memory inside the file be aligned on at minimum the classic 512 byte + MS-DOS page size. This means that, unlike ELF, some alignment padding + may need to be encoded into the file, making it slightly larger. Next + PE imposes an alignment restriction on segments once they've been + mapped into the virtual address space, which must be rounded to the + system page size. Like ELF, PE segments need to be properly ordered + but they're allowed to drift apart once mapped in a non-contiguous + sparsely mapped way. When inserting shell script content at the start + of a PE file, the most problematic thing is the need to round up to + the 64kb system granularity, which results in a lot of needless bytes + of padding being inserted by a naive second-pass linker. 3. Apple's Mach-O format is the strictest of them all. While both ELF and PE are defined in such a way that invites great creativity, XNU From c83ec5fdd992410ba426b7cbaedcaeb058aac717 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Mon, 22 Jul 2024 02:28:41 -0700 Subject: [PATCH 072/405] Fix more issues --- ape/specification.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ape/specification.md b/ape/specification.md index b7f846d03..c88ddaa63 100644 --- a/ape/specification.md +++ b/ape/specification.md @@ -239,11 +239,11 @@ iterations over APE's history before we eventually got it right: - `arg=$(( 9293))` b/c busybox sh disliked quoted space - `arg=9293 ` is generated by modern apelink program -Software that parses the APE file format, which needs to extract to be -able extract the Macho-O x86-64 header SHOULD support the old binaries -that use the previous encodings. To make backwards compatibility simple -the following regular expression may be used, which generalizes to all -defined formats: +Software that parses the APE file format, which needs to extract the +Macho-O x86-64 header SHOULD support the old binaries that use the +previous encodings. To make backwards compatibility simple the following +regular expression may be used, which generalizes to all defined +formats: ```c regcomp(&rx, From 3de6632be60f574cf18b68cd24312593f31bb456 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Mon, 22 Jul 2024 07:14:35 -0700 Subject: [PATCH 073/405] Graduate some clock_gettime() constants to #define - CLOCK_THREAD_CPUTIME_ID - CLOCK_PROCESS_CPUTIME_ID Cosmo now supports the above constants universally across supported OSes therefore it's now safe to let programs detect their presence w/ #ifdefs --- ape/specification.md | 4 ++-- libc/runtime/weakfree.c | 3 +-- libc/sysv/consts/clock.h | 6 ++++-- libc/thread/pthread_create.c | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/ape/specification.md b/ape/specification.md index c88ddaa63..9ac4a7a4d 100644 --- a/ape/specification.md +++ b/ape/specification.md @@ -402,8 +402,8 @@ arises in the fact that our Linux-flavored GCC and Clang toolchains producing TLS instructions that use the %fs convention. To solve these challenges, the `cosmocc` compiler will rewrite binary -objects after they've been compiled by GCC, so that `%gs` register is -used, rather than `%fs`. Morphing x86-64 binaries after they've been +objects after they've been compiled by GCC, so that the `%gs` register +is used, rather than `%fs`. Morphing x86-64 binaries after they've been compiled is normally difficult, due to the complexity of the machine instruction language. However GCC provides `-mno-tls-direct-seg-refs` which greatly reduces the complexity of this task. This flag forgoes diff --git a/libc/runtime/weakfree.c b/libc/runtime/weakfree.c index bd6e561ec..5e5f57877 100644 --- a/libc/runtime/weakfree.c +++ b/libc/runtime/weakfree.c @@ -24,7 +24,6 @@ * Thunks free() if it's linked, otherwise do nothing. */ void _weakfree(void *p) { - if (_weaken(free)) { + if (_weaken(free)) _weaken(free)(p); - } } diff --git a/libc/sysv/consts/clock.h b/libc/sysv/consts/clock.h index ae4f010e0..4b6e7b193 100644 --- a/libc/sysv/consts/clock.h +++ b/libc/sysv/consts/clock.h @@ -24,7 +24,9 @@ extern const int CLOCK_UPTIME_PRECISE; COSMOPOLITAN_C_END_ -#define CLOCK_REALTIME 0 -#define CLOCK_MONOTONIC CLOCK_MONOTONIC +#define CLOCK_REALTIME 0 +#define CLOCK_MONOTONIC CLOCK_MONOTONIC +#define CLOCK_PROCESS_CPUTIME_ID CLOCK_PROCESS_CPUTIME_ID +#define CLOCK_THREAD_CPUTIME_ID CLOCK_THREAD_CPUTIME_ID #endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_CLOCK_H_ */ diff --git a/libc/thread/pthread_create.c b/libc/thread/pthread_create.c index 42a3b45a1..6f9c86469 100644 --- a/libc/thread/pthread_create.c +++ b/libc/thread/pthread_create.c @@ -118,7 +118,7 @@ void _pthread_decimate(bool annihilation_only) { if (status != kPosixThreadZombie) break; // zombies only exist at the end of the linked list if (atomic_load_explicit(&pt->tib->tib_tid, memory_order_acquire)) - continue; // undead thread should that'll stop existing soon + continue; // undead thread that should stop existing soon dll_remove(&_pthread_list, e); dll_make_first(&list, e); } From 0a9a6f86bb4aa7ef1b40fefa249e83277921b4ba Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Mon, 22 Jul 2024 16:33:23 -0700 Subject: [PATCH 074/405] Support process shared condition variables --- libc/intrin/pthread_mutex_lock.c | 2 + libc/intrin/pthread_mutex_trylock.c | 2 + libc/intrin/pthread_mutex_unlock.c | 2 + libc/intrin/pthread_yield_np.c | 11 ++- .../{sched_yield.S => sys_sched_yield.S} | 5 +- libc/thread/pthread_cond_broadcast.c | 20 ++++- libc/thread/pthread_cond_destroy.c | 19 +++++ libc/thread/pthread_cond_init.c | 2 + libc/thread/pthread_cond_signal.c | 17 +++- libc/thread/pthread_cond_timedwait.c | 85 +++++++++++++++++-- libc/thread/sem_open.c | 3 +- libc/thread/sem_timedwait.c | 6 +- libc/thread/thread.h | 11 ++- test/posix/mutex_async_signal_safety_test.c | 2 +- 14 files changed, 168 insertions(+), 19 deletions(-) rename libc/intrin/{sched_yield.S => sys_sched_yield.S} (98%) diff --git a/libc/intrin/pthread_mutex_lock.c b/libc/intrin/pthread_mutex_lock.c index 99d4d9ba2..0b96949de 100644 --- a/libc/intrin/pthread_mutex_lock.c +++ b/libc/intrin/pthread_mutex_lock.c @@ -37,6 +37,7 @@ static errno_t pthread_mutex_lock_impl(pthread_mutex_t *mutex) { // get current state of lock word = atomic_load_explicit(&mutex->_word, memory_order_relaxed); +#if PTHREAD_USE_NSYNC // use fancy nsync mutex if possible if (MUTEX_TYPE(word) == PTHREAD_MUTEX_NORMAL && // MUTEX_PSHARED(word) == PTHREAD_PROCESS_PRIVATE && // @@ -44,6 +45,7 @@ static errno_t pthread_mutex_lock_impl(pthread_mutex_t *mutex) { _weaken(nsync_mu_lock)((nsync_mu *)mutex); return 0; } +#endif // implement barebones normal mutexes if (MUTEX_TYPE(word) == PTHREAD_MUTEX_NORMAL) { diff --git a/libc/intrin/pthread_mutex_trylock.c b/libc/intrin/pthread_mutex_trylock.c index 21513656a..a793eed34 100644 --- a/libc/intrin/pthread_mutex_trylock.c +++ b/libc/intrin/pthread_mutex_trylock.c @@ -46,6 +46,7 @@ errno_t pthread_mutex_trylock(pthread_mutex_t *mutex) { // get current state of lock word = atomic_load_explicit(&mutex->_word, memory_order_relaxed); +#if PTHREAD_USE_NSYNC // delegate to *NSYNC if possible if (MUTEX_TYPE(word) == PTHREAD_MUTEX_NORMAL && MUTEX_PSHARED(word) == PTHREAD_PROCESS_PRIVATE && // @@ -56,6 +57,7 @@ errno_t pthread_mutex_trylock(pthread_mutex_t *mutex) { return EBUSY; } } +#endif // handle normal mutexes if (MUTEX_TYPE(word) == PTHREAD_MUTEX_NORMAL) { diff --git a/libc/intrin/pthread_mutex_unlock.c b/libc/intrin/pthread_mutex_unlock.c index 652896475..4d796d9a4 100644 --- a/libc/intrin/pthread_mutex_unlock.c +++ b/libc/intrin/pthread_mutex_unlock.c @@ -45,6 +45,7 @@ errno_t pthread_mutex_unlock(pthread_mutex_t *mutex) { // get current state of lock word = atomic_load_explicit(&mutex->_word, memory_order_relaxed); +#if PTHREAD_USE_NSYNC // use fancy nsync mutex if possible if (MUTEX_TYPE(word) == PTHREAD_MUTEX_NORMAL && // MUTEX_PSHARED(word) == PTHREAD_PROCESS_PRIVATE && // @@ -52,6 +53,7 @@ errno_t pthread_mutex_unlock(pthread_mutex_t *mutex) { _weaken(nsync_mu_unlock)((nsync_mu *)mutex); return 0; } +#endif // implement barebones normal mutexes if (MUTEX_TYPE(word) == PTHREAD_MUTEX_NORMAL) { diff --git a/libc/intrin/pthread_yield_np.c b/libc/intrin/pthread_yield_np.c index dd209e6be..fefc3f283 100644 --- a/libc/intrin/pthread_yield_np.c +++ b/libc/intrin/pthread_yield_np.c @@ -22,6 +22,8 @@ #include "libc/runtime/syslib.internal.h" #include "libc/thread/thread.h" +void sys_sched_yield(void); + /** * Yields current thread's remaining timeslice to operating system. * @@ -30,13 +32,16 @@ int pthread_yield_np(void) { if (IsXnuSilicon()) { __syslib->__pthread_yield_np(); - } else if (IsOpenbsd()) { - pthread_pause_np(); // sched_yield() is punishingly slow on OpenBSD + } else if (IsOpenbsd() || IsNetbsd()) { + // sched_yield() is punishingly slow on OpenBSD + // it's ruinously slow it'll destroy everything + pthread_pause_np(); } else { - sched_yield(); + sys_sched_yield(); } return 0; } __weak_reference(pthread_yield_np, thrd_yield); +__weak_reference(pthread_yield_np, sched_yield); __weak_reference(pthread_yield_np, pthread_yield); diff --git a/libc/intrin/sched_yield.S b/libc/intrin/sys_sched_yield.S similarity index 98% rename from libc/intrin/sched_yield.S rename to libc/intrin/sys_sched_yield.S index 42433fa6d..eab709511 100644 --- a/libc/intrin/sched_yield.S +++ b/libc/intrin/sys_sched_yield.S @@ -19,12 +19,11 @@ #include "libc/dce.h" #include "libc/sysv/consts/nr.h" #include "libc/macros.internal.h" -.privileged // Relinquishes scheduled quantum. // // @return 0 on success, or -1 w/ errno -sched_yield: +sys_sched_yield: #ifdef __x86_64__ push %rbp mov %rsp,%rbp @@ -107,5 +106,5 @@ sched_yield: #else #error "arch unsupported" #endif - .endfn sched_yield,globl + .endfn sys_sched_yield,globl .previous diff --git a/libc/thread/pthread_cond_broadcast.c b/libc/thread/pthread_cond_broadcast.c index df68a2ec1..b757c867c 100644 --- a/libc/thread/pthread_cond_broadcast.c +++ b/libc/thread/pthread_cond_broadcast.c @@ -1,7 +1,7 @@ /*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-β”‚ β”‚ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi β”‚ β•žβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•‘ -β”‚ Copyright 2022 Justine Alexandra Roberts Tunney β”‚ +β”‚ Copyright 2024 Justine Alexandra Roberts Tunney β”‚ β”‚ β”‚ β”‚ Permission to use, copy, modify, and/or distribute this software for β”‚ β”‚ any purpose with or without fee is hereby granted, provided that the β”‚ @@ -16,8 +16,11 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/intrin/atomic.h" +#include "libc/limits.h" #include "libc/thread/thread.h" #include "third_party/nsync/cv.h" +#include "third_party/nsync/futex.internal.h" /** * Wakes all threads waiting on condition, e.g. @@ -37,6 +40,19 @@ * @see pthread_cond_wait */ errno_t pthread_cond_broadcast(pthread_cond_t *cond) { - nsync_cv_broadcast((nsync_cv *)cond); + +#if PTHREAD_USE_NSYNC + // favor *NSYNC if this is a process private condition variable + // if using Mike Burrows' code isn't possible, use a naive impl + if (!cond->_pshared) { + nsync_cv_broadcast((nsync_cv *)cond); + return 0; + } +#endif + + // roll forward the monotonic sequence + atomic_fetch_add_explicit(&cond->_sequence, 1, memory_order_acq_rel); + if (atomic_load_explicit(&cond->_waiters, memory_order_acquire)) + nsync_futex_wake_((atomic_int *)&cond->_sequence, INT_MAX, cond->_pshared); return 0; } diff --git a/libc/thread/pthread_cond_destroy.c b/libc/thread/pthread_cond_destroy.c index 3dbd8971b..0b77c88f2 100644 --- a/libc/thread/pthread_cond_destroy.c +++ b/libc/thread/pthread_cond_destroy.c @@ -16,8 +16,11 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/errno.h" +#include "libc/intrin/atomic.h" #include "libc/str/str.h" #include "libc/thread/thread.h" +#include "third_party/nsync/cv.h" /** * Destroys condition. @@ -26,6 +29,22 @@ * @raise EINVAL if threads are still waiting on condition */ errno_t pthread_cond_destroy(pthread_cond_t *cond) { + + // check if there's active waiters +#if PTHREAD_USE_NSYNC + if (cond->_pshared) { + if (((nsync_cv *)cond)->waiters) + return EINVAL; + } else { + if (atomic_load_explicit(&cond->_waiters, memory_order_relaxed)) + return EINVAL; + } +#else + if (atomic_load_explicit(&cond->_waiters, memory_order_relaxed)) + return EINVAL; +#endif + + // destroy object memset(cond, -1, sizeof(*cond)); return 0; } diff --git a/libc/thread/pthread_cond_init.c b/libc/thread/pthread_cond_init.c index 915e6bc6f..8f6fbe298 100644 --- a/libc/thread/pthread_cond_init.c +++ b/libc/thread/pthread_cond_init.c @@ -27,5 +27,7 @@ errno_t pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) { *cond = (pthread_cond_t){0}; + if (attr) + cond->_pshared = *attr; return 0; } diff --git a/libc/thread/pthread_cond_signal.c b/libc/thread/pthread_cond_signal.c index e490bb402..e2a615df0 100644 --- a/libc/thread/pthread_cond_signal.c +++ b/libc/thread/pthread_cond_signal.c @@ -16,8 +16,10 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/intrin/atomic.h" #include "libc/thread/thread.h" #include "third_party/nsync/cv.h" +#include "third_party/nsync/futex.internal.h" /** * Wakes at least one thread waiting on condition, e.g. @@ -37,6 +39,19 @@ * @see pthread_cond_wait */ errno_t pthread_cond_signal(pthread_cond_t *cond) { - nsync_cv_signal((nsync_cv *)cond); + +#if PTHREAD_USE_NSYNC + // favor *NSYNC if this is a process private condition variable + // if using Mike Burrows' code isn't possible, use a naive impl + if (!cond->_pshared) { + nsync_cv_signal((nsync_cv *)cond); + return 0; + } +#endif + + // roll forward the monotonic sequence + atomic_fetch_add_explicit(&cond->_sequence, 1, memory_order_acq_rel); + if (atomic_load_explicit(&cond->_waiters, memory_order_acquire)) + nsync_futex_wake_((atomic_int *)&cond->_sequence, 1, cond->_pshared); return 0; } diff --git a/libc/thread/pthread_cond_timedwait.c b/libc/thread/pthread_cond_timedwait.c index 6d964449b..84e5fe7ef 100644 --- a/libc/thread/pthread_cond_timedwait.c +++ b/libc/thread/pthread_cond_timedwait.c @@ -16,14 +16,61 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/calls/calls.h" +#include "libc/calls/cp.internal.h" #include "libc/errno.h" #include "libc/thread/lock.h" +#include "libc/thread/posixthread.internal.h" #include "libc/thread/thread.h" #include "libc/thread/thread2.h" #include "third_party/nsync/common.internal.h" #include "third_party/nsync/cv.h" +#include "third_party/nsync/futex.internal.h" #include "third_party/nsync/time.h" +struct PthreadWait { + pthread_cond_t *cond; + pthread_mutex_t *mutex; +}; + +static void pthread_cond_leave(void *arg) { + struct PthreadWait *wait = (struct PthreadWait *)arg; + if (pthread_mutex_lock(wait->mutex)) + __builtin_trap(); + atomic_fetch_sub_explicit(&wait->cond->_waiters, 1, memory_order_acq_rel); +} + +static errno_t pthread_cond_timedwait_impl(pthread_cond_t *cond, + pthread_mutex_t *mutex, + const struct timespec *abstime) { + + // this is a cancelation point + // check the cancelation status before we begin waiting + if (pthread_testcancel_np() == ECANCELED) + return ECANCELED; + + // get original monotonic sequence while lock is held + uint32_t seq1 = atomic_load_explicit(&cond->_sequence, memory_order_relaxed); + + // start waiting on condition variable + atomic_fetch_add_explicit(&cond->_waiters, 1, memory_order_acq_rel); + if (pthread_mutex_unlock(mutex)) + __builtin_trap(); + + // wait for sequence change, timeout, or cancelation + int rc; + struct PthreadWait waiter = {cond, mutex}; + pthread_cleanup_push(pthread_cond_leave, &waiter); + rc = nsync_futex_wait_((atomic_int *)&cond->_sequence, seq1, cond->_pshared, + abstime); + pthread_cleanup_pop(true); + if (rc == -EAGAIN) + rc = 0; + + // turn linux syscall status into posix errno + return -rc; +} + /** * Waits for condition with optional time limit, e.g. * @@ -49,11 +96,39 @@ */ errno_t pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime) { + + // validate arguments + struct PosixThread *pt; + if (!(pt = _pthread_self())) + return EINVAL; if (abstime && !(0 <= abstime->tv_nsec && abstime->tv_nsec < 1000000000)) return EINVAL; - if (MUTEX_TYPE(mutex->_word) != PTHREAD_MUTEX_NORMAL) - nsync_panic_("pthread cond needs normal mutex\n"); - return nsync_cv_wait_with_deadline( - (nsync_cv *)cond, (nsync_mu *)mutex, - abstime ? *abstime : nsync_time_no_deadline, 0); + + // look at the mutex argument + uint64_t muword = atomic_load_explicit(&mutex->_word, memory_order_relaxed); + + // check that mutex is held by caller + if (MUTEX_TYPE(muword) == PTHREAD_MUTEX_ERRORCHECK && + MUTEX_OWNER(muword) != gettid()) + return EPERM; + + // if condition variable is shared then mutex must be too + if (cond->_pshared) + if (MUTEX_PSHARED(muword) != PTHREAD_PROCESS_SHARED) + return EINVAL; + +#if PTHREAD_USE_NSYNC + // favor *NSYNC if this is a process private condition variable + // if using Mike Burrows' code isn't possible, use a naive impl + if (!cond->_pshared) + return nsync_cv_wait_with_deadline( + (nsync_cv *)cond, (nsync_mu *)mutex, + abstime ? *abstime : nsync_time_no_deadline, 0); +#endif + + errno_t err; + BEGIN_CANCELATION_POINT; + err = pthread_cond_timedwait_impl(cond, mutex, abstime); + END_CANCELATION_POINT; + return err; } diff --git a/libc/thread/sem_open.c b/libc/thread/sem_open.c index 9a3e5b2ce..d708ef7e4 100644 --- a/libc/thread/sem_open.c +++ b/libc/thread/sem_open.c @@ -183,7 +183,8 @@ sem_t *sem_open(const char *name, int oflag, ...) { #if 0 if (IsXnuSilicon()) { long kernel; - if (!(sem = calloc(1, sizeof(sem_t)))) return SEM_FAILED; + if (!(sem = calloc(1, sizeof(sem_t)))) + return SEM_FAILED; sem->sem_magic = SEM_MAGIC_KERNEL; kernel = _sysret(__syslib->__sem_open(name, oflag, mode, value)); if (kernel == -1) { diff --git a/libc/thread/sem_timedwait.c b/libc/thread/sem_timedwait.c index 2ffcbf5ee..bd2e5d9d9 100644 --- a/libc/thread/sem_timedwait.c +++ b/libc/thread/sem_timedwait.c @@ -81,13 +81,15 @@ int sem_timedwait(sem_t *sem, const struct timespec *abstime) { return ecanceled(); } rc = _sysret(__syslib->__sem_trywait(sem->sem_kernel)); - if (!rc) return 0; + if (!rc) + return 0; if (errno == EINTR && // _weaken(pthread_testcancel_np) && // _weaken(pthread_testcancel_np)()) { return ecanceled(); } - if (errno != EAGAIN) return -1; + if (errno != EAGAIN) + return -1; errno = e; struct timespec now = timespec_real(); if (timespec_cmp(*abstime, now) >= 0) { diff --git a/libc/thread/thread.h b/libc/thread/thread.h index af8ecd60c..406c19ff8 100644 --- a/libc/thread/thread.h +++ b/libc/thread/thread.h @@ -3,6 +3,7 @@ #define PTHREAD_KEYS_MAX 46 #define PTHREAD_STACK_MIN 65536 +#define PTHREAD_USE_NSYNC 1 #define PTHREAD_DESTRUCTOR_ITERATIONS 4 #define PTHREAD_BARRIER_SERIAL_THREAD 31337 @@ -74,7 +75,15 @@ typedef struct pthread_mutexattr_s { } pthread_mutexattr_t; typedef struct pthread_cond_s { - void *_nsync[2]; + union { + void *_align; + struct { + uint32_t _nsync; + char _pshared; + }; + }; + _Atomic(uint32_t) _sequence; + _Atomic(uint32_t) _waiters; } pthread_cond_t; typedef struct pthread_rwlock_s { diff --git a/test/posix/mutex_async_signal_safety_test.c b/test/posix/mutex_async_signal_safety_test.c index d9da7b6bc..5102ab2fb 100644 --- a/test/posix/mutex_async_signal_safety_test.c +++ b/test/posix/mutex_async_signal_safety_test.c @@ -66,7 +66,7 @@ int main() { if (ready) break; - for (int i = 0; i < 1000; ++i) { + for (int i = 0; i < 100; ++i) { if (pthread_kill(th, SIGUSR1)) _Exit(11); if (pthread_kill(th, SIGUSR1)) From 61c36c1dd6a5ac16077357daf67775661b6fbd82 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Mon, 22 Jul 2024 18:41:45 -0700 Subject: [PATCH 075/405] Allow pthread_condattr_setpshared() to set shared --- libc/thread/pthread_condattr_setpshared.c | 3 +- .../libc/thread/pthread_setaffinity_np_test.c | 59 +++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 test/libc/thread/pthread_setaffinity_np_test.c diff --git a/libc/thread/pthread_condattr_setpshared.c b/libc/thread/pthread_condattr_setpshared.c index 801017c67..8d59b2fa7 100644 --- a/libc/thread/pthread_condattr_setpshared.c +++ b/libc/thread/pthread_condattr_setpshared.c @@ -24,12 +24,13 @@ * * @param pshared can be one of * - `PTHREAD_PROCESS_PRIVATE` (default) - * - `PTHREAD_PROCESS_SHARED` (unsupported) + * - `PTHREAD_PROCESS_SHARED` * @return 0 on success, or error on failure * @raises EINVAL if `pshared` is invalid */ errno_t pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared) { switch (pshared) { + case PTHREAD_PROCESS_SHARED: case PTHREAD_PROCESS_PRIVATE: *attr = pshared; return 0; diff --git a/test/libc/thread/pthread_setaffinity_np_test.c b/test/libc/thread/pthread_setaffinity_np_test.c new file mode 100644 index 000000000..b2448f6ed --- /dev/null +++ b/test/libc/thread/pthread_setaffinity_np_test.c @@ -0,0 +1,59 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-β”‚ +β”‚ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi β”‚ +β•žβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•‘ +β”‚ Copyright 2024 Justine Alexandra Roberts Tunney β”‚ +β”‚ β”‚ +β”‚ Permission to use, copy, modify, and/or distribute this software for β”‚ +β”‚ any purpose with or without fee is hereby granted, provided that the β”‚ +β”‚ above copyright notice and this permission notice appear in all copies. β”‚ +β”‚ β”‚ +β”‚ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL β”‚ +β”‚ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED β”‚ +β”‚ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE β”‚ +β”‚ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL β”‚ +β”‚ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR β”‚ +β”‚ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER β”‚ +β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ +β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ +β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/calls/struct/cpuset.h" +#include "libc/dce.h" +#include "libc/runtime/runtime.h" +#include "libc/testlib/testlib.h" +#include "libc/thread/thread.h" +#include "libc/thread/thread2.h" + +TEST(pthread_setaffinity_np, test) { + + // works on almost nothing + if (IsXnu()) + return; + if (IsNetbsd()) + return; + if (IsOpenbsd()) + return; + if (__get_cpu_count() < 2) + return; + + // save bitset + cpu_set_t old; + if (!IsWindows()) + ASSERT_EQ(0, pthread_getaffinity_np(pthread_self(), sizeof(old), &old)); + + // go to first cpu + cpu_set_t bitset; + CPU_ZERO(&bitset); + CPU_SET(0, &bitset); + ASSERT_EQ(0, pthread_setaffinity_np(pthread_self(), sizeof(bitset), &bitset)); + ASSERT_EQ(0, sched_getcpu()); + + // go to second cpu + CPU_ZERO(&bitset); + CPU_SET(1, &bitset); + ASSERT_EQ(0, pthread_setaffinity_np(pthread_self(), sizeof(bitset), &bitset)); + ASSERT_EQ(1, sched_getcpu()); + + // restore bitset + if (!IsWindows()) + ASSERT_EQ(0, pthread_setaffinity_np(pthread_self(), sizeof(old), &old)); +} From 6e809ee49b0f40d504bf875c3b19447bbe006450 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Mon, 22 Jul 2024 18:48:54 -0700 Subject: [PATCH 076/405] Add unit test for process shared conditions --- libc/thread/pthread_cond_destroy.c | 2 +- test/posix/pthread_process_shared_test.c | 93 ++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 test/posix/pthread_process_shared_test.c diff --git a/libc/thread/pthread_cond_destroy.c b/libc/thread/pthread_cond_destroy.c index 0b77c88f2..c5a180e4a 100644 --- a/libc/thread/pthread_cond_destroy.c +++ b/libc/thread/pthread_cond_destroy.c @@ -32,7 +32,7 @@ errno_t pthread_cond_destroy(pthread_cond_t *cond) { // check if there's active waiters #if PTHREAD_USE_NSYNC - if (cond->_pshared) { + if (!cond->_pshared) { if (((nsync_cv *)cond)->waiters) return EINVAL; } else { diff --git a/test/posix/pthread_process_shared_test.c b/test/posix/pthread_process_shared_test.c new file mode 100644 index 000000000..449f54198 --- /dev/null +++ b/test/posix/pthread_process_shared_test.c @@ -0,0 +1,93 @@ +#include +#include +#include +#include +#include +#include + +int main() { + int ws; + FILE *f; + pid_t pid; + pthread_condattr_t ca; + pthread_mutexattr_t ma; + struct Shared { + atomic_int state; + pthread_cond_t cond; + pthread_mutex_t lock; + } *s; + if (!(f = tmpfile())) + return 0; + if (ftruncate(fileno(f), 512)) + return 1; + if ((s = (struct Shared *)mmap(0, 512, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, -1, 0)) == + MAP_FAILED) + return 2; + if (pthread_condattr_init(&ca)) + return 3; + if (pthread_mutexattr_init(&ma)) + return 4; + if (pthread_condattr_setpshared(&ca, PTHREAD_PROCESS_SHARED)) + return 5; + if (pthread_mutexattr_setpshared(&ma, PTHREAD_PROCESS_SHARED)) + return 6; + if (pthread_cond_init(&s->cond, &ca)) + return 7; + if (pthread_mutex_init(&s->lock, &ma)) + return 8; + if (pthread_mutexattr_destroy(&ma)) + return 9; + if (pthread_condattr_destroy(&ca)) + return 10; + if ((pid = fork()) == -1) + return 11; + if (!pid) { + alarm(2); + if (pthread_mutex_lock(&s->lock)) + return 12; + s->state = 1; + if (pthread_cond_wait(&s->cond, &s->lock)) + return 13; + if (pthread_mutex_unlock(&s->lock)) + return 14; + for (;;) + if (s->state == 2) + break; + if (pthread_mutex_lock(&s->lock)) + return 15; + if (pthread_cond_signal(&s->cond)) + return 16; + if (pthread_mutex_unlock(&s->lock)) + return 17; + _exit(0); + } + alarm(2); + for (;;) + if (s->state == 1) + break; + if (pthread_mutex_lock(&s->lock)) + return 18; + if (pthread_cond_signal(&s->cond)) + return 19; + if (pthread_mutex_unlock(&s->lock)) + return 20; + if (pthread_mutex_lock(&s->lock)) + return 21; + s->state = 2; + if (pthread_cond_wait(&s->cond, &s->lock)) + return 22; + if (pthread_mutex_unlock(&s->lock)) + return 23; + if (wait(&ws) != pid) + return 24; + if (!WIFEXITED(ws)) + return 25; + if (WEXITSTATUS(ws)) + return 26; + if (pthread_mutex_destroy(&s->lock)) + return 27; + if (pthread_cond_destroy(&s->cond)) + return 28; + return 0; +} From 62ace3623a6272756be1bfccd9a1cca02d52b9bf Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Mon, 22 Jul 2024 21:02:40 -0700 Subject: [PATCH 077/405] Release Cosmopolitan v3.5.9 --- libc/integral/normalize.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libc/integral/normalize.inc b/libc/integral/normalize.inc index 58e4d9aeb..6dc68490f 100644 --- a/libc/integral/normalize.inc +++ b/libc/integral/normalize.inc @@ -4,7 +4,7 @@ #define __COSMOPOLITAN_MAJOR__ 3 #define __COSMOPOLITAN_MINOR__ 5 -#define __COSMOPOLITAN_PATCH__ 8 +#define __COSMOPOLITAN_PATCH__ 9 #define __COSMOPOLITAN__ \ (100000000 * __COSMOPOLITAN_MAJOR__ + 1000000 * __COSMOPOLITAN_MINOR__ + \ __COSMOPOLITAN_PATCH__) From 5660ec474178520fc01f45df3db11e581070bba7 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Tue, 23 Jul 2024 03:16:17 -0700 Subject: [PATCH 078/405] Release Cosmopolitan v3.6.0 This release is an atomic upgrade to GCC 14.1.0 with C23 and C++23 --- Makefile | 7 +- build/definitions.mk | 4 +- ctl/string.cc | 3 + examples/unbourne.c | 11603 -------------- libc/calls/calls.h | 4 +- libc/calls/pipe.c | 2 +- libc/calls/pipe2.c | 2 +- libc/intrin/maps.h | 4 +- libc/intrin/mmap.c | 24 +- libc/isystem/__threading_support | 1 - libc/isystem/amxcomplexintrin.h | 1 + libc/isystem/amxfp16intrin.h | 1 + libc/isystem/avxifmaintrin.h | 1 + libc/isystem/avxneconvertintrin.h | 1 + libc/isystem/avxvnniint16intrin.h | 1 + libc/isystem/avxvnniint8intrin.h | 1 + libc/isystem/bmmintrin.h | 1 + libc/isystem/cmpccxaddintrin.h | 1 + libc/isystem/prfchiintrin.h | 1 + libc/isystem/raointintrin.h | 1 + libc/isystem/sha512intrin.h | 1 + libc/isystem/sm3intrin.h | 1 + libc/isystem/sm4intrin.h | 1 + libc/isystem/usermsrintrin.h | 1 + libc/math.h | 5 +- libc/proc/fork-nt.c | 2 +- libc/stdio/fmt.c | 3 + libc/tinymath/lgamma_r.c | 2 +- libc/tinymath/lgammaf_r.c | 2 +- libc/tinymath/lgammal.c | 2 +- test/libc/calls/stackoverflow1_test.c | 14 +- test/libc/calls/stackoverflow2_test.c | 14 +- test/libc/calls/stackoverflow3_test.c | 14 +- test/libc/calls/stackoverflow4_test.c | 14 +- test/libc/calls/stackoverflow5_test.c | 14 +- test/libc/intrin/fmax_test.c | 2 +- test/libc/log/backtrace.c | 13 +- test/libc/thread/makecontext_test.c | 2 +- .../libc/thread/pthread_setaffinity_np_test.c | 59 - test/net/http/hascontrolcodes_test.c | 2 +- third_party/BUILD.mk | 1 - third_party/aarch64/acc_prof.internal.h | 164 - third_party/aarch64/arm_acle.internal.h | 70 +- third_party/aarch64/arm_fp16.internal.h | 4 +- third_party/aarch64/arm_neon.internal.h | 2971 +--- third_party/aarch64/openacc.internal.h | 111 - third_party/aarch64/upgrade.sh | 4 +- third_party/bash/BUILD.mk | 99 - third_party/bash/LICENSE | 674 - third_party/bash/README.cosmo | 16 - third_party/bash/alias.c | 594 - third_party/bash/alias.h | 73 - third_party/bash/ansi_stdlib.h | 54 - third_party/bash/array.c | 1303 -- third_party/bash/array.h | 182 - third_party/bash/arrayfunc.c | 1699 -- third_party/bash/arrayfunc.h | 140 - third_party/bash/assoc.c | 611 - third_party/bash/assoc.h | 66 - third_party/bash/bashansi.h | 38 - third_party/bash/bashgetopt.c | 194 - third_party/bash/bashgetopt.h | 43 - third_party/bash/bashhist.c | 1079 -- third_party/bash/bashhist.h | 89 - third_party/bash/bashintl.h | 54 - third_party/bash/bashjmp.h | 47 - third_party/bash/bashline.c | 4839 ------ third_party/bash/bashline.h | 69 - third_party/bash/bashtypes.h | 42 - third_party/bash/bracecomp.c | 221 - third_party/bash/braces.c | 843 - third_party/bash/break.c | 104 - third_party/bash/builtext.h | 188 - third_party/bash/builtins.c | 2093 --- third_party/bash/builtins.h | 68 - third_party/bash/builtins_alias.c | 192 - third_party/bash/builtins_bind.c | 349 - third_party/bash/builtins_break.c | 104 - third_party/bash/builtins_builtin.c | 54 - third_party/bash/builtins_caller.c | 120 - third_party/bash/builtins_cd.c | 613 - third_party/bash/builtins_colon.c | 33 - third_party/bash/builtins_command.c | 107 - third_party/bash/builtins_complete.c | 805 - third_party/bash/builtins_declare.c | 969 -- third_party/bash/builtins_echo.c | 133 - third_party/bash/builtins_enable.c | 541 - third_party/bash/builtins_eval.c | 28 - third_party/bash/builtins_exec.c | 238 - third_party/bash/builtins_exit.c | 136 - third_party/bash/builtins_fc.c | 739 - third_party/bash/builtins_fg_bg.c | 146 - third_party/bash/builtins_getopts.c | 284 - third_party/bash/builtins_hash.c | 264 - third_party/bash/builtins_help.c | 512 - third_party/bash/builtins_history.c | 411 - third_party/bash/builtins_jobs.c | 240 - third_party/bash/builtins_kill.c | 235 - third_party/bash/builtins_let.c | 68 - third_party/bash/builtins_mapfile.c | 304 - third_party/bash/builtins_printf.c | 1303 -- third_party/bash/builtins_pushd.c | 690 - third_party/bash/builtins_read.c | 1205 -- third_party/bash/builtins_return.c | 40 - third_party/bash/builtins_set.c | 890 -- third_party/bash/builtins_setattr.c | 616 - third_party/bash/builtins_shift.c | 61 - third_party/bash/builtins_shopt.c | 900 -- third_party/bash/builtins_source.c | 154 - third_party/bash/builtins_suspend.c | 94 - third_party/bash/builtins_test.c | 52 - third_party/bash/builtins_times.c | 90 - third_party/bash/builtins_trap.c | 263 - third_party/bash/builtins_type.c | 373 - third_party/bash/builtins_ulimit.c | 741 - third_party/bash/builtins_umask.c | 281 - third_party/bash/builtins_wait.c | 320 - third_party/bash/casemod.c | 271 - third_party/bash/chartypes.h | 109 - third_party/bash/clktck.c | 61 - third_party/bash/clock.c | 87 - third_party/bash/collsyms.h | 140 - third_party/bash/command.h | 409 - third_party/bash/common.c | 1131 -- third_party/bash/common.h | 282 - third_party/bash/config-bot.h | 207 - third_party/bash/config-top.h | 201 - third_party/bash/config.h | 1235 -- third_party/bash/conftypes.h | 58 - third_party/bash/copy_cmd.c | 459 - third_party/bash/dispose_cmd.c | 342 - third_party/bash/dispose_cmd.h | 40 - third_party/bash/eaccess.c | 248 - third_party/bash/error.c | 537 - third_party/bash/error.h | 82 - third_party/bash/eval.c | 401 - third_party/bash/evalfile.c | 384 - third_party/bash/evalstring.c | 818 - third_party/bash/execute_cmd.c | 6229 -------- third_party/bash/execute_cmd.h | 123 - third_party/bash/expr.c | 1693 -- third_party/bash/externs.h | 554 - third_party/bash/filecntl.h | 53 - third_party/bash/findcmd.c | 696 - third_party/bash/findcmd.h | 47 - third_party/bash/flags.c | 385 - third_party/bash/flags.h | 87 - third_party/bash/fmtullong.c | 31 - third_party/bash/fmtulong.c | 191 - third_party/bash/fmtumax.c | 27 - third_party/bash/fnxform.c | 199 - third_party/bash/fpurge.c | 232 - third_party/bash/general.c | 1450 -- third_party/bash/general.h | 372 - third_party/bash/getenv.c | 233 - third_party/bash/getopt.c | 355 - third_party/bash/getopt.h | 82 - third_party/bash/gettext.h | 70 - third_party/bash/gettimeofday.c | 35 - third_party/bash/glob.c | 1609 -- third_party/bash/glob.h | 47 - third_party/bash/glob_loop.inc | 84 - third_party/bash/gm_loop.inc | 208 - third_party/bash/gmisc.c | 108 - third_party/bash/hashcmd.c | 195 - third_party/bash/hashcmd.h | 43 - third_party/bash/hashlib.c | 545 - third_party/bash/hashlib.h | 92 - third_party/bash/input.c | 677 - third_party/bash/input.h | 135 - third_party/bash/input_avail.c | 165 - third_party/bash/itos.c | 84 - third_party/bash/jobs.c | 5119 ------ third_party/bash/jobs.h | 325 - third_party/bash/list.c | 136 - third_party/bash/locale.c | 645 - third_party/bash/mailcheck.c | 491 - third_party/bash/mailcheck.h | 34 - third_party/bash/mailstat.c | 159 - third_party/bash/make_cmd.c | 907 -- third_party/bash/make_cmd.h | 72 - third_party/bash/makepath.c | 128 - third_party/bash/maxpath.h | 75 - third_party/bash/mbscasecmp.c | 79 - third_party/bash/mbschr.c | 91 - third_party/bash/mbscmp.c | 77 - third_party/bash/memalloc.h | 62 - third_party/bash/ndir.h | 37 - third_party/bash/netconn.c | 82 - third_party/bash/netopen.c | 351 - third_party/bash/ocache.h | 133 - third_party/bash/oslib.c | 159 - third_party/bash/parser.h | 102 - third_party/bash/patchlevel.h | 30 - third_party/bash/pathcanon.c | 234 - third_party/bash/pathexp.c | 637 - third_party/bash/pathexp.h | 104 - third_party/bash/pathnames.h | 33 - third_party/bash/pathphys.c | 296 - third_party/bash/pcomplete.c | 1757 --- third_party/bash/pcomplete.h | 177 - third_party/bash/pcomplib.c | 228 - third_party/bash/pipesize.h | 8 - third_party/bash/posixdir.h | 71 - third_party/bash/posixjmp.h | 46 - third_party/bash/posixselect.h | 47 - third_party/bash/posixstat.h | 162 - third_party/bash/posixtime.h | 84 - third_party/bash/posixwait.h | 107 - third_party/bash/print_cmd.c | 1654 -- third_party/bash/psize.c | 79 - third_party/bash/quit.h | 75 - third_party/bash/random.c | 240 - third_party/bash/read.c | 1205 -- third_party/bash/redir.c | 1528 -- third_party/bash/redir.h | 43 - third_party/bash/rename.c | 76 - third_party/bash/setlinebuf.c | 66 - third_party/bash/shell.c | 2136 --- third_party/bash/shell.h | 240 - third_party/bash/shmatch.c | 132 - third_party/bash/shmbchar.c | 137 - third_party/bash/shmbchar.h | 112 - third_party/bash/shmbutil.h | 559 - third_party/bash/shquote.c | 432 - third_party/bash/shtty.c | 330 - third_party/bash/shtty.h | 112 - third_party/bash/sig.c | 817 - third_party/bash/sig.h | 136 - third_party/bash/siglist.h | 44 - third_party/bash/signames.c | 446 - third_party/bash/signames.h | 2 - third_party/bash/sm_loop.inc | 981 -- third_party/bash/smatch.c | 638 - third_party/bash/spell.c | 212 - third_party/bash/stat-time.h | 214 - third_party/bash/stdc.h | 89 - third_party/bash/stringlib.c | 295 - third_party/bash/stringlist.c | 297 - third_party/bash/stringvec.c | 272 - third_party/bash/strmatch.c | 79 - third_party/bash/strmatch.h | 65 - third_party/bash/strtrans.c | 400 - third_party/bash/strvis.c | 154 - third_party/bash/subst.c | 13006 ---------------- third_party/bash/subst.h | 362 - third_party/bash/syntax.c | 269 - third_party/bash/syntax.h | 106 - third_party/bash/systimes.h | 55 - third_party/bash/test.c | 921 -- third_party/bash/test.h | 40 - third_party/bash/tilde.c | 493 - third_party/bash/tilde.h | 68 - third_party/bash/timer.h | 64 - third_party/bash/timers.c | 262 - third_party/bash/timeval.c | 179 - third_party/bash/tmpfile.c | 311 - third_party/bash/trap.c | 1575 -- third_party/bash/trap.h | 129 - third_party/bash/typemax.h | 141 - third_party/bash/uconvert.c | 124 - third_party/bash/ufuncs.c | 140 - third_party/bash/unicode.c | 339 - third_party/bash/unionwait.h | 98 - third_party/bash/unwind_prot.c | 383 - third_party/bash/unwind_prot.h | 52 - third_party/bash/utf8.c | 196 - third_party/bash/variables.c | 6590 -------- third_party/bash/variables.h | 462 - third_party/bash/version.c | 94 - third_party/bash/version.h | 17 - third_party/bash/winsize.c | 104 - third_party/bash/xmalloc.c | 225 - third_party/bash/xmalloc.h | 66 - third_party/bash/xmbsrtowcs.c | 523 - third_party/bash/y.tab.c | 9133 ----------- third_party/bash/y.tab.h | 191 - third_party/bash/zcatfd.c | 74 - third_party/bash/zgetline.c | 126 - third_party/bash/zmapfd.c | 93 - third_party/bash/zread.c | 228 - third_party/bash/zwrite.c | 64 - third_party/bzip2/bzip2.c | 1 + third_party/intel/amxcomplexintrin.internal.h | 23 + third_party/intel/amxfp16intrin.internal.h | 16 + third_party/intel/amxtileintrin.internal.h | 10 +- third_party/intel/avx2intrin.internal.h | 200 + .../intel/avx5124fmapsintrin.internal.h | 2 +- .../intel/avx5124vnniwintrin.internal.h | 2 +- third_party/intel/avx512bf16intrin.internal.h | 33 +- .../intel/avx512bf16vlintrin.internal.h | 98 +- .../intel/avx512bitalgintrin.internal.h | 161 +- .../intel/avx512bitalgvlintrin.internal.h | 141 + third_party/intel/avx512bwintrin.internal.h | 337 +- third_party/intel/avx512cdintrin.internal.h | 2 +- third_party/intel/avx512dqintrin.internal.h | 644 +- third_party/intel/avx512erintrin.internal.h | 20 +- third_party/intel/avx512fintrin.internal.h | 5797 +++---- third_party/intel/avx512fp16intrin.internal.h | 4345 +++--- .../intel/avx512fp16vlintrin.internal.h | 194 +- third_party/intel/avx512ifmaintrin.internal.h | 4 +- .../intel/avx512ifmavlintrin.internal.h | 44 +- third_party/intel/avx512pfintrin.internal.h | 2 +- .../intel/avx512vbmi2intrin.internal.h | 17 +- .../intel/avx512vbmi2vlintrin.internal.h | 89 +- third_party/intel/avx512vbmiintrin.internal.h | 4 +- .../intel/avx512vbmivlintrin.internal.h | 20 +- third_party/intel/avx512vlbwintrin.internal.h | 804 +- third_party/intel/avx512vldqintrin.internal.h | 252 +- third_party/intel/avx512vlintrin.internal.h | 1869 +-- third_party/intel/avx512vnniintrin.internal.h | 4 +- .../intel/avx512vnnivlintrin.internal.h | 4 +- .../intel/avx512vp2intersectintrin.internal.h | 4 +- .../avx512vp2intersectvlintrin.internal.h | 4 +- .../intel/avx512vpopcntdqintrin.internal.h | 4 +- .../intel/avx512vpopcntdqvlintrin.internal.h | 12 +- third_party/intel/avxifmaintrin.internal.h | 49 + third_party/intel/avxintrin.internal.h | 9 + .../intel/avxneconvertintrin.internal.h | 101 + .../intel/avxvnniint16intrin.internal.h | 101 + .../intel/avxvnniint8intrin.internal.h | 101 + third_party/intel/bmmintrin.internal.h | 6 + third_party/intel/cmpccxaddintrin.internal.h | 55 + third_party/intel/cpuid.internal.h | 44 +- third_party/intel/emmintrin.internal.h | 6 + third_party/intel/gfniintrin.internal.h | 82 +- third_party/intel/immintrin.internal.h | 12 +- third_party/intel/mm_malloc.internal.h | 24 +- third_party/intel/prfchiintrin.internal.h | 31 + third_party/intel/raointintrin.internal.h | 67 + third_party/intel/sha512intrin.internal.h | 36 + third_party/intel/sm3intrin.internal.h | 42 + third_party/intel/sm4intrin.internal.h | 41 + third_party/intel/smmintrin.internal.h | 8 +- third_party/intel/upgrade.sh | 15 + third_party/intel/usermsrintrin.internal.h | 31 + third_party/intel/vaesintrin.internal.h | 8 +- third_party/intel/vpclmulqdqintrin.internal.h | 8 +- third_party/intel/wmmintrin.internal.h | 25 +- third_party/intel/x86gprintrin.internal.h | 4 + third_party/intel/xmmintrin.internal.h | 10 +- third_party/libcxx/BUILD.mk | 1461 +- third_party/libcxx/CREDITS.TXT | 150 - third_party/libcxx/LICENSE.TXT | 311 - third_party/libcxx/README.cosmo | 9 +- .../libcxx/__algorithm/adjacent_find.h | 11 +- third_party/libcxx/__algorithm/all_of.h | 2 +- third_party/libcxx/__algorithm/any_of.h | 2 +- .../libcxx/__algorithm/binary_search.h | 21 +- third_party/libcxx/__algorithm/clamp.h | 30 +- third_party/libcxx/__algorithm/comp.h | 52 +- .../libcxx/__algorithm/comp_ref_type.h | 71 +- third_party/libcxx/__algorithm/copy.h | 15 +- .../libcxx/__algorithm/copy_backward.h | 26 +- third_party/libcxx/__algorithm/copy_if.h | 23 +- .../libcxx/__algorithm/copy_move_common.h | 101 +- third_party/libcxx/__algorithm/copy_n.h | 65 +- third_party/libcxx/__algorithm/count.h | 69 +- third_party/libcxx/__algorithm/count_if.h | 6 +- third_party/libcxx/__algorithm/equal.h | 88 +- third_party/libcxx/__algorithm/equal_range.h | 28 +- third_party/libcxx/__algorithm/fill.h | 26 +- third_party/libcxx/__algorithm/fill_n.h | 78 +- third_party/libcxx/__algorithm/find.h | 118 +- third_party/libcxx/__algorithm/find_end.h | 92 +- .../libcxx/__algorithm/find_first_of.h | 25 +- third_party/libcxx/__algorithm/find_if.h | 2 +- third_party/libcxx/__algorithm/find_if_not.h | 2 +- .../libcxx/__algorithm/find_segment_if.h | 62 + third_party/libcxx/__algorithm/fold.h | 128 + third_party/libcxx/__algorithm/for_each.h | 20 +- third_party/libcxx/__algorithm/for_each_n.h | 7 +- third_party/libcxx/__algorithm/generate.h | 10 +- third_party/libcxx/__algorithm/generate_n.h | 16 +- .../libcxx/__algorithm/half_positive.h | 26 +- .../libcxx/__algorithm/in_found_result.h | 7 +- .../libcxx/__algorithm/in_fun_result.h | 7 +- .../libcxx/__algorithm/in_in_out_result.h | 19 +- third_party/libcxx/__algorithm/in_in_result.h | 11 +- .../libcxx/__algorithm/in_out_out_result.h | 19 +- .../libcxx/__algorithm/in_out_result.h | 13 +- third_party/libcxx/__algorithm/includes.h | 46 +- .../libcxx/__algorithm/inplace_merge.h | 305 +- third_party/libcxx/__algorithm/is_heap.h | 20 +- .../libcxx/__algorithm/is_heap_until.h | 60 +- .../libcxx/__algorithm/is_partitioned.h | 23 +- .../libcxx/__algorithm/is_permutation.h | 186 +- third_party/libcxx/__algorithm/is_sorted.h | 20 +- .../libcxx/__algorithm/is_sorted_until.h | 37 +- third_party/libcxx/__algorithm/iter_swap.h | 3 +- .../libcxx/__algorithm/iterator_operations.h | 134 +- .../__algorithm/lexicographical_compare.h | 51 +- .../lexicographical_compare_three_way.h | 6 +- third_party/libcxx/__algorithm/lower_bound.h | 70 +- third_party/libcxx/__algorithm/make_heap.h | 24 +- .../libcxx/__algorithm/make_projected.h | 49 +- third_party/libcxx/__algorithm/max.h | 39 +- third_party/libcxx/__algorithm/max_element.h | 38 +- third_party/libcxx/__algorithm/merge.h | 67 +- third_party/libcxx/__algorithm/min.h | 39 +- third_party/libcxx/__algorithm/min_element.h | 33 +- .../libcxx/__algorithm/min_max_result.h | 2 +- third_party/libcxx/__algorithm/minmax.h | 48 +- .../libcxx/__algorithm/minmax_element.h | 32 +- third_party/libcxx/__algorithm/mismatch.h | 198 +- third_party/libcxx/__algorithm/move.h | 18 +- .../libcxx/__algorithm/move_backward.h | 18 +- .../libcxx/__algorithm/next_permutation.h | 67 +- third_party/libcxx/__algorithm/none_of.h | 2 +- third_party/libcxx/__algorithm/nth_element.h | 401 +- third_party/libcxx/__algorithm/partial_sort.h | 50 +- .../libcxx/__algorithm/partial_sort_copy.h | 100 +- third_party/libcxx/__algorithm/partition.h | 89 +- .../libcxx/__algorithm/partition_copy.h | 36 +- .../libcxx/__algorithm/partition_point.h | 34 +- third_party/libcxx/__algorithm/pop_heap.h | 33 +- .../libcxx/__algorithm/prev_permutation.h | 70 +- third_party/libcxx/__algorithm/pstl.h | 663 + .../libcxx/__algorithm/pstl_any_all_none_of.h | 95 - third_party/libcxx/__algorithm/pstl_backend.h | 125 - .../__algorithm/pstl_backends/cpu_backend.h | 47 - .../pstl_backends/cpu_backends/any_of.h | 90 - .../pstl_backends/cpu_backends/fill.h | 60 - .../pstl_backends/cpu_backends/find_if.h | 125 - .../pstl_backends/cpu_backends/for_each.h | 60 - .../pstl_backends/cpu_backends/merge.h | 79 - .../pstl_backends/cpu_backends/serial.h | 58 - .../pstl_backends/cpu_backends/thread.h | 59 - .../pstl_backends/cpu_backends/transform.h | 132 - third_party/libcxx/__algorithm/pstl_copy.h | 57 - third_party/libcxx/__algorithm/pstl_fill.h | 79 - third_party/libcxx/__algorithm/pstl_find.h | 89 - .../libcxx/__algorithm/pstl_for_each.h | 71 - .../__algorithm/pstl_frontend_dispatch.h | 45 - third_party/libcxx/__algorithm/pstl_merge.h | 56 - .../libcxx/__algorithm/pstl_transform.h | 66 - third_party/libcxx/__algorithm/push_heap.h | 36 +- .../libcxx/__algorithm/ranges_adjacent_find.h | 29 +- .../libcxx/__algorithm/ranges_all_of.h | 26 +- .../libcxx/__algorithm/ranges_any_of.h | 26 +- .../libcxx/__algorithm/ranges_binary_search.h | 30 +- third_party/libcxx/__algorithm/ranges_clamp.h | 29 +- .../libcxx/__algorithm/ranges_contains.h | 66 + .../__algorithm/ranges_contains_subrange.h | 97 + third_party/libcxx/__algorithm/ranges_copy.h | 16 +- .../libcxx/__algorithm/ranges_copy_backward.h | 18 +- .../libcxx/__algorithm/ranges_copy_if.h | 28 +- .../libcxx/__algorithm/ranges_copy_n.h | 20 +- third_party/libcxx/__algorithm/ranges_count.h | 24 +- .../libcxx/__algorithm/ranges_count_if.h | 27 +- .../libcxx/__algorithm/ranges_ends_with.h | 201 + third_party/libcxx/__algorithm/ranges_equal.h | 65 +- .../libcxx/__algorithm/ranges_equal_range.h | 40 +- third_party/libcxx/__algorithm/ranges_fill.h | 15 +- .../libcxx/__algorithm/ranges_fill_n.h | 11 +- third_party/libcxx/__algorithm/ranges_find.h | 19 +- .../libcxx/__algorithm/ranges_find_end.h | 39 +- .../libcxx/__algorithm/ranges_find_first_of.h | 75 +- .../libcxx/__algorithm/ranges_find_if.h | 26 +- .../libcxx/__algorithm/ranges_find_if_not.h | 26 +- .../libcxx/__algorithm/ranges_find_last.h | 175 + .../libcxx/__algorithm/ranges_for_each.h | 25 +- .../libcxx/__algorithm/ranges_for_each_n.h | 20 +- .../libcxx/__algorithm/ranges_generate.h | 22 +- .../libcxx/__algorithm/ranges_generate_n.h | 15 +- .../libcxx/__algorithm/ranges_includes.h | 39 +- .../libcxx/__algorithm/ranges_inplace_merge.h | 61 +- .../libcxx/__algorithm/ranges_is_heap.h | 29 +- .../libcxx/__algorithm/ranges_is_heap_until.h | 30 +- .../__algorithm/ranges_is_partitioned.h | 27 +- .../__algorithm/ranges_is_permutation.h | 74 +- .../libcxx/__algorithm/ranges_is_sorted.h | 22 +- .../__algorithm/ranges_is_sorted_until.h | 26 +- .../__algorithm/ranges_iterator_concept.h | 5 + .../ranges_lexicographical_compare.h | 78 +- .../libcxx/__algorithm/ranges_lower_bound.h | 31 +- .../libcxx/__algorithm/ranges_make_heap.h | 19 +- third_party/libcxx/__algorithm/ranges_max.h | 46 +- .../libcxx/__algorithm/ranges_max_element.h | 26 +- third_party/libcxx/__algorithm/ranges_merge.h | 96 +- third_party/libcxx/__algorithm/ranges_min.h | 40 +- .../libcxx/__algorithm/ranges_min_element.h | 25 +- .../libcxx/__algorithm/ranges_minmax.h | 56 +- .../__algorithm/ranges_minmax_element.h | 21 +- .../libcxx/__algorithm/ranges_mismatch.h | 65 +- third_party/libcxx/__algorithm/ranges_move.h | 21 +- .../libcxx/__algorithm/ranges_move_backward.h | 21 +- .../__algorithm/ranges_next_permutation.h | 5 + .../libcxx/__algorithm/ranges_none_of.h | 27 +- .../libcxx/__algorithm/ranges_nth_element.h | 20 +- .../libcxx/__algorithm/ranges_partial_sort.h | 20 +- .../__algorithm/ranges_partial_sort_copy.h | 78 +- .../libcxx/__algorithm/ranges_partition.h | 32 +- .../__algorithm/ranges_partition_copy.h | 54 +- .../__algorithm/ranges_partition_point.h | 29 +- .../libcxx/__algorithm/ranges_pop_heap.h | 21 +- .../__algorithm/ranges_prev_permutation.h | 13 +- .../libcxx/__algorithm/ranges_push_heap.h | 19 +- .../libcxx/__algorithm/ranges_remove.h | 24 +- .../libcxx/__algorithm/ranges_remove_copy.h | 53 +- .../__algorithm/ranges_remove_copy_if.h | 51 +- .../libcxx/__algorithm/ranges_remove_if.h | 24 +- .../libcxx/__algorithm/ranges_replace.h | 38 +- .../libcxx/__algorithm/ranges_replace_copy.h | 80 +- .../__algorithm/ranges_replace_copy_if.h | 59 +- .../libcxx/__algorithm/ranges_replace_if.h | 20 +- .../libcxx/__algorithm/ranges_reverse.h | 10 +- .../libcxx/__algorithm/ranges_reverse_copy.h | 17 +- .../libcxx/__algorithm/ranges_rotate.h | 24 +- .../libcxx/__algorithm/ranges_rotate_copy.h | 20 +- .../libcxx/__algorithm/ranges_sample.h | 32 +- .../libcxx/__algorithm/ranges_search.h | 35 +- .../libcxx/__algorithm/ranges_search_n.h | 39 +- .../__algorithm/ranges_set_difference.h | 51 +- .../__algorithm/ranges_set_intersection.h | 65 +- .../ranges_set_symmetric_difference.h | 59 +- .../libcxx/__algorithm/ranges_set_union.h | 62 +- .../libcxx/__algorithm/ranges_shuffle.h | 21 +- third_party/libcxx/__algorithm/ranges_sort.h | 19 +- .../libcxx/__algorithm/ranges_sort_heap.h | 19 +- .../__algorithm/ranges_stable_partition.h | 34 +- .../libcxx/__algorithm/ranges_stable_sort.h | 17 +- .../libcxx/__algorithm/ranges_starts_with.h | 13 +- .../libcxx/__algorithm/ranges_swap_ranges.h | 16 +- .../libcxx/__algorithm/ranges_transform.h | 125 +- .../libcxx/__algorithm/ranges_unique.h | 53 +- .../libcxx/__algorithm/ranges_unique_copy.h | 12 +- .../libcxx/__algorithm/ranges_upper_bound.h | 35 +- third_party/libcxx/__algorithm/remove.h | 33 +- third_party/libcxx/__algorithm/remove_copy.h | 20 +- .../libcxx/__algorithm/remove_copy_if.h | 20 +- third_party/libcxx/__algorithm/remove_if.h | 33 +- third_party/libcxx/__algorithm/replace.h | 12 +- third_party/libcxx/__algorithm/replace_copy.h | 23 +- .../libcxx/__algorithm/replace_copy_if.h | 23 +- third_party/libcxx/__algorithm/replace_if.h | 12 +- third_party/libcxx/__algorithm/reverse.h | 45 +- third_party/libcxx/__algorithm/reverse_copy.h | 12 +- third_party/libcxx/__algorithm/rotate.h | 265 +- third_party/libcxx/__algorithm/rotate_copy.h | 8 +- third_party/libcxx/__algorithm/sample.h | 87 +- third_party/libcxx/__algorithm/search.h | 124 +- third_party/libcxx/__algorithm/search_n.h | 85 +- .../libcxx/__algorithm/set_difference.h | 16 +- .../libcxx/__algorithm/set_intersection.h | 130 +- .../__algorithm/set_symmetric_difference.h | 8 +- third_party/libcxx/__algorithm/set_union.h | 8 +- third_party/libcxx/__algorithm/shift_left.h | 48 +- third_party/libcxx/__algorithm/shift_right.h | 130 +- third_party/libcxx/__algorithm/shuffle.h | 134 +- third_party/libcxx/__algorithm/sift_down.h | 140 +- third_party/libcxx/__algorithm/simd_utils.h | 164 + third_party/libcxx/__algorithm/sort.h | 332 +- third_party/libcxx/__algorithm/sort_heap.h | 29 +- .../libcxx/__algorithm/stable_partition.h | 493 +- third_party/libcxx/__algorithm/stable_sort.h | 343 +- third_party/libcxx/__algorithm/swap_ranges.h | 16 +- .../__algorithm/three_way_comp_ref_type.h | 29 +- third_party/libcxx/__algorithm/transform.h | 29 +- .../uniform_random_bit_generator_adaptor.h | 14 +- third_party/libcxx/__algorithm/unique.h | 11 +- third_party/libcxx/__algorithm/unique_copy.h | 5 + third_party/libcxx/__algorithm/unwrap_iter.h | 23 +- third_party/libcxx/__algorithm/unwrap_range.h | 14 +- third_party/libcxx/__algorithm/upper_bound.h | 20 +- third_party/libcxx/__assert | 117 +- third_party/libcxx/__assertion_handler | 31 + third_party/libcxx/__atomic/aliases.h | 52 +- third_party/libcxx/__atomic/atomic.h | 778 +- third_party/libcxx/__atomic/atomic_base.h | 343 +- third_party/libcxx/__atomic/atomic_flag.h | 281 +- third_party/libcxx/__atomic/atomic_init.h | 6 +- .../libcxx/__atomic/atomic_lock_free.h | 52 +- third_party/libcxx/__atomic/atomic_ref.h | 360 + third_party/libcxx/__atomic/atomic_sync.h | 223 +- .../libcxx/__atomic/check_memory_order.h | 26 +- third_party/libcxx/__atomic/contention_t.h | 4 +- third_party/libcxx/__atomic/cxx_atomic_impl.h | 763 +- third_party/libcxx/__atomic/fence.h | 14 +- .../libcxx/__atomic/is_always_lock_free.h | 2 +- third_party/libcxx/__atomic/kill_dependency.h | 6 +- third_party/libcxx/__atomic/memory_order.h | 13 +- third_party/libcxx/__atomic/to_gcc_order.h | 54 + third_party/libcxx/__availability | 348 - third_party/libcxx/__bit/bit_cast.h | 14 +- third_party/libcxx/__bit/bit_ceil.h | 22 +- third_party/libcxx/__bit/bit_floor.h | 2 +- third_party/libcxx/__bit/bit_width.h | 2 +- third_party/libcxx/__bit/blsr.h | 6 +- third_party/libcxx/__bit/byteswap.h | 13 +- third_party/libcxx/__bit/countl.h | 95 +- third_party/libcxx/__bit/countr.h | 40 +- third_party/libcxx/__bit/endian.h | 2 +- third_party/libcxx/__bit/has_single_bit.h | 2 +- .../libcxx/{setjmp.h => __bit/invert_if.h} | 40 +- third_party/libcxx/__bit/popcount.h | 24 +- third_party/libcxx/__bit/rotate.h | 36 +- third_party/libcxx/__bit_reference | 1985 +-- third_party/libcxx/__charconv/chars_format.h | 11 +- .../libcxx/__charconv/from_chars_integral.h | 15 +- .../libcxx/__charconv/from_chars_result.h | 5 +- .../libcxx/__charconv/to_chars_base_10.h | 7 +- .../__charconv/to_chars_floating_point.h | 19 +- .../libcxx/__charconv/to_chars_integral.h | 17 +- .../libcxx/__charconv/to_chars_result.h | 5 +- third_party/libcxx/__charconv/traits.h | 5 +- third_party/libcxx/__chrono/calendar.h | 12 +- .../libcxx/__chrono/convert_to_timespec.h | 15 +- third_party/libcxx/__chrono/convert_to_tm.h | 42 +- third_party/libcxx/__chrono/day.h | 91 +- third_party/libcxx/__chrono/duration.h | 721 +- third_party/libcxx/__chrono/exception.h | 135 + third_party/libcxx/__chrono/file_clock.h | 29 +- third_party/libcxx/__chrono/formatter.h | 299 +- third_party/libcxx/__chrono/hh_mm_ss.h | 115 +- .../libcxx/__chrono/high_resolution_clock.h | 3 +- third_party/libcxx/__chrono/leap_second.h | 126 + third_party/libcxx/__chrono/literals.h | 22 +- third_party/libcxx/__chrono/local_info.h | 50 + third_party/libcxx/__chrono/month.h | 102 +- third_party/libcxx/__chrono/month_weekday.h | 113 +- third_party/libcxx/__chrono/monthday.h | 142 +- third_party/libcxx/__chrono/ostream.h | 62 +- .../libcxx/__chrono/parser_std_format_spec.h | 12 +- third_party/libcxx/__chrono/steady_clock.h | 18 +- third_party/libcxx/__chrono/sys_info.h | 51 + third_party/libcxx/__chrono/system_clock.h | 22 +- third_party/libcxx/__chrono/time_point.h | 217 +- third_party/libcxx/__chrono/time_zone.h | 182 + third_party/libcxx/__chrono/time_zone_link.h | 79 + third_party/libcxx/__chrono/tzdb.h | 94 + third_party/libcxx/__chrono/tzdb_list.h | 108 + third_party/libcxx/__chrono/weekday.h | 229 +- third_party/libcxx/__chrono/year.h | 102 +- third_party/libcxx/__chrono/year_month.h | 128 +- third_party/libcxx/__chrono/year_month_day.h | 434 +- .../libcxx/__chrono/year_month_weekday.h | 368 +- third_party/libcxx/__chrono/zoned_time.h | 227 + .../__compare/common_comparison_category.h | 27 +- .../compare_partial_order_fallback.h | 68 +- .../__compare/compare_strong_order_fallback.h | 62 +- .../libcxx/__compare/compare_three_way.h | 17 +- .../__compare/compare_three_way_result.h | 21 +- .../__compare/compare_weak_order_fallback.h | 62 +- third_party/libcxx/__compare/ordering.h | 164 +- third_party/libcxx/__compare/partial_order.h | 65 +- third_party/libcxx/__compare/strong_order.h | 180 +- .../libcxx/__compare/synth_three_way.h | 9 +- .../libcxx/__compare/three_way_comparable.h | 36 +- third_party/libcxx/__compare/weak_order.h | 121 +- third_party/libcxx/__concepts/arithmetic.h | 12 +- third_party/libcxx/__concepts/assignable.h | 12 +- .../libcxx/__concepts/boolean_testable.h | 6 +- third_party/libcxx/__concepts/class_or_enum.h | 7 +- .../libcxx/__concepts/common_reference_with.h | 7 +- third_party/libcxx/__concepts/common_with.h | 30 +- third_party/libcxx/__concepts/constructible.h | 29 +- .../libcxx/__concepts/convertible_to.h | 8 +- third_party/libcxx/__concepts/copyable.h | 14 +- third_party/libcxx/__concepts/derived_from.h | 6 +- third_party/libcxx/__concepts/destructible.h | 2 +- .../libcxx/__concepts/different_from.h | 2 +- .../libcxx/__concepts/equality_comparable.h | 34 +- third_party/libcxx/__concepts/invocable.h | 6 +- third_party/libcxx/__concepts/movable.h | 8 +- third_party/libcxx/__concepts/predicate.h | 5 +- third_party/libcxx/__concepts/regular.h | 2 +- third_party/libcxx/__concepts/relation.h | 9 +- third_party/libcxx/__concepts/same_as.h | 4 +- third_party/libcxx/__concepts/semiregular.h | 2 +- third_party/libcxx/__concepts/swappable.h | 118 +- .../libcxx/__concepts/totally_ordered.h | 43 +- .../__condition_variable/condition_variable.h | 16 +- third_party/libcxx/__config | 1008 +- third_party/libcxx/__config_site | 9 +- third_party/libcxx/__configuration/abi.h | 159 + .../libcxx/__configuration/availability.h | 400 + third_party/libcxx/__configuration/compiler.h | 51 + third_party/libcxx/__configuration/language.h | 46 + third_party/libcxx/__configuration/platform.h | 54 + .../libcxx/__coroutine/coroutine_handle.h | 215 +- .../libcxx/__coroutine/coroutine_traits.h | 9 +- .../__coroutine/noop_coroutine_handle.h | 95 +- .../libcxx/__coroutine/trivial_awaitables.h | 18 +- third_party/libcxx/__debug | 266 - .../libcxx/__debug_utils/randomize_range.h | 3 +- third_party/libcxx/__debug_utils/sanitizers.h | 104 + .../strict_weak_ordering_check.h | 77 + third_party/libcxx/__exception/exception.h | 9 +- .../libcxx/__exception/exception_ptr.h | 86 +- .../libcxx/__exception/nested_exception.h | 22 +- third_party/libcxx/__exception/operations.h | 21 +- third_party/libcxx/__exception/terminate.h | 2 +- .../libcxx/__expected/bad_expected_access.h | 32 +- third_party/libcxx/__expected/expected.h | 1447 +- third_party/libcxx/__expected/unexpected.h | 5 + .../libcxx/__filesystem/copy_options.h | 61 +- .../libcxx/__filesystem/directory_entry.h | 287 +- .../libcxx/__filesystem/directory_iterator.h | 109 +- .../libcxx/__filesystem/directory_options.h | 51 +- third_party/libcxx/__filesystem/file_status.h | 47 +- .../libcxx/__filesystem/file_time_type.h | 5 +- third_party/libcxx/__filesystem/file_type.h | 21 +- .../libcxx/__filesystem/filesystem_error.h | 64 +- third_party/libcxx/__filesystem/operations.h | 287 +- third_party/libcxx/__filesystem/path.h | 766 +- .../libcxx/__filesystem/path_iterator.h | 63 +- .../libcxx/__filesystem/perm_options.h | 46 +- third_party/libcxx/__filesystem/perms.h | 67 +- .../recursive_directory_iterator.h | 148 +- third_party/libcxx/__filesystem/space_info.h | 11 +- third_party/libcxx/__filesystem/u8path.h | 69 +- third_party/libcxx/__format/buffer.h | 124 +- third_party/libcxx/__format/concepts.h | 31 +- .../libcxx/__format/container_adaptor.h | 10 +- .../libcxx/__format/escaped_output_table.h | 1655 +- .../extended_grapheme_cluster_table.h | 4 +- third_party/libcxx/__format/format_arg.h | 212 +- .../libcxx/__format/format_arg_store.h | 62 +- third_party/libcxx/__format/format_args.h | 10 +- third_party/libcxx/__format/format_context.h | 138 +- third_party/libcxx/__format/format_error.h | 24 +- .../libcxx/__format/format_functions.h | 385 +- .../libcxx/__format/format_parse_context.h | 30 +- third_party/libcxx/__format/format_string.h | 25 +- third_party/libcxx/__format/formatter.h | 7 +- third_party/libcxx/__format/formatter_bool.h | 11 +- third_party/libcxx/__format/formatter_char.h | 20 +- .../__format/formatter_floating_point.h | 226 +- .../libcxx/__format/formatter_integer.h | 44 +- .../libcxx/__format/formatter_integral.h | 129 +- .../libcxx/__format/formatter_output.h | 396 +- .../libcxx/__format/formatter_pointer.h | 20 +- .../libcxx/__format/formatter_string.h | 21 +- third_party/libcxx/__format/formatter_tuple.h | 23 +- .../__format/indic_conjunct_break_table.h | 350 + .../libcxx/__format/parser_std_format_spec.h | 425 +- .../libcxx/__format/range_default_formatter.h | 24 +- third_party/libcxx/__format/range_formatter.h | 45 +- third_party/libcxx/__format/unicode.h | 357 +- .../libcxx/__format/width_estimation_table.h | 9 +- third_party/libcxx/__format/write_escaped.h | 242 + .../libcxx/__functional/binary_function.h | 16 +- .../libcxx/__functional/binary_negate.h | 27 +- third_party/libcxx/__functional/bind.h | 418 +- third_party/libcxx/__functional/bind_back.h | 59 +- third_party/libcxx/__functional/bind_front.h | 32 +- third_party/libcxx/__functional/binder1st.h | 39 +- third_party/libcxx/__functional/binder2nd.h | 39 +- .../__functional/boyer_moore_searcher.h | 132 +- third_party/libcxx/__functional/compose.h | 25 +- .../libcxx/__functional/default_searcher.h | 29 +- third_party/libcxx/__functional/function.h | 1640 +- third_party/libcxx/__functional/hash.h | 695 +- third_party/libcxx/__functional/identity.h | 20 +- third_party/libcxx/__functional/invoke.h | 30 +- .../libcxx/__functional/is_transparent.h | 6 +- third_party/libcxx/__functional/mem_fn.h | 36 +- third_party/libcxx/__functional/mem_fun_ref.h | 213 +- third_party/libcxx/__functional/not_fn.h | 26 +- third_party/libcxx/__functional/operations.h | 571 +- .../libcxx/__functional/perfect_forward.h | 57 +- .../__functional/pointer_to_binary_function.h | 22 +- .../__functional/pointer_to_unary_function.h | 22 +- .../libcxx/__functional/ranges_operations.h | 60 +- .../libcxx/__functional/reference_wrapper.h | 143 +- .../libcxx/__functional/unary_function.h | 12 +- .../libcxx/__functional/unary_negate.h | 27 +- .../libcxx/__functional/weak_result_type.h | 225 +- third_party/libcxx/__fwd/array.h | 20 + .../bit_reference.h} | 11 +- third_party/libcxx/__fwd/complex.h | 42 + third_party/libcxx/__fwd/deque.h | 26 + .../{__format/format_fwd.h => __fwd/format.h} | 7 +- third_party/libcxx/__fwd/functional.h | 28 + third_party/libcxx/__fwd/get.h | 115 - third_party/libcxx/__fwd/ios.h | 2 + third_party/libcxx/__fwd/mdspan.h | 57 + third_party/libcxx/__fwd/{hash.h => memory.h} | 10 +- third_party/libcxx/__fwd/memory_resource.h | 2 +- third_party/libcxx/__fwd/pair.h | 20 + third_party/libcxx/__fwd/queue.h | 31 + third_party/libcxx/__fwd/span.h | 3 +- third_party/libcxx/__fwd/sstream.h | 1 + third_party/libcxx/__fwd/stack.h | 26 + third_party/libcxx/__fwd/string.h | 17 +- third_party/libcxx/__fwd/string_view.h | 10 +- third_party/libcxx/__fwd/subrange.h | 17 +- third_party/libcxx/__fwd/tuple.h | 23 + third_party/libcxx/__fwd/vector.h | 26 + third_party/libcxx/__hash_table | 3472 ++--- third_party/libcxx/__ios/fpos.h | 11 +- third_party/libcxx/__iterator/access.h | 90 +- third_party/libcxx/__iterator/advance.h | 83 +- .../libcxx/__iterator/aliasing_iterator.h | 127 + .../libcxx/__iterator/back_insert_iterator.h | 58 +- third_party/libcxx/__iterator/bounded_iter.h | 88 +- .../libcxx/__iterator/common_iterator.h | 237 +- third_party/libcxx/__iterator/concepts.h | 313 +- .../libcxx/__iterator/counted_iterator.h | 221 +- .../__iterator/cpp17_iterator_concepts.h | 190 + third_party/libcxx/__iterator/data.h | 30 +- .../libcxx/__iterator/default_sentinel.h | 2 +- third_party/libcxx/__iterator/distance.h | 49 +- third_party/libcxx/__iterator/empty.h | 19 +- .../libcxx/__iterator/erase_if_container.h | 9 +- .../libcxx/__iterator/front_insert_iterator.h | 66 +- .../libcxx/__iterator/incrementable_traits.h | 33 +- .../libcxx/__iterator/indirectly_comparable.h | 3 +- .../libcxx/__iterator/insert_iterator.h | 72 +- .../libcxx/__iterator/istream_iterator.h | 98 +- .../libcxx/__iterator/istreambuf_iterator.h | 126 +- third_party/libcxx/__iterator/iter_move.h | 71 +- third_party/libcxx/__iterator/iter_swap.h | 105 +- third_party/libcxx/__iterator/iterator.h | 16 +- .../libcxx/__iterator/iterator_traits.h | 407 +- .../libcxx/__iterator/iterator_with_data.h | 5 + third_party/libcxx/__iterator/mergeable.h | 15 +- third_party/libcxx/__iterator/move_iterator.h | 401 +- third_party/libcxx/__iterator/move_sentinel.h | 26 +- third_party/libcxx/__iterator/next.h | 23 +- .../libcxx/__iterator/ostream_iterator.h | 60 +- .../libcxx/__iterator/ostreambuf_iterator.h | 63 +- third_party/libcxx/__iterator/permutable.h | 3 +- third_party/libcxx/__iterator/prev.h | 23 +- third_party/libcxx/__iterator/projected.h | 28 +- .../__iterator/ranges_iterator_traits.h | 40 + .../libcxx/__iterator/readable_traits.h | 57 +- .../libcxx/__iterator/reverse_access.h | 60 +- .../libcxx/__iterator/reverse_iterator.h | 529 +- third_party/libcxx/__iterator/size.h | 32 +- third_party/libcxx/__iterator/sortable.h | 4 +- .../libcxx/__iterator/unreachable_sentinel.h | 5 +- third_party/libcxx/__iterator/wrap_iter.h | 307 +- third_party/libcxx/__locale | 2278 ++- .../libcxx/__locale_dir/locale_base_api.h | 100 + .../locale_base_api/bsd_locale_defaults.h | 30 +- .../locale_base_api/bsd_locale_fallbacks.h | 144 +- .../locale_base_api/locale_guard.h | 77 +- third_party/libcxx/__math/abs.h | 46 + third_party/libcxx/__math/copysign.h | 45 + third_party/libcxx/__math/error_functions.h | 60 + .../libcxx/__math/exponential_functions.h | 171 + third_party/libcxx/__math/fdim.h | 48 + third_party/libcxx/__math/fma.h | 55 + third_party/libcxx/__math/gamma.h | 62 + .../libcxx/__math/hyperbolic_functions.h | 76 + third_party/libcxx/__math/hypot.h | 48 + .../__math/inverse_hyperbolic_functions.h | 76 + .../__math/inverse_trigonometric_functions.h | 99 + third_party/libcxx/__math/logarithms.h | 124 + third_party/libcxx/__math/min_max.h | 74 + third_party/libcxx/__math/modulo.h | 63 + third_party/libcxx/__math/remainder.h | 73 + third_party/libcxx/__math/roots.h | 62 + .../libcxx/__math/rounding_functions.h | 245 + third_party/libcxx/__math/special_functions.h | 84 + third_party/libcxx/__math/traits.h | 188 + .../libcxx/__math/trigonometric_functions.h | 76 + third_party/libcxx/__mbstate_t.h | 17 +- .../libcxx/__mdspan/default_accessor.h | 66 + third_party/libcxx/__mdspan/extents.h | 142 +- third_party/libcxx/__mdspan/layout_left.h | 204 + third_party/libcxx/__mdspan/layout_right.h | 201 + third_party/libcxx/__mdspan/layout_stride.h | 366 + third_party/libcxx/__mdspan/mdspan.h | 319 + third_party/libcxx/__memory/addressof.h | 35 +- third_party/libcxx/__memory/align.h | 2 +- third_party/libcxx/__memory/aligned_alloc.h | 42 +- .../libcxx/__memory/allocate_at_least.h | 26 +- .../libcxx/__memory/allocation_guard.h | 81 +- third_party/libcxx/__memory/allocator.h | 327 +- third_party/libcxx/__memory/allocator_arg_t.h | 45 +- .../libcxx/__memory/allocator_destructor.h | 24 +- .../libcxx/__memory/allocator_traits.h | 427 +- third_party/libcxx/__memory/assume_aligned.h | 28 +- third_party/libcxx/__memory/auto_ptr.h | 94 +- .../libcxx/__memory/builtin_new_allocator.h | 23 +- third_party/libcxx/__memory/compressed_pair.h | 96 +- third_party/libcxx/__memory/concepts.h | 16 +- third_party/libcxx/__memory/construct_at.h | 86 +- third_party/libcxx/__memory/destruct_n.h | 55 +- third_party/libcxx/__memory/inout_ptr.h | 109 + third_party/libcxx/__memory/out_ptr.h | 101 + third_party/libcxx/__memory/pointer_traits.h | 261 +- .../libcxx/__memory/ranges_construct_at.h | 43 +- .../ranges_uninitialized_algorithms.h | 130 +- .../libcxx/__memory/raw_storage_iterator.h | 75 +- third_party/libcxx/__memory/shared_ptr.h | 2589 ++- third_party/libcxx/__memory/swap_allocator.h | 8 +- third_party/libcxx/__memory/temp_value.h | 32 +- .../libcxx/__memory/temporary_buffer.h | 82 +- .../__memory/uninitialized_algorithms.h | 644 +- third_party/libcxx/__memory/unique_ptr.h | 535 +- third_party/libcxx/__memory/uses_allocator.h | 27 +- .../__memory/uses_allocator_construction.h | 76 +- third_party/libcxx/__memory/voidify.h | 2 +- .../__memory_resource/memory_resource.h | 33 +- .../monotonic_buffer_resource.h | 2 +- .../__memory_resource/polymorphic_allocator.h | 15 +- .../libcxx/__memory_resource/pool_options.h | 2 +- .../synchronized_pool_resource.h | 6 +- .../unsynchronized_pool_resource.h | 2 +- third_party/libcxx/__mutex/lock_guard.h | 11 +- third_party/libcxx/__mutex/mutex.h | 6 +- third_party/libcxx/__mutex/once_flag.h | 159 + third_party/libcxx/__mutex/tag_types.h | 16 +- third_party/libcxx/__mutex/unique_lock.h | 20 +- third_party/libcxx/__node_handle | 213 +- third_party/libcxx/__numeric/accumulate.h | 33 +- .../libcxx/__numeric/adjacent_difference.h | 62 +- third_party/libcxx/__numeric/exclusive_scan.h | 17 +- third_party/libcxx/__numeric/gcd_lcm.h | 122 +- third_party/libcxx/__numeric/inclusive_scan.h | 17 +- third_party/libcxx/__numeric/inner_product.h | 39 +- third_party/libcxx/__numeric/iota.h | 10 +- third_party/libcxx/__numeric/midpoint.h | 63 +- third_party/libcxx/__numeric/partial_sum.h | 58 +- third_party/libcxx/__numeric/pstl.h | 174 + third_party/libcxx/__numeric/reduce.h | 22 +- .../libcxx/__numeric/saturation_arithmetic.h | 145 + .../__numeric/transform_exclusive_scan.h | 33 +- .../__numeric/transform_inclusive_scan.h | 38 +- .../libcxx/__numeric/transform_reduce.h | 33 +- third_party/libcxx/__ostream/basic_ostream.h | 860 + third_party/libcxx/__ostream/print.h | 179 + third_party/libcxx/__pstl/backend.h | 35 + third_party/libcxx/__pstl/backend_fwd.h | 301 + third_party/libcxx/__pstl/backends/default.h | 503 + .../libcxx/__pstl/backends/libdispatch.h | 397 + third_party/libcxx/__pstl/backends/serial.h | 181 + .../libcxx/__pstl/backends/std_thread.h | 136 + third_party/libcxx/__pstl/cpu_algos/any_of.h | 99 + .../libcxx/__pstl/cpu_algos/cpu_traits.h | 86 + third_party/libcxx/__pstl/cpu_algos/fill.h | 66 + third_party/libcxx/__pstl/cpu_algos/find_if.h | 137 + .../libcxx/__pstl/cpu_algos/for_each.h | 66 + third_party/libcxx/__pstl/cpu_algos/merge.h | 85 + .../libcxx/__pstl/cpu_algos/stable_sort.h | 47 + .../libcxx/__pstl/cpu_algos/transform.h | 153 + .../__pstl/cpu_algos/transform_reduce.h | 216 + third_party/libcxx/__pstl/dispatch.h | 66 + third_party/libcxx/__pstl/handle_exception.h | 57 + .../libcxx/__pstl/internal/algorithm_fwd.h | 1768 --- .../libcxx/__pstl/internal/algorithm_impl.h | 4174 ----- .../libcxx/__pstl/internal/execution_defs.h | 76 - .../libcxx/__pstl/internal/execution_impl.h | 97 - .../__pstl/internal/glue_algorithm_defs.h | 655 - .../__pstl/internal/glue_algorithm_impl.h | 1081 -- .../libcxx/__pstl/internal/glue_memory_defs.h | 81 - .../libcxx/__pstl/internal/glue_memory_impl.h | 379 - .../__pstl/internal/glue_numeric_defs.h | 175 - .../__pstl/internal/glue_numeric_impl.h | 319 - .../libcxx/__pstl/internal/memory_impl.h | 106 - .../libcxx/__pstl/internal/numeric_fwd.h | 251 - .../libcxx/__pstl/internal/numeric_impl.h | 536 - .../libcxx/__pstl/internal/omp/parallel_for.h | 64 - .../__pstl/internal/omp/parallel_for_each.h | 59 - .../__pstl/internal/omp/parallel_invoke.h | 50 - .../__pstl/internal/omp/parallel_merge.h | 98 - .../__pstl/internal/omp/parallel_reduce.h | 73 - .../__pstl/internal/omp/parallel_scan.h | 136 - .../omp/parallel_stable_partial_sort.h | 33 - .../internal/omp/parallel_stable_sort.h | 160 - .../internal/omp/parallel_transform_reduce.h | 113 - .../internal/omp/parallel_transform_scan.h | 32 - third_party/libcxx/__pstl/internal/omp/util.h | 171 - .../libcxx/__pstl/internal/parallel_backend.h | 39 - .../__pstl/internal/parallel_backend_omp.h | 58 - .../__pstl/internal/parallel_backend_serial.h | 114 - .../__pstl/internal/parallel_backend_tbb.h | 1293 -- .../__pstl/internal/parallel_backend_utils.h | 260 - .../__pstl/internal/unseq_backend_simd.h | 762 - third_party/libcxx/__pstl/internal/utils.h | 144 - third_party/libcxx/__pstl_config_site | 17 - third_party/libcxx/__pstl_memory | 15 - .../libcxx/__random/bernoulli_distribution.h | 150 +- .../libcxx/__random/binomial_distribution.h | 273 +- .../libcxx/__random/cauchy_distribution.h | 179 +- .../__random/chi_squared_distribution.h | 155 +- .../libcxx/__random/clamp_to_integral.h | 22 +- .../libcxx/__random/discard_block_engine.h | 243 +- .../libcxx/__random/discrete_distribution.h | 326 +- .../__random/exponential_distribution.h | 164 +- .../__random/extreme_value_distribution.h | 181 +- .../libcxx/__random/fisher_f_distribution.h | 179 +- .../libcxx/__random/gamma_distribution.h | 265 +- .../libcxx/__random/generate_canonical.h | 28 +- .../libcxx/__random/geometric_distribution.h | 147 +- .../libcxx/__random/independent_bits_engine.h | 327 +- .../libcxx/__random/is_seed_sequence.h | 8 +- third_party/libcxx/__random/is_valid.h | 67 +- .../__random/linear_congruential_engine.h | 547 +- third_party/libcxx/__random/log2.h | 39 +- .../libcxx/__random/lognormal_distribution.h | 169 +- .../libcxx/__random/mersenne_twister_engine.h | 1213 +- .../__random/negative_binomial_distribution.h | 213 +- .../libcxx/__random/normal_distribution.h | 259 +- .../piecewise_constant_distribution.h | 475 +- .../__random/piecewise_linear_distribution.h | 506 +- .../libcxx/__random/poisson_distribution.h | 372 +- third_party/libcxx/__random/random_device.h | 75 +- third_party/libcxx/__random/ranlux.h | 2 +- third_party/libcxx/__random/seed_seq.h | 237 +- .../libcxx/__random/shuffle_order_engine.h | 344 +- .../libcxx/__random/student_t_distribution.h | 162 +- .../__random/subtract_with_carry_engine.h | 453 +- .../__random/uniform_int_distribution.h | 387 +- .../__random/uniform_random_bit_generator.h | 14 +- .../__random/uniform_real_distribution.h | 179 +- .../libcxx/__random/weibull_distribution.h | 171 +- third_party/libcxx/__ranges/access.h | 222 +- third_party/libcxx/__ranges/all.h | 58 +- third_party/libcxx/__ranges/as_rvalue_view.h | 21 +- third_party/libcxx/__ranges/chunk_by_view.h | 235 + third_party/libcxx/__ranges/common_view.h | 90 +- third_party/libcxx/__ranges/concepts.h | 126 +- third_party/libcxx/__ranges/copyable_box.h | 182 - third_party/libcxx/__ranges/counted.h | 60 +- third_party/libcxx/__ranges/data.h | 84 +- third_party/libcxx/__ranges/drop_view.h | 304 +- third_party/libcxx/__ranges/drop_while_view.h | 19 +- third_party/libcxx/__ranges/elements_view.h | 7 +- third_party/libcxx/__ranges/empty.h | 61 +- third_party/libcxx/__ranges/empty_view.h | 32 +- third_party/libcxx/__ranges/enable_view.h | 11 +- third_party/libcxx/__ranges/filter_view.h | 333 +- third_party/libcxx/__ranges/iota_view.h | 628 +- third_party/libcxx/__ranges/istream_view.h | 6 +- third_party/libcxx/__ranges/join_view.h | 590 +- third_party/libcxx/__ranges/lazy_split_view.h | 252 +- third_party/libcxx/__ranges/movable_box.h | 247 + .../libcxx/__ranges/non_propagating_cache.h | 141 +- third_party/libcxx/__ranges/owning_view.h | 97 +- third_party/libcxx/__ranges/range_adaptor.h | 62 +- third_party/libcxx/__ranges/rbegin.h | 66 +- third_party/libcxx/__ranges/ref_view.h | 66 +- third_party/libcxx/__ranges/rend.h | 69 +- third_party/libcxx/__ranges/repeat_view.h | 266 + third_party/libcxx/__ranges/reverse_view.h | 247 +- third_party/libcxx/__ranges/single_view.h | 85 +- third_party/libcxx/__ranges/size.h | 53 +- third_party/libcxx/__ranges/split_view.h | 11 +- third_party/libcxx/__ranges/subrange.h | 370 +- third_party/libcxx/__ranges/take_view.h | 220 +- third_party/libcxx/__ranges/take_while_view.h | 27 +- third_party/libcxx/__ranges/to.h | 245 + third_party/libcxx/__ranges/transform_view.h | 331 +- third_party/libcxx/__ranges/view_interface.h | 111 +- third_party/libcxx/__ranges/views.h | 2 +- third_party/libcxx/__ranges/zip_view.h | 246 +- third_party/libcxx/__split_buffer | 644 +- .../libcxx/__stop_token/atomic_unique_lock.h | 5 +- .../libcxx/__stop_token/intrusive_list_view.h | 2 +- .../__stop_token/intrusive_shared_ptr.h | 6 + .../libcxx/__stop_token/stop_callback.h | 102 + third_party/libcxx/__stop_token/stop_source.h | 91 + third_party/libcxx/__stop_token/stop_state.h | 236 + third_party/libcxx/__stop_token/stop_token.h | 63 + third_party/libcxx/__string/char_traits.h | 960 +- .../libcxx/__string/constexpr_c_functions.h | 132 +- .../libcxx/__string/extern_template_lists.h | 194 +- .../libcxx/__support/android/locale_bionic.h | 72 - .../libcxx/__support/fuchsia/xlocale.h | 22 - third_party/libcxx/__support/ibm/gettod_zos.h | 54 - .../libcxx/__support/ibm/locale_mgmt_zos.h | 53 - third_party/libcxx/__support/ibm/nanosleep.h | 55 - third_party/libcxx/__support/ibm/xlocale.h | 129 - third_party/libcxx/__support/musl/xlocale.h | 52 - third_party/libcxx/__support/newlib/xlocale.h | 23 - .../libcxx/__support/openbsd/xlocale.h | 35 - .../libcxx/__support/win32/locale_win32.h | 282 - .../__support/xlocale/__nop_locale_mgmt.h | 34 +- .../__support/xlocale/__posix_l_fallback.h | 77 +- .../__support/xlocale/__strtonum_fallback.h | 35 +- third_party/libcxx/__system_error/errc.h | 213 +- .../libcxx/__system_error/error_category.h | 10 +- .../libcxx/__system_error/error_code.h | 12 +- .../libcxx/__system_error/error_condition.h | 13 +- .../libcxx/__system_error/system_error.h | 16 +- third_party/libcxx/__thread/formatter.h | 80 + third_party/libcxx/__thread/id.h | 121 + third_party/libcxx/__thread/jthread.h | 134 + .../libcxx/__thread/poll_with_backoff.h | 42 +- third_party/libcxx/__thread/support.h | 123 + third_party/libcxx/__thread/support/pthread.h | 217 + third_party/libcxx/__thread/this_thread.h | 74 + third_party/libcxx/__thread/thread.h | 258 + .../libcxx/__thread/timed_backoff_policy.h | 30 +- third_party/libcxx/__threading_support | 708 - third_party/libcxx/__tree | 3688 ++--- third_party/libcxx/__tuple/find_index.h | 62 + .../backend.h => __tuple/ignore.h} | 31 +- third_party/libcxx/__tuple/make_tuple_types.h | 30 +- third_party/libcxx/__tuple/sfinae_helpers.h | 147 +- third_party/libcxx/__tuple/tuple_element.h | 67 +- third_party/libcxx/__tuple/tuple_indices.h | 10 +- third_party/libcxx/__tuple/tuple_like.h | 27 +- third_party/libcxx/__tuple/tuple_like_ext.h | 24 +- .../libcxx/__tuple/tuple_like_no_subrange.h | 61 + third_party/libcxx/__tuple/tuple_size.h | 50 +- third_party/libcxx/__tuple/tuple_types.h | 3 +- third_party/libcxx/__type_traits/add_const.h | 6 +- third_party/libcxx/__type_traits/add_cv.h | 6 +- .../__type_traits/add_lvalue_reference.h | 3 +- .../libcxx/__type_traits/add_pointer.h | 14 +- .../libcxx/__type_traits/add_volatile.h | 6 +- .../libcxx/__type_traits/aligned_storage.h | 88 +- .../libcxx/__type_traits/aligned_union.h | 29 +- .../libcxx/__type_traits/alignment_of.h | 4 +- third_party/libcxx/__type_traits/apply_cv.h | 78 - .../libcxx/__type_traits/can_extract_key.h | 9 +- .../libcxx/__type_traits/common_reference.h | 125 +- .../libcxx/__type_traits/common_type.h | 45 +- .../libcxx/__type_traits/conjunction.h | 7 + third_party/libcxx/__type_traits/copy_cv.h | 49 +- third_party/libcxx/__type_traits/copy_cvref.h | 15 +- third_party/libcxx/__type_traits/datasizeof.h | 65 + third_party/libcxx/__type_traits/decay.h | 27 +- .../libcxx/__type_traits/desugars_to.h | 40 + third_party/libcxx/__type_traits/enable_if.h | 14 +- third_party/libcxx/__type_traits/extent.h | 33 +- .../has_unique_object_representation.h | 14 +- .../__type_traits/has_virtual_destructor.h | 4 +- .../libcxx/__type_traits/integral_constant.h | 15 +- third_party/libcxx/__type_traits/invoke.h | 520 +- .../libcxx/__type_traits/is_abstract.h | 4 +- .../libcxx/__type_traits/is_aggregate.h | 4 +- .../libcxx/__type_traits/is_allocator.h | 10 +- .../__type_traits/is_always_bitcastable.h | 83 +- .../libcxx/__type_traits/is_arithmetic.h | 6 +- third_party/libcxx/__type_traits/is_array.h | 27 +- .../libcxx/__type_traits/is_assignable.h | 25 +- third_party/libcxx/__type_traits/is_base_of.h | 3 +- .../libcxx/__type_traits/is_bounded_array.h | 15 +- .../libcxx/__type_traits/is_callable.h | 6 +- third_party/libcxx/__type_traits/is_class.h | 4 +- .../libcxx/__type_traits/is_compound.h | 16 +- third_party/libcxx/__type_traits/is_const.h | 16 +- .../__type_traits/is_constant_evaluated.h | 8 +- .../libcxx/__type_traits/is_constructible.h | 36 +- .../libcxx/__type_traits/is_convertible.h | 86 +- .../libcxx/__type_traits/is_copy_assignable.h | 37 - .../__type_traits/is_copy_constructible.h | 36 - .../__type_traits/is_core_convertible.h | 5 +- .../__type_traits/is_default_constructible.h | 33 - .../libcxx/__type_traits/is_destructible.h | 43 +- third_party/libcxx/__type_traits/is_empty.h | 3 +- third_party/libcxx/__type_traits/is_enum.h | 14 +- .../__type_traits/is_equality_comparable.h | 20 +- third_party/libcxx/__type_traits/is_final.h | 8 +- .../libcxx/__type_traits/is_floating_point.h | 6 +- .../libcxx/__type_traits/is_function.h | 14 +- .../libcxx/__type_traits/is_fundamental.h | 19 +- .../is_implicitly_default_constructible.h | 18 +- .../libcxx/__type_traits/is_integral.h | 16 +- .../libcxx/__type_traits/is_literal_type.h | 12 +- .../is_member_function_pointer.h | 64 - .../__type_traits/is_member_object_pointer.h | 48 - .../libcxx/__type_traits/is_member_pointer.h | 27 +- .../libcxx/__type_traits/is_move_assignable.h | 36 - .../__type_traits/is_move_constructible.h | 34 - .../__type_traits/is_nothrow_assignable.h | 28 +- .../__type_traits/is_nothrow_constructible.h | 79 +- .../__type_traits/is_nothrow_convertible.h | 27 +- .../is_nothrow_copy_assignable.h | 38 - .../is_nothrow_copy_constructible.h | 48 - .../is_nothrow_default_constructible.h | 32 - .../__type_traits/is_nothrow_destructible.h | 72 +- .../is_nothrow_move_assignable.h | 37 - .../is_nothrow_move_constructible.h | 45 - .../libcxx/__type_traits/is_null_pointer.h | 20 +- third_party/libcxx/__type_traits/is_object.h | 25 +- third_party/libcxx/__type_traits/is_pod.h | 4 +- third_party/libcxx/__type_traits/is_pointer.h | 32 +- .../libcxx/__type_traits/is_polymorphic.h | 3 +- .../__type_traits/is_primary_template.h | 9 +- .../libcxx/__type_traits/is_reference.h | 54 +- .../__type_traits/is_reference_wrapper.h | 13 +- third_party/libcxx/__type_traits/is_same.h | 2 +- third_party/libcxx/__type_traits/is_scalar.h | 43 +- .../libcxx/__type_traits/is_scoped_enum.h | 42 - third_party/libcxx/__type_traits/is_signed.h | 20 +- .../libcxx/__type_traits/is_signed_integer.h | 16 +- .../libcxx/__type_traits/is_standard_layout.h | 5 +- .../libcxx/__type_traits/is_swappable.h | 149 +- third_party/libcxx/__type_traits/is_trivial.h | 5 +- .../__type_traits/is_trivially_assignable.h | 29 +- .../is_trivially_constructible.h | 33 +- .../is_trivially_copy_assignable.h | 38 - .../is_trivially_copy_constructible.h | 33 - .../__type_traits/is_trivially_copyable.h | 5 +- .../is_trivially_default_constructible.h | 32 - .../__type_traits/is_trivially_destructible.h | 10 +- .../is_trivially_move_assignable.h | 36 - .../is_trivially_move_constructible.h | 33 - .../__type_traits/is_trivially_relocatable.h | 42 + .../libcxx/__type_traits/is_unbounded_array.h | 15 +- third_party/libcxx/__type_traits/is_union.h | 4 +- .../libcxx/__type_traits/is_unsigned.h | 20 +- .../__type_traits/is_unsigned_integer.h | 16 +- .../libcxx/__type_traits/is_valid_expansion.h | 6 +- third_party/libcxx/__type_traits/is_void.h | 24 +- .../libcxx/__type_traits/is_volatile.h | 16 +- third_party/libcxx/__type_traits/lazy.h | 2 +- .../__type_traits/make_32_64_or_128_bit.h | 19 +- .../__type_traits/make_const_lvalue_ref.h | 2 +- .../libcxx/__type_traits/make_signed.h | 37 +- .../libcxx/__type_traits/make_unsigned.h | 42 +- .../libcxx/__type_traits/maybe_const.h | 2 +- third_party/libcxx/__type_traits/nat.h | 11 +- third_party/libcxx/__type_traits/negation.h | 2 +- .../noexcept_move_assign_container.h | 16 +- third_party/libcxx/__type_traits/promote.h | 128 +- third_party/libcxx/__type_traits/rank.h | 12 +- .../libcxx/__type_traits/remove_all_extents.h | 21 +- .../libcxx/__type_traits/remove_const.h | 13 +- third_party/libcxx/__type_traits/remove_cv.h | 18 +- .../libcxx/__type_traits/remove_cvref.h | 18 +- .../libcxx/__type_traits/remove_extent.h | 21 +- .../libcxx/__type_traits/remove_pointer.h | 10 +- .../libcxx/__type_traits/remove_reference.h | 15 +- .../libcxx/__type_traits/remove_volatile.h | 13 +- third_party/libcxx/__type_traits/result_of.h | 19 +- .../libcxx/__type_traits/strip_signature.h | 8 +- .../libcxx/__type_traits/type_identity.h | 12 +- third_party/libcxx/__type_traits/type_list.h | 20 +- .../libcxx/__type_traits/underlying_type.h | 11 +- third_party/libcxx/__type_traits/unwrap_ref.h | 22 +- third_party/libcxx/__type_traits/void_t.h | 3 +- third_party/libcxx/__undef_macros | 12 + third_party/libcxx/__utility/as_const.h | 4 +- .../pair_like.h => __utility/as_lvalue.h} | 23 +- third_party/libcxx/__utility/cmp.h | 74 +- .../libcxx/__utility/convert_to_integral.h | 50 +- third_party/libcxx/__utility/declval.h | 6 +- third_party/libcxx/__utility/empty.h | 24 + .../libcxx/__utility/exception_guard.h | 13 +- third_party/libcxx/__utility/exchange.h | 21 +- third_party/libcxx/__utility/forward.h | 4 +- third_party/libcxx/__utility/forward_like.h | 4 +- third_party/libcxx/__utility/in_place.h | 14 +- .../libcxx/__utility/integer_sequence.h | 117 +- .../libcxx/__utility/is_pointer_in_range.h | 62 + third_party/libcxx/__utility/is_valid_range.h | 37 + third_party/libcxx/__utility/move.h | 13 +- third_party/libcxx/__utility/no_destroy.h | 54 + third_party/libcxx/__utility/pair.h | 1158 +- .../libcxx/__utility/piecewise_construct.h | 4 +- third_party/libcxx/__utility/priority_tag.h | 6 +- .../__utility/private_constructor_tag.h | 28 + third_party/libcxx/__utility/rel_ops.h | 39 +- third_party/libcxx/__utility/small_buffer.h | 99 + third_party/libcxx/__utility/swap.h | 29 +- .../libcxx/__utility/terminate_on_exception.h | 47 - third_party/libcxx/__utility/to_underlying.h | 8 +- third_party/libcxx/__utility/unreachable.h | 4 +- third_party/libcxx/__variant/monostate.h | 16 +- third_party/libcxx/__verbose_abort | 14 +- third_party/libcxx/algorithm | 326 +- third_party/libcxx/{src => }/algorithm.cpp | 5 +- third_party/libcxx/any | 813 +- third_party/libcxx/{src => }/any.cpp | 16 +- third_party/libcxx/array | 509 +- third_party/libcxx/atomic | 86 +- third_party/libcxx/atomic.cpp | 205 + third_party/libcxx/atomic_support.h | 132 + third_party/libcxx/barrier | 367 +- third_party/libcxx/barrier.cpp | 75 + third_party/libcxx/{src => }/bind.cpp | 23 +- third_party/libcxx/bit | 41 +- third_party/libcxx/bitset | 1314 +- third_party/libcxx/call_once.cpp | 70 + third_party/libcxx/cassert | 1 - third_party/libcxx/ccomplex | 1 - third_party/libcxx/cctype | 30 +- third_party/libcxx/cerrno | 8 +- third_party/libcxx/cfenv | 1 - third_party/libcxx/cfloat | 1 - third_party/libcxx/charconv | 43 +- third_party/libcxx/{src => }/charconv.cpp | 35 +- third_party/libcxx/chrono | 280 +- third_party/libcxx/{src => }/chrono.cpp | 129 +- .../{src => }/chrono_system_time_init.h | 0 third_party/libcxx/cinttypes | 1 - third_party/libcxx/ciso646 | 1 - third_party/libcxx/climits | 9 - third_party/libcxx/clocale | 1 - third_party/libcxx/cmath | 320 +- third_party/libcxx/codecvt | 792 +- third_party/libcxx/compare | 38 +- third_party/libcxx/complex | 2046 ++- third_party/libcxx/concepts | 55 +- third_party/libcxx/condition_variable | 300 +- third_party/libcxx/condition_variable.cpp | 71 + .../condition_variable_destructor.cpp | 28 +- .../libcxx/{src/include => }/config_elast.h | 0 third_party/libcxx/coroutine | 14 +- third_party/libcxx/csetjmp | 15 +- third_party/libcxx/csignal | 1 - third_party/libcxx/cstdarg | 1 - third_party/libcxx/cstdbool | 1 - third_party/libcxx/cstddef | 99 +- third_party/libcxx/cstdint | 1 - third_party/libcxx/cstdio | 7 +- third_party/libcxx/cstdlib | 3 +- third_party/libcxx/cstring | 1 - third_party/libcxx/ctgmath | 1 - third_party/libcxx/ctime | 1 - third_party/libcxx/ctype.h | 28 +- third_party/libcxx/cuchar | 3 +- third_party/libcxx/cwchar | 9 +- third_party/libcxx/cwctype | 1 - third_party/libcxx/deque | 3458 ++-- third_party/libcxx/errno.h | 522 +- third_party/libcxx/error_category.cpp | 37 + third_party/libcxx/exception | 1 - .../{__pstl_algorithm => exception.cpp} | 13 +- ...on_libcxxabi.ipp => exception_libcxxabi.h} | 15 +- third_party/libcxx/exception_pointer_cxxabi.h | 64 + third_party/libcxx/execution | 5 +- third_party/libcxx/expected | 20 +- .../libcxx/{__pstl_numeric => expected.cpp} | 10 +- third_party/libcxx/experimental/__config | 41 +- third_party/libcxx/experimental/__memory | 120 - .../libcxx/experimental/__simd/aligned_tag.h | 75 + .../libcxx/experimental/__simd/declaration.h | 81 + .../libcxx/experimental/__simd/reference.h | 105 + .../libcxx/experimental/__simd/scalar.h | 87 + third_party/libcxx/experimental/__simd/simd.h | 102 + .../libcxx/experimental/__simd/simd_mask.h | 90 + .../libcxx/experimental/__simd/traits.h | 75 + .../libcxx/experimental/__simd/utility.h | 103 + .../libcxx/experimental/__simd/vec_ext.h | 119 + third_party/libcxx/experimental/deque | 52 - third_party/libcxx/experimental/forward_list | 52 - third_party/libcxx/experimental/iterator | 69 +- third_party/libcxx/experimental/list | 52 - third_party/libcxx/experimental/map | 62 - third_party/libcxx/experimental/memory | 198 + .../libcxx/experimental/memory_resource | 444 - .../libcxx/experimental/propagate_const | 437 +- third_party/libcxx/experimental/regex | 69 - third_party/libcxx/experimental/set | 62 - third_party/libcxx/experimental/simd | 1621 +- third_party/libcxx/experimental/string | 73 - third_party/libcxx/experimental/type_traits | 70 +- third_party/libcxx/experimental/unordered_map | 78 - third_party/libcxx/experimental/unordered_set | 64 - third_party/libcxx/experimental/utility | 3 +- third_party/libcxx/experimental/vector | 52 - third_party/libcxx/ext/__hash | 130 +- third_party/libcxx/ext/hash_map | 872 ++ third_party/libcxx/ext/hash_set | 584 + third_party/libcxx/fenv.h | 70 +- third_party/libcxx/filesystem | 151 +- third_party/libcxx/float.h | 12 +- third_party/libcxx/format | 111 +- third_party/libcxx/forward_list | 2189 ++- third_party/libcxx/fs/directory_entry.cpp | 73 + .../filesystem => fs}/directory_iterator.cpp | 94 +- third_party/libcxx/fs/error.h | 232 + third_party/libcxx/fs/file_descriptor.h | 291 + third_party/libcxx/fs/filesystem_clock.cpp | 62 + third_party/libcxx/fs/filesystem_error.cpp | 39 + third_party/libcxx/fs/format_string.h | 77 + .../filesystem => fs}/int128_builtins.cpp | 14 +- third_party/libcxx/fs/operations.cpp | 965 ++ third_party/libcxx/fs/path.cpp | 441 + third_party/libcxx/fs/path_parser.h | 352 + .../{src/filesystem => fs}/posix_compat.h | 303 +- third_party/libcxx/fs/time_utils.h | 351 + third_party/libcxx/fstream | 2337 ++- third_party/libcxx/fstream.cpp | 37 + third_party/libcxx/functional | 78 +- third_party/libcxx/{src => }/functional.cpp | 12 +- third_party/libcxx/future | 2819 ++-- third_party/libcxx/future.cpp | 197 + third_party/libcxx/hash.cpp | 452 + third_party/libcxx/initializer_list | 70 +- third_party/libcxx/inttypes.h | 10 +- third_party/libcxx/iomanip | 733 +- third_party/libcxx/ios | 1119 +- third_party/libcxx/ios.cpp | 387 + .../libcxx/{src => }/ios.instantiations.cpp | 4 +- third_party/libcxx/iosfwd | 96 +- third_party/libcxx/iostream | 17 +- third_party/libcxx/iostream.cpp | 171 + third_party/libcxx/{src => }/iostream_init.h | 0 third_party/libcxx/istream | 2305 ++- third_party/libcxx/iterator | 101 +- third_party/libcxx/latch | 114 +- .../{src => }/legacy_pointer_safety.cpp | 8 +- third_party/libcxx/libcxx.imp | 53 - third_party/libcxx/limits | 908 +- third_party/libcxx/limits.h | 71 - third_party/libcxx/list | 2788 ++-- third_party/libcxx/locale | 6243 ++++---- third_party/libcxx/locale.cpp | 5717 +++++++ third_party/libcxx/locale.h | 4 - third_party/libcxx/map | 2540 ++- third_party/libcxx/math.h | 1398 +- third_party/libcxx/mdspan | 375 +- third_party/libcxx/memory | 110 +- third_party/libcxx/memory.cpp | 148 + third_party/libcxx/memory_resource | 34 +- .../libcxx/{src => }/memory_resource.cpp | 16 +- .../memory_resource_init_helper.h | 0 third_party/libcxx/module.modulemap | 1856 --- third_party/libcxx/mutex | 630 +- third_party/libcxx/mutex.cpp | 145 + .../libcxx/{src => }/mutex_destructor.cpp | 30 +- third_party/libcxx/new | 239 +- third_party/libcxx/new.cpp | 226 + third_party/libcxx/new_handler.cpp | 39 + .../exception_glibcxx.ipp => new_helpers.cpp} | 30 +- third_party/libcxx/numbers | 92 +- third_party/libcxx/numeric | 52 +- third_party/libcxx/optional | 1826 +-- third_party/libcxx/{src => }/optional.cpp | 16 +- third_party/libcxx/ostream | 1047 +- third_party/libcxx/ostream.cpp | 41 + third_party/libcxx/overridable_function.h | 129 + third_party/libcxx/print | 402 + third_party/libcxx/print.cpp | 64 + third_party/libcxx/queue | 1073 +- third_party/libcxx/random | 4 - third_party/libcxx/random.cpp | 181 + third_party/libcxx/random_shuffle.cpp | 51 + third_party/libcxx/ranges | 137 +- third_party/libcxx/ratio | 433 +- third_party/libcxx/refstring.h | 127 + third_party/libcxx/regex | 8690 +++++------ third_party/libcxx/{src => }/regex.cpp | 295 +- .../libcxx/{src/include => }/ryu/common.h | 14 +- third_party/libcxx/{src => }/ryu/d2fixed.cpp | 16 +- .../libcxx/{src/include => }/ryu/d2fixed.h | 0 .../include => }/ryu/d2fixed_full_table.h | 0 third_party/libcxx/{src => }/ryu/d2s.cpp | 18 +- .../libcxx/{src/include => }/ryu/d2s.h | 0 .../{src/include => }/ryu/d2s_full_table.h | 0 .../{src/include => }/ryu/d2s_intrinsics.h | 18 +- .../{src/include => }/ryu/digit_table.h | 0 third_party/libcxx/{src => }/ryu/f2s.cpp | 32 +- .../libcxx/{src/include => }/ryu/f2s.h | 0 .../libcxx/{src/include => }/ryu/ryu.h | 8 +- third_party/libcxx/scoped_allocator | 768 +- third_party/libcxx/semaphore | 210 +- third_party/libcxx/set | 1617 +- third_party/libcxx/shared_mutex | 550 +- third_party/libcxx/shared_mutex.cpp | 93 + third_party/libcxx/source_location | 6 +- third_party/libcxx/span | 680 +- third_party/libcxx/src/atomic.cpp | 220 - third_party/libcxx/src/barrier.cpp | 97 - third_party/libcxx/src/condition_variable.cpp | 96 - third_party/libcxx/src/debug.cpp | 559 - third_party/libcxx/src/exception.cpp | 35 - .../src/experimental/memory_resource.cpp | 149 - .../libcxx/src/filesystem/filesystem_common.h | 611 - .../libcxx/src/filesystem/operations.cpp | 2103 --- third_party/libcxx/src/future.cpp | 269 - third_party/libcxx/src/hash.cpp | 559 - .../libcxx/src/include/apple_availability.h | 34 - .../libcxx/src/include/atomic_support.h | 176 - third_party/libcxx/src/include/refstring.h | 140 - .../libcxx/src/include/sso_allocator.h | 82 - third_party/libcxx/src/ios.cpp | 443 - third_party/libcxx/src/iostream.cpp | 168 - .../libcxx/src/legacy_debug_handler.cpp | 54 - third_party/libcxx/src/locale.cpp | 6596 -------- third_party/libcxx/src/memory.cpp | 207 - .../libcxx/src/memory_resource_init_helper.h | 2 - third_party/libcxx/src/mutex.cpp | 262 - third_party/libcxx/src/new.cpp | 294 - third_party/libcxx/src/random.cpp | 216 - third_party/libcxx/src/ryu/README.txt | 11 - third_party/libcxx/src/shared_mutex.cpp | 120 - third_party/libcxx/src/std_stream.h | 361 - third_party/libcxx/src/string.cpp | 392 - third_party/libcxx/src/strstream.cpp | 340 - .../libcxx/src/support/ibm/mbsnrtowcs.cpp | 95 - .../libcxx/src/support/ibm/wcsnrtombs.cpp | 93 - .../libcxx/src/support/ibm/xlocale_zos.cpp | 138 - .../support/runtime/exception_fallback.ipp | 158 - .../support/runtime/exception_libcxxrt.ipp | 25 - .../src/support/runtime/exception_msvc.ipp | 163 - .../runtime/exception_pointer_cxxabi.ipp | 73 - .../runtime/exception_pointer_glibcxx.ipp | 77 - .../runtime/exception_pointer_msvc.ipp | 86 - .../exception_pointer_unimplemented.ipp | 79 - .../support/runtime/new_handler_fallback.ipp | 26 - .../support/runtime/stdexcept_vcruntime.ipp | 16 - .../libcxx/src/support/win32/locale_win32.cpp | 143 - .../libcxx/src/support/win32/support.cpp | 172 - .../libcxx/src/support/win32/thread_win32.cpp | 274 - third_party/libcxx/src/system_error.cpp | 298 - third_party/libcxx/src/thread.cpp | 217 - third_party/libcxx/src/valarray.cpp | 57 - third_party/libcxx/sso_allocator.h | 80 + third_party/libcxx/sstream | 1584 +- third_party/libcxx/stack | 359 +- third_party/libcxx/std_stream.h | 387 + third_party/libcxx/stdatomic.h | 24 +- third_party/libcxx/stdbool.h | 10 +- third_party/libcxx/stddef.h | 27 +- third_party/libcxx/stdexcept | 245 +- third_party/libcxx/{src => }/stdexcept.cpp | 15 +- ...except_default.ipp => stdexcept_default.h} | 12 +- third_party/libcxx/stdint.h | 6 +- third_party/libcxx/stdio.h | 34 +- third_party/libcxx/stdlib.h | 94 +- third_party/libcxx/stop_token | 56 + third_party/libcxx/streambuf | 515 +- third_party/libcxx/string | 5156 +++--- third_party/libcxx/string.cpp | 347 + third_party/libcxx/string.h | 2 +- third_party/libcxx/string_view | 1095 +- third_party/libcxx/strstream | 378 +- third_party/libcxx/strstream.cpp | 258 + third_party/libcxx/syncstream | 512 + third_party/libcxx/system_error | 1 - third_party/libcxx/system_error.cpp | 223 + third_party/libcxx/thread | 395 +- third_party/libcxx/thread.cpp | 173 + .../include => }/to_chars_floating_point.h | 74 +- third_party/libcxx/tuple | 2187 ++- third_party/libcxx/type_traits | 81 +- third_party/libcxx/typeindex | 66 +- third_party/libcxx/typeinfo | 276 +- third_party/libcxx/{src => }/typeinfo.cpp | 30 +- third_party/libcxx/uchar.h | 12 +- third_party/libcxx/unordered_map | 3129 ++-- third_party/libcxx/unordered_set | 2343 ++- third_party/libcxx/utility | 42 +- third_party/libcxx/valarray | 5838 +++---- third_party/libcxx/valarray.cpp | 49 + third_party/libcxx/variant | 1449 +- third_party/libcxx/{src => }/variant.cpp | 6 +- third_party/libcxx/vector | 4039 ++--- third_party/libcxx/{src => }/vector.cpp | 8 +- .../libcxx/{src => }/verbose_abort.cpp | 6 +- third_party/libcxx/version | 218 +- third_party/libcxx/wchar.h | 155 +- third_party/libcxx/wctype.h | 43 +- third_party/libcxxabi/BUILD.mk | 3 - third_party/libcxxabi/cxa_default_handlers.cc | 2 +- third_party/libcxxabi/cxa_exception.cc | 62 +- .../libcxxabi/cxa_exception_storage.cc | 3 +- third_party/libcxxabi/cxa_guard.cc | 1 + third_party/libcxxabi/cxa_guard_impl.h | 4 +- third_party/libcxxabi/cxa_handlers.cc | 2 +- third_party/libcxxabi/cxa_thread_atexit.cc | 2 +- third_party/libcxxabi/fallback_malloc.cc | 2 +- third_party/libcxxabi/stdlib_stdexcept.cc | 2 +- third_party/libcxxabi/test/BUILD.mk | 3 +- .../test/catch_const_pointer_nullptr.pass.cc | 2 + .../test/test_exception_storage.pass.cc | 1 - .../test/test_fallback_malloc.pass.cc | 2 - third_party/lua/lunix.c | 8 +- third_party/make/getopt.c | 5 +- third_party/make/getopt.h | 13 +- third_party/ncurses/write_entry.c | 2 + third_party/tree/file.c | 2 +- third_party/tree/list.c | 2 +- third_party/tree/tree.c | 35 +- third_party/tree/tree.h | 16 +- third_party/unzip/envargs.c | 4 +- third_party/unzip/unzpriv.h | 1 + third_party/zip/fileio.c | 2 + third_party/zip/util.c | 1 + third_party/zip/zip.c | 1 + third_party/zip/zipfile.c | 1 + third_party/zlib/macros.internal.h | 4 + tool/cosmocc/README.md | 6 +- tool/cosmocc/bin/cosmocc | 2 +- tool/cosmocc/bin/cosmocross | 2 +- tool/cosmocc/package.sh | 6 +- tool/lambda/tromp.c | 8 + tool/viz/lib/formatmatrix-byte.c | 4 +- tool/viz/lib/formatmatrix-double.c | 4 +- tool/viz/lib/formatmatrix-short.c | 4 +- tool/viz/lib/formatstringtable-assembly.c | 42 +- tool/viz/lib/formatstringtable-code.c | 19 +- tool/viz/lib/formatstringtable.c | 11 +- 1585 files changed, 117353 insertions(+), 271644 deletions(-) delete mode 100644 examples/unbourne.c delete mode 100644 libc/isystem/__threading_support create mode 100644 libc/isystem/amxcomplexintrin.h create mode 100644 libc/isystem/amxfp16intrin.h create mode 100644 libc/isystem/avxifmaintrin.h create mode 100644 libc/isystem/avxneconvertintrin.h create mode 100644 libc/isystem/avxvnniint16intrin.h create mode 100644 libc/isystem/avxvnniint8intrin.h create mode 100644 libc/isystem/bmmintrin.h create mode 100644 libc/isystem/cmpccxaddintrin.h create mode 100644 libc/isystem/prfchiintrin.h create mode 100644 libc/isystem/raointintrin.h create mode 100644 libc/isystem/sha512intrin.h create mode 100644 libc/isystem/sm3intrin.h create mode 100644 libc/isystem/sm4intrin.h create mode 100644 libc/isystem/usermsrintrin.h delete mode 100644 test/libc/thread/pthread_setaffinity_np_test.c delete mode 100644 third_party/aarch64/acc_prof.internal.h delete mode 100644 third_party/aarch64/openacc.internal.h delete mode 100644 third_party/bash/BUILD.mk delete mode 100644 third_party/bash/LICENSE delete mode 100644 third_party/bash/README.cosmo delete mode 100644 third_party/bash/alias.c delete mode 100644 third_party/bash/alias.h delete mode 100644 third_party/bash/ansi_stdlib.h delete mode 100644 third_party/bash/array.c delete mode 100644 third_party/bash/array.h delete mode 100644 third_party/bash/arrayfunc.c delete mode 100644 third_party/bash/arrayfunc.h delete mode 100644 third_party/bash/assoc.c delete mode 100644 third_party/bash/assoc.h delete mode 100644 third_party/bash/bashansi.h delete mode 100644 third_party/bash/bashgetopt.c delete mode 100644 third_party/bash/bashgetopt.h delete mode 100644 third_party/bash/bashhist.c delete mode 100644 third_party/bash/bashhist.h delete mode 100644 third_party/bash/bashintl.h delete mode 100644 third_party/bash/bashjmp.h delete mode 100644 third_party/bash/bashline.c delete mode 100644 third_party/bash/bashline.h delete mode 100644 third_party/bash/bashtypes.h delete mode 100644 third_party/bash/bracecomp.c delete mode 100644 third_party/bash/braces.c delete mode 100644 third_party/bash/break.c delete mode 100644 third_party/bash/builtext.h delete mode 100644 third_party/bash/builtins.c delete mode 100644 third_party/bash/builtins.h delete mode 100644 third_party/bash/builtins_alias.c delete mode 100644 third_party/bash/builtins_bind.c delete mode 100644 third_party/bash/builtins_break.c delete mode 100644 third_party/bash/builtins_builtin.c delete mode 100644 third_party/bash/builtins_caller.c delete mode 100644 third_party/bash/builtins_cd.c delete mode 100644 third_party/bash/builtins_colon.c delete mode 100644 third_party/bash/builtins_command.c delete mode 100644 third_party/bash/builtins_complete.c delete mode 100644 third_party/bash/builtins_declare.c delete mode 100644 third_party/bash/builtins_echo.c delete mode 100644 third_party/bash/builtins_enable.c delete mode 100644 third_party/bash/builtins_eval.c delete mode 100644 third_party/bash/builtins_exec.c delete mode 100644 third_party/bash/builtins_exit.c delete mode 100644 third_party/bash/builtins_fc.c delete mode 100644 third_party/bash/builtins_fg_bg.c delete mode 100644 third_party/bash/builtins_getopts.c delete mode 100644 third_party/bash/builtins_hash.c delete mode 100644 third_party/bash/builtins_help.c delete mode 100644 third_party/bash/builtins_history.c delete mode 100644 third_party/bash/builtins_jobs.c delete mode 100644 third_party/bash/builtins_kill.c delete mode 100644 third_party/bash/builtins_let.c delete mode 100644 third_party/bash/builtins_mapfile.c delete mode 100644 third_party/bash/builtins_printf.c delete mode 100644 third_party/bash/builtins_pushd.c delete mode 100644 third_party/bash/builtins_read.c delete mode 100644 third_party/bash/builtins_return.c delete mode 100644 third_party/bash/builtins_set.c delete mode 100644 third_party/bash/builtins_setattr.c delete mode 100644 third_party/bash/builtins_shift.c delete mode 100644 third_party/bash/builtins_shopt.c delete mode 100644 third_party/bash/builtins_source.c delete mode 100644 third_party/bash/builtins_suspend.c delete mode 100644 third_party/bash/builtins_test.c delete mode 100644 third_party/bash/builtins_times.c delete mode 100644 third_party/bash/builtins_trap.c delete mode 100644 third_party/bash/builtins_type.c delete mode 100644 third_party/bash/builtins_ulimit.c delete mode 100644 third_party/bash/builtins_umask.c delete mode 100644 third_party/bash/builtins_wait.c delete mode 100644 third_party/bash/casemod.c delete mode 100644 third_party/bash/chartypes.h delete mode 100644 third_party/bash/clktck.c delete mode 100644 third_party/bash/clock.c delete mode 100644 third_party/bash/collsyms.h delete mode 100644 third_party/bash/command.h delete mode 100644 third_party/bash/common.c delete mode 100644 third_party/bash/common.h delete mode 100644 third_party/bash/config-bot.h delete mode 100644 third_party/bash/config-top.h delete mode 100644 third_party/bash/config.h delete mode 100644 third_party/bash/conftypes.h delete mode 100644 third_party/bash/copy_cmd.c delete mode 100644 third_party/bash/dispose_cmd.c delete mode 100644 third_party/bash/dispose_cmd.h delete mode 100644 third_party/bash/eaccess.c delete mode 100644 third_party/bash/error.c delete mode 100644 third_party/bash/error.h delete mode 100644 third_party/bash/eval.c delete mode 100644 third_party/bash/evalfile.c delete mode 100644 third_party/bash/evalstring.c delete mode 100644 third_party/bash/execute_cmd.c delete mode 100644 third_party/bash/execute_cmd.h delete mode 100644 third_party/bash/expr.c delete mode 100644 third_party/bash/externs.h delete mode 100644 third_party/bash/filecntl.h delete mode 100644 third_party/bash/findcmd.c delete mode 100644 third_party/bash/findcmd.h delete mode 100644 third_party/bash/flags.c delete mode 100644 third_party/bash/flags.h delete mode 100644 third_party/bash/fmtullong.c delete mode 100644 third_party/bash/fmtulong.c delete mode 100644 third_party/bash/fmtumax.c delete mode 100644 third_party/bash/fnxform.c delete mode 100644 third_party/bash/fpurge.c delete mode 100644 third_party/bash/general.c delete mode 100644 third_party/bash/general.h delete mode 100644 third_party/bash/getenv.c delete mode 100644 third_party/bash/getopt.c delete mode 100644 third_party/bash/getopt.h delete mode 100644 third_party/bash/gettext.h delete mode 100644 third_party/bash/gettimeofday.c delete mode 100644 third_party/bash/glob.c delete mode 100644 third_party/bash/glob.h delete mode 100644 third_party/bash/glob_loop.inc delete mode 100644 third_party/bash/gm_loop.inc delete mode 100644 third_party/bash/gmisc.c delete mode 100644 third_party/bash/hashcmd.c delete mode 100644 third_party/bash/hashcmd.h delete mode 100644 third_party/bash/hashlib.c delete mode 100644 third_party/bash/hashlib.h delete mode 100644 third_party/bash/input.c delete mode 100644 third_party/bash/input.h delete mode 100644 third_party/bash/input_avail.c delete mode 100644 third_party/bash/itos.c delete mode 100644 third_party/bash/jobs.c delete mode 100644 third_party/bash/jobs.h delete mode 100644 third_party/bash/list.c delete mode 100644 third_party/bash/locale.c delete mode 100644 third_party/bash/mailcheck.c delete mode 100644 third_party/bash/mailcheck.h delete mode 100644 third_party/bash/mailstat.c delete mode 100644 third_party/bash/make_cmd.c delete mode 100644 third_party/bash/make_cmd.h delete mode 100644 third_party/bash/makepath.c delete mode 100644 third_party/bash/maxpath.h delete mode 100644 third_party/bash/mbscasecmp.c delete mode 100644 third_party/bash/mbschr.c delete mode 100644 third_party/bash/mbscmp.c delete mode 100644 third_party/bash/memalloc.h delete mode 100644 third_party/bash/ndir.h delete mode 100644 third_party/bash/netconn.c delete mode 100644 third_party/bash/netopen.c delete mode 100644 third_party/bash/ocache.h delete mode 100644 third_party/bash/oslib.c delete mode 100644 third_party/bash/parser.h delete mode 100644 third_party/bash/patchlevel.h delete mode 100644 third_party/bash/pathcanon.c delete mode 100644 third_party/bash/pathexp.c delete mode 100644 third_party/bash/pathexp.h delete mode 100644 third_party/bash/pathnames.h delete mode 100644 third_party/bash/pathphys.c delete mode 100644 third_party/bash/pcomplete.c delete mode 100644 third_party/bash/pcomplete.h delete mode 100644 third_party/bash/pcomplib.c delete mode 100644 third_party/bash/pipesize.h delete mode 100644 third_party/bash/posixdir.h delete mode 100644 third_party/bash/posixjmp.h delete mode 100644 third_party/bash/posixselect.h delete mode 100644 third_party/bash/posixstat.h delete mode 100644 third_party/bash/posixtime.h delete mode 100644 third_party/bash/posixwait.h delete mode 100644 third_party/bash/print_cmd.c delete mode 100644 third_party/bash/psize.c delete mode 100644 third_party/bash/quit.h delete mode 100644 third_party/bash/random.c delete mode 100644 third_party/bash/read.c delete mode 100644 third_party/bash/redir.c delete mode 100644 third_party/bash/redir.h delete mode 100644 third_party/bash/rename.c delete mode 100644 third_party/bash/setlinebuf.c delete mode 100644 third_party/bash/shell.c delete mode 100644 third_party/bash/shell.h delete mode 100644 third_party/bash/shmatch.c delete mode 100644 third_party/bash/shmbchar.c delete mode 100644 third_party/bash/shmbchar.h delete mode 100644 third_party/bash/shmbutil.h delete mode 100644 third_party/bash/shquote.c delete mode 100644 third_party/bash/shtty.c delete mode 100644 third_party/bash/shtty.h delete mode 100644 third_party/bash/sig.c delete mode 100644 third_party/bash/sig.h delete mode 100644 third_party/bash/siglist.h delete mode 100644 third_party/bash/signames.c delete mode 100644 third_party/bash/signames.h delete mode 100644 third_party/bash/sm_loop.inc delete mode 100644 third_party/bash/smatch.c delete mode 100644 third_party/bash/spell.c delete mode 100644 third_party/bash/stat-time.h delete mode 100644 third_party/bash/stdc.h delete mode 100644 third_party/bash/stringlib.c delete mode 100644 third_party/bash/stringlist.c delete mode 100644 third_party/bash/stringvec.c delete mode 100644 third_party/bash/strmatch.c delete mode 100644 third_party/bash/strmatch.h delete mode 100644 third_party/bash/strtrans.c delete mode 100644 third_party/bash/strvis.c delete mode 100644 third_party/bash/subst.c delete mode 100644 third_party/bash/subst.h delete mode 100644 third_party/bash/syntax.c delete mode 100644 third_party/bash/syntax.h delete mode 100644 third_party/bash/systimes.h delete mode 100644 third_party/bash/test.c delete mode 100644 third_party/bash/test.h delete mode 100644 third_party/bash/tilde.c delete mode 100644 third_party/bash/tilde.h delete mode 100644 third_party/bash/timer.h delete mode 100644 third_party/bash/timers.c delete mode 100644 third_party/bash/timeval.c delete mode 100644 third_party/bash/tmpfile.c delete mode 100644 third_party/bash/trap.c delete mode 100644 third_party/bash/trap.h delete mode 100644 third_party/bash/typemax.h delete mode 100644 third_party/bash/uconvert.c delete mode 100644 third_party/bash/ufuncs.c delete mode 100644 third_party/bash/unicode.c delete mode 100644 third_party/bash/unionwait.h delete mode 100644 third_party/bash/unwind_prot.c delete mode 100644 third_party/bash/unwind_prot.h delete mode 100644 third_party/bash/utf8.c delete mode 100644 third_party/bash/variables.c delete mode 100644 third_party/bash/variables.h delete mode 100644 third_party/bash/version.c delete mode 100644 third_party/bash/version.h delete mode 100644 third_party/bash/winsize.c delete mode 100644 third_party/bash/xmalloc.c delete mode 100644 third_party/bash/xmalloc.h delete mode 100644 third_party/bash/xmbsrtowcs.c delete mode 100644 third_party/bash/y.tab.c delete mode 100644 third_party/bash/y.tab.h delete mode 100644 third_party/bash/zcatfd.c delete mode 100644 third_party/bash/zgetline.c delete mode 100644 third_party/bash/zmapfd.c delete mode 100644 third_party/bash/zread.c delete mode 100644 third_party/bash/zwrite.c create mode 100644 third_party/intel/amxcomplexintrin.internal.h create mode 100644 third_party/intel/amxfp16intrin.internal.h create mode 100644 third_party/intel/avx512bitalgvlintrin.internal.h create mode 100644 third_party/intel/avxifmaintrin.internal.h create mode 100644 third_party/intel/avxneconvertintrin.internal.h create mode 100644 third_party/intel/avxvnniint16intrin.internal.h create mode 100644 third_party/intel/avxvnniint8intrin.internal.h create mode 100644 third_party/intel/bmmintrin.internal.h create mode 100644 third_party/intel/cmpccxaddintrin.internal.h create mode 100644 third_party/intel/prfchiintrin.internal.h create mode 100644 third_party/intel/raointintrin.internal.h create mode 100644 third_party/intel/sha512intrin.internal.h create mode 100644 third_party/intel/sm3intrin.internal.h create mode 100644 third_party/intel/sm4intrin.internal.h create mode 100644 third_party/intel/usermsrintrin.internal.h delete mode 100644 third_party/libcxx/CREDITS.TXT delete mode 100644 third_party/libcxx/LICENSE.TXT create mode 100644 third_party/libcxx/__algorithm/find_segment_if.h create mode 100644 third_party/libcxx/__algorithm/fold.h create mode 100644 third_party/libcxx/__algorithm/pstl.h delete mode 100644 third_party/libcxx/__algorithm/pstl_any_all_none_of.h delete mode 100644 third_party/libcxx/__algorithm/pstl_backend.h delete mode 100644 third_party/libcxx/__algorithm/pstl_backends/cpu_backend.h delete mode 100644 third_party/libcxx/__algorithm/pstl_backends/cpu_backends/any_of.h delete mode 100644 third_party/libcxx/__algorithm/pstl_backends/cpu_backends/fill.h delete mode 100644 third_party/libcxx/__algorithm/pstl_backends/cpu_backends/find_if.h delete mode 100644 third_party/libcxx/__algorithm/pstl_backends/cpu_backends/for_each.h delete mode 100644 third_party/libcxx/__algorithm/pstl_backends/cpu_backends/merge.h delete mode 100644 third_party/libcxx/__algorithm/pstl_backends/cpu_backends/serial.h delete mode 100644 third_party/libcxx/__algorithm/pstl_backends/cpu_backends/thread.h delete mode 100644 third_party/libcxx/__algorithm/pstl_backends/cpu_backends/transform.h delete mode 100644 third_party/libcxx/__algorithm/pstl_copy.h delete mode 100644 third_party/libcxx/__algorithm/pstl_fill.h delete mode 100644 third_party/libcxx/__algorithm/pstl_find.h delete mode 100644 third_party/libcxx/__algorithm/pstl_for_each.h delete mode 100644 third_party/libcxx/__algorithm/pstl_frontend_dispatch.h delete mode 100644 third_party/libcxx/__algorithm/pstl_merge.h delete mode 100644 third_party/libcxx/__algorithm/pstl_transform.h create mode 100644 third_party/libcxx/__algorithm/ranges_contains.h create mode 100644 third_party/libcxx/__algorithm/ranges_contains_subrange.h create mode 100644 third_party/libcxx/__algorithm/ranges_ends_with.h create mode 100644 third_party/libcxx/__algorithm/ranges_find_last.h create mode 100644 third_party/libcxx/__algorithm/simd_utils.h create mode 100644 third_party/libcxx/__assertion_handler create mode 100644 third_party/libcxx/__atomic/atomic_ref.h create mode 100644 third_party/libcxx/__atomic/to_gcc_order.h delete mode 100644 third_party/libcxx/__availability rename third_party/libcxx/{setjmp.h => __bit/invert_if.h} (56%) create mode 100644 third_party/libcxx/__chrono/exception.h create mode 100644 third_party/libcxx/__chrono/leap_second.h create mode 100644 third_party/libcxx/__chrono/local_info.h create mode 100644 third_party/libcxx/__chrono/sys_info.h create mode 100644 third_party/libcxx/__chrono/time_zone.h create mode 100644 third_party/libcxx/__chrono/time_zone_link.h create mode 100644 third_party/libcxx/__chrono/tzdb.h create mode 100644 third_party/libcxx/__chrono/tzdb_list.h create mode 100644 third_party/libcxx/__chrono/zoned_time.h create mode 100644 third_party/libcxx/__configuration/abi.h create mode 100644 third_party/libcxx/__configuration/availability.h create mode 100644 third_party/libcxx/__configuration/compiler.h create mode 100644 third_party/libcxx/__configuration/language.h create mode 100644 third_party/libcxx/__configuration/platform.h delete mode 100644 third_party/libcxx/__debug create mode 100644 third_party/libcxx/__debug_utils/sanitizers.h create mode 100644 third_party/libcxx/__debug_utils/strict_weak_ordering_check.h create mode 100644 third_party/libcxx/__format/indic_conjunct_break_table.h create mode 100644 third_party/libcxx/__format/write_escaped.h rename third_party/libcxx/{__type_traits/predicate_traits.h => __fwd/bit_reference.h} (64%) create mode 100644 third_party/libcxx/__fwd/complex.h create mode 100644 third_party/libcxx/__fwd/deque.h rename third_party/libcxx/{__format/format_fwd.h => __fwd/format.h} (86%) create mode 100644 third_party/libcxx/__fwd/functional.h delete mode 100644 third_party/libcxx/__fwd/get.h create mode 100644 third_party/libcxx/__fwd/mdspan.h rename third_party/libcxx/__fwd/{hash.h => memory.h} (77%) create mode 100644 third_party/libcxx/__fwd/queue.h create mode 100644 third_party/libcxx/__fwd/stack.h create mode 100644 third_party/libcxx/__fwd/vector.h create mode 100644 third_party/libcxx/__iterator/aliasing_iterator.h create mode 100644 third_party/libcxx/__iterator/cpp17_iterator_concepts.h create mode 100644 third_party/libcxx/__iterator/ranges_iterator_traits.h create mode 100644 third_party/libcxx/__locale_dir/locale_base_api.h create mode 100644 third_party/libcxx/__math/abs.h create mode 100644 third_party/libcxx/__math/copysign.h create mode 100644 third_party/libcxx/__math/error_functions.h create mode 100644 third_party/libcxx/__math/exponential_functions.h create mode 100644 third_party/libcxx/__math/fdim.h create mode 100644 third_party/libcxx/__math/fma.h create mode 100644 third_party/libcxx/__math/gamma.h create mode 100644 third_party/libcxx/__math/hyperbolic_functions.h create mode 100644 third_party/libcxx/__math/hypot.h create mode 100644 third_party/libcxx/__math/inverse_hyperbolic_functions.h create mode 100644 third_party/libcxx/__math/inverse_trigonometric_functions.h create mode 100644 third_party/libcxx/__math/logarithms.h create mode 100644 third_party/libcxx/__math/min_max.h create mode 100644 third_party/libcxx/__math/modulo.h create mode 100644 third_party/libcxx/__math/remainder.h create mode 100644 third_party/libcxx/__math/roots.h create mode 100644 third_party/libcxx/__math/rounding_functions.h create mode 100644 third_party/libcxx/__math/special_functions.h create mode 100644 third_party/libcxx/__math/traits.h create mode 100644 third_party/libcxx/__math/trigonometric_functions.h create mode 100644 third_party/libcxx/__mdspan/default_accessor.h create mode 100644 third_party/libcxx/__mdspan/layout_left.h create mode 100644 third_party/libcxx/__mdspan/layout_right.h create mode 100644 third_party/libcxx/__mdspan/layout_stride.h create mode 100644 third_party/libcxx/__mdspan/mdspan.h create mode 100644 third_party/libcxx/__memory/inout_ptr.h create mode 100644 third_party/libcxx/__memory/out_ptr.h create mode 100644 third_party/libcxx/__mutex/once_flag.h create mode 100644 third_party/libcxx/__numeric/pstl.h create mode 100644 third_party/libcxx/__numeric/saturation_arithmetic.h create mode 100644 third_party/libcxx/__ostream/basic_ostream.h create mode 100644 third_party/libcxx/__ostream/print.h create mode 100644 third_party/libcxx/__pstl/backend.h create mode 100644 third_party/libcxx/__pstl/backend_fwd.h create mode 100644 third_party/libcxx/__pstl/backends/default.h create mode 100644 third_party/libcxx/__pstl/backends/libdispatch.h create mode 100644 third_party/libcxx/__pstl/backends/serial.h create mode 100644 third_party/libcxx/__pstl/backends/std_thread.h create mode 100644 third_party/libcxx/__pstl/cpu_algos/any_of.h create mode 100644 third_party/libcxx/__pstl/cpu_algos/cpu_traits.h create mode 100644 third_party/libcxx/__pstl/cpu_algos/fill.h create mode 100644 third_party/libcxx/__pstl/cpu_algos/find_if.h create mode 100644 third_party/libcxx/__pstl/cpu_algos/for_each.h create mode 100644 third_party/libcxx/__pstl/cpu_algos/merge.h create mode 100644 third_party/libcxx/__pstl/cpu_algos/stable_sort.h create mode 100644 third_party/libcxx/__pstl/cpu_algos/transform.h create mode 100644 third_party/libcxx/__pstl/cpu_algos/transform_reduce.h create mode 100644 third_party/libcxx/__pstl/dispatch.h create mode 100644 third_party/libcxx/__pstl/handle_exception.h delete mode 100644 third_party/libcxx/__pstl/internal/algorithm_fwd.h delete mode 100644 third_party/libcxx/__pstl/internal/algorithm_impl.h delete mode 100644 third_party/libcxx/__pstl/internal/execution_defs.h delete mode 100644 third_party/libcxx/__pstl/internal/execution_impl.h delete mode 100644 third_party/libcxx/__pstl/internal/glue_algorithm_defs.h delete mode 100644 third_party/libcxx/__pstl/internal/glue_algorithm_impl.h delete mode 100644 third_party/libcxx/__pstl/internal/glue_memory_defs.h delete mode 100644 third_party/libcxx/__pstl/internal/glue_memory_impl.h delete mode 100644 third_party/libcxx/__pstl/internal/glue_numeric_defs.h delete mode 100644 third_party/libcxx/__pstl/internal/glue_numeric_impl.h delete mode 100644 third_party/libcxx/__pstl/internal/memory_impl.h delete mode 100644 third_party/libcxx/__pstl/internal/numeric_fwd.h delete mode 100644 third_party/libcxx/__pstl/internal/numeric_impl.h delete mode 100644 third_party/libcxx/__pstl/internal/omp/parallel_for.h delete mode 100644 third_party/libcxx/__pstl/internal/omp/parallel_for_each.h delete mode 100644 third_party/libcxx/__pstl/internal/omp/parallel_invoke.h delete mode 100644 third_party/libcxx/__pstl/internal/omp/parallel_merge.h delete mode 100644 third_party/libcxx/__pstl/internal/omp/parallel_reduce.h delete mode 100644 third_party/libcxx/__pstl/internal/omp/parallel_scan.h delete mode 100644 third_party/libcxx/__pstl/internal/omp/parallel_stable_partial_sort.h delete mode 100644 third_party/libcxx/__pstl/internal/omp/parallel_stable_sort.h delete mode 100644 third_party/libcxx/__pstl/internal/omp/parallel_transform_reduce.h delete mode 100644 third_party/libcxx/__pstl/internal/omp/parallel_transform_scan.h delete mode 100644 third_party/libcxx/__pstl/internal/omp/util.h delete mode 100644 third_party/libcxx/__pstl/internal/parallel_backend.h delete mode 100644 third_party/libcxx/__pstl/internal/parallel_backend_omp.h delete mode 100644 third_party/libcxx/__pstl/internal/parallel_backend_serial.h delete mode 100644 third_party/libcxx/__pstl/internal/parallel_backend_tbb.h delete mode 100644 third_party/libcxx/__pstl/internal/parallel_backend_utils.h delete mode 100644 third_party/libcxx/__pstl/internal/unseq_backend_simd.h delete mode 100644 third_party/libcxx/__pstl/internal/utils.h delete mode 100644 third_party/libcxx/__pstl_config_site delete mode 100644 third_party/libcxx/__pstl_memory create mode 100644 third_party/libcxx/__ranges/chunk_by_view.h delete mode 100644 third_party/libcxx/__ranges/copyable_box.h create mode 100644 third_party/libcxx/__ranges/movable_box.h create mode 100644 third_party/libcxx/__ranges/repeat_view.h create mode 100644 third_party/libcxx/__ranges/to.h create mode 100644 third_party/libcxx/__stop_token/stop_callback.h create mode 100644 third_party/libcxx/__stop_token/stop_source.h create mode 100644 third_party/libcxx/__stop_token/stop_state.h create mode 100644 third_party/libcxx/__stop_token/stop_token.h delete mode 100644 third_party/libcxx/__support/android/locale_bionic.h delete mode 100644 third_party/libcxx/__support/fuchsia/xlocale.h delete mode 100644 third_party/libcxx/__support/ibm/gettod_zos.h delete mode 100644 third_party/libcxx/__support/ibm/locale_mgmt_zos.h delete mode 100644 third_party/libcxx/__support/ibm/nanosleep.h delete mode 100644 third_party/libcxx/__support/ibm/xlocale.h delete mode 100644 third_party/libcxx/__support/musl/xlocale.h delete mode 100644 third_party/libcxx/__support/newlib/xlocale.h delete mode 100644 third_party/libcxx/__support/openbsd/xlocale.h delete mode 100644 third_party/libcxx/__support/win32/locale_win32.h create mode 100644 third_party/libcxx/__thread/formatter.h create mode 100644 third_party/libcxx/__thread/id.h create mode 100644 third_party/libcxx/__thread/jthread.h create mode 100644 third_party/libcxx/__thread/support.h create mode 100644 third_party/libcxx/__thread/support/pthread.h create mode 100644 third_party/libcxx/__thread/this_thread.h create mode 100644 third_party/libcxx/__thread/thread.h delete mode 100644 third_party/libcxx/__threading_support create mode 100644 third_party/libcxx/__tuple/find_index.h rename third_party/libcxx/{__algorithm/pstl_backends/cpu_backends/backend.h => __tuple/ignore.h} (52%) create mode 100644 third_party/libcxx/__tuple/tuple_like_no_subrange.h delete mode 100644 third_party/libcxx/__type_traits/apply_cv.h create mode 100644 third_party/libcxx/__type_traits/datasizeof.h create mode 100644 third_party/libcxx/__type_traits/desugars_to.h delete mode 100644 third_party/libcxx/__type_traits/is_copy_assignable.h delete mode 100644 third_party/libcxx/__type_traits/is_copy_constructible.h delete mode 100644 third_party/libcxx/__type_traits/is_default_constructible.h delete mode 100644 third_party/libcxx/__type_traits/is_member_function_pointer.h delete mode 100644 third_party/libcxx/__type_traits/is_member_object_pointer.h delete mode 100644 third_party/libcxx/__type_traits/is_move_assignable.h delete mode 100644 third_party/libcxx/__type_traits/is_move_constructible.h delete mode 100644 third_party/libcxx/__type_traits/is_nothrow_copy_assignable.h delete mode 100644 third_party/libcxx/__type_traits/is_nothrow_copy_constructible.h delete mode 100644 third_party/libcxx/__type_traits/is_nothrow_default_constructible.h delete mode 100644 third_party/libcxx/__type_traits/is_nothrow_move_assignable.h delete mode 100644 third_party/libcxx/__type_traits/is_nothrow_move_constructible.h delete mode 100644 third_party/libcxx/__type_traits/is_scoped_enum.h delete mode 100644 third_party/libcxx/__type_traits/is_trivially_copy_assignable.h delete mode 100644 third_party/libcxx/__type_traits/is_trivially_copy_constructible.h delete mode 100644 third_party/libcxx/__type_traits/is_trivially_default_constructible.h delete mode 100644 third_party/libcxx/__type_traits/is_trivially_move_assignable.h delete mode 100644 third_party/libcxx/__type_traits/is_trivially_move_constructible.h create mode 100644 third_party/libcxx/__type_traits/is_trivially_relocatable.h rename third_party/libcxx/{__tuple/pair_like.h => __utility/as_lvalue.h} (59%) create mode 100644 third_party/libcxx/__utility/empty.h create mode 100644 third_party/libcxx/__utility/is_pointer_in_range.h create mode 100644 third_party/libcxx/__utility/is_valid_range.h create mode 100644 third_party/libcxx/__utility/no_destroy.h create mode 100644 third_party/libcxx/__utility/private_constructor_tag.h create mode 100644 third_party/libcxx/__utility/small_buffer.h delete mode 100644 third_party/libcxx/__utility/terminate_on_exception.h rename third_party/libcxx/{src => }/algorithm.cpp (93%) rename third_party/libcxx/{src => }/any.cpp (66%) create mode 100644 third_party/libcxx/atomic.cpp create mode 100644 third_party/libcxx/atomic_support.h create mode 100644 third_party/libcxx/barrier.cpp rename third_party/libcxx/{src => }/bind.cpp (66%) create mode 100644 third_party/libcxx/call_once.cpp rename third_party/libcxx/{src => }/charconv.cpp (74%) rename third_party/libcxx/{src => }/chrono.cpp (62%) rename third_party/libcxx/{src => }/chrono_system_time_init.h (100%) create mode 100644 third_party/libcxx/condition_variable.cpp rename third_party/libcxx/{src => }/condition_variable_destructor.cpp (51%) rename third_party/libcxx/{src/include => }/config_elast.h (100%) create mode 100644 third_party/libcxx/error_category.cpp rename third_party/libcxx/{__pstl_algorithm => exception.cpp} (63%) rename third_party/libcxx/{src/support/runtime/exception_libcxxabi.ipp => exception_libcxxabi.h} (70%) create mode 100644 third_party/libcxx/exception_pointer_cxxabi.h rename third_party/libcxx/{__pstl_numeric => expected.cpp} (67%) delete mode 100644 third_party/libcxx/experimental/__memory create mode 100644 third_party/libcxx/experimental/__simd/aligned_tag.h create mode 100644 third_party/libcxx/experimental/__simd/declaration.h create mode 100644 third_party/libcxx/experimental/__simd/reference.h create mode 100644 third_party/libcxx/experimental/__simd/scalar.h create mode 100644 third_party/libcxx/experimental/__simd/simd.h create mode 100644 third_party/libcxx/experimental/__simd/simd_mask.h create mode 100644 third_party/libcxx/experimental/__simd/traits.h create mode 100644 third_party/libcxx/experimental/__simd/utility.h create mode 100644 third_party/libcxx/experimental/__simd/vec_ext.h delete mode 100644 third_party/libcxx/experimental/deque delete mode 100644 third_party/libcxx/experimental/forward_list delete mode 100644 third_party/libcxx/experimental/list delete mode 100644 third_party/libcxx/experimental/map create mode 100644 third_party/libcxx/experimental/memory delete mode 100644 third_party/libcxx/experimental/memory_resource delete mode 100644 third_party/libcxx/experimental/regex delete mode 100644 third_party/libcxx/experimental/set delete mode 100644 third_party/libcxx/experimental/string delete mode 100644 third_party/libcxx/experimental/unordered_map delete mode 100644 third_party/libcxx/experimental/unordered_set delete mode 100644 third_party/libcxx/experimental/vector create mode 100644 third_party/libcxx/ext/hash_map create mode 100644 third_party/libcxx/ext/hash_set create mode 100644 third_party/libcxx/fs/directory_entry.cpp rename third_party/libcxx/{src/filesystem => fs}/directory_iterator.cpp (73%) create mode 100644 third_party/libcxx/fs/error.h create mode 100644 third_party/libcxx/fs/file_descriptor.h create mode 100644 third_party/libcxx/fs/filesystem_clock.cpp create mode 100644 third_party/libcxx/fs/filesystem_error.cpp create mode 100644 third_party/libcxx/fs/format_string.h rename third_party/libcxx/{src/filesystem => fs}/int128_builtins.cpp (79%) create mode 100644 third_party/libcxx/fs/operations.cpp create mode 100644 third_party/libcxx/fs/path.cpp create mode 100644 third_party/libcxx/fs/path_parser.h rename third_party/libcxx/{src/filesystem => fs}/posix_compat.h (60%) create mode 100644 third_party/libcxx/fs/time_utils.h create mode 100644 third_party/libcxx/fstream.cpp rename third_party/libcxx/{src => }/functional.cpp (71%) create mode 100644 third_party/libcxx/future.cpp create mode 100644 third_party/libcxx/hash.cpp create mode 100644 third_party/libcxx/ios.cpp rename third_party/libcxx/{src => }/ios.instantiations.cpp (93%) create mode 100644 third_party/libcxx/iostream.cpp rename third_party/libcxx/{src => }/iostream_init.h (100%) rename third_party/libcxx/{src => }/legacy_pointer_safety.cpp (72%) delete mode 100644 third_party/libcxx/libcxx.imp delete mode 100644 third_party/libcxx/limits.h create mode 100644 third_party/libcxx/locale.cpp create mode 100644 third_party/libcxx/memory.cpp rename third_party/libcxx/{src => }/memory_resource.cpp (95%) rename third_party/libcxx/{src/experimental => }/memory_resource_init_helper.h (100%) delete mode 100644 third_party/libcxx/module.modulemap create mode 100644 third_party/libcxx/mutex.cpp rename third_party/libcxx/{src => }/mutex_destructor.cpp (61%) create mode 100644 third_party/libcxx/new.cpp create mode 100644 third_party/libcxx/new_handler.cpp rename third_party/libcxx/{src/support/runtime/exception_glibcxx.ipp => new_helpers.cpp} (56%) rename third_party/libcxx/{src => }/optional.cpp (78%) create mode 100644 third_party/libcxx/ostream.cpp create mode 100644 third_party/libcxx/overridable_function.h create mode 100644 third_party/libcxx/print create mode 100644 third_party/libcxx/print.cpp create mode 100644 third_party/libcxx/random.cpp create mode 100644 third_party/libcxx/random_shuffle.cpp create mode 100644 third_party/libcxx/refstring.h rename third_party/libcxx/{src => }/regex.cpp (50%) rename third_party/libcxx/{src/include => }/ryu/common.h (93%) rename third_party/libcxx/{src => }/ryu/d2fixed.cpp (98%) rename third_party/libcxx/{src/include => }/ryu/d2fixed.h (100%) rename third_party/libcxx/{src/include => }/ryu/d2fixed_full_table.h (100%) rename third_party/libcxx/{src => }/ryu/d2s.cpp (98%) rename third_party/libcxx/{src/include => }/ryu/d2s.h (100%) rename third_party/libcxx/{src/include => }/ryu/d2s_full_table.h (100%) rename third_party/libcxx/{src/include => }/ryu/d2s_intrinsics.h (96%) rename third_party/libcxx/{src/include => }/ryu/digit_table.h (100%) rename third_party/libcxx/{src => }/ryu/f2s.cpp (97%) rename third_party/libcxx/{src/include => }/ryu/f2s.h (100%) rename third_party/libcxx/{src/include => }/ryu/ryu.h (96%) create mode 100644 third_party/libcxx/shared_mutex.cpp delete mode 100644 third_party/libcxx/src/atomic.cpp delete mode 100644 third_party/libcxx/src/barrier.cpp delete mode 100644 third_party/libcxx/src/condition_variable.cpp delete mode 100644 third_party/libcxx/src/debug.cpp delete mode 100644 third_party/libcxx/src/exception.cpp delete mode 100644 third_party/libcxx/src/experimental/memory_resource.cpp delete mode 100644 third_party/libcxx/src/filesystem/filesystem_common.h delete mode 100644 third_party/libcxx/src/filesystem/operations.cpp delete mode 100644 third_party/libcxx/src/future.cpp delete mode 100644 third_party/libcxx/src/hash.cpp delete mode 100644 third_party/libcxx/src/include/apple_availability.h delete mode 100644 third_party/libcxx/src/include/atomic_support.h delete mode 100644 third_party/libcxx/src/include/refstring.h delete mode 100644 third_party/libcxx/src/include/sso_allocator.h delete mode 100644 third_party/libcxx/src/ios.cpp delete mode 100644 third_party/libcxx/src/iostream.cpp delete mode 100644 third_party/libcxx/src/legacy_debug_handler.cpp delete mode 100644 third_party/libcxx/src/locale.cpp delete mode 100644 third_party/libcxx/src/memory.cpp delete mode 100644 third_party/libcxx/src/memory_resource_init_helper.h delete mode 100644 third_party/libcxx/src/mutex.cpp delete mode 100644 third_party/libcxx/src/new.cpp delete mode 100644 third_party/libcxx/src/random.cpp delete mode 100644 third_party/libcxx/src/ryu/README.txt delete mode 100644 third_party/libcxx/src/shared_mutex.cpp delete mode 100644 third_party/libcxx/src/std_stream.h delete mode 100644 third_party/libcxx/src/string.cpp delete mode 100644 third_party/libcxx/src/strstream.cpp delete mode 100644 third_party/libcxx/src/support/ibm/mbsnrtowcs.cpp delete mode 100644 third_party/libcxx/src/support/ibm/wcsnrtombs.cpp delete mode 100644 third_party/libcxx/src/support/ibm/xlocale_zos.cpp delete mode 100644 third_party/libcxx/src/support/runtime/exception_fallback.ipp delete mode 100644 third_party/libcxx/src/support/runtime/exception_libcxxrt.ipp delete mode 100644 third_party/libcxx/src/support/runtime/exception_msvc.ipp delete mode 100644 third_party/libcxx/src/support/runtime/exception_pointer_cxxabi.ipp delete mode 100644 third_party/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp delete mode 100644 third_party/libcxx/src/support/runtime/exception_pointer_msvc.ipp delete mode 100644 third_party/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp delete mode 100644 third_party/libcxx/src/support/runtime/new_handler_fallback.ipp delete mode 100644 third_party/libcxx/src/support/runtime/stdexcept_vcruntime.ipp delete mode 100644 third_party/libcxx/src/support/win32/locale_win32.cpp delete mode 100644 third_party/libcxx/src/support/win32/support.cpp delete mode 100644 third_party/libcxx/src/support/win32/thread_win32.cpp delete mode 100644 third_party/libcxx/src/system_error.cpp delete mode 100644 third_party/libcxx/src/thread.cpp delete mode 100644 third_party/libcxx/src/valarray.cpp create mode 100644 third_party/libcxx/sso_allocator.h create mode 100644 third_party/libcxx/std_stream.h rename third_party/libcxx/{src => }/stdexcept.cpp (56%) rename third_party/libcxx/{src/support/runtime/stdexcept_default.ipp => stdexcept_default.h} (85%) create mode 100644 third_party/libcxx/stop_token create mode 100644 third_party/libcxx/string.cpp create mode 100644 third_party/libcxx/strstream.cpp create mode 100644 third_party/libcxx/syncstream create mode 100644 third_party/libcxx/system_error.cpp create mode 100644 third_party/libcxx/thread.cpp rename third_party/libcxx/{src/include => }/to_chars_floating_point.h (95%) rename third_party/libcxx/{src => }/typeinfo.cpp (68%) create mode 100644 third_party/libcxx/valarray.cpp rename third_party/libcxx/{src => }/variant.cpp (78%) rename third_party/libcxx/{src => }/vector.cpp (79%) rename third_party/libcxx/{src => }/verbose_abort.cpp (95%) diff --git a/Makefile b/Makefile index 69e141e25..485a17687 100644 --- a/Makefile +++ b/Makefile @@ -150,10 +150,10 @@ export MODE export SOURCE_DATE_EPOCH export TMPDIR -COSMOCC = .cosmocc/3.5.7 +COSMOCC = .cosmocc/3.6.0 BOOTSTRAP = $(COSMOCC)/bin TOOLCHAIN = $(COSMOCC)/bin/$(ARCH)-linux-cosmo- -DOWNLOAD := $(shell build/download-cosmocc.sh $(COSMOCC) 3.5.7 596876951b62ad2530c63afc40edd805d751fcb2416e544d249af04ad00bb4ed) +DOWNLOAD := $(shell build/download-cosmocc.sh $(COSMOCC) 3.6.0 4918c45ac3e0972ff260e2a249e25716881e39fb679d5e714ae216a2ef6c3f7e) AS = $(TOOLCHAIN)as CC = $(TOOLCHAIN)gcc @@ -293,8 +293,7 @@ include third_party/openmp/BUILD.mk # β”‚ include third_party/pcre/BUILD.mk # β”‚ include third_party/less/BUILD.mk # β”‚ include net/https/BUILD.mk # β”‚ -include third_party/regex/BUILD.mk # β”‚ -include third_party/bash/BUILD.mk #β”€β”˜ +include third_party/regex/BUILD.mk #β”€β”˜ include third_party/tidy/BUILD.mk include third_party/BUILD.mk include third_party/nsync/testing/BUILD.mk diff --git a/build/definitions.mk b/build/definitions.mk index 000d0a187..774983244 100644 --- a/build/definitions.mk +++ b/build/definitions.mk @@ -139,10 +139,10 @@ DEFAULT_CPPFLAGS += \ -isystem libc/isystem DEFAULT_CFLAGS = \ - -std=gnu2x + -std=gnu23 DEFAULT_CXXFLAGS = \ - -std=gnu++20 \ + -std=gnu++23 \ -fno-rtti \ -fno-exceptions \ -fuse-cxa-atexit \ diff --git a/ctl/string.cc b/ctl/string.cc index 064882178..c30bf699d 100644 --- a/ctl/string.cc +++ b/ctl/string.cc @@ -21,6 +21,9 @@ #include <__atomic/fence.h> #include +#include "libc/mem/mem.h" +#include "libc/str/str.h" + namespace ctl { void diff --git a/examples/unbourne.c b/examples/unbourne.c deleted file mode 100644 index 81f67fea3..000000000 --- a/examples/unbourne.c +++ /dev/null @@ -1,11603 +0,0 @@ -/*bin/echo ' #-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;coding:utf-8 -*-─ -β”‚ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi β”‚ -β•žβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•‘ -β”‚ Copyright 2020 Justine Alexandra Roberts Tunney β”‚ -β”‚ β”‚ -β”‚ Permission to use, copy, modify, and/or distribute this software for β”‚ -β”‚ any purpose with or without fee is hereby granted, provided that the β”‚ -β”‚ above copyright notice and this permission notice appear in all copies. β”‚ -β”‚ β”‚ -β”‚ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL β”‚ -β”‚ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED β”‚ -β”‚ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE β”‚ -β”‚ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL β”‚ -β”‚ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR β”‚ -β”‚ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER β”‚ -β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ -β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ -β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ -β”‚β–ˆβ–ˆβ–ˆβ–’ β–“β–‘β–‘β–‘β–’ β–ˆβ–“β–ˆβ–“ β–’β–’β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–“β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–“β–“β–“β–ˆβ–ˆβ–ˆβ–’β–ˆβ–ˆβ–’β–“β–ˆβ–“β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–“β–ˆβ–ˆβ–“β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–“β–ˆβ–ˆ β–‘ β–‘β–’ β–‘ β”‚ -β”‚β–ˆβ–‘ β–‘ β–ˆβ–‘β–’β–’β–’ β–ˆβ–“β–“β–“ β–’β–“β–ˆβ–ˆβ–ˆβ–ˆβ–“β–‘β–ˆβ–ˆβ–ˆβ–“β–ˆβ–“β–“β–“β–“β–ˆβ–“β–’β–“β–“β–ˆβ–ˆβ–ˆβ–“β–’β–’β–ˆβ–ˆβ–“β–“β–ˆβ–“β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–’β–ˆβ–ˆβ–“β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–“β–ˆβ–ˆ β–‘ β–’β–‘β–‘β–‘ β–‘β”‚ -β”‚β–ˆβ–ˆβ–ˆβ–“ β–’ β–“β–ˆβ–ˆβ–“ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–“β–‘β–ˆβ–“β–“β–ˆβ–“β–ˆβ–ˆβ–‘β–‘β–ˆβ–‘β–ˆβ–ˆβ–ˆβ–ˆβ–“β–ˆβ–“β–ˆβ–ˆβ–’β–ˆβ–ˆβ–’β–“β–“β–“β–ˆβ–“β–“β–ˆβ–“β–ˆβ–’β–ˆβ–ˆβ–“β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–“β–ˆβ–ˆβ–‘β–’ β–“β–‘ β”‚ -β”‚β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–“ β–’β–ˆβ–ˆβ–ˆβ–“β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–“β–“β–ˆβ–“β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–“β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–“β–ˆβ–ˆ β–’β–“β–“β–“β–’β–‘β–’ β–‘β”‚ -β”‚β–ˆβ–ˆβ–ˆβ–“ β–“β–“β–“β–“ β–’β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–“β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–“β–“β–ˆβ–ˆβ–“β–“β–“β–ˆβ–“β–ˆβ–ˆβ–ˆβ–ˆβ–“β–ˆβ–ˆβ–ˆβ–“β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–“β–ˆβ–ˆ β–’β–‘β–“β–’β–‘β–‘ β–‘β”‚ -β”‚β–ˆβ–ˆβ–ˆβ–“ β–ˆβ–’β–“β–’β–’β–‘β–“ β–’β–ˆβ–ˆβ–“β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–“β–ˆβ–ˆβ–“β–“β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–“β–ˆβ–ˆ β–‘β–‘β–’β–’β–“β–“β–’ β–‘β”‚ -β”‚β–ˆβ–ˆβ–ˆβ–“ β–“β–’β–“β–“β–“ β–ˆβ–“β–“ β–’β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–“β–ˆβ–ˆβ–“β–“β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–“β–ˆβ–ˆ β–‘ β–’β–’β–‘β–‘β–“β–“β–‘β”‚ -β”‚β–ˆβ–“β–ˆβ–“ β–ˆβ–’β–‘β–‘β–‘ β–ˆβ–“β–ˆβ–ˆβ–“ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–“β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–“β–“β–‘β–‘β–‘ β–’β–‘ β–‘β–‘ β–’β”‚ -β”‚β–ˆβ–“β–ˆβ–“β–‘β–ˆβ–“β–’β–“β–’ β–ˆβ–ˆβ–“β–ˆβ–“ β–“ β–“β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–’β–ˆβ–ˆβ–“β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–’β–‘β–’β–’β–’β–’β–’β–’β–’ β–‘β”‚ -β”‚β–ˆβ–“β–“β–’β–‘β–“β–“β–’β–“β–“ β–ˆβ–“β–“β–ˆβ–ˆ β–ˆβ–ˆ β–‘ β–‘ β–‘β–‘β–‘β–‘ β–‘β–‘β–‘ β–‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–“β–ˆβ–ˆβ–“β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ β–‘β–’β–“β–“β–’β–“β–“β–‘β–’β–“β–‘β–’β–‘ β”‚ -β”‚β–ˆβ–ˆβ–“β–“β–‘β–“β–’β–’β–“β–’β–‘β–“β–“β–“β–“β–“ β–ˆβ–“β–“β–‘ β–‘ β–‘β–‘ β–‘ β–‘ β–“β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–’β–ˆβ–ˆβ–“β–ˆβ–ˆβ–ˆβ–ˆβ–’β–’β–’β–‘β–‘β–“β–“β–’β–“β–’β–‘β–’β–‘β–‘β–’β–‘ β–‘β”‚ -β”‚β–ˆβ–“β–“β–“β–‘β–ˆβ–’β–’β–’β–’ β–ˆβ–“β–“β–“β–“ β–ˆβ–ˆβ–“β–“ β–‘ β–‘ β–’β–’ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–’β–ˆβ–ˆβ–“β–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–’β–’β–“β–“β–“β–“β–’β–‘β–‘ β–‘ β”‚ -β”‚β–ˆβ–ˆβ–“β–“β–‘β–ˆβ–‘β–’β–’β–’β–‘β–ˆβ–“β–“β–“β–“ β–ˆβ–“β–“β–ˆ β–‘ β–‘ β–‘β–‘β–‘β–‘β–“β–‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–’β–ˆβ–ˆ β–‘β–‘β–‘β–“β–’β–’β–“β–“β–“β–“ β–“β–’β–‘β–’β–’β–’β–’β–‘β–‘ β”‚ -β”‚β–’β–ˆβ–ˆβ–“β–’β–“β–‘β–’β–“β–‘β–‘β–“β–“β–“β–“β–“ β–“β–“β–“β–“ β–‘β–‘ β–’β–‘β–‘β–’β–‘β–‘ β–“β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–’β–ˆβ–ˆβ–‘ β–’ β–’β–‘β–‘β–’β–“β–’β–’β–‘β–’β–’β–“β–’ β–‘ β”‚ -β”‚β–’β–“β–“β–“β–’β–ˆβ–’β–’β–’β–’β–‘β–ˆβ–’β–’β–“β–“ β–“β–“β–ˆβ–“β–“β–“β–“β–“ β–‘β–’ β–‘ β–’ β–‘β–“β–“β–“β–‘β–‘β–‘ β–ˆβ–’ β–“ β–ˆβ–ˆβ–“β–ˆβ–ˆβ–ˆβ–’β–“β–‘β–“β–“β–’β–‘β–“β–‘β–‘β–‘β–‘β–’β–’β–‘β–‘β–‘ β–‘β”‚ -β”‚β–’β–ˆβ–’β–“β–‘β–“β–“β–‘β–“β–“β–‘β–“β–’β–“β–’β–’ β–ˆβ–“β–ˆβ–ˆβ–ˆβ–ˆβ–“β–ˆβ–ˆβ–ˆ β–‘ β–‘β–’β–‘ β–“β–“β–’β–’β–’β–’β–‘β–‘β–“ β–‘ β–‘β–ˆ β–“ β–’β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘ β–“β–“β–’β–’β–‘β–‘β–’β–’β–“β–’β–‘ β–‘β–‘β”‚ -β”‚β–‘β–“β–ˆβ–“β–’β–“β–“β–’β–“β–’β–‘β–ˆβ–“β–’β–“β–“ β–ˆβ–“β–ˆβ–ˆβ–ˆβ–ˆβ–“β–ˆβ–ˆβ–ˆβ–“β–“ β–‘β–’β–’β–’β–“β–“β–’β–’β–“β–“β–’β–‘β–’β–“β–‘ β–’ β–‘β–ˆβ–ˆ β–‘ β–ˆβ–ˆβ–ˆβ–’β–‘β–“β–‘ β–“β–’β–“β–’β–’β–‘ β–‘ β”‚ -β”‚β–‘β–ˆβ–“β–“β–“β–“β–“β–“β–’β–’β–“β–ˆβ–“β–’β–“β–“ β–ˆβ–“β–“β–ˆβ–ˆβ–ˆβ–“β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–“ β–‘β–’β–’β–’β–’β–’β–“β–’β–’β–‘β–‘β–’β–‘β–“ β–‘β–‘β–“β–’ β–’β–‘β–’β–‘ β–‘β–’ β–“β–‘β–“β–“β–‘β–‘ β–“β–“β–‘ β–‘β–‘β–‘β–‘ β–‘β–‘ β”‚ -β”‚ β–ˆβ–ˆβ–‘ β–‘ β–’β–ˆβ–“β–“β–“β–“ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–“β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–“β–‘β–’β–’β–’β–“β–“β–“β–“β–“β–“β–’β–’β–‘β–“β–’β–‘β–“β–’β–’β–’β–’β–“β–“β–“β–‘β–“β–’β–’β–‘β–’β–’β–“β–“β–’β–’β–‘β–’ β–‘ β–‘ β–‘β–‘β”‚ -β”‚ β–‘β–‘β–‘β–’ β–“β–“β–“β–“ β–ˆβ–“β–“β–ˆβ–“β–ˆβ–“β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–“β–‘β–’β–“β–’β–“β–“β–ˆβ–’β–‘β–’β–“β–“β–“β–’β–’β–“β–“β–’β–“β–“β–’β–ˆβ–‘β–’β–“β–’β–’ β–‘β–“β–’β–“ β–’β–’β–‘β–’β–‘ β–’ β–‘β–‘β–‘ β”‚ -β”‚ β–’β–‘β–‘ β–‘ β–“ β–‘β–“β–“β–“β–“ β–ˆβ–ˆβ–ˆβ–ˆβ–“β–ˆβ–“β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–’β–“β–’β–ˆβ–‘β–‘β–“β–’β–“ β–’β–“β–“β–‘β–’β–’β–“β–’β–’β–“β–’β–“β–’β–’β–“β–’β–“β–“β–ˆβ–“β–“ β–“β–‘β–’ β–‘β–‘β–‘β–‘β–‘ β–‘ β”‚ -β”‚ β–‘β–“ β–’β–‘β–‘β–‘β–‘ β–“β–ˆβ–“β–“β–“ β–ˆβ–“β–’β–ˆβ–ˆβ–ˆβ–“β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–“β–‘β–‘β–’β–’β–“β–’β–“β–’β–’β–“β–“β–’β–“β–“ β–“β–’β–“β–“β–’β–“β–’β–“β–’β–“β–“β–’β–“β–“ β–“β–’β–’β–‘β–’ β–“β–’ β–‘ β”‚ -β”‚ β–’β–‘ β–‘ β–‘β–‘ β–“β–’β–‘β–‘β–‘ β–ˆβ–“β–“β–ˆβ–ˆβ–“β–“β–ˆβ–ˆβ–ˆβ–ˆβ–“β–“β–“β–ˆβ–“β–‘β–‘β–’β–“β–“β–“β–’β–’β–“β–‘β–“β–“β–“β–’β–“β–’β–’β–’β–“β–’β–“β–“β–“β–“β–’β–’β–’β–’β–’β–‘β–’β–’β–’β–‘β–ˆβ–ˆ β”‚ -β”‚β–’ β–’β–’ β–’β–‘β–‘β–‘ β–“β–“β–“β–“β–’ β–“β–“β–“β–ˆβ–ˆβ–ˆβ–’β–ˆβ–ˆβ–ˆβ–“β–ˆβ–ˆβ–ˆβ–“β–“β–’β–’β–‘β–‘β–’β–’β–’β–’β–‘β–’β–’β–’β–’β–’β–“β–“β–’β–’β–‘β–“β–“β–“β–’β–“β–‘β–“β–“β–“β–’β–’β–’β–“β–‘β–“β–“β–“ β–‘ β–‘ β”‚ -β”‚β–’ β–‘ β–“ β–“β–“β–“β–“β–’ β–“β–’β–“β–“β–“β–ˆβ–’β–ˆβ–ˆβ–ˆβ–“β–“β–“β–ˆβ–’β–’β–“β–“β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–“β–’β–“β–‘β–’β–“β–‘β–“β–’β–“β–’β–“β–“β–’β–’β–’β–“β–‘β–’β–’β–‘ β–‘β–’β–“β–’β–‘ β”‚ -β”‚β–“ β–‘β–‘ β–‘ β–ˆ β–“β–“β–“β–“β–“ β–“β–“β–“β–ˆβ–“β–“β–“β–ˆβ–ˆβ–ˆβ–“β–ˆβ–“β–ˆβ–“β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–“β–“β–“β–“β–’β–“β–“β–“β–“β–’β–’β–“β–’β–’β–’ β–“β–“ β–“β–‘ β–‘β–“ β–‘ β”‚ -β”‚β–“ β–‘ β–‘ β–’β–“β–“β–“β–’β–’ β–“β–“β–“β–ˆβ–“β–ˆβ–’β–ˆβ–ˆβ–“β–“β–“β–ˆβ–“β–ˆβ–“β–ˆβ–“β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–“β–’β–’β–“β–“β–“β–’β–“β–“β–“β–’ β–’β–“ β–’ β–‘β–’β–“β–“β–“β–ˆ β–‘ β”‚ -β”‚β–“β–’β–‘β–‘β–’β–’β–‘β–’ β–‘β–‘β–“β–“β–“β–“β–“ β–“β–“β–“β–ˆβ–ˆβ–ˆβ–“β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–“β–’β–‘β–“β–’β–’β–’β–’β–’β–’β–“β–“β–‘ β–‘β–’β–’β–‘β–‘ β”‚ -β”‚β–“ β–‘β–“β–’β–’ β–‘β–‘β–’β–“β–’ β–‘β–“β–“β–ˆβ–“β–ˆβ–“β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–’β–‘β–‘ β–‘ β–‘ β–‘β–’β–‘ β–‘ β–‘ β–‘β–“β–’ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - unbourne is a gnu/systemd init process Β»cosmopolitanΒ» - - -╔────────────────────────────────────────────────────────────────────────────│─╗ -β”‚ cosmopolitan Β§ the unbourne shell ─╬─│┼ -β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”‚β”€β• - - The UNBOURNE SHELL is BASED off the Almquist Shell──colloquially - known as the Debian Almquist Shell, a.k.a. dash──which perfected - the work of the late Stephen Bourne whose shell set the standard - for decades thanks to a spark of brilliance from Ken Thompson. - - git://git.kernel.org/pub/scm/utils/dash/dash.git - 057cd650a4edd5856213d431a974ff35c6594489 - Fri Sep 03 15:00:58 2021 +0800 - - The UNBOURNE SHELL pays HOMAGE to the Stewards of House California: - - Almquist Shell - Derived from software contributed to Berkeley by Kenneth Almquist. - - Copyright 1991,1993 The Regents of the University of California - Copyright 1997-2021 Herbert Xu - Copyright 1997 Christos Zoulas - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. Neither the name of the University nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - SUCH DAMAGE. - - -╔──────────────────────────────────────────────────────────────────────┬───┬───╗ -β”‚ cosmopolitan Β§ the unbourne shell Β» build / / β”‚ -β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€'>/dev/null - - cc -Os -o unbourne unbourne.c - exit - -╔────────────────────────────────────────────────────────────────────────────│─╗ -β”‚ cosmopolitan Β§ the unbourne shell Β» macros ─╬─│┼ -β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”‚*/ - -#include "libc/assert.h" -#include "libc/calls/calls.h" -#include "libc/calls/struct/dirent.h" -#include "libc/calls/struct/rlimit.h" -#include "libc/calls/struct/rusage.h" -#include "libc/calls/struct/sigaction.h" -#include "libc/calls/struct/stat.h" -#include "libc/calls/struct/tms.h" -#include "libc/calls/termios.h" -#include "libc/ctype.h" -#include "libc/dce.h" -#include "libc/errno.h" -#include "libc/fmt/conv.h" -#include "libc/intrin/safemacros.h" -#include "libc/limits.h" -#include "libc/log/log.h" -#include "libc/macros.internal.h" -#include "libc/mem/alg.h" -#include "libc/mem/alloca.h" -#include "libc/mem/gc.h" -#include "libc/mem/mem.h" -#include "libc/paths.h" -#include "libc/runtime/runtime.h" -#include "libc/runtime/sysconf.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/at.h" -#include "libc/sysv/consts/dt.h" -#include "libc/sysv/consts/f.h" -#include "libc/sysv/consts/fd.h" -#include "libc/sysv/consts/fileno.h" -#include "libc/sysv/consts/o.h" -#include "libc/sysv/consts/ok.h" -#include "libc/sysv/consts/rlim.h" -#include "libc/sysv/consts/s.h" -#include "libc/sysv/consts/sig.h" -#include "libc/sysv/consts/w.h" -#include "third_party/gdtoa/gdtoa.h" -#include "third_party/linenoise/linenoise.h" -#include "third_party/musl/passwd.h" - -#define likely(expr) __builtin_expect(!!(expr), 1) -#define unlikely(expr) __builtin_expect(!!(expr), 0) - -#undef CEOF -#undef rflag - -/* - * The follow should be set to reflect the type of system you have: - * JOBS -> 1 if you have Berkeley job control, 0 otherwise. - * SHORTNAMES -> 1 if your linker cannot handle long names. - * define BSD if you are running 4.2 BSD or later. - * define SYSV if you are running under System V. - * define DEBUG=1 to compile in debugging ('set -o debug' to turn on) - * define DEBUG=2 to compile in and turn on debugging. - * define DO_SHAREDVFORK to indicate that vfork(2) shares its address - * with its parent. - * - * When debugging is on, debugging info will be written to ./trace and - * a quit signal will generate a core dump. - */ - -#define ALIASDEAD 2 -#define ALIASINUSE 1 -#define ARITH_MAX_PREC 8 -#define ATABSIZE 39 -#define CMDTABLESIZE 31 -#define JOBS 1 -#define NOPTS 17 -#define OUTPUT_ERR 01 -#define VTABSIZE 39 - -/* exceptions */ -#define EXINT 0 -#define EXERROR 1 -#define EXEND 3 -#define EXEXIT 4 - -/* - * The input line number. Input.c just defines this variable, and saves - * and restores it when files are pushed and popped. The user of this - * package must set its value. - */ -#define plinno (parsefile->linno) - -/* Syntax classes */ -#define CWORD 0 -#define CNL 1 -#define CBACK 2 -#define CSQUOTE 3 -#define CDQUOTE 4 -#define CENDQUOTE 5 -#define CBQUOTE 6 -#define CVAR 7 -#define CENDVAR 8 -#define CLP 9 -#define CRP 10 -#define CEOF 11 -#define CCTL 12 -#define CSPCL 13 - -/* Syntax classes for is_ functions */ -#define ISDIGIT 01 -#define ISUPPER 02 -#define ISLOWER 04 -#define ISUNDER 010 -#define ISSPECL 020 - -#define SYNBASE 129 -#define PEOF -129 - -#define EOF_NLEFT -99 - -#define BASESYNTAX (basesyntax + SYNBASE) -#define DQSYNTAX (dqsyntax + SYNBASE) -#define SQSYNTAX (sqsyntax + SYNBASE) -#define ARISYNTAX (arisyntax + SYNBASE) - -#define ARITH_ASS 1 -#define ARITH_OR 2 -#define ARITH_AND 3 -#define ARITH_BAD 4 -#define ARITH_NUM 5 -#define ARITH_VAR 6 -#define ARITH_NOT 7 -#define ARITH_BINOP_MIN 8 -#define ARITH_LE 8 -#define ARITH_GE 9 -#define ARITH_LT 10 -#define ARITH_GT 11 -#define ARITH_EQ 12 -#define ARITH_REM 13 -#define ARITH_BAND 14 -#define ARITH_LSHIFT 15 -#define ARITH_RSHIFT 16 -#define ARITH_MUL 17 -#define ARITH_ADD 18 -#define ARITH_BOR 19 -#define ARITH_SUB 20 -#define ARITH_BXOR 21 -#define ARITH_DIV 22 -#define ARITH_NE 23 -#define ARITH_BINOP_MAX 24 -#define ARITH_ASS_MIN 24 -#define ARITH_REMASS 24 -#define ARITH_BANDASS 25 -#define ARITH_LSHIFTASS 26 -#define ARITH_RSHIFTASS 27 -#define ARITH_MULASS 28 -#define ARITH_ADDASS 29 -#define ARITH_BORASS 30 -#define ARITH_SUBASS 31 -#define ARITH_BXORASS 32 -#define ARITH_DIVASS 33 -#define ARITH_ASS_MAX 34 -#define ARITH_LPAREN 34 -#define ARITH_RPAREN 35 -#define ARITH_BNOT 36 -#define ARITH_QMARK 37 -#define ARITH_COLON 38 - -/* expandarg() flags */ -#define EXP_FULL 0x1 -#define EXP_TILDE 0x2 -#define EXP_VARTILDE 0x4 -#define EXP_REDIR 0x8 -#define EXP_CASE 0x10 -#define EXP_VARTILDE2 0x40 -#define EXP_WORD 0x80 -#define EXP_QUOTED 0x100 -#define EXP_KEEPNUL 0x200 -#define EXP_DISCARD 0x400 - -/* reasons for skipping commands (see comment on breakcmd routine) */ -#define SKIPBREAK (1 << 0) -#define SKIPCONT (1 << 1) -#define SKIPFUNC (1 << 2) -#define SKIPFUNCDEF (1 << 3) - -#define TEOF 0 -#define TNL 1 -#define TSEMI 2 -#define TBACKGND 3 -#define TAND 4 -#define TOR 5 -#define TPIPE 6 -#define TLP 7 -#define TRP 8 -#define TENDCASE 9 -#define TENDBQUOTE 10 -#define TREDIR 11 -#define TWORD 12 -#define TNOT 13 -#define TCASE 14 -#define TDO 15 -#define TDONE 16 -#define TELIF 17 -#define TELSE 18 -#define TESAC 19 -#define TFI 20 -#define TFOR 21 -#define TIF 22 -#define TIN 23 -#define TTHEN 24 -#define TUNTIL 25 -#define TWHILE 26 -#define TBEGIN 27 -#define TEND 28 - -/* control characters in argument strings */ -#define CTL_FIRST -127 -#define CTLESC -127 -#define CTLVAR -126 -#define CTLENDVAR -125 -#define CTLBACKQ -124 -#define CTLARI -122 -#define CTLENDARI -121 -#define CTLQUOTEMARK -120 -#define CTL_LAST -120 - -/* variable substitution byte (follows CTLVAR) */ -#define VSTYPE 0x0f -#define VSNUL 0x10 - -/* values of VSTYPE field */ -#define VSNORMAL 0x1 -#define VSMINUS 0x2 -#define VSPLUS 0x3 -#define VSQUESTION 0x4 -#define VSASSIGN 0x5 -#define VSTRIMRIGHT 0x6 -#define VSTRIMRIGHTMAX 0x7 -#define VSTRIMLEFT 0x8 -#define VSTRIMLEFTMAX 0x9 -#define VSLENGTH 0xa -/* VSLENGTH must come last. */ - -/* values of checkkwd variable */ -#define CHKALIAS 0x1 -#define CHKKWD 0x2 -#define CHKNL 0x4 -#define CHKEOFMARK 0x8 - -/* flags in argument to evaltree */ -#define EV_EXIT 01 -#define EV_TESTED 02 - -#define INT_CHARS (sizeof(int) * CHAR_BIT / 3) - -/* - * These macros allow the user to suspend the handling of interrupt - * signals over a period of time. This is similar to SIGHOLD to or - * sigblock, but much more efficient and portable. (But hacking the - * kernel is so much more fun than worrying about efficiency and - * portability. :-)) - */ -#define barrier() ({ asm volatile("" : : : "memory"); }) -#define INTOFF \ - ({ \ - suppressint++; \ - barrier(); \ - 0; \ - }) -#define INTON \ - ({ \ - barrier(); \ - if (--suppressint == 0 && intpending) \ - onint(); \ - 0; \ - }) -#define FORCEINTON \ - ({ \ - barrier(); \ - suppressint = 0; \ - if (intpending) \ - onint(); \ - 0; \ - }) -#define SAVEINT(v) ((v) = suppressint) -#define RESTOREINT(v) \ - ({ \ - barrier(); \ - if ((suppressint = (v)) == 0 && intpending) \ - onint(); \ - 0; \ - }) -#define CLEAR_PENDING_INT intpending = 0 -#define int_pending() intpending - -/* - * Most machines require the value returned from malloc to be aligned - * in some way. The following macro will get this right on many machines. - */ -#define SHELL_SIZE \ - (sizeof(union { \ - int i; \ - char *cp; \ - double d; \ - }) - \ - 1) - -/* - * It appears that grabstackstr() will barf with such alignments - * because stalloc() will return a string allocated in a new stackblock. - */ -#define SHELL_ALIGN(nbytes) (((nbytes) + SHELL_SIZE) & ~SHELL_SIZE) - -/* - * Minimum size of a block - * - * Parse trees for commands are allocated in lifo order, so we use a stack - * to make this more efficient, and also to avoid all sorts of exception - * handling code to handle interrupts in the middle of a parse. - * - * The size 504 was chosen because the Ultrix malloc handles that size - * well. - */ -#define MINSIZE SHELL_ALIGN(504) - -/* flags */ -#define VEXPORT 0x001 -#define VREADONLY 0x002 -#define VSTRFIXED 0x004 -#define VTEXTFIXED 0x008 -#define VSTACK 0x010 -#define VUNSET 0x020 -#define VNOFUNC 0x040 -#define VNOSET 0x080 -#define VNOSAVE 0x100 - -/* - * Evaluate a command. - */ -#define ALIASCMD (kBuiltinCmds + 3) -#define BGCMD (kBuiltinCmds + 4) -#define BREAKCMD (kBuiltinCmds + 5) -#define CDCMD (kBuiltinCmds + 6) -#define COMMANDCMD (kBuiltinCmds + 8) -#define DOTCMD (kBuiltinCmds + 0) -#define ECHOCMD (kBuiltinCmds + 10) -#define EVALCMD (kBuiltinCmds + 11) -#define EXECCMD (kBuiltinCmds + 12) -#define EXITCMD (kBuiltinCmds + 13) -#define EXPORTCMD (kBuiltinCmds + 14) -#define FALSECMD (kBuiltinCmds + 15) -#define FGCMD (kBuiltinCmds + 16) -#define GETOPTSCMD (kBuiltinCmds + 17) -#define HASHCMD (kBuiltinCmds + 18) -#define JOBSCMD (kBuiltinCmds + 19) -#define KILLCMD (kBuiltinCmds + 20) -#define LOCALCMD (kBuiltinCmds + 21) -#define PRINTFCMD (kBuiltinCmds + 22) -#define PWDCMD (kBuiltinCmds + 23) -#define READCMD (kBuiltinCmds + 24) -#define RETURNCMD (kBuiltinCmds + 26) -#define SETCMD (kBuiltinCmds + 27) -#define SHIFTCMD (kBuiltinCmds + 28) -#define TESTCMD (kBuiltinCmds + 2) -#define TIMESCMD (kBuiltinCmds + 30) -#define TRAPCMD (kBuiltinCmds + 31) -#define TRUECMD (kBuiltinCmds + 1) -#define TYPECMD (kBuiltinCmds + 33) -#define ULIMITCMD (kBuiltinCmds + 34) -#define UMASKCMD (kBuiltinCmds + 35) -#define UNALIASCMD (kBuiltinCmds + 36) -#define UNSETCMD (kBuiltinCmds + 37) -#define WAITCMD (kBuiltinCmds + 38) - -#define BUILTIN_SPECIAL 0x1 -#define BUILTIN_REGULAR 0x2 -#define BUILTIN_ASSIGN 0x4 - -/* mode flags for set_curjob */ -#define CUR_DELETE 2 -#define CUR_RUNNING 1 -#define CUR_STOPPED 0 - -/* mode flags for dowait */ -#define DOWAIT_NONBLOCK 0 -#define DOWAIT_BLOCK 1 -#define DOWAIT_WAITCMD 2 -#define DOWAIT_WAITCMD_ALL 4 - -/* _rmescape() flags */ -#define RMESCAPE_ALLOC 0x01 -#define RMESCAPE_GLOB 0x02 -#define RMESCAPE_GROW 0x08 -#define RMESCAPE_HEAP 0x10 - -/* Add CTLESC when necessary. */ -#define QUOTES_ESC (EXP_FULL | EXP_CASE) - -#define IBUFSIZ (BUFSIZ + 1) -#define OUTBUFSIZ BUFSIZ -#define MEM_OUT -3 - -/* - * Sigmode records the current value of the signal handlers for the - * various modes. A value of zero means that the current handler is not - * known. S_HARD_IGN indicates that the signal was ignored on entry to - * the shell, - */ -#define S_DFL 1 -#define S_CATCH 2 -#define S_IGN 3 -#define S_HARD_IGN 4 -#define S_RESET 5 - -#define NCMD 0 -#define NPIPE 1 -#define NREDIR 2 -#define NBACKGND 3 -#define NSUBSHELL 4 -#define NAND 5 -#define NOR 6 -#define NSEMI 7 -#define NIF 8 -#define NWHILE 9 -#define NUNTIL 10 -#define NFOR 11 -#define NCASE 12 -#define NCLIST 13 -#define NDEFUN 14 -#define NARG 15 -#define NTO 16 -#define NCLOBBER 17 -#define NFROM 18 -#define NFROMTO 19 -#define NAPPEND 20 -#define NTOFD 21 -#define NFROMFD 22 -#define NHERE 23 -#define NXHERE 24 -#define NNOT 25 - -/* Mode argument to forkshell. Don't change FORK_FG or FORK_BG. */ -#define FORK_FG 0 -#define FORK_BG 1 -#define FORK_NOJOB 2 - -/* mode flags for showjob(s) */ -#define SHOW_PGID 0x01 -#define SHOW_PID 0x04 -#define SHOW_CHANGED 0x08 - -/* values of cmdtype */ -#define CMDUNKNOWN -1 -#define CMDNORMAL 0 -#define CMDFUNCTION 1 -#define CMDBUILTIN 2 - -/* action to find_command() */ -#define DO_ERR 0x01 -#define DO_ABS 0x02 -#define DO_NOFUNC 0x04 -#define DO_ALTPATH 0x08 -#define DO_REGBLTIN 0x10 - -/* flags passed to redirect */ -#define REDIR_PUSH 01 -#define REDIR_SAVEFD2 03 - -#define CD_PHYSICAL 1 -#define CD_PRINT 2 - -#define EMPTY -2 -#define CLOSED -1 -#define PIPESIZE 4096 - -#define rootshell (!shlvl) - -#define eflag optlist[0] -#define fflag optlist[1] -#define Iflag optlist[2] -#define iflag optlist[3] -#define mflag optlist[4] -#define nflag optlist[5] -#define sflag optlist[6] -#define xflag optlist[7] -#define vflag optlist[8] -#define Vflag optlist[9] -#define Eflag optlist[10] -#define Cflag optlist[11] -#define aflag optlist[12] -#define bflag optlist[13] -#define uflag optlist[14] -#define nolog optlist[15] -#define debug optlist[16] - -/* Used by expandstr to get here-doc like behaviour. */ -#define FAKEEOFMARK (char *)1 - -/* - * This file is included by programs which are optionally built into the - * shell. If SHELL is defined, we try to map the standard UNIX library - * routines to ash routines using defines. - */ -#define Printf out1fmt -#define INITARGS(argv) -#define setprogname(s) -#define getprogname() commandname - -#define setlocate(l, s) 0 -#define equal(s1, s2) (!strcmp(s1, s2)) -#define isodigit(c) ((c) >= '0' && (c) <= '7') -#define octtobin(c) ((c) - '0') -#define scopy(s1, s2) ((void)strcpy(s2, s1)) - -#define TRACE(param) -/* #define TRACE(param) \ */ -/* do { \ */ -/* printf("TRACE: "); \ */ -/* printf param; \ */ -/* } while (0) */ - -#define TRACEV(param) -#define digit_val(c) ((c) - '0') -#define is_alpha(c) isalpha((unsigned char)(c)) -#define is_digit(c) ((unsigned)((c) - '0') <= 9) -#define is_in_name(c) ((c) == '_' || isalnum((unsigned char)(c))) -#define is_name(c) ((c) == '_' || isalpha((unsigned char)(c))) -#define is_special(c) \ - ((is_type + SYNBASE)[(signed char)(c)] & (ISSPECL | ISDIGIT)) - -#define uninitialized_var(x) \ - x = x /* suppress uninitialized warning w/o code \ - */ - -/* - * Shell variables. - */ -#define vifs varinit[0] -#define vpath (&vifs)[1] -#define vps1 (&vpath)[1] -#define vps2 (&vps1)[1] -#define vps4 (&vps2)[1] -#define voptind (&vps4)[1] -#define vlineno (&voptind)[1] -#define defifs (defifsvar + 4) -#define defpath (defpathvar + 36) - -/* - * The following macros access the values of the above variables. They - * have to skip over the name. They return the null string for unset - * variables. - */ -#define ifsval() (vifs.text + 4) -#define ifsset() ((vifs.flags & VUNSET) == 0) -#define mailval() (vmail.text + 5) -#define mpathval() (vmpath.text + 9) -#define pathval() (vpath.text + 5) -#define ps1val() (vps1.text + 4) -#define ps2val() (vps2.text + 4) -#define ps4val() (vps4.text + 4) -#define optindval() (voptind.text + 7) -#define linenoval() (vlineno.text + 7) -#define mpathset() ((vmpath.flags & VUNSET) == 0) -#define environment() listvars(VEXPORT, VUNSET, 0) - -/*───────────────────────────────────────────────────────────────────────────│─╗ -β”‚ cosmopolitan Β§ the unbourne shell Β» data structures ─╬─│┼ -β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”‚*/ - -typedef void *pointer; - -struct redirtab { - struct redirtab *next; - int renamed[10]; -}; - -/* - * We enclose jmp_buf in a structure so that we can declare pointers to - * jump locations. The global variable handler contains the location to - * jump to when an exception occurs, and the global variable exception - * contains a code identifying the exception. To implement nested - * exception handlers, the user should save the value of handler on - * entry to an inner scope, set handler to point to a jmploc structure - * for the inner scope, and restore handler on exit from the scope. - */ -struct jmploc { - jmp_buf loc; -}; - -/* PEOF (the end of file marker) is defined in syntax.h */ -enum { - INPUT_PUSH_FILE = 1, - INPUT_NOFILE_OK = 2, -}; - -struct alias { - struct alias *next; - char *name; - char *val; - int flag; -}; - -struct shparam { - int nparam; /* # of positional parameters (without $0) */ - unsigned char malloc; /* if parameter list dynamically allocated */ - char **p; /* parameter list */ - int optind; /* next parameter to be processed by getopts */ - int optoff; /* used by getopts */ -}; - -struct strpush { - struct strpush *prev; /* preceding string on stack */ - char *prevstring; - int prevnleft; - struct alias *ap; /* if push was associated with an alias */ - char *string; /* remember the string since it may change */ - struct strpush *spfree; /* Delay freeing so we can stop nested aliases. */ - int lastc[2]; /* Remember last two characters for pungetc. */ - int unget; /* Number of outstanding calls to pungetc. */ -}; - -/* - * The parsefile structure pointed to by the global variable parsefile - * contains information about the current file being read. - */ -struct parsefile { - struct parsefile *prev; /* preceding file on stack */ - int linno; /* current line */ - int fd; /* file descriptor (or -1 if string) */ - int nleft; /* number of chars left in this line */ - int lleft; /* number of chars left in this buffer */ - char *nextc; /* next char in buffer */ - char *buf; /* input buffer */ - struct strpush *strpush; /* for pushing strings at this level */ - struct strpush basestrpush; /* so pushing one is fast */ - struct strpush *spfree; /* Delay freeing so we can stop nested aliases. */ - int lastc[2]; /* Remember last two characters for pungetc. */ - int unget; /* Number of outstanding calls to pungetc. */ -}; - -struct output { - char *nextc; - char *end; - char *buf; - unsigned bufsize; - int fd; - int flags; -}; - -struct heredoc { - struct heredoc *next; /* next here document in list */ - union node *here; /* redirection node */ - char *eofmark; /* string indicating end of input */ - int striptabs; /* if set, strip leading tabs */ -}; - -struct synstack { - const char *syntax; - struct synstack *prev; - struct synstack *next; - int innerdq; - int varpushed; - int dblquote; - int varnest; /* levels of variables expansion */ - int parenlevel; /* levels of parens in arithmetic */ - int dqvarnest; /* levels of variables expansion within double quotes */ -}; - -struct procstat { - int pid; /* process id */ - int status; /* last process status from wait() */ - char *cmd; /* text of command being run */ -}; - -/* - * A job structure contains information about a job. A job is either a - * single process or a set of processes contained in a pipeline. In the - * latter case, pidlist will be non-NULL, and will point to a -1 terminated - * array of pids. - */ -struct job { - struct procstat ps0; /* status of process */ - struct procstat *ps; /* status or processes when more than one */ - int stopstatus; /* status of a stopped job */ - unsigned nprocs : 16, /* number of processes */ - state : 8, -#define JOBRUNNING 0 -#define JOBSTOPPED 1 -#define JOBDONE 2 - sigint : 1, /* job was killed by SIGINT */ - jobctl : 1, /* job running under job control */ - waited : 1, /* true if this entry has been waited for */ - used : 1, /* true if this entry is in used */ - changed : 1; /* true if status has changed */ - struct job *prev_job; /* previous job */ -}; - -struct ncmd { - int type; - int linno; - union node *assign; - union node *args; - union node *redirect; -}; - -struct npipe { - int type; - int backgnd; - struct nodelist *cmdlist; -}; - -struct nredir { - int type; - int linno; - union node *n; - union node *redirect; -}; - -struct nbinary { - int type; - union node *ch1; - union node *ch2; -}; - -struct nif { - int type; - union node *test; - union node *ifpart; - union node *elsepart; -}; - -struct nfor { - int type; - int linno; - union node *args; - union node *body; - char *var_; -}; - -struct ncase { - int type; - int linno; - union node *expr; - union node *cases; -}; - -struct nclist { - int type; - union node *next; - union node *pattern; - union node *body; -}; - -struct ndefun { - int type; - int linno; - char *text; - union node *body; -}; - -struct narg { - int type; - union node *next; - char *text; - struct nodelist *backquote; -}; - -struct nfile { - int type; - union node *next; - int fd; - union node *fname; - char *expfname; -}; - -struct ndup { - int type; - union node *next; - int fd; - int dupfd; - union node *vname; -}; - -struct nhere { - int type; - union node *next; - int fd; - union node *doc; -}; - -struct nnot { - int type; - union node *com; -}; - -union node { - int type; - struct ncmd ncmd; - struct npipe npipe; - struct nredir nredir; - struct nbinary nbinary; - struct nif nif; - struct nfor nfor; - struct ncase ncase; - struct nclist nclist; - struct ndefun ndefun; - struct narg narg; - struct nfile nfile; - struct ndup ndup; - struct nhere nhere; - struct nnot nnot; -}; - -struct nodelist { - struct nodelist *next; - union node *n; -}; - -struct funcnode { - int count; - union node n; -}; - -struct localvar_list { - struct localvar_list *next; - struct localvar *lv; -}; - -struct Var { - struct Var *next; /* next entry in hash list */ - int flags; /* flags are defined above */ - const char *text; /* name=value */ - void (*func)(const char *); - /* function to be called when */ - /* the variable gets set/unset */ -}; - -struct localvar { - struct localvar *next; /* next local variable in list */ - struct Var *vp; /* the variable that was made local */ - int flags; /* saved flags */ - const char *text; /* saved text */ -}; - -union yystype { - int64_t val; - char *name; -}; - -struct strlist { - struct strlist *next; - char *text; -}; - -struct arglist { - struct strlist *list; - struct strlist **lastp; -}; - -/* - * Structure specifying which parts of the string should be searched - * for IFS characters. - */ -struct ifsregion { - struct ifsregion *next; /* next region in list */ - int begoff; /* offset of start of region */ - int endoff; /* offset of end of region */ - int nulonly; /* search for nul bytes only */ -}; - -struct builtincmd { - const char *name; - int (*builtin)(int, char **); - unsigned flags; -}; - -struct cmdentry { - int cmdtype; - union param { - int index; - const struct builtincmd *cmd; - struct funcnode *func; - } u; -}; - -struct tblentry { - struct tblentry *next; /* next entry in hash chain */ - union param param; /* definition of builtin function */ - short cmdtype; /* index identifying command */ - char rehash; /* if set, cd done since entry created */ - char cmdname[]; /* name of command */ -}; - -struct backcmd { /* result of evalbackcmd */ - int fd; /* file descriptor to read from */ - char *buf; /* buffer */ - int nleft; /* number of chars in buffer */ - struct job *jp; /* job structure for command */ -}; - -struct stack_block { - struct stack_block *prev; - char space[MINSIZE]; -}; - -struct stackmark { - struct stack_block *stackp; - char *stacknxt; - unsigned stacknleft; -}; - -struct limits { - const char *name; - int cmd; - int factor; /* multiply by to get rlim_{cur,max} values */ - char option; -}; - -struct t_op { - const char *op_text; - short op_num, op_type; -}; - -/*───────────────────────────────────────────────────────────────────────────│─╗ -β”‚ cosmopolitan Β§ the unbourne shell Β» bss ─╬─│┼ -β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”‚*/ - -static char **argptr; /* argument list for builtin commands */ -static char **gargv; -static char **t_wp; -static char *arg0; /* value of $0 */ -static char *cmdnextc; -static char *commandname; -static char *expdest; /* output of current string */ -static char *expdir; -static char *funcstring; /* block to allocate strings from */ -static char *minusc; /* argument to -c option */ -static char *optionarg; /* set by nextopt (like getopt) */ -static char *optptr; /* used by nextopt */ -static char *trap[NSIG]; /* trap handler commands */ -static char *wordtext; /* text of last word returned by readtoken */ -static char basebuf[IBUFSIZ]; /* buffer for top level input file */ -static char gotsig[NSIG - 1]; /* indicates specified signal received */ -static char nullstr[1]; /* zero length string */ -static char optlist[NOPTS]; -static char sigmode[NSIG - 1]; /* current value of signal */ -static const char *arith_buf; -static const char *arith_startbuf; -static const char *pathopt; -static int back_exitstatus; /* exit status of backquoted command */ -static int checkkwd; -static int doprompt; /* if set, prompt the user */ -static int errlinno; -static int evalskip; /* set if we are skipping commands */ -static int exception; -static int exitstatus; /* exit status of last command */ -static int funcblocksize; /* size of structures in function */ -static int funcline; /* start line of function, or 0 if not in one */ -static int funcstringsize; /* size of strings in node */ -static int initialpgrp; /* pgrp of shell on invocation */ -static int inps4; /* Prevent PS4 nesting. */ -static int job_warning; -static int jobctl; -static int last_token; -static int lasttoken; /* last token read */ -static int lineno; -static int loopnest; /* current loop nesting level */ -static int needprompt; /* true if interactive and at start of line */ -static int quoteflag; /* set if (part of) last token was quoted */ -static int rootpid; -static int rval; -static int shlvl; -static int skipcount; /* number of levels to skip */ -static int suppressint; -static int tokpushback; /* last token pushed back */ -static int trapcnt; /* number of non-null traps */ -static int ttyfd = -1; /* control terminal */ -static int vforked; /* Set if we are in the vforked child */ -static int whichprompt; /* 1 == PS1, 2 == PS2 */ -static int backgndpid; /* pid of last background process */ -static pointer funcblock; /* block to allocate function from */ -static struct arglist exparg; /* holds expanded arg list */ -static struct heredoc *heredoc; -static struct heredoc *heredoclist; /* list of here documents to read */ -static struct ifsregion *ifslastp; /* last struct in list */ -static struct ifsregion ifsfirst; /* first struct in list of ifs regions */ -static struct jmploc *handler; -static struct jmploc main_handler; -static struct job *curjob; /* current job */ -static struct job *jobtab; /* array of jobs */ -static struct localvar_list *localvar_stack; -static struct nodelist *argbackq; /* list of back quote expressions */ -static struct nodelist *backquotelist; -static struct output preverrout; -static struct parsefile basepf; /* top level input file */ -static struct redirtab *redirlist; -static struct shparam shellparam; /* current positional parameters */ -static struct stack_block stackbase; -static struct t_op const *t_wp_op; -static struct tblentry **lastcmdentry; -static struct tblentry *cmdtable[CMDTABLESIZE]; -static struct Var *vartab[VTABSIZE]; -static union node *redirnode; -static union yystype yylval; -static unsigned - closed_redirs; /* Bit map of currently closed file descriptors. */ -static unsigned expdir_max; -static unsigned njobs; /* size of array */ -static volatile sig_atomic_t gotsigchld; /* received SIGCHLD */ -static volatile sig_atomic_t intpending; -static volatile sig_atomic_t pending_sig; /* last pending signal */ -static struct alias *atab[ATABSIZE]; - -/*───────────────────────────────────────────────────────────────────────────│─╗ -β”‚ cosmopolitan Β§ the unbourne shell Β» data ─╬─│┼ -β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”‚*/ - -static char *curdir = nullstr; /* current working directory */ -static char *physdir = nullstr; /* physical working directory */ -static char *sstrend = stackbase.space + MINSIZE; -static char *stacknxt = stackbase.space; -static char defifsvar[] = "IFS= \t\n"; -static char defoptindvar[] = "OPTIND=1"; -static char linenovar[sizeof("LINENO=") + INT_CHARS + 1] = "LINENO="; -static int builtinloc = -1; /* index in path of %builtin, or -1 */ -static int savestatus = -1; /* exit status of last command outside traps */ -static struct output errout = {0, 0, 0, 0, 2, 0}; -static struct output output = {0, 0, 0, OUTBUFSIZ, 1, 0}; -static struct parsefile *parsefile = &basepf; /* current input file */ -static struct stack_block *stackp = &stackbase; -static unsigned stacknleft = MINSIZE; - -static struct output *out1 = &output; -static struct output *out2 = &errout; - -/*───────────────────────────────────────────────────────────────────────────│─╗ -β”‚ cosmopolitan Β§ the unbourne shell Β» rodata ─╬─│┼ -β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”‚*/ - -/* Array indicating which tokens mark the end of a list */ -static const char tokendlist[] = { - 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, -}; - -static const char *const tokname[] = { - "end of file", "newline", "\";\"", "\"&\"", "\"&&\"", - "\"||\"", "\"|\"", "\"(\"", "\")\"", "\";;\"", - "\"`\"", "redirection", "word", "\"!\"", "\"case\"", - "\"do\"", "\"done\"", "\"elif\"", "\"else\"", "\"esac\"", - "\"fi\"", "\"for\"", "\"if\"", "\"in\"", "\"then\"", - "\"until\"", "\"while\"", "\"{\"", "\"}\"", -}; - -static const char *const parsekwd[] = { - "!", "case", "do", "done", "elif", "else", "esac", "fi", - "for", "if", "in", "then", "until", "while", "{", "}"}; - -static const char defpathvar[] = - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"; - -static const char *const optnames[NOPTS] = { - "errexit", "noglob", "ignoreeof", "interactive", "monitor", "noexec", - "stdin", "xtrace", "verbose", "vi", "emacs", "noclobber", - "allexport", "notify", "nounset", "nolog", "debug", -}; - -static const char optletters[NOPTS] = { - 'e', 'f', 'I', 'i', 'm', 'n', 's', 'x', 'v', - 'V', 'E', 'C', 'a', 'b', 'u', 0, 0, -}; - -static const char spcstr[] = " "; -static const char snlfmt[] = "%s\n"; -static const char qchars[] = {CTLESC, CTLQUOTEMARK, 0}; -static const char illnum[] = "Illegal number: %s"; -static const char homestr[] = "HOME"; -static const char dolatstr[] = {CTLQUOTEMARK, CTLVAR, VSNORMAL, '@', - '=', CTLQUOTEMARK, '\0'}; - -/* TODO(jart): What's wrong with varinit? */ -#if defined(__GNUC__) || defined(__llvm__) -#pragma GCC diagnostic ignored "-Warray-bounds" -#endif - -/* Some macros depend on the order, add new variables to the end. */ -static void changepath(const char *); -static void getoptsreset(const char *); - -static struct Var varinit[] = { - {0, VSTRFIXED | VTEXTFIXED, defifsvar, 0}, - {0, VSTRFIXED | VTEXTFIXED, defpathvar, changepath}, - {0, VSTRFIXED | VTEXTFIXED, "PS1=$ ", 0}, - {0, VSTRFIXED | VTEXTFIXED, "PS2=> ", 0}, - {0, VSTRFIXED | VTEXTFIXED, "PS4=+ ", 0}, - {0, VSTRFIXED | VTEXTFIXED, defoptindvar, getoptsreset}, - {0, VSTRFIXED | VTEXTFIXED, linenovar, 0}, -}; - -static const char kPrec[ARITH_BINOP_MAX - ARITH_BINOP_MIN] = { -#define ARITH_PRECEDENCE(OP, PREC) [OP - ARITH_BINOP_MIN] = PREC - ARITH_PRECEDENCE(ARITH_MUL, 0), ARITH_PRECEDENCE(ARITH_DIV, 0), - ARITH_PRECEDENCE(ARITH_REM, 0), ARITH_PRECEDENCE(ARITH_ADD, 1), - ARITH_PRECEDENCE(ARITH_SUB, 1), ARITH_PRECEDENCE(ARITH_LSHIFT, 2), - ARITH_PRECEDENCE(ARITH_RSHIFT, 2), ARITH_PRECEDENCE(ARITH_LT, 3), - ARITH_PRECEDENCE(ARITH_LE, 3), ARITH_PRECEDENCE(ARITH_GT, 3), - ARITH_PRECEDENCE(ARITH_GE, 3), ARITH_PRECEDENCE(ARITH_EQ, 4), - ARITH_PRECEDENCE(ARITH_NE, 4), ARITH_PRECEDENCE(ARITH_BAND, 5), - ARITH_PRECEDENCE(ARITH_BXOR, 6), ARITH_PRECEDENCE(ARITH_BOR, 7), -#undef ARITH_PRECEDENCE -}; - -static const short nodesize[26] /* clang-format off */ = { - SHELL_ALIGN(sizeof(struct ncmd)), SHELL_ALIGN(sizeof(struct npipe)), - SHELL_ALIGN(sizeof(struct nredir)), SHELL_ALIGN(sizeof(struct nredir)), - SHELL_ALIGN(sizeof(struct nredir)), SHELL_ALIGN(sizeof(struct nbinary)), - SHELL_ALIGN(sizeof(struct nbinary)), SHELL_ALIGN(sizeof(struct nbinary)), - SHELL_ALIGN(sizeof(struct nif)), SHELL_ALIGN(sizeof(struct nbinary)), - SHELL_ALIGN(sizeof(struct nbinary)), SHELL_ALIGN(sizeof(struct nfor)), - SHELL_ALIGN(sizeof(struct ncase)), SHELL_ALIGN(sizeof(struct nclist)), - SHELL_ALIGN(sizeof(struct ndefun)), SHELL_ALIGN(sizeof(struct narg)), - SHELL_ALIGN(sizeof(struct nfile)), SHELL_ALIGN(sizeof(struct nfile)), - SHELL_ALIGN(sizeof(struct nfile)), SHELL_ALIGN(sizeof(struct nfile)), - SHELL_ALIGN(sizeof(struct nfile)), SHELL_ALIGN(sizeof(struct ndup)), - SHELL_ALIGN(sizeof(struct ndup)), SHELL_ALIGN(sizeof(struct nhere)), - SHELL_ALIGN(sizeof(struct nhere)), SHELL_ALIGN(sizeof(struct nnot)), -} /* clang-format on */; - -/* syntax table used when not in quotes */ -static const char basesyntax[] /* clang-format off */ = { - CEOF, CWORD, CCTL, CCTL, CCTL, CCTL, CCTL, CCTL, CCTL, - CCTL, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CSPCL, CNL, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CSPCL, - CWORD, CDQUOTE, CWORD, CVAR, CWORD, CSPCL, CSQUOTE, CSPCL, CSPCL, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CSPCL, - CSPCL, CWORD, CSPCL, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CBACK, CWORD, CWORD, CWORD, - CBQUOTE, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CSPCL, CENDVAR, CWORD, CWORD -} /* clang-format on */; - -/* syntax table used when in double quotes */ -static const char dqsyntax[] /* clang-format off */ = { - CEOF, CWORD, CCTL, CCTL, CCTL, CCTL, CCTL, CCTL, CCTL, - CCTL, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CNL, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CCTL, CENDQUOTE, CWORD, CVAR, CWORD, CWORD, CWORD, CWORD, CWORD, - CCTL, CWORD, CWORD, CCTL, CWORD, CCTL, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CCTL, CWORD, - CWORD, CCTL, CWORD, CCTL, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CCTL, CBACK, CCTL, CWORD, CWORD, - CBQUOTE, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CENDVAR, CCTL, CWORD -} /* clang-format on */; - -/* syntax table used when in single quotes */ -static const char sqsyntax[] /* clang-format off */ = { - CEOF, CWORD, CCTL, CCTL, CCTL, CCTL, CCTL, CCTL, CCTL, - CCTL, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CNL, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CCTL, CWORD, CWORD, CWORD, CWORD, CWORD, CENDQUOTE, CWORD, CWORD, - CCTL, CWORD, CWORD, CCTL, CWORD, CCTL, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CCTL, CWORD, - CWORD, CCTL, CWORD, CCTL, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CCTL, CCTL, CCTL, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CCTL, CWORD -} /* clang-format on */; - -/* syntax table used when in arithmetic */ -static const char arisyntax[] /* clang-format off */ = { - CEOF, CWORD, CCTL, CCTL, CCTL, CCTL, CCTL, CCTL, CCTL, - CCTL, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CNL, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CVAR, CWORD, CWORD, CWORD, CLP, CRP, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CBACK, CWORD, CWORD, CWORD, - CBQUOTE, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, CWORD, - CWORD, CWORD, CENDVAR, CWORD, CWORD -} /* clang-format on */; - -/* character classification table */ -static const char is_type[] /* clang-format off */ = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, ISSPECL, 0, ISSPECL, ISSPECL, 0, 0, - 0, 0, 0, ISSPECL, 0, 0, ISSPECL, 0, - 0, ISDIGIT, ISDIGIT, ISDIGIT, ISDIGIT, ISDIGIT, ISDIGIT, ISDIGIT, - ISDIGIT, ISDIGIT, ISDIGIT, 0, 0, 0, 0, 0, - ISSPECL, ISSPECL, ISUPPER, ISUPPER, ISUPPER, ISUPPER, ISUPPER, ISUPPER, - ISUPPER, ISUPPER, ISUPPER, ISUPPER, ISUPPER, ISUPPER, ISUPPER, ISUPPER, - ISUPPER, ISUPPER, ISUPPER, ISUPPER, ISUPPER, ISUPPER, ISUPPER, ISUPPER, - ISUPPER, ISUPPER, ISUPPER, ISUPPER, 0, 0, 0, 0, - ISUNDER, 0, ISLOWER, ISLOWER, ISLOWER, ISLOWER, ISLOWER, ISLOWER, - ISLOWER, ISLOWER, ISLOWER, ISLOWER, ISLOWER, ISLOWER, ISLOWER, ISLOWER, - ISLOWER, ISLOWER, ISLOWER, ISLOWER, ISLOWER, ISLOWER, ISLOWER, ISLOWER, - ISLOWER, ISLOWER, ISLOWER, ISLOWER, 0, 0, 0, 0, - 0 -} /* clang-format on */; - -static int aliascmd(); -static int bgcmd(); -static int breakcmd(); -static int cdcmd(); -static int commandcmd(); -static int dotcmd(); -static int echocmd(); -static int evalcmd(); -static int execcmd(); -static int exitcmd(); -static int exportcmd(); -static int falsecmd(); -static int fgcmd(); -static int getoptscmd(); -static int hashcmd(); -static int jobscmd(); -static int killcmd(); -static int localcmd(); -static int printfcmd(); -static int pwdcmd(); -static int readcmd(); -static int returncmd(); -static int setcmd(); -static int shiftcmd(); -static int testcmd(); -static int timescmd(); -static int trapcmd(); -static int truecmd(); -static int typecmd(); -static int ulimitcmd(); -static int umaskcmd(); -static int unaliascmd(); -static int unsetcmd(); -static int waitcmd(); - -static const struct builtincmd kBuiltinCmds[] = { - {".", dotcmd, 3}, // - {":", truecmd, 3}, // - {"[", testcmd, 0}, // - {"alias", aliascmd, 6}, // - {"bg", bgcmd, 2}, // - {"break", breakcmd, 3}, // - {"cd", cdcmd, 2}, // - {"chdir", cdcmd, 0}, // - {"command", commandcmd, 2}, // - {"continue", breakcmd, 3}, // - {"echo", echocmd, 0}, // - {"eval", NULL, 3}, // - {"exec", execcmd, 3}, // - {"exit", exitcmd, 3}, // - {"export", exportcmd, 7}, // - {"false", falsecmd, 2}, // - {"fg", fgcmd, 2}, // - {"getopts", getoptscmd, 2}, // - {"hash", hashcmd, 2}, // - {"jobs", jobscmd, 2}, // - {"kill", killcmd, 2}, // - {"local", localcmd, 7}, // - {"printf", printfcmd, 0}, // - {"pwd", pwdcmd, 2}, // - {"read", readcmd, 2}, // - {"readonly", exportcmd, 7}, // - {"return", returncmd, 3}, // - {"set", setcmd, 3}, // - {"shift", shiftcmd, 3}, // - {"test", testcmd, 0}, // - {"times", timescmd, 3}, // - {"trap", trapcmd, 3}, // - {"true", truecmd, 2}, // - {"type", typecmd, 2}, // - {"ulimit", ulimitcmd, 2}, // - {"umask", umaskcmd, 2}, // - {"unalias", unaliascmd, 2}, // - {"unset", unsetcmd, 3}, // - {"wait", waitcmd, 2}, // -}; - -enum token { - EOI, - FILRD, - FILWR, - FILEX, - FILEXIST, - FILREG, - FILDIR, - FILCDEV, - FILBDEV, - FILFIFO, - FILSOCK, - FILSYM, - FILGZ, - FILTT, - FILSUID, - FILSGID, - FILSTCK, - FILNT, - FILOT, - FILEQ, - FILUID, - FILGID, - STREZ, - STRNZ, - STREQ, - STRNE, - STRLT, - STRGT, - INTEQ, - INTNE, - INTGE, - INTGT, - INTLE, - INTLT, - UNOT, - BAND, - BOR, - LPAREN, - RPAREN, - OPERAND -}; - -enum token_types { UNOP, BINOP, BUNOP, BBINOP, PAREN }; - -static struct t_op const ops[] = { - {"-r", FILRD, UNOP}, - {"-w", FILWR, UNOP}, - {"-x", FILEX, UNOP}, - {"-e", FILEXIST, UNOP}, - {"-f", FILREG, UNOP}, - {"-d", FILDIR, UNOP}, - {"-c", FILCDEV, UNOP}, - {"-b", FILBDEV, UNOP}, - {"-p", FILFIFO, UNOP}, - {"-u", FILSUID, UNOP}, - {"-g", FILSGID, UNOP}, - {"-k", FILSTCK, UNOP}, - {"-s", FILGZ, UNOP}, - {"-t", FILTT, UNOP}, - {"-z", STREZ, UNOP}, - {"-n", STRNZ, UNOP}, - {"-h", FILSYM, UNOP}, /* for backwards compat */ - {"-O", FILUID, UNOP}, - {"-G", FILGID, UNOP}, - {"-L", FILSYM, UNOP}, - {"-S", FILSOCK, UNOP}, - {"=", STREQ, BINOP}, - {"!=", STRNE, BINOP}, - {"<", STRLT, BINOP}, - {">", STRGT, BINOP}, - {"-eq", INTEQ, BINOP}, - {"-ne", INTNE, BINOP}, - {"-ge", INTGE, BINOP}, - {"-gt", INTGT, BINOP}, - {"-le", INTLE, BINOP}, - {"-lt", INTLT, BINOP}, - {"-nt", FILNT, BINOP}, - {"-ot", FILOT, BINOP}, - {"-ef", FILEQ, BINOP}, - {"!", UNOT, BUNOP}, - {"-a", BAND, BBINOP}, - {"-o", BOR, BBINOP}, - {"(", LPAREN, PAREN}, - {")", RPAREN, PAREN}, - {0, 0, 0}, -}; - -/*───────────────────────────────────────────────────────────────────────────│─╗ -β”‚ cosmopolitan Β§ the unbourne shell Β» text ─╬─│┼ -β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”‚*/ - -/* - * Hack to calculate maximum length. - * (length * 8 - 1) * log10(2) + 1 + 1 + 12 - * The second 1 is for the minus sign and the 12 is a safety margin. - */ -static inline int max_int_length(int bytes) { - return (bytes * 8 - 1) * 0.30102999566398119521 + 14; -} - -/* prefix -- see if pfx is a prefix of string. */ -static char *prefix(const char *string, const char *pfx) { - while (*pfx) { - if (*pfx++ != *string++) - return 0; - } - return (char *)string; -} - -/* - * Wrapper around strcmp for qsort/bsearch/... - */ -static int pstrcmp(const void *a, const void *b) { - return strcmp(*(const char *const *)a, *(const char *const *)b); -} - -/* - * Find a string is in a sorted array. - */ -static const char *const *findstring(const char *s, const char *const *array, - unsigned nmemb) { - return bsearch(&s, array, nmemb, sizeof(const char *), pstrcmp); -} - -/* Types of operations (passed to the errmsg routine). */ -enum ShErrorAction { E_OPEN, E_CREAT, E_EXEC }; - -/* - * Return a string describing an error. The returned string may be a - * pointer to a static buffer that will be overwritten on the next call. - * Action describes the operation that got the error. - */ -static const char *errmsg(int e, enum ShErrorAction action) { - if (e != ENOENT && e != ENOTDIR) - return strerror(e); - switch (action) { - case E_OPEN: - return "No such file"; - case E_CREAT: - return "Directory nonexistent"; - default: - return "not found"; - } -} - -static inline void sigclearmask(void) { - sigset_t set; - sigemptyset(&set); - sigprocmask(SIG_SETMASK, &set, 0); -} - -/* - * Called to raise an exception. Since C doesn't include exceptions, we - * just do a longjmp to the exception handler. The type of exception is - * stored in the global variable "exception". - */ -wontreturn static void exraise(int e) { - if (vforked) - _exit(exitstatus); - INTOFF; - exception = e; - longjmp(handler->loc, 1); -} - -/* - * Called from trap.c when a SIGINT is received. (If the user specifies - * that SIGINT is to be trapped or ignored using the trap builtin, then - * this routine is not called.) Suppressint is nonzero when interrupts - * are held using the INTOFF macro. (The test for iflag is just - * defensive programming.) - */ -wontreturn static void onint(void) { - intpending = 0; - sigclearmask(); - if (!(rootshell && iflag)) { - signal(SIGINT, SIG_DFL); - raise(SIGINT); - } - exitstatus = SIGINT + 128; - exraise(EXINT); -} - -static pointer ckmalloc(unsigned nbytes) { - pointer p; - if (!(p = malloc(nbytes))) - abort(); - return p; -} - -static pointer ckrealloc(pointer p, unsigned nbytes) { - if (!(p = realloc(p, nbytes))) - abort(); - return p; -} - -#define stackblock() ((void *)stacknxt) -#define stackblocksize() stacknleft -#define STARTSTACKSTR(p) ((p) = stackblock()) -#define STPUTC(c, p) ((p) = _STPUTC((c), (p))) -#define CHECKSTRSPACE(n, p) \ - ({ \ - char *q = (p); \ - unsigned l = (n); \ - unsigned m = sstrend - q; \ - if (l > m) \ - (p) = makestrspace(l, q); \ - 0; \ - }) -#define USTPUTC(c, p) (*p++ = (c)) -#define STACKSTRNUL(p) \ - ((p) == sstrend ? (p = growstackstr(), *p = '\0') : (*p = '\0')) -#define STUNPUTC(p) (--p) -#define STTOPC(p) p[-1] -#define STADJUST(amount, p) (p += (amount)) -#define grabstackstr(p) stalloc((char *)(p) - (char *)stackblock()) -#define ungrabstackstr(s, p) stunalloc((s)) -#define stackstrend() ((void *)sstrend) -#define ckfree(p) free((pointer)(p)) - -static pointer stalloc(unsigned nbytes) { - char *p; - unsigned aligned; - aligned = SHELL_ALIGN(nbytes); - if (aligned > stacknleft) { - unsigned len; - unsigned blocksize; - struct stack_block *sp; - blocksize = aligned; - if (blocksize < MINSIZE) - blocksize = MINSIZE; - len = sizeof(struct stack_block) - MINSIZE + blocksize; - if (len < blocksize) - abort(); - INTOFF; - sp = ckmalloc(len); - sp->prev = stackp; - stacknxt = sp->space; - stacknleft = blocksize; - sstrend = stacknxt + blocksize; - stackp = sp; - INTON; - } - p = stacknxt; - stacknxt += aligned; - stacknleft -= aligned; - return p; -} - -static inline void grabstackblock(unsigned len) { - stalloc(len); -} - -static void pushstackmark(struct stackmark *mark, unsigned len) { - mark->stackp = stackp; - mark->stacknxt = stacknxt; - mark->stacknleft = stacknleft; - grabstackblock(len); -} - -static void popstackmark(struct stackmark *mark) { - struct stack_block *sp; - INTOFF; - while (stackp != mark->stackp) { - sp = stackp; - stackp = sp->prev; - ckfree(sp); - } - stacknxt = mark->stacknxt; - stacknleft = mark->stacknleft; - sstrend = mark->stacknxt + mark->stacknleft; - INTON; -} - -static void setstackmark(struct stackmark *mark) { - pushstackmark(mark, stacknxt == stackp->space && stackp != &stackbase); -} - -static void stunalloc(pointer p) { - stacknleft += stacknxt - (char *)p; - stacknxt = p; -} - -/* Like strdup but works with the ash stack. */ -static char *sstrdup(const char *p) { - unsigned len = strlen(p) + 1; - return memcpy(stalloc(len), p, len); -} - -int __xwrite(int, const void *, uint64_t); - -static void flushout(struct output *dest) { - unsigned len; - len = dest->nextc - dest->buf; - if (!len || dest->fd < 0) - return; - dest->nextc = dest->buf; - if ((__xwrite(dest->fd, dest->buf, len))) - dest->flags |= OUTPUT_ERR; -} - -static void flushall(void) { - flushout(&output); -} - -/*───────────────────────────────────────────────────────────────────────────│─╗ -β”‚ cosmopolitan Β§ the unbourne shell Β» output routines ─╬─│┼ -β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”‚β”€β• - When a builtin command is interrupted we have to discard - any pending output. - When a builtin command appears in back quotes, we want to - save the output of the command in a region obtained - via malloc, rather than doing a fork and reading the - output of the command via a pipe. */ - -static int xvsnprintf(char *outbuf, unsigned length, const char *fmt, - va_list ap) { - int ret; - INTOFF; - ret = vsnprintf(outbuf, length, fmt, ap); - INTON; - return ret; -} - -static int Xvasprintf(char **sp, unsigned size, const char *f, va_list ap) { - char *s; - int len; - va_list ap2; - va_copy(ap2, ap); - len = xvsnprintf(*sp, size, f, ap2); - va_end(ap2); - if (len < 0) - abort(); - if (len < size) - return len; - s = stalloc((len >= stackblocksize() ? len : stackblocksize()) + 1); - *sp = s; - len = xvsnprintf(s, len + 1, f, ap); - return len; -} - -static void outmem(const char *p, unsigned len, struct output *dest) { - unsigned bufsize; - unsigned offset; - unsigned nleft; - nleft = dest->end - dest->nextc; - if (likely(nleft >= len)) { - buffered: - dest->nextc = mempcpy(dest->nextc, p, len); - return; - } - bufsize = dest->bufsize; - if (!bufsize) { - (void)0; - } else if (dest->buf == NULL) { - offset = 0; - INTOFF; - dest->buf = ckrealloc(dest->buf, bufsize); - dest->bufsize = bufsize; - dest->end = dest->buf + bufsize; - dest->nextc = dest->buf + offset; - INTON; - } else { - flushout(dest); - } - nleft = dest->end - dest->nextc; - if (nleft > len) - goto buffered; - if ((__xwrite(dest->fd, p, len))) { - dest->flags |= OUTPUT_ERR; - } -} - -static void outstr(const char *p, struct output *file) { - unsigned len; - len = strlen(p); - outmem(p, len, file); -} - -static void outcslow(int c, struct output *dest) { - char buf = c; - outmem(&buf, 1, dest); -} - -printfesque(3) static int fmtstr(char *outbuf, unsigned length, const char *fmt, - ...) { - va_list ap; - int ret; - va_start(ap, fmt); - ret = xvsnprintf(outbuf, length, fmt, ap); - va_end(ap); - return ret > (int)length ? length : ret; -} - -printfesque(2) static int Xasprintf(char **sp, const char *fmt, ...) { - va_list ap; - int ret; - va_start(ap, fmt); - ret = Xvasprintf(sp, 0, fmt, ap); - va_end(ap); - return ret; -} - -static void doformat(struct output *dest, const char *f, va_list ap) { - struct stackmark smark; - char *s; - int len; - int olen; - setstackmark(&smark); - s = dest->nextc; - olen = dest->end - dest->nextc; - len = Xvasprintf(&s, olen, f, ap); - if (likely(olen > len)) { - dest->nextc += len; - goto out; - } - outmem(s, len, dest); -out: - popstackmark(&smark); -} - -printfesque(1) static void out1fmt(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - doformat(out1, fmt, ap); - va_end(ap); -} - -printfesque(2) static void outfmt(struct output *file, const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - doformat(file, fmt, ap); - va_end(ap); -} - -static void exvwarning(const char *msg, va_list ap) { - struct output *errs; - const char *name; - const char *fmt; - errs = out2; - name = arg0 ? arg0 : "sh"; - if (!commandname) { - fmt = "%s: %d: "; - } else { - fmt = "%s: %d: %s: "; - } - outfmt(errs, fmt, name, errlinno, commandname); - doformat(errs, msg, ap); - outcslow('\n', errs); -} - -/* error/warning routines for external builtins */ -printfesque(1) static void sh_warnx(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - exvwarning(fmt, ap); - va_end(ap); -} - -/* - * Exverror is called to raise the error exception. If the second argument - * is not NULL then error prints an error message using printf style - * formatting. It then raises the error exception. - */ -wontreturn static void exverror(int cond, const char *msg, va_list ap) { - exvwarning(msg, ap); - flushall(); - exraise(cond); -} - -wontreturn static void exerror(int cond, const char *msg, ...) { - va_list ap; - va_start(ap, msg); - exverror(cond, msg, ap); - va_end(ap); -} - -wontreturn static void sh_error(const char *msg, ...) { - va_list ap; - exitstatus = 2; - va_start(ap, msg); - exverror(EXERROR, msg, ap); - va_end(ap); -} - -wontreturn static void badnum(const char *s) { - sh_error(illnum, s); -} - -wontreturn static void synerror(const char *msg) { - errlinno = plinno; - sh_error("Syntax error: %s", msg); -} - -wontreturn static void yyerror(const char *s) { - sh_error("arithmetic expression: %s: \"%s\"", s, arith_startbuf); -} - -/* - * Called when an unexpected token is read during the parse. The - * argument is the token that is expected, or -1 if more than one type - * of token can occur at this point. - */ -wontreturn static void synexpect(int token) { - char msg[64]; - if (token >= 0) { - fmtstr(msg, 64, "%s unexpected (expecting %s)", tokname[lasttoken], - tokname[token]); - } else { - fmtstr(msg, 64, "%s unexpected", tokname[lasttoken]); - } - synerror(msg); -} - -wontreturn static void varunset(const char *end, const char *var_, - const char *umsg, int varflags) { - const char *msg; - const char *tail; - tail = nullstr; - msg = "parameter not set"; - if (umsg) { - if (*end == (char)CTLENDVAR) { - if (varflags & VSNUL) - tail = " or null"; - } else - msg = umsg; - } - sh_error("%.*s: %s%s", end - var_ - 1, var_, msg, tail); -} - -/* - * Convert a string into an integer of type int64. Allow trailing spaces. - */ -static int64_t atomax(const char *s, int base) { - char *p; - int64_t r; - errno = 0; - r = strtoimax(s, &p, base); - if (errno == ERANGE) - badnum(s); - /* - * Disallow completely blank strings in non-arithmetic (base != 0) - * contexts. - */ - if (p == s && base) - badnum(s); - while (isspace((unsigned char)*p)) - p++; - if (*p) - badnum(s); - return r; -} - -static int64_t atomax10(const char *s) { - return atomax(s, 10); -} - -/* - * Convert a string of digits to an integer, printing an error message - * on failure. - */ -static int number(const char *s) { - int64_t n = atomax10(s); - if (n < 0 || n > INT_MAX) - badnum(s); - return n; -} - -static inline int64_t getn(const char *s) { - return atomax10(s); -} - -/* - * When the parser reads in a string, it wants to stick the string on - * the stack and only adjust the stack pointer when it knows how big the - * string is. Stackblock (defined in stack.h) returns a pointer to a - * block of space on top of the stack and stackblocklen returns the - * length of this block. Growstackblock will grow this space by at least - * one byte, possibly moving it (like realloc). Grabstackblock actually - * allocates the part of the block that has been used. - */ -static void growstackblock(unsigned min) { - unsigned newlen; - newlen = stacknleft * 2; - if (newlen < stacknleft) - sh_error("Out of space"); - min = SHELL_ALIGN(min | 128); - if (newlen < min) - newlen += min; - if (stacknxt == stackp->space && stackp != &stackbase) { - struct stack_block *sp; - struct stack_block *prevstackp; - unsigned grosslen; - INTOFF; - sp = stackp; - prevstackp = sp->prev; - grosslen = newlen + sizeof(struct stack_block) - MINSIZE; - sp = ckrealloc((pointer)sp, grosslen); - sp->prev = prevstackp; - stackp = sp; - stacknxt = sp->space; - stacknleft = newlen; - sstrend = sp->space + newlen; - INTON; - } else { - char *oldspace = stacknxt; - int oldlen = stacknleft; - char *p = stalloc(newlen); - /* free the space we just allocated */ - stacknxt = memcpy(p, oldspace, oldlen); - stacknleft += newlen; - } -} - -/* - * The following routines are somewhat easier to use than the above. The - * user declares a variable of type STACKSTR, which may be declared to - * be a register. The macro STARTSTACKSTR initializes things. Then the - * user uses the macro STPUTC to add characters to the string. In - * effect, STPUTC(c, p) is the same as *p++ = c except that the stack is - * grown as necessary. When the user is done, she can just leave the - * string there and refer to it using stackblock(). Or she can allocate - * the space for it using grabstackstr(). If it is necessary to allow - * someone else to use the stack temporarily and then continue to grow - * the string, the user should use grabstack to allocate the space, and - * then call ungrabstr(p) to return to the previous mode of operation. - * - * USTPUTC is like STPUTC except that it doesn't check for overflow. - * CHECKSTACKSPACE can be called before USTPUTC to ensure that there - * is space for at least one character. - */ -static void *growstackstr(void) { - unsigned len = stackblocksize(); - growstackblock(0); - return (char *)stackblock() + len; -} - -static char *growstackto(unsigned len) { - if (stackblocksize() < len) - growstackblock(len); - return stackblock(); -} - -/* - * Make a copy of a string in safe storage. - */ -static char *savestr(const char *s) { - char *p = strdup(s); - if (!p) - sh_error("Out of space"); - return p; -} - -/* Called from CHECKSTRSPACE. */ -static char *makestrspace(unsigned newlen, char *p) { - unsigned len = p - stacknxt; - return growstackto(len + newlen) + len; -} - -static char *stnputs(const char *s, unsigned n, char *p) { - p = makestrspace(n, p); - p = mempcpy(p, s, n); - return p; -} - -static char *stputs(const char *s, char *p) { - return stnputs(s, strlen(s), p); -} - -static char *nodesavestr(s) -char *s; -{ - char *rtn = funcstring; - funcstring = stpcpy(funcstring, s) + 1; - return rtn; -} - -wontreturn static void shellexec(char **, const char *, int); -static char **listvars(int, int, char ***); -static char *argstr(char *p, int flag); -static char *conv_escape(char *, int *); -static char *evalvar(char *, int); -static char *expari(char *start, int flag); -static char *exptilde(char *startp, int flag); -static int shlex(void); -static char *lookupvar(const char *); -static char *mklong(const char *, const char *); -static char *rmescapes(char *, int); -static char *scanleft(char *, char *, char *, char *, int, int); -static char *scanright(char *, char *, char *, char *, int, int); -static char *single_quote(const char *); -static const char *const *findkwd(const char *); -static const char *expandstr(const char *); -static const char *getprompt(void *); -static double getdouble(void); -static enum token t_lex(char **); -static int aexpr(enum token); -static int binop0(void); -static int bltincmd(int, char **); -static int conv_escape_str(char *, char **); -static int decode_signal(const char *, int); -static int decode_signum(const char *); -static int describe_command(struct output *, char *, const char *, int); -static int eprintlist(struct output *, struct strlist *, int); -static int equalf(const char *, const char *); -static int evalbltin(const struct builtincmd *, int, char **, int); -static int evalcase(union node *, int); -static int evalcommand(union node *, int); -static int evalfor(union node *, int); -static int evalfun(struct funcnode *, int, char **, int); -static int evalloop(union node *, int); -static int evalpipe(union node *, int); -static int evalsubshell(union node *, int); -static int filstat(char *, enum token); -static int forkshell(struct job *, union node *, int); -static int getopts(char *, char *, char **); -static int isassignment(const char *p); -static int isoperand(char **); -static int newerf(const char *, const char *); -static int nexpr(enum token); -static int nextopt(const char *); -static int oexpr(enum token); -static int olderf(const char *, const char *); -static int64_t openhere(union node *); -static int openredirect(union node *); -static int options(int); -static int padvance_magic(const char **, const char *, int); -static int patmatch(char *, const char *); -static int pgetc(void); -static int pgetc_eatbnl(); -static int pmatch(const char *, const char *); -static int preadbuffer(void); -static ssize_t preadfd(void); -static int primary1(enum token); -static int procargs(int, char **); -static int readtoken(void); -static int readtoken1(int, char const *, char *, int); -static int redirectsafe(union node *, int); -static int savefd(int, int); -static int setinputfile(const char *, int); -static int sh_open(const char *pathname, int flags, int mayfail); -static int showvars(const char *, int, int); -static int stoppedjobs(void); -static int test_file_access(const char *, int); -static int unalias(const char *); -static int waitforjob(struct job *); -static int xxreadtoken(void); -static int64_t arith(const char *); -static int64_t assignment(int var_, int noeval); -static int64_t lookupvarint(const char *); -static long varvalue(char *, int, int, int); -static int64_t setvarint(const char *name, int64_t val, int flags); -static struct Var *setvar(const char *name, const char *val, int flags); -static struct Var *setvareq(char *s, int flags); -static struct alias **__lookupalias(const char *); -static struct alias *freealias(struct alias *); -static struct alias *lookupalias(const char *, int); -static struct funcnode *copyfunc(union node *); -static struct job *makejob(union node *, int); -static struct job *vforkexec(union node *n, char **argv, const char *path, - int idx); -static struct localvar_list *pushlocalvars(int push); -static struct nodelist *copynodelist(struct nodelist *); -static struct redirtab *pushredir(union node *redir); -static struct strlist *expsort(struct strlist *); -static struct strlist *msort(struct strlist *, int); -static struct tblentry *cmdlookup(const char *, int); -static uint64_t getuintmax(int); -static union node *andor(void); -static union node *command(void); -static union node *copynode(union node *); -static union node *list(int); -static union node *makename(void); -static union node *parsecmd(int); -static union node *pipeline(void); -static union node *simplecmd(void); -static unsigned esclen(const char *, const char *); -static unsigned memtodest(const char *p, unsigned len, int flags); -static unsigned strtodest(const char *p, int flags); -static void addcmdentry(char *, struct cmdentry *); -static void addfname(char *); -static void check_conversion(const char *, const char *); -static void clearcmdentry(void); -static void defun(union node *); -static void delete_cmd_entry(void); -static void dotrap(void); -static void dupredirect(union node *, int); -static void exitreset(void); -static void expandarg(union node *arg, struct arglist *arglist, int flag); -static void expandmeta(struct strlist *); -static void expbackq(union node *, int); -static void expmeta(char *, unsigned, unsigned); -static void expredir(union node *); -static void find_command(char *, struct cmdentry *, int, const char *); -static void fixredir(union node *, const char *, int); -static void forkreset(void); -static void freeparam(volatile struct shparam *); -static void hashcd(void); -static void ignoresig(int); -static void init(void); -static void minus_o(char *, int); -static void mklocal(char *name, int flags); -static void onsig(int); -static void optschanged(void); -static void parsefname(void); -static void parseheredoc(void); -static void popallfiles(void); -static void popfile(void); -static void poplocalvars(void); -static void popredir(int); -static void popstring(void); -static void prehash(union node *); -static void printalias(const struct alias *); -static void printentry(struct tblentry *); -static void pungetc(void); -static void pushfile(void); -static void pushstring(char *, void *); -static void read_profile(const char *); -static void redirect(union node *, int); -static void reset(void); -static void rmaliases(void); -static void setalias(const char *, const char *); -static void setinputfd(int fd, int push); -static void setinputstring(char *); -static void setinteractive(int); -static void setjobctl(int); -static void setparam(char **); -static void setprompt(int); -static void setsignal(int); -static void showjobs(struct output *, int); -static void sigblockall(sigset_t *oldmask); -static void sizenodelist(struct nodelist *); -static void syntax(const char *, const char *); -static void tryexec(char *, char **, char **); -static void unsetfunc(const char *); -static void unsetvar(const char *); -static void unwindfiles(struct parsefile *); -static void unwindlocalvars(struct localvar_list *stop); -static void unwindredir(struct redirtab *stop); -static unsigned cvtnum(int64_t num, int flags); - -static int getchr(void) { - int val = 0; - if (*gargv) - val = **gargv++; - return val; -} - -static char *getstr(void) { - char *val = nullstr; - if (*gargv) - val = *gargv++; - return val; -} - -/* - * Check for a valid number. This should be elsewhere. - */ -static int is_number(const char *p) { - do { - if (!is_digit(*p)) - return 0; - } while (*++p != '\0'); - return 1; -} - -static inline void freestdout() { - output.nextc = output.buf; - output.flags = 0; -} - -static inline void outc(int ch, struct output *file) { - if (file->nextc == file->end) - outcslow(ch, file); - else { - *file->nextc = ch; - file->nextc++; - } -} - -static inline char *_STPUTC(int c, char *p) { - if (p == sstrend) - p = growstackstr(); - *p++ = c; - return p; -} - -static void ifsfree(void) { - struct ifsregion *p = ifsfirst.next; - if (!p) - goto out; - INTOFF; - do { - struct ifsregion *ifsp; - ifsp = p->next; - ckfree(p); - p = ifsp; - } while (p); - ifsfirst.next = NULL; - INTON; -out: - ifslastp = NULL; -} - -static void setalias(const char *name, const char *val) { - struct alias *ap, **app; - app = __lookupalias(name); - ap = *app; - INTOFF; - if (ap) { - if (!(ap->flag & ALIASINUSE)) { - ckfree(ap->val); - } - ap->val = savestr(val); - ap->flag &= ~ALIASDEAD; - } else { - /* not found */ - ap = ckmalloc(sizeof(struct alias)); - ap->name = savestr(name); - ap->val = savestr(val); - ap->flag = 0; - ap->next = 0; - *app = ap; - } - INTON; -} - -static int unalias(const char *name) { - struct alias **app; - app = __lookupalias(name); - if (*app) { - INTOFF; - *app = freealias(*app); - INTON; - return (0); - } - return (1); -} - -static void rmaliases(void) { - struct alias *ap, **app; - int i; - INTOFF; - for (i = 0; i < ATABSIZE; i++) { - app = &atab[i]; - for (ap = *app; ap; ap = *app) { - *app = freealias(*app); - if (ap == *app) { - app = &ap->next; - } - } - } - INTON; -} - -struct alias *lookupalias(const char *name, int check) { - struct alias *ap = *__lookupalias(name); - if (check && ap && (ap->flag & ALIASINUSE)) - return (NULL); - return (ap); -} - -static int aliascmd(int argc, char **argv) { - /* TODO - sort output */ - char *n, *v; - int ret = 0; - struct alias *ap; - if (argc == 1) { - int i; - for (i = 0; i < ATABSIZE; i++) - for (ap = atab[i]; ap; ap = ap->next) { - printalias(ap); - } - return (0); - } - while ((n = *++argv) != NULL) { - if ((v = strchr(n + 1, '=')) == NULL) { /* n+1: funny ksh stuff */ - if ((ap = *__lookupalias(n)) == NULL) { - outfmt(out2, "%s: %s not found\n", "alias", n); - ret = 1; - } else - printalias(ap); - } else { - *v++ = '\0'; - setalias(n, v); - } - } - return (ret); -} - -static int unaliascmd(int argc, char **argv) { - int i; - while ((i = nextopt("a")) != '\0') { - if (i == 'a') { - rmaliases(); - return (0); - } - } - for (i = 0; *argptr; argptr++) { - if (unalias(*argptr)) { - outfmt(out2, "%s: %s not found\n", "unalias", *argptr); - i = 1; - } - } - return i; -} - -static struct alias *freealias(struct alias *ap) { - struct alias *next; - if (ap->flag & ALIASINUSE) { - ap->flag |= ALIASDEAD; - return ap; - } - next = ap->next; - ckfree(ap->name); - ckfree(ap->val); - ckfree(ap); - return next; -} - -static void printalias(const struct alias *ap) { - out1fmt("%s=%s\n", ap->name, single_quote(ap->val)); -} - -static struct alias **__lookupalias(const char *name) { - unsigned int hashval; - struct alias **app; - const char *p; - unsigned int ch; - p = name; - ch = (unsigned char)*p; - hashval = ch << 4; - while (ch) { - hashval += ch; - ch = (unsigned char)*++p; - } - app = &atab[hashval % ATABSIZE]; - for (; *app; app = &(*app)->next) { - if (equal(name, (*app)->name)) { - break; - } - } - return app; -} - -static int shlex() { - int value; - const char *buf = arith_buf; - const char *p; - for (;;) { - value = *buf; - switch (value) { - case ' ': - case '\t': - case '\n': - buf++; - continue; - default: - return ARITH_BAD; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - yylval.val = strtoimax(buf, (char **)&arith_buf, 0); - return ARITH_NUM; - case 'A': - case 'B': - case 'C': - case 'D': - case 'E': - case 'F': - case 'G': - case 'H': - case 'I': - case 'J': - case 'K': - case 'L': - case 'M': - case 'N': - case 'O': - case 'P': - case 'Q': - case 'R': - case 'S': - case 'T': - case 'U': - case 'V': - case 'W': - case 'X': - case 'Y': - case 'Z': - case '_': - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'f': - case 'g': - case 'h': - case 'i': - case 'j': - case 'k': - case 'l': - case 'm': - case 'n': - case 'o': - case 'p': - case 'q': - case 'r': - case 's': - case 't': - case 'u': - case 'v': - case 'w': - case 'x': - case 'y': - case 'z': - p = buf; - while (buf++, is_in_name(*buf)) - ; - yylval.name = stalloc(buf - p + 1); - *(char *)mempcpy(yylval.name, p, buf - p) = 0; - value = ARITH_VAR; - goto out; - case '=': - value += ARITH_ASS - '='; - checkeq: - buf++; - checkeqcur: - if (*buf != '=') - goto out; - value += 11; - break; - case '>': - switch (*++buf) { - case '=': - value += ARITH_GE - '>'; - break; - case '>': - value += ARITH_RSHIFT - '>'; - goto checkeq; - default: - value += ARITH_GT - '>'; - goto out; - } - break; - case '<': - switch (*++buf) { - case '=': - value += ARITH_LE - '<'; - break; - case '<': - value += ARITH_LSHIFT - '<'; - goto checkeq; - default: - value += ARITH_LT - '<'; - goto out; - } - break; - case '|': - if (*++buf != '|') { - value += ARITH_BOR - '|'; - goto checkeqcur; - } - value += ARITH_OR - '|'; - break; - case '&': - if (*++buf != '&') { - value += ARITH_BAND - '&'; - goto checkeqcur; - } - value += ARITH_AND - '&'; - break; - case '!': - if (*++buf != '=') { - value += ARITH_NOT - '!'; - goto out; - } - value += ARITH_NE - '!'; - break; - case 0: - goto out; - case '(': - value += ARITH_LPAREN - '('; - break; - case ')': - value += ARITH_RPAREN - ')'; - break; - case '*': - value += ARITH_MUL - '*'; - goto checkeq; - case '/': - value += ARITH_DIV - '/'; - goto checkeq; - case '%': - value += ARITH_REM - '%'; - goto checkeq; - case '+': - value += ARITH_ADD - '+'; - goto checkeq; - case '-': - value += ARITH_SUB - '-'; - goto checkeq; - case '~': - value += ARITH_BNOT - '~'; - break; - case '^': - value += ARITH_BXOR - '^'; - goto checkeq; - case '?': - value += ARITH_QMARK - '?'; - break; - case ':': - value += ARITH_COLON - ':'; - break; - } - break; - } - buf++; -out: - arith_buf = buf; - return value; -} - -/* - * Compares two strings up to the first = or '\0'. The first string must - * be terminated by '='; the second may be terminated by either '=' or - * '\0'. - */ -static int varcmp(const char *p, const char *q) { - int c, d; - while ((c = *p) == (d = *q)) { - if (!c || c == '=') - goto out; - p++; - q++; - } - if (c == '=') - c = 0; - if (d == '=') - d = 0; -out: - return c - d; -} - -static inline int varequal(const char *a, const char *b) { - return !varcmp(a, b); -} - -/* - * Search the environment of a builtin command. - */ -static inline char *bltinlookup(const char *name) { - return lookupvar(name); -} - -static inline int arith_prec(int op) { - return kPrec[op - ARITH_BINOP_MIN]; -} - -static inline int higher_prec(int op1, int op2) { - return arith_prec(op1) < arith_prec(op2); -} - -static int64_t do_binop(int op, int64_t a, int64_t b) { - switch (op) { - default: - case ARITH_REM: - case ARITH_DIV: - if (!b) - yyerror("division by zero"); - return op == ARITH_REM ? a % b : a / b; - case ARITH_MUL: - return a * b; - case ARITH_ADD: - return a + b; - case ARITH_SUB: - return a - b; - case ARITH_LSHIFT: - return a << b; - case ARITH_RSHIFT: - return a >> b; - case ARITH_LT: - return a < b; - case ARITH_LE: - return a <= b; - case ARITH_GT: - return a > b; - case ARITH_GE: - return a >= b; - case ARITH_EQ: - return a == b; - case ARITH_NE: - return a != b; - case ARITH_BAND: - return a & b; - case ARITH_BXOR: - return a ^ b; - case ARITH_BOR: - return a | b; - } -} - -static int64_t primary(int token, union yystype *val, int op, int noeval) { - int64_t result; -again: - switch (token) { - case ARITH_LPAREN: - result = assignment(op, noeval); - if (last_token != ARITH_RPAREN) - yyerror("expecting ')'"); - last_token = shlex(); - return result; - case ARITH_NUM: - last_token = op; - return val->val; - case ARITH_VAR: - last_token = op; - return noeval ? val->val : lookupvarint(val->name); - case ARITH_ADD: - token = op; - *val = yylval; - op = shlex(); - goto again; - case ARITH_SUB: - *val = yylval; - return -primary(op, val, shlex(), noeval); - case ARITH_NOT: - *val = yylval; - return !primary(op, val, shlex(), noeval); - case ARITH_BNOT: - *val = yylval; - return ~primary(op, val, shlex(), noeval); - default: - yyerror("expecting primary"); - } -} - -static int64_t binop2(int64_t a, int op, int prec, int noeval) { - for (;;) { - union yystype val; - int64_t b; - int op2; - int token; - token = shlex(); - val = yylval; - b = primary(token, &val, shlex(), noeval); - op2 = last_token; - if (op2 >= ARITH_BINOP_MIN && op2 < ARITH_BINOP_MAX && - higher_prec(op2, op)) { - b = binop2(b, op2, arith_prec(op), noeval); - op2 = last_token; - } - a = noeval ? b : do_binop(op, a, b); - if (op2 < ARITH_BINOP_MIN || op2 >= ARITH_BINOP_MAX || - arith_prec(op2) >= prec) { - return a; - } - op = op2; - } -} - -static int64_t binop(int token, union yystype *val, int op, int noeval) { - int64_t a = primary(token, val, op, noeval); - op = last_token; - if (op < ARITH_BINOP_MIN || op >= ARITH_BINOP_MAX) - return a; - return binop2(a, op, ARITH_MAX_PREC, noeval); -} - -static int64_t and (int token, union yystype *val, int op, int noeval) { - int64_t a = binop(token, val, op, noeval); - int64_t b; - op = last_token; - if (op != ARITH_AND) - return a; - token = shlex(); - *val = yylval; - b = and(token, val, shlex(), noeval | !a); - return a && b; -} - -static int64_t or (int token, union yystype *val, int op, int noeval) { - int64_t a = and(token, val, op, noeval); - int64_t b; - op = last_token; - if (op != ARITH_OR) - return a; - token = shlex(); - *val = yylval; - b = or (token, val, shlex(), noeval | !!a); - return a || b; -} - -static int64_t cond(int token, union yystype *val, int op, int noeval) { - int64_t a = or (token, val, op, noeval); - int64_t b; - int64_t c; - if (last_token != ARITH_QMARK) - return a; - b = assignment(shlex(), noeval | !a); - if (last_token != ARITH_COLON) - yyerror("expecting ':'"); - token = shlex(); - *val = yylval; - c = cond(token, val, shlex(), noeval | !!a); - return a ? b : c; -} - -static int64_t assignment(int var_, int noeval) { - union yystype val = yylval; - int op = shlex(); - int64_t result; - if (var_ != ARITH_VAR) - return cond(var_, &val, op, noeval); - if (op != ARITH_ASS && (op < ARITH_ASS_MIN || op >= ARITH_ASS_MAX)) { - return cond(var_, &val, op, noeval); - } - result = assignment(shlex(), noeval); - if (noeval) - return result; - return setvarint( - val.name, - (op == ARITH_ASS ? result - : do_binop(op - 11, lookupvarint(val.name), result)), - 0); -} - -static int64_t arith(const char *s) { - int64_t result; - arith_buf = arith_startbuf = s; - result = assignment(shlex(), 0); - if (last_token) - yyerror("expecting EOF"); - return result; -} - -/* - * The cd and pwd commands. - */ -static inline int padvance(const char **path, const char *name) { - return padvance_magic(path, name, 1); -} - -static char *getpwd(void); -static const char *updatepwd(const char *); -static int cdopt(void); -static int docd(const char *, int); -static void setpwd(const char *, int); - -static int cdopt() { - int flags = 0; - int i, j; - j = 'L'; - while ((i = nextopt("LP"))) { - if (i != j) { - flags ^= CD_PHYSICAL; - j = i; - } - } - return flags; -} - -static int cdcmd(int argc, char **argv) { - const char *dest; - const char *path; - const char *p; - char c; - struct stat statb; - int flags; - int len; - flags = cdopt(); - dest = *argptr; - if (!dest) - dest = bltinlookup(homestr); - else if (dest[0] == '-' && dest[1] == '\0') { - dest = bltinlookup("OLDPWD"); - flags |= CD_PRINT; - } - if (!dest) - dest = nullstr; - if (*dest == '/') - goto step6; - if (*dest == '.') { - c = dest[1]; - dotdot: - switch (c) { - case '\0': - case '/': - goto step6; - case '.': - c = dest[2]; - if (c != '.') - goto dotdot; - } - } - if (!*dest) - dest = "."; - path = bltinlookup("CDPATH"); - while (p = path, (len = padvance_magic(&path, dest, 0)) >= 0) { - c = *p; - p = stalloc(len); - if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) { - if (c && c != ':') - flags |= CD_PRINT; - docd: - if (!docd(p, flags)) - goto out; - goto err; - } - } -step6: - p = dest; - goto docd; -err: - sh_error("can't cd to %s", dest); - __builtin_unreachable(); -out: - if (flags & CD_PRINT) - out1fmt(snlfmt, curdir); - return 0; -} - -/* - * Actually do the chdir. We also call hashcd to let the routines in exec.c - * know that the current directory has changed. - */ -static int docd(const char *dest, int flags) { - const char *dir = 0; - int err; - TRACE(("docd(\"%s\", %d) called\n", dest, flags)); - INTOFF; - if (!(flags & CD_PHYSICAL)) { - dir = updatepwd(dest); - if (dir) - dest = dir; - } - err = chdir(dest); - if (err) - goto out; - setpwd(dir, 1); - hashcd(); -out: - INTON; - return err; -} - -/* - * Update curdir (the name of the current directory) in response to a - * cd command. - */ -static const char *updatepwd(const char *dir) { - char *new; - char *p; - char *cdcomppath; - const char *lim; - cdcomppath = sstrdup(dir); - STARTSTACKSTR(new); - if (*dir != '/') { - if (curdir == nullstr) - return 0; - new = stputs(curdir, new); - } - new = makestrspace(strlen(dir) + 2, new); - lim = (char *)stackblock() + 1; - if (*dir != '/') { - if (new[-1] != '/') - USTPUTC('/', new); - if (new > lim && *lim == '/') - lim++; - } else { - USTPUTC('/', new); - cdcomppath++; - if (dir[1] == '/' && dir[2] != '/') { - USTPUTC('/', new); - cdcomppath++; - lim++; - } - } - p = strtok(cdcomppath, "/"); - while (p) { - switch (*p) { - case '.': - if (p[1] == '.' && p[2] == '\0') { - while (new > lim) { - STUNPUTC(new); - if (new[-1] == '/') - break; - } - break; - } else if (p[1] == '\0') - break; - /* fall through */ - default: - new = stputs(p, new); - USTPUTC('/', new); - } - p = strtok(0, "/"); - } - if (new > lim) - STUNPUTC(new); - *new = 0; - return stackblock(); -} - -/* - * Find out what the current directory is. If we already know the - * current directory, this routine returns immediately. - */ -static inline char *getpwd() { - char buf[PATH_MAX]; - if (getcwd(buf, sizeof(buf))) - return savestr(buf); - sh_warnx("getcwd() failed: %s", strerror(errno)); - return nullstr; -} - -static int pwdcmd(int argc, char **argv) { - int flags; - const char *dir = curdir; - flags = cdopt(); - if (flags) { - if (physdir == nullstr) - setpwd(dir, 0); - dir = physdir; - } - out1fmt(snlfmt, dir); - return 0; -} - -static void setpwd(const char *val, int setold) { - char *oldcur, *dir; - oldcur = dir = curdir; - if (setold) { - setvar("OLDPWD", oldcur, VEXPORT); - } - INTOFF; - if (physdir != nullstr) { - if (physdir != oldcur) - free(physdir); - physdir = nullstr; - } - if (oldcur == val || !val) { - char *s = getpwd(); - physdir = s; - if (!val) - dir = s; - } else - dir = savestr(val); - if (oldcur != dir && oldcur != nullstr) { - free(oldcur); - } - curdir = dir; - INTON; - setvar("PWD", dir, VEXPORT); -} - -/* - * Errors and exceptions. - */ - -/* - * NEOF is returned by parsecmd when it encounters an end of file. It - * must be distinct from NULL, so we use the address of a variable that - * happens to be handy. - */ -#define NEOF ((union node *)&tokpushback) - -/* - * Return of a legal variable name (a letter or underscore followed by zero or - * more letters, underscores, and digits). - */ -static char *endofname(const char *name) { - char *p; - p = (char *)name; - if (!is_name(*p)) - return p; - while (*++p) { - if (!is_in_name(*p)) - break; - } - return p; -} - -static inline int goodname(const char *p) { - return !*endofname(p); -} -static inline int parser_eof(void) { - return tokpushback && lasttoken == TEOF; -} -static inline int have_traps(void) { - return trapcnt; -} - -static const struct builtincmd kBltin = { - .name = nullstr, - .builtin = bltincmd, - .flags = BUILTIN_REGULAR, -}; - -/* - * Evaluate a parse tree. The value is left in the global variable - * exitstatus. - */ -static int evaltree(union node *n, int flags) { - int checkexit = 0; - int (*evalfn)(union node *, int); - struct stackmark smark; - unsigned isor; - int status = 0; - setstackmark(&smark); - if (nflag) - goto out; - if (n == NULL) { - TRACE(("evaltree(NULL) called\n")); - goto out; - } - dotrap(); - TRACE(("pid %d, evaltree(%p: %d, %d) called\n", getpid(), n, n->type, flags)); - switch (n->type) { - default: - case NNOT: - status = !evaltree(n->nnot.com, EV_TESTED); - goto setstatus; - case NREDIR: - errlinno = lineno = n->nredir.linno; - if (funcline) - lineno -= funcline - 1; - expredir(n->nredir.redirect); - pushredir(n->nredir.redirect); - status = (redirectsafe(n->nredir.redirect, REDIR_PUSH) - ?: evaltree(n->nredir.n, flags & EV_TESTED)); - if (n->nredir.redirect) - popredir(0); - goto setstatus; - case NCMD: - evalfn = evalcommand; - checkexit: - checkexit = ~flags & EV_TESTED; - goto calleval; - case NFOR: - evalfn = evalfor; - goto calleval; - case NWHILE: - case NUNTIL: - evalfn = evalloop; - goto calleval; - case NSUBSHELL: - case NBACKGND: - evalfn = evalsubshell; - goto checkexit; - case NPIPE: - evalfn = evalpipe; - goto checkexit; - case NCASE: - evalfn = evalcase; - goto calleval; - case NAND: - case NOR: - case NSEMI: - isor = n->type - NAND; - status = - evaltree(n->nbinary.ch1, (flags | ((isor >> 1) - 1)) & EV_TESTED); - if ((!status) == isor || evalskip) - break; - n = n->nbinary.ch2; - evaln: - evalfn = evaltree; - calleval: - status = evalfn(n, flags); - goto setstatus; - case NIF: - status = evaltree(n->nif.test, EV_TESTED); - if (evalskip) - break; - if (!status) { - n = n->nif.ifpart; - goto evaln; - } else if (n->nif.elsepart) { - n = n->nif.elsepart; - goto evaln; - } - status = 0; - goto setstatus; - case NDEFUN: - defun(n); - setstatus: - exitstatus = status; - break; - } -out: - dotrap(); - if (eflag && checkexit & status) - goto exexit; - if (flags & EV_EXIT) { - exexit: - exraise(EXEND); - } - popstackmark(&smark); - return exitstatus; -} - -wontreturn static void evaltreenr(union node *n, int flags) { - evaltree(n, flags); - abort(); -} - -/* - * Execute a command or commands contained in a string. - */ -static int evalstring(char *s, int flags) { - union node *n; - struct stackmark smark; - int status; - s = sstrdup(s); - setinputstring(s); - setstackmark(&smark); - status = 0; - for (; (n = parsecmd(0)) != NEOF; popstackmark(&smark)) { - int i; - i = evaltree(n, flags & ~(parser_eof() ? 0 : EV_EXIT)); - if (n) - status = i; - if (evalskip) - break; - } - popstackmark(&smark); - popfile(); - stunalloc(s); - return status; -} - -static int evalcmd(int argc, char **argv, int flags) { - char *p; - char *concat; - char **ap; - if (argc > 1) { - p = argv[1]; - if (argc > 2) { - STARTSTACKSTR(concat); - ap = argv + 2; - for (;;) { - concat = stputs(p, concat); - if ((p = *ap++) == NULL) - break; - STPUTC(' ', concat); - } - STPUTC('\0', concat); - p = grabstackstr(concat); - } - return evalstring(p, flags & EV_TESTED); - } - return 0; -} - -static int skiploop(void) { - int skip = evalskip; - switch (skip) { - case 0: - break; - case SKIPBREAK: - case SKIPCONT: - if (likely(--skipcount <= 0)) { - evalskip = 0; - break; - } - skip = SKIPBREAK; - break; - } - return skip; -} - -static int evalloop(union node *n, int flags) { - int skip; - int status; - loopnest++; - status = 0; - flags &= EV_TESTED; - do { - int i; - i = evaltree(n->nbinary.ch1, EV_TESTED); - skip = skiploop(); - if (skip == SKIPFUNC) - status = i; - if (skip) - continue; - if (n->type != NWHILE) - i = !i; - if (i != 0) - break; - status = evaltree(n->nbinary.ch2, flags); - skip = skiploop(); - } while (!(skip & ~SKIPCONT)); - loopnest--; - return status; -} - -static int evalfor(union node *n, int flags) { - struct arglist arglist; - union node *argp; - struct strlist *sp; - int status; - errlinno = lineno = n->nfor.linno; - if (funcline) - lineno -= funcline - 1; - arglist.lastp = &arglist.list; - for (argp = n->nfor.args; argp; argp = argp->narg.next) { - expandarg(argp, &arglist, EXP_FULL | EXP_TILDE); - } - *arglist.lastp = NULL; - status = 0; - loopnest++; - flags &= EV_TESTED; - for (sp = arglist.list; sp; sp = sp->next) { - setvar(n->nfor.var_, sp->text, 0); - status = evaltree(n->nfor.body, flags); - if (skiploop() & ~SKIPCONT) - break; - } - loopnest--; - return status; -} - -/* - * See if a pattern matches in a case statement. - */ -static int casematch(union node *pattern, char *val) { - struct stackmark smark; - int result; - setstackmark(&smark); - argbackq = pattern->narg.backquote; - STARTSTACKSTR(expdest); - argstr(pattern->narg.text, EXP_TILDE | EXP_CASE); - ifsfree(); - result = patmatch(stackblock(), val); - popstackmark(&smark); - return result; -} - -static int evalcase(union node *n, int flags) { - union node *cp; - union node *patp; - struct arglist arglist; - int status = 0; - errlinno = lineno = n->ncase.linno; - if (funcline) - lineno -= funcline - 1; - arglist.lastp = &arglist.list; - expandarg(n->ncase.expr, &arglist, EXP_TILDE); - for (cp = n->ncase.cases; cp && evalskip == 0; cp = cp->nclist.next) { - for (patp = cp->nclist.pattern; patp; patp = patp->narg.next) { - if (casematch(patp, arglist.list->text)) { - /* Ensure body is non-empty as otherwise - * EV_EXIT may prevent us from setting the - * exit status. - */ - if (evalskip == 0 && cp->nclist.body) { - status = evaltree(cp->nclist.body, flags); - } - goto out; - } - } - } -out: - return status; -} - -/* - * Kick off a subshell to evaluate a tree. - */ -static int evalsubshell(union node *n, int flags) { - struct job *jp; - int backgnd = (n->type == NBACKGND); - int status; - errlinno = lineno = n->nredir.linno; - if (funcline) - lineno -= funcline - 1; - expredir(n->nredir.redirect); - INTOFF; - if (!backgnd && flags & EV_EXIT && !have_traps()) { - forkreset(); - goto nofork; - } - jp = makejob(n, 1); - if (forkshell(jp, n, backgnd) == 0) { - flags |= EV_EXIT; - if (backgnd) - flags &= ~EV_TESTED; - nofork: - INTON; - redirect(n->nredir.redirect, 0); - evaltreenr(n->nredir.n, flags); - /* never returns */ - } - status = 0; - if (!backgnd) - status = waitforjob(jp); - INTON; - return status; -} - -/* - * Compute the names of the files in a redirection list. - */ -static void expredir(union node *n) { - union node *redir; - for (redir = n; redir; redir = redir->nfile.next) { - struct arglist fn; - fn.lastp = &fn.list; - switch (redir->type) { - case NFROMTO: - case NFROM: - case NTO: - case NCLOBBER: - case NAPPEND: - expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR); - redir->nfile.expfname = fn.list->text; - break; - case NFROMFD: - case NTOFD: - if (redir->ndup.vname) { - expandarg(redir->ndup.vname, &fn, EXP_TILDE | EXP_REDIR); - fixredir(redir, fn.list->text, 1); - } - break; - } - } -} - -/* - * Evaluate a pipeline. All the processes in the pipeline are children - * of the process creating the pipeline. (This differs from some versions - * of the shell, which make the last process in a pipeline the parent - * of all the rest.) - */ -static int evalpipe(union node *n, int flags) { - struct job *jp; - struct nodelist *lp; - int pipelen; - int prevfd; - int pip[2]; - int status = 0; - TRACE(("evalpipe(0x%lx) called\n", (long)n)); - pipelen = 0; - for (lp = n->npipe.cmdlist; lp; lp = lp->next) - pipelen++; - flags |= EV_EXIT; - INTOFF; - jp = makejob(n, pipelen); - prevfd = -1; - for (lp = n->npipe.cmdlist; lp; lp = lp->next) { - prehash(lp->n); - pip[1] = -1; - if (lp->next) { - if (pipe(pip) < 0) { - close(prevfd); - sh_error("Pipe call failed"); - } - } - if (forkshell(jp, lp->n, n->npipe.backgnd) == 0) { - INTON; - if (pip[1] >= 0) { - close(pip[0]); - } - if (prevfd > 0) { - dup2(prevfd, 0); - close(prevfd); - } - if (pip[1] > 1) { - dup2(pip[1], 1); - close(pip[1]); - } - evaltreenr(lp->n, flags); - /* never returns */ - } - if (prevfd >= 0) - close(prevfd); - prevfd = pip[0]; - close(pip[1]); - } - if (n->npipe.backgnd == 0) { - status = waitforjob(jp); - TRACE(("evalpipe: job done exit status %d\n", status)); - } - INTON; - return status; -} - -/* - * Execute a command inside back quotes. If it's a builtin command, we - * want to save its output in a block obtained from malloc. Otherwise - * we fork off a subprocess and get the output of the command via a pipe. - * Should be called with interrupts off. - */ -static void evalbackcmd(union node *n, struct backcmd *result) { - int pip[2]; - struct job *jp; - result->fd = -1; - result->buf = NULL; - result->nleft = 0; - result->jp = NULL; - if (n == NULL) { - goto out; - } - if (pipe(pip) < 0) - sh_error("Pipe call failed"); - jp = makejob(n, 1); - if (forkshell(jp, n, FORK_NOJOB) == 0) { - FORCEINTON; - close(pip[0]); - if (pip[1] != 1) { - dup2(pip[1], 1); - close(pip[1]); - } - ifsfree(); - evaltreenr(n, EV_EXIT); - __builtin_unreachable(); - } - close(pip[1]); - result->fd = pip[0]; - result->jp = jp; -out: - TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n", result->fd, - result->buf, result->nleft, result->jp)); -} - -static struct strlist *fill_arglist(struct arglist *arglist, - union node **argpp) { - struct strlist **lastp = arglist->lastp; - union node *argp; - while ((argp = *argpp)) { - expandarg(argp, arglist, EXP_FULL | EXP_TILDE); - *argpp = argp->narg.next; - if (*lastp) - break; - } - return *lastp; -} - -static int parse_command_args(struct arglist *arglist, union node **argpp, - const char **path) { - struct strlist *sp = arglist->list; - char *cp, c; - for (;;) { - sp = unlikely(sp->next != NULL) ? sp->next : fill_arglist(arglist, argpp); - if (!sp) - return 0; - cp = sp->text; - if (*cp++ != '-') - break; - if (!(c = *cp++)) - break; - if (c == '-' && !*cp) { - if (likely(!sp->next) && !fill_arglist(arglist, argpp)) - return 0; - sp = sp->next; - break; - } - do { - switch (c) { - case 'p': - *path = defpath; - break; - default: - /* run 'typecmd' for other options */ - return 0; - } - } while ((c = *cp++)); - } - arglist->list = sp; - return DO_NOFUNC; -} - -/* - * Execute a simple command. - */ -static int evalcommand(union node *cmd, int flags) { - struct localvar_list *localvar_stop; - struct parsefile *file_stop; - struct redirtab *redir_stop; - union node *argp; - struct arglist arglist; - struct arglist varlist; - char **argv; - int argc; - struct strlist *osp; - struct strlist *sp; - struct cmdentry cmdentry; - struct job *jp; - char *lastarg; - const char *path; - int spclbltin; - int cmd_flag; - int execcmd; - int status; - char **nargv; - int vflags; - int vlocal; - errlinno = lineno = cmd->ncmd.linno; - if (funcline) - lineno -= funcline - 1; - /* First expand the arguments. */ - TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags)); - file_stop = parsefile; - back_exitstatus = 0; - cmdentry.cmdtype = CMDBUILTIN; - cmdentry.u.cmd = &kBltin; - varlist.lastp = &varlist.list; - *varlist.lastp = NULL; - arglist.lastp = &arglist.list; - *arglist.lastp = NULL; - cmd_flag = 0; - execcmd = 0; - spclbltin = -1; - vflags = 0; - vlocal = 0; - path = NULL; - argc = 0; - argp = cmd->ncmd.args; - if ((osp = fill_arglist(&arglist, &argp))) { - int pseudovarflag = 0; - for (;;) { - find_command(arglist.list->text, &cmdentry, cmd_flag | DO_REGBLTIN, - pathval()); - vlocal++; - /* implement bltin and command here */ - if (cmdentry.cmdtype != CMDBUILTIN) - break; - pseudovarflag = cmdentry.u.cmd->flags & BUILTIN_ASSIGN; - if (likely(spclbltin < 0)) { - spclbltin = cmdentry.u.cmd->flags & BUILTIN_SPECIAL; - vlocal = spclbltin ^ BUILTIN_SPECIAL; - } - execcmd = cmdentry.u.cmd == EXECCMD; - if (likely(cmdentry.u.cmd != COMMANDCMD)) - break; - cmd_flag = parse_command_args(&arglist, &argp, &path); - if (!cmd_flag) - break; - } - for (; argp; argp = argp->narg.next) { - expandarg(argp, &arglist, - (pseudovarflag && isassignment(argp->narg.text)) - ? EXP_VARTILDE - : EXP_FULL | EXP_TILDE); - } - for (sp = arglist.list; sp; sp = sp->next) - argc++; - if (execcmd && argc > 1) - vflags = VEXPORT; - } - localvar_stop = pushlocalvars(vlocal); - /* Reserve one extra spot at the front for shellexec. */ - nargv = stalloc(sizeof(char *) * (argc + 2)); - argv = ++nargv; - for (sp = arglist.list; sp; sp = sp->next) { - TRACE(("evalcommand arg: %s\n", sp->text)); - *nargv++ = sp->text; - } - *nargv = NULL; - lastarg = NULL; - if (iflag && funcline == 0 && argc > 0) - lastarg = nargv[-1]; - preverrout.fd = 2; - expredir(cmd->ncmd.redirect); - redir_stop = pushredir(cmd->ncmd.redirect); - status = redirectsafe(cmd->ncmd.redirect, REDIR_PUSH | REDIR_SAVEFD2); - if (unlikely(status)) { - bail: - exitstatus = status; - /* We have a redirection error. */ - if (spclbltin > 0) - exraise(EXERROR); - goto out; - } - for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) { - struct strlist **spp; - spp = varlist.lastp; - expandarg(argp, &varlist, EXP_VARTILDE); - if (vlocal) - mklocal((*spp)->text, VEXPORT); - else - setvareq((*spp)->text, vflags); - } - /* Print the command if xflag is set. */ - if (xflag && !inps4) { - struct output *out; - int sep; - out = &preverrout; - inps4 = 1; - outstr(expandstr(ps4val()), out); - inps4 = 0; - sep = 0; - sep = eprintlist(out, varlist.list, sep); - eprintlist(out, osp, sep); - outcslow('\n', out); - } - /* Now locate the command. */ - if (cmdentry.cmdtype != CMDBUILTIN || - !(cmdentry.u.cmd->flags & BUILTIN_REGULAR)) { - path = unlikely(path != NULL) ? path : pathval(); /* wut */ - find_command(argv[0], &cmdentry, cmd_flag | DO_ERR, path); - } - jp = NULL; - /* Execute the command. */ - switch (cmdentry.cmdtype) { - case CMDUNKNOWN: - status = 127; - goto bail; - default: - /* Fork off a child process if necessary. */ - if (!(flags & EV_EXIT) || have_traps()) { - INTOFF; - jp = vforkexec(cmd, argv, path, cmdentry.u.index); - break; - } - shellexec(argv, path, cmdentry.u.index); - __builtin_unreachable(); - case CMDBUILTIN: - if (evalbltin(cmdentry.u.cmd, argc, argv, flags) && - !(exception == EXERROR && spclbltin <= 0)) { - raise: - longjmp(handler->loc, 1); - } - break; - case CMDFUNCTION: - if (evalfun(cmdentry.u.func, argc, argv, flags)) - goto raise; - break; - } - status = waitforjob(jp); - FORCEINTON; -out: - if (cmd->ncmd.redirect) - popredir(execcmd); - unwindredir(redir_stop); - unwindfiles(file_stop); - unwindlocalvars(localvar_stop); - if (lastarg) { - /* dsl: I think this is intended to be used to support - * '_' in 'vi' command mode during line editing... - * However I implemented that within libedit itself. - */ - setvar("_", lastarg, 0); - } - return status; -} - -static int evalbltin(const struct builtincmd *cmd, int argc, char **argv, - int flags) { - char *volatile savecmdname; - struct jmploc *volatile savehandler; - struct jmploc jmploc; - int status; - int i; - - savecmdname = commandname; - savehandler = handler; - if ((i = setjmp(jmploc.loc))) - goto cmddone; - handler = &jmploc; - commandname = argv[0]; - argptr = argv + 1; - optptr = NULL; /* initialize nextopt */ - if (cmd == EVALCMD) - status = evalcmd(argc, argv, flags); - else - status = (*cmd->builtin)(argc, argv); - flushall(); - if (out1->flags) - sh_warnx("%s: I/O error", commandname); - status |= out1->flags; - exitstatus = status; -cmddone: - freestdout(); - commandname = savecmdname; - handler = savehandler; - - return i; -} - -/* - * Free a parse tree. - */ -static void freefunc(struct funcnode *f) { - if (f && --f->count < 0) - ckfree(f); -} - -static int evalfun(struct funcnode *func, int argc, char **argv, int flags) { - volatile struct shparam saveparam; - struct jmploc *volatile savehandler; - struct jmploc jmploc; - int e; - int savefuncline; - int saveloopnest; - saveparam = shellparam; - savefuncline = funcline; - saveloopnest = loopnest; - savehandler = handler; - if ((e = setjmp(jmploc.loc))) { - goto funcdone; - } - INTOFF; - handler = &jmploc; - shellparam.malloc = 0; - func->count++; - funcline = func->n.ndefun.linno; - loopnest = 0; - INTON; - shellparam.nparam = argc - 1; - shellparam.p = argv + 1; - shellparam.optind = 1; - shellparam.optoff = -1; - evaltree(func->n.ndefun.body, flags & EV_TESTED); -funcdone: - INTOFF; - loopnest = saveloopnest; - funcline = savefuncline; - freefunc(func); - freeparam(&shellparam); - shellparam = saveparam; - handler = savehandler; - INTON; - evalskip &= ~(SKIPFUNC | SKIPFUNCDEF); - return e; -} - -/* - * Search for a command. This is called before we fork so that the - * location of the command will be available in the parent as well as - * the child. The check for "goodname" is an overly conservative - * check that the name will not be subject to expansion. - */ -static void prehash(union node *n) { - struct cmdentry entry; - if (n->type == NCMD && n->ncmd.args) { - if (goodname(n->ncmd.args->narg.text)) { - find_command(n->ncmd.args->narg.text, &entry, 0, pathval()); - } - } -} - -/*───────────────────────────────────────────────────────────────────────────│─╗ -β”‚ cosmopolitan Β§ the unbourne shell Β» builtins ─╬─│┼ -β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”‚β”€β• - Builtin commands whose functions are closely tied to evaluation are - implemented here. */ - -static int falsecmd(int argc, char **argv) { - return 1; -} - -static int truecmd(int argc, char **argv) { - return 0; -} - -/* No command given. */ -static int bltincmd(int argc, char **argv) { - /* - * Preserve exitstatus of a previous possible redirection - * as POSIX mandates - */ - return back_exitstatus; -} - -/* - * Handle break and continue commands. Break, continue, and return are - * all handled by setting the evalskip flag. The evaluation routines - * above all check this flag, and if it is set they start skipping - * commands rather than executing them. The variable skipcount is - * the number of loops to break/continue, or the number of function - * levels to return. (The latter is always 1.) It should probably - * be an error to break out of more loops than exist, but it isn't - * in the standard shell so we don't make it one here. - */ -static int breakcmd(int argc, char **argv) { - int n = argc > 1 ? number(argv[1]) : 1; - if (n <= 0) - badnum(argv[1]); - if (n > loopnest) - n = loopnest; - if (n > 0) { - evalskip = (**argv == 'c') ? SKIPCONT : SKIPBREAK; - skipcount = n; - } - return 0; -} - -/* The return command. */ -static int returncmd(int argc, char **argv) { - int skip; - int status; - /* - * If called outside a function, do what ksh does; - * skip the rest of the file. - */ - if (argv[1]) { - skip = SKIPFUNC; - status = number(argv[1]); - } else { - skip = SKIPFUNCDEF; - status = exitstatus; - } - evalskip = skip; - return status; -} - -static int execcmd(int argc, char **argv) { - if (argc > 1) { - iflag = 0; /* exit on error */ - mflag = 0; - optschanged(); - shellexec(argv + 1, pathval(), 0); - } - return 0; -} - -static int eprintlist(struct output *out, struct strlist *sp, int sep) { - while (sp) { - const char *p; - p = &" %s"[!sep]; /* XXX: -Wstring-plus-int: p = " %s" + (1 - sep); */ - sep |= 1; - outfmt(out, p, sp->text); - sp = sp->next; - } - return sep; -} - -/* - * When commands are first encountered, they are entered in a hash table. - * This ensures that a full path search will not have to be done for them - * on each invocation. - * - * We should investigate converting to a linear search, even though that - * would make the command name "hash" a misnomer. - */ - -/* - * Exec a program. Never returns. If you change this routine, you may - * have to change the find_command routine as well. - */ -wontreturn static void shellexec(char **argv, const char *path, int idx) { - char *cmdname; - int e; - char **envp; - int exerrno; - envp = environment(); - if (strchr(argv[0], '/') != NULL) { - tryexec(argv[0], argv, envp); - e = errno; - } else { - e = ENOENT; - while (padvance(&path, argv[0]) >= 0) { - cmdname = stackblock(); - if (--idx < 0 && pathopt == NULL) { - tryexec(cmdname, argv, envp); - if (errno != ENOENT && errno != ENOTDIR) - e = errno; - } - } - } - /* Map to POSIX errors */ - exerrno = (e == ELOOP || e == ENAMETOOLONG || e == ENOENT || e == ENOTDIR) - ? 127 - : 126; - exitstatus = exerrno; - TRACE(("shellexec failed for %s, errno %d, suppressint %d\n", argv[0], e, - suppressint)); - exerror(EXEND, "%s: %s", argv[0], errmsg(e, E_EXEC)); -} - -static void tryexec(char *cmd, char **argv, char **envp) { - char *const path_bshell = _PATH_BSHELL; -repeat: - execve(cmd, argv, envp); - if (cmd != path_bshell && errno == ENOEXEC) { - *argv-- = cmd; - *argv = cmd = path_bshell; - goto repeat; - } -} - -static const char *legal_pathopt(const char *opt, const char *term, int magic) { - switch (magic) { - case 0: - opt = NULL; - break; - case 1: - opt = prefix(opt, "builtin") ?: prefix(opt, "func"); - break; - default: - opt += strcspn(opt, term); - break; - } - if (opt && *opt == '%') - opt++; - return opt; -} - -/* - * Do a path search. The variable path (passed by reference) should be - * set to the start of the path before the first call; padvance will update - * this value as it proceeds. Successive calls to padvance will return - * the possible path expansions in sequence. If an option (indicated by - * a percent sign) appears in the path entry then the global variable - * pathopt will be set to point to it; otherwise pathopt will be set to - * NULL. - * - * If magic is 0 then pathopt recognition will be disabled. If magic is - * 1 we shall recognise %builtin/%func. Otherwise we shall accept any - * pathopt. - */ -static int padvance_magic(const char **path, const char *name, int magic) { - const char *term = "%:"; - const char *lpathopt; - const char *p; - char *q; - const char *start; - unsigned qlen; - unsigned len; - if (*path == NULL) - return -1; - lpathopt = NULL; - start = *path; - if (*start == '%' && (p = legal_pathopt(start + 1, term, magic))) { - lpathopt = start + 1; - start = p; - term = ":"; - } - len = strcspn(start, term); - p = start + len; - if (*p == '%') { - unsigned extra = strchrnul(p, ':') - p; - if (legal_pathopt(p + 1, term, magic)) - lpathopt = p + 1; - else - len += extra; - p += extra; - } - pathopt = lpathopt; - *path = *p == ':' ? p + 1 : NULL; - /* "2" is for '/' and '\0' */ - qlen = len + strlen(name) + 2; - q = growstackto(qlen); - if (likely(len)) { - q = mempcpy(q, start, len); - *q++ = '/'; - } - strcpy(q, name); - return qlen; -} - -/*** Command hashing code ***/ -static int hashcmd(int argc, char **argv) { - struct tblentry **pp; - struct tblentry *cmdp; - int c; - struct cmdentry entry; - char *name; - while ((c = nextopt("r")) != '\0') { - clearcmdentry(); - return 0; - } - if (*argptr == NULL) { - for (pp = cmdtable; pp < &cmdtable[CMDTABLESIZE]; pp++) { - for (cmdp = *pp; cmdp; cmdp = cmdp->next) { - if (cmdp->cmdtype == CMDNORMAL) { - printentry(cmdp); - } - } - } - return 0; - } - c = 0; - while ((name = *argptr) != NULL) { - if ((cmdp = cmdlookup(name, 0)) && - (cmdp->cmdtype == CMDNORMAL || - (cmdp->cmdtype == CMDBUILTIN && - !(cmdp->param.cmd->flags & BUILTIN_REGULAR) && builtinloc > 0))) { - delete_cmd_entry(); - } - find_command(name, &entry, DO_ERR, pathval()); - if (entry.cmdtype == CMDUNKNOWN) - c = 1; - argptr++; - } - return c; -} - -static void printentry(struct tblentry *cmdp) { - int idx; - const char *path; - char *name; - idx = cmdp->param.index; - path = pathval(); - do { - padvance(&path, cmdp->cmdname); - } while (--idx >= 0); - name = stackblock(); - outstr(name, out1); - out1fmt(snlfmt, cmdp->rehash ? "*" : nullstr); -} - -static int cmdloop(int top); - -/* - * Read a file containing shell functions. - */ -static void readcmdfile(char *name) { - setinputfile(name, INPUT_PUSH_FILE); - cmdloop(0); - popfile(); -} - -/* - * Search the table of builtin commands. - */ -static struct builtincmd *find_builtin(const char *name) { - return bsearch(&name, kBuiltinCmds, - sizeof(kBuiltinCmds) / sizeof(kBuiltinCmds[0]), - sizeof(kBuiltinCmds[0]), pstrcmp); -} - -/* - * Resolve a command name. If you change this routine, you may have to - * change the shellexec routine as well. - */ -static void find_command(char *name, struct cmdentry *entry, int act, - const char *path) { - char *fullname; - struct stat statb; - struct tblentry *cmdp; - struct builtincmd *bcmd; - int e, bit, idx, prev, updatetbl, len; - /* If name contains a slash, don't use PATH or hash table */ - if (strchr(name, '/') != NULL) { - entry->u.index = -1; - if (act & DO_ABS) { - while (stat(name, &statb) < 0) { - entry->cmdtype = CMDUNKNOWN; - return; - } - } - entry->cmdtype = CMDNORMAL; - return; - } - updatetbl = (path == pathval()); - if (!updatetbl) - act |= DO_ALTPATH; - /* If name is in the table, check answer will be ok */ - if ((cmdp = cmdlookup(name, 0)) != NULL) { - switch (cmdp->cmdtype) { - default: - case CMDNORMAL: - bit = DO_ALTPATH | DO_REGBLTIN; - break; - case CMDFUNCTION: - bit = DO_NOFUNC; - break; - case CMDBUILTIN: - bit = cmdp->param.cmd->flags & BUILTIN_REGULAR ? 0 : DO_REGBLTIN; - break; - } - if (act & bit) { - if (act & bit & DO_REGBLTIN) - goto fail; - updatetbl = 0; - cmdp = NULL; - } else if (cmdp->rehash == 0) { - /* if not invalidated by cd, we're done */ - goto success; - } - } - /* If %builtin not in path, check for builtin next */ - bcmd = find_builtin(name); - if (bcmd && ((bcmd->flags & BUILTIN_REGULAR) | (act & DO_ALTPATH) | - (builtinloc <= 0))) { - goto builtin_success; - } - if (act & DO_REGBLTIN) - goto fail; - /* We have to search path. */ - prev = -1; /* where to start */ - if (cmdp && cmdp->rehash) { /* doing a rehash */ - if (cmdp->cmdtype == CMDBUILTIN) - prev = builtinloc; - else - prev = cmdp->param.index; - } - e = ENOENT; - idx = -1; -loop: - while ((len = padvance(&path, name)) >= 0) { - const char *lpathopt = pathopt; - fullname = stackblock(); - idx++; - if (lpathopt) { - if (*lpathopt == 'b') { - if (bcmd) - goto builtin_success; - continue; - } else if (!(act & DO_NOFUNC)) { - /* handled below */ - } else { - /* ignore unimplemented options */ - continue; - } - } - /* if rehash, don't redo absolute path names */ - if (fullname[0] == '/' && idx <= prev) { - if (idx < prev) - continue; - TRACE(("searchexec \"%s\": no change\n", name)); - goto success; - } - while (stat(fullname, &statb) < 0) { - if (errno != ENOENT && errno != ENOTDIR) - e = errno; - goto loop; - } - e = EACCES; /* if we fail, this will be the error */ - if (!S_ISREG(statb.st_mode)) - continue; - if (lpathopt) { /* this is a %func directory */ - stalloc(len); - readcmdfile(fullname); - if ((cmdp = cmdlookup(name, 0)) == NULL || cmdp->cmdtype != CMDFUNCTION) { - sh_error("%s not defined in %s", name, fullname); - } - stunalloc(fullname); - goto success; - } - TRACE(("searchexec \"%s\" returns \"%s\"\n", name, fullname)); - if (!updatetbl) { - entry->cmdtype = CMDNORMAL; - entry->u.index = idx; - return; - } - INTOFF; - cmdp = cmdlookup(name, 1); - cmdp->cmdtype = CMDNORMAL; - cmdp->param.index = idx; - INTON; - goto success; - } - /* We failed. If there was an entry for this command, delete it */ - if (cmdp && updatetbl) - delete_cmd_entry(); - if (act & DO_ERR) - sh_warnx("%s: %s", name, errmsg(e, E_EXEC)); -fail: - entry->cmdtype = CMDUNKNOWN; - return; -builtin_success: - if (!updatetbl) { - entry->cmdtype = CMDBUILTIN; - entry->u.cmd = bcmd; - return; - } - INTOFF; - cmdp = cmdlookup(name, 1); - cmdp->cmdtype = CMDBUILTIN; - cmdp->param.cmd = bcmd; - INTON; -success: - cmdp->rehash = 0; - entry->cmdtype = cmdp->cmdtype; - entry->u = cmdp->param; -} - -/* - * Called when a cd is done. Marks all commands so the next time they - * are executed they will be rehashed. - */ -static void hashcd(void) { - struct tblentry **pp; - struct tblentry *cmdp; - for (pp = cmdtable; pp < &cmdtable[CMDTABLESIZE]; pp++) { - for (cmdp = *pp; cmdp; cmdp = cmdp->next) { - if (cmdp->cmdtype == CMDNORMAL || - (cmdp->cmdtype == CMDBUILTIN && - !(cmdp->param.cmd->flags & BUILTIN_REGULAR) && builtinloc > 0)) { - cmdp->rehash = 1; - } - } - } -} - -/* - * Fix command hash table when PATH changed. - * Called before PATH is changed. The argument is the new value of PATH; - * pathval() still returns the old value at this point. - * Called with interrupts off. - */ -static void changepath(const char *newval) { - int idx; - int bltin; - const char *neu; - neu = newval; - idx = 0; - bltin = -1; - for (;;) { - if (*neu == '%' && prefix(neu + 1, "builtin")) { - bltin = idx; - break; - } - neu = strchr(neu, ':'); - if (!neu) - break; - idx++; - neu++; - } - builtinloc = bltin; - clearcmdentry(); -} - -/* - * Clear out command entries. The argument specifies the first entry in - * PATH which has changed. - */ -static void clearcmdentry(void) { - struct tblentry **tblp; - struct tblentry **pp; - struct tblentry *cmdp; - INTOFF; - for (tblp = cmdtable; tblp < &cmdtable[CMDTABLESIZE]; tblp++) { - pp = tblp; - while ((cmdp = *pp) != NULL) { - if (cmdp->cmdtype == CMDNORMAL || - (cmdp->cmdtype == CMDBUILTIN && - !(cmdp->param.cmd->flags & BUILTIN_REGULAR) && builtinloc > 0)) { - *pp = cmdp->next; - ckfree(cmdp); - } else { - pp = &cmdp->next; - } - } - } - INTON; -} - -/* - * Locate a command in the command hash table. If "add" is nonzero, - * add the command to the table if it is not already present. The - * variable "lastcmdentry" is set to point to the address of the link - * pointing to the entry, so that delete_cmd_entry can delete the - * entry. - * - * Interrupts must be off if called with add != 0. - */ -static struct tblentry *cmdlookup(const char *name, int add) { - unsigned int hashval; - const char *p; - struct tblentry *cmdp; - struct tblentry **pp; - p = name; - hashval = (unsigned char)*p << 4; - while (*p) - hashval += (unsigned char)*p++; - hashval &= 0x7FFF; - pp = &cmdtable[hashval % CMDTABLESIZE]; - for (cmdp = *pp; cmdp; cmdp = cmdp->next) { - if (equal(cmdp->cmdname, name)) - break; - pp = &cmdp->next; - } - if (add && cmdp == NULL) { - cmdp = *pp = ckmalloc(sizeof(struct tblentry) + strlen(name) + 1); - cmdp->next = NULL; - cmdp->cmdtype = CMDUNKNOWN; - strcpy(cmdp->cmdname, name); - } - lastcmdentry = pp; - return cmdp; -} - -/* - * Delete the command entry returned on the last lookup. - */ -static void delete_cmd_entry(void) { - struct tblentry *cmdp; - INTOFF; - cmdp = *lastcmdentry; - *lastcmdentry = cmdp->next; - if (cmdp->cmdtype == CMDFUNCTION) - freefunc(cmdp->param.func); - ckfree(cmdp); - INTON; -} - -/* - * Add a new command entry, replacing any existing command entry for - * the same name - except special builtins. - */ -static void addcmdentry(char *name, struct cmdentry *entry) { - struct tblentry *cmdp; - cmdp = cmdlookup(name, 1); - if (cmdp->cmdtype == CMDFUNCTION) { - freefunc(cmdp->param.func); - } - cmdp->cmdtype = entry->cmdtype; - cmdp->param = entry->u; - cmdp->rehash = 0; -} - -/* Define a shell function. */ -static void defun(union node *func) { - struct cmdentry entry; - INTOFF; - entry.cmdtype = CMDFUNCTION; - entry.u.func = copyfunc(func); - addcmdentry(func->ndefun.text, &entry); - INTON; -} - -/* Delete a function if it exists. */ -static void unsetfunc(const char *name) { - struct tblentry *cmdp; - if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->cmdtype == CMDFUNCTION) { - delete_cmd_entry(); - } -} - -/* Locate and print what a word is... */ -static int typecmd(int argc, char **argv) { - int i; - int err = 0; - for (i = 1; i < argc; i++) { - err |= describe_command(out1, argv[i], NULL, 1); - } - return err; -} - -static int describe_command(struct output *out, char *command, const char *path, - int verbose) { - struct cmdentry entry; - struct tblentry *cmdp; - const struct alias *ap; - if (verbose) { - outstr(command, out); - } - /* First look at the keywords */ - if (findkwd(command)) { - outstr(verbose ? " is a shell keyword" : command, out); - goto out; - } - /* Then look at the aliases */ - if ((ap = lookupalias(command, 0)) != NULL) { - if (verbose) { - outfmt(out, " is an alias for %s", ap->val); - } else { - outstr("alias ", out); - printalias(ap); - return 0; - } - goto out; - } - /* Then if the standard search path is used, check if it is - * a tracked alias. - */ - if (path == NULL) { - path = pathval(); - cmdp = cmdlookup(command, 0); - } else { - cmdp = NULL; - } - if (cmdp != NULL) { - entry.cmdtype = cmdp->cmdtype; - entry.u = cmdp->param; - } else { - /* Finally use brute force */ - find_command(command, &entry, DO_ABS, path); - } - switch (entry.cmdtype) { - case CMDNORMAL: { - int j = entry.u.index; - char *p; - if (j == -1) { - p = command; - } else { - do { - padvance(&path, command); - } while (--j >= 0); - p = stackblock(); - } - if (verbose) { - outfmt(out, " is%s %s", cmdp ? " a tracked alias for" : nullstr, p); - } else { - outstr(p, out); - } - break; - } - case CMDFUNCTION: - if (verbose) { - outstr(" is a shell function", out); - } else { - outstr(command, out); - } - break; - case CMDBUILTIN: - if (verbose) { - outfmt(out, " is a %sshell builtin", - entry.u.cmd->flags & BUILTIN_SPECIAL ? "special " : nullstr); - } else { - outstr(command, out); - } - break; - default: - if (verbose) { - outstr(": not found\n", out); - } - return 127; - } -out: - outc('\n', out); - return 0; -} - -static int commandcmd(argc, argv) -int argc; -char **argv; -{ - char *cmd; - int c; - enum { - VERIFY_BRIEF = 1, - VERIFY_VERBOSE = 2, - } verify = 0; - const char *path = NULL; - while ((c = nextopt("pvV")) != '\0') - if (c == 'V') - verify |= VERIFY_VERBOSE; - else if (c == 'v') - verify |= VERIFY_BRIEF; - else - path = defpath; - cmd = *argptr; - if (verify && cmd) { - return describe_command(out1, cmd, path, verify - VERIFY_BRIEF); - } - return 0; -} - -/* - * Prepare a pattern for a glob(3) call. - * - * Returns an stalloced string. - */ -static inline char *preglob(const char *pattern, int flag) { - flag |= RMESCAPE_GLOB; - return rmescapes((char *)pattern, flag); -} - -static unsigned esclen(const char *start, const char *p) { - unsigned esc = 0; - while (p > start && *--p == (char)CTLESC) { - esc++; - } - return esc; -} - -static inline const char *getpwhome(const char *name) { - struct passwd *pw = getpwnam(name); - return pw ? pw->pw_dir : 0; -} - -static void ifsbreakup(char *string, int maxargs, struct arglist *arglist); -static void recordregion(int start, int end, int nulonly); - -/* - * Perform variable substitution and command substitution on an - * argument, placing the resulting list of arguments in arglist. If - * EXP_FULL is true, perform splitting and file name expansion. When - * arglist is NULL, perform here document expansion. - */ -static void expandarg(union node *arg, struct arglist *arglist, int flag) { - struct strlist *sp; - char *p; - argbackq = arg->narg.backquote; - STARTSTACKSTR(expdest); - argstr(arg->narg.text, flag); - if (arglist == NULL) { - /* here document expanded */ - goto out; - } - p = grabstackstr(expdest); - exparg.lastp = &exparg.list; - /* - * TODO - EXP_REDIR - */ - if (flag & EXP_FULL) { - ifsbreakup(p, -1, &exparg); - *exparg.lastp = NULL; - exparg.lastp = &exparg.list; - expandmeta(exparg.list); - } else { - sp = (struct strlist *)stalloc(sizeof(struct strlist)); - sp->text = p; - *exparg.lastp = sp; - exparg.lastp = &sp->next; - } - *exparg.lastp = NULL; - if (exparg.list) { - *arglist->lastp = exparg.list; - arglist->lastp = exparg.lastp; - } -out: - ifsfree(); -} - -/* - * Perform variable and command substitution. If EXP_FULL is set, output - * CTLESC characters to allow for further processing. Otherwise treat $@ - * like $* since no splitting will be performed. - */ -static char *argstr(char *p, int flag) { - static const int DOLATSTRLEN = 6; - static const char spclchars[] = {'=', ':', CTLQUOTEMARK, CTLENDVAR, - CTLESC, CTLVAR, CTLBACKQ, CTLARI, - CTLENDARI, 0}; - const char *reject = spclchars; - int c; - int breakall = (flag & (EXP_WORD | EXP_QUOTED)) == EXP_WORD; - int inquotes; - unsigned length; - int startloc; - reject += !!(flag & EXP_VARTILDE2); - reject += flag & EXP_VARTILDE ? 0 : 2; - inquotes = 0; - length = 0; - if (flag & EXP_TILDE) { - flag &= ~EXP_TILDE; - tilde: - if (*p == '~') - p = exptilde(p, flag); - } -start: - startloc = expdest - (char *)stackblock(); - for (;;) { - int end; - length += strcspn(p + length, reject); - end = 0; - c = (signed char)p[length]; - if (!(c & 0x80) || c == CTLENDARI || c == CTLENDVAR) { - /* - * c == '=' || c == ':' || c == '\0' || - * c == CTLENDARI || c == CTLENDVAR - */ - length++; - /* c == '\0' || c == CTLENDARI || c == CTLENDVAR */ - end = !!((c - 1) & 0x80); - } - if (length > 0 && !(flag & EXP_DISCARD)) { - int newloc; - char *q; - q = stnputs(p, length, expdest); - q[-1] &= end - 1; - expdest = q - (flag & EXP_WORD ? end : 0); - newloc = q - (char *)stackblock() - end; - if (breakall && !inquotes && newloc > startloc) { - recordregion(startloc, newloc, 0); - } - startloc = newloc; - } - p += length + 1; - length = 0; - if (end) - break; - switch (c) { - case '=': - flag |= EXP_VARTILDE2; - reject++; - /* fall through */ - case ':': - /* - * sort of a hack - expand tildes in variable - * assignments (after the first '=' and after ':'s). - */ - if (*--p == '~') { - goto tilde; - } - continue; - case CTLQUOTEMARK: - /* "$@" syntax adherence hack */ - if (!inquotes && !memcmp(p, dolatstr + 1, DOLATSTRLEN - 1)) { - p = evalvar(p + 1, flag | EXP_QUOTED) + 1; - goto start; - } - inquotes ^= EXP_QUOTED; - addquote: - if (flag & QUOTES_ESC) { - p--; - length++; - startloc++; - } - break; - case CTLESC: - startloc++; - length++; - goto addquote; - case CTLVAR: - p = evalvar(p, flag | inquotes); - goto start; - case CTLBACKQ: - expbackq(argbackq->n, flag | inquotes); - goto start; - case CTLARI: - p = expari(p, flag | inquotes); - goto start; - } - } - return p - 1; -} - -static char *exptilde(char *startp, int flag) { - signed char c; - char *name; - const char *home; - char *p; - p = startp; - name = p + 1; - while ((c = *++p) != '\0') { - switch (c) { - case CTLESC: - return (startp); - case CTLQUOTEMARK: - return (startp); - case ':': - if (flag & EXP_VARTILDE) - goto done; - break; - case '/': - case CTLENDVAR: - goto done; - } - } -done: - if (flag & EXP_DISCARD) - goto out; - *p = '\0'; - if (*name == '\0') { - home = lookupvar(homestr); - } else { - home = getpwhome(name); - } - *p = c; - if (!home) - goto lose; - strtodest(home, flag | EXP_QUOTED); -out: - return (p); -lose: - return (startp); -} - -static void removerecordregions(int endoff) { - if (ifslastp == NULL) - return; - if (ifsfirst.endoff > endoff) { - while (ifsfirst.next != NULL) { - struct ifsregion *ifsp; - INTOFF; - ifsp = ifsfirst.next->next; - ckfree(ifsfirst.next); - ifsfirst.next = ifsp; - INTON; - } - if (ifsfirst.begoff > endoff) - ifslastp = NULL; - else { - ifslastp = &ifsfirst; - ifsfirst.endoff = endoff; - } - return; - } - ifslastp = &ifsfirst; - while (ifslastp->next && ifslastp->next->begoff < endoff) { - ifslastp = ifslastp->next; - } - while (ifslastp->next != NULL) { - struct ifsregion *ifsp; - INTOFF; - ifsp = ifslastp->next->next; - ckfree(ifslastp->next); - ifslastp->next = ifsp; - INTON; - } - if (ifslastp->endoff > endoff) - ifslastp->endoff = endoff; -} - -/* - * Expand arithmetic expression. Backup to start of expression, - * evaluate, place result in (backed up) result, adjust string position. - */ -static char *expari(char *start, int flag) { - struct stackmark sm; - int begoff; - int endoff; - int len; - int64_t result; - char *p; - p = stackblock(); - begoff = expdest - p; - p = argstr(start, flag & EXP_DISCARD); - if (flag & EXP_DISCARD) - goto out; - start = stackblock(); - endoff = expdest - start; - start += begoff; - STADJUST(start - expdest, expdest); - removerecordregions(begoff); - if (likely(flag & QUOTES_ESC)) - rmescapes(start, 0); - pushstackmark(&sm, endoff); - result = arith(start); - popstackmark(&sm); - len = cvtnum(result, flag); - if (likely(!(flag & EXP_QUOTED))) - recordregion(begoff, begoff + len, 0); -out: - return p; -} - -/* - * Expand stuff in backwards quotes. - */ -static void expbackq(union node *cmd, int flag) { - struct backcmd in; - int i; - char buf[128]; - char *p; - char *dest; - int startloc; - struct stackmark smark; - if (flag & EXP_DISCARD) - goto out; - INTOFF; - startloc = expdest - (char *)stackblock(); - pushstackmark(&smark, startloc); - evalbackcmd(cmd, (struct backcmd *)&in); - popstackmark(&smark); - p = in.buf; - i = in.nleft; - if (i == 0) - goto read; - for (;;) { - memtodest(p, i, flag); - read: - if (in.fd < 0) - break; - do { - i = read(in.fd, buf, sizeof buf); - } while (i < 0 && errno == EINTR); - TRACE(("expbackq: read returns %d\n", i)); - if (i <= 0) - break; - p = buf; - } - if (in.buf) - ckfree(in.buf); - if (in.fd >= 0) { - close(in.fd); - back_exitstatus = waitforjob(in.jp); - } - INTON; - /* Eat all trailing newlines */ - dest = expdest; - for (; dest > ((char *)stackblock() + startloc) && dest[-1] == '\n';) { - STUNPUTC(dest); - } - expdest = dest; - if (!(flag & EXP_QUOTED)) { - recordregion(startloc, dest - (char *)stackblock(), 0); - } - TRACE(("evalbackq: size=%d: \"%.*s\"\n", - (dest - (char *)stackblock()) - startloc, - (dest - (char *)stackblock()) - startloc, - (char *)stackblock() + startloc)); -out: - argbackq = argbackq->next; -} - -static char *scanleft(char *startp, char *rmesc, char *rmescend, char *str, - int quotes, int zero) { - char *loc; - char *loc2; - char c; - loc = startp; - loc2 = rmesc; - do { - int match; - const char *s = loc2; - c = *loc2; - if (zero) { - *loc2 = '\0'; - s = rmesc; - } - match = pmatch(str, s); - *loc2 = c; - if (match) - return loc; - if (quotes && *loc == (char)CTLESC) - loc++; - loc++; - loc2++; - } while (c); - return 0; -} - -static char *scanright(char *startp, char *rmesc, char *rmescend, char *str, - int quotes, int zero) { - int esc = 0; - char *loc; - char *loc2; - for (loc = str - 1, loc2 = rmescend; loc >= startp; loc2--) { - int match; - char c = *loc2; - const char *s = loc2; - if (zero) { - *loc2 = '\0'; - s = rmesc; - } - match = pmatch(str, s); - *loc2 = c; - if (match) - return loc; - loc--; - if (quotes) { - if (--esc < 0) { - esc = esclen(startp, loc); - } - if (esc % 2) { - esc--; - loc--; - } - } - } - return 0; -} - -static char *subevalvar(char *start, char *str, int strloc, int startloc, - int varflags, int flag) { - int subtype = varflags & VSTYPE; - int quotes = flag & QUOTES_ESC; - char *startp; - char *loc; - long amount; - char *rmesc, *rmescend; - int zero; - char *(*scan)(char *, char *, char *, char *, int, int); - char *p; - p = argstr(start, (flag & EXP_DISCARD) | EXP_TILDE | (str ? 0 : EXP_CASE)); - if (flag & EXP_DISCARD) - return p; - startp = (char *)stackblock() + startloc; - switch (subtype) { - case VSASSIGN: - setvar(str, startp, 0); - loc = startp; - goto out; - case VSQUESTION: - varunset(start, str, startp, varflags); - __builtin_unreachable(); - } - subtype -= VSTRIMRIGHT; - rmesc = startp; - rmescend = (char *)stackblock() + strloc; - if (quotes) { - rmesc = rmescapes(startp, RMESCAPE_ALLOC | RMESCAPE_GROW); - if (rmesc != startp) { - rmescend = expdest; - startp = (char *)stackblock() + startloc; - } - } - rmescend--; - str = (char *)stackblock() + strloc; - preglob(str, 0); - /* zero = subtype == VSTRIMLEFT || subtype == VSTRIMLEFTMAX */ - zero = subtype >> 1; - /* VSTRIMLEFT/VSTRIMRIGHTMAX -> scanleft */ - scan = (subtype & 1) ^ zero ? scanleft : scanright; - loc = scan(startp, rmesc, rmescend, str, quotes, zero); - if (loc) { - if (zero) { - memmove(startp, loc, str - loc); - loc = startp + (str - loc) - 1; - } - *loc = '\0'; - } else - loc = str - 1; -out: - amount = loc - expdest; - STADJUST(amount, expdest); - /* Remove any recorded regions beyond start of variable */ - removerecordregions(startloc); - return p; -} - -/* - * Expand a variable, and return a pointer to the next character in the - * input string. - */ -static char *evalvar(char *p, int flag) { - int subtype; - int varflags; - char *var_; - int patloc; - int startloc; - long varlen; - int discard; - int quoted; - varflags = *p++; - subtype = varflags & VSTYPE; - quoted = flag & EXP_QUOTED; - var_ = p; - startloc = expdest - (char *)stackblock(); - p = strchr(p, '=') + 1; -again: - varlen = varvalue(var_, varflags, flag, quoted); - if (varflags & VSNUL) - varlen--; - discard = varlen < 0 ? EXP_DISCARD : 0; - switch (subtype) { - case VSPLUS: - discard ^= EXP_DISCARD; - /* fall through */ - case 0: - case VSMINUS: - p = argstr(p, flag | EXP_TILDE | EXP_WORD | (discard ^ EXP_DISCARD)); - goto record; - case VSASSIGN: - case VSQUESTION: - p = subevalvar(p, var_, 0, startloc, varflags, - (flag & ~QUOTES_ESC) | (discard ^ EXP_DISCARD)); - if ((flag | ~discard) & EXP_DISCARD) - goto record; - varflags &= ~VSNUL; - subtype = VSNORMAL; - goto again; - } - if ((discard & ~flag) && uflag) - varunset(p, var_, 0, 0); - if (subtype == VSLENGTH) { - p++; - if (flag & EXP_DISCARD) - return p; - cvtnum(varlen > 0 ? varlen : 0, flag); - goto really_record; - } - if (subtype == VSNORMAL) - goto record; - flag |= discard; - if (!(flag & EXP_DISCARD)) { - /* - * Terminate the string and start recording the pattern - * right after it - */ - STPUTC('\0', expdest); - } - patloc = expdest - (char *)stackblock(); - p = subevalvar(p, NULL, patloc, startloc, varflags, flag); -record: - if ((flag | discard) & EXP_DISCARD) - return p; -really_record: - if (quoted) { - quoted = *var_ == '@' && shellparam.nparam; - if (!quoted) - return p; - } - recordregion(startloc, expdest - (char *)stackblock(), quoted); - return p; -} - -/* - * Put a string on the stack. - */ -static unsigned memtodest(const char *p, unsigned len, int flags) { - const char *syntax = flags & EXP_QUOTED ? DQSYNTAX : BASESYNTAX; - char *q; - char *s; - if (unlikely(!len)) - return 0; - q = makestrspace(len * 2, expdest); - s = q; - do { - int c = (signed char)*p++; - if (c) { - if ((flags & QUOTES_ESC) && - ((syntax[c] == CCTL) || (flags & EXP_QUOTED && syntax[c] == CBACK))) { - USTPUTC(CTLESC, q); - } - } else if (!(flags & EXP_KEEPNUL)) - continue; - USTPUTC(c, q); - } while (--len); - expdest = q; - return q - s; -} - -static unsigned strtodest(const char *p, int flags) { - unsigned len = strlen(p); - memtodest(p, len, flags); - return len; -} - -/* - * Add the value of a specialized variable to the stack string. - */ -static long varvalue(char *name, int varflags, int flags, int quoted) { - int num; - char *p; - int i; - int sep; - char sepc; - char **ap; - int subtype = varflags & VSTYPE; - int discard = - (subtype == VSPLUS || subtype == VSLENGTH) | (flags & EXP_DISCARD); - long len = 0; - char c; - if (!subtype) { - if (discard) - return -1; - sh_error("Bad substitution"); - } - flags |= EXP_KEEPNUL; - flags &= discard ? ~QUOTES_ESC : ~0; - sep = (flags & EXP_FULL) << CHAR_BIT; - switch (*name) { - case '$': - num = rootpid; - goto numvar; - case '?': - num = exitstatus; - goto numvar; - case '#': - num = shellparam.nparam; - goto numvar; - case '!': - num = backgndpid; - if (num == 0) - return -1; - numvar: - len = cvtnum(num, flags); - break; - case '-': - p = makestrspace(NOPTS, expdest); - for (i = NOPTS - 1; i >= 0; i--) { - if (optlist[i] && optletters[i]) { - USTPUTC(optletters[i], p); - len++; - } - } - expdest = p; - break; - case '@': - if (quoted && sep) - goto param; - /* fall through */ - case '*': - /* We will set c to 0 or ~0 depending on whether - * we're doing field splitting. We won't do field - * splitting if either we're quoted or sep is zero. - * - * Instead of testing (quoted || !sep) the following - * trick optimises away any branches by using the - * fact that EXP_QUOTED (which is the only bit that - * can be set in quoted) is the same as EXP_FULL << - * CHAR_BIT (which is the only bit that can be set - * in sep). - */ - /* #if EXP_QUOTED >> CHAR_BIT != EXP_FULL */ - /* #error The following two lines expect EXP_QUOTED == EXP_FULL << - * CHAR_BIT */ - /* #endif */ - c = !((quoted | ~sep) & EXP_QUOTED) - 1; - sep &= ~quoted; - sep |= ifsset() ? (unsigned char)(c & ifsval()[0]) : ' '; - param: - sepc = sep; - if (!(ap = shellparam.p)) - return -1; - while ((p = *ap++)) { - len += strtodest(p, flags); - if (*ap && sep) { - len++; - memtodest(&sepc, 1, flags); - } - } - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - num = atoi(name); - if (num < 0 || num > shellparam.nparam) - return -1; - p = num ? shellparam.p[num - 1] : arg0; - goto value; - default: - p = lookupvar(name); - value: - if (!p) - return -1; - len = strtodest(p, flags); - break; - } - if (discard) - STADJUST(-len, expdest); - return len; -} - -/* - * Record the fact that we have to scan this region of the - * string for IFS characters. - */ -static void recordregion(int start, int end, int nulonly) { - struct ifsregion *ifsp; - if (ifslastp == NULL) { - ifsp = &ifsfirst; - } else { - INTOFF; - ifsp = (struct ifsregion *)ckmalloc(sizeof(struct ifsregion)); - ifsp->next = NULL; - ifslastp->next = ifsp; - INTON; - } - ifslastp = ifsp; - ifslastp->begoff = start; - ifslastp->endoff = end; - ifslastp->nulonly = nulonly; -} - -/* - * Break the argument string into pieces based upon IFS and add the - * strings to the argument list. The regions of the string to be - * searched for IFS characters have been stored by recordregion. - * If maxargs is non-negative, at most maxargs arguments will be created, by - * joining together the last arguments. - */ -static void ifsbreakup(char *string, int maxargs, struct arglist *arglist) { - struct ifsregion *ifsp; - struct strlist *sp; - char *start; - char *p; - char *q; - char *r = NULL; - const char *ifs, *realifs; - int ifsspc; - int nulonly; - start = string; - if (ifslastp != NULL) { - ifsspc = 0; - nulonly = 0; - realifs = ifsset() ? ifsval() : defifs; - ifsp = &ifsfirst; - do { - int afternul; - p = string + ifsp->begoff; - afternul = nulonly; - nulonly = ifsp->nulonly; - ifs = nulonly ? nullstr : realifs; - ifsspc = 0; - while (p < string + ifsp->endoff) { - int c; - bool isifs; - bool isdefifs; - q = p; - c = *p++; - if (c == (char)CTLESC) - c = *p++; - isifs = !!strchr(ifs, c); - isdefifs = false; - if (isifs) - isdefifs = !!strchr(defifs, c); - /* If only reading one more argument: - * If we have exactly one field, - * read that field without its terminator. - * If we have more than one field, - * read all fields including their terminators, - * except for trailing IFS whitespace. - * - * This means that if we have only IFS - * characters left, and at most one - * of them is non-whitespace, we stop - * reading here. - * Otherwise, we read all the remaining - * characters except for trailing - * IFS whitespace. - * - * In any case, r indicates the start - * of the characters to remove, or NULL - * if no characters should be removed. - */ - if (!maxargs) { - if (isdefifs) { - if (!r) - r = q; - continue; - } - if (!(isifs && ifsspc)) - r = NULL; - ifsspc = 0; - continue; - } - if (ifsspc) { - if (isifs) - q = p; - start = q; - if (isdefifs) - continue; - isifs = false; - } - if (isifs) { - if (!(afternul || nulonly)) - ifsspc = isdefifs; - /* Ignore IFS whitespace at start */ - if (q == start && ifsspc) { - start = p; - ifsspc = 0; - continue; - } - if (maxargs > 0 && !--maxargs) { - r = q; - continue; - } - *q = '\0'; - sp = (struct strlist *)stalloc(sizeof *sp); - sp->text = start; - *arglist->lastp = sp; - arglist->lastp = &sp->next; - start = p; - continue; - } - ifsspc = 0; - } - } while ((ifsp = ifsp->next) != NULL); - if (nulonly) - goto add; - } - if (r) - *r = '\0'; - if (!*start) - return; -add: - sp = (struct strlist *)stalloc(sizeof *sp); - sp->text = start; - *arglist->lastp = sp; - arglist->lastp = &sp->next; -} - -/* - * Expand shell metacharacters. At this point, the only control characters - * should be escapes. The results are stored in the list exparg. - */ -static void expandmeta(struct strlist *str) { - static const char metachars[] = {'*', '?', '[', 0}; - /* TODO - EXP_REDIR */ - while (str) { - struct strlist **savelastp; - struct strlist *sp; - char *p; - unsigned len; - if (fflag) - goto nometa; - if (!strpbrk(str->text, metachars)) - goto nometa; - savelastp = exparg.lastp; - INTOFF; - p = preglob(str->text, RMESCAPE_ALLOC | RMESCAPE_HEAP); - len = strlen(p); - expdir_max = len + PATH_MAX; - expdir = ckmalloc(expdir_max); - expmeta(p, len, 0); - ckfree(expdir); - if (p != str->text) - ckfree(p); - INTON; - if (exparg.lastp == savelastp) { - /* - * no matches - */ - nometa: - *exparg.lastp = str; - rmescapes(str->text, 0); - exparg.lastp = &str->next; - } else { - *exparg.lastp = NULL; - *savelastp = sp = expsort(*savelastp); - while (sp->next != NULL) - sp = sp->next; - exparg.lastp = &sp->next; - } - str = str->next; - } -} - -/* - * Do metacharacter (i.e. *, ?, [...]) expansion. - */ -static void expmeta(char *name, unsigned name_len, unsigned expdir_len) { - char *enddir = expdir + expdir_len; - char *p; - const char *cp; - char *start; - char *endname; - int metaflag; - struct stat statb; - DIR *dirp; - struct dirent *dp; - int atend; - int matchdot; - int esc; - metaflag = 0; - start = name; - for (p = name; esc = 0, *p; p += esc + 1) { - if (*p == '*' || *p == '?') - metaflag = 1; - else if (*p == '[') { - char *q = p + 1; - if (*q == '!') - q++; - for (;;) { - if (*q == '\\') - q++; - if (*q == '/' || *q == '\0') - break; - if (*++q == ']') { - metaflag = 1; - break; - } - } - } else { - if (*p == '\\' && p[1]) - esc++; - if (p[esc] == '/') { - if (metaflag) - break; - start = p + esc + 1; - } - } - } - if (metaflag == 0) { /* we've reached the end of the file name */ - if (!expdir_len) - return; - p = name; - do { - if (*p == '\\' && p[1]) - p++; - *enddir++ = *p; - } while (*p++); - if (lstat(expdir, &statb) >= 0) - addfname(expdir); - return; - } - endname = p; - if (name < start) { - p = name; - do { - if (*p == '\\' && p[1]) - p++; - *enddir++ = *p++; - } while (p < start); - } - *enddir = 0; - cp = expdir; - expdir_len = enddir - cp; - if (!expdir_len) - cp = "."; - if ((dirp = opendir(cp)) == NULL) - return; - if (*endname == 0) { - atend = 1; - } else { - atend = 0; - *endname = '\0'; - endname += esc + 1; - } - name_len -= endname - name; - matchdot = 0; - p = start; - if (*p == '\\') - p++; - if (*p == '.') - matchdot++; - while (!int_pending() && (dp = readdir(dirp)) != NULL) { - if (dp->d_name[0] == '.' && !matchdot) - continue; - if (pmatch(start, dp->d_name)) { - if (atend) { - scopy(dp->d_name, enddir); - addfname(expdir); - } else { - unsigned offset; - unsigned len; - p = stpcpy(enddir, dp->d_name); - *p = '/'; - offset = p - expdir + 1; - len = offset + name_len + NAME_MAX; - if (len > expdir_max) { - len += PATH_MAX; - expdir = ckrealloc(expdir, len); - expdir_max = len; - } - expmeta(endname, name_len, offset); - enddir = expdir + expdir_len; - } - } - } - closedir(dirp); - if (!atend) - endname[-esc - 1] = esc ? '\\' : '/'; -} - -/* - * Add a file name to the list. - */ -static void addfname(char *name) { - struct strlist *sp; - sp = (struct strlist *)stalloc(sizeof *sp); - sp->text = sstrdup(name); - *exparg.lastp = sp; - exparg.lastp = &sp->next; -} - -/* - * Sort the results of file name expansion. It calculates the number of - * strings to sort and then calls msort (short for merge sort) to do the - * work. - */ -static struct strlist *expsort(struct strlist *str) { - int len; - struct strlist *sp; - len = 0; - for (sp = str; sp; sp = sp->next) - len++; - return msort(str, len); -} - -static struct strlist *msort(struct strlist *list, int len) { - struct strlist *p, *q = NULL; - struct strlist **lpp; - int half; - int n; - if (len <= 1) - return list; - half = len >> 1; - p = list; - for (n = half; --n >= 0;) { - q = p; - p = p->next; - } - q->next = NULL; /* terminate first half of list */ - q = msort(list, half); /* sort first half of list */ - p = msort(p, len - half); /* sort second half */ - lpp = &list; - for (;;) { - if (strcmp(p->text, q->text) < 0) { - *lpp = p; - lpp = &p->next; - if ((p = *lpp) == NULL) { - *lpp = q; - break; - } - } else { - *lpp = q; - lpp = &q->next; - if ((q = *lpp) == NULL) { - *lpp = p; - break; - } - } - } - return list; -} - -/* - * Returns true if the pattern matches the string. - */ -static inline int patmatch(char *pattern, const char *string) { - return pmatch(preglob(pattern, 0), string); -} - -static int ccmatch(const char *p, int chr, const char **r) { - static const struct class { - char name[10]; - int (*fn)(int); - } classes[] = {{.name = ":alnum:]", .fn = isalnum}, - {.name = ":cntrl:]", .fn = iscntrl}, - {.name = ":lower:]", .fn = islower}, - {.name = ":space:]", .fn = isspace}, - {.name = ":alpha:]", .fn = isalpha}, - {.name = ":digit:]", .fn = isdigit}, - {.name = ":print:]", .fn = isprint}, - {.name = ":upper:]", .fn = isupper}, - {.name = ":blank:]", .fn = isblank}, - {.name = ":graph:]", .fn = isgraph}, - {.name = ":punct:]", .fn = ispunct}, - {.name = ":xdigit:]", .fn = isxdigit}}; - const struct class *class, *end; - end = classes + sizeof(classes) / sizeof(classes[0]); - for (class = classes; class < end; class ++) { - const char *q; - q = prefix(p, class->name); - if (!q) - continue; - *r = q; - return class->fn(chr); - } - *r = 0; - return 0; -} - -static int pmatch(const char *pattern, const char *string) { - const char *p, *q; - char c; - p = pattern; - q = string; - for (;;) { - switch (c = *p++) { - case '\0': - goto breakloop; - case '\\': - if (*p) { - c = *p++; - } - goto dft; - case '?': - if (*q++ == '\0') - return 0; - break; - case '*': - c = *p; - while (c == '*') - c = *++p; - if (c != '\\' && c != '?' && c != '*' && c != '[') { - while (*q != c) { - if (*q == '\0') - return 0; - q++; - } - } - do { - if (pmatch(p, q)) - return 1; - } while (*q++ != '\0'); - return 0; - case '[': { - const char *startp; - int invert, found; - char chr; - startp = p; - invert = 0; - if (*p == '!') { - invert++; - p++; - } - found = 0; - chr = *q; - if (chr == '\0') - return 0; - c = *p++; - do { - if (!c) { - p = startp; - c = '['; - goto dft; - } - if (c == '[') { - const char *r; - found |= !!ccmatch(p, chr, &r); - if (r) { - p = r; - continue; - } - } else if (c == '\\') - c = *p++; - if (*p == '-' && p[1] != ']') { - p++; - if (*p == '\\') - p++; - if (chr >= c && chr <= *p) - found = 1; - p++; - } else { - if (chr == c) - found = 1; - } - } while ((c = *p++) != ']'); - if (found == invert) - return 0; - q++; - break; - } - dft: - default: - if (*q++ != c) - return 0; - break; - } - } -breakloop: - if (*q != '\0') - return 0; - return 1; -} - -/* - * Remove any CTLESC characters from a string. - */ -static char *rmescapes(char *str, int flag) { - char *p, *q, *r; - int notescaped; - int globbing; - p = strpbrk(str, qchars); - if (!p) { - return str; - } - q = p; - r = str; - if (flag & RMESCAPE_ALLOC) { - unsigned len = p - str; - unsigned fulllen = len + strlen(p) + 1; - if (flag & RMESCAPE_GROW) { - int strloc = str - (char *)stackblock(); - r = makestrspace(fulllen, expdest); - str = (char *)stackblock() + strloc; - p = str + len; - } else if (flag & RMESCAPE_HEAP) { - r = ckmalloc(fulllen); - } else { - r = stalloc(fulllen); - } - q = r; - if (len > 0) { - q = mempcpy(q, str, len); - } - } - globbing = flag & RMESCAPE_GLOB; - notescaped = globbing; - while (*p) { - if (*p == (char)CTLQUOTEMARK) { - p++; - notescaped = globbing; - continue; - } - if (*p == '\\') { - /* naked back slash */ - notescaped = 0; - goto copy; - } - if (*p == (char)CTLESC) { - p++; - if (notescaped) - *q++ = '\\'; - } - notescaped = globbing; - copy: - *q++ = *p++; - } - *q = '\0'; - if (flag & RMESCAPE_GROW) { - expdest = r; - STADJUST(q - r + 1, expdest); - } - return r; -} - -/* - * Our own itoa(). - */ -static unsigned cvtnum(int64_t num, int flags) { - int len = max_int_length(sizeof(num)); - char buf[len]; - len = fmtstr(buf, len, "%ld", num); - return memtodest(buf, len, flags); -} - -static void freestrings(struct strpush *sp) { - INTOFF; - do { - struct strpush *psp; - if (sp->ap) { - sp->ap->flag &= ~ALIASINUSE; - if (sp->ap->flag & ALIASDEAD) - unalias(sp->ap->name); - } - psp = sp; - sp = sp->spfree; - if (psp != &(parsefile->basestrpush)) - ckfree(psp); - } while (sp); - parsefile->spfree = NULL; - INTON; -} - -static int pgetc_nofree(void) { - int c; - if (parsefile->unget) - return parsefile->lastc[--parsefile->unget]; - if (--parsefile->nleft >= 0) - c = (signed char)*parsefile->nextc++; - else - c = preadbuffer(); - parsefile->lastc[1] = parsefile->lastc[0]; - parsefile->lastc[0] = c; - return c; -} - -/* - * Read a character from the script, returning PEOF on end of file. - * Nul characters in the input are silently discarded. - */ -int pgetc(void) { - struct strpush *sp = parsefile->spfree; - if (unlikely(sp)) - freestrings(sp); - return pgetc_nofree(); -} - -static void AddUniqueCompletion(linenoiseCompletions *c, char *s) { - size_t i; - if (!s) - return; - for (i = 0; i < c->len; ++i) { - if (!strcmp(s, c->cvec[i])) { - return; - } - } - c->cvec = realloc(c->cvec, ++c->len * sizeof(*c->cvec)); - c->cvec[c->len - 1] = s; -} - -static void CompleteCommand(const char *p, const char *q, const char *b, - linenoiseCompletions *c) { - DIR *d; - size_t i; - struct dirent *e; - const char *x, *y, *path; - struct tblentry **pp, *cmdp; - for (pp = cmdtable; pp < &cmdtable[CMDTABLESIZE]; pp++) { - for (cmdp = *pp; cmdp; cmdp = cmdp->next) { - if (cmdp->cmdtype >= 0 && !strncmp(cmdp->cmdname, p, q - p)) { - AddUniqueCompletion(c, strdup(cmdp->cmdname)); - } - } - } - for (i = 0; i < ARRAYLEN(kBuiltinCmds); ++i) { - if (!strncmp(kBuiltinCmds[i].name, p, q - p)) { - AddUniqueCompletion(c, strdup(kBuiltinCmds[i].name)); - } - } - for (y = x = lookupvar("PATH"); *y; x = y + 1) { - if ((path = strndup(x, (y = strchrnul(x, ':')) - x))) { - if ((d = opendir(path))) { - while ((e = readdir(d))) { - if (e->d_type == DT_REG && !strncmp(e->d_name, p, q - p)) { - AddUniqueCompletion(c, strdup(e->d_name)); - } - } - closedir(d); - } - free((void *)path); - } - } -} - -static void CompleteFilename(const char *p, const char *q, const char *b, - linenoiseCompletions *c) { - DIR *d; - char *buf; - const char *g; - struct dirent *e; - if ((buf = malloc(512))) { - if ((g = memrchr(p, '/', q - p))) { - *(char *)mempcpy(buf, p, MIN(g - p, 511)) = 0; - p = ++g; - } else { - strcpy(buf, "."); - } - if ((d = opendir(buf))) { - while ((e = readdir(d))) { - if (!strcmp(e->d_name, ".")) - continue; - if (!strcmp(e->d_name, "..")) - continue; - if (!strncmp(e->d_name, p, q - p)) { - snprintf(buf, 512, "%.*s%s%s", p - b, b, e->d_name, - e->d_type == DT_DIR ? "/" : ""); - AddUniqueCompletion(c, strdup(buf)); - } - } - closedir(d); - } - free(buf); - } -} - -static void ShellCompletion(const char *p, linenoiseCompletions *c) { - bool slashed; - const char *q, *b; - for (slashed = false, b = p, q = (p += strlen(p)); p > b; --p) { - if (p[-1] == '/' && p[-1] == '\\') - slashed = true; - if (!isalnum(p[-1]) && - (p[-1] != '.' && p[-1] != '_' && p[-1] != '-' && p[-1] != '+' && - p[-1] != '[' && p[-1] != '/' && p[-1] != '\\')) { - break; - } - } - if (b == p && !slashed) { - CompleteCommand(p, q, b, c); - } else { - CompleteFilename(p, q, b, c); - } -} - -static char *ShellHint(const char *p, const char **ansi1, const char **ansi2) { - char *h = 0; - linenoiseCompletions c = {0}; - ShellCompletion(p, &c); - if (c.len == 1) { - h = strdup(c.cvec[0] + strlen(p)); - } - linenoiseFreeCompletions(&c); - return h; -} - -static ssize_t preadfd(void) { - ssize_t nr; - char *p, *buf = parsefile->buf; - parsefile->nextc = buf; -retry: - if (!parsefile->fd && isatty(0)) { - linenoiseSetFreeHintsCallback(free); - if (!IsWindows()) { - // TODO(jart): Cache $PATH search. - linenoiseSetHintsCallback(ShellHint); - linenoiseSetCompletionCallback(ShellCompletion); - } - char ps1[256]; - snprintf(ps1, sizeof(ps1), "%d >: ", exitstatus); - if ((p = linenoiseWithHistory(ps1, "unbourne"))) { - nr = min(strlen(p), IBUFSIZ - 2); - memcpy(buf, p, nr); - buf[nr++] = '\n'; - free(p); - } else { - write(1, "\n", 1); - nr = 0; - } - } else { - nr = read(parsefile->fd, buf, IBUFSIZ - 1); - } - if (nr < 0) { - if (errno == EINTR) - goto retry; - if (parsefile->fd == 0 && errno == EAGAIN) { - int flags = fcntl(0, F_GETFL, 0); - if (flags >= 0 && flags & O_NONBLOCK) { - flags &= ~O_NONBLOCK; - if (fcntl(0, F_SETFL, flags) >= 0) { - outstr("sh: turning off NDELAY mode\n", out2); - goto retry; - } - } - } - } - return nr; -} - -/* - * Refill the input buffer and return the next input character: - * - * 1) If a string was pushed back on the input, pop it; - * 2) If an EOF was pushed back (parsenleft == EOF_NLEFT) or we are reading - * from a string so we can't refill the buffer, return EOF. - * 3) If the is more stuff in this buffer, use it else call read to fill it. - * 4) Process input up to the next newline, deleting nul characters. - */ -static int preadbuffer(void) { - char *q; - int more; - char savec; - if (unlikely(parsefile->strpush)) { - popstring(); - return pgetc_nofree(); - } - if (unlikely(parsefile->nleft == EOF_NLEFT || parsefile->buf == NULL)) - return PEOF; - flushall(); - more = parsefile->lleft; - if (more <= 0) { - again: - if ((more = preadfd()) <= 0) { - parsefile->lleft = parsefile->nleft = EOF_NLEFT; - return PEOF; - } - } - q = parsefile->nextc; - /* delete nul characters */ - for (;;) { - int c; - more--; - c = *q; - if (!c) - memmove(q, q + 1, more); - else { - q++; - if (c == '\n') { - parsefile->nleft = q - parsefile->nextc - 1; - break; - } - } - if (more <= 0) { - parsefile->nleft = q - parsefile->nextc - 1; - if (parsefile->nleft < 0) - goto again; - break; - } - } - parsefile->lleft = more; - savec = *q; - *q = '\0'; - if (vflag) { - outstr(parsefile->nextc, out2); - } - *q = savec; - return (signed char)*parsefile->nextc++; -} - -/* - * Undo a call to pgetc. Only two characters may be pushed back. - * PEOF may be pushed back. - */ -static void pungetc(void) { - parsefile->unget++; -} - -/* - * Push a string back onto the input at this current parsefile level. - * We handle aliases this way. - */ -static void pushstring(char *s, void *ap) { - struct strpush *sp; - unsigned len; - len = strlen(s); - INTOFF; - /*dprintf("*** calling pushstring: %s, %d\n", s, len);*/ - if ((unsigned long)parsefile->strpush | (unsigned long)parsefile->spfree) { - sp = ckmalloc(sizeof(struct strpush)); - sp->prev = parsefile->strpush; - parsefile->strpush = sp; - } else - sp = parsefile->strpush = &(parsefile->basestrpush); - sp->prevstring = parsefile->nextc; - sp->prevnleft = parsefile->nleft; - sp->unget = parsefile->unget; - sp->spfree = parsefile->spfree; - memcpy(sp->lastc, parsefile->lastc, sizeof(sp->lastc)); - sp->ap = (struct alias *)ap; - if (ap) { - ((struct alias *)ap)->flag |= ALIASINUSE; - sp->string = s; - } - parsefile->nextc = s; - parsefile->nleft = len; - parsefile->unget = 0; - parsefile->spfree = NULL; - INTON; -} - -static void popstring(void) { - struct strpush *sp = parsefile->strpush; - INTOFF; - if (sp->ap) { - if (parsefile->nextc[-1] == ' ' || parsefile->nextc[-1] == '\t') { - checkkwd |= CHKALIAS; - } - if (sp->string != sp->ap->val) { - ckfree(sp->string); - } - } - parsefile->nextc = sp->prevstring; - parsefile->nleft = sp->prevnleft; - parsefile->unget = sp->unget; - memcpy(parsefile->lastc, sp->lastc, sizeof(sp->lastc)); - /*dprintf("*** calling popstring: restoring to '%s'\n", parsenextc);*/ - parsefile->strpush = sp->prev; - parsefile->spfree = sp; - INTON; -} - -/* - * Set the input to take input from a file. If push is set, push the - * old input onto the stack first. - */ -static int setinputfile(const char *fname, int flags) { - int fd; - INTOFF; - fd = sh_open(fname, O_RDONLY, flags & INPUT_NOFILE_OK); - if (fd < 0) - goto out; - if (fd < 10) - fd = savefd(fd, fd); - setinputfd(fd, flags & INPUT_PUSH_FILE); -out: - INTON; - return fd; -} - -/* - * Like setinputfile, but takes an open file descriptor. Call this with - * interrupts off. - */ -static void setinputfd(int fd, int push) { - if (push) { - pushfile(); - parsefile->buf = 0; - } - parsefile->fd = fd; - if (parsefile->buf == NULL) - parsefile->buf = ckmalloc(IBUFSIZ); - parsefile->lleft = parsefile->nleft = 0; - plinno = 1; -} - -/* - * Like setinputfile, but takes input from a string. - */ -static void setinputstring(char *string) { - INTOFF; - pushfile(); - parsefile->nextc = string; - parsefile->nleft = strlen(string); - parsefile->buf = NULL; - plinno = 1; - INTON; -} - -/* - * To handle the "." command, a stack of input files is used. Pushfile - * adds a new entry to the stack and popfile restores the previous level. - */ -static void pushfile(void) { - struct parsefile *pf; - pf = (struct parsefile *)ckmalloc(sizeof(struct parsefile)); - pf->prev = parsefile; - pf->fd = -1; - pf->strpush = NULL; - pf->spfree = NULL; - pf->basestrpush.prev = NULL; - pf->unget = 0; - parsefile = pf; -} - -static void popfile(void) { - struct parsefile *pf = parsefile; - INTOFF; - if (pf->fd >= 0) - close(pf->fd); - if (pf->buf) - ckfree(pf->buf); - if (parsefile->spfree) - freestrings(parsefile->spfree); - while (pf->strpush) { - popstring(); - freestrings(parsefile->spfree); - } - parsefile = pf->prev; - ckfree(pf); - INTON; -} - -static void unwindfiles(struct parsefile *stop) { - while (parsefile != stop) - popfile(); -} - -/* - * Return to top level. - */ -static void popallfiles(void) { - unwindfiles(&basepf); -} - -static char *commandtext(union node *); -static int dowait(int, struct job *); -static int getstatus(struct job *); -static int jobno(const struct job *); -static int restartjob(struct job *, int); -static int sprint_status(char *, int, int); -static int waitproc(int, int *); -static struct job *getjob(const char *, int); -static struct job *growjobtab(void); -static void cmdlist(union node *, int); -static void cmdputs(const char *); -static void cmdtxt(union node *); -static void forkchild(struct job *, union node *, int); -static void forkparent(struct job *, union node *, int, int); -static void freejob(struct job *); -static void set_curjob(struct job *, unsigned); -static void showpipe(struct job *, struct output *); -static void xtcsetpgrp(int, int); - -static void set_curjob(struct job *jp, unsigned mode) { - struct job *jp1; - struct job **jpp, **curp; - /* first remove from list */ - jpp = curp = &curjob; - do { - jp1 = *jpp; - if (jp1 == jp) - break; - jpp = &jp1->prev_job; - } while (1); - *jpp = jp1->prev_job; - /* Then re-insert in correct position */ - jpp = curp; - switch (mode) { - default: - case CUR_DELETE: - /* job being deleted */ - break; - case CUR_RUNNING: - /* newly created job or backgrounded job, - put after all stopped jobs. */ - do { - jp1 = *jpp; - if (!JOBS || !jp1 || jp1->state != JOBSTOPPED) - break; - jpp = &jp1->prev_job; - } while (1); - /* FALLTHROUGH */ - case CUR_STOPPED: - /* newly stopped job - becomes curjob */ - jp->prev_job = *jpp; - *jpp = jp; - break; - } -} - -/* - * Turn job control on and off. - * - * Note: This code assumes that the third arg to ioctl is a character - * pointer, which is true on Berkeley systems but not System V. Since - * System V doesn't have job control yet, this isn't a problem now. - * - * Called with interrupts off. - */ -static void setjobctl(int on) { - int fd; - int pgrp; - if (IsWindows()) - return; /* TODO(jart) */ - if (on == jobctl || rootshell == 0) - return; - if (on) { - int ofd; - ofd = fd = sh_open(_PATH_TTY, O_RDWR, 1); - if (fd < 0) { - fd += 3; - while (!isatty(fd)) - if (--fd < 0) - goto out; - } - fd = savefd(fd, ofd); - do { /* while we are in the background */ - if ((pgrp = tcgetpgrp(fd)) < 0) { - out: - sh_warnx("can't access tty; job control turned off"); - mflag = on = 0; - goto close; - } - if (pgrp == getpgrp()) - break; - killpg(0, SIGTTIN); - } while (1); - initialpgrp = pgrp; - setsignal(SIGTSTP); - setsignal(SIGTTOU); - setsignal(SIGTTIN); - pgrp = rootpid; - setpgid(0, pgrp); - xtcsetpgrp(fd, pgrp); - } else { - /* turning job control off */ - fd = ttyfd; - pgrp = initialpgrp; - xtcsetpgrp(fd, pgrp); - setpgid(0, pgrp); - setsignal(SIGTSTP); - setsignal(SIGTTOU); - setsignal(SIGTTIN); - close: - close(fd); - fd = -1; - } - ttyfd = fd; - jobctl = on; -} - -static int decode_signum(const char *string) { - int signo = -1; - if (is_number(string)) { - signo = atoi(string); - if (signo >= NSIG) - signo = -1; - } - return signo; -} - -static int killcmd(argc, argv) -int argc; -char **argv; -{ - int signo = -1; - int list = 0; - int i; - int pid; - struct job *jp; - if (argc <= 1) { - usage: - sh_error("Usage: kill [-s sigspec | -signum | -sigspec] [pid | job]... or\n" - "kill -l [exitstatus]"); - } - if (**++argv == '-') { - signo = decode_signal(*argv + 1, 1); - if (signo < 0) { - int c; - while ((c = nextopt("ls:")) != '\0') - switch (c) { - default: - case 'l': - list = 1; - break; - case 's': - signo = decode_signal(optionarg, 1); - if (signo < 0) { - sh_error("invalid signal number or name: %s", optionarg); - } - break; - } - argv = argptr; - } else - argv++; - } - if (!list && signo < 0) - signo = SIGTERM; - if ((signo < 0 || !*argv) ^ list) { - goto usage; - } - if (list) { - struct output *out; - out = out1; - if (!*argv) { - outstr("0\n", out); - for (i = 1; i < NSIG; i++) { - outfmt(out, snlfmt, strsignal(i)); - } - return 0; - } - signo = number(*argv); - if (signo > 128) - signo -= 128; - if (0 < signo && signo < NSIG) - outfmt(out, snlfmt, strsignal(signo)); - else - sh_error("invalid signal number or exit status: %s", *argv); - return 0; - } - i = 0; - do { - if (**argv == '%') { - jp = getjob(*argv, 0); - pid = -jp->ps[0].pid; - } else - pid = **argv == '-' ? -number(*argv + 1) : number(*argv); - if (kill(pid, signo) != 0) { - sh_warnx("%s\n", strerror(errno)); - i = 1; - } - } while (*++argv); - return i; -} - -static int jobno(const struct job *jp) { - return jp - jobtab + 1; -} - -static int fgcmd(int argc, char **argv) { - struct job *jp; - struct output *out; - int mode; - int retval; - mode = (**argv == 'f') ? FORK_FG : FORK_BG; - nextopt(nullstr); - argv = argptr; - out = out1; - do { - jp = getjob(*argv, 1); - if (mode == FORK_BG) { - set_curjob(jp, CUR_RUNNING); - outfmt(out, "[%d] ", jobno(jp)); - } - outstr(jp->ps->cmd, out); - showpipe(jp, out); - retval = restartjob(jp, mode); - } while (*argv && *++argv); - return retval; -} - -static int bgcmd(int argc, char **argv) __attribute__((__alias__("fgcmd"))); - -static int restartjob(struct job *jp, int mode) { - struct procstat *ps; - int i; - int status; - int pgid; - INTOFF; - if (jp->state == JOBDONE) - goto out; - jp->state = JOBRUNNING; - pgid = jp->ps->pid; - if (mode == FORK_FG) - xtcsetpgrp(ttyfd, pgid); - killpg(pgid, SIGCONT); - ps = jp->ps; - i = jp->nprocs; - do { - if (WIFSTOPPED(ps->status)) { - ps->status = -1; - } - } while (ps++, --i); -out: - status = (mode == FORK_FG) ? waitforjob(jp) : 0; - INTON; - return status; -} - -static int sprint_status(char *os, int status, int sigonly) { - char *s = os; - int st; - st = WEXITSTATUS(status); - if (!WIFEXITED(status)) { - st = WSTOPSIG(status); - if (!WIFSTOPPED(status)) - st = WTERMSIG(status); - if (sigonly) { - if (st == SIGINT || st == SIGPIPE) - goto out; - if (WIFSTOPPED(status)) - goto out; - } - s = stpncpy(s, strsignal(st), 32); - } else if (!sigonly) { - if (st) - s += fmtstr(s, 16, "Done(%d)", st); - else - s = stpcpy(s, "Done"); - } -out: - return s - os; -} - -static void showjob(struct output *out, struct job *jp, int mode) { - struct procstat *ps; - struct procstat *psend; - int col; - int indent; - char s[80]; - ps = jp->ps; - if (mode & SHOW_PGID) { - /* just output process (group) id of pipeline */ - outfmt(out, "%d\n", ps->pid); - return; - } - col = fmtstr(s, 16, "[%d] ", jobno(jp)); - indent = col; - if (jp == curjob) - s[col - 2] = '+'; - else if (curjob && jp == curjob->prev_job) - s[col - 2] = '-'; - if (mode & SHOW_PID) - col += fmtstr(s + col, 16, "%d ", ps->pid); - psend = ps + jp->nprocs; - if (jp->state == JOBRUNNING) { - scopy("Running", s + col); - col += strlen("Running"); - } else { - int status = psend[-1].status; - if (jp->state == JOBSTOPPED) - status = jp->stopstatus; - col += sprint_status(s + col, status, 0); - } - goto start; - do { - /* for each process */ - col = fmtstr(s, 48, " |\n%*c%d ", indent, ' ', ps->pid) - 3; - start: - outfmt(out, "%s%*c%s", s, 33 - col >= 0 ? 33 - col : 0, ' ', ps->cmd); - if (!(mode & SHOW_PID)) { - showpipe(jp, out); - break; - } - if (++ps == psend) { - outcslow('\n', out); - break; - } - } while (1); - jp->changed = 0; - if (jp->state == JOBDONE) { - TRACE(("showjob: freeing job %d\n", jobno(jp))); - freejob(jp); - } -} - -static int jobscmd(int argc, char **argv) { - int mode, m; - struct output *out; - mode = 0; - while ((m = nextopt("lp"))) - if (m == 'l') - mode = SHOW_PID; - else - mode = SHOW_PGID; - out = out1; - argv = argptr; - if (*argv) - do - showjob(out, getjob(*argv, 0), mode); - while (*++argv); - else - showjobs(out, mode); - return 0; -} - -/* - * Print a list of jobs. If "change" is nonzero, only print jobs whose - * statuses have changed since the last call to showjobs. - */ -static void showjobs(struct output *out, int mode) { - struct job *jp; - TRACE(("showjobs(%x) called\n", mode)); - /* If not even one job changed, there is nothing to do */ - dowait(DOWAIT_NONBLOCK, NULL); - for (jp = curjob; jp; jp = jp->prev_job) { - if (!(mode & SHOW_CHANGED) || jp->changed) - showjob(out, jp, mode); - } -} - -/* - * Mark a job structure as unused. - */ -static void freejob(struct job *jp) { - struct procstat *ps; - int i; - INTOFF; - for (i = jp->nprocs, ps = jp->ps; --i >= 0; ps++) { - if (ps->cmd != nullstr) - ckfree(ps->cmd); - } - if (jp->ps != &jp->ps0) - ckfree(jp->ps); - jp->used = 0; - set_curjob(jp, CUR_DELETE); - INTON; -} - -static int waitcmd(int argc, char **argv) { - struct job *job; - int retval; - struct job *jp; - nextopt(nullstr); - retval = 0; - argv = argptr; - if (!*argv) { - /* wait for all jobs */ - for (;;) { - jp = curjob; - while (1) { - if (!jp) { - /* no running procs */ - goto out; - } - if (jp->state == JOBRUNNING) - break; - jp->waited = 1; - jp = jp->prev_job; - } - if (!dowait(DOWAIT_WAITCMD_ALL, 0)) - goto sigout; - } - } - retval = 127; - do { - if (**argv != '%') { - int pid = number(*argv); - job = curjob; - goto start; - do { - if (job->ps[job->nprocs - 1].pid == pid) - break; - job = job->prev_job; - start: - if (!job) - goto repeat; - } while (1); - } else - job = getjob(*argv, 0); - /* loop until process terminated or stopped */ - if (!dowait(DOWAIT_WAITCMD, job)) - goto sigout; - job->waited = 1; - retval = getstatus(job); - repeat:; - } while (*++argv); -out: - return retval; -sigout: - retval = 128 + pending_sig; - goto out; -} - -/* - * Convert a job name to a job structure. - */ -static struct job *getjob(const char *name, int getctl) { - struct job *jp; - struct job *found; - const char *err_msg = "No such job: %s"; - unsigned num; - int c; - const char *p; - char *(*match)(const char *, const char *); - jp = curjob; - p = name; - if (!p) - goto currentjob; - if (*p != '%') - goto err; - c = *++p; - if (!c) - goto currentjob; - if (!p[1]) { - if (c == '+' || c == '%') { - currentjob: - err_msg = "No current job"; - goto check; - } else if (c == '-') { - if (jp) - jp = jp->prev_job; - err_msg = "No previous job"; - check: - if (!jp) - goto err; - goto gotit; - } - } - if (is_number(p)) { - num = atoi(p); - if (num > 0 && num <= njobs) { - jp = jobtab + num - 1; - if (jp->used) - goto gotit; - goto err; - } - } - match = prefix; - if (*p == '?') { - match = strstr; - p++; - } - found = 0; - while (jp) { - if (match(jp->ps[0].cmd, p)) { - if (found) - goto err; - found = jp; - err_msg = "%s: ambiguous"; - } - jp = jp->prev_job; - } - if (!found) - goto err; - jp = found; -gotit: - err_msg = "job %s not created under job control"; - if (getctl && jp->jobctl == 0) - goto err; - return jp; -err: - sh_error(err_msg, name); -} - -/* - * Return a new job structure. - * Called with interrupts off. - */ -struct job *makejob(union node *node, int nprocs) { - int i; - struct job *jp; - for (i = njobs, jp = jobtab;; jp++) { - if (--i < 0) { - jp = growjobtab(); - break; - } - if (jp->used == 0) - break; - if (jp->state != JOBDONE || !jp->waited) - continue; - if (jobctl) - continue; - freejob(jp); - break; - } - memset(jp, 0, sizeof(*jp)); - if (jobctl) - jp->jobctl = 1; - jp->prev_job = curjob; - curjob = jp; - jp->used = 1; - jp->ps = &jp->ps0; - if (nprocs > 1) { - jp->ps = ckmalloc(nprocs * sizeof(struct procstat)); - } - TRACE(("makejob(0x%lx, %d) returns %%%d\n", (long)node, nprocs, jobno(jp))); - return jp; -} - -#if defined(__GNUC__) && __GNUC__ >= 12 -#pragma GCC diagnostic ignored "-Wuse-after-free" -#endif - -static struct job *growjobtab(void) { - unsigned len; - long offset; - struct job *jp, *jq; - len = njobs * sizeof(*jp); - jq = jobtab; - jp = ckrealloc(jq, len + 4 * sizeof(*jp)); - offset = (char *)jp - (char *)jq; - if (offset) { - /* Relocate pointers */ - unsigned l = len; - jq = (struct job *)((char *)jq + l); - while (l) { - l -= sizeof(*jp); - jq--; -#define joff(p) ((struct job *)((char *)(p) + l)) -#define jmove(p) (p) = (void *)((char *)(p) + offset) - if (likely(joff(jp)->ps == &jq->ps0)) - jmove(joff(jp)->ps); - if (joff(jp)->prev_job) - jmove(joff(jp)->prev_job); - } - if (curjob) - jmove(curjob); -#undef joff -#undef jmove - } - njobs += 4; - jobtab = jp; - jp = (struct job *)((char *)jp + len); - jq = jp + 3; - do { - jq->used = 0; - } while (--jq >= jp); - return jp; -} - -/* - * Fork off a subshell. If we are doing job control, give the subshell its - * own process group. Jp is a job structure that the job is to be added to. - * N is the command that will be evaluated by the child. Both jp and n may - * be NULL. The mode parameter can be one of the following: - * FORK_FG - Fork off a foreground process. - * FORK_BG - Fork off a background process. - * FORK_NOJOB - Like FORK_FG, but don't give the process its own - * process group even if job control is on. - * - * When job control is turned off, background processes have their standard - * input redirected to /dev/null (except for the second and later processes - * in a pipeline). - * - * Called with interrupts off. - */ -static void forkchild(struct job *jp, union node *n, int mode) { - int lvforked; - int oldlvl; - TRACE(("Child shell %d\n", getpid())); - oldlvl = shlvl; - lvforked = vforked; - if (!lvforked) { - shlvl++; - forkreset(); - /* do job control only in root shell */ - jobctl = 0; - } - if (mode != FORK_NOJOB && jp->jobctl && !oldlvl) { - int pgrp; - if (jp->nprocs == 0) - pgrp = getpid(); - else - pgrp = jp->ps[0].pid; - /* This can fail because we are doing it in the parent also */ - (void)setpgid(0, pgrp); - if (mode == FORK_FG) - xtcsetpgrp(ttyfd, pgrp); - setsignal(SIGTSTP); - setsignal(SIGTTOU); - } else if (mode == FORK_BG) { - ignoresig(SIGINT); - ignoresig(SIGQUIT); - if (jp->nprocs == 0) { - close(0); - sh_open(_PATH_DEVNULL, O_RDONLY, 0); - } - } - if (!oldlvl && iflag) { - setsignal(SIGINT); - setsignal(SIGQUIT); - setsignal(SIGTERM); - } - if (lvforked) - return; - for (jp = curjob; jp; jp = jp->prev_job) - freejob(jp); -} - -static void forkparent(struct job *jp, union node *n, int mode, int pid) { - if (pid < 0) { - TRACE(("Fork failed, errno=%d", errno)); - if (jp) - freejob(jp); - sh_error("Cannot fork"); - __builtin_unreachable(); - } - TRACE(("In parent shell: child = %d\n", pid)); - if (!jp) - return; - if (mode != FORK_NOJOB && jp->jobctl) { - int pgrp; - if (jp->nprocs == 0) - pgrp = pid; - else - pgrp = jp->ps[0].pid; - /* This can fail because we are doing it in the child also */ - (void)setpgid(pid, pgrp); - } - if (mode == FORK_BG) { - backgndpid = pid; /* set $! */ - set_curjob(jp, CUR_RUNNING); - } - if (jp) { - struct procstat *ps = &jp->ps[jp->nprocs++]; - ps->pid = pid; - ps->status = -1; - ps->cmd = nullstr; - if (jobctl && n) - ps->cmd = commandtext(n); - } -} - -static int forkshell(struct job *jp, union node *n, int mode) { - int pid; - TRACE(("forkshell(%%%d, %p, %d) called\n", jobno(jp), n, mode)); - pid = fork(); - if (pid == 0) { - forkchild(jp, n, mode); - } else { - forkparent(jp, n, mode, pid); - } - return pid; -} - -static struct job *vforkexec(union node *n, char **argv, const char *path, - int idx) { - struct job *jp; - int pid; - jp = makejob(n, 1); - sigblockall(NULL); - vforked++; - pid = vfork(); - if (!pid) { - forkchild(jp, n, FORK_FG); - sigclearmask(); - shellexec(argv, path, idx); - __builtin_unreachable(); - } - vforked = 0; - sigclearmask(); - forkparent(jp, n, FORK_FG, pid); - return jp; -} - -/* - * Wait for job to finish. - * - * Under job control we have the problem that while a child process is - * running interrupts generated by the user are sent to the child but not - * to the shell. This means that an infinite loop started by an inter- - * active user may be hard to kill. With job control turned off, an - * interactive user may place an interactive program inside a loop. If - * the interactive program catches interrupts, the user doesn't want - * these interrupts to also abort the loop. The approach we take here - * is to have the shell ignore interrupt signals while waiting for a - * foreground process to terminate, and then send itself an interrupt - * signal if the child process was terminated by an interrupt signal. - * Unfortunately, some programs want to do a bit of cleanup and then - * exit on interrupt; unless these processes terminate themselves by - * sending a signal to themselves (instead of calling exit) they will - * confuse this approach. - * - * Called with interrupts off. - */ -static int waitforjob(struct job *jp) { - int st; - TRACE(("waitforjob(%%%d) called\n", jp ? jobno(jp) : 0)); - dowait(jp ? DOWAIT_BLOCK : DOWAIT_NONBLOCK, jp); - if (!jp) - return exitstatus; - st = getstatus(jp); - if (jp->jobctl) { - xtcsetpgrp(ttyfd, rootpid); - /* - * This is truly gross. - * If we're doing job control, then we did a TIOCSPGRP which - * caused us (the shell) to no longer be in the controlling - * session -- so we wouldn't have seen any ^C/SIGINT. So, we - * intuit from the subprocess exit status whether a SIGINT - * occurred, and if so interrupt ourselves. Yuck. - mycroft - */ - if (jp->sigint) - raise(SIGINT); - } - if (!JOBS || jp->state == JOBDONE) - freejob(jp); - return st; -} - -/* - * Wait for a process to terminate. - */ -static int waitone(int block, struct job *job) { - int pid; - int status; - struct job *jp; - struct job *thisjob = NULL; - int state; - INTOFF; - TRACE(("dowait(%d) called\n", block)); - pid = waitproc(block, &status); - TRACE(("wait returns pid %d, status=%d\n", pid, status)); - if (pid <= 0) - goto out; - for (jp = curjob; jp; jp = jp->prev_job) { - struct procstat *sp; - struct procstat *spend; - if (jp->state == JOBDONE) - continue; - state = JOBDONE; - spend = jp->ps + jp->nprocs; - sp = jp->ps; - do { - if (sp->pid == pid) { - TRACE(("Job %d: changing status of proc %d from 0x%x to 0x%x\n", - jobno(jp), pid, sp->status, status)); - sp->status = status; - thisjob = jp; - } - if (sp->status == -1) - state = JOBRUNNING; - if (state == JOBRUNNING) - continue; - if (WIFSTOPPED(sp->status)) { - jp->stopstatus = sp->status; - state = JOBSTOPPED; - } - } while (++sp < spend); - if (thisjob) - goto gotjob; - } - goto out; -gotjob: - if (state != JOBRUNNING) { - thisjob->changed = 1; - if (thisjob->state != state) { - TRACE(("Job %d: changing state from %d to %d\n", jobno(thisjob), - thisjob->state, state)); - thisjob->state = state; - if (state == JOBSTOPPED) { - set_curjob(thisjob, CUR_STOPPED); - } - } - } -out: - INTON; - if (thisjob && thisjob == job) { - char s[48 + 1]; - int len; - len = sprint_status(s, status, 1); - if (len) { - s[len] = '\n'; - s[len + 1] = 0; - outstr(s, out2); - } - } - return pid; -} - -static int dowait(int block, struct job *jp) { - int gotchld = *(volatile int *)&gotsigchld; - int rpid; - int pid; - if (jp && jp->state != JOBRUNNING) - block = DOWAIT_NONBLOCK; - if (block == DOWAIT_NONBLOCK && !gotchld) - return 1; - rpid = 1; - do { - pid = waitone(block, jp); - rpid &= !!pid; - block &= ~DOWAIT_WAITCMD_ALL; - if (!pid || (jp && jp->state != JOBRUNNING)) - block = DOWAIT_NONBLOCK; - } while (pid >= 0); - return rpid; -} - -/* - * Do a wait system call. If block is zero, we return -1 rather than - * blocking. If block is DOWAIT_WAITCMD, we return 0 when a signal - * other than SIGCHLD interrupted the wait. - * - * We use sigsuspend in conjunction with a non-blocking wait3 in - * order to ensure that waitcmd exits promptly upon the reception - * of a signal. - * - * For code paths other than waitcmd we either use a blocking wait3 - * or a non-blocking wait3. For the latter case the caller of dowait - * must ensure that it is called over and over again until all dead - * children have been reaped. Otherwise zombies may linger. - */ -static int waitproc(int block, int *status) { - sigset_t oldmask; - int flags = block == DOWAIT_BLOCK ? 0 : WNOHANG; - int err; - if (jobctl) - flags |= WUNTRACED; - do { - gotsigchld = 0; - do - err = wait3(status, flags, NULL); - while (err < 0 && errno == EINTR); - if (err || (err = -!block)) - break; - sigblockall(&oldmask); - while (!gotsigchld && !pending_sig) - sigsuspend(&oldmask); - sigclearmask(); - } while (gotsigchld); - return err; -} - -/* - * return 1 if there are stopped jobs, otherwise 0 - */ -static int stoppedjobs(void) { - struct job *jp; - int retval; - retval = 0; - if (job_warning) - goto out; - jp = curjob; - if (jp && jp->state == JOBSTOPPED) { - outstr("You have stopped jobs.\n", out2); - job_warning = 2; - retval++; - } -out: - return retval; -} - -/* - * Return a string identifying a command (to be printed by the - * jobs command). - */ -static char *commandtext(union node *n) { - char *name; - STARTSTACKSTR(cmdnextc); - cmdtxt(n); - name = stackblock(); - TRACE(("commandtext: name %p, end %p\n", name, cmdnextc)); - return savestr(name); -} - -static void cmdtxt(union node *n) { - union node *np; - struct nodelist *lp; - const char *p; - char s[2]; - if (!n) - return; - switch (n->type) { - default: - case NPIPE: - lp = n->npipe.cmdlist; - for (;;) { - cmdtxt(lp->n); - lp = lp->next; - if (!lp) - break; - cmdputs(" | "); - } - break; - case NSEMI: - p = "; "; - goto binop; - case NAND: - p = " && "; - goto binop; - case NOR: - p = " || "; - binop: - cmdtxt(n->nbinary.ch1); - cmdputs(p); - n = n->nbinary.ch2; - goto donode; - case NREDIR: - case NBACKGND: - n = n->nredir.n; - goto donode; - case NNOT: - cmdputs("!"); - n = n->nnot.com; - donode: - cmdtxt(n); - break; - case NIF: - cmdputs("if "); - cmdtxt(n->nif.test); - cmdputs("; then "); - if (n->nif.elsepart) { - cmdtxt(n->nif.ifpart); - cmdputs("; else "); - n = n->nif.elsepart; - } else { - n = n->nif.ifpart; - } - p = "; fi"; - goto dotail; - case NSUBSHELL: - cmdputs("("); - n = n->nredir.n; - p = ")"; - goto dotail; - case NWHILE: - p = "while "; - goto until; - case NUNTIL: - p = "until "; - until: - cmdputs(p); - cmdtxt(n->nbinary.ch1); - n = n->nbinary.ch2; - p = "; done"; - dodo: - cmdputs("; do "); - dotail: - cmdtxt(n); - goto dotail2; - case NFOR: - cmdputs("for "); - cmdputs(n->nfor.var_); - cmdputs(" in "); - cmdlist(n->nfor.args, 1); - n = n->nfor.body; - p = "; done"; - goto dodo; - case NDEFUN: - cmdputs(n->ndefun.text); - p = "() { ... }"; - goto dotail2; - case NCMD: - cmdlist(n->ncmd.args, 1); - cmdlist(n->ncmd.redirect, 0); - break; - case NARG: - p = n->narg.text; - dotail2: - cmdputs(p); - break; - case NHERE: - case NXHERE: - p = "<<..."; - goto dotail2; - case NCASE: - cmdputs("case "); - cmdputs(n->ncase.expr->narg.text); - cmdputs(" in "); - for (np = n->ncase.cases; np; np = np->nclist.next) { - cmdtxt(np->nclist.pattern); - cmdputs(") "); - cmdtxt(np->nclist.body); - cmdputs(";; "); - } - p = "esac"; - goto dotail2; - case NTO: - p = ">"; - goto redir; - case NCLOBBER: - p = ">|"; - goto redir; - case NAPPEND: - p = ">>"; - goto redir; - case NTOFD: - p = ">&"; - goto redir; - case NFROM: - p = "<"; - goto redir; - case NFROMFD: - p = "<&"; - goto redir; - case NFROMTO: - p = "<>"; - redir: - s[0] = n->nfile.fd + '0'; - s[1] = '\0'; - cmdputs(s); - cmdputs(p); - if (n->type == NTOFD || n->type == NFROMFD) { - s[0] = n->ndup.dupfd + '0'; - p = s; - goto dotail2; - } else { - n = n->nfile.fname; - goto donode; - } - } -} - -static void cmdlist(union node *np, int sep) { - for (; np; np = np->narg.next) { - if (!sep) - cmdputs(spcstr); - cmdtxt(np); - if (sep && np->narg.next) - cmdputs(spcstr); - } -} - -static void cmdputs(const char *s) { - const char *p, *str; - char cc[2] = " "; - char *nextc; - signed char c; - int subtype = 0; - int quoted = 0; - static const char vstype[VSTYPE + 1][4] = { - "", "}", "-", "+", "?", "=", "%", "%%", "#", "##", - }; - nextc = makestrspace((strlen(s) + 1) * 8, cmdnextc); - p = s; - while ((c = *p++) != 0) { - str = 0; - switch (c) { - case CTLESC: - c = *p++; - break; - case CTLVAR: - subtype = *p++; - if ((subtype & VSTYPE) == VSLENGTH) - str = "${#"; - else - str = "${"; - goto dostr; - case CTLENDVAR: - str = &"\"}"[!quoted]; - quoted >>= 1; - subtype = 0; - goto dostr; - case CTLBACKQ: - str = "$(...)"; - goto dostr; - case CTLARI: - str = "$(("; - goto dostr; - case CTLENDARI: - str = "))"; - goto dostr; - case CTLQUOTEMARK: - quoted ^= 1; - c = '"'; - break; - case '=': - if (subtype == 0) - break; - if ((subtype & VSTYPE) != VSNORMAL) - quoted <<= 1; - str = vstype[subtype & VSTYPE]; - if (subtype & VSNUL) - c = ':'; - else - goto checkstr; - break; - case '\'': - case '\\': - case '"': - case '$': - /* These can only happen inside quotes */ - cc[0] = c; - str = cc; - c = '\\'; - break; - default: - break; - } - USTPUTC(c, nextc); - checkstr: - if (!str) - continue; - dostr: - while ((c = *str++)) { - USTPUTC(c, nextc); - } - } - if (quoted & 1) { - USTPUTC('"', nextc); - } - *nextc = 0; - cmdnextc = nextc; -} - -static void showpipe(struct job *jp, struct output *out) { - struct procstat *sp; - struct procstat *spend; - spend = jp->ps + jp->nprocs; - for (sp = jp->ps + 1; sp < spend; sp++) - outfmt(out, " | %s", sp->cmd); - outcslow('\n', out); - flushall(); -} - -static void xtcsetpgrp(int fd, int pgrp) { - int err; - sigblockall(NULL); - err = tcsetpgrp(fd, pgrp); - sigclearmask(); - if (err) - sh_error("Cannot set tty process group (%s)", strerror(errno)); -} - -static int getstatus(struct job *job) { - int status; - int retval; - status = job->ps[job->nprocs - 1].status; - retval = WEXITSTATUS(status); - if (!WIFEXITED(status)) { - retval = WSTOPSIG(status); - if (!WIFSTOPPED(status)) { - /* XXX: limits number of signals */ - retval = WTERMSIG(status); - if (retval == SIGINT) - job->sigint = 1; - } - retval += 128; - } - TRACE(("getstatus: job %d, nproc %d, status %x, retval %x\n", jobno(job), - job->nprocs, status, retval)); - return retval; -} - -/** handle one line of the read command. - * more fields than variables -> remainder shall be part of last variable. - * less fields than variables -> remaining variables unset. - * - * @param line complete line of input - * @param ac argument count - * @param ap argument (variable) list - * @param len length of line including trailing '\0' - */ -static void readcmd_handle_line(char *s, int ac, char **ap) { - struct arglist arglist; - struct strlist *sl; - s = grabstackstr(s); - arglist.lastp = &arglist.list; - ifsbreakup(s, ac, &arglist); - *arglist.lastp = NULL; - ifsfree(); - sl = arglist.list; - do { - if (!sl) { - /* nullify remaining arguments */ - do { - setvar(*ap, nullstr, 0); - } while (*++ap); - return; - } - /* set variable to field */ - rmescapes(sl->text, 0); - setvar(*ap, sl->text, 0); - sl = sl->next; - } while (*++ap); -} - -/* - * The read builtin. The -e option causes backslashes to escape the - * following character. The -p option followed by an argument prompts - * with the argument. - * - * This uses unbuffered input, which may be avoidable in some cases. - */ -static int readcmd(int argc, char **argv) { - char **ap; - char c; - int rflag; - char *prompt; - char *p; - int startloc; - int newloc; - int status; - int i; - rflag = 0; - prompt = NULL; - while ((i = nextopt("p:r")) != '\0') { - if (i == 'p') - prompt = optionarg; - else - rflag = 1; - } - if (prompt && isatty(0)) { - outstr(prompt, out2); - } - if (!*(ap = argptr)) - sh_error("arg count"); - status = 0; - STARTSTACKSTR(p); - goto start; - for (;;) { - switch (read(0, &c, 1)) { - case 1: - break; - default: - if (errno == EINTR && !pending_sig) - continue; - /* fall through */ - case 0: - status = 1; - goto out; - } - if (!c) - continue; - if (newloc >= startloc) { - if (c == '\n') - goto resetbs; - goto put; - } - if (!rflag && c == '\\') { - newloc = p - (char *)stackblock(); - continue; - } - if (c == '\n') - break; - put: - CHECKSTRSPACE(2, p); - if (strchr(qchars, c)) - USTPUTC(CTLESC, p); - USTPUTC(c, p); - if (newloc >= startloc) { - resetbs: - recordregion(startloc, newloc, 0); - start: - startloc = p - (char *)stackblock(); - newloc = startloc - 1; - } - } -out: - recordregion(startloc, p - (char *)stackblock(), 0); - STACKSTRNUL(p); - readcmd_handle_line(p + 1, argc - (ap - argv), ap); - return status; -} - -/*───────────────────────────────────────────────────────────────────────────│─╗ -β”‚ cosmopolitan Β§ the unbourne shell Β» builtins Β» umask ─╬─│┼ -β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”‚β”€β• - This code was ripped from pdksh 5.2.14 and hacked for use with - dash by Herbert Xu. Public Domain. */ - -static int umaskcmd(int argc, char **argv) { - char *ap; - int mask; - int i; - int symbolic_mode = 0; - while ((i = nextopt("S")) != '\0') { - symbolic_mode = 1; - } - INTOFF; - mask = umask(0); - umask(mask); - INTON; - if ((ap = *argptr) == NULL) { - if (symbolic_mode) { - char buf[18]; - int j; - mask = ~mask; - ap = buf; - for (i = 0; i < 3; i++) { - *ap++ = "ugo"[i]; - *ap++ = '='; - for (j = 0; j < 3; j++) - if (mask & (1u << (8 - (3 * i + j)))) - *ap++ = "rwx"[j]; - *ap++ = ','; - } - ap[-1] = '\0'; - out1fmt("%s\n", buf); - } else { - out1fmt("%.4o\n", mask); - } - } else { - int new_mask; - if (isdigit((unsigned char)*ap)) { - new_mask = 0; - do { - if (*ap >= '8' || *ap < '0') - sh_error(illnum, *argptr); - new_mask = (new_mask << 3) + (*ap - '0'); - } while (*++ap != '\0'); - } else { - int positions, new_val; - char op; - mask = ~mask; - new_mask = mask; - positions = 0; - while (*ap) { - while (*ap && strchr("augo", *ap)) - switch (*ap++) { - case 'a': - positions |= 0111; - break; - case 'u': - positions |= 0100; - break; - case 'g': - positions |= 0010; - break; - case 'o': - positions |= 0001; - break; - } - if (!positions) - positions = 0111; /* default is a */ - if (!strchr("=+-", op = *ap)) - break; - ap++; - new_val = 0; - while (*ap && strchr("rwxugoXs", *ap)) - switch (*ap++) { - case 'r': - new_val |= 04; - break; - case 'w': - new_val |= 02; - break; - case 'x': - new_val |= 01; - break; - case 'u': - new_val |= mask >> 6; - break; - case 'g': - new_val |= mask >> 3; - break; - case 'o': - new_val |= mask >> 0; - break; - case 'X': - if (mask & 0111) - new_val |= 01; - break; - case 's': /* ignored */ - break; - } - new_val = (new_val & 07) * positions; - switch (op) { - case '-': - new_mask &= ~new_val; - break; - case '=': - new_mask = new_val | (new_mask & ~(positions * 07)); - break; - case '+': - new_mask |= new_val; - } - if (*ap == ',') { - positions = 0; - ap++; - } else if (!strchr("=+-", *ap)) - break; - } - if (*ap) { - sh_error("Illegal mode: %s", *argptr); - return 1; - } - new_mask = ~new_mask; - } - umask(new_mask); - } - return 0; -} - -/*───────────────────────────────────────────────────────────────────────────│─╗ -β”‚ cosmopolitan Β§ the unbourne shell Β» builtins Β» ulimit ─╬─│┼ -β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”‚β”€β• - This code, originally by Doug Gwyn, Doug Kingston, Eric Gisin, and - Michael Rendell was ripped from pdksh 5.0.8 and hacked for use with - ash by J.T. Conklin. Public Domain. */ - -enum limtype { SOFT = 0x1, HARD = 0x2 }; - -static void printlim(enum limtype how, const struct rlimit *limit, - const struct limits *l) { - uint64_t val; - val = limit->rlim_max; - if (how & SOFT) - val = limit->rlim_cur; - if (val == RLIM_INFINITY) - out1fmt("unlimited\n"); - else { - val /= l->factor; - out1fmt("%ld\n", (int64_t)val); - } -} - -static int ulimitcmd(int argc, char **argv) { - static const struct limits limits[] = {{(char *)0, 0, 0, '\0'}}; - int c; - uint64_t val = 0; - enum limtype how = SOFT | HARD; - const struct limits *l; - int set, all = 0; - int optc, what; - struct rlimit limit; - what = 'f'; - while ((optc = nextopt("HSa")) != '\0') { - switch (optc) { - case 'H': - how = HARD; - break; - case 'S': - how = SOFT; - break; - case 'a': - all = 1; - break; - default: - what = optc; - } - } - for (l = limits; l->option != what; l++) - ; - set = *argptr ? 1 : 0; - if (set) { - char *p = *argptr; - if (all || argptr[1]) - sh_error("too many arguments"); - if (strcmp(p, "unlimited") == 0) - val = RLIM_INFINITY; - else { - val = (uint64_t)0; - while ((c = *p++) >= '0' && c <= '9') { - val = (val * 10) + (long)(c - '0'); - if (val < (uint64_t)0) - break; - } - if (c) - sh_error("bad number"); - val *= l->factor; - } - } - if (all) { - for (l = limits; l->name; l++) { - getrlimit(l->cmd, &limit); - out1fmt("%-20s ", l->name); - printlim(how, &limit, l); - } - return 0; - } - getrlimit(l->cmd, &limit); - if (set) { - if (how & HARD) - limit.rlim_max = val; - if (how & SOFT) - limit.rlim_cur = val; - if (setrlimit(l->cmd, &limit) < 0) - sh_error("error setting limit (%s)", strerror(errno)); - } else { - printlim(how, &limit, l); - } - return 0; -} - -/* - * Produce a possibly single quoted string suitable as input to the shell. - * The return string is allocated on the stack. - */ -static char *single_quote(const char *s) { - char *p; - STARTSTACKSTR(p); - do { - char *q; - unsigned len; - len = strchrnul(s, '\'') - s; - q = p = makestrspace(len + 3, p); - *q++ = '\''; - q = mempcpy(q, s, len); - *q++ = '\''; - s += len; - STADJUST(q - p, p); - len = strspn(s, "'"); - if (!len) - break; - q = p = makestrspace(len + 3, p); - *q++ = '"'; - q = mempcpy(q, s, len); - *q++ = '"'; - s += len; - STADJUST(q - p, p); - } while (*s); - USTPUTC(0, p); - return stackblock(); -} - -/* - * Process the shell command line arguments. - */ -static int procargs(int argc, char **argv) { - int i; - const char *xminusc; - char **xargv; - int login; - xargv = argv; - login = xargv[0] && xargv[0][0] == '-'; - arg0 = xargv[0]; - if (argc > 0) - xargv++; - for (i = 0; i < NOPTS; i++) - optlist[i] = 2; - argptr = xargv; - login |= options(1); - xargv = argptr; - xminusc = minusc; - if (*xargv == NULL) { - if (xminusc) - sh_error("-c requires an argument"); - sflag = 1; - } - /* JART: fuck tty check this is documented behavior w/ no args */ - if (iflag == 2 && sflag == 1 /* && isatty(0) && isatty(1) */) - iflag = 1; - if (mflag == 2) - mflag = iflag; - for (i = 0; i < NOPTS; i++) - if (optlist[i] == 2) - optlist[i] = 0; - /* POSIX 1003.2: first arg after -c cmd is $0, remainder $1... */ - if (xminusc) { - minusc = *xargv++; - if (*xargv) - goto setarg0; - } else if (!sflag) { - setinputfile(*xargv, 0); - setarg0: - arg0 = *xargv++; - } - shellparam.p = xargv; - shellparam.optind = 1; - shellparam.optoff = -1; - /* assert(shellparam.malloc == 0 && shellparam.nparam == 0); */ - while (*xargv) { - shellparam.nparam++; - xargv++; - } - optschanged(); - return login; -} - -static void optschanged(void) { - setinteractive(iflag); - setjobctl(mflag); -} - -static void setoption(int flag, int val) { - int i; - for (i = 0; i < NOPTS; i++) - if (optletters[i] == flag) { - optlist[i] = val; - if (val) { - /* #%$ hack for ksh semantics */ - if (flag == 'V') - Eflag = 0; - else if (flag == 'E') - Vflag = 0; - } - return; - } - sh_error("Illegal option -%c", flag); - __builtin_unreachable(); -} - -/* - * Process shell options. The global variable argptr contains a pointer - * to the argument list; we advance it past the options. - */ -static int options(int cmdline) { - char *p; - int val; - int c; - int login = 0; - if (cmdline) - minusc = NULL; - while ((p = *argptr) != NULL) { - argptr++; - if ((c = *p++) == '-') { - val = 1; - if (p[0] == '\0' || (p[0] == '-' && p[1] == '\0')) { - if (!cmdline) { - /* "-" means turn off -x and -v */ - if (p[0] == '\0') - xflag = vflag = 0; - /* "--" means reset params */ - else if (*argptr == NULL) - setparam(argptr); - } - break; /* "-" or "--" terminates options */ - } - } else if (c == '+') { - val = 0; - } else { - argptr--; - break; - } - while ((c = *p++) != '\0') { - if (c == 'c' && cmdline) { - minusc = p; /* command is after shell args*/ - } else if (c == 'l' && cmdline) { - login = 1; - } else if (c == 'o') { - minus_o(*argptr, val); - if (*argptr) - argptr++; - } else { - setoption(c, val); - } - } - } - return login; -} - -static void minus_o(char *name, int val) { - int i; - if (name == NULL) { - if (val) { - outstr("Current option settings\n", out1); - for (i = 0; i < NOPTS; i++) { - out1fmt("%-16s%s\n", optnames[i], optlist[i] ? "on" : "off"); - } - } else { - for (i = 0; i < NOPTS; i++) { - out1fmt("set %s %s\n", optlist[i] ? "-o" : "+o", optnames[i]); - } - } - } else { - for (i = 0; i < NOPTS; i++) - if (equal(name, optnames[i])) { - optlist[i] = val; - return; - } - sh_error("Illegal option -o %s", name); - } -} - -/* - * Set the shell parameters. - */ -static void setparam(char **argv) { - char **newparam; - char **ap; - int nparam; - for (nparam = 0; argv[nparam]; nparam++) - ; - ap = newparam = ckmalloc((nparam + 1) * sizeof *ap); - while (*argv) { - *ap++ = savestr(*argv++); - } - *ap = NULL; - freeparam(&shellparam); - shellparam.malloc = 1; - shellparam.nparam = nparam; - shellparam.p = newparam; - shellparam.optind = 1; - shellparam.optoff = -1; -} - -/* - * Free the list of positional parameters. - */ -static void freeparam(volatile struct shparam *param) { - char **ap; - if (param->malloc) { - for (ap = param->p; *ap; ap++) - ckfree(*ap); - ckfree(param->p); - } -} - -/* - * The shift builtin command. - */ -static int shiftcmd(int argc, char **argv) { - int n; - char **ap1, **ap2; - n = 1; - if (argc > 1) - n = number(argv[1]); - if (n > shellparam.nparam) - sh_error("can't shift that many"); - INTOFF; - shellparam.nparam -= n; - for (ap1 = shellparam.p; --n >= 0; ap1++) { - if (shellparam.malloc) - ckfree(*ap1); - } - ap2 = shellparam.p; - while ((*ap2++ = *ap1++) != NULL) - ; - shellparam.optind = 1; - shellparam.optoff = -1; - INTON; - return 0; -} - -/* - * The set command builtin. - */ -static int setcmd(int argc, char **argv) { - if (argc == 1) - return showvars(nullstr, 0, VUNSET); - INTOFF; - options(0); - optschanged(); - if (*argptr != NULL) { - setparam(argptr); - } - INTON; - return 0; -} - -static void getoptsreset(value) const char *value; -{ - shellparam.optind = number(value) ?: 1; - shellparam.optoff = -1; -} - -/* - * The getopts builtin. Shellparam.optnext points to the next argument - * to be processed. Shellparam.optptr points to the next character to - * be processed in the current argument. If shellparam.optnext is NULL, - * then it's the first time getopts has been called. - */ -static int getoptscmd(int argc, char **argv) { - char **optbase; - if (argc < 3) - sh_error("Usage: getopts optstring var [arg]"); - else if (argc == 3) { - optbase = shellparam.p; - if ((unsigned)shellparam.optind > shellparam.nparam + 1) { - shellparam.optind = 1; - shellparam.optoff = -1; - } - } else { - optbase = &argv[3]; - if ((unsigned)shellparam.optind > argc - 2) { - shellparam.optind = 1; - shellparam.optoff = -1; - } - } - return getopts(argv[1], argv[2], optbase); -} - -static int getopts(char *optstr, char *optvar, char **optfirst) { - char *p, *q; - char c = '?'; - int done = 0; - char s[2]; - char **optnext; - int ind = shellparam.optind; - int off = shellparam.optoff; - shellparam.optind = -1; - optnext = optfirst + ind - 1; - if (ind <= 1 || off < 0 || strlen(optnext[-1]) < off) - p = NULL; - else - p = optnext[-1] + off; - if (p == NULL || *p == '\0') { - /* Current word is done, advance */ - p = *optnext; - if (p == NULL || *p != '-' || *++p == '\0') { - atend: - p = NULL; - done = 1; - goto out; - } - optnext++; - if (p[0] == '-' && p[1] == '\0') /* check for "--" */ - goto atend; - } - c = *p++; - for (q = optstr; *q != c;) { - if (*q == '\0') { - if (optstr[0] == ':') { - s[0] = c; - s[1] = '\0'; - setvar("OPTARG", s, 0); - } else { - outfmt(&errout, "Illegal option -%c\n", c); - (void)unsetvar("OPTARG"); - } - c = '?'; - goto out; - } - if (*++q == ':') - q++; - } - if (*++q == ':') { - if (*p == '\0' && (p = *optnext) == NULL) { - if (optstr[0] == ':') { - s[0] = c; - s[1] = '\0'; - setvar("OPTARG", s, 0); - c = ':'; - } else { - outfmt(&errout, "No arg for -%c option\n", c); - (void)unsetvar("OPTARG"); - c = '?'; - } - goto out; - } - if (p == *optnext) - optnext++; - setvar("OPTARG", p, 0); - p = NULL; - } else - setvar("OPTARG", nullstr, 0); -out: - ind = optnext - optfirst + 1; - setvarint("OPTIND", ind, VNOFUNC); - s[0] = c; - s[1] = '\0'; - setvar(optvar, s, 0); - shellparam.optoff = p ? p - *(optnext - 1) : -1; - shellparam.optind = ind; - return done; -} - -/* - * XXX - should get rid of. have all builtins use getopt(3). the - * library getopt must have the BSD extension function variable "optreset" - * otherwise it can't be used within the shell safely. - * - * Standard option processing (a la getopt) for builtin routines. The - * only argument that is passed to nextopt is the option string; the - * other arguments are unnecessary. It return the character, or '\0' on - * end of input. - */ -static int nextopt(const char *optstring) { - char *p; - const char *q; - char c; - if ((p = optptr) == NULL || *p == '\0') { - p = *argptr; - if (p == NULL || *p != '-' || *++p == '\0') - return '\0'; - argptr++; - if (p[0] == '-' && p[1] == '\0') /* check for "--" */ - return '\0'; - } - c = *p++; - for (q = optstring; *q != c;) { - if (*q == '\0') - sh_error("Illegal option -%c", c); - if (*++q == ':') - q++; - } - if (*++q == ':') { - if (*p == '\0' && (p = *argptr++) == NULL) { - sh_error("No arg for -%c option", c); - } - optionarg = p; - p = NULL; - } - optptr = p; - return c; -} - -/* values returned by readtoken */ -static int isassignment(const char *p) { - const char *q = endofname(p); - if (p == q) - return 0; - return *q == '='; -} - -static inline int realeofmark(const char *eofmark) { - return eofmark && eofmark != FAKEEOFMARK; -} - -/* - * Read and parse a command. Returns NEOF on end of file. (NULL is a - * valid parse tree indicating a blank line.) - */ -static union node *parsecmd(int interact) { - tokpushback = 0; - checkkwd = 0; - heredoclist = 0; - doprompt = interact; - if (doprompt) - setprompt(doprompt); - needprompt = 0; - return list(1); -} - -static union node *list(int nlflag) { - int chknl = nlflag & 1 ? 0 : CHKNL; - union node *n1, *n2, *n3; - int tok; - n1 = NULL; - for (;;) { - checkkwd = chknl | CHKKWD | CHKALIAS; - tok = readtoken(); - switch (tok) { - case TNL: - parseheredoc(); - return n1; - case TEOF: - if (!n1 && !chknl) - n1 = NEOF; - out_eof: - parseheredoc(); - tokpushback++; - lasttoken = TEOF; - return n1; - } - tokpushback++; - if (nlflag == 2 && tokendlist[tok]) - return n1; - nlflag |= 2; - n2 = andor(); - tok = readtoken(); - if (tok == TBACKGND) { - if (n2->type == NPIPE) { - n2->npipe.backgnd = 1; - } else { - if (n2->type != NREDIR) { - n3 = stalloc(sizeof(struct nredir)); - n3->nredir.n = n2; - n3->nredir.redirect = NULL; - n2 = n3; - } - n2->type = NBACKGND; - } - } - if (n1 == NULL) { - n1 = n2; - } else { - n3 = (union node *)stalloc(sizeof(struct nbinary)); - n3->type = NSEMI; - n3->nbinary.ch1 = n1; - n3->nbinary.ch2 = n2; - n1 = n3; - } - switch (tok) { - case TEOF: - goto out_eof; - case TNL: - tokpushback++; - /* fall through */ - case TBACKGND: - case TSEMI: - break; - default: - if (!chknl) - synexpect(-1); - tokpushback++; - return n1; - } - } -} - -static union node *andor(void) { - union node *n1, *n2, *n3; - int t; - n1 = pipeline(); - for (;;) { - if ((t = readtoken()) == TAND) { - t = NAND; - } else if (t == TOR) { - t = NOR; - } else { - tokpushback++; - return n1; - } - checkkwd = CHKNL | CHKKWD | CHKALIAS; - n2 = pipeline(); - n3 = (union node *)stalloc(sizeof(struct nbinary)); - n3->type = t; - n3->nbinary.ch1 = n1; - n3->nbinary.ch2 = n2; - n1 = n3; - } -} - -static union node *pipeline(void) { - union node *n1, *n2, *pipenode; - struct nodelist *lp, *prev; - int negate; - negate = 0; - TRACE(("pipeline: entered\n")); - if (readtoken() == TNOT) { - negate = !negate; - checkkwd = CHKKWD | CHKALIAS; - } else - tokpushback++; - n1 = command(); - if (readtoken() == TPIPE) { - pipenode = (union node *)stalloc(sizeof(struct npipe)); - pipenode->type = NPIPE; - pipenode->npipe.backgnd = 0; - lp = (struct nodelist *)stalloc(sizeof(struct nodelist)); - pipenode->npipe.cmdlist = lp; - lp->n = n1; - do { - prev = lp; - lp = (struct nodelist *)stalloc(sizeof(struct nodelist)); - checkkwd = CHKNL | CHKKWD | CHKALIAS; - lp->n = command(); - prev->next = lp; - } while (readtoken() == TPIPE); - lp->next = NULL; - n1 = pipenode; - } - tokpushback++; - if (negate) { - n2 = (union node *)stalloc(sizeof(struct nnot)); - n2->type = NNOT; - n2->nnot.com = n1; - return n2; - } else - return n1; -} - -static union node *command(void) { - union node *n1, *n2; - union node *ap, **app; - union node *cp, **cpp; - union node *redir, **rpp; - union node **rpp2; - int t; - int savelinno; - redir = NULL; - rpp2 = &redir; - savelinno = plinno; - switch (readtoken()) { - default: - synexpect(-1); - __builtin_unreachable(); - case TIF: - n1 = (union node *)stalloc(sizeof(struct nif)); - n1->type = NIF; - n1->nif.test = list(0); - if (readtoken() != TTHEN) - synexpect(TTHEN); - n1->nif.ifpart = list(0); - n2 = n1; - while (readtoken() == TELIF) { - n2->nif.elsepart = (union node *)stalloc(sizeof(struct nif)); - n2 = n2->nif.elsepart; - n2->type = NIF; - n2->nif.test = list(0); - if (readtoken() != TTHEN) - synexpect(TTHEN); - n2->nif.ifpart = list(0); - } - if (lasttoken == TELSE) - n2->nif.elsepart = list(0); - else { - n2->nif.elsepart = NULL; - tokpushback++; - } - t = TFI; - break; - case TWHILE: - case TUNTIL: { - int got; - n1 = (union node *)stalloc(sizeof(struct nbinary)); - n1->type = (lasttoken == TWHILE) ? NWHILE : NUNTIL; - n1->nbinary.ch1 = list(0); - if ((got = readtoken()) != TDO) { - TRACE(("expecting DO got %s %s\n", tokname[got], - got == TWORD ? wordtext : "")); - synexpect(TDO); - } - n1->nbinary.ch2 = list(0); - t = TDONE; - break; - } - case TFOR: - if (readtoken() != TWORD || quoteflag || !goodname(wordtext)) - synerror("Bad for loop variable"); - n1 = (union node *)stalloc(sizeof(struct nfor)); - n1->type = NFOR; - n1->nfor.linno = savelinno; - n1->nfor.var_ = wordtext; - checkkwd = CHKNL | CHKKWD | CHKALIAS; - if (readtoken() == TIN) { - app = ≈ - while (readtoken() == TWORD) { - n2 = (union node *)stalloc(sizeof(struct narg)); - n2->type = NARG; - n2->narg.text = wordtext; - n2->narg.backquote = backquotelist; - *app = n2; - app = &n2->narg.next; - } - *app = NULL; - n1->nfor.args = ap; - if (lasttoken != TNL && lasttoken != TSEMI) - synexpect(-1); - } else { - n2 = (union node *)stalloc(sizeof(struct narg)); - n2->type = NARG; - n2->narg.text = (char *)dolatstr; - n2->narg.backquote = NULL; - n2->narg.next = NULL; - n1->nfor.args = n2; - /* - * Newline or semicolon here is optional (but note - * that the original Bourne shell only allowed NL). - */ - if (lasttoken != TSEMI) - tokpushback++; - } - checkkwd = CHKNL | CHKKWD | CHKALIAS; - if (readtoken() != TDO) - synexpect(TDO); - n1->nfor.body = list(0); - t = TDONE; - break; - case TCASE: - n1 = (union node *)stalloc(sizeof(struct ncase)); - n1->type = NCASE; - n1->ncase.linno = savelinno; - if (readtoken() != TWORD) - synexpect(TWORD); - n1->ncase.expr = n2 = (union node *)stalloc(sizeof(struct narg)); - n2->type = NARG; - n2->narg.text = wordtext; - n2->narg.backquote = backquotelist; - n2->narg.next = NULL; - checkkwd = CHKNL | CHKKWD | CHKALIAS; - if (readtoken() != TIN) - synexpect(TIN); - cpp = &n1->ncase.cases; - next_case: - checkkwd = CHKNL | CHKKWD; - t = readtoken(); - while (t != TESAC) { - if (lasttoken == TLP) - readtoken(); - *cpp = cp = (union node *)stalloc(sizeof(struct nclist)); - cp->type = NCLIST; - app = &cp->nclist.pattern; - for (;;) { - *app = ap = (union node *)stalloc(sizeof(struct narg)); - ap->type = NARG; - ap->narg.text = wordtext; - ap->narg.backquote = backquotelist; - if (readtoken() != TPIPE) - break; - app = &ap->narg.next; - readtoken(); - } - ap->narg.next = NULL; - if (lasttoken != TRP) - synexpect(TRP); - cp->nclist.body = list(2); - cpp = &cp->nclist.next; - checkkwd = CHKNL | CHKKWD; - if ((t = readtoken()) != TESAC) { - if (t != TENDCASE) - synexpect(TENDCASE); - else - goto next_case; - } - } - *cpp = NULL; - goto redir; - case TLP: - n1 = (union node *)stalloc(sizeof(struct nredir)); - n1->type = NSUBSHELL; - n1->nredir.linno = savelinno; - n1->nredir.n = list(0); - n1->nredir.redirect = NULL; - t = TRP; - break; - case TBEGIN: - n1 = list(0); - t = TEND; - break; - case TWORD: - case TREDIR: - tokpushback++; - return simplecmd(); - } - if (readtoken() != t) - synexpect(t); -redir: - /* Now check for redirection which may follow command */ - checkkwd = CHKKWD | CHKALIAS; - rpp = rpp2; - while (readtoken() == TREDIR) { - *rpp = n2 = redirnode; - rpp = &n2->nfile.next; - parsefname(); - } - tokpushback++; - *rpp = NULL; - if (redir) { - if (n1->type != NSUBSHELL) { - n2 = (union node *)stalloc(sizeof(struct nredir)); - n2->type = NREDIR; - n2->nredir.linno = savelinno; - n2->nredir.n = n1; - n1 = n2; - } - n1->nredir.redirect = redir; - } - return n1; -} - -static union node *simplecmd(void) { - union node *args, **app; - union node *n = NULL; - union node *vars, **vpp; - union node **rpp, *redir; - int savecheckkwd; - int savelinno; - args = NULL; - app = &args; - vars = NULL; - vpp = &vars; - redir = NULL; - rpp = &redir; - savecheckkwd = CHKALIAS; - savelinno = plinno; - for (;;) { - checkkwd = savecheckkwd; - switch (readtoken()) { - case TWORD: - n = (union node *)stalloc(sizeof(struct narg)); - n->type = NARG; - n->narg.text = wordtext; - n->narg.backquote = backquotelist; - if (savecheckkwd && isassignment(wordtext)) { - *vpp = n; - vpp = &n->narg.next; - } else { - *app = n; - app = &n->narg.next; - savecheckkwd = 0; - } - break; - case TREDIR: - *rpp = n = redirnode; - rpp = &n->nfile.next; - parsefname(); /* read name of redirection file */ - break; - case TLP: - if (args && app == &args->narg.next && !vars && !redir) { - struct builtincmd *bcmd; - const char *name; - /* We have a function */ - if (readtoken() != TRP) - synexpect(TRP); - name = n->narg.text; - if (!goodname(name) || - ((bcmd = find_builtin(name)) && bcmd->flags & BUILTIN_SPECIAL)) - synerror("Bad function name"); - n->type = NDEFUN; - checkkwd = CHKNL | CHKKWD | CHKALIAS; - n->ndefun.text = n->narg.text; - n->ndefun.linno = plinno; - n->ndefun.body = command(); - return n; - } - /* fall through */ - default: - tokpushback++; - goto out; - } - } -out: - *app = NULL; - *vpp = NULL; - *rpp = NULL; - n = (union node *)stalloc(sizeof(struct ncmd)); - n->type = NCMD; - n->ncmd.linno = savelinno; - n->ncmd.args = args; - n->ncmd.assign = vars; - n->ncmd.redirect = redir; - return n; -} - -static union node *makename(void) { - union node *n; - n = (union node *)stalloc(sizeof(struct narg)); - n->type = NARG; - n->narg.next = NULL; - n->narg.text = wordtext; - n->narg.backquote = backquotelist; - return n; -} - -static void fixredir(union node *n, const char *text, int err) { - TRACE(("Fix redir %s %d\n", text, err)); - if (!err) - n->ndup.vname = NULL; - if (is_digit(text[0]) && text[1] == '\0') - n->ndup.dupfd = digit_val(text[0]); - else if (text[0] == '-' && text[1] == '\0') - n->ndup.dupfd = -1; - else { - if (err) - synerror("Bad fd number"); - else - n->ndup.vname = makename(); - } -} - -static void parsefname(void) { - union node *n = redirnode; - if (n->type == NHERE) - checkkwd = CHKEOFMARK; - if (readtoken() != TWORD) - synexpect(-1); - if (n->type == NHERE) { - struct heredoc *here = heredoc; - struct heredoc *p; - if (quoteflag == 0) - n->type = NXHERE; - TRACE(("Here document %d\n", n->type)); - rmescapes(wordtext, 0); - here->eofmark = wordtext; - here->next = NULL; - if (heredoclist == NULL) - heredoclist = here; - else { - for (p = heredoclist; p->next; p = p->next) - ; - p->next = here; - } - } else if (n->type == NTOFD || n->type == NFROMFD) { - fixredir(n, wordtext, 0); - } else { - n->nfile.fname = makename(); - } -} - -/* - * Input any here documents. - */ -static void parseheredoc(void) { - struct heredoc *here; - union node *n; - here = heredoclist; - heredoclist = 0; - while (here) { - if (needprompt) { - setprompt(2); - } - if (here->here->type == NHERE) - readtoken1(pgetc(), SQSYNTAX, here->eofmark, here->striptabs); - else - readtoken1(pgetc_eatbnl(), DQSYNTAX, here->eofmark, here->striptabs); - n = (union node *)stalloc(sizeof(struct narg)); - n->narg.type = NARG; - n->narg.next = NULL; - n->narg.text = wordtext; - n->narg.backquote = backquotelist; - here->here->nhere.doc = n; - here = here->next; - } -} - -static int readtoken(void) { - int t; - int kwd = checkkwd; -top: - t = xxreadtoken(); - /* - * eat newlines - */ - if (kwd & CHKNL) { - while (t == TNL) { - parseheredoc(); - checkkwd = 0; - t = xxreadtoken(); - } - } - kwd |= checkkwd; - checkkwd = 0; - if (t != TWORD || quoteflag) { - goto out; - } - /* - * check for keywords - */ - if (kwd & CHKKWD) { - const char *const *pp; - const int KWDOFFSET = 13; - if ((pp = findkwd(wordtext))) { - lasttoken = t = pp - parsekwd + KWDOFFSET; - TRACE(("keyword %s recognized\n", tokname[t])); - goto out; - } - } - if (kwd & CHKALIAS) { - struct alias *ap; - if ((ap = lookupalias(wordtext, 1)) != NULL) { - if (*ap->val) { - pushstring(ap->val, ap); - } - goto top; - } - } -out: - return (t); -} - -static void nlprompt(void) { - plinno++; - if (doprompt) - setprompt(2); -} - -static void nlnoprompt(void) { - plinno++; - needprompt = doprompt; -} - -/* - * Read the next input token. - * If the token is a word, we set backquotelist to the list of cmds in - * backquotes. We set quoteflag to true if any part of the word was - * quoted. - * If the token is TREDIR, then we set redirnode to a structure containing - * the redirection. - * - * [Change comment: here documents and internal procedures] - * [Readtoken shouldn't have any arguments. Perhaps we should make the - * word parsing code into a separate routine. In this case, readtoken - * doesn't need to have any internal procedures, but parseword does. - * We could also make parseoperator in essence the main routine, and - * have parseword (readtoken1?) handle both words and redirection.] - */ -static int xxreadtoken(void) { -#define RETURN(token) return lasttoken = token - int c; - if (tokpushback) { - tokpushback = 0; - return lasttoken; - } - if (needprompt) { - setprompt(2); - } - for (;;) { /* until token or start of word found */ - c = pgetc_eatbnl(); - switch (c) { - case ' ': - case '\t': - continue; - case '#': - while ((c = pgetc()) != '\n' && c != PEOF) - ; - pungetc(); - continue; - case '\n': - nlnoprompt(); - RETURN(TNL); - case PEOF: - RETURN(TEOF); - case '&': - if (pgetc_eatbnl() == '&') - RETURN(TAND); - pungetc(); - RETURN(TBACKGND); - case '|': - if (pgetc_eatbnl() == '|') - RETURN(TOR); - pungetc(); - RETURN(TPIPE); - case ';': - if (pgetc_eatbnl() == ';') - RETURN(TENDCASE); - pungetc(); - RETURN(TSEMI); - case '(': - RETURN(TLP); - case ')': - RETURN(TRP); - } - break; - } - return readtoken1(c, BASESYNTAX, (char *)NULL, 0); -#undef RETURN -} - -static int pgetc_eatbnl(void) { - int c; - while ((c = pgetc()) == '\\') { - if (pgetc() != '\n') { - pungetc(); - break; - } - nlprompt(); - } - return c; -} - -static int pgetc_top(struct synstack *stack) { - return stack->syntax == SQSYNTAX ? pgetc() : pgetc_eatbnl(); -} - -static void synstack_push(struct synstack **stack, struct synstack *next, - const char *syntax) { - memset(next, 0, sizeof(*next)); - next->syntax = syntax; - next->next = *stack; - (*stack)->prev = next; - *stack = next; -} - -static void synstack_pop(struct synstack **stack) { - *stack = (*stack)->next; -} - -/* - * If eofmark is NULL, read a word or a redirection symbol. If eofmark - * is not NULL, read a here document. In the latter case, eofmark is the - * word which marks the end of the document and striptabs is true if - * leading tabs should be stripped from the document. The argument firstc - * is the first character of the input token or document. - * - * Because C does not have internal subroutines, I have simulated them - * using goto's to implement the subroutine linkage. The following macros - * will run code that appears at the end of readtoken1. - */ - -#define CHECKEND() \ - { \ - goto checkend; \ - checkend_return:; \ - } -#define PARSEREDIR() \ - { \ - goto parseredir; \ - parseredir_return:; \ - } -#define PARSESUB() \ - { \ - goto parsesub; \ - parsesub_return:; \ - } -#define PARSEBACKQOLD() \ - { \ - oldstyle = 1; \ - goto parsebackq; \ - parsebackq_oldreturn:; \ - } -#define PARSEBACKQNEW() \ - { \ - oldstyle = 0; \ - goto parsebackq; \ - parsebackq_newreturn:; \ - } -#define PARSEARITH() \ - { \ - goto parsearith; \ - parsearith_return:; \ - } - -static int readtoken1(int firstc, char const *syntax, char *eofmark, - int striptabs) { - int c = firstc; - char *out; - unsigned len; - struct nodelist *bqlist; - int quotef; - int oldstyle; - /* syntax stack */ - struct synstack synbase = {.syntax = syntax}; - struct synstack *synstack = &synbase; - if (syntax == DQSYNTAX) - synstack->dblquote = 1; - quotef = 0; - bqlist = NULL; - STARTSTACKSTR(out); -loop: { /* for each line, until end of word */ - CHECKEND(); /* set c to PEOF if at end of here document */ - for (;;) { /* until end of line or end of word */ - CHECKSTRSPACE(4, out); /* permit 4 calls to USTPUTC */ - switch (synstack->syntax[c]) { - case CNL: /* '\n' */ - if (synstack->syntax == BASESYNTAX && !synstack->varnest) - goto endword; /* exit outer loop */ - USTPUTC(c, out); - nlprompt(); - c = pgetc_top(synstack); - goto loop; /* continue outer loop */ - case CWORD: - USTPUTC(c, out); - break; - case CCTL: - if ((!eofmark) | synstack->dblquote | synstack->varnest) - USTPUTC(CTLESC, out); - USTPUTC(c, out); - break; - /* backslash */ - case CBACK: - c = pgetc(); - if (c == PEOF) { - USTPUTC(CTLESC, out); - USTPUTC('\\', out); - pungetc(); - } else { - if (synstack->dblquote && c != '\\' && c != '`' && c != '$' && - (c != '"' || (eofmark != NULL && !synstack->varnest)) && - (c != '}' || !synstack->varnest)) { - USTPUTC(CTLESC, out); - USTPUTC('\\', out); - } - USTPUTC(CTLESC, out); - USTPUTC(c, out); - quotef++; - } - break; - case CSQUOTE: - synstack->syntax = SQSYNTAX; - quotemark: - if (eofmark == NULL) { - USTPUTC(CTLQUOTEMARK, out); - } - break; - case CDQUOTE: - synstack->syntax = DQSYNTAX; - synstack->dblquote = 1; - toggledq: - if (synstack->varnest) - synstack->innerdq ^= 1; - goto quotemark; - case CENDQUOTE: - if (eofmark && !synstack->varnest) { - USTPUTC(c, out); - break; - } - if (synstack->dqvarnest == 0) { - synstack->syntax = BASESYNTAX; - synstack->dblquote = 0; - } - quotef++; - if (c == '"') - goto toggledq; - goto quotemark; - case CVAR: /* '$' */ - PARSESUB(); /* parse substitution */ - break; - case CENDVAR: /* '}' */ - if (!synstack->innerdq && synstack->varnest > 0) { - if (!--synstack->varnest && synstack->varpushed) - synstack_pop(&synstack); - else if (synstack->dqvarnest > 0) - synstack->dqvarnest--; - USTPUTC(CTLENDVAR, out); - } else { - USTPUTC(c, out); - } - break; - case CLP: /* '(' in arithmetic */ - synstack->parenlevel++; - USTPUTC(c, out); - break; - case CRP: /* ')' in arithmetic */ - if (synstack->parenlevel > 0) { - USTPUTC(c, out); - --synstack->parenlevel; - } else { - if (pgetc_eatbnl() == ')') { - USTPUTC(CTLENDARI, out); - synstack_pop(&synstack); - } else { - /* - * unbalanced parens - * (don't 2nd guess - no error) - */ - pungetc(); - USTPUTC(')', out); - } - } - break; - case CBQUOTE: /* '`' */ - if (checkkwd & CHKEOFMARK) { - USTPUTC('`', out); - break; - } - PARSEBACKQOLD(); - break; - case CEOF: - goto endword; /* exit outer loop */ - default: - if (synstack->varnest == 0) - goto endword; /* exit outer loop */ - USTPUTC(c, out); - } - c = pgetc_top(synstack); - } -} -endword: - if (synstack->syntax == ARISYNTAX) - synerror("Missing '))'"); - if (synstack->syntax != BASESYNTAX && eofmark == NULL) - synerror("Unterminated quoted string"); - if (synstack->varnest != 0) { - /* { */ - synerror("Missing '}'"); - } - USTPUTC('\0', out); - len = out - (char *)stackblock(); - out = stackblock(); - if (eofmark == NULL) { - if ((c == '>' || c == '<') && quotef == 0 && len <= 2 && - (*out == '\0' || is_digit(*out))) { - PARSEREDIR(); - return lasttoken = TREDIR; - } else { - pungetc(); - } - } - quoteflag = quotef; - backquotelist = bqlist; - grabstackblock(len); - wordtext = out; - return lasttoken = TWORD; - /* end of readtoken routine */ - - /* - * Check to see whether we are at the end of the here document. When this - * is called, c is set to the first character of the next input line. If - * we are at the end of the here document, this routine sets the c to PEOF. - */ -checkend: { - if (realeofmark(eofmark)) { - int markloc; - char *p; - if (striptabs) { - while (c == '\t') - c = pgetc(); - } - markloc = out - (char *)stackblock(); - for (p = eofmark; STPUTC(c, out), *p; p++) { - if (c != *p) - goto more_heredoc; - c = pgetc(); - } - if (c == '\n' || c == PEOF) { - c = PEOF; - nlnoprompt(); - } else { - int len2; - more_heredoc: - p = (char *)stackblock() + markloc + 1; - len2 = out - p; - if (len2) { - len2 -= c < 0; - c = p[-1]; - if (len2) { - char *str; - str = alloca(len2 + 1); - *(char *)mempcpy(str, p, len2) = 0; - pushstring(str, NULL); - } - } - } - STADJUST((char *)stackblock() + markloc - out, out); - } - goto checkend_return; -} - - /* - * Parse a redirection operator. The variable "out" points to a string - * specifying the fd to be redirected. The variable "c" contains the - * first character of the redirection operator. - */ -parseredir: { - char fd = *out; - union node *np; - np = (union node *)stalloc(sizeof(struct nfile)); - if (c == '>') { - np->nfile.fd = 1; - c = pgetc_eatbnl(); - if (c == '>') - np->type = NAPPEND; - else if (c == '|') - np->type = NCLOBBER; - else if (c == '&') - np->type = NTOFD; - else { - np->type = NTO; - pungetc(); - } - } else { /* c == '<' */ - np->nfile.fd = 0; - switch (c = pgetc_eatbnl()) { - case '<': - if (sizeof(struct nfile) != sizeof(struct nhere)) { - np = (union node *)stalloc(sizeof(struct nhere)); - np->nfile.fd = 0; - } - np->type = NHERE; - heredoc = (struct heredoc *)stalloc(sizeof(struct heredoc)); - heredoc->here = np; - if ((c = pgetc_eatbnl()) == '-') { - heredoc->striptabs = 1; - } else { - heredoc->striptabs = 0; - pungetc(); - } - break; - case '&': - np->type = NFROMFD; - break; - case '>': - np->type = NFROMTO; - break; - default: - np->type = NFROM; - pungetc(); - break; - } - } - if (fd != '\0') - np->nfile.fd = digit_val(fd); - redirnode = np; - goto parseredir_return; -} - - /* - * Parse a substitution. At this point, we have read the dollar sign - * and nothing else. - */ -parsesub: { - int subtype; - int typeloc; - char *p; - static const char types[] = "}-+?="; - c = pgetc_eatbnl(); - if ((checkkwd & CHKEOFMARK) || - (c != '(' && c != '{' && !is_name(c) && !is_special(c))) { - USTPUTC('$', out); - pungetc(); - } else if (c == '(') { /* $(command) or $((arith)) */ - if (pgetc_eatbnl() == '(') { - PARSEARITH(); - } else { - pungetc(); - PARSEBACKQNEW(); - } - } else { - const char *newsyn = synstack->syntax; - USTPUTC(CTLVAR, out); - typeloc = out - (char *)stackblock(); - STADJUST(1, out); - subtype = VSNORMAL; - if (likely(c == '{')) { - c = pgetc_eatbnl(); - subtype = 0; - } - varname: - if (is_name(c)) { - do { - STPUTC(c, out); - c = pgetc_eatbnl(); - } while (is_in_name(c)); - } else if (is_digit(c)) { - do { - STPUTC(c, out); - c = pgetc_eatbnl(); - } while ((subtype <= 0 || subtype >= VSLENGTH) && is_digit(c)); - } else if (c != '}') { - int cc = c; - c = pgetc_eatbnl(); - if (!subtype && cc == '#') { - subtype = VSLENGTH; - if (c == '_' || isalnum(c)) - goto varname; - cc = c; - c = pgetc_eatbnl(); - if (cc == '}' || c != '}') { - pungetc(); - subtype = 0; - c = cc; - cc = '#'; - } - } - if (!is_special(cc)) { - if (subtype == VSLENGTH) - subtype = 0; - goto badsub; - } - USTPUTC(cc, out); - } else - goto badsub; - if (subtype == 0) { - int cc = c; - switch (c) { - case ':': - subtype = VSNUL; - c = pgetc_eatbnl(); - /*FALLTHROUGH*/ - default: - p = strchr(types, c); - if (p == NULL) - break; - subtype |= p - types + VSNORMAL; - break; - case '%': - case '#': - subtype = c == '#' ? VSTRIMLEFT : VSTRIMRIGHT; - c = pgetc_eatbnl(); - if (c == cc) - subtype++; - else - pungetc(); - newsyn = BASESYNTAX; - break; - } - } else { - if (subtype == VSLENGTH && c != '}') - subtype = 0; - badsub: - pungetc(); - } - if (newsyn == ARISYNTAX) - newsyn = DQSYNTAX; - if ((newsyn != synstack->syntax || synstack->innerdq) && - subtype != VSNORMAL) { - synstack_push(&synstack, synstack->prev ?: alloca(sizeof(*synstack)), - newsyn); - synstack->varpushed++; - synstack->dblquote = newsyn != BASESYNTAX; - } - *((char *)stackblock() + typeloc) = subtype; - if (subtype != VSNORMAL) { - synstack->varnest++; - if (synstack->dblquote) - synstack->dqvarnest++; - } - STPUTC('=', out); - } - goto parsesub_return; -} - - /* - * Called to parse command substitutions. Newstyle is set if the command - * is enclosed inside $(...); nlpp is a pointer to the head of the linked - * list of commands (passed by reference), and savelen is the number of - * characters on the top of the stack which must be preserved. - */ -parsebackq: { - struct nodelist **nlpp; - union node *n; - char *str; - unsigned savelen; - struct heredoc *saveheredoclist; - int uninitialized_var(saveprompt); - str = NULL; - savelen = out - (char *)stackblock(); - if (savelen > 0) { - str = alloca(savelen); - memcpy(str, stackblock(), savelen); - } - if (oldstyle) { - /* We must read until the closing backquote, giving special - treatment to some slashes, and then push the string and - reread it as input, interpreting it normally. */ - char *pout; - int pc; - unsigned psavelen; - char *pstr; - STARTSTACKSTR(pout); - for (;;) { - if (needprompt) { - setprompt(2); - } - switch (pc = pgetc_eatbnl()) { - case '`': - goto done; - case '\\': - pc = pgetc(); - if (pc != '\\' && pc != '`' && pc != '$' && - (!synstack->dblquote || pc != '"')) - STPUTC('\\', pout); - break; - case PEOF: - synerror("EOF in backquote substitution"); - case '\n': - nlnoprompt(); - break; - default: - break; - } - STPUTC(pc, pout); - } - done: - STPUTC('\0', pout); - psavelen = pout - (char *)stackblock(); - if (psavelen > 0) { - pstr = grabstackstr(pout); - setinputstring(pstr); - } - } - nlpp = &bqlist; - while (*nlpp) - nlpp = &(*nlpp)->next; - *nlpp = (struct nodelist *)stalloc(sizeof(struct nodelist)); - (*nlpp)->next = NULL; - saveheredoclist = heredoclist; - heredoclist = NULL; - if (oldstyle) { - saveprompt = doprompt; - doprompt = 0; - } - n = list(2); - if (oldstyle) - doprompt = saveprompt; - else { - if (readtoken() != TRP) - synexpect(TRP); - setinputstring(nullstr); - } - parseheredoc(); - heredoclist = saveheredoclist; - (*nlpp)->n = n; - /* Start reading from old file again. */ - popfile(); - /* Ignore any pushed back tokens left from the backquote parsing. */ - if (oldstyle) - tokpushback = 0; - out = growstackto(savelen + 1); - if (str) { - memcpy(out, str, savelen); - STADJUST(savelen, out); - } - USTPUTC(CTLBACKQ, out); - if (oldstyle) - goto parsebackq_oldreturn; - else - goto parsebackq_newreturn; -} - -/* - * Parse an arithmetic expansion (indicate start of one and set state) - */ -parsearith: { - synstack_push(&synstack, synstack->prev ?: alloca(sizeof(*synstack)), - ARISYNTAX); - synstack->dblquote = 1; - USTPUTC(CTLARI, out); - goto parsearith_return; -} - -} /* end of readtoken */ - -static void setprompt(int which) { - struct stackmark smark; - int show; - needprompt = 0; - whichprompt = which; - show = 0; - if (show) { - pushstackmark(&smark, stackblocksize()); - outstr(getprompt(NULL), out2); - popstackmark(&smark); - } -} - -static const char *expandstr(const char *ps) { - struct parsefile *file_stop; - struct jmploc *volatile savehandler; - struct heredoc *saveheredoclist; - const char *result; - int saveprompt; - struct jmploc jmploc; - union node n; - int err; - file_stop = parsefile; - setinputstring((char *)ps); /* XXX Fix (char *) cast. */ - saveheredoclist = heredoclist; - heredoclist = NULL; - saveprompt = doprompt; - doprompt = 0; - result = ps; - savehandler = handler; - if (unlikely(err = setjmp(jmploc.loc))) - goto out; - handler = &jmploc; - readtoken1(pgetc_eatbnl(), DQSYNTAX, FAKEEOFMARK, 0); - n.narg.type = NARG; - n.narg.next = NULL; - n.narg.text = wordtext; - n.narg.backquote = backquotelist; - expandarg(&n, NULL, EXP_QUOTED); - result = stackblock(); -out: - handler = savehandler; - if (err && exception != EXERROR) - longjmp(handler->loc, 1); - doprompt = saveprompt; - unwindfiles(file_stop); - heredoclist = saveheredoclist; - return result; -} - -/* - * called by editline -- any expansions to the prompt - * should be added here. - */ -static const char *getprompt(void *unused) { - const char *prompt; - switch (whichprompt) { - default: - case 0: - return nullstr; - case 1: - prompt = ps1val(); - break; - case 2: - prompt = ps2val(); - break; - } - return expandstr(prompt); -} - -const char *const *findkwd(const char *s) { - return findstring(s, parsekwd, sizeof(parsekwd) / sizeof(const char *)); -} - -static unsigned update_closed_redirs(int fd, int nfd) { - unsigned val = closed_redirs; - unsigned bit = 1 << fd; - if (nfd >= 0) - closed_redirs &= ~bit; - else - closed_redirs |= bit; - return val & bit; -} - -/* - * Process a list of redirection commands. If the REDIR_PUSH flag is set, - * old file descriptors are stashed away so that the redirection can be - * undone by calling popredir. If the REDIR_BACKQ flag is set, then the - * standard output, and the standard error if it becomes a duplicate of - * stdout, is saved in memory. - */ -static void redirect(union node *redir, int flags) { - union node *n; - struct redirtab *sv; - int i; - int fd; - int newfd; - int *p; - if (!redir) - return; - sv = NULL; - INTOFF; - if (likely(flags & REDIR_PUSH)) - sv = redirlist; - n = redir; - do { - newfd = openredirect(n); - if (newfd < -1) - continue; - fd = n->nfile.fd; - if (sv) { - int closed; - p = &sv->renamed[fd]; - i = *p; - closed = update_closed_redirs(fd, newfd); - if (likely(i == EMPTY)) { - i = CLOSED; - if (fd != newfd && !closed) { - i = savefd(fd, fd); - fd = -1; - } - } - *p = i; - } - if (fd == newfd) - continue; - dupredirect(n, newfd); - } while ((n = n->nfile.next)); - INTON; - if (flags & REDIR_SAVEFD2 && sv->renamed[2] >= 0) - preverrout.fd = sv->renamed[2]; -} - -wontreturn static int sh_open_fail(const char *pathname, int flags, int e) { - const char *word; - int action; - word = "open"; - action = E_OPEN; - if (flags & O_CREAT) { - word = "create"; - action = E_CREAT; - } - sh_error("cannot %s %s: %s", word, pathname, errmsg(e, action)); -} - -static int sh_open(const char *pathname, int flags, int mayfail) { - int fd; - int e; - do { - fd = open(pathname, flags, 0666); - e = errno; - } while (fd < 0 && e == EINTR && !pending_sig); - if (mayfail || fd >= 0) - return fd; - sh_open_fail(pathname, flags, e); -} - -static int openredirect(union node *redir) { - struct stat sb; - char *fname; - int flags; - int f; - switch (redir->nfile.type) { - case NFROM: - flags = O_RDONLY; - do_open: - f = sh_open(redir->nfile.expfname, flags, 0); - break; - case NFROMTO: - flags = O_RDWR | O_CREAT; - goto do_open; - case NTO: - /* Take care of noclobber mode. */ - if (Cflag) { - fname = redir->nfile.expfname; - if (stat(fname, &sb) < 0) { - flags = O_WRONLY | O_CREAT | O_EXCL; - goto do_open; - } - if (S_ISREG(sb.st_mode)) - goto ecreate; - f = sh_open(fname, O_WRONLY, 0); - if (!fstat(f, &sb) && S_ISREG(sb.st_mode)) { - close(f); - goto ecreate; - } - break; - } - /* FALLTHROUGH */ - case NCLOBBER: - flags = O_WRONLY | O_CREAT | O_TRUNC; - goto do_open; - case NAPPEND: - flags = O_WRONLY | O_CREAT | O_APPEND; - goto do_open; - case NTOFD: - case NFROMFD: - f = redir->ndup.dupfd; - if (f == redir->nfile.fd) - f = -2; - break; - default: - /* Fall through to eliminate warning. */ - case NHERE: - case NXHERE: - f = openhere(redir); - break; - } - return f; -ecreate: - sh_open_fail(fname, O_CREAT, EEXIST); -} - -static void dupredirect(union node *redir, int f) { - int fd = redir->nfile.fd; - int err = 0; - if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) { - /* if not ">&-" */ - if (f >= 0) { - if (dup2(f, fd) < 0) { - err = errno; - goto err; - } - return; - } - f = fd; - } else if (dup2(f, fd) < 0) { - err = errno; - } - close(f); - if (err < 0) - goto err; - return; -err: - sh_error("%ld: %s", f, strerror(err)); -} - -/* - * Handle here documents. Normally we fork off a process to write the - * data to a pipe. If the document is short, we can stuff the data in - * the pipe without forking. - */ -static int64_t openhere(union node *redir) { - char *p; - int pip[2]; - unsigned len = 0; - if (pipe(pip) < 0) - sh_error("Pipe call failed"); - p = redir->nhere.doc->narg.text; - if (redir->type == NXHERE) { - expandarg(redir->nhere.doc, NULL, EXP_QUOTED); - p = stackblock(); - } - len = strlen(p); - if (len <= PIPESIZE) { - __xwrite(pip[1], p, len); - goto out; - } - if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) { - close(pip[0]); - signal(SIGINT, SIG_IGN); - signal(SIGQUIT, SIG_IGN); - signal(SIGHUP, SIG_IGN); - signal(SIGPIPE, SIG_DFL); - __xwrite(pip[1], p, len); - _exit(0); - } -out: - close(pip[1]); - return pip[0]; -} - -/* - * Undo the effects of the last redirection. - */ -static void popredir(int drop) { - struct redirtab *rp; - int i; - INTOFF; - rp = redirlist; - for (i = 0; i < 10; i++) { - int closed; - if (rp->renamed[i] == EMPTY) - continue; - closed = drop ? 1 : update_closed_redirs(i, rp->renamed[i]); - switch (rp->renamed[i]) { - case CLOSED: - if (!closed) - close(i); - break; - default: - if (!drop) - dup2(rp->renamed[i], i); - close(rp->renamed[i]); - break; - } - } - redirlist = rp->next; - ckfree(rp); - INTON; -} - -/* - * Move a file descriptor to > 10. Invokes sh_error on error unless - * the original file dscriptor is not open. - */ -static int savefd(int from, int ofd) { - int newfd; - int err; - newfd = fcntl(from, F_DUPFD, 10); - err = newfd < 0 ? errno : 0; - if (err != EBADF) { - close(ofd); - if (err) { - sh_error("%d: %s", from, strerror(err)); - } else { - fcntl(newfd, F_SETFD, FD_CLOEXEC); - } - } - return newfd; -} - -static int redirectsafe(union node *redir, int flags) { - int err; - volatile int saveint; - struct jmploc *volatile savehandler = handler; - struct jmploc jmploc; - SAVEINT(saveint); - if (!(err = setjmp(jmploc.loc) * 2)) { - handler = &jmploc; - redirect(redir, flags); - } - handler = savehandler; - if (err && exception != EXERROR) - longjmp(handler->loc, 1); - RESTOREINT(saveint); - return err; -} - -static void unwindredir(struct redirtab *stop) { - while (redirlist != stop) - popredir(0); -} - -static struct redirtab *pushredir(union node *redir) { - struct redirtab *sv; - struct redirtab *q; - int i; - q = redirlist; - if (!redir) - goto out; - sv = ckmalloc(sizeof(struct redirtab)); - sv->next = q; - redirlist = sv; - for (i = 0; i < 10; i++) - sv->renamed[i] = EMPTY; -out: - return q; -} - -/* - * The trap builtin. - */ -static int trapcmd(int argc, char **argv) { - char *action; - char **ap; - int signo; - nextopt(nullstr); - ap = argptr; - if (!*ap) { - for (signo = 0; signo < NSIG; signo++) { - if (trap[signo] != NULL) { - out1fmt("trap -- %s %s\n", single_quote(trap[signo]), strsignal(signo)); - } - } - return 0; - } - if (!ap[1] || decode_signum(*ap) >= 0) - action = NULL; - else - action = *ap++; - while (*ap) { - if ((signo = decode_signal(*ap, 0)) < 0) { - outfmt(out2, "trap: %s: bad trap\n", *ap); - return 1; - } - INTOFF; - if (action) { - if (action[0] == '-' && action[1] == '\0') - action = NULL; - else { - if (*action) - trapcnt++; - action = savestr(action); - } - } - if (trap[signo]) { - if (*trap[signo]) - trapcnt--; - ckfree(trap[signo]); - } - trap[signo] = action; - if (signo != 0) - setsignal(signo); - INTON; - ap++; - } - return 0; -} - -/* - * Set the signal handler for the specified signal. The routine figures - * out what it should be set to. - */ -static void setsignal(int signo) { - int action; - int lvforked; - char *t, tsig; - struct sigaction act; - lvforked = vforked; - if ((t = trap[signo]) == NULL) - action = S_DFL; - else if (*t != '\0') - action = S_CATCH; - else - action = S_IGN; - if (rootshell && action == S_DFL && !lvforked) { - if (signo == SIGINT) { - if (iflag || minusc || sflag == 0) - action = S_CATCH; - } else if (signo == SIGQUIT || signo == SIGTERM) { - if (iflag) - action = S_IGN; - } else if (signo == SIGTSTP || signo == SIGTTOU) { - if (mflag) - action = S_IGN; - } - } - if (signo == SIGCHLD) - action = S_CATCH; - t = &sigmode[signo - 1]; - tsig = *t; - if (tsig == 0) { - /* - * current setting unknown - */ - if (sigaction(signo, 0, &act) == -1) { - /* - * Pretend it worked; maybe we should give a warning - * here, but other shells don't. We don't alter - * sigmode, so that we retry every time. - */ - return; - } - if (act.sa_handler == SIG_IGN) { - if (mflag && (signo == SIGTSTP || signo == SIGTTIN || signo == SIGTTOU)) { - tsig = S_IGN; /* don't hard ignore these */ - } else - tsig = S_HARD_IGN; - } else { - tsig = S_RESET; /* force to be set */ - } - } - if (tsig == S_HARD_IGN || tsig == action) - return; - switch (action) { - case S_CATCH: - act.sa_handler = onsig; - break; - case S_IGN: - act.sa_handler = SIG_IGN; - break; - default: - act.sa_handler = SIG_DFL; - } - if (!lvforked) - *t = action; - act.sa_flags = 0; - sigfillset(&act.sa_mask); - sigaction(signo, &act, 0); -} - -/* - * Ignore a signal. - */ -static void ignoresig(int signo) { - if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) { - signal(signo, SIG_IGN); - } - if (!vforked) - sigmode[signo - 1] = S_HARD_IGN; -} - -/* - * Signal handler. - */ -static void onsig(int signo) { - if (vforked) - return; - if (signo == SIGCHLD) { - gotsigchld = 1; - if (!trap[SIGCHLD]) - return; - } - gotsig[signo - 1] = 1; - pending_sig = signo; - if (signo == SIGINT && !trap[SIGINT]) { - if (!suppressint) - onint(); - intpending = 1; - } -} - -/* - * Called to execute a trap. Perhaps we should avoid entering new trap - * handlers while we are executing a trap handler. - */ -static void dotrap(void) { - char *p; - char *q; - int i; - int status, last_status; - if (!pending_sig) - return; - status = savestatus; - last_status = status; - if (likely(status < 0)) { - status = exitstatus; - savestatus = status; - } - pending_sig = 0; - barrier(); - for (i = 0, q = gotsig; i < NSIG - 1; i++, q++) { - if (!*q) - continue; - if (evalskip) { - pending_sig = i + 1; - break; - } - *q = 0; - p = trap[i + 1]; - if (!p) - continue; - evalstring(p, 0); - if (evalskip != SKIPFUNC) - exitstatus = status; - } - savestatus = last_status; -} - -/* - * Controls whether the shell is interactive or not. - */ -static void setinteractive(int on) { - static int is_interactive; - if (++on == is_interactive) - return; - is_interactive = on; - setsignal(SIGINT); - setsignal(SIGQUIT); - setsignal(SIGTERM); -} - -/* - * Called to exit the shell. - */ -wontreturn static void exitshell(void) { - struct jmploc loc; - char *p; - savestatus = exitstatus; - TRACE(("pid %d, exitshell(%d)\n", getpid(), savestatus)); - if (setjmp(loc.loc)) - goto out; - handler = &loc; - if ((p = trap[0])) { - trap[0] = NULL; - evalskip = 0; - evalstring(p, 0); - evalskip = SKIPFUNCDEF; - } -out: - exitreset(); - /* - * Disable job control so that whoever had the foreground before we - * started can get it back. - */ - if (likely(!setjmp(loc.loc))) - setjobctl(0); - flushall(); - _exit(exitstatus); -} - -static int decode_signal(const char *string, int minsig) { - int signo; - signo = decode_signum(string); - if (signo >= 0) - return signo; - for (signo = minsig; signo < NSIG; signo++) { - if (!strcasecmp(string, strsignal(signo))) { - return signo; - } - } - return -1; -} - -static void sigblockall(sigset_t *oldmask) { - sigset_t mask; - sigfillset(&mask); - sigprocmask(SIG_SETMASK, &mask, oldmask); -} - -#define PF(f, func) \ - { \ - switch ((char *)param - (char *)array) { \ - default: \ - (void)Printf(f, array[0], array[1], func); \ - break; \ - case sizeof(*param): \ - (void)Printf(f, array[0], func); \ - break; \ - case 0: \ - (void)Printf(f, func); \ - break; \ - } \ - } - -#define ASPF(sp, f, func) \ - ({ \ - int ret; \ - switch ((char *)param - (char *)array) { \ - default: \ - ret = Xasprintf(sp, f, array[0], array[1], func); \ - break; \ - case sizeof(*param): \ - ret = Xasprintf(sp, f, array[0], func); \ - break; \ - case 0: \ - ret = Xasprintf(sp, f, func); \ - break; \ - } \ - ret; \ - }) - -static int print_escape_str(const char *f, int *param, int *array, char *s) { - struct stackmark smark; - char *p, *q; - int done; - int len; - int total; - setstackmark(&smark); - done = conv_escape_str(s, &q); - p = stackblock(); - len = q - p; - total = len - 1; - q[-1] = (!!((f[1] - 's') | done) - 1) & f[2]; - total += !!q[-1]; - if (f[1] == 's') - goto easy; - p = makestrspace(len, q); - memset(p, 'X', total); - p[total] = 0; - q = stackblock(); - total = ASPF(&p, f, p); - len = strchrnul(p, 'X') - p; - memcpy(p + len, q, strspn(p + len, "X")); -easy: - outmem(p, total, out1); - popstackmark(&smark); - return done; -} - -static int printfcmd(int argc, char *argv[]) { - static const char kSkip1[] = "#-+ 0"; - static const char kSkip2[] = "*0123456789"; - char *fmt; - char *format; - int ch; - rval = 0; - nextopt(nullstr); - argv = argptr; - format = *argv; - if (!format) - sh_error("usage: printf format [arg ...]"); - gargv = ++argv; - do { - /* - * Basic algorithm is to scan the format string for conversion - * specifications -- once one is found, find out if the field - * width or precision is a '*'; if it is, gather up value. - * Note, format strings are reused as necessary to use up the - * provided arguments, arguments of zero/null string are - * provided to use up the format string. - */ - /* find next format specification */ - for (fmt = format; (ch = *fmt++);) { - char *start; - char nextch; - int array[2]; - int *param; - if (ch == '\\') { - int c_ch; - fmt = conv_escape(fmt, &c_ch); - ch = c_ch; - goto pc; - } - if (ch != '%' || (*fmt == '%' && (++fmt || 1))) { - pc: - outc(ch, out1); - continue; - } - /* Ok - we've found a format specification, - Save its address for a later printf(). */ - start = fmt - 1; - param = array; - /* skip to field width */ - fmt += strspn(fmt, kSkip1); - if (*fmt == '*') { - ++fmt; - *param++ = getuintmax(1); - } else { - /* skip to possible '.', - * get following precision - */ - fmt += strspn(fmt, kSkip2); - } - if (*fmt == '.') { - ++fmt; - if (*fmt == '*') { - ++fmt; - *param++ = getuintmax(1); - } else - fmt += strspn(fmt, kSkip2); - } - ch = *fmt; - if (!ch) - sh_error("missing format character"); - /* null terminate format string to we can use it - as an argument to printf. */ - nextch = fmt[1]; - fmt[1] = 0; - switch (ch) { - case 'b': - *fmt = 's'; - /* escape if a \c was encountered */ - if (print_escape_str(start, param, array, getstr())) - goto out; - *fmt = 'b'; - break; - case 'c': { - int p = getchr(); - PF(start, p); - break; - } - case 's': { - char *p = getstr(); - PF(start, p); - break; - } - case 'd': - case 'i': { - uint64_t p = getuintmax(1); - start = mklong(start, fmt); - PF(start, p); - break; - } - case 'o': - case 'u': - case 'x': - case 'X': { - uint64_t p = getuintmax(0); - start = mklong(start, fmt); - PF(start, p); - break; - } - case 'a': - case 'A': - case 'e': - case 'E': - case 'f': - case 'F': - case 'g': - case 'G': { - double p = getdouble(); - PF(start, p); - break; - } - default: - sh_error("%s: invalid directive", start); - } - *++fmt = nextch; - } - } while (gargv != argv && *gargv); -out: - return rval; -} - -/* - * Print SysV echo(1) style escape string - * Halts processing string if a \c escape is encountered. - */ -static int conv_escape_str(char *str, char **sp) { - int c; - int ch; - char *cp; - /* convert string into a temporary buffer... */ - STARTSTACKSTR(cp); - do { - c = ch = *str++; - if (ch != '\\') - continue; - c = *str++; - if (c == 'c') { - /* \c as in SYSV echo - abort all processing.... */ - c = ch = 0x100; - continue; - } - /* - * %b string octal constants are not like those in C. - * They start with a \0, and are followed by 0, 1, 2, - * or 3 octal digits. - */ - if (c == '0' && isodigit(*str)) - str++; - /* Finally test for sequences valid in the format string */ - str = conv_escape(str - 1, &c); - } while (STPUTC(c, cp), (char)ch); - *sp = cp; - return ch; -} - -/* - * Print "standard" escape characters - */ -static char *conv_escape(char *str, int *conv_ch) { - int value; - int ch; - ch = *str; - switch (ch) { - default: - if (!isodigit(*str)) { - value = '\\'; - goto out; - } - ch = 3; - value = 0; - do { - value <<= 3; - value += octtobin(*str++); - } while (isodigit(*str) && --ch); - goto out; - case '\\': - value = '\\'; - break; /* backslash */ - case 'a': - value = '\a'; - break; /* alert */ - case 'b': - value = '\b'; - break; /* backspace */ - case 'f': - value = '\f'; - break; /* form-feed */ - case 'e': - value = '\e'; - break; /* escape */ - case 'n': - value = '\n'; - break; /* newline */ - case 'r': - value = '\r'; - break; /* carriage-return */ - case 't': - value = '\t'; - break; /* tab */ - case 'v': - value = '\v'; - break; /* vertical-tab */ - } - str++; -out: - *conv_ch = value; - return str; -} - -#define PRIdMAX "ld" - -static char *mklong(const char *str, const char *ch) { - /* - * Replace a string like "%92.3u" with "%92.3"PRIuMAX. - * - * Although C99 does not guarantee it, we assume PRIiMAX, - * PRIoMAX, PRIuMAX, PRIxMAX, and PRIXMAX are all the same - * as PRIdMAX with the final 'd' replaced by the corresponding - * character. - */ - char *copy; - unsigned len; - len = ch - str + sizeof(PRIdMAX); - STARTSTACKSTR(copy); - copy = makestrspace(len, copy); - memcpy(copy, str, len - sizeof(PRIdMAX)); - memcpy(copy + len - sizeof(PRIdMAX), PRIdMAX, sizeof(PRIdMAX)); - copy[len - 2] = *ch; - return (copy); -} - -static uint64_t getuintmax(int sign) { - uint64_t val = 0; - char *cp, *ep; - cp = *gargv; - if (cp == NULL) - goto out; - gargv++; - val = (unsigned char)cp[1]; - if (*cp == '\"' || *cp == '\'') - goto out; - errno = 0; - val = sign ? strtoimax(cp, &ep, 0) : strtoumax(cp, &ep, 0); - check_conversion(cp, ep); -out: - return val; -} - -static double getdouble(void) { - double val; - char *cp, *ep; - cp = *gargv; - if (cp == NULL) - return 0; - gargv++; - if (*cp == '\"' || *cp == '\'') - return (unsigned char)cp[1]; - errno = 0; - val = strtod(cp, &ep); - check_conversion(cp, ep); - return val; -} - -static void check_conversion(const char *s, const char *ep) { - if (*ep) { - if (ep == s) - sh_warnx("%s: expected numeric value", s); - else - sh_warnx("%s: not completely converted", s); - rval = 1; - } else if (errno == ERANGE) { - sh_warnx("%s: %s", s, strerror(ERANGE)); - rval = 1; - } -} - -static int echocmd(int argc, char **argv) { - const char *lastfmt = snlfmt; - int nonl; - if (*++argv && equal(*argv, "-n")) { - argv++; - lastfmt = "%s"; - } - do { - const char *fmt = "%s "; - char *s = *argv; - if (!s || !*++argv) - fmt = lastfmt; - nonl = print_escape_str(fmt, NULL, NULL, s ?: nullstr); - } while (!nonl && *argv); - return 0; -} - -/* - * test(1); version 7-like -- author Erik Baalbergen - * modified by Eric Gisin to be used as built-in. - * modified by Arnold Robbins to add SVR3 compatibility - * (-x -c -b -p -u -g -k) plus Korn's -L -nt -ot -ef and new -S (socket). - * modified by J.T. Conklin for NetBSD. - * - * This program is in the Public Domain. - */ - -/* test(1) accepts the following grammar: - oexpr ::= aexpr | aexpr "-o" oexpr ; - aexpr ::= nexpr | nexpr "-a" aexpr ; - nexpr ::= primary | "!" primary - primary ::= unary-operator operand - | operand binary-operator operand - | operand - | "(" oexpr ")" - ; - unary-operator ::= "-r"|"-w"|"-x"|"-f"|"-d"|"-c"|"-b"|"-p"| - "-u"|"-g"|"-k"|"-s"|"-t"|"-z"|"-n"|"-o"|"-O"|"-G"|"-L"|"-S"; - binary-operator ::= "="|"!="|"-eq"|"-ne"|"-ge"|"-gt"|"-le"|"-lt"| - "-nt"|"-ot"|"-ef"; - operand ::= -*/ - -static inline int faccessat_confused_about_superuser(void) { - return 0; -} - -static const struct t_op *getop(const char *s) { - const struct t_op *op; - for (op = ops; op->op_text; op++) { - if (strcmp(s, op->op_text) == 0) - return op; - } - return NULL; -} - -static int testcmd(int argc, char **argv) { - const struct t_op *op; - enum token n; - int res = 1; - if (*argv[0] == '[') { - if (*argv[--argc] != ']') - sh_error("missing ]"); - argv[argc] = NULL; - } - t_wp_op = NULL; -recheck: - argv++; - argc--; - if (argc < 1) - return res; - /* - * POSIX prescriptions: he who wrote this deserves the Nobel - * peace prize. - */ - switch (argc) { - case 3: - op = getop(argv[1]); - if (op && op->op_type == BINOP) { - n = OPERAND; - goto eval; - } - /* fall through */ - case 4: - if (!strcmp(argv[0], "(") && !strcmp(argv[argc - 1], ")")) { - argv[--argc] = NULL; - argv++; - argc--; - } else if (!strcmp(argv[0], "!")) { - res = 0; - goto recheck; - } - } - n = t_lex(argv); -eval: - t_wp = argv; - res ^= oexpr(n); - argv = t_wp; - if (argv[0] != NULL && argv[1] != NULL) - syntax(argv[0], "unexpected operator"); - return res; -} - -static void syntax(const char *op, const char *msg) { - if (op && *op) { - sh_error("%s: %s", op, msg); - } else { - sh_error("%s", msg); - } -} - -static int oexpr(enum token n) { - int res = 0; - for (;;) { - res |= aexpr(n); - n = t_lex(t_wp + 1); - if (n != BOR) - break; - n = t_lex(t_wp += 2); - } - return res; -} - -static int aexpr(enum token n) { - int res = 1; - for (;;) { - if (!nexpr(n)) - res = 0; - n = t_lex(t_wp + 1); - if (n != BAND) - break; - n = t_lex(t_wp += 2); - } - return res; -} - -static int nexpr(enum token n) { - if (n != UNOT) - return primary1(n); - n = t_lex(t_wp + 1); - if (n != EOI) - t_wp++; - return !nexpr(n); -} - -static int primary1(enum token n) { - enum token nn; - int res; - if (n == EOI) - return 0; /* missing expression */ - if (n == LPAREN) { - if ((nn = t_lex(++t_wp)) == RPAREN) - return 0; /* missing expression */ - res = oexpr(nn); - if (t_lex(++t_wp) != RPAREN) - syntax(NULL, "closing paren expected"); - return res; - } - if (t_wp_op && t_wp_op->op_type == UNOP) { - /* unary expression */ - if (*++t_wp == NULL) - syntax(t_wp_op->op_text, "argument expected"); - switch (n) { - case STREZ: - return strlen(*t_wp) == 0; - case STRNZ: - return strlen(*t_wp) != 0; - case FILTT: - return isatty(getn(*t_wp)); - case FILRD: - return test_file_access(*t_wp, R_OK); - case FILWR: - return test_file_access(*t_wp, W_OK); - case FILEX: - return test_file_access(*t_wp, X_OK); - default: - return filstat(*t_wp, n); - } - } - if (t_lex(t_wp + 1), t_wp_op && t_wp_op->op_type == BINOP) { - return binop0(); - } - return strlen(*t_wp) > 0; -} - -static int binop0(void) { - const char *opnd1, *opnd2; - struct t_op const *op; - opnd1 = *t_wp; - (void)t_lex(++t_wp); - op = t_wp_op; - if ((opnd2 = *++t_wp) == (char *)0) - syntax(op->op_text, "argument expected"); - switch (op->op_num) { - default: - case STREQ: - return strcmp(opnd1, opnd2) == 0; - case STRNE: - return strcmp(opnd1, opnd2) != 0; - case STRLT: - return strcmp(opnd1, opnd2) < 0; - case STRGT: - return strcmp(opnd1, opnd2) > 0; - case INTEQ: - return getn(opnd1) == getn(opnd2); - case INTNE: - return getn(opnd1) != getn(opnd2); - case INTGE: - return getn(opnd1) >= getn(opnd2); - case INTGT: - return getn(opnd1) > getn(opnd2); - case INTLE: - return getn(opnd1) <= getn(opnd2); - case INTLT: - return getn(opnd1) < getn(opnd2); - case FILNT: - return newerf(opnd1, opnd2); - case FILOT: - return olderf(opnd1, opnd2); - case FILEQ: - return equalf(opnd1, opnd2); - } -} - -static int filstat(char *nm, enum token mode) { - struct stat s; - if (mode == FILSYM ? lstat(nm, &s) : stat(nm, &s)) - return 0; - switch (mode) { - case FILEXIST: - return 1; - case FILREG: - return S_ISREG(s.st_mode); - case FILDIR: - return S_ISDIR(s.st_mode); - case FILCDEV: - return S_ISCHR(s.st_mode); - case FILBDEV: - return S_ISBLK(s.st_mode); - case FILFIFO: - return S_ISFIFO(s.st_mode); - case FILSOCK: - return S_ISSOCK(s.st_mode); - case FILSYM: - return S_ISLNK(s.st_mode); - case FILSUID: - return (s.st_mode & S_ISUID) != 0; - case FILSGID: - return (s.st_mode & S_ISGID) != 0; - case FILSTCK: - return (s.st_mode & S_ISVTX) != 0; - case FILGZ: - return !!s.st_size; - case FILUID: - return s.st_uid == geteuid(); - case FILGID: - return s.st_gid == getegid(); - default: - return 1; - } -} - -static enum token t_lex(char **tp) { - struct t_op const *op; - char *s = *tp; - if (s == 0) { - t_wp_op = (struct t_op *)0; - return EOI; - } - op = getop(s); - if (op && !(op->op_type == UNOP && isoperand(tp)) && - !(op->op_num == LPAREN && !tp[1])) { - t_wp_op = op; - return op->op_num; - } - t_wp_op = (struct t_op *)0; - return OPERAND; -} - -static int isoperand(char **tp) { - struct t_op const *op; - char *s; - if (!(s = tp[1])) - return 1; - if (!tp[2]) - return 0; - op = getop(s); - return op && op->op_type == BINOP; -} - -static int newerf(const char *f1, const char *f2) { - struct stat b1, b2; - return (stat(f1, &b1) == 0 && stat(f2, &b2) == 0 && - (b1.st_mtim.tv_sec > b2.st_mtim.tv_sec || - (b1.st_mtim.tv_sec == b2.st_mtim.tv_sec && - (b1.st_mtim.tv_nsec > b2.st_mtim.tv_nsec)))); -} - -static int olderf(const char *f1, const char *f2) { - struct stat b1, b2; - return (stat(f1, &b1) == 0 && stat(f2, &b2) == 0 && - (b1.st_mtim.tv_sec < b2.st_mtim.tv_sec || - (b1.st_mtim.tv_sec == b2.st_mtim.tv_sec && - (b1.st_mtim.tv_nsec < b2.st_mtim.tv_nsec)))); -} - -static int equalf(const char *f1, const char *f2) { - struct stat b1, b2; - return (stat(f1, &b1) == 0 && stat(f2, &b2) == 0 && b1.st_dev == b2.st_dev && - b1.st_ino == b2.st_ino); -} - -static int has_exec_bit_set(const char *path) { - struct stat st; - if (stat(path, &st)) - return 0; - return st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH); -} - -static int test_file_access(const char *path, int mode) { - if (faccessat_confused_about_superuser() && mode == X_OK && geteuid() == 0 && - !has_exec_bit_set(path)) { - return 0; - } - return !faccessat(AT_FDCWD, path, mode, AT_EACCESS); -} - -static int timescmd() { - struct tms buf; - long int clk_tck = sysconf(_SC_CLK_TCK); - int mutime, mstime, mcutime, mcstime; - double utime, stime, cutime, cstime; - times(&buf); - utime = (double)buf.tms_utime / clk_tck; - mutime = utime / 60; - utime -= mutime * 60.0; - stime = (double)buf.tms_stime / clk_tck; - mstime = stime / 60; - stime -= mstime * 60.0; - cutime = (double)buf.tms_cutime / clk_tck; - mcutime = cutime / 60; - cutime -= mcutime * 60.0; - cstime = (double)buf.tms_cstime / clk_tck; - mcstime = cstime / 60; - cstime -= mcstime * 60.0; - Printf("%dm%fs %dm%fs\n%dm%fs %dm%fs\n", mutime, utime, mstime, stime, - mcutime, cutime, mcstime, cstime); - return 0; -} - -/* - * Find the appropriate entry in the hash table from the name. - */ -static struct Var **hashvar(const char *p) { - unsigned int hashval; - hashval = ((unsigned char)*p) << 4; - while (*p && *p != '=') - hashval += (unsigned char)*p++; - return &vartab[hashval % VTABSIZE]; -} - -/* - * This routine initializes the builtin variables. It is called when the - * shell is initialized. - */ -static void initvar(void) { - struct Var *vp; - struct Var *end; - struct Var **vpp; - vp = varinit; - end = vp + sizeof(varinit) / sizeof(varinit[0]); - do { - vpp = hashvar(vp->text); - vp->next = *vpp; - *vpp = vp; - } while (++vp < end); - /* PS1 depends on uid */ - if (!geteuid()) { - vps1.text = "PS1=# "; - } -} - -/* - * Set the value of a variable. The flags argument is ored with the - * flags of the variable. If val is NULL, the variable is unset. - */ -static struct Var *setvar(const char *name, const char *val, int flags) { - char *p, *q; - unsigned namelen; - char *nameeq; - unsigned vallen; - struct Var *vp; - q = endofname(name); - p = strchrnul(q, '='); - namelen = p - name; - if (!namelen || p != q) - sh_error("%.*s: bad variable name", namelen, name); - vallen = 0; - if (val == NULL) { - flags |= VUNSET; - } else { - vallen = strlen(val); - } - INTOFF; - p = mempcpy(nameeq = ckmalloc(namelen + vallen + 2), name, namelen); - if (val) { - *p++ = '='; - p = mempcpy(p, val, vallen); - } - *p = '\0'; - vp = setvareq(nameeq, flags | VNOSAVE); - INTON; - return vp; -} - -/* - * Set the given integer as the value of a variable. The flags argument is - * ored with the flags of the variable. - */ -static int64_t setvarint(const char *name, int64_t val, int flags) { - int len = max_int_length(sizeof(val)); - char buf[len]; - fmtstr(buf, len, "%ld", val); - setvar(name, buf, flags); - return val; -} - -static struct Var **findvar(struct Var **vpp, const char *name) { - for (; *vpp; vpp = &(*vpp)->next) { - if (varequal((*vpp)->text, name)) { - break; - } - } - return vpp; -} - -/* - * Same as setvar except that the variable and value are passed in - * the first argument as name=value. Since the first argument will - * be actually stored in the table, it should not be a string that - * will go away. - * Called with interrupts off. - */ -static struct Var *setvareq(char *s, int flags) { - struct Var *vp, **vpp; - vpp = hashvar(s); - flags |= (VEXPORT & (((unsigned)(1 - aflag)) - 1)); - vpp = findvar(vpp, s); - vp = *vpp; - if (vp) { - if (vp->flags & VREADONLY) { - const char *n; - if (flags & VNOSAVE) - free(s); - n = vp->text; - sh_error("%.*s: is read only", strchrnul(n, '=') - n, n); - } - if (flags & VNOSET) - goto out; - if (vp->func && (flags & VNOFUNC) == 0) - (*vp->func)(strchrnul(s, '=') + 1); - if ((vp->flags & (VTEXTFIXED | VSTACK)) == 0) - ckfree(vp->text); - if (((flags & (VEXPORT | VREADONLY | VSTRFIXED | VUNSET)) | - (vp->flags & VSTRFIXED)) == VUNSET) { - *vpp = vp->next; - ckfree(vp); - out_free: - if ((flags & (VTEXTFIXED | VSTACK | VNOSAVE)) == VNOSAVE) - ckfree(s); - goto out; - } - flags |= vp->flags & ~(VTEXTFIXED | VSTACK | VNOSAVE | VUNSET); - } else { - if (flags & VNOSET) - goto out; - if ((flags & (VEXPORT | VREADONLY | VSTRFIXED | VUNSET)) == VUNSET) - goto out_free; - /* not found */ - vp = ckmalloc(sizeof(*vp)); - vp->next = *vpp; - vp->func = NULL; - *vpp = vp; - } - if (!(flags & (VTEXTFIXED | VSTACK | VNOSAVE))) - s = savestr(s); - vp->text = s; - vp->flags = flags; -out: - return vp; -} - -/* - * Find the value of a variable. Returns NULL if not set. - */ -static char *lookupvar(const char *name) { - struct Var *v; - if ((v = *findvar(hashvar(name), name)) && !(v->flags & VUNSET)) { - if (v == &vlineno && v->text == linenovar) { - fmtstr(linenovar + 7, sizeof(linenovar) - 7, "%d", lineno); - } - return strchrnul(v->text, '=') + 1; - } - return NULL; -} - -static int64_t lookupvarint(const char *name) { - return atomax(lookupvar(name) ?: nullstr, 0); -} - -/* - * Generate a list of variables satisfying the given conditions. - */ -static char **listvars(int on, int off, char ***end) { - struct Var **vpp; - struct Var *vp; - char **ep; - int mask; - STARTSTACKSTR(ep); - vpp = vartab; - mask = on | off; - do { - for (vp = *vpp; vp; vp = vp->next) - if ((vp->flags & mask) == on) { - if (ep == stackstrend()) - ep = growstackstr(); - *ep++ = (char *)vp->text; - } - } while (++vpp < vartab + VTABSIZE); - if (ep == stackstrend()) - ep = growstackstr(); - if (end) - *end = ep; - *ep++ = NULL; - return grabstackstr(ep); -} - -static int vpcmp(const void *a, const void *b) { - return varcmp(*(const char **)a, *(const char **)b); -} - -/* - * POSIX requires that 'set' (but not export or readonly) output the - * variables in lexicographic order - by the locale's collating order (sigh). - * Maybe we could keep them in an ordered balanced binary tree - * instead of hashed lists. - * For now just roll 'em through qsort for printing... - */ -static int showvars(const char *prefix, int on, int off) { - const char *sep; - char **ep, **epend; - ep = listvars(on, off, &epend); - qsort(ep, epend - ep, sizeof(char *), vpcmp); - sep = *prefix ? spcstr : prefix; - for (; ep < epend; ep++) { - const char *p; - const char *q; - p = strchrnul(*ep, '='); - q = nullstr; - if (*p) - q = single_quote(++p); - out1fmt("%s%s%.*s%s\n", prefix, sep, (int)(p - *ep), *ep, q); - } - return 0; -} - -/* - * The export and readonly commands. - */ -static int exportcmd(int argc, char **argv) { - struct Var *vp; - char *name; - const char *p; - char **aptr; - int flag = argv[0][0] == 'r' ? VREADONLY : VEXPORT; - int notp; - notp = nextopt("p") - 'p'; - if (notp && ((name = *(aptr = argptr)))) { - do { - if ((p = strchr(name, '=')) != NULL) { - p++; - } else { - if ((vp = *findvar(hashvar(name), name))) { - vp->flags |= flag; - continue; - } - } - setvar(name, p, flag); - } while ((name = *++aptr) != NULL); - } else { - showvars(argv[0], flag, 0); - } - return 0; -} - -/* - * The "local" command. - */ -static int localcmd(int argc, char **argv) { - char *name; - if (!localvar_stack) - sh_error("not in a function"); - argv = argptr; - while ((name = *argv++) != NULL) { - mklocal(name, 0); - } - return 0; -} - -/* - * Make a variable a local variable. When a variable is made local, it's - * value and flags are saved in a localvar structure. The saved values - * will be restored when the shell function returns. We handle the name - * "-" as a special case. - */ -static void mklocal(char *name, int flags) { - struct localvar *lvp; - struct Var **vpp; - struct Var *vp; - INTOFF; - lvp = ckmalloc(sizeof(struct localvar)); - if (name[0] == '-' && name[1] == '\0') { - char *p; - p = ckmalloc(sizeof(optlist)); - lvp->text = memcpy(p, optlist, sizeof(optlist)); - vp = NULL; - } else { - char *eq; - vpp = hashvar(name); - vp = *findvar(vpp, name); - eq = strchr(name, '='); - if (vp == NULL) { - if (eq) - vp = setvareq(name, VSTRFIXED | flags); - else - vp = setvar(name, NULL, VSTRFIXED | flags); - lvp->flags = VUNSET; - } else { - lvp->text = vp->text; - lvp->flags = vp->flags; - vp->flags |= VSTRFIXED | VTEXTFIXED; - if (eq) - setvareq(name, flags); - } - } - lvp->vp = vp; - lvp->next = localvar_stack->lv; - localvar_stack->lv = lvp; - INTON; -} - -/* - * Called after a function returns. - * Interrupts must be off. - */ -static void poplocalvars(void) { - struct localvar_list *ll; - struct localvar *lvp, *next; - struct Var *vp; - INTOFF; - ll = localvar_stack; - localvar_stack = ll->next; - next = ll->lv; - ckfree(ll); - while ((lvp = next) != NULL) { - next = lvp->next; - vp = lvp->vp; - TRACE(("poplocalvar %s\n", vp ? vp->text : "-")); - if (vp == NULL) { /* $- saved */ - memcpy(optlist, lvp->text, sizeof(optlist)); - ckfree(lvp->text); - optschanged(); - } else if (lvp->flags == VUNSET) { - vp->flags &= ~(VSTRFIXED | VREADONLY); - unsetvar(vp->text); - } else { - if (vp->func) - (*vp->func)(strchrnul(lvp->text, '=') + 1); - if ((vp->flags & (VTEXTFIXED | VSTACK)) == 0) - ckfree(vp->text); - vp->flags = lvp->flags; - vp->text = lvp->text; - } - ckfree(lvp); - } - INTON; -} - -/* - * Create a new localvar environment. - */ -static struct localvar_list *pushlocalvars(int push) { - struct localvar_list *ll; - struct localvar_list *top; - top = localvar_stack; - if (!push) - goto out; - INTOFF; - ll = ckmalloc(sizeof(*ll)); - ll->lv = NULL; - ll->next = top; - localvar_stack = ll; - INTON; -out: - return top; -} - -static void unwindlocalvars(struct localvar_list *stop) { - while (localvar_stack != stop) - poplocalvars(); -} - -/* - * The unset builtin command. We unset the function before we unset the - * variable to allow a function to be unset when there is a readonly variable - * with the same name. - */ -static int unsetcmd(int argc, char **argv) { - char **ap; - int i; - int flag = 0; - while ((i = nextopt("vf")) != '\0') { - flag = i; - } - for (ap = argptr; *ap; ap++) { - if (flag != 'f') { - unsetvar(*ap); - continue; - } - if (flag != 'v') - unsetfunc(*ap); - } - return 0; -} - -static void unsetvar(const char *s) { - setvar(s, 0, 0); -} - -/* - * Initialization code. - */ -static void init() { - /* from input.c: */ - { - basepf.nextc = basepf.buf = basebuf; - basepf.linno = 1; - } - /* from trap.c: */ - { - sigmode[SIGCHLD - 1] = S_DFL; - setsignal(SIGCHLD); - } - /* from var.c: */ - { - char **envp; - static char ppid[32] = "PPID="; - const char *p; - struct stat st1, st2; - initvar(); - for (envp = environ; *envp; envp++) { - p = endofname(*envp); - if (p != *envp && *p == '=') { - setvareq(*envp, VEXPORT | VTEXTFIXED); - } - } - setvareq(defifsvar, VTEXTFIXED); - setvareq(defoptindvar, VTEXTFIXED); - fmtstr(ppid + 5, sizeof(ppid) - 5, "%ld", (long)getppid()); - setvareq(ppid, VTEXTFIXED); - p = lookupvar("PWD"); - if (p) { - if (*p != '/' || stat(p, &st1) || stat(".", &st2) || - st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino) { - p = 0; - } - } - setpwd(p, 0); - } -} - -/* - * This routine is called when an error or an interrupt occurs in an - * interactive shell and control is returned to the main command loop - * but prior to exitshell. - */ -static void exitreset() { - /* from eval.c: */ - { - if (savestatus >= 0) { - if (exception == EXEXIT || evalskip == SKIPFUNCDEF) - exitstatus = savestatus; - savestatus = -1; - } - evalskip = 0; - loopnest = 0; - inps4 = 0; - } - /* from expand.c: */ - { - ifsfree(); - } - /* from redir.c: */ - { - /* - * Discard all saved file descriptors. - */ - unwindredir(0); - } -} - -/* - * This routine is called when we enter a subshell. - */ -static void forkreset() { - /* from input.c: */ - { - popallfiles(); - if (parsefile->fd > 0) { - close(parsefile->fd); - parsefile->fd = 0; - } - } - /* from main.c: */ - { - handler = &main_handler; - } - /* from redir.c: */ - { - redirlist = NULL; - } - /* from trap.c: */ - { - char **tp; - INTOFF; - for (tp = trap; tp < &trap[NSIG]; tp++) { - if (*tp && **tp) { /* trap not NULL or SIG_IGN */ - ckfree(*tp); - *tp = NULL; - if (tp != &trap[0]) - setsignal(tp - trap); - } - } - trapcnt = 0; - INTON; - } -} - -/* - * This routine is called when an error or an interrupt occurs in an - * interactive shell and control is returned to the main command loop. - */ -static void reset() { - /* from input.c: */ - { - /* clear input buffer */ - basepf.lleft = basepf.nleft = 0; - basepf.unget = 0; - popallfiles(); - } - /* from var.c: */ - { - unwindlocalvars(0); - } -} - -static void calcsize(union node *n) { - if (n == NULL) - return; - funcblocksize += nodesize[n->type]; - switch (n->type) { - case NCMD: - calcsize(n->ncmd.redirect); - calcsize(n->ncmd.args); - calcsize(n->ncmd.assign); - break; - case NPIPE: - sizenodelist(n->npipe.cmdlist); - break; - case NREDIR: - case NBACKGND: - case NSUBSHELL: - calcsize(n->nredir.redirect); - calcsize(n->nredir.n); - break; - case NAND: - case NOR: - case NSEMI: - case NWHILE: - case NUNTIL: - calcsize(n->nbinary.ch2); - calcsize(n->nbinary.ch1); - break; - case NIF: - calcsize(n->nif.elsepart); - calcsize(n->nif.ifpart); - calcsize(n->nif.test); - break; - case NFOR: - funcstringsize += strlen(n->nfor.var_) + 1; - calcsize(n->nfor.body); - calcsize(n->nfor.args); - break; - case NCASE: - calcsize(n->ncase.cases); - calcsize(n->ncase.expr); - break; - case NCLIST: - calcsize(n->nclist.body); - calcsize(n->nclist.pattern); - calcsize(n->nclist.next); - break; - case NDEFUN: - calcsize(n->ndefun.body); - funcstringsize += strlen(n->ndefun.text) + 1; - break; - case NARG: - sizenodelist(n->narg.backquote); - funcstringsize += strlen(n->narg.text) + 1; - calcsize(n->narg.next); - break; - case NTO: - case NCLOBBER: - case NFROM: - case NFROMTO: - case NAPPEND: - calcsize(n->nfile.fname); - calcsize(n->nfile.next); - break; - case NTOFD: - case NFROMFD: - calcsize(n->ndup.vname); - calcsize(n->ndup.next); - break; - case NHERE: - case NXHERE: - calcsize(n->nhere.doc); - calcsize(n->nhere.next); - break; - case NNOT: - calcsize(n->nnot.com); - break; - }; -} - -/* - * Make a copy of a parse tree. - */ -static struct funcnode *copyfunc(union node *n) { - struct funcnode *f; - unsigned blocksize; - funcblocksize = offsetof(struct funcnode, n); - funcstringsize = 0; - calcsize(n); - blocksize = funcblocksize; - f = ckmalloc(blocksize + funcstringsize); - funcblock = (char *)f + offsetof(struct funcnode, n); - funcstring = (char *)f + blocksize; - copynode(n); - f->count = 0; - return f; -} - -static void sizenodelist(struct nodelist *lp) { - while (lp) { - funcblocksize += SHELL_ALIGN(sizeof(struct nodelist)); - calcsize(lp->n); - lp = lp->next; - } -} - -static union node *copynode(union node *n) { - union node *new; - if (n == NULL) - return NULL; - new = funcblock; - funcblock = (char *)funcblock + nodesize[n->type]; - switch (n->type) { - case NCMD: - new->ncmd.redirect = copynode(n->ncmd.redirect); - new->ncmd.args = copynode(n->ncmd.args); - new->ncmd.assign = copynode(n->ncmd.assign); - new->ncmd.linno = n->ncmd.linno; - break; - case NPIPE: - new->npipe.cmdlist = copynodelist(n->npipe.cmdlist); - new->npipe.backgnd = n->npipe.backgnd; - break; - case NREDIR: - case NBACKGND: - case NSUBSHELL: - new->nredir.redirect = copynode(n->nredir.redirect); - new->nredir.n = copynode(n->nredir.n); - new->nredir.linno = n->nredir.linno; - break; - case NAND: - case NOR: - case NSEMI: - case NWHILE: - case NUNTIL: - new->nbinary.ch2 = copynode(n->nbinary.ch2); - new->nbinary.ch1 = copynode(n->nbinary.ch1); - break; - case NIF: - new->nif.elsepart = copynode(n->nif.elsepart); - new->nif.ifpart = copynode(n->nif.ifpart); - new->nif.test = copynode(n->nif.test); - break; - case NFOR: - new->nfor.var_ = nodesavestr(n->nfor.var_); - new->nfor.body = copynode(n->nfor.body); - new->nfor.args = copynode(n->nfor.args); - new->nfor.linno = n->nfor.linno; - break; - case NCASE: - new->ncase.cases = copynode(n->ncase.cases); - new->ncase.expr = copynode(n->ncase.expr); - new->ncase.linno = n->ncase.linno; - break; - case NCLIST: - new->nclist.body = copynode(n->nclist.body); - new->nclist.pattern = copynode(n->nclist.pattern); - new->nclist.next = copynode(n->nclist.next); - break; - case NDEFUN: - new->ndefun.body = copynode(n->ndefun.body); - new->ndefun.text = nodesavestr(n->ndefun.text); - new->ndefun.linno = n->ndefun.linno; - break; - case NARG: - new->narg.backquote = copynodelist(n->narg.backquote); - new->narg.text = nodesavestr(n->narg.text); - new->narg.next = copynode(n->narg.next); - break; - case NTO: - case NCLOBBER: - case NFROM: - case NFROMTO: - case NAPPEND: - new->nfile.fname = copynode(n->nfile.fname); - new->nfile.fd = n->nfile.fd; - new->nfile.next = copynode(n->nfile.next); - break; - case NTOFD: - case NFROMFD: - new->ndup.vname = copynode(n->ndup.vname); - new->ndup.dupfd = n->ndup.dupfd; - new->ndup.fd = n->ndup.fd; - new->ndup.next = copynode(n->ndup.next); - break; - case NHERE: - case NXHERE: - new->nhere.doc = copynode(n->nhere.doc); - new->nhere.fd = n->nhere.fd; - new->nhere.next = copynode(n->nhere.next); - break; - case NNOT: - new->nnot.com = copynode(n->nnot.com); - break; - }; - new->type = n->type; - return new; -} - -static struct nodelist *copynodelist(struct nodelist *lp) { - struct nodelist *start; - struct nodelist **lpp; - lpp = &start; - while (lp) { - *lpp = funcblock; - funcblock = (char *)funcblock + SHELL_ALIGN(sizeof(struct nodelist)); - (*lpp)->n = copynode(lp->n); - lp = lp->next; - lpp = &(*lpp)->next; - } - *lpp = NULL; - return start; -} - -/* - * Read and execute commands. "Top" is nonzero for the top level command - * loop; it turns on prompting if the shell is interactive. - */ -static int cmdloop(int top) { - union node *n; - struct stackmark smark; - int inter; - int status = 0; - int numeof = 0; - TRACE(("cmdloop(%d) called\n", top)); - for (;;) { - int skip; - setstackmark(&smark); - if (jobctl) - showjobs(out2, SHOW_CHANGED); - inter = 0; - if (iflag && top) { - inter++; - /* chkmail(); */ - } - n = parsecmd(inter); - /* showtree(n); DEBUG */ - if (n == NEOF) { - if (!top || numeof >= 50) - break; - if (!stoppedjobs()) { - if (!Iflag) { - if (iflag) - outcslow('\n', out2); - break; - } - outstr("\nUse \"exit\" to leave shell.\n", out2); - } - numeof++; - } else { - int i; - job_warning = (job_warning == 2) ? 1 : 0; - numeof = 0; - i = evaltree(n, 0); - if (n) - status = i; - } - popstackmark(&smark); - skip = evalskip; - if (skip) { - evalskip &= ~(SKIPFUNC | SKIPFUNCDEF); - break; - } - } - return status; -} - -/* - * Read /etc/profile or .profile. Return on error. - */ -static void read_profile(const char *name) { - name = expandstr(name); - if (setinputfile(name, INPUT_PUSH_FILE | INPUT_NOFILE_OK) < 0) - return; - cmdloop(0); - popfile(); -} - -/* - * Take commands from a file. To be compatible we should do a path - * search for the file, which is necessary to find sub-commands. - */ -static char *find_dot_file(char *basename) { - char *fullname; - const char *path = pathval(); - struct stat statb; - int len; - /* don't try this for absolute or relative paths */ - if (strchr(basename, '/')) - return basename; - while ((len = padvance(&path, basename)) >= 0) { - fullname = stackblock(); - if ((!pathopt || *pathopt == 'f') && !stat(fullname, &statb) && - S_ISREG(statb.st_mode)) { - /* This will be freed by the caller. */ - return stalloc(len); - } - } - /* not found in the PATH */ - sh_error("%s: not found", basename); -} - -static int dotcmd(int argc, char **argv) { - int status = 0; - nextopt(nullstr); - argv = argptr; - if (*argv) { - char *fullname; - fullname = find_dot_file(*argv); - setinputfile(fullname, INPUT_PUSH_FILE); - commandname = fullname; - status = cmdloop(0); - popfile(); - } - return status; -} - -static int exitcmd(int argc, char **argv) { - if (stoppedjobs()) - return 0; - if (argc > 1) - savestatus = number(argv[1]); - exraise(EXEXIT); -} - -/** - * Main routine. We initialize things, parse the arguments, execute - * profiles if we're a login shell, and then call cmdloop to execute - * commands. The setjmp call sets up the location to jump to when an - * exception occurs. When an exception occurs the variable "state" - * is used to figure out how far we had gotten. - */ -int main(int argc, char **argv) { - char *shinit; - volatile int state; - struct stackmark smark; - int login; - state = 0; - if (unlikely(setjmp(main_handler.loc))) { - int e; - int s; - exitreset(); - e = exception; - s = state; - if (e == EXEND || e == EXEXIT || s == 0 || iflag == 0 || shlvl) - exitshell(); - reset(); - if (e == EXINT) { - outcslow('\n', out2); - } - popstackmark(&smark); - FORCEINTON; /* enable interrupts */ - if (s == 1) { - goto state1; - } else if (s == 2) { - goto state2; - } else if (s == 3) { - goto state3; - } else { - goto state4; - } - } - handler = &main_handler; - rootpid = getpid(); - init(); - setstackmark(&smark); - login = procargs(argc, argv); - if (login) { - state = 1; - read_profile("/etc/profile"); - state1: - state = 2; - read_profile("$HOME/.profile"); - } -state2: - state = 3; - if (iflag) { - if ((shinit = lookupvar("ENV")) != NULL && *shinit != '\0') { - read_profile(shinit); - } - } - popstackmark(&smark); -state3: - state = 4; - if (minusc) - evalstring(minusc, sflag ? 0 : EV_EXIT); - if (sflag || minusc == NULL) { - state4: /* XXX ??? - why isn't this before the "if" statement */ - cmdloop(1); - } - exitshell(); -} diff --git a/libc/calls/calls.h b/libc/calls/calls.h index f2b8985ca..b5fd6d824 100644 --- a/libc/calls/calls.h +++ b/libc/calls/calls.h @@ -133,8 +133,8 @@ int nice(int) libcesque; int open(const char *, int, ...) libcesque; int openat(int, const char *, int, ...) libcesque; int pause(void) libcesque; -int pipe(int[hasatleast 2]) libcesque; -int pipe2(int[hasatleast 2], int) libcesque; +int pipe(int[2]) libcesque; +int pipe2(int[2], int) libcesque; int posix_fadvise(int, int64_t, int64_t, int) libcesque; int posix_madvise(void *, uint64_t, int) libcesque; int raise(int) libcesque; diff --git a/libc/calls/pipe.c b/libc/calls/pipe.c index 1071cfaf8..9f897996a 100644 --- a/libc/calls/pipe.c +++ b/libc/calls/pipe.c @@ -33,7 +33,7 @@ * @asyncsignalsafe * @see pipe2() */ -int pipe(int pipefd[hasatleast 2]) { +int pipe(int pipefd[2]) { int rc; if (!pipefd) { // needed for windows which is polyfilled diff --git a/libc/calls/pipe2.c b/libc/calls/pipe2.c index caab1cb42..7286fd8db 100644 --- a/libc/calls/pipe2.c +++ b/libc/calls/pipe2.c @@ -39,7 +39,7 @@ * @param flags can have O_CLOEXEC or O_DIRECT or O_NONBLOCK * @return 0 on success, or -1 w/ errno and pipefd isn't modified */ -int pipe2(int pipefd[hasatleast 2], int flags) { +int pipe2(int pipefd[2], int flags) { int rc; if (flags & ~(O_CLOEXEC | O_NONBLOCK | (O_DIRECT != -1u ? O_DIRECT : 0))) { return einval(); diff --git a/libc/intrin/maps.h b/libc/intrin/maps.h index 35bb44e97..a438d1221 100644 --- a/libc/intrin/maps.h +++ b/libc/intrin/maps.h @@ -20,14 +20,14 @@ struct Map { intptr_t hand; /* windows nt only */ union { struct Tree tree; - struct Map *free; + struct Map *freed; }; }; struct Maps { atomic_int lock; struct Tree *maps; - _Atomic(struct Map *) free; + _Atomic(struct Map *) freed; size_t count; size_t pages; _Atomic(char *) pick; diff --git a/libc/intrin/mmap.c b/libc/intrin/mmap.c index 47e102a4c..cc342b73f 100644 --- a/libc/intrin/mmap.c +++ b/libc/intrin/mmap.c @@ -131,7 +131,7 @@ static int __muntrack(char *addr, size_t size, int pagesz, if (addr <= map_addr && addr + PGUP(size) >= map_addr + PGUP(map_size)) { // remove mapping completely tree_remove(&__maps.maps, &map->tree); - map->free = *deleted; + map->freed = *deleted; *deleted = map; __maps.pages -= (map_size + pagesz - 1) / pagesz; __maps.count -= 1; @@ -155,7 +155,7 @@ static int __muntrack(char *addr, size_t size, int pagesz, __maps.pages -= (left + pagesz - 1) / pagesz; leftmap->addr = map_addr; leftmap->size = left; - leftmap->free = *deleted; + leftmap->freed = *deleted; *deleted = leftmap; __maps_check(); } else { @@ -171,7 +171,7 @@ static int __muntrack(char *addr, size_t size, int pagesz, __maps.pages -= (right + pagesz - 1) / pagesz; rightmap->addr = addr; rightmap->size = right; - rightmap->free = *deleted; + rightmap->freed = *deleted; *deleted = rightmap; __maps_check(); } else { @@ -200,7 +200,7 @@ static int __muntrack(char *addr, size_t size, int pagesz, __maps.count += 1; middlemap->addr = addr; middlemap->size = size; - middlemap->free = *deleted; + middlemap->freed = *deleted; *deleted = middlemap; __maps_check(); } else { @@ -217,9 +217,9 @@ static int __muntrack(char *addr, size_t size, int pagesz, void __maps_free(struct Map *map) { map->size = 0; map->addr = MAP_FAILED; - map->free = atomic_load_explicit(&__maps.free, memory_order_relaxed); + map->freed = atomic_load_explicit(&__maps.freed, memory_order_relaxed); for (;;) { - if (atomic_compare_exchange_weak_explicit(&__maps.free, &map->free, map, + if (atomic_compare_exchange_weak_explicit(&__maps.freed, &map->freed, map, memory_order_release, memory_order_relaxed)) break; @@ -229,7 +229,7 @@ void __maps_free(struct Map *map) { static void __maps_free_all(struct Map *list) { struct Map *next; for (struct Map *map = list; map; map = next) { - next = map->free; + next = map->freed; __maps_free(map); } } @@ -285,9 +285,9 @@ static void __maps_insert(struct Map *map) { struct Map *__maps_alloc(void) { struct Map *map; - map = atomic_load_explicit(&__maps.free, memory_order_relaxed); + map = atomic_load_explicit(&__maps.freed, memory_order_relaxed); while (map) { - if (atomic_compare_exchange_weak_explicit(&__maps.free, &map, map->free, + if (atomic_compare_exchange_weak_explicit(&__maps.freed, &map, map->freed, memory_order_acquire, memory_order_relaxed)) return map; @@ -346,7 +346,7 @@ static int __munmap(char *addr, size_t size) { // delete mappings int rc = 0; - for (struct Map *map = deleted; map; map = map->free) { + for (struct Map *map = deleted; map; map = map->freed) { if (!IsWindows()) { if (sys_munmap(map->addr, map->size)) rc = -1; @@ -359,7 +359,7 @@ static int __munmap(char *addr, size_t size) { } } - // free mappings + // freed mappings __maps_free_all(deleted); return rc; @@ -451,7 +451,7 @@ TryAgain: } // polyfill map fixed noreplace - // we assume non-linux gives us addr if it's free + // we assume non-linux gives us addr if it's freed // that's what linux (e.g. rhel7) did before noreplace if (noreplace && res.addr != addr) { if (!IsWindows()) { diff --git a/libc/isystem/__threading_support b/libc/isystem/__threading_support deleted file mode 100644 index 118b4ff82..000000000 --- a/libc/isystem/__threading_support +++ /dev/null @@ -1 +0,0 @@ -#include "third_party/libcxx/__threading_support" diff --git a/libc/isystem/amxcomplexintrin.h b/libc/isystem/amxcomplexintrin.h new file mode 100644 index 000000000..b6b9ea7d3 --- /dev/null +++ b/libc/isystem/amxcomplexintrin.h @@ -0,0 +1 @@ +#include "third_party/intel/amxcomplexintrin.internal.h" diff --git a/libc/isystem/amxfp16intrin.h b/libc/isystem/amxfp16intrin.h new file mode 100644 index 000000000..6b4043496 --- /dev/null +++ b/libc/isystem/amxfp16intrin.h @@ -0,0 +1 @@ +#include "third_party/intel/amxfp16intrin.internal.h" diff --git a/libc/isystem/avxifmaintrin.h b/libc/isystem/avxifmaintrin.h new file mode 100644 index 000000000..a93835f7e --- /dev/null +++ b/libc/isystem/avxifmaintrin.h @@ -0,0 +1 @@ +#include "third_party/intel/avxifmaintrin.internal.h" diff --git a/libc/isystem/avxneconvertintrin.h b/libc/isystem/avxneconvertintrin.h new file mode 100644 index 000000000..691504600 --- /dev/null +++ b/libc/isystem/avxneconvertintrin.h @@ -0,0 +1 @@ +#include "third_party/intel/avxneconvertintrin.internal.h" diff --git a/libc/isystem/avxvnniint16intrin.h b/libc/isystem/avxvnniint16intrin.h new file mode 100644 index 000000000..fc8c6d0ab --- /dev/null +++ b/libc/isystem/avxvnniint16intrin.h @@ -0,0 +1 @@ +#include "third_party/intel/avxvnniint16intrin.internal.h" diff --git a/libc/isystem/avxvnniint8intrin.h b/libc/isystem/avxvnniint8intrin.h new file mode 100644 index 000000000..ccb746b56 --- /dev/null +++ b/libc/isystem/avxvnniint8intrin.h @@ -0,0 +1 @@ +#include "third_party/intel/avxvnniint8intrin.internal.h" diff --git a/libc/isystem/bmmintrin.h b/libc/isystem/bmmintrin.h new file mode 100644 index 000000000..6649e02b0 --- /dev/null +++ b/libc/isystem/bmmintrin.h @@ -0,0 +1 @@ +#include "third_party/intel/bmmintrin.internal.h" diff --git a/libc/isystem/cmpccxaddintrin.h b/libc/isystem/cmpccxaddintrin.h new file mode 100644 index 000000000..48fd2c5db --- /dev/null +++ b/libc/isystem/cmpccxaddintrin.h @@ -0,0 +1 @@ +#include "third_party/intel/cmpccxaddintrin.internal.h" diff --git a/libc/isystem/prfchiintrin.h b/libc/isystem/prfchiintrin.h new file mode 100644 index 000000000..f76698468 --- /dev/null +++ b/libc/isystem/prfchiintrin.h @@ -0,0 +1 @@ +#include "third_party/intel/prfchiintrin.internal.h" diff --git a/libc/isystem/raointintrin.h b/libc/isystem/raointintrin.h new file mode 100644 index 000000000..4f41b106a --- /dev/null +++ b/libc/isystem/raointintrin.h @@ -0,0 +1 @@ +#include "third_party/intel/raointintrin.internal.h" diff --git a/libc/isystem/sha512intrin.h b/libc/isystem/sha512intrin.h new file mode 100644 index 000000000..f364a7e5f --- /dev/null +++ b/libc/isystem/sha512intrin.h @@ -0,0 +1 @@ +#include "third_party/intel/sha512intrin.internal.h" diff --git a/libc/isystem/sm3intrin.h b/libc/isystem/sm3intrin.h new file mode 100644 index 000000000..2f35eeba6 --- /dev/null +++ b/libc/isystem/sm3intrin.h @@ -0,0 +1 @@ +#include "third_party/intel/sm3intrin.internal.h" diff --git a/libc/isystem/sm4intrin.h b/libc/isystem/sm4intrin.h new file mode 100644 index 000000000..91edac356 --- /dev/null +++ b/libc/isystem/sm4intrin.h @@ -0,0 +1 @@ +#include "third_party/intel/sm4intrin.internal.h" diff --git a/libc/isystem/usermsrintrin.h b/libc/isystem/usermsrintrin.h new file mode 100644 index 000000000..85a8d8130 --- /dev/null +++ b/libc/isystem/usermsrintrin.h @@ -0,0 +1 @@ +#include "third_party/intel/usermsrintrin.internal.h" diff --git a/libc/math.h b/libc/math.h index 0b63b361a..6b8539a5e 100644 --- a/libc/math.h +++ b/libc/math.h @@ -159,10 +159,7 @@ typedef double double_t; #define fpclassify(x) \ __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, x) -#define signbit(x) \ - (sizeof(x) == sizeof(long double) ? __builtin_signbitl(x) \ - : sizeof(x) == sizeof(float) ? __builtin_signbitf(x) \ - : __builtin_signbit(x)) +#define signbit(x) __builtin_signbit(x) extern int signgam; diff --git a/libc/proc/fork-nt.c b/libc/proc/fork-nt.c index a4a938e1d..cfc5f13e6 100644 --- a/libc/proc/fork-nt.c +++ b/libc/proc/fork-nt.c @@ -271,8 +271,8 @@ textwindows void WinMainForked(void) { __threaded = false; // fixup memory manager - __maps.free = 0; __maps.maps = 0; + __maps.freed = 0; __maps.count = 0; __maps.pages = 0; for (struct Tree *e = tree_first(maps); e; e = tree_next(e)) { diff --git a/libc/stdio/fmt.c b/libc/stdio/fmt.c index 69d6da94f..7ba1ac506 100644 --- a/libc/stdio/fmt.c +++ b/libc/stdio/fmt.c @@ -449,7 +449,10 @@ static int __fmt_stoa(int out(const char *, void *, size_t), void *arg, } else if (signbit == 15) { precision = strnlen16((const char16_t *)p, precision); } else { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstringop-overread" precision = strnlen(p, precision); +#pragma GCC diagnostic pop } } diff --git a/libc/tinymath/lgamma_r.c b/libc/tinymath/lgamma_r.c index 4632b144c..0257db75a 100644 --- a/libc/tinymath/lgamma_r.c +++ b/libc/tinymath/lgamma_r.c @@ -204,7 +204,7 @@ static double sin_pi(double x) double lgamma_r(double x, int *signgamp) { union {double f; uint64_t i;} u = {x}; - double_t t,y,z,nadj,p,p1,p2,p3,q,r,w; + double_t t,y,z,nadj=0,p,p1,p2,p3,q,r,w; uint32_t ix; int sign,i; diff --git a/libc/tinymath/lgammaf_r.c b/libc/tinymath/lgammaf_r.c index ee6b7a286..d70f7d736 100644 --- a/libc/tinymath/lgammaf_r.c +++ b/libc/tinymath/lgammaf_r.c @@ -139,7 +139,7 @@ static float sin_pi(float x) float lgammaf_r(float x, int *signgamp) { union {float f; uint32_t i;} u = {x}; - float t,y,z,nadj,p,p1,p2,p3,q,r,w; + float t,y,z,nadj=0,p,p1,p2,p3,q,r,w; uint32_t ix; int i,sign; diff --git a/libc/tinymath/lgammal.c b/libc/tinymath/lgammal.c index ec3309acb..452335ba7 100644 --- a/libc/tinymath/lgammal.c +++ b/libc/tinymath/lgammal.c @@ -247,7 +247,7 @@ static long double sin_pi(long double x) } long double lgammal_r(long double x, int *sg) { - long double t, y, z, nadj, p, p1, p2, q, r, w; + long double t, y, z, nadj=0, p, p1, p2, q, r, w; union ldshape u = {x}; uint32_t ix = (u.i.se & 0x7fffU)<<16 | u.i.m>>48; int sign = u.i.se >> 15; diff --git a/test/libc/calls/stackoverflow1_test.c b/test/libc/calls/stackoverflow1_test.c index 88b6fff9d..5ad8db39e 100644 --- a/test/libc/calls/stackoverflow1_test.c +++ b/test/libc/calls/stackoverflow1_test.c @@ -80,23 +80,19 @@ void SetUp(void) { sigaction(SIGSEGV, &sa, 0); } -int StackOverflow(int f(), int n) { - if (n < INT_MAX) { - return f(f, n + 1) - 1; - } else { - return INT_MAX; - } +int StackOverflow(void); +int (*pStackOverflow)(void) = StackOverflow; +int StackOverflow(void) { + return pStackOverflow(); } -int (*pStackOverflow)(int (*)(), int) = StackOverflow; - TEST(stackoverflow, standardStack_altStack_process_longjmp) { if (IsTiny()) return; // TODO(jart): why? int jumpcode; if (!(jumpcode = setjmp(recover))) { - exit(pStackOverflow(pStackOverflow, 0)); + exit(pStackOverflow()); } ASSERT_EQ(123, jumpcode); ASSERT_TRUE(smashed_stack); diff --git a/test/libc/calls/stackoverflow2_test.c b/test/libc/calls/stackoverflow2_test.c index 6888c0ad1..7c3f926ba 100644 --- a/test/libc/calls/stackoverflow2_test.c +++ b/test/libc/calls/stackoverflow2_test.c @@ -51,16 +51,12 @@ void CrashHandler(int sig, siginfo_t *si, void *ctx) { longjmp(recover, 123); } -int StackOverflow(int f(), int n) { - if (n < INT_MAX) { - return f(f, n + 1) - 1; - } else { - return INT_MAX; - } +int StackOverflow(void); +int (*pStackOverflow)(void) = StackOverflow; +int StackOverflow(void) { + return pStackOverflow(); } -int (*pStackOverflow)(int (*)(), int) = StackOverflow; - void *MyPosixThread(void *arg) { int jumpcode; struct sigaction sa, o1, o2; @@ -75,7 +71,7 @@ void *MyPosixThread(void *arg) { sigaction(SIGBUS, &sa, &o1); sigaction(SIGSEGV, &sa, &o2); if (!(jumpcode = setjmp(recover))) { - exit(pStackOverflow(pStackOverflow, 0)); + exit(pStackOverflow()); } ASSERT_EQ(123, jumpcode); sigaction(SIGSEGV, &o2, 0); diff --git a/test/libc/calls/stackoverflow3_test.c b/test/libc/calls/stackoverflow3_test.c index d7cfe2870..4eee5ff05 100644 --- a/test/libc/calls/stackoverflow3_test.c +++ b/test/libc/calls/stackoverflow3_test.c @@ -85,16 +85,12 @@ void CrashHandler(int sig, siginfo_t *si, void *arg) { #endif } -int StackOverflow(int f(), int n) { - if (n < INT_MAX) { - return f(f, n + 1) - 1; - } else { - return INT_MAX; - } +int StackOverflow(void); +int (*pStackOverflow)(void) = StackOverflow; +int StackOverflow(void) { + return pStackOverflow(); } -int (*pStackOverflow)(int (*)(), int) = StackOverflow; - void *MyPosixThread(void *arg) { struct sigaction sa; struct sigaltstack ss; @@ -107,7 +103,7 @@ void *MyPosixThread(void *arg) { sa.sa_sigaction = CrashHandler; sigaction(SIGBUS, &sa, 0); sigaction(SIGSEGV, &sa, 0); - exit(pStackOverflow(pStackOverflow, 0)); + exit(pStackOverflow()); return 0; } diff --git a/test/libc/calls/stackoverflow4_test.c b/test/libc/calls/stackoverflow4_test.c index 8547d4b24..d5b907f82 100644 --- a/test/libc/calls/stackoverflow4_test.c +++ b/test/libc/calls/stackoverflow4_test.c @@ -45,16 +45,12 @@ void CrashHandler(int sig) { pthread_exit((void *)123L); } -int StackOverflow(int f(), int n) { - if (n < INT_MAX) { - return f(f, n + 1) - 1; - } else { - return INT_MAX; - } +int StackOverflow(void); +int (*pStackOverflow)(void) = StackOverflow; +int StackOverflow(void) { + return pStackOverflow(); } -int (*pStackOverflow)(int (*)(), int) = StackOverflow; - void *MyPosixThread(void *arg) { struct sigaction sa; struct sigaltstack ss; @@ -67,7 +63,7 @@ void *MyPosixThread(void *arg) { sa.sa_handler = CrashHandler; sigaction(SIGBUS, &sa, 0); sigaction(SIGSEGV, &sa, 0); - exit(pStackOverflow(pStackOverflow, 0)); + exit(pStackOverflow()); return 0; } diff --git a/test/libc/calls/stackoverflow5_test.c b/test/libc/calls/stackoverflow5_test.c index 611604448..5db0a7369 100644 --- a/test/libc/calls/stackoverflow5_test.c +++ b/test/libc/calls/stackoverflow5_test.c @@ -34,18 +34,14 @@ void CrashHandler(int sig) { pthread_exit(0); } -int StackOverflow(int f(), int n) { - if (n < INT_MAX) { - return f(f, n + 1) - 1; - } else { - return INT_MAX; - } +int StackOverflow(void); +int (*pStackOverflow)(void) = StackOverflow; +int StackOverflow(void) { + return pStackOverflow(); } -int (*pStackOverflow)(int (*)(), int) = StackOverflow; - void *MyPosixThread(void *arg) { - exit(pStackOverflow(pStackOverflow, 0)); + exit(pStackOverflow()); return 0; } diff --git a/test/libc/intrin/fmax_test.c b/test/libc/intrin/fmax_test.c index b662a4f7e..9d37d725f 100644 --- a/test/libc/intrin/fmax_test.c +++ b/test/libc/intrin/fmax_test.c @@ -16,8 +16,8 @@ β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ +#include "libc/math.h" #include "libc/testlib/testlib.h" -#include "third_party/libcxx/math.h" TEST(fmax, test) { EXPECT_TRUE(fmax(2., 3.) == 3.); diff --git a/test/libc/log/backtrace.c b/test/libc/log/backtrace.c index 0d553b1ed..22ce298db 100644 --- a/test/libc/log/backtrace.c +++ b/test/libc/log/backtrace.c @@ -17,6 +17,7 @@ β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ #include "libc/fmt/conv.h" +#include "libc/intrin/weaken.h" #include "libc/limits.h" #include "libc/log/log.h" #include "libc/mem/leaks.h" @@ -27,12 +28,8 @@ #include "libc/str/str.h" #ifdef __x86_64__ -int StackOverflow(int f(), int n) { - if (n < INT_MAX) { - return f(f, n + 1) - 1; - } else { - return INT_MAX; - } +int StackOverflow(void) { + return _weaken(StackOverflow)(); } void FpuCrash(void) { @@ -95,7 +92,7 @@ int (*pRodataOverrunCrash)(int) = RodataOverrunCrash; char *(*pStackOverrunCrash)(int) = StackOverrunCrash; char *(*pMemoryLeakCrash)(void) = MemoryLeakCrash; int (*pNpeCrash)(char *) = NpeCrash; -int (*pStackOverflow)(int (*)(), int) = StackOverflow; +int (*pStackOverflow)(void) = StackOverflow; int main(int argc, char *argv[]) { ShowCrashReports(); @@ -123,7 +120,7 @@ int main(int argc, char *argv[]) { case 8: exit(pNpeCrash(0)); case 9: - exit(pStackOverflow(pStackOverflow, 0)); + exit(pStackOverflow()); default: fputs("error: unrecognized argument\n", stderr); exit(1); diff --git a/test/libc/thread/makecontext_test.c b/test/libc/thread/makecontext_test.c index 629dc07b8..e7d2a69d1 100644 --- a/test/libc/thread/makecontext_test.c +++ b/test/libc/thread/makecontext_test.c @@ -21,6 +21,7 @@ #include "libc/dce.h" #include "libc/intrin/kprintf.h" #include "libc/limits.h" +#include "libc/math.h" #include "libc/mem/gc.h" #include "libc/nt/createfile.h" #include "libc/nt/enum/accessmask.h" @@ -36,7 +37,6 @@ #include "libc/testlib/testlib.h" #include "libc/thread/thread.h" #include "libc/x/x.h" -#include "third_party/libcxx/math.h" bool gotsome; ucontext_t uc, goback; diff --git a/test/libc/thread/pthread_setaffinity_np_test.c b/test/libc/thread/pthread_setaffinity_np_test.c deleted file mode 100644 index b2448f6ed..000000000 --- a/test/libc/thread/pthread_setaffinity_np_test.c +++ /dev/null @@ -1,59 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-β”‚ -β”‚ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi β”‚ -β•žβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•‘ -β”‚ Copyright 2024 Justine Alexandra Roberts Tunney β”‚ -β”‚ β”‚ -β”‚ Permission to use, copy, modify, and/or distribute this software for β”‚ -β”‚ any purpose with or without fee is hereby granted, provided that the β”‚ -β”‚ above copyright notice and this permission notice appear in all copies. β”‚ -β”‚ β”‚ -β”‚ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL β”‚ -β”‚ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED β”‚ -β”‚ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE β”‚ -β”‚ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL β”‚ -β”‚ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR β”‚ -β”‚ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER β”‚ -β”‚ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR β”‚ -β”‚ PERFORMANCE OF THIS SOFTWARE. β”‚ -β•šβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€*/ -#include "libc/calls/struct/cpuset.h" -#include "libc/dce.h" -#include "libc/runtime/runtime.h" -#include "libc/testlib/testlib.h" -#include "libc/thread/thread.h" -#include "libc/thread/thread2.h" - -TEST(pthread_setaffinity_np, test) { - - // works on almost nothing - if (IsXnu()) - return; - if (IsNetbsd()) - return; - if (IsOpenbsd()) - return; - if (__get_cpu_count() < 2) - return; - - // save bitset - cpu_set_t old; - if (!IsWindows()) - ASSERT_EQ(0, pthread_getaffinity_np(pthread_self(), sizeof(old), &old)); - - // go to first cpu - cpu_set_t bitset; - CPU_ZERO(&bitset); - CPU_SET(0, &bitset); - ASSERT_EQ(0, pthread_setaffinity_np(pthread_self(), sizeof(bitset), &bitset)); - ASSERT_EQ(0, sched_getcpu()); - - // go to second cpu - CPU_ZERO(&bitset); - CPU_SET(1, &bitset); - ASSERT_EQ(0, pthread_setaffinity_np(pthread_self(), sizeof(bitset), &bitset)); - ASSERT_EQ(1, sched_getcpu()); - - // restore bitset - if (!IsWindows()) - ASSERT_EQ(0, pthread_setaffinity_np(pthread_self(), sizeof(old), &old)); -} diff --git a/test/net/http/hascontrolcodes_test.c b/test/net/http/hascontrolcodes_test.c index 0bead7c42..291fda443 100644 --- a/test/net/http/hascontrolcodes_test.c +++ b/test/net/http/hascontrolcodes_test.c @@ -31,7 +31,7 @@ TEST(HasControlCodes, test) { } TEST(HasControlCodes, testDoesUtf8) { - EXPECT_EQ(-1, HasControlCodes(u8"β†’", -1, kControlC0 | kControlC1)); + EXPECT_EQ(-1, HasControlCodes("β†’", -1, kControlC0 | kControlC1)); EXPECT_EQ(-1, HasControlCodes("\304\200", -1, kControlC0 | kControlC1)); EXPECT_NE(-1, HasControlCodes("\300\200", -1, kControlC0 | kControlC1)); EXPECT_EQ(-1, HasControlCodes("\300\200", -1, kControlC1)); diff --git a/third_party/BUILD.mk b/third_party/BUILD.mk index f785620d3..5117534ca 100644 --- a/third_party/BUILD.mk +++ b/third_party/BUILD.mk @@ -5,7 +5,6 @@ o/$(MODE)/third_party: \ o/$(MODE)/third_party/argon2 \ o/$(MODE)/third_party/awk \ - o/$(MODE)/third_party/bash \ o/$(MODE)/third_party/bzip2 \ o/$(MODE)/third_party/chibicc \ o/$(MODE)/third_party/compiler_rt \ diff --git a/third_party/aarch64/acc_prof.internal.h b/third_party/aarch64/acc_prof.internal.h deleted file mode 100644 index fbe73440a..000000000 --- a/third_party/aarch64/acc_prof.internal.h +++ /dev/null @@ -1,164 +0,0 @@ -#if defined(__aarch64__) && !(__ASSEMBLER__ + __LINKER__ + 0) -#ifndef _ACC_PROF_H -#define _ACC_PROF_H 1 -#include "third_party/aarch64/openacc.internal.h" -#ifdef __cplusplus -extern "C" { -#endif -typedef enum acc_event_t -{ - acc_ev_none = 0, - acc_ev_device_init_start, - acc_ev_device_init_end, - acc_ev_device_shutdown_start, - acc_ev_device_shutdown_end, - acc_ev_runtime_shutdown, - acc_ev_create, - acc_ev_delete, - acc_ev_alloc, - acc_ev_free, - acc_ev_enter_data_start, - acc_ev_enter_data_end, - acc_ev_exit_data_start, - acc_ev_exit_data_end, - acc_ev_update_start, - acc_ev_update_end, - acc_ev_compute_construct_start, - acc_ev_compute_construct_end, - acc_ev_enqueue_launch_start, - acc_ev_enqueue_launch_end, - acc_ev_enqueue_upload_start, - acc_ev_enqueue_upload_end, - acc_ev_enqueue_download_start, - acc_ev_enqueue_download_end, - acc_ev_wait_start, - acc_ev_wait_end, - acc_ev_last -} acc_event_t; -typedef signed long int _acc_prof_ssize_t; -typedef unsigned long int _acc_prof_size_t; -typedef int _acc_prof_int_t; -#define _ACC_PROF_VALID_BYTES_STRUCT(_struct, _lastfield, _valid_bytes_lastfield) offsetof (_struct, _lastfield) + (_valid_bytes_lastfield) -#if 0 -#define _ACC_PROF_VALID_BYTES_TYPE_N(_type, _n, _valid_bytes_type) ((_n - 1) * sizeof (_type) + (_valid_bytes_type)) -#endif -#define _ACC_PROF_VALID_BYTES_BASICTYPE(_basictype) (sizeof (_basictype)) -typedef struct acc_prof_info -{ - acc_event_t event_type; - _acc_prof_int_t valid_bytes; - _acc_prof_int_t version; - acc_device_t device_type; - _acc_prof_int_t device_number; - _acc_prof_int_t thread_id; - _acc_prof_ssize_t async; - _acc_prof_ssize_t async_queue; - const char *src_file; - const char *func_name; - _acc_prof_int_t line_no, end_line_no; - _acc_prof_int_t func_line_no, func_end_line_no; -#define _ACC_PROF_INFO_VALID_BYTES _ACC_PROF_VALID_BYTES_STRUCT (acc_prof_info, func_end_line_no, _ACC_PROF_VALID_BYTES_BASICTYPE (_acc_prof_int_t)) -} acc_prof_info; -#define _ACC_PROF_INFO_VERSION 201711 -typedef enum acc_construct_t -{ - acc_construct_parallel = 0, - acc_construct_kernels, - acc_construct_loop, - acc_construct_data, - acc_construct_enter_data, - acc_construct_exit_data, - acc_construct_host_data, - acc_construct_atomic, - acc_construct_declare, - acc_construct_init, - acc_construct_shutdown, - acc_construct_set, - acc_construct_update, - acc_construct_routine, - acc_construct_wait, - acc_construct_runtime_api, - acc_construct_serial -} acc_construct_t; -typedef struct acc_data_event_info -{ - acc_event_t event_type; - _acc_prof_int_t valid_bytes; - acc_construct_t parent_construct; - _acc_prof_int_t implicit; - void *tool_info; - const char *var_name; - _acc_prof_size_t bytes; - const void *host_ptr; - const void *device_ptr; -#define _ACC_DATA_EVENT_INFO_VALID_BYTES _ACC_PROF_VALID_BYTES_STRUCT (acc_data_event_info, device_ptr, _ACC_PROF_VALID_BYTES_BASICTYPE (void *)) -} acc_data_event_info; -typedef struct acc_launch_event_info -{ - acc_event_t event_type; - _acc_prof_int_t valid_bytes; - acc_construct_t parent_construct; - _acc_prof_int_t implicit; - void *tool_info; - const char *kernel_name; - _acc_prof_size_t num_gangs, num_workers, vector_length; -#define _ACC_LAUNCH_EVENT_INFO_VALID_BYTES _ACC_PROF_VALID_BYTES_STRUCT (acc_launch_event_info, vector_length, _ACC_PROF_VALID_BYTES_BASICTYPE (_acc_prof_size_t)) -} acc_launch_event_info; -typedef struct acc_other_event_info -{ - acc_event_t event_type; - _acc_prof_int_t valid_bytes; - acc_construct_t parent_construct; - _acc_prof_int_t implicit; - void *tool_info; -#define _ACC_OTHER_EVENT_INFO_VALID_BYTES _ACC_PROF_VALID_BYTES_STRUCT (acc_other_event_info, tool_info, _ACC_PROF_VALID_BYTES_BASICTYPE (void *)) -} acc_other_event_info; -typedef union acc_event_info -{ - acc_event_t event_type; - acc_data_event_info data_event; - acc_launch_event_info launch_event; - acc_other_event_info other_event; -} acc_event_info; -typedef enum acc_device_api -{ - acc_device_api_none = 0, - acc_device_api_cuda, - acc_device_api_opencl, - acc_device_api_coi, - acc_device_api_other -} acc_device_api; -typedef struct acc_api_info -{ - acc_device_api device_api; - _acc_prof_int_t valid_bytes; - acc_device_t device_type; - _acc_prof_int_t vendor; - const void *device_handle; - const void *context_handle; - const void *async_handle; -#define _ACC_API_INFO_VALID_BYTES _ACC_PROF_VALID_BYTES_STRUCT (acc_api_info, async_handle, _ACC_PROF_VALID_BYTES_BASICTYPE (void *)) -} acc_api_info; -typedef void (*acc_prof_callback) (acc_prof_info *, acc_event_info *, - acc_api_info *); -typedef enum acc_register_t -{ - acc_reg = 0, - acc_toggle = 1, - acc_toggle_per_thread = 2 -} acc_register_t; -typedef void (*acc_prof_reg) (acc_event_t, acc_prof_callback, acc_register_t); -extern void acc_prof_register (acc_event_t, acc_prof_callback, - acc_register_t) __GOACC_NOTHROW; -extern void acc_prof_unregister (acc_event_t, acc_prof_callback, - acc_register_t) __GOACC_NOTHROW; -typedef void (*acc_query_fn) (); -typedef acc_query_fn (*acc_prof_lookup_func) (const char *); -extern acc_query_fn acc_prof_lookup (const char *) __GOACC_NOTHROW; -extern void acc_register_library (acc_prof_reg, acc_prof_reg, - acc_prof_lookup_func); -#ifdef __cplusplus -} -#endif -#endif -#endif diff --git a/third_party/aarch64/arm_acle.internal.h b/third_party/aarch64/arm_acle.internal.h index 687b133d2..dd2a40da4 100644 --- a/third_party/aarch64/arm_acle.internal.h +++ b/third_party/aarch64/arm_acle.internal.h @@ -27,6 +27,32 @@ _GCC_ARM_ACLE_DATA_FN (revsh, bswap16, int16_t, int16_t) _GCC_ARM_ACLE_DATA_FN (rev, bswap32, uint32_t, uint32_t) _GCC_ARM_ACLE_DATA_FN (revll, bswap64, uint64_t, uint64_t) #undef _GCC_ARM_ACLE_DATA_FN +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +__pld (void const volatile *__addr) +{ + return __builtin_aarch64_pld (__addr); +} +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +__pli (void const volatile *__addr) +{ + return __builtin_aarch64_pli (__addr); +} +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +__plix (unsigned int __cache, unsigned int __rettn, + void const volatile *__addr) +{ + return __builtin_aarch64_plix (__cache, __rettn, __addr); +} +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +__pldx (unsigned int __access, unsigned int __cache, unsigned int __rettn, + void const volatile *__addr) +{ + return __builtin_aarch64_pldx (__access, __cache, __rettn, __addr); +} __extension__ extern __inline unsigned long __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) __revl (unsigned long __value) @@ -188,34 +214,7 @@ __ttest (void) #pragma GCC pop_options #endif #ifdef __ARM_FEATURE_LS64 -#pragma GCC push_options -#pragma GCC target ("+nothing+ls64") typedef __arm_data512_t data512_t; -__extension__ extern __inline data512_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_ld64b (const void *__addr) -{ - return __builtin_aarch64_ld64b (__addr); -} -__extension__ extern __inline void -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_st64b (void *__addr, data512_t __value) -{ - __builtin_aarch64_st64b (__addr, __value); -} -__extension__ extern __inline uint64_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_st64bv (void *__addr, data512_t __value) -{ - return __builtin_aarch64_st64bv (__addr, __value); -} -__extension__ extern __inline uint64_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -__arm_st64bv0 (void *__addr, data512_t __value) -{ - return __builtin_aarch64_st64bv0 (__addr, __value); -} -#pragma GCC pop_options #endif #pragma GCC push_options #pragma GCC target ("+nothing+rng") @@ -233,7 +232,7 @@ __rndrrs (uint64_t *__res) } #pragma GCC pop_options #pragma GCC push_options -#pragma GCC target ("arch=armv8.5-a+memtag") +#pragma GCC target ("+nothing+memtag") #define __arm_mte_create_random_tag(__ptr, __u64_mask) __builtin_aarch64_memtag_irg(__ptr, __u64_mask) #define __arm_mte_exclude_tag(__ptr, __u64_excluded) __builtin_aarch64_memtag_gmi(__ptr, __u64_excluded) #define __arm_mte_ptrdiff(__ptr_a, __ptr_b) __builtin_aarch64_memtag_subp(__ptr_a, __ptr_b) @@ -241,6 +240,21 @@ __rndrrs (uint64_t *__res) #define __arm_mte_set_tag(__tagged_address) __builtin_aarch64_memtag_set_tag(__tagged_address) #define __arm_mte_get_tag(__address) __builtin_aarch64_memtag_get_tag(__address) #pragma GCC pop_options +#define __arm_rsr(__regname) __builtin_aarch64_rsr (__regname) +#define __arm_rsrp(__regname) __builtin_aarch64_rsrp (__regname) +#define __arm_rsr64(__regname) __builtin_aarch64_rsr64 (__regname) +#define __arm_rsrf(__regname) __builtin_aarch64_rsrf (__regname) +#define __arm_rsrf64(__regname) __builtin_aarch64_rsrf64 (__regname) +#define __arm_wsr(__regname, __value) __builtin_aarch64_wsr (__regname, __value) +#define __arm_wsrp(__regname, __value) __builtin_aarch64_wsrp (__regname, __value) +#define __arm_wsr64(__regname, __value) __builtin_aarch64_wsr64 (__regname, __value) +#define __arm_wsrf(__regname, __value) __builtin_aarch64_wsrf (__regname, __value) +#define __arm_wsrf64(__regname, __value) __builtin_aarch64_wsrf64 (__regname, __value) +#pragma GCC push_options +#pragma GCC target ("+nothing+d128") +#define __arm_rsr128(__regname) __builtin_aarch64_rsr128 (__regname) +#define __arm_wsr128(__regname, __value) __builtin_aarch64_wsr128 (__regname, __value) +#pragma GCC pop_options #ifdef __cplusplus } #endif diff --git a/third_party/aarch64/arm_fp16.internal.h b/third_party/aarch64/arm_fp16.internal.h index 84185a620..090fe6fab 100644 --- a/third_party/aarch64/arm_fp16.internal.h +++ b/third_party/aarch64/arm_fp16.internal.h @@ -2,7 +2,7 @@ #ifndef _AARCH64_FP16_H_ #define _AARCH64_FP16_H_ #pragma GCC push_options -#pragma GCC target ("arch=armv8.2-a+fp16") +#pragma GCC target ("+nothing+fp16") typedef __fp16 float16_t; __extension__ extern __inline float16_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) @@ -260,7 +260,7 @@ __extension__ extern __inline float16_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vnegh_f16 (float16_t __a) { - return __builtin_aarch64_neghf (__a); + return -__a; } __extension__ extern __inline float16_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) diff --git a/third_party/aarch64/arm_neon.internal.h b/third_party/aarch64/arm_neon.internal.h index 1cbe2db72..ed99f55bf 100644 --- a/third_party/aarch64/arm_neon.internal.h +++ b/third_party/aarch64/arm_neon.internal.h @@ -2330,2358 +2330,6 @@ vgetq_lane_u64 (uint64x2_t __a, const int __b) { return __aarch64_vget_lane_any (__a, __b); } -__extension__ extern __inline poly8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p8_f16 (float16x4_t __a) -{ - return (poly8x8_t) __a; -} -__extension__ extern __inline poly8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p8_f64 (float64x1_t __a) -{ - return (poly8x8_t) __a; -} -__extension__ extern __inline poly8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p8_s8 (int8x8_t __a) -{ - return (poly8x8_t) __a; -} -__extension__ extern __inline poly8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p8_s16 (int16x4_t __a) -{ - return (poly8x8_t) __a; -} -__extension__ extern __inline poly8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p8_s32 (int32x2_t __a) -{ - return (poly8x8_t) __a; -} -__extension__ extern __inline poly8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p8_s64 (int64x1_t __a) -{ - return (poly8x8_t) __a; -} -__extension__ extern __inline poly8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p8_f32 (float32x2_t __a) -{ - return (poly8x8_t) __a; -} -__extension__ extern __inline poly8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p8_u8 (uint8x8_t __a) -{ - return (poly8x8_t) __a; -} -__extension__ extern __inline poly8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p8_u16 (uint16x4_t __a) -{ - return (poly8x8_t) __a; -} -__extension__ extern __inline poly8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p8_u32 (uint32x2_t __a) -{ - return (poly8x8_t) __a; -} -__extension__ extern __inline poly8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p8_u64 (uint64x1_t __a) -{ - return (poly8x8_t) __a; -} -__extension__ extern __inline poly8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p8_p16 (poly16x4_t __a) -{ - return (poly8x8_t) __a; -} -__extension__ extern __inline poly8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p8_p64 (poly64x1_t __a) -{ - return (poly8x8_t) __a; -} -__extension__ extern __inline poly8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p8_f64 (float64x2_t __a) -{ - return (poly8x16_t) __a; -} -__extension__ extern __inline poly8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p8_s8 (int8x16_t __a) -{ - return (poly8x16_t) __a; -} -__extension__ extern __inline poly8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p8_s16 (int16x8_t __a) -{ - return (poly8x16_t) __a; -} -__extension__ extern __inline poly8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p8_s32 (int32x4_t __a) -{ - return (poly8x16_t) __a; -} -__extension__ extern __inline poly8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p8_s64 (int64x2_t __a) -{ - return (poly8x16_t) __a; -} -__extension__ extern __inline poly8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p8_f16 (float16x8_t __a) -{ - return (poly8x16_t) __a; -} -__extension__ extern __inline poly8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p8_f32 (float32x4_t __a) -{ - return (poly8x16_t) __a; -} -__extension__ extern __inline poly8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p8_u8 (uint8x16_t __a) -{ - return (poly8x16_t) __a; -} -__extension__ extern __inline poly8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p8_u16 (uint16x8_t __a) -{ - return (poly8x16_t) __a; -} -__extension__ extern __inline poly8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p8_u32 (uint32x4_t __a) -{ - return (poly8x16_t) __a; -} -__extension__ extern __inline poly8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p8_u64 (uint64x2_t __a) -{ - return (poly8x16_t) __a; -} -__extension__ extern __inline poly8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p8_p16 (poly16x8_t __a) -{ - return (poly8x16_t) __a; -} -__extension__ extern __inline poly8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p8_p64 (poly64x2_t __a) -{ - return (poly8x16_t) __a; -} -__extension__ extern __inline poly8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p8_p128 (poly128_t __a) -{ - return (poly8x16_t)__a; -} -__extension__ extern __inline poly16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p16_f16 (float16x4_t __a) -{ - return (poly16x4_t) __a; -} -__extension__ extern __inline poly16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p16_f64 (float64x1_t __a) -{ - return (poly16x4_t) __a; -} -__extension__ extern __inline poly16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p16_s8 (int8x8_t __a) -{ - return (poly16x4_t) __a; -} -__extension__ extern __inline poly16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p16_s16 (int16x4_t __a) -{ - return (poly16x4_t) __a; -} -__extension__ extern __inline poly16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p16_s32 (int32x2_t __a) -{ - return (poly16x4_t) __a; -} -__extension__ extern __inline poly16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p16_s64 (int64x1_t __a) -{ - return (poly16x4_t) __a; -} -__extension__ extern __inline poly16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p16_f32 (float32x2_t __a) -{ - return (poly16x4_t) __a; -} -__extension__ extern __inline poly16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p16_u8 (uint8x8_t __a) -{ - return (poly16x4_t) __a; -} -__extension__ extern __inline poly16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p16_u16 (uint16x4_t __a) -{ - return (poly16x4_t) __a; -} -__extension__ extern __inline poly16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p16_u32 (uint32x2_t __a) -{ - return (poly16x4_t) __a; -} -__extension__ extern __inline poly16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p16_u64 (uint64x1_t __a) -{ - return (poly16x4_t) __a; -} -__extension__ extern __inline poly16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p16_p8 (poly8x8_t __a) -{ - return (poly16x4_t) __a; -} -__extension__ extern __inline poly16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p16_p64 (poly64x1_t __a) -{ - return (poly16x4_t) __a; -} -__extension__ extern __inline poly16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p16_f64 (float64x2_t __a) -{ - return (poly16x8_t) __a; -} -__extension__ extern __inline poly16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p16_s8 (int8x16_t __a) -{ - return (poly16x8_t) __a; -} -__extension__ extern __inline poly16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p16_s16 (int16x8_t __a) -{ - return (poly16x8_t) __a; -} -__extension__ extern __inline poly16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p16_s32 (int32x4_t __a) -{ - return (poly16x8_t) __a; -} -__extension__ extern __inline poly16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p16_s64 (int64x2_t __a) -{ - return (poly16x8_t) __a; -} -__extension__ extern __inline poly16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p16_f16 (float16x8_t __a) -{ - return (poly16x8_t) __a; -} -__extension__ extern __inline poly16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p16_f32 (float32x4_t __a) -{ - return (poly16x8_t) __a; -} -__extension__ extern __inline poly16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p16_u8 (uint8x16_t __a) -{ - return (poly16x8_t) __a; -} -__extension__ extern __inline poly16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p16_u16 (uint16x8_t __a) -{ - return (poly16x8_t) __a; -} -__extension__ extern __inline poly16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p16_u32 (uint32x4_t __a) -{ - return (poly16x8_t) __a; -} -__extension__ extern __inline poly16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p16_u64 (uint64x2_t __a) -{ - return (poly16x8_t) __a; -} -__extension__ extern __inline poly16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p16_p8 (poly8x16_t __a) -{ - return (poly16x8_t) __a; -} -__extension__ extern __inline poly16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p16_p64 (poly64x2_t __a) -{ - return (poly16x8_t) __a; -} -__extension__ extern __inline poly16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p16_p128 (poly128_t __a) -{ - return (poly16x8_t)__a; -} -__extension__ extern __inline poly64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p64_f16 (float16x4_t __a) -{ - return (poly64x1_t) __a; -} -__extension__ extern __inline poly64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p64_f64 (float64x1_t __a) -{ - return (poly64x1_t) __a; -} -__extension__ extern __inline poly64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p64_s8 (int8x8_t __a) -{ - return (poly64x1_t) __a; -} -__extension__ extern __inline poly64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p64_s16 (int16x4_t __a) -{ - return (poly64x1_t) __a; -} -__extension__ extern __inline poly64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p64_s32 (int32x2_t __a) -{ - return (poly64x1_t) __a; -} -__extension__ extern __inline poly64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p64_s64 (int64x1_t __a) -{ - return (poly64x1_t) __a; -} -__extension__ extern __inline poly64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p64_f32 (float32x2_t __a) -{ - return (poly64x1_t) __a; -} -__extension__ extern __inline poly64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p64_u8 (uint8x8_t __a) -{ - return (poly64x1_t) __a; -} -__extension__ extern __inline poly64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p64_u16 (uint16x4_t __a) -{ - return (poly64x1_t) __a; -} -__extension__ extern __inline poly64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p64_u32 (uint32x2_t __a) -{ - return (poly64x1_t) __a; -} -__extension__ extern __inline poly64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p64_u64 (uint64x1_t __a) -{ - return (poly64x1_t) __a; -} -__extension__ extern __inline poly64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p64_p8 (poly8x8_t __a) -{ - return (poly64x1_t) __a; -} -__extension__ extern __inline poly64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p64_p16 (poly16x4_t __a) -{ - return (poly64x1_t)__a; -} -__extension__ extern __inline poly64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p64_f64 (float64x2_t __a) -{ - return (poly64x2_t) __a; -} -__extension__ extern __inline poly64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p64_s8 (int8x16_t __a) -{ - return (poly64x2_t) __a; -} -__extension__ extern __inline poly64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p64_s16 (int16x8_t __a) -{ - return (poly64x2_t) __a; -} -__extension__ extern __inline poly64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p64_s32 (int32x4_t __a) -{ - return (poly64x2_t) __a; -} -__extension__ extern __inline poly64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p64_s64 (int64x2_t __a) -{ - return (poly64x2_t) __a; -} -__extension__ extern __inline poly64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p64_f16 (float16x8_t __a) -{ - return (poly64x2_t) __a; -} -__extension__ extern __inline poly64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p64_f32 (float32x4_t __a) -{ - return (poly64x2_t) __a; -} -__extension__ extern __inline poly64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p64_p128 (poly128_t __a) -{ - return (poly64x2_t)__a; -} -__extension__ extern __inline poly64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p64_u8 (uint8x16_t __a) -{ - return (poly64x2_t) __a; -} -__extension__ extern __inline poly64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p64_u16 (uint16x8_t __a) -{ - return (poly64x2_t) __a; -} -__extension__ extern __inline poly64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p64_p16 (poly16x8_t __a) -{ - return (poly64x2_t)__a; -} -__extension__ extern __inline poly64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p64_u32 (uint32x4_t __a) -{ - return (poly64x2_t) __a; -} -__extension__ extern __inline poly64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p64_u64 (uint64x2_t __a) -{ - return (poly64x2_t) __a; -} -__extension__ extern __inline poly64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p64_p8 (poly8x16_t __a) -{ - return (poly64x2_t) __a; -} -__extension__ extern __inline poly128_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p128_p8 (poly8x16_t __a) -{ - return (poly128_t)__a; -} -__extension__ extern __inline poly128_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p128_p16 (poly16x8_t __a) -{ - return (poly128_t)__a; -} -__extension__ extern __inline poly128_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p128_f16 (float16x8_t __a) -{ - return (poly128_t) __a; -} -__extension__ extern __inline poly128_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p128_f32 (float32x4_t __a) -{ - return (poly128_t)__a; -} -__extension__ extern __inline poly128_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p128_p64 (poly64x2_t __a) -{ - return (poly128_t)__a; -} -__extension__ extern __inline poly128_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p128_s64 (int64x2_t __a) -{ - return (poly128_t)__a; -} -__extension__ extern __inline poly128_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p128_u64 (uint64x2_t __a) -{ - return (poly128_t)__a; -} -__extension__ extern __inline poly128_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p128_s8 (int8x16_t __a) -{ - return (poly128_t)__a; -} -__extension__ extern __inline poly128_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p128_s16 (int16x8_t __a) -{ - return (poly128_t)__a; -} -__extension__ extern __inline poly128_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p128_s32 (int32x4_t __a) -{ - return (poly128_t)__a; -} -__extension__ extern __inline poly128_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p128_u8 (uint8x16_t __a) -{ - return (poly128_t)__a; -} -__extension__ extern __inline poly128_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p128_u16 (uint16x8_t __a) -{ - return (poly128_t)__a; -} -__extension__ extern __inline poly128_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p128_u32 (uint32x4_t __a) -{ - return (poly128_t)__a; -} -__extension__ extern __inline float16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f16_f64 (float64x1_t __a) -{ - return (float16x4_t) __a; -} -__extension__ extern __inline float16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f16_s8 (int8x8_t __a) -{ - return (float16x4_t) __a; -} -__extension__ extern __inline float16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f16_s16 (int16x4_t __a) -{ - return (float16x4_t) __a; -} -__extension__ extern __inline float16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f16_s32 (int32x2_t __a) -{ - return (float16x4_t) __a; -} -__extension__ extern __inline float16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f16_s64 (int64x1_t __a) -{ - return (float16x4_t) __a; -} -__extension__ extern __inline float16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f16_f32 (float32x2_t __a) -{ - return (float16x4_t) __a; -} -__extension__ extern __inline float16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f16_u8 (uint8x8_t __a) -{ - return (float16x4_t) __a; -} -__extension__ extern __inline float16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f16_u16 (uint16x4_t __a) -{ - return (float16x4_t) __a; -} -__extension__ extern __inline float16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f16_u32 (uint32x2_t __a) -{ - return (float16x4_t) __a; -} -__extension__ extern __inline float16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f16_u64 (uint64x1_t __a) -{ - return (float16x4_t) __a; -} -__extension__ extern __inline float16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f16_p8 (poly8x8_t __a) -{ - return (float16x4_t) __a; -} -__extension__ extern __inline float16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f16_p16 (poly16x4_t __a) -{ - return (float16x4_t) __a; -} -__extension__ extern __inline float16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f16_p64 (poly64x1_t __a) -{ - return (float16x4_t) __a; -} -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f16_f64 (float64x2_t __a) -{ - return (float16x8_t) __a; -} -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f16_s8 (int8x16_t __a) -{ - return (float16x8_t) __a; -} -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f16_s16 (int16x8_t __a) -{ - return (float16x8_t) __a; -} -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f16_s32 (int32x4_t __a) -{ - return (float16x8_t) __a; -} -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f16_s64 (int64x2_t __a) -{ - return (float16x8_t) __a; -} -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f16_f32 (float32x4_t __a) -{ - return (float16x8_t) __a; -} -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f16_u8 (uint8x16_t __a) -{ - return (float16x8_t) __a; -} -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f16_u16 (uint16x8_t __a) -{ - return (float16x8_t) __a; -} -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f16_u32 (uint32x4_t __a) -{ - return (float16x8_t) __a; -} -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f16_u64 (uint64x2_t __a) -{ - return (float16x8_t) __a; -} -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f16_p8 (poly8x16_t __a) -{ - return (float16x8_t) __a; -} -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f16_p128 (poly128_t __a) -{ - return (float16x8_t) __a; -} -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f16_p16 (poly16x8_t __a) -{ - return (float16x8_t) __a; -} -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f16_p64 (poly64x2_t __a) -{ - return (float16x8_t) __a; -} -__extension__ extern __inline float32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f32_f16 (float16x4_t __a) -{ - return (float32x2_t) __a; -} -__extension__ extern __inline float32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f32_f64 (float64x1_t __a) -{ - return (float32x2_t) __a; -} -__extension__ extern __inline float32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f32_s8 (int8x8_t __a) -{ - return (float32x2_t) __a; -} -__extension__ extern __inline float32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f32_s16 (int16x4_t __a) -{ - return (float32x2_t) __a; -} -__extension__ extern __inline float32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f32_s32 (int32x2_t __a) -{ - return (float32x2_t) __a; -} -__extension__ extern __inline float32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f32_s64 (int64x1_t __a) -{ - return (float32x2_t) __a; -} -__extension__ extern __inline float32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f32_u8 (uint8x8_t __a) -{ - return (float32x2_t) __a; -} -__extension__ extern __inline float32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f32_u16 (uint16x4_t __a) -{ - return (float32x2_t) __a; -} -__extension__ extern __inline float32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f32_u32 (uint32x2_t __a) -{ - return (float32x2_t) __a; -} -__extension__ extern __inline float32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f32_u64 (uint64x1_t __a) -{ - return (float32x2_t) __a; -} -__extension__ extern __inline float32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f32_p8 (poly8x8_t __a) -{ - return (float32x2_t) __a; -} -__extension__ extern __inline float32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f32_p16 (poly16x4_t __a) -{ - return (float32x2_t) __a; -} -__extension__ extern __inline float32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f32_p64 (poly64x1_t __a) -{ - return (float32x2_t) __a; -} -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f32_f16 (float16x8_t __a) -{ - return (float32x4_t) __a; -} -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f32_f64 (float64x2_t __a) -{ - return (float32x4_t) __a; -} -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f32_s8 (int8x16_t __a) -{ - return (float32x4_t) __a; -} -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f32_s16 (int16x8_t __a) -{ - return (float32x4_t) __a; -} -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f32_s32 (int32x4_t __a) -{ - return (float32x4_t) __a; -} -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f32_s64 (int64x2_t __a) -{ - return (float32x4_t) __a; -} -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f32_u8 (uint8x16_t __a) -{ - return (float32x4_t) __a; -} -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f32_u16 (uint16x8_t __a) -{ - return (float32x4_t) __a; -} -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f32_u32 (uint32x4_t __a) -{ - return (float32x4_t) __a; -} -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f32_u64 (uint64x2_t __a) -{ - return (float32x4_t) __a; -} -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f32_p8 (poly8x16_t __a) -{ - return (float32x4_t) __a; -} -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f32_p16 (poly16x8_t __a) -{ - return (float32x4_t) __a; -} -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f32_p64 (poly64x2_t __a) -{ - return (float32x4_t) __a; -} -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f32_p128 (poly128_t __a) -{ - return (float32x4_t)__a; -} -__extension__ extern __inline float64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f64_f16 (float16x4_t __a) -{ - return (float64x1_t) __a; -} -__extension__ extern __inline float64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f64_f32 (float32x2_t __a) -{ - return (float64x1_t) __a; -} -__extension__ extern __inline float64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f64_p8 (poly8x8_t __a) -{ - return (float64x1_t) __a; -} -__extension__ extern __inline float64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f64_p16 (poly16x4_t __a) -{ - return (float64x1_t) __a; -} -__extension__ extern __inline float64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f64_p64 (poly64x1_t __a) -{ - return (float64x1_t) __a; -} -__extension__ extern __inline float64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f64_s8 (int8x8_t __a) -{ - return (float64x1_t) __a; -} -__extension__ extern __inline float64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f64_s16 (int16x4_t __a) -{ - return (float64x1_t) __a; -} -__extension__ extern __inline float64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f64_s32 (int32x2_t __a) -{ - return (float64x1_t) __a; -} -__extension__ extern __inline float64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f64_s64 (int64x1_t __a) -{ - return (float64x1_t) __a; -} -__extension__ extern __inline float64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f64_u8 (uint8x8_t __a) -{ - return (float64x1_t) __a; -} -__extension__ extern __inline float64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f64_u16 (uint16x4_t __a) -{ - return (float64x1_t) __a; -} -__extension__ extern __inline float64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f64_u32 (uint32x2_t __a) -{ - return (float64x1_t) __a; -} -__extension__ extern __inline float64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f64_u64 (uint64x1_t __a) -{ - return (float64x1_t) __a; -} -__extension__ extern __inline float64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f64_f16 (float16x8_t __a) -{ - return (float64x2_t) __a; -} -__extension__ extern __inline float64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f64_f32 (float32x4_t __a) -{ - return (float64x2_t) __a; -} -__extension__ extern __inline float64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f64_p8 (poly8x16_t __a) -{ - return (float64x2_t) __a; -} -__extension__ extern __inline float64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f64_p16 (poly16x8_t __a) -{ - return (float64x2_t) __a; -} -__extension__ extern __inline float64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f64_p64 (poly64x2_t __a) -{ - return (float64x2_t) __a; -} -__extension__ extern __inline float64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f64_s8 (int8x16_t __a) -{ - return (float64x2_t) __a; -} -__extension__ extern __inline float64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f64_s16 (int16x8_t __a) -{ - return (float64x2_t) __a; -} -__extension__ extern __inline float64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f64_s32 (int32x4_t __a) -{ - return (float64x2_t) __a; -} -__extension__ extern __inline float64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f64_s64 (int64x2_t __a) -{ - return (float64x2_t) __a; -} -__extension__ extern __inline float64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f64_u8 (uint8x16_t __a) -{ - return (float64x2_t) __a; -} -__extension__ extern __inline float64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f64_u16 (uint16x8_t __a) -{ - return (float64x2_t) __a; -} -__extension__ extern __inline float64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f64_u32 (uint32x4_t __a) -{ - return (float64x2_t) __a; -} -__extension__ extern __inline float64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f64_u64 (uint64x2_t __a) -{ - return (float64x2_t) __a; -} -__extension__ extern __inline int64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s64_f16 (float16x4_t __a) -{ - return (int64x1_t) __a; -} -__extension__ extern __inline int64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s64_f64 (float64x1_t __a) -{ - return (int64x1_t) __a; -} -__extension__ extern __inline int64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s64_s8 (int8x8_t __a) -{ - return (int64x1_t) __a; -} -__extension__ extern __inline int64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s64_s16 (int16x4_t __a) -{ - return (int64x1_t) __a; -} -__extension__ extern __inline int64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s64_s32 (int32x2_t __a) -{ - return (int64x1_t) __a; -} -__extension__ extern __inline int64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s64_f32 (float32x2_t __a) -{ - return (int64x1_t) __a; -} -__extension__ extern __inline int64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s64_u8 (uint8x8_t __a) -{ - return (int64x1_t) __a; -} -__extension__ extern __inline int64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s64_u16 (uint16x4_t __a) -{ - return (int64x1_t) __a; -} -__extension__ extern __inline int64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s64_u32 (uint32x2_t __a) -{ - return (int64x1_t) __a; -} -__extension__ extern __inline int64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s64_u64 (uint64x1_t __a) -{ - return (int64x1_t) __a; -} -__extension__ extern __inline int64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s64_p8 (poly8x8_t __a) -{ - return (int64x1_t) __a; -} -__extension__ extern __inline int64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s64_p16 (poly16x4_t __a) -{ - return (int64x1_t) __a; -} -__extension__ extern __inline int64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s64_p64 (poly64x1_t __a) -{ - return (int64x1_t) __a; -} -__extension__ extern __inline int64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s64_f64 (float64x2_t __a) -{ - return (int64x2_t) __a; -} -__extension__ extern __inline int64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s64_s8 (int8x16_t __a) -{ - return (int64x2_t) __a; -} -__extension__ extern __inline int64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s64_s16 (int16x8_t __a) -{ - return (int64x2_t) __a; -} -__extension__ extern __inline int64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s64_s32 (int32x4_t __a) -{ - return (int64x2_t) __a; -} -__extension__ extern __inline int64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s64_f16 (float16x8_t __a) -{ - return (int64x2_t) __a; -} -__extension__ extern __inline int64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s64_f32 (float32x4_t __a) -{ - return (int64x2_t) __a; -} -__extension__ extern __inline int64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s64_u8 (uint8x16_t __a) -{ - return (int64x2_t) __a; -} -__extension__ extern __inline int64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s64_u16 (uint16x8_t __a) -{ - return (int64x2_t) __a; -} -__extension__ extern __inline int64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s64_u32 (uint32x4_t __a) -{ - return (int64x2_t) __a; -} -__extension__ extern __inline int64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s64_u64 (uint64x2_t __a) -{ - return (int64x2_t) __a; -} -__extension__ extern __inline int64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s64_p8 (poly8x16_t __a) -{ - return (int64x2_t) __a; -} -__extension__ extern __inline int64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s64_p16 (poly16x8_t __a) -{ - return (int64x2_t) __a; -} -__extension__ extern __inline int64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s64_p64 (poly64x2_t __a) -{ - return (int64x2_t) __a; -} -__extension__ extern __inline int64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s64_p128 (poly128_t __a) -{ - return (int64x2_t)__a; -} -__extension__ extern __inline uint64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u64_f16 (float16x4_t __a) -{ - return (uint64x1_t) __a; -} -__extension__ extern __inline uint64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u64_f64 (float64x1_t __a) -{ - return (uint64x1_t) __a; -} -__extension__ extern __inline uint64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u64_s8 (int8x8_t __a) -{ - return (uint64x1_t) __a; -} -__extension__ extern __inline uint64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u64_s16 (int16x4_t __a) -{ - return (uint64x1_t) __a; -} -__extension__ extern __inline uint64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u64_s32 (int32x2_t __a) -{ - return (uint64x1_t) __a; -} -__extension__ extern __inline uint64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u64_s64 (int64x1_t __a) -{ - return (uint64x1_t) __a; -} -__extension__ extern __inline uint64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u64_f32 (float32x2_t __a) -{ - return (uint64x1_t) __a; -} -__extension__ extern __inline uint64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u64_u8 (uint8x8_t __a) -{ - return (uint64x1_t) __a; -} -__extension__ extern __inline uint64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u64_u16 (uint16x4_t __a) -{ - return (uint64x1_t) __a; -} -__extension__ extern __inline uint64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u64_u32 (uint32x2_t __a) -{ - return (uint64x1_t) __a; -} -__extension__ extern __inline uint64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u64_p8 (poly8x8_t __a) -{ - return (uint64x1_t) __a; -} -__extension__ extern __inline uint64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u64_p16 (poly16x4_t __a) -{ - return (uint64x1_t) __a; -} -__extension__ extern __inline uint64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u64_p64 (poly64x1_t __a) -{ - return (uint64x1_t) __a; -} -__extension__ extern __inline uint64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u64_f64 (float64x2_t __a) -{ - return (uint64x2_t) __a; -} -__extension__ extern __inline uint64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u64_s8 (int8x16_t __a) -{ - return (uint64x2_t) __a; -} -__extension__ extern __inline uint64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u64_s16 (int16x8_t __a) -{ - return (uint64x2_t) __a; -} -__extension__ extern __inline uint64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u64_s32 (int32x4_t __a) -{ - return (uint64x2_t) __a; -} -__extension__ extern __inline uint64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u64_s64 (int64x2_t __a) -{ - return (uint64x2_t) __a; -} -__extension__ extern __inline uint64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u64_f16 (float16x8_t __a) -{ - return (uint64x2_t) __a; -} -__extension__ extern __inline uint64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u64_f32 (float32x4_t __a) -{ - return (uint64x2_t) __a; -} -__extension__ extern __inline uint64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u64_u8 (uint8x16_t __a) -{ - return (uint64x2_t) __a; -} -__extension__ extern __inline uint64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u64_u16 (uint16x8_t __a) -{ - return (uint64x2_t) __a; -} -__extension__ extern __inline uint64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u64_u32 (uint32x4_t __a) -{ - return (uint64x2_t) __a; -} -__extension__ extern __inline uint64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u64_p8 (poly8x16_t __a) -{ - return (uint64x2_t) __a; -} -__extension__ extern __inline uint64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u64_p16 (poly16x8_t __a) -{ - return (uint64x2_t) __a; -} -__extension__ extern __inline uint64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u64_p64 (poly64x2_t __a) -{ - return (uint64x2_t) __a; -} -__extension__ extern __inline uint64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u64_p128 (poly128_t __a) -{ - return (uint64x2_t)__a; -} -__extension__ extern __inline int8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s8_f16 (float16x4_t __a) -{ - return (int8x8_t) __a; -} -__extension__ extern __inline int8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s8_f64 (float64x1_t __a) -{ - return (int8x8_t) __a; -} -__extension__ extern __inline int8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s8_s16 (int16x4_t __a) -{ - return (int8x8_t) __a; -} -__extension__ extern __inline int8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s8_s32 (int32x2_t __a) -{ - return (int8x8_t) __a; -} -__extension__ extern __inline int8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s8_s64 (int64x1_t __a) -{ - return (int8x8_t) __a; -} -__extension__ extern __inline int8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s8_f32 (float32x2_t __a) -{ - return (int8x8_t) __a; -} -__extension__ extern __inline int8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s8_u8 (uint8x8_t __a) -{ - return (int8x8_t) __a; -} -__extension__ extern __inline int8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s8_u16 (uint16x4_t __a) -{ - return (int8x8_t) __a; -} -__extension__ extern __inline int8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s8_u32 (uint32x2_t __a) -{ - return (int8x8_t) __a; -} -__extension__ extern __inline int8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s8_u64 (uint64x1_t __a) -{ - return (int8x8_t) __a; -} -__extension__ extern __inline int8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s8_p8 (poly8x8_t __a) -{ - return (int8x8_t) __a; -} -__extension__ extern __inline int8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s8_p16 (poly16x4_t __a) -{ - return (int8x8_t) __a; -} -__extension__ extern __inline int8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s8_p64 (poly64x1_t __a) -{ - return (int8x8_t) __a; -} -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s8_f64 (float64x2_t __a) -{ - return (int8x16_t) __a; -} -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s8_s16 (int16x8_t __a) -{ - return (int8x16_t) __a; -} -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s8_s32 (int32x4_t __a) -{ - return (int8x16_t) __a; -} -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s8_s64 (int64x2_t __a) -{ - return (int8x16_t) __a; -} -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s8_f16 (float16x8_t __a) -{ - return (int8x16_t) __a; -} -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s8_f32 (float32x4_t __a) -{ - return (int8x16_t) __a; -} -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s8_u8 (uint8x16_t __a) -{ - return (int8x16_t) __a; -} -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s8_u16 (uint16x8_t __a) -{ - return (int8x16_t) __a; -} -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s8_u32 (uint32x4_t __a) -{ - return (int8x16_t) __a; -} -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s8_u64 (uint64x2_t __a) -{ - return (int8x16_t) __a; -} -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s8_p8 (poly8x16_t __a) -{ - return (int8x16_t) __a; -} -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s8_p16 (poly16x8_t __a) -{ - return (int8x16_t) __a; -} -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s8_p64 (poly64x2_t __a) -{ - return (int8x16_t) __a; -} -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s8_p128 (poly128_t __a) -{ - return (int8x16_t)__a; -} -__extension__ extern __inline int16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s16_f16 (float16x4_t __a) -{ - return (int16x4_t) __a; -} -__extension__ extern __inline int16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s16_f64 (float64x1_t __a) -{ - return (int16x4_t) __a; -} -__extension__ extern __inline int16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s16_s8 (int8x8_t __a) -{ - return (int16x4_t) __a; -} -__extension__ extern __inline int16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s16_s32 (int32x2_t __a) -{ - return (int16x4_t) __a; -} -__extension__ extern __inline int16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s16_s64 (int64x1_t __a) -{ - return (int16x4_t) __a; -} -__extension__ extern __inline int16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s16_f32 (float32x2_t __a) -{ - return (int16x4_t) __a; -} -__extension__ extern __inline int16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s16_u8 (uint8x8_t __a) -{ - return (int16x4_t) __a; -} -__extension__ extern __inline int16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s16_u16 (uint16x4_t __a) -{ - return (int16x4_t) __a; -} -__extension__ extern __inline int16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s16_u32 (uint32x2_t __a) -{ - return (int16x4_t) __a; -} -__extension__ extern __inline int16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s16_u64 (uint64x1_t __a) -{ - return (int16x4_t) __a; -} -__extension__ extern __inline int16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s16_p8 (poly8x8_t __a) -{ - return (int16x4_t) __a; -} -__extension__ extern __inline int16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s16_p16 (poly16x4_t __a) -{ - return (int16x4_t) __a; -} -__extension__ extern __inline int16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s16_p64 (poly64x1_t __a) -{ - return (int16x4_t) __a; -} -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s16_f64 (float64x2_t __a) -{ - return (int16x8_t) __a; -} -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s16_s8 (int8x16_t __a) -{ - return (int16x8_t) __a; -} -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s16_s32 (int32x4_t __a) -{ - return (int16x8_t) __a; -} -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s16_s64 (int64x2_t __a) -{ - return (int16x8_t) __a; -} -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s16_f16 (float16x8_t __a) -{ - return (int16x8_t) __a; -} -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s16_f32 (float32x4_t __a) -{ - return (int16x8_t) __a; -} -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s16_u8 (uint8x16_t __a) -{ - return (int16x8_t) __a; -} -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s16_u16 (uint16x8_t __a) -{ - return (int16x8_t) __a; -} -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s16_u32 (uint32x4_t __a) -{ - return (int16x8_t) __a; -} -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s16_u64 (uint64x2_t __a) -{ - return (int16x8_t) __a; -} -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s16_p8 (poly8x16_t __a) -{ - return (int16x8_t) __a; -} -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s16_p16 (poly16x8_t __a) -{ - return (int16x8_t) __a; -} -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s16_p64 (poly64x2_t __a) -{ - return (int16x8_t) __a; -} -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s16_p128 (poly128_t __a) -{ - return (int16x8_t)__a; -} -__extension__ extern __inline int32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s32_f16 (float16x4_t __a) -{ - return (int32x2_t) __a; -} -__extension__ extern __inline int32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s32_f64 (float64x1_t __a) -{ - return (int32x2_t) __a; -} -__extension__ extern __inline int32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s32_s8 (int8x8_t __a) -{ - return (int32x2_t) __a; -} -__extension__ extern __inline int32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s32_s16 (int16x4_t __a) -{ - return (int32x2_t) __a; -} -__extension__ extern __inline int32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s32_s64 (int64x1_t __a) -{ - return (int32x2_t) __a; -} -__extension__ extern __inline int32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s32_f32 (float32x2_t __a) -{ - return (int32x2_t) __a; -} -__extension__ extern __inline int32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s32_u8 (uint8x8_t __a) -{ - return (int32x2_t) __a; -} -__extension__ extern __inline int32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s32_u16 (uint16x4_t __a) -{ - return (int32x2_t) __a; -} -__extension__ extern __inline int32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s32_u32 (uint32x2_t __a) -{ - return (int32x2_t) __a; -} -__extension__ extern __inline int32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s32_u64 (uint64x1_t __a) -{ - return (int32x2_t) __a; -} -__extension__ extern __inline int32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s32_p8 (poly8x8_t __a) -{ - return (int32x2_t) __a; -} -__extension__ extern __inline int32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s32_p16 (poly16x4_t __a) -{ - return (int32x2_t) __a; -} -__extension__ extern __inline int32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s32_p64 (poly64x1_t __a) -{ - return (int32x2_t) __a; -} -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s32_f64 (float64x2_t __a) -{ - return (int32x4_t) __a; -} -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s32_s8 (int8x16_t __a) -{ - return (int32x4_t) __a; -} -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s32_s16 (int16x8_t __a) -{ - return (int32x4_t) __a; -} -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s32_s64 (int64x2_t __a) -{ - return (int32x4_t) __a; -} -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s32_f16 (float16x8_t __a) -{ - return (int32x4_t) __a; -} -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s32_f32 (float32x4_t __a) -{ - return (int32x4_t) __a; -} -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s32_u8 (uint8x16_t __a) -{ - return (int32x4_t) __a; -} -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s32_u16 (uint16x8_t __a) -{ - return (int32x4_t) __a; -} -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s32_u32 (uint32x4_t __a) -{ - return (int32x4_t) __a; -} -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s32_u64 (uint64x2_t __a) -{ - return (int32x4_t) __a; -} -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s32_p8 (poly8x16_t __a) -{ - return (int32x4_t) __a; -} -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s32_p16 (poly16x8_t __a) -{ - return (int32x4_t) __a; -} -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s32_p64 (poly64x2_t __a) -{ - return (int32x4_t) __a; -} -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s32_p128 (poly128_t __a) -{ - return (int32x4_t)__a; -} -__extension__ extern __inline uint8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u8_f16 (float16x4_t __a) -{ - return (uint8x8_t) __a; -} -__extension__ extern __inline uint8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u8_f64 (float64x1_t __a) -{ - return (uint8x8_t) __a; -} -__extension__ extern __inline uint8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u8_s8 (int8x8_t __a) -{ - return (uint8x8_t) __a; -} -__extension__ extern __inline uint8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u8_s16 (int16x4_t __a) -{ - return (uint8x8_t) __a; -} -__extension__ extern __inline uint8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u8_s32 (int32x2_t __a) -{ - return (uint8x8_t) __a; -} -__extension__ extern __inline uint8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u8_s64 (int64x1_t __a) -{ - return (uint8x8_t) __a; -} -__extension__ extern __inline uint8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u8_f32 (float32x2_t __a) -{ - return (uint8x8_t) __a; -} -__extension__ extern __inline uint8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u8_u16 (uint16x4_t __a) -{ - return (uint8x8_t) __a; -} -__extension__ extern __inline uint8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u8_u32 (uint32x2_t __a) -{ - return (uint8x8_t) __a; -} -__extension__ extern __inline uint8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u8_u64 (uint64x1_t __a) -{ - return (uint8x8_t) __a; -} -__extension__ extern __inline uint8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u8_p8 (poly8x8_t __a) -{ - return (uint8x8_t) __a; -} -__extension__ extern __inline uint8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u8_p16 (poly16x4_t __a) -{ - return (uint8x8_t) __a; -} -__extension__ extern __inline uint8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u8_p64 (poly64x1_t __a) -{ - return (uint8x8_t) __a; -} -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u8_f64 (float64x2_t __a) -{ - return (uint8x16_t) __a; -} -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u8_s8 (int8x16_t __a) -{ - return (uint8x16_t) __a; -} -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u8_s16 (int16x8_t __a) -{ - return (uint8x16_t) __a; -} -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u8_s32 (int32x4_t __a) -{ - return (uint8x16_t) __a; -} -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u8_s64 (int64x2_t __a) -{ - return (uint8x16_t) __a; -} -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u8_f16 (float16x8_t __a) -{ - return (uint8x16_t) __a; -} -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u8_f32 (float32x4_t __a) -{ - return (uint8x16_t) __a; -} -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u8_u16 (uint16x8_t __a) -{ - return (uint8x16_t) __a; -} -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u8_u32 (uint32x4_t __a) -{ - return (uint8x16_t) __a; -} -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u8_u64 (uint64x2_t __a) -{ - return (uint8x16_t) __a; -} -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u8_p8 (poly8x16_t __a) -{ - return (uint8x16_t) __a; -} -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u8_p16 (poly16x8_t __a) -{ - return (uint8x16_t) __a; -} -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u8_p64 (poly64x2_t __a) -{ - return (uint8x16_t) __a; -} -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u8_p128 (poly128_t __a) -{ - return (uint8x16_t)__a; -} -__extension__ extern __inline uint16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u16_f16 (float16x4_t __a) -{ - return (uint16x4_t) __a; -} -__extension__ extern __inline uint16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u16_f64 (float64x1_t __a) -{ - return (uint16x4_t) __a; -} -__extension__ extern __inline uint16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u16_s8 (int8x8_t __a) -{ - return (uint16x4_t) __a; -} -__extension__ extern __inline uint16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u16_s16 (int16x4_t __a) -{ - return (uint16x4_t) __a; -} -__extension__ extern __inline uint16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u16_s32 (int32x2_t __a) -{ - return (uint16x4_t) __a; -} -__extension__ extern __inline uint16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u16_s64 (int64x1_t __a) -{ - return (uint16x4_t) __a; -} -__extension__ extern __inline uint16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u16_f32 (float32x2_t __a) -{ - return (uint16x4_t) __a; -} -__extension__ extern __inline uint16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u16_u8 (uint8x8_t __a) -{ - return (uint16x4_t) __a; -} -__extension__ extern __inline uint16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u16_u32 (uint32x2_t __a) -{ - return (uint16x4_t) __a; -} -__extension__ extern __inline uint16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u16_u64 (uint64x1_t __a) -{ - return (uint16x4_t) __a; -} -__extension__ extern __inline uint16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u16_p8 (poly8x8_t __a) -{ - return (uint16x4_t) __a; -} -__extension__ extern __inline uint16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u16_p16 (poly16x4_t __a) -{ - return (uint16x4_t) __a; -} -__extension__ extern __inline uint16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u16_p64 (poly64x1_t __a) -{ - return (uint16x4_t) __a; -} -__extension__ extern __inline uint16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u16_f64 (float64x2_t __a) -{ - return (uint16x8_t) __a; -} -__extension__ extern __inline uint16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u16_s8 (int8x16_t __a) -{ - return (uint16x8_t) __a; -} -__extension__ extern __inline uint16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u16_s16 (int16x8_t __a) -{ - return (uint16x8_t) __a; -} -__extension__ extern __inline uint16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u16_s32 (int32x4_t __a) -{ - return (uint16x8_t) __a; -} -__extension__ extern __inline uint16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u16_s64 (int64x2_t __a) -{ - return (uint16x8_t) __a; -} -__extension__ extern __inline uint16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u16_f16 (float16x8_t __a) -{ - return (uint16x8_t) __a; -} -__extension__ extern __inline uint16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u16_f32 (float32x4_t __a) -{ - return (uint16x8_t) __a; -} -__extension__ extern __inline uint16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u16_u8 (uint8x16_t __a) -{ - return (uint16x8_t) __a; -} -__extension__ extern __inline uint16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u16_u32 (uint32x4_t __a) -{ - return (uint16x8_t) __a; -} -__extension__ extern __inline uint16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u16_u64 (uint64x2_t __a) -{ - return (uint16x8_t) __a; -} -__extension__ extern __inline uint16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u16_p8 (poly8x16_t __a) -{ - return (uint16x8_t) __a; -} -__extension__ extern __inline uint16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u16_p16 (poly16x8_t __a) -{ - return (uint16x8_t) __a; -} -__extension__ extern __inline uint16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u16_p64 (poly64x2_t __a) -{ - return (uint16x8_t) __a; -} -__extension__ extern __inline uint16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u16_p128 (poly128_t __a) -{ - return (uint16x8_t)__a; -} -__extension__ extern __inline uint32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u32_f16 (float16x4_t __a) -{ - return (uint32x2_t) __a; -} -__extension__ extern __inline uint32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u32_f64 (float64x1_t __a) -{ - return (uint32x2_t) __a; -} -__extension__ extern __inline uint32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u32_s8 (int8x8_t __a) -{ - return (uint32x2_t) __a; -} -__extension__ extern __inline uint32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u32_s16 (int16x4_t __a) -{ - return (uint32x2_t) __a; -} -__extension__ extern __inline uint32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u32_s32 (int32x2_t __a) -{ - return (uint32x2_t) __a; -} -__extension__ extern __inline uint32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u32_s64 (int64x1_t __a) -{ - return (uint32x2_t) __a; -} -__extension__ extern __inline uint32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u32_f32 (float32x2_t __a) -{ - return (uint32x2_t) __a; -} -__extension__ extern __inline uint32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u32_u8 (uint8x8_t __a) -{ - return (uint32x2_t) __a; -} -__extension__ extern __inline uint32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u32_u16 (uint16x4_t __a) -{ - return (uint32x2_t) __a; -} -__extension__ extern __inline uint32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u32_u64 (uint64x1_t __a) -{ - return (uint32x2_t) __a; -} -__extension__ extern __inline uint32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u32_p8 (poly8x8_t __a) -{ - return (uint32x2_t) __a; -} -__extension__ extern __inline uint32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u32_p16 (poly16x4_t __a) -{ - return (uint32x2_t) __a; -} -__extension__ extern __inline uint32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u32_p64 (poly64x1_t __a) -{ - return (uint32x2_t) __a; -} -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u32_f64 (float64x2_t __a) -{ - return (uint32x4_t) __a; -} -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u32_s8 (int8x16_t __a) -{ - return (uint32x4_t) __a; -} -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u32_s16 (int16x8_t __a) -{ - return (uint32x4_t) __a; -} -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u32_s32 (int32x4_t __a) -{ - return (uint32x4_t) __a; -} -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u32_s64 (int64x2_t __a) -{ - return (uint32x4_t) __a; -} -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u32_f16 (float16x8_t __a) -{ - return (uint32x4_t) __a; -} -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u32_f32 (float32x4_t __a) -{ - return (uint32x4_t) __a; -} -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u32_u8 (uint8x16_t __a) -{ - return (uint32x4_t) __a; -} -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u32_u16 (uint16x8_t __a) -{ - return (uint32x4_t) __a; -} -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u32_u64 (uint64x2_t __a) -{ - return (uint32x4_t) __a; -} -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u32_p8 (poly8x16_t __a) -{ - return (uint32x4_t) __a; -} -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u32_p16 (poly16x8_t __a) -{ - return (uint32x4_t) __a; -} -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u32_p64 (poly64x2_t __a) -{ - return (uint32x4_t) __a; -} -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u32_p128 (poly128_t __a) -{ - return (uint32x4_t)__a; -} -__extension__ extern __inline float64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f64_p128 (poly128_t __a) -{ - return (float64x2_t) __a; -} -__extension__ extern __inline poly128_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p128_f64 (float64x2_t __a) -{ - return (poly128_t) __a; -} __extension__ extern __inline float16x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vset_lane_f16 (float16_t __elem, float16x4_t __vec, const int __index) @@ -6332,37 +3980,37 @@ __extension__ extern __inline int8x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vshrn_n_s16 (int16x8_t __a, const int __b) { - return __builtin_aarch64_shrnv8hi (__a, __b); + return __builtin_aarch64_shrn_nv8hi (__a, __b); } __extension__ extern __inline int16x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vshrn_n_s32 (int32x4_t __a, const int __b) { - return __builtin_aarch64_shrnv4si (__a, __b); + return __builtin_aarch64_shrn_nv4si (__a, __b); } __extension__ extern __inline int32x2_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vshrn_n_s64 (int64x2_t __a, const int __b) { - return __builtin_aarch64_shrnv2di (__a, __b); + return __builtin_aarch64_shrn_nv2di (__a, __b); } __extension__ extern __inline uint8x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vshrn_n_u16 (uint16x8_t __a, const int __b) { - return __builtin_aarch64_shrnv8hi_uus (__a, __b); + return __builtin_aarch64_shrn_nv8hi_uus (__a, __b); } __extension__ extern __inline uint16x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vshrn_n_u32 (uint32x4_t __a, const int __b) { - return __builtin_aarch64_shrnv4si_uus (__a, __b); + return __builtin_aarch64_shrn_nv4si_uus (__a, __b); } __extension__ extern __inline uint32x2_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vshrn_n_u64 (uint64x2_t __a, const int __b) { - return __builtin_aarch64_shrnv2di_uus (__a, __b); + return __builtin_aarch64_shrn_nv2di_uus (__a, __b); } __extension__ extern __inline int32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) @@ -6944,37 +4592,37 @@ __extension__ extern __inline int8x16_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vqshrn_high_n_s16 (int8x8_t __a, int16x8_t __b, const int __c) { - return __builtin_aarch64_sqshrn2_nv8hi (__a, __b, __c); + return __builtin_aarch64_sqsshrn2_nv8hi (__a, __b, __c); } __extension__ extern __inline int16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vqshrn_high_n_s32 (int16x4_t __a, int32x4_t __b, const int __c) { - return __builtin_aarch64_sqshrn2_nv4si (__a, __b, __c); + return __builtin_aarch64_sqsshrn2_nv4si (__a, __b, __c); } __extension__ extern __inline int32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vqshrn_high_n_s64 (int32x2_t __a, int64x2_t __b, const int __c) { - return __builtin_aarch64_sqshrn2_nv2di (__a, __b, __c); + return __builtin_aarch64_sqsshrn2_nv2di (__a, __b, __c); } __extension__ extern __inline uint8x16_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vqshrn_high_n_u16 (uint8x8_t __a, uint16x8_t __b, const int __c) { - return __builtin_aarch64_uqshrn2_nv8hi_uuus (__a, __b, __c); + return __builtin_aarch64_uqushrn2_nv8hi_uuus (__a, __b, __c); } __extension__ extern __inline uint16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vqshrn_high_n_u32 (uint16x4_t __a, uint32x4_t __b, const int __c) { - return __builtin_aarch64_uqshrn2_nv4si_uuus (__a, __b, __c); + return __builtin_aarch64_uqushrn2_nv4si_uuus (__a, __b, __c); } __extension__ extern __inline uint32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vqshrn_high_n_u64 (uint32x2_t __a, uint64x2_t __b, const int __c) { - return __builtin_aarch64_uqshrn2_nv2di_uuus (__a, __b, __c); + return __builtin_aarch64_uqushrn2_nv2di_uuus (__a, __b, __c); } __extension__ extern __inline uint8x16_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) @@ -6998,73 +4646,73 @@ __extension__ extern __inline int8x16_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vrshrn_high_n_s16 (int8x8_t __a, int16x8_t __b, const int __c) { - return __builtin_aarch64_rshrn2v8hi (__a, __b, __c); + return __builtin_aarch64_rshrn2_nv8hi (__a, __b, __c); } __extension__ extern __inline int16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vrshrn_high_n_s32 (int16x4_t __a, int32x4_t __b, const int __c) { - return __builtin_aarch64_rshrn2v4si (__a, __b, __c); + return __builtin_aarch64_rshrn2_nv4si (__a, __b, __c); } __extension__ extern __inline int32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vrshrn_high_n_s64 (int32x2_t __a, int64x2_t __b, const int __c) { - return __builtin_aarch64_rshrn2v2di (__a, __b, __c); + return __builtin_aarch64_rshrn2_nv2di (__a, __b, __c); } __extension__ extern __inline uint8x16_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vrshrn_high_n_u16 (uint8x8_t __a, uint16x8_t __b, const int __c) { - return __builtin_aarch64_rshrn2v8hi_uuus (__a, __b, __c); + return __builtin_aarch64_rshrn2_nv8hi_uuus (__a, __b, __c); } __extension__ extern __inline uint16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vrshrn_high_n_u32 (uint16x4_t __a, uint32x4_t __b, const int __c) { - return __builtin_aarch64_rshrn2v4si_uuus (__a, __b, __c); + return __builtin_aarch64_rshrn2_nv4si_uuus (__a, __b, __c); } __extension__ extern __inline uint32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vrshrn_high_n_u64 (uint32x2_t __a, uint64x2_t __b, const int __c) { - return __builtin_aarch64_rshrn2v2di_uuus (__a, __b, __c); + return __builtin_aarch64_rshrn2_nv2di_uuus (__a, __b, __c); } __extension__ extern __inline int8x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vrshrn_n_s16 (int16x8_t __a, const int __b) { - return __builtin_aarch64_rshrnv8hi (__a, __b); + return __builtin_aarch64_rshrn_nv8hi (__a, __b); } __extension__ extern __inline int16x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vrshrn_n_s32 (int32x4_t __a, const int __b) { - return __builtin_aarch64_rshrnv4si (__a, __b); + return __builtin_aarch64_rshrn_nv4si (__a, __b); } __extension__ extern __inline int32x2_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vrshrn_n_s64 (int64x2_t __a, const int __b) { - return __builtin_aarch64_rshrnv2di (__a, __b); + return __builtin_aarch64_rshrn_nv2di (__a, __b); } __extension__ extern __inline uint8x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vrshrn_n_u16 (uint16x8_t __a, const int __b) { - return __builtin_aarch64_rshrnv8hi_uus (__a, __b); + return __builtin_aarch64_rshrn_nv8hi_uus (__a, __b); } __extension__ extern __inline uint16x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vrshrn_n_u32 (uint32x4_t __a, const int __b) { - return __builtin_aarch64_rshrnv4si_uus (__a, __b); + return __builtin_aarch64_rshrn_nv4si_uus (__a, __b); } __extension__ extern __inline uint32x2_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vrshrn_n_u64 (uint64x2_t __a, const int __b) { - return __builtin_aarch64_rshrnv2di_uus (__a, __b); + return __builtin_aarch64_rshrn_nv2di_uus (__a, __b); } __extension__ extern __inline uint32x2_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) @@ -7082,37 +4730,37 @@ __extension__ extern __inline int8x16_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vshrn_high_n_s16 (int8x8_t __a, int16x8_t __b, const int __c) { - return __builtin_aarch64_shrn2v8hi (__a, __b, __c); + return __builtin_aarch64_ushrn2_nv8hi (__a, __b, __c); } __extension__ extern __inline int16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vshrn_high_n_s32 (int16x4_t __a, int32x4_t __b, const int __c) { - return __builtin_aarch64_shrn2v4si (__a, __b, __c); + return __builtin_aarch64_ushrn2_nv4si (__a, __b, __c); } __extension__ extern __inline int32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vshrn_high_n_s64 (int32x2_t __a, int64x2_t __b, const int __c) { - return __builtin_aarch64_shrn2v2di (__a, __b, __c); + return __builtin_aarch64_ushrn2_nv2di (__a, __b, __c); } __extension__ extern __inline uint8x16_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vshrn_high_n_u16 (uint8x8_t __a, uint16x8_t __b, const int __c) { - return __builtin_aarch64_shrn2v8hi_uuus (__a, __b, __c); + return __builtin_aarch64_ushrn2_nv8hi_uuus (__a, __b, __c); } __extension__ extern __inline uint16x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vshrn_high_n_u32 (uint16x4_t __a, uint32x4_t __b, const int __c) { - return __builtin_aarch64_shrn2v4si_uuus (__a, __b, __c); + return __builtin_aarch64_ushrn2_nv4si_uuus (__a, __b, __c); } __extension__ extern __inline uint32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vshrn_high_n_u64 (uint32x2_t __a, uint64x2_t __b, const int __c) { - return __builtin_aarch64_shrn2v2di_uuus (__a, __b, __c); + return __builtin_aarch64_ushrn2_nv2di_uuus (__a, __b, __c); } __extension__ extern __inline poly8x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) @@ -8679,7 +6327,7 @@ vqrdmlshs_laneq_s32 (int32_t __a, int32_t __b, int32x4_t __c, const int __d) } #pragma GCC pop_options #pragma GCC push_options -#pragma GCC target ("+nothing+crypto") +#pragma GCC target ("+nothing+aes") __extension__ extern __inline uint8x16_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vaeseq_u8 (uint8x16_t data, uint8x16_t key) @@ -8704,150 +6352,163 @@ vaesimcq_u8 (uint8x16_t data) { return __builtin_aarch64_crypto_aesimcv16qi_uu (data); } +__extension__ extern __inline poly128_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vmull_p64 (poly64_t __a, poly64_t __b) +{ + return + __builtin_aarch64_crypto_pmulldi_ppp (__a, __b); +} +__extension__ extern __inline poly128_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vmull_high_p64 (poly64x2_t __a, poly64x2_t __b) +{ + return __builtin_aarch64_crypto_pmullv2di_ppp (__a, __b); +} #pragma GCC pop_options __extension__ extern __inline uint64x1_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vcage_f64 (float64x1_t __a, float64x1_t __b) { - return vabs_f64 (__a) >= vabs_f64 (__b); + return vcreate_u64 (__builtin_aarch64_facgedf_uss (__a[0], __b[0])); } __extension__ extern __inline uint32_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vcages_f32 (float32_t __a, float32_t __b) { - return __builtin_fabsf (__a) >= __builtin_fabsf (__b) ? -1 : 0; + return __builtin_aarch64_facgesf_uss (__a, __b); } __extension__ extern __inline uint32x2_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vcage_f32 (float32x2_t __a, float32x2_t __b) { - return vabs_f32 (__a) >= vabs_f32 (__b); + return __builtin_aarch64_facgev2sf_uss (__a, __b); } __extension__ extern __inline uint32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vcageq_f32 (float32x4_t __a, float32x4_t __b) { - return vabsq_f32 (__a) >= vabsq_f32 (__b); + return __builtin_aarch64_facgev4sf_uss (__a, __b); } __extension__ extern __inline uint64_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vcaged_f64 (float64_t __a, float64_t __b) { - return __builtin_fabs (__a) >= __builtin_fabs (__b) ? -1 : 0; + return __builtin_aarch64_facgedf_uss (__a, __b); } __extension__ extern __inline uint64x2_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vcageq_f64 (float64x2_t __a, float64x2_t __b) { - return vabsq_f64 (__a) >= vabsq_f64 (__b); + return __builtin_aarch64_facgev2df_uss (__a, __b); } __extension__ extern __inline uint32_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vcagts_f32 (float32_t __a, float32_t __b) { - return __builtin_fabsf (__a) > __builtin_fabsf (__b) ? -1 : 0; + return __builtin_aarch64_facgtsf_uss (__a, __b); } __extension__ extern __inline uint32x2_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vcagt_f32 (float32x2_t __a, float32x2_t __b) { - return vabs_f32 (__a) > vabs_f32 (__b); + return __builtin_aarch64_facgtv2sf_uss (__a, __b); } __extension__ extern __inline uint64x1_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vcagt_f64 (float64x1_t __a, float64x1_t __b) { - return vabs_f64 (__a) > vabs_f64 (__b); + return vcreate_u64 (__builtin_aarch64_facgtdf_uss (__a[0], __b[0])); } __extension__ extern __inline uint32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vcagtq_f32 (float32x4_t __a, float32x4_t __b) { - return vabsq_f32 (__a) > vabsq_f32 (__b); + return __builtin_aarch64_facgtv4sf_uss (__a, __b); } __extension__ extern __inline uint64_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vcagtd_f64 (float64_t __a, float64_t __b) { - return __builtin_fabs (__a) > __builtin_fabs (__b) ? -1 : 0; + return __builtin_aarch64_facgtdf_uss (__a, __b); } __extension__ extern __inline uint64x2_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vcagtq_f64 (float64x2_t __a, float64x2_t __b) { - return vabsq_f64 (__a) > vabsq_f64 (__b); + return __builtin_aarch64_facgtv2df_uss (__a, __b); } __extension__ extern __inline uint32x2_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vcale_f32 (float32x2_t __a, float32x2_t __b) { - return vabs_f32 (__a) <= vabs_f32 (__b); + return __builtin_aarch64_faclev2sf_uss (__a, __b); } __extension__ extern __inline uint64x1_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vcale_f64 (float64x1_t __a, float64x1_t __b) { - return vabs_f64 (__a) <= vabs_f64 (__b); + return vcreate_u64 (__builtin_aarch64_facledf_uss (__a[0], __b[0])); } __extension__ extern __inline uint64_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vcaled_f64 (float64_t __a, float64_t __b) { - return __builtin_fabs (__a) <= __builtin_fabs (__b) ? -1 : 0; + return __builtin_aarch64_facledf_uss (__a, __b); } __extension__ extern __inline uint32_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vcales_f32 (float32_t __a, float32_t __b) { - return __builtin_fabsf (__a) <= __builtin_fabsf (__b) ? -1 : 0; + return __builtin_aarch64_faclesf_uss (__a, __b); } __extension__ extern __inline uint32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vcaleq_f32 (float32x4_t __a, float32x4_t __b) { - return vabsq_f32 (__a) <= vabsq_f32 (__b); + return __builtin_aarch64_faclev4sf_uss (__a, __b); } __extension__ extern __inline uint64x2_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vcaleq_f64 (float64x2_t __a, float64x2_t __b) { - return vabsq_f64 (__a) <= vabsq_f64 (__b); + return __builtin_aarch64_faclev2df_uss (__a, __b); } __extension__ extern __inline uint32x2_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vcalt_f32 (float32x2_t __a, float32x2_t __b) { - return vabs_f32 (__a) < vabs_f32 (__b); + return __builtin_aarch64_facltv2sf_uss (__a, __b); } __extension__ extern __inline uint64x1_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vcalt_f64 (float64x1_t __a, float64x1_t __b) { - return vabs_f64 (__a) < vabs_f64 (__b); + return vcreate_u64 (__builtin_aarch64_facltdf_uss (__a[0], __b[0])); } __extension__ extern __inline uint64_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vcaltd_f64 (float64_t __a, float64_t __b) { - return __builtin_fabs (__a) < __builtin_fabs (__b) ? -1 : 0; + return __builtin_aarch64_facltdf_uss (__a, __b); } __extension__ extern __inline uint32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vcaltq_f32 (float32x4_t __a, float32x4_t __b) { - return vabsq_f32 (__a) < vabsq_f32 (__b); + return __builtin_aarch64_facltv4sf_uss (__a, __b); } __extension__ extern __inline uint64x2_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vcaltq_f64 (float64x2_t __a, float64x2_t __b) { - return vabsq_f64 (__a) < vabsq_f64 (__b); + return __builtin_aarch64_facltv2df_uss (__a, __b); } __extension__ extern __inline uint32_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vcalts_f32 (float32_t __a, float32_t __b) { - return __builtin_fabsf (__a) < __builtin_fabsf (__b) ? -1 : 0; + return __builtin_aarch64_facltsf_uss (__a, __b); } __extension__ extern __inline uint32x2_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) @@ -13691,6 +11352,121 @@ vld1q_lane_u64 (const uint64_t *__src, uint64x2_t __vec, const int __lane) { return __aarch64_vset_lane_any (*__src, __vec, __lane); } +#pragma GCC push_options +#pragma GCC target ("+nothing+rcpc3+simd") +__extension__ extern __inline uint64x1_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vldap1_lane_u64 (const uint64_t *__src, uint64x1_t __vec, const int __lane) +{ + return __builtin_aarch64_vec_ldap1_lanev1di_usus ( + (const __builtin_aarch64_simd_di *) __src, __vec, __lane); +} +__extension__ extern __inline uint64x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vldap1q_lane_u64 (const uint64_t *__src, uint64x2_t __vec, const int __lane) +{ + return __builtin_aarch64_vec_ldap1_lanev2di_usus ( + (const __builtin_aarch64_simd_di *) __src, __vec, __lane); +} +__extension__ extern __inline int64x1_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vldap1_lane_s64 (const int64_t *__src, int64x1_t __vec, const int __lane) +{ + return __builtin_aarch64_vec_ldap1_lanev1di ( + (const __builtin_aarch64_simd_di *) __src, __vec, __lane); +} +__extension__ extern __inline int64x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vldap1q_lane_s64 (const int64_t *__src, int64x2_t __vec, const int __lane) +{ + return __builtin_aarch64_vec_ldap1_lanev2di ( + (const __builtin_aarch64_simd_di *) __src, __vec, __lane); +} +__extension__ extern __inline float64x1_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vldap1_lane_f64 (const float64_t *__src, float64x1_t __vec, const int __lane) +{ + return __builtin_aarch64_vec_ldap1_lanev1df ( + (const __builtin_aarch64_simd_df *) __src, __vec, __lane); +} +__extension__ extern __inline float64x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vldap1q_lane_f64 (const float64_t *__src, float64x2_t __vec, const int __lane) +{ + return __builtin_aarch64_vec_ldap1_lanev2df ( + (const __builtin_aarch64_simd_df *) __src, __vec, __lane); +} +__extension__ extern __inline poly64x1_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vldap1_lane_p64 (const poly64_t *__src, poly64x1_t __vec, const int __lane) +{ + return __builtin_aarch64_vec_ldap1_lanev1di_psps ( + (const __builtin_aarch64_simd_di *) __src, __vec, __lane); +} +__extension__ extern __inline poly64x2_t +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vldap1q_lane_p64 (const poly64_t *__src, poly64x2_t __vec, const int __lane) +{ + return __builtin_aarch64_vec_ldap1_lanev2di_psps ( + (const __builtin_aarch64_simd_di *) __src, __vec, __lane); +} +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vstl1_lane_u64 (uint64_t *__src, uint64x1_t __vec, const int __lane) +{ + __builtin_aarch64_vec_stl1_lanev1di_sus ((__builtin_aarch64_simd_di *) __src, + __vec, __lane); +} +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vstl1q_lane_u64 (uint64_t *__src, uint64x2_t __vec, const int __lane) +{ + __builtin_aarch64_vec_stl1_lanev2di_sus ((__builtin_aarch64_simd_di *) __src, + __vec, __lane); +} +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vstl1_lane_s64 (int64_t *__src, int64x1_t __vec, const int __lane) +{ + __builtin_aarch64_vec_stl1_lanev1di ((__builtin_aarch64_simd_di *) __src, + __vec, __lane); +} +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vstl1q_lane_s64 (int64_t *__src, int64x2_t __vec, const int __lane) +{ + __builtin_aarch64_vec_stl1_lanev2di ((__builtin_aarch64_simd_di *) __src, + __vec, __lane); +} +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vstl1_lane_f64 (float64_t *__src, float64x1_t __vec, const int __lane) +{ + __builtin_aarch64_vec_stl1_lanev1df ((__builtin_aarch64_simd_df *) __src, + __vec, __lane); +} +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vstl1q_lane_f64 (float64_t *__src, float64x2_t __vec, const int __lane) +{ + __builtin_aarch64_vec_stl1_lanev2df ((__builtin_aarch64_simd_df *) __src, + __vec, __lane); +} +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vstl1_lane_p64 (poly64_t *__src, poly64x1_t __vec, const int __lane) +{ + __builtin_aarch64_vec_stl1_lanev1di_sps ((__builtin_aarch64_simd_di *) __src, + __vec, __lane); +} +__extension__ extern __inline void +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +vstl1q_lane_p64 (poly64_t *__src, poly64x2_t __vec, const int __lane) +{ + __builtin_aarch64_vec_stl1_lanev2di_sps ((__builtin_aarch64_simd_di *) __src, + __vec, __lane); +} +#pragma GCC pop_options __extension__ extern __inline int64x1x2_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vld2_s64 (const int64_t * __a) @@ -17192,13 +14968,13 @@ __extension__ extern __inline int64_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vpaddd_s64 (int64x2_t __a) { - return __builtin_aarch64_addpdi (__a); + return __builtin_aarch64_reduc_plus_scal_v2di (__a); } __extension__ extern __inline uint64_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vpaddd_u64 (uint64x2_t __a) { - return __builtin_aarch64_addpdi_uu (__a); + return __builtin_aarch64_reduc_plus_scal_v2di_uu (__a); } __extension__ extern __inline int64x2_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) @@ -19866,7 +17642,7 @@ vrsrad_n_u64 (uint64_t __a, uint64_t __b, const int __c) return __builtin_aarch64_ursra_ndi_uuus (__a, __b, __c); } #pragma GCC push_options -#pragma GCC target ("+nothing+crypto") +#pragma GCC target ("+nothing+sha2") __extension__ extern __inline uint32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vsha1cq_u32 (uint32x4_t __hash_abcd, uint32_t __hash_e, uint32x4_t __wk) @@ -19930,19 +17706,6 @@ vsha256su1q_u32 (uint32x4_t __tw0_3, uint32x4_t __w8_11, uint32x4_t __w12_15) return __builtin_aarch64_crypto_sha256su1v4si_uuuu (__tw0_3, __w8_11, __w12_15); } -__extension__ extern __inline poly128_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vmull_p64 (poly64_t __a, poly64_t __b) -{ - return - __builtin_aarch64_crypto_pmulldi_ppp (__a, __b); -} -__extension__ extern __inline poly128_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vmull_high_p64 (poly64x2_t __a, poly64x2_t __b) -{ - return __builtin_aarch64_crypto_pmullv2di_ppp (__a, __b); -} #pragma GCC pop_options __extension__ extern __inline int8x8_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) @@ -24007,7 +21770,7 @@ __INTERLEAVE_LIST (zip) #pragma GCC pop_options #include "third_party/aarch64/arm_fp16.internal.h" #pragma GCC push_options -#pragma GCC target ("arch=armv8.2-a+fp16") +#pragma GCC target ("+nothing+simd+fp16") __extension__ extern __inline float16x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vabs_f16 (float16x4_t __a) @@ -24994,7 +22757,7 @@ vminnmvq_f16 (float16x8_t __a) } #pragma GCC pop_options #pragma GCC push_options -#pragma GCC target ("arch=armv8.2-a+dotprod") +#pragma GCC target ("+nothing+dotprod") __extension__ extern __inline uint32x2_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vdot_u32 (uint32x2_t __r, uint8x8_t __a, uint8x8_t __b) @@ -25072,7 +22835,7 @@ vdotq_laneq_s32 (int32x4_t __r, int8x16_t __a, int8x16_t __b, const int __index) } #pragma GCC pop_options #pragma GCC push_options -#pragma GCC target ("arch=armv8.2-a+sm4") +#pragma GCC target ("+nothing+sm4") __extension__ extern __inline uint32x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vsm3ss1q_u32 (uint32x4_t __a, uint32x4_t __b, uint32x4_t __c) @@ -25129,7 +22892,7 @@ vsm4ekeyq_u32 (uint32x4_t __a, uint32x4_t __b) } #pragma GCC pop_options #pragma GCC push_options -#pragma GCC target ("arch=armv8.2-a+sha3") +#pragma GCC target ("+nothing+sha3") __extension__ extern __inline uint64x2_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vsha512hq_u64 (uint64x2_t __a, uint64x2_t __b, uint64x2_t __c) @@ -25674,7 +23437,7 @@ vcmlaq_rot270_laneq_f32 (float32x4_t __r, float32x4_t __a, float32x4_t __b, } #pragma GCC pop_options #pragma GCC push_options -#pragma GCC target ("arch=armv8.2-a+fp16fml") +#pragma GCC target ("+nothing+fp16fml") __extension__ extern __inline float32x2_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vfmlal_low_f16 (float32x2_t __r, float16x4_t __a, float16x4_t __b) @@ -25938,7 +23701,7 @@ vrnd64xq_f64 (float64x2_t __a) #pragma GCC pop_options #include "third_party/aarch64/arm_bf16.internal.h" #pragma GCC push_options -#pragma GCC target ("arch=armv8.2-a+bf16") +#pragma GCC target ("+nothing+bf16") __extension__ extern __inline bfloat16x4_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vset_lane_bf16 (bfloat16_t __elem, bfloat16x4_t __vec, const int __index) @@ -26264,354 +24027,6 @@ vst4q_bf16 (bfloat16_t * __a, bfloat16x8x4_t __val) { __builtin_aarch64_st4v8bf ((__builtin_aarch64_simd_bf *) __a, __val); } -__extension__ extern __inline bfloat16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_bf16_u8 (uint8x8_t __a) -{ - return (bfloat16x4_t)__a; -} -__extension__ extern __inline bfloat16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_bf16_u16 (uint16x4_t __a) -{ - return (bfloat16x4_t)__a; -} -__extension__ extern __inline bfloat16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_bf16_u32 (uint32x2_t __a) -{ - return (bfloat16x4_t)__a; -} -__extension__ extern __inline bfloat16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_bf16_u64 (uint64x1_t __a) -{ - return (bfloat16x4_t)__a; -} -__extension__ extern __inline bfloat16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_bf16_s8 (int8x8_t __a) -{ - return (bfloat16x4_t)__a; -} -__extension__ extern __inline bfloat16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_bf16_s16 (int16x4_t __a) -{ - return (bfloat16x4_t)__a; -} -__extension__ extern __inline bfloat16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_bf16_s32 (int32x2_t __a) -{ - return (bfloat16x4_t)__a; -} -__extension__ extern __inline bfloat16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_bf16_s64 (int64x1_t __a) -{ - return (bfloat16x4_t)__a; -} -__extension__ extern __inline bfloat16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_bf16_p8 (poly8x8_t __a) -{ - return (bfloat16x4_t)__a; -} -__extension__ extern __inline bfloat16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_bf16_p16 (poly16x4_t __a) -{ - return (bfloat16x4_t)__a; -} -__extension__ extern __inline bfloat16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_bf16_p64 (poly64x1_t __a) -{ - return (bfloat16x4_t)__a; -} -__extension__ extern __inline bfloat16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_bf16_f16 (float16x4_t __a) -{ - return (bfloat16x4_t)__a; -} -__extension__ extern __inline bfloat16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_bf16_f32 (float32x2_t __a) -{ - return (bfloat16x4_t)__a; -} -__extension__ extern __inline bfloat16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_bf16_f64 (float64x1_t __a) -{ - return (bfloat16x4_t)__a; -} -__extension__ extern __inline bfloat16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_bf16_u8 (uint8x16_t __a) -{ - return (bfloat16x8_t)__a; -} -__extension__ extern __inline bfloat16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_bf16_u16 (uint16x8_t __a) -{ - return (bfloat16x8_t)__a; -} -__extension__ extern __inline bfloat16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_bf16_u32 (uint32x4_t __a) -{ - return (bfloat16x8_t)__a; -} -__extension__ extern __inline bfloat16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_bf16_u64 (uint64x2_t __a) -{ - return (bfloat16x8_t)__a; -} -__extension__ extern __inline bfloat16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_bf16_s8 (int8x16_t __a) -{ - return (bfloat16x8_t)__a; -} -__extension__ extern __inline bfloat16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_bf16_s16 (int16x8_t __a) -{ - return (bfloat16x8_t)__a; -} -__extension__ extern __inline bfloat16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_bf16_s32 (int32x4_t __a) -{ - return (bfloat16x8_t)__a; -} -__extension__ extern __inline bfloat16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_bf16_s64 (int64x2_t __a) -{ - return (bfloat16x8_t)__a; -} -__extension__ extern __inline bfloat16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_bf16_p8 (poly8x16_t __a) -{ - return (bfloat16x8_t)__a; -} -__extension__ extern __inline bfloat16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_bf16_p16 (poly16x8_t __a) -{ - return (bfloat16x8_t)__a; -} -__extension__ extern __inline bfloat16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_bf16_p64 (poly64x2_t __a) -{ - return (bfloat16x8_t)__a; -} -__extension__ extern __inline bfloat16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_bf16_p128 (poly128_t __a) -{ - return (bfloat16x8_t)__a; -} -__extension__ extern __inline bfloat16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_bf16_f16 (float16x8_t __a) -{ - return (bfloat16x8_t)__a; -} -__extension__ extern __inline bfloat16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_bf16_f32 (float32x4_t __a) -{ - return (bfloat16x8_t)__a; -} -__extension__ extern __inline bfloat16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_bf16_f64 (float64x2_t __a) -{ - return (bfloat16x8_t)__a; -} -__extension__ extern __inline int8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s8_bf16 (bfloat16x4_t __a) -{ - return (int8x8_t)__a; -} -__extension__ extern __inline int16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s16_bf16 (bfloat16x4_t __a) -{ - return (int16x4_t)__a; -} -__extension__ extern __inline int32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s32_bf16 (bfloat16x4_t __a) -{ - return (int32x2_t)__a; -} -__extension__ extern __inline int64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_s64_bf16 (bfloat16x4_t __a) -{ - return (int64x1_t)__a; -} -__extension__ extern __inline uint8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u8_bf16 (bfloat16x4_t __a) -{ - return (uint8x8_t)__a; -} -__extension__ extern __inline uint16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u16_bf16 (bfloat16x4_t __a) -{ - return (uint16x4_t)__a; -} -__extension__ extern __inline uint32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u32_bf16 (bfloat16x4_t __a) -{ - return (uint32x2_t)__a; -} -__extension__ extern __inline uint64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_u64_bf16 (bfloat16x4_t __a) -{ - return (uint64x1_t)__a; -} -__extension__ extern __inline float16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f16_bf16 (bfloat16x4_t __a) -{ - return (float16x4_t)__a; -} -__extension__ extern __inline float32x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f32_bf16 (bfloat16x4_t __a) -{ - return (float32x2_t)__a; -} -__extension__ extern __inline float64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_f64_bf16 (bfloat16x4_t __a) -{ - return (float64x1_t)__a; -} -__extension__ extern __inline poly8x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p8_bf16 (bfloat16x4_t __a) -{ - return (poly8x8_t)__a; -} -__extension__ extern __inline poly16x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p16_bf16 (bfloat16x4_t __a) -{ - return (poly16x4_t)__a; -} -__extension__ extern __inline poly64x1_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpret_p64_bf16 (bfloat16x4_t __a) -{ - return (poly64x1_t)__a; -} -__extension__ extern __inline int8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s8_bf16 (bfloat16x8_t __a) -{ - return (int8x16_t)__a; -} -__extension__ extern __inline int16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s16_bf16 (bfloat16x8_t __a) -{ - return (int16x8_t)__a; -} -__extension__ extern __inline int32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s32_bf16 (bfloat16x8_t __a) -{ - return (int32x4_t)__a; -} -__extension__ extern __inline int64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_s64_bf16 (bfloat16x8_t __a) -{ - return (int64x2_t)__a; -} -__extension__ extern __inline uint8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u8_bf16 (bfloat16x8_t __a) -{ - return (uint8x16_t)__a; -} -__extension__ extern __inline uint16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u16_bf16 (bfloat16x8_t __a) -{ - return (uint16x8_t)__a; -} -__extension__ extern __inline uint32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u32_bf16 (bfloat16x8_t __a) -{ - return (uint32x4_t)__a; -} -__extension__ extern __inline uint64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_u64_bf16 (bfloat16x8_t __a) -{ - return (uint64x2_t)__a; -} -__extension__ extern __inline float16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f16_bf16 (bfloat16x8_t __a) -{ - return (float16x8_t)__a; -} -__extension__ extern __inline float32x4_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f32_bf16 (bfloat16x8_t __a) -{ - return (float32x4_t)__a; -} -__extension__ extern __inline float64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_f64_bf16 (bfloat16x8_t __a) -{ - return (float64x2_t)__a; -} -__extension__ extern __inline poly8x16_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p8_bf16 (bfloat16x8_t __a) -{ - return (poly8x16_t)__a; -} -__extension__ extern __inline poly16x8_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p16_bf16 (bfloat16x8_t __a) -{ - return (poly16x8_t)__a; -} -__extension__ extern __inline poly64x2_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p64_bf16 (bfloat16x8_t __a) -{ - return (poly64x2_t)__a; -} -__extension__ extern __inline poly128_t -__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) -vreinterpretq_p128_bf16 (bfloat16x8_t __a) -{ - return (poly128_t)__a; -} __extension__ extern __inline float32x2_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vbfdot_f32 (float32x2_t __r, bfloat16x4_t __a, bfloat16x4_t __b) @@ -26864,7 +24279,7 @@ vst4q_lane_bf16 (bfloat16_t *__ptr, bfloat16x8x4_t __val, const int __lane) } #pragma GCC pop_options #pragma GCC push_options -#pragma GCC target ("arch=armv8.2-a+i8mm") +#pragma GCC target ("+nothing+i8mm") __extension__ extern __inline int32x2_t __attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) vusdot_s32 (int32x2_t __r, uint8x8_t __a, int8x8_t __b) diff --git a/third_party/aarch64/openacc.internal.h b/third_party/aarch64/openacc.internal.h deleted file mode 100644 index f42e14bb6..000000000 --- a/third_party/aarch64/openacc.internal.h +++ /dev/null @@ -1,111 +0,0 @@ -#if defined(__aarch64__) && !(__ASSEMBLER__ + __LINKER__ + 0) -#ifndef _OPENACC_H -#define _OPENACC_H 1 -#ifdef __cplusplus -extern "C" { -#endif -#if __cplusplus >= 201103 -# define __GOACC_NOTHROW noexcept -#elif __cplusplus -# define __GOACC_NOTHROW throw () -#else -# define __GOACC_NOTHROW __attribute__ ((__nothrow__)) -#endif -typedef enum acc_device_t { - acc_device_current = -1, - acc_device_none = 0, - acc_device_default = 1, - acc_device_host = 2, - acc_device_not_host = 4, - acc_device_nvidia = 5, - acc_device_radeon = 8, - _ACC_device_hwm, - _ACC_highest = __INT_MAX__, - _ACC_neg = -1 -} acc_device_t; -typedef enum acc_device_property_t { - acc_property_memory = 1, - acc_property_free_memory = 2, - acc_property_name = 0x10001, - acc_property_vendor = 0x10002, - acc_property_driver = 0x10003 -} acc_device_property_t; -typedef enum acc_async_t { - acc_async_noval = -1, - acc_async_sync = -2 -} acc_async_t; -int acc_get_num_devices (acc_device_t) __GOACC_NOTHROW; -void acc_set_device_type (acc_device_t) __GOACC_NOTHROW; -acc_device_t acc_get_device_type (void) __GOACC_NOTHROW; -void acc_set_device_num (int, acc_device_t) __GOACC_NOTHROW; -int acc_get_device_num (acc_device_t) __GOACC_NOTHROW; -size_t acc_get_property - (int, acc_device_t, acc_device_property_t) __GOACC_NOTHROW; -const char *acc_get_property_string - (int, acc_device_t, acc_device_property_t) __GOACC_NOTHROW; -int acc_async_test (int) __GOACC_NOTHROW; -int acc_async_test_all (void) __GOACC_NOTHROW; -void acc_wait (int) __GOACC_NOTHROW; -void acc_async_wait (int) __GOACC_NOTHROW; -void acc_wait_async (int, int) __GOACC_NOTHROW; -void acc_wait_all (void) __GOACC_NOTHROW; -void acc_async_wait_all (void) __GOACC_NOTHROW; -void acc_wait_all_async (int) __GOACC_NOTHROW; -void acc_init (acc_device_t) __GOACC_NOTHROW; -void acc_shutdown (acc_device_t) __GOACC_NOTHROW; -#ifdef __cplusplus -int acc_on_device (int __arg) __GOACC_NOTHROW; -#else -int acc_on_device (acc_device_t __arg) __GOACC_NOTHROW; -#endif -void *acc_malloc (size_t) __GOACC_NOTHROW; -void acc_free (void *) __GOACC_NOTHROW; -void *acc_copyin (void *, size_t) __GOACC_NOTHROW; -void *acc_present_or_copyin (void *, size_t) __GOACC_NOTHROW; -void *acc_pcopyin (void *, size_t) __GOACC_NOTHROW; -void *acc_create (void *, size_t) __GOACC_NOTHROW; -void *acc_present_or_create (void *, size_t) __GOACC_NOTHROW; -void *acc_pcreate (void *, size_t) __GOACC_NOTHROW; -void acc_copyout (void *, size_t) __GOACC_NOTHROW; -void acc_delete (void *, size_t) __GOACC_NOTHROW; -void acc_update_device (void *, size_t) __GOACC_NOTHROW; -void acc_update_self (void *, size_t) __GOACC_NOTHROW; -void acc_map_data (void *, void *, size_t) __GOACC_NOTHROW; -void acc_unmap_data (void *) __GOACC_NOTHROW; -void *acc_deviceptr (void *) __GOACC_NOTHROW; -void *acc_hostptr (void *) __GOACC_NOTHROW; -int acc_is_present (void *, size_t) __GOACC_NOTHROW; -void acc_memcpy_to_device (void *, void *, size_t) __GOACC_NOTHROW; -void acc_memcpy_from_device (void *, void *, size_t) __GOACC_NOTHROW; -void acc_attach (void **) __GOACC_NOTHROW; -void acc_attach_async (void **, int) __GOACC_NOTHROW; -void acc_detach (void **) __GOACC_NOTHROW; -void acc_detach_async (void **, int) __GOACC_NOTHROW; -void acc_copyout_finalize (void *, size_t) __GOACC_NOTHROW; -void acc_copyout_finalize_async (void *, size_t, int) __GOACC_NOTHROW; -void acc_delete_finalize (void *, size_t) __GOACC_NOTHROW; -void acc_delete_finalize_async (void *, size_t, int) __GOACC_NOTHROW; -void acc_detach_finalize (void **) __GOACC_NOTHROW; -void acc_detach_finalize_async (void **, int) __GOACC_NOTHROW; -void acc_copyin_async (void *, size_t, int) __GOACC_NOTHROW; -void acc_create_async (void *, size_t, int) __GOACC_NOTHROW; -void acc_copyout_async (void *, size_t, int) __GOACC_NOTHROW; -void acc_delete_async (void *, size_t, int) __GOACC_NOTHROW; -void acc_update_device_async (void *, size_t, int) __GOACC_NOTHROW; -void acc_update_self_async (void *, size_t, int) __GOACC_NOTHROW; -void acc_memcpy_to_device_async (void *, void *, size_t, int) __GOACC_NOTHROW; -void acc_memcpy_from_device_async (void *, void *, size_t, int) __GOACC_NOTHROW; -void *acc_get_current_cuda_device (void) __GOACC_NOTHROW; -void *acc_get_current_cuda_context (void) __GOACC_NOTHROW; -void *acc_get_cuda_stream (int) __GOACC_NOTHROW; -int acc_set_cuda_stream (int, void *) __GOACC_NOTHROW; -#ifdef __cplusplus -} -#pragma acc routine seq -inline int acc_on_device (acc_device_t __arg) __GOACC_NOTHROW -{ - return acc_on_device ((int) __arg); -} -#endif -#endif -#endif diff --git a/third_party/aarch64/upgrade.sh b/third_party/aarch64/upgrade.sh index 1e4e6c5b7..083af0c1a 100755 --- a/third_party/aarch64/upgrade.sh +++ b/third_party/aarch64/upgrade.sh @@ -13,17 +13,15 @@ # 3. You should fix up the `#pragma GCC aarch64` things. # -s=/opt/goodies/include +s=/opt/include d=third_party/aarch64 FILES=' -acc_prof arm_acle arm_bf16 arm_fp16 arm_neon arm_sve -openacc ' strip_c_comments() { diff --git a/third_party/bash/BUILD.mk b/third_party/bash/BUILD.mk deleted file mode 100644 index 03c4cb94a..000000000 --- a/third_party/bash/BUILD.mk +++ /dev/null @@ -1,99 +0,0 @@ -#-*-mode:bashfile-gbash;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐ -#── vi: set noet ft=bash ts=8 sw=8 fenc=utf-8 :vi β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - -PKGS += THIRD_PARTY_BASH - -THIRD_PARTY_BASH_A = o/$(MODE)/third_party/bash/bash.a -THIRD_PARTY_BASH_FILES := $(wildcard third_party/bash/*) -THIRD_PARTY_BASH_HDRS = $(filter %.h,$(THIRD_PARTY_BASH_FILES)) -THIRD_PARTY_BASH_INCS = $(filter %.inc,$(THIRD_PARTY_BASH_FILES)) -THIRD_PARTY_BASH_SRCS = $(filter %.c,$(THIRD_PARTY_BASH_FILES)) -THIRD_PARTY_BASH_OBJS = $(THIRD_PARTY_BASH_SRCS:%.c=o/$(MODE)/%.o) -THIRD_PARTY_BASH_COMS = o/$(MODE)/third_party/bash/bash -THIRD_PARTY_BASH_CHECKS = $(THIRD_PARTY_BASH_A).pkg - -THIRD_PARTY_BASH_BINS = \ - $(THIRD_PARTY_BASH_COMS) \ - $(THIRD_PARTY_BASH_COMS:%=%.dbg) - -THIRD_PARTY_BASH_DIRECTDEPS = \ - LIBC_CALLS \ - LIBC_FMT \ - LIBC_INTRIN \ - LIBC_MEM \ - LIBC_NEXGEN32E \ - LIBC_PROC \ - LIBC_RUNTIME \ - LIBC_SOCK \ - LIBC_STDIO \ - LIBC_STR \ - LIBC_SYSV \ - LIBC_THREAD \ - THIRD_PARTY_COMPILER_RT \ - THIRD_PARTY_GDTOA \ - THIRD_PARTY_GETOPT \ - THIRD_PARTY_MUSL \ - THIRD_PARTY_NCURSES \ - THIRD_PARTY_READLINE \ - THIRD_PARTY_REGEX \ - THIRD_PARTY_TZ - -THIRD_PARTY_BASH_DEPS := \ - $(call uniq,$(foreach x,$(THIRD_PARTY_BASH_DIRECTDEPS),$($(x)))) - -$(THIRD_PARTY_BASH_A).pkg: \ - $(THIRD_PARTY_BASH_OBJS) \ - $(foreach x,$(THIRD_PARTY_BASH_DIRECTDEPS),$($(x)_A).pkg) - -$(THIRD_PARTY_BASH_A): \ - third_party/bash/ \ - $(THIRD_PARTY_BASH_A).pkg \ - $(filter-out %main.o,$(THIRD_PARTY_BASH_OBJS)) - -o/$(MODE)/third_party/bash/bash.dbg: \ - $(THIRD_PARTY_BASH_DEPS) \ - $(THIRD_PARTY_BASH_A) \ - $(THIRD_PARTY_BASH_A).pkg \ - o/$(MODE)/third_party/bash/shell.o \ - $(CRT) \ - $(APE_NO_MODIFY_SELF) - @$(APELINK) - -$(THIRD_PARTY_BASH_OBJS): private \ - CPPFLAGS += \ - -DHAVE_CONFIG_H \ - -DSHELL \ - -DPACKAGE=\"bash\" \ - -DLOCALEDIR=\"/zip/usr/share/locale\" \ - -DCONF_HOSTTYPE=\"unknown\" \ - -DCONF_OSTYPE=\"linux-cosmo\" \ - -DCONF_MACHTYPE=\"unknown-pc-unknown-cosmo\" \ - -DCONF_VENDOR=\"pc\" - -$(THIRD_PARTY_BASH_OBJS): private \ - CFLAGS += \ - -Wno-unused-but-set-variable \ - -Wno-discarded-qualifiers \ - -Wno-maybe-uninitialized \ - -Wno-pointer-to-int-cast \ - -Wno-stringop-truncation \ - -Wno-format-zero-length \ - -Wno-format-overflow \ - -Wno-char-subscripts \ - -Wno-nonnull-compare \ - -Wno-unused-variable \ - -Wno-missing-braces \ - -Wno-use-after-free \ - -Wno-unused-label \ - -Wno-unused-value \ - -Wno-return-type \ - -Wno-parentheses \ - -fportcosmo - -$(THIRD_PARTY_BASH_OBJS): third_party/bash/BUILD.mk - -.PHONY: o/$(MODE)/third_party/bash -o/$(MODE)/third_party/bash: \ - $(THIRD_PARTY_BASH_BINS) \ - $(THIRD_PARTY_BASH_CHECKS) - diff --git a/third_party/bash/LICENSE b/third_party/bash/LICENSE deleted file mode 100644 index 94a9ed024..000000000 --- a/third_party/bash/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/third_party/bash/README.cosmo b/third_party/bash/README.cosmo deleted file mode 100644 index f56894f1b..000000000 --- a/third_party/bash/README.cosmo +++ /dev/null @@ -1,16 +0,0 @@ -DESCRIPTION - - the bourne again shell - -LICENSE - - GPL v3 - -ORIGIN - - https://ftp.gnu.org/gnu/bash/bash-5.2.tar.gz - -LOCAL CHANGES - - - Force disable mkfifo() code - - Added runtime check for broken BSD /dev/fd stuff diff --git a/third_party/bash/alias.c b/third_party/bash/alias.c deleted file mode 100644 index 23f967fa8..000000000 --- a/third_party/bash/alias.c +++ /dev/null @@ -1,594 +0,0 @@ -/* alias.c -- Not a full alias, but just the kind that we use in the - shell. Csh style alias is somewhere else (`over there, in a box'). */ - -/* Copyright (C) 1987-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if defined (ALIAS) - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include -#include "chartypes.h" -#include "bashansi.h" -#include "command.h" -#include "general.h" -#include "externs.h" -#include "alias.h" - -#if defined (PROGRAMMABLE_COMPLETION) -# include "pcomplete.h" -#endif - -#if defined (HAVE_MBSTR_H) && defined (HAVE_MBSCHR) -# include /* mbschr */ -#endif - -#define ALIAS_HASH_BUCKETS 64 /* must be power of two */ - -typedef int sh_alias_map_func_t PARAMS((alias_t *)); - -static void free_alias_data PARAMS((PTR_T)); -static alias_t **map_over_aliases PARAMS((sh_alias_map_func_t *)); -static void sort_aliases PARAMS((alias_t **)); -static int qsort_alias_compare PARAMS((alias_t **, alias_t **)); - -#if defined (READLINE) -static int skipquotes PARAMS((char *, int)); -static int skipws PARAMS((char *, int)); -static int rd_token PARAMS((char *, int)); -#endif - -/* Non-zero means expand all words on the line. Otherwise, expand - after first expansion if the expansion ends in a space. */ -int alias_expand_all = 0; - -/* The list of aliases that we have. */ -HASH_TABLE *aliases = (HASH_TABLE *)NULL; - -void -initialize_aliases () -{ - if (aliases == 0) - aliases = hash_create (ALIAS_HASH_BUCKETS); -} - -/* Scan the list of aliases looking for one with NAME. Return NULL - if the alias doesn't exist, else a pointer to the alias_t. */ -alias_t * -find_alias (name) - char *name; -{ - BUCKET_CONTENTS *al; - - if (aliases == 0) - return ((alias_t *)NULL); - - al = hash_search (name, aliases, 0); - return (al ? (alias_t *)al->data : (alias_t *)NULL); -} - -/* Return the value of the alias for NAME, or NULL if there is none. */ -char * -get_alias_value (name) - char *name; -{ - alias_t *alias; - - if (aliases == 0) - return ((char *)NULL); - - alias = find_alias (name); - return (alias ? alias->value : (char *)NULL); -} - -/* Make a new alias from NAME and VALUE. If NAME can be found, - then replace its value. */ -void -add_alias (name, value) - char *name, *value; -{ - BUCKET_CONTENTS *elt; - alias_t *temp; - int n; - - if (aliases == 0) - { - initialize_aliases (); - temp = (alias_t *)NULL; - } - else - temp = find_alias (name); - - if (temp) - { - free (temp->value); - temp->value = savestring (value); - temp->flags &= ~AL_EXPANDNEXT; - if (value[0]) - { - n = value[strlen (value) - 1]; - if (n == ' ' || n == '\t') - temp->flags |= AL_EXPANDNEXT; - } - } - else - { - temp = (alias_t *)xmalloc (sizeof (alias_t)); - temp->name = savestring (name); - temp->value = savestring (value); - temp->flags = 0; - - if (value[0]) - { - n = value[strlen (value) - 1]; - if (n == ' ' || n == '\t') - temp->flags |= AL_EXPANDNEXT; - } - - elt = hash_insert (savestring (name), aliases, HASH_NOSRCH); - elt->data = temp; -#if defined (PROGRAMMABLE_COMPLETION) - set_itemlist_dirty (&it_aliases); -#endif - } -} - -/* Delete a single alias structure. */ -static void -free_alias_data (data) - PTR_T data; -{ - register alias_t *a; - - a = (alias_t *)data; - - if (a->flags & AL_BEINGEXPANDED) - clear_string_list_expander (a); /* call back to the parser */ - - free (a->value); - free (a->name); - free (data); -} - -/* Remove the alias with name NAME from the alias table. Returns - the number of aliases left in the table, or -1 if the alias didn't - exist. */ -int -remove_alias (name) - char *name; -{ - BUCKET_CONTENTS *elt; - - if (aliases == 0) - return (-1); - - elt = hash_remove (name, aliases, 0); - if (elt) - { - free_alias_data (elt->data); - free (elt->key); /* alias name */ - free (elt); /* XXX */ -#if defined (PROGRAMMABLE_COMPLETION) - set_itemlist_dirty (&it_aliases); -#endif - return (aliases->nentries); - } - return (-1); -} - -/* Delete all aliases. */ -void -delete_all_aliases () -{ - if (aliases == 0) - return; - - hash_flush (aliases, free_alias_data); - hash_dispose (aliases); - aliases = (HASH_TABLE *)NULL; -#if defined (PROGRAMMABLE_COMPLETION) - set_itemlist_dirty (&it_aliases); -#endif -} - -/* Return an array of aliases that satisfy the conditions tested by FUNCTION. - If FUNCTION is NULL, return all aliases. */ -static alias_t ** -map_over_aliases (function) - sh_alias_map_func_t *function; -{ - register int i; - register BUCKET_CONTENTS *tlist; - alias_t *alias, **list; - int list_index; - - i = HASH_ENTRIES (aliases); - if (i == 0) - return ((alias_t **)NULL); - - list = (alias_t **)xmalloc ((i + 1) * sizeof (alias_t *)); - for (i = list_index = 0; i < aliases->nbuckets; i++) - { - for (tlist = hash_items (i, aliases); tlist; tlist = tlist->next) - { - alias = (alias_t *)tlist->data; - - if (!function || (*function) (alias)) - { - list[list_index++] = alias; - list[list_index] = (alias_t *)NULL; - } - } - } - return (list); -} - -static void -sort_aliases (array) - alias_t **array; -{ - qsort (array, strvec_len ((char **)array), sizeof (alias_t *), (QSFUNC *)qsort_alias_compare); -} - -static int -qsort_alias_compare (as1, as2) - alias_t **as1, **as2; -{ - int result; - - if ((result = (*as1)->name[0] - (*as2)->name[0]) == 0) - result = strcmp ((*as1)->name, (*as2)->name); - - return (result); -} - -/* Return a sorted list of all defined aliases */ -alias_t ** -all_aliases () -{ - alias_t **list; - - if (aliases == 0 || HASH_ENTRIES (aliases) == 0) - return ((alias_t **)NULL); - - list = map_over_aliases ((sh_alias_map_func_t *)NULL); - if (list) - sort_aliases (list); - return (list); -} - -char * -alias_expand_word (s) - char *s; -{ - alias_t *r; - - r = find_alias (s); - return (r ? savestring (r->value) : (char *)NULL); -} - -/* Readline support functions -- expand all aliases in a line. */ - -#if defined (READLINE) - -/* Return non-zero if CHARACTER is a member of the class of characters - that are self-delimiting in the shell (this really means that these - characters delimit tokens). */ -#define self_delimiting(character) (member ((character), " \t\n\r;|&()")) - -/* Return non-zero if CHARACTER is a member of the class of characters - that delimit commands in the shell. */ -#define command_separator(character) (member ((character), "\r\n;|&(")) - -/* If this is 1, we are checking the next token read for alias expansion - because it is the first word in a command. */ -static int command_word; - -/* This is for skipping quoted strings in alias expansions. */ -#define quote_char(c) (((c) == '\'') || ((c) == '"')) - -/* Consume a quoted string from STRING, starting at string[START] (so - string[START] is the opening quote character), and return the index - of the closing quote character matching the opening quote character. - This handles single matching pairs of unquoted quotes; it could afford - to be a little smarter... This skips words between balanced pairs of - quotes, words where the first character is quoted with a `\', and other - backslash-escaped characters. */ - -static int -skipquotes (string, start) - char *string; - int start; -{ - register int i; - int delimiter = string[start]; - - /* i starts at START + 1 because string[START] is the opening quote - character. */ - for (i = start + 1 ; string[i] ; i++) - { - if (string[i] == '\\') - { - i++; /* skip backslash-quoted quote characters, too */ - if (string[i] == 0) - break; - continue; - } - - if (string[i] == delimiter) - return i; - } - return (i); -} - -/* Skip the white space and any quoted characters in STRING, starting at - START. Return the new index into STRING, after zero or more characters - have been skipped. */ -static int -skipws (string, start) - char *string; - int start; -{ - register int i; - int pass_next, backslash_quoted_word; - unsigned char peekc; - - /* skip quoted strings, in ' or ", and words in which a character is quoted - with a `\'. */ - i = backslash_quoted_word = pass_next = 0; - - /* Skip leading whitespace (or separator characters), and quoted words. - But save it in the output. */ - - for (i = start; string[i]; i++) - { - if (pass_next) - { - pass_next = 0; - continue; - } - - if (whitespace (string[i])) - { - backslash_quoted_word = 0; /* we are no longer in a backslash-quoted word */ - continue; - } - - if (string[i] == '\\') - { - peekc = string[i+1]; - if (peekc == 0) - break; - if (ISLETTER (peekc)) - backslash_quoted_word++; /* this is a backslash-quoted word */ - else - pass_next++; - continue; - } - - /* This only handles single pairs of non-escaped quotes. This - overloads backslash_quoted_word to also mean that a word like - ""f is being scanned, so that the quotes will inhibit any expansion - of the word. */ - if (quote_char(string[i])) - { - i = skipquotes (string, i); - /* This could be a line that contains a single quote character, - in which case skipquotes () terminates with string[i] == '\0' - (the end of the string). Check for that here. */ - if (string[i] == '\0') - break; - - peekc = string[i + 1]; - if (ISLETTER (peekc)) - backslash_quoted_word++; - continue; - } - - /* If we're in the middle of some kind of quoted word, let it - pass through. */ - if (backslash_quoted_word) - continue; - - /* If this character is a shell command separator, then set a hint for - alias_expand that the next token is the first word in a command. */ - - if (command_separator (string[i])) - { - command_word++; - continue; - } - break; - } - return (i); -} - -/* Characters that may appear in a token. Basically, anything except white - space and a token separator. */ -#define token_char(c) (!((whitespace (string[i]) || self_delimiting (string[i])))) - -/* Read from START in STRING until the next separator character, and return - the index of that separator. Skip backslash-quoted characters. Call - skipquotes () for quoted strings in the middle or at the end of tokens, - so all characters show up (e.g. foo'' and foo""bar) */ -static int -rd_token (string, start) - char *string; - int start; -{ - register int i; - - /* From here to next separator character is a token. */ - for (i = start; string[i] && token_char (string[i]); i++) - { - if (string[i] == '\\') - { - i++; /* skip backslash-escaped character */ - if (string[i] == 0) - break; - continue; - } - - /* If this character is a quote character, we want to call skipquotes - to get the whole quoted portion as part of this word. That word - will not generally match an alias, even if te unquoted word would - have. The presence of the quotes in the token serves then to - inhibit expansion. */ - if (quote_char (string[i])) - { - i = skipquotes (string, i); - /* This could be a line that contains a single quote character, - in which case skipquotes () terminates with string[i] == '\0' - (the end of the string). Check for that here. */ - if (string[i] == '\0') - break; - - /* Now string[i] is the matching quote character, and the - quoted portion of the token has been scanned. */ - continue; - } - } - return (i); -} - -/* Return a new line, with any aliases substituted. */ -char * -alias_expand (string) - char *string; -{ - register int i, j, start; - char *line, *token; - int line_len, tl, real_start, expand_next, expand_this_token; - alias_t *alias; - - line_len = strlen (string) + 1; - line = (char *)xmalloc (line_len); - token = (char *)xmalloc (line_len); - - line[0] = i = 0; - expand_next = 0; - command_word = 1; /* initialized to expand the first word on the line */ - - /* Each time through the loop we find the next word in line. If it - has an alias, substitute the alias value. If the value ends in ` ', - then try again with the next word. Else, if there is no value, or if - the value does not end in space, we are done. */ - - for (;;) - { - - token[0] = 0; - start = i; - - /* Skip white space and quoted characters */ - i = skipws (string, start); - - if (start == i && string[i] == '\0') - { - free (token); - return (line); - } - - /* copy the just-skipped characters into the output string, - expanding it if there is not enough room. */ - j = strlen (line); - tl = i - start; /* number of characters just skipped */ - RESIZE_MALLOCED_BUFFER (line, j, (tl + 1), line_len, (tl + 50)); - strncpy (line + j, string + start, tl); - line[j + tl] = '\0'; - - real_start = i; - - command_word = command_word || (command_separator (string[i])); - expand_this_token = (command_word || expand_next); - expand_next = 0; - - /* Read the next token, and copy it into TOKEN. */ - start = i; - i = rd_token (string, start); - - tl = i - start; /* token length */ - - /* If tl == 0, but we're not at the end of the string, then we have a - single-character token, probably a delimiter */ - if (tl == 0 && string[i] != '\0') - { - tl = 1; - i++; /* move past it */ - } - - strncpy (token, string + start, tl); - token [tl] = '\0'; - - /* If there is a backslash-escaped character quoted in TOKEN, - then we don't do alias expansion. This should check for all - other quoting characters, too. */ - if (mbschr (token, '\\')) - expand_this_token = 0; - - /* If we should be expanding here, if we are expanding all words, or if - we are in a location in the string where an expansion is supposed to - take place, see if this word has a substitution. If it does, then do - the expansion. Note that we defer the alias value lookup until we - are sure we are expanding this token. */ - - if ((token[0]) && - (expand_this_token || alias_expand_all) && - (alias = find_alias (token))) - { - char *v; - int vlen, llen; - - v = alias->value; - vlen = strlen (v); - llen = strlen (line); - - /* +3 because we possibly add one more character below. */ - RESIZE_MALLOCED_BUFFER (line, llen, (vlen + 3), line_len, (vlen + 50)); - - strcpy (line + llen, v); - - if ((expand_this_token && vlen && whitespace (v[vlen - 1])) || - alias_expand_all) - expand_next = 1; - } - else - { - int llen, tlen; - - llen = strlen (line); - tlen = i - real_start; /* tlen == strlen(token) */ - - RESIZE_MALLOCED_BUFFER (line, llen, (tlen + 1), line_len, (llen + tlen + 50)); - - strncpy (line + llen, string + real_start, tlen); - line[llen + tlen] = '\0'; - } - command_word = 0; - } -} -#endif /* READLINE */ -#endif /* ALIAS */ diff --git a/third_party/bash/alias.h b/third_party/bash/alias.h deleted file mode 100644 index 4e2d67c0f..000000000 --- a/third_party/bash/alias.h +++ /dev/null @@ -1,73 +0,0 @@ -/* alias.h -- structure definitions. */ - -/* Copyright (C) 1987-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_ALIAS_H_) -#define _ALIAS_H_ - -#include "stdc.h" - -#include "hashlib.h" - -typedef struct alias { - char *name; - char *value; - char flags; -} alias_t; - -/* Values for `flags' member of struct alias. */ -#define AL_EXPANDNEXT 0x1 -#define AL_BEINGEXPANDED 0x2 - -/* The list of known aliases. */ -extern HASH_TABLE *aliases; - -extern void initialize_aliases PARAMS((void)); - -/* Scan the list of aliases looking for one with NAME. Return NULL - if the alias doesn't exist, else a pointer to the alias. */ -extern alias_t *find_alias PARAMS((char *)); - -/* Return the value of the alias for NAME, or NULL if there is none. */ -extern char *get_alias_value PARAMS((char *)); - -/* Make a new alias from NAME and VALUE. If NAME can be found, - then replace its value. */ -extern void add_alias PARAMS((char *, char *)); - -/* Remove the alias with name NAME from the alias list. Returns - the index of the removed alias, or -1 if the alias didn't exist. */ -extern int remove_alias PARAMS((char *)); - -/* Remove all aliases. */ -extern void delete_all_aliases PARAMS((void)); - -/* Return an array of all defined aliases. */ -extern alias_t **all_aliases PARAMS((void)); - -/* Expand a single word for aliases. */ -extern char *alias_expand_word PARAMS((char *)); - -/* Return a new line, with any aliases expanded. */ -extern char *alias_expand PARAMS((char *)); - -/* Helper definition for the parser */ -extern void clear_string_list_expander PARAMS((alias_t *)); - -#endif /* _ALIAS_H_ */ diff --git a/third_party/bash/ansi_stdlib.h b/third_party/bash/ansi_stdlib.h deleted file mode 100644 index 7dc2ee0cf..000000000 --- a/third_party/bash/ansi_stdlib.h +++ /dev/null @@ -1,54 +0,0 @@ -/* ansi_stdlib.h -- An ANSI Standard stdlib.h. */ -/* A minimal stdlib.h containing extern declarations for those functions - that bash uses. */ - -/* Copyright (C) 1993 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_STDLIB_H_) -#define _STDLIB_H_ 1 - -/* String conversion functions. */ -extern int atoi (); - -extern double atof (); -extern double strtod (); - -/* Memory allocation functions. */ -/* Generic pointer type. */ -#ifndef PTR_T - -#if defined (__STDC__) -# define PTR_T void * -#else -# define PTR_T char * -#endif - -#endif /* PTR_T */ - -extern PTR_T malloc (); -extern PTR_T realloc (); -extern void free (); - -/* Other miscellaneous functions. */ -extern void abort (); -extern void exit (); -extern char *getenv (); -extern void qsort (); - -#endif /* _STDLIB_H */ diff --git a/third_party/bash/array.c b/third_party/bash/array.c deleted file mode 100644 index 39a0ef51b..000000000 --- a/third_party/bash/array.c +++ /dev/null @@ -1,1303 +0,0 @@ -/* - * array.c - functions to create, destroy, access, and manipulate arrays - * of strings. - * - * Arrays are sparse doubly-linked lists. An element's index is stored - * with it. - * - * Chet Ramey - * chet@ins.cwru.edu - */ - -/* Copyright (C) 1997-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if defined (ARRAY_VARS) - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include -#include "bashansi.h" - -#include "shell.h" -#include "array.h" -#include "common.h" - -#define ADD_BEFORE(ae, new) \ - do { \ - ae->prev->next = new; \ - new->prev = ae->prev; \ - ae->prev = new; \ - new->next = ae; \ - } while(0) - -#define ADD_AFTER(ae, new) \ - do { \ - ae->next->prev = new; \ - new->next = ae->next; \ - new->prev = ae; \ - ae->next = new; \ - } while (0) - -static char *array_to_string_internal PARAMS((ARRAY_ELEMENT *, ARRAY_ELEMENT *, char *, int)); - -static char *spacesep = " "; - -#define IS_LASTREF(a) (a->lastref) - -#define LASTREF_START(a, i) \ - (IS_LASTREF(a) && i >= element_index(a->lastref)) ? a->lastref \ - : element_forw(a->head) - -#define LASTREF(a) (a->lastref ? a->lastref : element_forw(a->head)) - -#define INVALIDATE_LASTREF(a) a->lastref = 0 -#define SET_LASTREF(a, e) a->lastref = (e) -#define UNSET_LASTREF(a) a->lastref = 0; - -ARRAY * -array_create() -{ - ARRAY *r; - ARRAY_ELEMENT *head; - - r = (ARRAY *)xmalloc(sizeof(ARRAY)); - r->max_index = -1; - r->num_elements = 0; - r->lastref = (ARRAY_ELEMENT *)0; - head = array_create_element(-1, (char *)NULL); /* dummy head */ - head->prev = head->next = head; - r->head = head; - return(r); -} - -void -array_flush (a) -ARRAY *a; -{ - register ARRAY_ELEMENT *r, *r1; - - if (a == 0) - return; - for (r = element_forw(a->head); r != a->head; ) { - r1 = element_forw(r); - array_dispose_element(r); - r = r1; - } - a->head->next = a->head->prev = a->head; - a->max_index = -1; - a->num_elements = 0; - INVALIDATE_LASTREF(a); -} - -void -array_dispose(a) -ARRAY *a; -{ - if (a == 0) - return; - array_flush (a); - array_dispose_element(a->head); - free(a); -} - -ARRAY * -array_copy(a) -ARRAY *a; -{ - ARRAY *a1; - ARRAY_ELEMENT *ae, *new; - - if (a == 0) - return((ARRAY *) NULL); - a1 = array_create(); - a1->max_index = a->max_index; - a1->num_elements = a->num_elements; - for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae)) { - new = array_create_element(element_index(ae), element_value(ae)); - ADD_BEFORE(a1->head, new); - if (ae == LASTREF(a)) - SET_LASTREF(a1, new); - } - return(a1); -} - -/* - * Make and return a new array composed of the elements in array A from - * S to E, inclusive. - */ -ARRAY * -array_slice(array, s, e) -ARRAY *array; -ARRAY_ELEMENT *s, *e; -{ - ARRAY *a; - ARRAY_ELEMENT *p, *n; - int i; - arrayind_t mi; - - a = array_create (); - - for (mi = 0, p = s, i = 0; p != e; p = element_forw(p), i++) { - n = array_create_element (element_index(p), element_value(p)); - ADD_BEFORE(a->head, n); - mi = element_index(n); - } - a->num_elements = i; - a->max_index = mi; - return a; -} - -/* - * Walk the array, calling FUNC once for each element, with the array - * element as the argument. - */ -void -array_walk(a, func, udata) -ARRAY *a; -sh_ae_map_func_t *func; -void *udata; -{ - register ARRAY_ELEMENT *ae; - - if (a == 0 || array_empty(a)) - return; - for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae)) - if ((*func)(ae, udata) < 0) - return; -} - -/* - * Shift the array A N elements to the left. Delete the first N elements - * and subtract N from the indices of the remaining elements. If FLAGS - * does not include AS_DISPOSE, this returns a singly-linked null-terminated - * list of elements so the caller can dispose of the chain. If FLAGS - * includes AS_DISPOSE, this function disposes of the shifted-out elements - * and returns NULL. - */ -ARRAY_ELEMENT * -array_shift(a, n, flags) -ARRAY *a; -int n, flags; -{ - register ARRAY_ELEMENT *ae, *ret; - register int i; - - if (a == 0 || array_empty(a) || n <= 0) - return ((ARRAY_ELEMENT *)NULL); - - INVALIDATE_LASTREF(a); - for (i = 0, ret = ae = element_forw(a->head); ae != a->head && i < n; ae = element_forw(ae), i++) - ; - if (ae == a->head) { - /* Easy case; shifting out all of the elements */ - if (flags & AS_DISPOSE) { - array_flush (a); - return ((ARRAY_ELEMENT *)NULL); - } - for (ae = ret; element_forw(ae) != a->head; ae = element_forw(ae)) - ; - element_forw(ae) = (ARRAY_ELEMENT *)NULL; - a->head->next = a->head->prev = a->head; - a->max_index = -1; - a->num_elements = 0; - return ret; - } - /* - * ae now points to the list of elements we want to retain. - * ret points to the list we want to either destroy or return. - */ - ae->prev->next = (ARRAY_ELEMENT *)NULL; /* null-terminate RET */ - - a->head->next = ae; /* slice RET out of the array */ - ae->prev = a->head; - - for ( ; ae != a->head; ae = element_forw(ae)) - element_index(ae) -= n; /* renumber retained indices */ - - a->num_elements -= n; /* modify bookkeeping information */ - a->max_index = element_index(a->head->prev); - - if (flags & AS_DISPOSE) { - for (ae = ret; ae; ) { - ret = element_forw(ae); - array_dispose_element(ae); - ae = ret; - } - return ((ARRAY_ELEMENT *)NULL); - } - - return ret; -} - -/* - * Shift array A right N indices. If S is non-null, it becomes the value of - * the new element 0. Returns the number of elements in the array after the - * shift. - */ -int -array_rshift (a, n, s) -ARRAY *a; -int n; -char *s; -{ - register ARRAY_ELEMENT *ae, *new; - - if (a == 0 || (array_empty(a) && s == 0)) - return 0; - else if (n <= 0) - return (a->num_elements); - - ae = element_forw(a->head); - if (s) { - new = array_create_element(0, s); - ADD_BEFORE(ae, new); - a->num_elements++; - if (array_num_elements(a) == 1) { /* array was empty */ - a->max_index = 0; - return 1; - } - } - - /* - * Renumber all elements in the array except the one we just added. - */ - for ( ; ae != a->head; ae = element_forw(ae)) - element_index(ae) += n; - - a->max_index = element_index(a->head->prev); - - INVALIDATE_LASTREF(a); - return (a->num_elements); -} - -ARRAY_ELEMENT * -array_unshift_element(a) -ARRAY *a; -{ - return (array_shift (a, 1, 0)); -} - -int -array_shift_element(a, v) -ARRAY *a; -char *v; -{ - return (array_rshift (a, 1, v)); -} - -ARRAY * -array_quote(array) -ARRAY *array; -{ - ARRAY_ELEMENT *a; - char *t; - - if (array == 0 || array_head(array) == 0 || array_empty(array)) - return (ARRAY *)NULL; - for (a = element_forw(array->head); a != array->head; a = element_forw(a)) { - t = quote_string (a->value); - FREE(a->value); - a->value = t; - } - return array; -} - -ARRAY * -array_quote_escapes(array) -ARRAY *array; -{ - ARRAY_ELEMENT *a; - char *t; - - if (array == 0 || array_head(array) == 0 || array_empty(array)) - return (ARRAY *)NULL; - for (a = element_forw(array->head); a != array->head; a = element_forw(a)) { - t = quote_escapes (a->value); - FREE(a->value); - a->value = t; - } - return array; -} - -ARRAY * -array_dequote(array) -ARRAY *array; -{ - ARRAY_ELEMENT *a; - char *t; - - if (array == 0 || array_head(array) == 0 || array_empty(array)) - return (ARRAY *)NULL; - for (a = element_forw(array->head); a != array->head; a = element_forw(a)) { - t = dequote_string (a->value); - FREE(a->value); - a->value = t; - } - return array; -} - -ARRAY * -array_dequote_escapes(array) -ARRAY *array; -{ - ARRAY_ELEMENT *a; - char *t; - - if (array == 0 || array_head(array) == 0 || array_empty(array)) - return (ARRAY *)NULL; - for (a = element_forw(array->head); a != array->head; a = element_forw(a)) { - t = dequote_escapes (a->value); - FREE(a->value); - a->value = t; - } - return array; -} - -ARRAY * -array_remove_quoted_nulls(array) -ARRAY *array; -{ - ARRAY_ELEMENT *a; - - if (array == 0 || array_head(array) == 0 || array_empty(array)) - return (ARRAY *)NULL; - for (a = element_forw(array->head); a != array->head; a = element_forw(a)) - a->value = remove_quoted_nulls (a->value); - return array; -} - -/* - * Return a string whose elements are the members of array A beginning at - * index START and spanning NELEM members. Null elements are counted. - * Since arrays are sparse, unset array elements are not counted. - */ -char * -array_subrange (a, start, nelem, starsub, quoted, pflags) -ARRAY *a; -arrayind_t start, nelem; -int starsub, quoted, pflags; -{ - ARRAY *a2; - ARRAY_ELEMENT *h, *p; - arrayind_t i; - char *t; - WORD_LIST *wl; - - p = a ? array_head (a) : 0; - if (p == 0 || array_empty (a) || start > array_max_index(a)) - return ((char *)NULL); - - /* - * Find element with index START. If START corresponds to an unset - * element (arrays can be sparse), use the first element whose index - * is >= START. If START is < 0, we count START indices back from - * the end of A (not elements, even with sparse arrays -- START is an - * index). - */ - for (p = element_forw(p); p != array_head(a) && start > element_index(p); p = element_forw(p)) - ; - - if (p == a->head) - return ((char *)NULL); - - /* Starting at P, take NELEM elements, inclusive. */ - for (i = 0, h = p; p != a->head && i < nelem; i++, p = element_forw(p)) - ; - - a2 = array_slice(a, h, p); - - wl = array_to_word_list(a2); - array_dispose(a2); - if (wl == 0) - return (char *)NULL; - t = string_list_pos_params(starsub ? '*' : '@', wl, quoted, pflags); /* XXX */ - dispose_words(wl); - - return t; -} - -char * -array_patsub (a, pat, rep, mflags) -ARRAY *a; -char *pat, *rep; -int mflags; -{ - char *t; - int pchar, qflags, pflags; - WORD_LIST *wl, *save; - - if (a == 0 || array_head(a) == 0 || array_empty(a)) - return ((char *)NULL); - - wl = array_to_word_list(a); - if (wl == 0) - return (char *)NULL; - - for (save = wl; wl; wl = wl->next) { - t = pat_subst (wl->word->word, pat, rep, mflags); - FREE (wl->word->word); - wl->word->word = t; - } - - pchar = (mflags & MATCH_STARSUB) == MATCH_STARSUB ? '*' : '@'; - qflags = (mflags & MATCH_QUOTED) == MATCH_QUOTED ? Q_DOUBLE_QUOTES : 0; - pflags = (mflags & MATCH_ASSIGNRHS) ? PF_ASSIGNRHS : 0; - - t = string_list_pos_params (pchar, save, qflags, pflags); - dispose_words(save); - - return t; -} - -char * -array_modcase (a, pat, modop, mflags) -ARRAY *a; -char *pat; -int modop; -int mflags; -{ - char *t; - int pchar, qflags, pflags; - WORD_LIST *wl, *save; - - if (a == 0 || array_head(a) == 0 || array_empty(a)) - return ((char *)NULL); - - wl = array_to_word_list(a); - if (wl == 0) - return ((char *)NULL); - - for (save = wl; wl; wl = wl->next) { - t = sh_modcase(wl->word->word, pat, modop); - FREE(wl->word->word); - wl->word->word = t; - } - - pchar = (mflags & MATCH_STARSUB) == MATCH_STARSUB ? '*' : '@'; - qflags = (mflags & MATCH_QUOTED) == MATCH_QUOTED ? Q_DOUBLE_QUOTES : 0; - pflags = (mflags & MATCH_ASSIGNRHS) ? PF_ASSIGNRHS : 0; - - t = string_list_pos_params (pchar, save, qflags, pflags); - dispose_words(save); - - return t; -} - -/* - * Allocate and return a new array element with index INDEX and value - * VALUE. - */ -ARRAY_ELEMENT * -array_create_element(indx, value) -arrayind_t indx; -char *value; -{ - ARRAY_ELEMENT *r; - - r = (ARRAY_ELEMENT *)xmalloc(sizeof(ARRAY_ELEMENT)); - r->ind = indx; - r->value = value ? savestring(value) : (char *)NULL; - r->next = r->prev = (ARRAY_ELEMENT *) NULL; - return(r); -} - -#ifdef INCLUDE_UNUSED -ARRAY_ELEMENT * -array_copy_element(ae) -ARRAY_ELEMENT *ae; -{ - return(ae ? array_create_element(element_index(ae), element_value(ae)) - : (ARRAY_ELEMENT *) NULL); -} -#endif - -void -array_dispose_element(ae) -ARRAY_ELEMENT *ae; -{ - if (ae) { - FREE(ae->value); - free(ae); - } -} - -/* - * Add a new element with index I and value V to array A (a[i] = v). - */ -int -array_insert(a, i, v) -ARRAY *a; -arrayind_t i; -char *v; -{ - register ARRAY_ELEMENT *new, *ae, *start; - arrayind_t startind; - int direction; - - if (a == 0) - return(-1); - new = array_create_element(i, v); - if (i > array_max_index(a)) { - /* - * Hook onto the end. This also works for an empty array. - * Fast path for the common case of allocating arrays - * sequentially. - */ - ADD_BEFORE(a->head, new); - a->max_index = i; - a->num_elements++; - SET_LASTREF(a, new); - return(0); - } else if (i < array_first_index(a)) { - /* Hook at the beginning */ - ADD_AFTER(a->head, new); - a->num_elements++; - SET_LASTREF(a, new); - return(0); - } -#if OPTIMIZE_SEQUENTIAL_ARRAY_ASSIGNMENT - /* - * Otherwise we search for the spot to insert it. The lastref - * handle optimizes the case of sequential or almost-sequential - * assignments that are not at the end of the array. - */ - start = LASTREF(a); - /* Use same strategy as array_reference to avoid paying large penalty - for semi-random assignment pattern. */ - startind = element_index(start); - if (i < startind/2) { - start = element_forw(a->head); - startind = element_index(start); - direction = 1; - } else if (i >= startind) { - direction = 1; - } else { - direction = -1; - } -#else - start = element_forw(ae->head); - startind = element_index(start); - direction = 1; -#endif - for (ae = start; ae != a->head; ) { - if (element_index(ae) == i) { - /* - * Replacing an existing element. - */ - free(element_value(ae)); - /* Just swap in the new value */ - ae->value = new->value; - new->value = 0; - array_dispose_element(new); - SET_LASTREF(a, ae); - return(0); - } else if (direction == 1 && element_index(ae) > i) { - ADD_BEFORE(ae, new); - a->num_elements++; - SET_LASTREF(a, new); - return(0); - } else if (direction == -1 && element_index(ae) < i) { - ADD_AFTER(ae, new); - a->num_elements++; - SET_LASTREF(a, new); - return(0); - } - ae = direction == 1 ? element_forw(ae) : element_back(ae); - } - array_dispose_element(new); - INVALIDATE_LASTREF(a); - return (-1); /* problem */ -} - -/* - * Delete the element with index I from array A and return it so the - * caller can dispose of it. - */ -ARRAY_ELEMENT * -array_remove(a, i) -ARRAY *a; -arrayind_t i; -{ - register ARRAY_ELEMENT *ae, *start; - arrayind_t startind; - int direction; - - if (a == 0 || array_empty(a)) - return((ARRAY_ELEMENT *) NULL); - if (i > array_max_index(a) || i < array_first_index(a)) - return((ARRAY_ELEMENT *)NULL); /* Keep roving pointer into array to optimize sequential access */ - start = LASTREF(a); - /* Use same strategy as array_reference to avoid paying large penalty - for semi-random assignment pattern. */ - startind = element_index(start); - if (i < startind/2) { - start = element_forw(a->head); - startind = element_index(start); - direction = 1; - } else if (i >= startind) { - direction = 1; - } else { - direction = -1; - } - for (ae = start; ae != a->head; ) { - if (element_index(ae) == i) { - ae->next->prev = ae->prev; - ae->prev->next = ae->next; - a->num_elements--; - if (i == array_max_index(a)) - a->max_index = element_index(ae->prev); -#if 0 - INVALIDATE_LASTREF(a); -#else - if (ae->next != a->head) - SET_LASTREF(a, ae->next); - else if (ae->prev != a->head) - SET_LASTREF(a, ae->prev); - else - INVALIDATE_LASTREF(a); -#endif - return(ae); - } - ae = (direction == 1) ? element_forw(ae) : element_back(ae); - if (direction == 1 && element_index(ae) > i) - break; - else if (direction == -1 && element_index(ae) < i) - break; - } - return((ARRAY_ELEMENT *) NULL); -} - -/* - * Return the value of a[i]. - */ -char * -array_reference(a, i) -ARRAY *a; -arrayind_t i; -{ - register ARRAY_ELEMENT *ae, *start; - arrayind_t startind; - int direction; - - if (a == 0 || array_empty(a)) - return((char *) NULL); - if (i > array_max_index(a) || i < array_first_index(a)) - return((char *)NULL); /* Keep roving pointer into array to optimize sequential access */ - start = LASTREF(a); /* lastref pointer */ - startind = element_index(start); - if (i < startind/2) { /* XXX - guess */ - start = element_forw(a->head); - startind = element_index(start); - direction = 1; - } else if (i >= startind) { - direction = 1; - } else { - direction = -1; - } - for (ae = start; ae != a->head; ) { - if (element_index(ae) == i) { - SET_LASTREF(a, ae); - return(element_value(ae)); - } - ae = (direction == 1) ? element_forw(ae) : element_back(ae); - /* Take advantage of index ordering to short-circuit */ - /* If we don't find it, set the lastref pointer to the element - that's `closest', assuming that the unsuccessful reference - will quickly be followed by an assignment. No worse than - not changing it from the previous value or resetting it. */ - if (direction == 1 && element_index(ae) > i) { - start = ae; /* use for SET_LASTREF below */ - break; - } else if (direction == -1 && element_index(ae) < i) { - start = ae; /* use for SET_LASTREF below */ - break; - } - } -#if 0 - UNSET_LASTREF(a); -#else - SET_LASTREF(a, start); -#endif - return((char *) NULL); -} - -/* Convenience routines for the shell to translate to and from the form used - by the rest of the code. */ - -WORD_LIST * -array_to_word_list(a) -ARRAY *a; -{ - WORD_LIST *list; - ARRAY_ELEMENT *ae; - - if (a == 0 || array_empty(a)) - return((WORD_LIST *)NULL); - list = (WORD_LIST *)NULL; - for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae)) - list = make_word_list (make_bare_word(element_value(ae)), list); - return (REVERSE_LIST(list, WORD_LIST *)); -} - -ARRAY * -array_from_word_list (list) -WORD_LIST *list; -{ - ARRAY *a; - - if (list == 0) - return((ARRAY *)NULL); - a = array_create(); - return (array_assign_list (a, list)); -} - -WORD_LIST * -array_keys_to_word_list(a) -ARRAY *a; -{ - WORD_LIST *list; - ARRAY_ELEMENT *ae; - char *t; - - if (a == 0 || array_empty(a)) - return((WORD_LIST *)NULL); - list = (WORD_LIST *)NULL; - for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae)) { - t = itos(element_index(ae)); - list = make_word_list (make_bare_word(t), list); - free(t); - } - return (REVERSE_LIST(list, WORD_LIST *)); -} - -WORD_LIST * -array_to_kvpair_list(a) -ARRAY *a; -{ - WORD_LIST *list; - ARRAY_ELEMENT *ae; - char *k, *v; - - if (a == 0 || array_empty(a)) - return((WORD_LIST *)NULL); - list = (WORD_LIST *)NULL; - for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae)) { - k = itos(element_index(ae)); - v = element_value(ae); - list = make_word_list (make_bare_word(k), list); - list = make_word_list (make_bare_word(v), list); - free(k); - } - return (REVERSE_LIST(list, WORD_LIST *)); -} - -ARRAY * -array_assign_list (array, list) -ARRAY *array; -WORD_LIST *list; -{ - register WORD_LIST *l; - register arrayind_t i; - - for (l = list, i = 0; l; l = l->next, i++) - array_insert(array, i, l->word->word); - return array; -} - -char ** -array_to_argv (a, countp) -ARRAY *a; -int *countp; -{ - char **ret, *t; - int i; - ARRAY_ELEMENT *ae; - - if (a == 0 || array_empty(a)) { - if (countp) - *countp = 0; - return ((char **)NULL); - } - ret = strvec_create (array_num_elements (a) + 1); - i = 0; - for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae)) { - t = element_value (ae); - if (t) - ret[i++] = savestring (t); - } - ret[i] = (char *)NULL; - if (countp) - *countp = i; - return (ret); -} - -ARRAY * -array_from_argv(a, vec, count) -ARRAY *a; -char **vec; -int count; -{ - arrayind_t i; - ARRAY_ELEMENT *ae; - char *t; - - if (a == 0 || array_num_elements (a) == 0) - { - for (i = 0; i < count; i++) - array_insert (a, i, t); - return a; - } - - /* Fast case */ - if (array_num_elements (a) == count && count == 1) - { - ae = element_forw (a->head); - t = vec[0] ? savestring (vec[0]) : 0; - ARRAY_ELEMENT_REPLACE (ae, t); - } - else if (array_num_elements (a) <= count) - { - /* modify in array_num_elements members in place, then add */ - ae = a->head; - for (i = 0; i < array_num_elements (a); i++) - { - ae = element_forw (ae); - t = vec[0] ? savestring (vec[0]) : 0; - ARRAY_ELEMENT_REPLACE (ae, t); - } - /* add any more */ - for ( ; i < count; i++) - array_insert (a, i, vec[i]); - } - else - { - /* deleting elements. it's faster to rebuild the array. */ - array_flush (a); - for (i = 0; i < count; i++) - array_insert (a, i, vec[i]); - } - - return a; -} - -/* - * Return a string that is the concatenation of the elements in A from START - * to END, separated by SEP. - */ -static char * -array_to_string_internal (start, end, sep, quoted) -ARRAY_ELEMENT *start, *end; -char *sep; -int quoted; -{ - char *result, *t; - ARRAY_ELEMENT *ae; - int slen, rsize, rlen, reg; - - if (start == end) /* XXX - should not happen */ - return ((char *)NULL); - - slen = strlen(sep); - result = NULL; - for (rsize = rlen = 0, ae = start; ae != end; ae = element_forw(ae)) { - if (rsize == 0) - result = (char *)xmalloc (rsize = 64); - if (element_value(ae)) { - t = quoted ? quote_string(element_value(ae)) : element_value(ae); - reg = strlen(t); - RESIZE_MALLOCED_BUFFER (result, rlen, (reg + slen + 2), - rsize, rsize); - strcpy(result + rlen, t); - rlen += reg; - if (quoted) - free(t); - /* - * Add a separator only after non-null elements. - */ - if (element_forw(ae) != end) { - strcpy(result + rlen, sep); - rlen += slen; - } - } - } - if (result) - result[rlen] = '\0'; /* XXX */ - return(result); -} - -char * -array_to_kvpair (a, quoted) -ARRAY *a; -int quoted; -{ - char *result, *valstr, *is; - char indstr[INT_STRLEN_BOUND(intmax_t) + 1]; - ARRAY_ELEMENT *ae; - int rsize, rlen, elen; - - if (a == 0 || array_empty (a)) - return((char *)NULL); - - result = (char *)xmalloc (rsize = 128); - result[rlen = 0] = '\0'; - - for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae)) { - is = inttostr (element_index(ae), indstr, sizeof(indstr)); - valstr = element_value (ae) ? - (ansic_shouldquote (element_value (ae)) ? - ansic_quote (element_value(ae), 0, (int *)0) : - sh_double_quote (element_value (ae))) - : (char *)NULL; - elen = STRLEN (is) + 8 + STRLEN (valstr); - RESIZE_MALLOCED_BUFFER (result, rlen, (elen + 1), rsize, rsize); - - strcpy (result + rlen, is); - rlen += STRLEN (is); - result[rlen++] = ' '; - if (valstr) { - strcpy (result + rlen, valstr); - rlen += STRLEN (valstr); - } else { - strcpy (result + rlen, "\"\""); - rlen += 2; - } - - if (element_forw(ae) != a->head) - result[rlen++] = ' '; - - FREE (valstr); - } - RESIZE_MALLOCED_BUFFER (result, rlen, 1, rsize, 8); - result[rlen] = '\0'; - - if (quoted) { - /* This is not as efficient as it could be... */ - valstr = sh_single_quote (result); - free (result); - result = valstr; - } - return(result); -} - -char * -array_to_assign (a, quoted) -ARRAY *a; -int quoted; -{ - char *result, *valstr, *is; - char indstr[INT_STRLEN_BOUND(intmax_t) + 1]; - ARRAY_ELEMENT *ae; - int rsize, rlen, elen; - - if (a == 0 || array_empty (a)) - return((char *)NULL); - - result = (char *)xmalloc (rsize = 128); - result[0] = '('; - rlen = 1; - - for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae)) { - is = inttostr (element_index(ae), indstr, sizeof(indstr)); - valstr = element_value (ae) ? - (ansic_shouldquote (element_value (ae)) ? - ansic_quote (element_value(ae), 0, (int *)0) : - sh_double_quote (element_value (ae))) - : (char *)NULL; - elen = STRLEN (is) + 8 + STRLEN (valstr); - RESIZE_MALLOCED_BUFFER (result, rlen, (elen + 1), rsize, rsize); - - result[rlen++] = '['; - strcpy (result + rlen, is); - rlen += STRLEN (is); - result[rlen++] = ']'; - result[rlen++] = '='; - if (valstr) { - strcpy (result + rlen, valstr); - rlen += STRLEN (valstr); - } - - if (element_forw(ae) != a->head) - result[rlen++] = ' '; - - FREE (valstr); - } - RESIZE_MALLOCED_BUFFER (result, rlen, 1, rsize, 8); - result[rlen++] = ')'; - result[rlen] = '\0'; - if (quoted) { - /* This is not as efficient as it could be... */ - valstr = sh_single_quote (result); - free (result); - result = valstr; - } - return(result); -} - -char * -array_to_string (a, sep, quoted) -ARRAY *a; -char *sep; -int quoted; -{ - if (a == 0) - return((char *)NULL); - if (array_empty(a)) - return(savestring("")); - return (array_to_string_internal (element_forw(a->head), a->head, sep, quoted)); -} - -#if defined (INCLUDE_UNUSED) || defined (TEST_ARRAY) -/* - * Return an array consisting of elements in S, separated by SEP - */ -ARRAY * -array_from_string(s, sep) -char *s, *sep; -{ - ARRAY *a; - WORD_LIST *w; - - if (s == 0) - return((ARRAY *)NULL); - w = list_string (s, sep, 0); - if (w == 0) - return((ARRAY *)NULL); - a = array_from_word_list (w); - return (a); -} -#endif - -#if defined (TEST_ARRAY) -/* - * To make a running version, compile -DTEST_ARRAY and link with: - * xmalloc.o syntax.o lib/malloc/libmalloc.a lib/sh/libsh.a - */ -int interrupt_immediately = 0; - -int -signal_is_trapped(s) -int s; -{ - return 0; -} - -void -fatal_error(const char *s, ...) -{ - fprintf(stderr, "array_test: fatal memory error\n"); - abort(); -} - -void -programming_error(const char *s, ...) -{ - fprintf(stderr, "array_test: fatal programming error\n"); - abort(); -} - -WORD_DESC * -make_bare_word (s) -const char *s; -{ - WORD_DESC *w; - - w = (WORD_DESC *)xmalloc(sizeof(WORD_DESC)); - w->word = s ? savestring(s) : savestring (""); - w->flags = 0; - return w; -} - -WORD_LIST * -make_word_list(x, l) -WORD_DESC *x; -WORD_LIST *l; -{ - WORD_LIST *w; - - w = (WORD_LIST *)xmalloc(sizeof(WORD_LIST)); - w->word = x; - w->next = l; - return w; -} - -WORD_LIST * -list_string(s, t, i) -char *s, *t; -int i; -{ - char *r, *a; - WORD_LIST *wl; - - if (s == 0) - return (WORD_LIST *)NULL; - r = savestring(s); - wl = (WORD_LIST *)NULL; - a = strtok(r, t); - while (a) { - wl = make_word_list (make_bare_word(a), wl); - a = strtok((char *)NULL, t); - } - return (REVERSE_LIST (wl, WORD_LIST *)); -} - -GENERIC_LIST * -list_reverse (list) -GENERIC_LIST *list; -{ - register GENERIC_LIST *next, *prev; - - for (prev = 0; list; ) { - next = list->next; - list->next = prev; - prev = list; - list = next; - } - return prev; -} - -char * -pat_subst(s, t, u, i) -char *s, *t, *u; -int i; -{ - return ((char *)NULL); -} - -char * -quote_string(s) -char *s; -{ - return savestring(s); -} - -print_element(ae) -ARRAY_ELEMENT *ae; -{ - char lbuf[INT_STRLEN_BOUND (intmax_t) + 1]; - - printf("array[%s] = %s\n", - inttostr (element_index(ae), lbuf, sizeof (lbuf)), - element_value(ae)); -} - -print_array(a) -ARRAY *a; -{ - printf("\n"); - array_walk(a, print_element, (void *)NULL); -} - -main() -{ - ARRAY *a, *new_a, *copy_of_a; - ARRAY_ELEMENT *ae, *aew; - char *s; - - a = array_create(); - array_insert(a, 1, "one"); - array_insert(a, 7, "seven"); - array_insert(a, 4, "four"); - array_insert(a, 1029, "one thousand twenty-nine"); - array_insert(a, 12, "twelve"); - array_insert(a, 42, "forty-two"); - print_array(a); - s = array_to_string (a, " ", 0); - printf("s = %s\n", s); - copy_of_a = array_from_string(s, " "); - printf("copy_of_a:"); - print_array(copy_of_a); - array_dispose(copy_of_a); - printf("\n"); - free(s); - ae = array_remove(a, 4); - array_dispose_element(ae); - ae = array_remove(a, 1029); - array_dispose_element(ae); - array_insert(a, 16, "sixteen"); - print_array(a); - s = array_to_string (a, " ", 0); - printf("s = %s\n", s); - copy_of_a = array_from_string(s, " "); - printf("copy_of_a:"); - print_array(copy_of_a); - array_dispose(copy_of_a); - printf("\n"); - free(s); - array_insert(a, 2, "two"); - array_insert(a, 1029, "new one thousand twenty-nine"); - array_insert(a, 0, "zero"); - array_insert(a, 134, ""); - print_array(a); - s = array_to_string (a, ":", 0); - printf("s = %s\n", s); - copy_of_a = array_from_string(s, ":"); - printf("copy_of_a:"); - print_array(copy_of_a); - array_dispose(copy_of_a); - printf("\n"); - free(s); - new_a = array_copy(a); - print_array(new_a); - s = array_to_string (new_a, ":", 0); - printf("s = %s\n", s); - copy_of_a = array_from_string(s, ":"); - free(s); - printf("copy_of_a:"); - print_array(copy_of_a); - array_shift(copy_of_a, 2, AS_DISPOSE); - printf("copy_of_a shifted by two:"); - print_array(copy_of_a); - ae = array_shift(copy_of_a, 2, 0); - printf("copy_of_a shifted by two:"); - print_array(copy_of_a); - for ( ; ae; ) { - aew = element_forw(ae); - array_dispose_element(ae); - ae = aew; - } - array_rshift(copy_of_a, 1, (char *)0); - printf("copy_of_a rshift by 1:"); - print_array(copy_of_a); - array_rshift(copy_of_a, 2, "new element zero"); - printf("copy_of_a rshift again by 2 with new element zero:"); - print_array(copy_of_a); - s = array_to_assign(copy_of_a, 0); - printf("copy_of_a=%s\n", s); - free(s); - ae = array_shift(copy_of_a, array_num_elements(copy_of_a), 0); - for ( ; ae; ) { - aew = element_forw(ae); - array_dispose_element(ae); - ae = aew; - } - array_dispose(copy_of_a); - printf("\n"); - array_dispose(a); - array_dispose(new_a); -} - -#endif /* TEST_ARRAY */ -#endif /* ARRAY_VARS */ diff --git a/third_party/bash/array.h b/third_party/bash/array.h deleted file mode 100644 index 4214e8b41..000000000 --- a/third_party/bash/array.h +++ /dev/null @@ -1,182 +0,0 @@ -/* array.h -- definitions for the interface exported by array.c that allows - the rest of the shell to manipulate array variables. */ - -/* Copyright (C) 1997-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - - -#ifndef _ARRAY_H_ -#define _ARRAY_H_ - -#include "stdc.h" - -typedef intmax_t arrayind_t; - -typedef struct array { - arrayind_t max_index; - arrayind_t num_elements; -#ifdef ALT_ARRAY_IMPLEMENTATION - arrayind_t first_index; - arrayind_t alloc_size; - struct array_element **elements; -#else - struct array_element *head; - struct array_element *lastref; -#endif -} ARRAY; - -typedef struct array_element { - arrayind_t ind; - char *value; -#ifndef ALT_ARRAY_IMPLEMENTATION - struct array_element *next, *prev; -#endif -} ARRAY_ELEMENT; - -#define ARRAY_DEFAULT_SIZE 1024 - -typedef int sh_ae_map_func_t PARAMS((ARRAY_ELEMENT *, void *)); - -/* Basic operations on entire arrays */ -#ifdef ALT_ARRAY_IMPLEMENTATION -extern void array_alloc PARAMS((ARRAY *, arrayind_t)); -extern void array_resize PARAMS((ARRAY *, arrayind_t)); -extern void array_expand PARAMS((ARRAY *, arrayind_t)); -extern void array_dispose_elements PARAMS((ARRAY_ELEMENT **)); -#endif -extern ARRAY *array_create PARAMS((void)); -extern void array_flush PARAMS((ARRAY *)); -extern void array_dispose PARAMS((ARRAY *)); -extern ARRAY *array_copy PARAMS((ARRAY *)); -#ifndef ALT_ARRAY_IMPLEMENTATION -extern ARRAY *array_slice PARAMS((ARRAY *, ARRAY_ELEMENT *, ARRAY_ELEMENT *)); -#else -extern ARRAY *array_slice PARAMS((ARRAY *, arrayind_t, arrayind_t)); -#endif - -extern void array_walk PARAMS((ARRAY *, sh_ae_map_func_t *, void *)); - -#ifndef ALT_ARRAY_IMPLEMENTATION -extern ARRAY_ELEMENT *array_shift PARAMS((ARRAY *, int, int)); -#else -extern ARRAY_ELEMENT **array_shift PARAMS((ARRAY *, int, int)); -#endif -extern int array_rshift PARAMS((ARRAY *, int, char *)); -extern ARRAY_ELEMENT *array_unshift_element PARAMS((ARRAY *)); -extern int array_shift_element PARAMS((ARRAY *, char *)); - -extern ARRAY *array_quote PARAMS((ARRAY *)); -extern ARRAY *array_quote_escapes PARAMS((ARRAY *)); -extern ARRAY *array_dequote PARAMS((ARRAY *)); -extern ARRAY *array_dequote_escapes PARAMS((ARRAY *)); -extern ARRAY *array_remove_quoted_nulls PARAMS((ARRAY *)); - -extern char *array_subrange PARAMS((ARRAY *, arrayind_t, arrayind_t, int, int, int)); -extern char *array_patsub PARAMS((ARRAY *, char *, char *, int)); -extern char *array_modcase PARAMS((ARRAY *, char *, int, int)); - -/* Basic operations on array elements. */ -extern ARRAY_ELEMENT *array_create_element PARAMS((arrayind_t, char *)); -extern ARRAY_ELEMENT *array_copy_element PARAMS((ARRAY_ELEMENT *)); -extern void array_dispose_element PARAMS((ARRAY_ELEMENT *)); - -extern int array_insert PARAMS((ARRAY *, arrayind_t, char *)); -extern ARRAY_ELEMENT *array_remove PARAMS((ARRAY *, arrayind_t)); -extern char *array_reference PARAMS((ARRAY *, arrayind_t)); - -/* Converting to and from arrays */ -extern WORD_LIST *array_to_word_list PARAMS((ARRAY *)); -extern ARRAY *array_from_word_list PARAMS((WORD_LIST *)); -extern WORD_LIST *array_keys_to_word_list PARAMS((ARRAY *)); -extern WORD_LIST *array_to_kvpair_list PARAMS((ARRAY *)); - -extern ARRAY *array_assign_list PARAMS((ARRAY *, WORD_LIST *)); - -extern char **array_to_argv PARAMS((ARRAY *, int *)); -extern ARRAY *array_from_argv PARAMS((ARRAY *, char **, int)); - -extern char *array_to_kvpair PARAMS((ARRAY *, int)); -extern char *array_to_assign PARAMS((ARRAY *, int)); -extern char *array_to_string PARAMS((ARRAY *, char *, int)); -extern ARRAY *array_from_string PARAMS((char *, char *)); - -/* Flags for array_shift */ -#define AS_DISPOSE 0x01 - -#define array_num_elements(a) ((a)->num_elements) -#define array_max_index(a) ((a)->max_index) -#ifndef ALT_ARRAY_IMPLEMENTATION -#define array_first_index(a) ((a)->head->next->ind) -#define array_head(a) ((a)->head) -#define array_alloc_size(a) ((a)->alloc_size) -#else -#define array_first_index(a) ((a)->first_index) -#define array_head(a) ((a)->elements) -#endif -#define array_empty(a) ((a)->num_elements == 0) - -#define element_value(ae) ((ae)->value) -#define element_index(ae) ((ae)->ind) - -#ifndef ALT_ARRAY_IMPLEMENTATION -#define element_forw(ae) ((ae)->next) -#define element_back(ae) ((ae)->prev) -#else -extern arrayind_t element_forw PARAMS((ARRAY *, arrayind_t)); -extern arrayind_t element_back PARAMS((ARRAY *, arrayind_t)); -#endif - - -#define set_element_value(ae, val) ((ae)->value = (val)) - -#ifdef ALT_ARRAY_IMPLEMENTATION -#define set_first_index(a, i) ((a)->first_index = (i)) -#endif - -#define set_max_index(a, i) ((a)->max_index = (i)) -#define set_num_elements(a, n) ((a)->num_elements = (n)) - -/* Convenience */ -#define array_push(a,v) \ - do { array_rshift ((a), 1, (v)); } while (0) -#define array_pop(a) \ - do { array_shift ((a), 1, AS_DISPOSE); } while (0) - -#define GET_ARRAY_FROM_VAR(n, v, a) \ - do { \ - (v) = find_variable (n); \ - (a) = ((v) && array_p ((v))) ? array_cell (v) : (ARRAY *)0; \ - } while (0) - -#define ARRAY_ELEMENT_REPLACE(ae, v) \ - do { \ - free ((ae)->value); \ - (ae)->value = (v); \ - } while (0) - -#ifdef ALT_ARRAY_IMPLEMENTATION -#define ARRAY_VALUE_REPLACE(a, i, v) \ - ARRAY_ELEMENT_REPLACE((a)->elements[(i)], (v)) -#endif - -#define ALL_ELEMENT_SUB(c) ((c) == '@' || (c) == '*') - -/* In eval.c, but uses ARRAY * */ -extern int execute_array_command PARAMS((ARRAY *, void *)); - -#endif /* _ARRAY_H_ */ diff --git a/third_party/bash/arrayfunc.c b/third_party/bash/arrayfunc.c deleted file mode 100644 index db8e07f3f..000000000 --- a/third_party/bash/arrayfunc.c +++ /dev/null @@ -1,1699 +0,0 @@ -/* arrayfunc.c -- High-level array functions used by other parts of the shell. */ - -/* Copyright (C) 2001-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if defined (ARRAY_VARS) - -#if defined (HAVE_UNISTD_H) -# include -#endif -#include - -#include "bashintl.h" - -#include "shell.h" -#include "execute_cmd.h" -#include "pathexp.h" - -#include "shmbutil.h" -#if defined (HAVE_MBSTR_H) && defined (HAVE_MBSCHR) -# include /* mbschr */ -#endif - -#include "common.h" - -#ifndef LBRACK -# define LBRACK '[' -# define RBRACK ']' -#endif - -/* This variable means to not expand associative array subscripts more than - once, when performing variable expansion. */ -int assoc_expand_once = 0; - -/* Ditto for indexed array subscripts -- currently unused */ -int array_expand_once = 0; - -static SHELL_VAR *bind_array_var_internal PARAMS((SHELL_VAR *, arrayind_t, char *, char *, int)); -static SHELL_VAR *assign_array_element_internal PARAMS((SHELL_VAR *, char *, char *, char *, int, char *, int, array_eltstate_t *)); - -static void assign_assoc_from_kvlist PARAMS((SHELL_VAR *, WORD_LIST *, HASH_TABLE *, int)); - -static char *quote_assign PARAMS((const char *)); -static void quote_array_assignment_chars PARAMS((WORD_LIST *)); -static char *quote_compound_array_word PARAMS((char *, int)); -static char *array_value_internal PARAMS((const char *, int, int, array_eltstate_t *)); - -/* Standard error message to use when encountering an invalid array subscript */ -const char * const bash_badsub_errmsg = N_("bad array subscript"); - -/* **************************************************************** */ -/* */ -/* Functions to manipulate array variables and perform assignments */ -/* */ -/* **************************************************************** */ - -/* Convert a shell variable to an array variable. The original value is - saved as array[0]. */ -SHELL_VAR * -convert_var_to_array (var) - SHELL_VAR *var; -{ - char *oldval; - ARRAY *array; - - oldval = value_cell (var); - array = array_create (); - if (oldval) - array_insert (array, 0, oldval); - - FREE (value_cell (var)); - var_setarray (var, array); - - /* these aren't valid anymore */ - var->dynamic_value = (sh_var_value_func_t *)NULL; - var->assign_func = (sh_var_assign_func_t *)NULL; - - INVALIDATE_EXPORTSTR (var); - if (exported_p (var)) - array_needs_making++; - - VSETATTR (var, att_array); - if (oldval) - VUNSETATTR (var, att_invisible); - - /* Make sure it's not marked as an associative array any more */ - VUNSETATTR (var, att_assoc); - - /* Since namerefs can't be array variables, turn off nameref attribute */ - VUNSETATTR (var, att_nameref); - - return var; -} - -/* Convert a shell variable to an array variable. The original value is - saved as array[0]. */ -SHELL_VAR * -convert_var_to_assoc (var) - SHELL_VAR *var; -{ - char *oldval; - HASH_TABLE *hash; - - oldval = value_cell (var); - hash = assoc_create (0); - if (oldval) - assoc_insert (hash, savestring ("0"), oldval); - - FREE (value_cell (var)); - var_setassoc (var, hash); - - /* these aren't valid anymore */ - var->dynamic_value = (sh_var_value_func_t *)NULL; - var->assign_func = (sh_var_assign_func_t *)NULL; - - INVALIDATE_EXPORTSTR (var); - if (exported_p (var)) - array_needs_making++; - - VSETATTR (var, att_assoc); - if (oldval) - VUNSETATTR (var, att_invisible); - - /* Make sure it's not marked as an indexed array any more */ - VUNSETATTR (var, att_array); - - /* Since namerefs can't be array variables, turn off nameref attribute */ - VUNSETATTR (var, att_nameref); - - return var; -} - -char * -make_array_variable_value (entry, ind, key, value, flags) - SHELL_VAR *entry; - arrayind_t ind; - char *key; - char *value; - int flags; -{ - SHELL_VAR *dentry; - char *newval; - - /* If we're appending, we need the old value of the array reference, so - fake out make_variable_value with a dummy SHELL_VAR */ - if (flags & ASS_APPEND) - { - dentry = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR)); - dentry->name = savestring (entry->name); - if (assoc_p (entry)) - newval = assoc_reference (assoc_cell (entry), key); - else - newval = array_reference (array_cell (entry), ind); - if (newval) - dentry->value = savestring (newval); - else - { - dentry->value = (char *)xmalloc (1); - dentry->value[0] = '\0'; - } - dentry->exportstr = 0; - dentry->attributes = entry->attributes & ~(att_array|att_assoc|att_exported); - /* Leave the rest of the members uninitialized; the code doesn't look - at them. */ - newval = make_variable_value (dentry, value, flags); - dispose_variable (dentry); - } - else - newval = make_variable_value (entry, value, flags); - - return newval; -} - -/* Assign HASH[KEY]=VALUE according to FLAGS. ENTRY is an associative array - variable; HASH is the hash table to assign into. HASH may or may not be - the hash table associated with ENTRY; if it's not, the caller takes care - of it. - XXX - make sure that any dynamic associative array variables recreate the - hash table on each assignment. BASH_CMDS and BASH_ALIASES already do this */ -static SHELL_VAR * -bind_assoc_var_internal (entry, hash, key, value, flags) - SHELL_VAR *entry; - HASH_TABLE *hash; - char *key; - char *value; - int flags; -{ - char *newval; - - /* Use the existing array contents to expand the value */ - newval = make_array_variable_value (entry, 0, key, value, flags); - - if (entry->assign_func) - (*entry->assign_func) (entry, newval, 0, key); - else - assoc_insert (hash, key, newval); - - FREE (newval); - - VUNSETATTR (entry, att_invisible); /* no longer invisible */ - - /* check mark_modified_variables if we ever want to export array vars */ - return (entry); -} - -/* Perform ENTRY[IND]=VALUE or ENTRY[KEY]=VALUE. This is not called for every - assignment to an associative array; see assign_compound_array_list below. */ -static SHELL_VAR * -bind_array_var_internal (entry, ind, key, value, flags) - SHELL_VAR *entry; - arrayind_t ind; - char *key; - char *value; - int flags; -{ - char *newval; - - newval = make_array_variable_value (entry, ind, key, value, flags); - - if (entry->assign_func) - (*entry->assign_func) (entry, newval, ind, key); - else if (assoc_p (entry)) - assoc_insert (assoc_cell (entry), key, newval); - else - array_insert (array_cell (entry), ind, newval); - FREE (newval); - - VUNSETATTR (entry, att_invisible); /* no longer invisible */ - - /* check mark_modified_variables if we ever want to export array vars */ - return (entry); -} - -/* Perform an array assignment name[ind]=value. If NAME already exists and - is not an array, and IND is 0, perform name=value instead. If NAME exists - and is not an array, and IND is not 0, convert it into an array with the - existing value as name[0]. - - If NAME does not exist, just create an array variable, no matter what - IND's value may be. */ -SHELL_VAR * -bind_array_variable (name, ind, value, flags) - char *name; - arrayind_t ind; - char *value; - int flags; -{ - SHELL_VAR *entry; - - entry = find_shell_variable (name); - - if (entry == (SHELL_VAR *) 0) - { - /* Is NAME a nameref variable that points to an unset variable? */ - entry = find_variable_nameref_for_create (name, 0); - if (entry == INVALID_NAMEREF_VALUE) - return ((SHELL_VAR *)0); - if (entry && nameref_p (entry)) - entry = make_new_array_variable (nameref_cell (entry)); - } - if (entry == (SHELL_VAR *) 0) - entry = make_new_array_variable (name); - else if ((readonly_p (entry) && (flags&ASS_FORCE) == 0) || noassign_p (entry)) - { - if (readonly_p (entry)) - err_readonly (name); - return (entry); - } - else if (array_p (entry) == 0) - entry = convert_var_to_array (entry); - - /* ENTRY is an array variable, and ARRAY points to the value. */ - return (bind_array_var_internal (entry, ind, 0, value, flags)); -} - -SHELL_VAR * -bind_array_element (entry, ind, value, flags) - SHELL_VAR *entry; - arrayind_t ind; - char *value; - int flags; -{ - return (bind_array_var_internal (entry, ind, 0, value, flags)); -} - -SHELL_VAR * -bind_assoc_variable (entry, name, key, value, flags) - SHELL_VAR *entry; - char *name; - char *key; - char *value; - int flags; -{ - if ((readonly_p (entry) && (flags&ASS_FORCE) == 0) || noassign_p (entry)) - { - if (readonly_p (entry)) - err_readonly (name); - return (entry); - } - - return (bind_assoc_var_internal (entry, assoc_cell (entry), key, value, flags)); -} - -inline void -init_eltstate (array_eltstate_t *estatep) -{ - if (estatep) - { - estatep->type = ARRAY_INVALID; - estatep->subtype = 0; - estatep->key = estatep->value = 0; - estatep->ind = INTMAX_MIN; - } -} - -inline void -flush_eltstate (array_eltstate_t *estatep) -{ - if (estatep) - FREE (estatep->key); -} - -/* Parse NAME, a lhs of an assignment statement of the form v[s], and - assign VALUE to that array element by calling bind_array_variable(). - Flags are ASS_ assignment flags */ -SHELL_VAR * -assign_array_element (name, value, flags, estatep) - char *name, *value; - int flags; - array_eltstate_t *estatep; -{ - char *sub, *vname; - int sublen, isassoc, avflags; - SHELL_VAR *entry; - - avflags = 0; - if (flags & ASS_NOEXPAND) - avflags |= AV_NOEXPAND; - if (flags & ASS_ONEWORD) - avflags |= AV_ONEWORD; - vname = array_variable_name (name, avflags, &sub, &sublen); - - if (vname == 0) - return ((SHELL_VAR *)NULL); - - entry = find_variable (vname); - isassoc = entry && assoc_p (entry); - - /* We don't allow assignment to `*' or `@' associative array keys if the - caller hasn't told us the subscript has already been expanded - (ASS_NOEXPAND). If the caller has explicitly told us it's ok - (ASS_ALLOWALLSUB) we allow it. */ - if (((isassoc == 0 || (flags & (ASS_NOEXPAND|ASS_ALLOWALLSUB)) == 0) && - (ALL_ELEMENT_SUB (sub[0]) && sub[1] == ']')) || - (sublen <= 1) || - (sub[sublen] != '\0')) /* sanity check */ - { - free (vname); - err_badarraysub (name); - return ((SHELL_VAR *)NULL); - } - - entry = assign_array_element_internal (entry, name, vname, sub, sublen, value, flags, estatep); - -#if ARRAY_EXPORT - if (entry && exported_p (entry)) - { - INVALIDATE_EXPORTSTR (entry); - array_needs_making = 1; - } -#endif - - free (vname); - return entry; -} - -static SHELL_VAR * -assign_array_element_internal (entry, name, vname, sub, sublen, value, flags, estatep) - SHELL_VAR *entry; - char *name; /* only used for error messages */ - char *vname; - char *sub; - int sublen; - char *value; - int flags; - array_eltstate_t *estatep; -{ - char *akey, *nkey; - arrayind_t ind; - char *newval; - - /* rely on the caller to initialize estatep */ - - if (entry && assoc_p (entry)) - { - sub[sublen-1] = '\0'; - if ((flags & ASS_NOEXPAND) == 0) - akey = expand_subscript_string (sub, 0); /* [ */ - else - akey = savestring (sub); - sub[sublen-1] = ']'; - if (akey == 0 || *akey == 0) - { - err_badarraysub (name); - FREE (akey); - return ((SHELL_VAR *)NULL); - } - if (estatep) - nkey = savestring (akey); /* assoc_insert/assoc_replace frees akey */ - entry = bind_assoc_variable (entry, vname, akey, value, flags); - if (estatep) - { - estatep->type = ARRAY_ASSOC; - estatep->key = nkey; - estatep->value = entry ? assoc_reference (assoc_cell (entry), nkey) : 0; - } - } - else - { - ind = array_expand_index (entry, sub, sublen, 0); - /* negative subscripts to indexed arrays count back from end */ - if (entry && ind < 0) - ind = (array_p (entry) ? array_max_index (array_cell (entry)) : 0) + 1 + ind; - if (ind < 0) - { - err_badarraysub (name); - return ((SHELL_VAR *)NULL); - } - entry = bind_array_variable (vname, ind, value, flags); - if (estatep) - { - estatep->type = ARRAY_INDEXED; - estatep->ind = ind; - estatep->value = entry ? array_reference (array_cell (entry), ind) : 0; - } - } - - return (entry); -} - -/* Find the array variable corresponding to NAME. If there is no variable, - create a new array variable. If the variable exists but is not an array, - convert it to an indexed array. If FLAGS&1 is non-zero, an existing - variable is checked for the readonly or noassign attribute in preparation - for assignment (e.g., by the `read' builtin). If FLAGS&2 is non-zero, we - create an associative array. */ -SHELL_VAR * -find_or_make_array_variable (name, flags) - char *name; - int flags; -{ - SHELL_VAR *var; - - var = find_variable (name); - if (var == 0) - { - /* See if we have a nameref pointing to a variable that hasn't been - created yet. */ - var = find_variable_last_nameref (name, 1); - if (var && nameref_p (var) && invisible_p (var)) - { - internal_warning (_("%s: removing nameref attribute"), name); - VUNSETATTR (var, att_nameref); - } - if (var && nameref_p (var)) - { - if (valid_nameref_value (nameref_cell (var), 2) == 0) - { - sh_invalidid (nameref_cell (var)); - return ((SHELL_VAR *)NULL); - } - var = (flags & 2) ? make_new_assoc_variable (nameref_cell (var)) : make_new_array_variable (nameref_cell (var)); - } - } - - if (var == 0) - var = (flags & 2) ? make_new_assoc_variable (name) : make_new_array_variable (name); - else if ((flags & 1) && (readonly_p (var) || noassign_p (var))) - { - if (readonly_p (var)) - err_readonly (name); - return ((SHELL_VAR *)NULL); - } - else if ((flags & 2) && array_p (var)) - { - set_exit_status (EXECUTION_FAILURE); - report_error (_("%s: cannot convert indexed to associative array"), name); - return ((SHELL_VAR *)NULL); - } - else if (flags & 2) - var = assoc_p (var) ? var : convert_var_to_assoc (var); - else if (array_p (var) == 0 && assoc_p (var) == 0) - var = convert_var_to_array (var); - - return (var); -} - -/* Perform a compound assignment statement for array NAME, where VALUE is - the text between the parens: NAME=( VALUE ) */ -SHELL_VAR * -assign_array_from_string (name, value, flags) - char *name, *value; - int flags; -{ - SHELL_VAR *var; - int vflags; - - vflags = 1; - if (flags & ASS_MKASSOC) - vflags |= 2; - - var = find_or_make_array_variable (name, vflags); - if (var == 0) - return ((SHELL_VAR *)NULL); - - return (assign_array_var_from_string (var, value, flags)); -} - -/* Sequentially assign the indices of indexed array variable VAR from the - words in LIST. */ -SHELL_VAR * -assign_array_var_from_word_list (var, list, flags) - SHELL_VAR *var; - WORD_LIST *list; - int flags; -{ - register arrayind_t i; - register WORD_LIST *l; - ARRAY *a; - - a = array_cell (var); - i = (flags & ASS_APPEND) ? array_max_index (a) + 1 : 0; - - for (l = list; l; l = l->next, i++) - bind_array_var_internal (var, i, 0, l->word->word, flags & ~ASS_APPEND); - - VUNSETATTR (var, att_invisible); /* no longer invisible */ - - return var; -} - -WORD_LIST * -expand_compound_array_assignment (var, value, flags) - SHELL_VAR *var; - char *value; - int flags; -{ - WORD_LIST *list, *nlist; - char *val; - int ni; - - /* This condition is true when invoked from the declare builtin with a - command like - declare -a d='([1]="" [2]="bdef" [5]="hello world" "test")' */ - if (*value == '(') /*)*/ - { - ni = 1; - val = extract_array_assignment_list (value, &ni); - if (val == 0) - return (WORD_LIST *)NULL; - } - else - val = value; - - /* Expand the value string into a list of words, performing all the - shell expansions including pathname generation and word splitting. */ - /* First we split the string on whitespace, using the shell parser - (ksh93 seems to do this). */ - /* XXX - this needs a rethink, maybe use split_at_delims */ - list = parse_string_to_word_list (val, 1, "array assign"); - - /* If the parser has quoted CTLESC and CTNLNUL with CTLESC in unquoted - words, we need to remove those here because the code below assumes - they are there because they exist in the original word. */ - /* XXX - if we rethink parse_string_to_word_list above, change this. */ - for (nlist = list; nlist; nlist = nlist->next) - if ((nlist->word->flags & W_QUOTED) == 0) - remove_quoted_escapes (nlist->word->word); - - /* Note that we defer expansion of the assignment statements for associative - arrays here, so we don't have to scan the subscript and find the ending - bracket twice. See the caller below. */ - if (var && assoc_p (var)) - { - if (val != value) - free (val); - return list; - } - - /* If we're using [subscript]=value, we need to quote each [ and ] to - prevent unwanted filename expansion. This doesn't need to be done - for associative array expansion, since that uses a different expansion - function (see assign_compound_array_list below). */ - if (list) - quote_array_assignment_chars (list); - - /* Now that we've split it, perform the shell expansions on each - word in the list. */ - nlist = list ? expand_words_no_vars (list) : (WORD_LIST *)NULL; - - dispose_words (list); - - if (val != value) - free (val); - - return nlist; -} - -#if ASSOC_KVPAIR_ASSIGNMENT -static void -assign_assoc_from_kvlist (var, nlist, h, flags) - SHELL_VAR *var; - WORD_LIST *nlist; - HASH_TABLE *h; - int flags; -{ - WORD_LIST *list; - char *akey, *aval, *k, *v; - - for (list = nlist; list; list = list->next) - { - k = list->word->word; - v = list->next ? list->next->word->word : 0; - - if (list->next) - list = list->next; - - akey = expand_subscript_string (k, 0); - if (akey == 0 || *akey == 0) - { - err_badarraysub (k); - FREE (akey); - continue; - } - - aval = expand_subscript_string (v, 0); - if (aval == 0) - { - aval = (char *)xmalloc (1); - aval[0] = '\0'; /* like do_assignment_internal */ - } - - bind_assoc_var_internal (var, h, akey, aval, flags); - free (aval); - } -} - -/* Return non-zero if L appears to be a key-value pair associative array - compound assignment. */ -int -kvpair_assignment_p (l) - WORD_LIST *l; -{ - return (l && (l->word->flags & W_ASSIGNMENT) == 0 && l->word->word[0] != '['); /*]*/ -} - -char * -expand_and_quote_kvpair_word (w) - char *w; -{ - char *r, *s, *t; - - t = w ? expand_subscript_string (w, 0) : 0; - s = (t && strchr (t, CTLESC)) ? quote_escapes (t) : t; - r = sh_single_quote (s ? s : ""); - if (s != t) - free (s); - free (t); - return r; -} -#endif - -/* Callers ensure that VAR is not NULL. Associative array assignments have not - been expanded when this is called, or have been expanded once and single- - quoted, so we don't have to scan through an unquoted expanded subscript to - find the ending bracket; indexed array assignments have been expanded and - possibly single-quoted to prevent further expansion. - - If this is an associative array, we perform the assignments into NHASH and - set NHASH to be the value of VAR after processing the assignments in NLIST */ -void -assign_compound_array_list (var, nlist, flags) - SHELL_VAR *var; - WORD_LIST *nlist; - int flags; -{ - ARRAY *a; - HASH_TABLE *h, *nhash; - WORD_LIST *list; - char *w, *val, *nval, *savecmd; - int len, iflags, free_val; - arrayind_t ind, last_ind; - char *akey; - - a = (var && array_p (var)) ? array_cell (var) : (ARRAY *)0; - nhash = h = (var && assoc_p (var)) ? assoc_cell (var) : (HASH_TABLE *)0; - - akey = (char *)0; - ind = 0; - - /* Now that we are ready to assign values to the array, kill the existing - value. */ - if ((flags & ASS_APPEND) == 0) - { - if (a && array_p (var)) - array_flush (a); - else if (h && assoc_p (var)) - nhash = assoc_create (h->nbuckets); - } - - last_ind = (a && (flags & ASS_APPEND)) ? array_max_index (a) + 1 : 0; - -#if ASSOC_KVPAIR_ASSIGNMENT - if (assoc_p (var) && kvpair_assignment_p (nlist)) - { - iflags = flags & ~ASS_APPEND; - assign_assoc_from_kvlist (var, nlist, nhash, iflags); - if (nhash && nhash != h) - { - h = assoc_cell (var); - var_setassoc (var, nhash); - assoc_dispose (h); - } - return; - } -#endif - - for (list = nlist; list; list = list->next) - { - /* Don't allow var+=(values) to make assignments in VALUES append to - existing values by default. */ - iflags = flags & ~ASS_APPEND; - w = list->word->word; - - /* We have a word of the form [ind]=value */ - if ((list->word->flags & W_ASSIGNMENT) && w[0] == '[') - { - /* Don't have to handle embedded quotes specially any more, since - associative array subscripts have not been expanded yet (see - above). */ - len = skipsubscript (w, 0, 0); - - /* XXX - changes for `+=' */ - if (w[len] != ']' || (w[len+1] != '=' && (w[len+1] != '+' || w[len+2] != '='))) - { - if (assoc_p (var)) - { - err_badarraysub (w); - continue; - } - nval = make_variable_value (var, w, flags); - if (var->assign_func) - (*var->assign_func) (var, nval, last_ind, 0); - else - array_insert (a, last_ind, nval); - FREE (nval); - last_ind++; - continue; - } - - if (len == 1) - { - err_badarraysub (w); - continue; - } - - if (ALL_ELEMENT_SUB (w[1]) && len == 2 && array_p (var)) - { - set_exit_status (EXECUTION_FAILURE); - report_error (_("%s: cannot assign to non-numeric index"), w); - continue; - } - - if (array_p (var)) - { - ind = array_expand_index (var, w + 1, len, 0); - /* negative subscripts to indexed arrays count back from end */ - if (ind < 0) - ind = array_max_index (array_cell (var)) + 1 + ind; - if (ind < 0) - { - err_badarraysub (w); - continue; - } - - last_ind = ind; - } - else if (assoc_p (var)) - { - /* This is not performed above, see expand_compound_array_assignment */ - w[len] = '\0'; /*[*/ - akey = expand_subscript_string (w+1, 0); - w[len] = ']'; - /* And we need to expand the value also, see below */ - if (akey == 0 || *akey == 0) - { - err_badarraysub (w); - FREE (akey); - continue; - } - } - - /* XXX - changes for `+=' -- just accept the syntax. ksh93 doesn't do this */ - if (w[len + 1] == '+' && w[len + 2] == '=') - { - iflags |= ASS_APPEND; - val = w + len + 3; - } - else - val = w + len + 2; - } - else if (assoc_p (var)) - { - set_exit_status (EXECUTION_FAILURE); - report_error (_("%s: %s: must use subscript when assigning associative array"), var->name, w); - continue; - } - else /* No [ind]=value, just a stray `=' */ - { - ind = last_ind; - val = w; - } - - free_val = 0; - /* See above; we need to expand the value here */ - if (assoc_p (var)) - { - val = expand_subscript_string (val, 0); - if (val == 0) - { - val = (char *)xmalloc (1); - val[0] = '\0'; /* like do_assignment_internal */ - } - free_val = 1; - } - - savecmd = this_command_name; - if (integer_p (var)) - this_command_name = (char *)NULL; /* no command name for errors */ - if (assoc_p (var)) - bind_assoc_var_internal (var, nhash, akey, val, iflags); - else - bind_array_var_internal (var, ind, akey, val, iflags); - last_ind++; - this_command_name = savecmd; - - if (free_val) - free (val); - } - - if (assoc_p (var) && nhash && nhash != h) - { - h = assoc_cell (var); - var_setassoc (var, nhash); - assoc_dispose (h); - } -} - -/* Perform a compound array assignment: VAR->name=( VALUE ). The - VALUE has already had the parentheses stripped. */ -SHELL_VAR * -assign_array_var_from_string (var, value, flags) - SHELL_VAR *var; - char *value; - int flags; -{ - WORD_LIST *nlist; - - if (value == 0) - return var; - - nlist = expand_compound_array_assignment (var, value, flags); - assign_compound_array_list (var, nlist, flags); - - if (nlist) - dispose_words (nlist); - - if (var) - VUNSETATTR (var, att_invisible); /* no longer invisible */ - - return (var); -} - -/* Quote globbing chars and characters in $IFS before the `=' in an assignment - statement (usually a compound array assignment) to protect them from - unwanted filename expansion or word splitting. */ -static char * -quote_assign (string) - const char *string; -{ - size_t slen; - int saw_eq; - char *temp, *t, *subs; - const char *s, *send; - int ss, se; - DECLARE_MBSTATE; - - slen = strlen (string); - send = string + slen; - - t = temp = (char *)xmalloc (slen * 2 + 1); - saw_eq = 0; - for (s = string; *s; ) - { - if (*s == '=') - saw_eq = 1; - if (saw_eq == 0 && *s == '[') /* looks like a subscript */ - { - ss = s - string; - se = skipsubscript (string, ss, 0); - subs = substring (s, ss, se); - *t++ = '\\'; - strcpy (t, subs); - t += se - ss; - *t++ = '\\'; - *t++ = ']'; - s += se + 1; - free (subs); - continue; - } - if (saw_eq == 0 && (glob_char_p (s) || isifs (*s))) - *t++ = '\\'; - - COPY_CHAR_P (t, s, send); - } - *t = '\0'; - return temp; -} - -/* Take a word W of the form [IND]=VALUE and transform it to ['IND']='VALUE' - to prevent further expansion. This is called for compound assignments to - indexed arrays. W has already undergone word expansions. If W has no [IND]=, - just single-quote and return it. */ -static char * -quote_compound_array_word (w, type) - char *w; - int type; -{ - char *nword, *sub, *value, *t; - int ind, wlen, i; - - if (w[0] != LBRACK) - return (sh_single_quote (w)); /* XXX - quote CTLESC */ - ind = skipsubscript (w, 0, 0); - if (w[ind] != RBRACK) - return (sh_single_quote (w)); /* XXX - quote CTLESC */ - - wlen = strlen (w); - w[ind] = '\0'; - t = (strchr (w+1, CTLESC)) ? quote_escapes (w+1) : w+1; - sub = sh_single_quote (t); - if (t != w+1) - free (t); - w[ind] = RBRACK; - - nword = xmalloc (wlen * 4 + 5); /* wlen*4 is max single quoted length */ - nword[0] = LBRACK; - i = STRLEN (sub); - memcpy (nword+1, sub, i); - free (sub); - i++; /* accommodate the opening LBRACK */ - nword[i++] = w[ind++]; /* RBRACK */ - if (w[ind] == '+') - nword[i++] = w[ind++]; - nword[i++] = w[ind++]; - t = (strchr (w+ind, CTLESC)) ? quote_escapes (w+ind) : w+ind; - value = sh_single_quote (t); - if (t != w+ind) - free (t); - strcpy (nword + i, value); - - return nword; -} - -/* Expand the key and value in W, which is of the form [KEY]=VALUE, and - reconstruct W with the expanded and single-quoted version: - ['expanded-key']='expanded-value'. If there is no [KEY]=, single-quote the - word and return it. Very similar to previous function, but does not assume - W has already been expanded, and expands the KEY and VALUE separately. - Used for compound assignments to associative arrays that are arguments to - declaration builtins (declare -A a=( list )). */ -char * -expand_and_quote_assoc_word (w, type) - char *w; - int type; -{ - char *nword, *key, *value, *s, *t; - int ind, wlen, i; - - if (w[0] != LBRACK) - return (sh_single_quote (w)); /* XXX - quote_escapes */ - ind = skipsubscript (w, 0, 0); - if (w[ind] != RBRACK) - return (sh_single_quote (w)); /* XXX - quote_escapes */ - - w[ind] = '\0'; - t = expand_subscript_string (w+1, 0); - s = (t && strchr (t, CTLESC)) ? quote_escapes (t) : t; - key = sh_single_quote (s ? s : ""); - if (s != t) - free (s); - w[ind] = RBRACK; - free (t); - - wlen = STRLEN (key); - nword = xmalloc (wlen + 5); - nword[0] = LBRACK; - memcpy (nword+1, key, wlen); - i = wlen + 1; /* accommodate the opening LBRACK */ - - nword[i++] = w[ind++]; /* RBRACK */ - if (w[ind] == '+') - nword[i++] = w[ind++]; - nword[i++] = w[ind++]; - - t = expand_subscript_string (w+ind, 0); - s = (t && strchr (t, CTLESC)) ? quote_escapes (t) : t; - value = sh_single_quote (s ? s : ""); - if (s != t) - free (s); - free (t); - nword = xrealloc (nword, wlen + 5 + STRLEN (value)); - strcpy (nword + i, value); - - free (key); - free (value); - - return nword; -} - -/* For each word in a compound array assignment, if the word looks like - [ind]=value, single-quote ind and value, but leave the brackets and - the = sign (and any `+') alone. If it's not an assignment, just single- - quote the word. This is used for indexed arrays. */ -void -quote_compound_array_list (list, type) - WORD_LIST *list; - int type; -{ - char *s, *t; - WORD_LIST *l; - - for (l = list; l; l = l->next) - { - if (l->word == 0 || l->word->word == 0) - continue; /* should not happen, but just in case... */ - if ((l->word->flags & W_ASSIGNMENT) == 0) - { - s = (strchr (l->word->word, CTLESC)) ? quote_escapes (l->word->word) : l->word->word; - t = sh_single_quote (s); - if (s != l->word->word) - free (s); - } - else - t = quote_compound_array_word (l->word->word, type); - free (l->word->word); - l->word->word = t; - } -} - -/* For each word in a compound array assignment, if the word looks like - [ind]=value, quote globbing chars and characters in $IFS before the `='. */ -static void -quote_array_assignment_chars (list) - WORD_LIST *list; -{ - char *nword; - WORD_LIST *l; - - for (l = list; l; l = l->next) - { - if (l->word == 0 || l->word->word == 0 || l->word->word[0] == '\0') - continue; /* should not happen, but just in case... */ - /* Don't bother if it hasn't been recognized as an assignment or - doesn't look like [ind]=value */ - if ((l->word->flags & W_ASSIGNMENT) == 0) - continue; - if (l->word->word[0] != '[' || mbschr (l->word->word, '=') == 0) /* ] */ - continue; - - nword = quote_assign (l->word->word); - free (l->word->word); - l->word->word = nword; - l->word->flags |= W_NOGLOB; /* XXX - W_NOSPLIT also? */ - } -} - -/* skipsubscript moved to subst.c to use private functions. 2009/02/24. */ - -/* This function is called with SUB pointing to just after the beginning - `[' of an array subscript and removes the array element to which SUB - expands from array VAR. A subscript of `*' or `@' unsets the array. */ -/* If FLAGS&1 (VA_NOEXPAND) we don't expand the subscript; we just use it - as-is. If FLAGS&VA_ONEWORD, we don't try to use skipsubscript to parse - the subscript, we just assume the subscript ends with a close bracket, - if one is present, and use what's inside the brackets. */ -int -unbind_array_element (var, sub, flags) - SHELL_VAR *var; - char *sub; - int flags; -{ - arrayind_t ind; - char *akey; - ARRAY_ELEMENT *ae; - - /* Assume that the caller (unset_builtin) passes us a null-terminated SUB, - so we don't have to use VA_ONEWORD or parse the subscript again with - skipsubscript(). */ - - if (ALL_ELEMENT_SUB (sub[0]) && sub[1] == 0) - { - if (array_p (var) || assoc_p (var)) - { - if (flags & VA_ALLOWALL) - { - unbind_variable (var->name); /* XXX -- {array,assoc}_flush ? */ - return (0); - } - /* otherwise we fall through and try to unset element `@' or `*' */ - } - else - return -2; /* don't allow this to unset scalar variables */ - } - - if (assoc_p (var)) - { - akey = (flags & VA_NOEXPAND) ? sub : expand_subscript_string (sub, 0); - if (akey == 0 || *akey == 0) - { - builtin_error ("[%s]: %s", sub, _(bash_badsub_errmsg)); - FREE (akey); - return -1; - } - assoc_remove (assoc_cell (var), akey); - if (akey != sub) - free (akey); - } - else if (array_p (var)) - { - if (ALL_ELEMENT_SUB (sub[0]) && sub[1] == 0) - { - /* We can go several ways here: - 1) remove the array (backwards compatible) - 2) empty the array (new behavior) - 3) do nothing; treat the `@' or `*' as an expression and throw - an error - */ - /* Behavior 1 */ - if (shell_compatibility_level <= 51) - { - unbind_variable (name_cell (var)); - return 0; - } - else /* Behavior 2 */ - { - array_flush (array_cell (var)); - return 0; - } - /* Fall through for behavior 3 */ - } - ind = array_expand_index (var, sub, strlen (sub) + 1, 0); - /* negative subscripts to indexed arrays count back from end */ - if (ind < 0) - ind = array_max_index (array_cell (var)) + 1 + ind; - if (ind < 0) - { - builtin_error ("[%s]: %s", sub, _(bash_badsub_errmsg)); - return -1; - } - ae = array_remove (array_cell (var), ind); - if (ae) - array_dispose_element (ae); - } - else /* array_p (var) == 0 && assoc_p (var) == 0 */ - { - akey = this_command_name; - ind = array_expand_index (var, sub, strlen (sub) + 1, 0); - this_command_name = akey; - if (ind == 0) - { - unbind_variable (var->name); - return (0); - } - else - return -2; /* any subscript other than 0 is invalid with scalar variables */ - } - - return 0; -} - -/* Format and output an array assignment in compound form VAR=(VALUES), - suitable for re-use as input. */ -void -print_array_assignment (var, quoted) - SHELL_VAR *var; - int quoted; -{ - char *vstr; - - vstr = array_to_assign (array_cell (var), quoted); - - if (vstr == 0) - printf ("%s=%s\n", var->name, quoted ? "'()'" : "()"); - else - { - printf ("%s=%s\n", var->name, vstr); - free (vstr); - } -} - -/* Format and output an associative array assignment in compound form - VAR=(VALUES), suitable for re-use as input. */ -void -print_assoc_assignment (var, quoted) - SHELL_VAR *var; - int quoted; -{ - char *vstr; - - vstr = assoc_to_assign (assoc_cell (var), quoted); - - if (vstr == 0) - printf ("%s=%s\n", var->name, quoted ? "'()'" : "()"); - else - { - printf ("%s=%s\n", var->name, vstr); - free (vstr); - } -} - -/***********************************************************************/ -/* */ -/* Utility functions to manage arrays and their contents for expansion */ -/* */ -/***********************************************************************/ - -/* Return 1 if NAME is a properly-formed array reference v[sub]. */ - -/* Return 1 if NAME is a properly-formed array reference v[sub]. */ - -/* When NAME is a properly-formed array reference and a non-null argument SUBP - is supplied, '[' and ']' that enclose the subscript are replaced by '\0', - and the pointer to the subscript in NAME is assigned to *SUBP, so that NAME - and SUBP can be later used as the array name and the subscript, - respectively. When SUBP is the null pointer, the original string NAME will - not be modified. */ -/* We need to reserve 1 for FLAGS, which we pass to skipsubscript. */ -int -tokenize_array_reference (name, flags, subp) - char *name; - int flags; - char **subp; -{ - char *t; - int r, len, isassoc, ssflags; - SHELL_VAR *entry; - - t = mbschr (name, '['); /* ] */ - isassoc = 0; - if (t) - { - *t = '\0'; - r = legal_identifier (name); - if (flags & VA_NOEXPAND) /* Don't waste a lookup if we don't need one */ - isassoc = (entry = find_variable (name)) && assoc_p (entry); - *t = '['; - if (r == 0) - return 0; - - ssflags = 0; - if (isassoc && ((flags & (VA_NOEXPAND|VA_ONEWORD)) == (VA_NOEXPAND|VA_ONEWORD))) - len = strlen (t) - 1; - else if (isassoc) - { - if (flags & VA_NOEXPAND) - ssflags |= 1; - len = skipsubscript (t, 0, ssflags); - } - else - /* Check for a properly-terminated non-null subscript. */ - len = skipsubscript (t, 0, 0); /* arithmetic expression */ - - if (t[len] != ']' || len == 1 || t[len+1] != '\0') - return 0; - -#if 0 - /* Could check and allow subscripts consisting only of whitespace for - existing associative arrays, using isassoc */ - for (r = 1; r < len; r++) - if (whitespace (t[r]) == 0) - break; - if (r == len) - return 0; /* Fail if the subscript contains only whitespaces. */ -#endif - - if (subp) - { - t[0] = t[len] = '\0'; - *subp = t + 1; - } - - /* This allows blank subscripts */ - return 1; - } - return 0; -} - -/* Return 1 if NAME is a properly-formed array reference v[sub]. */ - -/* We need to reserve 1 for FLAGS, which we pass to skipsubscript. */ -int -valid_array_reference (name, flags) - const char *name; - int flags; -{ - return tokenize_array_reference ((char *)name, flags, (char **)NULL); -} - -/* Expand the array index beginning at S and extending LEN characters. */ -arrayind_t -array_expand_index (var, s, len, flags) - SHELL_VAR *var; - char *s; - int len; - int flags; -{ - char *exp, *t, *savecmd; - int expok, eflag; - arrayind_t val; - - exp = (char *)xmalloc (len); - strncpy (exp, s, len - 1); - exp[len - 1] = '\0'; -#if 0 /* TAG: maybe bash-5.2 */ - if ((flags & AV_NOEXPAND) == 0) - t = expand_arith_string (exp, Q_DOUBLE_QUOTES|Q_ARITH|Q_ARRAYSUB); /* XXX - Q_ARRAYSUB for future use */ - else - t = exp; -#else - t = expand_arith_string (exp, Q_DOUBLE_QUOTES|Q_ARITH|Q_ARRAYSUB); /* XXX - Q_ARRAYSUB for future use */ -#endif - savecmd = this_command_name; - this_command_name = (char *)NULL; - eflag = (shell_compatibility_level > 51) ? 0 : EXP_EXPANDED; - val = evalexp (t, eflag, &expok); /* XXX - was 0 but we expanded exp already */ - this_command_name = savecmd; - if (t != exp) - free (t); - free (exp); - if (expok == 0) - { - set_exit_status (EXECUTION_FAILURE); - - if (no_longjmp_on_fatal_error) - return 0; - top_level_cleanup (); - jump_to_top_level (DISCARD); - } - return val; -} - -/* Return the name of the variable specified by S without any subscript. - If SUBP is non-null, return a pointer to the start of the subscript - in *SUBP. If LENP is non-null, the length of the subscript is returned - in *LENP. This returns newly-allocated memory. */ -char * -array_variable_name (s, flags, subp, lenp) - const char *s; - int flags; - char **subp; - int *lenp; -{ - char *t, *ret; - int ind, ni, ssflags; - - t = mbschr (s, '['); - if (t == 0) - { - if (subp) - *subp = t; - if (lenp) - *lenp = 0; - return ((char *)NULL); - } - ind = t - s; - if ((flags & (AV_NOEXPAND|AV_ONEWORD)) == (AV_NOEXPAND|AV_ONEWORD)) - ni = strlen (s) - 1; - else - { - ssflags = 0; - if (flags & AV_NOEXPAND) - ssflags |= 1; - ni = skipsubscript (s, ind, ssflags); - } - if (ni <= ind + 1 || s[ni] != ']') - { - err_badarraysub (s); - if (subp) - *subp = t; - if (lenp) - *lenp = 0; - return ((char *)NULL); - } - - *t = '\0'; - ret = savestring (s); - *t++ = '['; /* ] */ - - if (subp) - *subp = t; - if (lenp) - *lenp = ni - ind; - - return ret; -} - -/* Return the variable specified by S without any subscript. If SUBP is - non-null, return a pointer to the start of the subscript in *SUBP. - If LENP is non-null, the length of the subscript is returned in *LENP. */ -SHELL_VAR * -array_variable_part (s, flags, subp, lenp) - const char *s; - int flags; - char **subp; - int *lenp; -{ - char *t; - SHELL_VAR *var; - - t = array_variable_name (s, flags, subp, lenp); - if (t == 0) - return ((SHELL_VAR *)NULL); - var = find_variable (t); /* XXX - handle namerefs here? */ - - free (t); - return var; /* now return invisible variables; caller must handle */ -} - -#define INDEX_ERROR() \ - do \ - { \ - if (var) \ - err_badarraysub (var->name); \ - else \ - { \ - t[-1] = '\0'; \ - err_badarraysub (s); \ - t[-1] = '['; /* ] */\ - } \ - return ((char *)NULL); \ - } \ - while (0) - -/* Return a string containing the elements in the array and subscript - described by S. If the subscript is * or @, obeys quoting rules akin - to the expansion of $* and $@ including double quoting. If RTYPE - is non-null it gets 1 if the array reference is name[*], 2 if the - reference is name[@], and 0 otherwise. */ -static char * -array_value_internal (s, quoted, flags, estatep) - const char *s; - int quoted, flags; - array_eltstate_t *estatep; -{ - int len, isassoc, subtype; - arrayind_t ind; - char *akey; - char *retval, *t, *temp; - WORD_LIST *l; - SHELL_VAR *var; - - var = array_variable_part (s, flags, &t, &len); /* XXX */ - - /* Expand the index, even if the variable doesn't exist, in case side - effects are needed, like ${w[i++]} where w is unset. */ -#if 0 - if (var == 0) - return (char *)NULL; -#endif - - if (len == 0) - return ((char *)NULL); /* error message already printed */ - - isassoc = var && assoc_p (var); - /* [ */ - akey = 0; - subtype = 0; - if (estatep) - estatep->value = (char *)NULL; - - /* Backwards compatibility: we only change the behavior of A[@] and A[*] - for associative arrays, and the caller has to request it. */ - if ((isassoc == 0 || (flags & AV_ATSTARKEYS) == 0) && ALL_ELEMENT_SUB (t[0]) && t[1] == ']') - { - if (estatep) - estatep->subtype = (t[0] == '*') ? 1 : 2; - if ((flags & AV_ALLOWALL) == 0) - { - err_badarraysub (s); - return ((char *)NULL); - } - else if (var == 0 || value_cell (var) == 0) - return ((char *)NULL); - else if (invisible_p (var)) - return ((char *)NULL); - else if (array_p (var) == 0 && assoc_p (var) == 0) - { - if (estatep) - estatep->type = ARRAY_SCALAR; - l = add_string_to_list (value_cell (var), (WORD_LIST *)NULL); - } - else if (assoc_p (var)) - { - if (estatep) - estatep->type = ARRAY_ASSOC; - l = assoc_to_word_list (assoc_cell (var)); - if (l == (WORD_LIST *)NULL) - return ((char *)NULL); - } - else - { - if (estatep) - estatep->type = ARRAY_INDEXED; - l = array_to_word_list (array_cell (var)); - if (l == (WORD_LIST *)NULL) - return ((char *) NULL); - } - - /* Caller of array_value takes care of inspecting estatep->subtype and - duplicating retval if subtype == 0, so this is not a memory leak */ - if (t[0] == '*' && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))) - { - temp = string_list_dollar_star (l, quoted, (flags & AV_ASSIGNRHS) ? PF_ASSIGNRHS : 0); - retval = quote_string (temp); - free (temp); - } - else /* ${name[@]} or unquoted ${name[*]} */ - retval = string_list_dollar_at (l, quoted, (flags & AV_ASSIGNRHS) ? PF_ASSIGNRHS : 0); - - dispose_words (l); - } - else - { - if (estatep) - estatep->subtype = 0; - if (var == 0 || array_p (var) || assoc_p (var) == 0) - { - if ((flags & AV_USEIND) == 0 || estatep == 0) - { - ind = array_expand_index (var, t, len, flags); - if (ind < 0) - { - /* negative subscripts to indexed arrays count back from end */ - if (var && array_p (var)) - ind = array_max_index (array_cell (var)) + 1 + ind; - if (ind < 0) - INDEX_ERROR(); - } - if (estatep) - estatep->ind = ind; - } - else if (estatep && (flags & AV_USEIND)) - ind = estatep->ind; - if (estatep && var) - estatep->type = array_p (var) ? ARRAY_INDEXED : ARRAY_SCALAR; - } - else if (assoc_p (var)) - { - t[len - 1] = '\0'; - if (estatep) - estatep->type = ARRAY_ASSOC; - if ((flags & AV_USEIND) && estatep && estatep->key) - akey = savestring (estatep->key); - else if ((flags & AV_NOEXPAND) == 0) - akey = expand_subscript_string (t, 0); /* [ */ - else - akey = savestring (t); - t[len - 1] = ']'; - if (akey == 0 || *akey == 0) - { - FREE (akey); - INDEX_ERROR(); - } - } - - if (var == 0 || value_cell (var) == 0) - { - FREE (akey); - return ((char *)NULL); - } - else if (invisible_p (var)) - { - FREE (akey); - return ((char *)NULL); - } - if (array_p (var) == 0 && assoc_p (var) == 0) - retval = (ind == 0) ? value_cell (var) : (char *)NULL; - else if (assoc_p (var)) - { - retval = assoc_reference (assoc_cell (var), akey); - if (estatep && estatep->key && (flags & AV_USEIND)) - free (akey); /* duplicated estatep->key */ - else if (estatep) - estatep->key = akey; /* XXX - caller must manage */ - else /* not saving it anywhere */ - free (akey); - } - else - retval = array_reference (array_cell (var), ind); - - if (estatep) - estatep->value = retval; - } - - return retval; -} - -/* Return a string containing the elements described by the array and - subscript contained in S, obeying quoting for subscripts * and @. */ -char * -array_value (s, quoted, flags, estatep) - const char *s; - int quoted, flags; - array_eltstate_t *estatep; -{ - char *retval; - - retval = array_value_internal (s, quoted, flags|AV_ALLOWALL, estatep); - return retval; -} - -/* Return the value of the array indexing expression S as a single string. - If (FLAGS & AV_ALLOWALL) is 0, do not allow `@' and `*' subscripts. This - is used by other parts of the shell such as the arithmetic expression - evaluator in expr.c. */ -char * -get_array_value (s, flags, estatep) - const char *s; - int flags; - array_eltstate_t *estatep; -{ - char *retval; - - retval = array_value_internal (s, 0, flags, estatep); - return retval; -} - -char * -array_keys (s, quoted, pflags) - char *s; - int quoted, pflags; -{ - int len; - char *retval, *t, *temp; - WORD_LIST *l; - SHELL_VAR *var; - - var = array_variable_part (s, 0, &t, &len); - - /* [ */ - if (var == 0 || ALL_ELEMENT_SUB (t[0]) == 0 || t[1] != ']') - return (char *)NULL; - - if (var_isset (var) == 0 || invisible_p (var)) - return (char *)NULL; - - if (array_p (var) == 0 && assoc_p (var) == 0) - l = add_string_to_list ("0", (WORD_LIST *)NULL); - else if (assoc_p (var)) - l = assoc_keys_to_word_list (assoc_cell (var)); - else - l = array_keys_to_word_list (array_cell (var)); - if (l == (WORD_LIST *)NULL) - return ((char *) NULL); - - retval = string_list_pos_params (t[0], l, quoted, pflags); - - dispose_words (l); - return retval; -} -#endif /* ARRAY_VARS */ diff --git a/third_party/bash/arrayfunc.h b/third_party/bash/arrayfunc.h deleted file mode 100644 index 69112b579..000000000 --- a/third_party/bash/arrayfunc.h +++ /dev/null @@ -1,140 +0,0 @@ -/* arrayfunc.h -- declarations for miscellaneous array functions in arrayfunc.c */ - -/* Copyright (C) 2001-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_ARRAYFUNC_H_) -#define _ARRAYFUNC_H_ - -/* Must include variables.h before including this file. */ - -/* An object to encapsulate the state of an array element. It can describe - an array assignment A[KEY]=VALUE or a[IND]=VALUE depending on TYPE, or - for passing array subscript references around, where VALUE would be - ${a[IND]} or ${A[KEY]}. This is not dependent on ARRAY_VARS so we can - use it in function parameters. */ - -/* values for `type' field */ -#define ARRAY_INVALID -1 -#define ARRAY_SCALAR 0 -#define ARRAY_INDEXED 1 -#define ARRAY_ASSOC 2 - -/* KEY will contain allocated memory if called through the assign_array_element - code path because of how assoc_insert works. */ -typedef struct element_state -{ - short type; /* assoc or indexed, says which fields are valid */ - short subtype; /* `*', `@', or something else */ - arrayind_t ind; - char *key; /* can be allocated memory */ - char *value; -} array_eltstate_t; - -#if defined (ARRAY_VARS) - -/* This variable means to not expand associative array subscripts more than - once, when performing variable expansion. */ -extern int assoc_expand_once; - -/* The analog for indexed array subscripts */ -extern int array_expand_once; - -/* Flags for array_value_internal and callers array_value/get_array_value; also - used by array_variable_name and array_variable_part. */ -#define AV_ALLOWALL 0x001 /* treat a[@] like $@ and a[*] like $* */ -#define AV_QUOTED 0x002 -#define AV_USEIND 0x004 -#define AV_USEVAL 0x008 /* XXX - should move this */ -#define AV_ASSIGNRHS 0x010 /* no splitting, special case ${a[@]} */ -#define AV_NOEXPAND 0x020 /* don't run assoc subscripts through word expansion */ -#define AV_ONEWORD 0x040 /* not used yet */ -#define AV_ATSTARKEYS 0x080 /* accept a[@] and a[*] but use them as keys, not special values */ - -/* Flags for valid_array_reference. Value 1 is reserved for skipsubscript(). - Also used by unbind_array_element, which is currently the only function - that uses VA_ALLOWALL. */ -#define VA_NOEXPAND 0x001 -#define VA_ONEWORD 0x002 -#define VA_ALLOWALL 0x004 /* allow @ to mean all elements of the array */ - -extern SHELL_VAR *convert_var_to_array PARAMS((SHELL_VAR *)); -extern SHELL_VAR *convert_var_to_assoc PARAMS((SHELL_VAR *)); - -extern char *make_array_variable_value PARAMS((SHELL_VAR *, arrayind_t, char *, char *, int)); - -extern SHELL_VAR *bind_array_variable PARAMS((char *, arrayind_t, char *, int)); -extern SHELL_VAR *bind_array_element PARAMS((SHELL_VAR *, arrayind_t, char *, int)); -extern SHELL_VAR *assign_array_element PARAMS((char *, char *, int, array_eltstate_t *)); - -extern SHELL_VAR *bind_assoc_variable PARAMS((SHELL_VAR *, char *, char *, char *, int)); - -extern SHELL_VAR *find_or_make_array_variable PARAMS((char *, int)); - -extern SHELL_VAR *assign_array_from_string PARAMS((char *, char *, int)); -extern SHELL_VAR *assign_array_var_from_word_list PARAMS((SHELL_VAR *, WORD_LIST *, int)); - -extern WORD_LIST *expand_compound_array_assignment PARAMS((SHELL_VAR *, char *, int)); -extern void assign_compound_array_list PARAMS((SHELL_VAR *, WORD_LIST *, int)); -extern SHELL_VAR *assign_array_var_from_string PARAMS((SHELL_VAR *, char *, int)); - -extern char *expand_and_quote_assoc_word PARAMS((char *, int)); -extern void quote_compound_array_list PARAMS((WORD_LIST *, int)); - -extern int kvpair_assignment_p PARAMS((WORD_LIST *)); -extern char *expand_and_quote_kvpair_word PARAMS((char *)); - -extern int unbind_array_element PARAMS((SHELL_VAR *, char *, int)); -extern int skipsubscript PARAMS((const char *, int, int)); - -extern void print_array_assignment PARAMS((SHELL_VAR *, int)); -extern void print_assoc_assignment PARAMS((SHELL_VAR *, int)); - -extern arrayind_t array_expand_index PARAMS((SHELL_VAR *, char *, int, int)); -extern int valid_array_reference PARAMS((const char *, int)); -extern int tokenize_array_reference PARAMS((char *, int, char **)); - -extern char *array_value PARAMS((const char *, int, int, array_eltstate_t *)); -extern char *get_array_value PARAMS((const char *, int, array_eltstate_t *)); - -extern char *array_keys PARAMS((char *, int, int)); - -extern char *array_variable_name PARAMS((const char *, int, char **, int *)); -extern SHELL_VAR *array_variable_part PARAMS((const char *, int, char **, int *)); - -extern void init_eltstate (array_eltstate_t *); -extern void flush_eltstate (array_eltstate_t *); - -#else - -#define AV_ALLOWALL 0 -#define AV_QUOTED 0 -#define AV_USEIND 0 -#define AV_USEVAL 0 -#define AV_ASSIGNRHS 0 -#define AV_NOEXPAND 0 -#define AV_ONEWORD 0 -#define AV_ATSTARKEYS 0 - -#define VA_NOEXPAND 0 -#define VA_ONEWORD 0 -#define VA_ALLOWALL 0 - -#endif - -#endif /* !_ARRAYFUNC_H_ */ diff --git a/third_party/bash/assoc.c b/third_party/bash/assoc.c deleted file mode 100644 index e29fade75..000000000 --- a/third_party/bash/assoc.c +++ /dev/null @@ -1,611 +0,0 @@ -/* - * assoc.c - functions to manipulate associative arrays - * - * Associative arrays are standard shell hash tables. - * - * Chet Ramey - * chet@ins.cwru.edu - */ - -/* Copyright (C) 2008,2009,2011-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if defined (ARRAY_VARS) - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include -#include "bashansi.h" - -#include "shell.h" -#include "array.h" -#include "assoc.h" -#include "common.h" - -static WORD_LIST *assoc_to_word_list_internal PARAMS((HASH_TABLE *, int)); - -/* assoc_create == hash_create */ - -void -assoc_dispose (hash) - HASH_TABLE *hash; -{ - if (hash) - { - hash_flush (hash, 0); - hash_dispose (hash); - } -} - -void -assoc_flush (hash) - HASH_TABLE *hash; -{ - hash_flush (hash, 0); -} - -int -assoc_insert (hash, key, value) - HASH_TABLE *hash; - char *key; - char *value; -{ - BUCKET_CONTENTS *b; - - b = hash_search (key, hash, HASH_CREATE); - if (b == 0) - return -1; - /* If we are overwriting an existing element's value, we're not going to - use the key. Nothing in the array assignment code path frees the key - string, so we can free it here to avoid a memory leak. */ - if (b->key != key) - free (key); - FREE (b->data); - b->data = value ? savestring (value) : (char *)0; - return (0); -} - -/* Like assoc_insert, but returns b->data instead of freeing it */ -PTR_T -assoc_replace (hash, key, value) - HASH_TABLE *hash; - char *key; - char *value; -{ - BUCKET_CONTENTS *b; - PTR_T t; - - b = hash_search (key, hash, HASH_CREATE); - if (b == 0) - return (PTR_T)0; - /* If we are overwriting an existing element's value, we're not going to - use the key. Nothing in the array assignment code path frees the key - string, so we can free it here to avoid a memory leak. */ - if (b->key != key) - free (key); - t = b->data; - b->data = value ? savestring (value) : (char *)0; - return t; -} - -void -assoc_remove (hash, string) - HASH_TABLE *hash; - char *string; -{ - BUCKET_CONTENTS *b; - - b = hash_remove (string, hash, 0); - if (b) - { - free ((char *)b->data); - free (b->key); - free (b); - } -} - -char * -assoc_reference (hash, string) - HASH_TABLE *hash; - char *string; -{ - BUCKET_CONTENTS *b; - - if (hash == 0) - return (char *)0; - - b = hash_search (string, hash, 0); - return (b ? (char *)b->data : 0); -} - -/* Quote the data associated with each element of the hash table ASSOC, - using quote_string */ -HASH_TABLE * -assoc_quote (h) - HASH_TABLE *h; -{ - int i; - BUCKET_CONTENTS *tlist; - char *t; - - if (h == 0 || assoc_empty (h)) - return ((HASH_TABLE *)NULL); - - for (i = 0; i < h->nbuckets; i++) - for (tlist = hash_items (i, h); tlist; tlist = tlist->next) - { - t = quote_string ((char *)tlist->data); - FREE (tlist->data); - tlist->data = t; - } - - return h; -} - -/* Quote escape characters in the data associated with each element - of the hash table ASSOC, using quote_escapes */ -HASH_TABLE * -assoc_quote_escapes (h) - HASH_TABLE *h; -{ - int i; - BUCKET_CONTENTS *tlist; - char *t; - - if (h == 0 || assoc_empty (h)) - return ((HASH_TABLE *)NULL); - - for (i = 0; i < h->nbuckets; i++) - for (tlist = hash_items (i, h); tlist; tlist = tlist->next) - { - t = quote_escapes ((char *)tlist->data); - FREE (tlist->data); - tlist->data = t; - } - - return h; -} - -HASH_TABLE * -assoc_dequote (h) - HASH_TABLE *h; -{ - int i; - BUCKET_CONTENTS *tlist; - char *t; - - if (h == 0 || assoc_empty (h)) - return ((HASH_TABLE *)NULL); - - for (i = 0; i < h->nbuckets; i++) - for (tlist = hash_items (i, h); tlist; tlist = tlist->next) - { - t = dequote_string ((char *)tlist->data); - FREE (tlist->data); - tlist->data = t; - } - - return h; -} - -HASH_TABLE * -assoc_dequote_escapes (h) - HASH_TABLE *h; -{ - int i; - BUCKET_CONTENTS *tlist; - char *t; - - if (h == 0 || assoc_empty (h)) - return ((HASH_TABLE *)NULL); - - for (i = 0; i < h->nbuckets; i++) - for (tlist = hash_items (i, h); tlist; tlist = tlist->next) - { - t = dequote_escapes ((char *)tlist->data); - FREE (tlist->data); - tlist->data = t; - } - - return h; -} - -HASH_TABLE * -assoc_remove_quoted_nulls (h) - HASH_TABLE *h; -{ - int i; - BUCKET_CONTENTS *tlist; - char *t; - - if (h == 0 || assoc_empty (h)) - return ((HASH_TABLE *)NULL); - - for (i = 0; i < h->nbuckets; i++) - for (tlist = hash_items (i, h); tlist; tlist = tlist->next) - { - t = remove_quoted_nulls ((char *)tlist->data); - tlist->data = t; - } - - return h; -} - -/* - * Return a string whose elements are the members of array H beginning at - * the STARTth element and spanning NELEM members. Null elements are counted. - */ -char * -assoc_subrange (hash, start, nelem, starsub, quoted, pflags) - HASH_TABLE *hash; - arrayind_t start, nelem; - int starsub, quoted, pflags; -{ - WORD_LIST *l, *save, *h, *t; - int i, j; - char *ret; - - if (assoc_empty (hash)) - return ((char *)NULL); - - save = l = assoc_to_word_list (hash); - if (save == 0) - return ((char *)NULL); - - for (i = 1; l && i < start; i++) - l = l->next; - if (l == 0) - { - dispose_words (save); - return ((char *)NULL); - } - for (j = 0,h = t = l; l && j < nelem; j++) - { - t = l; - l = l->next; - } - - t->next = (WORD_LIST *)NULL; - - ret = string_list_pos_params (starsub ? '*' : '@', h, quoted, pflags); - - if (t != l) - t->next = l; - - dispose_words (save); - return (ret); - -} - -char * -assoc_patsub (h, pat, rep, mflags) - HASH_TABLE *h; - char *pat, *rep; - int mflags; -{ - char *t; - int pchar, qflags, pflags; - WORD_LIST *wl, *save; - - if (h == 0 || assoc_empty (h)) - return ((char *)NULL); - - wl = assoc_to_word_list (h); - if (wl == 0) - return (char *)NULL; - - for (save = wl; wl; wl = wl->next) - { - t = pat_subst (wl->word->word, pat, rep, mflags); - FREE (wl->word->word); - wl->word->word = t; - } - - pchar = (mflags & MATCH_STARSUB) == MATCH_STARSUB ? '*' : '@'; - qflags = (mflags & MATCH_QUOTED) == MATCH_QUOTED ? Q_DOUBLE_QUOTES : 0; - pflags = (mflags & MATCH_ASSIGNRHS) == MATCH_ASSIGNRHS ? PF_ASSIGNRHS : 0; - - t = string_list_pos_params (pchar, save, qflags, pflags); - dispose_words (save); - - return t; -} - -char * -assoc_modcase (h, pat, modop, mflags) - HASH_TABLE *h; - char *pat; - int modop; - int mflags; -{ - char *t; - int pchar, qflags, pflags; - WORD_LIST *wl, *save; - - if (h == 0 || assoc_empty (h)) - return ((char *)NULL); - - wl = assoc_to_word_list (h); - if (wl == 0) - return ((char *)NULL); - - for (save = wl; wl; wl = wl->next) - { - t = sh_modcase (wl->word->word, pat, modop); - FREE (wl->word->word); - wl->word->word = t; - } - - pchar = (mflags & MATCH_STARSUB) == MATCH_STARSUB ? '*' : '@'; - qflags = (mflags & MATCH_QUOTED) == MATCH_QUOTED ? Q_DOUBLE_QUOTES : 0; - pflags = (mflags & MATCH_ASSIGNRHS) == MATCH_ASSIGNRHS ? PF_ASSIGNRHS : 0; - - t = string_list_pos_params (pchar, save, qflags, pflags); - dispose_words (save); - - return t; -} - -char * -assoc_to_kvpair (hash, quoted) - HASH_TABLE *hash; - int quoted; -{ - char *ret; - char *istr, *vstr; - int i, rsize, rlen, elen; - BUCKET_CONTENTS *tlist; - - if (hash == 0 || assoc_empty (hash)) - return (char *)0; - - ret = xmalloc (rsize = 128); - ret[rlen = 0] = '\0'; - - for (i = 0; i < hash->nbuckets; i++) - for (tlist = hash_items (i, hash); tlist; tlist = tlist->next) - { - if (ansic_shouldquote (tlist->key)) - istr = ansic_quote (tlist->key, 0, (int *)0); - else if (sh_contains_shell_metas (tlist->key)) - istr = sh_double_quote (tlist->key); - else if (ALL_ELEMENT_SUB (tlist->key[0]) && tlist->key[1] == '\0') - istr = sh_double_quote (tlist->key); - else - istr = tlist->key; - - vstr = tlist->data ? (ansic_shouldquote ((char *)tlist->data) ? - ansic_quote ((char *)tlist->data, 0, (int *)0) : - sh_double_quote ((char *)tlist->data)) - : (char *)0; - - elen = STRLEN (istr) + 4 + STRLEN (vstr); - RESIZE_MALLOCED_BUFFER (ret, rlen, (elen+1), rsize, rsize); - - strcpy (ret+rlen, istr); - rlen += STRLEN (istr); - ret[rlen++] = ' '; - if (vstr) - { - strcpy (ret + rlen, vstr); - rlen += STRLEN (vstr); - } - else - { - strcpy (ret + rlen, "\"\""); - rlen += 2; - } - ret[rlen++] = ' '; - - if (istr != tlist->key) - FREE (istr); - - FREE (vstr); - } - - RESIZE_MALLOCED_BUFFER (ret, rlen, 1, rsize, 8); - ret[rlen] = '\0'; - - if (quoted) - { - vstr = sh_single_quote (ret); - free (ret); - ret = vstr; - } - - return ret; -} - -char * -assoc_to_assign (hash, quoted) - HASH_TABLE *hash; - int quoted; -{ - char *ret; - char *istr, *vstr; - int i, rsize, rlen, elen; - BUCKET_CONTENTS *tlist; - - if (hash == 0 || assoc_empty (hash)) - return (char *)0; - - ret = xmalloc (rsize = 128); - ret[0] = '('; - rlen = 1; - - for (i = 0; i < hash->nbuckets; i++) - for (tlist = hash_items (i, hash); tlist; tlist = tlist->next) - { - if (ansic_shouldquote (tlist->key)) - istr = ansic_quote (tlist->key, 0, (int *)0); - else if (sh_contains_shell_metas (tlist->key)) - istr = sh_double_quote (tlist->key); - else if (ALL_ELEMENT_SUB (tlist->key[0]) && tlist->key[1] == '\0') - istr = sh_double_quote (tlist->key); - else - istr = tlist->key; - - vstr = tlist->data ? (ansic_shouldquote ((char *)tlist->data) ? - ansic_quote ((char *)tlist->data, 0, (int *)0) : - sh_double_quote ((char *)tlist->data)) - : (char *)0; - - elen = STRLEN (istr) + 8 + STRLEN (vstr); - RESIZE_MALLOCED_BUFFER (ret, rlen, (elen+1), rsize, rsize); - - ret[rlen++] = '['; - strcpy (ret+rlen, istr); - rlen += STRLEN (istr); - ret[rlen++] = ']'; - ret[rlen++] = '='; - if (vstr) - { - strcpy (ret + rlen, vstr); - rlen += STRLEN (vstr); - } - ret[rlen++] = ' '; - - if (istr != tlist->key) - FREE (istr); - - FREE (vstr); - } - - RESIZE_MALLOCED_BUFFER (ret, rlen, 1, rsize, 8); - ret[rlen++] = ')'; - ret[rlen] = '\0'; - - if (quoted) - { - vstr = sh_single_quote (ret); - free (ret); - ret = vstr; - } - - return ret; -} - -static WORD_LIST * -assoc_to_word_list_internal (h, t) - HASH_TABLE *h; - int t; -{ - WORD_LIST *list; - int i; - BUCKET_CONTENTS *tlist; - char *w; - - if (h == 0 || assoc_empty (h)) - return((WORD_LIST *)NULL); - list = (WORD_LIST *)NULL; - - for (i = 0; i < h->nbuckets; i++) - for (tlist = hash_items (i, h); tlist; tlist = tlist->next) - { - w = (t == 0) ? (char *)tlist->data : (char *)tlist->key; - list = make_word_list (make_bare_word(w), list); - } - return (REVERSE_LIST(list, WORD_LIST *)); -} - -WORD_LIST * -assoc_to_word_list (h) - HASH_TABLE *h; -{ - return (assoc_to_word_list_internal (h, 0)); -} - -WORD_LIST * -assoc_keys_to_word_list (h) - HASH_TABLE *h; -{ - return (assoc_to_word_list_internal (h, 1)); -} - -WORD_LIST * -assoc_to_kvpair_list (h) - HASH_TABLE *h; -{ - WORD_LIST *list; - int i; - BUCKET_CONTENTS *tlist; - char *k, *v; - - if (h == 0 || assoc_empty (h)) - return((WORD_LIST *)NULL); - list = (WORD_LIST *)NULL; - - for (i = 0; i < h->nbuckets; i++) - for (tlist = hash_items (i, h); tlist; tlist = tlist->next) - { - k = (char *)tlist->key; - v = (char *)tlist->data; - list = make_word_list (make_bare_word (k), list); - list = make_word_list (make_bare_word (v), list); - } - return (REVERSE_LIST(list, WORD_LIST *)); -} - -char * -assoc_to_string (h, sep, quoted) - HASH_TABLE *h; - char *sep; - int quoted; -{ - BUCKET_CONTENTS *tlist; - int i; - char *result, *t, *w; - WORD_LIST *list, *l; - - if (h == 0) - return ((char *)NULL); - if (assoc_empty (h)) - return (savestring ("")); - - result = NULL; - l = list = NULL; - /* This might be better implemented directly, but it's simple to implement - by converting to a word list first, possibly quoting the data, then - using list_string */ - for (i = 0; i < h->nbuckets; i++) - for (tlist = hash_items (i, h); tlist; tlist = tlist->next) - { - w = (char *)tlist->data; - if (w == 0) - continue; - t = quoted ? quote_string (w) : savestring (w); - list = make_word_list (make_bare_word(t), list); - FREE (t); - } - - l = REVERSE_LIST(list, WORD_LIST *); - - result = l ? string_list_internal (l, sep) : savestring (""); - dispose_words (l); - - return result; -} - -#endif /* ARRAY_VARS */ diff --git a/third_party/bash/assoc.h b/third_party/bash/assoc.h deleted file mode 100644 index 664d13740..000000000 --- a/third_party/bash/assoc.h +++ /dev/null @@ -1,66 +0,0 @@ -/* assoc.h -- definitions for the interface exported by assoc.c that allows - the rest of the shell to manipulate associative array variables. */ - -/* Copyright (C) 2008,2009-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#ifndef _ASSOC_H_ -#define _ASSOC_H_ - -#include "stdc.h" -#include "hashlib.h" - -#define ASSOC_HASH_BUCKETS 1024 - -#define assoc_empty(h) ((h)->nentries == 0) -#define assoc_num_elements(h) ((h)->nentries) - -#define assoc_create(n) (hash_create((n))) - -#define assoc_copy(h) (hash_copy((h), 0)) - -#define assoc_walk(h, f) (hash_walk((h), (f)) - -extern void assoc_dispose PARAMS((HASH_TABLE *)); -extern void assoc_flush PARAMS((HASH_TABLE *)); - -extern int assoc_insert PARAMS((HASH_TABLE *, char *, char *)); -extern PTR_T assoc_replace PARAMS((HASH_TABLE *, char *, char *)); -extern void assoc_remove PARAMS((HASH_TABLE *, char *)); - -extern char *assoc_reference PARAMS((HASH_TABLE *, char *)); - -extern char *assoc_subrange PARAMS((HASH_TABLE *, arrayind_t, arrayind_t, int, int, int)); -extern char *assoc_patsub PARAMS((HASH_TABLE *, char *, char *, int)); -extern char *assoc_modcase PARAMS((HASH_TABLE *, char *, int, int)); - -extern HASH_TABLE *assoc_quote PARAMS((HASH_TABLE *)); -extern HASH_TABLE *assoc_quote_escapes PARAMS((HASH_TABLE *)); -extern HASH_TABLE *assoc_dequote PARAMS((HASH_TABLE *)); -extern HASH_TABLE *assoc_dequote_escapes PARAMS((HASH_TABLE *)); -extern HASH_TABLE *assoc_remove_quoted_nulls PARAMS((HASH_TABLE *)); - -extern char *assoc_to_kvpair PARAMS((HASH_TABLE *, int)); -extern char *assoc_to_assign PARAMS((HASH_TABLE *, int)); - -extern WORD_LIST *assoc_to_word_list PARAMS((HASH_TABLE *)); -extern WORD_LIST *assoc_keys_to_word_list PARAMS((HASH_TABLE *)); -extern WORD_LIST *assoc_to_kvpair_list PARAMS((HASH_TABLE *)); - -extern char *assoc_to_string PARAMS((HASH_TABLE *, char *, int)); -#endif /* _ASSOC_H_ */ diff --git a/third_party/bash/bashansi.h b/third_party/bash/bashansi.h deleted file mode 100644 index dd2a544cd..000000000 --- a/third_party/bash/bashansi.h +++ /dev/null @@ -1,38 +0,0 @@ -/* bashansi.h -- Typically included information required by picky compilers. */ - -/* Copyright (C) 1993-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_BASHANSI_H_) -#define _BASHANSI_H_ - -#if defined (HAVE_STRING_H) -# include -#endif /* !HAVE_STRING_H */ - -#if defined (HAVE_STRINGS_H) -# include -#endif /* !HAVE_STRINGS_H */ - -#if defined (HAVE_STDLIB_H) -# include -#else -# include "ansi_stdlib.h" -#endif /* !HAVE_STDLIB_H */ - -#endif /* !_BASHANSI_H_ */ diff --git a/third_party/bash/bashgetopt.c b/third_party/bash/bashgetopt.c deleted file mode 100644 index 7c41d6433..000000000 --- a/third_party/bash/bashgetopt.c +++ /dev/null @@ -1,194 +0,0 @@ -/* bashgetopt.c -- `getopt' for use by the builtins. */ - -/* Copyright (C) 1992-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "bashansi.h" -#include "chartypes.h" -#include - -#include "shell.h" -#include "common.h" - -#include "bashgetopt.h" - -#define ISOPT(s) (((*(s) == '-') || (plus && *(s) == '+')) && (s)[1]) -#define NOTOPT(s) (((*(s) != '-') && (!plus || *(s) != '+')) || (s)[1] == '\0') - -static int sp; - -char *list_optarg; -int list_optflags; -int list_optopt; -int list_opttype; - -static WORD_LIST *lhead = (WORD_LIST *)NULL; -WORD_LIST *lcurrent = (WORD_LIST *)NULL; -WORD_LIST *loptend; /* Points to the first non-option argument in the list */ - -int -internal_getopt(list, opts) -WORD_LIST *list; -char *opts; -{ - register int c; - register char *cp; - int plus; /* nonzero means to handle +option */ - static char errstr[3] = { '-', '\0', '\0' }; - - plus = *opts == '+'; - if (plus) - opts++; - - if (list == 0) { - list_optarg = (char *)NULL; - list_optflags = 0; - loptend = (WORD_LIST *)NULL; /* No non-option arguments */ - return -1; - } - - if (list != lhead || lhead == 0) { - /* Hmmm.... called with a different word list. Reset. */ - sp = 1; - lcurrent = lhead = list; - loptend = (WORD_LIST *)NULL; - } - - if (sp == 1) { - if (lcurrent == 0 || NOTOPT(lcurrent->word->word)) { - lhead = (WORD_LIST *)NULL; - loptend = lcurrent; - return(-1); - } else if (ISHELP (lcurrent->word->word)) { - lhead = (WORD_LIST *)NULL; - loptend = lcurrent; - return (GETOPT_HELP); - } else if (lcurrent->word->word[0] == '-' && - lcurrent->word->word[1] == '-' && - lcurrent->word->word[2] == 0) { - lhead = (WORD_LIST *)NULL; - loptend = lcurrent->next; - return(-1); - } - errstr[0] = list_opttype = lcurrent->word->word[0]; - } - - list_optopt = c = lcurrent->word->word[sp]; - - if (c == ':' || (cp = strchr(opts, c)) == NULL) { - errstr[1] = c; - sh_invalidopt (errstr); - if (lcurrent->word->word[++sp] == '\0') { - lcurrent = lcurrent->next; - sp = 1; - } - list_optarg = NULL; - list_optflags = 0; - if (lcurrent) - loptend = lcurrent->next; - return('?'); - } - - if (*++cp == ':' || *cp == ';') { - /* `:': Option requires an argument. */ - /* `;': option argument may be missing */ - /* We allow -l2 as equivalent to -l 2 */ - if (lcurrent->word->word[sp+1]) { - list_optarg = lcurrent->word->word + sp + 1; - list_optflags = 0; - lcurrent = lcurrent->next; - /* If the specifier is `;', don't set optarg if the next - argument looks like another option. */ -#if 0 - } else if (lcurrent->next && (*cp == ':' || lcurrent->next->word->word[0] != '-')) { -#else - } else if (lcurrent->next && (*cp == ':' || NOTOPT(lcurrent->next->word->word))) { -#endif - lcurrent = lcurrent->next; - list_optarg = lcurrent->word->word; - list_optflags = lcurrent->word->flags; - lcurrent = lcurrent->next; - } else if (*cp == ';') { - list_optarg = (char *)NULL; - list_optflags = 0; - lcurrent = lcurrent->next; - } else { /* lcurrent->next == NULL */ - errstr[1] = c; - sh_needarg (errstr); - sp = 1; - list_optarg = (char *)NULL; - list_optflags = 0; - return('?'); - } - sp = 1; - } else if (*cp == '#') { - /* option requires a numeric argument */ - if (lcurrent->word->word[sp+1]) { - if (DIGIT(lcurrent->word->word[sp+1])) { - list_optarg = lcurrent->word->word + sp + 1; - list_optflags = 0; - lcurrent = lcurrent->next; - } else { - list_optarg = (char *)NULL; - list_optflags = 0; - } - } else { - if (lcurrent->next && legal_number(lcurrent->next->word->word, (intmax_t *)0)) { - lcurrent = lcurrent->next; - list_optarg = lcurrent->word->word; - list_optflags = lcurrent->word->flags; - lcurrent = lcurrent->next; - } else { - errstr[1] = c; - sh_neednumarg (errstr); - sp = 1; - list_optarg = (char *)NULL; - list_optflags = 0; - return ('?'); - } - } - - } else { - /* No argument, just return the option. */ - if (lcurrent->word->word[++sp] == '\0') { - sp = 1; - lcurrent = lcurrent->next; - } - list_optarg = (char *)NULL; - list_optflags = 0; - } - - return(c); -} - -/* - * reset_internal_getopt -- force the in[ft]ernal getopt to reset - */ - -void -reset_internal_getopt () -{ - lhead = lcurrent = loptend = (WORD_LIST *)NULL; - sp = 1; -} diff --git a/third_party/bash/bashgetopt.h b/third_party/bash/bashgetopt.h deleted file mode 100644 index 5ee811ad1..000000000 --- a/third_party/bash/bashgetopt.h +++ /dev/null @@ -1,43 +0,0 @@ -/* bashgetopt.h -- extern declarations for stuff defined in bashgetopt.c. */ - -/* Copyright (C) 1993-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -/* See getopt.h for the explanation of these variables. */ - -#if !defined (__BASH_GETOPT_H) -# define __BASH_GETOPT_H - -#include "stdc.h" - -#define GETOPT_EOF -1 -#define GETOPT_HELP -99 - -extern char *list_optarg; -extern int list_optflags; - -extern int list_optopt; -extern int list_opttype; - -extern WORD_LIST *lcurrent; -extern WORD_LIST *loptend; - -extern int internal_getopt PARAMS((WORD_LIST *, char *)); -extern void reset_internal_getopt PARAMS((void)); - -#endif /* !__BASH_GETOPT_H */ diff --git a/third_party/bash/bashhist.c b/third_party/bash/bashhist.c deleted file mode 100644 index fc7979abf..000000000 --- a/third_party/bash/bashhist.c +++ /dev/null @@ -1,1079 +0,0 @@ -/* bashhist.c -- bash interface to the GNU history library. */ - -/* Copyright (C) 1993-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if defined (HISTORY) - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX - # include -# endif -# include -#endif - -#include "bashtypes.h" -#include -#include -#include "bashansi.h" -#include "posixstat.h" -#include "filecntl.h" - -#include "bashintl.h" - -#if defined (SYSLOG_HISTORY) -# include -#endif - -#include "shell.h" -#include "flags.h" -#include "parser.h" -#include "input.h" -#include "parser.h" /* for the struct dstack stuff. */ -#include "pathexp.h" /* for the struct ignorevar stuff */ -#include "bashhist.h" /* matching prototypes and declarations */ -#include "common.h" - -#include "third_party/readline/history.h" -#include "glob.h" -#include "strmatch.h" - -#if defined (READLINE) -# include "bashline.h" -extern int rl_done, rl_dispatching; /* should really include readline.h */ -#endif - -#ifndef HISTSIZE_DEFAULT -# define HISTSIZE_DEFAULT "500" -#endif - -#if !defined (errno) -extern int errno; -#endif - -static int histignore_item_func PARAMS((struct ign *)); -static int check_history_control PARAMS((char *)); -static void hc_erasedups PARAMS((char *)); -static void really_add_history PARAMS((char *)); - -static struct ignorevar histignore = -{ - "HISTIGNORE", - (struct ign *)0, - 0, - (char *)0, - (sh_iv_item_func_t *)histignore_item_func, -}; - -#define HIGN_EXPAND 0x01 - -/* Declarations of bash history variables. */ -/* Non-zero means to remember lines typed to the shell on the history - list. This is different than the user-controlled behaviour; this - becomes zero when we read lines from a file, for example. */ -int remember_on_history = 0; -int enable_history_list = -1; /* value for `set -o history' */ - -/* The number of lines that Bash has added to this history session. The - difference between the number of the top element in the history list - (offset from history_base) and the number of lines in the history file. - Appending this session's history to the history file resets this to 0. */ -int history_lines_this_session; - -/* The number of lines that Bash has read from the history file. */ -int history_lines_in_file; - -#if defined (BANG_HISTORY) -/* Non-zero means do no history expansion on this line, regardless - of what history_expansion says. */ -int history_expansion_inhibited; -/* If non-zero, double quotes can quote the history expansion character. */ -int double_quotes_inhibit_history_expansion = 0; -#endif - -/* With the old default, every line was saved in the history individually. - I.e., if the user enters: - bash$ for i in a b c - > do - > echo $i - > done - Each line will be individually saved in the history. - bash$ history - 10 for i in a b c - 11 do - 12 echo $i - 13 done - 14 history - If the variable command_oriented_history is set, multiple lines - which form one command will be saved as one history entry. - bash$ for i in a b c - > do - > echo $i - > done - bash$ history - 10 for i in a b c - do - echo $i - done - 11 history - The user can then recall the whole command all at once instead - of just being able to recall one line at a time. - - This is now enabled by default. - */ -int command_oriented_history = 1; - -/* Set to 1 if the first line of a possibly-multi-line command was saved - in the history list. Managed by maybe_add_history(), but global so - the history-manipluating builtins can see it. */ -int current_command_first_line_saved = 0; - -/* Set to the number of the most recent line of a possibly-multi-line command - that contains a shell comment. Used by bash_add_history() to determine - whether to add a newline or a semicolon. */ -int current_command_line_comment = 0; - -/* Non-zero means to store newlines in the history list when using - command_oriented_history rather than trying to use semicolons. */ -int literal_history; - -/* Non-zero means to append the history to the history file at shell - exit, even if the history has been stifled. */ -int force_append_history; - -/* A nit for picking at history saving. Flags have the following values: - - Value == 0 means save all lines parsed by the shell on the history. - Value & HC_IGNSPACE means save all lines that do not start with a space. - Value & HC_IGNDUPS means save all lines that do not match the last - line saved. - Value & HC_ERASEDUPS means to remove all other matching lines from the - history list before saving the latest line. */ -int history_control; - -/* Set to 1 if the last command was added to the history list successfully - as a separate history entry; set to 0 if the line was ignored or added - to a previous entry as part of command-oriented-history processing. */ -int hist_last_line_added; - -/* Set to 1 if builtins/history.def:push_history added the last history - entry. */ -int hist_last_line_pushed; - -#if defined (READLINE) -/* If non-zero, and readline is being used, the user is offered the - chance to re-edit a failed history expansion. */ -int history_reediting; - -/* If non-zero, and readline is being used, don't directly execute a - line with history substitution. Reload it into the editing buffer - instead and let the user further edit and confirm with a newline. */ -int hist_verify; - -#endif /* READLINE */ - -/* Non-zero means to not save function definitions in the history list. */ -int dont_save_function_defs; - -#if defined (BANG_HISTORY) -static int bash_history_inhibit_expansion PARAMS((char *, int)); -#endif -#if defined (READLINE) -static void re_edit PARAMS((char *)); -#endif -static int history_expansion_p PARAMS((char *)); -static int shell_comment PARAMS((char *)); -static int should_expand PARAMS((char *)); -static HIST_ENTRY *last_history_entry PARAMS((void)); -static char *expand_histignore_pattern PARAMS((char *)); -static int history_should_ignore PARAMS((char *)); - -#if defined (BANG_HISTORY) -/* Is the history expansion starting at string[i] one that should not - be expanded? */ -static int -bash_history_inhibit_expansion (string, i) - char *string; - int i; -{ - int t, si; - char hx[2]; - - hx[0] = history_expansion_char; - hx[1] = '\0'; - - /* The shell uses ! as a pattern negation character in globbing [...] - expressions, so let those pass without expansion. */ - if (i > 0 && (string[i - 1] == '[') && member (']', string + i + 1)) - return (1); - /* The shell uses ! as the indirect expansion character, so let those - expansions pass as well. */ - else if (i > 1 && string[i - 1] == '{' && string[i - 2] == '$' && - member ('}', string + i + 1)) - return (1); - /* The shell uses $! as a defined parameter expansion. */ - else if (i > 1 && string[i - 1] == '$' && string[i] == '!') - return (1); -#if defined (EXTENDED_GLOB) - else if (extended_glob && i > 1 && string[i+1] == '(' && member (')', string + i + 2)) - return (1); -#endif - - si = 0; - /* If we're supposed to be in single-quoted string, skip over the - single-quoted part and then look at what's left. */ - if (history_quoting_state == '\'') - { - si = skip_to_delim (string, 0, "'", SD_NOJMP|SD_HISTEXP); - if (string[si] == 0 || si >= i) - return (1); - si++; - } - - /* Make sure the history expansion should not be skipped by quoting or - command/process substitution. */ - if ((t = skip_to_histexp (string, si, hx, SD_NOJMP|SD_HISTEXP)) > 0) - { - /* Skip instances of history expansion appearing on the line before - this one. */ - while (t < i) - { - t = skip_to_histexp (string, t+1, hx, SD_NOJMP|SD_HISTEXP); - if (t <= 0) - return 0; - } - return (t > i); - } - else - return (0); -} -#endif - -void -bash_initialize_history () -{ - history_quotes_inhibit_expansion = 1; - history_search_delimiter_chars = ";&()|<>"; -#if defined (BANG_HISTORY) - history_inhibit_expansion_function = bash_history_inhibit_expansion; - sv_histchars ("histchars"); -#endif -} - -void -bash_history_reinit (interact) - int interact; -{ -#if defined (BANG_HISTORY) - history_expansion = (interact == 0) ? histexp_flag : HISTEXPAND_DEFAULT; - history_expansion_inhibited = (interact == 0) ? 1 - histexp_flag : 0; /* changed in bash_history_enable() */ - history_inhibit_expansion_function = bash_history_inhibit_expansion; -#endif - remember_on_history = enable_history_list; -} - -void -bash_history_disable () -{ - remember_on_history = 0; -#if defined (BANG_HISTORY) - history_expansion_inhibited = 1; -#endif -} - -void -bash_history_enable () -{ - remember_on_history = enable_history_list = 1; -#if defined (BANG_HISTORY) - history_expansion_inhibited = 0; - history_inhibit_expansion_function = bash_history_inhibit_expansion; -#endif - sv_history_control ("HISTCONTROL"); - sv_histignore ("HISTIGNORE"); -} - -/* Load the history list from the history file. */ -void -load_history () -{ - char *hf; - - /* Truncate history file for interactive shells which desire it. - Note that the history file is automatically truncated to the - size of HISTSIZE if the user does not explicitly set the size - differently. */ - set_if_not ("HISTSIZE", HISTSIZE_DEFAULT); - sv_histsize ("HISTSIZE"); - - set_if_not ("HISTFILESIZE", get_string_value ("HISTSIZE")); - sv_histsize ("HISTFILESIZE"); - - /* Read the history in HISTFILE into the history list. */ - hf = get_string_value ("HISTFILE"); - - if (hf && *hf && file_exists (hf)) - { - read_history (hf); - /* We have read all of the lines from the history file, even if we - read more lines than $HISTSIZE. Remember the total number of lines - we read so we don't count the last N lines as new over and over - again. */ - history_lines_in_file = history_lines_read_from_file; - using_history (); - /* history_lines_in_file = where_history () + history_base - 1; */ - } -} - -void -bash_clear_history () -{ - clear_history (); - history_lines_this_session = 0; - /* XXX - reset history_lines_read_from_file? */ -} - -/* Delete and free the history list entry at offset I. */ -int -bash_delete_histent (i) - int i; -{ - HIST_ENTRY *discard; - - discard = remove_history (i); - if (discard) - { - free_history_entry (discard); - history_lines_this_session--; - } - return discard != 0; -} - -int -bash_delete_history_range (first, last) - int first, last; -{ - register int i; - HIST_ENTRY **discard_list; - - discard_list = remove_history_range (first, last); - if (discard_list == 0) - return 0; - for (i = 0; discard_list[i]; i++) - free_history_entry (discard_list[i]); - free (discard_list); - history_lines_this_session -= i; - - return 1; -} - -int -bash_delete_last_history () -{ - register int i; - HIST_ENTRY **hlist, *histent; - int r; - - hlist = history_list (); - if (hlist == NULL) - return 0; - - for (i = 0; hlist[i]; i++) - ; - i--; - - /* History_get () takes a parameter that must be offset by history_base. */ - histent = history_get (history_base + i); /* Don't free this */ - if (histent == NULL) - return 0; - - r = bash_delete_histent (i); - - if (where_history () > history_length) - history_set_pos (history_length); - - return r; -} - -#ifdef INCLUDE_UNUSED -/* Write the existing history out to the history file. */ -void -save_history () -{ - char *hf; - int r; - - hf = get_string_value ("HISTFILE"); - if (hf && *hf && file_exists (hf)) - { - /* Append only the lines that occurred this session to - the history file. */ - using_history (); - - if (history_lines_this_session <= where_history () || force_append_history) - r = append_history (history_lines_this_session, hf); - else - r = write_history (hf); - sv_histsize ("HISTFILESIZE"); - } -} -#endif - -int -maybe_append_history (filename) - char *filename; -{ - int fd, result, histlen; - struct stat buf; - - result = EXECUTION_SUCCESS; - if (history_lines_this_session > 0) - { - /* If the filename was supplied, then create it if necessary. */ - if (stat (filename, &buf) == -1 && errno == ENOENT) - { - fd = open (filename, O_WRONLY|O_CREAT, 0600); - if (fd < 0) - { - builtin_error (_("%s: cannot create: %s"), filename, strerror (errno)); - return (EXECUTION_FAILURE); - } - close (fd); - } - /* cap the number of lines we write at the length of the history list */ - histlen = where_history (); - if (histlen > 0 && history_lines_this_session > histlen) - history_lines_this_session = histlen; /* reset below anyway */ - result = append_history (history_lines_this_session, filename); - /* Pretend we already read these lines from the file because we just - added them */ - history_lines_in_file += history_lines_this_session; - history_lines_this_session = 0; - } - else - history_lines_this_session = 0; /* reset if > where_history() */ - - return (result); -} - -/* If this is an interactive shell, then append the lines executed - this session to the history file. */ -int -maybe_save_shell_history () -{ - int result; - char *hf; - - result = 0; - if (history_lines_this_session > 0) - { - hf = get_string_value ("HISTFILE"); - - if (hf && *hf) - { - /* If the file doesn't exist, then create it. */ - if (file_exists (hf) == 0) - { - int file; - file = open (hf, O_CREAT | O_TRUNC | O_WRONLY, 0600); - if (file != -1) - close (file); - } - - /* Now actually append the lines if the history hasn't been - stifled. If the history has been stifled, rewrite the - history file. */ - using_history (); - if (history_lines_this_session <= where_history () || force_append_history) - { - result = append_history (history_lines_this_session, hf); - history_lines_in_file += history_lines_this_session; - } - else - { - result = write_history (hf); - history_lines_in_file = history_lines_written_to_file; - /* history_lines_in_file = where_history () + history_base - 1; */ - } - history_lines_this_session = 0; - - sv_histsize ("HISTFILESIZE"); - } - } - return (result); -} - -#if defined (READLINE) -/* Tell readline () that we have some text for it to edit. */ -static void -re_edit (text) - char *text; -{ - if (bash_input.type == st_stdin) - bash_re_edit (text); -} -#endif /* READLINE */ - -/* Return 1 if this line needs history expansion. */ -static int -history_expansion_p (line) - char *line; -{ - register char *s; - - for (s = line; *s; s++) - if (*s == history_expansion_char || *s == history_subst_char) - return 1; - return 0; -} - -/* Do pre-processing on LINE. If PRINT_CHANGES is non-zero, then - print the results of expanding the line if there were any changes. - If there is an error, return NULL, otherwise the expanded line is - returned. If ADDIT is non-zero the line is added to the history - list after history expansion. ADDIT is just a suggestion; - REMEMBER_ON_HISTORY can veto, and does. - Right now this does history expansion. */ -char * -pre_process_line (line, print_changes, addit) - char *line; - int print_changes, addit; -{ - char *history_value; - char *return_value; - int expanded; - - return_value = line; - expanded = 0; - -# if defined (BANG_HISTORY) - /* History expand the line. If this results in no errors, then - add that line to the history if ADDIT is non-zero. */ - if (!history_expansion_inhibited && history_expansion && history_expansion_p (line)) - { - int old_len; - - /* If we are expanding the second or later line of a multi-line - command, decrease history_length so references to history expansions - in these lines refer to the previous history entry and not the - current command. */ - old_len = history_length; - if (history_length > 0 && command_oriented_history && current_command_first_line_saved && current_command_line_count > 1) - history_length--; - expanded = history_expand (line, &history_value); - if (history_length >= 0 && command_oriented_history && current_command_first_line_saved && current_command_line_count > 1) - history_length = old_len; - - if (expanded) - { - if (print_changes) - { - if (expanded < 0) - internal_error ("%s", history_value); -#if defined (READLINE) - else if (hist_verify == 0 || expanded == 2) -#else - else -#endif - fprintf (stderr, "%s\n", history_value); - } - - /* If there was an error, return NULL. */ - if (expanded < 0 || expanded == 2) /* 2 == print only */ - { -# if defined (READLINE) - if (expanded == 2 && rl_dispatching == 0 && *history_value) -# else - if (expanded == 2 && *history_value) -# endif /* !READLINE */ - maybe_add_history (history_value); - - free (history_value); - -# if defined (READLINE) - /* New hack. We can allow the user to edit the - failed history expansion. */ - if (history_reediting && expanded < 0 && rl_done) - re_edit (line); -# endif /* READLINE */ - return ((char *)NULL); - } - -# if defined (READLINE) - if (hist_verify && expanded == 1) - { - re_edit (history_value); - free (history_value); - return ((char *)NULL); - } -# endif - } - - /* Let other expansions know that return_value can be free'ed, - and that a line has been added to the history list. Note - that we only add lines that have something in them. */ - expanded = 1; - return_value = history_value; - } -# endif /* BANG_HISTORY */ - - if (addit && remember_on_history && *return_value) - maybe_add_history (return_value); - -#if 0 - if (expanded == 0) - return_value = savestring (line); -#endif - - return (return_value); -} - -/* Return 1 if the first non-whitespace character in LINE is a `#', indicating - that the line is a shell comment. Return 2 if there is a comment after the - first non-whitespace character. Return 0 if the line does not contain a - comment. */ -static int -shell_comment (line) - char *line; -{ - char *p; - int n; - - if (dstack.delimiter_depth != 0 || (parser_state & PST_HEREDOC)) - return 0; - if (line == 0) - return 0; - for (p = line; p && *p && whitespace (*p); p++) - ; - if (p && *p == '#') - return 1; - n = skip_to_delim (line, p - line, "#", SD_NOJMP|SD_GLOB|SD_EXTGLOB|SD_COMPLETE); - return (line[n] == '#') ? 2 : 0; -} - -#ifdef INCLUDE_UNUSED -/* Remove shell comments from LINE. A `#' and anything after it is a comment. - This isn't really useful yet, since it doesn't handle quoting. */ -static char * -filter_comments (line) - char *line; -{ - char *p; - - for (p = line; p && *p && *p != '#'; p++) - ; - if (p && *p == '#') - *p = '\0'; - return (line); -} -#endif - -/* Check LINE against what HISTCONTROL says to do. Returns 1 if the line - should be saved; 0 if it should be discarded. */ -static int -check_history_control (line) - char *line; -{ - HIST_ENTRY *temp; - int r; - - if (history_control == 0) - return 1; - - /* ignorespace or ignoreboth */ - if ((history_control & HC_IGNSPACE) && *line == ' ') - return 0; - - /* ignoredups or ignoreboth */ - if (history_control & HC_IGNDUPS) - { - using_history (); - temp = previous_history (); - - r = (temp == 0 || STREQ (temp->line, line) == 0); - - using_history (); - - if (r == 0) - return r; - } - - return 1; -} - -/* Remove all entries matching LINE from the history list. Triggered when - HISTCONTROL includes `erasedups'. */ -static void -hc_erasedups (line) - char *line; -{ - HIST_ENTRY *temp; - int r; - - using_history (); - while (temp = previous_history ()) - { - if (STREQ (temp->line, line)) - { - r = where_history (); - temp = remove_history (r); - if (temp) - free_history_entry (temp); - } - } - using_history (); -} - -/* Add LINE to the history list, handling possibly multi-line compound - commands. We note whether or not we save the first line of each command - (which is usually the entire command and history entry), and don't add - the second and subsequent lines of a multi-line compound command if we - didn't save the first line. We don't usually save shell comment lines in - compound commands in the history, because they could have the effect of - commenting out the rest of the command when the entire command is saved as - a single history entry (when COMMAND_ORIENTED_HISTORY is enabled). If - LITERAL_HISTORY is set, we're saving lines in the history with embedded - newlines, so it's OK to save comment lines. If we're collecting the body - of a here-document, we should act as if literal_history is enabled, because - we want to save the entire contents of the here-document as it was - entered. We also make sure to save multiple-line quoted strings or other - constructs. */ -void -maybe_add_history (line) - char *line; -{ - int is_comment; - - hist_last_line_added = 0; - is_comment = shell_comment (line); - - /* Don't use the value of history_control to affect the second - and subsequent lines of a multi-line command (old code did - this only when command_oriented_history is enabled). */ - if (current_command_line_count > 1) - { - if (current_command_first_line_saved && - ((parser_state & PST_HEREDOC) || literal_history || dstack.delimiter_depth != 0 || is_comment != 1)) - bash_add_history (line); - current_command_line_comment = is_comment ? current_command_line_count : -2; - return; - } - - /* This is the first line of a (possible multi-line) command. Note whether - or not we should save the first line and remember it. */ - current_command_line_comment = is_comment ? current_command_line_count : -2; - current_command_first_line_saved = check_add_history (line, 0); -} - -/* Just check LINE against HISTCONTROL and HISTIGNORE and add it to the - history if it's OK. Used by `history -s' as well as maybe_add_history(). - Returns 1 if the line was saved in the history, 0 otherwise. */ -int -check_add_history (line, force) - char *line; - int force; -{ - if (check_history_control (line) && history_should_ignore (line) == 0) - { - /* We're committed to saving the line. If the user has requested it, - remove other matching lines from the history. */ - if (history_control & HC_ERASEDUPS) - hc_erasedups (line); - - if (force) - { - really_add_history (line); - using_history (); - } - else - bash_add_history (line); - return 1; - } - return 0; -} - -#if defined (SYSLOG_HISTORY) -#define SYSLOG_MAXMSG 1024 -#define SYSLOG_MAXLEN SYSLOG_MAXMSG -#define SYSLOG_MAXHDR 256 - -#ifndef OPENLOG_OPTS -#define OPENLOG_OPTS 0 -#endif - -#if defined (SYSLOG_SHOPT) -int syslog_history = SYSLOG_SHOPT; -#else -int syslog_history = 1; -#endif - -void -bash_syslog_history (line) - const char *line; -{ - char trunc[SYSLOG_MAXLEN], *msg; - char loghdr[SYSLOG_MAXHDR]; - char seqbuf[32], *seqnum; - int hdrlen, msglen, seqlen, chunks, i; - static int first = 1; - - if (first) - { - openlog (shell_name, OPENLOG_OPTS, SYSLOG_FACILITY); - first = 0; - } - - hdrlen = snprintf (loghdr, sizeof(loghdr), "HISTORY: PID=%d UID=%d", getpid(), current_user.uid); - msglen = strlen (line); - - if ((msglen + hdrlen + 1) < SYSLOG_MAXLEN) - syslog (SYSLOG_FACILITY|SYSLOG_LEVEL, "%s %s", loghdr, line); - else - { - chunks = ((msglen + hdrlen) / SYSLOG_MAXLEN) + 1; - for (msg = line, i = 0; i < chunks; i++) - { - seqnum = inttostr (i + 1, seqbuf, sizeof (seqbuf)); - seqlen = STRLEN (seqnum); - - /* 7 == "(seq=) " */ - strncpy (trunc, msg, SYSLOG_MAXLEN - hdrlen - seqlen - 7 - 1); - trunc[SYSLOG_MAXLEN - 1] = '\0'; - syslog (SYSLOG_FACILITY|SYSLOG_LEVEL, "%s (seq=%s) %s", loghdr, seqnum, trunc); - msg += SYSLOG_MAXLEN - hdrlen - seqlen - 8; - } - } -} -#endif - -/* Add a line to the history list. - The variable COMMAND_ORIENTED_HISTORY controls the style of history - remembering; when non-zero, and LINE is not the first line of a - complete parser construct, append LINE to the last history line instead - of adding it as a new line. */ -void -bash_add_history (line) - char *line; -{ - int add_it, offset, curlen, is_comment; - HIST_ENTRY *current, *old; - char *chars_to_add, *new_line; - - add_it = 1; - if (command_oriented_history && current_command_line_count > 1) - { - is_comment = shell_comment (line); - - /* The second and subsequent lines of a here document have the trailing - newline preserved. We don't want to add extra newlines here, but we - do want to add one after the first line (which is the command that - contains the here-doc specifier). parse.y:history_delimiting_chars() - does the right thing to take care of this for us. We don't want to - add extra newlines if the user chooses to enable literal_history, - so we have to duplicate some of what that function does here. */ - /* If we're in a here document and past the first line, - (current_command_line_count > 2) - don't add a newline here. This will also take care of the literal_history - case if the other conditions are met. */ - if ((parser_state & PST_HEREDOC) && here_doc_first_line == 0 && line[strlen (line) - 1] == '\n') - chars_to_add = ""; - else if (current_command_line_count == current_command_line_comment+1) - chars_to_add = "\n"; - else if (literal_history) - chars_to_add = "\n"; - else - chars_to_add = history_delimiting_chars (line); - - using_history (); - current = previous_history (); - - current_command_line_comment = is_comment ? current_command_line_count : -2; - - if (current) - { - /* If the previous line ended with an escaped newline (escaped - with backslash, but otherwise unquoted), then remove the quoted - newline, since that is what happens when the line is parsed. */ - curlen = strlen (current->line); - - if (dstack.delimiter_depth == 0 && current->line[curlen - 1] == '\\' && - current->line[curlen - 2] != '\\') - { - current->line[curlen - 1] = '\0'; - curlen--; - chars_to_add = ""; - } - - /* If we're not in some kind of quoted construct, the current history - entry ends with a newline, and we're going to add a semicolon, - don't. In some cases, it results in a syntax error (e.g., before - a close brace), and it should not be needed. */ - if (dstack.delimiter_depth == 0 && current->line[curlen - 1] == '\n' && *chars_to_add == ';') - chars_to_add++; - - new_line = (char *)xmalloc (1 - + curlen - + strlen (line) - + strlen (chars_to_add)); - sprintf (new_line, "%s%s%s", current->line, chars_to_add, line); - offset = where_history (); - old = replace_history_entry (offset, new_line, current->data); - free (new_line); - - if (old) - free_history_entry (old); - - add_it = 0; - } - } - - if (add_it && history_is_stifled() && history_length == 0 && history_length == history_max_entries) - add_it = 0; - - if (add_it) - really_add_history (line); - -#if defined (SYSLOG_HISTORY) - if (syslog_history) - bash_syslog_history (line); -#endif - - using_history (); -} - -static void -really_add_history (line) - char *line; -{ - hist_last_line_added = 1; - hist_last_line_pushed = 0; - add_history (line); - history_lines_this_session++; -} - -int -history_number () -{ - using_history (); - return ((remember_on_history || enable_history_list) ? history_base + where_history () : 1); -} - -static int -should_expand (s) - char *s; -{ - char *p; - - for (p = s; p && *p; p++) - { - if (*p == '\\') - p++; - else if (*p == '&') - return 1; - } - return 0; -} - -static int -histignore_item_func (ign) - struct ign *ign; -{ - if (should_expand (ign->val)) - ign->flags |= HIGN_EXPAND; - return (0); -} - -void -setup_history_ignore (varname) - char *varname; -{ - setup_ignore_patterns (&histignore); -} - -static HIST_ENTRY * -last_history_entry () -{ - HIST_ENTRY *he; - - using_history (); - he = previous_history (); - using_history (); - return he; -} - -char * -last_history_line () -{ - HIST_ENTRY *he; - - he = last_history_entry (); - if (he == 0) - return ((char *)NULL); - return he->line; -} - -static char * -expand_histignore_pattern (pat) - char *pat; -{ - HIST_ENTRY *phe; - char *ret; - - phe = last_history_entry (); - - if (phe == (HIST_ENTRY *)0) - return (savestring (pat)); - - ret = strcreplace (pat, '&', phe->line, 1); - - return ret; -} - -/* Return 1 if we should not put LINE into the history according to the - patterns in HISTIGNORE. */ -static int -history_should_ignore (line) - char *line; -{ - register int i, match; - char *npat; - - if (histignore.num_ignores == 0) - return 0; - - for (i = match = 0; i < histignore.num_ignores; i++) - { - if (histignore.ignores[i].flags & HIGN_EXPAND) - npat = expand_histignore_pattern (histignore.ignores[i].val); - else - npat = histignore.ignores[i].val; - - match = strmatch (npat, line, FNMATCH_EXTFLAG) != FNM_NOMATCH; - - if (histignore.ignores[i].flags & HIGN_EXPAND) - free (npat); - - if (match) - break; - } - - return match; -} -#endif /* HISTORY */ diff --git a/third_party/bash/bashhist.h b/third_party/bash/bashhist.h deleted file mode 100644 index 615f5d256..000000000 --- a/third_party/bash/bashhist.h +++ /dev/null @@ -1,89 +0,0 @@ -/* bashhist.h -- interface to the bash history functions in bashhist.c. */ - -/* Copyright (C) 1993-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_BASHHIST_H_) -#define _BASHHIST_H_ - -#include "stdc.h" - -/* Flag values for history_control */ -#define HC_IGNSPACE 0x01 -#define HC_IGNDUPS 0x02 -#define HC_ERASEDUPS 0x04 - -#define HC_IGNBOTH (HC_IGNSPACE|HC_IGNDUPS) - -#if defined (STRICT_POSIX) -# undef HISTEXPAND_DEFAULT -# define HISTEXPAND_DEFAULT 0 -#else -# if !defined (HISTEXPAND_DEFAULT) -# define HISTEXPAND_DEFAULT 1 -# endif /* !HISTEXPAND_DEFAULT */ -#endif - -extern int remember_on_history; -extern int enable_history_list; /* value for `set -o history' */ -extern int literal_history; /* controlled by `shopt lithist' */ -extern int force_append_history; -extern int history_lines_this_session; -extern int history_lines_in_file; -extern int history_expansion; -extern int history_control; -extern int command_oriented_history; -extern int current_command_first_line_saved; -extern int current_command_first_line_comment; -extern int hist_last_line_added; -extern int hist_last_line_pushed; - -extern int dont_save_function_defs; - -# if defined (READLINE) -extern int hist_verify; -# endif - -# if defined (BANG_HISTORY) -extern int history_expansion_inhibited; -extern int double_quotes_inhibit_history_expansion; -# endif /* BANG_HISTORY */ - -extern void bash_initialize_history PARAMS((void)); -extern void bash_history_reinit PARAMS((int)); -extern void bash_history_disable PARAMS((void)); -extern void bash_history_enable PARAMS((void)); -extern void bash_clear_history PARAMS((void)); -extern int bash_delete_histent PARAMS((int)); -extern int bash_delete_history_range PARAMS((int, int)); -extern int bash_delete_last_history PARAMS((void)); -extern void load_history PARAMS((void)); -extern void save_history PARAMS((void)); -extern int maybe_append_history PARAMS((char *)); -extern int maybe_save_shell_history PARAMS((void)); -extern char *pre_process_line PARAMS((char *, int, int)); -extern void maybe_add_history PARAMS((char *)); -extern void bash_add_history PARAMS((char *)); -extern int check_add_history PARAMS((char *, int)); -extern int history_number PARAMS((void)); - -extern void setup_history_ignore PARAMS((char *)); - -extern char *last_history_line PARAMS((void)); - -#endif /* _BASHHIST_H_ */ diff --git a/third_party/bash/bashintl.h b/third_party/bash/bashintl.h deleted file mode 100644 index dd3268331..000000000 --- a/third_party/bash/bashintl.h +++ /dev/null @@ -1,54 +0,0 @@ -/* bashintl.h -- Internationalization functions and defines. */ - -/* Copyright (C) 1996-2009 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_BASHINTL_H_) -#define _BASHINTL_H_ - -#if defined (BUILDTOOL) -# undef ENABLE_NLS -# define ENABLE_NLS 0 -#endif - -/* Include this *after* config.h */ -#include "gettext.h" - -#if defined (HAVE_LOCALE_H) -# include -#endif - -#define _(msgid) gettext(msgid) -#define N_(msgid) msgid -#define D_(d, msgid) dgettext(d, msgid) - -#define P_(m1, m2, n) ngettext(m1, m2, n) - -#if defined (HAVE_SETLOCALE) && !defined (LC_ALL) -# undef HAVE_SETLOCALE -#endif - -#if !defined (HAVE_SETLOCALE) -# define setlocale(cat, loc) -#endif - -#if !defined (HAVE_LOCALE_H) || !defined (HAVE_LOCALECONV) -# define locale_decpoint() '.' -#endif - -#endif /* !_BASHINTL_H_ */ diff --git a/third_party/bash/bashjmp.h b/third_party/bash/bashjmp.h deleted file mode 100644 index 1a4721bc8..000000000 --- a/third_party/bash/bashjmp.h +++ /dev/null @@ -1,47 +0,0 @@ -/* bashjmp.h -- wrapper for setjmp.h with necessary bash definitions. */ - -/* Copyright (C) 1987-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#ifndef _BASHJMP_H_ -#define _BASHJMP_H_ - -#include "posixjmp.h" - -extern procenv_t top_level; -extern procenv_t subshell_top_level; -extern procenv_t return_catch; /* used by `return' builtin */ -extern procenv_t wait_intr_buf; - -extern int no_longjmp_on_fatal_error; - -#define SHFUNC_RETURN() sh_longjmp (return_catch, 1) - -#define COPY_PROCENV(old, save) \ - xbcopy ((char *)old, (char *)save, sizeof (procenv_t)); - -/* Values for the second argument to longjmp/siglongjmp. */ -#define NOT_JUMPED 0 /* Not returning from a longjmp. */ -#define FORCE_EOF 1 /* We want to stop parsing. */ -#define DISCARD 2 /* Discard current command. */ -#define EXITPROG 3 /* Unconditionally exit the program now. */ -#define ERREXIT 4 /* Exit due to error condition */ -#define SIGEXIT 5 /* Exit due to fatal terminating signal */ -#define EXITBLTIN 6 /* Exit due to the exit builtin. */ - -#endif /* _BASHJMP_H_ */ diff --git a/third_party/bash/bashline.c b/third_party/bash/bashline.c deleted file mode 100644 index 2870bd927..000000000 --- a/third_party/bash/bashline.c +++ /dev/null @@ -1,4839 +0,0 @@ -/* bashline.c -- Bash's interface to the readline library. */ - -/* Copyright (C) 1987-2022 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if defined (READLINE) - -#include "bashtypes.h" -#include "posixstat.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#if defined (HAVE_GRP_H) -# include -#endif - -#if defined (HAVE_NETDB_H) -# include -#endif - -#include - -#include -#include "chartypes.h" -#include "bashansi.h" -#include "bashintl.h" - -#include "shell.h" -#include "input.h" -#include "parser.h" -#include "builtins.h" -#include "bashhist.h" -#include "bashline.h" -#include "execute_cmd.h" -#include "findcmd.h" -#include "pathexp.h" -#include "shmbutil.h" -#include "trap.h" -#include "flags.h" -#include "timer.h" - -#if defined (HAVE_MBSTR_H) && defined (HAVE_MBSCHR) -# include /* mbschr */ -#endif - -#include "common.h" -#include "builtext.h" /* for read_builtin */ - -#include "third_party/readline/rlconf.h" -#include "third_party/readline/readline.h" -#include "third_party/readline/history.h" -#include "third_party/readline/rlmbutil.h" - -#include "glob.h" - -#if defined (ALIAS) -# include "alias.h" -#endif - -#if defined (PROGRAMMABLE_COMPLETION) -# include "pcomplete.h" -#endif - -/* These should agree with the defines for emacs_mode and vi_mode in - rldefs.h, even though that's not a public readline header file. */ -#ifndef EMACS_EDITING_MODE -# define NO_EDITING_MODE -1 -# define EMACS_EDITING_MODE 1 -# define VI_EDITING_MODE 0 -#endif - -/* Copied from rldefs.h, since that's not a public readline header file. */ -#ifndef FUNCTION_TO_KEYMAP - -#if defined (CRAY) -# define FUNCTION_TO_KEYMAP(map, key) (Keymap)((int)map[key].function) -# define KEYMAP_TO_FUNCTION(data) (rl_command_func_t *)((int)(data)) -#else -# define FUNCTION_TO_KEYMAP(map, key) (Keymap)(map[key].function) -# define KEYMAP_TO_FUNCTION(data) (rl_command_func_t *)(data) -#endif - -#endif - -#define RL_BOOLEAN_VARIABLE_VALUE(s) ((s)[0] == 'o' && (s)[1] == 'n' && (s)[2] == '\0') - -#if defined (BRACE_COMPLETION) -extern int bash_brace_completion PARAMS((int, int)); -#endif /* BRACE_COMPLETION */ - -/* To avoid including curses.h/term.h/termcap.h and that whole mess. */ -#ifdef _MINIX -extern int tputs PARAMS((const char *string, int nlines, void (*outx)(int))); -#else -extern int tputs PARAMS((const char *string, int nlines, int (*outx)(int))); -#endif - -/* Forward declarations */ - -/* Functions bound to keys in Readline for Bash users. */ -static int shell_expand_line PARAMS((int, int)); -static int display_shell_version PARAMS((int, int)); - -static int bash_ignore_filenames PARAMS((char **)); -static int bash_ignore_everything PARAMS((char **)); -static int bash_progcomp_ignore_filenames PARAMS((char **)); - -#if defined (BANG_HISTORY) -static char *history_expand_line_internal PARAMS((char *)); -static int history_expand_line PARAMS((int, int)); -static int tcsh_magic_space PARAMS((int, int)); -#endif /* BANG_HISTORY */ -#ifdef ALIAS -static int alias_expand_line PARAMS((int, int)); -#endif -#if defined (BANG_HISTORY) && defined (ALIAS) -static int history_and_alias_expand_line PARAMS((int, int)); -#endif - -static int bash_forward_shellword PARAMS((int, int)); -static int bash_backward_shellword PARAMS((int, int)); -static int bash_kill_shellword PARAMS((int, int)); -static int bash_backward_kill_shellword PARAMS((int, int)); -static int bash_transpose_shellwords PARAMS((int, int)); - -static int bash_spell_correct_shellword PARAMS((int, int)); - -/* Helper functions for Readline. */ -static char *restore_tilde PARAMS((char *, char *)); -static char *maybe_restore_tilde PARAMS((char *, char *)); - -static char *bash_filename_rewrite_hook PARAMS((char *, int)); - -static void bash_directory_expansion PARAMS((char **)); -static int bash_filename_stat_hook PARAMS((char **)); -static int bash_command_name_stat_hook PARAMS((char **)); -static int bash_directory_completion_hook PARAMS((char **)); -static int filename_completion_ignore PARAMS((char **)); -static int bash_push_line PARAMS((void)); - -static int executable_completion PARAMS((const char *, int)); - -static rl_icppfunc_t *save_directory_hook PARAMS((void)); -static void restore_directory_hook PARAMS((rl_icppfunc_t)); - -static int directory_exists PARAMS((const char *, int)); - -static void cleanup_expansion_error PARAMS((void)); -static void maybe_make_readline_line PARAMS((char *)); -static void set_up_new_line PARAMS((char *)); - -static int check_redir PARAMS((int)); -static char **attempt_shell_completion PARAMS((const char *, int, int)); -static char *variable_completion_function PARAMS((const char *, int)); -static char *hostname_completion_function PARAMS((const char *, int)); -static char *command_subst_completion_function PARAMS((const char *, int)); - -static void build_history_completion_array PARAMS((void)); -static char *history_completion_generator PARAMS((const char *, int)); -static int dynamic_complete_history PARAMS((int, int)); -static int bash_dabbrev_expand PARAMS((int, int)); - -static void initialize_hostname_list PARAMS((void)); -static void add_host_name PARAMS((char *)); -static void snarf_hosts_from_file PARAMS((char *)); -static char **hostnames_matching PARAMS((char *)); - -static void _ignore_completion_names PARAMS((char **, sh_ignore_func_t *)); -static int name_is_acceptable PARAMS((const char *)); -static int test_for_directory PARAMS((const char *)); -static int test_for_canon_directory PARAMS((const char *)); -static int return_zero PARAMS((const char *)); - -static char *bash_dequote_filename PARAMS((char *, int)); -static char *quote_word_break_chars PARAMS((char *)); -static int bash_check_expchar PARAMS((char *, int, int *, int *)); -static void set_filename_quote_chars PARAMS((int, int, int)); -static void set_filename_bstab PARAMS((const char *)); -static char *bash_quote_filename PARAMS((char *, int, char *)); - -#ifdef _MINIX -static void putx PARAMS((int)); -#else -static int putx PARAMS((int)); -#endif -static int readline_get_char_offset PARAMS((int)); -static void readline_set_char_offset PARAMS((int, int *)); - -static Keymap get_cmd_xmap_from_edit_mode PARAMS((void)); -static Keymap get_cmd_xmap_from_keymap PARAMS((Keymap)); - -static void init_unix_command_map PARAMS((void)); -static int isolate_sequence PARAMS((char *, int, int, int *)); - -static int set_saved_history PARAMS((void)); - -#if defined (ALIAS) -static int posix_edit_macros PARAMS((int, int)); -#endif - -static int bash_event_hook PARAMS((void)); - -#if defined (PROGRAMMABLE_COMPLETION) -static int find_cmd_start PARAMS((int)); -static int find_cmd_end PARAMS((int)); -static char *find_cmd_name PARAMS((int, int *, int *)); -static char *prog_complete_return PARAMS((const char *, int)); - -static char **prog_complete_matches; -#endif - -extern int no_symbolic_links; -extern STRING_INT_ALIST word_token_alist[]; -extern sh_timer *read_timeout; - -/* SPECIFIC_COMPLETION_FUNCTIONS specifies that we have individual - completion functions which indicate what type of completion should be - done (at or before point) that can be bound to key sequences with - the readline library. */ -#define SPECIFIC_COMPLETION_FUNCTIONS - -#if defined (SPECIFIC_COMPLETION_FUNCTIONS) -static int bash_specific_completion PARAMS((int, rl_compentry_func_t *)); - -static int bash_complete_filename_internal PARAMS((int)); -static int bash_complete_username_internal PARAMS((int)); -static int bash_complete_hostname_internal PARAMS((int)); -static int bash_complete_variable_internal PARAMS((int)); -static int bash_complete_command_internal PARAMS((int)); - -static int bash_complete_filename PARAMS((int, int)); -static int bash_possible_filename_completions PARAMS((int, int)); -static int bash_complete_username PARAMS((int, int)); -static int bash_possible_username_completions PARAMS((int, int)); -static int bash_complete_hostname PARAMS((int, int)); -static int bash_possible_hostname_completions PARAMS((int, int)); -static int bash_complete_variable PARAMS((int, int)); -static int bash_possible_variable_completions PARAMS((int, int)); -static int bash_complete_command PARAMS((int, int)); -static int bash_possible_command_completions PARAMS((int, int)); - -static int completion_glob_pattern PARAMS((char *)); -static char *glob_complete_word PARAMS((const char *, int)); -static int bash_glob_completion_internal PARAMS((int)); -static int bash_glob_complete_word PARAMS((int, int)); -static int bash_glob_expand_word PARAMS((int, int)); -static int bash_glob_list_expansions PARAMS((int, int)); - -#endif /* SPECIFIC_COMPLETION_FUNCTIONS */ - -static int edit_and_execute_command PARAMS((int, int, int, char *)); -#if defined (VI_MODE) -static int vi_edit_and_execute_command PARAMS((int, int)); -static int bash_vi_complete PARAMS((int, int)); -#endif -static int emacs_edit_and_execute_command PARAMS((int, int)); - -/* Non-zero once initialize_readline () has been called. */ -int bash_readline_initialized = 0; - -/* If non-zero, we do hostname completion, breaking words at `@' and - trying to complete the stuff after the `@' from our own internal - host list. */ -int perform_hostname_completion = 1; - -/* If non-zero, we don't do command completion on an empty line. */ -int no_empty_command_completion; - -/* Set FORCE_FIGNORE if you want to honor FIGNORE even if it ignores the - only possible matches. Set to 0 if you want to match filenames if they - are the only possible matches, even if FIGNORE says to. */ -int force_fignore = 1; - -/* Perform spelling correction on directory names during word completion */ -int dircomplete_spelling = 0; - -/* Expand directory names during word/filename completion. */ -#if DIRCOMPLETE_EXPAND_DEFAULT -int dircomplete_expand = 1; -int dircomplete_expand_relpath = 1; -#else -int dircomplete_expand = 0; -int dircomplete_expand_relpath = 0; -#endif - -/* When non-zero, perform `normal' shell quoting on completed filenames - even when the completed name contains a directory name with a shell - variable reference, so dollar signs in a filename get quoted appropriately. - Set to zero to remove dollar sign (and braces or parens as needed) from - the set of characters that will be quoted. */ -int complete_fullquote = 1; - -static char *bash_completer_word_break_characters = " \t\n\"'@><=;|&(:"; -static char *bash_nohostname_word_break_characters = " \t\n\"'><=;|&(:"; -/* )) */ - -static const char *default_filename_quote_characters = " \t\n\\\"'@<>=;|&()#$`?*[!:{~"; /*}*/ -static char *custom_filename_quote_characters = 0; -static char filename_bstab[256]; - -static rl_hook_func_t *old_rl_startup_hook = (rl_hook_func_t *)NULL; - -static int dot_in_path = 0; - -/* Set to non-zero when dabbrev-expand is running */ -static int dabbrev_expand_active = 0; - -/* What kind of quoting is performed by bash_quote_filename: - COMPLETE_DQUOTE = double-quoting the filename - COMPLETE_SQUOTE = single_quoting the filename - COMPLETE_BSQUOTE = backslash-quoting special chars in the filename -*/ -#define COMPLETE_DQUOTE 1 -#define COMPLETE_SQUOTE 2 -#define COMPLETE_BSQUOTE 3 -static int completion_quoting_style = COMPLETE_BSQUOTE; - -/* Flag values for the final argument to bash_default_completion */ -#define DEFCOMP_CMDPOS 1 - -static rl_command_func_t *vi_tab_binding = rl_complete; - -/* Change the readline VI-mode keymaps into or out of Posix.2 compliance. - Called when the shell is put into or out of `posix' mode. */ -void -posix_readline_initialize (on_or_off) - int on_or_off; -{ - static char kseq[2] = { CTRL ('I'), 0 }; /* TAB */ - - if (on_or_off) - rl_variable_bind ("comment-begin", "#"); -#if defined (VI_MODE) - if (on_or_off) - { - vi_tab_binding = rl_function_of_keyseq (kseq, vi_insertion_keymap, (int *)NULL); - rl_bind_key_in_map (CTRL ('I'), rl_insert, vi_insertion_keymap); - } - else - { - if (rl_function_of_keyseq (kseq, vi_insertion_keymap, (int *)NULL) == rl_insert) - rl_bind_key_in_map (CTRL ('I'), vi_tab_binding, vi_insertion_keymap); - } -#endif -} - -void -reset_completer_word_break_chars () -{ - rl_completer_word_break_characters = perform_hostname_completion ? savestring (bash_completer_word_break_characters) : savestring (bash_nohostname_word_break_characters); -} - -/* When this function returns, rl_completer_word_break_characters points to - dynamically allocated memory. */ -int -enable_hostname_completion (on_or_off) - int on_or_off; -{ - int old_value; - char *nv, *nval; - const char *at; - - old_value = perform_hostname_completion; - - if (on_or_off) - { - perform_hostname_completion = 1; - rl_special_prefixes = "$@"; - } - else - { - perform_hostname_completion = 0; - rl_special_prefixes = "$"; - } - - /* Now we need to figure out how to appropriately modify and assign - rl_completer_word_break_characters depending on whether we want - hostname completion on or off. */ - - /* If this is the first time this has been called - (bash_readline_initialized == 0), use the sames values as before, but - allocate new memory for rl_completer_word_break_characters. */ - - if (bash_readline_initialized == 0 && - (rl_completer_word_break_characters == 0 || - rl_completer_word_break_characters == rl_basic_word_break_characters)) - { - if (on_or_off) - rl_completer_word_break_characters = savestring (bash_completer_word_break_characters); - else - rl_completer_word_break_characters = savestring (bash_nohostname_word_break_characters); - } - else - { - /* See if we have anything to do. */ - at = strchr (rl_completer_word_break_characters, '@'); - if ((at == 0 && on_or_off == 0) || (at != 0 && on_or_off != 0)) - return old_value; - - /* We have something to do. Do it. */ - nval = (char *)xmalloc (strlen (rl_completer_word_break_characters) + 1 + on_or_off); - - if (on_or_off == 0) - { - /* Turn it off -- just remove `@' from word break chars. We want - to remove all occurrences of `@' from the char list, so we loop - rather than just copy the rest of the list over AT. */ - for (nv = nval, at = rl_completer_word_break_characters; *at; ) - if (*at != '@') - *nv++ = *at++; - else - at++; - *nv = '\0'; - } - else - { - nval[0] = '@'; - strcpy (nval + 1, rl_completer_word_break_characters); - } - - free ((void *)rl_completer_word_break_characters); - rl_completer_word_break_characters = nval; - } - - return (old_value); -} - -/* Called once from parse.y if we are going to use readline. */ -void -initialize_readline () -{ - rl_command_func_t *func; - char kseq[2]; - - if (bash_readline_initialized) - return; - - rl_terminal_name = get_string_value ("TERM"); - rl_instream = stdin; - rl_outstream = stderr; - - /* Allow conditional parsing of the ~/.inputrc file. */ - rl_readline_name = "Bash"; - - /* Add bindable names before calling rl_initialize so they may be - referenced in the various inputrc files. */ - rl_add_defun ("shell-expand-line", shell_expand_line, -1); -#ifdef BANG_HISTORY - rl_add_defun ("history-expand-line", history_expand_line, -1); - rl_add_defun ("magic-space", tcsh_magic_space, -1); -#endif - - rl_add_defun ("shell-forward-word", bash_forward_shellword, -1); - rl_add_defun ("shell-backward-word", bash_backward_shellword, -1); - rl_add_defun ("shell-kill-word", bash_kill_shellword, -1); - rl_add_defun ("shell-backward-kill-word", bash_backward_kill_shellword, -1); - rl_add_defun ("shell-transpose-words", bash_transpose_shellwords, -1); - - rl_add_defun ("spell-correct-word", bash_spell_correct_shellword, -1); - rl_bind_key_if_unbound_in_map ('s', bash_spell_correct_shellword, emacs_ctlx_keymap); - -#ifdef ALIAS - rl_add_defun ("alias-expand-line", alias_expand_line, -1); -# ifdef BANG_HISTORY - rl_add_defun ("history-and-alias-expand-line", history_and_alias_expand_line, -1); -# endif -#endif - - /* Backwards compatibility. */ - rl_add_defun ("insert-last-argument", rl_yank_last_arg, -1); - - rl_add_defun ("display-shell-version", display_shell_version, -1); - rl_add_defun ("edit-and-execute-command", emacs_edit_and_execute_command, -1); -#if defined (VI_MODE) - rl_add_defun ("vi-edit-and-execute-command", vi_edit_and_execute_command, -1); -#endif - -#if defined (BRACE_COMPLETION) - rl_add_defun ("complete-into-braces", bash_brace_completion, -1); -#endif - -#if defined (SPECIFIC_COMPLETION_FUNCTIONS) - rl_add_defun ("complete-filename", bash_complete_filename, -1); - rl_add_defun ("possible-filename-completions", bash_possible_filename_completions, -1); - rl_add_defun ("complete-username", bash_complete_username, -1); - rl_add_defun ("possible-username-completions", bash_possible_username_completions, -1); - rl_add_defun ("complete-hostname", bash_complete_hostname, -1); - rl_add_defun ("possible-hostname-completions", bash_possible_hostname_completions, -1); - rl_add_defun ("complete-variable", bash_complete_variable, -1); - rl_add_defun ("possible-variable-completions", bash_possible_variable_completions, -1); - rl_add_defun ("complete-command", bash_complete_command, -1); - rl_add_defun ("possible-command-completions", bash_possible_command_completions, -1); - rl_add_defun ("glob-complete-word", bash_glob_complete_word, -1); - rl_add_defun ("glob-expand-word", bash_glob_expand_word, -1); - rl_add_defun ("glob-list-expansions", bash_glob_list_expansions, -1); -#endif - - rl_add_defun ("dynamic-complete-history", dynamic_complete_history, -1); - rl_add_defun ("dabbrev-expand", bash_dabbrev_expand, -1); - - /* Bind defaults before binding our custom shell keybindings. */ - if (RL_ISSTATE(RL_STATE_INITIALIZED) == 0) - rl_initialize (); - - /* Bind up our special shell functions. */ - rl_bind_key_if_unbound_in_map (CTRL('E'), shell_expand_line, emacs_meta_keymap); - -#ifdef BANG_HISTORY - rl_bind_key_if_unbound_in_map ('^', history_expand_line, emacs_meta_keymap); -#endif - - rl_bind_key_if_unbound_in_map (CTRL ('V'), display_shell_version, emacs_ctlx_keymap); - - /* In Bash, the user can switch editing modes with "set -o [vi emacs]", - so it is not necessary to allow C-M-j for context switching. Turn - off this occasionally confusing behaviour. */ - kseq[0] = CTRL('J'); - kseq[1] = '\0'; - func = rl_function_of_keyseq (kseq, emacs_meta_keymap, (int *)NULL); - if (func == rl_vi_editing_mode) - rl_unbind_key_in_map (CTRL('J'), emacs_meta_keymap); - kseq[0] = CTRL('M'); - func = rl_function_of_keyseq (kseq, emacs_meta_keymap, (int *)NULL); - if (func == rl_vi_editing_mode) - rl_unbind_key_in_map (CTRL('M'), emacs_meta_keymap); -#if defined (VI_MODE) - kseq[0] = CTRL('E'); - func = rl_function_of_keyseq (kseq, vi_movement_keymap, (int *)NULL); - if (func == rl_emacs_editing_mode) - rl_unbind_key_in_map (CTRL('E'), vi_movement_keymap); -#endif - -#if defined (BRACE_COMPLETION) - rl_bind_key_if_unbound_in_map ('{', bash_brace_completion, emacs_meta_keymap); /*}*/ -#endif /* BRACE_COMPLETION */ - -#if defined (SPECIFIC_COMPLETION_FUNCTIONS) - rl_bind_key_if_unbound_in_map ('/', bash_complete_filename, emacs_meta_keymap); - rl_bind_key_if_unbound_in_map ('/', bash_possible_filename_completions, emacs_ctlx_keymap); - - /* Have to jump through hoops here because there is a default binding for - M-~ (rl_tilde_expand) */ - kseq[0] = '~'; - kseq[1] = '\0'; - func = rl_function_of_keyseq (kseq, emacs_meta_keymap, (int *)NULL); - if (func == 0 || func == rl_tilde_expand) - rl_bind_keyseq_in_map (kseq, bash_complete_username, emacs_meta_keymap); - - rl_bind_key_if_unbound_in_map ('~', bash_possible_username_completions, emacs_ctlx_keymap); - - rl_bind_key_if_unbound_in_map ('@', bash_complete_hostname, emacs_meta_keymap); - rl_bind_key_if_unbound_in_map ('@', bash_possible_hostname_completions, emacs_ctlx_keymap); - - rl_bind_key_if_unbound_in_map ('$', bash_complete_variable, emacs_meta_keymap); - rl_bind_key_if_unbound_in_map ('$', bash_possible_variable_completions, emacs_ctlx_keymap); - - rl_bind_key_if_unbound_in_map ('!', bash_complete_command, emacs_meta_keymap); - rl_bind_key_if_unbound_in_map ('!', bash_possible_command_completions, emacs_ctlx_keymap); - - rl_bind_key_if_unbound_in_map ('g', bash_glob_complete_word, emacs_meta_keymap); - rl_bind_key_if_unbound_in_map ('*', bash_glob_expand_word, emacs_ctlx_keymap); - rl_bind_key_if_unbound_in_map ('g', bash_glob_list_expansions, emacs_ctlx_keymap); - -#endif /* SPECIFIC_COMPLETION_FUNCTIONS */ - - kseq[0] = TAB; - kseq[1] = '\0'; - func = rl_function_of_keyseq (kseq, emacs_meta_keymap, (int *)NULL); - if (func == 0 || func == rl_tab_insert) - rl_bind_key_in_map (TAB, dynamic_complete_history, emacs_meta_keymap); - - /* Tell the completer that we want a crack first. */ - rl_attempted_completion_function = attempt_shell_completion; - - /* Tell the completer that we might want to follow symbolic links or - do other expansion on directory names. */ - set_directory_hook (); - - rl_filename_rewrite_hook = bash_filename_rewrite_hook; - - rl_filename_stat_hook = bash_filename_stat_hook; - - /* Tell the filename completer we want a chance to ignore some names. */ - rl_ignore_some_completions_function = filename_completion_ignore; - - /* Bind C-xC-e to invoke emacs and run result as commands. */ - rl_bind_key_if_unbound_in_map (CTRL ('E'), emacs_edit_and_execute_command, emacs_ctlx_keymap); -#if defined (VI_MODE) - rl_bind_key_if_unbound_in_map ('v', vi_edit_and_execute_command, vi_movement_keymap); -# if defined (ALIAS) - rl_bind_key_if_unbound_in_map ('@', posix_edit_macros, vi_movement_keymap); -# endif - - rl_bind_key_in_map ('\\', bash_vi_complete, vi_movement_keymap); - rl_bind_key_in_map ('*', bash_vi_complete, vi_movement_keymap); - rl_bind_key_in_map ('=', bash_vi_complete, vi_movement_keymap); -#endif - - rl_completer_quote_characters = "'\""; - - /* This sets rl_completer_word_break_characters and rl_special_prefixes - to the appropriate values, depending on whether or not hostname - completion is enabled. */ - enable_hostname_completion (perform_hostname_completion); - - /* characters that need to be quoted when appearing in filenames. */ - rl_filename_quote_characters = default_filename_quote_characters; - set_filename_bstab (rl_filename_quote_characters); - - rl_filename_quoting_function = bash_quote_filename; - rl_filename_dequoting_function = bash_dequote_filename; - rl_char_is_quoted_p = char_is_quoted; - - /* Add some default bindings for the "shellwords" functions, roughly - parallelling the default word bindings in emacs mode. */ - rl_bind_key_if_unbound_in_map (CTRL('B'), bash_backward_shellword, emacs_meta_keymap); - rl_bind_key_if_unbound_in_map (CTRL('D'), bash_kill_shellword, emacs_meta_keymap); - rl_bind_key_if_unbound_in_map (CTRL('F'), bash_forward_shellword, emacs_meta_keymap); - rl_bind_key_if_unbound_in_map (CTRL('T'), bash_transpose_shellwords, emacs_meta_keymap); - -#if 0 - /* This is superfluous and makes it impossible to use tab completion in - vi mode even when explicitly binding it in ~/.inputrc. sv_strict_posix() - should already have called posix_readline_initialize() when - posixly_correct was set. */ - if (posixly_correct) - posix_readline_initialize (1); -#endif - - bash_readline_initialized = 1; -} - -void -bashline_reinitialize () -{ - bash_readline_initialized = 0; -} - -void -bashline_set_event_hook () -{ - rl_signal_event_hook = bash_event_hook; -} - -void -bashline_reset_event_hook () -{ - rl_signal_event_hook = 0; -} - -/* On Sun systems at least, rl_attempted_completion_function can end up - getting set to NULL, and rl_completion_entry_function set to do command - word completion if Bash is interrupted while trying to complete a command - word. This just resets all the completion functions to the right thing. - It's called from throw_to_top_level(). */ -void -bashline_reset () -{ - tilde_initialize (); - rl_attempted_completion_function = attempt_shell_completion; - rl_completion_entry_function = NULL; - rl_ignore_some_completions_function = filename_completion_ignore; - - complete_fullquote = 1; - rl_filename_quote_characters = default_filename_quote_characters; - set_filename_bstab (rl_filename_quote_characters); - - set_directory_hook (); - rl_filename_stat_hook = bash_filename_stat_hook; - - bashline_reset_event_hook (); - - rl_sort_completion_matches = 1; -} - -/* Contains the line to push into readline. */ -static char *push_to_readline = (char *)NULL; - -/* Push the contents of push_to_readline into the - readline buffer. */ -static int -bash_push_line () -{ - if (push_to_readline) - { - rl_insert_text (push_to_readline); - free (push_to_readline); - push_to_readline = (char *)NULL; - rl_startup_hook = old_rl_startup_hook; - } - return 0; -} - -/* Call this to set the initial text for the next line to read - from readline. */ -int -bash_re_edit (line) - char *line; -{ - FREE (push_to_readline); - - push_to_readline = savestring (line); - old_rl_startup_hook = rl_startup_hook; - rl_startup_hook = bash_push_line; - - return (0); -} - -static int -display_shell_version (count, c) - int count, c; -{ - rl_crlf (); - show_shell_version (0); - putc ('\r', rl_outstream); - fflush (rl_outstream); - rl_on_new_line (); - rl_redisplay (); - return 0; -} - -/* **************************************************************** */ -/* */ -/* Readline Stuff */ -/* */ -/* **************************************************************** */ - -/* If the user requests hostname completion, then simply build a list - of hosts, and complete from that forever more, or at least until - HOSTFILE is unset. */ - -/* THIS SHOULD BE A STRINGLIST. */ -/* The kept list of hostnames. */ -static char **hostname_list = (char **)NULL; - -/* The physical size of the above list. */ -static int hostname_list_size; - -/* The number of hostnames in the above list. */ -static int hostname_list_length; - -/* Whether or not HOSTNAME_LIST has been initialized. */ -int hostname_list_initialized = 0; - -/* Initialize the hostname completion table. */ -static void -initialize_hostname_list () -{ - char *temp; - - temp = get_string_value ("HOSTFILE"); - if (temp == 0) - temp = get_string_value ("hostname_completion_file"); - if (temp == 0) - temp = DEFAULT_HOSTS_FILE; - - snarf_hosts_from_file (temp); - - if (hostname_list) - hostname_list_initialized++; -} - -/* Add NAME to the list of hosts. */ -static void -add_host_name (name) - char *name; -{ - if (hostname_list_length + 2 > hostname_list_size) - { - hostname_list_size = (hostname_list_size + 32) - (hostname_list_size % 32); - hostname_list = strvec_resize (hostname_list, hostname_list_size); - } - - hostname_list[hostname_list_length++] = savestring (name); - hostname_list[hostname_list_length] = (char *)NULL; -} - -#define cr_whitespace(c) ((c) == '\r' || (c) == '\n' || whitespace(c)) - -static void -snarf_hosts_from_file (filename) - char *filename; -{ - FILE *file; - char *temp, buffer[256], name[256]; - register int i, start; - - file = fopen (filename, "r"); - if (file == 0) - return; - - while (temp = fgets (buffer, 255, file)) - { - /* Skip to first character. */ - for (i = 0; buffer[i] && cr_whitespace (buffer[i]); i++) - ; - - /* If comment or blank line, ignore. */ - if (buffer[i] == '\0' || buffer[i] == '#') - continue; - - /* If `preprocessor' directive, do the include. */ - if (strncmp (buffer + i, "$include ", 9) == 0) - { - char *incfile, *t; - - /* Find start of filename. */ - for (incfile = buffer + i + 9; *incfile && whitespace (*incfile); incfile++) - ; - - /* Find end of filename. */ - for (t = incfile; *t && cr_whitespace (*t) == 0; t++) - ; - - *t = '\0'; - - snarf_hosts_from_file (incfile); - continue; - } - - /* Skip internet address if present. */ - if (DIGIT (buffer[i])) - for (; buffer[i] && cr_whitespace (buffer[i]) == 0; i++); - - /* Gobble up names. Each name is separated with whitespace. */ - while (buffer[i]) - { - for (; cr_whitespace (buffer[i]); i++) - ; - if (buffer[i] == '\0' || buffer[i] == '#') - break; - - /* Isolate the current word. */ - for (start = i; buffer[i] && cr_whitespace (buffer[i]) == 0; i++) - ; - if (i == start) - continue; - strncpy (name, buffer + start, i - start); - name[i - start] = '\0'; - add_host_name (name); - } - } - fclose (file); -} - -/* Return the hostname list. */ -char ** -get_hostname_list () -{ - if (hostname_list_initialized == 0) - initialize_hostname_list (); - return (hostname_list); -} - -void -clear_hostname_list () -{ - register int i; - - if (hostname_list_initialized == 0) - return; - for (i = 0; i < hostname_list_length; i++) - free (hostname_list[i]); - hostname_list_length = hostname_list_initialized = 0; -} - -/* Return a NULL terminated list of hostnames which begin with TEXT. - Initialize the hostname list the first time if necessary. - The array is malloc ()'ed, but not the individual strings. */ -static char ** -hostnames_matching (text) - char *text; -{ - register int i, len, nmatch, rsize; - char **result; - - if (hostname_list_initialized == 0) - initialize_hostname_list (); - - if (hostname_list_initialized == 0) - return ((char **)NULL); - - /* Special case. If TEXT consists of nothing, then the whole list is - what is desired. */ - if (*text == '\0') - { - result = strvec_create (1 + hostname_list_length); - for (i = 0; i < hostname_list_length; i++) - result[i] = hostname_list[i]; - result[i] = (char *)NULL; - return (result); - } - - /* Scan until found, or failure. */ - len = strlen (text); - result = (char **)NULL; - for (i = nmatch = rsize = 0; i < hostname_list_length; i++) - { - if (STREQN (text, hostname_list[i], len) == 0) - continue; - - /* OK, it matches. Add it to the list. */ - if (nmatch >= (rsize - 1)) - { - rsize = (rsize + 16) - (rsize % 16); - result = strvec_resize (result, rsize); - } - - result[nmatch++] = hostname_list[i]; - } - if (nmatch) - result[nmatch] = (char *)NULL; - return (result); -} - -/* This vi mode command causes VI_EDIT_COMMAND to be run on the current - command being entered (if no explicit argument is given), otherwise on - a command from the history file. */ - -#define VI_EDIT_COMMAND "fc -e \"${VISUAL:-${EDITOR:-vi}}\"" -#define EMACS_EDIT_COMMAND "fc -e \"${VISUAL:-${EDITOR:-emacs}}\"" -#define POSIX_VI_EDIT_COMMAND "fc -e vi" - -static int -edit_and_execute_command (count, c, editing_mode, edit_command) - int count, c, editing_mode; - char *edit_command; -{ - char *command, *metaval; - int r, rrs, metaflag; - sh_parser_state_t ps; - - rrs = rl_readline_state; - saved_command_line_count = current_command_line_count; - - /* Accept the current line. */ - rl_newline (1, c); - - if (rl_explicit_arg) - { - command = (char *)xmalloc (strlen (edit_command) + 8); - sprintf (command, "%s %d", edit_command, count); - } - else - { - /* Take the command we were just editing, add it to the history file, - then call fc to operate on it. We have to add a dummy command to - the end of the history because fc ignores the last command (assumes - it's supposed to deal with the command before the `fc'). */ - /* This breaks down when using command-oriented history and are not - finished with the command, so we should not ignore the last command */ - using_history (); - current_command_line_count++; /* for rl_newline above */ - bash_add_history (rl_line_buffer); - current_command_line_count = 0; /* for dummy history entry */ - bash_add_history (""); - history_lines_this_session++; - using_history (); - command = savestring (edit_command); - } - - metaval = rl_variable_value ("input-meta"); - metaflag = RL_BOOLEAN_VARIABLE_VALUE (metaval); - - if (rl_deprep_term_function) - (*rl_deprep_term_function) (); - rl_clear_signals (); - save_parser_state (&ps); - r = parse_and_execute (command, (editing_mode == VI_EDITING_MODE) ? "v" : "C-xC-e", SEVAL_NOHIST); - restore_parser_state (&ps); - - /* if some kind of reset_parser was called, undo it. */ - reset_readahead_token (); - - if (rl_prep_term_function) - (*rl_prep_term_function) (metaflag); - rl_set_signals (); - - current_command_line_count = saved_command_line_count; - - /* Now erase the contents of the current line and undo the effects of the - rl_accept_line() above. We don't even want to make the text we just - executed available for undoing. */ - rl_line_buffer[0] = '\0'; /* XXX */ - rl_point = rl_end = 0; - rl_done = 0; - rl_readline_state = rrs; - -#if defined (VI_MODE) - if (editing_mode == VI_EDITING_MODE) - rl_vi_insertion_mode (1, c); -#endif - - rl_forced_update_display (); - - return r; -} - -#if defined (VI_MODE) -static int -vi_edit_and_execute_command (count, c) - int count, c; -{ - if (posixly_correct) - return (edit_and_execute_command (count, c, VI_EDITING_MODE, POSIX_VI_EDIT_COMMAND)); - else - return (edit_and_execute_command (count, c, VI_EDITING_MODE, VI_EDIT_COMMAND)); -} -#endif /* VI_MODE */ - -static int -emacs_edit_and_execute_command (count, c) - int count, c; -{ - return (edit_and_execute_command (count, c, EMACS_EDITING_MODE, EMACS_EDIT_COMMAND)); -} - -#if defined (ALIAS) -static int -posix_edit_macros (count, key) - int count, key; -{ - int c; - char alias_name[3], *alias_value, *macro; - - c = rl_read_key (); - if (c <= 0) - return 0; - alias_name[0] = '_'; - alias_name[1] = c; - alias_name[2] = '\0'; - - alias_value = get_alias_value (alias_name); - if (alias_value && *alias_value) - { - macro = savestring (alias_value); - rl_push_macro_input (macro); - } - return 0; -} -#endif - -/* Bindable commands that move `shell-words': that is, sequences of - non-unquoted-metacharacters. */ - -#define WORDDELIM(c) (shellmeta(c) || shellblank(c)) - -static int -bash_forward_shellword (count, key) - int count, key; -{ - size_t slen; - int c, p; - DECLARE_MBSTATE; - - if (count < 0) - return (bash_backward_shellword (-count, key)); - - /* The tricky part of this is deciding whether or not the first character - we're on is an unquoted metacharacter. Not completely handled yet. */ - /* XXX - need to test this stuff with backslash-escaped shell - metacharacters and unclosed single- and double-quoted strings. */ - - p = rl_point; - slen = rl_end; - - while (count) - { - if (p == rl_end) - { - rl_point = rl_end; - return 0; - } - - /* Are we in a quoted string? If we are, move to the end of the quoted - string and continue the outer loop. We only want quoted strings, not - backslash-escaped characters, but char_is_quoted doesn't - differentiate. */ - if (char_is_quoted (rl_line_buffer, p) && p > 0 && rl_line_buffer[p-1] != '\\') - { - do - ADVANCE_CHAR (rl_line_buffer, slen, p); - while (p < rl_end && char_is_quoted (rl_line_buffer, p)); - count--; - continue; - } - - /* Rest of code assumes we are not in a quoted string. */ - /* Move forward until we hit a non-metacharacter. */ - while (p < rl_end && (c = rl_line_buffer[p]) && WORDDELIM (c)) - { - switch (c) - { - default: - ADVANCE_CHAR (rl_line_buffer, slen, p); - continue; /* straight back to loop, don't increment p */ - case '\\': - if (p < rl_end && rl_line_buffer[p]) - ADVANCE_CHAR (rl_line_buffer, slen, p); - break; - case '\'': - p = skip_to_delim (rl_line_buffer, ++p, "'", SD_NOJMP); - break; - case '"': - p = skip_to_delim (rl_line_buffer, ++p, "\"", SD_NOJMP); - break; - } - - if (p < rl_end) - p++; - } - - if (rl_line_buffer[p] == 0 || p == rl_end) - { - rl_point = rl_end; - rl_ding (); - return 0; - } - - /* Now move forward until we hit a non-quoted metacharacter or EOL */ - while (p < rl_end && (c = rl_line_buffer[p]) && WORDDELIM (c) == 0) - { - switch (c) - { - default: - ADVANCE_CHAR (rl_line_buffer, slen, p); - continue; /* straight back to loop, don't increment p */ - case '\\': - if (p < rl_end && rl_line_buffer[p]) - ADVANCE_CHAR (rl_line_buffer, slen, p); - break; - case '\'': - p = skip_to_delim (rl_line_buffer, ++p, "'", SD_NOJMP); - break; - case '"': - p = skip_to_delim (rl_line_buffer, ++p, "\"", SD_NOJMP); - break; - } - - if (p < rl_end) - p++; - } - - if (p == rl_end || rl_line_buffer[p] == 0) - { - rl_point = rl_end; - return (0); - } - - count--; - } - - rl_point = p; - return (0); -} - -static int -bash_backward_shellword (count, key) - int count, key; -{ - size_t slen; - int c, p, prev_p; - DECLARE_MBSTATE; - - if (count < 0) - return (bash_forward_shellword (-count, key)); - - p = rl_point; - slen = rl_end; - - while (count) - { - if (p == 0) - { - rl_point = 0; - return 0; - } - - /* Move backward until we hit a non-metacharacter. We want to deal - with the characters before point, so we move off a word if we're - at its first character. */ - BACKUP_CHAR (rl_line_buffer, slen, p); - while (p > 0) - { - c = rl_line_buffer[p]; - if (WORDDELIM (c) == 0 || char_is_quoted (rl_line_buffer, p)) - break; - BACKUP_CHAR (rl_line_buffer, slen, p); - } - - if (p == 0) - { - rl_point = 0; - return 0; - } - - /* Now move backward until we hit a metacharacter or BOL. Leave point - at the start of the shellword or at BOL. */ - prev_p = p; - while (p > 0) - { - c = rl_line_buffer[p]; - if (WORDDELIM (c) && char_is_quoted (rl_line_buffer, p) == 0) - { - p = prev_p; - break; - } - prev_p = p; - BACKUP_CHAR (rl_line_buffer, slen, p); - } - - count--; - } - - rl_point = p; - return 0; -} - -static int -bash_kill_shellword (count, key) - int count, key; -{ - int p; - - if (count < 0) - return (bash_backward_kill_shellword (-count, key)); - - p = rl_point; - bash_forward_shellword (count, key); - - if (rl_point != p) - rl_kill_text (p, rl_point); - - rl_point = p; - if (rl_editing_mode == EMACS_EDITING_MODE) /* 1 == emacs_mode */ - rl_mark = rl_point; - - return 0; -} - -static int -bash_backward_kill_shellword (count, key) - int count, key; -{ - int p; - - if (count < 0) - return (bash_kill_shellword (-count, key)); - - p = rl_point; - bash_backward_shellword (count, key); - - if (rl_point != p) - rl_kill_text (p, rl_point); - - if (rl_editing_mode == EMACS_EDITING_MODE) /* 1 == emacs_mode */ - rl_mark = rl_point; - - return 0; -} - -static int -bash_transpose_shellwords (count, key) - int count, key; -{ - char *word1, *word2; - int w1_beg, w1_end, w2_beg, w2_end; - int orig_point = rl_point; - - if (count == 0) - return 0; - - /* Find the two shell words. */ - bash_forward_shellword (count, key); - w2_end = rl_point; - bash_backward_shellword (1, key); - w2_beg = rl_point; - bash_backward_shellword (count, key); - w1_beg = rl_point; - bash_forward_shellword (1, key); - w1_end = rl_point; - - /* check that there really are two words. */ - if ((w1_beg == w2_beg) || (w2_beg < w1_end)) - { - rl_ding (); - rl_point = orig_point; - return 1; - } - - /* Get the text of the words. */ - word1 = rl_copy_text (w1_beg, w1_end); - word2 = rl_copy_text (w2_beg, w2_end); - - /* We are about to do many insertions and deletions. Remember them - as one operation. */ - rl_begin_undo_group (); - - /* Do the stuff at word2 first, so that we don't have to worry - about word1 moving. */ - rl_point = w2_beg; - rl_delete_text (w2_beg, w2_end); - rl_insert_text (word1); - - rl_point = w1_beg; - rl_delete_text (w1_beg, w1_end); - rl_insert_text (word2); - - /* This is exactly correct since the text before this point has not - changed in length. */ - rl_point = w2_end; - - /* I think that does it. */ - rl_end_undo_group (); - xfree (word1); - xfree (word2); - - return 0; -} - -/* Directory name spelling correction on the current word (not shellword). - COUNT > 1 is not exactly correct yet. */ -static int -bash_spell_correct_shellword (count, key) - int count, key; -{ - int opoint, wbeg, wend; - char *text, *newdir; - - opoint = rl_point; - while (count) - { - bash_backward_shellword (1, key); - wbeg = rl_point; - bash_forward_shellword (1, key); - wend = rl_point; - - if (wbeg > wend) - break; - - text = rl_copy_text (wbeg, wend); - - newdir = dirspell (text); - if (newdir) - { - rl_begin_undo_group (); - rl_delete_text (wbeg, wend); - rl_point = wbeg; - if (*newdir) - rl_insert_text (newdir); - rl_mark = wbeg; - rl_end_undo_group (); - } - - free (text); - free (newdir); - - if (rl_point >= rl_end) - break; - - count--; - - if (count) - bash_forward_shellword (1, key); /* XXX */ - } - - return 0; -} - -/* **************************************************************** */ -/* */ -/* How To Do Shell Completion */ -/* */ -/* **************************************************************** */ - -#define COMMAND_SEPARATORS ";|&{(`" -/* )} */ -#define COMMAND_SEPARATORS_PLUS_WS ";|&{(` \t" -/* )} */ - -/* check for redirections and other character combinations that are not - command separators */ -static int -check_redir (ti) - int ti; -{ - register int this_char, prev_char; - - /* Handle the two character tokens `>&', `<&', and `>|'. - We are not in a command position after one of these. */ - this_char = rl_line_buffer[ti]; - prev_char = (ti > 0) ? rl_line_buffer[ti - 1] : 0; - - if ((this_char == '&' && (prev_char == '<' || prev_char == '>')) || - (this_char == '|' && prev_char == '>')) - return (1); - else if (this_char == '{' && prev_char == '$') /*}*/ - return (1); -#if 0 /* Not yet */ - else if (this_char == '(' && prev_char == '$') /*)*/ - return (1); - else if (this_char == '(' && prev_char == '<') /*)*/ - return (1); -#if defined (EXTENDED_GLOB) - else if (extended_glob && this_char == '(' && prev_char == '!') /*)*/ - return (1); -#endif -#endif - else if (char_is_quoted (rl_line_buffer, ti)) - return (1); - return (0); -} - -#if defined (PROGRAMMABLE_COMPLETION) -/* - * XXX - because of the <= start test, and setting os = s+1, this can - * potentially return os > start. This is probably not what we want to - * happen, but fix later after 2.05a-release. - */ -static int -find_cmd_start (start) - int start; -{ - register int s, os, ns; - - os = 0; - /* Flags == SD_NOJMP only because we want to skip over command substitutions - in assignment statements. Have to test whether this affects `standalone' - command substitutions as individual words. */ - while (((s = skip_to_delim (rl_line_buffer, os, COMMAND_SEPARATORS, SD_NOJMP|SD_COMPLETE/*|SD_NOSKIPCMD*/)) <= start) && - rl_line_buffer[s]) - { - /* Handle >| token crudely; treat as > not | */ - if (s > 0 && rl_line_buffer[s] == '|' && rl_line_buffer[s-1] == '>') - { - ns = skip_to_delim (rl_line_buffer, s+1, COMMAND_SEPARATORS, SD_NOJMP|SD_COMPLETE/*|SD_NOSKIPCMD*/); - if (ns > start || rl_line_buffer[ns] == 0) - return os; - os = ns+1; - continue; - } - /* The only reserved word in COMMAND_SEPARATORS is `{', so handle that - specially, making sure it's in a spot acceptable for reserved words */ - if (s >= os && rl_line_buffer[s] == '{') - { - int pc, nc; /* index of previous non-whitespace, next char */ - for (pc = (s > os) ? s - 1 : os; pc > os && whitespace(rl_line_buffer[pc]); pc--) - ; - nc = rl_line_buffer[s+1]; - /* must be preceded by a command separator or be the first non- - whitespace character since the last command separator, and - followed by a shell break character (not another `{') to be a reserved word. */ - if ((pc > os && (rl_line_buffer[s-1] == '{' || strchr (COMMAND_SEPARATORS, rl_line_buffer[pc]) == 0)) || - (shellbreak(nc) == 0)) /* }} */ - { - /* Not a reserved word, look for another delim */ - ns = skip_to_delim (rl_line_buffer, s+1, COMMAND_SEPARATORS, SD_NOJMP|SD_COMPLETE/*|SD_NOSKIPCMD*/); - if (ns > start || rl_line_buffer[ns] == 0) - return os; - os = ns+1; - continue; - } - } - os = s+1; - } - return os; -} - -static int -find_cmd_end (end) - int end; -{ - register int e; - - e = skip_to_delim (rl_line_buffer, end, COMMAND_SEPARATORS, SD_NOJMP|SD_COMPLETE); - return e; -} - -static char * -find_cmd_name (start, sp, ep) - int start; - int *sp, *ep; -{ - char *name; - register int s, e; - - for (s = start; whitespace (rl_line_buffer[s]); s++) - ; - - /* skip until a shell break character */ - e = skip_to_delim (rl_line_buffer, s, "()<>;&| \t\n", SD_NOJMP|SD_COMPLETE); - - name = substring (rl_line_buffer, s, e); - - if (sp) - *sp = s; - if (ep) - *ep = e; - - return (name); -} - -static char * -prog_complete_return (text, matchnum) - const char *text; - int matchnum; -{ - static int ind; - - if (matchnum == 0) - ind = 0; - - if (prog_complete_matches == 0 || prog_complete_matches[ind] == 0) - return (char *)NULL; - return (prog_complete_matches[ind++]); -} - -#endif /* PROGRAMMABLE_COMPLETION */ - -/* Try and catch completion attempts that are syntax errors or otherwise - invalid. */ -static int -invalid_completion (text, ind) - const char *text; - int ind; -{ - int pind; - - /* If we don't catch these here, the next clause will */ - if (ind > 0 && rl_line_buffer[ind] == '(' && /*)*/ - member (rl_line_buffer[ind-1], "$<>")) - return 0; - - pind = ind - 1; - while (pind > 0 && whitespace (rl_line_buffer[pind])) - pind--; - /* If we have only whitespace preceding a paren, it's valid */ - if (ind >= 0 && pind <= 0 && rl_line_buffer[ind] == '(') /*)*/ - return 0; - /* Flag the invalid completions, which are mostly syntax errors */ - if (ind > 0 && rl_line_buffer[ind] == '(' && /*)*/ - member (rl_line_buffer[pind], COMMAND_SEPARATORS) == 0) - return 1; - - return 0; -} - -/* Do some completion on TEXT. The indices of TEXT in RL_LINE_BUFFER are - at START and END. Return an array of matches, or NULL if none. */ -static char ** -attempt_shell_completion (text, start, end) - const char *text; - int start, end; -{ - int in_command_position, ti, qc, dflags; - char **matches, *command_separator_chars; -#if defined (PROGRAMMABLE_COMPLETION) - int have_progcomps, was_assignment; - COMPSPEC *iw_compspec; -#endif - - command_separator_chars = COMMAND_SEPARATORS; - matches = (char **)NULL; - rl_ignore_some_completions_function = filename_completion_ignore; - - complete_fullquote = 1; /* full filename quoting by default */ - rl_filename_quote_characters = default_filename_quote_characters; - set_filename_bstab (rl_filename_quote_characters); - set_directory_hook (); - rl_filename_stat_hook = bash_filename_stat_hook; - - rl_sort_completion_matches = 1; /* sort by default */ - - /* Determine if this could be a command word. It is if it appears at - the start of the line (ignoring preceding whitespace), or if it - appears after a character that separates commands. It cannot be a - command word if we aren't at the top-level prompt. */ - ti = start - 1; - qc = -1; - - while ((ti > -1) && (whitespace (rl_line_buffer[ti]))) - ti--; - -#if 1 - /* If this is an open quote, maybe we're trying to complete a quoted - command name. */ - if (ti >= 0 && (rl_line_buffer[ti] == '"' || rl_line_buffer[ti] == '\'')) - { - qc = rl_line_buffer[ti]; - ti--; - while (ti > -1 && (whitespace (rl_line_buffer[ti]))) - ti--; - } -#endif - - in_command_position = 0; - if (ti < 0) - { - /* Only do command completion at the start of a line when we - are prompting at the top level. */ - if (current_prompt_string == ps1_prompt) - in_command_position++; - else if (parser_in_command_position ()) - in_command_position++; - } - else if (member (rl_line_buffer[ti], command_separator_chars)) - { - in_command_position++; - - if (check_redir (ti) == 1) - in_command_position = -1; /* sentinel that we're not the first word on the line */ - } - else - { - /* This still could be in command position. It is possible - that all of the previous words on the line are variable - assignments. */ - } - - if (in_command_position > 0 && invalid_completion (text, ti)) - { - rl_attempted_completion_over = 1; - return ((char **)NULL); - } - - /* Check that we haven't incorrectly flagged a closed command substitution - as indicating we're in a command position. */ - if (in_command_position > 0 && ti >= 0 && rl_line_buffer[ti] == '`' && - *text != '`' && unclosed_pair (rl_line_buffer, end, "`") == 0) - in_command_position = -1; /* not following a command separator */ - - /* Special handling for command substitution. If *TEXT is a backquote, - it can be the start or end of an old-style command substitution, or - unmatched. If it's unmatched, both calls to unclosed_pair will - succeed. Don't bother if readline found a single quote and we are - completing on the substring. */ - if (*text == '`' && rl_completion_quote_character != '\'' && - (in_command_position > 0 || (unclosed_pair (rl_line_buffer, start, "`") && - unclosed_pair (rl_line_buffer, end, "`")))) - matches = rl_completion_matches (text, command_subst_completion_function); - -#if defined (PROGRAMMABLE_COMPLETION) - /* Attempt programmable completion. */ - have_progcomps = prog_completion_enabled && (progcomp_size () > 0); - iw_compspec = progcomp_search (INITIALWORD); - if (matches == 0 && - (in_command_position == 0 || text[0] == '\0' || (in_command_position > 0 && iw_compspec)) && - current_prompt_string == ps1_prompt) - { - int s, e, s1, e1, os, foundcs; - char *n; - - /* XXX - don't free the members */ - if (prog_complete_matches) - free (prog_complete_matches); - prog_complete_matches = (char **)NULL; - - os = start; - n = 0; - was_assignment = 0; - s = find_cmd_start (os); - e = find_cmd_end (end); - do - { - /* Don't read past the end of rl_line_buffer */ - if (s > rl_end) - { - s1 = s = e1; - break; - } - /* Or past point if point is within an assignment statement */ - else if (was_assignment && s > rl_point) - { - s1 = s = e1; - break; - } - /* Skip over assignment statements preceding a command name. If we - don't find a command name at all, we can perform command name - completion. If we find a partial command name, we should perform - command name completion on it. */ - FREE (n); - n = find_cmd_name (s, &s1, &e1); - s = e1 + 1; - } - while (was_assignment = assignment (n, 0)); - s = s1; /* reset to index where name begins */ - - /* s == index of where command name begins (reset above) - e == end of current command, may be end of line - s1 = index of where command name begins - e1 == index of where command name ends - start == index of where word to be completed begins - end == index of where word to be completed ends - if (s == start) we are doing command word completion for sure - if (e1 == end) we are at the end of the command name and completing it */ - if (start == 0 && end == 0 && e != 0 && text[0] == '\0') /* beginning of non-empty line */ - foundcs = 0; - else if (start == end && start == s1 && e != 0 && e1 > end) /* beginning of command name, leading whitespace */ - foundcs = 0; - else if (e == 0 && e == s && text[0] == '\0' && have_progcomps) /* beginning of empty line */ - prog_complete_matches = programmable_completions (EMPTYCMD, text, s, e, &foundcs); - else if (start == end && text[0] == '\0' && s1 > start && whitespace (rl_line_buffer[start])) - foundcs = 0; /* whitespace before command name */ - else if (e > s && was_assignment == 0 && e1 == end && rl_line_buffer[e] == 0 && whitespace (rl_line_buffer[e-1]) == 0) - { - /* not assignment statement, but still want to perform command - completion if we are composing command word. */ - foundcs = 0; - in_command_position = s == start && STREQ (n, text); /* XXX */ - } - else if (e > s && was_assignment == 0 && have_progcomps) - { - prog_complete_matches = programmable_completions (n, text, s, e, &foundcs); - /* command completion if programmable completion fails */ - /* If we have a completion for the initial word, we can prefer that */ - in_command_position = s == start && (iw_compspec || STREQ (n, text)); /* XXX */ - if (iw_compspec && in_command_position) - foundcs = 0; - } - /* empty command name following command separator */ - else if (s >= e && n[0] == '\0' && text[0] == '\0' && start > 0 && - was_assignment == 0 && member (rl_line_buffer[start-1], COMMAND_SEPARATORS)) - { - foundcs = 0; - in_command_position = 1; - } - else if (s >= e && n[0] == '\0' && text[0] == '\0' && start > 0) - { - foundcs = 0; /* empty command name following optional assignments */ - in_command_position += was_assignment; - } - else if (s == start && e == end && STREQ (n, text) && start > 0) - { - foundcs = 0; /* partial command name following assignments */ - in_command_position = 1; - } - else - foundcs = 0; - - /* If we have defined a compspec for the initial (command) word, call - it and process the results like any other programmable completion. */ - if (in_command_position && have_progcomps && foundcs == 0 && iw_compspec) - prog_complete_matches = programmable_completions (INITIALWORD, text, s, e, &foundcs); - - FREE (n); - /* XXX - if we found a COMPSPEC for the command, just return whatever - the programmable completion code returns, and disable the default - filename completion that readline will do unless the COPT_DEFAULT - option has been set with the `-o default' option to complete or - compopt. */ - if (foundcs) - { - pcomp_set_readline_variables (foundcs, 1); - /* Turn what the programmable completion code returns into what - readline wants. I should have made compute_lcd_of_matches - external... */ - matches = rl_completion_matches (text, prog_complete_return); - if ((foundcs & COPT_DEFAULT) == 0) - rl_attempted_completion_over = 1; /* no default */ - if (matches || ((foundcs & COPT_BASHDEFAULT) == 0)) - return (matches); - } - } -#endif - - if (matches == 0) - { - dflags = 0; - if (in_command_position > 0) - dflags |= DEFCOMP_CMDPOS; - matches = bash_default_completion (text, start, end, qc, dflags); - } - - return matches; -} - -char ** -bash_default_completion (text, start, end, qc, compflags) - const char *text; - int start, end, qc, compflags; -{ - char **matches, *t; - - matches = (char **)NULL; - - /* New posix-style command substitution or variable name? */ - if (*text == '$') - { - if (qc != '\'' && text[1] == '(') /* ) */ - matches = rl_completion_matches (text, command_subst_completion_function); - else - { - matches = rl_completion_matches (text, variable_completion_function); - /* If a single match, see if it expands to a directory name and append - a slash if it does. This requires us to expand the variable name, - so we don't want to display errors if the variable is unset. This - can happen with dynamic variables whose value has never been - requested. */ - if (matches && matches[0] && matches[1] == 0) - { - t = savestring (matches[0]); - bash_filename_stat_hook (&t); - /* doesn't use test_for_directory because that performs tilde - expansion */ - if (file_isdir (t)) - rl_completion_append_character = '/'; - free (t); - } - } - } - - /* If the word starts in `~', and there is no slash in the word, then - try completing this word as a username. */ - if (matches == 0 && *text == '~' && mbschr (text, '/') == 0) - matches = rl_completion_matches (text, rl_username_completion_function); - - /* Another one. Why not? If the word starts in '@', then look through - the world of known hostnames for completion first. */ - if (matches == 0 && perform_hostname_completion && *text == '@') - matches = rl_completion_matches (text, hostname_completion_function); - - /* And last, (but not least) if this word is in a command position, then - complete over possible command names, including aliases, functions, - and command names. */ - if (matches == 0 && (compflags & DEFCOMP_CMDPOS)) - { - /* If END == START and text[0] == 0, we are trying to complete an empty - command word. */ - if (no_empty_command_completion && end == start && text[0] == '\0') - { - matches = (char **)NULL; - rl_ignore_some_completions_function = bash_ignore_everything; - } - else - { -#define CMD_IS_DIR(x) (absolute_pathname(x) == 0 && absolute_program(x) == 0 && *(x) != '~' && test_for_directory (x)) - - dot_in_path = 0; - matches = rl_completion_matches (text, command_word_completion_function); - - /* If we are attempting command completion and nothing matches, we - do not want readline to perform filename completion for us. We - still want to be able to complete partial pathnames, so set the - completion ignore function to something which will remove - filenames and leave directories in the match list. */ - if (matches == (char **)NULL) - rl_ignore_some_completions_function = bash_ignore_filenames; - else if (matches[1] == 0 && CMD_IS_DIR(matches[0]) && dot_in_path == 0) - /* If we found a single match, without looking in the current - directory (because it's not in $PATH), but the found name is - also a command in the current directory, suppress appending any - terminating character, since it's ambiguous. */ - { - rl_completion_suppress_append = 1; - rl_filename_completion_desired = 0; - } - else if (matches[0] && matches[1] && STREQ (matches[0], matches[1]) && CMD_IS_DIR (matches[0])) - /* There are multiple instances of the same match (duplicate - completions haven't yet been removed). In this case, all of - the matches will be the same, and the duplicate removal code - will distill them all down to one. We turn on - rl_completion_suppress_append for the same reason as above. - Remember: we only care if there's eventually a single unique - completion. If there are multiple completions this won't - make a difference and the problem won't occur. */ - { - rl_completion_suppress_append = 1; - rl_filename_completion_desired = 0; - } - } - } - - /* This could be a globbing pattern, so try to expand it using pathname - expansion. */ - if (!matches && completion_glob_pattern ((char *)text)) - { - matches = rl_completion_matches (text, glob_complete_word); - /* A glob expression that matches more than one filename is problematic. - If we match more than one filename, punt. */ - if (matches && matches[1] && rl_completion_type == TAB) - { - strvec_dispose (matches); - matches = (char **)0; - } - else if (matches && matches[1] && rl_completion_type == '!') - { - rl_completion_suppress_append = 1; - rl_filename_completion_desired = 0; - } - } - - return (matches); -} - -static int -bash_command_name_stat_hook (name) - char **name; -{ - char *cname, *result; - - /* If it's not something we're going to look up in $PATH, just call the - normal filename stat hook. */ - if (absolute_program (*name)) - return (bash_filename_stat_hook (name)); - - cname = *name; - /* XXX - we could do something here with converting aliases, builtins, - and functions into something that came out as executable, but we don't. */ - result = search_for_command (cname, 0); - if (result) - { - *name = result; - return 1; - } - return 0; -} - -static int -executable_completion (filename, searching_path) - const char *filename; - int searching_path; -{ - char *f, c; - int r; - - /* This gets an unquoted filename, so we need to quote special characters - in the filename before the completion hook gets it. */ -#if 0 - f = savestring (filename); -#else - c = 0; - f = bash_quote_filename ((char *)filename, SINGLE_MATCH, &c); -#endif - bash_directory_completion_hook (&f); - - r = searching_path ? executable_file (f) : executable_or_directory (f); - free (f); - return r; -} - -/* This is the function to call when the word to complete is in a position - where a command word can be found. It grovels $PATH, looking for commands - that match. It also scans aliases, function names, and the shell_builtin - table. */ -char * -command_word_completion_function (hint_text, state) - const char *hint_text; - int state; -{ - static char *hint = (char *)NULL; - static char *path = (char *)NULL; - static char *val = (char *)NULL; - static char *filename_hint = (char *)NULL; - static char *fnhint = (char *)NULL; - static char *dequoted_hint = (char *)NULL; - static char *directory_part = (char *)NULL; - static char **glob_matches = (char **)NULL; - static int path_index, hint_len, istate, igncase; - static int mapping_over, local_index, searching_path, hint_is_dir; - static int old_glob_ignore_case, globpat; - static SHELL_VAR **varlist = (SHELL_VAR **)NULL; -#if defined (ALIAS) - static alias_t **alias_list = (alias_t **)NULL; -#endif /* ALIAS */ - char *temp, *cval; - - /* We have to map over the possibilities for command words. If we have - no state, then make one just for that purpose. */ - if (state == 0) - { - rl_filename_stat_hook = bash_command_name_stat_hook; - - if (dequoted_hint && dequoted_hint != hint) - free (dequoted_hint); - if (hint) - free (hint); - - mapping_over = searching_path = 0; - hint_is_dir = CMD_IS_DIR (hint_text); - val = (char *)NULL; - - temp = rl_variable_value ("completion-ignore-case"); - igncase = RL_BOOLEAN_VARIABLE_VALUE (temp); - - old_glob_ignore_case = glob_ignore_case; - - if (glob_matches) - { - free (glob_matches); - glob_matches = (char **)NULL; - } - - globpat = completion_glob_pattern ((char *)hint_text); - - /* If this is an absolute program name, do not check it against - aliases, reserved words, functions or builtins. We must check - whether or not it is unique, and, if so, whether that filename - is executable. */ - if (globpat || absolute_program (hint_text)) - { - /* Perform tilde expansion on what's passed, so we don't end up - passing filenames with tildes directly to stat(). The rest of - the shell doesn't do variable expansion on the word following - the tilde, so we don't do it here even if direxpand is set. */ - if (*hint_text == '~') - { - hint = bash_tilde_expand (hint_text, 0); - directory_part = savestring (hint_text); - temp = strchr (directory_part, '/'); - if (temp) - *temp = 0; - else - { - free (directory_part); - directory_part = (char *)NULL; - } - } - else if (dircomplete_expand) - { - hint = savestring (hint_text); - bash_directory_completion_hook (&hint); - } - else - hint = savestring (hint_text); - - dequoted_hint = hint; - /* If readline's completer found a quote character somewhere, but - didn't set the quote character, there must have been a quote - character embedded in the filename. It can't be at the start of - the filename, so we need to dequote the filename before we look - in the file system for it. */ - if (rl_completion_found_quote && rl_completion_quote_character == 0) - { - dequoted_hint = bash_dequote_filename (hint, 0); - free (hint); - hint = dequoted_hint; - } - hint_len = strlen (hint); - - if (filename_hint) - free (filename_hint); - - fnhint = filename_hint = savestring (hint); - - istate = 0; - - if (globpat) - { - mapping_over = 5; - goto globword; - } - else - { - if (dircomplete_expand && path_dot_or_dotdot (filename_hint)) - { - dircomplete_expand = 0; - set_directory_hook (); - dircomplete_expand = 1; - } - mapping_over = 4; - goto inner; - } - } - - dequoted_hint = hint = savestring (hint_text); - hint_len = strlen (hint); - - if (rl_completion_found_quote && rl_completion_quote_character == 0) - dequoted_hint = bash_dequote_filename (hint, 0); - - path = get_string_value ("PATH"); - path_index = dot_in_path = 0; - - /* Initialize the variables for each type of command word. */ - local_index = 0; - - if (varlist) - free (varlist); - - varlist = all_visible_functions (); - -#if defined (ALIAS) - if (alias_list) - free (alias_list); - - alias_list = all_aliases (); -#endif /* ALIAS */ - } - - /* mapping_over says what we are currently hacking. Note that every case - in this list must fall through when there are no more possibilities. */ - - switch (mapping_over) - { - case 0: /* Aliases come first. */ -#if defined (ALIAS) - while (alias_list && alias_list[local_index]) - { - register char *alias; - - alias = alias_list[local_index++]->name; - - if (igncase == 0 && (STREQN (alias, hint, hint_len))) - return (savestring (alias)); - else if (igncase && strncasecmp (alias, hint, hint_len) == 0) - return (savestring (alias)); - } -#endif /* ALIAS */ - local_index = 0; - mapping_over++; - - case 1: /* Then shell reserved words. */ - { - while (word_token_alist[local_index].word) - { - register char *reserved_word; - - reserved_word = word_token_alist[local_index++].word; - - if (STREQN (reserved_word, hint, hint_len)) - return (savestring (reserved_word)); - } - local_index = 0; - mapping_over++; - } - - case 2: /* Then function names. */ - while (varlist && varlist[local_index]) - { - register char *varname; - - varname = varlist[local_index++]->name; - - /* Honor completion-ignore-case for shell function names. */ - if (igncase == 0 && (STREQN (varname, hint, hint_len))) - return (savestring (varname)); - else if (igncase && strncasecmp (varname, hint, hint_len) == 0) - return (savestring (varname)); - } - local_index = 0; - mapping_over++; - - case 3: /* Then shell builtins. */ - for (; local_index < num_shell_builtins; local_index++) - { - /* Ignore it if it doesn't have a function pointer or if it - is not currently enabled. */ - if (!shell_builtins[local_index].function || - (shell_builtins[local_index].flags & BUILTIN_ENABLED) == 0) - continue; - - if (STREQN (shell_builtins[local_index].name, hint, hint_len)) - { - int i = local_index++; - - return (savestring (shell_builtins[i].name)); - } - } - local_index = 0; - mapping_over++; - } - -globword: - /* Limited support for completing command words with globbing chars. Only - a single match (multiple matches that end up reducing the number of - characters in the common prefix are bad) will ever be returned on - regular completion. */ - if (globpat) - { - if (state == 0) - { - rl_filename_completion_desired = 1; - - glob_ignore_case = igncase; - glob_matches = shell_glob_filename (hint, 0); - glob_ignore_case = old_glob_ignore_case; - - if (GLOB_FAILED (glob_matches) || glob_matches == 0) - { - glob_matches = (char **)NULL; - return ((char *)NULL); - } - - local_index = 0; - - if (glob_matches[1] && rl_completion_type == TAB) /* multiple matches are bad */ - return ((char *)NULL); - } - - while (val = glob_matches[local_index++]) - { - if (executable_or_directory (val)) - { - if (*hint_text == '~' && directory_part) - { - temp = maybe_restore_tilde (val, directory_part); - free (val); - val = temp; - } - return (val); - } - free (val); - } - - glob_ignore_case = old_glob_ignore_case; - return ((char *)NULL); - } - - /* If the text passed is a directory in the current directory, return it - as a possible match. Executables in directories in the current - directory can be specified using relative pathnames and successfully - executed even when `.' is not in $PATH. */ - if (hint_is_dir) - { - hint_is_dir = 0; /* only return the hint text once */ - return (savestring (hint_text)); - } - - /* Repeatedly call filename_completion_function while we have - members of PATH left. Question: should we stat each file? - Answer: we call executable_file () on each file. */ - outer: - - istate = (val != (char *)NULL); - - if (istate == 0) - { - char *current_path; - - /* Get the next directory from the path. If there is none, then we - are all done. */ - if (path == 0 || path[path_index] == 0 || - (current_path = extract_colon_unit (path, &path_index)) == 0) - return ((char *)NULL); - - searching_path = 1; - if (*current_path == 0) - { - free (current_path); - current_path = savestring ("."); - } - - if (*current_path == '~') - { - char *t; - - t = bash_tilde_expand (current_path, 0); - free (current_path); - current_path = t; - } - - if (current_path[0] == '.' && current_path[1] == '\0') - dot_in_path = 1; - - if (fnhint && fnhint != filename_hint) - free (fnhint); - if (filename_hint) - free (filename_hint); - - filename_hint = sh_makepath (current_path, hint, 0); - /* Need a quoted version (though it doesn't matter much in most - cases) because rl_filename_completion_function dequotes the - filename it gets, assuming that it's been quoted as part of - the input line buffer. */ - if (strpbrk (filename_hint, "\"'\\")) - fnhint = sh_backslash_quote (filename_hint, filename_bstab, 0); - else - fnhint = filename_hint; - free (current_path); /* XXX */ - } - - inner: - val = rl_filename_completion_function (fnhint, istate); - if (mapping_over == 4 && dircomplete_expand) - set_directory_hook (); - - istate = 1; - - if (val == 0) - { - /* If the hint text is an absolute program, then don't bother - searching through PATH. */ - if (absolute_program (hint)) - return ((char *)NULL); - - goto outer; - } - else - { - int match, freetemp; - - if (absolute_program (hint)) - { -#if 0 - if (igncase == 0) - match = strncmp (val, hint, hint_len) == 0; - else - match = strncasecmp (val, hint, hint_len) == 0; -#else - /* Why duplicate the comparison rl_filename_completion_function - already performs? */ - match = 1; -#endif - - /* If we performed tilde expansion, restore the original - filename. */ - if (*hint_text == '~') - temp = maybe_restore_tilde (val, directory_part); - else - temp = savestring (val); - freetemp = 1; - } - else - { - temp = strrchr (val, '/'); - - if (temp) - { - temp++; - if (igncase == 0) - freetemp = match = strncmp (temp, hint, hint_len) == 0; - else - freetemp = match = strncasecmp (temp, hint, hint_len) == 0; - if (match) - temp = savestring (temp); - } - else - freetemp = match = 0; - } - - /* If we have found a match, and it is an executable file, return it. - We don't return directory names when searching $PATH, since the - bash execution code won't find executables in directories which - appear in directories in $PATH when they're specified using - relative pathnames. */ -#if 0 - /* If we're not searching $PATH and we have a relative pathname, we - need to re-canonicalize it before testing whether or not it's an - executable or a directory so the shell treats .. relative to $PWD - according to the physical/logical option. The shell already - canonicalizes the directory name in order to tell readline where - to look, so not doing it here will be inconsistent. */ - /* XXX -- currently not used -- will introduce more inconsistency, - since shell does not canonicalize ../foo before passing it to - shell_execve(). */ - if (match && searching_path == 0 && *val == '.') - { - char *t, *t1; - - t = get_working_directory ("command-word-completion"); - t1 = make_absolute (val, t); - free (t); - cval = sh_canonpath (t1, PATH_CHECKDOTDOT|PATH_CHECKEXISTS); - } - else -#endif - cval = val; - - if (match && executable_completion ((searching_path ? val : cval), searching_path)) - { - if (cval != val) - free (cval); - free (val); - val = ""; /* So it won't be NULL. */ - return (temp); - } - else - { - if (freetemp) - free (temp); - if (cval != val) - free (cval); - free (val); - goto inner; - } - } -} - -/* Completion inside an unterminated command substitution. */ -static char * -command_subst_completion_function (text, state) - const char *text; - int state; -{ - static char **matches = (char **)NULL; - static const char *orig_start; - static char *filename_text = (char *)NULL; - static int cmd_index, start_len; - char *value; - - if (state == 0) - { - if (filename_text) - free (filename_text); - orig_start = text; - if (*text == '`') - text++; - else if (*text == '$' && text[1] == '(') /* ) */ - text += 2; - /* If the text was quoted, suppress any quote character that the - readline completion code would insert. */ - rl_completion_suppress_quote = 1; - start_len = text - orig_start; - filename_text = savestring (text); - if (matches) - free (matches); - - /* - * At this point we can entertain the idea of re-parsing - * `filename_text' into a (possibly incomplete) command name and - * arguments, and doing completion based on that. This is - * currently very rudimentary, but it is a small improvement. - */ - for (value = filename_text + strlen (filename_text) - 1; value > filename_text; value--) - if (whitespace (*value) || member (*value, COMMAND_SEPARATORS)) - break; - if (value <= filename_text) - matches = rl_completion_matches (filename_text, command_word_completion_function); - else - { - value++; - start_len += value - filename_text; - if (whitespace (value[-1])) - matches = rl_completion_matches (value, rl_filename_completion_function); - else - matches = rl_completion_matches (value, command_word_completion_function); - } - - /* If there is more than one match, rl_completion_matches has already - put the lcd in matches[0]. Skip over it. */ - cmd_index = matches && matches[0] && matches[1]; - - /* If there's a single match and it's a directory, set the append char - to the expected `/'. Otherwise, don't append anything. */ - if (matches && matches[0] && matches[1] == 0 && test_for_directory (matches[0])) - rl_completion_append_character = '/'; - else - rl_completion_suppress_append = 1; - } - - if (matches == 0 || matches[cmd_index] == 0) - { - rl_filename_quoting_desired = 0; /* disable quoting */ - return ((char *)NULL); - } - else - { - value = (char *)xmalloc (1 + start_len + strlen (matches[cmd_index])); - - if (start_len == 1) - value[0] = *orig_start; - else - strncpy (value, orig_start, start_len); - - strcpy (value + start_len, matches[cmd_index]); - - cmd_index++; - return (value); - } -} - -/* Okay, now we write the entry_function for variable completion. */ -static char * -variable_completion_function (text, state) - const char *text; - int state; -{ - static char **varlist = (char **)NULL; - static int varlist_index; - static char *varname = (char *)NULL; - static int first_char, first_char_loc; - - if (!state) - { - if (varname) - free (varname); - - first_char_loc = 0; - first_char = text[0]; - - if (first_char == '$') - first_char_loc++; - - if (text[first_char_loc] == '{') - first_char_loc++; - - varname = savestring (text + first_char_loc); - - if (varlist) - strvec_dispose (varlist); - - varlist = all_variables_matching_prefix (varname); - varlist_index = 0; - } - - if (!varlist || !varlist[varlist_index]) - { - return ((char *)NULL); - } - else - { - char *value; - - value = (char *)xmalloc (4 + strlen (varlist[varlist_index])); - - if (first_char_loc) - { - value[0] = first_char; - if (first_char_loc == 2) - value[1] = '{'; - } - - strcpy (value + first_char_loc, varlist[varlist_index]); - if (first_char_loc == 2) - strcat (value, "}"); - - varlist_index++; - return (value); - } -} - -/* How about a completion function for hostnames? */ -static char * -hostname_completion_function (text, state) - const char *text; - int state; -{ - static char **list = (char **)NULL; - static int list_index = 0; - static int first_char, first_char_loc; - - /* If we don't have any state, make some. */ - if (state == 0) - { - FREE (list); - - list = (char **)NULL; - - first_char_loc = 0; - first_char = *text; - - if (first_char == '@') - first_char_loc++; - - list = hostnames_matching ((char *)text+first_char_loc); - list_index = 0; - } - - if (list && list[list_index]) - { - char *t; - - t = (char *)xmalloc (2 + strlen (list[list_index])); - *t = first_char; - strcpy (t + first_char_loc, list[list_index]); - list_index++; - return (t); - } - - return ((char *)NULL); -} - -/* - * A completion function for service names from /etc/services (or wherever). - */ -char * -bash_servicename_completion_function (text, state) - const char *text; - int state; -{ -#if defined (__WIN32__) || defined (__OPENNT) || !defined (HAVE_GETSERVENT) - return ((char *)NULL); -#else - static char *sname = (char *)NULL; - static struct servent *srvent; - static int snamelen; - char *value; - char **alist, *aentry; - int afound; - - if (state == 0) - { - FREE (sname); - - sname = savestring (text); - snamelen = strlen (sname); - setservent (0); - } - - while (srvent = getservent ()) - { - afound = 0; - if (snamelen == 0 || (STREQN (sname, srvent->s_name, snamelen))) - break; - /* Not primary, check aliases */ - for (alist = srvent->s_aliases; *alist; alist++) - { - aentry = *alist; - if (STREQN (sname, aentry, snamelen)) - { - afound = 1; - break; - } - } - - if (afound) - break; - } - - if (srvent == 0) - { - endservent (); - return ((char *)NULL); - } - - value = afound ? savestring (aentry) : savestring (srvent->s_name); - return value; -#endif -} - -/* - * A completion function for group names from /etc/group (or wherever). - */ -char * -bash_groupname_completion_function (text, state) - const char *text; - int state; -{ -#if defined (__WIN32__) || defined (__OPENNT) || !defined (HAVE_GRP_H) - return ((char *)NULL); -#else - static char *gname = (char *)NULL; - static struct group *grent; - static int gnamelen; - char *value; - - if (state == 0) - { - FREE (gname); - gname = savestring (text); - gnamelen = strlen (gname); - - setgrent (); - } - - while (grent = getgrent ()) - { - if (gnamelen == 0 || (STREQN (gname, grent->gr_name, gnamelen))) - break; - } - - if (grent == 0) - { - endgrent (); - return ((char *)NULL); - } - - value = savestring (grent->gr_name); - return (value); -#endif -} - -/* Functions to perform history and alias expansions on the current line. */ - -#if defined (BANG_HISTORY) -/* Perform history expansion on the current line. If no history expansion - is done, pre_process_line() returns what it was passed, so we need to - allocate a new line here. */ -static char * -history_expand_line_internal (line) - char *line; -{ - char *new_line; - int old_verify; - - old_verify = hist_verify; - hist_verify = 0; - new_line = pre_process_line (line, 0, 0); - hist_verify = old_verify; - - return (new_line == line) ? savestring (line) : new_line; -} -#endif - -/* There was an error in expansion. Let the preprocessor print - the error here. */ -static void -cleanup_expansion_error () -{ - char *to_free; -#if defined (BANG_HISTORY) - int old_verify; - - old_verify = hist_verify; - hist_verify = 0; -#endif - - fprintf (rl_outstream, "\r\n"); - to_free = pre_process_line (rl_line_buffer, 1, 0); -#if defined (BANG_HISTORY) - hist_verify = old_verify; -#endif - if (to_free != rl_line_buffer) - FREE (to_free); - putc ('\r', rl_outstream); - rl_forced_update_display (); -} - -/* If NEW_LINE differs from what is in the readline line buffer, add an - undo record to get from the readline line buffer contents to the new - line and make NEW_LINE the current readline line. */ -static void -maybe_make_readline_line (new_line) - char *new_line; -{ - if (new_line && strcmp (new_line, rl_line_buffer) != 0) - { - rl_point = rl_end; - - rl_add_undo (UNDO_BEGIN, 0, 0, 0); - rl_delete_text (0, rl_point); - rl_point = rl_end = rl_mark = 0; - rl_insert_text (new_line); - rl_add_undo (UNDO_END, 0, 0, 0); - } -} - -/* Make NEW_LINE be the current readline line. This frees NEW_LINE. */ -static void -set_up_new_line (new_line) - char *new_line; -{ - int old_point, at_end; - - old_point = rl_point; - at_end = rl_point == rl_end; - - /* If the line was history and alias expanded, then make that - be one thing to undo. */ - maybe_make_readline_line (new_line); - free (new_line); - - /* Place rl_point where we think it should go. */ - if (at_end) - rl_point = rl_end; - else if (old_point < rl_end) - { - rl_point = old_point; - if (!whitespace (rl_line_buffer[rl_point])) - rl_forward_word (1, 0); - } -} - -#if defined (ALIAS) -/* Expand aliases in the current readline line. */ -static int -alias_expand_line (count, ignore) - int count, ignore; -{ - char *new_line; - - new_line = alias_expand (rl_line_buffer); - - if (new_line) - { - set_up_new_line (new_line); - return (0); - } - else - { - cleanup_expansion_error (); - return (1); - } -} -#endif - -#if defined (BANG_HISTORY) -/* History expand the line. */ -static int -history_expand_line (count, ignore) - int count, ignore; -{ - char *new_line; - - new_line = history_expand_line_internal (rl_line_buffer); - - if (new_line) - { - set_up_new_line (new_line); - return (0); - } - else - { - cleanup_expansion_error (); - return (1); - } -} - -/* Expand history substitutions in the current line and then insert a - space (hopefully close to where we were before). */ -static int -tcsh_magic_space (count, ignore) - int count, ignore; -{ - int dist_from_end, old_point; - - old_point = rl_point; - dist_from_end = rl_end - rl_point; - if (history_expand_line (count, ignore) == 0) - { - /* Try a simple heuristic from Stephen Gildea . - This works if all expansions were before rl_point or if no expansions - were performed. */ - rl_point = (old_point == 0) ? old_point : rl_end - dist_from_end; - rl_insert (1, ' '); - return (0); - } - else - return (1); -} -#endif /* BANG_HISTORY */ - -/* History and alias expand the line. */ -static int -history_and_alias_expand_line (count, ignore) - int count, ignore; -{ - char *new_line, *t; - - new_line = 0; -#if defined (BANG_HISTORY) - new_line = history_expand_line_internal (rl_line_buffer); -#endif - -#if defined (ALIAS) - if (new_line) - { - char *alias_line; - - alias_line = alias_expand (new_line); - free (new_line); - new_line = alias_line; - } -#endif /* ALIAS */ - - if (new_line) - { - set_up_new_line (new_line); - return (0); - } - else - { - cleanup_expansion_error (); - return (1); - } -} - -/* History and alias expand the line, then perform the shell word - expansions by calling expand_string. This can't use set_up_new_line() - because we want the variable expansions as a separate undo'able - set of operations. */ -static int -shell_expand_line (count, ignore) - int count, ignore; -{ - char *new_line, *t; - WORD_LIST *expanded_string; - WORD_DESC *w; - - new_line = 0; -#if defined (BANG_HISTORY) - new_line = history_expand_line_internal (rl_line_buffer); -#endif - - t = expand_string_dollar_quote (new_line ? new_line : rl_line_buffer, 0); - FREE (new_line); - new_line = t; - -#if defined (ALIAS) - if (new_line) - { - char *alias_line; - - alias_line = alias_expand (new_line); - free (new_line); - new_line = alias_line; - } -#endif /* ALIAS */ - - if (new_line) - { - int old_point = rl_point; - int at_end = rl_point == rl_end; - - /* If the line was history and alias expanded, then make that - be one thing to undo. */ - maybe_make_readline_line (new_line); - free (new_line); - - /* If there is variable expansion to perform, do that as a separate - operation to be undone. */ - -#if 1 - w = alloc_word_desc (); - w->word = savestring (rl_line_buffer); - w->flags = rl_explicit_arg ? (W_NOPROCSUB|W_NOCOMSUB) : 0; - expanded_string = expand_word (w, rl_explicit_arg ? Q_HERE_DOCUMENT : 0); - dispose_word (w); -#else - new_line = savestring (rl_line_buffer); - expanded_string = expand_string (new_line, 0); - FREE (new_line); -#endif - - if (expanded_string == 0) - { - new_line = (char *)xmalloc (1); - new_line[0] = '\0'; - } - else - { - new_line = string_list (expanded_string); - dispose_words (expanded_string); - } - - maybe_make_readline_line (new_line); - free (new_line); - - /* Place rl_point where we think it should go. */ - if (at_end) - rl_point = rl_end; - else if (old_point < rl_end) - { - rl_point = old_point; - if (!whitespace (rl_line_buffer[rl_point])) - rl_forward_word (1, 0); - } - return 0; - } - else - { - cleanup_expansion_error (); - return 1; - } -} - -/* If FIGNORE is set, then don't match files with the given suffixes when - completing filenames. If only one of the possibilities has an acceptable - suffix, delete the others, else just return and let the completer - signal an error. It is called by the completer when real - completions are done on filenames by the completer's internal - function, not for completion lists (M-?) and not on "other" - completion types, such as hostnames or commands. */ - -static struct ignorevar fignore = -{ - "FIGNORE", - (struct ign *)0, - 0, - (char *)0, - (sh_iv_item_func_t *) 0, -}; - -static void -_ignore_completion_names (names, name_func) - char **names; - sh_ignore_func_t *name_func; -{ - char **newnames; - int idx, nidx; - char **oldnames; - int oidx; - - /* If there is only one completion, see if it is acceptable. If it is - not, free it up. In any case, short-circuit and return. This is a - special case because names[0] is not the prefix of the list of names - if there is only one completion; it is the completion itself. */ - if (names[1] == (char *)0) - { - if (force_fignore) - if ((*name_func) (names[0]) == 0) - { - free (names[0]); - names[0] = (char *)NULL; - } - - return; - } - - /* Allocate space for array to hold list of pointers to matching - filenames. The pointers are copied back to NAMES when done. */ - for (nidx = 1; names[nidx]; nidx++) - ; - newnames = strvec_create (nidx + 1); - - if (force_fignore == 0) - { - oldnames = strvec_create (nidx - 1); - oidx = 0; - } - - newnames[0] = names[0]; - for (idx = nidx = 1; names[idx]; idx++) - { - if ((*name_func) (names[idx])) - newnames[nidx++] = names[idx]; - else if (force_fignore == 0) - oldnames[oidx++] = names[idx]; - else - free (names[idx]); - } - - newnames[nidx] = (char *)NULL; - - /* If none are acceptable then let the completer handle it. */ - if (nidx == 1) - { - if (force_fignore) - { - free (names[0]); - names[0] = (char *)NULL; - } - else - free (oldnames); - - free (newnames); - return; - } - - if (force_fignore == 0) - { - while (oidx) - free (oldnames[--oidx]); - free (oldnames); - } - - /* If only one is acceptable, copy it to names[0] and return. */ - if (nidx == 2) - { - free (names[0]); - names[0] = newnames[1]; - names[1] = (char *)NULL; - free (newnames); - return; - } - - /* Copy the acceptable names back to NAMES, set the new array end, - and return. */ - for (nidx = 1; newnames[nidx]; nidx++) - names[nidx] = newnames[nidx]; - names[nidx] = (char *)NULL; - free (newnames); -} - -static int -name_is_acceptable (name) - const char *name; -{ - struct ign *p; - int nlen; - - for (nlen = strlen (name), p = fignore.ignores; p->val; p++) - { - if (nlen > p->len && p->len > 0 && STREQ (p->val, &name[nlen - p->len])) - return (0); - } - - return (1); -} - -#if 0 -static int -ignore_dot_names (name) - char *name; -{ - return (name[0] != '.'); -} -#endif - -static int -filename_completion_ignore (names) - char **names; -{ -#if 0 - if (glob_dot_filenames == 0) - _ignore_completion_names (names, ignore_dot_names); -#endif - - setup_ignore_patterns (&fignore); - - if (fignore.num_ignores == 0) - return 0; - - _ignore_completion_names (names, name_is_acceptable); - - return 0; -} - -/* Return 1 if NAME is a directory. NAME undergoes tilde expansion. */ -static int -test_for_directory (name) - const char *name; -{ - char *fn; - int r; - - fn = bash_tilde_expand (name, 0); - r = file_isdir (fn); - free (fn); - - return (r); -} - -static int -test_for_canon_directory (name) - const char *name; -{ - char *fn; - int r; - - fn = (*name == '~') ? bash_tilde_expand (name, 0) : savestring (name); - bash_filename_stat_hook (&fn); - r = file_isdir (fn); - free (fn); - - return (r); -} - -/* Remove files from NAMES, leaving directories. */ -static int -bash_ignore_filenames (names) - char **names; -{ - _ignore_completion_names (names, test_for_directory); - return 0; -} - -static int -bash_progcomp_ignore_filenames (names) - char **names; -{ - _ignore_completion_names (names, test_for_canon_directory); - return 0; -} - -static int -return_zero (name) - const char *name; -{ - return 0; -} - -static int -bash_ignore_everything (names) - char **names; -{ - _ignore_completion_names (names, return_zero); - return 0; -} - -/* Replace a tilde-prefix in VAL with a `~', assuming the user typed it. VAL - is an expanded filename. DIRECTORY_PART is the tilde-prefix portion - of the un-tilde-expanded version of VAL (what the user typed). */ -static char * -restore_tilde (val, directory_part) - char *val, *directory_part; -{ - int l, vl, dl2, xl; - char *dh2, *expdir, *ret, *v; - - vl = strlen (val); - - /* We need to duplicate the expansions readline performs on the directory - portion before passing it to our completion function. */ - dh2 = directory_part ? bash_dequote_filename (directory_part, 0) : 0; - bash_directory_expansion (&dh2); - dl2 = strlen (dh2); - - expdir = bash_tilde_expand (directory_part, 0); - xl = strlen (expdir); - if (*directory_part == '~' && STREQ (directory_part, expdir)) - { - /* tilde expansion failed, so what should we return? we use what the - user typed. */ - v = mbschr (val, '/'); - vl = STRLEN (v); - ret = (char *)xmalloc (xl + vl + 2); - strcpy (ret, directory_part); - if (v && *v) - strcpy (ret + xl, v); - - free (dh2); - free (expdir); - - return ret; - } - free (expdir); - - /* - dh2 = unexpanded but dequoted tilde-prefix - dl2 = length of tilde-prefix - expdir = tilde-expanded tilde-prefix - xl = length of expanded tilde-prefix - l = length of remainder after tilde-prefix - */ - l = (vl - xl) + 1; - if (l <= 0) - { - free (dh2); - return (savestring (val)); /* XXX - just punt */ - } - - ret = (char *)xmalloc (dl2 + 2 + l); - strcpy (ret, dh2); - strcpy (ret + dl2, val + xl); - - free (dh2); - return (ret); -} - -static char * -maybe_restore_tilde (val, directory_part) - char *val, *directory_part; -{ - rl_icppfunc_t *save; - char *ret; - - save = (dircomplete_expand == 0) ? save_directory_hook () : (rl_icppfunc_t *)0; - ret = restore_tilde (val, directory_part); - if (save) - restore_directory_hook (save); - return ret; -} - -/* Simulate the expansions that will be performed by - rl_filename_completion_function. This must be called with the address of - a pointer to malloc'd memory. */ -static void -bash_directory_expansion (dirname) - char **dirname; -{ - char *d, *nd; - - d = savestring (*dirname); - - if ((rl_directory_rewrite_hook) && (*rl_directory_rewrite_hook) (&d)) - { - free (*dirname); - *dirname = d; - } - else if (rl_directory_completion_hook && (*rl_directory_completion_hook) (&d)) - { - free (*dirname); - *dirname = d; - } - else if (rl_completion_found_quote) - { - nd = bash_dequote_filename (d, rl_completion_quote_character); - free (*dirname); - free (d); - *dirname = nd; - } - else - free (d); -} - -/* If necessary, rewrite directory entry */ -static char * -bash_filename_rewrite_hook (fname, fnlen) - char *fname; - int fnlen; -{ - char *conv; - - conv = fnx_fromfs (fname, fnlen); - if (conv != fname) - conv = savestring (conv); - return conv; -} - -/* Functions to save and restore the appropriate directory hook */ -/* This is not static so the shopt code can call it */ -void -set_directory_hook () -{ - if (dircomplete_expand) - { - rl_directory_completion_hook = bash_directory_completion_hook; - rl_directory_rewrite_hook = (rl_icppfunc_t *)0; - } - else - { - rl_directory_rewrite_hook = bash_directory_completion_hook; - rl_directory_completion_hook = (rl_icppfunc_t *)0; - } -} - -static rl_icppfunc_t * -save_directory_hook () -{ - rl_icppfunc_t *ret; - - if (dircomplete_expand) - { - ret = rl_directory_completion_hook; - rl_directory_completion_hook = (rl_icppfunc_t *)NULL; - } - else - { - ret = rl_directory_rewrite_hook; - rl_directory_rewrite_hook = (rl_icppfunc_t *)NULL; - } - - return ret; -} - -static void -restore_directory_hook (hookf) - rl_icppfunc_t *hookf; -{ - if (dircomplete_expand) - rl_directory_completion_hook = hookf; - else - rl_directory_rewrite_hook = hookf; -} - -/* Check whether not DIRNAME, with any trailing slash removed, exists. If - SHOULD_DEQUOTE is non-zero, we dequote the directory name first. */ -static int -directory_exists (dirname, should_dequote) - const char *dirname; - int should_dequote; -{ - char *new_dirname; - int dirlen, r; - struct stat sb; - - /* We save the string and chop the trailing slash because stat/lstat behave - inconsistently if one is present. */ - new_dirname = should_dequote ? bash_dequote_filename ((char *)dirname, rl_completion_quote_character) : savestring (dirname); - dirlen = STRLEN (new_dirname); - if (new_dirname[dirlen - 1] == '/') - new_dirname[dirlen - 1] = '\0'; -#if defined (HAVE_LSTAT) - r = lstat (new_dirname, &sb) == 0; -#else - r = stat (new_dirname, &sb) == 0; -#endif - free (new_dirname); - return (r); -} - -/* Expand a filename before the readline completion code passes it to stat(2). - The filename will already have had tilde expansion performed. */ -static int -bash_filename_stat_hook (dirname) - char **dirname; -{ - char *local_dirname, *new_dirname, *t; - int should_expand_dirname, return_value; - int global_nounset; - WORD_LIST *wl; - - local_dirname = *dirname; - should_expand_dirname = return_value = 0; - if (t = mbschr (local_dirname, '$')) - should_expand_dirname = '$'; - else if (t = mbschr (local_dirname, '`')) /* XXX */ - should_expand_dirname = '`'; - - if (should_expand_dirname && directory_exists (local_dirname, 0)) - should_expand_dirname = 0; - - if (should_expand_dirname) - { - new_dirname = savestring (local_dirname); - /* no error messages, and expand_prompt_string doesn't longjmp so we don't - have to worry about restoring this setting. */ - global_nounset = unbound_vars_is_error; - unbound_vars_is_error = 0; - wl = expand_prompt_string (new_dirname, 0, W_NOCOMSUB|W_NOPROCSUB|W_COMPLETE); /* does the right thing */ - unbound_vars_is_error = global_nounset; - if (wl) - { - free (new_dirname); - new_dirname = string_list (wl); - /* Tell the completer we actually expanded something and change - *dirname only if we expanded to something non-null -- stat - behaves unpredictably when passed null or empty strings */ - if (new_dirname && *new_dirname) - { - free (local_dirname); /* XXX */ - local_dirname = *dirname = new_dirname; - return_value = STREQ (local_dirname, *dirname) == 0; - } - else - free (new_dirname); - dispose_words (wl); - } - else - free (new_dirname); - } - - /* This is very similar to the code in bash_directory_completion_hook below, - but without spelling correction and not worrying about whether or not - we change relative pathnames. */ - if (no_symbolic_links == 0 && (local_dirname[0] != '.' || local_dirname[1])) - { - char *temp1, *temp2; - - t = get_working_directory ("symlink-hook"); - temp1 = make_absolute (local_dirname, t); - free (t); - temp2 = sh_canonpath (temp1, PATH_CHECKDOTDOT|PATH_CHECKEXISTS); - - /* If we can't canonicalize, bail. */ - if (temp2 == 0) - { - free (temp1); - return return_value; - } - - free (local_dirname); - *dirname = temp2; - free (temp1); - } - - return (return_value); -} - -/* Handle symbolic link references and other directory name - expansions while hacking completion. This should return 1 if it modifies - the DIRNAME argument, 0 otherwise. It should make sure not to modify - DIRNAME if it returns 0. */ -static int -bash_directory_completion_hook (dirname) - char **dirname; -{ - char *local_dirname, *new_dirname, *t; - int return_value, should_expand_dirname, nextch, closer; - WORD_LIST *wl; - - return_value = should_expand_dirname = nextch = closer = 0; - local_dirname = *dirname; - - should_expand_dirname = bash_check_expchar (local_dirname, 1, &nextch, &closer); - - if (should_expand_dirname && directory_exists (local_dirname, 1)) - should_expand_dirname = 0; - - if (should_expand_dirname) - { - new_dirname = savestring (local_dirname); - wl = expand_prompt_string (new_dirname, 0, W_NOCOMSUB|W_NOPROCSUB|W_COMPLETE); /* does the right thing */ - if (wl) - { - *dirname = string_list (wl); - /* Tell the completer to replace the directory name only if we - actually expanded something. */ - return_value = STREQ (local_dirname, *dirname) == 0; - free (local_dirname); - free (new_dirname); - dispose_words (wl); - local_dirname = *dirname; - - set_filename_quote_chars (should_expand_dirname, nextch, closer); - } - else - { - free (new_dirname); - free (local_dirname); - *dirname = (char *)xmalloc (1); - **dirname = '\0'; - return 1; - } - } - else - { - /* Dequote the filename even if we don't expand it. */ - new_dirname = bash_dequote_filename (local_dirname, rl_completion_quote_character); - return_value = STREQ (local_dirname, new_dirname) == 0; - free (local_dirname); - local_dirname = *dirname = new_dirname; - } - - /* no_symbolic_links == 0 -> use (default) logical view of the file system. - local_dirname[0] == '.' && local_dirname[1] == '/' means files in the - current directory (./). - local_dirname[0] == '.' && local_dirname[1] == 0 means relative pathnames - in the current directory (e.g., lib/sh). - XXX - should we do spelling correction on these? */ - - /* This is test as it was in bash-4.2: skip relative pathnames in current - directory. Change test to - (local_dirname[0] != '.' || (local_dirname[1] && local_dirname[1] != '/')) - if we want to skip paths beginning with ./ also. */ - if (no_symbolic_links == 0 && (local_dirname[0] != '.' || local_dirname[1])) - { - char *temp1, *temp2; - int len1, len2; - - /* If we have a relative path - (local_dirname[0] != '/' && local_dirname[0] != '.') - that is canonical after appending it to the current directory, then - temp1 = temp2+'/' - That is, - strcmp (temp1, temp2) == 0 - after adding a slash to temp2 below. It should be safe to not - change those. - */ - t = get_working_directory ("symlink-hook"); - temp1 = make_absolute (local_dirname, t); - free (t); - temp2 = sh_canonpath (temp1, PATH_CHECKDOTDOT|PATH_CHECKEXISTS); - - /* Try spelling correction if initial canonicalization fails. Make - sure we are set to replace the directory name with the results so - subsequent directory checks don't fail. */ - if (temp2 == 0 && dircomplete_spelling && dircomplete_expand) - { - size_t l1, l2; - - temp2 = dirspell (temp1); - l2 = STRLEN (temp2); - /* Don't take matches if they are shorter than the original path */ - if (temp2 && l2 < strlen (temp1) && STREQN (temp1, temp2, l2)) - { - free (temp2); - temp2 = 0; - } - if (temp2) - { - free (temp1); - temp1 = temp2; - temp2 = sh_canonpath (temp1, PATH_CHECKDOTDOT|PATH_CHECKEXISTS); - return_value |= temp2 != 0; - } - } - /* If we can't canonicalize, bail. */ - if (temp2 == 0) - { - free (temp1); - return return_value; - } - len1 = strlen (temp1); - if (temp1[len1 - 1] == '/') - { - len2 = strlen (temp2); - if (len2 > 2) /* don't append `/' to `/' or `//' */ - { - temp2 = (char *)xrealloc (temp2, len2 + 2); - temp2[len2] = '/'; - temp2[len2 + 1] = '\0'; - } - } - - /* dircomplete_expand_relpath == 0 means we want to leave relative - pathnames that are unchanged by canonicalization alone. - *local_dirname != '/' && *local_dirname != '.' == relative pathname - (consistent with general.c:absolute_pathname()) - temp1 == temp2 (after appending a slash to temp2) means the pathname - is not changed by canonicalization as described above. */ - if (dircomplete_expand_relpath || ((local_dirname[0] != '/' && local_dirname[0] != '.') && STREQ (temp1, temp2) == 0)) - return_value |= STREQ (local_dirname, temp2) == 0; - free (local_dirname); - *dirname = temp2; - free (temp1); - } - - return (return_value); -} - -static char **history_completion_array = (char **)NULL; -static int harry_size; -static int harry_len; - -static void -build_history_completion_array () -{ - register int i, j; - HIST_ENTRY **hlist; - char **tokens; - - /* First, clear out the current dynamic history completion list. */ - if (harry_size) - { - strvec_dispose (history_completion_array); - history_completion_array = (char **)NULL; - harry_size = 0; - harry_len = 0; - } - - /* Next, grovel each line of history, making each shell-sized token - a separate entry in the history_completion_array. */ - hlist = history_list (); - - if (hlist) - { - for (i = 0; hlist[i]; i++) - ; - for ( --i; i >= 0; i--) - { - /* Separate each token, and place into an array. */ - tokens = history_tokenize (hlist[i]->line); - - for (j = 0; tokens && tokens[j]; j++) - { - if (harry_len + 2 > harry_size) - history_completion_array = strvec_resize (history_completion_array, harry_size += 10); - - history_completion_array[harry_len++] = tokens[j]; - history_completion_array[harry_len] = (char *)NULL; - } - free (tokens); - } - - /* Sort the complete list of tokens. */ - if (dabbrev_expand_active == 0) - qsort (history_completion_array, harry_len, sizeof (char *), (QSFUNC *)strvec_strcmp); - } -} - -static char * -history_completion_generator (hint_text, state) - const char *hint_text; - int state; -{ - static int local_index, len; - static const char *text; - - /* If this is the first call to the generator, then initialize the - list of strings to complete over. */ - if (state == 0) - { - if (dabbrev_expand_active) /* This is kind of messy */ - rl_completion_suppress_append = 1; - local_index = 0; - build_history_completion_array (); - text = hint_text; - len = strlen (text); - } - - while (history_completion_array && history_completion_array[local_index]) - { - /* XXX - should this use completion-ignore-case? */ - if (strncmp (text, history_completion_array[local_index++], len) == 0) - return (savestring (history_completion_array[local_index - 1])); - } - return ((char *)NULL); -} - -static int -dynamic_complete_history (count, key) - int count, key; -{ - int r; - rl_compentry_func_t *orig_func; - rl_completion_func_t *orig_attempt_func; - rl_compignore_func_t *orig_ignore_func; - - orig_func = rl_completion_entry_function; - orig_attempt_func = rl_attempted_completion_function; - orig_ignore_func = rl_ignore_some_completions_function; - - rl_completion_entry_function = history_completion_generator; - rl_attempted_completion_function = (rl_completion_func_t *)NULL; - rl_ignore_some_completions_function = filename_completion_ignore; - - /* XXX - use rl_completion_mode here? */ - if (rl_last_func == dynamic_complete_history) - r = rl_complete_internal ('?'); - else - r = rl_complete_internal (TAB); - - rl_completion_entry_function = orig_func; - rl_attempted_completion_function = orig_attempt_func; - rl_ignore_some_completions_function = orig_ignore_func; - - return r; -} - -static int -bash_dabbrev_expand (count, key) - int count, key; -{ - int r, orig_suppress, orig_sort; - rl_compentry_func_t *orig_func; - rl_completion_func_t *orig_attempt_func; - rl_compignore_func_t *orig_ignore_func; - - orig_func = rl_menu_completion_entry_function; - orig_attempt_func = rl_attempted_completion_function; - orig_ignore_func = rl_ignore_some_completions_function; - orig_suppress = rl_completion_suppress_append; - orig_sort = rl_sort_completion_matches; - - rl_menu_completion_entry_function = history_completion_generator; - rl_attempted_completion_function = (rl_completion_func_t *)NULL; - rl_ignore_some_completions_function = filename_completion_ignore; - rl_filename_completion_desired = 0; - rl_completion_suppress_append = 1; - rl_sort_completion_matches = 0; - - /* XXX - use rl_completion_mode here? */ - dabbrev_expand_active = 1; - if (rl_last_func == bash_dabbrev_expand) - rl_last_func = rl_menu_complete; - r = rl_menu_complete (count, key); - dabbrev_expand_active = 0; - - rl_last_func = bash_dabbrev_expand; - rl_menu_completion_entry_function = orig_func; - rl_attempted_completion_function = orig_attempt_func; - rl_ignore_some_completions_function = orig_ignore_func; - rl_completion_suppress_append = orig_suppress; - rl_sort_completion_matches = orig_sort; - - return r; -} - -#if defined (SPECIFIC_COMPLETION_FUNCTIONS) -static int -bash_complete_username (ignore, ignore2) - int ignore, ignore2; -{ - return bash_complete_username_internal (rl_completion_mode (bash_complete_username)); -} - -static int -bash_possible_username_completions (ignore, ignore2) - int ignore, ignore2; -{ - return bash_complete_username_internal ('?'); -} - -static int -bash_complete_username_internal (what_to_do) - int what_to_do; -{ - return bash_specific_completion (what_to_do, rl_username_completion_function); -} - -static int -bash_complete_filename (ignore, ignore2) - int ignore, ignore2; -{ - return bash_complete_filename_internal (rl_completion_mode (bash_complete_filename)); -} - -static int -bash_possible_filename_completions (ignore, ignore2) - int ignore, ignore2; -{ - return bash_complete_filename_internal ('?'); -} - -static int -bash_complete_filename_internal (what_to_do) - int what_to_do; -{ - rl_compentry_func_t *orig_func; - rl_completion_func_t *orig_attempt_func; - rl_icppfunc_t *orig_dir_func; - rl_compignore_func_t *orig_ignore_func; - const char *orig_rl_completer_word_break_characters; - int r; - - orig_func = rl_completion_entry_function; - orig_attempt_func = rl_attempted_completion_function; - orig_ignore_func = rl_ignore_some_completions_function; - orig_rl_completer_word_break_characters = rl_completer_word_break_characters; - - orig_dir_func = save_directory_hook (); - - rl_completion_entry_function = rl_filename_completion_function; - rl_attempted_completion_function = (rl_completion_func_t *)NULL; - rl_ignore_some_completions_function = filename_completion_ignore; - rl_completer_word_break_characters = " \t\n\"\'"; - - r = rl_complete_internal (what_to_do); - - rl_completion_entry_function = orig_func; - rl_attempted_completion_function = orig_attempt_func; - rl_ignore_some_completions_function = orig_ignore_func; - rl_completer_word_break_characters = orig_rl_completer_word_break_characters; - - restore_directory_hook (orig_dir_func); - - return r; -} - -static int -bash_complete_hostname (ignore, ignore2) - int ignore, ignore2; -{ - return bash_complete_hostname_internal (rl_completion_mode (bash_complete_hostname)); -} - -static int -bash_possible_hostname_completions (ignore, ignore2) - int ignore, ignore2; -{ - return bash_complete_hostname_internal ('?'); -} - -static int -bash_complete_variable (ignore, ignore2) - int ignore, ignore2; -{ - return bash_complete_variable_internal (rl_completion_mode (bash_complete_variable)); -} - -static int -bash_possible_variable_completions (ignore, ignore2) - int ignore, ignore2; -{ - return bash_complete_variable_internal ('?'); -} - -static int -bash_complete_command (ignore, ignore2) - int ignore, ignore2; -{ - return bash_complete_command_internal (rl_completion_mode (bash_complete_command)); -} - -static int -bash_possible_command_completions (ignore, ignore2) - int ignore, ignore2; -{ - return bash_complete_command_internal ('?'); -} - -static int -bash_complete_hostname_internal (what_to_do) - int what_to_do; -{ - return bash_specific_completion (what_to_do, hostname_completion_function); -} - -static int -bash_complete_variable_internal (what_to_do) - int what_to_do; -{ - return bash_specific_completion (what_to_do, variable_completion_function); -} - -static int -bash_complete_command_internal (what_to_do) - int what_to_do; -{ - return bash_specific_completion (what_to_do, command_word_completion_function); -} - -static int -completion_glob_pattern (string) - char *string; -{ - return (glob_pattern_p (string) == 1); -} - -static char *globtext; -static char *globorig; - -static char * -glob_complete_word (text, state) - const char *text; - int state; -{ - static char **matches = (char **)NULL; - static int ind; - int glen; - char *ret, *ttext; - - if (state == 0) - { - rl_filename_completion_desired = 1; - FREE (matches); - if (globorig != globtext) - FREE (globorig); - FREE (globtext); - - ttext = bash_tilde_expand (text, 0); - - if (rl_explicit_arg) - { - globorig = savestring (ttext); - glen = strlen (ttext); - globtext = (char *)xmalloc (glen + 2); - strcpy (globtext, ttext); - globtext[glen] = '*'; - globtext[glen+1] = '\0'; - } - else - globtext = globorig = savestring (ttext); - - if (ttext != text) - free (ttext); - - matches = shell_glob_filename (globtext, 0); - if (GLOB_FAILED (matches)) - matches = (char **)NULL; - ind = 0; - } - - ret = matches ? matches[ind] : (char *)NULL; - ind++; - return ret; -} - -static int -bash_glob_completion_internal (what_to_do) - int what_to_do; -{ - return bash_specific_completion (what_to_do, glob_complete_word); -} - -/* A special quoting function so we don't end up quoting globbing characters - in the word if there are no matches or multiple matches. */ -static char * -bash_glob_quote_filename (s, rtype, qcp) - char *s; - int rtype; - char *qcp; -{ - if (globorig && qcp && *qcp == '\0' && STREQ (s, globorig)) - return (savestring (s)); - else - return (bash_quote_filename (s, rtype, qcp)); -} - -static int -bash_glob_complete_word (count, key) - int count, key; -{ - int r; - rl_quote_func_t *orig_quoting_function; - - if (rl_editing_mode == EMACS_EDITING_MODE) - rl_explicit_arg = 1; /* force `*' append */ - orig_quoting_function = rl_filename_quoting_function; - rl_filename_quoting_function = bash_glob_quote_filename; - - r = bash_glob_completion_internal (rl_completion_mode (bash_glob_complete_word)); - - rl_filename_quoting_function = orig_quoting_function; - return r; -} - -static int -bash_glob_expand_word (count, key) - int count, key; -{ - return bash_glob_completion_internal ('*'); -} - -static int -bash_glob_list_expansions (count, key) - int count, key; -{ - return bash_glob_completion_internal ('?'); -} - -static int -bash_specific_completion (what_to_do, generator) - int what_to_do; - rl_compentry_func_t *generator; -{ - rl_compentry_func_t *orig_func; - rl_completion_func_t *orig_attempt_func; - rl_compignore_func_t *orig_ignore_func; - int r; - - orig_func = rl_completion_entry_function; - orig_attempt_func = rl_attempted_completion_function; - orig_ignore_func = rl_ignore_some_completions_function; - rl_completion_entry_function = generator; - rl_attempted_completion_function = NULL; - rl_ignore_some_completions_function = orig_ignore_func; - - r = rl_complete_internal (what_to_do); - - rl_completion_entry_function = orig_func; - rl_attempted_completion_function = orig_attempt_func; - rl_ignore_some_completions_function = orig_ignore_func; - - return r; -} - -#endif /* SPECIFIC_COMPLETION_FUNCTIONS */ - -#if defined (VI_MODE) -/* Completion, from vi mode's point of view. This is a modified version of - rl_vi_complete which uses the bash globbing code to implement what POSIX - specifies, which is to append a `*' and attempt filename generation (which - has the side effect of expanding any globbing characters in the word). */ -static int -bash_vi_complete (count, key) - int count, key; -{ -#if defined (SPECIFIC_COMPLETION_FUNCTIONS) - int p, r; - char *t; - - if ((rl_point < rl_end) && (!whitespace (rl_line_buffer[rl_point]))) - { - if (!whitespace (rl_line_buffer[rl_point + 1])) - rl_vi_end_word (1, 'E'); - rl_point++; - } - - /* Find boundaries of current word, according to vi definition of a - `bigword'. */ - t = 0; - if (rl_point > 0) - { - p = rl_point; - rl_vi_bWord (1, 'B'); - r = rl_point; - rl_point = p; - p = r; - - t = substring (rl_line_buffer, p, rl_point); - } - - if (t && completion_glob_pattern (t) == 0) - rl_explicit_arg = 1; /* XXX - force glob_complete_word to append `*' */ - FREE (t); - - if (key == '*') /* Expansion and replacement. */ - r = bash_glob_expand_word (count, key); - else if (key == '=') /* List possible completions. */ - r = bash_glob_list_expansions (count, key); - else if (key == '\\') /* Standard completion */ - r = bash_glob_complete_word (count, key); - else - r = rl_complete (0, key); - - if (key == '*' || key == '\\') - rl_vi_start_inserting (key, 1, 1); - - return (r); -#else - return rl_vi_complete (count, key); -#endif /* !SPECIFIC_COMPLETION_FUNCTIONS */ -} -#endif /* VI_MODE */ - -/* Filename quoting for completion. */ -/* A function to strip unquoted quote characters (single quotes, double - quotes, and backslashes). It allows single quotes to appear - within double quotes, and vice versa. It should be smarter. */ -static char * -bash_dequote_filename (text, quote_char) - char *text; - int quote_char; -{ - char *ret, *p, *r; - int l, quoted; - - l = strlen (text); - ret = (char *)xmalloc (l + 1); - for (quoted = quote_char, p = text, r = ret; p && *p; p++) - { - /* Allow backslash-escaped characters to pass through unscathed. */ - if (*p == '\\') - { - /* Backslashes are preserved within single quotes. */ - if (quoted == '\'') - *r++ = *p; - /* Backslashes are preserved within double quotes unless the - character is one that is defined to be escaped */ - else if (quoted == '"' && ((sh_syntaxtab[(unsigned char)p[1]] & CBSDQUOTE) == 0)) - *r++ = *p; - - *r++ = *++p; - if (*p == '\0') - return ret; /* XXX - was break; */ - continue; - } - /* Close quote. */ - if (quoted && *p == quoted) - { - quoted = 0; - continue; - } - /* Open quote. */ - if (quoted == 0 && (*p == '\'' || *p == '"')) - { - quoted = *p; - continue; - } - *r++ = *p; - } - *r = '\0'; - return ret; -} - -/* Quote characters that the readline completion code would treat as - word break characters with backslashes. Pass backslash-quoted - characters through without examination. */ -static char * -quote_word_break_chars (text) - char *text; -{ - char *ret, *r, *s; - int l; - - l = strlen (text); - ret = (char *)xmalloc ((2 * l) + 1); - for (s = text, r = ret; *s; s++) - { - /* Pass backslash-quoted characters through, including the backslash. */ - if (*s == '\\') - { - *r++ = '\\'; - *r++ = *++s; - if (*s == '\0') - break; - continue; - } - /* OK, we have an unquoted character. Check its presence in - rl_completer_word_break_characters. */ - if (mbschr (rl_completer_word_break_characters, *s)) - *r++ = '\\'; - /* XXX -- check for standalone tildes here and backslash-quote them */ - if (s == text && *s == '~' && file_exists (text)) - *r++ = '\\'; - *r++ = *s; - } - *r = '\0'; - return ret; -} - -/* Return a character in DIRNAME that will cause shell expansion to be - performed. If NEXTP is non-null, *NEXTP gets the expansion character that - follows RET (e.g., '{' or `(' for `$'). If CLOSERP is non-null, *CLOSERP - gets the character that should close . If NEED_CLOSER is non- - zero, any expansion pair that isn't closed causes this function to - return 0, which indicates that we didn't find an expansion character. It's - used in case DIRNAME is going to be expanded. If DIRNAME is just going to - be quoted, NEED_CLOSER will be 0. */ -static int -bash_check_expchar (dirname, need_closer, nextp, closerp) - char *dirname; - int need_closer; - int *nextp, *closerp; -{ - char *t; - int ret, n, c; - - ret = n = c = 0; - if (t = mbschr (dirname, '$')) - { - ret = '$'; - n = t[1]; - /* Deliberately does not handle the deprecated $[...] arithmetic - expansion syntax */ - if (n == '(') - c = ')'; - else if (n == '{') - c = '}'; - else - n = 0; - - if (c && need_closer) /* XXX */ - { - int p; - char delims[2]; - - delims[0] = c; delims[1] = 0; - p = skip_to_delim (t, 1, delims, SD_NOJMP|SD_COMPLETE); - if (t[p] != c) - ret = 0; - } - } - else if (dirname[0] == '~') - ret = '~'; - else - { - t = mbschr (dirname, '`'); - if (t) - { - if (need_closer == 0) - ret = '`'; - else if (unclosed_pair (dirname, strlen (dirname), "`") == 0) - ret = '`'; - } - } - - if (nextp) - *nextp = n; - if (closerp) - *closerp = c; - - return ret; -} - -/* Make sure EXPCHAR and, if non-zero, NEXTCH and CLOSER are not in the set - of characters to be backslash-escaped. This is the only place - custom_filename_quote_characters is modified. */ -static void -set_filename_quote_chars (expchar, nextch, closer) - int expchar, nextch, closer; -{ - int i, j, c; - - if (rl_filename_quote_characters && *rl_filename_quote_characters) - { - i = strlen (default_filename_quote_characters); - custom_filename_quote_characters = xrealloc (custom_filename_quote_characters, i+1); - for (i = j = 0; c = default_filename_quote_characters[i]; i++) - { - if (c == expchar || c == nextch || c == closer) - continue; - custom_filename_quote_characters[j++] = c; - } - custom_filename_quote_characters[j] = '\0'; - rl_filename_quote_characters = custom_filename_quote_characters; - set_filename_bstab (rl_filename_quote_characters); - } -} - -/* Use characters in STRING to populate the table of characters that should - be backslash-quoted. The table will be used for sh_backslash_quote from - this file. */ -static void -set_filename_bstab (string) - const char *string; -{ - const char *s; - - memset (filename_bstab, 0, sizeof (filename_bstab)); - for (s = string; s && *s; s++) - filename_bstab[(unsigned char)*s] = 1; -} - -/* Quote a filename using double quotes, single quotes, or backslashes - depending on the value of completion_quoting_style. If we're - completing using backslashes, we need to quote some additional - characters (those that readline treats as word breaks), so we call - quote_word_break_chars on the result. This returns newly-allocated - memory. */ -static char * -bash_quote_filename (s, rtype, qcp) - char *s; - int rtype; - char *qcp; -{ - char *rtext, *mtext, *ret; - int rlen, cs; - int expchar, nextch, closer; - - rtext = (char *)NULL; - - /* If RTYPE == MULT_MATCH, it means that there is - more than one match. In this case, we do not add - the closing quote or attempt to perform tilde - expansion. If RTYPE == SINGLE_MATCH, we try - to perform tilde expansion, because single and double - quotes inhibit tilde expansion by the shell. */ - - cs = completion_quoting_style; - /* Might need to modify the default completion style based on *qcp, - since it's set to any user-provided opening quote. We also change - to single-quoting if there is no user-provided opening quote and - the word being completed contains newlines, since those are not - quoted correctly using backslashes (a backslash-newline pair is - special to the shell parser). */ - expchar = nextch = closer = 0; - if (*qcp == '\0' && cs == COMPLETE_BSQUOTE && dircomplete_expand == 0 && - (expchar = bash_check_expchar (s, 0, &nextch, &closer)) && - file_exists (s) == 0) - { - /* Usually this will have been set by bash_directory_completion_hook, - but there are cases where it will not be. */ - if (rl_filename_quote_characters != custom_filename_quote_characters) - set_filename_quote_chars (expchar, nextch, closer); - complete_fullquote = 0; - } - else if (*qcp == '\0' && cs == COMPLETE_BSQUOTE && mbschr (s, '\n')) - cs = COMPLETE_SQUOTE; - else if (*qcp == '"') - cs = COMPLETE_DQUOTE; - else if (*qcp == '\'') - cs = COMPLETE_SQUOTE; -#if defined (BANG_HISTORY) - else if (*qcp == '\0' && history_expansion && cs == COMPLETE_DQUOTE && - history_expansion_inhibited == 0 && mbschr (s, '!')) - cs = COMPLETE_BSQUOTE; - - if (*qcp == '"' && history_expansion && cs == COMPLETE_DQUOTE && - history_expansion_inhibited == 0 && mbschr (s, '!')) - { - cs = COMPLETE_BSQUOTE; - *qcp = '\0'; - } -#endif - - /* Don't tilde-expand backslash-quoted filenames, since only single and - double quotes inhibit tilde expansion. */ - mtext = s; - if (mtext[0] == '~' && rtype == SINGLE_MATCH && cs != COMPLETE_BSQUOTE) - mtext = bash_tilde_expand (s, 0); - - switch (cs) - { - case COMPLETE_DQUOTE: - rtext = sh_double_quote (mtext); - break; - case COMPLETE_SQUOTE: - rtext = sh_single_quote (mtext); - break; - case COMPLETE_BSQUOTE: - rtext = sh_backslash_quote (mtext, complete_fullquote ? 0 : filename_bstab, 0); - break; - } - - if (mtext != s) - free (mtext); - - /* We may need to quote additional characters: those that readline treats - as word breaks that are not quoted by backslash_quote. */ - /* XXX - test complete_fullquote here? */ - if (rtext && cs == COMPLETE_BSQUOTE && rl_completer_word_break_characters) - { - mtext = quote_word_break_chars (rtext); - free (rtext); - rtext = mtext; - } - - /* Leave the opening quote intact. The readline completion code takes - care of avoiding doubled opening quotes. */ - if (rtext) - { - rlen = strlen (rtext); - ret = (char *)xmalloc (rlen + 1); - strcpy (ret, rtext); - } - else - { - ret = (char *)xmalloc (rlen = 1); - ret[0] = '\0'; - } - - /* If there are multiple matches, cut off the closing quote. */ - if (rtype == MULT_MATCH && cs != COMPLETE_BSQUOTE) - ret[rlen - 1] = '\0'; - free (rtext); - return ret; -} - -/* Support for binding readline key sequences to Unix commands. Each editing - mode has a separate Unix command keymap. */ - -static Keymap emacs_std_cmd_xmap; -#if defined (VI_MODE) -static Keymap vi_insert_cmd_xmap; -static Keymap vi_movement_cmd_xmap; -#endif - -#ifdef _MINIX -static void -#else -static int -#endif -putx(c) - int c; -{ - int x; - x = putc (c, rl_outstream); -#ifndef _MINIX - return x; -#endif -} - -static int -readline_get_char_offset (ind) - int ind; -{ - int r, old_ch; - - r = ind; -#if defined (HANDLE_MULTIBYTE) - if (locale_mb_cur_max > 1) - { - old_ch = rl_line_buffer[ind]; - rl_line_buffer[ind] = '\0'; - r = MB_STRLEN (rl_line_buffer); - rl_line_buffer[ind] = old_ch; - } -#endif - return r; -} - -static void -readline_set_char_offset (ind, varp) - int ind; - int *varp; -{ - int i; - - i = ind; - -#if defined (HANDLE_MULTIBYTE) - if (i > 0 && locale_mb_cur_max > 1) - i = _rl_find_next_mbchar (rl_line_buffer, 0, i, 0); /* XXX */ -#endif - if (i != *varp) - { - if (i > rl_end) - i = rl_end; - else if (i < 0) - i = 0; - *varp = i; - } -} - -int -bash_execute_unix_command (count, key) - int count; /* ignored */ - int key; -{ - int type; - register int i, r; - intmax_t mi; - sh_parser_state_t ps; - char *cmd, *value, *ce, old_ch; - SHELL_VAR *v; - char ibuf[INT_STRLEN_BOUND(int) + 1]; - Keymap cmd_xmap; - const char *kseq; - size_t kslen; - - kseq = rl_executing_keyseq; - kslen = rl_key_sequence_length; - - /* If we have a numeric argument, chop it off the front of the key sequence */ - if (count > 1 || rl_explicit_arg) - { - i = rl_trim_arg_from_keyseq (rl_executing_keyseq, rl_key_sequence_length, rl_get_keymap ()); - if (i > 0) - { - kseq = rl_executing_keyseq + i; - kslen = rl_key_sequence_length - i; - } - } - - /* First, we need to find the right command to execute. This is tricky, - because we might have already indirected into another keymap, so we - have to walk cmd_xmap using the entire key sequence. */ - cmd_xmap = get_cmd_xmap_from_keymap (rl_get_keymap ()); - cmd = (char *)rl_function_of_keyseq_len (kseq, kslen, cmd_xmap, &type); - - if (type == ISKMAP && (type = ((Keymap) cmd)[ANYOTHERKEY].type) == ISMACR) - cmd = (char*)((Keymap) cmd)[ANYOTHERKEY].function; - - if (cmd == 0 || type != ISMACR) - { - rl_crlf (); - internal_error (_("bash_execute_unix_command: cannot find keymap for command")); - rl_forced_update_display (); - return 1; - } - - ce = rl_get_termcap ("ce"); - if (ce) /* clear current line */ - { - rl_clear_visible_line (); - fflush (rl_outstream); - } - else - rl_crlf (); /* move to a new line */ - - v = bind_variable ("READLINE_LINE", rl_line_buffer, 0); - if (v) - VSETATTR (v, att_exported); - - i = readline_get_char_offset (rl_point); - value = inttostr (i, ibuf, sizeof (ibuf)); - v = bind_int_variable ("READLINE_POINT", value, 0); - if (v) - VSETATTR (v, att_exported); - - i = readline_get_char_offset (rl_mark); - value = inttostr (i, ibuf, sizeof (ibuf)); - v = bind_int_variable ("READLINE_MARK", value, 0); - if (v) - VSETATTR (v, att_exported); - - if (count > 1 || rl_explicit_arg) - { - value = inttostr (count, ibuf, sizeof (ibuf)); - v = bind_int_variable ("READLINE_ARGUMENT", value, 0); - if (v) - VSETATTR (v, att_exported); - } - array_needs_making = 1; - - save_parser_state (&ps); - rl_clear_signals (); - r = parse_and_execute (savestring (cmd), "bash_execute_unix_command", SEVAL_NOHIST); - rl_set_signals (); - restore_parser_state (&ps); - - v = find_variable ("READLINE_LINE"); - maybe_make_readline_line (v ? value_cell (v) : 0); - - v = find_variable ("READLINE_POINT"); - if (v && legal_number (value_cell (v), &mi)) - readline_set_char_offset (mi, &rl_point); - - v = find_variable ("READLINE_MARK"); - if (v && legal_number (value_cell (v), &mi)) - readline_set_char_offset (mi, &rl_mark); - - check_unbind_variable ("READLINE_LINE"); - check_unbind_variable ("READLINE_POINT"); - check_unbind_variable ("READLINE_MARK"); - check_unbind_variable ("READLINE_ARGUMENT"); - array_needs_making = 1; - - /* and restore the readline buffer and display after command execution. */ - /* If we clear the last line of the prompt above, redraw only that last - line. If the command returns 124, we redraw unconditionally as in - previous versions. */ - if (ce && r != 124) - rl_redraw_prompt_last_line (); - else - rl_forced_update_display (); - - return 0; -} - -int -print_unix_command_map () -{ - Keymap save, cmd_xmap; - - save = rl_get_keymap (); - cmd_xmap = get_cmd_xmap_from_keymap (save); - rl_set_keymap (cmd_xmap); - rl_macro_dumper (1); - rl_set_keymap (save); - return 0; -} - -static void -init_unix_command_map () -{ - emacs_std_cmd_xmap = rl_make_bare_keymap (); - - emacs_std_cmd_xmap[CTRL('X')].type = ISKMAP; - emacs_std_cmd_xmap[CTRL('X')].function = KEYMAP_TO_FUNCTION (rl_make_bare_keymap ()); - emacs_std_cmd_xmap[ESC].type = ISKMAP; - emacs_std_cmd_xmap[ESC].function = KEYMAP_TO_FUNCTION (rl_make_bare_keymap ()); - -#if defined (VI_MODE) - vi_insert_cmd_xmap = rl_make_bare_keymap (); - vi_movement_cmd_xmap = rl_make_bare_keymap (); -#endif -} - -static Keymap -get_cmd_xmap_from_edit_mode () -{ - if (emacs_std_cmd_xmap == 0) - init_unix_command_map (); - - switch (rl_editing_mode) - { - case EMACS_EDITING_MODE: - return emacs_std_cmd_xmap; -#if defined (VI_MODE) - case VI_EDITING_MODE: - return (get_cmd_xmap_from_keymap (rl_get_keymap ())); -#endif - default: - return (Keymap)NULL; - } -} - -static Keymap -get_cmd_xmap_from_keymap (kmap) - Keymap kmap; -{ - if (emacs_std_cmd_xmap == 0) - init_unix_command_map (); - - if (kmap == emacs_standard_keymap) - return emacs_std_cmd_xmap; - else if (kmap == emacs_meta_keymap) - return (FUNCTION_TO_KEYMAP (emacs_std_cmd_xmap, ESC)); - else if (kmap == emacs_ctlx_keymap) - return (FUNCTION_TO_KEYMAP (emacs_std_cmd_xmap, CTRL('X'))); -#if defined (VI_MODE) - else if (kmap == vi_insertion_keymap) - return vi_insert_cmd_xmap; - else if (kmap == vi_movement_keymap) - return vi_movement_cmd_xmap; -#endif - else - return (Keymap)NULL; -} - -static int -isolate_sequence (string, ind, need_dquote, startp) - char *string; - int ind, need_dquote, *startp; -{ - register int i; - int c, passc, delim; - - for (i = ind; string[i] && whitespace (string[i]); i++) - ; - /* NEED_DQUOTE means that the first non-white character *must* be `"'. */ - if (need_dquote && string[i] != '"') - { - builtin_error (_("%s: first non-whitespace character is not `\"'"), string); - return -1; - } - - /* We can have delimited strings even if NEED_DQUOTE == 0, like the command - string to bind the key sequence to. */ - delim = (string[i] == '"' || string[i] == '\'') ? string[i] : 0; - - if (startp) - *startp = delim ? ++i : i; - - for (passc = 0; c = string[i]; i++) - { - if (passc) - { - passc = 0; - continue; - } - if (c == '\\') - { - passc++; - continue; - } - if (c == delim) - break; - } - - if (delim && string[i] != delim) - { - builtin_error (_("no closing `%c' in %s"), delim, string); - return -1; - } - - return i; -} - -int -bind_keyseq_to_unix_command (line) - char *line; -{ - Keymap kmap, cmd_xmap; - char *kseq, *value; - int i, kstart; - - kmap = rl_get_keymap (); - - /* We duplicate some of the work done by rl_parse_and_bind here, but - this code only has to handle `"keyseq": ["]command["]' and can - generate an error for anything else. */ - i = isolate_sequence (line, 0, 1, &kstart); - if (i < 0) - return -1; - - /* Create the key sequence string to pass to rl_generic_bind */ - kseq = substring (line, kstart, i); - - for ( ; line[i] && line[i] != ':'; i++) - ; - if (line[i] != ':') - { - builtin_error (_("%s: missing colon separator"), line); - FREE (kseq); - return -1; - } - - i = isolate_sequence (line, i + 1, 0, &kstart); - if (i < 0) - { - FREE (kseq); - return -1; - } - - /* Create the value string containing the command to execute. */ - value = substring (line, kstart, i); - - /* Save the command to execute and the key sequence in the CMD_XMAP */ - cmd_xmap = get_cmd_xmap_from_keymap (kmap); - rl_generic_bind (ISMACR, kseq, value, cmd_xmap); - - /* and bind the key sequence in the current keymap to a function that - understands how to execute from CMD_XMAP */ - rl_bind_keyseq_in_map (kseq, bash_execute_unix_command, kmap); - - free (kseq); - return 0; -} - -int -unbind_unix_command (kseq) - char *kseq; -{ - Keymap cmd_xmap; - - cmd_xmap = get_cmd_xmap_from_keymap (rl_get_keymap ()); - if (rl_bind_keyseq_in_map (kseq, (rl_command_func_t *)NULL, cmd_xmap) != 0) - { - builtin_error (_("`%s': cannot unbind in command keymap"), kseq); - return 0; - } - return 1; -} - -/* Used by the programmable completion code. Complete TEXT as a filename, - but return only directories as matches. Dequotes the filename before - attempting to find matches. */ -char ** -bash_directory_completion_matches (text) - const char *text; -{ - char **m1; - char *dfn; - int qc; - - qc = rl_dispatching ? rl_completion_quote_character : 0; - /* If rl_completion_found_quote != 0, rl_completion_matches will call the - filename dequoting function, causing the directory name to be dequoted - twice. */ - if (rl_dispatching && rl_completion_found_quote == 0) - dfn = bash_dequote_filename ((char *)text, qc); - else - dfn = (char *)text; - m1 = rl_completion_matches (dfn, rl_filename_completion_function); - if (dfn != text) - free (dfn); - - if (m1 == 0 || m1[0] == 0) - return m1; - /* We don't bother recomputing the lcd of the matches, because it will just - get thrown away by the programmable completion code and recomputed - later. */ - (void)bash_progcomp_ignore_filenames (m1); - return m1; -} - -char * -bash_dequote_text (text) - const char *text; -{ - char *dtxt; - int qc; - - qc = (text[0] == '"' || text[0] == '\'') ? text[0] : 0; - dtxt = bash_dequote_filename ((char *)text, qc); - return (dtxt); -} - -/* This event hook is designed to be called after readline receives a signal - that interrupts read(2). It gives reasonable responsiveness to interrupts - and fatal signals without executing too much code in a signal handler - context. */ -static int -bash_event_hook () -{ - int sig; - - /* XXX - see if we need to do anything here if sigterm_received == 1, - we probably don't want to reset the event hook since we will not be - jumping to the top level */ - if (sigterm_received) - { - /* RESET_SIGTERM; */ - return 0; - } - - sig = 0; - if (terminating_signal) - sig = terminating_signal; - else if (interrupt_state) - sig = SIGINT; - else if (read_timeout && read_timeout->alrmflag) - sig = SIGALRM; - else if (RL_ISSTATE (RL_STATE_TIMEOUT)) /* just in case */ - { - sig = SIGALRM; - if (read_timeout) - read_timeout->alrmflag = 1; - } - else - sig = first_pending_trap (); - - /* If we're going to longjmp to top_level, make sure we clean up readline. - check_signals will call QUIT, which will eventually longjmp to top_level, - calling run_interrupt_trap along the way. The check against read_timeout - is so we can clean up the read builtin's state. */ - if (terminating_signal || interrupt_state || (read_timeout && read_timeout->alrmflag)) - rl_cleanup_after_signal (); - bashline_reset_event_hook (); - - RL_UNSETSTATE (RL_STATE_TIMEOUT); /* XXX */ - - /* posix mode SIGINT during read -e. We only get here if SIGINT is trapped. */ - if (posixly_correct && this_shell_builtin == read_builtin && sig == SIGINT) - { - last_command_exit_value = 128|SIGINT; - throw_to_top_level (); - } - - check_signals_and_traps (); /* XXX */ - return 0; -} - -#endif /* READLINE */ diff --git a/third_party/bash/bashline.h b/third_party/bash/bashline.h deleted file mode 100644 index d40228e29..000000000 --- a/third_party/bash/bashline.h +++ /dev/null @@ -1,69 +0,0 @@ -/* bashline.h -- interface to the bash readline functions in bashline.c. */ - -/* Copyright (C) 1993-2019 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_BASHLINE_H_) -#define _BASHLINE_H_ - -#include "stdc.h" - -extern int bash_readline_initialized; -extern int hostname_list_initialized; - -/* these are controlled via shopt */ -extern int perform_hostname_completion; -extern int no_empty_command_completion; -extern int force_fignore; -extern int dircomplete_spelling; -extern int dircomplete_expand; -extern int dircomplete_expand_relpath; -extern int complete_fullquote; - -extern void posix_readline_initialize PARAMS((int)); -extern void reset_completer_word_break_chars PARAMS((void)); -extern int enable_hostname_completion PARAMS((int)); -extern void initialize_readline PARAMS((void)); -extern void bashline_reset PARAMS((void)); -extern void bashline_reinitialize PARAMS((void)); -extern int bash_re_edit PARAMS((char *)); - -extern void bashline_set_event_hook PARAMS((void)); -extern void bashline_reset_event_hook PARAMS((void)); - -extern int bind_keyseq_to_unix_command PARAMS((char *)); -extern int bash_execute_unix_command PARAMS((int, int)); -extern int print_unix_command_map PARAMS((void)); -extern int unbind_unix_command PARAMS((char *)); - -extern char **bash_default_completion PARAMS((const char *, int, int, int, int)); - -extern void set_directory_hook PARAMS((void)); - -/* Used by programmable completion code. */ -extern char *command_word_completion_function PARAMS((const char *, int)); -extern char *bash_groupname_completion_function PARAMS((const char *, int)); -extern char *bash_servicename_completion_function PARAMS((const char *, int)); - -extern char **get_hostname_list PARAMS((void)); -extern void clear_hostname_list PARAMS((void)); - -extern char **bash_directory_completion_matches PARAMS((const char *)); -extern char *bash_dequote_text PARAMS((const char *)); - -#endif /* _BASHLINE_H_ */ diff --git a/third_party/bash/bashtypes.h b/third_party/bash/bashtypes.h deleted file mode 100644 index 01afef4b4..000000000 --- a/third_party/bash/bashtypes.h +++ /dev/null @@ -1,42 +0,0 @@ -/* bashtypes.h -- Bash system types. */ - -/* Copyright (C) 1993-2009 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_BASHTYPES_H_) -# define _BASHTYPES_H_ - -#if defined (CRAY) -# define word __word -#endif - -#include - -#if defined (CRAY) -# undef word -#endif - -#if defined (HAVE_INTTYPES_H) -# include -#endif - -#if HAVE_STDINT_H -# include -#endif - -#endif /* _BASHTYPES_H_ */ diff --git a/third_party/bash/bracecomp.c b/third_party/bash/bracecomp.c deleted file mode 100644 index 1e67640e6..000000000 --- a/third_party/bash/bracecomp.c +++ /dev/null @@ -1,221 +0,0 @@ -/* bracecomp.c -- Complete a filename with the possible completions enclosed - in csh-style braces such that the list of completions is available to the - shell. */ - -/* Original version by tromey@cns.caltech.edu, Fri Feb 7 1992. */ - -/* Copyright (C) 1993-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if defined (BRACE_EXPANSION) && defined (READLINE) - -#include - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include "bashansi.h" -#include "shmbutil.h" - -#include "shell.h" -#include "third_party/readline/readline.h" - -static int _strcompare PARAMS((char **, char **)); - -/* Find greatest common prefix of two strings. */ -static int -string_gcd (s1, s2) - char *s1, *s2; -{ - register int i; - - if (s1 == NULL || s2 == NULL) - return (0); - - for (i = 0; *s1 && *s2; ++s1, ++s2, ++i) - { - if (*s1 != *s2) - break; - } - - return (i); -} - -static char * -really_munge_braces (array, real_start, real_end, gcd_zero) - char **array; - int real_start, real_end, gcd_zero; -{ - int start, end, gcd; - char *result, *subterm, *x; - int result_size, flag, tlen; - - flag = 0; - - if (real_start == real_end) - { - x = array[real_start] ? sh_backslash_quote (array[real_start] + gcd_zero, 0, 0) - : sh_backslash_quote (array[0], 0, 0); - return x; - } - - result = (char *)xmalloc (result_size = 16); - *result = '\0'; - - for (start = real_start; start < real_end; start = end + 1) - { - gcd = strlen (array[start]); - for (end = start + 1; end < real_end; end++) - { - int temp; - - temp = string_gcd (array[start], array[end]); - - if (temp <= gcd_zero) - break; - - gcd = temp; - } - end--; - - if (gcd_zero == 0 && start == real_start && end != (real_end - 1)) - { - /* In this case, add in a leading '{', because we are at - top level, and there isn't a consistent prefix. */ - result_size += 1; - result = (char *)xrealloc (result, result_size); - result[0] = '{'; result[1] = '\0'; - flag++; - } - - /* Make sure we backslash quote every substring we insert into the - resultant brace expression. This is so the default filename - quoting function won't inappropriately quote the braces. */ - if (start == end) - { - x = savestring (array[start] + gcd_zero); - subterm = sh_backslash_quote (x, 0, 0); - free (x); - } - else - { - /* If there is more than one element in the subarray, - insert the (quoted) prefix and an opening brace. */ - tlen = gcd - gcd_zero; - x = (char *)xmalloc (tlen + 1); - strncpy (x, array[start] + gcd_zero, tlen); - x[tlen] = '\0'; - subterm = sh_backslash_quote (x, 0, 0); - free (x); - result_size += strlen (subterm) + 1; - result = (char *)xrealloc (result, result_size); - strcat (result, subterm); - free (subterm); - strcat (result, "{"); - subterm = really_munge_braces (array, start, end + 1, gcd); - subterm[strlen (subterm) - 1] = '}'; - } - - result_size += strlen (subterm) + 1; - result = (char *)xrealloc (result, result_size); - strcat (result, subterm); - strcat (result, ","); - free (subterm); - } - - if (gcd_zero == 0) - result[strlen (result) - 1] = flag ? '}' : '\0'; - return (result); -} - -static int -_strcompare (s1, s2) - char **s1, **s2; -{ - int result; - - result = **s1 - **s2; - if (result == 0) - result = strcmp (*s1, *s2); - - return result; -} - -static int -hack_braces_completion (names) - char **names; -{ - register int i; - char *temp; - - i = strvec_len (names); - if (MB_CUR_MAX > 1 && i > 2) - qsort (names+1, i-1, sizeof (char *), (QSFUNC *)_strcompare); - - temp = really_munge_braces (names, 1, i, 0); - - for (i = 0; names[i]; ++i) - { - free (names[i]); - names[i] = NULL; - } - names[0] = temp; - return 0; -} - -/* We handle quoting ourselves within hack_braces_completion, so we turn off - rl_filename_quoting_desired and rl_filename_quoting_function. */ -int -bash_brace_completion (count, ignore) - int count, ignore; -{ - rl_compignore_func_t *orig_ignore_func; - rl_compentry_func_t *orig_entry_func; - rl_quote_func_t *orig_quoting_func; - rl_completion_func_t *orig_attempt_func; - int orig_quoting_desired, r; - - orig_ignore_func = rl_ignore_some_completions_function; - orig_attempt_func = rl_attempted_completion_function; - orig_entry_func = rl_completion_entry_function; - orig_quoting_func = rl_filename_quoting_function; - orig_quoting_desired = rl_filename_quoting_desired; - - rl_completion_entry_function = rl_filename_completion_function; - rl_attempted_completion_function = (rl_completion_func_t *)NULL; - rl_ignore_some_completions_function = hack_braces_completion; - rl_filename_quoting_function = (rl_quote_func_t *)NULL; - rl_filename_quoting_desired = 0; - - r = rl_complete_internal (TAB); - - rl_ignore_some_completions_function = orig_ignore_func; - rl_attempted_completion_function = orig_attempt_func; - rl_completion_entry_function = orig_entry_func; - rl_filename_quoting_function = orig_quoting_func; - rl_filename_quoting_desired = orig_quoting_desired; - - return r; -} -#endif /* BRACE_EXPANSION && READLINE */ diff --git a/third_party/bash/braces.c b/third_party/bash/braces.c deleted file mode 100644 index e91d326ea..000000000 --- a/third_party/bash/braces.c +++ /dev/null @@ -1,843 +0,0 @@ -/* braces.c -- code for doing word expansion in curly braces. */ - -/* Copyright (C) 1987-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -/* Stuff in curly braces gets expanded before all other shell expansions. */ - -#include "config.h" - -#if defined (BRACE_EXPANSION) - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include - -#include "bashansi.h" -#include "bashintl.h" - -#if defined (SHELL) -# include "shell.h" -#else -# if defined (TEST) -typedef char *WORD_DESC; -typedef char **WORD_LIST; -#define _(X) X -# endif /* TEST */ -#endif /* SHELL */ - -#include "typemax.h" /* INTMAX_MIN, INTMAX_MAX */ -#include "general.h" -#include "shmbutil.h" -#include "chartypes.h" - -#ifndef errno -extern int errno; -#endif - -#define brace_whitespace(c) (!(c) || (c) == ' ' || (c) == '\t' || (c) == '\n') - -#define BRACE_SEQ_SPECIFIER ".." - -extern int asprintf PARAMS((char **, const char *, ...)) __attribute__((__format__ (printf, 2, 3))); - -/* Basic idea: - - Segregate the text into 3 sections: preamble (stuff before an open brace), - postamble (stuff after the matching close brace) and amble (stuff after - preamble, and before postamble). Expand amble, and then tack on the - expansions to preamble. Expand postamble, and tack on the expansions to - the result so far. - */ - -/* The character which is used to separate arguments. */ -static const int brace_arg_separator = ','; - -#if defined (PARAMS) -static int brace_gobbler PARAMS((char *, size_t, int *, int)); -static char **expand_amble PARAMS((char *, size_t, int)); -static char **expand_seqterm PARAMS((char *, size_t)); -static char **mkseq PARAMS((intmax_t, intmax_t, intmax_t, int, int)); -static char **array_concat PARAMS((char **, char **)); -#else -static int brace_gobbler (); -static char **expand_amble (); -static char **expand_seqterm (); -static char **mkseq(); -static char **array_concat (); -#endif - -#if 0 -static void -dump_result (a) - char **a; -{ - int i; - - for (i = 0; a[i]; i++) - printf ("dump_result: a[%d] = -%s-\n", i, a[i]); -} -#endif - -/* Return an array of strings; the brace expansion of TEXT. */ -char ** -brace_expand (text) - char *text; -{ - register int start; - size_t tlen; - char *preamble, *postamble, *amble; - size_t alen; - char **tack, **result; - int i, j, c, c1; - - DECLARE_MBSTATE; - - /* Find the text of the preamble. */ - tlen = strlen (text); - i = 0; -#if defined (CSH_BRACE_COMPAT) - c = brace_gobbler (text, tlen, &i, '{'); /* } */ -#else - /* Make sure that when we exit this loop, c == 0 or text[i] begins a - valid brace expansion sequence. */ - do - { - c = brace_gobbler (text, tlen, &i, '{'); /* } */ - c1 = c; - /* Verify that c begins a valid brace expansion word. If it doesn't, we - go on. Loop stops when there are no more open braces in the word. */ - if (c) - { - start = j = i + 1; /* { */ - c = brace_gobbler (text, tlen, &j, '}'); - if (c == 0) /* it's not */ - { - i++; - c = c1; - continue; - } - else /* it is */ - { - c = c1; - break; - } - } - else - break; - } - while (c); -#endif /* !CSH_BRACE_COMPAT */ - - preamble = (char *)xmalloc (i + 1); - if (i > 0) - strncpy (preamble, text, i); - preamble[i] = '\0'; - - result = (char **)xmalloc (2 * sizeof (char *)); - result[0] = preamble; - result[1] = (char *)NULL; - - /* Special case. If we never found an exciting character, then - the preamble is all of the text, so just return that. */ - if (c != '{') - return (result); - - /* Find the amble. This is the stuff inside this set of braces. */ - start = ++i; - c = brace_gobbler (text, tlen, &i, '}'); - - /* What if there isn't a matching close brace? */ - if (c == 0) - { -#if defined (NOTDEF) - /* Well, if we found an unquoted BRACE_ARG_SEPARATOR between START - and I, then this should be an error. Otherwise, it isn't. */ - j = start; - while (j < i) - { - if (text[j] == '\\') - { - j++; - ADVANCE_CHAR (text, tlen, j); - continue; - } - - if (text[j] == brace_arg_separator) - { /* { */ - strvec_dispose (result); - set_exit_status (EXECUTION_FAILURE); - report_error ("no closing `%c' in %s", '}', text); - throw_to_top_level (); - } - ADVANCE_CHAR (text, tlen, j); - } -#endif - free (preamble); /* Same as result[0]; see initialization. */ - result[0] = savestring (text); - return (result); - } - -#if defined (SHELL) - amble = substring (text, start, i); - alen = i - start; -#else - amble = (char *)xmalloc (1 + (i - start)); - strncpy (amble, &text[start], (i - start)); - alen = i - start; - amble[alen] = '\0'; -#endif - -#if defined (SHELL) - INITIALIZE_MBSTATE; - - /* If the amble does not contain an unquoted BRACE_ARG_SEPARATOR, then - just return without doing any expansion. */ - j = 0; - while (amble[j]) - { - if (amble[j] == '\\') - { - j++; - ADVANCE_CHAR (amble, alen, j); - continue; - } - - if (amble[j] == brace_arg_separator) - break; - - ADVANCE_CHAR (amble, alen, j); - } - - if (amble[j] == 0) - { - tack = expand_seqterm (amble, alen); - if (tack) - goto add_tack; - else if (text[i + 1]) - { - /* If the sequence expansion fails (e.g., because the integers - overflow), but there is more in the string, try and process - the rest of the string, which may contain additional brace - expansions. Treat the unexpanded sequence term as a simple - string (including the braces). */ - tack = strvec_create (2); - tack[0] = savestring (text+start-1); - tack[0][i-start+2] = '\0'; - tack[1] = (char *)0; - goto add_tack; - } - else - { - free (amble); - free (preamble); - result[0] = savestring (text); - return (result); - } - } -#endif /* SHELL */ - - tack = expand_amble (amble, alen, 0); -add_tack: - result = array_concat (result, tack); - free (amble); - if (tack != result) - strvec_dispose (tack); - - postamble = text + i + 1; - - if (postamble && *postamble) - { - tack = brace_expand (postamble); - result = array_concat (result, tack); - if (tack != result) - strvec_dispose (tack); - } - - return (result); -} - -/* Expand the text found inside of braces. We simply try to split the - text at BRACE_ARG_SEPARATORs into separate strings. We then brace - expand each slot which needs it, until there are no more slots which - need it. */ -static char ** -expand_amble (text, tlen, flags) - char *text; - size_t tlen; - int flags; -{ - char **result, **partial, **tresult; - char *tem; - int start, i, c; - -#if defined (SHELL) - DECLARE_MBSTATE; -#endif - - result = (char **)NULL; - - start = i = 0; - c = 1; - while (c) - { - c = brace_gobbler (text, tlen, &i, brace_arg_separator); -#if defined (SHELL) - tem = substring (text, start, i); -#else - tem = (char *)xmalloc (1 + (i - start)); - strncpy (tem, &text[start], (i - start)); - tem[i - start] = '\0'; -#endif - - partial = brace_expand (tem); - - if (!result) - result = partial; - else - { - register int lr, lp, j; - - lr = strvec_len (result); - lp = strvec_len (partial); - - tresult = strvec_mresize (result, lp + lr + 1); - if (tresult == 0) - { - internal_error (_("brace expansion: cannot allocate memory for %s"), tem); - free (tem); - strvec_dispose (partial); - strvec_dispose (result); - result = (char **)NULL; - return result; - } - else - result = tresult; - - for (j = 0; j < lp; j++) - result[lr + j] = partial[j]; - - result[lr + j] = (char *)NULL; - free (partial); - } - free (tem); -#if defined (SHELL) - ADVANCE_CHAR (text, tlen, i); -#else - i++; -#endif - start = i; - } - return (result); -} - -#define ST_BAD 0 -#define ST_INT 1 -#define ST_CHAR 2 -#define ST_ZINT 3 - -static char ** -mkseq (start, end, incr, type, width) - intmax_t start, end, incr; - int type, width; -{ - intmax_t n, prevn; - int i, nelem; - char **result, *t; - - if (incr == 0) - incr = 1; - - if (start > end && incr > 0) - incr = -incr; - else if (start < end && incr < 0) - { - if (incr == INTMAX_MIN) /* Don't use -INTMAX_MIN */ - return ((char **)NULL); - incr = -incr; - } - - /* Check that end-start will not overflow INTMAX_MIN, INTMAX_MAX. The +3 - and -2, not strictly necessary, are there because of the way the number - of elements and value passed to strvec_create() are calculated below. */ - if (SUBOVERFLOW (end, start, INTMAX_MIN+3, INTMAX_MAX-2)) - return ((char **)NULL); - - prevn = sh_imaxabs (end - start); - /* Need to check this way in case INT_MAX == INTMAX_MAX */ - if (INT_MAX == INTMAX_MAX && (ADDOVERFLOW (prevn, 2, INT_MIN, INT_MAX))) - return ((char **)NULL); - /* Make sure the assignment to nelem below doesn't end up <= 0 due to - intmax_t overflow */ - else if (ADDOVERFLOW ((prevn/sh_imaxabs(incr)), 1, INTMAX_MIN, INTMAX_MAX)) - return ((char **)NULL); - - /* XXX - TOFIX: potentially allocating a lot of extra memory if - imaxabs(incr) != 1 */ - /* Instead of a simple nelem = prevn + 1, something like: - nelem = (prevn / imaxabs(incr)) + 1; - would work */ - if ((prevn / sh_imaxabs (incr)) > INT_MAX - 3) /* check int overflow */ - return ((char **)NULL); - nelem = (prevn / sh_imaxabs(incr)) + 1; - result = strvec_mcreate (nelem + 1); - if (result == 0) - { - internal_error (_("brace expansion: failed to allocate memory for %u elements"), (unsigned int)nelem); - return ((char **)NULL); - } - - /* Make sure we go through the loop at least once, so {3..3} prints `3' */ - i = 0; - n = start; - do - { -#if defined (SHELL) - if (ISINTERRUPT) - { - result[i] = (char *)NULL; - strvec_dispose (result); - result = (char **)NULL; - } - QUIT; -#endif - if (type == ST_INT) - result[i++] = t = itos (n); - else if (type == ST_ZINT) - { - int len, arg; - arg = n; - len = asprintf (&t, "%0*d", width, arg); - result[i++] = t; - } - else - { - if (t = (char *)malloc (2)) - { - t[0] = n; - t[1] = '\0'; - } - result[i++] = t; - } - - /* We failed to allocate memory for this number, so we bail. */ - if (t == 0) - { - char *p, lbuf[INT_STRLEN_BOUND(intmax_t) + 1]; - - /* Easier to do this than mess around with various intmax_t printf - formats (%ld? %lld? %jd?) and PRIdMAX. */ - p = inttostr (n, lbuf, sizeof (lbuf)); - internal_error (_("brace expansion: failed to allocate memory for `%s'"), p); - strvec_dispose (result); - return ((char **)NULL); - } - - /* Handle overflow and underflow of n+incr */ - if (ADDOVERFLOW (n, incr, INTMAX_MIN, INTMAX_MAX)) - break; - - n += incr; - - if ((incr < 0 && n < end) || (incr > 0 && n > end)) - break; - } - while (1); - - result[i] = (char *)0; - return (result); -} - -static char ** -expand_seqterm (text, tlen) - char *text; - size_t tlen; -{ - char *t, *lhs, *rhs; - int lhs_t, rhs_t, lhs_l, rhs_l, width; - intmax_t lhs_v, rhs_v, incr; - intmax_t tl, tr; - char **result, *ep, *oep; - - t = strstr (text, BRACE_SEQ_SPECIFIER); - if (t == 0) - return ((char **)NULL); - - lhs_l = t - text; /* index of start of BRACE_SEQ_SPECIFIER */ - lhs = substring (text, 0, lhs_l); - rhs = substring (text, lhs_l + sizeof(BRACE_SEQ_SPECIFIER) - 1, tlen); - - if (lhs[0] == 0 || rhs[0] == 0) - { - free (lhs); - free (rhs); - return ((char **)NULL); - } - - /* Now figure out whether LHS and RHS are integers or letters. Both - sides have to match. */ - lhs_t = (legal_number (lhs, &tl)) ? ST_INT : - ((ISALPHA (lhs[0]) && lhs[1] == 0) ? ST_CHAR : ST_BAD); - - /* Decide on rhs and whether or not it looks like the user specified - an increment */ - ep = 0; - if (ISDIGIT (rhs[0]) || ((rhs[0] == '+' || rhs[0] == '-') && ISDIGIT (rhs[1]))) - { - rhs_t = ST_INT; - errno = 0; - tr = strtoimax (rhs, &ep, 10); - if (errno == ERANGE || (ep && *ep != 0 && *ep != '.')) - rhs_t = ST_BAD; /* invalid */ - } - else if (ISALPHA (rhs[0]) && (rhs[1] == 0 || rhs[1] == '.')) - { - rhs_t = ST_CHAR; - ep = rhs + 1; - } - else - { - rhs_t = ST_BAD; - ep = 0; - } - - incr = 1; - if (rhs_t != ST_BAD) - { - oep = ep; - errno = 0; - if (ep && *ep == '.' && ep[1] == '.' && ep[2]) - incr = strtoimax (ep + 2, &ep, 10); - if (*ep != 0 || errno == ERANGE) - rhs_t = ST_BAD; /* invalid incr or overflow */ - tlen -= ep - oep; - } - - if (lhs_t != rhs_t || lhs_t == ST_BAD || rhs_t == ST_BAD) - { - free (lhs); - free (rhs); - return ((char **)NULL); - } - - /* OK, we have something. It's either a sequence of integers, ascending - or descending, or a sequence or letters, ditto. Generate the sequence, - put it into a string vector, and return it. */ - - if (lhs_t == ST_CHAR) - { - lhs_v = (unsigned char)lhs[0]; - rhs_v = (unsigned char)rhs[0]; - width = 1; - } - else - { - lhs_v = tl; /* integer truncation */ - rhs_v = tr; - - /* Decide whether or not the terms need zero-padding */ - rhs_l = tlen - lhs_l - sizeof (BRACE_SEQ_SPECIFIER) + 1; - width = 0; - if (lhs_l > 1 && lhs[0] == '0') - width = lhs_l, lhs_t = ST_ZINT; - if (lhs_l > 2 && lhs[0] == '-' && lhs[1] == '0') - width = lhs_l, lhs_t = ST_ZINT; - if (rhs_l > 1 && rhs[0] == '0' && width < rhs_l) - width = rhs_l, lhs_t = ST_ZINT; - if (rhs_l > 2 && rhs[0] == '-' && rhs[1] == '0' && width < rhs_l) - width = rhs_l, lhs_t = ST_ZINT; - - if (width < lhs_l && lhs_t == ST_ZINT) - width = lhs_l; - if (width < rhs_l && lhs_t == ST_ZINT) - width = rhs_l; - } - - result = mkseq (lhs_v, rhs_v, incr, lhs_t, width); - - free (lhs); - free (rhs); - - return (result); -} - -/* Start at INDEX, and skip characters in TEXT. Set INDEX to the - index of the character matching SATISFY. This understands about - quoting. Return the character that caused us to stop searching; - this is either the same as SATISFY, or 0. */ -/* If SATISFY is `}', we are looking for a brace expression, so we - should enforce the rules that govern valid brace expansions: - 1) to count as an arg separator, a comma or `..' has to be outside - an inner set of braces. -*/ -static int -brace_gobbler (text, tlen, indx, satisfy) - char *text; - size_t tlen; - int *indx; - int satisfy; -{ - register int i, c, quoted, level, commas, pass_next; -#if defined (SHELL) - int si; - char *t; -#endif - DECLARE_MBSTATE; - - level = quoted = pass_next = 0; -#if defined (CSH_BRACE_COMPAT) - commas = 1; -#else - commas = (satisfy == '}') ? 0 : 1; -#endif - - i = *indx; - while (c = text[i]) - { - if (pass_next) - { - pass_next = 0; -#if defined (SHELL) - ADVANCE_CHAR (text, tlen, i); -#else - i++; -#endif - continue; - } - - /* A backslash escapes the next character. This allows backslash to - escape the quote character in a double-quoted string. */ - if (c == '\\' && (quoted == 0 || quoted == '"' || quoted == '`')) - { - pass_next = 1; - i++; - continue; - } - -#if defined (SHELL) - /* If compiling for the shell, treat ${...} like \{...} */ - if (c == '$' && text[i+1] == '{' && quoted != '\'') /* } */ - { - pass_next = 1; - i++; - if (quoted == 0) - level++; - continue; - } -#endif - - if (quoted) - { - if (c == quoted) - quoted = 0; -#if defined (SHELL) - /* The shell allows quoted command substitutions */ - if (quoted == '"' && c == '$' && text[i+1] == '(') /*)*/ - goto comsub; -#endif -#if defined (SHELL) - ADVANCE_CHAR (text, tlen, i); -#else - i++; -#endif - continue; - } - - if (c == '"' || c == '\'' || c == '`') - { - quoted = c; - i++; - continue; - } - -#if defined (SHELL) - /* Pass new-style command and process substitutions through unchanged. */ - if ((c == '$' || c == '<' || c == '>') && text[i+1] == '(') /* ) */ - { -comsub: - si = i + 2; - t = extract_command_subst (text, &si, 0); - i = si; - free (t); - i++; - continue; - } -#endif - - if (c == satisfy && level == 0 && quoted == 0 && commas > 0) - { - /* We ignore an open brace surrounded by whitespace, and also - an open brace followed immediately by a close brace preceded - by whitespace. */ - if (c == '{' && - ((!i || brace_whitespace (text[i - 1])) && - (brace_whitespace (text[i + 1]) || text[i + 1] == '}'))) - { - i++; - continue; - } - - break; - } - - if (c == '{') - level++; - else if (c == '}' && level) - level--; -#if !defined (CSH_BRACE_COMPAT) - else if (satisfy == '}' && c == brace_arg_separator && level == 0) - commas++; - else if (satisfy == '}' && STREQN (text+i, BRACE_SEQ_SPECIFIER, 2) && - text[i+2] != satisfy && level == 0) - commas++; -#endif - -#if defined (SHELL) - ADVANCE_CHAR (text, tlen, i); -#else - i++; -#endif - } - - *indx = i; - return (c); -} - -/* Return a new array of strings which is the result of appending each - string in ARR2 to each string in ARR1. The resultant array is - len (arr1) * len (arr2) long. For convenience, ARR1 (and its contents) - are free ()'ed. ARR1 can be NULL, in that case, a new version of ARR2 - is returned. */ -static char ** -array_concat (arr1, arr2) - char **arr1, **arr2; -{ - register int i, j, len, len1, len2; - register char **result; - - if (arr1 == 0) - return (arr2); /* XXX - see if we can get away without copying? */ - - if (arr2 == 0) - return (arr1); /* XXX - caller expects us to free arr1 */ - - /* We can only short-circuit if the array consists of a single null element; - otherwise we need to replicate the contents of the other array and - prefix (or append, below) an empty element to each one. */ - if (arr1[0] && arr1[0][0] == 0 && arr1[1] == 0) - { - strvec_dispose (arr1); - return (arr2); /* XXX - use flags to see if we can avoid copying here */ - } - - if (arr2[0] && arr2[0][0] == 0 && arr2[1] == 0) - return (arr1); /* XXX - rather than copying and freeing it */ - - len1 = strvec_len (arr1); - len2 = strvec_len (arr2); - - result = (char **)malloc ((1 + (len1 * len2)) * sizeof (char *)); - if (result == 0) - return (result); - - len = 0; - for (i = 0; i < len1; i++) - { - int strlen_1 = strlen (arr1[i]); - - for (j = 0; j < len2; j++) - { - result[len] = (char *)xmalloc (1 + strlen_1 + strlen (arr2[j])); - strcpy (result[len], arr1[i]); - strcpy (result[len] + strlen_1, arr2[j]); - len++; - } - free (arr1[i]); - } - free (arr1); - - result[len] = (char *)NULL; - return (result); -} - -#if defined (TEST) -#include - -void * -xmalloc(n) - size_t n; -{ - return (malloc (n)); -} - -void * -xrealloc(p, n) - void *p; - size_t n; -{ - return (realloc (p, n)); -} - -int -internal_error (format, arg1, arg2) - char *format, *arg1, *arg2; -{ - fprintf (stderr, format, arg1, arg2); - fprintf (stderr, "\n"); -} - -main () -{ - char example[256]; - - for (;;) - { - char **result; - int i; - - fprintf (stderr, "brace_expand> "); - - if ((!fgets (example, 256, stdin)) || - (strncmp (example, "quit", 4) == 0)) - break; - - if (strlen (example)) - example[strlen (example) - 1] = '\0'; - - result = brace_expand (example); - - for (i = 0; result[i]; i++) - printf ("%s\n", result[i]); - - strvec_dispose (result); - } -} - -/* - * Local variables: - * compile-command: "gcc -g -Bstatic -DTEST -o brace_expand braces.c general.o" - * end: - */ - -#endif /* TEST */ -#endif /* BRACE_EXPANSION */ diff --git a/third_party/bash/break.c b/third_party/bash/break.c deleted file mode 100644 index 827b1a556..000000000 --- a/third_party/bash/break.c +++ /dev/null @@ -1,104 +0,0 @@ -/* break.c, created from break.def. */ -#line 22 "./break.def" - -#line 34 "./break.def" -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include "bashintl.h" - -#include "shell.h" -#include "execute_cmd.h" -#include "common.h" - -static int check_loop_level PARAMS((void)); - -/* The depth of while's and until's. */ -int loop_level = 0; - -/* Non-zero when a "break" instruction is encountered. */ -int breaking = 0; - -/* Non-zero when we have encountered a continue instruction. */ -int continuing = 0; - -/* Set up to break x levels, where x defaults to 1, but can be specified - as the first argument. */ -int -break_builtin (list) - WORD_LIST *list; -{ - intmax_t newbreak; - - CHECK_HELPOPT (list); - - if (check_loop_level () == 0) - return (EXECUTION_SUCCESS); - - (void)get_numeric_arg (list, 1, &newbreak); - - if (newbreak <= 0) - { - sh_erange (list->word->word, _("loop count")); - breaking = loop_level; - return (EXECUTION_FAILURE); - } - - if (newbreak > loop_level) - newbreak = loop_level; - - breaking = newbreak; - - return (EXECUTION_SUCCESS); -} - -#line 101 "./break.def" - -/* Set up to continue x levels, where x defaults to 1, but can be specified - as the first argument. */ -int -continue_builtin (list) - WORD_LIST *list; -{ - intmax_t newcont; - - CHECK_HELPOPT (list); - - if (check_loop_level () == 0) - return (EXECUTION_SUCCESS); - - (void)get_numeric_arg (list, 1, &newcont); - - if (newcont <= 0) - { - sh_erange (list->word->word, _("loop count")); - breaking = loop_level; - return (EXECUTION_FAILURE); - } - - if (newcont > loop_level) - newcont = loop_level; - - continuing = newcont; - - return (EXECUTION_SUCCESS); -} - -/* Return non-zero if a break or continue command would be okay. - Print an error message if break or continue is meaningless here. */ -static int -check_loop_level () -{ -#if defined (BREAK_COMPLAINS) - if (loop_level == 0 && posixly_correct == 0) - builtin_error (_("only meaningful in a `for', `while', or `until' loop")); -#endif /* BREAK_COMPLAINS */ - - return (loop_level); -} diff --git a/third_party/bash/builtext.h b/third_party/bash/builtext.h deleted file mode 100644 index a7723fa10..000000000 --- a/third_party/bash/builtext.h +++ /dev/null @@ -1,188 +0,0 @@ -/* builtext.h - The list of builtins found in libbuiltins.a. */ -#if defined (ALIAS) -extern int alias_builtin PARAMS((WORD_LIST *)); -extern char * const alias_doc[]; -#endif /* ALIAS */ -#if defined (ALIAS) -extern int unalias_builtin PARAMS((WORD_LIST *)); -extern char * const unalias_doc[]; -#endif /* ALIAS */ -#if defined (READLINE) -extern int bind_builtin PARAMS((WORD_LIST *)); -extern char * const bind_doc[]; -#endif /* READLINE */ -extern int break_builtin PARAMS((WORD_LIST *)); -extern char * const break_doc[]; -extern int continue_builtin PARAMS((WORD_LIST *)); -extern char * const continue_doc[]; -extern int builtin_builtin PARAMS((WORD_LIST *)); -extern char * const builtin_doc[]; -#if defined (DEBUGGER) -extern int caller_builtin PARAMS((WORD_LIST *)); -extern char * const caller_doc[]; -#endif /* DEBUGGER */ -extern int cd_builtin PARAMS((WORD_LIST *)); -extern char * const cd_doc[]; -extern int pwd_builtin PARAMS((WORD_LIST *)); -extern char * const pwd_doc[]; -extern int colon_builtin PARAMS((WORD_LIST *)); -extern char * const colon_doc[]; -extern int colon_builtin PARAMS((WORD_LIST *)); -extern char * const true_doc[]; -extern int false_builtin PARAMS((WORD_LIST *)); -extern char * const false_doc[]; -extern int command_builtin PARAMS((WORD_LIST *)); -extern char * const command_doc[]; -extern int declare_builtin PARAMS((WORD_LIST *)); -extern char * const declare_doc[]; -extern int declare_builtin PARAMS((WORD_LIST *)); -extern char * const typeset_doc[]; -extern int local_builtin PARAMS((WORD_LIST *)); -extern char * const local_doc[]; -#if defined (V9_ECHO) -extern int echo_builtin PARAMS((WORD_LIST *)); -extern char * const echo_doc[]; -#endif /* V9_ECHO */ -#if !defined (V9_ECHO) -extern int echo_builtin PARAMS((WORD_LIST *)); -extern char * const echo_doc[]; -#endif /* !V9_ECHO */ -extern int enable_builtin PARAMS((WORD_LIST *)); -extern char * const enable_doc[]; -extern int eval_builtin PARAMS((WORD_LIST *)); -extern char * const eval_doc[]; -extern int getopts_builtin PARAMS((WORD_LIST *)); -extern char * const getopts_doc[]; -extern int exec_builtin PARAMS((WORD_LIST *)); -extern char * const exec_doc[]; -extern int exit_builtin PARAMS((WORD_LIST *)); -extern char * const exit_doc[]; -extern int logout_builtin PARAMS((WORD_LIST *)); -extern char * const logout_doc[]; -#if defined (HISTORY) -extern int fc_builtin PARAMS((WORD_LIST *)); -extern char * const fc_doc[]; -#endif /* HISTORY */ -#if defined (JOB_CONTROL) -extern int fg_builtin PARAMS((WORD_LIST *)); -extern char * const fg_doc[]; -#endif /* JOB_CONTROL */ -#if defined (JOB_CONTROL) -extern int bg_builtin PARAMS((WORD_LIST *)); -extern char * const bg_doc[]; -#endif /* JOB_CONTROL */ -extern int hash_builtin PARAMS((WORD_LIST *)); -extern char * const hash_doc[]; -#if defined (HELP_BUILTIN) -extern int help_builtin PARAMS((WORD_LIST *)); -extern char * const help_doc[]; -#endif /* HELP_BUILTIN */ -#if defined (HISTORY) -extern int history_builtin PARAMS((WORD_LIST *)); -extern char * const history_doc[]; -#endif /* HISTORY */ -#if defined (JOB_CONTROL) -extern int jobs_builtin PARAMS((WORD_LIST *)); -extern char * const jobs_doc[]; -#endif /* JOB_CONTROL */ -#if defined (JOB_CONTROL) -extern int disown_builtin PARAMS((WORD_LIST *)); -extern char * const disown_doc[]; -#endif /* JOB_CONTROL */ -extern int kill_builtin PARAMS((WORD_LIST *)); -extern char * const kill_doc[]; -extern int let_builtin PARAMS((WORD_LIST *)); -extern char * const let_doc[]; -extern int read_builtin PARAMS((WORD_LIST *)); -extern char * const read_doc[]; -extern int return_builtin PARAMS((WORD_LIST *)); -extern char * const return_doc[]; -extern int set_builtin PARAMS((WORD_LIST *)); -extern char * const set_doc[]; -extern int unset_builtin PARAMS((WORD_LIST *)); -extern char * const unset_doc[]; -extern int export_builtin PARAMS((WORD_LIST *)); -extern char * const export_doc[]; -extern int readonly_builtin PARAMS((WORD_LIST *)); -extern char * const readonly_doc[]; -extern int shift_builtin PARAMS((WORD_LIST *)); -extern char * const shift_doc[]; -extern int source_builtin PARAMS((WORD_LIST *)); -extern char * const source_doc[]; -extern int source_builtin PARAMS((WORD_LIST *)); -extern char * const dot_doc[]; -#if defined (JOB_CONTROL) -extern int suspend_builtin PARAMS((WORD_LIST *)); -extern char * const suspend_doc[]; -#endif /* JOB_CONTROL */ -extern int test_builtin PARAMS((WORD_LIST *)); -extern char * const test_doc[]; -extern int test_builtin PARAMS((WORD_LIST *)); -extern char * const test_bracket_doc[]; -extern int times_builtin PARAMS((WORD_LIST *)); -extern char * const times_doc[]; -extern int trap_builtin PARAMS((WORD_LIST *)); -extern char * const trap_doc[]; -extern int type_builtin PARAMS((WORD_LIST *)); -extern char * const type_doc[]; -#if !defined (_MINIX) -extern int ulimit_builtin PARAMS((WORD_LIST *)); -extern char * const ulimit_doc[]; -#endif /* !_MINIX */ -extern int umask_builtin PARAMS((WORD_LIST *)); -extern char * const umask_doc[]; -#if defined (JOB_CONTROL) -extern int wait_builtin PARAMS((WORD_LIST *)); -extern char * const wait_doc[]; -#endif /* JOB_CONTROL */ -#if !defined (JOB_CONTROL) -extern int wait_builtin PARAMS((WORD_LIST *)); -extern char * const wait_doc[]; -#endif /* !JOB_CONTROL */ -extern char * const for_doc[]; -extern char * const arith_for_doc[]; -extern char * const select_doc[]; -extern char * const time_doc[]; -extern char * const case_doc[]; -extern char * const if_doc[]; -extern char * const while_doc[]; -extern char * const until_doc[]; -extern char * const coproc_doc[]; -extern char * const function_doc[]; -extern char * const grouping_braces_doc[]; -extern char * const fg_percent_doc[]; -extern char * const arith_doc[]; -extern char * const conditional_doc[]; -extern char * const variable_help_doc[]; -#if defined (PUSHD_AND_POPD) -extern int pushd_builtin PARAMS((WORD_LIST *)); -extern char * const pushd_doc[]; -#endif /* PUSHD_AND_POPD */ -#if defined (PUSHD_AND_POPD) -extern int popd_builtin PARAMS((WORD_LIST *)); -extern char * const popd_doc[]; -#endif /* PUSHD_AND_POPD */ -#if defined (PUSHD_AND_POPD) -extern int dirs_builtin PARAMS((WORD_LIST *)); -extern char * const dirs_doc[]; -#endif /* PUSHD_AND_POPD */ -extern int shopt_builtin PARAMS((WORD_LIST *)); -extern char * const shopt_doc[]; -extern int printf_builtin PARAMS((WORD_LIST *)); -extern char * const printf_doc[]; -#if defined (PROGRAMMABLE_COMPLETION) -extern int complete_builtin PARAMS((WORD_LIST *)); -extern char * const complete_doc[]; -#endif /* PROGRAMMABLE_COMPLETION */ -#if defined (PROGRAMMABLE_COMPLETION) -extern int compgen_builtin PARAMS((WORD_LIST *)); -extern char * const compgen_doc[]; -#endif /* PROGRAMMABLE_COMPLETION */ -#if defined (PROGRAMMABLE_COMPLETION) -extern int compopt_builtin PARAMS((WORD_LIST *)); -extern char * const compopt_doc[]; -#endif /* PROGRAMMABLE_COMPLETION */ -extern int mapfile_builtin PARAMS((WORD_LIST *)); -extern char * const mapfile_doc[]; -extern int mapfile_builtin PARAMS((WORD_LIST *)); -extern char * const readarray_doc[]; diff --git a/third_party/bash/builtins.c b/third_party/bash/builtins.c deleted file mode 100644 index 3d5fffc26..000000000 --- a/third_party/bash/builtins.c +++ /dev/null @@ -1,2093 +0,0 @@ -/* builtins.c -- the built in shell commands. */ - -/* This file is manufactured by ./mkbuiltins, and should not be - edited by hand. See the source to mkbuiltins for details. */ - -/* Copyright (C) 1987-2022 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -/* The list of shell builtins. Each element is name, function, flags, - long-doc, short-doc. The long-doc field contains a pointer to an array - of help lines. The function takes a WORD_LIST *; the first word in the - list is the first arg to the command. The list has already had word - expansion performed. - - Functions which need to look at only the simple commands (e.g. - the enable_builtin ()), should ignore entries where - (array[i].function == (sh_builtin_func_t *)NULL). Such entries are for - the list of shell reserved control structures, like `if' and `while'. - The end of the list is denoted with a NULL name field. */ - -/* TRANSLATORS: Please do not translate command names in descriptions */ - -#include "builtins.h" -#include "builtext.h" -#include "bashintl.h" - -struct builtin static_shell_builtins[] = { -#if defined (ALIAS) - { "alias", alias_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | ASSIGNMENT_BUILTIN | POSIX_BUILTIN, alias_doc, - N_("alias [-p] [name[=value] ... ]"), (char *)NULL }, -#endif /* ALIAS */ -#if defined (ALIAS) - { "unalias", unalias_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, unalias_doc, - N_("unalias [-a] name [name ...]"), (char *)NULL }, -#endif /* ALIAS */ -#if defined (READLINE) - { "bind", bind_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, bind_doc, - N_("bind [-lpsvPSVX] [-m keymap] [-f filename] [-q name] [-u name] [-r keyseq] [-x keyseq:shell-command] [keyseq:readline-function or readline-command]"), (char *)NULL }, -#endif /* READLINE */ - { "break", break_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, break_doc, - N_("break [n]"), (char *)NULL }, - { "continue", continue_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, continue_doc, - N_("continue [n]"), (char *)NULL }, - { "builtin", builtin_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, builtin_doc, - N_("builtin [shell-builtin [arg ...]]"), (char *)NULL }, -#if defined (DEBUGGER) - { "caller", caller_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, caller_doc, - N_("caller [expr]"), (char *)NULL }, -#endif /* DEBUGGER */ - { "cd", cd_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, cd_doc, - N_("cd [-L|[-P [-e]] [-@]] [dir]"), (char *)NULL }, - { "pwd", pwd_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, pwd_doc, - N_("pwd [-LP]"), (char *)NULL }, - { ":", colon_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, colon_doc, - ":", (char *)NULL }, - { "true", colon_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, true_doc, - "true", (char *)NULL }, - { "false", false_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, false_doc, - "false", (char *)NULL }, - { "command", command_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, command_doc, - N_("command [-pVv] command [arg ...]"), (char *)NULL }, - { "declare", declare_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | ASSIGNMENT_BUILTIN | LOCALVAR_BUILTIN | ARRAYREF_BUILTIN, declare_doc, - N_("declare [-aAfFgiIlnrtux] [name[=value] ...] or declare -p [-aAfFilnrtux] [name ...]"), (char *)NULL }, - { "typeset", declare_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | ASSIGNMENT_BUILTIN | LOCALVAR_BUILTIN | ARRAYREF_BUILTIN, typeset_doc, - N_("typeset [-aAfFgiIlnrtux] name[=value] ... or typeset -p [-aAfFilnrtux] [name ...]"), (char *)NULL }, - { "local", local_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | ASSIGNMENT_BUILTIN | LOCALVAR_BUILTIN | ARRAYREF_BUILTIN, local_doc, - N_("local [option] name[=value] ..."), (char *)NULL }, -#if defined (V9_ECHO) - { "echo", echo_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, echo_doc, - N_("echo [-neE] [arg ...]"), (char *)NULL }, -#endif /* V9_ECHO */ -#if !defined (V9_ECHO) - { "echo", echo_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, echo_doc, - N_("echo [-n] [arg ...]"), (char *)NULL }, -#endif /* !V9_ECHO */ - { "enable", enable_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, enable_doc, - N_("enable [-a] [-dnps] [-f filename] [name ...]"), (char *)NULL }, - { "eval", eval_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, eval_doc, - N_("eval [arg ...]"), (char *)NULL }, - { "getopts", getopts_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, getopts_doc, - N_("getopts optstring name [arg ...]"), (char *)NULL }, - { "exec", exec_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, exec_doc, - N_("exec [-cl] [-a name] [command [argument ...]] [redirection ...]"), (char *)NULL }, - { "exit", exit_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, exit_doc, - N_("exit [n]"), (char *)NULL }, - { "logout", logout_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, logout_doc, - N_("logout [n]"), (char *)NULL }, -#if defined (HISTORY) - { "fc", fc_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, fc_doc, - N_("fc [-e ename] [-lnr] [first] [last] or fc -s [pat=rep] [command]"), (char *)NULL }, -#endif /* HISTORY */ -#if defined (JOB_CONTROL) - { "fg", fg_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, fg_doc, - N_("fg [job_spec]"), (char *)NULL }, -#endif /* JOB_CONTROL */ -#if defined (JOB_CONTROL) - { "bg", bg_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, bg_doc, - N_("bg [job_spec ...]"), (char *)NULL }, -#endif /* JOB_CONTROL */ - { "hash", hash_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, hash_doc, - N_("hash [-lr] [-p pathname] [-dt] [name ...]"), (char *)NULL }, -#if defined (HELP_BUILTIN) - { "help", help_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, help_doc, - N_("help [-dms] [pattern ...]"), (char *)NULL }, -#endif /* HELP_BUILTIN */ -#if defined (HISTORY) - { "history", history_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, history_doc, - N_("history [-c] [-d offset] [n] or history -anrw [filename] or history -ps arg [arg...]"), (char *)NULL }, -#endif /* HISTORY */ -#if defined (JOB_CONTROL) - { "jobs", jobs_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, jobs_doc, - N_("jobs [-lnprs] [jobspec ...] or jobs -x command [args]"), (char *)NULL }, -#endif /* JOB_CONTROL */ -#if defined (JOB_CONTROL) - { "disown", disown_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, disown_doc, - N_("disown [-h] [-ar] [jobspec ... | pid ...]"), (char *)NULL }, -#endif /* JOB_CONTROL */ - { "kill", kill_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, kill_doc, - N_("kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]"), (char *)NULL }, - { "let", let_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | ARRAYREF_BUILTIN, let_doc, - N_("let arg [arg ...]"), (char *)NULL }, - { "read", read_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN | ARRAYREF_BUILTIN, read_doc, - N_("read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]"), (char *)NULL }, - { "return", return_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, return_doc, - N_("return [n]"), (char *)NULL }, - { "set", set_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, set_doc, - N_("set [-abefhkmnptuvxBCEHPT] [-o option-name] [--] [-] [arg ...]"), (char *)NULL }, - { "unset", unset_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN | ARRAYREF_BUILTIN, unset_doc, - N_("unset [-f] [-v] [-n] [name ...]"), (char *)NULL }, - { "export", export_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN | ASSIGNMENT_BUILTIN, export_doc, - N_("export [-fn] [name[=value] ...] or export -p"), (char *)NULL }, - { "readonly", readonly_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN | ASSIGNMENT_BUILTIN, readonly_doc, - N_("readonly [-aAf] [name[=value] ...] or readonly -p"), (char *)NULL }, - { "shift", shift_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, shift_doc, - N_("shift [n]"), (char *)NULL }, - { "source", source_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, source_doc, - N_("source filename [arguments]"), (char *)NULL }, - { ".", source_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, dot_doc, - N_(". filename [arguments]"), (char *)NULL }, -#if defined (JOB_CONTROL) - { "suspend", suspend_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, suspend_doc, - N_("suspend [-f]"), (char *)NULL }, -#endif /* JOB_CONTROL */ - { "test", test_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | ARRAYREF_BUILTIN, test_doc, - N_("test [expr]"), (char *)NULL }, - { "[", test_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | ARRAYREF_BUILTIN, test_bracket_doc, - N_("[ arg... ]"), (char *)NULL }, - { "times", times_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, times_doc, - "times", (char *)NULL }, - { "trap", trap_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | SPECIAL_BUILTIN, trap_doc, - N_("trap [-lp] [[arg] signal_spec ...]"), (char *)NULL }, - { "type", type_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, type_doc, - N_("type [-afptP] name [name ...]"), (char *)NULL }, -#if !defined (_MINIX) - { "ulimit", ulimit_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, ulimit_doc, - N_("ulimit [-SHabcdefiklmnpqrstuvxPRT] [limit]"), (char *)NULL }, -#endif /* !_MINIX */ - { "umask", umask_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN, umask_doc, - N_("umask [-p] [-S] [mode]"), (char *)NULL }, -#if defined (JOB_CONTROL) - { "wait", wait_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN | ARRAYREF_BUILTIN, wait_doc, - N_("wait [-fn] [-p var] [id ...]"), (char *)NULL }, -#endif /* JOB_CONTROL */ -#if !defined (JOB_CONTROL) - { "wait", wait_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | POSIX_BUILTIN | ARRAYREF_BUILTIN, wait_doc, - N_("wait [pid ...]"), (char *)NULL }, -#endif /* !JOB_CONTROL */ - { "for", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, for_doc, - N_("for NAME [in WORDS ... ] ; do COMMANDS; done"), (char *)NULL }, - { "for ((", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, arith_for_doc, - N_("for (( exp1; exp2; exp3 )); do COMMANDS; done"), (char *)NULL }, - { "select", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, select_doc, - N_("select NAME [in WORDS ... ;] do COMMANDS; done"), (char *)NULL }, - { "time", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, time_doc, - N_("time [-p] pipeline"), (char *)NULL }, - { "case", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, case_doc, - N_("case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac"), (char *)NULL }, - { "if", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, if_doc, - N_("if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMANDS; ]... [ else COMMANDS; ] fi"), (char *)NULL }, - { "while", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, while_doc, - N_("while COMMANDS; do COMMANDS-2; done"), (char *)NULL }, - { "until", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, until_doc, - N_("until COMMANDS; do COMMANDS-2; done"), (char *)NULL }, - { "coproc", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, coproc_doc, - N_("coproc [NAME] command [redirections]"), (char *)NULL }, - { "function", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, function_doc, - N_("function name { COMMANDS ; } or name () { COMMANDS ; }"), (char *)NULL }, - { "{ ... }", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, grouping_braces_doc, - N_("{ COMMANDS ; }"), (char *)NULL }, - { "%", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, fg_percent_doc, - N_("job_spec [&]"), (char *)NULL }, - { "(( ... ))", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, arith_doc, - N_("(( expression ))"), (char *)NULL }, - { "[[ ... ]]", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, conditional_doc, - N_("[[ expression ]]"), (char *)NULL }, - { "variables", (sh_builtin_func_t *)0x0, BUILTIN_ENABLED | STATIC_BUILTIN, variable_help_doc, - N_("variables - Names and meanings of some shell variables"), (char *)NULL }, -#if defined (PUSHD_AND_POPD) - { "pushd", pushd_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, pushd_doc, - N_("pushd [-n] [+N | -N | dir]"), (char *)NULL }, -#endif /* PUSHD_AND_POPD */ -#if defined (PUSHD_AND_POPD) - { "popd", popd_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, popd_doc, - N_("popd [-n] [+N | -N]"), (char *)NULL }, -#endif /* PUSHD_AND_POPD */ -#if defined (PUSHD_AND_POPD) - { "dirs", dirs_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, dirs_doc, - N_("dirs [-clpv] [+N] [-N]"), (char *)NULL }, -#endif /* PUSHD_AND_POPD */ - { "shopt", shopt_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, shopt_doc, - N_("shopt [-pqsu] [-o] [optname ...]"), (char *)NULL }, - { "printf", printf_builtin, BUILTIN_ENABLED | STATIC_BUILTIN | ARRAYREF_BUILTIN, printf_doc, - N_("printf [-v var] format [arguments]"), (char *)NULL }, -#if defined (PROGRAMMABLE_COMPLETION) - { "complete", complete_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, complete_doc, - N_("complete [-abcdefgjksuv] [-pr] [-DEI] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [name ...]"), (char *)NULL }, -#endif /* PROGRAMMABLE_COMPLETION */ -#if defined (PROGRAMMABLE_COMPLETION) - { "compgen", compgen_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, compgen_doc, - N_("compgen [-abcdefgjksuv] [-o option] [-A action] [-G globpat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] [word]"), (char *)NULL }, -#endif /* PROGRAMMABLE_COMPLETION */ -#if defined (PROGRAMMABLE_COMPLETION) - { "compopt", compopt_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, compopt_doc, - N_("compopt [-o|+o option] [-DEI] [name ...]"), (char *)NULL }, -#endif /* PROGRAMMABLE_COMPLETION */ - { "mapfile", mapfile_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, mapfile_doc, - N_("mapfile [-d delim] [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]"), (char *)NULL }, - { "readarray", mapfile_builtin, BUILTIN_ENABLED | STATIC_BUILTIN, readarray_doc, - N_("readarray [-d delim] [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]"), (char *)NULL }, - { (char *)0x0, (sh_builtin_func_t *)0x0, 0, (char **)0x0, (char *)0x0, (char *)0x0 } -}; - -struct builtin *shell_builtins = static_shell_builtins; -struct builtin *current_builtin; - -int num_shell_builtins = - sizeof (static_shell_builtins) / sizeof (struct builtin) - 1; -#if defined (ALIAS) -char * const alias_doc[] = { -#if defined (HELP_BUILTIN) -N_("Define or display aliases.\n\ - \n\ - Without arguments, `alias' prints the list of aliases in the reusable\n\ - form `alias NAME=VALUE' on standard output.\n\ - \n\ - Otherwise, an alias is defined for each NAME whose VALUE is given.\n\ - A trailing space in VALUE causes the next word to be checked for\n\ - alias substitution when the alias is expanded.\n\ - \n\ - Options:\n\ - -p print all defined aliases in a reusable format\n\ - \n\ - Exit Status:\n\ - alias returns true unless a NAME is supplied for which no alias has been\n\ - defined."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#endif /* ALIAS */ -#if defined (ALIAS) -char * const unalias_doc[] = { -#if defined (HELP_BUILTIN) -N_("Remove each NAME from the list of defined aliases.\n\ - \n\ - Options:\n\ - -a remove all alias definitions\n\ - \n\ - Return success unless a NAME is not an existing alias."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#endif /* ALIAS */ -#if defined (READLINE) -char * const bind_doc[] = { -#if defined (HELP_BUILTIN) -N_("Set Readline key bindings and variables.\n\ - \n\ - Bind a key sequence to a Readline function or a macro, or set a\n\ - Readline variable. The non-option argument syntax is equivalent to\n\ - that found in ~/.inputrc, but must be passed as a single argument:\n\ - e.g., bind '\"\\C-x\\C-r\": re-read-init-file'.\n\ - \n\ - Options:\n\ - -m keymap Use KEYMAP as the keymap for the duration of this\n\ - command. Acceptable keymap names are emacs,\n\ - emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move,\n\ - vi-command, and vi-insert.\n\ - -l List names of functions.\n\ - -P List function names and bindings.\n\ - -p List functions and bindings in a form that can be\n\ - reused as input.\n\ - -S List key sequences that invoke macros and their values\n\ - -s List key sequences that invoke macros and their values\n\ - in a form that can be reused as input.\n\ - -V List variable names and values\n\ - -v List variable names and values in a form that can\n\ - be reused as input.\n\ - -q function-name Query about which keys invoke the named function.\n\ - -u function-name Unbind all keys which are bound to the named function.\n\ - -r keyseq Remove the binding for KEYSEQ.\n\ - -f filename Read key bindings from FILENAME.\n\ - -x keyseq:shell-command Cause SHELL-COMMAND to be executed when\n\ - KEYSEQ is entered.\n\ - -X List key sequences bound with -x and associated commands\n\ - in a form that can be reused as input.\n\ - \n\ - Exit Status:\n\ - bind returns 0 unless an unrecognized option is given or an error occurs."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#endif /* READLINE */ -char * const break_doc[] = { -#if defined (HELP_BUILTIN) -N_("Exit for, while, or until loops.\n\ - \n\ - Exit a FOR, WHILE or UNTIL loop. If N is specified, break N enclosing\n\ - loops.\n\ - \n\ - Exit Status:\n\ - The exit status is 0 unless N is not greater than or equal to 1."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const continue_doc[] = { -#if defined (HELP_BUILTIN) -N_("Resume for, while, or until loops.\n\ - \n\ - Resumes the next iteration of the enclosing FOR, WHILE or UNTIL loop.\n\ - If N is specified, resumes the Nth enclosing loop.\n\ - \n\ - Exit Status:\n\ - The exit status is 0 unless N is not greater than or equal to 1."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const builtin_doc[] = { -#if defined (HELP_BUILTIN) -N_("Execute shell builtins.\n\ - \n\ - Execute SHELL-BUILTIN with arguments ARGs without performing command\n\ - lookup. This is useful when you wish to reimplement a shell builtin\n\ - as a shell function, but need to execute the builtin within the function.\n\ - \n\ - Exit Status:\n\ - Returns the exit status of SHELL-BUILTIN, or false if SHELL-BUILTIN is\n\ - not a shell builtin."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#if defined (DEBUGGER) -char * const caller_doc[] = { -#if defined (HELP_BUILTIN) -N_("Return the context of the current subroutine call.\n\ - \n\ - Without EXPR, returns \"$line $filename\". With EXPR, returns\n\ - \"$line $subroutine $filename\"; this extra information can be used to\n\ - provide a stack trace.\n\ - \n\ - The value of EXPR indicates how many call frames to go back before the\n\ - current one; the top frame is frame 0.\n\ - \n\ - Exit Status:\n\ - Returns 0 unless the shell is not executing a shell function or EXPR\n\ - is invalid."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#endif /* DEBUGGER */ -char * const cd_doc[] = { -#if defined (HELP_BUILTIN) -N_("Change the shell working directory.\n\ - \n\ - Change the current directory to DIR. The default DIR is the value of the\n\ - HOME shell variable. If DIR is \"-\", it is converted to $OLDPWD.\n\ - \n\ - The variable CDPATH defines the search path for the directory containing\n\ - DIR. Alternative directory names in CDPATH are separated by a colon (:).\n\ - A null directory name is the same as the current directory. If DIR begins\n\ - with a slash (/), then CDPATH is not used.\n\ - \n\ - If the directory is not found, and the shell option `cdable_vars' is set,\n\ - the word is assumed to be a variable name. If that variable has a value,\n\ - its value is used for DIR.\n\ - \n\ - Options:\n\ - -L force symbolic links to be followed: resolve symbolic\n\ - links in DIR after processing instances of `..'\n\ - -P use the physical directory structure without following\n\ - symbolic links: resolve symbolic links in DIR before\n\ - processing instances of `..'\n\ - -e if the -P option is supplied, and the current working\n\ - directory cannot be determined successfully, exit with\n\ - a non-zero status\n\ - -@ on systems that support it, present a file with extended\n\ - attributes as a directory containing the file attributes\n\ - \n\ - The default is to follow symbolic links, as if `-L' were specified.\n\ - `..' is processed by removing the immediately previous pathname component\n\ - back to a slash or the beginning of DIR.\n\ - \n\ - Exit Status:\n\ - Returns 0 if the directory is changed, and if $PWD is set successfully when\n\ - -P is used; non-zero otherwise."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const pwd_doc[] = { -#if defined (HELP_BUILTIN) -N_("Print the name of the current working directory.\n\ - \n\ - Options:\n\ - -L print the value of $PWD if it names the current working\n\ - directory\n\ - -P print the physical directory, without any symbolic links\n\ - \n\ - By default, `pwd' behaves as if `-L' were specified.\n\ - \n\ - Exit Status:\n\ - Returns 0 unless an invalid option is given or the current directory\n\ - cannot be read."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const colon_doc[] = { -#if defined (HELP_BUILTIN) -N_("Null command.\n\ - \n\ - No effect; the command does nothing.\n\ - \n\ - Exit Status:\n\ - Always succeeds."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const true_doc[] = { -#if defined (HELP_BUILTIN) -N_("Return a successful result.\n\ - \n\ - Exit Status:\n\ - Always succeeds."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const false_doc[] = { -#if defined (HELP_BUILTIN) -N_("Return an unsuccessful result.\n\ - \n\ - Exit Status:\n\ - Always fails."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const command_doc[] = { -#if defined (HELP_BUILTIN) -N_("Execute a simple command or display information about commands.\n\ - \n\ - Runs COMMAND with ARGS suppressing shell function lookup, or display\n\ - information about the specified COMMANDs. Can be used to invoke commands\n\ - on disk when a function with the same name exists.\n\ - \n\ - Options:\n\ - -p use a default value for PATH that is guaranteed to find all of\n\ - the standard utilities\n\ - -v print a description of COMMAND similar to the `type' builtin\n\ - -V print a more verbose description of each COMMAND\n\ - \n\ - Exit Status:\n\ - Returns exit status of COMMAND, or failure if COMMAND is not found."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const declare_doc[] = { -#if defined (HELP_BUILTIN) -N_("Set variable values and attributes.\n\ - \n\ - Declare variables and give them attributes. If no NAMEs are given,\n\ - display the attributes and values of all variables.\n\ - \n\ - Options:\n\ - -f restrict action or display to function names and definitions\n\ - -F restrict display to function names only (plus line number and\n\ - source file when debugging)\n\ - -g create global variables when used in a shell function; otherwise\n\ - ignored\n\ - -I if creating a local variable, inherit the attributes and value\n\ - of a variable with the same name at a previous scope\n\ - -p display the attributes and value of each NAME\n\ - \n\ - Options which set attributes:\n\ - -a to make NAMEs indexed arrays (if supported)\n\ - -A to make NAMEs associative arrays (if supported)\n\ - -i to make NAMEs have the `integer' attribute\n\ - -l to convert the value of each NAME to lower case on assignment\n\ - -n make NAME a reference to the variable named by its value\n\ - -r to make NAMEs readonly\n\ - -t to make NAMEs have the `trace' attribute\n\ - -u to convert the value of each NAME to upper case on assignment\n\ - -x to make NAMEs export\n\ - \n\ - Using `+' instead of `-' turns off the given attribute.\n\ - \n\ - Variables with the integer attribute have arithmetic evaluation (see\n\ - the `let' command) performed when the variable is assigned a value.\n\ - \n\ - When used in a function, `declare' makes NAMEs local, as with the `local'\n\ - command. The `-g' option suppresses this behavior.\n\ - \n\ - Exit Status:\n\ - Returns success unless an invalid option is supplied or a variable\n\ - assignment error occurs."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const typeset_doc[] = { -#if defined (HELP_BUILTIN) -N_("Set variable values and attributes.\n\ - \n\ - A synonym for `declare'. See `help declare'."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const local_doc[] = { -#if defined (HELP_BUILTIN) -N_("Define local variables.\n\ - \n\ - Create a local variable called NAME, and give it VALUE. OPTION can\n\ - be any option accepted by `declare'.\n\ - \n\ - Local variables can only be used within a function; they are visible\n\ - only to the function where they are defined and its children.\n\ - \n\ - Exit Status:\n\ - Returns success unless an invalid option is supplied, a variable\n\ - assignment error occurs, or the shell is not executing a function."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#if defined (V9_ECHO) -char * const echo_doc[] = { -#if defined (HELP_BUILTIN) -N_("Write arguments to the standard output.\n\ - \n\ - Display the ARGs, separated by a single space character and followed by a\n\ - newline, on the standard output.\n\ - \n\ - Options:\n\ - -n do not append a newline\n\ - -e enable interpretation of the following backslash escapes\n\ - -E explicitly suppress interpretation of backslash escapes\n\ - \n\ - `echo' interprets the following backslash-escaped characters:\n\ - \\a alert (bell)\n\ - \\b backspace\n\ - \\c suppress further output\n\ - \\e escape character\n\ - \\E escape character\n\ - \\f form feed\n\ - \\n new line\n\ - \\r carriage return\n\ - \\t horizontal tab\n\ - \\v vertical tab\n\ - \\\\ backslash\n\ - \\0nnn the character whose ASCII code is NNN (octal). NNN can be\n\ - 0 to 3 octal digits\n\ - \\xHH the eight-bit character whose value is HH (hexadecimal). HH\n\ - can be one or two hex digits\n\ - \\uHHHH the Unicode character whose value is the hexadecimal value HHHH.\n\ - HHHH can be one to four hex digits.\n\ - \\UHHHHHHHH the Unicode character whose value is the hexadecimal value\n\ - HHHHHHHH. HHHHHHHH can be one to eight hex digits.\n\ - \n\ - Exit Status:\n\ - Returns success unless a write error occurs."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#endif /* V9_ECHO */ -#if !defined (V9_ECHO) -char * const echo_doc[] = { -#if defined (HELP_BUILTIN) -N_("Write arguments to the standard output.\n\ - \n\ - Display the ARGs on the standard output followed by a newline.\n\ - \n\ - Options:\n\ - -n do not append a newline\n\ - \n\ - Exit Status:\n\ - Returns success unless a write error occurs."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#endif /* !V9_ECHO */ -char * const enable_doc[] = { -#if defined (HELP_BUILTIN) -N_("Enable and disable shell builtins.\n\ - \n\ - Enables and disables builtin shell commands. Disabling allows you to\n\ - execute a disk command which has the same name as a shell builtin\n\ - without using a full pathname.\n\ - \n\ - Options:\n\ - -a print a list of builtins showing whether or not each is enabled\n\ - -n disable each NAME or display a list of disabled builtins\n\ - -p print the list of builtins in a reusable format\n\ - -s print only the names of Posix `special' builtins\n\ - \n\ - Options controlling dynamic loading:\n\ - -f Load builtin NAME from shared object FILENAME\n\ - -d Remove a builtin loaded with -f\n\ - \n\ - Without options, each NAME is enabled.\n\ - \n\ - To use the `test' found in $PATH instead of the shell builtin\n\ - version, type `enable -n test'.\n\ - \n\ - Exit Status:\n\ - Returns success unless NAME is not a shell builtin or an error occurs."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const eval_doc[] = { -#if defined (HELP_BUILTIN) -N_("Execute arguments as a shell command.\n\ - \n\ - Combine ARGs into a single string, use the result as input to the shell,\n\ - and execute the resulting commands.\n\ - \n\ - Exit Status:\n\ - Returns exit status of command or success if command is null."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const getopts_doc[] = { -#if defined (HELP_BUILTIN) -N_("Parse option arguments.\n\ - \n\ - Getopts is used by shell procedures to parse positional parameters\n\ - as options.\n\ - \n\ - OPTSTRING contains the option letters to be recognized; if a letter\n\ - is followed by a colon, the option is expected to have an argument,\n\ - which should be separated from it by white space.\n\ - \n\ - Each time it is invoked, getopts will place the next option in the\n\ - shell variable $name, initializing name if it does not exist, and\n\ - the index of the next argument to be processed into the shell\n\ - variable OPTIND. OPTIND is initialized to 1 each time the shell or\n\ - a shell script is invoked. When an option requires an argument,\n\ - getopts places that argument into the shell variable OPTARG.\n\ - \n\ - getopts reports errors in one of two ways. If the first character\n\ - of OPTSTRING is a colon, getopts uses silent error reporting. In\n\ - this mode, no error messages are printed. If an invalid option is\n\ - seen, getopts places the option character found into OPTARG. If a\n\ - required argument is not found, getopts places a ':' into NAME and\n\ - sets OPTARG to the option character found. If getopts is not in\n\ - silent mode, and an invalid option is seen, getopts places '?' into\n\ - NAME and unsets OPTARG. If a required argument is not found, a '?'\n\ - is placed in NAME, OPTARG is unset, and a diagnostic message is\n\ - printed.\n\ - \n\ - If the shell variable OPTERR has the value 0, getopts disables the\n\ - printing of error messages, even if the first character of\n\ - OPTSTRING is not a colon. OPTERR has the value 1 by default.\n\ - \n\ - Getopts normally parses the positional parameters, but if arguments\n\ - are supplied as ARG values, they are parsed instead.\n\ - \n\ - Exit Status:\n\ - Returns success if an option is found; fails if the end of options is\n\ - encountered or an error occurs."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const exec_doc[] = { -#if defined (HELP_BUILTIN) -N_("Replace the shell with the given command.\n\ - \n\ - Execute COMMAND, replacing this shell with the specified program.\n\ - ARGUMENTS become the arguments to COMMAND. If COMMAND is not specified,\n\ - any redirections take effect in the current shell.\n\ - \n\ - Options:\n\ - -a name pass NAME as the zeroth argument to COMMAND\n\ - -c execute COMMAND with an empty environment\n\ - -l place a dash in the zeroth argument to COMMAND\n\ - \n\ - If the command cannot be executed, a non-interactive shell exits, unless\n\ - the shell option `execfail' is set.\n\ - \n\ - Exit Status:\n\ - Returns success unless COMMAND is not found or a redirection error occurs."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const exit_doc[] = { -#if defined (HELP_BUILTIN) -N_("Exit the shell.\n\ - \n\ - Exits the shell with a status of N. If N is omitted, the exit status\n\ - is that of the last command executed."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const logout_doc[] = { -#if defined (HELP_BUILTIN) -N_("Exit a login shell.\n\ - \n\ - Exits a login shell with exit status N. Returns an error if not executed\n\ - in a login shell."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#if defined (HISTORY) -char * const fc_doc[] = { -#if defined (HELP_BUILTIN) -N_("Display or execute commands from the history list.\n\ - \n\ - fc is used to list or edit and re-execute commands from the history list.\n\ - FIRST and LAST can be numbers specifying the range, or FIRST can be a\n\ - string, which means the most recent command beginning with that\n\ - string.\n\ - \n\ - Options:\n\ - -e ENAME select which editor to use. Default is FCEDIT, then EDITOR,\n\ - then vi\n\ - -l list lines instead of editing\n\ - -n omit line numbers when listing\n\ - -r reverse the order of the lines (newest listed first)\n\ - \n\ - With the `fc -s [pat=rep ...] [command]' format, COMMAND is\n\ - re-executed after the substitution OLD=NEW is performed.\n\ - \n\ - A useful alias to use with this is r='fc -s', so that typing `r cc'\n\ - runs the last command beginning with `cc' and typing `r' re-executes\n\ - the last command.\n\ - \n\ - Exit Status:\n\ - Returns success or status of executed command; non-zero if an error occurs."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#endif /* HISTORY */ -#if defined (JOB_CONTROL) -char * const fg_doc[] = { -#if defined (HELP_BUILTIN) -N_("Move job to the foreground.\n\ - \n\ - Place the job identified by JOB_SPEC in the foreground, making it the\n\ - current job. If JOB_SPEC is not present, the shell's notion of the\n\ - current job is used.\n\ - \n\ - Exit Status:\n\ - Status of command placed in foreground, or failure if an error occurs."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#endif /* JOB_CONTROL */ -#if defined (JOB_CONTROL) -char * const bg_doc[] = { -#if defined (HELP_BUILTIN) -N_("Move jobs to the background.\n\ - \n\ - Place the jobs identified by each JOB_SPEC in the background, as if they\n\ - had been started with `&'. If JOB_SPEC is not present, the shell's notion\n\ - of the current job is used.\n\ - \n\ - Exit Status:\n\ - Returns success unless job control is not enabled or an error occurs."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#endif /* JOB_CONTROL */ -char * const hash_doc[] = { -#if defined (HELP_BUILTIN) -N_("Remember or display program locations.\n\ - \n\ - Determine and remember the full pathname of each command NAME. If\n\ - no arguments are given, information about remembered commands is displayed.\n\ - \n\ - Options:\n\ - -d forget the remembered location of each NAME\n\ - -l display in a format that may be reused as input\n\ - -p pathname use PATHNAME as the full pathname of NAME\n\ - -r forget all remembered locations\n\ - -t print the remembered location of each NAME, preceding\n\ - each location with the corresponding NAME if multiple\n\ - NAMEs are given\n\ - Arguments:\n\ - NAME Each NAME is searched for in $PATH and added to the list\n\ - of remembered commands.\n\ - \n\ - Exit Status:\n\ - Returns success unless NAME is not found or an invalid option is given."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#if defined (HELP_BUILTIN) -char * const help_doc[] = { -#if defined (HELP_BUILTIN) -N_("Display information about builtin commands.\n\ - \n\ - Displays brief summaries of builtin commands. If PATTERN is\n\ - specified, gives detailed help on all commands matching PATTERN,\n\ - otherwise the list of help topics is printed.\n\ - \n\ - Options:\n\ - -d output short description for each topic\n\ - -m display usage in pseudo-manpage format\n\ - -s output only a short usage synopsis for each topic matching\n\ - PATTERN\n\ - \n\ - Arguments:\n\ - PATTERN Pattern specifying a help topic\n\ - \n\ - Exit Status:\n\ - Returns success unless PATTERN is not found or an invalid option is given."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#endif /* HELP_BUILTIN */ -#if defined (HISTORY) -char * const history_doc[] = { -#if defined (HELP_BUILTIN) -N_("Display or manipulate the history list.\n\ - \n\ - Display the history list with line numbers, prefixing each modified\n\ - entry with a `*'. An argument of N lists only the last N entries.\n\ - \n\ - Options:\n\ - -c clear the history list by deleting all of the entries\n\ - -d offset delete the history entry at position OFFSET. Negative\n\ - offsets count back from the end of the history list\n\ - \n\ - -a append history lines from this session to the history file\n\ - -n read all history lines not already read from the history file\n\ - and append them to the history list\n\ - -r read the history file and append the contents to the history\n\ - list\n\ - -w write the current history to the history file\n\ - \n\ - -p perform history expansion on each ARG and display the result\n\ - without storing it in the history list\n\ - -s append the ARGs to the history list as a single entry\n\ - \n\ - If FILENAME is given, it is used as the history file. Otherwise,\n\ - if HISTFILE has a value, that is used, else ~/.bash_history.\n\ - \n\ - If the HISTTIMEFORMAT variable is set and not null, its value is used\n\ - as a format string for strftime(3) to print the time stamp associated\n\ - with each displayed history entry. No time stamps are printed otherwise.\n\ - \n\ - Exit Status:\n\ - Returns success unless an invalid option is given or an error occurs."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#endif /* HISTORY */ -#if defined (JOB_CONTROL) -char * const jobs_doc[] = { -#if defined (HELP_BUILTIN) -N_("Display status of jobs.\n\ - \n\ - Lists the active jobs. JOBSPEC restricts output to that job.\n\ - Without options, the status of all active jobs is displayed.\n\ - \n\ - Options:\n\ - -l lists process IDs in addition to the normal information\n\ - -n lists only processes that have changed status since the last\n\ - notification\n\ - -p lists process IDs only\n\ - -r restrict output to running jobs\n\ - -s restrict output to stopped jobs\n\ - \n\ - If -x is supplied, COMMAND is run after all job specifications that\n\ - appear in ARGS have been replaced with the process ID of that job's\n\ - process group leader.\n\ - \n\ - Exit Status:\n\ - Returns success unless an invalid option is given or an error occurs.\n\ - If -x is used, returns the exit status of COMMAND."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#endif /* JOB_CONTROL */ -#if defined (JOB_CONTROL) -char * const disown_doc[] = { -#if defined (HELP_BUILTIN) -N_("Remove jobs from current shell.\n\ - \n\ - Removes each JOBSPEC argument from the table of active jobs. Without\n\ - any JOBSPECs, the shell uses its notion of the current job.\n\ - \n\ - Options:\n\ - -a remove all jobs if JOBSPEC is not supplied\n\ - -h mark each JOBSPEC so that SIGHUP is not sent to the job if the\n\ - shell receives a SIGHUP\n\ - -r remove only running jobs\n\ - \n\ - Exit Status:\n\ - Returns success unless an invalid option or JOBSPEC is given."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#endif /* JOB_CONTROL */ -char * const kill_doc[] = { -#if defined (HELP_BUILTIN) -N_("Send a signal to a job.\n\ - \n\ - Send the processes identified by PID or JOBSPEC the signal named by\n\ - SIGSPEC or SIGNUM. If neither SIGSPEC nor SIGNUM is present, then\n\ - SIGTERM is assumed.\n\ - \n\ - Options:\n\ - -s sig SIG is a signal name\n\ - -n sig SIG is a signal number\n\ - -l list the signal names; if arguments follow `-l' they are\n\ - assumed to be signal numbers for which names should be listed\n\ - -L synonym for -l\n\ - \n\ - Kill is a shell builtin for two reasons: it allows job IDs to be used\n\ - instead of process IDs, and allows processes to be killed if the limit\n\ - on processes that you can create is reached.\n\ - \n\ - Exit Status:\n\ - Returns success unless an invalid option is given or an error occurs."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const let_doc[] = { -#if defined (HELP_BUILTIN) -N_("Evaluate arithmetic expressions.\n\ - \n\ - Evaluate each ARG as an arithmetic expression. Evaluation is done in\n\ - fixed-width integers with no check for overflow, though division by 0\n\ - is trapped and flagged as an error. The following list of operators is\n\ - grouped into levels of equal-precedence operators. The levels are listed\n\ - in order of decreasing precedence.\n\ - \n\ - id++, id-- variable post-increment, post-decrement\n\ - ++id, --id variable pre-increment, pre-decrement\n\ - -, + unary minus, plus\n\ - !, ~ logical and bitwise negation\n\ - ** exponentiation\n\ - *, /, % multiplication, division, remainder\n\ - +, - addition, subtraction\n\ - <<, >> left and right bitwise shifts\n\ - <=, >=, <, > comparison\n\ - ==, != equality, inequality\n\ - & bitwise AND\n\ - ^ bitwise XOR\n\ - | bitwise OR\n\ - && logical AND\n\ - || logical OR\n\ - expr ? expr : expr\n\ - conditional operator\n\ - =, *=, /=, %=,\n\ - +=, -=, <<=, >>=,\n\ - &=, ^=, |= assignment\n\ - \n\ - Shell variables are allowed as operands. The name of the variable\n\ - is replaced by its value (coerced to a fixed-width integer) within\n\ - an expression. The variable need not have its integer attribute\n\ - turned on to be used in an expression.\n\ - \n\ - Operators are evaluated in order of precedence. Sub-expressions in\n\ - parentheses are evaluated first and may override the precedence\n\ - rules above.\n\ - \n\ - Exit Status:\n\ - If the last ARG evaluates to 0, let returns 1; let returns 0 otherwise."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const read_doc[] = { -#if defined (HELP_BUILTIN) -N_("Read a line from the standard input and split it into fields.\n\ - \n\ - Reads a single line from the standard input, or from file descriptor FD\n\ - if the -u option is supplied. The line is split into fields as with word\n\ - splitting, and the first word is assigned to the first NAME, the second\n\ - word to the second NAME, and so on, with any leftover words assigned to\n\ - the last NAME. Only the characters found in $IFS are recognized as word\n\ - delimiters. By default, the backslash character escapes delimiter characters\n\ - and newline.\n\ - \n\ - If no NAMEs are supplied, the line read is stored in the REPLY variable.\n\ - \n\ - Options:\n\ - -a array assign the words read to sequential indices of the array\n\ - variable ARRAY, starting at zero\n\ - -d delim continue until the first character of DELIM is read, rather\n\ - than newline\n\ - -e use Readline to obtain the line\n\ - -i text use TEXT as the initial text for Readline\n\ - -n nchars return after reading NCHARS characters rather than waiting\n\ - for a newline, but honor a delimiter if fewer than\n\ - NCHARS characters are read before the delimiter\n\ - -N nchars return only after reading exactly NCHARS characters, unless\n\ - EOF is encountered or read times out, ignoring any\n\ - delimiter\n\ - -p prompt output the string PROMPT without a trailing newline before\n\ - attempting to read\n\ - -r do not allow backslashes to escape any characters\n\ - -s do not echo input coming from a terminal\n\ - -t timeout time out and return failure if a complete line of\n\ - input is not read within TIMEOUT seconds. The value of the\n\ - TMOUT variable is the default timeout. TIMEOUT may be a\n\ - fractional number. If TIMEOUT is 0, read returns\n\ - immediately, without trying to read any data, returning\n\ - success only if input is available on the specified\n\ - file descriptor. The exit status is greater than 128\n\ - if the timeout is exceeded\n\ - -u fd read from file descriptor FD instead of the standard input\n\ - \n\ - Exit Status:\n\ - The return code is zero, unless end-of-file is encountered, read times out\n\ - (in which case it's greater than 128), a variable assignment error occurs,\n\ - or an invalid file descriptor is supplied as the argument to -u."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const return_doc[] = { -#if defined (HELP_BUILTIN) -N_("Return from a shell function.\n\ - \n\ - Causes a function or sourced script to exit with the return value\n\ - specified by N. If N is omitted, the return status is that of the\n\ - last command executed within the function or script.\n\ - \n\ - Exit Status:\n\ - Returns N, or failure if the shell is not executing a function or script."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const set_doc[] = { -#if defined (HELP_BUILTIN) -N_("Set or unset values of shell options and positional parameters.\n\ - \n\ - Change the value of shell attributes and positional parameters, or\n\ - display the names and values of shell variables.\n\ - \n\ - Options:\n\ - -a Mark variables which are modified or created for export.\n\ - -b Notify of job termination immediately.\n\ - -e Exit immediately if a command exits with a non-zero status.\n\ - -f Disable file name generation (globbing).\n\ - -h Remember the location of commands as they are looked up.\n\ - -k All assignment arguments are placed in the environment for a\n\ - command, not just those that precede the command name.\n\ - -m Job control is enabled.\n\ - -n Read commands but do not execute them.\n\ - -o option-name\n\ - Set the variable corresponding to option-name:\n\ - allexport same as -a\n\ - braceexpand same as -B\n\ - emacs use an emacs-style line editing interface\n\ - errexit same as -e\n\ - errtrace same as -E\n\ - functrace same as -T\n\ - hashall same as -h\n\ - histexpand same as -H\n\ - history enable command history\n\ - ignoreeof the shell will not exit upon reading EOF\n\ - interactive-comments\n\ - allow comments to appear in interactive commands\n\ - keyword same as -k\n\ - monitor same as -m\n\ - noclobber same as -C\n\ - noexec same as -n\n\ - noglob same as -f\n\ - nolog currently accepted but ignored\n\ - notify same as -b\n\ - nounset same as -u\n\ - onecmd same as -t\n\ - physical same as -P\n\ - pipefail the return value of a pipeline is the status of\n\ - the last command to exit with a non-zero status,\n\ - or zero if no command exited with a non-zero status\n\ - posix change the behavior of bash where the default\n\ - operation differs from the Posix standard to\n\ - match the standard\n\ - privileged same as -p\n\ - verbose same as -v\n\ - vi use a vi-style line editing interface\n\ - xtrace same as -x\n\ - -p Turned on whenever the real and effective user ids do not match.\n\ - Disables processing of the $ENV file and importing of shell\n\ - functions. Turning this option off causes the effective uid and\n\ - gid to be set to the real uid and gid.\n\ - -t Exit after reading and executing one command.\n\ - -u Treat unset variables as an error when substituting.\n\ - -v Print shell input lines as they are read.\n\ - -x Print commands and their arguments as they are executed.\n\ - -B the shell will perform brace expansion\n\ - -C If set, disallow existing regular files to be overwritten\n\ - by redirection of output.\n\ - -E If set, the ERR trap is inherited by shell functions.\n\ - -H Enable ! style history substitution. This flag is on\n\ - by default when the shell is interactive.\n\ - -P If set, do not resolve symbolic links when executing commands\n\ - such as cd which change the current directory.\n\ - -T If set, the DEBUG and RETURN traps are inherited by shell functions.\n\ - -- Assign any remaining arguments to the positional parameters.\n\ - If there are no remaining arguments, the positional parameters\n\ - are unset.\n\ - - Assign any remaining arguments to the positional parameters.\n\ - The -x and -v options are turned off.\n\ - \n\ - Using + rather than - causes these flags to be turned off. The\n\ - flags can also be used upon invocation of the shell. The current\n\ - set of flags may be found in $-. The remaining n ARGs are positional\n\ - parameters and are assigned, in order, to $1, $2, .. $n. If no\n\ - ARGs are given, all shell variables are printed.\n\ - \n\ - Exit Status:\n\ - Returns success unless an invalid option is given."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const unset_doc[] = { -#if defined (HELP_BUILTIN) -N_("Unset values and attributes of shell variables and functions.\n\ - \n\ - For each NAME, remove the corresponding variable or function.\n\ - \n\ - Options:\n\ - -f treat each NAME as a shell function\n\ - -v treat each NAME as a shell variable\n\ - -n treat each NAME as a name reference and unset the variable itself\n\ - rather than the variable it references\n\ - \n\ - Without options, unset first tries to unset a variable, and if that fails,\n\ - tries to unset a function.\n\ - \n\ - Some variables cannot be unset; also see `readonly'.\n\ - \n\ - Exit Status:\n\ - Returns success unless an invalid option is given or a NAME is read-only."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const export_doc[] = { -#if defined (HELP_BUILTIN) -N_("Set export attribute for shell variables.\n\ - \n\ - Marks each NAME for automatic export to the environment of subsequently\n\ - executed commands. If VALUE is supplied, assign VALUE before exporting.\n\ - \n\ - Options:\n\ - -f refer to shell functions\n\ - -n remove the export property from each NAME\n\ - -p display a list of all exported variables and functions\n\ - \n\ - An argument of `--' disables further option processing.\n\ - \n\ - Exit Status:\n\ - Returns success unless an invalid option is given or NAME is invalid."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const readonly_doc[] = { -#if defined (HELP_BUILTIN) -N_("Mark shell variables as unchangeable.\n\ - \n\ - Mark each NAME as read-only; the values of these NAMEs may not be\n\ - changed by subsequent assignment. If VALUE is supplied, assign VALUE\n\ - before marking as read-only.\n\ - \n\ - Options:\n\ - -a refer to indexed array variables\n\ - -A refer to associative array variables\n\ - -f refer to shell functions\n\ - -p display a list of all readonly variables or functions,\n\ - depending on whether or not the -f option is given\n\ - \n\ - An argument of `--' disables further option processing.\n\ - \n\ - Exit Status:\n\ - Returns success unless an invalid option is given or NAME is invalid."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const shift_doc[] = { -#if defined (HELP_BUILTIN) -N_("Shift positional parameters.\n\ - \n\ - Rename the positional parameters $N+1,$N+2 ... to $1,$2 ... If N is\n\ - not given, it is assumed to be 1.\n\ - \n\ - Exit Status:\n\ - Returns success unless N is negative or greater than $#."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const source_doc[] = { -#if defined (HELP_BUILTIN) -N_("Execute commands from a file in the current shell.\n\ - \n\ - Read and execute commands from FILENAME in the current shell. The\n\ - entries in $PATH are used to find the directory containing FILENAME.\n\ - If any ARGUMENTS are supplied, they become the positional parameters\n\ - when FILENAME is executed.\n\ - \n\ - Exit Status:\n\ - Returns the status of the last command executed in FILENAME; fails if\n\ - FILENAME cannot be read."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const dot_doc[] = { -#if defined (HELP_BUILTIN) -N_("Execute commands from a file in the current shell.\n\ - \n\ - Read and execute commands from FILENAME in the current shell. The\n\ - entries in $PATH are used to find the directory containing FILENAME.\n\ - If any ARGUMENTS are supplied, they become the positional parameters\n\ - when FILENAME is executed.\n\ - \n\ - Exit Status:\n\ - Returns the status of the last command executed in FILENAME; fails if\n\ - FILENAME cannot be read."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#if defined (JOB_CONTROL) -char * const suspend_doc[] = { -#if defined (HELP_BUILTIN) -N_("Suspend shell execution.\n\ - \n\ - Suspend the execution of this shell until it receives a SIGCONT signal.\n\ - Unless forced, login shells and shells without job control cannot be\n\ - suspended.\n\ - \n\ - Options:\n\ - -f force the suspend, even if the shell is a login shell or job\n\ - control is not enabled.\n\ - \n\ - Exit Status:\n\ - Returns success unless job control is not enabled or an error occurs."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#endif /* JOB_CONTROL */ -char * const test_doc[] = { -#if defined (HELP_BUILTIN) -N_("Evaluate conditional expression.\n\ - \n\ - Exits with a status of 0 (true) or 1 (false) depending on\n\ - the evaluation of EXPR. Expressions may be unary or binary. Unary\n\ - expressions are often used to examine the status of a file. There\n\ - are string operators and numeric comparison operators as well.\n\ - \n\ - The behavior of test depends on the number of arguments. Read the\n\ - bash manual page for the complete specification.\n\ - \n\ - File operators:\n\ - \n\ - -a FILE True if file exists.\n\ - -b FILE True if file is block special.\n\ - -c FILE True if file is character special.\n\ - -d FILE True if file is a directory.\n\ - -e FILE True if file exists.\n\ - -f FILE True if file exists and is a regular file.\n\ - -g FILE True if file is set-group-id.\n\ - -h FILE True if file is a symbolic link.\n\ - -L FILE True if file is a symbolic link.\n\ - -k FILE True if file has its `sticky' bit set.\n\ - -p FILE True if file is a named pipe.\n\ - -r FILE True if file is readable by you.\n\ - -s FILE True if file exists and is not empty.\n\ - -S FILE True if file is a socket.\n\ - -t FD True if FD is opened on a terminal.\n\ - -u FILE True if the file is set-user-id.\n\ - -w FILE True if the file is writable by you.\n\ - -x FILE True if the file is executable by you.\n\ - -O FILE True if the file is effectively owned by you.\n\ - -G FILE True if the file is effectively owned by your group.\n\ - -N FILE True if the file has been modified since it was last read.\n\ - \n\ - FILE1 -nt FILE2 True if file1 is newer than file2 (according to\n\ - modification date).\n\ - \n\ - FILE1 -ot FILE2 True if file1 is older than file2.\n\ - \n\ - FILE1 -ef FILE2 True if file1 is a hard link to file2.\n\ - \n\ - String operators:\n\ - \n\ - -z STRING True if string is empty.\n\ - \n\ - -n STRING\n\ - STRING True if string is not empty.\n\ - \n\ - STRING1 = STRING2\n\ - True if the strings are equal.\n\ - STRING1 != STRING2\n\ - True if the strings are not equal.\n\ - STRING1 < STRING2\n\ - True if STRING1 sorts before STRING2 lexicographically.\n\ - STRING1 > STRING2\n\ - True if STRING1 sorts after STRING2 lexicographically.\n\ - \n\ - Other operators:\n\ - \n\ - -o OPTION True if the shell option OPTION is enabled.\n\ - -v VAR True if the shell variable VAR is set.\n\ - -R VAR True if the shell variable VAR is set and is a name\n\ - reference.\n\ - ! EXPR True if expr is false.\n\ - EXPR1 -a EXPR2 True if both expr1 AND expr2 are true.\n\ - EXPR1 -o EXPR2 True if either expr1 OR expr2 is true.\n\ - \n\ - arg1 OP arg2 Arithmetic tests. OP is one of -eq, -ne,\n\ - -lt, -le, -gt, or -ge.\n\ - \n\ - Arithmetic binary operators return true if ARG1 is equal, not-equal,\n\ - less-than, less-than-or-equal, greater-than, or greater-than-or-equal\n\ - than ARG2.\n\ - \n\ - Exit Status:\n\ - Returns success if EXPR evaluates to true; fails if EXPR evaluates to\n\ - false or an invalid argument is given."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const test_bracket_doc[] = { -#if defined (HELP_BUILTIN) -N_("Evaluate conditional expression.\n\ - \n\ - This is a synonym for the \"test\" builtin, but the last argument must\n\ - be a literal `]', to match the opening `['."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const times_doc[] = { -#if defined (HELP_BUILTIN) -N_("Display process times.\n\ - \n\ - Prints the accumulated user and system times for the shell and all of its\n\ - child processes.\n\ - \n\ - Exit Status:\n\ - Always succeeds."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const trap_doc[] = { -#if defined (HELP_BUILTIN) -N_("Trap signals and other events.\n\ - \n\ - Defines and activates handlers to be run when the shell receives signals\n\ - or other conditions.\n\ - \n\ - ARG is a command to be read and executed when the shell receives the\n\ - signal(s) SIGNAL_SPEC. If ARG is absent (and a single SIGNAL_SPEC\n\ - is supplied) or `-', each specified signal is reset to its original\n\ - value. If ARG is the null string each SIGNAL_SPEC is ignored by the\n\ - shell and by the commands it invokes.\n\ - \n\ - If a SIGNAL_SPEC is EXIT (0) ARG is executed on exit from the shell. If\n\ - a SIGNAL_SPEC is DEBUG, ARG is executed before every simple command. If\n\ - a SIGNAL_SPEC is RETURN, ARG is executed each time a shell function or a\n\ - script run by the . or source builtins finishes executing. A SIGNAL_SPEC\n\ - of ERR means to execute ARG each time a command's failure would cause the\n\ - shell to exit when the -e option is enabled.\n\ - \n\ - If no arguments are supplied, trap prints the list of commands associated\n\ - with each signal.\n\ - \n\ - Options:\n\ - -l print a list of signal names and their corresponding numbers\n\ - -p display the trap commands associated with each SIGNAL_SPEC\n\ - \n\ - Each SIGNAL_SPEC is either a signal name in or a signal number.\n\ - Signal names are case insensitive and the SIG prefix is optional. A\n\ - signal may be sent to the shell with \"kill -signal $$\".\n\ - \n\ - Exit Status:\n\ - Returns success unless a SIGSPEC is invalid or an invalid option is given."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const type_doc[] = { -#if defined (HELP_BUILTIN) -N_("Display information about command type.\n\ - \n\ - For each NAME, indicate how it would be interpreted if used as a\n\ - command name.\n\ - \n\ - Options:\n\ - -a display all locations containing an executable named NAME;\n\ - includes aliases, builtins, and functions, if and only if\n\ - the `-p' option is not also used\n\ - -f suppress shell function lookup\n\ - -P force a PATH search for each NAME, even if it is an alias,\n\ - builtin, or function, and returns the name of the disk file\n\ - that would be executed\n\ - -p returns either the name of the disk file that would be executed,\n\ - or nothing if `type -t NAME' would not return `file'\n\ - -t output a single word which is one of `alias', `keyword',\n\ - `function', `builtin', `file' or `', if NAME is an alias,\n\ - shell reserved word, shell function, shell builtin, disk file,\n\ - or not found, respectively\n\ - \n\ - Arguments:\n\ - NAME Command name to be interpreted.\n\ - \n\ - Exit Status:\n\ - Returns success if all of the NAMEs are found; fails if any are not found."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#if !defined (_MINIX) -char * const ulimit_doc[] = { -#if defined (HELP_BUILTIN) -N_("Modify shell resource limits.\n\ - \n\ - Provides control over the resources available to the shell and processes\n\ - it creates, on systems that allow such control.\n\ - \n\ - Options:\n\ - -S use the `soft' resource limit\n\ - -H use the `hard' resource limit\n\ - -a all current limits are reported\n\ - -b the socket buffer size\n\ - -c the maximum size of core files created\n\ - -d the maximum size of a process's data segment\n\ - -e the maximum scheduling priority (`nice')\n\ - -f the maximum size of files written by the shell and its children\n\ - -i the maximum number of pending signals\n\ - -k the maximum number of kqueues allocated for this process\n\ - -l the maximum size a process may lock into memory\n\ - -m the maximum resident set size\n\ - -n the maximum number of open file descriptors\n\ - -p the pipe buffer size\n\ - -q the maximum number of bytes in POSIX message queues\n\ - -r the maximum real-time scheduling priority\n\ - -s the maximum stack size\n\ - -t the maximum amount of cpu time in seconds\n\ - -u the maximum number of user processes\n\ - -v the size of virtual memory\n\ - -x the maximum number of file locks\n\ - -P the maximum number of pseudoterminals\n\ - -R the maximum time a real-time process can run before blocking\n\ - -T the maximum number of threads\n\ - \n\ - Not all options are available on all platforms.\n\ - \n\ - If LIMIT is given, it is the new value of the specified resource; the\n\ - special LIMIT values `soft', `hard', and `unlimited' stand for the\n\ - current soft limit, the current hard limit, and no limit, respectively.\n\ - Otherwise, the current value of the specified resource is printed. If\n\ - no option is given, then -f is assumed.\n\ - \n\ - Values are in 1024-byte increments, except for -t, which is in seconds,\n\ - -p, which is in increments of 512 bytes, and -u, which is an unscaled\n\ - number of processes.\n\ - \n\ - Exit Status:\n\ - Returns success unless an invalid option is supplied or an error occurs."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#endif /* !_MINIX */ -char * const umask_doc[] = { -#if defined (HELP_BUILTIN) -N_("Display or set file mode mask.\n\ - \n\ - Sets the user file-creation mask to MODE. If MODE is omitted, prints\n\ - the current value of the mask.\n\ - \n\ - If MODE begins with a digit, it is interpreted as an octal number;\n\ - otherwise it is a symbolic mode string like that accepted by chmod(1).\n\ - \n\ - Options:\n\ - -p if MODE is omitted, output in a form that may be reused as input\n\ - -S makes the output symbolic; otherwise an octal number is output\n\ - \n\ - Exit Status:\n\ - Returns success unless MODE is invalid or an invalid option is given."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#if defined (JOB_CONTROL) -char * const wait_doc[] = { -#if defined (HELP_BUILTIN) -N_("Wait for job completion and return exit status.\n\ - \n\ - Waits for each process identified by an ID, which may be a process ID or a\n\ - job specification, and reports its termination status. If ID is not\n\ - given, waits for all currently active child processes, and the return\n\ - status is zero. If ID is a job specification, waits for all processes\n\ - in that job's pipeline.\n\ - \n\ - If the -n option is supplied, waits for a single job from the list of IDs,\n\ - or, if no IDs are supplied, for the next job to complete and returns its\n\ - exit status.\n\ - \n\ - If the -p option is supplied, the process or job identifier of the job\n\ - for which the exit status is returned is assigned to the variable VAR\n\ - named by the option argument. The variable will be unset initially, before\n\ - any assignment. This is useful only when the -n option is supplied.\n\ - \n\ - If the -f option is supplied, and job control is enabled, waits for the\n\ - specified ID to terminate, instead of waiting for it to change status.\n\ - \n\ - Exit Status:\n\ - Returns the status of the last ID; fails if ID is invalid or an invalid\n\ - option is given, or if -n is supplied and the shell has no unwaited-for\n\ - children."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#endif /* JOB_CONTROL */ -#if !defined (JOB_CONTROL) -char * const wait_doc[] = { -#if defined (HELP_BUILTIN) -N_("Wait for process completion and return exit status.\n\ - \n\ - Waits for each process specified by a PID and reports its termination status.\n\ - If PID is not given, waits for all currently active child processes,\n\ - and the return status is zero. PID must be a process ID.\n\ - \n\ - Exit Status:\n\ - Returns the status of the last PID; fails if PID is invalid or an invalid\n\ - option is given."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#endif /* !JOB_CONTROL */ -char * const for_doc[] = { -#if defined (HELP_BUILTIN) -N_("Execute commands for each member in a list.\n\ - \n\ - The `for' loop executes a sequence of commands for each member in a\n\ - list of items. If `in WORDS ...;' is not present, then `in \"$@\"' is\n\ - assumed. For each element in WORDS, NAME is set to that element, and\n\ - the COMMANDS are executed.\n\ - \n\ - Exit Status:\n\ - Returns the status of the last command executed."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const arith_for_doc[] = { -#if defined (HELP_BUILTIN) -N_("Arithmetic for loop.\n\ - \n\ - Equivalent to\n\ - (( EXP1 ))\n\ - while (( EXP2 )); do\n\ - COMMANDS\n\ - (( EXP3 ))\n\ - done\n\ - EXP1, EXP2, and EXP3 are arithmetic expressions. If any expression is\n\ - omitted, it behaves as if it evaluates to 1.\n\ - \n\ - Exit Status:\n\ - Returns the status of the last command executed."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const select_doc[] = { -#if defined (HELP_BUILTIN) -N_("Select words from a list and execute commands.\n\ - \n\ - The WORDS are expanded, generating a list of words. The\n\ - set of expanded words is printed on the standard error, each\n\ - preceded by a number. If `in WORDS' is not present, `in \"$@\"'\n\ - is assumed. The PS3 prompt is then displayed and a line read\n\ - from the standard input. If the line consists of the number\n\ - corresponding to one of the displayed words, then NAME is set\n\ - to that word. If the line is empty, WORDS and the prompt are\n\ - redisplayed. If EOF is read, the command completes. Any other\n\ - value read causes NAME to be set to null. The line read is saved\n\ - in the variable REPLY. COMMANDS are executed after each selection\n\ - until a break command is executed.\n\ - \n\ - Exit Status:\n\ - Returns the status of the last command executed."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const time_doc[] = { -#if defined (HELP_BUILTIN) -N_("Report time consumed by pipeline's execution.\n\ - \n\ - Execute PIPELINE and print a summary of the real time, user CPU time,\n\ - and system CPU time spent executing PIPELINE when it terminates.\n\ - \n\ - Options:\n\ - -p print the timing summary in the portable Posix format\n\ - \n\ - The value of the TIMEFORMAT variable is used as the output format.\n\ - \n\ - Exit Status:\n\ - The return status is the return status of PIPELINE."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const case_doc[] = { -#if defined (HELP_BUILTIN) -N_("Execute commands based on pattern matching.\n\ - \n\ - Selectively execute COMMANDS based upon WORD matching PATTERN. The\n\ - `|' is used to separate multiple patterns.\n\ - \n\ - Exit Status:\n\ - Returns the status of the last command executed."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const if_doc[] = { -#if defined (HELP_BUILTIN) -N_("Execute commands based on conditional.\n\ - \n\ - The `if COMMANDS' list is executed. If its exit status is zero, then the\n\ - `then COMMANDS' list is executed. Otherwise, each `elif COMMANDS' list is\n\ - executed in turn, and if its exit status is zero, the corresponding\n\ - `then COMMANDS' list is executed and the if command completes. Otherwise,\n\ - the `else COMMANDS' list is executed, if present. The exit status of the\n\ - entire construct is the exit status of the last command executed, or zero\n\ - if no condition tested true.\n\ - \n\ - Exit Status:\n\ - Returns the status of the last command executed."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const while_doc[] = { -#if defined (HELP_BUILTIN) -N_("Execute commands as long as a test succeeds.\n\ - \n\ - Expand and execute COMMANDS-2 as long as the final command in COMMANDS has\n\ - an exit status of zero.\n\ - \n\ - Exit Status:\n\ - Returns the status of the last command executed."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const until_doc[] = { -#if defined (HELP_BUILTIN) -N_("Execute commands as long as a test does not succeed.\n\ - \n\ - Expand and execute COMMANDS-2 as long as the final command in COMMANDS has\n\ - an exit status which is not zero.\n\ - \n\ - Exit Status:\n\ - Returns the status of the last command executed."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const coproc_doc[] = { -#if defined (HELP_BUILTIN) -N_("Create a coprocess named NAME.\n\ - \n\ - Execute COMMAND asynchronously, with the standard output and standard\n\ - input of the command connected via a pipe to file descriptors assigned\n\ - to indices 0 and 1 of an array variable NAME in the executing shell.\n\ - The default NAME is \"COPROC\".\n\ - \n\ - Exit Status:\n\ - The coproc command returns an exit status of 0."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const function_doc[] = { -#if defined (HELP_BUILTIN) -N_("Define shell function.\n\ - \n\ - Create a shell function named NAME. When invoked as a simple command,\n\ - NAME runs COMMANDs in the calling shell's context. When NAME is invoked,\n\ - the arguments are passed to the function as $1...$n, and the function's\n\ - name is in $FUNCNAME.\n\ - \n\ - Exit Status:\n\ - Returns success unless NAME is readonly."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const grouping_braces_doc[] = { -#if defined (HELP_BUILTIN) -N_("Group commands as a unit.\n\ - \n\ - Run a set of commands in a group. This is one way to redirect an\n\ - entire set of commands.\n\ - \n\ - Exit Status:\n\ - Returns the status of the last command executed."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const fg_percent_doc[] = { -#if defined (HELP_BUILTIN) -N_("Resume job in foreground.\n\ - \n\ - Equivalent to the JOB_SPEC argument to the `fg' command. Resume a\n\ - stopped or background job. JOB_SPEC can specify either a job name\n\ - or a job number. Following JOB_SPEC with a `&' places the job in\n\ - the background, as if the job specification had been supplied as an\n\ - argument to `bg'.\n\ - \n\ - Exit Status:\n\ - Returns the status of the resumed job."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const arith_doc[] = { -#if defined (HELP_BUILTIN) -N_("Evaluate arithmetic expression.\n\ - \n\ - The EXPRESSION is evaluated according to the rules for arithmetic\n\ - evaluation. Equivalent to `let \"EXPRESSION\"'.\n\ - \n\ - Exit Status:\n\ - Returns 1 if EXPRESSION evaluates to 0; returns 0 otherwise."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const conditional_doc[] = { -#if defined (HELP_BUILTIN) -N_("Execute conditional command.\n\ - \n\ - Returns a status of 0 or 1 depending on the evaluation of the conditional\n\ - expression EXPRESSION. Expressions are composed of the same primaries used\n\ - by the `test' builtin, and may be combined using the following operators:\n\ - \n\ - ( EXPRESSION ) Returns the value of EXPRESSION\n\ - ! EXPRESSION True if EXPRESSION is false; else false\n\ - EXPR1 && EXPR2 True if both EXPR1 and EXPR2 are true; else false\n\ - EXPR1 || EXPR2 True if either EXPR1 or EXPR2 is true; else false\n\ - \n\ - When the `==' and `!=' operators are used, the string to the right of\n\ - the operator is used as a pattern and pattern matching is performed.\n\ - When the `=~' operator is used, the string to the right of the operator\n\ - is matched as a regular expression.\n\ - \n\ - The && and || operators do not evaluate EXPR2 if EXPR1 is sufficient to\n\ - determine the expression's value.\n\ - \n\ - Exit Status:\n\ - 0 or 1 depending on value of EXPRESSION."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const variable_help_doc[] = { -#if defined (HELP_BUILTIN) -N_("Common shell variable names and usage.\n\ - \n\ - BASH_VERSION Version information for this Bash.\n\ - CDPATH A colon-separated list of directories to search\n\ - for directories given as arguments to `cd'.\n\ - GLOBIGNORE A colon-separated list of patterns describing filenames to\n\ - be ignored by pathname expansion.\n\ - HISTFILE The name of the file where your command history is stored.\n\ - HISTFILESIZE The maximum number of lines this file can contain.\n\ - HISTSIZE The maximum number of history lines that a running\n\ - shell can access.\n\ - HOME The complete pathname to your login directory.\n\ - HOSTNAME The name of the current host.\n\ - HOSTTYPE The type of CPU this version of Bash is running under.\n\ - IGNOREEOF Controls the action of the shell on receipt of an EOF\n\ - character as the sole input. If set, then the value\n\ - of it is the number of EOF characters that can be seen\n\ - in a row on an empty line before the shell will exit\n\ - (default 10). When unset, EOF signifies the end of input.\n\ - MACHTYPE A string describing the current system Bash is running on.\n\ - MAILCHECK How often, in seconds, Bash checks for new mail.\n\ - MAILPATH A colon-separated list of filenames which Bash checks\n\ - for new mail.\n\ - OSTYPE The version of Unix this version of Bash is running on.\n\ - PATH A colon-separated list of directories to search when\n\ - looking for commands.\n\ - PROMPT_COMMAND A command to be executed before the printing of each\n\ - primary prompt.\n\ - PS1 The primary prompt string.\n\ - PS2 The secondary prompt string.\n\ - PWD The full pathname of the current directory.\n\ - SHELLOPTS A colon-separated list of enabled shell options.\n\ - TERM The name of the current terminal type.\n\ - TIMEFORMAT The output format for timing statistics displayed by the\n\ - `time' reserved word.\n\ - auto_resume Non-null means a command word appearing on a line by\n\ - itself is first looked for in the list of currently\n\ - stopped jobs. If found there, that job is foregrounded.\n\ - A value of `exact' means that the command word must\n\ - exactly match a command in the list of stopped jobs. A\n\ - value of `substring' means that the command word must\n\ - match a substring of the job. Any other value means that\n\ - the command must be a prefix of a stopped job.\n\ - histchars Characters controlling history expansion and quick\n\ - substitution. The first character is the history\n\ - substitution character, usually `!'. The second is\n\ - the `quick substitution' character, usually `^'. The\n\ - third is the `history comment' character, usually `#'.\n\ - HISTIGNORE A colon-separated list of patterns used to decide which\n\ - commands should be saved on the history list.\n\ -"), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#if defined (PUSHD_AND_POPD) -char * const pushd_doc[] = { -#if defined (HELP_BUILTIN) -N_("Add directories to stack.\n\ - \n\ - Adds a directory to the top of the directory stack, or rotates\n\ - the stack, making the new top of the stack the current working\n\ - directory. With no arguments, exchanges the top two directories.\n\ - \n\ - Options:\n\ - -n Suppresses the normal change of directory when adding\n\ - directories to the stack, so only the stack is manipulated.\n\ - \n\ - Arguments:\n\ - +N Rotates the stack so that the Nth directory (counting\n\ - from the left of the list shown by `dirs', starting with\n\ - zero) is at the top.\n\ - \n\ - -N Rotates the stack so that the Nth directory (counting\n\ - from the right of the list shown by `dirs', starting with\n\ - zero) is at the top.\n\ - \n\ - dir Adds DIR to the directory stack at the top, making it the\n\ - new current working directory.\n\ - \n\ - The `dirs' builtin displays the directory stack.\n\ - \n\ - Exit Status:\n\ - Returns success unless an invalid argument is supplied or the directory\n\ - change fails."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#endif /* PUSHD_AND_POPD */ -#if defined (PUSHD_AND_POPD) -char * const popd_doc[] = { -#if defined (HELP_BUILTIN) -N_("Remove directories from stack.\n\ - \n\ - Removes entries from the directory stack. With no arguments, removes\n\ - the top directory from the stack, and changes to the new top directory.\n\ - \n\ - Options:\n\ - -n Suppresses the normal change of directory when removing\n\ - directories from the stack, so only the stack is manipulated.\n\ - \n\ - Arguments:\n\ - +N Removes the Nth entry counting from the left of the list\n\ - shown by `dirs', starting with zero. For example: `popd +0'\n\ - removes the first directory, `popd +1' the second.\n\ - \n\ - -N Removes the Nth entry counting from the right of the list\n\ - shown by `dirs', starting with zero. For example: `popd -0'\n\ - removes the last directory, `popd -1' the next to last.\n\ - \n\ - The `dirs' builtin displays the directory stack.\n\ - \n\ - Exit Status:\n\ - Returns success unless an invalid argument is supplied or the directory\n\ - change fails."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#endif /* PUSHD_AND_POPD */ -#if defined (PUSHD_AND_POPD) -char * const dirs_doc[] = { -#if defined (HELP_BUILTIN) -N_("Display directory stack.\n\ - \n\ - Display the list of currently remembered directories. Directories\n\ - find their way onto the list with the `pushd' command; you can get\n\ - back up through the list with the `popd' command.\n\ - \n\ - Options:\n\ - -c clear the directory stack by deleting all of the elements\n\ - -l do not print tilde-prefixed versions of directories relative\n\ - to your home directory\n\ - -p print the directory stack with one entry per line\n\ - -v print the directory stack with one entry per line prefixed\n\ - with its position in the stack\n\ - \n\ - Arguments:\n\ - +N Displays the Nth entry counting from the left of the list\n\ - shown by dirs when invoked without options, starting with\n\ - zero.\n\ - \n\ - -N Displays the Nth entry counting from the right of the list\n\ - shown by dirs when invoked without options, starting with\n\ - zero.\n\ - \n\ - Exit Status:\n\ - Returns success unless an invalid option is supplied or an error occurs."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#endif /* PUSHD_AND_POPD */ -char * const shopt_doc[] = { -#if defined (HELP_BUILTIN) -N_("Set and unset shell options.\n\ - \n\ - Change the setting of each shell option OPTNAME. Without any option\n\ - arguments, list each supplied OPTNAME, or all shell options if no\n\ - OPTNAMEs are given, with an indication of whether or not each is set.\n\ - \n\ - Options:\n\ - -o restrict OPTNAMEs to those defined for use with `set -o'\n\ - -p print each shell option with an indication of its status\n\ - -q suppress output\n\ - -s enable (set) each OPTNAME\n\ - -u disable (unset) each OPTNAME\n\ - \n\ - Exit Status:\n\ - Returns success if OPTNAME is enabled; fails if an invalid option is\n\ - given or OPTNAME is disabled."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const printf_doc[] = { -#if defined (HELP_BUILTIN) -N_("Formats and prints ARGUMENTS under control of the FORMAT.\n\ - \n\ - Options:\n\ - -v var assign the output to shell variable VAR rather than\n\ - display it on the standard output\n\ - \n\ - FORMAT is a character string which contains three types of objects: plain\n\ - characters, which are simply copied to standard output; character escape\n\ - sequences, which are converted and copied to the standard output; and\n\ - format specifications, each of which causes printing of the next successive\n\ - argument.\n\ - \n\ - In addition to the standard format specifications described in printf(1),\n\ - printf interprets:\n\ - \n\ - %b expand backslash escape sequences in the corresponding argument\n\ - %q quote the argument in a way that can be reused as shell input\n\ - %Q like %q, but apply any precision to the unquoted argument before\n\ - quoting\n\ - %(fmt)T output the date-time string resulting from using FMT as a format\n\ - string for strftime(3)\n\ - \n\ - The format is re-used as necessary to consume all of the arguments. If\n\ - there are fewer arguments than the format requires, extra format\n\ - specifications behave as if a zero value or null string, as appropriate,\n\ - had been supplied.\n\ - \n\ - Exit Status:\n\ - Returns success unless an invalid option is given or a write or assignment\n\ - error occurs."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#if defined (PROGRAMMABLE_COMPLETION) -char * const complete_doc[] = { -#if defined (HELP_BUILTIN) -N_("Specify how arguments are to be completed by Readline.\n\ - \n\ - For each NAME, specify how arguments are to be completed. If no options\n\ - are supplied, existing completion specifications are printed in a way that\n\ - allows them to be reused as input.\n\ - \n\ - Options:\n\ - -p print existing completion specifications in a reusable format\n\ - -r remove a completion specification for each NAME, or, if no\n\ - NAMEs are supplied, all completion specifications\n\ - -D apply the completions and actions as the default for commands\n\ - without any specific completion defined\n\ - -E apply the completions and actions to \"empty\" commands --\n\ - completion attempted on a blank line\n\ - -I apply the completions and actions to the initial (usually the\n\ - command) word\n\ - \n\ - When completion is attempted, the actions are applied in the order the\n\ - uppercase-letter options are listed above. If multiple options are supplied,\n\ - the -D option takes precedence over -E, and both take precedence over -I.\n\ - \n\ - Exit Status:\n\ - Returns success unless an invalid option is supplied or an error occurs."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#endif /* PROGRAMMABLE_COMPLETION */ -#if defined (PROGRAMMABLE_COMPLETION) -char * const compgen_doc[] = { -#if defined (HELP_BUILTIN) -N_("Display possible completions depending on the options.\n\ - \n\ - Intended to be used from within a shell function generating possible\n\ - completions. If the optional WORD argument is supplied, matches against\n\ - WORD are generated.\n\ - \n\ - Exit Status:\n\ - Returns success unless an invalid option is supplied or an error occurs."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#endif /* PROGRAMMABLE_COMPLETION */ -#if defined (PROGRAMMABLE_COMPLETION) -char * const compopt_doc[] = { -#if defined (HELP_BUILTIN) -N_("Modify or display completion options.\n\ - \n\ - Modify the completion options for each NAME, or, if no NAMEs are supplied,\n\ - the completion currently being executed. If no OPTIONs are given, print\n\ - the completion options for each NAME or the current completion specification.\n\ - \n\ - Options:\n\ - -o option Set completion option OPTION for each NAME\n\ - -D Change options for the \"default\" command completion\n\ - -E Change options for the \"empty\" command completion\n\ - -I Change options for completion on the initial word\n\ - \n\ - Using `+o' instead of `-o' turns off the specified option.\n\ - \n\ - Arguments:\n\ - \n\ - Each NAME refers to a command for which a completion specification must\n\ - have previously been defined using the `complete' builtin. If no NAMEs\n\ - are supplied, compopt must be called by a function currently generating\n\ - completions, and the options for that currently-executing completion\n\ - generator are modified.\n\ - \n\ - Exit Status:\n\ - Returns success unless an invalid option is supplied or NAME does not\n\ - have a completion specification defined."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -#endif /* PROGRAMMABLE_COMPLETION */ -char * const mapfile_doc[] = { -#if defined (HELP_BUILTIN) -N_("Read lines from the standard input into an indexed array variable.\n\ - \n\ - Read lines from the standard input into the indexed array variable ARRAY, or\n\ - from file descriptor FD if the -u option is supplied. The variable MAPFILE\n\ - is the default ARRAY.\n\ - \n\ - Options:\n\ - -d delim Use DELIM to terminate lines, instead of newline\n\ - -n count Copy at most COUNT lines. If COUNT is 0, all lines are copied\n\ - -O origin Begin assigning to ARRAY at index ORIGIN. The default index is 0\n\ - -s count Discard the first COUNT lines read\n\ - -t Remove a trailing DELIM from each line read (default newline)\n\ - -u fd Read lines from file descriptor FD instead of the standard input\n\ - -C callback Evaluate CALLBACK each time QUANTUM lines are read\n\ - -c quantum Specify the number of lines read between each call to\n\ - CALLBACK\n\ - \n\ - Arguments:\n\ - ARRAY Array variable name to use for file data\n\ - \n\ - If -C is supplied without -c, the default quantum is 5000. When\n\ - CALLBACK is evaluated, it is supplied the index of the next array\n\ - element to be assigned and the line to be assigned to that element\n\ - as additional arguments.\n\ - \n\ - If not supplied with an explicit origin, mapfile will clear ARRAY before\n\ - assigning to it.\n\ - \n\ - Exit Status:\n\ - Returns success unless an invalid option is given or ARRAY is readonly or\n\ - not an indexed array."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; -char * const readarray_doc[] = { -#if defined (HELP_BUILTIN) -N_("Read lines from a file into an array variable.\n\ - \n\ - A synonym for `mapfile'."), -#endif /* HELP_BUILTIN */ - (char *)NULL -}; diff --git a/third_party/bash/builtins.h b/third_party/bash/builtins.h deleted file mode 100644 index 015659356..000000000 --- a/third_party/bash/builtins.h +++ /dev/null @@ -1,68 +0,0 @@ -/* builtins.h -- What a builtin looks like, and where to find them. */ - -/* Copyright (C) 1987-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#ifndef BUILTINS_H -#define BUILTINS_H - -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include "command.h" -#include "general.h" - -#if defined (ALIAS) -#include "alias.h" -#endif - -/* Flags describing various things about a builtin. */ -#define BUILTIN_ENABLED 0x01 /* This builtin is enabled. */ -#define BUILTIN_DELETED 0x02 /* This has been deleted with enable -d. */ -#define STATIC_BUILTIN 0x04 /* This builtin is not dynamically loaded. */ -#define SPECIAL_BUILTIN 0x08 /* This is a Posix `special' builtin. */ -#define ASSIGNMENT_BUILTIN 0x10 /* This builtin takes assignment statements. */ -#define POSIX_BUILTIN 0x20 /* This builtins is special in the Posix command search order. */ -#define LOCALVAR_BUILTIN 0x40 /* This builtin creates local variables */ -#define ARRAYREF_BUILTIN 0x80 /* This builtin takes array references as arguments */ - -#define BASE_INDENT 4 - -/* The thing that we build the array of builtins out of. */ -struct builtin { - char *name; /* The name that the user types. */ - sh_builtin_func_t *function; /* The address of the invoked function. */ - int flags; /* One of the #defines above. */ - char * const *long_doc; /* NULL terminated array of strings. */ - const char *short_doc; /* Short version of documentation. */ - char *handle; /* for future use */ -}; - -/* Found in builtins.c, created by builtins/mkbuiltins. */ -extern int num_shell_builtins; /* Number of shell builtins. */ -extern struct builtin static_shell_builtins[]; -extern struct builtin *shell_builtins; -extern struct builtin *current_builtin; - -#endif /* BUILTINS_H */ diff --git a/third_party/bash/builtins_alias.c b/third_party/bash/builtins_alias.c deleted file mode 100644 index 8eb017ba3..000000000 --- a/third_party/bash/builtins_alias.c +++ /dev/null @@ -1,192 +0,0 @@ -/* alias.c, created from alias.def. */ -#line 42 "./alias.def" - -#include "config.h" - -#if defined (ALIAS) - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -# include "bashansi.h" -# include "bashintl.h" - -# include -# include "shell.h" -# include "alias.h" -# include "common.h" -# include "bashgetopt.h" - -/* Flags for print_alias */ -#define AL_REUSABLE 0x01 - -static void print_alias PARAMS((alias_t *, int)); - -/* Hack the alias command in a Korn shell way. */ -int -alias_builtin (list) - WORD_LIST *list; -{ - int any_failed, offset, pflag, dflags; - alias_t **alias_list, *t; - char *name, *value; - - dflags = posixly_correct ? 0 : AL_REUSABLE; - pflag = 0; - reset_internal_getopt (); - while ((offset = internal_getopt (list, "p")) != -1) - { - switch (offset) - { - case 'p': - pflag = 1; - dflags |= AL_REUSABLE; - break; - CASE_HELPOPT; - default: - builtin_usage (); - return (EX_USAGE); - } - } - - list = loptend; - - if (list == 0 || pflag) - { - if (aliases == 0) - return (EXECUTION_SUCCESS); - - alias_list = all_aliases (); - - if (alias_list == 0) - return (EXECUTION_SUCCESS); - - for (offset = 0; alias_list[offset]; offset++) - print_alias (alias_list[offset], dflags); - - free (alias_list); /* XXX - Do not free the strings. */ - - if (list == 0) - return (sh_chkwrite (EXECUTION_SUCCESS)); - } - - any_failed = 0; - while (list) - { - name = list->word->word; - - for (offset = 0; name[offset] && name[offset] != '='; offset++) - ; - - if (offset && name[offset] == '=') - { - name[offset] = '\0'; - value = name + offset + 1; - - if (legal_alias_name (name, 0) == 0) - { - builtin_error (_("`%s': invalid alias name"), name); - any_failed++; - } - else - add_alias (name, value); - } - else - { - t = find_alias (name); - if (t) - print_alias (t, dflags); - else - { - sh_notfound (name); - any_failed++; - } - } - list = list->next; - } - - return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS); -} -#endif /* ALIAS */ - -#line 166 "./alias.def" - -#if defined (ALIAS) -/* Remove aliases named in LIST from the aliases database. */ -int -unalias_builtin (list) - register WORD_LIST *list; -{ - register alias_t *alias; - int opt, aflag; - - aflag = 0; - reset_internal_getopt (); - while ((opt = internal_getopt (list, "a")) != -1) - { - switch (opt) - { - case 'a': - aflag = 1; - break; - CASE_HELPOPT; - default: - builtin_usage (); - return (EX_USAGE); - } - } - - list = loptend; - - if (aflag) - { - delete_all_aliases (); - return (EXECUTION_SUCCESS); - } - - if (list == 0) - { - builtin_usage (); - return (EX_USAGE); - } - - aflag = 0; - while (list) - { - alias = find_alias (list->word->word); - - if (alias) - remove_alias (alias->name); - else - { - sh_notfound (list->word->word); - aflag++; - } - - list = list->next; - } - - return (aflag ? EXECUTION_FAILURE : EXECUTION_SUCCESS); -} - -/* Output ALIAS in such a way as to allow it to be read back in. */ -static void -print_alias (alias, flags) - alias_t *alias; - int flags; -{ - char *value; - - value = sh_single_quote (alias->value); - if (flags & AL_REUSABLE) - printf ("alias %s", (alias->name && alias->name[0] == '-') ? "-- " : ""); - printf ("%s=%s\n", alias->name, value); - free (value); - - fflush (stdout); -} -#endif /* ALIAS */ diff --git a/third_party/bash/builtins_bind.c b/third_party/bash/builtins_bind.c deleted file mode 100644 index 1fe36ab9a..000000000 --- a/third_party/bash/builtins_bind.c +++ /dev/null @@ -1,349 +0,0 @@ -/* bind.c, created from bind.def. */ -#line 22 "./bind.def" - -#include "config.h" - -#line 63 "./bind.def" - -#if defined (READLINE) - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include -#include -#if !defined (errno) -extern int errno; -#endif /* !errno */ - -#include "third_party/readline/readline.h" -#include "third_party/readline/history.h" - -#include "bashintl.h" - -#include "shell.h" -#include "bashline.h" -#include "bashgetopt.h" -#include "common.h" - -static int query_bindings PARAMS((char *)); -static int unbind_command PARAMS((char *)); -static int unbind_keyseq PARAMS((char *)); - -#define BIND_RETURN(x) do { return_code = x; goto bind_exit; } while (0) - -#define LFLAG 0x0001 -#define PFLAG 0x0002 -#define FFLAG 0x0004 -#define VFLAG 0x0008 -#define QFLAG 0x0010 -#define MFLAG 0x0020 -#define RFLAG 0x0040 -#define PPFLAG 0x0080 -#define VVFLAG 0x0100 -#define SFLAG 0x0200 -#define SSFLAG 0x0400 -#define UFLAG 0x0800 -#define XFLAG 0x1000 -#define XXFLAG 0x2000 - -int -bind_builtin (list) - WORD_LIST *list; -{ - int return_code; - Keymap kmap, saved_keymap; - int flags, opt; - char *initfile, *map_name, *fun_name, *unbind_name, *remove_seq, *cmd_seq, *t; - - if (no_line_editing) - { -#if 0 - builtin_error (_("line editing not enabled")); - return (EXECUTION_FAILURE); -#else - builtin_warning (_("line editing not enabled")); -#endif - } - - kmap = saved_keymap = (Keymap) NULL; - flags = 0; - initfile = map_name = fun_name = unbind_name = remove_seq = cmd_seq = (char *)NULL; - return_code = EXECUTION_SUCCESS; - - if (bash_readline_initialized == 0) - initialize_readline (); - - begin_unwind_frame ("bind_builtin"); - unwind_protect_var (rl_outstream); - - rl_outstream = stdout; - - reset_internal_getopt (); - while ((opt = internal_getopt (list, "lvpVPsSXf:q:u:m:r:x:")) != -1) - { - switch (opt) - { - case 'l': - flags |= LFLAG; - break; - case 'v': - flags |= VFLAG; - break; - case 'p': - flags |= PFLAG; - break; - case 'f': - flags |= FFLAG; - initfile = list_optarg; - break; - case 'm': - flags |= MFLAG; - map_name = list_optarg; - break; - case 'q': - flags |= QFLAG; - fun_name = list_optarg; - break; - case 'u': - flags |= UFLAG; - unbind_name = list_optarg; - break; - case 'r': - flags |= RFLAG; - remove_seq = list_optarg; - break; - case 'V': - flags |= VVFLAG; - break; - case 'P': - flags |= PPFLAG; - break; - case 's': - flags |= SFLAG; - break; - case 'S': - flags |= SSFLAG; - break; - case 'x': - flags |= XFLAG; - cmd_seq = list_optarg; - break; - case 'X': - flags |= XXFLAG; - break; - case GETOPT_HELP: - default: - builtin_usage (); - BIND_RETURN (EX_USAGE); - } - } - - list = loptend; - - /* First, see if we need to install a special keymap for this - command. Then start on the arguments. */ - - if ((flags & MFLAG) && map_name) - { - kmap = rl_get_keymap_by_name (map_name); - if (kmap == 0) - { - builtin_error (_("`%s': invalid keymap name"), map_name); - BIND_RETURN (EXECUTION_FAILURE); - } - } - - if (kmap) - { - saved_keymap = rl_get_keymap (); - rl_set_keymap (kmap); - } - - /* XXX - we need to add exclusive use tests here. It doesn't make sense - to use some of these options together. */ - /* Now hack the option arguments */ - if (flags & LFLAG) - rl_list_funmap_names (); - - if (flags & PFLAG) - rl_function_dumper (1); - - if (flags & PPFLAG) - rl_function_dumper (0); - - if (flags & SFLAG) - rl_macro_dumper (1); - - if (flags & SSFLAG) - rl_macro_dumper (0); - - if (flags & VFLAG) - rl_variable_dumper (1); - - if (flags & VVFLAG) - rl_variable_dumper (0); - - if ((flags & FFLAG) && initfile) - { - if (rl_read_init_file (initfile) != 0) - { - t = printable_filename (initfile, 0); - builtin_error (_("%s: cannot read: %s"), t, strerror (errno)); - if (t != initfile) - free (t); - BIND_RETURN (EXECUTION_FAILURE); - } - } - - if ((flags & QFLAG) && fun_name) - return_code = query_bindings (fun_name); - - if ((flags & UFLAG) && unbind_name) - return_code = unbind_command (unbind_name); - - if ((flags & RFLAG) && remove_seq) - { - opt = unbind_keyseq (remove_seq); - BIND_RETURN (opt); - } - - if (flags & XFLAG) - return_code = bind_keyseq_to_unix_command (cmd_seq); - - if (flags & XXFLAG) - return_code = print_unix_command_map (); - - /* Process the rest of the arguments as binding specifications. */ - while (list) - { - int olen, nlen, d, i; - char **obindings, **nbindings; - - obindings = rl_invoking_keyseqs (bash_execute_unix_command); - olen = obindings ? strvec_len (obindings) : 0; - - rl_parse_and_bind (list->word->word); - - nbindings = rl_invoking_keyseqs (bash_execute_unix_command); - nlen = nbindings ? strvec_len (nbindings) : 0; - - if (nlen < olen) /* fewer bind -x bindings */ - for (d = olen - nlen, i = 0; i < olen && d > 0; i++) - if (nlen == 0 || strvec_search (nbindings, obindings[i]) < 0) - { - unbind_unix_command (obindings[i]); - d--; - } - - strvec_dispose (obindings); - strvec_dispose (nbindings); - - list = list->next; - } - - bind_exit: - if (saved_keymap) - rl_set_keymap (saved_keymap); - - run_unwind_frame ("bind_builtin"); - - if (return_code < 0) - return_code = EXECUTION_FAILURE; - - return (sh_chkwrite (return_code)); -} - -static int -query_bindings (name) - char *name; -{ - rl_command_func_t *function; - char **keyseqs; - int j; - - function = rl_named_function (name); - if (function == 0) - { - builtin_error (_("`%s': unknown function name"), name); - return EXECUTION_FAILURE; - } - - keyseqs = rl_invoking_keyseqs (function); - - if (!keyseqs) - { - printf (_("%s is not bound to any keys.\n"), name); - return EXECUTION_FAILURE; - } - - printf (_("%s can be invoked via "), name); - for (j = 0; j < 5 && keyseqs[j]; j++) - printf ("\"%s\"%s", keyseqs[j], keyseqs[j + 1] ? ", " : ".\n"); - if (keyseqs[j]) - printf ("...\n"); - strvec_dispose (keyseqs); - return EXECUTION_SUCCESS; -} - -static int -unbind_command (name) - char *name; -{ - rl_command_func_t *function; - - function = rl_named_function (name); - if (function == 0) - { - builtin_error (_("`%s': unknown function name"), name); - return EXECUTION_FAILURE; - } - - rl_unbind_function_in_map (function, rl_get_keymap ()); - return EXECUTION_SUCCESS; -} - -static int -unbind_keyseq (seq) - char *seq; -{ - char *kseq; - int kslen, type; - rl_command_func_t *f; - - kseq = (char *)xmalloc ((2 * strlen (seq)) + 1); - if (rl_translate_keyseq (seq, kseq, &kslen)) - { - free (kseq); - builtin_error (_("`%s': cannot unbind"), seq); - return EXECUTION_FAILURE; - } - if ((f = rl_function_of_keyseq_len (kseq, kslen, (Keymap)0, &type)) == 0) - { - free (kseq); - return (EXECUTION_SUCCESS); - } - if (type == ISKMAP) - f = ((Keymap) f)[ANYOTHERKEY].function; - - /* I wish this didn't have to translate the key sequence again, but readline - doesn't have a binding function that takes a translated key sequence as - an argument. */ - if (rl_bind_keyseq (seq, (rl_command_func_t *)NULL) != 0) - { - free (kseq); - builtin_error (_("`%s': cannot unbind"), seq); - return (EXECUTION_FAILURE); - } - - if (f == bash_execute_unix_command) - unbind_unix_command (seq); - - free (kseq); - return (EXECUTION_SUCCESS); -} -#endif /* READLINE */ diff --git a/third_party/bash/builtins_break.c b/third_party/bash/builtins_break.c deleted file mode 100644 index 827b1a556..000000000 --- a/third_party/bash/builtins_break.c +++ /dev/null @@ -1,104 +0,0 @@ -/* break.c, created from break.def. */ -#line 22 "./break.def" - -#line 34 "./break.def" -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include "bashintl.h" - -#include "shell.h" -#include "execute_cmd.h" -#include "common.h" - -static int check_loop_level PARAMS((void)); - -/* The depth of while's and until's. */ -int loop_level = 0; - -/* Non-zero when a "break" instruction is encountered. */ -int breaking = 0; - -/* Non-zero when we have encountered a continue instruction. */ -int continuing = 0; - -/* Set up to break x levels, where x defaults to 1, but can be specified - as the first argument. */ -int -break_builtin (list) - WORD_LIST *list; -{ - intmax_t newbreak; - - CHECK_HELPOPT (list); - - if (check_loop_level () == 0) - return (EXECUTION_SUCCESS); - - (void)get_numeric_arg (list, 1, &newbreak); - - if (newbreak <= 0) - { - sh_erange (list->word->word, _("loop count")); - breaking = loop_level; - return (EXECUTION_FAILURE); - } - - if (newbreak > loop_level) - newbreak = loop_level; - - breaking = newbreak; - - return (EXECUTION_SUCCESS); -} - -#line 101 "./break.def" - -/* Set up to continue x levels, where x defaults to 1, but can be specified - as the first argument. */ -int -continue_builtin (list) - WORD_LIST *list; -{ - intmax_t newcont; - - CHECK_HELPOPT (list); - - if (check_loop_level () == 0) - return (EXECUTION_SUCCESS); - - (void)get_numeric_arg (list, 1, &newcont); - - if (newcont <= 0) - { - sh_erange (list->word->word, _("loop count")); - breaking = loop_level; - return (EXECUTION_FAILURE); - } - - if (newcont > loop_level) - newcont = loop_level; - - continuing = newcont; - - return (EXECUTION_SUCCESS); -} - -/* Return non-zero if a break or continue command would be okay. - Print an error message if break or continue is meaningless here. */ -static int -check_loop_level () -{ -#if defined (BREAK_COMPLAINS) - if (loop_level == 0 && posixly_correct == 0) - builtin_error (_("only meaningful in a `for', `while', or `until' loop")); -#endif /* BREAK_COMPLAINS */ - - return (loop_level); -} diff --git a/third_party/bash/builtins_builtin.c b/third_party/bash/builtins_builtin.c deleted file mode 100644 index 2029376cc..000000000 --- a/third_party/bash/builtins_builtin.c +++ /dev/null @@ -1,54 +0,0 @@ -/* builtin.c, created from builtin.def. */ -#line 22 "./builtin.def" - -#line 36 "./builtin.def" -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include "shell.h" -#include "execute_cmd.h" -#include "common.h" -#include "bashgetopt.h" - -/* Run the command mentioned in list directly, without going through the - normal alias/function/builtin/filename lookup process. */ -int -builtin_builtin (list) - WORD_LIST *list; -{ - sh_builtin_func_t *function; - register char *command; - - if (no_options (list)) - return (EX_USAGE); - list = loptend; /* skip over possible `--' */ - - if (list == 0) - return (EXECUTION_SUCCESS); - - command = list->word->word; -#if defined (DISABLED_BUILTINS) - function = builtin_address (command); -#else /* !DISABLED_BUILTINS */ - function = find_shell_builtin (command); -#endif /* !DISABLED_BUILTINS */ - - if (function == 0) - { - sh_notbuiltin (command); - return (EXECUTION_FAILURE); - } - else - { - this_command_name = command; - this_shell_builtin = function; /* overwrite "builtin" as this builtin */ - list = list->next; - return ((*function) (list)); - } -} diff --git a/third_party/bash/builtins_caller.c b/third_party/bash/builtins_caller.c deleted file mode 100644 index accb9455e..000000000 --- a/third_party/bash/builtins_caller.c +++ /dev/null @@ -1,120 +0,0 @@ -/* caller.c, created from caller.def. */ -#line 23 "./caller.def" - -#line 41 "./caller.def" - -#include "config.h" -#include -#include "chartypes.h" -#include "bashtypes.h" - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include - -#include "bashintl.h" - -#include "shell.h" -#include "common.h" -#include "builtext.h" -#include "bashgetopt.h" - -#ifdef LOADABLE_BUILTIN -# include "builtins.h" -#endif - -#if !defined (errno) -extern int errno; -#endif /* !errno */ - -int -caller_builtin (list) - WORD_LIST *list; -{ -#if !defined (ARRAY_VARS) - printf ("1 NULL\n"); - return (EXECUTION_FAILURE); -#else - SHELL_VAR *funcname_v, *bash_source_v, *bash_lineno_v; - ARRAY *funcname_a, *bash_source_a, *bash_lineno_a; - char *funcname_s, *source_s, *lineno_s; - intmax_t num; - - CHECK_HELPOPT (list); - - GET_ARRAY_FROM_VAR ("FUNCNAME", funcname_v, funcname_a); - GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a); - GET_ARRAY_FROM_VAR ("BASH_LINENO", bash_lineno_v, bash_lineno_a); - - if (bash_lineno_a == 0 || array_empty (bash_lineno_a)) - return (EXECUTION_FAILURE); - - if (bash_source_a == 0 || array_empty (bash_source_a)) - return (EXECUTION_FAILURE); - - if (no_options (list)) - return (EX_USAGE); - list = loptend; /* skip over possible `--' */ - - /* If there is no argument list, then give short form: line filename. */ - if (list == 0) - { - lineno_s = array_reference (bash_lineno_a, 0); - source_s = array_reference (bash_source_a, 1); - printf("%s %s\n", lineno_s ? lineno_s : "NULL", source_s ? source_s : "NULL"); - return (EXECUTION_SUCCESS); - } - - if (funcname_a == 0 || array_empty (funcname_a)) - return (EXECUTION_FAILURE); - - if (legal_number (list->word->word, &num)) - { - lineno_s = array_reference (bash_lineno_a, num); - source_s = array_reference (bash_source_a, num+1); - funcname_s = array_reference (funcname_a, num+1); - - if (lineno_s == NULL|| source_s == NULL || funcname_s == NULL) - return (EXECUTION_FAILURE); - - printf("%s %s %s\n", lineno_s, funcname_s, source_s); - } - else - { - sh_invalidnum (list->word->word); - builtin_usage (); - return (EX_USAGE); - } - - return (EXECUTION_SUCCESS); -#endif -} - -#ifdef LOADABLE_BUILTIN -static char *caller_doc[] = { -N_("Returns the context of the current subroutine call.\n\ - \n\ - Without EXPR, returns \"$line $filename\". With EXPR, returns\n\ - \"$line $subroutine $filename\"; this extra information can be used to\n\ - provide a stack trace.\n\ - \n\ - The value of EXPR indicates how many call frames to go back before the\n\ - current one; the top frame is frame 0."), - (char *)NULL -}; - -struct builtin caller_struct = { - "caller", - caller_builtin, - BUILTIN_ENABLED, - caller_doc, - "caller [EXPR]", - 0 -}; - -#endif /* LOADABLE_BUILTIN */ diff --git a/third_party/bash/builtins_cd.c b/third_party/bash/builtins_cd.c deleted file mode 100644 index 29f3b735d..000000000 --- a/third_party/bash/builtins_cd.c +++ /dev/null @@ -1,613 +0,0 @@ -/* cd.c, created from cd.def. */ -#line 22 "./cd.def" -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include "bashtypes.h" -#include "posixdir.h" -#include "posixstat.h" -#if defined (HAVE_SYS_PARAM_H) -#include -#endif -#include - -#include - -#include "bashansi.h" -#include "bashintl.h" - -#include -#include "tilde.h" - -#include "shell.h" -#include "flags.h" -#include "maxpath.h" -#include "common.h" -#include "bashgetopt.h" - -#if !defined (errno) -extern int errno; -#endif /* !errno */ - -extern const char * const bash_getcwd_errstr; - -static int bindpwd PARAMS((int)); -static int setpwd PARAMS((char *)); -static char *resetpwd PARAMS((char *)); -static int change_to_directory PARAMS((char *, int, int)); - -static int cdxattr PARAMS((char *, char **)); -static void resetxattr PARAMS((void)); - -/* Change this to 1 to get cd spelling correction by default. */ -int cdspelling = 0; - -int cdable_vars; - -static int eflag; /* file scope so bindpwd() can see it */ -static int xattrflag; /* O_XATTR support for openat */ -static int xattrfd = -1; - -#line 115 "./cd.def" - -/* Just set $PWD, don't change OLDPWD. Used by `pwd -P' in posix mode. */ -static int -setpwd (dirname) - char *dirname; -{ - int old_anm; - SHELL_VAR *tvar; - - old_anm = array_needs_making; - tvar = bind_variable ("PWD", dirname ? dirname : "", 0); - if (tvar && readonly_p (tvar)) - return EXECUTION_FAILURE; - if (tvar && old_anm == 0 && array_needs_making && exported_p (tvar)) - { - update_export_env_inplace ("PWD=", 4, dirname ? dirname : ""); - array_needs_making = 0; - } - return EXECUTION_SUCCESS; -} - -static int -bindpwd (no_symlinks) - int no_symlinks; -{ - char *dirname, *pwdvar; - int old_anm, r, canon_failed; - SHELL_VAR *tvar; - - r = sh_chkwrite (EXECUTION_SUCCESS); - -#define tcwd the_current_working_directory - dirname = tcwd ? (no_symlinks ? sh_physpath (tcwd, 0) : tcwd) - : get_working_directory ("cd"); -#undef tcwd - - /* If canonicalization fails, reset dirname to the_current_working_directory */ - canon_failed = 0; - if (dirname == 0) - { - canon_failed = 1; - dirname = the_current_working_directory; - } - - old_anm = array_needs_making; - pwdvar = get_string_value ("PWD"); - - tvar = bind_variable ("OLDPWD", pwdvar, 0); - if (tvar && readonly_p (tvar)) - r = EXECUTION_FAILURE; - - if (old_anm == 0 && array_needs_making && exported_p (tvar)) - { - update_export_env_inplace ("OLDPWD=", 7, pwdvar); - array_needs_making = 0; - } - - if (setpwd (dirname) == EXECUTION_FAILURE) - r = EXECUTION_FAILURE; - if (canon_failed && eflag) - r = EXECUTION_FAILURE; - - if (dirname && dirname != the_current_working_directory) - free (dirname); - - return (r); -} - -/* Call get_working_directory to reset the value of - the_current_working_directory () */ -static char * -resetpwd (caller) - char *caller; -{ - char *tdir; - - FREE (the_current_working_directory); - the_current_working_directory = (char *)NULL; - tdir = get_working_directory (caller); - return (tdir); -} - -static int -cdxattr (dir, ndirp) - char *dir; /* don't assume we can always free DIR */ - char **ndirp; /* return new constructed directory name */ -{ -#if defined (O_XATTR) - int apfd, fd, r, e; - char buf[11+40+40]; /* construct new `fake' path for pwd */ - - apfd = openat (AT_FDCWD, dir, O_RDONLY|O_NONBLOCK); - if (apfd < 0) - return -1; - fd = openat (apfd, ".", O_XATTR); - e = errno; - close (apfd); /* ignore close error for now */ - errno = e; - if (fd < 0) - return -1; - r = fchdir (fd); /* assume fchdir exists everywhere with O_XATTR */ - if (r < 0) - { - close (fd); - return -1; - } - /* NFSv4 and ZFS extended attribute directories do not have names which are - visible in the standard Unix directory tree structure. To ensure we have - a valid name for $PWD, we synthesize one under /proc, but to keep that - path valid, we need to keep the file descriptor open as long as we are in - this directory. This imposes a certain structure on /proc. */ - if (ndirp) - { - sprintf (buf, "/proc/%d/fd/%d", getpid(), fd); - *ndirp = savestring (buf); - } - - if (xattrfd >= 0) - close (xattrfd); - xattrfd = fd; - - return r; -#else - return -1; -#endif -} - -/* Clean up the O_XATTR baggage. Currently only closes xattrfd */ -static void -resetxattr () -{ -#if defined (O_XATTR) - if (xattrfd >= 0) - { - close (xattrfd); - xattrfd = -1; - } -#else - xattrfd = -1; /* not strictly necessary */ -#endif -} - -#define LCD_DOVARS 0x001 -#define LCD_DOSPELL 0x002 -#define LCD_PRINTPATH 0x004 -#define LCD_FREEDIRNAME 0x008 - -/* This builtin is ultimately the way that all user-visible commands should - change the current working directory. It is called by cd_to_string (), - so the programming interface is simple, and it handles errors and - restrictions properly. */ -int -cd_builtin (list) - WORD_LIST *list; -{ - char *dirname, *cdpath, *path, *temp; - int path_index, no_symlinks, opt, lflag, e; - -#if defined (RESTRICTED_SHELL) - if (restricted) - { - sh_restricted ((char *)NULL); - return (EXECUTION_FAILURE); - } -#endif /* RESTRICTED_SHELL */ - - eflag = 0; - no_symlinks = no_symbolic_links; - xattrflag = 0; - reset_internal_getopt (); -#if defined (O_XATTR) - while ((opt = internal_getopt (list, "eLP@")) != -1) -#else - while ((opt = internal_getopt (list, "eLP")) != -1) -#endif - { - switch (opt) - { - case 'P': - no_symlinks = 1; - break; - case 'L': - no_symlinks = 0; - break; - case 'e': - eflag = 1; - break; -#if defined (O_XATTR) - case '@': - xattrflag = 1; - break; -#endif - CASE_HELPOPT; - default: - builtin_usage (); - return (EX_USAGE); - } - } - list = loptend; - - lflag = (cdable_vars ? LCD_DOVARS : 0) | - ((interactive && cdspelling) ? LCD_DOSPELL : 0); - if (eflag && no_symlinks == 0) - eflag = 0; - - if (list == 0) - { - /* `cd' without arguments is equivalent to `cd $HOME' */ - dirname = get_string_value ("HOME"); - - if (dirname == 0) - { - builtin_error (_("HOME not set")); - return (EXECUTION_FAILURE); - } - lflag = 0; - } -#if defined (CD_COMPLAINS) - else if (list->next) - { - builtin_error (_("too many arguments")); - return (EXECUTION_FAILURE); - } -#endif -#if 0 - else if (list->word->word[0] == '\0') - { - builtin_error (_("null directory")); - return (EXECUTION_FAILURE); - } -#endif - else if (list->word->word[0] == '-' && list->word->word[1] == '\0') - { - /* This is `cd -', equivalent to `cd $OLDPWD' */ - dirname = get_string_value ("OLDPWD"); - - if (dirname == 0) - { - builtin_error (_("OLDPWD not set")); - return (EXECUTION_FAILURE); - } -#if 0 - lflag = interactive ? LCD_PRINTPATH : 0; -#else - lflag = LCD_PRINTPATH; /* According to SUSv3 */ -#endif - } - else if (absolute_pathname (list->word->word)) - dirname = list->word->word; - else if (privileged_mode == 0 && (cdpath = get_string_value ("CDPATH"))) - { - dirname = list->word->word; - - /* Find directory in $CDPATH. */ - path_index = 0; - while (path = extract_colon_unit (cdpath, &path_index)) - { - /* OPT is 1 if the path element is non-empty */ - opt = path[0] != '\0'; - temp = sh_makepath (path, dirname, MP_DOTILDE); - free (path); - - if (change_to_directory (temp, no_symlinks, xattrflag)) - { - /* POSIX.2 says that if a nonempty directory from CDPATH - is used to find the directory to change to, the new - directory name is echoed to stdout, whether or not - the shell is interactive. */ - if (opt && (path = no_symlinks ? temp : the_current_working_directory)) - printf ("%s\n", path); - - free (temp); -#if 0 - /* Posix.2 says that after using CDPATH, the resultant - value of $PWD will not contain `.' or `..'. */ - return (bindpwd (posixly_correct || no_symlinks)); -#else - return (bindpwd (no_symlinks)); -#endif - } - else - free (temp); - } - -#if 0 - /* changed for bash-4.2 Posix cd description steps 5-6 */ - /* POSIX.2 says that if `.' does not appear in $CDPATH, we don't - try the current directory, so we just punt now with an error - message if POSIXLY_CORRECT is non-zero. The check for cdpath[0] - is so we don't mistakenly treat a CDPATH value of "" as not - specifying the current directory. */ - if (posixly_correct && cdpath[0]) - { - builtin_error ("%s: %s", dirname, strerror (ENOENT)); - return (EXECUTION_FAILURE); - } -#endif - } - else - dirname = list->word->word; - - /* When we get here, DIRNAME is the directory to change to. If we - chdir successfully, just return. */ - if (change_to_directory (dirname, no_symlinks, xattrflag)) - { - if (lflag & LCD_PRINTPATH) - printf ("%s\n", dirname); - return (bindpwd (no_symlinks)); - } - - /* If the user requests it, then perhaps this is the name of - a shell variable, whose value contains the directory to - change to. */ - if (lflag & LCD_DOVARS) - { - temp = get_string_value (dirname); - if (temp && change_to_directory (temp, no_symlinks, xattrflag)) - { - printf ("%s\n", temp); - return (bindpwd (no_symlinks)); - } - } - - /* If the user requests it, try to find a directory name similar in - spelling to the one requested, in case the user made a simple - typo. This is similar to the UNIX 8th and 9th Edition shells. */ - if (lflag & LCD_DOSPELL) - { - temp = dirspell (dirname); - if (temp && change_to_directory (temp, no_symlinks, xattrflag)) - { - printf ("%s\n", temp); - free (temp); - return (bindpwd (no_symlinks)); - } - else - FREE (temp); - } - - e = errno; - temp = printable_filename (dirname, 0); - builtin_error ("%s: %s", temp, strerror (e)); - if (temp != dirname) - free (temp); - return (EXECUTION_FAILURE); -} - -#line 478 "./cd.def" - -/* Non-zero means that pwd always prints the physical directory, without - symbolic links. */ -static int verbatim_pwd; - -/* Print the name of the current working directory. */ -int -pwd_builtin (list) - WORD_LIST *list; -{ - char *directory; - int opt, pflag; - - verbatim_pwd = no_symbolic_links; - pflag = 0; - reset_internal_getopt (); - while ((opt = internal_getopt (list, "LP")) != -1) - { - switch (opt) - { - case 'P': - verbatim_pwd = pflag = 1; - break; - case 'L': - verbatim_pwd = 0; - break; - CASE_HELPOPT; - default: - builtin_usage (); - return (EX_USAGE); - } - } - list = loptend; - -#define tcwd the_current_working_directory - - directory = tcwd ? (verbatim_pwd ? sh_physpath (tcwd, 0) : tcwd) - : get_working_directory ("pwd"); - - /* Try again using getcwd() if canonicalization fails (for instance, if - the file system has changed state underneath bash). */ - if ((tcwd && directory == 0) || - (posixly_correct && same_file (".", tcwd, (struct stat *)0, (struct stat *)0) == 0)) - { - if (directory && directory != tcwd) - free (directory); - directory = resetpwd ("pwd"); - } - -#undef tcwd - - if (directory) - { - opt = EXECUTION_SUCCESS; - printf ("%s\n", directory); - /* This is dumb but posix-mandated. */ - if (posixly_correct && pflag) - opt = setpwd (directory); - if (directory != the_current_working_directory) - free (directory); - return (sh_chkwrite (opt)); - } - else - return (EXECUTION_FAILURE); -} - -/* Do the work of changing to the directory NEWDIR. Handle symbolic - link following, etc. This function *must* return with - the_current_working_directory either set to NULL (in which case - getcwd() will eventually be called), or set to a string corresponding - to the working directory. Return 1 on success, 0 on failure. */ - -static int -change_to_directory (newdir, nolinks, xattr) - char *newdir; - int nolinks, xattr; -{ - char *t, *tdir, *ndir; - int err, canon_failed, r, ndlen; - - tdir = (char *)NULL; - - if (the_current_working_directory == 0) - { - t = get_working_directory ("chdir"); - FREE (t); - } - - t = make_absolute (newdir, the_current_working_directory); - - /* TDIR is either the canonicalized absolute pathname of NEWDIR - (nolinks == 0) or the absolute physical pathname of NEWDIR - (nolinks != 0). */ - tdir = nolinks ? sh_physpath (t, 0) - : sh_canonpath (t, PATH_CHECKDOTDOT|PATH_CHECKEXISTS); - - ndlen = strlen (newdir); - - /* Use the canonicalized version of NEWDIR, or, if canonicalization - failed, use the non-canonical form. */ - canon_failed = 0; - if (tdir && *tdir) - free (t); - else - { - FREE (tdir); - tdir = t; - canon_failed = 1; - } - - /* In POSIX mode, if we're resolving symlinks logically and sh_canonpath - returns NULL (because it checks the path, it will return NULL if the - resolved path doesn't exist), fail immediately. */ -#if defined (ENAMETOOLONG) - if (posixly_correct && nolinks == 0 && canon_failed && (errno != ENAMETOOLONG || ndlen > PATH_MAX)) -#else - if (posixly_correct && nolinks == 0 && canon_failed && ndlen > PATH_MAX) -#endif - { -#if defined ENAMETOOLONG - if (errno != ENOENT && errno != ENAMETOOLONG) -#else - if (errno != ENOENT) -#endif - errno = ENOTDIR; - free (tdir); - return (0); - } - -#if defined (O_XATTR) - if (xattrflag) - { - r = cdxattr (nolinks ? newdir : tdir, &ndir); - if (r >= 0) - { - canon_failed = 0; - free (tdir); - tdir = ndir; - } - else - { - err = errno; - free (tdir); - errno = err; - return (0); /* no xattr */ - } - } - else -#endif - { - r = chdir (nolinks ? newdir : tdir); - if (r >= 0) - resetxattr (); - } - - /* If the chdir succeeds, update the_current_working_directory. */ - if (r == 0) - { - /* If canonicalization failed, but the chdir succeeded, reset the - shell's idea of the_current_working_directory. */ - if (canon_failed) - { - t = resetpwd ("cd"); - if (t == 0) - set_working_directory (tdir); - else - free (t); - } - else - set_working_directory (tdir); - - free (tdir); - return (1); - } - - /* We failed to change to the appropriate directory name. If we tried - what the user passed (nolinks != 0), punt now. */ - if (nolinks) - { - free (tdir); - return (0); - } - - err = errno; - - /* We're not in physical mode (nolinks == 0), but we failed to change to - the canonicalized directory name (TDIR). Try what the user passed - verbatim. If we succeed, reinitialize the_current_working_directory. - POSIX requires that we just fail here, so we do in posix mode. */ - if (posixly_correct == 0 && chdir (newdir) == 0) - { - t = resetpwd ("cd"); - if (t == 0) - set_working_directory (tdir); - else - free (t); - - r = 1; - } - else - { - errno = err; - r = 0; - } - - free (tdir); - return r; -} diff --git a/third_party/bash/builtins_colon.c b/third_party/bash/builtins_colon.c deleted file mode 100644 index dcb10e91c..000000000 --- a/third_party/bash/builtins_colon.c +++ /dev/null @@ -1,33 +0,0 @@ -/* colon.c, created from colon.def. */ -#line 22 "./colon.def" - -#line 34 "./colon.def" - -#line 43 "./colon.def" - -#line 52 "./colon.def" - -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "bashansi.h" -#include "shell.h" - -/* Return a successful result. */ -int -colon_builtin (ignore) - WORD_LIST *ignore; -{ - return (0); -} - -/* Return an unsuccessful result. */ -int -false_builtin (ignore) - WORD_LIST *ignore; -{ - return (1); -} diff --git a/third_party/bash/builtins_command.c b/third_party/bash/builtins_command.c deleted file mode 100644 index c41887ec9..000000000 --- a/third_party/bash/builtins_command.c +++ /dev/null @@ -1,107 +0,0 @@ -/* command.c, created from command.def. */ -#line 22 "./command.def" - -#line 41 "./command.def" - -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include "bashansi.h" - -#include "shell.h" -#include "execute_cmd.h" -#include "flags.h" -#include "bashgetopt.h" -#include "common.h" - -#if defined (_CS_PATH) && defined (HAVE_CONFSTR) && !HAVE_DECL_CONFSTR -extern size_t confstr PARAMS((int, char *, size_t)); -#endif - -/* Run the commands mentioned in LIST without paying attention to shell - functions. */ -int -command_builtin (list) - WORD_LIST *list; -{ - int result, verbose, use_standard_path, opt; - COMMAND *command; - - verbose = use_standard_path = 0; - reset_internal_getopt (); - while ((opt = internal_getopt (list, "pvV")) != -1) - { - switch (opt) - { - case 'p': - use_standard_path = CDESC_STDPATH; - break; - case 'V': - verbose = CDESC_SHORTDESC|CDESC_ABSPATH; /* look in common.h for constants */ - break; - case 'v': - verbose = CDESC_REUSABLE; /* ditto */ - break; - CASE_HELPOPT; - default: - builtin_usage (); - return (EX_USAGE); - } - } - list = loptend; - - if (list == 0) - return (EXECUTION_SUCCESS); - -#if defined (RESTRICTED_SHELL) - if (use_standard_path && restricted) - { - sh_restricted ("-p"); - return (EXECUTION_FAILURE); - } -#endif - - if (verbose) - { - int found, any_found; - - for (any_found = 0; list; list = list->next) - { - found = describe_command (list->word->word, verbose|use_standard_path); - - if (found == 0 && verbose != CDESC_REUSABLE) - sh_notfound (list->word->word); - - any_found += found; - } - - return (any_found ? EXECUTION_SUCCESS : EXECUTION_FAILURE); - } - - begin_unwind_frame ("command_builtin"); - -#define COMMAND_BUILTIN_FLAGS (CMD_NO_FUNCTIONS | CMD_INHIBIT_EXPANSION | CMD_COMMAND_BUILTIN | (use_standard_path ? CMD_STDPATH : 0)) - - INTERNAL_DEBUG (("command_builtin: running execute_command for `%s'", list->word->word)); - - /* We don't want this to be reparsed (consider command echo 'foo &'), so - just make a simple_command structure and call execute_command with it. */ - command = make_bare_simple_command (); - command->value.Simple->words = (WORD_LIST *)copy_word_list (list); - command->value.Simple->redirects = (REDIRECT *)NULL; - command->flags |= COMMAND_BUILTIN_FLAGS; - command->value.Simple->flags |= COMMAND_BUILTIN_FLAGS; - - add_unwind_protect ((char *)dispose_command, command); - result = execute_command (command); - - run_unwind_frame ("command_builtin"); - - return (result); -} diff --git a/third_party/bash/builtins_complete.c b/third_party/bash/builtins_complete.c deleted file mode 100644 index 2309fe446..000000000 --- a/third_party/bash/builtins_complete.c +++ /dev/null @@ -1,805 +0,0 @@ -/* complete.c, created from complete.def. */ -#line 22 "./complete.def" - -#line 51 "./complete.def" - -#include "config.h" - -#include - -#include "bashtypes.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "bashansi.h" -#include "bashintl.h" - -#include "shell.h" -#include "builtins.h" -#include "pcomplete.h" -#include "bashline.h" - -#include "common.h" -#include "bashgetopt.h" - -#include "third_party/readline/readline.h" - -#define STRDUP(x) ((x) ? savestring (x) : (char *)NULL) - -/* Structure containing all the non-action (binary) options; filled in by - build_actions(). */ -struct _optflags { - int pflag; - int rflag; - int Dflag; - int Eflag; - int Iflag; -}; - -static int find_compact PARAMS((char *)); -static int find_compopt PARAMS((char *)); - -static int build_actions PARAMS((WORD_LIST *, struct _optflags *, unsigned long *, unsigned long *)); - -static int remove_cmd_completions PARAMS((WORD_LIST *)); - -static int print_one_completion PARAMS((char *, COMPSPEC *)); -static int print_compitem PARAMS((BUCKET_CONTENTS *)); -static void print_compopts PARAMS((const char *, COMPSPEC *, int)); -static void print_all_completions PARAMS((void)); -static int print_cmd_completions PARAMS((WORD_LIST *)); - -static void print_compoptions PARAMS((unsigned long, int)); -static void print_compactions PARAMS((unsigned long)); -static void print_arg PARAMS((const char *, const char *, int)); -static void print_cmd_name PARAMS((const char *)); - -static char *Garg, *Warg, *Parg, *Sarg, *Xarg, *Farg, *Carg; - -static const struct _compacts { - const char * const actname; - unsigned long actflag; - int actopt; -} compacts[] = { - { "alias", CA_ALIAS, 'a' }, - { "arrayvar", CA_ARRAYVAR, 0 }, - { "binding", CA_BINDING, 0 }, - { "builtin", CA_BUILTIN, 'b' }, - { "command", CA_COMMAND, 'c' }, - { "directory", CA_DIRECTORY, 'd' }, - { "disabled", CA_DISABLED, 0 }, - { "enabled", CA_ENABLED, 0 }, - { "export", CA_EXPORT, 'e' }, - { "file", CA_FILE, 'f' }, - { "function", CA_FUNCTION, 0 }, - { "helptopic", CA_HELPTOPIC, 0 }, - { "hostname", CA_HOSTNAME, 0 }, - { "group", CA_GROUP, 'g' }, - { "job", CA_JOB, 'j' }, - { "keyword", CA_KEYWORD, 'k' }, - { "running", CA_RUNNING, 0 }, - { "service", CA_SERVICE, 's' }, - { "setopt", CA_SETOPT, 0 }, - { "shopt", CA_SHOPT, 0 }, - { "signal", CA_SIGNAL, 0 }, - { "stopped", CA_STOPPED, 0 }, - { "user", CA_USER, 'u' }, - { "variable", CA_VARIABLE, 'v' }, - { (char *)NULL, 0, 0 }, -}; - -/* This should be a STRING_INT_ALIST */ -static const struct _compopt { - const char * const optname; - unsigned long optflag; -} compopts[] = { - { "bashdefault", COPT_BASHDEFAULT }, - { "default", COPT_DEFAULT }, - { "dirnames", COPT_DIRNAMES }, - { "filenames",COPT_FILENAMES}, - { "noquote", COPT_NOQUOTE }, - { "nosort", COPT_NOSORT }, - { "nospace", COPT_NOSPACE }, - { "plusdirs", COPT_PLUSDIRS }, - { (char *)NULL, 0 }, -}; - -static int -find_compact (name) - char *name; -{ - register int i; - - for (i = 0; compacts[i].actname; i++) - if (STREQ (name, compacts[i].actname)) - return i; - return -1; -} - -static int -find_compopt (name) - char *name; -{ - register int i; - - for (i = 0; compopts[i].optname; i++) - if (STREQ (name, compopts[i].optname)) - return i; - return -1; -} - -/* Build the actions and compspec options from the options specified in LIST. - ACTP is a pointer to an unsigned long in which to place the bitmap of - actions. OPTP is a pointer to an unsigned long in which to place the - bitmap of compspec options (arguments to `-o'). PP, if non-null, gets 1 - if -p is supplied; RP, if non-null, gets 1 if -r is supplied. - If either is null, the corresponding option generates an error. - This also sets variables corresponding to options that take arguments as - a side effect; the caller should ensure that those variables are set to - NULL before calling build_actions. Return value: - EX_USAGE = bad option - EXECUTION_SUCCESS = some options supplied - EXECUTION_FAILURE = no options supplied -*/ - -static int -build_actions (list, flagp, actp, optp) - WORD_LIST *list; - struct _optflags *flagp; - unsigned long *actp, *optp; -{ - int opt, ind, opt_given; - unsigned long acts, copts; - WORD_DESC w; - - acts = copts = (unsigned long)0L; - opt_given = 0; - - reset_internal_getopt (); - while ((opt = internal_getopt (list, "abcdefgjko:prsuvA:G:W:P:S:X:F:C:DEI")) != -1) - { - opt_given = 1; - switch (opt) - { - case 'r': - if (flagp) - { - flagp->rflag = 1; - break; - } - else - { - sh_invalidopt ("-r"); - builtin_usage (); - return (EX_USAGE); - } - - case 'p': - if (flagp) - { - flagp->pflag = 1; - break; - } - else - { - sh_invalidopt ("-p"); - builtin_usage (); - return (EX_USAGE); - } - - case 'a': - acts |= CA_ALIAS; - break; - case 'b': - acts |= CA_BUILTIN; - break; - case 'c': - acts |= CA_COMMAND; - break; - case 'd': - acts |= CA_DIRECTORY; - break; - case 'e': - acts |= CA_EXPORT; - break; - case 'f': - acts |= CA_FILE; - break; - case 'g': - acts |= CA_GROUP; - break; - case 'j': - acts |= CA_JOB; - break; - case 'k': - acts |= CA_KEYWORD; - break; - case 's': - acts |= CA_SERVICE; - break; - case 'u': - acts |= CA_USER; - break; - case 'v': - acts |= CA_VARIABLE; - break; - case 'o': - ind = find_compopt (list_optarg); - if (ind < 0) - { - sh_invalidoptname (list_optarg); - return (EX_USAGE); - } - copts |= compopts[ind].optflag; - break; - case 'A': - ind = find_compact (list_optarg); - if (ind < 0) - { - builtin_error (_("%s: invalid action name"), list_optarg); - return (EX_USAGE); - } - acts |= compacts[ind].actflag; - break; - case 'C': - Carg = list_optarg; - break; - case 'D': - if (flagp) - { - flagp->Dflag = 1; - break; - } - else - { - sh_invalidopt ("-D"); - builtin_usage (); - return (EX_USAGE); - } - case 'E': - if (flagp) - { - flagp->Eflag = 1; - break; - } - else - { - sh_invalidopt ("-E"); - builtin_usage (); - return (EX_USAGE); - } - case 'I': - if (flagp) - { - flagp->Iflag = 1; - break; - } - else - { - sh_invalidopt ("-I"); - builtin_usage (); - return (EX_USAGE); - } - case 'F': - w.word = Farg = list_optarg; - w.flags = 0; - if (check_identifier (&w, posixly_correct) == 0 || strpbrk (Farg, shell_break_chars) != 0) - { - sh_invalidid (Farg); - return (EX_USAGE); - } - break; - case 'G': - Garg = list_optarg; - break; - case 'P': - Parg = list_optarg; - break; - case 'S': - Sarg = list_optarg; - break; - case 'W': - Warg = list_optarg; - break; - case 'X': - Xarg = list_optarg; - break; - CASE_HELPOPT; - default: - builtin_usage (); - return (EX_USAGE); - } - } - - *actp = acts; - *optp = copts; - - return (opt_given ? EXECUTION_SUCCESS : EXECUTION_FAILURE); -} - -/* Add, remove, and display completion specifiers. */ -int -complete_builtin (list) - WORD_LIST *list; -{ - int opt_given, rval; - unsigned long acts, copts; - COMPSPEC *cs; - struct _optflags oflags; - WORD_LIST *l, *wl; - - if (list == 0) - { - print_all_completions (); - return (EXECUTION_SUCCESS); - } - - opt_given = oflags.pflag = oflags.rflag = 0; - oflags.Dflag = oflags.Eflag = oflags.Iflag = 0; - - acts = copts = (unsigned long)0L; - Garg = Warg = Parg = Sarg = Xarg = Farg = Carg = (char *)NULL; - cs = (COMPSPEC *)NULL; - - /* Build the actions from the arguments. Also sets the [A-Z]arg variables - as a side effect if they are supplied as options. */ - rval = build_actions (list, &oflags, &acts, &copts); - if (rval == EX_USAGE) - return (rval); - opt_given = rval != EXECUTION_FAILURE; - - list = loptend; - - if (oflags.Dflag) - wl = make_word_list (make_bare_word (DEFAULTCMD), (WORD_LIST *)NULL); - else if (oflags.Eflag) - wl = make_word_list (make_bare_word (EMPTYCMD), (WORD_LIST *)NULL); - else if (oflags.Iflag) - wl = make_word_list (make_bare_word (INITIALWORD), (WORD_LIST *)NULL); - else - wl = (WORD_LIST *)NULL; - - /* -p overrides everything else */ - if (oflags.pflag || (list == 0 && opt_given == 0)) - { - if (wl) - { - rval = print_cmd_completions (wl); - dispose_words (wl); - return rval; - } - else if (list == 0) - { - print_all_completions (); - return (EXECUTION_SUCCESS); - } - return (print_cmd_completions (list)); - } - - /* next, -r overrides everything else. */ - if (oflags.rflag) - { - if (wl) - { - rval = remove_cmd_completions (wl); - dispose_words (wl); - return rval; - } - else if (list == 0) - { - progcomp_flush (); - return (EXECUTION_SUCCESS); - } - return (remove_cmd_completions (list)); - } - - if (wl == 0 && list == 0 && opt_given) - { - builtin_usage (); - return (EX_USAGE); - } - - /* If we get here, we need to build a compspec and add it for each - remaining argument. */ - cs = compspec_create (); - cs->actions = acts; - cs->options = copts; - - cs->globpat = STRDUP (Garg); - cs->words = STRDUP (Warg); - cs->prefix = STRDUP (Parg); - cs->suffix = STRDUP (Sarg); - cs->funcname = STRDUP (Farg); - cs->command = STRDUP (Carg); - cs->filterpat = STRDUP (Xarg); - - for (rval = EXECUTION_SUCCESS, l = wl ? wl : list ; l; l = l->next) - { - /* Add CS as the compspec for the specified commands. */ - if (progcomp_insert (l->word->word, cs) == 0) - rval = EXECUTION_FAILURE; - } - - dispose_words (wl); - return (rval); -} - -static int -remove_cmd_completions (list) - WORD_LIST *list; -{ - WORD_LIST *l; - int ret; - - for (ret = EXECUTION_SUCCESS, l = list; l; l = l->next) - { - if (progcomp_remove (l->word->word) == 0) - { - builtin_error (_("%s: no completion specification"), l->word->word); - ret = EXECUTION_FAILURE; - } - } - return ret; -} - -static void -print_compoptions (copts, full) - unsigned long copts; - int full; -{ - const struct _compopt *co; - - for (co = compopts; co->optname; co++) - if (copts & co->optflag) - printf ("-o %s ", co->optname); - else if (full) - printf ("+o %s ", co->optname); -} - -static void -print_compactions (acts) - unsigned long acts; -{ - const struct _compacts *ca; - - /* simple flags first */ - for (ca = compacts; ca->actname; ca++) - if (ca->actopt && (acts & ca->actflag)) - printf ("-%c ", ca->actopt); - - /* then the rest of the actions */ - for (ca = compacts; ca->actname; ca++) - if (ca->actopt == 0 && (acts & ca->actflag)) - printf ("-A %s ", ca->actname); -} - -static void -print_arg (arg, flag, quote) - const char *arg, *flag; - int quote; -{ - char *x; - - if (arg) - { - x = quote ? sh_single_quote (arg) : (char *)arg; - printf ("%s %s ", flag, x); - if (x != arg) - free (x); - } -} - -static void -print_cmd_name (cmd) - const char *cmd; -{ - char *x; - - if (STREQ (cmd, DEFAULTCMD)) - printf ("-D"); - else if (STREQ (cmd, EMPTYCMD)) - printf ("-E"); - else if (STREQ (cmd, INITIALWORD)) - printf ("-I"); - else if (*cmd == 0) /* XXX - can this happen? */ - printf ("''"); - else if (sh_contains_shell_metas (cmd)) - { - x = sh_single_quote (cmd); - printf ("%s", x); - free (x); - } - else - printf ("%s", cmd); -} - -static int -print_one_completion (cmd, cs) - char *cmd; - COMPSPEC *cs; -{ - printf ("complete "); - - print_compoptions (cs->options, 0); - print_compactions (cs->actions); - - /* now the rest of the arguments */ - - /* arguments that require quoting */ - print_arg (cs->globpat, "-G", 1); - print_arg (cs->words, "-W", 1); - print_arg (cs->prefix, "-P", 1); - print_arg (cs->suffix, "-S", 1); - print_arg (cs->filterpat, "-X", 1); - - print_arg (cs->command, "-C", 1); - - /* simple arguments that don't require quoting */ - print_arg (cs->funcname, "-F", sh_contains_shell_metas (cs->funcname) != 0); - - print_cmd_name (cmd); - printf ("\n"); - - return (0); -} - -static void -print_compopts (cmd, cs, full) - const char *cmd; - COMPSPEC *cs; - int full; -{ - printf ("compopt "); - - print_compoptions (cs->options, full); - print_cmd_name (cmd); - - printf ("\n"); -} - -static int -print_compitem (item) - BUCKET_CONTENTS *item; -{ - COMPSPEC *cs; - char *cmd; - - cmd = item->key; - cs = (COMPSPEC *)item->data; - - return (print_one_completion (cmd, cs)); -} - -static void -print_all_completions () -{ - progcomp_walk (print_compitem); -} - -static int -print_cmd_completions (list) - WORD_LIST *list; -{ - WORD_LIST *l; - COMPSPEC *cs; - int ret; - - for (ret = EXECUTION_SUCCESS, l = list; l; l = l->next) - { - cs = progcomp_search (l->word->word); - if (cs) - print_one_completion (l->word->word, cs); - else - { - builtin_error (_("%s: no completion specification"), l->word->word); - ret = EXECUTION_FAILURE; - } - } - - return (sh_chkwrite (ret)); -} - -#line 663 "./complete.def" - -int -compgen_builtin (list) - WORD_LIST *list; -{ - int rval; - unsigned long acts, copts; - COMPSPEC *cs; - STRINGLIST *sl; - char *word, **matches; - char *old_line; - int old_ind; - - if (list == 0) - return (EXECUTION_SUCCESS); - - acts = copts = (unsigned long)0L; - Garg = Warg = Parg = Sarg = Xarg = Farg = Carg = (char *)NULL; - cs = (COMPSPEC *)NULL; - - /* Build the actions from the arguments. Also sets the [A-Z]arg variables - as a side effect if they are supplied as options. */ - rval = build_actions (list, (struct _optflags *)NULL, &acts, &copts); - if (rval == EX_USAGE) - return (rval); - if (rval == EXECUTION_FAILURE) - return (EXECUTION_SUCCESS); - - list = loptend; - - word = (list && list->word) ? list->word->word : ""; - - if (Farg) - builtin_error (_("warning: -F option may not work as you expect")); - if (Carg) - builtin_error (_("warning: -C option may not work as you expect")); - - /* If we get here, we need to build a compspec and evaluate it. */ - cs = compspec_create (); - cs->actions = acts; - cs->options = copts; - cs->refcount = 1; - - cs->globpat = STRDUP (Garg); - cs->words = STRDUP (Warg); - cs->prefix = STRDUP (Parg); - cs->suffix = STRDUP (Sarg); - cs->funcname = STRDUP (Farg); - cs->command = STRDUP (Carg); - cs->filterpat = STRDUP (Xarg); - - rval = EXECUTION_FAILURE; - - /* probably don't have to save these, just being safe */ - old_line = pcomp_line; - old_ind = pcomp_ind; - pcomp_line = (char *)NULL; - pcomp_ind = 0; - sl = gen_compspec_completions (cs, "compgen", word, 0, 0, 0); - pcomp_line = old_line; - pcomp_ind = old_ind; - - /* If the compspec wants the bash default completions, temporarily - turn off programmable completion and call the bash completion code. */ - if ((sl == 0 || sl->list_len == 0) && (copts & COPT_BASHDEFAULT)) - { - matches = bash_default_completion (word, 0, 0, 0, 0); - sl = completions_to_stringlist (matches); - strvec_dispose (matches); - } - - /* This isn't perfect, but it's the best we can do, given what readline - exports from its set of completion utility functions. */ - if ((sl == 0 || sl->list_len == 0) && (copts & COPT_DEFAULT)) - { - matches = rl_completion_matches (word, rl_filename_completion_function); - strlist_dispose (sl); - sl = completions_to_stringlist (matches); - strvec_dispose (matches); - } - - if (sl) - { - if (sl->list && sl->list_len) - { - rval = EXECUTION_SUCCESS; - strlist_print (sl, (char *)NULL); - } - strlist_dispose (sl); - } - - compspec_dispose (cs); - return (rval); -} - -#line 788 "./complete.def" - -int -compopt_builtin (list) - WORD_LIST *list; -{ - int opts_on, opts_off, *opts, opt, oind, ret, Dflag, Eflag, Iflag; - WORD_LIST *l, *wl; - COMPSPEC *cs; - - opts_on = opts_off = Eflag = Dflag = Iflag = 0; - ret = EXECUTION_SUCCESS; - - reset_internal_getopt (); - while ((opt = internal_getopt (list, "+o:DEI")) != -1) - { - opts = (list_opttype == '-') ? &opts_on : &opts_off; - - switch (opt) - { - case 'o': - oind = find_compopt (list_optarg); - if (oind < 0) - { - sh_invalidoptname (list_optarg); - return (EX_USAGE); - } - *opts |= compopts[oind].optflag; - break; - case 'D': - Dflag = 1; - break; - case 'E': - Eflag = 1; - break; - case 'I': - Iflag = 1; - break; - CASE_HELPOPT; - default: - builtin_usage (); - return (EX_USAGE); - } - } - list = loptend; - - if (Dflag) - wl = make_word_list (make_bare_word (DEFAULTCMD), (WORD_LIST *)NULL); - else if (Eflag) - wl = make_word_list (make_bare_word (EMPTYCMD), (WORD_LIST *)NULL); - else if (Iflag) - wl = make_word_list (make_bare_word (INITIALWORD), (WORD_LIST *)NULL); - else - wl = (WORD_LIST *)NULL; - - if (list == 0 && wl == 0) - { - if (RL_ISSTATE (RL_STATE_COMPLETING) == 0 || pcomp_curcs == 0) - { - builtin_error (_("not currently executing completion function")); - return (EXECUTION_FAILURE); - } - cs = pcomp_curcs; - - if (opts_on == 0 && opts_off == 0) - { - print_compopts (pcomp_curcmd, cs, 1); - return (sh_chkwrite (ret)); - } - - /* Set the compspec options */ - pcomp_set_compspec_options (cs, opts_on, 1); - pcomp_set_compspec_options (cs, opts_off, 0); - - /* And change the readline variables the options control */ - pcomp_set_readline_variables (opts_on, 1); - pcomp_set_readline_variables (opts_off, 0); - - return (ret); - } - - for (l = wl ? wl : list; l; l = l->next) - { - cs = progcomp_search (l->word->word); - if (cs == 0) - { - builtin_error (_("%s: no completion specification"), l->word->word); - ret = EXECUTION_FAILURE; - continue; - } - if (opts_on == 0 && opts_off == 0) - { - print_compopts (l->word->word, cs, 1); - continue; /* XXX -- fill in later */ - } - - /* Set the compspec options */ - pcomp_set_compspec_options (cs, opts_on, 1); - pcomp_set_compspec_options (cs, opts_off, 0); - } - - if (wl) - dispose_words (wl); - - return (ret); -} diff --git a/third_party/bash/builtins_declare.c b/third_party/bash/builtins_declare.c deleted file mode 100644 index 77f9f8e35..000000000 --- a/third_party/bash/builtins_declare.c +++ /dev/null @@ -1,969 +0,0 @@ -/* declare.c, created from declare.def. */ -#line 22 "./declare.def" - -#line 64 "./declare.def" - -#line 72 "./declare.def" - -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include - -#include "bashansi.h" -#include "bashintl.h" - -#include "shell.h" -#include "flags.h" -#include "common.h" -#include "builtext.h" -#include "bashgetopt.h" - -static SHELL_VAR *declare_find_variable PARAMS((const char *, int, int)); -static char *declare_build_newname PARAMS((char *, char *, int, char *, int)); -static char *declare_transform_name PARAMS((char *, int, int)); - -static int declare_internal PARAMS((register WORD_LIST *, int)); - -/* Declare or change variable attributes. */ -int -declare_builtin (list) - register WORD_LIST *list; -{ - return (declare_internal (list, 0)); -} - -#line 122 "./declare.def" -int -local_builtin (list) - register WORD_LIST *list; -{ - /* Catch a straight `local --help' before checking function context */ - if (list && list->word && STREQ (list->word->word, "--help")) - { - builtin_help (); - return (EX_USAGE); - } - - if (variable_context) - return (declare_internal (list, 1)); - else - { - builtin_error (_("can only be used in a function")); - return (EXECUTION_FAILURE); - } -} - -#if defined (ARRAY_VARS) -# define DECLARE_OPTS "+acfgilnprtuxAFGI" -#else -# define DECLARE_OPTS "+cfgilnprtuxFGI" -#endif - -static SHELL_VAR * -declare_find_variable (name, mkglobal, chklocal) - const char *name; - int mkglobal, chklocal; -{ - SHELL_VAR *var; - - if (mkglobal == 0) - return (find_variable (name)); - else if (chklocal) - { - var = find_variable (name); - if (var && local_p (var) && var->context == variable_context) - return var; - return (find_global_variable (name)); - } - else - return (find_global_variable (name)); -} - -/* Build a new string - NAME[SUBSCRIPT][[+]=VALUE] - from expanding a nameref into NAME */ -static char * -declare_build_newname (name, subscript_start, offset, value, aflags) - char *name, *subscript_start; - int offset; - char *value; - int aflags; -{ - size_t namelen, savelen; - char *ret; - - savelen = namelen = strlen (name); - if (subscript_start) - { - *subscript_start = '['; /* ] */ - namelen += strlen (subscript_start); - } - ret = xmalloc (namelen + 2 + strlen (value) + 1); - strcpy (ret, name); - if (subscript_start) - strcpy (ret + savelen, subscript_start); - if (offset) - { - if (aflags & ASS_APPEND) - ret[namelen++] = '+'; - ret[namelen++] = '='; - if (value && *value) - strcpy (ret + namelen, value); - else - ret[namelen] = '\0'; - } - - return (ret); -} - -static char * -declare_transform_name (name, flags_on, flags_off) - char *name; - int flags_on, flags_off; -{ - SHELL_VAR *var, *v; - char *newname; - - var = find_variable (name); - if (var == 0) - newname = nameref_transform_name (name, ASS_MKLOCAL); - else if ((flags_on & att_nameref) == 0 && (flags_off & att_nameref) == 0) - { - /* Ok, we're following namerefs here, so let's make sure that if - we followed one, it was at the same context (see below for - more details). */ - v = find_variable_last_nameref (name, 1); - newname = (v && v->context != variable_context) ? name : name_cell (var); - } - else - newname = name; /* dealing with nameref attribute */ - - return (newname); -} - -/* The workhorse function. */ -static int -declare_internal (list, local_var) - register WORD_LIST *list; - int local_var; -{ - int flags_on, flags_off, *flags; - int any_failed, assign_error, pflag, nodefs, opt, onref, offref; - int mkglobal, chklocal, inherit_flag; - char *t, *subscript_start; - SHELL_VAR *var, *refvar, *v; - FUNCTION_DEF *shell_fn; - - flags_on = flags_off = any_failed = assign_error = pflag = nodefs = 0; - mkglobal = chklocal = inherit_flag = 0; - refvar = (SHELL_VAR *)NULL; - reset_internal_getopt (); - while ((opt = internal_getopt (list, DECLARE_OPTS)) != -1) - { - flags = list_opttype == '+' ? &flags_off : &flags_on; - - /* If you add options here, see whether or not they need to be added to - the loop in subst.c:shell_expand_word_list() */ - switch (opt) - { - case 'a': -#if defined (ARRAY_VARS) - *flags |= att_array; - break; -#else - builtin_usage (); - return (EX_USAGE); -#endif - case 'A': -#if defined (ARRAY_VARS) - *flags |= att_assoc; - break; -#else - builtin_usage (); - return (EX_USAGE); -#endif - case 'p': - pflag++; - break; - case 'F': - nodefs++; - *flags |= att_function; - break; - case 'f': - *flags |= att_function; - break; - case 'G': - if (flags == &flags_on) - chklocal = 1; - /*FALLTHROUGH*/ - case 'g': - if (flags == &flags_on) - mkglobal = 1; - break; - case 'i': - *flags |= att_integer; - break; - case 'n': - *flags |= att_nameref; - break; - case 'r': - *flags |= att_readonly; - break; - case 't': - *flags |= att_trace; - break; - case 'x': - *flags |= att_exported; - array_needs_making = 1; - break; -#if defined (CASEMOD_ATTRS) -# if defined (CASEMOD_CAPCASE) - case 'c': - *flags |= att_capcase; - if (flags == &flags_on) - flags_off |= att_uppercase|att_lowercase; - break; -# endif - case 'l': - *flags |= att_lowercase; - if (flags == &flags_on) - flags_off |= att_capcase|att_uppercase; - break; - case 'u': - *flags |= att_uppercase; - if (flags == &flags_on) - flags_off |= att_capcase|att_lowercase; - break; -#endif /* CASEMOD_ATTRS */ - case 'I': - inherit_flag = MKLOC_INHERIT; - break; - CASE_HELPOPT; - default: - builtin_usage (); - return (EX_USAGE); - } - } - - list = loptend; - - /* If there are no more arguments left, then we just want to show - some variables. */ - if (list == 0) /* declare -[aAfFilnrtux] */ - { - /* Show local variables defined at this context level if this is - the `local' builtin. */ - if (local_var) - show_local_var_attributes (0, nodefs); /* XXX - fix up args later */ - else if (pflag && (flags_on == 0 || flags_on == att_function)) - show_all_var_attributes (flags_on == 0, nodefs); - else if (flags_on == 0) - return (set_builtin ((WORD_LIST *)NULL)); - else - set_or_show_attributes ((WORD_LIST *)NULL, flags_on, nodefs); - - return (sh_chkwrite (EXECUTION_SUCCESS)); - } - - if (pflag) /* declare -p [-aAfFilnrtux] [name ...] */ - { - for (any_failed = 0; list; list = list->next) - { - if (flags_on & att_function) - pflag = show_func_attributes (list->word->word, nodefs); - else if (local_var) - pflag = show_localname_attributes (list->word->word, nodefs); - else - pflag = show_name_attributes (list->word->word, nodefs); - if (pflag) - { - sh_notfound (list->word->word); - any_failed++; - } - } - return (sh_chkwrite (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS)); - } - - /* Some option combinations that don't make any sense */ - if ((flags_on & att_function) && (flags_on & (att_array|att_assoc|att_integer|att_nameref))) - { - char *optchar; - - if (flags_on & att_nameref) - optchar = "-n"; - else if (flags_on & att_integer) - optchar = "-i"; - else if (flags_on & att_assoc) - optchar = "-A"; - else if (flags_on & att_array) - optchar = "-a"; - - sh_invalidopt (optchar); - return (EXECUTION_FAILURE); - } - -#define NEXT_VARIABLE() free (name); list = list->next; continue - - /* There are arguments left, so we are making variables. */ - while (list) /* declare [-aAfFilnrtux] name[=value] [name[=value] ...] */ - { - char *value, *name, *newname; - int offset, aflags, wflags, created_var; - int assoc_noexpand; -#if defined (ARRAY_VARS) - int making_array_special, compound_array_assign, simple_array_assign; - int var_exists, array_exists, creating_array, array_subscript_assignment; -#endif - - name = savestring (list->word->word); - wflags = list->word->flags; -#if defined (ARRAY_VARS) - assoc_noexpand = assoc_expand_once && (wflags & W_ASSIGNMENT); -#else - assoc_noexpand = 0; -#endif - /* XXX - we allow unbalanced brackets if assoc_noexpand is set, we count - brackets and make sure they match if assoc_noexpand is not set. So we - need to make sure we're checking assoc_noexpand and expand_once_flag - for backwards compatibility. We also use assoc_noexpand below when - we call assign_array_element, so we need to make sure they're - consistent in how they count brackets. */ - offset = assignment (name, assoc_noexpand ? 2 : 0); - aflags = 0; - created_var = 0; - - if (local_var && variable_context && STREQ (name, "-")) - { - var = make_local_variable ("-", 0); - FREE (value_cell (var)); /* just in case */ - value = get_current_options (); - var_setvalue (var, value); - VSETATTR (var, att_invisible); - NEXT_VARIABLE (); - } - - /* If we are declaring a function, then complain about it in some way. - We don't let people make functions by saying `typeset -f foo=bar'. */ - - /* Can't define functions using assignment statements */ - if (offset && (flags_on & att_function)) /* declare -f [-rix] foo=bar */ - { - builtin_error (_("cannot use `-f' to make functions")); - free (name); - return (EXECUTION_FAILURE); - } - - /* There should be a way, however, to let people look at a particular - function definition by saying `typeset -f foo'. This is the only - place in this builtin where we deal with functions. */ - - if (flags_on & att_function) - { - /* Should we restrict this when the shell is in posix mode even if - the function was created before the shell entered posix mode? - Previous versions of the shell enforced the restriction. */ - if (posixly_correct && legal_identifier (name) == 0) - { - sh_invalidid (name); - assign_error++; - NEXT_VARIABLE (); - } - - var = find_function (name); - - if (var) - { - if (readonly_p (var) && (flags_off & att_readonly)) - { - builtin_error (_("%s: readonly function"), name); - any_failed++; - NEXT_VARIABLE (); - } - /* declare -[Ff] name [name...] */ - if (flags_on == att_function && flags_off == 0) - { -#if defined (DEBUGGER) - if (nodefs && debugging_mode) - { - shell_fn = find_function_def (name_cell (var)); - if (shell_fn) - printf ("%s %d %s\n", name_cell (var), shell_fn->line, shell_fn->source_file); - else - printf ("%s\n", name_cell (var)); - } - else -#endif /* DEBUGGER */ - { - t = nodefs ? name_cell (var) : named_function_string (name, function_cell (var), FUNC_MULTILINE|FUNC_EXTERNAL); - printf ("%s\n", t); - any_failed = sh_chkwrite (any_failed); - } - } - else /* declare -[fF] -[rx] name [name...] */ - { - VSETATTR (var, flags_on); - flags_off &= ~att_function; /* makes no sense */ - VUNSETATTR (var, flags_off); - } - } - else - any_failed++; - - NEXT_VARIABLE (); - } - - if (offset) /* declare [-aAfFirx] name=value */ - { - name[offset] = '\0'; - value = name + offset + 1; - if (name[offset - 1] == '+') - { - aflags |= ASS_APPEND; - name[offset - 1] = '\0'; - } - } - else - value = ""; - - /* Do some lexical error checking on the LHS and RHS of the assignment - that is specific to nameref variables. */ - if (flags_on & att_nameref) - { -#if defined (ARRAY_VARS) - if (valid_array_reference (name, 0)) - { - builtin_error (_("%s: reference variable cannot be an array"), name); - any_failed++; - NEXT_VARIABLE (); - } - else -#endif - /* disallow self references at global scope, warn at function scope */ - if (check_selfref (name, value, 0)) - { - if (variable_context == 0) - { - builtin_error (_("%s: nameref variable self references not allowed"), name); - assign_error++; /* XXX any_failed++ instead? */ - NEXT_VARIABLE (); - } - else - builtin_warning (_("%s: circular name reference"), name); - } - if (value && *value && (aflags & ASS_APPEND) == 0 && valid_nameref_value (value, 1) == 0) - { - builtin_error (_("`%s': invalid variable name for name reference"), value); - assign_error++; - NEXT_VARIABLE (); - } - } - -restart_new_var_name: - - /* The rest of the loop body deals with declare -[aAlinrtux] name [name...] - where each NAME can be an assignment statement. */ - - subscript_start = (char *)NULL; /* used below */ -#if defined (ARRAY_VARS) - /* Determine whether we are creating or assigning an array variable */ - var_exists = array_exists = creating_array = 0; - compound_array_assign = simple_array_assign = 0; - array_subscript_assignment = 0; - if (t = strchr (name, '[')) /* ] */ - { - /* If offset != 0 we have already validated any array reference - because assignment() calls skipsubscript() */ - if (offset == 0 && valid_array_reference (name, 0) == 0) - { - sh_invalidid (name); - assign_error++; - NEXT_VARIABLE (); - } - subscript_start = t; - *t = '\0'; - making_array_special = 1; /* XXX - should this check offset? */ - array_subscript_assignment = offset != 0; - } - else - making_array_special = 0; -#endif - - /* Ensure the argument is a valid, well-formed shell identifier. */ - if (legal_identifier (name) == 0) - { - sh_invalidid (name); - assign_error++; - NEXT_VARIABLE (); - } - - /* If VARIABLE_CONTEXT has a non-zero value, then we are executing - inside of a function. This means we should make local variables, - not global ones. */ - - /* XXX - this has consequences when we're making a local copy of a - variable that was in the temporary environment. Watch out - for this. */ - refvar = (SHELL_VAR *)NULL; - if (variable_context && mkglobal == 0) - { - /* We don't check newname for validity here. We should not have an - invalid name assigned as the value of a nameref, but this could - cause problems. */ - newname = declare_transform_name (name, flags_on, flags_off); - -#if defined (ARRAY_VARS) - /* Pass 1 as second argument to make_local_{assoc,array}_variable - return an existing {array,assoc} variable to be flagged as an - error below. */ - if (flags_on & att_assoc) - var = make_local_assoc_variable (newname, MKLOC_ARRAYOK|inherit_flag); - else if ((flags_on & att_array) || making_array_special) - var = make_local_array_variable (newname, MKLOC_ASSOCOK|inherit_flag); - else -#endif - if (offset == 0 && (flags_on & att_nameref)) - { - /* First look for refvar at current scope */ - refvar = find_variable_last_nameref (name, 1); - /* VARIABLE_CONTEXT != 0, so we are attempting to create or modify - the attributes for a local variable at the same scope. If we've - used a reference from a previous context to resolve VAR, we - want to throw REFVAR and VAR away and create a new local var. */ - if (refvar && refvar->context != variable_context) - { - refvar = 0; - var = make_local_variable (name, inherit_flag); - } - else if (refvar && refvar->context == variable_context) - var = refvar; - /* Maybe we just want to create a new local variable */ - else if ((var = find_variable (name)) == 0 || var->context != variable_context) - var = make_local_variable (name, inherit_flag); - /* otherwise we have a var at the right context */ - } - else - /* XXX - check name for validity here with valid_nameref_value? */ - var = make_local_variable ((flags_on & att_nameref) ? name : newname, inherit_flag); /* sets att_invisible for new vars */ - - if (var == 0) - { - any_failed++; - NEXT_VARIABLE (); - } - if (var && nameref_p (var) && readonly_p (var) && nameref_cell (var) && (flags_off & att_nameref)) - { - sh_readonly (name); - any_failed++; - NEXT_VARIABLE (); - } - } - else - var = (SHELL_VAR *)NULL; - - /* VAR is non-null if we just created or fetched a local variable. */ - - /* Here's what ksh93 seems to do as of the 2012 version: if we are - using declare -n to modify the value of an existing nameref - variable, don't follow the nameref chain at all and just search - for a nameref at the current context. If we have a nameref, - modify its value (changing which variable it references). */ - if (var == 0 && (flags_on & att_nameref)) - { - /* See if we are trying to modify an existing nameref variable, - but don't follow the nameref chain. */ - var = mkglobal ? find_global_variable_noref (name) : find_variable_noref (name); - if (var && nameref_p (var) == 0) - var = 0; - } - - /* However, if we're turning off the nameref attribute on an existing - nameref variable, we first follow the nameref chain to the end, - modify the value of the variable this nameref variable references - if there is an assignment statement argument, - *CHANGING ITS VALUE AS A SIDE EFFECT*, then turn off the nameref - flag *LEAVING THE NAMEREF VARIABLE'S VALUE UNCHANGED* */ - else if (var == 0 && (flags_off & att_nameref)) - { - /* See if we are trying to modify an existing nameref variable */ - refvar = mkglobal ? find_global_variable_last_nameref (name, 0) : find_variable_last_nameref (name, 0); - if (refvar && nameref_p (refvar) == 0) - refvar = 0; - /* If the nameref is readonly but doesn't have a value, ksh93 - allows the nameref attribute to be removed. If it's readonly - and has a value, even if the value doesn't reference an - existing variable, we disallow the modification */ - if (refvar && nameref_cell (refvar) && readonly_p (refvar)) - { - sh_readonly (name); - any_failed++; - NEXT_VARIABLE (); - } - - /* If all we're doing is turning off the nameref attribute, don't - bother with VAR at all, whether it exists or not. Just turn it - off and go on. */ - if (refvar && flags_on == 0 && offset == 0 && flags_off == att_nameref) - { - VUNSETATTR (refvar, att_nameref); - NEXT_VARIABLE (); - } - - if (refvar) - var = declare_find_variable (nameref_cell (refvar), mkglobal, 0); - } -#if defined (ARRAY_VARS) - /* If we have an array assignment to a nameref, remove the nameref - attribute and go on. This handles - declare -n xref[=value]; declare [-a] xref[1]=one */ - else if (var == 0 && offset && array_subscript_assignment) - { - var = mkglobal ? find_global_variable_noref (name) : find_variable_noref (name); - if (var && nameref_p (var)) - { - internal_warning (_("%s: removing nameref attribute"), name); - FREE (value_cell (var)); /* XXX - bash-4.3 compat */ - var_setvalue (var, (char *)NULL); - VUNSETATTR (var, att_nameref); - } - } -#endif - - /* See if we are trying to set flags or value (or create) for an - existing nameref that points to a non-existent variable: e.g., - declare -n foo=bar - unset foo # unsets bar - declare -i foo - foo=4+4 - declare -p foo - */ - if (var == 0 && (mkglobal || flags_on || flags_off || offset)) - { - refvar = mkglobal ? find_global_variable_last_nameref (name, 0) : find_variable_last_nameref (name, 0); - if (refvar && nameref_p (refvar) == 0) - refvar = 0; - if (refvar) - var = declare_find_variable (nameref_cell (refvar), mkglobal, 0); - if (refvar && var == 0) - { - /* I'm not sure subscript_start is ever non-null here. In any - event, build a new name from the nameref value, including any - subscript, and add the [[+]=value] if offset != 0 */ - newname = declare_build_newname (nameref_cell (refvar), subscript_start, offset, value, aflags); - free (name); - name = newname; - - if (offset) - { - offset = assignment (name, 0); - /* If offset was valid previously, but substituting the - the nameref value results in an invalid assignment, - throw an invalid identifier error */ - if (offset == 0) - { - sh_invalidid (name); - assign_error++; - NEXT_VARIABLE (); - } - name[(aflags & ASS_APPEND) ? offset - 1 : offset] = '\0'; - value = name + offset + 1; - } - - /* OK, let's turn off the nameref attribute. - Now everything else applies to VAR. */ - if (flags_off & att_nameref) - VUNSETATTR (refvar, att_nameref); - - goto restart_new_var_name; - /* NOTREACHED */ - } - } - if (var == 0) - var = declare_find_variable (name, mkglobal, chklocal); - - /* At this point, VAR is the variable we are dealing with; REFVAR is the - nameref variable we dereferenced to get VAR, if any. */ -#if defined (ARRAY_VARS) - var_exists = var != 0; - array_exists = var && (array_p (var) || assoc_p (var)); - creating_array = flags_on & (att_array|att_assoc); -#endif - - /* Make a new variable if we need to. */ - if (var == 0) - { -#if defined (ARRAY_VARS) - if (flags_on & att_assoc) - var = make_new_assoc_variable (name); - else if ((flags_on & att_array) || making_array_special) - var = make_new_array_variable (name); - else -#endif - var = mkglobal ? bind_global_variable (name, (char *)NULL, ASS_FORCE) : bind_variable (name, (char *)NULL, ASS_FORCE); - - if (var == 0) - { - /* Has to appear in brackets */ - NEXT_VARIABLE (); - } - if (offset == 0) - VSETATTR (var, att_invisible); - created_var = 1; - } - - /* Nameref variable error checking. */ - - /* Can't take an existing array variable and make it a nameref */ - else if ((array_p (var) || assoc_p (var)) && (flags_on & att_nameref)) - { - builtin_error (_("%s: reference variable cannot be an array"), name); - any_failed++; - NEXT_VARIABLE (); - } - /* Can't have an invalid identifier as nameref value */ - else if (nameref_p (var) && (flags_on & att_nameref) == 0 && (flags_off & att_nameref) == 0 && offset && valid_nameref_value (value, 1) == 0) - { - builtin_error (_("`%s': invalid variable name for name reference"), value); - any_failed++; - NEXT_VARIABLE (); - } - /* Can't make an existing variable a nameref if its current value is not - a valid identifier. Check of offset is to allow an assignment to a - nameref var as part of the declare word to override existing value. */ - else if ((flags_on & att_nameref) && nameref_p (var) == 0 && var_isset (var) && offset == 0 && valid_nameref_value (value_cell (var), 0) == 0) - { - builtin_error (_("`%s': invalid variable name for name reference"), value_cell (var)); - any_failed++; - NEXT_VARIABLE (); - } - /* Can't make an existing readonly variable a nameref. */ - else if ((flags_on & att_nameref) && readonly_p (var)) - { - sh_readonly (name); - any_failed++; - NEXT_VARIABLE (); - } - - /* Readonly variable error checking. */ - - /* Cannot use declare +r to turn off readonly attribute. */ - if (readonly_p (var) && (flags_off & att_readonly)) - { - sh_readonly (name_cell (var)); - any_failed++; - NEXT_VARIABLE (); - } - /* Cannot use declare to assign value to readonly or noassign variable. */ - else if ((readonly_p (var) || noassign_p (var)) && offset) - { - if (readonly_p (var)) - sh_readonly (name); - assign_error++; - NEXT_VARIABLE (); - } - -#if defined (ARRAY_VARS) - /* Array variable error checking. */ - - /* Cannot use declare +a name or declare +A name to remove an array variable. */ - if (((flags_off & att_array) && array_p (var)) || ((flags_off & att_assoc) && assoc_p (var))) - { - builtin_error (_("%s: cannot destroy array variables in this way"), name); - any_failed++; - NEXT_VARIABLE (); - } - else if ((flags_on & att_array) && assoc_p (var)) - { - builtin_error (_("%s: cannot convert associative to indexed array"), name); - any_failed++; - NEXT_VARIABLE (); - } - else if ((flags_on & att_assoc) && array_p (var)) - { - builtin_error (_("%s: cannot convert indexed to associative array"), name); - any_failed++; - NEXT_VARIABLE (); - } - - /* make declare A[2]=foo as similar to A[2]=foo as possible if A is - already an array or assoc variable. */ - if (array_subscript_assignment && array_exists && creating_array == 0) - simple_array_assign = 1; - else if ((making_array_special || creating_array || array_exists) && offset) - { - int vlen; - vlen = STRLEN (value); -/*itrace("declare_builtin: name = %s value = %s flags = %d", name, value, wflags);*/ - - if (shell_compatibility_level > 43 && (wflags & W_COMPASSIGN) == 0 && - value[0] == '(' && value[vlen-1] == ')') - { - /* I don't believe this warning is printed any more. - We use creating_array to allow things like - declare -a foo$bar='(abc)' - to work as they have in the past. */ - if (array_exists == 0 && creating_array == 0) - internal_warning (_("%s: quoted compound array assignment deprecated"), list->word->word); - compound_array_assign = array_exists || creating_array; - simple_array_assign = making_array_special; - } - else if (value[0] == '(' && value[vlen-1] == ')' && (shell_compatibility_level < 44 || (wflags & W_COMPASSIGN))) - compound_array_assign = 1; - else - simple_array_assign = 1; - } - - /* declare -A name[[n]] makes name an associative array variable. */ - if (flags_on & att_assoc) - { - if (assoc_p (var) == 0) - var = convert_var_to_assoc (var); - } - /* declare -a name[[n]] or declare name[n] makes NAME an indexed - array variable. */ - else if ((making_array_special || (flags_on & att_array)) && array_p (var) == 0 && assoc_p (var) == 0) - var = convert_var_to_array (var); -#endif /* ARRAY_VARS */ - - /* ksh93 compat: turning on nameref attribute turns off -ilu */ - if (flags_on & att_nameref) - VUNSETATTR (var, att_integer|att_uppercase|att_lowercase|att_capcase); - - /* XXX - we note that we are turning on nameref attribute and defer - setting it until the assignment has been made so we don't do an - inadvertent nameref lookup. Might have to do the same thing for - flags_off&att_nameref. */ - /* XXX - ksh93 makes it an error to set a readonly nameref variable - using a single typeset command. */ - onref = (flags_on & att_nameref); - flags_on &= ~att_nameref; -#if defined (ARRAY_VARS) - /* I don't believe this condition ever tests true, but array variables - may not be namerefs */ - if (array_p (var) || assoc_p (var) || compound_array_assign || simple_array_assign) - onref = 0; -#endif - - /* ksh93 seems to do this */ - offref = (flags_off & att_nameref); - flags_off &= ~att_nameref; - - VSETATTR (var, flags_on); - VUNSETATTR (var, flags_off); - -#if defined (ARRAY_VARS) - if (offset && compound_array_assign) - assign_array_var_from_string (var, value, aflags|ASS_FORCE); - else if (simple_array_assign && subscript_start) - { - int local_aflags; - - /* declare [-aA] name[N]=value */ - *subscript_start = '['; /* ] */ - /* XXX - problem here with appending */ - local_aflags = aflags&ASS_APPEND; - local_aflags |= assoc_noexpand ? ASS_NOEXPAND : 0; - local_aflags |= ASS_ALLOWALLSUB; /* allow declare a[@]=at */ - var = assign_array_element (name, value, local_aflags, (array_eltstate_t *)0); /* XXX - not aflags */ - *subscript_start = '\0'; - if (var == 0) /* some kind of assignment error */ - { - assign_error++; - flags_on |= onref; - flags_off |= offref; - NEXT_VARIABLE (); - } - } - else if (simple_array_assign) - { - /* let bind_{array,assoc}_variable take care of this. */ - if (assoc_p (var)) - bind_assoc_variable (var, name, savestring ("0"), value, aflags|ASS_FORCE); - else - bind_array_variable (name, 0, value, aflags|ASS_FORCE); - } - else -#endif - /* XXX - no ASS_FORCE here */ - /* bind_variable_value duplicates the essential internals of bind_variable() */ - if (offset) - { - if (onref || nameref_p (var)) - aflags |= ASS_NAMEREF; - v = bind_variable_value (var, value, aflags); - if (v == 0 && (onref || nameref_p (var))) - { - if (valid_nameref_value (value, 1) == 0) - sh_invalidid (value); - assign_error++; - /* XXX - unset this variable? or leave it as normal var? */ - if (created_var) - delete_var (name_cell (var), mkglobal ? global_variables : shell_variables); - flags_on |= onref; /* undo change from above */ - flags_off |= offref; - NEXT_VARIABLE (); - } - } - - /* If we found this variable in the temporary environment, as with - `var=value declare -x var', make sure it is treated identically - to `var=value export var'. Do the same for `declare -r' and - `readonly'. Preserve the attributes, except for att_tempvar. */ - /* XXX -- should this create a variable in the global scope, or - modify the local variable flags? ksh93 has it modify the - global scope. - Need to handle case like in set_var_attribute where a temporary - variable is in the same table as the function local vars. */ - if ((flags_on & (att_exported|att_readonly)) && tempvar_p (var)) - { - SHELL_VAR *tv; - char *tvalue; - - tv = find_tempenv_variable (name_cell (var)); - if (tv) - { - tvalue = var_isset (var) ? savestring (value_cell (var)) : savestring (""); - tv = bind_variable (name_cell (var), tvalue, 0); - if (tv) - { - tv->attributes |= var->attributes & ~att_tempvar; - if (tv->context > 0) - VSETATTR (tv, att_propagate); - } - free (tvalue); - } - VSETATTR (var, att_propagate); - } - - /* Turn on nameref attribute we deferred above. */ - VSETATTR (var, onref); - flags_on |= onref; - VUNSETATTR (var, offref); - flags_off |= offref; - - /* Yuck. ksh93 compatibility. XXX - need to investigate more but - definitely happens when turning off nameref attribute on nameref - (see comments above). Under no circumstances allow this to turn - off readonly attribute on readonly nameref variable. */ - if (refvar) - { - if (flags_off & att_readonly) - flags_off &= ~att_readonly; - VUNSETATTR (refvar, flags_off); - } - - stupidly_hack_special_variables (name); - - NEXT_VARIABLE (); - } - - return (assign_error ? EX_BADASSIGN - : ((any_failed == 0) ? EXECUTION_SUCCESS - : EXECUTION_FAILURE)); -} diff --git a/third_party/bash/builtins_echo.c b/third_party/bash/builtins_echo.c deleted file mode 100644 index 957d2e34c..000000000 --- a/third_party/bash/builtins_echo.c +++ /dev/null @@ -1,133 +0,0 @@ -/* echo.c, created from echo.def. */ -#line 22 "./echo.def" -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "bashansi.h" - -#include -#include "shell.h" - -#include "common.h" - -#line 73 "./echo.def" - -#line 88 "./echo.def" - -#if defined (V9_ECHO) -# define VALID_ECHO_OPTIONS "neE" -#else /* !V9_ECHO */ -# define VALID_ECHO_OPTIONS "n" -#endif /* !V9_ECHO */ - -/* System V machines already have a /bin/sh with a v9 behaviour. We - give Bash the identical behaviour for these machines so that the - existing system shells won't barf. Regrettably, the SUS v2 has - standardized the Sys V echo behavior. This variable is external - so that we can have a `shopt' variable to control it at runtime. */ -#if defined (DEFAULT_ECHO_TO_XPG) || defined (STRICT_POSIX) -int xpg_echo = 1; -#else -int xpg_echo = 0; -#endif /* DEFAULT_ECHO_TO_XPG */ - -/* Print the words in LIST to standard output. If the first word is - `-n', then don't print a trailing newline. We also support the - echo syntax from Version 9 Unix systems. */ -int -echo_builtin (list) - WORD_LIST *list; -{ - int display_return, do_v9, i, len; - char *temp, *s; - - do_v9 = xpg_echo; - display_return = 1; - - if (posixly_correct && xpg_echo) - goto just_echo; - - for (; list && (temp = list->word->word) && *temp == '-'; list = list->next) - { - /* If it appears that we are handling options, then make sure that - all of the options specified are actually valid. Otherwise, the - string should just be echoed. */ - temp++; - - for (i = 0; temp[i]; i++) - { - if (strchr (VALID_ECHO_OPTIONS, temp[i]) == 0) - break; - } - - /* echo - and echo - both mean to just echo the arguments. */ - if (*temp == 0 || temp[i]) - break; - - /* All of the options in TEMP are valid options to ECHO. - Handle them. */ - while (i = *temp++) - { - switch (i) - { - case 'n': - display_return = 0; - break; -#if defined (V9_ECHO) - case 'e': - do_v9 = 1; - break; - case 'E': - do_v9 = 0; - break; -#endif /* V9_ECHO */ - default: - goto just_echo; /* XXX */ - } - } - } - -just_echo: - - clearerr (stdout); /* clear error before writing and testing success */ - - while (list) - { - i = len = 0; - temp = do_v9 ? ansicstr (list->word->word, STRLEN (list->word->word), 1, &i, &len) - : list->word->word; - if (temp) - { - if (do_v9) - { - for (s = temp; len > 0; len--) - putchar (*s++); - } - else - printf ("%s", temp); -#if defined (SunOS5) - fflush (stdout); /* Fix for bug in SunOS 5.5 printf(3) */ -#endif - } - QUIT; - if (do_v9 && temp) - free (temp); - list = list->next; - if (i) - { - display_return = 0; - break; - } - if (list) - putchar(' '); - QUIT; - } - - if (display_return) - putchar ('\n'); - - return (sh_chkwrite (EXECUTION_SUCCESS)); -} diff --git a/third_party/bash/builtins_enable.c b/third_party/bash/builtins_enable.c deleted file mode 100644 index 6edacda69..000000000 --- a/third_party/bash/builtins_enable.c +++ /dev/null @@ -1,541 +0,0 @@ -/* enable.c, created from enable.def. */ -#line 22 "./enable.def" - -#line 50 "./enable.def" - -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include -#include "bashansi.h" -#include "bashintl.h" - -#include "shell.h" -#include "builtins.h" -#include "flags.h" -#include "common.h" -#include "bashgetopt.h" -#include "findcmd.h" - -#if defined (PROGRAMMABLE_COMPLETION) -# include "pcomplete.h" -#endif - -#define ENABLED 1 -#define DISABLED 2 -#define SPECIAL 4 -#define SILENT 8 /* affects dyn_load_builtin behavior */ - -#define AFLAG 0x01 -#define DFLAG 0x02 -#define FFLAG 0x04 -#define NFLAG 0x08 -#define PFLAG 0x10 -#define SFLAG 0x20 - -#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM) -static int dyn_load_builtin PARAMS((WORD_LIST *, int, char *)); -#endif - -#if defined (HAVE_DLCLOSE) -static int dyn_unload_builtin PARAMS((char *)); -static void delete_builtin PARAMS((struct builtin *)); -static int local_dlclose PARAMS((void *)); -#endif - -#define STRUCT_SUFFIX "_struct" -/* for now */ -#define LOAD_SUFFIX "_builtin_load" -#define UNLOAD_SUFFIX "_builtin_unload" - -static void list_some_builtins PARAMS((int)); -static int enable_shell_command PARAMS((char *, int)); - -/* Enable/disable shell commands present in LIST. If list is not specified, - then print out a list of shell commands showing which are enabled and - which are disabled. */ -int -enable_builtin (list) - WORD_LIST *list; -{ - int result, flags; - int opt, filter; - WORD_LIST *next; -#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM) - char *filename; -#endif - - result = EXECUTION_SUCCESS; - flags = 0; - - reset_internal_getopt (); - while ((opt = internal_getopt (list, "adnpsf:")) != -1) - { - switch (opt) - { - case 'a': - flags |= AFLAG; - break; - case 'n': - flags |= NFLAG; - break; - case 'p': - flags |= PFLAG; - break; - case 's': - flags |= SFLAG; - break; - case 'f': -#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM) - flags |= FFLAG; - filename = list_optarg; - break; -#else - builtin_error (_("dynamic loading not available")); - return (EX_USAGE); -#endif -#if defined (HAVE_DLCLOSE) - case 'd': - flags |= DFLAG; - break; -#else - builtin_error (_("dynamic loading not available")); - return (EX_USAGE); -#endif /* HAVE_DLCLOSE */ - CASE_HELPOPT; - default: - builtin_usage (); - return (EX_USAGE); - } - } - - list = loptend; - -#if defined (RESTRICTED_SHELL) - /* Restricted shells cannot load new builtins. */ - if (restricted && (flags & (FFLAG|DFLAG))) - { - sh_restricted ((char *)NULL); - return (EXECUTION_FAILURE); - } -#endif - - if (list == 0 || (flags & PFLAG)) - { - filter = (flags & AFLAG) ? (ENABLED | DISABLED) - : (flags & NFLAG) ? DISABLED : ENABLED; - - if (flags & SFLAG) - filter |= SPECIAL; - - list_some_builtins (filter); - result = sh_chkwrite (EXECUTION_SUCCESS); - } -#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM) - else if (flags & FFLAG) - { - filter = (flags & NFLAG) ? DISABLED : ENABLED; - if (flags & SFLAG) - filter |= SPECIAL; - - result = dyn_load_builtin (list, filter, filename); - if (result != EXECUTION_SUCCESS) - result = EXECUTION_FAILURE; /* normalize return value */ -#if defined (PROGRAMMABLE_COMPLETION) - set_itemlist_dirty (&it_builtins); -#endif - } -#endif -#if defined (HAVE_DLCLOSE) - else if (flags & DFLAG) - { - while (list) - { - opt = dyn_unload_builtin (list->word->word); - if (opt == EXECUTION_FAILURE) - result = EXECUTION_FAILURE; - list = list->next; - } -#if defined (PROGRAMMABLE_COMPLETION) - set_itemlist_dirty (&it_builtins); -#endif - } -#endif - else - { - while (list) - { - opt = enable_shell_command (list->word->word, flags & NFLAG); - next = list->next; - -#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM) - /* If we try to enable a non-existent builtin, and we have dynamic - loading, try the equivalent of `enable -f name name'. */ - if (opt == EX_NOTFOUND) - { - int dflags, r; - - dflags = ENABLED|SILENT|((flags & SFLAG) ? SPECIAL : 0); - - list->next = 0; - r = dyn_load_builtin (list, dflags, list->word->word); - list->next = next; - if (r == EXECUTION_SUCCESS) - opt = r; -#if defined (PROGRAMMABLE_COMPLETION) - set_itemlist_dirty (&it_builtins); -#endif - } -#endif - - if (opt == EX_NOTFOUND) - { - sh_notbuiltin (list->word->word); - result = EXECUTION_FAILURE; - } - else if (opt != EXECUTION_SUCCESS) - result = EXECUTION_FAILURE; - - list = next; - } - } - return (result); -} - -/* List some builtins. - FILTER is a mask with two slots: ENABLED and DISABLED. */ -static void -list_some_builtins (filter) - int filter; -{ - register int i; - - for (i = 0; i < num_shell_builtins; i++) - { - if (shell_builtins[i].function == 0 || (shell_builtins[i].flags & BUILTIN_DELETED)) - continue; - - if ((filter & SPECIAL) && - (shell_builtins[i].flags & SPECIAL_BUILTIN) == 0) - continue; - - if ((filter & ENABLED) && (shell_builtins[i].flags & BUILTIN_ENABLED)) - printf ("enable %s\n", shell_builtins[i].name); - else if ((filter & DISABLED) && - ((shell_builtins[i].flags & BUILTIN_ENABLED) == 0)) - printf ("enable -n %s\n", shell_builtins[i].name); - } -} - -/* Enable the shell command NAME. If DISABLE_P is non-zero, then - disable NAME instead. */ -static int -enable_shell_command (name, disable_p) - char *name; - int disable_p; -{ - struct builtin *b; - - b = builtin_address_internal (name, 1); - if (b == 0) - return (EX_NOTFOUND); - - if (disable_p) - b->flags &= ~BUILTIN_ENABLED; -#if defined (RESTRICTED_SHELL) - else if (restricted && ((b->flags & BUILTIN_ENABLED) == 0)) - { - sh_restricted ((char *)NULL); - return (EXECUTION_FAILURE); - } -#endif - else - b->flags |= BUILTIN_ENABLED; - -#if defined (PROGRAMMABLE_COMPLETION) - set_itemlist_dirty (&it_enabled); - set_itemlist_dirty (&it_disabled); -#endif - - return (EXECUTION_SUCCESS); -} - -#if defined (HAVE_DLOPEN) && defined (HAVE_DLSYM) - -#if defined (HAVE_DLFCN_H) -# include -#endif - -static int -dyn_load_builtin (list, flags, filename) - WORD_LIST *list; - int flags; - char *filename; -{ - WORD_LIST *l; - void *handle; - - int total, size, new, replaced, r; - char *struct_name, *name, *funcname; - sh_load_func_t *loadfunc; - struct builtin **new_builtins, *b, *new_shell_builtins, *old_builtin; - char *loadables_path, *load_path; - - if (list == 0) - return (EXECUTION_FAILURE); - -#ifndef RTLD_LAZY -#define RTLD_LAZY 1 -#endif - - handle = 0; - if (absolute_program (filename) == 0) - { - loadables_path = get_string_value ("BASH_LOADABLES_PATH"); - if (loadables_path) - { - load_path = find_in_path (filename, loadables_path, FS_NODIRS|FS_EXEC_PREFERRED); - if (load_path) - { -#if defined (_AIX) - handle = dlopen (load_path, RTLD_NOW|RTLD_GLOBAL); -#else - handle = dlopen (load_path, RTLD_LAZY); -#endif /* !_AIX */ - free (load_path); - } - } - } - - /* Fall back to current directory for now */ - if (handle == 0) -#if defined (_AIX) - handle = dlopen (filename, RTLD_NOW|RTLD_GLOBAL); -#else - handle = dlopen (filename, RTLD_LAZY); -#endif /* !_AIX */ - - if (handle == 0) - { - /* If we've been told to be quiet, don't complain about not finding the - specified shared object. */ - if ((flags & SILENT) == 0) - { - name = printable_filename (filename, 0); - builtin_error (_("cannot open shared object %s: %s"), name, dlerror ()); - if (name != filename) - free (name); - } - return (EX_NOTFOUND); - } - - for (new = 0, l = list; l; l = l->next, new++) - ; - new_builtins = (struct builtin **)xmalloc (new * sizeof (struct builtin *)); - - /* For each new builtin in the shared object, find it and its describing - structure. If this is overwriting an existing builtin, do so, otherwise - save the loaded struct for creating the new list of builtins. */ - for (replaced = new = 0; list; list = list->next) - { - name = list->word->word; - - size = strlen (name); - struct_name = (char *)xmalloc (size + 8); - strcpy (struct_name, name); - strcpy (struct_name + size, STRUCT_SUFFIX); - - old_builtin = builtin_address_internal (name, 1); - - b = (struct builtin *)dlsym (handle, struct_name); - if (b == 0) - { - name = printable_filename (filename, 0); - builtin_error (_("cannot find %s in shared object %s: %s"), - struct_name, name, dlerror ()); - if (name != filename) - free (name); - free (struct_name); - continue; - } - - funcname = xrealloc (struct_name, size + sizeof (LOAD_SUFFIX) + 1); - strcpy (funcname, name); - strcpy (funcname + size, LOAD_SUFFIX); - - loadfunc = (sh_load_func_t *)dlsym (handle, funcname); - if (loadfunc) - { - /* Add warning if running an init function more than once */ - if (old_builtin && (old_builtin->flags & STATIC_BUILTIN) == 0) - builtin_warning (_("%s: dynamic builtin already loaded"), name); - r = (*loadfunc) (name); - if (r == 0) - { - builtin_error (_("load function for %s returns failure (%d): not loaded"), name, r); - free (funcname); - continue; - } - } - free (funcname); - - b->flags &= ~STATIC_BUILTIN; - if (flags & SPECIAL) - b->flags |= SPECIAL_BUILTIN; - b->handle = handle; - - if (old_builtin) - { - replaced++; - FASTCOPY ((char *)b, (char *)old_builtin, sizeof (struct builtin)); - } - else - new_builtins[new++] = b; - } - - if (replaced == 0 && new == 0) - { - free (new_builtins); - dlclose (handle); - return (EXECUTION_FAILURE); - } - - if (new) - { - total = num_shell_builtins + new; - size = (total + 1) * sizeof (struct builtin); - - new_shell_builtins = (struct builtin *)xmalloc (size); - FASTCOPY ((char *)shell_builtins, (char *)new_shell_builtins, - num_shell_builtins * sizeof (struct builtin)); - for (replaced = 0; replaced < new; replaced++) - FASTCOPY ((char *)new_builtins[replaced], - (char *)&new_shell_builtins[num_shell_builtins + replaced], - sizeof (struct builtin)); - - new_shell_builtins[total].name = (char *)0; - new_shell_builtins[total].function = (sh_builtin_func_t *)0; - new_shell_builtins[total].flags = 0; - - if (shell_builtins != static_shell_builtins) - free (shell_builtins); - - shell_builtins = new_shell_builtins; - num_shell_builtins = total; - initialize_shell_builtins (); - } - - free (new_builtins); - return (EXECUTION_SUCCESS); -} -#endif - -#if defined (HAVE_DLCLOSE) -static void -delete_builtin (b) - struct builtin *b; -{ - int ind, size; - struct builtin *new_shell_builtins; - - /* XXX - funky pointer arithmetic - XXX */ -#ifdef __STDC__ - ind = b - shell_builtins; -#else - ind = ((int)b - (int)shell_builtins) / sizeof (struct builtin); -#endif - size = num_shell_builtins * sizeof (struct builtin); - new_shell_builtins = (struct builtin *)xmalloc (size); - - /* Copy shell_builtins[0]...shell_builtins[ind - 1] to new_shell_builtins */ - if (ind) - FASTCOPY ((char *)shell_builtins, (char *)new_shell_builtins, - ind * sizeof (struct builtin)); - /* Copy shell_builtins[ind+1]...shell_builtins[num_shell_builtins to - new_shell_builtins, starting at ind. */ - FASTCOPY ((char *)(&shell_builtins[ind+1]), - (char *)(&new_shell_builtins[ind]), - (num_shell_builtins - ind) * sizeof (struct builtin)); - - if (shell_builtins != static_shell_builtins) - free (shell_builtins); - - /* The result is still sorted. */ - num_shell_builtins--; - shell_builtins = new_shell_builtins; -} - -/* Tenon's MachTen has a dlclose that doesn't return a value, so we - finesse it with a local wrapper. */ -static int -local_dlclose (handle) - void *handle; -{ -#if !defined (__MACHTEN__) - return (dlclose (handle)); -#else /* __MACHTEN__ */ - dlclose (handle); - return ((dlerror () != NULL) ? -1 : 0); -#endif /* __MACHTEN__ */ -} - -static int -dyn_unload_builtin (name) - char *name; -{ - struct builtin *b; - void *handle; - char *funcname; - sh_unload_func_t *unloadfunc; - int ref, i, size; - - b = builtin_address_internal (name, 1); - if (b == 0) - { - sh_notbuiltin (name); - return (EXECUTION_FAILURE); - } - if (b->flags & STATIC_BUILTIN) - { - builtin_error (_("%s: not dynamically loaded"), name); - return (EXECUTION_FAILURE); - } - - handle = (void *)b->handle; - for (ref = i = 0; i < num_shell_builtins; i++) - { - if (shell_builtins[i].handle == b->handle) - ref++; - } - - /* Call any unload function */ - size = strlen (name); - funcname = xmalloc (size + sizeof (UNLOAD_SUFFIX) + 1); - strcpy (funcname, name); - strcpy (funcname + size, UNLOAD_SUFFIX); - - unloadfunc = (sh_unload_func_t *)dlsym (handle, funcname); - if (unloadfunc) - (*unloadfunc) (name); /* void function */ - free (funcname); - - /* Don't remove the shared object unless the reference count of builtins - using it drops to zero. */ - if (ref == 1 && local_dlclose (handle) != 0) - { - builtin_error (_("%s: cannot delete: %s"), name, dlerror ()); - return (EXECUTION_FAILURE); - } - - /* Now remove this entry from the builtin table and reinitialize. */ - delete_builtin (b); - - return (EXECUTION_SUCCESS); -} -#endif diff --git a/third_party/bash/builtins_eval.c b/third_party/bash/builtins_eval.c deleted file mode 100644 index 8bb0b8b23..000000000 --- a/third_party/bash/builtins_eval.c +++ /dev/null @@ -1,28 +0,0 @@ -/* eval.c, created from eval.def. */ -#line 22 "./eval.def" - -#line 34 "./eval.def" - -#include "config.h" -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include "shell.h" -#include "bashgetopt.h" -#include "common.h" - -/* Parse the string that these words make, and execute the command found. */ -int -eval_builtin (list) - WORD_LIST *list; -{ - if (no_options (list)) - return (EX_USAGE); - list = loptend; /* skip over possible `--' */ - - return (list ? evalstring (string_list (list), "eval", SEVAL_NOHIST) : EXECUTION_SUCCESS); -} diff --git a/third_party/bash/builtins_exec.c b/third_party/bash/builtins_exec.c deleted file mode 100644 index ae5ca7eb6..000000000 --- a/third_party/bash/builtins_exec.c +++ /dev/null @@ -1,238 +0,0 @@ -/* exec.c, created from exec.def. */ -#line 22 "./exec.def" - -#line 43 "./exec.def" - -#include "config.h" - -#include "bashtypes.h" -#include "posixstat.h" -#include -#include - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include - -#include "bashansi.h" -#include "bashintl.h" - -#include "shell.h" -#include "execute_cmd.h" -#include "findcmd.h" -#if defined (JOB_CONTROL) -# include "jobs.h" -#endif -#include "flags.h" -#include "trap.h" -#if defined (HISTORY) -# include "bashhist.h" -#endif -#include "common.h" -#include "bashgetopt.h" -#include "input.h" - -/* Not all systems declare ERRNO in errno.h... and some systems #define it! */ -#if !defined (errno) -extern int errno; -#endif /* !errno */ - -extern REDIRECT *redirection_undo_list; -extern char *exec_argv0; - -int no_exit_on_failed_exec; - -/* If the user wants this to look like a login shell, then - prepend a `-' onto NAME and return the new name. */ -static char * -mkdashname (name) - char *name; -{ - char *ret; - - ret = (char *)xmalloc (2 + strlen (name)); - ret[0] = '-'; - strcpy (ret + 1, name); - return ret; -} - -int -exec_builtin (list) - WORD_LIST *list; -{ - int exit_value = EXECUTION_FAILURE; - int cleanenv, login, opt, orig_job_control; - char *argv0, *command, **args, **env, *newname, *com2; - - cleanenv = login = orig_job_control = 0; - exec_argv0 = argv0 = (char *)NULL; - - reset_internal_getopt (); - while ((opt = internal_getopt (list, "cla:")) != -1) - { - switch (opt) - { - case 'c': - cleanenv = 1; - break; - case 'l': - login = 1; - break; - case 'a': - argv0 = list_optarg; - break; - CASE_HELPOPT; - default: - builtin_usage (); - return (EX_USAGE); - } - } - list = loptend; - - /* First, let the redirections remain. */ - dispose_redirects (redirection_undo_list); - redirection_undo_list = (REDIRECT *)NULL; - - if (list == 0) - return (EXECUTION_SUCCESS); - -#if defined (RESTRICTED_SHELL) - if (restricted) - { - sh_restricted ((char *)NULL); - return (EXECUTION_FAILURE); - } -#endif /* RESTRICTED_SHELL */ - - args = strvec_from_word_list (list, 1, 0, (int *)NULL); - env = (char **)0; - - /* A command with a slash anywhere in its name is not looked up in $PATH. */ - command = absolute_program (args[0]) ? args[0] : search_for_command (args[0], 1); - - if (command == 0) - { - if (file_isdir (args[0])) - { -#if defined (EISDIR) - builtin_error (_("%s: cannot execute: %s"), args[0], strerror (EISDIR)); -#else - builtin_error (_("%s: cannot execute: %s"), args[0], strerror (errno)); -#endif - exit_value = EX_NOEXEC; - } - else - { - sh_notfound (args[0]); - exit_value = EX_NOTFOUND; /* As per Posix.2, 3.14.6 */ - } - goto failed_exec; - } - - com2 = full_pathname (command); - if (com2) - { - if (command != args[0]) - free (command); - command = com2; - } - - if (argv0) - { - free (args[0]); - args[0] = login ? mkdashname (argv0) : savestring (argv0); - exec_argv0 = savestring (args[0]); - } - else if (login) - { - newname = mkdashname (args[0]); - free (args[0]); - args[0] = newname; - } - - /* Decrement SHLVL by 1 so a new shell started here has the same value, - preserving the appearance. After we do that, we need to change the - exported environment to include the new value. If we've already forked - and are in a subshell, we don't want to decrement the shell level, - since we are `increasing' the level */ - - if (cleanenv == 0 && (subshell_environment & SUBSHELL_PAREN) == 0) - adjust_shell_level (-1); - - if (cleanenv) - { - env = strvec_create (1); - env[0] = (char *)0; - } - else - { - maybe_make_export_env (); - env = export_env; - } - -#if defined (HISTORY) - if (interactive_shell && subshell_environment == 0) - maybe_save_shell_history (); -#endif /* HISTORY */ - - reset_signal_handlers (); /* leave trap strings in place */ - -#if defined (JOB_CONTROL) - orig_job_control = job_control; /* XXX - was also interactive_shell */ - if (subshell_environment == 0) - end_job_control (); - if (interactive || job_control) - default_tty_job_signals (); /* undo initialize_job_signals */ -#endif /* JOB_CONTROL */ - -#if defined (BUFFERED_INPUT) - if (default_buffered_input >= 0) - sync_buffered_stream (default_buffered_input); -#endif - - exit_value = shell_execve (command, args, env); - - /* We have to set this to NULL because shell_execve has called realloc() - to stuff more items at the front of the array, which may have caused - the memory to be freed by realloc(). We don't want to free it twice. */ - args = (char **)NULL; - if (cleanenv == 0) - adjust_shell_level (1); - - if (exit_value == EX_NOTFOUND) /* no duplicate error message */ - goto failed_exec; - else if (executable_file (command) == 0) - { - builtin_error (_("%s: cannot execute: %s"), command, strerror (errno)); - exit_value = EX_NOEXEC; /* As per Posix.2, 3.14.6 */ - } - else - file_error (command); - -failed_exec: - FREE (command); - - if (subshell_environment || (interactive == 0 && no_exit_on_failed_exec == 0)) - exit_shell (last_command_exit_value = exit_value); - - if (args) - strvec_dispose (args); - - if (env && env != export_env) - strvec_dispose (env); - - /* If we're not exiting after the exec fails, we restore the shell signal - handlers and then modify the signal dispositions based on the trap strings - before the failed exec. */ - initialize_signals (1); - restore_traps (); - -#if defined (JOB_CONTROL) - if (orig_job_control) - restart_job_control (); -#endif /* JOB_CONTROL */ - - return (exit_value); -} diff --git a/third_party/bash/builtins_exit.c b/third_party/bash/builtins_exit.c deleted file mode 100644 index 89f8d3a78..000000000 --- a/third_party/bash/builtins_exit.c +++ /dev/null @@ -1,136 +0,0 @@ -/* exit.c, created from exit.def. */ -#line 22 "./exit.def" - -#line 31 "./exit.def" - -#include "config.h" - -#include "bashtypes.h" -#include - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "bashintl.h" - -#include "shell.h" -#include "execute_cmd.h" -#include "jobs.h" -#include "trap.h" - -#include "common.h" -#include "builtext.h" /* for jobs_builtin */ - -extern int check_jobs_at_exit; - -static int exit_or_logout PARAMS((WORD_LIST *)); -static int sourced_logout; - -int -exit_builtin (list) - WORD_LIST *list; -{ - CHECK_HELPOPT (list); - - if (interactive) - { - fprintf (stderr, login_shell ? _("logout\n") : "exit\n"); - fflush (stderr); - } - - return (exit_or_logout (list)); -} - -#line 79 "./exit.def" - -/* How to logout. */ -int -logout_builtin (list) - WORD_LIST *list; -{ - CHECK_HELPOPT (list); - - if (login_shell == 0 /* && interactive */) - { - builtin_error (_("not login shell: use `exit'")); - return (EXECUTION_FAILURE); - } - else - return (exit_or_logout (list)); -} - -static int -exit_or_logout (list) - WORD_LIST *list; -{ - int exit_value; - -#if defined (JOB_CONTROL) - int exit_immediate_okay, stopmsg; - - exit_immediate_okay = (interactive == 0 || - last_shell_builtin == exit_builtin || - last_shell_builtin == logout_builtin || - last_shell_builtin == jobs_builtin); - - /* Check for stopped jobs if the user wants to. */ - if (exit_immediate_okay == 0) - { - register int i; - for (i = stopmsg = 0; i < js.j_jobslots; i++) - if (jobs[i] && STOPPED (i)) - stopmsg = JSTOPPED; - else if (check_jobs_at_exit && stopmsg == 0 && jobs[i] && RUNNING (i)) - stopmsg = JRUNNING; - - if (stopmsg == JSTOPPED) - fprintf (stderr, _("There are stopped jobs.\n")); - else if (stopmsg == JRUNNING) - fprintf (stderr, _("There are running jobs.\n")); - - if (stopmsg && check_jobs_at_exit) - list_all_jobs (JLIST_STANDARD); - - if (stopmsg) - { - /* This is NOT superfluous because EOF can get here without - going through the command parser. Set both last and this - so that either `exit', `logout', or ^D will work to exit - immediately if nothing intervenes. */ - this_shell_builtin = last_shell_builtin = exit_builtin; - return (EXECUTION_FAILURE); - } - } -#endif /* JOB_CONTROL */ - - /* Get return value if present. This means that you can type - `logout 5' to a shell, and it returns 5. */ - - /* If we're running the exit trap (running_trap == 1, since running_trap - gets set to SIG+1), and we don't have a argument given to `exit' - (list == 0), use the exit status we saved before running the trap - commands (trap_saved_exit_value). */ - exit_value = (running_trap == 1 && list == 0) ? trap_saved_exit_value : get_exitstat (list); - - bash_logout (); - - last_command_exit_value = exit_value; - - /* Exit the program. */ - jump_to_top_level (EXITBLTIN); - /*NOTREACHED*/ -} - -void -bash_logout () -{ - /* Run our `~/.bash_logout' file if it exists, and this is a login shell. */ - if (login_shell && sourced_logout++ == 0 && subshell_environment == 0) - { - maybe_execute_file ("~/.bash_logout", 1); -#ifdef SYS_BASH_LOGOUT - maybe_execute_file (SYS_BASH_LOGOUT, 1); -#endif - } -} diff --git a/third_party/bash/builtins_fc.c b/third_party/bash/builtins_fc.c deleted file mode 100644 index 20d4b5433..000000000 --- a/third_party/bash/builtins_fc.c +++ /dev/null @@ -1,739 +0,0 @@ -/* fc.c, created from fc.def. */ -#line 22 "./fc.def" - -#line 51 "./fc.def" - -#include "config.h" - -#if defined (HISTORY) -#if defined (HAVE_SYS_PARAM_H) -# include -#endif -#include "bashtypes.h" -#include "posixstat.h" -#if ! defined(_MINIX) && defined (HAVE_SYS_FILE_H) -# include -#endif - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include -#include "chartypes.h" - -#include "bashansi.h" -#include "bashintl.h" -#include - -#include "shell.h" -#include "builtins.h" -#include "flags.h" -#include "parser.h" -#include "bashhist.h" -#include "maxpath.h" -#include "third_party/readline/history.h" -#include "bashgetopt.h" -#include "common.h" - -#if !defined (errno) -extern int errno; -#endif /* !errno */ - -#define HIST_INVALID INT_MIN -#define HIST_ERANGE INT_MIN+1 -#define HIST_NOTFOUND INT_MIN+2 - -/* Values for the flags argument to fc_gethnum */ -#define HN_LISTING 0x01 -#define HN_FIRST 0x02 - -extern int unlink PARAMS((const char *)); - -extern FILE *sh_mktmpfp PARAMS((char *, int, char **)); - -extern int suppress_debug_trap_verbose; - -/* **************************************************************** */ -/* */ -/* The K*rn shell style fc command (Fix Command) */ -/* */ -/* **************************************************************** */ - -/* fc builtin command (fix command) for Bash for those who - like K*rn-style history better than csh-style. - - fc [-e ename] [-nlr] [first] [last] - - FIRST and LAST can be numbers specifying the range, or FIRST can be - a string, which means the most recent command beginning with that - string. - - -e ENAME selects which editor to use. Default is FCEDIT, then EDITOR, - then the editor which corresponds to the current readline editing - mode, then vi. - - -l means list lines instead of editing. - -n means no line numbers listed. - -r means reverse the order of the lines (making it newest listed first). - - fc -e - [pat=rep ...] [command] - fc -s [pat=rep ...] [command] - - Equivalent to !command:sg/pat/rep execpt there can be multiple PAT=REP's. -*/ - -/* Data structure describing a list of global replacements to perform. */ -typedef struct repl { - struct repl *next; - char *pat; - char *rep; -} REPL; - -/* Accessors for HIST_ENTRY lists that are called HLIST. */ -#define histline(i) (hlist[(i)]->line) -#define histdata(i) (hlist[(i)]->data) - -#define FREE_RLIST() \ - do { \ - for (rl = rlist; rl; ) { \ - REPL *r; \ - r = rl->next; \ - if (rl->pat) \ - free (rl->pat); \ - if (rl->rep) \ - free (rl->rep); \ - free (rl); \ - rl = r; \ - } \ - } while (0) - -static char *fc_dosubs PARAMS((char *, REPL *)); -static char *fc_gethist PARAMS((char *, HIST_ENTRY **, int)); -static int fc_gethnum PARAMS((char *, HIST_ENTRY **, int)); -static int fc_number PARAMS((WORD_LIST *)); -static void fc_replhist PARAMS((char *)); -#ifdef INCLUDE_UNUSED -static char *fc_readline PARAMS((FILE *)); -static void fc_addhist PARAMS((char *)); -#endif - -static void -set_verbose_flag () -{ - echo_input_at_read = verbose_flag; -} - -/* String to execute on a file that we want to edit. */ -#define FC_EDIT_COMMAND "${FCEDIT:-${EDITOR:-vi}}" -#if defined (STRICT_POSIX) -# define POSIX_FC_EDIT_COMMAND "${FCEDIT:-ed}" -#else -# define POSIX_FC_EDIT_COMMAND "${FCEDIT:-${EDITOR:-ed}}" -#endif - -int -fc_builtin (list) - WORD_LIST *list; -{ - register int i; - register char *sep; - int numbering, reverse, listing, execute; - int histbeg, histend, last_hist, retval, opt, rh, real_last; - FILE *stream; - REPL *rlist, *rl; - char *ename, *command, *newcom, *fcedit; - HIST_ENTRY **hlist; - char *fn; - - numbering = 1; - reverse = listing = execute = 0; - ename = (char *)NULL; - - /* Parse out the options and set which of the two forms we're in. */ - reset_internal_getopt (); - lcurrent = list; /* XXX */ - while (fc_number (loptend = lcurrent) == 0 && - (opt = internal_getopt (list, ":e:lnrs")) != -1) - { - switch (opt) - { - case 'n': - numbering = 0; - break; - - case 'l': - listing = HN_LISTING; /* for fc_gethnum */ - break; - - case 'r': - reverse = 1; - break; - - case 's': - execute = 1; - break; - - case 'e': - ename = list_optarg; - break; - - CASE_HELPOPT; - default: - builtin_usage (); - return (EX_USAGE); - } - } - - list = loptend; - - if (ename && (*ename == '-') && (ename[1] == '\0')) - execute = 1; - - /* The "execute" form of the command (re-run, with possible string - substitutions). */ - if (execute) - { - rlist = (REPL *)NULL; - while (list && ((sep = (char *)strchr (list->word->word, '=')) != NULL)) - { - *sep++ = '\0'; - rl = (REPL *)xmalloc (sizeof (REPL)); - rl->next = (REPL *)NULL; - rl->pat = savestring (list->word->word); - rl->rep = savestring (sep); - - if (rlist == NULL) - rlist = rl; - else - { - rl->next = rlist; - rlist = rl; - } - list = list->next; - } - - /* If we have a list of substitutions to do, then reverse it - to get the replacements in the proper order. */ - - rlist = REVERSE_LIST (rlist, REPL *); - - hlist = history_list (); - - /* If we still have something in list, it is a command spec. - Otherwise, we use the most recent command in time. */ - command = fc_gethist (list ? list->word->word : (char *)NULL, hlist, 0); - - if (command == NULL) - { - builtin_error (_("no command found")); - if (rlist) - FREE_RLIST (); - - return (EXECUTION_FAILURE); - } - - if (rlist) - { - newcom = fc_dosubs (command, rlist); - free (command); - FREE_RLIST (); - command = newcom; - } - - fprintf (stderr, "%s\n", command); - fc_replhist (command); /* replace `fc -s' with command */ - /* Posix says that the re-executed commands should be entered into the - history. */ - return (parse_and_execute (command, "fc", SEVAL_NOHIST)); - } - - /* This is the second form of the command (the list-or-edit-and-rerun - form). */ - hlist = history_list (); - if (hlist == 0) - return (EXECUTION_SUCCESS); - for (i = 0; hlist[i]; i++); - - /* With the Bash implementation of history, the current command line - ("fc blah..." and so on) is already part of the history list by - the time we get to this point. This just skips over that command - and makes the last command that this deals with be the last command - the user entered before the fc. We need to check whether the - line was actually added (HISTIGNORE may have caused it to not be), - so we check hist_last_line_added. */ - - /* Even though command substitution through parse_and_execute turns off - remember_on_history, command substitution in a shell when set -o history - has been enabled (interactive or not) should use it in the last_hist - calculation as if it were on. */ - rh = remember_on_history || ((subshell_environment & SUBSHELL_COMSUB) && enable_history_list); - last_hist = i - rh - hist_last_line_added; - - /* Make sure that real_last is calculated the same way here and in - fc_gethnum. The return value from fc_gethnum is treated specially if - it is == real_last and we are listing commands. */ - real_last = i; - /* back up from the end to the last non-null history entry */ - while (hlist[real_last] == 0 && real_last > 0) - real_last--; - - /* XXX */ - if (i == last_hist && hlist[last_hist] == 0) - while (last_hist >= 0 && hlist[last_hist] == 0) - last_hist--; - if (last_hist < 0) - last_hist = 0; /* per POSIX */ - - if (list) - { - histbeg = fc_gethnum (list->word->word, hlist, listing|HN_FIRST); - list = list->next; - - if (list) - histend = fc_gethnum (list->word->word, hlist, listing); - else if (histbeg == real_last) - histend = listing ? real_last : histbeg; - else - histend = listing ? last_hist : histbeg; - } - else - { - /* The default for listing is the last 16 history items. */ - if (listing) - { - histend = last_hist; - histbeg = histend - 16 + 1; /* +1 because loop below uses >= */ - if (histbeg < 0) - histbeg = 0; - } - else - /* For editing, it is the last history command. */ - histbeg = histend = last_hist; - } - - if (histbeg == HIST_INVALID || histend == HIST_INVALID) - { - sh_erange ((char *)NULL, _("history specification")); - return (EXECUTION_FAILURE); - } - else if (histbeg == HIST_ERANGE || histend == HIST_ERANGE) - { - sh_erange ((char *)NULL, _("history specification")); - return (EXECUTION_FAILURE); - } - else if (histbeg == HIST_NOTFOUND || histend == HIST_NOTFOUND) - { - builtin_error (_("no command found")); - return (EXECUTION_FAILURE); - } - - /* We don't throw an error for line specifications out of range, per POSIX */ - if (histbeg < 0) - histbeg = 0; - if (histend < 0) - histend = 0; - - /* "When not listing, the fc command that caused the editing shall not be - entered into the history list." */ - if (listing == 0 && hist_last_line_added) - { - bash_delete_last_history (); - /* If we're editing a single command -- the last command in the - history -- and we just removed the dummy command added by - edit_and_execute_command (), we need to check whether or not we - just removed the last command in the history and need to back - the pointer up. remember_on_history is off because we're running - in parse_and_execute(). */ - if (histbeg == histend && histend == last_hist && hlist[last_hist] == 0) - last_hist = histbeg = --histend; - - if (hlist[last_hist] == 0) - last_hist--; - if (histend >= last_hist) - histend = last_hist; - else if (histbeg >= last_hist) - histbeg = last_hist; - } - - if (histbeg == HIST_INVALID || histend == HIST_INVALID) - { - sh_erange ((char *)NULL, _("history specification")); - return (EXECUTION_FAILURE); - } - else if (histbeg == HIST_ERANGE || histend == HIST_ERANGE) - { - sh_erange ((char *)NULL, _("history specification")); - return (EXECUTION_FAILURE); - } - else if (histbeg == HIST_NOTFOUND || histend == HIST_NOTFOUND) - { - builtin_error (_("no command found")); - return (EXECUTION_FAILURE); - } - - /* We don't throw an error for line specifications out of range, per POSIX */ - if (histbeg < 0) - histbeg = 0; - if (histend < 0) - histend = 0; - - if (histend < histbeg) - { - i = histend; - histend = histbeg; - histbeg = i; - - reverse = 1; - } - - if (listing) - stream = stdout; - else - { - numbering = 0; - stream = sh_mktmpfp ("bash-fc", MT_USERANDOM|MT_USETMPDIR, &fn); - if (stream == 0) - { - builtin_error (_("%s: cannot open temp file: %s"), fn ? fn : "", strerror (errno)); - FREE (fn); - return (EXECUTION_FAILURE); - } - } - - for (i = reverse ? histend : histbeg; reverse ? i >= histbeg : i <= histend; reverse ? i-- : i++) - { - QUIT; - if (hlist[i] == 0) - continue; - if (numbering) - fprintf (stream, "%d", i + history_base); - if (listing) - { - if (posixly_correct) - fputs ("\t", stream); - else - fprintf (stream, "\t%c", histdata (i) ? '*' : ' '); - } - if (histline (i)) - fprintf (stream, "%s\n", histline (i)); - } - - if (listing) - return (sh_chkwrite (EXECUTION_SUCCESS)); - - fflush (stream); - if (ferror (stream)) - { - sh_wrerror (); - fclose (stream); - FREE (fn); - return (EXECUTION_FAILURE); - } - fclose (stream); - - /* Now edit the file of commands. */ - if (ename) - { - command = (char *)xmalloc (strlen (ename) + strlen (fn) + 2); - sprintf (command, "%s %s", ename, fn); - } - else - { - fcedit = posixly_correct ? POSIX_FC_EDIT_COMMAND : FC_EDIT_COMMAND; - command = (char *)xmalloc (3 + strlen (fcedit) + strlen (fn)); - sprintf (command, "%s %s", fcedit, fn); - } - retval = parse_and_execute (command, "fc", SEVAL_NOHIST); - if (retval != EXECUTION_SUCCESS) - { - unlink (fn); - free (fn); - return (EXECUTION_FAILURE); - } - -#if defined (READLINE) - /* If we're executing as part of a dispatched readline command like - {emacs,vi}_edit_and_execute_command, the readline state will indicate it. - We could remove the partial command from the history, but ksh93 doesn't - so we stay compatible. */ -#endif - - /* Make sure parse_and_execute doesn't turn this off, even though a - call to parse_and_execute farther up the function call stack (e.g., - if this is called by vi_edit_and_execute_command) may have already - called bash_history_disable. */ - remember_on_history = 1; - - /* Turn on the `v' flag while fc_execute_file runs so the commands - will be echoed as they are read by the parser. */ - begin_unwind_frame ("fc builtin"); - add_unwind_protect (xfree, fn); - add_unwind_protect (unlink, fn); - add_unwind_protect (set_verbose_flag, (char *)NULL); - unwind_protect_int (suppress_debug_trap_verbose); - echo_input_at_read = 1; - suppress_debug_trap_verbose = 1; - - retval = fc_execute_file (fn); - run_unwind_frame ("fc builtin"); - - return (retval); -} - -/* Return 1 if LIST->word->word is a legal number for fc's use. */ -static int -fc_number (list) - WORD_LIST *list; -{ - char *s; - - if (list == 0) - return 0; - s = list->word->word; - if (*s == '-') - s++; - return (legal_number (s, (intmax_t *)NULL)); -} - -/* Return an absolute index into HLIST which corresponds to COMMAND. If - COMMAND is a number, then it was specified in relative terms. If it - is a string, then it is the start of a command line present in HLIST. - MODE includes HN_LISTING if we are listing commands, and does not if we - are executing them. If MODE includes HN_FIRST we are looking for the - first history number specification. */ -static int -fc_gethnum (command, hlist, mode) - char *command; - HIST_ENTRY **hlist; - int mode; -{ - int sign, n, clen, rh; - register int i, j, last_hist, real_last, listing; - register char *s; - - listing = mode & HN_LISTING; - sign = 1; - /* Count history elements. */ - for (i = 0; hlist[i]; i++); - - /* With the Bash implementation of history, the current command line - ("fc blah..." and so on) is already part of the history list by - the time we get to this point. This just skips over that command - and makes the last command that this deals with be the last command - the user entered before the fc. We need to check whether the - line was actually added (HISTIGNORE may have caused it to not be), - so we check hist_last_line_added. This needs to agree with the - calculation of last_hist in fc_builtin above. */ - /* Even though command substitution through parse_and_execute turns off - remember_on_history, command substitution in a shell when set -o history - has been enabled (interactive or not) should use it in the last_hist - calculation as if it were on. */ - rh = remember_on_history || ((subshell_environment & SUBSHELL_COMSUB) && enable_history_list); - last_hist = i - rh - hist_last_line_added; - - if (i == last_hist && hlist[last_hist] == 0) - while (last_hist >= 0 && hlist[last_hist] == 0) - last_hist--; - if (last_hist < 0) - return (-1); - - real_last = i; - i = last_hist; - - /* No specification defaults to most recent command. */ - if (command == NULL) - return (i); - - /* back up from the end to the last non-null history entry */ - while (hlist[real_last] == 0 && real_last > 0) - real_last--; - - /* Otherwise, there is a specification. It can be a number relative to - the current position, or an absolute history number. */ - s = command; - - /* Handle possible leading minus sign. */ - if (s && (*s == '-')) - { - sign = -1; - s++; - } - - if (s && DIGIT(*s)) - { - n = atoi (s); - n *= sign; - - /* We want to return something that is an offset to HISTORY_BASE. */ - - /* If the value is negative or zero, then it is an offset from - the current history item. */ - /* We don't use HN_FIRST here, so we don't return different values - depending on whether we're looking for the first or last in a - pair of range arguments, but nobody else does, either. */ - if (n < 0) - { - n += i + 1; - return (n < 0 ? 0 : n); - } - else if (n == 0) - return ((sign == -1) ? (listing ? real_last : HIST_INVALID) : i); - else - { - /* If we're out of range (greater than I (last history entry) or - less than HISTORY_BASE, we want to return different values - based on whether or not we are looking for the first or last - value in a desired range of history entries. */ - n -= history_base; - if (n < 0) - return (mode & HN_FIRST ? 0 : i); - else if (n >= i) - return (mode & HN_FIRST ? 0 : i); - else - return n; - } - } - - clen = strlen (command); - for (j = i; j >= 0; j--) - { - if (STREQN (command, histline (j), clen)) - return (j); - } - return (HIST_NOTFOUND); -} - -/* Locate the most recent history line which begins with - COMMAND in HLIST, and return a malloc()'ed copy of it. - MODE is 1 if we are listing commands, 0 if we are executing them. */ -static char * -fc_gethist (command, hlist, mode) - char *command; - HIST_ENTRY **hlist; - int mode; -{ - int i; - - if (hlist == 0) - return ((char *)NULL); - - i = fc_gethnum (command, hlist, mode); - - if (i >= 0) - return (savestring (histline (i))); - else - return ((char *)NULL); -} - -#ifdef INCLUDE_UNUSED -/* Read the edited history lines from STREAM and return them - one at a time. This can read unlimited length lines. The - caller should free the storage. */ -static char * -fc_readline (stream) - FILE *stream; -{ - register int c; - int line_len = 0, lindex = 0; - char *line = (char *)NULL; - - while ((c = getc (stream)) != EOF) - { - if ((lindex + 2) >= line_len) - line = (char *)xrealloc (line, (line_len += 128)); - - if (c == '\n') - { - line[lindex++] = '\n'; - line[lindex++] = '\0'; - return (line); - } - else - line[lindex++] = c; - } - - if (!lindex) - { - if (line) - free (line); - - return ((char *)NULL); - } - - if (lindex + 2 >= line_len) - line = (char *)xrealloc (line, lindex + 3); - - line[lindex++] = '\n'; /* Finish with newline if none in file */ - line[lindex++] = '\0'; - return (line); -} -#endif - -/* Perform the SUBS on COMMAND. - SUBS is a list of substitutions, and COMMAND is a simple string. - Return a pointer to a malloc'ed string which contains the substituted - command. */ -static char * -fc_dosubs (command, subs) - char *command; - REPL *subs; -{ - register char *new, *t; - register REPL *r; - - for (new = savestring (command), r = subs; r; r = r->next) - { - t = strsub (new, r->pat, r->rep, 1); - free (new); - new = t; - } - return (new); -} - -/* Use `command' to replace the last entry in the history list, which, - by this time, is `fc blah...'. The intent is that the new command - become the history entry, and that `fc' should never appear in the - history list. This way you can do `r' to your heart's content. */ -static void -fc_replhist (command) - char *command; -{ - int n; - - if (command == 0 || *command == '\0') - return; - - n = strlen (command); - if (command[n - 1] == '\n') - command[n - 1] = '\0'; - - if (command && *command) - { - bash_delete_last_history (); - maybe_add_history (command); /* Obeys HISTCONTROL setting. */ - } -} - -#ifdef INCLUDE_UNUSED -/* Add LINE to the history, after removing a single trailing newline. */ -static void -fc_addhist (line) - char *line; -{ - register int n; - - if (line == 0 || *line == 0) - return; - - n = strlen (line); - - if (line[n - 1] == '\n') - line[n - 1] = '\0'; - - if (line && *line) - maybe_add_history (line); /* Obeys HISTCONTROL setting. */ -} -#endif - -#endif /* HISTORY */ diff --git a/third_party/bash/builtins_fg_bg.c b/third_party/bash/builtins_fg_bg.c deleted file mode 100644 index 93ce42d19..000000000 --- a/third_party/bash/builtins_fg_bg.c +++ /dev/null @@ -1,146 +0,0 @@ -/* fg_bg.c, created from fg_bg.def. */ -#line 22 "./fg_bg.def" - -#line 36 "./fg_bg.def" - -#include "config.h" - -#include "bashtypes.h" -#include - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "bashintl.h" - -#include "shell.h" -#include "execute_cmd.h" -#include "jobs.h" -#include "common.h" -#include "bashgetopt.h" - -#if defined (JOB_CONTROL) -static int fg_bg PARAMS((WORD_LIST *, int)); - -/* How to bring a job into the foreground. */ -int -fg_builtin (list) - WORD_LIST *list; -{ - int fg_bit; - register WORD_LIST *t; - - CHECK_HELPOPT (list); - - if (job_control == 0) - { - sh_nojobs ((char *)NULL); - return (EXECUTION_FAILURE); - } - - if (no_options (list)) - return (EX_USAGE); - list = loptend; - - /* If the last arg on the line is '&', then start this job in the - background. Else, fg the job. */ - for (t = list; t && t->next; t = t->next) - ; - fg_bit = (t && t->word->word[0] == '&' && t->word->word[1] == '\0') == 0; - - return (fg_bg (list, fg_bit)); -} -#endif /* JOB_CONTROL */ - -#line 100 "./fg_bg.def" - -#if defined (JOB_CONTROL) -/* How to put a job into the background. */ -int -bg_builtin (list) - WORD_LIST *list; -{ - int r; - - CHECK_HELPOPT (list); - - if (job_control == 0) - { - sh_nojobs ((char *)NULL); - return (EXECUTION_FAILURE); - } - - if (no_options (list)) - return (EX_USAGE); - list = loptend; - - /* This relies on the fact that fg_bg() takes a WORD_LIST *, but only acts - on the first member (if any) of that list. */ - r = EXECUTION_SUCCESS; - do - { - if (fg_bg (list, 0) == EXECUTION_FAILURE) - r = EXECUTION_FAILURE; - if (list) - list = list->next; - } - while (list); - - return r; -} - -/* How to put a job into the foreground/background. */ -static int -fg_bg (list, foreground) - WORD_LIST *list; - int foreground; -{ - sigset_t set, oset; - int job, status, old_async_pid; - JOB *j; - - BLOCK_CHILD (set, oset); - job = get_job_spec (list); - - if (INVALID_JOB (job)) - { - if (job != DUP_JOB) - sh_badjob (list ? list->word->word : _("current")); - - goto failure; - } - - j = get_job_by_jid (job); - /* Or if j->pgrp == shell_pgrp. */ - if (IS_JOBCONTROL (job) == 0) - { - builtin_error (_("job %d started without job control"), job + 1); - goto failure; - } - - if (foreground == 0) - { - old_async_pid = last_asynchronous_pid; - last_asynchronous_pid = j->pgrp; /* As per Posix.2 5.4.2 */ - } - - status = start_job (job, foreground); - - if (status >= 0) - { - /* win: */ - UNBLOCK_CHILD (oset); - return (foreground ? status : EXECUTION_SUCCESS); - } - else - { - if (foreground == 0) - last_asynchronous_pid = old_async_pid; - - failure: - UNBLOCK_CHILD (oset); - return (EXECUTION_FAILURE); - } -} -#endif /* JOB_CONTROL */ diff --git a/third_party/bash/builtins_getopts.c b/third_party/bash/builtins_getopts.c deleted file mode 100644 index 961906259..000000000 --- a/third_party/bash/builtins_getopts.c +++ /dev/null @@ -1,284 +0,0 @@ -/* getopts.c, created from getopts.def. */ -#line 22 "./getopts.def" - -#line 64 "./getopts.def" - -#include "config.h" - -#include - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include "bashansi.h" -#include "bashintl.h" - -#include "shell.h" -#include "execute_cmd.h" -#include "common.h" -#include "bashgetopt.h" -#include "getopt.h" - -#define G_EOF -1 -#define G_INVALID_OPT -2 -#define G_ARG_MISSING -3 - -static int getopts_unbind_variable PARAMS((char *)); -static int getopts_bind_variable PARAMS((char *, char *)); -static int dogetopts PARAMS((int, char **)); - -/* getopts_reset is magic code for when OPTIND is reset. N is the - value that has just been assigned to OPTIND. */ -void -getopts_reset (newind) - int newind; -{ - sh_optind = newind; - sh_badopt = 0; -} - -static int -getopts_unbind_variable (name) - char *name; -{ -#if 0 - return (unbind_variable (name)); -#else - return (unbind_variable_noref (name)); -#endif -} - -static int -getopts_bind_variable (name, value) - char *name, *value; -{ - SHELL_VAR *v; - - if (legal_identifier (name)) - { - v = bind_variable (name, value, 0); - if (v && (readonly_p (v) || noassign_p (v))) - return (EX_MISCERROR); - return (v ? EXECUTION_SUCCESS : EXECUTION_FAILURE); - } - else - { - sh_invalidid (name); - return (EXECUTION_FAILURE); - } -} - -/* Error handling is now performed as specified by Posix.2, draft 11 - (identical to that of ksh-88). The special handling is enabled if - the first character of the option string is a colon; this handling - disables diagnostic messages concerning missing option arguments - and invalid option characters. The handling is as follows. - - INVALID OPTIONS: - name -> "?" - if (special_error) then - OPTARG = option character found - no error output - else - OPTARG unset - diagnostic message - fi - - MISSING OPTION ARGUMENT; - if (special_error) then - name -> ":" - OPTARG = option character found - else - name -> "?" - OPTARG unset - diagnostic message - fi - */ - -static int -dogetopts (argc, argv) - int argc; - char **argv; -{ - int ret, special_error, old_opterr, i, n; - char strval[2], numval[16]; - char *optstr; /* list of options */ - char *name; /* variable to get flag val */ - char *t; - - if (argc < 3) - { - builtin_usage (); - return (EX_USAGE); - } - - /* argv[0] is "getopts". */ - - optstr = argv[1]; - name = argv[2]; - argc -= 2; - argv += 2; - - special_error = optstr[0] == ':'; - - if (special_error) - { - old_opterr = sh_opterr; - optstr++; - sh_opterr = 0; /* suppress diagnostic messages */ - } - - if (argc > 1) - { - sh_getopt_restore_state (argv); - t = argv[0]; - argv[0] = dollar_vars[0]; - ret = sh_getopt (argc, argv, optstr); - argv[0] = t; - } - else if (rest_of_args == (WORD_LIST *)NULL) - { - for (i = 0; i < 10 && dollar_vars[i]; i++) - ; - - sh_getopt_restore_state (dollar_vars); - ret = sh_getopt (i, dollar_vars, optstr); - } - else - { - register WORD_LIST *words; - char **v; - - i = number_of_args () + 1; /* +1 for $0 */ - v = strvec_create (i + 1); - for (i = 0; i < 10 && dollar_vars[i]; i++) - v[i] = dollar_vars[i]; - for (words = rest_of_args; words; words = words->next, i++) - v[i] = words->word->word; - v[i] = (char *)NULL; - sh_getopt_restore_state (v); - ret = sh_getopt (i, v, optstr); - free (v); - } - - if (special_error) - sh_opterr = old_opterr; - - /* Set the OPTIND variable in any case, to handle "--" skipping. It's - highly unlikely that 14 digits will be too few. */ - if (sh_optind < 10) - { - numval[14] = sh_optind + '0'; - numval[15] = '\0'; - i = 14; - } - else - { - numval[i = 15] = '\0'; - n = sh_optind; - do - { - numval[--i] = (n % 10) + '0'; - } - while (n /= 10); - } - bind_variable ("OPTIND", numval + i, 0); - - /* If an error occurred, decide which one it is and set the return - code appropriately. In all cases, the option character in error - is in OPTOPT. If an invalid option was encountered, OPTARG is - NULL. If a required option argument was missing, OPTARG points - to a NULL string (that is, sh_optarg[0] == 0). */ - if (ret == '?') - { - if (sh_optarg == NULL) - ret = G_INVALID_OPT; - else if (sh_optarg[0] == '\0') - ret = G_ARG_MISSING; - } - - if (ret == G_EOF) - { - getopts_unbind_variable ("OPTARG"); - getopts_bind_variable (name, "?"); - return (EXECUTION_FAILURE); - } - - if (ret == G_INVALID_OPT) - { - /* Invalid option encountered. */ - ret = getopts_bind_variable (name, "?"); - - if (special_error) - { - strval[0] = (char)sh_optopt; - strval[1] = '\0'; - bind_variable ("OPTARG", strval, 0); - } - else - getopts_unbind_variable ("OPTARG"); - - return (ret); - } - - if (ret == G_ARG_MISSING) - { - /* Required argument missing. */ - if (special_error) - { - ret = getopts_bind_variable (name, ":"); - - strval[0] = (char)sh_optopt; - strval[1] = '\0'; - bind_variable ("OPTARG", strval, 0); - } - else - { - ret = getopts_bind_variable (name, "?"); - getopts_unbind_variable ("OPTARG"); - } - return (ret); - } - - bind_variable ("OPTARG", sh_optarg, 0); - - strval[0] = (char) ret; - strval[1] = '\0'; - return (getopts_bind_variable (name, strval)); -} - -/* The getopts builtin. Build an argv, and call dogetopts with it. */ -int -getopts_builtin (list) - WORD_LIST *list; -{ - char **av; - int ac, ret; - - if (list == 0) - { - builtin_usage (); - return EX_USAGE; - } - - reset_internal_getopt (); - if ((ret = internal_getopt (list, "")) != -1) - { - if (ret == GETOPT_HELP) - builtin_help (); - else - builtin_usage (); - return (EX_USAGE); - } - list = loptend; - - av = make_builtin_argv (list, &ac); - ret = dogetopts (ac, av); - free ((char *)av); - - return (ret); -} diff --git a/third_party/bash/builtins_hash.c b/third_party/bash/builtins_hash.c deleted file mode 100644 index 39fc71948..000000000 --- a/third_party/bash/builtins_hash.c +++ /dev/null @@ -1,264 +0,0 @@ -/* hash.c, created from hash.def. */ -#line 22 "./hash.def" - -#line 46 "./hash.def" - -#include "config.h" - -#include - -#include "bashtypes.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include - -#include "bashansi.h" -#include "bashintl.h" - -#include "shell.h" -#include "builtins.h" -#include "execute_cmd.h" -#include "flags.h" -#include "findcmd.h" -#include "hashcmd.h" -#include "common.h" -#include "bashgetopt.h" - -extern int dot_found_in_search; - -static int add_hashed_command PARAMS((char *, int)); -static int print_hash_info PARAMS((BUCKET_CONTENTS *)); -static int print_portable_hash_info PARAMS((BUCKET_CONTENTS *)); -static int print_hashed_commands PARAMS((int)); -static int list_hashed_filename_targets PARAMS((WORD_LIST *, int)); - -/* Print statistics on the current state of hashed commands. If LIST is - not empty, then rehash (or hash in the first place) the specified - commands. */ -int -hash_builtin (list) - WORD_LIST *list; -{ - int expunge_hash_table, list_targets, list_portably, delete, opt; - char *w, *pathname; - - if (hashing_enabled == 0) - { - builtin_error (_("hashing disabled")); - return (EXECUTION_FAILURE); - } - - expunge_hash_table = list_targets = list_portably = delete = 0; - pathname = (char *)NULL; - reset_internal_getopt (); - while ((opt = internal_getopt (list, "dlp:rt")) != -1) - { - switch (opt) - { - case 'd': - delete = 1; - break; - case 'l': - list_portably = 1; - break; - case 'p': - pathname = list_optarg; - break; - case 'r': - expunge_hash_table = 1; - break; - case 't': - list_targets = 1; - break; - CASE_HELPOPT; - default: - builtin_usage (); - return (EX_USAGE); - } - } - list = loptend; - - /* hash -t requires at least one argument. */ - if (list == 0 && (delete || list_targets)) - { - sh_needarg (delete ? "-d" : "-t"); - return (EXECUTION_FAILURE); - } - - /* We want hash -r to be silent, but hash -- to print hashing info, so - we test expunge_hash_table. */ - if (list == 0 && expunge_hash_table == 0) - { - opt = print_hashed_commands (list_portably); - if (opt == 0 && posixly_correct == 0 && - (list_portably == 0 || shell_compatibility_level <= 50)) - printf (_("%s: hash table empty\n"), this_command_name); - - return (sh_chkwrite (EXECUTION_SUCCESS)); - } - - if (expunge_hash_table) - phash_flush (); - - /* If someone runs `hash -r -t xyz' he will be disappointed. */ - if (list_targets) - return (list_hashed_filename_targets (list, list_portably)); - -#if defined (RESTRICTED_SHELL) - if (restricted && pathname) - { - if (strchr (pathname, '/')) - { - sh_restricted (pathname); - return (EXECUTION_FAILURE); - } - /* If we are changing the hash table in a restricted shell, make sure the - target pathname can be found using a $PATH search. */ - w = find_user_command (pathname); - if (w == 0 || *w == 0 || executable_file (w) == 0) - { - sh_notfound (pathname); - free (w); - return (EXECUTION_FAILURE); - } - free (w); - } -#endif - - for (opt = EXECUTION_SUCCESS; list; list = list->next) - { - /* Add, remove or rehash the specified commands. */ - w = list->word->word; - if (absolute_program (w)) - continue; - else if (pathname) - { - if (file_isdir (pathname)) - { -#ifdef EISDIR - builtin_error ("%s: %s", pathname, strerror (EISDIR)); -#else - builtin_error (_("%s: is a directory"), pathname); -#endif - opt = EXECUTION_FAILURE; - } - else - phash_insert (w, pathname, 0, 0); - } - else if (delete) - { - if (phash_remove (w)) - { - sh_notfound (w); - opt = EXECUTION_FAILURE; - } - } - else if (add_hashed_command (w, 0)) - opt = EXECUTION_FAILURE; - } - - fflush (stdout); - return (opt); -} - -static int -add_hashed_command (w, quiet) - char *w; - int quiet; -{ - int rv; - char *full_path; - - rv = 0; - if (find_function (w) == 0 && find_shell_builtin (w) == 0) - { - phash_remove (w); - full_path = find_user_command (w); - if (full_path && executable_file (full_path)) - phash_insert (w, full_path, dot_found_in_search, 0); - else - { - if (quiet == 0) - sh_notfound (w); - rv++; - } - FREE (full_path); - } - return (rv); -} - -/* Print information about current hashed info. */ -static int -print_hash_info (item) - BUCKET_CONTENTS *item; -{ - printf ("%4d\t%s\n", item->times_found, pathdata(item)->path); - return 0; -} - -static int -print_portable_hash_info (item) - BUCKET_CONTENTS *item; -{ - char *fp, *fn; - - fp = printable_filename (pathdata(item)->path, 1); - fn = printable_filename (item->key, 1); - printf ("builtin hash -p %s %s\n", fp, fn); - if (fp != pathdata(item)->path) - free (fp); - if (fn != item->key) - free (fn); - return 0; -} - -static int -print_hashed_commands (fmt) - int fmt; -{ - if (hashed_filenames == 0 || HASH_ENTRIES (hashed_filenames) == 0) - return (0); - - if (fmt == 0) - printf (_("hits\tcommand\n")); - hash_walk (hashed_filenames, fmt ? print_portable_hash_info : print_hash_info); - return (1); -} - -static int -list_hashed_filename_targets (list, fmt) - WORD_LIST *list; - int fmt; -{ - int all_found, multiple; - char *target; - WORD_LIST *l; - - all_found = 1; - multiple = list->next != 0; - - for (l = list; l; l = l->next) - { - target = phash_search (l->word->word); - if (target == 0) - { - all_found = 0; - sh_notfound (l->word->word); - continue; - } - if (fmt) - printf ("builtin hash -p %s %s\n", target, l->word->word); - else - { - if (multiple) - printf ("%s\t", l->word->word); - printf ("%s\n", target); - } - free (target); - } - - return (all_found ? EXECUTION_SUCCESS : EXECUTION_FAILURE); -} diff --git a/third_party/bash/builtins_help.c b/third_party/bash/builtins_help.c deleted file mode 100644 index cbb015c46..000000000 --- a/third_party/bash/builtins_help.c +++ /dev/null @@ -1,512 +0,0 @@ -/* help.c, created from help.def. */ -#line 22 "./help.def" - -#line 45 "./help.def" - -#include "config.h" - -#if defined (HELP_BUILTIN) -#include - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include - -#include "filecntl.h" -#include - -#include "bashintl.h" - -#include "shell.h" -#include "builtins.h" -#include "execute_cmd.h" -#include "pathexp.h" -#include "common.h" -#include "bashgetopt.h" - -#include "strmatch.h" -#include "glob.h" - -#ifndef errno -extern int errno; -#endif - -extern const char * const bash_copyright; -extern const char * const bash_license; - -static void show_builtin_command_help PARAMS((void)); -static int open_helpfile PARAMS((char *)); -static void show_desc PARAMS((char *, int)); -static void show_manpage PARAMS((char *, int)); -static void show_longdoc PARAMS((int)); - -/* Print out a list of the known functions in the shell, and what they do. - If LIST is supplied, print out the list which matches for each pattern - specified. */ -int -help_builtin (list) - WORD_LIST *list; -{ - register int i; - char *pattern, *name; - int plen, match_found, sflag, dflag, mflag, m, pass, this_found; - - dflag = sflag = mflag = 0; - reset_internal_getopt (); - while ((i = internal_getopt (list, "dms")) != -1) - { - switch (i) - { - case 'd': - dflag = 1; - break; - case 'm': - mflag = 1; - break; - case 's': - sflag = 1; - break; - CASE_HELPOPT; - default: - builtin_usage (); - return (EX_USAGE); - } - } - list = loptend; - - if (list == 0) - { - show_shell_version (0); - show_builtin_command_help (); - return (EXECUTION_SUCCESS); - } - - /* We should consider making `help bash' do something. */ - - if (glob_pattern_p (list->word->word) == 1) - { - printf ("%s", ngettext ("Shell commands matching keyword `", "Shell commands matching keywords `", (list->next ? 2 : 1))); - print_word_list (list, ", "); - printf ("%s", _("'\n\n")); - } - - for (match_found = 0, pattern = ""; list; list = list->next) - { - pattern = list->word->word; - plen = strlen (pattern); - - for (pass = 1, this_found = 0; pass < 3; pass++) - { - for (i = 0; name = shell_builtins[i].name; i++) - { - QUIT; - - /* First pass: look for exact string or pattern matches. - Second pass: look for prefix matches like bash-4.2 */ - if (pass == 1) - m = (strcmp (pattern, name) == 0) || - (strmatch (pattern, name, FNMATCH_EXTFLAG) != FNM_NOMATCH); - else - m = strncmp (pattern, name, plen) == 0; - - if (m) - { - this_found = 1; - match_found++; - if (dflag) - { - show_desc (name, i); - continue; - } - else if (mflag) - { - show_manpage (name, i); - continue; - } - - printf ("%s: %s\n", name, _(shell_builtins[i].short_doc)); - - if (sflag == 0) - show_longdoc (i); - } - } - if (pass == 1 && this_found == 1) - break; - } - } - - if (match_found == 0) - { - builtin_error (_("no help topics match `%s'. Try `help help' or `man -k %s' or `info %s'."), pattern, pattern, pattern); - return (EXECUTION_FAILURE); - } - - return (sh_chkwrite (EXECUTION_SUCCESS)); -} - -void -builtin_help () -{ - int ind; - ptrdiff_t d; - - current_builtin = builtin_address_internal (this_command_name, 0); - if (current_builtin == 0) - return; - - d = current_builtin - shell_builtins; - -#if defined (__STDC__) - ind = (int)d; -#else - ind = (int)d / sizeof (struct builtin); -#endif - - printf ("%s: %s\n", this_command_name, _(shell_builtins[ind].short_doc)); - show_longdoc (ind); -} - -static int -open_helpfile (name) - char *name; -{ - int fd; - - fd = open (name, O_RDONLY); - if (fd == -1) - { - builtin_error (_("%s: cannot open: %s"), name, strerror (errno)); - return -1; - } - return fd; -} - -/* By convention, enforced by mkbuiltins.c, if separate help files are being - used, the long_doc array contains one string -- the full pathname of the - help file for this builtin. */ -static void -show_longdoc (i) - int i; -{ - register int j; - char * const *doc; - int fd; - - doc = shell_builtins[i].long_doc; - - if (doc && doc[0] && *doc[0] == '/' && doc[1] == (char *)NULL) - { - fd = open_helpfile (doc[0]); - if (fd < 0) - return; - zcatfd (fd, 1, doc[0]); - close (fd); - } - else if (doc) - for (j = 0; doc[j]; j++) - printf ("%*s%s\n", BASE_INDENT, " ", _(doc[j])); -} - -static void -show_desc (name, i) - char *name; - int i; -{ - register int j, r; - char **doc, *line; - int fd, usefile; - - doc = (char **)shell_builtins[i].long_doc; - - usefile = (doc && doc[0] && *doc[0] == '/' && doc[1] == (char *)NULL); - if (usefile) - { - fd = open_helpfile (doc[0]); - if (fd < 0) - return; - r = zmapfd (fd, &line, doc[0]); - close (fd); - /* XXX - handle errors if zmapfd returns < 0 */ - } - else - line = doc ? doc[0] : (char *)NULL; - - printf ("%s - ", name); - for (j = 0; line && line[j]; j++) - { - putchar (line[j]); - if (line[j] == '\n') - break; - } - - fflush (stdout); - - if (usefile) - free (line); -} - -/* Print builtin help in pseudo-manpage format. */ -static void -show_manpage (name, i) - char *name; - int i; -{ - register int j; - char **doc, *line; - int fd, usefile; - - doc = (char **)shell_builtins[i].long_doc; - - usefile = (doc && doc[0] && *doc[0] == '/' && doc[1] == (char *)NULL); - if (usefile) - { - fd = open_helpfile (doc[0]); - if (fd < 0) - return; - zmapfd (fd, &line, doc[0]); - close (fd); - } - else - line = doc ? _(doc[0]) : (char *)NULL; - - /* NAME */ - printf ("NAME\n"); - printf ("%*s%s - ", BASE_INDENT, " ", name); - for (j = 0; line && line[j]; j++) - { - putchar (line[j]); - if (line[j] == '\n') - break; - } - printf ("\n"); - - /* SYNOPSIS */ - printf ("SYNOPSIS\n"); - printf ("%*s%s\n\n", BASE_INDENT, " ", _(shell_builtins[i].short_doc)); - - /* DESCRIPTION */ - printf ("DESCRIPTION\n"); - if (usefile == 0) - { - for (j = 0; doc[j]; j++) - printf ("%*s%s\n", BASE_INDENT, " ", _(doc[j])); - } - else - { - for (j = 0; line && line[j]; j++) - { - putchar (line[j]); - if (line[j] == '\n') - printf ("%*s", BASE_INDENT, " "); - } - } - putchar ('\n'); - - /* SEE ALSO */ - printf ("SEE ALSO\n"); - printf ("%*sbash(1)\n\n", BASE_INDENT, " "); - - /* IMPLEMENTATION */ - printf ("IMPLEMENTATION\n"); - printf ("%*s", BASE_INDENT, " "); - show_shell_version (0); - printf ("%*s", BASE_INDENT, " "); - printf ("%s\n", _(bash_copyright)); - printf ("%*s", BASE_INDENT, " "); - printf ("%s\n", _(bash_license)); - - fflush (stdout); - if (usefile) - free (line); -} - -static void -dispcolumn (i, buf, bufsize, width, height) - int i; - char *buf; - size_t bufsize; - int width, height; -{ - int j; - int dispcols; - char *helpdoc; - - /* first column */ - helpdoc = _(shell_builtins[i].short_doc); - - buf[0] = (shell_builtins[i].flags & BUILTIN_ENABLED) ? ' ' : '*'; - strncpy (buf + 1, helpdoc, width - 2); - buf[width - 2] = '>'; /* indicate truncation */ - buf[width - 1] = '\0'; - printf ("%s", buf); - if (((i << 1) >= num_shell_builtins) || (i+height >= num_shell_builtins)) - { - printf ("\n"); - return; - } - - dispcols = strlen (buf); - /* two spaces */ - for (j = dispcols; j < width; j++) - putc (' ', stdout); - - /* second column */ - helpdoc = _(shell_builtins[i+height].short_doc); - - buf[0] = (shell_builtins[i+height].flags & BUILTIN_ENABLED) ? ' ' : '*'; - strncpy (buf + 1, helpdoc, width - 3); - buf[width - 3] = '>'; /* indicate truncation */ - buf[width - 2] = '\0'; - - printf ("%s\n", buf); -} - -#if defined (HANDLE_MULTIBYTE) -static void -wdispcolumn (i, buf, bufsize, width, height) - int i; - char *buf; - size_t bufsize; - int width, height; -{ - int j; - int dispcols, dispchars; - char *helpdoc; - wchar_t *wcstr; - size_t slen, n; - - /* first column */ - helpdoc = _(shell_builtins[i].short_doc); - - wcstr = 0; - slen = mbstowcs ((wchar_t *)0, helpdoc, 0); - if (slen == -1) - { - dispcolumn (i, buf, bufsize, width, height); - return; - } - - /* No bigger than the passed max width */ - if (slen >= width) - slen = width - 2; - wcstr = (wchar_t *)xmalloc (sizeof (wchar_t) * (width + 2)); - n = mbstowcs (wcstr+1, helpdoc, slen + 1); - wcstr[n+1] = L'\0'; - - /* Turn tabs and newlines into spaces for column display, since wcwidth - returns -1 for them */ - for (j = 1; j < n; j++) - if (wcstr[j] == L'\n' || wcstr[j] == L'\t') - wcstr[j] = L' '; - - /* dispchars == number of characters that will be displayed */ - dispchars = wcsnwidth (wcstr+1, slen, width - 2); - /* dispcols == number of columns required to display DISPCHARS */ - dispcols = wcswidth (wcstr+1, dispchars) + 1; /* +1 for ' ' or '*' */ - - wcstr[0] = (shell_builtins[i].flags & BUILTIN_ENABLED) ? L' ' : L'*'; - - if (dispcols >= width-2) - { - wcstr[dispchars] = L'>'; /* indicate truncation */ - wcstr[dispchars+1] = L'\0'; - } - - printf ("%ls", wcstr); - if (((i << 1) >= num_shell_builtins) || (i+height >= num_shell_builtins)) - { - printf ("\n"); - free (wcstr); - return; - } - - /* at least one space */ - for (j = dispcols; j < width; j++) - putc (' ', stdout); - - /* second column */ - helpdoc = _(shell_builtins[i+height].short_doc); - slen = mbstowcs ((wchar_t *)0, helpdoc, 0); - if (slen == -1) - { - /* for now */ - printf ("%c%s\n", (shell_builtins[i+height].flags & BUILTIN_ENABLED) ? ' ' : '*', helpdoc); - free (wcstr); - return; - } - - /* Reuse wcstr since it is already width wide chars long */ - if (slen >= width) - slen = width - 2; - n = mbstowcs (wcstr+1, helpdoc, slen + 1); - wcstr[n+1] = L'\0'; /* make sure null-terminated */ - - /* Turn tabs and newlines into spaces for column display */ - for (j = 1; j < n; j++) - if (wcstr[j] == L'\n' || wcstr[j] == L'\t') - wcstr[j] = L' '; - - /* dispchars == number of characters that will be displayed */ - dispchars = wcsnwidth (wcstr+1, slen, width - 2); - dispcols = wcswidth (wcstr+1, dispchars) + 1; /* +1 for ' ' or '*' */ - - wcstr[0] = (shell_builtins[i+height].flags & BUILTIN_ENABLED) ? L' ' : L'*'; - - /* The dispchars-1 is there for terminals that behave strangely when you - have \n in the nth column for terminal width n; this is what bash-4.3 - did. */ - if (dispcols >= width - 2) - { - wcstr[dispchars-1] = L'>'; /* indicate truncation */ - wcstr[dispchars] = L'\0'; - } - - printf ("%ls\n", wcstr); - - free (wcstr); -} -#endif /* HANDLE_MULTIBYTE */ - -static void -show_builtin_command_help () -{ - int i, j; - int height, width; - char *t, blurb[128]; - - printf ( -_("These shell commands are defined internally. Type `help' to see this list.\n\ -Type `help name' to find out more about the function `name'.\n\ -Use `info bash' to find out more about the shell in general.\n\ -Use `man -k' or `info' to find out more about commands not in this list.\n\ -\n\ -A star (*) next to a name means that the command is disabled.\n\ -\n")); - - width = default_columns (); - - width /= 2; - if (width > sizeof (blurb)) - width = sizeof (blurb); - if (width <= 3) - width = 40; - height = (num_shell_builtins + 1) / 2; /* number of rows */ - - for (i = 0; i < height; i++) - { - QUIT; - -#if defined (HANDLE_MULTIBYTE) - if (MB_CUR_MAX > 1) - wdispcolumn (i, blurb, sizeof (blurb), width, height); - else -#endif - dispcolumn (i, blurb, sizeof (blurb), width, height); - } -} -#endif /* HELP_BUILTIN */ diff --git a/third_party/bash/builtins_history.c b/third_party/bash/builtins_history.c deleted file mode 100644 index 7a6a833e1..000000000 --- a/third_party/bash/builtins_history.c +++ /dev/null @@ -1,411 +0,0 @@ -/* history.c, created from history.def. */ -#line 22 "./history.def" - -#line 58 "./history.def" - -#include "config.h" - -#if defined (HISTORY) -#include "bashtypes.h" -#if ! defined(_MINIX) && defined (HAVE_SYS_FILE_H) -# include -#endif -#include "posixstat.h" -#include "filecntl.h" -#include -#include -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "bashansi.h" -#include "bashintl.h" - -#include "shell.h" -#include "flags.h" -#include "parser.h" -#include "bashhist.h" -#include "third_party/readline/history.h" -#include "bashgetopt.h" -#include "common.h" - -#if !defined (errno) -extern int errno; -#endif - -static char *histtime PARAMS((HIST_ENTRY *, const char *)); -static int display_history PARAMS((WORD_LIST *)); -static void push_history PARAMS((WORD_LIST *)); -static int expand_and_print_history PARAMS((WORD_LIST *)); - -#define AFLAG 0x01 -#define RFLAG 0x02 -#define WFLAG 0x04 -#define NFLAG 0x08 -#define SFLAG 0x10 -#define PFLAG 0x20 -#define CFLAG 0x40 -#define DFLAG 0x80 - -#ifndef TIMELEN_MAX -# define TIMELEN_MAX 128 -#endif - -int -history_builtin (list) - WORD_LIST *list; -{ - int flags, opt, result, old_history_lines, obase, ind; - char *filename, *delete_arg, *range; - intmax_t delete_offset; - - flags = 0; - reset_internal_getopt (); - while ((opt = internal_getopt (list, "acd:npsrw")) != -1) - { - switch (opt) - { - case 'a': - flags |= AFLAG; - break; - case 'c': - flags |= CFLAG; - break; - case 'n': - flags |= NFLAG; - break; - case 'r': - flags |= RFLAG; - break; - case 'w': - flags |= WFLAG; - break; - case 's': - flags |= SFLAG; - break; - case 'd': - flags |= DFLAG; - delete_arg = list_optarg; - break; - case 'p': -#if defined (BANG_HISTORY) - flags |= PFLAG; -#endif - break; - CASE_HELPOPT; - default: - builtin_usage (); - return (EX_USAGE); - } - } - list = loptend; - - opt = flags & (AFLAG|RFLAG|WFLAG|NFLAG); - if (opt && opt != AFLAG && opt != RFLAG && opt != WFLAG && opt != NFLAG) - { - builtin_error (_("cannot use more than one of -anrw")); - return (EXECUTION_FAILURE); - } - - /* clear the history, but allow other arguments to add to it again. */ - if (flags & CFLAG) - { - bash_clear_history (); - if (list == 0) - return (EXECUTION_SUCCESS); - } - - if (flags & SFLAG) - { - if (list) - push_history (list); - return (EXECUTION_SUCCESS); - } -#if defined (BANG_HISTORY) - else if (flags & PFLAG) - { - if (list) - return (expand_and_print_history (list)); - return (sh_chkwrite (EXECUTION_SUCCESS)); - } -#endif - else if ((flags & DFLAG) && (range = strchr ((delete_arg[0] == '-') ? delete_arg + 1 : delete_arg, '-'))) - { - intmax_t delete_start, delete_end; - *range++ = '\0'; - if (legal_number (delete_arg, &delete_start) == 0 || legal_number (range, &delete_end) == 0) - { - range[-1] = '-'; - sh_erange (delete_arg, _("history position")); - return (EXECUTION_FAILURE); - } - if (delete_arg[0] == '-' && delete_start < 0) - /* the_history[history_length] == 0x0, so this is correct */ - delete_start += history_length; - /* numbers as displayed by display_history are offset by history_base */ - else if (delete_start > 0) - delete_start -= history_base; - - if (delete_start < 0 || delete_start >= history_length) - { - sh_erange (delete_arg, _("history position")); - return (EXECUTION_FAILURE); - } - - if (range[0] == '-' && delete_end < 0) - delete_end += history_length; - else if (delete_end > 0) - delete_end -= history_base; - - if (delete_end < 0 || delete_end >= history_length) - { - sh_erange (range, _("history position")); - return (EXECUTION_FAILURE); - } - /* XXX - print error if end < start? */ - result = bash_delete_history_range (delete_start, delete_end); - if (where_history () > history_length) - history_set_pos (history_length); - return (result ? EXECUTION_SUCCESS : EXECUTION_FAILURE); - } - else if (flags & DFLAG) - { - if (legal_number (delete_arg, &delete_offset) == 0) - { - sh_erange (delete_arg, _("history position")); - return (EXECUTION_FAILURE); - } - /* check for negative offsets, count back from end of list */ - if (delete_arg[0] == '-' && delete_offset < 0) - { - /* since the_history[history_length] == 0x0, this calculation means - that history -d -1 will delete the last history entry, which at - this point is the history -d -1 we just added. */ - ind = history_length + delete_offset; - if (ind < 0) /* offset by history_base below */ - { - sh_erange (delete_arg, _("history position")); - return (EXECUTION_FAILURE); - } - opt = ind + history_base; /* compensate for opt - history_base below */ - } - else if ((delete_offset < history_base) || (delete_offset >= (history_base + history_length))) - { - sh_erange (delete_arg, _("history position")); - return (EXECUTION_FAILURE); - } - else - opt = delete_offset; - - /* Positive arguments from numbers as displayed by display_history need - to be offset by history_base */ - result = bash_delete_histent (opt - history_base); - /* Since remove_history changes history_length, this can happen if - we delete the last history entry. */ - if (where_history () > history_length) - history_set_pos (history_length); - return (result ? EXECUTION_SUCCESS : EXECUTION_FAILURE); - } - else if ((flags & (AFLAG|RFLAG|NFLAG|WFLAG|CFLAG)) == 0) - { - result = display_history (list); - return (sh_chkwrite (result)); - } - - filename = list ? list->word->word : get_string_value ("HISTFILE"); - result = EXECUTION_SUCCESS; - -#if defined (RESTRICTED_SHELL) - if (restricted && strchr (filename, '/')) - { - sh_restricted (filename); - return (EXECUTION_FAILURE); - } -#endif - - if (flags & AFLAG) /* Append session's history to file. */ - result = maybe_append_history (filename); - else if (flags & WFLAG) /* Write entire history. */ - result = write_history (filename); - else if (flags & RFLAG) /* Read entire file. */ - { - result = read_history (filename); - history_lines_in_file = history_lines_read_from_file; - /* history_lines_in_file = where_history () + history_base - 1; */ - } - else if (flags & NFLAG) /* Read `new' history from file. */ - { - /* Read all of the lines in the file that we haven't already read. */ - old_history_lines = history_lines_in_file; - obase = history_base; - - using_history (); - result = read_history_range (filename, history_lines_in_file, -1); - using_history (); - - history_lines_in_file = history_lines_read_from_file; - /* history_lines_in_file = where_history () + history_base - 1; */ - - /* If we're rewriting the history file at shell exit rather than just - appending the lines from this session to it, the question is whether - we reset history_lines_this_session to 0, losing any history entries - we had before we read the new entries from the history file, or - whether we count the new entries we just read from the file as - history lines added during this session. - Right now, we do the latter. This will cause these history entries - to be written to the history file along with any intermediate entries - we add when we do a `history -a', but the alternative is losing - them altogether. */ - if (force_append_history == 0) - history_lines_this_session += history_lines_in_file - old_history_lines + - history_base - obase; - } - - return (result ? EXECUTION_FAILURE : EXECUTION_SUCCESS); -} - -/* Accessors for HIST_ENTRY lists that are called HLIST. */ -#define histline(i) (hlist[(i)]->line) -#define histdata(i) (hlist[(i)]->data) - -static char * -histtime (hlist, histtimefmt) - HIST_ENTRY *hlist; - const char *histtimefmt; -{ - static char timestr[TIMELEN_MAX]; - time_t t; - struct tm *tm; - - t = history_get_time (hlist); - tm = t ? localtime (&t) : 0; - if (t && tm) - strftime (timestr, sizeof (timestr), histtimefmt, tm); - else if (hlist->timestamp && hlist->timestamp[0]) - snprintf (timestr, sizeof (timestr), _("%s: invalid timestamp"), - (hlist->timestamp[0] == '#') ? hlist->timestamp + 1: hlist->timestamp); - else - strcpy (timestr, "??"); - return timestr; -} - -static int -display_history (list) - WORD_LIST *list; -{ - register int i; - intmax_t limit; - HIST_ENTRY **hlist; - char *histtimefmt, *timestr; - - if (list) - { - if (get_numeric_arg (list, 0, &limit) == 0) - return (EXECUTION_FAILURE); - - if (limit < 0) - limit = -limit; - } - else - limit = -1; - - hlist = history_list (); - - if (hlist) - { - for (i = 0; hlist[i]; i++) - ; - - if (0 <= limit && limit < i) - i -= limit; - else - i = 0; - - histtimefmt = get_string_value ("HISTTIMEFORMAT"); - - while (hlist[i]) - { - QUIT; - - timestr = (histtimefmt && *histtimefmt) ? histtime (hlist[i], histtimefmt) : (char *)NULL; - printf ("%5d%c %s%s\n", i + history_base, - histdata(i) ? '*' : ' ', - ((timestr && *timestr) ? timestr : ""), - histline(i)); - i++; - } - } - - return (EXECUTION_SUCCESS); -} - -/* Remove the last entry in the history list and add each argument in - LIST to the history. */ -static void -push_history (list) - WORD_LIST *list; -{ - char *s; - - /* Delete the last history entry if it was a single entry added to the - history list (generally the `history -s' itself), or if `history -s' - is being used in a compound command and the compound command was - added to the history as a single element (command-oriented history). - If you don't want history -s to remove the compound command from the - history, change #if 0 to #if 1 below. */ -#if 0 - if (remember_on_history && hist_last_line_pushed == 0 && - hist_last_line_added && bash_delete_last_history () == 0) -#else - if (remember_on_history && hist_last_line_pushed == 0 && - (hist_last_line_added || - (current_command_line_count > 0 && current_command_first_line_saved && command_oriented_history)) - && bash_delete_last_history () == 0) -#endif - return; - - s = string_list (list); - /* Call check_add_history with FORCE set to 1 to skip the check against - current_command_line_count. If history -s is used in a compound - command, the above code will delete the compound command's history - entry and this call will add the line to the history as a separate - entry. Without FORCE=1, if current_command_line_count were > 1, the - line would be appended to the entry before the just-deleted entry. */ - check_add_history (s, 1); /* obeys HISTCONTROL, HISTIGNORE */ - - hist_last_line_pushed = 1; /* XXX */ - free (s); -} - -#if defined (BANG_HISTORY) -static int -expand_and_print_history (list) - WORD_LIST *list; -{ - char *s; - int r, result; - - if (hist_last_line_pushed == 0 && hist_last_line_added && bash_delete_last_history () == 0) - return EXECUTION_FAILURE; - result = EXECUTION_SUCCESS; - while (list) - { - r = history_expand (list->word->word, &s); - if (r < 0) - { - builtin_error (_("%s: history expansion failed"), list->word->word); - result = EXECUTION_FAILURE; - } - else - { - fputs (s, stdout); - putchar ('\n'); - } - FREE (s); - list = list->next; - } - fflush (stdout); - return result; -} -#endif /* BANG_HISTORY */ -#endif /* HISTORY */ diff --git a/third_party/bash/builtins_jobs.c b/third_party/bash/builtins_jobs.c deleted file mode 100644 index e8cd2eec0..000000000 --- a/third_party/bash/builtins_jobs.c +++ /dev/null @@ -1,240 +0,0 @@ -/* jobs.c, created from jobs.def. */ -#line 22 "./jobs.def" - -#line 48 "./jobs.def" - -#include "config.h" - -#if defined (JOB_CONTROL) -#include "bashtypes.h" -#include -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "bashansi.h" -#include "bashintl.h" - -#include "shell.h" -#include "jobs.h" -#include "execute_cmd.h" -#include "bashgetopt.h" -#include "common.h" - -#define JSTATE_ANY 0x0 -#define JSTATE_RUNNING 0x1 -#define JSTATE_STOPPED 0x2 - -static int execute_list_with_replacements PARAMS((WORD_LIST *)); - -/* The `jobs' command. Prints outs a list of active jobs. If the - argument `-l' is given, then the process id's are printed also. - If the argument `-p' is given, print the process group leader's - pid only. If `-n' is given, only processes that have changed - status since the last notification are printed. If -x is given, - replace all job specs with the pid of the appropriate process - group leader and execute the command. The -r and -s options mean - to print info about running and stopped jobs only, respectively. */ -int -jobs_builtin (list) - WORD_LIST *list; -{ - int form, execute, state, opt, any_failed, job; - sigset_t set, oset; - - execute = any_failed = 0; - form = JLIST_STANDARD; - state = JSTATE_ANY; - - reset_internal_getopt (); - while ((opt = internal_getopt (list, "lpnxrs")) != -1) - { - switch (opt) - { - case 'l': - form = JLIST_LONG; - break; - case 'p': - form = JLIST_PID_ONLY; - break; - case 'n': - form = JLIST_CHANGED_ONLY; - break; - case 'x': - if (form != JLIST_STANDARD) - { - builtin_error (_("no other options allowed with `-x'")); - return (EXECUTION_FAILURE); - } - execute++; - break; - case 'r': - state = JSTATE_RUNNING; - break; - case 's': - state = JSTATE_STOPPED; - break; - - CASE_HELPOPT; - default: - builtin_usage (); - return (EX_USAGE); - } - } - - list = loptend; - - if (execute) - return (execute_list_with_replacements (list)); - - if (!list) - { - switch (state) - { - case JSTATE_ANY: - list_all_jobs (form); - break; - case JSTATE_RUNNING: - list_running_jobs (form); - break; - case JSTATE_STOPPED: - list_stopped_jobs (form); - break; - } - return (EXECUTION_SUCCESS); - } - - while (list) - { - BLOCK_CHILD (set, oset); - job = get_job_spec (list); - - if ((job == NO_JOB) || jobs == 0 || get_job_by_jid (job) == 0) - { - sh_badjob (list->word->word); - any_failed++; - } - else if (job != DUP_JOB) - list_one_job ((JOB *)NULL, form, 0, job); - - UNBLOCK_CHILD (oset); - list = list->next; - } - return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS); -} - -static int -execute_list_with_replacements (list) - WORD_LIST *list; -{ - register WORD_LIST *l; - int job, result; - COMMAND *command; - JOB *j; - - /* First do the replacement of job specifications with pids. */ - for (l = list; l; l = l->next) - { - if (l->word->word[0] == '%') /* we have a winner */ - { - job = get_job_spec (l); - - /* A bad job spec is not really a job spec! Pass it through. */ - if (INVALID_JOB (job)) - continue; - - j = get_job_by_jid (job); - free (l->word->word); - l->word->word = itos (j->pgrp); - } - } - - /* Next make a new simple command and execute it. */ - begin_unwind_frame ("jobs_builtin"); - - command = make_bare_simple_command (); - command->value.Simple->words = copy_word_list (list); - command->value.Simple->redirects = (REDIRECT *)NULL; - command->flags |= CMD_INHIBIT_EXPANSION; - command->value.Simple->flags |= CMD_INHIBIT_EXPANSION; - - add_unwind_protect (dispose_command, command); - result = execute_command (command); - dispose_command (command); - - discard_unwind_frame ("jobs_builtin"); - return (result); -} -#endif /* JOB_CONTROL */ - -#line 231 "./jobs.def" - -#if defined (JOB_CONTROL) -int -disown_builtin (list) - WORD_LIST *list; -{ - int opt, job, retval, nohup_only, running_jobs, all_jobs; - sigset_t set, oset; - intmax_t pid_value; - - nohup_only = running_jobs = all_jobs = 0; - reset_internal_getopt (); - while ((opt = internal_getopt (list, "ahr")) != -1) - { - switch (opt) - { - case 'a': - all_jobs = 1; - break; - case 'h': - nohup_only = 1; - break; - case 'r': - running_jobs = 1; - break; - CASE_HELPOPT; - default: - builtin_usage (); - return (EX_USAGE); - } - } - list = loptend; - retval = EXECUTION_SUCCESS; - - /* `disown -a' or `disown -r' */ - if (list == 0 && (all_jobs || running_jobs)) - { - if (nohup_only) - nohup_all_jobs (running_jobs); - else - delete_all_jobs (running_jobs); - return (EXECUTION_SUCCESS); - } - - do - { - BLOCK_CHILD (set, oset); - job = (list && legal_number (list->word->word, &pid_value) && pid_value == (pid_t) pid_value) - ? get_job_by_pid ((pid_t) pid_value, 0, 0) - : get_job_spec (list); - - if (job == NO_JOB || jobs == 0 || INVALID_JOB (job)) - { - sh_badjob (list ? list->word->word : _("current")); - retval = EXECUTION_FAILURE; - } - else if (nohup_only) - nohup_job (job); - else - delete_job (job, 1); - UNBLOCK_CHILD (oset); - - if (list) - list = list->next; - } - while (list); - - return (retval); -} -#endif /* JOB_CONTROL */ diff --git a/third_party/bash/builtins_kill.c b/third_party/bash/builtins_kill.c deleted file mode 100644 index 8a1e73de1..000000000 --- a/third_party/bash/builtins_kill.c +++ /dev/null @@ -1,235 +0,0 @@ -/* kill.c, created from kill.def. */ -#line 22 "./kill.def" - -#line 46 "./kill.def" - -#include "config.h" - -#include -#include -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include "bashansi.h" -#include "bashintl.h" - -#include - -#include "shell.h" -#include "trap.h" -#include "jobs.h" -#include "common.h" - -/* Not all systems declare ERRNO in errno.h... and some systems #define it! */ -#if !defined (errno) -extern int errno; -#endif /* !errno */ - -static void kill_error PARAMS((pid_t, int)); - -#if !defined (CONTINUE_AFTER_KILL_ERROR) -# define CONTINUE_OR_FAIL return (EXECUTION_FAILURE) -#else -# define CONTINUE_OR_FAIL goto continue_killing -#endif /* CONTINUE_AFTER_KILL_ERROR */ - -/* Here is the kill builtin. We only have it so that people can type - kill -KILL %1? No, if you fill up the process table this way you - can still kill some. */ -int -kill_builtin (list) - WORD_LIST *list; -{ - int sig, any_succeeded, listing, saw_signal, dflags; - char *sigspec, *word; - pid_t pid; - intmax_t pid_value; - - if (list == 0) - { - builtin_usage (); - return (EX_USAGE); - } - CHECK_HELPOPT (list); - - any_succeeded = listing = saw_signal = 0; - sig = SIGTERM; - sigspec = "TERM"; - - dflags = DSIG_NOCASE | ((posixly_correct == 0) ? DSIG_SIGPREFIX : 0); - /* Process options. */ - while (list) - { - word = list->word->word; - - if (ISOPTION (word, 'l') || ISOPTION (word, 'L')) - { - listing++; - list = list->next; - } - else if (ISOPTION (word, 's') || ISOPTION (word, 'n')) - { - list = list->next; - if (list) - { - sigspec = list->word->word; -use_sigspec: - if (sigspec[0] == '0' && sigspec[1] == '\0') - sig = 0; - else - sig = decode_signal (sigspec, dflags); - list = list->next; - saw_signal++; - } - else - { - sh_needarg (word); - return (EXECUTION_FAILURE); - } - } - else if (word[0] == '-' && word[1] == 's' && ISALPHA (word[2])) - { - sigspec = word + 2; - goto use_sigspec; - } - else if (word[0] == '-' && word[1] == 'n' && ISDIGIT (word[2])) - { - sigspec = word + 2; - goto use_sigspec; - } - else if (ISOPTION (word, '-')) - { - list = list->next; - break; - } - else if (ISOPTION (word, '?')) - { - builtin_usage (); - return (EX_USAGE); - } - /* If this is a signal specification then process it. We only process - the first one seen; other arguments may signify process groups (e.g, - -num == process group num). */ - else if (*word == '-' && saw_signal == 0) - { - sigspec = word + 1; - sig = decode_signal (sigspec, dflags); - saw_signal++; - list = list->next; - } - else - break; - } - - if (listing) - return (display_signal_list (list, 0)); - - /* OK, we are killing processes. */ - if (sig == NO_SIG) - { - sh_invalidsig (sigspec); - return (EXECUTION_FAILURE); - } - - if (list == 0) - { - builtin_usage (); - return (EX_USAGE); - } - - while (list) - { - word = list->word->word; - - if (*word == '-') - word++; - - /* Use the entire argument in case of minus sign presence. */ - if (*word && legal_number (list->word->word, &pid_value) && (pid_value == (pid_t)pid_value)) - { - pid = (pid_t) pid_value; - - if (kill_pid (pid, sig, pid < -1) < 0) - { - if (errno == EINVAL) - sh_invalidsig (sigspec); - else - kill_error (pid, errno); - CONTINUE_OR_FAIL; - } - else - any_succeeded++; - } -#if defined (JOB_CONTROL) - else if (*list->word->word && *list->word->word != '%') - { - builtin_error (_("%s: arguments must be process or job IDs"), list->word->word); - CONTINUE_OR_FAIL; - } - else if (*word) - /* Posix.2 says you can kill without job control active (4.32.4) */ - { /* Must be a job spec. Check it out. */ - int job; - sigset_t set, oset; - JOB *j; - - BLOCK_CHILD (set, oset); - job = get_job_spec (list); - - if (INVALID_JOB (job)) - { - if (job != DUP_JOB) - sh_badjob (list->word->word); - UNBLOCK_CHILD (oset); - CONTINUE_OR_FAIL; - } - - j = get_job_by_jid (job); - /* Job spec used. Kill the process group. If the job was started - without job control, then its pgrp == shell_pgrp, so we have - to be careful. We take the pid of the first job in the pipeline - in that case. */ - pid = IS_JOBCONTROL (job) ? j->pgrp : j->pipe->pid; - - UNBLOCK_CHILD (oset); - - if (kill_pid (pid, sig, 1) < 0) - { - if (errno == EINVAL) - sh_invalidsig (sigspec); - else - kill_error (pid, errno); - CONTINUE_OR_FAIL; - } - else - any_succeeded++; - } -#endif /* !JOB_CONTROL */ - else - { - sh_badpid (list->word->word); - CONTINUE_OR_FAIL; - } - continue_killing: - list = list->next; - } - - return (any_succeeded ? EXECUTION_SUCCESS : EXECUTION_FAILURE); -} - -static void -kill_error (pid, e) - pid_t pid; - int e; -{ - char *x; - - x = strerror (e); - if (x == 0) - x = _("Unknown error"); - builtin_error ("(%ld) - %s", (long)pid, x); -} diff --git a/third_party/bash/builtins_let.c b/third_party/bash/builtins_let.c deleted file mode 100644 index ae2971270..000000000 --- a/third_party/bash/builtins_let.c +++ /dev/null @@ -1,68 +0,0 @@ -/* let.c, created from let.def. */ -#line 66 "./let.def" - -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include "bashintl.h" - -#include "shell.h" -#include "common.h" - -/* Arithmetic LET function. */ -int -let_builtin (list) - WORD_LIST *list; -{ - intmax_t ret; - int expok; - - CHECK_HELPOPT (list); - - /* Skip over leading `--' argument. */ - if (list && list->word && ISOPTION (list->word->word, '-')) - list = list->next; - - if (list == 0) - { - builtin_error (_("expression expected")); - return (EXECUTION_FAILURE); - } - - for (; list; list = list->next) - { - ret = evalexp (list->word->word, EXP_EXPANDED, &expok); - if (expok == 0) - return (EXECUTION_FAILURE); - } - - return ((ret == 0) ? EXECUTION_FAILURE : EXECUTION_SUCCESS); -} - -#ifdef INCLUDE_UNUSED -int -exp_builtin (list) - WORD_LIST *list; -{ - char *exp; - intmax_t ret; - int expok; - - if (list == 0) - { - builtin_error (_("expression expected")); - return (EXECUTION_FAILURE); - } - - exp = string_list (list); - ret = evalexp (exp, EXP_EXPANDED, &expok); - (void)free (exp); - return (((ret == 0) || (expok == 0)) ? EXECUTION_FAILURE : EXECUTION_SUCCESS); -} -#endif diff --git a/third_party/bash/builtins_mapfile.c b/third_party/bash/builtins_mapfile.c deleted file mode 100644 index 2ceafffea..000000000 --- a/third_party/bash/builtins_mapfile.c +++ /dev/null @@ -1,304 +0,0 @@ -/* mapfile.c, created from mapfile.def. */ -#line 23 "./mapfile.def" - -#line 59 "./mapfile.def" - -#line 67 "./mapfile.def" - -#include "config.h" - -#include "builtins.h" -#include "bashtypes.h" -#include "posixstat.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "bashansi.h" -#include "bashintl.h" - -#include -#include - -#include "bashintl.h" -#include "shell.h" -#include "common.h" -#include "bashgetopt.h" - -#if !defined (errno) -extern int errno; -#endif - -#if defined (ARRAY_VARS) - -static int run_callback PARAMS((const char *, unsigned int, const char *)); - -#define DEFAULT_ARRAY_NAME "MAPFILE" -#define DEFAULT_VARIABLE_NAME "MAPLINE" /* not used right now */ - -/* The value specifying how frequently `mapfile' calls the callback. */ -#define DEFAULT_QUANTUM 5000 - -/* Values for FLAGS */ -#define MAPF_CLEARARRAY 0x01 -#define MAPF_CHOP 0x02 - -static int delim; - -static int -run_callback (callback, curindex, curline) - const char *callback; - unsigned int curindex; - const char *curline; -{ - unsigned int execlen; - char *execstr, *qline; - int flags; - - qline = sh_single_quote (curline); - execlen = strlen (callback) + strlen (qline) + 10; - /* 1 for each space between %s and %d, - another 1 for the last nul char for C string. */ - execlen += 3; - execstr = xmalloc (execlen); - - flags = SEVAL_NOHIST; -#if 0 - if (interactive) - flags |= SEVAL_INTERACT; -#endif - snprintf (execstr, execlen, "%s %d %s", callback, curindex, qline); - free (qline); - return evalstring (execstr, NULL, flags); -} - -static void -do_chop(line, delim) - char *line; - unsigned char delim; -{ - int length; - - length = strlen (line); - if (length && (unsigned char)line[length-1] == delim) - line[length-1] = '\0'; -} - -static int -mapfile (fd, line_count_goal, origin, nskip, callback_quantum, callback, array_name, delim, flags) - int fd; - long line_count_goal, origin, nskip, callback_quantum; - char *callback, *array_name; - int delim; - int flags; -{ - char *line; - size_t line_length; - unsigned int array_index, line_count; - SHELL_VAR *entry; - struct stat sb; - int unbuffered_read; - - line = NULL; - line_length = 0; - unbuffered_read = 0; - - /* The following check should be done before reading any lines. Doing it - here allows us to call bind_array_element instead of bind_array_variable - and skip the variable lookup on every call. */ - entry = builtin_find_indexed_array (array_name, flags & MAPF_CLEARARRAY); - if (entry == 0) - return EXECUTION_FAILURE; - -#ifndef __CYGWIN__ - /* If the delimiter is a newline, turn on unbuffered reads for pipes - (terminals are ok). If the delimiter is not a newline, unbuffered reads - for every file descriptor that's not a regular file. */ - if (delim == '\n') - unbuffered_read = (lseek (fd, 0L, SEEK_CUR) < 0) && (errno == ESPIPE); - else - unbuffered_read = (fstat (fd, &sb) != 0) || (S_ISREG (sb.st_mode) == 0); -#else - unbuffered_read = 1; -#endif - - zreset (); - - /* Skip any lines at beginning of file? */ - for (line_count = 0; line_count < nskip; line_count++) - if (zgetline (fd, &line, &line_length, delim, unbuffered_read) < 0) - break; - - line = 0; - line_length = 0; - - /* Reset the buffer for bash own stream */ - for (array_index = origin, line_count = 1; - zgetline (fd, &line, &line_length, delim, unbuffered_read) != -1; - array_index++) - { - /* Remove trailing newlines? */ - if (flags & MAPF_CHOP) - do_chop (line, delim); - - /* Has a callback been registered and if so is it time to call it? */ - if (callback && line_count && (line_count % callback_quantum) == 0) - { - /* Reset the buffer for bash own stream. */ - if (unbuffered_read == 0) - zsyncfd (fd); - - run_callback (callback, array_index, line); - } - - /* XXX - bad things can happen if the callback modifies ENTRY, e.g., - unsetting it or changing it to a non-indexed-array type. */ - bind_array_element (entry, array_index, line, 0); - - /* Have we exceeded # of lines to store? */ - line_count++; - if (line_count_goal != 0 && line_count > line_count_goal) - break; - } - - free (line); - - if (unbuffered_read == 0) - zsyncfd (fd); - - return EXECUTION_SUCCESS; -} - -int -mapfile_builtin (list) - WORD_LIST *list; -{ - int opt, code, fd, flags; - intmax_t intval; - long lines, origin, nskip, callback_quantum; - char *array_name, *callback; - - fd = 0; - lines = origin = nskip = 0; - flags = MAPF_CLEARARRAY; - callback_quantum = DEFAULT_QUANTUM; - callback = 0; - delim = '\n'; - - reset_internal_getopt (); - while ((opt = internal_getopt (list, "d:u:n:O:tC:c:s:")) != -1) - { - switch (opt) - { - case 'd': - delim = *list_optarg; - break; - case 'u': - code = legal_number (list_optarg, &intval); - if (code == 0 || intval < 0 || intval != (int)intval) - { - builtin_error (_("%s: invalid file descriptor specification"), list_optarg); - return (EXECUTION_FAILURE); - } - else - fd = intval; - - if (sh_validfd (fd) == 0) - { - builtin_error (_("%d: invalid file descriptor: %s"), fd, strerror (errno)); - return (EXECUTION_FAILURE); - } - break; - - case 'n': - code = legal_number (list_optarg, &intval); - if (code == 0 || intval < 0 || intval != (unsigned)intval) - { - builtin_error (_("%s: invalid line count"), list_optarg); - return (EXECUTION_FAILURE); - } - else - lines = intval; - break; - - case 'O': - code = legal_number (list_optarg, &intval); - if (code == 0 || intval < 0 || intval != (unsigned)intval) - { - builtin_error (_("%s: invalid array origin"), list_optarg); - return (EXECUTION_FAILURE); - } - else - origin = intval; - flags &= ~MAPF_CLEARARRAY; - break; - case 't': - flags |= MAPF_CHOP; - break; - case 'C': - callback = list_optarg; - break; - case 'c': - code = legal_number (list_optarg, &intval); - if (code == 0 || intval <= 0 || intval != (unsigned)intval) - { - builtin_error (_("%s: invalid callback quantum"), list_optarg); - return (EXECUTION_FAILURE); - } - else - callback_quantum = intval; - break; - case 's': - code = legal_number (list_optarg, &intval); - if (code == 0 || intval < 0 || intval != (unsigned)intval) - { - builtin_error (_("%s: invalid line count"), list_optarg); - return (EXECUTION_FAILURE); - } - else - nskip = intval; - break; - CASE_HELPOPT; - default: - builtin_usage (); - return (EX_USAGE); - } - } - list = loptend; - - if (list == 0) - array_name = DEFAULT_ARRAY_NAME; - else if (list->word == 0 || list->word->word == 0) - { - builtin_error ("internal error: getting variable name"); - return (EXECUTION_FAILURE); - } - else if (list->word->word[0] == '\0') - { - builtin_error (_("empty array variable name")); - return (EX_USAGE); - } - else - array_name = list->word->word; - - if (legal_identifier (array_name) == 0) - { - sh_invalidid (array_name); - return (EXECUTION_FAILURE); - } - - return mapfile (fd, lines, origin, nskip, callback_quantum, callback, array_name, delim, flags); -} - -#else - -int -mapfile_builtin (list) - WORD_LIST *list; -{ - builtin_error (_("array variable support required")); - return (EXECUTION_FAILURE); -} - -#endif /* ARRAY_VARS */ diff --git a/third_party/bash/builtins_printf.c b/third_party/bash/builtins_printf.c deleted file mode 100644 index 2ec4e1ba8..000000000 --- a/third_party/bash/builtins_printf.c +++ /dev/null @@ -1,1303 +0,0 @@ -/* printf.c, created from printf.def. */ -#line 22 "./printf.def" - -#line 57 "./printf.def" - -#include "config.h" - -#include "bashtypes.h" - -#include -#if defined (HAVE_LIMITS_H) -# include -#else - /* Assume 32-bit ints. */ -# define INT_MAX 2147483647 -# define INT_MIN (-2147483647-1) -#endif - -#if defined (PREFER_STDARG) -# include -#else -# include -#endif - -#include -#include "chartypes.h" - -#ifdef HAVE_INTTYPES_H -# include -#endif - -#include "posixtime.h" -#include "bashansi.h" -#include "bashintl.h" - -#define NEED_STRFTIME_DECL - -#include "shell.h" -#include "shmbutil.h" -#include "stdc.h" -#include "bashgetopt.h" -#include "common.h" - -#if defined (PRI_MACROS_BROKEN) -# undef PRIdMAX -#endif - -#if !defined (PRIdMAX) -# if HAVE_LONG_LONG -# define PRIdMAX "lld" -# else -# define PRIdMAX "ld" -# endif -#endif - -#if !defined (errno) -extern int errno; -#endif - -#define PC(c) \ - do { \ - char b[2]; \ - tw++; \ - b[0] = c; b[1] = '\0'; \ - if (vflag) \ - vbadd (b, 1); \ - else \ - putchar (c); \ - QUIT; \ - } while (0) - -#define PF(f, func) \ - do { \ - int nw; \ - clearerr (stdout); \ - if (have_fieldwidth && have_precision) \ - nw = vflag ? vbprintf (f, fieldwidth, precision, func) : printf (f, fieldwidth, precision, func); \ - else if (have_fieldwidth) \ - nw = vflag ? vbprintf (f, fieldwidth, func) : printf (f, fieldwidth, func); \ - else if (have_precision) \ - nw = vflag ? vbprintf (f, precision, func) : printf (f, precision, func); \ - else \ - nw = vflag ? vbprintf (f, func) : printf (f, func); \ - tw += nw; \ - QUIT; \ - if (ferror (stdout)) \ - { \ - sh_wrerror (); \ - clearerr (stdout); \ - return (EXECUTION_FAILURE); \ - } \ - } while (0) - -/* We free the buffer used by mklong() if it's `too big'. */ -#define PRETURN(value) \ - do \ - { \ - QUIT; \ - if (vflag) \ - { \ - SHELL_VAR *v; \ - v = builtin_bind_variable (vname, vbuf, bindflags); \ - stupidly_hack_special_variables (vname); \ - if (v == 0 || readonly_p (v) || noassign_p (v)) \ - return (EXECUTION_FAILURE); \ - } \ - if (conv_bufsize > 4096 ) \ - { \ - free (conv_buf); \ - conv_bufsize = 0; \ - conv_buf = 0; \ - } \ - if (vbsize > 4096) \ - { \ - free (vbuf); \ - vbsize = 0; \ - vbuf = 0; \ - } \ - else if (vbuf) \ - vbuf[0] = 0; \ - if (ferror (stdout) == 0) \ - fflush (stdout); \ - QUIT; \ - if (ferror (stdout)) \ - { \ - sh_wrerror (); \ - clearerr (stdout); \ - return (EXECUTION_FAILURE); \ - } \ - return (value); \ - } \ - while (0) - -#define SKIP1 "#'-+ 0" -#define LENMODS "hjlLtz" - -#ifndef TIMELEN_MAX -# define TIMELEN_MAX 128 -#endif - -extern time_t shell_start_time; - -#if !HAVE_ASPRINTF -extern int asprintf PARAMS((char **, const char *, ...)) __attribute__((__format__ (printf, 2, 3))); -#endif - -#if !HAVE_VSNPRINTF -extern int vsnprintf PARAMS((char *, size_t, const char *, va_list)) __attribute__((__format__ (printf, 3, 0))); -#endif - -static void printf_erange PARAMS((char *)); -static int printstr PARAMS((char *, char *, int, int, int)); -static int tescape PARAMS((char *, char *, int *, int *)); -static char *bexpand PARAMS((char *, int, int *, int *)); -static char *vbadd PARAMS((char *, int)); -static int vbprintf PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); -static char *mklong PARAMS((char *, char *, size_t)); -static int getchr PARAMS((void)); -static char *getstr PARAMS((void)); -static int getint PARAMS((void)); -static intmax_t getintmax PARAMS((void)); -static uintmax_t getuintmax PARAMS((void)); - -#if defined (HAVE_LONG_DOUBLE) && HAVE_DECL_STRTOLD && !defined(STRTOLD_BROKEN) -typedef long double floatmax_t; -# define USE_LONG_DOUBLE 1 -# define FLOATMAX_CONV "L" -# define strtofltmax strtold -#else -typedef double floatmax_t; -# define USE_LONG_DOUBLE 0 -# define FLOATMAX_CONV "" -# define strtofltmax strtod -#endif -static double getdouble PARAMS((void)); -static floatmax_t getfloatmax PARAMS((void)); - -static intmax_t asciicode PARAMS((void)); - -static WORD_LIST *garglist, *orig_arglist; -static int retval; -static int conversion_error; - -/* printf -v var support */ -static int vflag = 0; -static int bindflags = 0; -static char *vbuf, *vname; -static size_t vbsize; -static int vblen; - -static intmax_t tw; - -static char *conv_buf; -static size_t conv_bufsize; - -int -printf_builtin (list) - WORD_LIST *list; -{ - int ch, fieldwidth, precision; - int have_fieldwidth, have_precision, use_Lmod, altform; - char convch, thisch, nextch, *format, *modstart, *precstart, *fmt, *start; -#if defined (HANDLE_MULTIBYTE) - char mbch[25]; /* 25 > MB_LEN_MAX, plus can handle 4-byte UTF-8 and large Unicode characters*/ - int mbind, mblen; -#endif -#if defined (ARRAY_VARS) - int arrayflags; -#endif - - conversion_error = 0; - vflag = 0; - - reset_internal_getopt (); - while ((ch = internal_getopt (list, "v:")) != -1) - { - switch (ch) - { - case 'v': - vname = list_optarg; - bindflags = 0; -#if defined (ARRAY_VARS) - SET_VFLAGS (list_optflags, arrayflags, bindflags); - retval = legal_identifier (vname) || valid_array_reference (vname, arrayflags); -#else - retval = legal_identifier (vname); -#endif - if (retval) - { - vflag = 1; - if (vbsize == 0) - vbuf = xmalloc (vbsize = 16); - vblen = 0; - if (vbuf) - vbuf[0] = 0; - } - else - { - sh_invalidid (vname); - return (EX_USAGE); - } - break; - CASE_HELPOPT; - default: - builtin_usage (); - return (EX_USAGE); - } - } - list = loptend; /* skip over possible `--' */ - - if (list == 0) - { - builtin_usage (); - return (EX_USAGE); - } - - /* Allow printf -v var "" to act like var="" */ - if (vflag && list->word->word && list->word->word[0] == '\0') - { - SHELL_VAR *v; - v = builtin_bind_variable (vname, "", 0); - stupidly_hack_special_variables (vname); - return ((v == 0 || readonly_p (v) || noassign_p (v)) ? EXECUTION_FAILURE : EXECUTION_SUCCESS); - } - - if (list->word->word == 0 || list->word->word[0] == '\0') - return (EXECUTION_SUCCESS); - - format = list->word->word; - tw = 0; - retval = EXECUTION_SUCCESS; - - garglist = orig_arglist = list->next; - - /* If the format string is empty after preprocessing, return immediately. */ - if (format == 0 || *format == 0) - return (EXECUTION_SUCCESS); - - /* Basic algorithm is to scan the format string for conversion - specifications -- once one is found, find out if the field - width or precision is a '*'; if it is, gather up value. Note, - format strings are reused as necessary to use up the provided - arguments, arguments of zero/null string are provided to use - up the format string. */ - do - { - tw = 0; - /* find next format specification */ - for (fmt = format; *fmt; fmt++) - { - precision = fieldwidth = 0; - have_fieldwidth = have_precision = altform = 0; - precstart = 0; - - if (*fmt == '\\') - { - fmt++; - /* A NULL third argument to tescape means to bypass the - special processing for arguments to %b. */ -#if defined (HANDLE_MULTIBYTE) - /* Accommodate possible use of \u or \U, which can result in - multibyte characters */ - memset (mbch, '\0', sizeof (mbch)); - fmt += tescape (fmt, mbch, &mblen, (int *)NULL); - for (mbind = 0; mbind < mblen; mbind++) - PC (mbch[mbind]); -#else - fmt += tescape (fmt, &nextch, (int *)NULL, (int *)NULL); - PC (nextch); -#endif - fmt--; /* for loop will increment it for us again */ - continue; - } - - if (*fmt != '%') - { - PC (*fmt); - continue; - } - - /* ASSERT(*fmt == '%') */ - start = fmt++; - - if (*fmt == '%') /* %% prints a % */ - { - PC ('%'); - continue; - } - - /* Found format specification, skip to field width. We check for - alternate form for possible later use. */ - for (; *fmt && strchr(SKIP1, *fmt); ++fmt) - if (*fmt == '#') - altform++; - - /* Skip optional field width. */ - if (*fmt == '*') - { - fmt++; - have_fieldwidth = 1; - fieldwidth = getint (); - } - else - while (DIGIT (*fmt)) - fmt++; - - /* Skip optional '.' and precision */ - if (*fmt == '.') - { - ++fmt; - if (*fmt == '*') - { - fmt++; - have_precision = 1; - precision = getint (); - } - else - { - /* Negative precisions are allowed but treated as if the - precision were missing; I would like to allow a leading - `+' in the precision number as an extension, but lots - of asprintf/fprintf implementations get this wrong. */ -#if 0 - if (*fmt == '-' || *fmt == '+') -#else - if (*fmt == '-') -#endif - fmt++; - if (DIGIT (*fmt)) - precstart = fmt; - while (DIGIT (*fmt)) - fmt++; - } - } - - /* skip possible format modifiers */ - modstart = fmt; - use_Lmod = 0; - while (*fmt && strchr (LENMODS, *fmt)) - { - use_Lmod |= USE_LONG_DOUBLE && *fmt == 'L'; - fmt++; - } - - if (*fmt == 0) - { - builtin_error (_("`%s': missing format character"), start); - PRETURN (EXECUTION_FAILURE); - } - - convch = *fmt; - thisch = modstart[0]; - nextch = modstart[1]; - modstart[0] = convch; - modstart[1] = '\0'; - - QUIT; - switch(convch) - { - case 'c': - { - char p; - - p = getchr (); - PF(start, p); - break; - } - - case 's': - { - char *p; - - p = getstr (); - PF(start, p); - break; - } - - case '(': - { - char *timefmt, timebuf[TIMELEN_MAX], *t; - int n; - intmax_t arg; - time_t secs; - struct tm *tm; - - modstart[1] = nextch; /* restore char after left paren */ - timefmt = xmalloc (strlen (fmt) + 3); - fmt++; /* skip over left paren */ - for (t = timefmt, n = 1; *fmt; ) - { - if (*fmt == '(') - n++; - else if (*fmt == ')') - n--; - if (n == 0) - break; - *t++ = *fmt++; - } - *t = '\0'; - if (*++fmt != 'T') - { - builtin_warning (_("`%c': invalid time format specification"), *fmt); - fmt = start; - free (timefmt); - PC (*fmt); - continue; - } - if (timefmt[0] == '\0') - { - timefmt[0] = '%'; - timefmt[1] = 'X'; /* locale-specific current time - should we use `+'? */ - timefmt[2] = '\0'; - } - /* argument is seconds since the epoch with special -1 and -2 */ - /* default argument is equivalent to -1; special case */ - arg = garglist ? getintmax () : -1; - if (arg == -1) - secs = NOW; /* roughly date +%s */ - else if (arg == -2) - secs = shell_start_time; /* roughly $SECONDS */ - else - secs = arg; -#if defined (HAVE_TZSET) - sv_tz ("TZ"); /* XXX -- just make sure */ -#endif - tm = localtime (&secs); - if (tm == 0) - { - secs = 0; - tm = localtime (&secs); - } - n = tm ? strftime (timebuf, sizeof (timebuf), timefmt, tm) : 0; - free (timefmt); - if (n == 0) - timebuf[0] = '\0'; - else - timebuf[sizeof(timebuf) - 1] = '\0'; - /* convert to %s format that preserves fieldwidth and precision */ - modstart[0] = 's'; - modstart[1] = '\0'; - n = printstr (start, timebuf, strlen (timebuf), fieldwidth, precision); /* XXX - %s for now */ - if (n < 0) - { - if (ferror (stdout) == 0) - { - sh_wrerror (); - clearerr (stdout); - } - PRETURN (EXECUTION_FAILURE); - } - break; - } - - case 'n': - { - char *var; - - var = getstr (); - if (var && *var) - { - if (legal_identifier (var)) - bind_var_to_int (var, tw, 0); - else - { - sh_invalidid (var); - PRETURN (EXECUTION_FAILURE); - } - } - break; - } - - case 'b': /* expand escapes in argument */ - { - char *p, *xp; - int rlen, r; - - p = getstr (); - ch = rlen = r = 0; - xp = bexpand (p, strlen (p), &ch, &rlen); - - if (xp) - { - /* Have to use printstr because of possible NUL bytes - in XP -- printf does not handle that well. */ - r = printstr (start, xp, rlen, fieldwidth, precision); - if (r < 0) - { - if (ferror (stdout) == 0) - { - sh_wrerror (); - clearerr (stdout); - } - retval = EXECUTION_FAILURE; - } - free (xp); - } - - if (ch || r < 0) - PRETURN (retval); - break; - } - - case 'q': /* print with shell quoting */ - case 'Q': - { - char *p, *xp; - int r, mpr; - size_t slen; - - r = 0; - p = getstr (); - /* Decode precision and apply it to the unquoted string. */ - if (convch == 'Q' && precstart) - { - mpr = *precstart++ - '0'; - while (DIGIT (*precstart)) - mpr = (mpr * 10) + (*precstart++ - '0'); - /* Error if precision > INT_MAX here? */ - precision = (mpr < 0 || mpr > INT_MAX) ? INT_MAX : mpr; - slen = strlen (p); - /* printf precision works in bytes. */ - if (precision < slen) - p[precision] = '\0'; - } - if (p && *p == 0) /* XXX - getstr never returns null */ - xp = savestring ("''"); - else if (ansic_shouldquote (p)) - xp = ansic_quote (p, 0, (int *)0); - else - xp = sh_backslash_quote (p, 0, 3); - if (xp) - { - if (convch == 'Q') - { - slen = strlen (xp); - if (slen > precision) - precision = slen; - } - /* Use printstr to get fieldwidth and precision right. */ - r = printstr (start, xp, strlen (xp), fieldwidth, precision); - if (r < 0) - { - sh_wrerror (); - clearerr (stdout); - } - free (xp); - } - - if (r < 0) - PRETURN (EXECUTION_FAILURE); - break; - } - - case 'd': - case 'i': - { - char *f; - long p; - intmax_t pp; - - p = pp = getintmax (); - if (p != pp) - { - f = mklong (start, PRIdMAX, sizeof (PRIdMAX) - 2); - PF (f, pp); - } - else - { - /* Optimize the common case where the integer fits - in "long". This also works around some long - long and/or intmax_t library bugs in the common - case, e.g. glibc 2.2 x86. */ - f = mklong (start, "l", 1); - PF (f, p); - } - break; - } - - case 'o': - case 'u': - case 'x': - case 'X': - { - char *f; - unsigned long p; - uintmax_t pp; - - p = pp = getuintmax (); - if (p != pp) - { - f = mklong (start, PRIdMAX, sizeof (PRIdMAX) - 2); - PF (f, pp); - } - else - { - f = mklong (start, "l", 1); - PF (f, p); - } - break; - } - - case 'e': - case 'E': - case 'f': - case 'F': - case 'g': - case 'G': -#if defined (HAVE_PRINTF_A_FORMAT) - case 'a': - case 'A': -#endif - { - char *f; - - if (use_Lmod || posixly_correct == 0) - { - floatmax_t p; - - p = getfloatmax (); - f = mklong (start, "L", 1); - PF (f, p); - } - else /* posixly_correct */ - { - double p; - - p = getdouble (); - f = mklong (start, "", 0); - PF (f, p); - } - - break; - } - - /* We don't output unrecognized format characters; we print an - error message and return a failure exit status. */ - default: - builtin_error (_("`%c': invalid format character"), convch); - PRETURN (EXECUTION_FAILURE); - } - - modstart[0] = thisch; - modstart[1] = nextch; - } - - if (ferror (stdout)) - { - /* PRETURN will print error message. */ - PRETURN (EXECUTION_FAILURE); - } - } - while (garglist && garglist != list->next); - - if (conversion_error) - retval = EXECUTION_FAILURE; - - PRETURN (retval); -} - -static void -printf_erange (s) - char *s; -{ - builtin_error (_("warning: %s: %s"), s, strerror(ERANGE)); -} - -/* We duplicate a lot of what printf(3) does here. */ -static int -printstr (fmt, string, len, fieldwidth, precision) - char *fmt; /* format */ - char *string; /* expanded string argument */ - int len; /* length of expanded string */ - int fieldwidth; /* argument for width of `*' */ - int precision; /* argument for precision of `*' */ -{ -#if 0 - char *s; -#endif - int padlen, nc, ljust, i; - int fw, pr; /* fieldwidth and precision */ - intmax_t mfw, mpr; - - if (string == 0) - string = ""; - -#if 0 - s = fmt; -#endif - if (*fmt == '%') - fmt++; - - ljust = fw = 0; - pr = -1; - mfw = 0; - mpr = -1; - - /* skip flags */ - while (strchr (SKIP1, *fmt)) - { - if (*fmt == '-') - ljust = 1; - fmt++; - } - - /* get fieldwidth, if present. rely on caller to clamp fieldwidth at INT_MAX */ - if (*fmt == '*') - { - fmt++; - fw = fieldwidth; - if (fw < 0) - { - fw = -fw; - ljust = 1; - } - } - else if (DIGIT (*fmt)) - { - mfw = *fmt++ - '0'; - while (DIGIT (*fmt)) - mfw = (mfw * 10) + (*fmt++ - '0'); - /* Error if fieldwidth > INT_MAX here? */ - fw = (mfw < 0 || mfw > INT_MAX) ? INT_MAX : mfw; - } - - /* get precision, if present. doesn't handle negative precisions */ - if (*fmt == '.') - { - fmt++; - if (*fmt == '*') - { - fmt++; - pr = precision; - } - else if (DIGIT (*fmt)) - { - mpr = *fmt++ - '0'; - while (DIGIT (*fmt)) - mpr = (mpr * 10) + (*fmt++ - '0'); - /* Error if precision > INT_MAX here? */ - pr = (mpr < 0 || mpr > INT_MAX) ? INT_MAX : mpr; - if (pr < precision && precision < INT_MAX) - pr = precision; /* XXX */ - } - else - pr = 0; /* "a null digit string is treated as zero" */ - } - -#if 0 - /* If we remove this, get rid of `s'. */ - if (*fmt != 'b' && *fmt != 'q') - { - internal_error (_("format parsing problem: %s"), s); - fw = pr = 0; - } -#endif - - /* chars from string to print */ - nc = (pr >= 0 && pr <= len) ? pr : len; - - padlen = fw - nc; - if (padlen < 0) - padlen = 0; - if (ljust) - padlen = -padlen; - - /* leading pad characters */ - for (; padlen > 0; padlen--) - PC (' '); - - /* output NC characters from STRING */ - for (i = 0; i < nc; i++) - PC (string[i]); - - /* output any necessary trailing padding */ - for (; padlen < 0; padlen++) - PC (' '); - - return (ferror (stdout) ? -1 : 0); -} - -/* Convert STRING by expanding the escape sequences specified by the - POSIX standard for printf's `%b' format string. If SAWC is non-null, - perform the processing appropriate for %b arguments. In particular, - recognize `\c' and use that as a string terminator. If we see \c, set - *SAWC to 1 before returning. LEN is the length of STRING. */ - -/* Translate a single backslash-escape sequence starting at ESTART (the - character after the backslash) and return the number of characters - consumed by the sequence. CP is the place to return the translated - value. *SAWC is set to 1 if the escape sequence was \c, since that means - to short-circuit the rest of the processing. If SAWC is null, we don't - do the \c short-circuiting, and \c is treated as an unrecognized escape - sequence; we also bypass the other processing specific to %b arguments. */ -static int -tescape (estart, cp, lenp, sawc) - char *estart; - char *cp; - int *lenp, *sawc; -{ - register char *p; - int temp, c, evalue; - unsigned long uvalue; - - p = estart; - if (lenp) - *lenp = 1; - - switch (c = *p++) - { -#if defined (__STDC__) - case 'a': *cp = '\a'; break; -#else - case 'a': *cp = '\007'; break; -#endif - - case 'b': *cp = '\b'; break; - - case 'e': - case 'E': *cp = '\033'; break; /* ESC -- non-ANSI */ - - case 'f': *cp = '\f'; break; - - case 'n': *cp = '\n'; break; - - case 'r': *cp = '\r'; break; - - case 't': *cp = '\t'; break; - - case 'v': *cp = '\v'; break; - - /* The octal escape sequences are `\0' followed by up to three octal - digits (if SAWC), or `\' followed by up to three octal digits (if - !SAWC). As an extension, we allow the latter form even if SAWC. */ - case '0': case '1': case '2': case '3': - case '4': case '5': case '6': case '7': - evalue = OCTVALUE (c); - for (temp = 2 + (!evalue && !!sawc); ISOCTAL (*p) && temp--; p++) - evalue = (evalue * 8) + OCTVALUE (*p); - *cp = evalue & 0xFF; - break; - - /* And, as another extension, we allow \xNN, where each N is a - hex digit. */ - case 'x': - for (temp = 2, evalue = 0; ISXDIGIT ((unsigned char)*p) && temp--; p++) - evalue = (evalue * 16) + HEXVALUE (*p); - if (p == estart + 1) - { - builtin_error (_("missing hex digit for \\x")); - *cp = '\\'; - return 0; - } - *cp = evalue & 0xFF; - break; - -#if defined (HANDLE_MULTIBYTE) - case 'u': - case 'U': - temp = (c == 'u') ? 4 : 8; /* \uNNNN \UNNNNNNNN */ - for (uvalue = 0; ISXDIGIT ((unsigned char)*p) && temp--; p++) - uvalue = (uvalue * 16) + HEXVALUE (*p); - if (p == estart + 1) - { - builtin_error (_("missing unicode digit for \\%c"), c); - *cp = '\\'; - return 0; - } - if (uvalue <= 0x7f) /* <= 0x7f translates directly */ - *cp = uvalue; - else - { - temp = u32cconv (uvalue, cp); - cp[temp] = '\0'; - if (lenp) - *lenp = temp; - } - break; -#endif - - case '\\': /* \\ -> \ */ - *cp = c; - break; - - /* SAWC == 0 means that \', \", and \? are recognized as escape - sequences, though the only processing performed is backslash - removal. */ - case '\'': case '"': case '?': - if (!sawc) - *cp = c; - else - { - *cp = '\\'; - return 0; - } - break; - - case 'c': - if (sawc) - { - *sawc = 1; - break; - } - /* other backslash escapes are passed through unaltered */ - default: - *cp = '\\'; - return 0; - } - return (p - estart); -} - -static char * -bexpand (string, len, sawc, lenp) - char *string; - int len, *sawc, *lenp; -{ - int temp; - char *ret, *r, *s, c; -#if defined (HANDLE_MULTIBYTE) - char mbch[25]; - int mbind, mblen; -#endif - - if (string == 0 || len == 0) - { - if (sawc) - *sawc = 0; - if (lenp) - *lenp = 0; - ret = (char *)xmalloc (1); - ret[0] = '\0'; - return (ret); - } - - ret = (char *)xmalloc (len + 1); - for (r = ret, s = string; s && *s; ) - { - c = *s++; - if (c != '\\' || *s == '\0') - { - *r++ = c; - continue; - } - temp = 0; -#if defined (HANDLE_MULTIBYTE) - memset (mbch, '\0', sizeof (mbch)); - s += tescape (s, mbch, &mblen, &temp); -#else - s += tescape (s, &c, (int *)NULL, &temp); -#endif - if (temp) - { - if (sawc) - *sawc = 1; - break; - } - -#if defined (HANDLE_MULTIBYTE) - for (mbind = 0; mbind < mblen; mbind++) - *r++ = mbch[mbind]; -#else - *r++ = c; -#endif - } - - *r = '\0'; - if (lenp) - *lenp = r - ret; - return ret; -} - -static char * -vbadd (buf, blen) - char *buf; - int blen; -{ - size_t nlen; - - nlen = vblen + blen + 1; - if (nlen >= vbsize) - { - vbsize = ((nlen + 63) >> 6) << 6; - vbuf = (char *)xrealloc (vbuf, vbsize); - } - - if (blen == 1) - vbuf[vblen++] = buf[0]; - else if (blen > 1) - { - FASTCOPY (buf, vbuf + vblen, blen); - vblen += blen; - } - vbuf[vblen] = '\0'; - -#ifdef DEBUG - if (strlen (vbuf) != vblen) - internal_error ("printf:vbadd: vblen (%d) != strlen (vbuf) (%d)", vblen, (int)strlen (vbuf)); -#endif - - return vbuf; -} - -static int -#if defined (PREFER_STDARG) -vbprintf (const char *format, ...) -#else -vbprintf (format, va_alist) - const char *format; - va_dcl -#endif -{ - va_list args; - size_t nlen; - int blen; - - SH_VA_START (args, format); - blen = vsnprintf (vbuf + vblen, vbsize - vblen, format, args); - va_end (args); - - nlen = vblen + blen + 1; - if (nlen >= vbsize) - { - vbsize = ((nlen + 63) >> 6) << 6; - vbuf = (char *)xrealloc (vbuf, vbsize); - SH_VA_START (args, format); - blen = vsnprintf (vbuf + vblen, vbsize - vblen, format, args); - va_end (args); - } - - vblen += blen; - vbuf[vblen] = '\0'; - -#ifdef DEBUG - if (strlen (vbuf) != vblen) - internal_error ("printf:vbprintf: vblen (%d) != strlen (vbuf) (%d)", vblen, (int)strlen (vbuf)); -#endif - - return (blen); -} - -static char * -mklong (str, modifiers, mlen) - char *str; - char *modifiers; - size_t mlen; -{ - size_t len, slen; - - slen = strlen (str); - len = slen + mlen + 1; - - if (len > conv_bufsize) - { - conv_bufsize = (((len + 1023) >> 10) << 10); - conv_buf = (char *)xrealloc (conv_buf, conv_bufsize); - } - - FASTCOPY (str, conv_buf, slen - 1); - FASTCOPY (modifiers, conv_buf + slen - 1, mlen); - - conv_buf[len - 2] = str[slen - 1]; - conv_buf[len - 1] = '\0'; - return (conv_buf); -} - -static int -getchr () -{ - int ret; - - if (garglist == 0) - return ('\0'); - - ret = (int)garglist->word->word[0]; - garglist = garglist->next; - return ret; -} - -static char * -getstr () -{ - char *ret; - - if (garglist == 0) - return (""); - - ret = garglist->word->word; - garglist = garglist->next; - return ret; -} - -static int -getint () -{ - intmax_t ret; - - ret = getintmax (); - - if (garglist == 0) - return ret; - - if (ret > INT_MAX) - { - printf_erange (garglist->word->word); - ret = INT_MAX; - } - else if (ret < INT_MIN) - { - printf_erange (garglist->word->word); - ret = INT_MIN; - } - - return ((int)ret); -} - -static intmax_t -getintmax () -{ - intmax_t ret; - char *ep; - - if (garglist == 0) - return (0); - - if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"') - return asciicode (); - - errno = 0; - ret = strtoimax (garglist->word->word, &ep, 0); - - if (*ep) - { - sh_invalidnum (garglist->word->word); - /* POSIX.2 says ``...a diagnostic message shall be written to standard - error, and the utility shall not exit with a zero exit status, but - shall continue processing any remaining operands and shall write the - value accumulated at the time the error was detected to standard - output.'' Yecch. */ -#if 0 - ret = 0; /* return partially-converted value from strtoimax */ -#endif - conversion_error = 1; - } - else if (errno == ERANGE) - printf_erange (garglist->word->word); - - garglist = garglist->next; - return (ret); -} - -static uintmax_t -getuintmax () -{ - uintmax_t ret; - char *ep; - - if (garglist == 0) - return (0); - - if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"') - return asciicode (); - - errno = 0; - ret = strtoumax (garglist->word->word, &ep, 0); - - if (*ep) - { - sh_invalidnum (garglist->word->word); -#if 0 - /* Same POSIX.2 conversion error requirements as getintmax(). */ - ret = 0; -#endif - conversion_error = 1; - } - else if (errno == ERANGE) - printf_erange (garglist->word->word); - - garglist = garglist->next; - return (ret); -} - -static double -getdouble () -{ - double ret; - char *ep; - - if (garglist == 0) - return (0); - - if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"') - return asciicode (); - - errno = 0; - ret = strtod (garglist->word->word, &ep); - - if (*ep) - { - sh_invalidnum (garglist->word->word); - conversion_error = 1; - } - else if (errno == ERANGE) - printf_erange (garglist->word->word); - - garglist = garglist->next; - return (ret); -} - -static floatmax_t -getfloatmax () -{ - floatmax_t ret; - char *ep; - - if (garglist == 0) - return (0); - - if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"') - return asciicode (); - - errno = 0; - ret = strtofltmax (garglist->word->word, &ep); - - if (*ep) - { - sh_invalidnum (garglist->word->word); -#if 0 - /* Same thing about POSIX.2 conversion error requirements. */ - ret = 0; -#endif - conversion_error = 1; - } - else if (errno == ERANGE) - printf_erange (garglist->word->word); - - garglist = garglist->next; - return (ret); -} - -/* NO check is needed for garglist here. */ -static intmax_t -asciicode () -{ - register intmax_t ch; -#if defined (HANDLE_MULTIBYTE) - wchar_t wc; - size_t slen; - int mblength; -#endif - DECLARE_MBSTATE; - -#if defined (HANDLE_MULTIBYTE) - slen = strlen (garglist->word->word+1); - wc = 0; - mblength = mbtowc (&wc, garglist->word->word+1, slen); - if (mblength > 0) - ch = wc; /* XXX */ - else -#endif - ch = (unsigned char)garglist->word->word[1]; - - garglist = garglist->next; - return (ch); -} diff --git a/third_party/bash/builtins_pushd.c b/third_party/bash/builtins_pushd.c deleted file mode 100644 index 6c9c02352..000000000 --- a/third_party/bash/builtins_pushd.c +++ /dev/null @@ -1,690 +0,0 @@ -/* pushd.c, created from pushd.def. */ -#line 22 "./pushd.def" - -#line 55 "./pushd.def" - -#line 84 "./pushd.def" - -#line 115 "./pushd.def" - -#include "config.h" - -#if defined (PUSHD_AND_POPD) -#include -#if defined (HAVE_SYS_PARAM_H) -# include -#endif - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include "bashansi.h" -#include "bashintl.h" - -#include - -#include "tilde.h" - -#include "shell.h" -#include "maxpath.h" -#include "common.h" -#include "builtext.h" - -#ifdef LOADABLE_BUILTIN -# include "builtins.h" -#endif - -#if !defined (errno) -extern int errno; -#endif /* !errno */ - -/* The list of remembered directories. */ -static char **pushd_directory_list = (char **)NULL; - -/* Number of existing slots in this list. */ -static int directory_list_size; - -/* Offset to the end of the list. */ -static int directory_list_offset; - -static void pushd_error PARAMS((int, char *)); -static void clear_directory_stack PARAMS((void)); -static int cd_to_string PARAMS((char *)); -static int change_to_temp PARAMS((char *)); -static void add_dirstack_element PARAMS((char *)); -static int get_dirstack_index PARAMS((intmax_t, int, int *)); - -#define NOCD 0x01 -#define ROTATE 0x02 -#define LONGFORM 0x04 -#define CLEARSTAK 0x08 - -int -pushd_builtin (list) - WORD_LIST *list; -{ - WORD_LIST *orig_list; - char *temp, *current_directory, *top; - int j, flags, skipopt; - intmax_t num; - char direction; - - orig_list = list; - - CHECK_HELPOPT (list); - if (list && list->word && ISOPTION (list->word->word, '-')) - { - list = list->next; - skipopt = 1; - } - else - skipopt = 0; - - /* If there is no argument list then switch current and - top of list. */ - if (list == 0) - { - if (directory_list_offset == 0) - { - builtin_error (_("no other directory")); - return (EXECUTION_FAILURE); - } - - current_directory = get_working_directory ("pushd"); - if (current_directory == 0) - return (EXECUTION_FAILURE); - - j = directory_list_offset - 1; - temp = pushd_directory_list[j]; - pushd_directory_list[j] = current_directory; - j = change_to_temp (temp); - free (temp); - return j; - } - - for (flags = 0; skipopt == 0 && list; list = list->next) - { - if (ISOPTION (list->word->word, 'n')) - { - flags |= NOCD; - } - else if (ISOPTION (list->word->word, '-')) - { - list = list->next; - break; - } - else if (list->word->word[0] == '-' && list->word->word[1] == '\0') - /* Let `pushd -' work like it used to. */ - break; - else if (((direction = list->word->word[0]) == '+') || direction == '-') - { - if (legal_number (list->word->word + 1, &num) == 0) - { - sh_invalidnum (list->word->word); - builtin_usage (); - return (EX_USAGE); - } - - if (direction == '-') - num = directory_list_offset - num; - - if (num > directory_list_offset || num < 0) - { - pushd_error (directory_list_offset, list->word->word); - return (EXECUTION_FAILURE); - } - flags |= ROTATE; - } - else if (*list->word->word == '-') - { - sh_invalidopt (list->word->word); - builtin_usage (); - return (EX_USAGE); - } - else - break; - } - - if (flags & ROTATE) - { - /* Rotate the stack num times. Remember, the current - directory acts like it is part of the stack. */ - temp = get_working_directory ("pushd"); - - if (num == 0) - { - j = ((flags & NOCD) == 0) ? change_to_temp (temp) : EXECUTION_SUCCESS; - free (temp); - return j; - } - - do - { - top = pushd_directory_list[directory_list_offset - 1]; - - for (j = directory_list_offset - 2; j > -1; j--) - pushd_directory_list[j + 1] = pushd_directory_list[j]; - - pushd_directory_list[j + 1] = temp; - - temp = top; - num--; - } - while (num); - - j = ((flags & NOCD) == 0) ? change_to_temp (temp) : EXECUTION_SUCCESS; - free (temp); - return j; - } - - if (list == 0) - return (EXECUTION_SUCCESS); - - /* Change to the directory in list->word->word. Save the current - directory on the top of the stack. */ - current_directory = get_working_directory ("pushd"); - if (current_directory == 0) - return (EXECUTION_FAILURE); - - j = ((flags & NOCD) == 0) ? cd_builtin (skipopt ? orig_list : list) : EXECUTION_SUCCESS; - if (j == EXECUTION_SUCCESS) - { - add_dirstack_element ((flags & NOCD) ? savestring (list->word->word) : current_directory); - dirs_builtin ((WORD_LIST *)NULL); - if (flags & NOCD) - free (current_directory); - return (EXECUTION_SUCCESS); - } - else - { - free (current_directory); - return (EXECUTION_FAILURE); - } -} - -/* Pop the directory stack, and then change to the new top of the stack. - If LIST is non-null it should consist of a word +N or -N, which says - what element to delete from the stack. The default is the top one. */ -int -popd_builtin (list) - WORD_LIST *list; -{ - register int i; - intmax_t which; - int flags; - char direction; - char *which_word; - - CHECK_HELPOPT (list); - - which_word = (char *)NULL; - for (flags = 0, which = 0, direction = '+'; list; list = list->next) - { - if (ISOPTION (list->word->word, 'n')) - { - flags |= NOCD; - } - else if (ISOPTION (list->word->word, '-')) - { - list = list->next; - break; - } - else if (((direction = list->word->word[0]) == '+') || direction == '-') - { - if (legal_number (list->word->word + 1, &which) == 0) - { - sh_invalidnum (list->word->word); - builtin_usage (); - return (EX_USAGE); - } - which_word = list->word->word; - } - else if (*list->word->word == '-') - { - sh_invalidopt (list->word->word); - builtin_usage (); - return (EX_USAGE); - } - else if (*list->word->word) - { - builtin_error (_("%s: invalid argument"), list->word->word); - builtin_usage (); - return (EX_USAGE); - } - else - break; - } - - if (which > directory_list_offset || (which < -directory_list_offset) || (directory_list_offset == 0 && which == 0)) - { - pushd_error (directory_list_offset, which_word ? which_word : ""); - return (EXECUTION_FAILURE); - } - - /* Handle case of no specification, or top of stack specification. */ - if ((direction == '+' && which == 0) || - (direction == '-' && which == directory_list_offset)) - { - i = ((flags & NOCD) == 0) ? cd_to_string (pushd_directory_list[directory_list_offset - 1]) - : EXECUTION_SUCCESS; - if (i != EXECUTION_SUCCESS) - return (i); - free (pushd_directory_list[--directory_list_offset]); - } - else - { - /* Since an offset other than the top directory was specified, - remove that directory from the list and shift the remainder - of the list into place. */ - i = (direction == '+') ? directory_list_offset - which : which; - if (i < 0 || i > directory_list_offset) - { - pushd_error (directory_list_offset, which_word ? which_word : ""); - return (EXECUTION_FAILURE); - } - free (pushd_directory_list[i]); - directory_list_offset--; - - /* Shift the remainder of the list into place. */ - for (; i < directory_list_offset; i++) - pushd_directory_list[i] = pushd_directory_list[i + 1]; - } - - dirs_builtin ((WORD_LIST *)NULL); - return (EXECUTION_SUCCESS); -} - -/* Print the current list of directories on the directory stack. */ -int -dirs_builtin (list) - WORD_LIST *list; -{ - int flags, desired_index, index_flag, vflag; - intmax_t i; - char *temp, *w; - - CHECK_HELPOPT (list); - for (flags = vflag = index_flag = 0, desired_index = -1, w = ""; list; list = list->next) - { - if (ISOPTION (list->word->word, 'l')) - { - flags |= LONGFORM; - } - else if (ISOPTION (list->word->word, 'c')) - { - flags |= CLEARSTAK; - } - else if (ISOPTION (list->word->word, 'v')) - { - vflag |= 2; - } - else if (ISOPTION (list->word->word, 'p')) - { - vflag |= 1; - } - else if (ISOPTION (list->word->word, '-')) - { - list = list->next; - break; - } - else if (*list->word->word == '+' || *list->word->word == '-') - { - int sign; - if (legal_number (w = list->word->word + 1, &i) == 0) - { - sh_invalidnum (list->word->word); - builtin_usage (); - return (EX_USAGE); - } - sign = (*list->word->word == '+') ? 1 : -1; - desired_index = get_dirstack_index (i, sign, &index_flag); - } - else - { - sh_invalidopt (list->word->word); - builtin_usage (); - return (EX_USAGE); - } - } - - if (flags & CLEARSTAK) - { - clear_directory_stack (); - return (EXECUTION_SUCCESS); - } - - if (index_flag && (desired_index < 0 || desired_index > directory_list_offset)) - { - pushd_error (directory_list_offset, w); - return (EXECUTION_FAILURE); - } - -#define DIRSTACK_FORMAT(temp) \ - (flags & LONGFORM) ? temp : polite_directory_format (temp) - - /* The first directory printed is always the current working directory. */ - if (index_flag == 0 || (index_flag == 1 && desired_index == 0)) - { - temp = get_working_directory ("dirs"); - if (temp == 0) - temp = savestring (_("")); - if (vflag & 2) - printf ("%2d %s", 0, DIRSTACK_FORMAT (temp)); - else - printf ("%s", DIRSTACK_FORMAT (temp)); - free (temp); - if (index_flag) - { - putchar ('\n'); - return (sh_chkwrite (EXECUTION_SUCCESS)); - } - } - -#define DIRSTACK_ENTRY(i) \ - (flags & LONGFORM) ? pushd_directory_list[i] \ - : polite_directory_format (pushd_directory_list[i]) - - /* Now print the requested directory stack entries. */ - if (index_flag) - { - if (vflag & 2) - printf ("%2d %s", directory_list_offset - desired_index, - DIRSTACK_ENTRY (desired_index)); - else - printf ("%s", DIRSTACK_ENTRY (desired_index)); - } - else - for (i = directory_list_offset - 1; i >= 0; i--) - if (vflag >= 2) - printf ("\n%2d %s", directory_list_offset - (int)i, DIRSTACK_ENTRY (i)); - else - printf ("%s%s", (vflag & 1) ? "\n" : " ", DIRSTACK_ENTRY (i)); - - putchar ('\n'); - - return (sh_chkwrite (EXECUTION_SUCCESS)); -} - -static void -pushd_error (offset, arg) - int offset; - char *arg; -{ - if (offset == 0) - builtin_error (_("directory stack empty")); - else - sh_erange (arg, _("directory stack index")); -} - -static void -clear_directory_stack () -{ - register int i; - - for (i = 0; i < directory_list_offset; i++) - free (pushd_directory_list[i]); - directory_list_offset = 0; -} - -/* Switch to the directory in NAME. This uses the cd_builtin to do the work, - so if the result is EXECUTION_FAILURE then an error message has already - been printed. */ -static int -cd_to_string (name) - char *name; -{ - WORD_LIST *tlist; - WORD_LIST *dir; - int result; - - dir = make_word_list (make_word (name), NULL); - tlist = make_word_list (make_word ("--"), dir); - result = cd_builtin (tlist); - dispose_words (tlist); - return (result); -} - -static int -change_to_temp (temp) - char *temp; -{ - int tt; - - tt = temp ? cd_to_string (temp) : EXECUTION_FAILURE; - - if (tt == EXECUTION_SUCCESS) - dirs_builtin ((WORD_LIST *)NULL); - - return (tt); -} - -static void -add_dirstack_element (dir) - char *dir; -{ - if (directory_list_offset == directory_list_size) - pushd_directory_list = strvec_resize (pushd_directory_list, directory_list_size += 10); - pushd_directory_list[directory_list_offset++] = dir; -} - -static int -get_dirstack_index (ind, sign, indexp) - intmax_t ind; - int sign, *indexp; -{ - if (indexp) - *indexp = sign > 0 ? 1 : 2; - - /* dirs +0 prints the current working directory. */ - /* dirs -0 prints last element in directory stack */ - if (ind == 0 && sign > 0) - return 0; - else if (ind == directory_list_offset) - { - if (indexp) - *indexp = sign > 0 ? 2 : 1; - return 0; - } - else if (ind >= 0 && ind <= directory_list_offset) - return (sign > 0 ? directory_list_offset - ind : ind); - else - return -1; -} - -/* Used by the tilde expansion code. */ -char * -get_dirstack_from_string (string) - char *string; -{ - int ind, sign, index_flag; - intmax_t i; - - sign = 1; - if (*string == '-' || *string == '+') - { - sign = (*string == '-') ? -1 : 1; - string++; - } - if (legal_number (string, &i) == 0) - return ((char *)NULL); - - index_flag = 0; - ind = get_dirstack_index (i, sign, &index_flag); - if (index_flag && (ind < 0 || ind > directory_list_offset)) - return ((char *)NULL); - if (index_flag == 0 || (index_flag == 1 && ind == 0)) - return (get_string_value ("PWD")); - else - return (pushd_directory_list[ind]); -} - -#ifdef INCLUDE_UNUSED -char * -get_dirstack_element (ind, sign) - intmax_t ind; - int sign; -{ - int i; - - i = get_dirstack_index (ind, sign, (int *)NULL); - return (i < 0 || i > directory_list_offset) ? (char *)NULL - : pushd_directory_list[i]; -} -#endif - -void -set_dirstack_element (ind, sign, value) - intmax_t ind; - int sign; - char *value; -{ - int i; - - i = get_dirstack_index (ind, sign, (int *)NULL); - if (ind == 0 || i < 0 || i > directory_list_offset) - return; - free (pushd_directory_list[i]); - pushd_directory_list[i] = savestring (value); -} - -WORD_LIST * -get_directory_stack (flags) - int flags; -{ - register int i; - WORD_LIST *ret; - char *d, *t; - - for (ret = (WORD_LIST *)NULL, i = 0; i < directory_list_offset; i++) - { - d = (flags&1) ? polite_directory_format (pushd_directory_list[i]) - : pushd_directory_list[i]; - ret = make_word_list (make_word (d), ret); - } - /* Now the current directory. */ - d = get_working_directory ("dirstack"); - i = 0; /* sentinel to decide whether or not to free d */ - if (d == 0) - d = "."; - else - { - t = (flags&1) ? polite_directory_format (d) : d; - /* polite_directory_format sometimes returns its argument unchanged. - If it does not, we can free d right away. If it does, we need to - mark d to be deleted later. */ - if (t != d) - { - free (d); - d = t; - } - else /* t == d, so d is what we want */ - i = 1; - } - ret = make_word_list (make_word (d), ret); - if (i) - free (d); - return ret; /* was (REVERSE_LIST (ret, (WORD_LIST *)); */ -} - -#ifdef LOADABLE_BUILTIN -char * const dirs_doc[] = { -N_("Display the list of currently remembered directories. Directories\n\ - find their way onto the list with the `pushd' command; you can get\n\ - back up through the list with the `popd' command.\n\ - \n\ - Options:\n\ - -c clear the directory stack by deleting all of the elements\n\ - -l do not print tilde-prefixed versions of directories relative\n\ - to your home directory\n\ - -p print the directory stack with one entry per line\n\ - -v print the directory stack with one entry per line prefixed\n\ - with its position in the stack\n\ - \n\ - Arguments:\n\ - +N Displays the Nth entry counting from the left of the list shown by\n\ - dirs when invoked without options, starting with zero.\n\ - \n\ - -N Displays the Nth entry counting from the right of the list shown by\n\ - dirs when invoked without options, starting with zero."), - (char *)NULL -}; - -char * const pushd_doc[] = { -N_("Adds a directory to the top of the directory stack, or rotates\n\ - the stack, making the new top of the stack the current working\n\ - directory. With no arguments, exchanges the top two directories.\n\ - \n\ - Options:\n\ - -n Suppresses the normal change of directory when adding\n\ - directories to the stack, so only the stack is manipulated.\n\ - \n\ - Arguments:\n\ - +N Rotates the stack so that the Nth directory (counting\n\ - from the left of the list shown by `dirs', starting with\n\ - zero) is at the top.\n\ - \n\ - -N Rotates the stack so that the Nth directory (counting\n\ - from the right of the list shown by `dirs', starting with\n\ - zero) is at the top.\n\ - \n\ - dir Adds DIR to the directory stack at the top, making it the\n\ - new current working directory.\n\ - \n\ - The `dirs' builtin displays the directory stack."), - (char *)NULL -}; - -char * const popd_doc[] = { -N_("Removes entries from the directory stack. With no arguments, removes\n\ - the top directory from the stack, and changes to the new top directory.\n\ - \n\ - Options:\n\ - -n Suppresses the normal change of directory when removing\n\ - directories from the stack, so only the stack is manipulated.\n\ - \n\ - Arguments:\n\ - +N Removes the Nth entry counting from the left of the list\n\ - shown by `dirs', starting with zero. For example: `popd +0'\n\ - removes the first directory, `popd +1' the second.\n\ - \n\ - -N Removes the Nth entry counting from the right of the list\n\ - shown by `dirs', starting with zero. For example: `popd -0'\n\ - removes the last directory, `popd -1' the next to last.\n\ - \n\ - The `dirs' builtin displays the directory stack."), - (char *)NULL -}; - -struct builtin pushd_struct = { - "pushd", - pushd_builtin, - BUILTIN_ENABLED, - pushd_doc, - "pushd [+N | -N] [-n] [dir]", - 0 -}; - -struct builtin popd_struct = { - "popd", - popd_builtin, - BUILTIN_ENABLED, - popd_doc, - "popd [+N | -N] [-n]", - 0 -}; - -struct builtin dirs_struct = { - "dirs", - dirs_builtin, - BUILTIN_ENABLED, - dirs_doc, - "dirs [-clpv] [+N] [-N]", - 0 -}; -#endif /* LOADABLE_BUILTIN */ - -#endif /* PUSHD_AND_POPD */ diff --git a/third_party/bash/builtins_read.c b/third_party/bash/builtins_read.c deleted file mode 100644 index fc4346dda..000000000 --- a/third_party/bash/builtins_read.c +++ /dev/null @@ -1,1205 +0,0 @@ -/* read.c, created from read.def. */ -#line 22 "./read.def" - -#line 70 "./read.def" - -#include "config.h" - -#include "bashtypes.h" -#include "posixstat.h" - -#include - -#include "bashansi.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include -#include - -#ifdef __CYGWIN__ -# include -# include -#endif - -#include "bashintl.h" - -#include "shell.h" -#include "common.h" -#include "bashgetopt.h" -#include "trap.h" - -#include "shtty.h" - -#if defined (READLINE) -#include "bashline.h" -#include "third_party/readline/readline.h" -#endif - -#if defined (BUFFERED_INPUT) -# include "input.h" -#endif - -#include "shmbutil.h" -#include "timer.h" - -#if !defined(errno) -extern int errno; -#endif - -struct ttsave -{ - int fd; - TTYSTRUCT attrs; -}; - -#if defined (READLINE) -static void reset_attempted_completion_function PARAMS((char *)); -static int set_itext PARAMS((void)); -static char *edit_line PARAMS((char *, char *)); -static void set_eol_delim PARAMS((int)); -static void reset_eol_delim PARAMS((char *)); -static void set_readline_timeout PARAMS((sh_timer *t, time_t, long)); -#endif -static SHELL_VAR *bind_read_variable PARAMS((char *, char *, int)); -#if defined (HANDLE_MULTIBYTE) -static int read_mbchar PARAMS((int, char *, int, int, int)); -#endif -static void ttyrestore PARAMS((struct ttsave *)); - -static sighandler sigalrm PARAMS((int)); -static void reset_timeout PARAMS((void)); - -/* Try this to see what the rest of the shell can do with the information. */ -sh_timer *read_timeout; - -static int reading, tty_modified; -static SigHandler *old_alrm; -static unsigned char delim; - -static struct ttsave termsave; - -/* In all cases, SIGALRM just sets a flag that we check periodically. This - avoids problems with the semi-tricky stuff we do with the xfree of - input_string at the top of the unwind-protect list (see below). */ - -/* Set a flag that check_read_timeout can check. This relies on zread or - read_builtin calling trap.c:check_signals() (which calls check_read_timeout()) */ -static sighandler -sigalrm (s) - int s; -{ - /* Display warning if this is called without read_timeout set? */ - if (read_timeout) - read_timeout->alrmflag = 1; -} - -static void -reset_timeout () -{ - /* Cancel alarm before restoring signal handler. */ - if (read_timeout) - shtimer_clear (read_timeout); - read_timeout = 0; -} - -void -check_read_timeout () -{ - if (read_timeout && shtimer_chktimeout (read_timeout)) - sh_longjmp (read_timeout->jmpenv, 1); -} - -int -read_builtin_timeout (fd) - int fd; -{ - if ((read_timeout == 0) || - (read_timeout->fd != fd) || - (read_timeout->tmout.tv_sec == 0 && read_timeout->tmout.tv_usec == 0)) - return 0; - - return ((read_timeout->flags & SHTIMER_ALARM) ? shtimer_alrm (read_timeout) - : shtimer_select (read_timeout)); -} - -/* Read the value of the shell variables whose names follow. - The reading is done from the current input stream, whatever - that may be. Successive words of the input line are assigned - to the variables mentioned in LIST. The last variable in LIST - gets the remainder of the words on the line. If no variables - are mentioned in LIST, then the default variable is $REPLY. */ -int -read_builtin (list) - WORD_LIST *list; -{ - register char *varname; - int size, nr, pass_next, saw_escape, eof, opt, retval, code, print_ps2, nflag; - volatile int i; - int input_is_tty, input_is_pipe, unbuffered_read, skip_ctlesc, skip_ctlnul; - int raw, edit, nchars, silent, have_timeout, ignore_delim, fd; - int lastsig, t_errno; - int mb_cur_max; - unsigned int tmsec, tmusec; - long ival, uval; - intmax_t intval; - char c; - char *input_string, *orig_input_string, *ifs_chars, *prompt, *arrayname; - char *e, *t, *t1, *ps2, *tofree; - struct stat tsb; - SHELL_VAR *var; - TTYSTRUCT ttattrs, ttset; - sigset_t chldset, prevset; -#if defined (ARRAY_VARS) - WORD_LIST *alist; - int vflags; -#endif - int bindflags; -#if defined (READLINE) - char *rlbuf, *itext; - int rlind; - FILE *save_instream; -#endif - - USE_VAR(size); - USE_VAR(i); - USE_VAR(pass_next); - USE_VAR(print_ps2); - USE_VAR(saw_escape); - USE_VAR(input_is_pipe); -/* USE_VAR(raw); */ - USE_VAR(edit); - USE_VAR(tmsec); - USE_VAR(tmusec); - USE_VAR(nchars); - USE_VAR(silent); - USE_VAR(ifs_chars); - USE_VAR(prompt); - USE_VAR(arrayname); -#if defined (READLINE) - USE_VAR(rlbuf); - USE_VAR(rlind); - USE_VAR(itext); -#endif - USE_VAR(list); - USE_VAR(ps2); - USE_VAR(lastsig); - - reading = tty_modified = 0; - read_timeout = 0; - - i = 0; /* Index into the string that we are reading. */ - raw = edit = 0; /* Not reading raw input by default. */ - silent = 0; - arrayname = prompt = (char *)NULL; - fd = 0; /* file descriptor to read from */ - -#if defined (READLINE) - rlbuf = itext = (char *)0; - rlind = 0; -#endif - - mb_cur_max = MB_CUR_MAX; - tmsec = tmusec = 0; /* no timeout */ - nr = nchars = input_is_tty = input_is_pipe = unbuffered_read = have_timeout = 0; - delim = '\n'; /* read until newline */ - ignore_delim = nflag = 0; - - reset_internal_getopt (); - while ((opt = internal_getopt (list, "ersa:d:i:n:p:t:u:N:")) != -1) - { - switch (opt) - { - case 'r': - raw = 1; - break; - case 'p': - prompt = list_optarg; - break; - case 's': - silent = 1; - break; - case 'e': -#if defined (READLINE) - edit = 1; -#endif - break; - case 'i': -#if defined (READLINE) - itext = list_optarg; -#endif - break; -#if defined (ARRAY_VARS) - case 'a': - arrayname = list_optarg; - break; -#endif - case 't': - code = uconvert (list_optarg, &ival, &uval, (char **)NULL); - if (code == 0 || ival < 0 || uval < 0) - { - builtin_error (_("%s: invalid timeout specification"), list_optarg); - return (EXECUTION_FAILURE); - } - else - { - have_timeout = 1; - tmsec = ival; - tmusec = uval; - } - break; - case 'N': - ignore_delim = 1; - delim = -1; - case 'n': - nflag = 1; - code = legal_number (list_optarg, &intval); - if (code == 0 || intval < 0 || intval != (int)intval) - { - sh_invalidnum (list_optarg); - return (EXECUTION_FAILURE); - } - else - nchars = intval; - break; - case 'u': - code = legal_number (list_optarg, &intval); - if (code == 0 || intval < 0 || intval != (int)intval) - { - builtin_error (_("%s: invalid file descriptor specification"), list_optarg); - return (EXECUTION_FAILURE); - } - else - fd = intval; - if (sh_validfd (fd) == 0) - { - builtin_error (_("%d: invalid file descriptor: %s"), fd, strerror (errno)); - return (EXECUTION_FAILURE); - } - break; - case 'd': - delim = *list_optarg; - break; - CASE_HELPOPT; - default: - builtin_usage (); - return (EX_USAGE); - } - } - list = loptend; - - /* `read -t 0 var' tests whether input is available with select/FIONREAD, - and fails if those are unavailable */ - if (have_timeout && tmsec == 0 && tmusec == 0) - return (input_avail (fd) ? EXECUTION_SUCCESS : EXECUTION_FAILURE); - - /* Convenience: check early whether or not the first of possibly several - variable names is a valid identifier, and bail early if so. */ -#if defined (ARRAY_VARS) - if (list) - SET_VFLAGS (list->word->flags, vflags, bindflags); - if (list && legal_identifier (list->word->word) == 0 && valid_array_reference (list->word->word, vflags) == 0) -#else - bindflags = 0; - if (list && legal_identifier (list->word->word) == 0) -#endif - { - sh_invalidid (list->word->word); - return (EXECUTION_FAILURE); - } - - /* If we're asked to ignore the delimiter, make sure we do. */ - if (ignore_delim) - delim = -1; - - /* IF IFS is unset, we use the default of " \t\n". */ - ifs_chars = getifs (); - if (ifs_chars == 0) /* XXX - shouldn't happen */ - ifs_chars = ""; - /* If we want to read exactly NCHARS chars, don't split on IFS */ - if (ignore_delim) - ifs_chars = ""; - for (skip_ctlesc = skip_ctlnul = 0, e = ifs_chars; *e; e++) - skip_ctlesc |= *e == CTLESC, skip_ctlnul |= *e == CTLNUL; - - input_string = (char *)xmalloc (size = 112); /* XXX was 128 */ - input_string[0] = '\0'; - - /* More input and options validation */ - if (nflag == 1 && nchars == 0) - { - retval = read (fd, &c, 0); - retval = (retval >= 0) ? EXECUTION_SUCCESS : EXECUTION_FAILURE; - goto assign_vars; /* bail early if asked to read 0 chars */ - } - - /* $TMOUT, if set, is the default timeout for read. */ - if (have_timeout == 0 && (e = get_string_value ("TMOUT"))) - { - code = uconvert (e, &ival, &uval, (char **)NULL); - if (code == 0 || ival < 0 || uval < 0) - tmsec = tmusec = 0; - else - { - tmsec = ival; - tmusec = uval; - } - } - -#if defined (SIGCHLD) - sigemptyset (&chldset); - sigprocmask (SIG_BLOCK, (sigset_t *)0, &chldset); - sigaddset (&chldset, SIGCHLD); -#endif - - begin_unwind_frame ("read_builtin"); - -#if defined (BUFFERED_INPUT) - if (interactive == 0 && default_buffered_input >= 0 && fd_is_bash_input (fd)) - sync_buffered_stream (default_buffered_input); -#endif - -#if 1 - input_is_tty = isatty (fd); -#else - input_is_tty = 1; -#endif - if (input_is_tty == 0) -#ifndef __CYGWIN__ - input_is_pipe = (lseek (fd, 0L, SEEK_CUR) < 0) && (errno == ESPIPE); -#else - input_is_pipe = 1; -#endif - - /* If the -p, -e or -s flags were given, but input is not coming from the - terminal, turn them off. */ - if ((prompt || edit || silent) && input_is_tty == 0) - { - prompt = (char *)NULL; -#if defined (READLINE) - itext = (char *)NULL; -#endif - edit = silent = 0; - } - -#if defined (READLINE) - if (edit) - add_unwind_protect (xfree, rlbuf); -#endif - - pass_next = 0; /* Non-zero signifies last char was backslash. */ - saw_escape = 0; /* Non-zero signifies that we saw an escape char */ - - if (tmsec > 0 || tmusec > 0) - { - /* Turn off the timeout if stdin is a regular file (e.g. from - input redirection). */ - if ((fstat (fd, &tsb) < 0) || S_ISREG (tsb.st_mode)) - tmsec = tmusec = 0; - } - - if (tmsec > 0 || tmusec > 0) - { - read_timeout = shtimer_alloc (); - read_timeout->flags = SHTIMER_LONGJMP; - -#if defined (HAVE_SELECT) - read_timeout->flags |= (edit || posixly_correct) ? SHTIMER_ALARM : SHTIMER_SELECT; -#else - read_timeout->flags |= SHTIMER_ALARM; -#endif - read_timeout->fd = fd; - - read_timeout->alrm_handler = sigalrm; - } - - if (tmsec > 0 || tmusec > 0) - { - code = setjmp_nosigs (read_timeout->jmpenv); - if (code) - { - reset_timeout (); - sigprocmask (SIG_SETMASK, &prevset, (sigset_t *)0); - - /* Tricky. The top of the unwind-protect stack is the free of - input_string. We want to run all the rest and use input_string, - so we have to save input_string temporarily, run the unwind- - protects, then restore input_string so we can use it later */ - orig_input_string = 0; - input_string[i] = '\0'; /* make sure it's terminated */ - if (i == 0) - { - t = (char *)xmalloc (1); - t[0] = 0; - } - else - t = savestring (input_string); - - run_unwind_frame ("read_builtin"); - input_string = t; - retval = 128+SIGALRM; - goto assign_vars; - } - if (interactive_shell == 0) - initialize_terminating_signals (); - add_unwind_protect (reset_timeout, (char *)NULL); -#if defined (READLINE) - if (edit) - { - add_unwind_protect (reset_attempted_completion_function, (char *)NULL); - add_unwind_protect (bashline_reset_event_hook, (char *)NULL); - set_readline_timeout (read_timeout, tmsec, tmusec); - } - else -#endif - shtimer_set (read_timeout, tmsec, tmusec); - } - - /* If we've been asked to read only NCHARS chars, or we're using some - character other than newline to terminate the line, do the right - thing to readline or the tty. */ - if (nchars > 0 || delim != '\n') - { -#if defined (READLINE) - if (edit) - { - if (nchars > 0) - { - unwind_protect_int (rl_num_chars_to_read); - rl_num_chars_to_read = nchars; - } - if (delim != '\n') - { - set_eol_delim (delim); - add_unwind_protect (reset_eol_delim, (char *)NULL); - } - } - else -#endif - if (input_is_tty) - { - /* ttsave() */ - termsave.fd = fd; - ttgetattr (fd, &ttattrs); - termsave.attrs = ttattrs; - - ttset = ttattrs; - i = silent ? ttfd_cbreak (fd, &ttset) : ttfd_onechar (fd, &ttset); - if (i < 0) - sh_ttyerror (1); - tty_modified = 1; - add_unwind_protect ((Function *)ttyrestore, (char *)&termsave); - if (interactive_shell == 0) - initialize_terminating_signals (); - } - } - else if (silent) /* turn off echo but leave term in canonical mode */ - { - /* ttsave (); */ - termsave.fd = fd; - ttgetattr (fd, &ttattrs); - termsave.attrs = ttattrs; - - ttset = ttattrs; - i = ttfd_noecho (fd, &ttset); /* ttnoecho (); */ - if (i < 0) - sh_ttyerror (1); - - tty_modified = 1; - add_unwind_protect ((Function *)ttyrestore, (char *)&termsave); - if (interactive_shell == 0) - initialize_terminating_signals (); - } - -#if defined (READLINE) - save_instream = 0; - if (edit && fd != 0) - { - if (bash_readline_initialized == 0) - initialize_readline (); - - unwind_protect_var (rl_instream); - save_instream = rl_instream; - rl_instream = fdopen (fd, "r"); - } -#endif - - /* This *must* be the top unwind-protect on the stack, so the manipulation - of the unwind-protect stack after the realloc() works right. */ - add_unwind_protect (xfree, input_string); - - check_read_timeout (); - /* These only matter if edit == 0 */ - if ((nchars > 0) && (input_is_tty == 0) && ignore_delim) /* read -N */ - unbuffered_read = 2; -#if 0 - else if ((nchars > 0) || (delim != '\n') || input_is_pipe) -#else - else if (((nchars > 0 || delim != '\n') && input_is_tty) || input_is_pipe) - unbuffered_read = 1; -#endif - if (prompt && edit == 0) - { - fprintf (stderr, "%s", prompt); - fflush (stderr); - } - -#if defined (__CYGWIN__) && defined (O_TEXT) - setmode (0, O_TEXT); -#endif - - ps2 = 0; - for (print_ps2 = eof = retval = 0;;) - { - check_read_timeout (); - -#if defined (READLINE) - if (edit) - { - /* If we have a null delimiter, don't treat NULL as ending the line */ - if (rlbuf && rlbuf[rlind] == '\0' && delim != '\0') - { - free (rlbuf); - rlbuf = (char *)0; - } -#if defined (SIGCHLD) - if (tmsec > 0 || tmusec > 0) - sigprocmask (SIG_SETMASK, &chldset, &prevset); -#endif - if (rlbuf == 0) - { - reading = 1; - rlbuf = edit_line (prompt ? prompt : "", itext); - reading = 0; - rlind = 0; - } -#if defined (SIGCHLD) - if (tmsec > 0 || tmusec > 0) - sigprocmask (SIG_SETMASK, &prevset, (sigset_t *)0); -#endif - if (rlbuf == 0) - { - eof = 1; - break; - } - c = rlbuf[rlind++]; - } - else - { -#endif - - if (print_ps2) - { - if (ps2 == 0) - ps2 = get_string_value ("PS2"); - fprintf (stderr, "%s", ps2 ? ps2 : ""); - fflush (stderr); - print_ps2 = 0; - } - - reading = 1; - check_read_timeout (); - errno = 0; - -#if defined (SIGCHLD) - if (tmsec > 0 || tmusec > 0) - sigprocmask (SIG_SETMASK, &chldset, &prevset); -#endif - if (unbuffered_read == 2) - retval = posixly_correct ? zreadintr (fd, &c, 1) : zreadn (fd, &c, nchars - nr); - else if (unbuffered_read) - retval = posixly_correct ? zreadintr (fd, &c, 1) : zread (fd, &c, 1); - else - retval = posixly_correct ? zreadcintr (fd, &c) : zreadc (fd, &c); -#if defined (SIGCHLD) - if (tmsec > 0 || tmusec > 0) - sigprocmask (SIG_SETMASK, &prevset, (sigset_t *)0); -#endif - - reading = 0; - - if (retval <= 0) - { - int t; - - t = errno; - if (retval < 0 && errno == EINTR) - { - check_signals (); /* in case we didn't call zread via zreadc */ - lastsig = LASTSIG(); - if (lastsig == 0) - lastsig = trapped_signal_received; -#if 0 - run_pending_traps (); /* because interrupt_immediately is not set */ -#endif - } - else - lastsig = 0; - if (terminating_signal && tty_modified) - ttyrestore (&termsave); /* fix terminal before exiting */ - CHECK_TERMSIG; - eof = 1; - errno = t; /* preserve it for the error message below */ - break; - } - - QUIT; /* in case we didn't call check_signals() */ -#if defined (READLINE) - } -#endif - - if (retval <= 0) /* XXX shouldn't happen */ - check_read_timeout (); - - /* XXX -- use i + mb_cur_max (at least 4) for multibyte/read_mbchar */ - if (i + (mb_cur_max > 4 ? mb_cur_max : 4) >= size) - { - char *t; - t = (char *)xrealloc (input_string, size += 128); - - /* Only need to change unwind-protect if input_string changes */ - if (t != input_string) - { - input_string = t; - remove_unwind_protect (); - add_unwind_protect (xfree, input_string); - } - } - - /* If the next character is to be accepted verbatim, a backslash - newline pair still disappears from the input. */ - if (pass_next) - { - pass_next = 0; - if (c == '\n') - { - if (skip_ctlesc == 0 && i > 0) - i--; /* back up over the CTLESC */ - if (interactive && input_is_tty && raw == 0) - print_ps2 = 1; - } - else - goto add_char; - continue; - } - - /* This may cause problems if IFS contains CTLESC */ - if (c == '\\' && raw == 0) - { - pass_next++; - if (skip_ctlesc == 0) - { - saw_escape++; - input_string[i++] = CTLESC; - } - continue; - } - - if (ignore_delim == 0 && (unsigned char)c == delim) - break; - - if (c == '\0' && delim != '\0') - continue; /* skip NUL bytes in input */ - - if ((skip_ctlesc == 0 && c == CTLESC) || (skip_ctlnul == 0 && c == CTLNUL)) - { - saw_escape++; - input_string[i++] = CTLESC; - } - -add_char: - input_string[i++] = c; - check_read_timeout (); - -#if defined (HANDLE_MULTIBYTE) - /* XXX - what if C == 127? Can DEL introduce a multibyte sequence? */ - if (mb_cur_max > 1 && is_basic (c) == 0) - { - input_string[i] = '\0'; /* for simplicity and debugging */ - /* If we got input from readline, grab the next multibyte char from - rlbuf. */ -# if defined (READLINE) - if (edit) - { - size_t clen; - clen = mbrlen (rlbuf + rlind - 1, mb_cur_max, (mbstate_t *)NULL); - /* We only deal with valid multibyte sequences longer than one - byte. If we get anything else, we leave the one character - copied and move on to the next. */ - if ((int)clen > 1) - { - memcpy (input_string+i, rlbuf+rlind, clen-1); - i += clen - 1; - rlind += clen - 1; - } - } - else -# endif - if (locale_utf8locale == 0 || ((c & 0x80) != 0)) - i += read_mbchar (fd, input_string, i, c, unbuffered_read); - } -#endif - - nr++; - - if (nchars > 0 && nr >= nchars) - break; - } - input_string[i] = '\0'; - check_read_timeout (); - -#if defined (READLINE) - if (edit) - free (rlbuf); -#endif - - if (retval < 0) - { - t_errno = errno; - if (errno != EINTR) - builtin_error (_("read error: %d: %s"), fd, strerror (errno)); - run_unwind_frame ("read_builtin"); - return ((t_errno != EINTR) ? EXECUTION_FAILURE : 128+lastsig); - } - - if (tmsec > 0 || tmusec > 0) - reset_timeout (); - - if (nchars > 0 || delim != '\n') - { -#if defined (READLINE) - if (edit) - { - if (nchars > 0) - rl_num_chars_to_read = 0; - if (delim != '\n') - reset_eol_delim ((char *)NULL); - } - else -#endif - if (input_is_tty) - ttyrestore (&termsave); - } - else if (silent) - ttyrestore (&termsave); - - if (unbuffered_read == 0) - zsyncfd (fd); - -#if defined (READLINE) - if (save_instream) - rl_instream = save_instream; /* can't portably free it */ -#endif - - discard_unwind_frame ("read_builtin"); - - retval = eof ? EXECUTION_FAILURE : EXECUTION_SUCCESS; - -assign_vars: - -#if defined (ARRAY_VARS) - /* If -a was given, take the string read, break it into a list of words, - an assign them to `arrayname' in turn. */ - if (arrayname) - { - /* pass 1 for flags arg to clear the existing array + 2 to check for a - valid identifier. */ - var = builtin_find_indexed_array (arrayname, 3); - if (var == 0) - { - free (input_string); - return EXECUTION_FAILURE; /* readonly or noassign */ - } - - alist = list_string (input_string, ifs_chars, 0); - if (alist) - { - if (saw_escape) - dequote_list (alist); - else - word_list_remove_quoted_nulls (alist); - assign_array_var_from_word_list (var, alist, 0); - dispose_words (alist); - } - free (input_string); - return (retval); - } -#endif /* ARRAY_VARS */ - - /* If there are no variables, save the text of the line read to the - variable $REPLY. ksh93 strips leading and trailing IFS whitespace, - so that `read x ; echo "$x"' and `read ; echo "$REPLY"' behave the - same way, but I believe that the difference in behaviors is useful - enough to not do it. Without the bash behavior, there is no way - to read a line completely without interpretation or modification - unless you mess with $IFS (e.g., setting it to the empty string). - If you disagree, change the occurrences of `#if 0' to `#if 1' below. */ - if (list == 0) - { -#if 0 - orig_input_string = input_string; - for (t = input_string; ifs_chars && *ifs_chars && spctabnl(*t) && isifs(*t); t++) - ; - input_string = t; - input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars, saw_escape); -#endif - - if (saw_escape) - { - t = dequote_string (input_string); - var = bind_variable ("REPLY", t, 0); - free (t); - } - else - var = bind_variable ("REPLY", input_string, 0); - if (var == 0 || readonly_p (var) || noassign_p (var)) - retval = EXECUTION_FAILURE; - else - VUNSETATTR (var, att_invisible); - - free (input_string); - return (retval); - } - - /* This code implements the Posix.2 spec for splitting the words - read and assigning them to variables. */ - orig_input_string = input_string; - - /* Remove IFS white space at the beginning of the input string. If - $IFS is null, no field splitting is performed. */ - for (t = input_string; ifs_chars && *ifs_chars && spctabnl(*t) && isifs(*t); t++) - ; - input_string = t; - for (; list->next; list = list->next) - { - varname = list->word->word; -#if defined (ARRAY_VARS) - SET_VFLAGS (list->word->flags, vflags, bindflags); - if (legal_identifier (varname) == 0 && valid_array_reference (varname, vflags) == 0) -#else - if (legal_identifier (varname) == 0) -#endif - { - sh_invalidid (varname); - free (orig_input_string); - return (EXECUTION_FAILURE); - } - - /* If there are more variables than words read from the input, - the remaining variables are set to the empty string. */ - if (*input_string) - { - /* This call updates INPUT_STRING. */ - t = get_word_from_string (&input_string, ifs_chars, &e); - if (t) - *e = '\0'; - /* Don't bother to remove the CTLESC unless we added one - somewhere while reading the string. */ - if (t && saw_escape) - { - t1 = dequote_string (t); - var = bind_read_variable (varname, t1, bindflags); - free (t1); - } - else - var = bind_read_variable (varname, t ? t : "", bindflags); - } - else - { - t = (char *)0; - var = bind_read_variable (varname, "", bindflags); - } - - FREE (t); - if (var == 0) - { - free (orig_input_string); - return (EXECUTION_FAILURE); - } - - stupidly_hack_special_variables (varname); - VUNSETATTR (var, att_invisible); - } - - /* Now assign the rest of the line to the last variable argument. */ -#if defined (ARRAY_VARS) - SET_VFLAGS (list->word->flags, vflags, bindflags); - if (legal_identifier (list->word->word) == 0 && valid_array_reference (list->word->word, vflags) == 0) -#else - if (legal_identifier (list->word->word) == 0) -#endif - { - sh_invalidid (list->word->word); - free (orig_input_string); - return (EXECUTION_FAILURE); - } - -#if 0 - /* This has to be done this way rather than using string_list - and list_string because Posix.2 says that the last variable gets the - remaining words and their intervening separators. */ - input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars, saw_escape); -#else - /* Check whether or not the number of fields is exactly the same as the - number of variables. */ - tofree = NULL; - if (*input_string) - { - t1 = input_string; - t = get_word_from_string (&input_string, ifs_chars, &e); - if (*input_string == 0) - tofree = input_string = t; - else - { - input_string = strip_trailing_ifs_whitespace (t1, ifs_chars, saw_escape); - tofree = t; - } - } -#endif - - if (saw_escape && input_string && *input_string) - { - t = dequote_string (input_string); - var = bind_read_variable (list->word->word, t, bindflags); - free (t); - } - else - var = bind_read_variable (list->word->word, input_string ? input_string : "", bindflags); - - if (var) - { - stupidly_hack_special_variables (list->word->word); - VUNSETATTR (var, att_invisible); - } - else - retval = EXECUTION_FAILURE; - - FREE (tofree); - free (orig_input_string); - - return (retval); -} - -static SHELL_VAR * -bind_read_variable (name, value, flags) - char *name, *value; - int flags; -{ - SHELL_VAR *v; - - v = builtin_bind_variable (name, value, flags); - return (v == 0 ? v - : ((readonly_p (v) || noassign_p (v)) ? (SHELL_VAR *)NULL : v)); -} - -#if defined (HANDLE_MULTIBYTE) -static int -read_mbchar (fd, string, ind, ch, unbuffered) - int fd; - char *string; - int ind, ch, unbuffered; -{ - char mbchar[MB_LEN_MAX + 1]; - int i, n, r; - char c; - size_t ret; - mbstate_t ps, ps_back; - wchar_t wc; - - memset (&ps, '\0', sizeof (mbstate_t)); - memset (&ps_back, '\0', sizeof (mbstate_t)); - - mbchar[0] = ch; - i = 1; - for (n = 0; n <= MB_LEN_MAX; n++) - { - ps_back = ps; - ret = mbrtowc (&wc, mbchar, i, &ps); - if (ret == (size_t)-2) - { - ps = ps_back; - - /* We don't want to be interrupted during a multibyte char read */ - if (unbuffered == 2) - r = zreadn (fd, &c, 1); - else if (unbuffered) - r = zread (fd, &c, 1); - else - r = zreadc (fd, &c); - if (r <= 0) - goto mbchar_return; - mbchar[i++] = c; - continue; - } - else if (ret == (size_t)-1 || ret == (size_t)0 || ret > (size_t)0) - break; - } - -mbchar_return: - if (i > 1) /* read a multibyte char */ - /* mbchar[0] is already string[ind-1] */ - for (r = 1; r < i; r++) - string[ind+r-1] = mbchar[r]; - return i - 1; -} -#endif - - -static void -ttyrestore (ttp) - struct ttsave *ttp; -{ - ttsetattr (ttp->fd, &(ttp->attrs)); - tty_modified = 0; -} - -void -read_tty_cleanup () -{ - if (tty_modified) - ttyrestore (&termsave); -} - -int -read_tty_modified () -{ - return (tty_modified); -} - -#if defined (READLINE) -static rl_completion_func_t *old_attempted_completion_function = 0; -static rl_hook_func_t *old_startup_hook; -static char *deftext; - -static void -reset_attempted_completion_function (cp) - char *cp; -{ - if (rl_attempted_completion_function == 0 && old_attempted_completion_function) - rl_attempted_completion_function = old_attempted_completion_function; -} - -static int -set_itext () -{ - int r1, r2; - - r1 = r2 = 0; - if (old_startup_hook) - r1 = (*old_startup_hook) (); - if (deftext) - { - r2 = rl_insert_text (deftext); - deftext = (char *)NULL; - rl_startup_hook = old_startup_hook; - old_startup_hook = (rl_hook_func_t *)NULL; - } - return (r1 || r2); -} - -static char * -edit_line (p, itext) - char *p; - char *itext; -{ - char *ret; - int len; - - if (bash_readline_initialized == 0) - initialize_readline (); - - old_attempted_completion_function = rl_attempted_completion_function; - rl_attempted_completion_function = (rl_completion_func_t *)NULL; - bashline_set_event_hook (); - if (itext) - { - old_startup_hook = rl_startup_hook; - rl_startup_hook = set_itext; - deftext = itext; - } - - ret = readline (p); - - rl_attempted_completion_function = old_attempted_completion_function; - old_attempted_completion_function = (rl_completion_func_t *)NULL; - bashline_reset_event_hook (); - - if (ret == 0) - { - if (RL_ISSTATE (RL_STATE_TIMEOUT)) - { - sigalrm (SIGALRM); /* simulate receiving SIGALRM */ - check_read_timeout (); - } - return ret; - } - - len = strlen (ret); - ret = (char *)xrealloc (ret, len + 2); - ret[len++] = delim; - ret[len] = '\0'; - return ret; -} - -static void -set_readline_timeout (t, sec, usec) - sh_timer *t; - time_t sec; - long usec; -{ - t->tmout.tv_sec = sec; - t->tmout.tv_usec = usec; - rl_set_timeout (sec, usec); -} - -static int old_delim_ctype; -static rl_command_func_t *old_delim_func; -static int old_newline_ctype; -static rl_command_func_t *old_newline_func; - -static unsigned char delim_char; - -static void -set_eol_delim (c) - int c; -{ - Keymap cmap; - - if (bash_readline_initialized == 0) - initialize_readline (); - cmap = rl_get_keymap (); - - /* Save the old delimiter char binding */ - old_newline_ctype = cmap[RETURN].type; - old_newline_func = cmap[RETURN].function; - old_delim_ctype = cmap[c].type; - old_delim_func = cmap[c].function; - - /* Change newline to self-insert */ - cmap[RETURN].type = ISFUNC; - cmap[RETURN].function = rl_insert; - - /* Bind the delimiter character to accept-line. */ - cmap[c].type = ISFUNC; - cmap[c].function = rl_newline; - - delim_char = c; -} - -static void -reset_eol_delim (cp) - char *cp; -{ - Keymap cmap; - - cmap = rl_get_keymap (); - - cmap[RETURN].type = old_newline_ctype; - cmap[RETURN].function = old_newline_func; - - cmap[delim_char].type = old_delim_ctype; - cmap[delim_char].function = old_delim_func; -} -#endif diff --git a/third_party/bash/builtins_return.c b/third_party/bash/builtins_return.c deleted file mode 100644 index 7f5fbd289..000000000 --- a/third_party/bash/builtins_return.c +++ /dev/null @@ -1,40 +0,0 @@ -/* return.c, created from return.def. */ -#line 22 "./return.def" - -#line 36 "./return.def" - -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include "bashintl.h" - -#include "shell.h" -#include "execute_cmd.h" -#include "common.h" -#include "bashgetopt.h" - -/* If we are executing a user-defined function then exit with the value - specified as an argument. if no argument is given, then the last - exit status is used. */ -int -return_builtin (list) - WORD_LIST *list; -{ - CHECK_HELPOPT (list); - - return_catch_value = get_exitstat (list); - - if (return_catch_flag) - sh_longjmp (return_catch, 1); - else - { - builtin_error (_("can only `return' from a function or sourced script")); - return (EX_USAGE); - } -} diff --git a/third_party/bash/builtins_set.c b/third_party/bash/builtins_set.c deleted file mode 100644 index ed1db4508..000000000 --- a/third_party/bash/builtins_set.c +++ /dev/null @@ -1,890 +0,0 @@ -/* set.c, created from set.def. */ -#line 22 "./set.def" - -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include - -#include "bashansi.h" -#include "bashintl.h" - -#include "shell.h" -#include "parser.h" -#include "flags.h" -#include "common.h" -#include "bashgetopt.h" - -#if defined (READLINE) -# include "input.h" -# include "bashline.h" -# include "third_party/readline/readline.h" -#endif - -#if defined (HISTORY) -# include "bashhist.h" -#endif - -#line 153 "./set.def" - -typedef int setopt_set_func_t PARAMS((int, char *)); -typedef int setopt_get_func_t PARAMS((char *)); - -static int find_minus_o_option PARAMS((char *)); - -static void print_minus_o_option PARAMS((char *, int, int)); -static void print_all_shell_variables PARAMS((void)); - -static int set_ignoreeof PARAMS((int, char *)); -static int set_posix_mode PARAMS((int, char *)); - -#if defined (READLINE) -static int set_edit_mode PARAMS((int, char *)); -static int get_edit_mode PARAMS((char *)); -#endif - -#if defined (HISTORY) -static int bash_set_history PARAMS((int, char *)); -#endif - -static const char * const on = "on"; -static const char * const off = "off"; - -static int previous_option_value; - -/* A struct used to match long options for set -o to the corresponding - option letter or internal variable. The functions can be called to - dynamically generate values. If you add a new variable name here - that doesn't have a corresponding single-character option letter, make - sure to set the value appropriately in reset_shell_options. */ -const struct { - char *name; - int letter; - int *variable; - setopt_set_func_t *set_func; - setopt_get_func_t *get_func; -} o_options[] = { - { "allexport", 'a', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, -#if defined (BRACE_EXPANSION) - { "braceexpand",'B', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, -#endif -#if defined (READLINE) - { "emacs", '\0', (int *)NULL, set_edit_mode, get_edit_mode }, -#endif - { "errexit", 'e', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, - { "errtrace", 'E', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, - { "functrace", 'T', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, - { "hashall", 'h', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, -#if defined (BANG_HISTORY) - { "histexpand", 'H', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, -#endif /* BANG_HISTORY */ -#if defined (HISTORY) - { "history", '\0', &enable_history_list, bash_set_history, (setopt_get_func_t *)NULL }, -#endif - { "ignoreeof", '\0', &ignoreeof, set_ignoreeof, (setopt_get_func_t *)NULL }, - { "interactive-comments", '\0', &interactive_comments, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, - { "keyword", 'k', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, -#if defined (JOB_CONTROL) - { "monitor", 'm', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, -#endif - { "noclobber", 'C', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, - { "noexec", 'n', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, - { "noglob", 'f', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, -#if defined (HISTORY) - { "nolog", '\0', &dont_save_function_defs, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, -#endif -#if defined (JOB_CONTROL) - { "notify", 'b', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, -#endif /* JOB_CONTROL */ - { "nounset", 'u', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, - { "onecmd", 't', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, - { "physical", 'P', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, - { "pipefail", '\0', &pipefail_opt, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, - { "posix", '\0', &posixly_correct, set_posix_mode, (setopt_get_func_t *)NULL }, - { "privileged", 'p', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, - { "verbose", 'v', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, -#if defined (READLINE) - { "vi", '\0', (int *)NULL, set_edit_mode, get_edit_mode }, -#endif - { "xtrace", 'x', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, - {(char *)NULL, 0 , (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL }, -}; - -#define N_O_OPTIONS (sizeof (o_options) / sizeof (o_options[0])) - -#define GET_BINARY_O_OPTION_VALUE(i, name) \ - ((o_options[i].get_func) ? (*o_options[i].get_func) (name) \ - : (*o_options[i].variable)) - -#define SET_BINARY_O_OPTION_VALUE(i, onoff, name) \ - ((o_options[i].set_func) ? (*o_options[i].set_func) (onoff, name) \ - : (*o_options[i].variable = (onoff == FLAG_ON))) - -static int -find_minus_o_option (name) - char *name; -{ - register int i; - - for (i = 0; o_options[i].name; i++) - if (STREQ (name, o_options[i].name)) - return i; - return -1; -} - -int -minus_o_option_value (name) - char *name; -{ - register int i; - int *on_or_off; - - i = find_minus_o_option (name); - if (i < 0) - return (-1); - - if (o_options[i].letter) - { - on_or_off = find_flag (o_options[i].letter); - return ((on_or_off == FLAG_UNKNOWN) ? -1 : *on_or_off); - } - else - return (GET_BINARY_O_OPTION_VALUE (i, name)); -} - -#define MINUS_O_FORMAT "%-15s\t%s\n" - -static void -print_minus_o_option (name, value, pflag) - char *name; - int value, pflag; -{ - if (pflag == 0) - printf (MINUS_O_FORMAT, name, value ? on : off); - else - printf ("set %co %s\n", value ? '-' : '+', name); -} - -void -list_minus_o_opts (mode, reusable) - int mode, reusable; -{ - register int i; - int *on_or_off, value; - - for (i = 0; o_options[i].name; i++) - { - if (o_options[i].letter) - { - value = 0; - on_or_off = find_flag (o_options[i].letter); - if (on_or_off == FLAG_UNKNOWN) - on_or_off = &value; - if (mode == -1 || mode == *on_or_off) - print_minus_o_option (o_options[i].name, *on_or_off, reusable); - } - else - { - value = GET_BINARY_O_OPTION_VALUE (i, o_options[i].name); - if (mode == -1 || mode == value) - print_minus_o_option (o_options[i].name, value, reusable); - } - } -} - -char ** -get_minus_o_opts () -{ - char **ret; - int i; - - ret = strvec_create (N_O_OPTIONS + 1); - for (i = 0; o_options[i].name; i++) - ret[i] = o_options[i].name; - ret[i] = (char *)NULL; - return ret; -} - -char * -get_current_options () -{ - char *temp; - int i, posixopts; - - posixopts = num_posix_options (); /* shopts modified by posix mode */ - /* Make the buffer big enough to hold the set -o options and the shopt - options modified by posix mode. */ - temp = (char *)xmalloc (1 + N_O_OPTIONS + posixopts); - for (i = 0; o_options[i].name; i++) - { - if (o_options[i].letter) - temp[i] = *(find_flag (o_options[i].letter)); - else - temp[i] = GET_BINARY_O_OPTION_VALUE (i, o_options[i].name); - } - - /* Add the shell options that are modified by posix mode to the end of the - bitmap. They will be handled in set_current_options() */ - get_posix_options (temp+i); - temp[i+posixopts] = '\0'; - return (temp); -} - -void -set_current_options (bitmap) - const char *bitmap; -{ - int i, v, cv, *on_or_off; - - if (bitmap == 0) - return; - - for (i = 0; o_options[i].name; i++) - { - v = bitmap[i] ? FLAG_ON : FLAG_OFF; - if (o_options[i].letter) - { - /* We should not get FLAG_UNKNOWN here */ - on_or_off = find_flag (o_options[i].letter); - cv = *on_or_off ? FLAG_ON : FLAG_OFF; - if (v != cv) - change_flag (o_options[i].letter, v); - } - else - { - cv = GET_BINARY_O_OPTION_VALUE (i, o_options[i].name); - cv = cv ? FLAG_ON : FLAG_OFF; - if (v != cv) - SET_BINARY_O_OPTION_VALUE (i, v, o_options[i].name); - } - } - - /* Now reset the variables changed by posix mode */ - set_posix_options (bitmap+i); -} - -static int -set_ignoreeof (on_or_off, option_name) - int on_or_off; - char *option_name; -{ - ignoreeof = on_or_off == FLAG_ON; - unbind_variable_noref ("ignoreeof"); - if (ignoreeof) - bind_variable ("IGNOREEOF", "10", 0); - else - unbind_variable_noref ("IGNOREEOF"); - sv_ignoreeof ("IGNOREEOF"); - return 0; -} - -static int -set_posix_mode (on_or_off, option_name) - int on_or_off; - char *option_name; -{ - /* short-circuit on no-op */ - if ((on_or_off == FLAG_ON && posixly_correct) || - (on_or_off == FLAG_OFF && posixly_correct == 0)) - return 0; - - posixly_correct = on_or_off == FLAG_ON; - if (posixly_correct == 0) - unbind_variable_noref ("POSIXLY_CORRECT"); - else - bind_variable ("POSIXLY_CORRECT", "y", 0); - sv_strict_posix ("POSIXLY_CORRECT"); - return (0); -} - -#if defined (READLINE) -/* Magic. This code `knows' how readline handles rl_editing_mode. */ -static int -set_edit_mode (on_or_off, option_name) - int on_or_off; - char *option_name; -{ - int isemacs; - - if (on_or_off == FLAG_ON) - { - rl_variable_bind ("editing-mode", option_name); - - if (interactive) - with_input_from_stdin (); - no_line_editing = 0; - } - else - { - isemacs = rl_editing_mode == 1; - if ((isemacs && *option_name == 'e') || (!isemacs && *option_name == 'v')) - { - if (interactive) - with_input_from_stream (stdin, "stdin"); - no_line_editing = 1; - } - } - return 1-no_line_editing; -} - -static int -get_edit_mode (name) - char *name; -{ - return (*name == 'e' ? no_line_editing == 0 && rl_editing_mode == 1 - : no_line_editing == 0 && rl_editing_mode == 0); -} -#endif /* READLINE */ - -#if defined (HISTORY) -static int -bash_set_history (on_or_off, option_name) - int on_or_off; - char *option_name; -{ - if (on_or_off == FLAG_ON) - { - enable_history_list = 1; - bash_history_enable (); - if (history_lines_this_session == 0) - load_history (); - } - else - { - enable_history_list = 0; - bash_history_disable (); - } - return (1 - enable_history_list); -} -#endif - -int -set_minus_o_option (on_or_off, option_name) - int on_or_off; - char *option_name; -{ - register int i; - - i = find_minus_o_option (option_name); - if (i < 0) - { - sh_invalidoptname (option_name); - return (EX_USAGE); - } - - if (o_options[i].letter == 0) - { - previous_option_value = GET_BINARY_O_OPTION_VALUE (i, o_options[i].name); - SET_BINARY_O_OPTION_VALUE (i, on_or_off, option_name); - return (EXECUTION_SUCCESS); - } - else - { - if ((previous_option_value = change_flag (o_options[i].letter, on_or_off)) == FLAG_ERROR) - { - sh_invalidoptname (option_name); - return (EXECUTION_FAILURE); - } - else - return (EXECUTION_SUCCESS); - } -} - -static void -print_all_shell_variables () -{ - SHELL_VAR **vars; - - vars = all_shell_variables (); - if (vars) - { - print_var_list (vars); - free (vars); - } - - /* POSIX.2 does not allow function names and definitions to be output when - `set' is invoked without options (PASC Interp #202). */ - if (posixly_correct == 0) - { - vars = all_shell_functions (); - if (vars) - { - print_func_list (vars); - free (vars); - } - } -} - -void -set_shellopts () -{ - char *value; - char tflag[N_O_OPTIONS]; - int vsize, i, vptr, *ip, exported; - SHELL_VAR *v; - - for (vsize = i = 0; o_options[i].name; i++) - { - tflag[i] = 0; - if (o_options[i].letter) - { - ip = find_flag (o_options[i].letter); - if (ip && *ip) - { - vsize += strlen (o_options[i].name) + 1; - tflag[i] = 1; - } - } - else if (GET_BINARY_O_OPTION_VALUE (i, o_options[i].name)) - { - vsize += strlen (o_options[i].name) + 1; - tflag[i] = 1; - } - } - - value = (char *)xmalloc (vsize + 1); - - for (i = vptr = 0; o_options[i].name; i++) - { - if (tflag[i]) - { - strcpy (value + vptr, o_options[i].name); - vptr += strlen (o_options[i].name); - value[vptr++] = ':'; - } - } - - if (vptr) - vptr--; /* cut off trailing colon */ - value[vptr] = '\0'; - - v = find_variable ("SHELLOPTS"); - - /* Turn off the read-only attribute so we can bind the new value, and - note whether or not the variable was exported. */ - if (v) - { - VUNSETATTR (v, att_readonly); - exported = exported_p (v); - } - else - exported = 0; - - v = bind_variable ("SHELLOPTS", value, 0); - - /* Turn the read-only attribute back on, and turn off the export attribute - if it was set implicitly by mark_modified_vars and SHELLOPTS was not - exported before we bound the new value. */ - VSETATTR (v, att_readonly); - if (mark_modified_vars && exported == 0 && exported_p (v)) - VUNSETATTR (v, att_exported); - - free (value); -} - -void -parse_shellopts (value) - char *value; -{ - char *vname; - int vptr; - - vptr = 0; - while (vname = extract_colon_unit (value, &vptr)) - { - set_minus_o_option (FLAG_ON, vname); - free (vname); - } -} - -void -initialize_shell_options (no_shellopts) - int no_shellopts; -{ - char *temp; - SHELL_VAR *var; - - if (no_shellopts == 0) - { - var = find_variable ("SHELLOPTS"); - /* set up any shell options we may have inherited. */ - if (var && imported_p (var)) - { - temp = (array_p (var) || assoc_p (var)) ? (char *)NULL : savestring (value_cell (var)); - if (temp) - { - parse_shellopts (temp); - free (temp); - } - } - } - - /* Set up the $SHELLOPTS variable. */ - set_shellopts (); -} - -/* Reset the values of the -o options that are not also shell flags. This is - called from execute_cmd.c:initialize_subshell() when setting up a subshell - to run an executable shell script without a leading `#!'. */ -void -reset_shell_options () -{ - pipefail_opt = 0; - ignoreeof = 0; - -#if defined (STRICT_POSIX) - posixly_correct = 1; -#else - posixly_correct = 0; -#endif -#if defined (HISTORY) - dont_save_function_defs = 0; - remember_on_history = enable_history_list = 1; /* XXX */ -#endif -} - -/* Set some flags from the word values in the input list. If LIST is empty, - then print out the values of the variables instead. If LIST contains - non-flags, then set $1 - $9 to the successive words of LIST. */ -int -set_builtin (list) - WORD_LIST *list; -{ - int on_or_off, flag_name, force_assignment, opts_changed, rv, r; - register char *arg; - char s[3]; - - if (list == 0) - { - print_all_shell_variables (); - return (sh_chkwrite (EXECUTION_SUCCESS)); - } - - /* Check validity of flag arguments. */ - rv = EXECUTION_SUCCESS; - reset_internal_getopt (); - while ((flag_name = internal_getopt (list, optflags)) != -1) - { - switch (flag_name) - { - case 'i': /* don't allow set -i */ - s[0] = list_opttype; - s[1] = 'i'; - s[2] = '\0'; - sh_invalidopt (s); - builtin_usage (); - return (EX_USAGE); - CASE_HELPOPT; - case '?': - builtin_usage (); - return (list_optopt == '?' ? EXECUTION_SUCCESS : EX_USAGE); - default: - break; - } - } - - /* Do the set command. While the list consists of words starting with - '-' or '+' treat them as flags, otherwise, start assigning them to - $1 ... $n. */ - for (force_assignment = opts_changed = 0; list; ) - { - arg = list->word->word; - - /* If the argument is `--' or `-' then signal the end of the list - and remember the remaining arguments. */ - if (arg[0] == '-' && (!arg[1] || (arg[1] == '-' && !arg[2]))) - { - list = list->next; - - /* `set --' unsets the positional parameters. */ - if (arg[1] == '-') - force_assignment = 1; - - /* Until told differently, the old shell behaviour of - `set - [arg ...]' being equivalent to `set +xv [arg ...]' - stands. Posix.2 says the behaviour is marked as obsolescent. */ - else - { - change_flag ('x', '+'); - change_flag ('v', '+'); - opts_changed = 1; - } - - break; - } - - if ((on_or_off = *arg) && (on_or_off == '-' || on_or_off == '+')) - { - while (flag_name = *++arg) - { - if (flag_name == '?') - { - builtin_usage (); - return (EXECUTION_SUCCESS); - } - else if (flag_name == 'o') /* -+o option-name */ - { - char *option_name; - WORD_LIST *opt; - - opt = list->next; - - if (opt == 0) - { - list_minus_o_opts (-1, (on_or_off == '+')); - rv = sh_chkwrite (rv); - continue; - } - - option_name = opt->word->word; - - if (option_name == 0 || *option_name == '\0' || - *option_name == '-' || *option_name == '+') - { - list_minus_o_opts (-1, (on_or_off == '+')); - continue; - } - list = list->next; /* Skip over option name. */ - - opts_changed = 1; - if ((r = set_minus_o_option (on_or_off, option_name)) != EXECUTION_SUCCESS) - { - set_shellopts (); - return (r); - } - } - else if (change_flag (flag_name, on_or_off) == FLAG_ERROR) - { - s[0] = on_or_off; - s[1] = flag_name; - s[2] = '\0'; - sh_invalidopt (s); - builtin_usage (); - set_shellopts (); - return (EXECUTION_FAILURE); - } - opts_changed = 1; - } - } - else - { - break; - } - list = list->next; - } - - /* Assigning $1 ... $n */ - if (list || force_assignment) - remember_args (list, 1); - /* Set up new value of $SHELLOPTS */ - if (opts_changed) - set_shellopts (); - return (rv); -} - -#line 830 "./set.def" - -#define NEXT_VARIABLE() any_failed++; list = list->next; continue; - -int -unset_builtin (list) - WORD_LIST *list; -{ - int unset_function, unset_variable, unset_array, opt, nameref, any_failed; - int global_unset_func, global_unset_var, vflags, base_vflags, valid_id; - char *name, *tname; - - unset_function = unset_variable = unset_array = nameref = any_failed = 0; - global_unset_func = global_unset_var = 0; - - reset_internal_getopt (); - while ((opt = internal_getopt (list, "fnv")) != -1) - { - switch (opt) - { - case 'f': - global_unset_func = 1; - break; - case 'v': - global_unset_var = 1; - break; - case 'n': - nameref = 1; - break; - CASE_HELPOPT; - default: - builtin_usage (); - return (EX_USAGE); - } - } - - list = loptend; - - if (global_unset_func && global_unset_var) - { - builtin_error (_("cannot simultaneously unset a function and a variable")); - return (EXECUTION_FAILURE); - } - else if (unset_function && nameref) - nameref = 0; - -#if defined (ARRAY_VARS) - base_vflags = assoc_expand_once ? VA_NOEXPAND : 0; -#endif - - while (list) - { - SHELL_VAR *var; - int tem; -#if defined (ARRAY_VARS) - char *t; -#endif - - name = list->word->word; - - unset_function = global_unset_func; - unset_variable = global_unset_var; - -#if defined (ARRAY_VARS) - vflags = builtin_arrayref_flags (list->word, base_vflags); -#endif - -#if defined (ARRAY_VARS) - unset_array = 0; - /* XXX valid array reference second arg was 0 */ - if (!unset_function && nameref == 0 && tokenize_array_reference (name, vflags, &t)) - unset_array = 1; -#endif - /* Get error checking out of the way first. The low-level functions - just perform the unset, relying on the caller to verify. */ - valid_id = legal_identifier (name); - - /* Whether or not we are in posix mode, if neither -f nor -v appears, - skip over trying to unset variables with invalid names and just - treat them as potential shell function names. */ - if (global_unset_func == 0 && global_unset_var == 0 && valid_id == 0) - { - unset_variable = unset_array = 0; - unset_function = 1; - } - - /* Bash allows functions with names which are not valid identifiers - to be created when not in posix mode, so check only when in posix - mode when unsetting a function. */ - if (unset_function == 0 && valid_id == 0) - { - sh_invalidid (name); - NEXT_VARIABLE (); - } - - /* Search for functions here if -f supplied or if NAME cannot be a - variable name. */ - var = unset_function ? find_function (name) - : (nameref ? find_variable_last_nameref (name, 0) : find_variable (name)); - - /* Some variables (but not functions yet) cannot be unset, period. */ - if (var && unset_function == 0 && non_unsettable_p (var)) - { - builtin_error (_("%s: cannot unset"), name); - NEXT_VARIABLE (); - } - - /* if we have a nameref we want to use it */ - if (var && unset_function == 0 && nameref == 0 && STREQ (name, name_cell(var)) == 0) - name = name_cell (var); - - /* Posix.2 says try variables first, then functions. If we would - find a function after unsuccessfully searching for a variable, - note that we're acting on a function now as if -f were - supplied. The readonly check below takes care of it. */ - if (var == 0 && nameref == 0 && unset_variable == 0 && unset_function == 0) - { - if (var = find_function (name)) - unset_function = 1; - } - - /* Posix.2 says that unsetting readonly variables is an error. */ - if (var && readonly_p (var)) - { - builtin_error (_("%s: cannot unset: readonly %s"), - var->name, unset_function ? "function" : "variable"); - NEXT_VARIABLE (); - } - - /* Unless the -f option is supplied, the name refers to a variable. */ -#if defined (ARRAY_VARS) - if (var && unset_array) - { - if (shell_compatibility_level <= 51) - vflags |= VA_ALLOWALL; - - /* Let unbind_array_element decide what to do with non-array vars */ - tem = unbind_array_element (var, t, vflags); /* XXX new third arg */ - if (tem == -2 && array_p (var) == 0 && assoc_p (var) == 0) - { - builtin_error (_("%s: not an array variable"), var->name); - NEXT_VARIABLE (); - } - else if (tem < 0) - any_failed++; - } - else -#endif /* ARRAY_VARS */ - /* If we're trying to unset a nameref variable whose value isn't a set - variable, make sure we still try to unset the nameref's value */ - if (var == 0 && nameref == 0 && unset_function == 0) - { - var = find_variable_last_nameref (name, 0); - if (var && nameref_p (var)) - { -#if defined (ARRAY_VARS) - if (valid_array_reference (nameref_cell (var), 0)) - { - int len; - - tname = savestring (nameref_cell (var)); - if (var = array_variable_part (tname, 0, &t, &len)) - { - /* change to what unbind_array_element now expects */ - if (t[len - 1] == ']') - t[len - 1] = 0; - tem = unbind_array_element (var, t, vflags); /* XXX new third arg */ - } - free (tname); - } - else -#endif - tem = unbind_variable (nameref_cell (var)); - } - else - tem = unbind_variable (name); - } - else - tem = unset_function ? unbind_func (name) : (nameref ? unbind_nameref (name) : unbind_variable (name)); - - /* This is what Posix.2 says: ``If neither -f nor -v - is specified, the name refers to a variable; if a variable by - that name does not exist, a function by that name, if any, - shall be unset.'' */ - if (tem == -1 && nameref == 0 && unset_function == 0 && unset_variable == 0) - tem = unbind_func (name); - - name = list->word->word; /* reset above for namerefs */ - - /* SUSv3, POSIX.1-2001 say: ``Unsetting a variable or function that - was not previously set shall not be considered an error.'' */ - - if (unset_function == 0) - stupidly_hack_special_variables (name); - - list = list->next; - } - - return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS); -} diff --git a/third_party/bash/builtins_setattr.c b/third_party/bash/builtins_setattr.c deleted file mode 100644 index 8a9ccefa4..000000000 --- a/third_party/bash/builtins_setattr.c +++ /dev/null @@ -1,616 +0,0 @@ -/* setattr.c, created from setattr.def. */ -#line 22 "./setattr.def" - -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include -#include "bashansi.h" -#include "bashintl.h" - -#include "shell.h" -#include "execute_cmd.h" -#include "flags.h" -#include "common.h" -#include "bashgetopt.h" - -extern sh_builtin_func_t *this_shell_builtin; - -#ifdef ARRAY_VARS -extern int declare_builtin PARAMS((WORD_LIST *)); -#endif - -#define READONLY_OR_EXPORT \ - (this_shell_builtin == readonly_builtin || this_shell_builtin == export_builtin) - -#line 69 "./setattr.def" - -/* For each variable name in LIST, make that variable appear in the - environment passed to simple commands. If there is no LIST, then - print all such variables. An argument of `-n' says to remove the - exported attribute from variables named in LIST. An argument of - -f indicates that the names present in LIST refer to functions. */ -int -export_builtin (list) - register WORD_LIST *list; -{ - return (set_or_show_attributes (list, att_exported, 0)); -} - -#line 103 "./setattr.def" - -/* For each variable name in LIST, make that variable readonly. Given an - empty LIST, print out all existing readonly variables. */ -int -readonly_builtin (list) - register WORD_LIST *list; -{ - return (set_or_show_attributes (list, att_readonly, 0)); -} - -#if defined (ARRAY_VARS) -# define ATTROPTS "aAfnp" -#else -# define ATTROPTS "fnp" -#endif - -/* For each variable name in LIST, make that variable have the specified - ATTRIBUTE. An arg of `-n' says to remove the attribute from the the - remaining names in LIST (doesn't work for readonly). */ -int -set_or_show_attributes (list, attribute, nodefs) - register WORD_LIST *list; - int attribute, nodefs; -{ - register SHELL_VAR *var; - int assign, undo, any_failed, assign_error, opt; - int functions_only, arrays_only, assoc_only; - int aflags; - char *name; -#if defined (ARRAY_VARS) - WORD_LIST *nlist, *tlist; - WORD_DESC *w; - char optw[8]; - int opti; -#endif - - functions_only = arrays_only = assoc_only = 0; - undo = any_failed = assign_error = 0; - /* Read arguments from the front of the list. */ - reset_internal_getopt (); - while ((opt = internal_getopt (list, ATTROPTS)) != -1) - { - switch (opt) - { - case 'n': - undo = 1; - break; - case 'f': - functions_only = 1; - break; -#if defined (ARRAY_VARS) - case 'a': - arrays_only = 1; - break; - case 'A': - assoc_only = 1; - break; -#endif - case 'p': - break; - CASE_HELPOPT; - default: - builtin_usage (); - return (EX_USAGE); - } - } - list = loptend; - - if (list) - { - if (attribute & att_exported) - array_needs_making = 1; - - /* Cannot undo readonly status, silently disallowed. */ - if (undo && (attribute & att_readonly)) - attribute &= ~att_readonly; - - while (list) - { - name = list->word->word; - - if (functions_only) /* xxx -f name */ - { - var = find_function (name); - if (var == 0) - { - builtin_error (_("%s: not a function"), name); - any_failed++; - } - else if ((attribute & att_exported) && undo == 0 && exportable_function_name (name) == 0) - { - builtin_error (_("%s: cannot export"), name); - any_failed++; - } - else - SETVARATTR (var, attribute, undo); - - list = list->next; - continue; - } - - /* xxx [-np] name[=value] */ - assign = assignment (name, 0); - - aflags = 0; - if (assign) - { - name[assign] = '\0'; - if (name[assign - 1] == '+') - { - aflags |= ASS_APPEND; - name[assign - 1] = '\0'; - } - } - - if (legal_identifier (name) == 0) - { - sh_invalidid (name); - if (assign) - assign_error++; - else - any_failed++; - list = list->next; - continue; - } - - if (assign) /* xxx [-np] name=value */ - { - name[assign] = '='; - if (aflags & ASS_APPEND) - name[assign - 1] = '+'; -#if defined (ARRAY_VARS) - /* Let's try something here. Turn readonly -a xxx=yyy into - declare -ra xxx=yyy and see what that gets us. */ - if (arrays_only || assoc_only) - { - tlist = list->next; - list->next = (WORD_LIST *)NULL; - /* Add -g to avoid readonly/export creating local variables: - only local/declare/typeset create local variables */ - opti = 0; - optw[opti++] = '-'; - optw[opti++] = 'g'; - if (attribute & att_readonly) - optw[opti++] = 'r'; - if (attribute & att_exported) - optw[opti++] = 'x'; - if (arrays_only) - optw[opti++] = 'a'; - else - optw[opti++] = 'A'; - optw[opti] = '\0'; - - w = make_word (optw); - nlist = make_word_list (w, list); - - opt = declare_builtin (nlist); - if (opt != EXECUTION_SUCCESS) - assign_error++; - list->next = tlist; - dispose_word (w); - free (nlist); - } - else -#endif - /* This word has already been expanded once with command - and parameter expansion. Call do_assignment_no_expand (), - which does not do command or parameter substitution. If - the assignment is not performed correctly, flag an error. */ - if (do_assignment_no_expand (name) == 0) - assign_error++; - name[assign] = '\0'; - if (aflags & ASS_APPEND) - name[assign - 1] = '\0'; - } - - set_var_attribute (name, attribute, undo); - if (assign) /* restore word */ - { - name[assign] = '='; - if (aflags & ASS_APPEND) - name[assign-1] = '+'; - } - list = list->next; - } - } - else - { - SHELL_VAR **variable_list; - register int i; - - if ((attribute & att_function) || functions_only) - { - variable_list = all_shell_functions (); - if (attribute != att_function) - attribute &= ~att_function; /* so declare -xf works, for example */ - } - else - variable_list = all_shell_variables (); - -#if defined (ARRAY_VARS) - if (attribute & att_array) - { - arrays_only++; - if (attribute != att_array) - attribute &= ~att_array; - } - else if (attribute & att_assoc) - { - assoc_only++; - if (attribute != att_assoc) - attribute &= ~att_assoc; - } -#endif - - if (variable_list) - { - for (i = 0; var = variable_list[i]; i++) - { -#if defined (ARRAY_VARS) - if (arrays_only && array_p (var) == 0) - continue; - else if (assoc_only && assoc_p (var) == 0) - continue; -#endif - - /* If we imported a variable that's not a valid identifier, don't - show it in any lists. */ - if ((var->attributes & (att_invisible|att_imported)) == (att_invisible|att_imported)) - continue; - - if ((var->attributes & attribute)) - { - show_var_attributes (var, READONLY_OR_EXPORT, nodefs); - if (any_failed = sh_chkwrite (any_failed)) - break; - } - } - free (variable_list); - } - } - - return (assign_error ? EX_BADASSIGN - : ((any_failed == 0) ? EXECUTION_SUCCESS - : EXECUTION_FAILURE)); -} - -/* Show all variable variables (v == 1) or functions (v == 0) with - attributes. */ -int -show_all_var_attributes (v, nodefs) - int v, nodefs; -{ - SHELL_VAR **variable_list, *var; - int any_failed; - register int i; - - variable_list = v ? all_shell_variables () : all_shell_functions (); - if (variable_list == 0) - return (EXECUTION_SUCCESS); - - for (i = any_failed = 0; var = variable_list[i]; i++) - { - /* There is no equivalent `declare -'. */ - if (variable_context && var->context == variable_context && STREQ (var->name, "-")) - printf ("local -\n"); - else - show_var_attributes (var, READONLY_OR_EXPORT, nodefs); - if (any_failed = sh_chkwrite (any_failed)) - break; - } - free (variable_list); - return (any_failed == 0 ? EXECUTION_SUCCESS : EXECUTION_FAILURE); -} - -/* Show all local variable variables with their attributes. This shows unset - local variables (all_local_variables called with 0 argument). */ -int -show_local_var_attributes (v, nodefs) - int v, nodefs; -{ - SHELL_VAR **variable_list, *var; - int any_failed; - register int i; - - variable_list = all_local_variables (0); - if (variable_list == 0) - return (EXECUTION_SUCCESS); - - for (i = any_failed = 0; var = variable_list[i]; i++) - { - /* There is no equivalent `declare -'. */ - if (STREQ (var->name, "-")) - printf ("local -\n"); - else - show_var_attributes (var, READONLY_OR_EXPORT, nodefs); - if (any_failed = sh_chkwrite (any_failed)) - break; - } - free (variable_list); - return (any_failed == 0 ? EXECUTION_SUCCESS : EXECUTION_FAILURE); -} - -int -var_attribute_string (var, pattr, flags) - SHELL_VAR *var; - int pattr; - char *flags; /* filled in with attributes */ -{ - int i; - - i = 0; - - /* pattr == 0 means we are called from `declare'. */ - if (pattr == 0 || posixly_correct == 0) - { -#if defined (ARRAY_VARS) - if (array_p (var)) - flags[i++] = 'a'; - - if (assoc_p (var)) - flags[i++] = 'A'; -#endif - - if (function_p (var)) - flags[i++] = 'f'; - - if (integer_p (var)) - flags[i++] = 'i'; - - if (nameref_p (var)) - flags[i++] = 'n'; - - if (readonly_p (var)) - flags[i++] = 'r'; - - if (trace_p (var)) - flags[i++] = 't'; - - if (exported_p (var)) - flags[i++] = 'x'; - - if (capcase_p (var)) - flags[i++] = 'c'; - - if (lowercase_p (var)) - flags[i++] = 'l'; - - if (uppercase_p (var)) - flags[i++] = 'u'; - } - else - { -#if defined (ARRAY_VARS) - if (array_p (var)) - flags[i++] = 'a'; - - if (assoc_p (var)) - flags[i++] = 'A'; -#endif - - if (function_p (var)) - flags[i++] = 'f'; - } - - flags[i] = '\0'; - return i; -} - -/* Show the attributes for shell variable VAR. If NODEFS is non-zero, - don't show function definitions along with the name. If PATTR is - non-zero, it indicates we're being called from `export' or `readonly'. - In POSIX mode, this prints the name of the calling builtin (`export' - or `readonly') instead of `declare', and doesn't print function defs - when called by `export' or `readonly'. */ -int -show_var_attributes (var, pattr, nodefs) - SHELL_VAR *var; - int pattr, nodefs; -{ - char flags[MAX_ATTRIBUTES], *x; - int i; - - i = var_attribute_string (var, pattr, flags); - - /* If we're printing functions with definitions, print the function def - first, then the attributes, instead of printing output that can't be - reused as input to recreate the current state. */ - if (function_p (var) && nodefs == 0 && (pattr == 0 || posixly_correct == 0)) - { - printf ("%s\n", named_function_string (var->name, function_cell (var), FUNC_MULTILINE|FUNC_EXTERNAL)); - nodefs++; - if (pattr == 0 && i == 1 && flags[0] == 'f') - return 0; /* don't print `declare -f name' */ - } - - if (pattr == 0 || posixly_correct == 0) - printf ("declare -%s ", i ? flags : "-"); - else if (i) - printf ("%s -%s ", this_command_name, flags); - else - printf ("%s ", this_command_name); - -#if defined (ARRAY_VARS) - if (invisible_p (var) && (array_p (var) || assoc_p (var))) - printf ("%s\n", var->name); - else if (array_p (var)) - print_array_assignment (var, 0); - else if (assoc_p (var)) - print_assoc_assignment (var, 0); - else -#endif - /* force `readonly' and `export' to not print out function definitions - when in POSIX mode. */ - if (nodefs || (function_p (var) && pattr != 0 && posixly_correct)) - printf ("%s\n", var->name); - else if (function_p (var)) - printf ("%s\n", named_function_string (var->name, function_cell (var), FUNC_MULTILINE|FUNC_EXTERNAL)); - else if (invisible_p (var) || var_isset (var) == 0) - printf ("%s\n", var->name); - else - { - if (ansic_shouldquote (value_cell (var))) - x = ansic_quote (value_cell (var), 0, (int *)0); - else - x = sh_double_quote (value_cell (var)); - printf ("%s=%s\n", var->name, x); - free (x); - } - return (0); -} - -int -show_name_attributes (name, nodefs) - char *name; - int nodefs; -{ - SHELL_VAR *var; - - var = find_variable_noref (name); - - if (var) /* show every variable with attributes, even unset ones */ - { - show_var_attributes (var, READONLY_OR_EXPORT, nodefs); - return (0); - } - else - return (1); -} - -int -show_localname_attributes (name, nodefs) - char *name; - int nodefs; -{ - SHELL_VAR *var; - - var = find_variable_noref (name); - - if (var && local_p (var) && var->context == variable_context) /* show every variable with attributes, even unset ones */ - { - show_var_attributes (var, READONLY_OR_EXPORT, nodefs); - return (0); - } - else - return (1); -} - -int -show_func_attributes (name, nodefs) - char *name; - int nodefs; -{ - SHELL_VAR *var; - - var = find_function (name); - - if (var) - { - show_var_attributes (var, READONLY_OR_EXPORT, nodefs); - return (0); - } - else - return (1); -} - -void -set_var_attribute (name, attribute, undo) - char *name; - int attribute, undo; -{ - SHELL_VAR *var, *tv, *v, *refvar; - char *tvalue; - - if (undo) - var = find_variable (name); - else - { - tv = find_tempenv_variable (name); - /* XXX -- need to handle case where tv is a temp variable in a - function-scope context, since function_env has been merged into - the local variables table. */ - if (tv && tempvar_p (tv)) - { - tvalue = var_isset (tv) ? savestring (value_cell (tv)) : savestring (""); - - var = bind_variable (tv->name, tvalue, 0); - if (var == 0) - { - free (tvalue); - return; /* XXX - no error message here */ - } - var->attributes |= tv->attributes & ~att_tempvar; - /* This avoids an error message when propagating a read-only var - later on. */ - if (posixly_correct || shell_compatibility_level <= 44) - { - if (var->context == 0 && (attribute & att_readonly)) - { - /* Don't bother to set the `propagate to the global variables - table' flag if we've just bound the variable in that - table */ - v = find_global_variable (tv->name); - if (v != var) - VSETATTR (tv, att_propagate); - } - else - VSETATTR (tv, att_propagate); - if (var->context != 0) - VSETATTR (var, att_propagate); - } - - SETVARATTR (tv, attribute, undo); /* XXX */ - - stupidly_hack_special_variables (tv->name); - - free (tvalue); - } - else - { - var = find_variable_notempenv (name); - if (var == 0) - { - /* We might have a nameref pointing to something that we can't - resolve to a shell variable. If we do, skip it. We do a little - checking just so we can print an error message. */ - refvar = find_variable_nameref_for_create (name, 0); - if (refvar == INVALID_NAMEREF_VALUE) - return; - /* Otherwise we probably have a nameref pointing to a variable - that hasn't been created yet. bind_variable will take care - of that. */ - } - if (var == 0) - { - var = bind_variable (name, (char *)NULL, 0); - if (var) - VSETATTR (var, att_invisible); - } - else if (var->context != 0) - VSETATTR (var, att_propagate); - } - } - - if (var) - SETVARATTR (var, attribute, undo); - - if (var && (exported_p (var) || (attribute & att_exported))) - array_needs_making++; /* XXX */ -} diff --git a/third_party/bash/builtins_shift.c b/third_party/bash/builtins_shift.c deleted file mode 100644 index 669b60e38..000000000 --- a/third_party/bash/builtins_shift.c +++ /dev/null @@ -1,61 +0,0 @@ -/* shift.c, created from shift.def. */ -#line 22 "./shift.def" - -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include "bashansi.h" -#include "bashintl.h" - -#include "shell.h" -#include "common.h" - -#line 49 "./shift.def" - -int print_shift_error; - -/* Shift the arguments ``left''. Shift DOLLAR_VARS down then take one - off of REST_OF_ARGS and place it into DOLLAR_VARS[9]. If LIST has - anything in it, it is a number which says where to start the - shifting. Return > 0 if `times' > $#, otherwise 0. */ -int -shift_builtin (list) - WORD_LIST *list; -{ - intmax_t times; - int itimes, nargs; - - CHECK_HELPOPT (list); - - if (get_numeric_arg (list, 0, ×) == 0) - return (EXECUTION_FAILURE); - - if (times == 0) - return (EXECUTION_SUCCESS); - else if (times < 0) - { - sh_erange (list ? list->word->word : NULL, _("shift count")); - return (EXECUTION_FAILURE); - } - nargs = number_of_args (); - if (times > nargs) - { - if (print_shift_error) - sh_erange (list ? list->word->word : NULL, _("shift count")); - return (EXECUTION_FAILURE); - } - else if (times == nargs) - clear_dollar_vars (); - else - shift_args (itimes = times); - - invalidate_cached_quoted_dollar_at (); - - return (EXECUTION_SUCCESS); -} diff --git a/third_party/bash/builtins_shopt.c b/third_party/bash/builtins_shopt.c deleted file mode 100644 index 3935c8077..000000000 --- a/third_party/bash/builtins_shopt.c +++ /dev/null @@ -1,900 +0,0 @@ -/* shopt.c, created from shopt.def. */ -#line 22 "./shopt.def" - -#line 43 "./shopt.def" - -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include - -#include "version.h" - -#include "bashintl.h" - -#include "shell.h" -#include "flags.h" -#include "common.h" -#include "bashgetopt.h" - -#if defined (READLINE) -# include "bashline.h" -#endif - -#if defined (HISTORY) -# include "bashhist.h" -#endif - -#define UNSETOPT 0 -#define SETOPT 1 - -#define OPTFMT "%-15s\t%s\n" - -extern int allow_null_glob_expansion, fail_glob_expansion, glob_dot_filenames; -extern int cdable_vars, mail_warning, source_uses_path; -extern int no_exit_on_failed_exec, print_shift_error; -extern int check_hashed_filenames, promptvars; -extern int cdspelling, expand_aliases; -extern int extended_quote; -extern int check_window_size; -extern int glob_ignore_case, match_ignore_case; -extern int hup_on_exit; -extern int xpg_echo; -extern int gnu_error_format; -extern int check_jobs_at_exit; -extern int autocd; -extern int glob_star; -extern int glob_asciirange; -extern int glob_always_skip_dot_and_dotdot; -extern int lastpipe_opt; -extern int inherit_errexit; -extern int localvar_inherit; -extern int localvar_unset; -extern int varassign_redir_autoclose; -extern int singlequote_translations; -extern int patsub_replacement; - -#if defined (EXTENDED_GLOB) -extern int extended_glob; -#endif - -#if defined (READLINE) -extern int hist_verify, history_reediting, perform_hostname_completion; -extern int no_empty_command_completion; -extern int force_fignore; -extern int dircomplete_spelling, dircomplete_expand; -extern int complete_fullquote; - -extern int enable_hostname_completion PARAMS((int)); -#endif - -#if defined (PROGRAMMABLE_COMPLETION) -extern int prog_completion_enabled; -extern int progcomp_alias; -#endif - -#if defined (DEBUGGER) -extern int debugging_mode; -#endif - -#if defined (ARRAY_VARS) -extern int assoc_expand_once; -extern int array_expand_once; -int expand_once_flag; -#endif - -#if defined (SYSLOG_HISTORY) -extern int syslog_history; -#endif - -static void shopt_error PARAMS((char *)); - -static int set_shellopts_after_change PARAMS((char *, int)); -static int set_compatibility_level PARAMS((char *, int)); - -#if defined (RESTRICTED_SHELL) -static int set_restricted_shell PARAMS((char *, int)); -#endif - -#if defined (READLINE) -static int shopt_enable_hostname_completion PARAMS((char *, int)); -static int shopt_set_complete_direxpand PARAMS((char *, int)); -#endif - -#if defined (ARRAY_VARS) -static int set_assoc_expand PARAMS((char *, int)); -#endif - -static int shopt_set_debug_mode PARAMS((char *, int)); - -static int shopt_login_shell; -static int shopt_compat31; -static int shopt_compat32; -static int shopt_compat40; -static int shopt_compat41; -static int shopt_compat42; -static int shopt_compat43; -static int shopt_compat44; - -typedef int shopt_set_func_t PARAMS((char *, int)); - -/* If you add a new variable name here, make sure to set the default value - appropriately in reset_shopt_options. */ - -static struct { - char *name; - int *value; - shopt_set_func_t *set_func; -} shopt_vars[] = { - { "autocd", &autocd, (shopt_set_func_t *)NULL }, -#if defined (ARRAY_VARS) - { "assoc_expand_once", &expand_once_flag, set_assoc_expand }, -#endif - { "cdable_vars", &cdable_vars, (shopt_set_func_t *)NULL }, - { "cdspell", &cdspelling, (shopt_set_func_t *)NULL }, - { "checkhash", &check_hashed_filenames, (shopt_set_func_t *)NULL }, -#if defined (JOB_CONTROL) - { "checkjobs", &check_jobs_at_exit, (shopt_set_func_t *)NULL }, -#endif - { "checkwinsize", &check_window_size, (shopt_set_func_t *)NULL }, -#if defined (HISTORY) - { "cmdhist", &command_oriented_history, (shopt_set_func_t *)NULL }, -#endif - { "compat31", &shopt_compat31, set_compatibility_level }, - { "compat32", &shopt_compat32, set_compatibility_level }, - { "compat40", &shopt_compat40, set_compatibility_level }, - { "compat41", &shopt_compat41, set_compatibility_level }, - { "compat42", &shopt_compat42, set_compatibility_level }, - { "compat43", &shopt_compat43, set_compatibility_level }, - { "compat44", &shopt_compat44, set_compatibility_level }, -#if defined (READLINE) - { "complete_fullquote", &complete_fullquote, (shopt_set_func_t *)NULL}, - { "direxpand", &dircomplete_expand, shopt_set_complete_direxpand }, - { "dirspell", &dircomplete_spelling, (shopt_set_func_t *)NULL }, -#endif - { "dotglob", &glob_dot_filenames, (shopt_set_func_t *)NULL }, - { "execfail", &no_exit_on_failed_exec, (shopt_set_func_t *)NULL }, - { "expand_aliases", &expand_aliases, (shopt_set_func_t *)NULL }, -#if defined (DEBUGGER) - { "extdebug", &debugging_mode, shopt_set_debug_mode }, -#endif -#if defined (EXTENDED_GLOB) - { "extglob", &extended_glob, (shopt_set_func_t *)NULL }, -#endif - { "extquote", &extended_quote, (shopt_set_func_t *)NULL }, - { "failglob", &fail_glob_expansion, (shopt_set_func_t *)NULL }, -#if defined (READLINE) - { "force_fignore", &force_fignore, (shopt_set_func_t *)NULL }, -#endif - { "globasciiranges", &glob_asciirange, (shopt_set_func_t *)NULL }, - { "globskipdots", &glob_always_skip_dot_and_dotdot, (shopt_set_func_t *)NULL }, - { "globstar", &glob_star, (shopt_set_func_t *)NULL }, - { "gnu_errfmt", &gnu_error_format, (shopt_set_func_t *)NULL }, -#if defined (HISTORY) - { "histappend", &force_append_history, (shopt_set_func_t *)NULL }, -#endif -#if defined (READLINE) - { "histreedit", &history_reediting, (shopt_set_func_t *)NULL }, - { "histverify", &hist_verify, (shopt_set_func_t *)NULL }, - { "hostcomplete", &perform_hostname_completion, shopt_enable_hostname_completion }, -#endif - { "huponexit", &hup_on_exit, (shopt_set_func_t *)NULL }, - { "inherit_errexit", &inherit_errexit, (shopt_set_func_t *)NULL }, - { "interactive_comments", &interactive_comments, set_shellopts_after_change }, - { "lastpipe", &lastpipe_opt, (shopt_set_func_t *)NULL }, -#if defined (HISTORY) - { "lithist", &literal_history, (shopt_set_func_t *)NULL }, -#endif - { "localvar_inherit", &localvar_inherit, (shopt_set_func_t *)NULL }, - { "localvar_unset", &localvar_unset, (shopt_set_func_t *)NULL }, - { "login_shell", &shopt_login_shell, set_login_shell }, - { "mailwarn", &mail_warning, (shopt_set_func_t *)NULL }, -#if defined (READLINE) - { "no_empty_cmd_completion", &no_empty_command_completion, (shopt_set_func_t *)NULL }, -#endif - { "nocaseglob", &glob_ignore_case, (shopt_set_func_t *)NULL }, - { "nocasematch", &match_ignore_case, (shopt_set_func_t *)NULL }, - { "noexpand_translation", &singlequote_translations, (shopt_set_func_t *)NULL }, - { "nullglob", &allow_null_glob_expansion, (shopt_set_func_t *)NULL }, - { "patsub_replacement", &patsub_replacement, (shopt_set_func_t *)NULL }, -#if defined (PROGRAMMABLE_COMPLETION) - { "progcomp", &prog_completion_enabled, (shopt_set_func_t *)NULL }, -# if defined (ALIAS) - { "progcomp_alias", &progcomp_alias, (shopt_set_func_t *)NULL }, -# endif -#endif - { "promptvars", &promptvars, (shopt_set_func_t *)NULL }, -#if defined (RESTRICTED_SHELL) - { "restricted_shell", &restricted_shell, set_restricted_shell }, -#endif - { "shift_verbose", &print_shift_error, (shopt_set_func_t *)NULL }, - { "sourcepath", &source_uses_path, (shopt_set_func_t *)NULL }, -#if defined (SYSLOG_HISTORY) && defined (SYSLOG_SHOPT) - { "syslog_history", &syslog_history, (shopt_set_func_t *)NULL }, -#endif - { "varredir_close", &varassign_redir_autoclose, (shopt_set_func_t *)NULL }, - { "xpg_echo", &xpg_echo, (shopt_set_func_t *)NULL }, - { (char *)0, (int *)0, (shopt_set_func_t *)NULL } -}; - -#define N_SHOPT_OPTIONS (sizeof (shopt_vars) / sizeof (shopt_vars[0])) - -#define GET_SHOPT_OPTION_VALUE(i) (*shopt_vars[i].value) - -static const char * const on = "on"; -static const char * const off = "off"; - -static int find_shopt PARAMS((char *)); -static int toggle_shopts PARAMS((int, WORD_LIST *, int)); -static void print_shopt PARAMS((char *, int, int)); -static int list_shopts PARAMS((WORD_LIST *, int)); -static int list_some_shopts PARAMS((int, int)); -static int list_shopt_o_options PARAMS((WORD_LIST *, int)); -static int list_some_o_options PARAMS((int, int)); -static int set_shopt_o_options PARAMS((int, WORD_LIST *, int)); - -#define SFLAG 0x01 -#define UFLAG 0x02 -#define QFLAG 0x04 -#define OFLAG 0x08 -#define PFLAG 0x10 - -int -shopt_builtin (list) - WORD_LIST *list; -{ - int opt, flags, rval; - - flags = 0; - reset_internal_getopt (); - while ((opt = internal_getopt (list, "psuoq")) != -1) - { - switch (opt) - { - case 's': - flags |= SFLAG; - break; - case 'u': - flags |= UFLAG; - break; - case 'q': - flags |= QFLAG; - break; - case 'o': - flags |= OFLAG; - break; - case 'p': - flags |= PFLAG; - break; - CASE_HELPOPT; - default: - builtin_usage (); - return (EX_USAGE); - } - } - list = loptend; - - if ((flags & (SFLAG|UFLAG)) == (SFLAG|UFLAG)) - { - builtin_error (_("cannot set and unset shell options simultaneously")); - return (EXECUTION_FAILURE); - } - - rval = EXECUTION_SUCCESS; - if ((flags & OFLAG) && ((flags & (SFLAG|UFLAG)) == 0)) /* shopt -o */ - rval = list_shopt_o_options (list, flags); - else if (list && (flags & OFLAG)) /* shopt -so args */ - rval = set_shopt_o_options ((flags & SFLAG) ? FLAG_ON : FLAG_OFF, list, flags & QFLAG); - else if (flags & OFLAG) /* shopt -so */ - rval = list_some_o_options ((flags & SFLAG) ? 1 : 0, flags); - else if (list && (flags & (SFLAG|UFLAG))) /* shopt -su args */ - rval = toggle_shopts ((flags & SFLAG) ? SETOPT : UNSETOPT, list, flags & QFLAG); - else if ((flags & (SFLAG|UFLAG)) == 0) /* shopt [args] */ - rval = list_shopts (list, flags); - else /* shopt -su */ - rval = list_some_shopts ((flags & SFLAG) ? SETOPT : UNSETOPT, flags); - return (rval); -} - -/* Reset the options managed by `shopt' to the values they would have at - shell startup. Variables from shopt_vars. */ -void -reset_shopt_options () -{ - autocd = cdable_vars = cdspelling = 0; - check_hashed_filenames = CHECKHASH_DEFAULT; - check_window_size = CHECKWINSIZE_DEFAULT; - allow_null_glob_expansion = glob_dot_filenames = 0; - no_exit_on_failed_exec = 0; - expand_aliases = 0; - extended_quote = 1; - fail_glob_expansion = 0; - glob_asciirange = GLOBASCII_DEFAULT; - glob_star = 0; - gnu_error_format = 0; - hup_on_exit = 0; - inherit_errexit = 0; - interactive_comments = 1; - lastpipe_opt = 0; - localvar_inherit = localvar_unset = 0; - mail_warning = 0; - glob_ignore_case = match_ignore_case = 0; - print_shift_error = 0; - source_uses_path = promptvars = 1; - varassign_redir_autoclose = 0; - singlequote_translations = 0; - patsub_replacement = 1; - -#if defined (JOB_CONTROL) - check_jobs_at_exit = 0; -#endif - -#if defined (EXTENDED_GLOB) - extended_glob = EXTGLOB_DEFAULT; -#endif - -#if defined (ARRAY_VARS) - expand_once_flag = assoc_expand_once = 0; -#endif - -#if defined (HISTORY) - literal_history = 0; - force_append_history = 0; - command_oriented_history = 1; -#endif - -#if defined (SYSLOG_HISTORY) -# if defined (SYSLOG_SHOPT) - syslog_history = SYSLOG_SHOPT; -# else - syslog_history = 1; -# endif /* SYSLOG_SHOPT */ -#endif - -#if defined (READLINE) - complete_fullquote = 1; - force_fignore = 1; - hist_verify = history_reediting = 0; - perform_hostname_completion = 1; -# if DIRCOMPLETE_EXPAND_DEFAULT - dircomplete_expand = 1; -# else - dircomplete_expand = 0; -#endif - dircomplete_spelling = 0; - no_empty_command_completion = 0; -#endif - -#if defined (PROGRAMMABLE_COMPLETION) - prog_completion_enabled = 1; -# if defined (ALIAS) - progcomp_alias = 0; -# endif -#endif - -#if defined (DEFAULT_ECHO_TO_XPG) || defined (STRICT_POSIX) - xpg_echo = 1; -#else - xpg_echo = 0; -#endif /* DEFAULT_ECHO_TO_XPG */ - - shopt_login_shell = login_shell; -} - -static int -find_shopt (name) - char *name; -{ - int i; - - for (i = 0; shopt_vars[i].name; i++) - if (STREQ (name, shopt_vars[i].name)) - return i; - return -1; -} - -static void -shopt_error (s) - char *s; -{ - builtin_error (_("%s: invalid shell option name"), s); -} - -static int -toggle_shopts (mode, list, quiet) - int mode; - WORD_LIST *list; - int quiet; -{ - WORD_LIST *l; - int ind, rval; - SHELL_VAR *v; - - for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next) - { - ind = find_shopt (l->word->word); - if (ind < 0) - { - shopt_error (l->word->word); - rval = EXECUTION_FAILURE; - } - else - { - *shopt_vars[ind].value = mode; /* 1 for set, 0 for unset */ - if (shopt_vars[ind].set_func) - (*shopt_vars[ind].set_func) (shopt_vars[ind].name, mode); - } - } - - /* Don't set $BASHOPTS here if it hasn't already been initialized */ - if (v = find_variable ("BASHOPTS")) - set_bashopts (); - return (rval); -} - -static void -print_shopt (name, val, flags) - char *name; - int val, flags; -{ - if (flags & PFLAG) - printf ("shopt %s %s\n", val ? "-s" : "-u", name); - else - printf (OPTFMT, name, val ? on : off); -} - -/* List the values of all or any of the `shopt' options. Returns 0 if - all were listed or all variables queried were on; 1 otherwise. */ -static int -list_shopts (list, flags) - WORD_LIST *list; - int flags; -{ - WORD_LIST *l; - int i, val, rval; - - if (list == 0) - { - for (i = 0; shopt_vars[i].name; i++) - { - val = *shopt_vars[i].value; - if ((flags & QFLAG) == 0) - print_shopt (shopt_vars[i].name, val, flags); - } - return (sh_chkwrite (EXECUTION_SUCCESS)); - } - - for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next) - { - i = find_shopt (l->word->word); - if (i < 0) - { - shopt_error (l->word->word); - rval = EXECUTION_FAILURE; - continue; - } - val = *shopt_vars[i].value; - if (val == 0) - rval = EXECUTION_FAILURE; - if ((flags & QFLAG) == 0) - print_shopt (l->word->word, val, flags); - } - - return (sh_chkwrite (rval)); -} - -static int -list_some_shopts (mode, flags) - int mode, flags; -{ - int val, i; - - for (i = 0; shopt_vars[i].name; i++) - { - val = *shopt_vars[i].value; - if (((flags & QFLAG) == 0) && mode == val) - print_shopt (shopt_vars[i].name, val, flags); - } - return (sh_chkwrite (EXECUTION_SUCCESS)); -} - -static int -list_shopt_o_options (list, flags) - WORD_LIST *list; - int flags; -{ - WORD_LIST *l; - int val, rval; - - if (list == 0) - { - if ((flags & QFLAG) == 0) - list_minus_o_opts (-1, (flags & PFLAG)); - return (sh_chkwrite (EXECUTION_SUCCESS)); - } - - for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next) - { - val = minus_o_option_value (l->word->word); - if (val == -1) - { - sh_invalidoptname (l->word->word); - rval = EXECUTION_FAILURE; - continue; - } - if (val == 0) - rval = EXECUTION_FAILURE; - if ((flags & QFLAG) == 0) - { - if (flags & PFLAG) - printf ("set %co %s\n", val ? '-' : '+', l->word->word); - else - printf (OPTFMT, l->word->word, val ? on : off); - } - } - return (sh_chkwrite (rval)); -} - -static int -list_some_o_options (mode, flags) - int mode, flags; -{ - if ((flags & QFLAG) == 0) - list_minus_o_opts (mode, (flags & PFLAG)); - return (sh_chkwrite (EXECUTION_SUCCESS)); -} - -static int -set_shopt_o_options (mode, list, quiet) - int mode; - WORD_LIST *list; - int quiet; -{ - WORD_LIST *l; - int rval; - - for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next) - { - if (set_minus_o_option (mode, l->word->word) == EXECUTION_FAILURE) - rval = EXECUTION_FAILURE; - } - set_shellopts (); - return rval; -} - -/* If we set or unset interactive_comments with shopt, make sure the - change is reflected in $SHELLOPTS. */ -static int -set_shellopts_after_change (option_name, mode) - char *option_name; - int mode; -{ - set_shellopts (); - return (0); -} - -static int -shopt_set_debug_mode (option_name, mode) - char *option_name; - int mode; -{ -#if defined (DEBUGGER) - error_trace_mode = function_trace_mode = debugging_mode; - set_shellopts (); - if (debugging_mode) - init_bash_argv (); -#endif - return (0); -} - -#if defined (READLINE) -static int -shopt_enable_hostname_completion (option_name, mode) - char *option_name; - int mode; -{ - return (enable_hostname_completion (mode)); -} -#endif - -static int -set_compatibility_level (option_name, mode) - char *option_name; - int mode; -{ - int ind, oldval; - char *rhs; - - /* If we're unsetting one of the compatibility options, make sure the - current value is in the range of the compatNN space. */ - if (mode == 0) - oldval = shell_compatibility_level; - - /* If we're setting something, redo some of the work we did above in - toggle_shopt(). Unset everything and reset the appropriate option - based on OPTION_NAME. */ - if (mode) - { - shopt_compat31 = shopt_compat32 = 0; - shopt_compat40 = shopt_compat41 = shopt_compat42 = shopt_compat43 = 0; - shopt_compat44 = 0; - ind = find_shopt (option_name); - *shopt_vars[ind].value = mode; - } - - /* Then set shell_compatibility_level based on what remains */ - if (shopt_compat31) - shell_compatibility_level = 31; - else if (shopt_compat32) - shell_compatibility_level = 32; - else if (shopt_compat40) - shell_compatibility_level = 40; - else if (shopt_compat41) - shell_compatibility_level = 41; - else if (shopt_compat42) - shell_compatibility_level = 42; - else if (shopt_compat43) - shell_compatibility_level = 43; - else if (shopt_compat44) - shell_compatibility_level = 44; - else if (oldval > 44 && shell_compatibility_level < DEFAULT_COMPAT_LEVEL) - ; - else - shell_compatibility_level = DEFAULT_COMPAT_LEVEL; - - /* Make sure the current compatibility level is reflected in BASH_COMPAT */ - rhs = itos (shell_compatibility_level); - bind_variable ("BASH_COMPAT", rhs, 0); - free (rhs); - - return 0; -} - -/* Set and unset the various compatibility options from the value of - shell_compatibility_level; used by sv_shcompat */ -void -set_compatibility_opts () -{ - shopt_compat31 = shopt_compat32 = 0; - shopt_compat40 = shopt_compat41 = shopt_compat42 = shopt_compat43 = 0; - shopt_compat44 = 0; - switch (shell_compatibility_level) - { - case DEFAULT_COMPAT_LEVEL: - case 51: /* completeness */ - case 50: - break; - case 44: - shopt_compat44 = 1; break; - case 43: - shopt_compat43 = 1; break; - case 42: - shopt_compat42 = 1; break; - case 41: - shopt_compat41 = 1; break; - case 40: - shopt_compat40 = 1; break; - case 32: - shopt_compat32 = 1; break; - case 31: - shopt_compat31 = 1; break; - } -} - -#if defined (READLINE) -static int -shopt_set_complete_direxpand (option_name, mode) - char *option_name; - int mode; -{ - set_directory_hook (); - return 0; -} -#endif - -#if defined (RESTRICTED_SHELL) -/* Don't allow the value of restricted_shell to be modified. */ - -static int -set_restricted_shell (option_name, mode) - char *option_name; - int mode; -{ - static int save_restricted = -1; - - if (save_restricted == -1) - save_restricted = shell_is_restricted (shell_name); - - restricted_shell = save_restricted; - return (0); -} -#endif /* RESTRICTED_SHELL */ - -/* Not static so shell.c can call it to initialize shopt_login_shell */ -int -set_login_shell (option_name, mode) - char *option_name; - int mode; -{ - shopt_login_shell = login_shell != 0; - return (0); -} - -char ** -get_shopt_options () -{ - char **ret; - int n, i; - - n = sizeof (shopt_vars) / sizeof (shopt_vars[0]); - ret = strvec_create (n + 1); - for (i = 0; shopt_vars[i].name; i++) - ret[i] = savestring (shopt_vars[i].name); - ret[i] = (char *)NULL; - return ret; -} - -/* - * External interface for other parts of the shell. NAME is a string option; - * MODE is 0 if we want to unset an option; 1 if we want to set an option. - * REUSABLE is 1 if we want to print output in a form that may be reused. - */ -int -shopt_setopt (name, mode) - char *name; - int mode; -{ - WORD_LIST *wl; - int r; - - wl = add_string_to_list (name, (WORD_LIST *)NULL); - r = toggle_shopts (mode, wl, 0); - dispose_words (wl); - return r; -} - -int -shopt_listopt (name, reusable) - char *name; - int reusable; -{ - int i; - - if (name == 0) - return (list_shopts ((WORD_LIST *)NULL, reusable ? PFLAG : 0)); - - i = find_shopt (name); - if (i < 0) - { - shopt_error (name); - return (EXECUTION_FAILURE); - } - - print_shopt (name, *shopt_vars[i].value, reusable ? PFLAG : 0); - return (sh_chkwrite (EXECUTION_SUCCESS)); -} - -void -set_bashopts () -{ - char *value; - char tflag[N_SHOPT_OPTIONS]; - int vsize, i, vptr, *ip, exported; - SHELL_VAR *v; - - for (vsize = i = 0; shopt_vars[i].name; i++) - { - tflag[i] = 0; - if (GET_SHOPT_OPTION_VALUE (i)) - { - vsize += strlen (shopt_vars[i].name) + 1; - tflag[i] = 1; - } - } - - value = (char *)xmalloc (vsize + 1); - - for (i = vptr = 0; shopt_vars[i].name; i++) - { - if (tflag[i]) - { - strcpy (value + vptr, shopt_vars[i].name); - vptr += strlen (shopt_vars[i].name); - value[vptr++] = ':'; - } - } - - if (vptr) - vptr--; /* cut off trailing colon */ - value[vptr] = '\0'; - - v = find_variable ("BASHOPTS"); - - /* Turn off the read-only attribute so we can bind the new value, and - note whether or not the variable was exported. */ - if (v) - { - VUNSETATTR (v, att_readonly); - exported = exported_p (v); - } - else - exported = 0; - - v = bind_variable ("BASHOPTS", value, 0); - - /* Turn the read-only attribute back on, and turn off the export attribute - if it was set implicitly by mark_modified_vars and SHELLOPTS was not - exported before we bound the new value. */ - VSETATTR (v, att_readonly); - if (mark_modified_vars && exported == 0 && exported_p (v)) - VUNSETATTR (v, att_exported); - - free (value); -} - -void -parse_bashopts (value) - char *value; -{ - char *vname; - int vptr, ind; - - vptr = 0; - while (vname = extract_colon_unit (value, &vptr)) - { - ind = find_shopt (vname); - if (ind >= 0) - { - *shopt_vars[ind].value = 1; - if (shopt_vars[ind].set_func) - (*shopt_vars[ind].set_func) (shopt_vars[ind].name, 1); - } - free (vname); - } -} - -void -initialize_bashopts (no_bashopts) - int no_bashopts; -{ - char *temp; - SHELL_VAR *var; - - if (no_bashopts == 0) - { - var = find_variable ("BASHOPTS"); - /* set up any shell options we may have inherited. */ - if (var && imported_p (var)) - { - temp = (array_p (var) || assoc_p (var)) ? (char *)NULL : savestring (value_cell (var)); - if (temp) - { - parse_bashopts (temp); - free (temp); - } - } - } - - /* Set up the $BASHOPTS variable. */ - set_bashopts (); -} - -#if defined (ARRAY_VARS) -static int -set_assoc_expand (option_name, mode) - char *option_name; - int mode; -{ -#if 0 /* leave this disabled */ - if (shell_compatibility_level <= 51) -#endif - assoc_expand_once = expand_once_flag; - return 0; -} -#endif diff --git a/third_party/bash/builtins_source.c b/third_party/bash/builtins_source.c deleted file mode 100644 index 001b900da..000000000 --- a/third_party/bash/builtins_source.c +++ /dev/null @@ -1,154 +0,0 @@ -/* source.c, created from source.def. */ -#line 22 "./source.def" - -#line 37 "./source.def" - -#line 53 "./source.def" - -#include "config.h" - -#include "bashtypes.h" -#include "posixstat.h" -#include "filecntl.h" -#if ! defined(_MINIX) && defined (HAVE_SYS_FILE_H) -# include -#endif -#include - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "bashansi.h" -#include "bashintl.h" - -#include "shell.h" -#include "execute_cmd.h" -#include "flags.h" -#include "findcmd.h" -#include "common.h" -#include "bashgetopt.h" -#include "trap.h" - -#if !defined (errno) -extern int errno; -#endif /* !errno */ - -static void maybe_pop_dollar_vars PARAMS((void)); - -/* If non-zero, `.' uses $PATH to look up the script to be sourced. */ -int source_uses_path = 1; - -/* If non-zero, `.' looks in the current directory if the filename argument - is not found in the $PATH. */ -int source_searches_cwd = 1; - -/* If this . script is supplied arguments, we save the dollar vars and - replace them with the script arguments for the duration of the script's - execution. If the script does not change the dollar vars, we restore - what we saved. If the dollar vars are changed in the script, and we are - not executing a shell function, we leave the new values alone and free - the saved values. */ -static void -maybe_pop_dollar_vars () -{ - if (variable_context == 0 && (dollar_vars_changed () & ARGS_SETBLTIN)) - dispose_saved_dollar_vars (); - else - pop_dollar_vars (); - if (debugging_mode) - pop_args (); /* restore BASH_ARGC and BASH_ARGV */ - set_dollar_vars_unchanged (); - invalidate_cached_quoted_dollar_at (); /* just invalidate to be safe */ -} - -/* Read and execute commands from the file passed as argument. Guess what. - This cannot be done in a subshell, since things like variable assignments - take place in there. So, I open the file, place it into a large string, - close the file, and then execute the string. */ -int -source_builtin (list) - WORD_LIST *list; -{ - int result; - char *filename, *debug_trap, *x; - - if (no_options (list)) - return (EX_USAGE); - list = loptend; - - if (list == 0) - { - builtin_error (_("filename argument required")); - builtin_usage (); - return (EX_USAGE); - } - -#if defined (RESTRICTED_SHELL) - if (restricted && strchr (list->word->word, '/')) - { - sh_restricted (list->word->word); - return (EXECUTION_FAILURE); - } -#endif - - filename = (char *)NULL; - /* XXX -- should this be absolute_pathname? */ - if (posixly_correct && strchr (list->word->word, '/')) - filename = savestring (list->word->word); - else if (absolute_pathname (list->word->word)) - filename = savestring (list->word->word); - else if (source_uses_path) - filename = find_path_file (list->word->word); - if (filename == 0) - { - if (source_searches_cwd == 0) - { - x = printable_filename (list->word->word, 0); - builtin_error (_("%s: file not found"), x); - if (x != list->word->word) - free (x); - if (posixly_correct && interactive_shell == 0 && executing_command_builtin == 0) - { - last_command_exit_value = EXECUTION_FAILURE; - jump_to_top_level (EXITPROG); - } - return (EXECUTION_FAILURE); - } - else - filename = savestring (list->word->word); - } - - begin_unwind_frame ("source"); - add_unwind_protect (xfree, filename); - - if (list->next) - { - push_dollar_vars (); - add_unwind_protect ((Function *)maybe_pop_dollar_vars, (char *)NULL); - if (debugging_mode || shell_compatibility_level <= 44) - init_bash_argv (); /* Initialize BASH_ARGV and BASH_ARGC */ - remember_args (list->next, 1); - if (debugging_mode) - push_args (list->next); /* Update BASH_ARGV and BASH_ARGC */ - } - set_dollar_vars_unchanged (); - - /* Don't inherit the DEBUG trap unless function_trace_mode (overloaded) - is set. XXX - should sourced files inherit the RETURN trap? Functions - don't. */ - debug_trap = TRAP_STRING (DEBUG_TRAP); - if (debug_trap && function_trace_mode == 0) - { - debug_trap = savestring (debug_trap); - add_unwind_protect (xfree, debug_trap); - add_unwind_protect (maybe_set_debug_trap, debug_trap); - restore_default_signal (DEBUG_TRAP); - } - - result = source_file (filename, (list && list->next)); - - run_unwind_frame ("source"); - - return (result); -} diff --git a/third_party/bash/builtins_suspend.c b/third_party/bash/builtins_suspend.c deleted file mode 100644 index fe96213f3..000000000 --- a/third_party/bash/builtins_suspend.c +++ /dev/null @@ -1,94 +0,0 @@ -/* suspend.c, created from suspend.def. */ -#line 22 "./suspend.def" - -#line 40 "./suspend.def" - -#include "config.h" - -#if defined (JOB_CONTROL) -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include "bashtypes.h" -#include -#include "bashintl.h" -#include "shell.h" -#include "jobs.h" -#include "common.h" -#include "bashgetopt.h" - -static sighandler suspend_continue PARAMS((int)); - -static SigHandler *old_cont; -#if 0 -static SigHandler *old_stop; -#endif - -/* Continue handler. */ -static sighandler -suspend_continue (sig) - int sig; -{ - set_signal_handler (SIGCONT, old_cont); -#if 0 - set_signal_handler (SIGSTOP, old_stop); -#endif - SIGRETURN (0); -} - -/* Suspending the shell. If -f is the arg, then do the suspend - no matter what. Otherwise, complain if a login shell. */ -int -suspend_builtin (list) - WORD_LIST *list; -{ - int opt, force; - - reset_internal_getopt (); - force = 0; - while ((opt = internal_getopt (list, "f")) != -1) - switch (opt) - { - case 'f': - force++; - break; - CASE_HELPOPT; - default: - builtin_usage (); - return (EX_USAGE); - } - - list = loptend; - no_args (list); - - if (force == 0) - { - if (job_control == 0) - { - sh_nojobs (_("cannot suspend")); - return (EXECUTION_FAILURE); - } - - if (login_shell) - { - builtin_error (_("cannot suspend a login shell")); - return (EXECUTION_FAILURE); - } - } - - /* XXX - should we put ourselves back into the original pgrp now? If so, - call end_job_control() here and do the right thing in suspend_continue - (that is, call restart_job_control()). */ - old_cont = (SigHandler *)set_signal_handler (SIGCONT, suspend_continue); -#if 0 - old_stop = (SigHandler *)set_signal_handler (SIGSTOP, SIG_DFL); -#endif - killpg (shell_pgrp, SIGSTOP); - return (EXECUTION_SUCCESS); -} - -#endif /* JOB_CONTROL */ diff --git a/third_party/bash/builtins_test.c b/third_party/bash/builtins_test.c deleted file mode 100644 index 05f757d68..000000000 --- a/third_party/bash/builtins_test.c +++ /dev/null @@ -1,52 +0,0 @@ -/* test.c, created from test.def. */ -#line 22 "./test.def" - -#line 104 "./test.def" - -#line 114 "./test.def" - -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include "bashansi.h" -#include "bashintl.h" - -#include "shell.h" -#include "execute_cmd.h" -#include "test.h" -#include "common.h" - -/* TEST/[ builtin. */ -int -test_builtin (list) - WORD_LIST *list; -{ - char **argv; - int argc, result; - - /* We let Matthew Bradburn and Kevin Braunsdorf's code do the - actual test command. So turn the list of args into an array - of strings, since that is what their code wants. */ - if (list == 0) - { - if (this_command_name[0] == '[' && !this_command_name[1]) - { - builtin_error (_("missing `]'")); - return (EX_BADUSAGE); - } - - return (EXECUTION_FAILURE); - } - - argv = make_builtin_argv (list, &argc); - result = test_command (argc, argv); - free ((char *)argv); - - return (result); -} diff --git a/third_party/bash/builtins_times.c b/third_party/bash/builtins_times.c deleted file mode 100644 index 34de78d61..000000000 --- a/third_party/bash/builtins_times.c +++ /dev/null @@ -1,90 +0,0 @@ -/* times.c, created from times.def. */ -#line 22 "./times.def" - -#line 34 "./times.def" - -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include -#include "bashtypes.h" -#include "shell.h" - -#include "posixtime.h" - -#if defined (HAVE_SYS_TIMES_H) -# include -#endif /* HAVE_SYS_TIMES_H */ - -#if defined (HAVE_SYS_RESOURCE_H) && !defined (RLIMTYPE) -# include -#endif - -#include "common.h" - -/* Print the totals for system and user time used. */ -int -times_builtin (list) - WORD_LIST *list; -{ -#if defined (HAVE_GETRUSAGE) && defined (HAVE_TIMEVAL) && defined (RUSAGE_SELF) - struct rusage self, kids; - - USE_VAR(list); - - if (no_options (list)) - return (EX_USAGE); - - getrusage (RUSAGE_SELF, &self); - getrusage (RUSAGE_CHILDREN, &kids); /* terminated child processes */ - - print_timeval (stdout, &self.ru_utime); - putchar (' '); - print_timeval (stdout, &self.ru_stime); - putchar ('\n'); - print_timeval (stdout, &kids.ru_utime); - putchar (' '); - print_timeval (stdout, &kids.ru_stime); - putchar ('\n'); - -#else -# if defined (HAVE_TIMES) - /* This uses the POSIX.1/XPG5 times(2) interface, which fills in a - `struct tms' with values of type clock_t. */ - struct tms t; - - USE_VAR(list); - - if (no_options (list)) - return (EX_USAGE); - - times (&t); - - print_clock_t (stdout, t.tms_utime); - putchar (' '); - print_clock_t (stdout, t.tms_stime); - putchar ('\n'); - print_clock_t (stdout, t.tms_cutime); - putchar (' '); - print_clock_t (stdout, t.tms_cstime); - putchar ('\n'); - -# else /* !HAVE_TIMES */ - - USE_VAR(list); - - if (no_options (list)) - return (EX_USAGE); - printf ("0.00 0.00\n0.00 0.00\n"); - -# endif /* HAVE_TIMES */ -#endif /* !HAVE_TIMES */ - - return (sh_chkwrite (EXECUTION_SUCCESS)); -} diff --git a/third_party/bash/builtins_trap.c b/third_party/bash/builtins_trap.c deleted file mode 100644 index 6d150a406..000000000 --- a/third_party/bash/builtins_trap.c +++ /dev/null @@ -1,263 +0,0 @@ -/* trap.c, created from trap.def. */ -#line 22 "./trap.def" - -#line 58 "./trap.def" - -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include "bashtypes.h" -#include -#include -#include "bashansi.h" - -#include "shell.h" -#include "trap.h" -#include "common.h" -#include "bashgetopt.h" - -static void showtrap PARAMS((int, int)); -static int display_traps PARAMS((WORD_LIST *, int)); - -/* The trap command: - - trap - trap - trap -l - trap -p [sigspec ...] - trap [--] - - Set things up so that ARG is executed when SIGNAL(s) N is received. - If ARG is the empty string, then ignore the SIGNAL(s). If there is - no ARG, then set the trap for SIGNAL(s) to its original value. Just - plain "trap" means to print out the list of commands associated with - each signal number. Single arg of "-l" means list the signal names. */ - -/* Possible operations to perform on the list of signals.*/ -#define SET 0 /* Set this signal to first_arg. */ -#define REVERT 1 /* Revert to this signals original value. */ -#define IGNORE 2 /* Ignore this signal. */ - -int -trap_builtin (list) - WORD_LIST *list; -{ - int list_signal_names, display, result, opt; - - list_signal_names = display = 0; - result = EXECUTION_SUCCESS; - - reset_internal_getopt (); - while ((opt = internal_getopt (list, "lp")) != -1) - { - switch (opt) - { - case 'l': - list_signal_names++; - break; - case 'p': - display++; - break; - CASE_HELPOPT; - default: - builtin_usage (); - return (EX_USAGE); - } - } - list = loptend; - - opt = DSIG_NOCASE|DSIG_SIGPREFIX; /* flags for decode_signal */ - - if (list_signal_names) - return (sh_chkwrite (display_signal_list ((WORD_LIST *)NULL, 1))); - else if (display || list == 0) - { - initialize_terminating_signals (); - get_all_original_signals (); - return (sh_chkwrite (display_traps (list, display && posixly_correct))); - } - else - { - char *first_arg; - int operation, sig, first_signal; - - operation = SET; - first_arg = list->word->word; - first_signal = first_arg && *first_arg && all_digits (first_arg) && signal_object_p (first_arg, opt); - - /* Backwards compatibility. XXX - question about whether or not we - should throw an error if an all-digit argument doesn't correspond - to a valid signal number (e.g., if it's `50' on a system with only - 32 signals). */ - if (first_signal) - operation = REVERT; - /* When in posix mode, the historical behavior of looking for a - missing first argument is disabled. To revert to the original - signal handling disposition, use `-' as the first argument. */ - else if (posixly_correct == 0 && first_arg && *first_arg && - (*first_arg != '-' || first_arg[1]) && - signal_object_p (first_arg, opt) && list->next == 0) - operation = REVERT; - else - { - list = list->next; - if (list == 0) - { - builtin_usage (); - return (EX_USAGE); - } - else if (*first_arg == '\0') - operation = IGNORE; - else if (first_arg[0] == '-' && !first_arg[1]) - operation = REVERT; - } - - /* If we're in a command substitution, we haven't freed the trap strings - (though we reset the signal handlers). If we're setting a trap to - handle a signal here, free the rest of the trap strings since they - don't apply any more. */ - if (subshell_environment & SUBSHELL_RESETTRAP) - { - free_trap_strings (); - subshell_environment &= ~SUBSHELL_RESETTRAP; - } - - while (list) - { - sig = decode_signal (list->word->word, opt); - - if (sig == NO_SIG) - { - sh_invalidsig (list->word->word); - result = EXECUTION_FAILURE; - } - else - { - switch (operation) - { - case SET: - set_signal (sig, first_arg); - break; - - case REVERT: - restore_default_signal (sig); - - /* Signals that the shell treats specially need special - handling. */ - switch (sig) - { - case SIGINT: - /* XXX - should we do this if original disposition - was SIG_IGN? */ - if (interactive) - set_signal_handler (SIGINT, sigint_sighandler); - /* special cases for interactive == 0 */ - else if (interactive_shell && (sourcelevel||running_trap||parse_and_execute_level)) - set_signal_handler (SIGINT, sigint_sighandler); - else - set_signal_handler (SIGINT, termsig_sighandler); - break; - - case SIGQUIT: - /* Always ignore SIGQUIT. */ - set_signal_handler (SIGQUIT, SIG_IGN); - break; - case SIGTERM: -#if defined (JOB_CONTROL) - case SIGTTIN: - case SIGTTOU: - case SIGTSTP: -#endif /* JOB_CONTROL */ - if (interactive) - set_signal_handler (sig, SIG_IGN); - break; - } - break; - - case IGNORE: - ignore_signal (sig); - break; - } - } - list = list->next; - } - } - - return (result); -} - -static void -showtrap (i, show_default) - int i, show_default; -{ - char *t, *p, *sn; - int free_t; - - free_t = 1; - p = trap_list[i]; - if (p == (char *)DEFAULT_SIG && signal_is_hard_ignored (i) == 0) - { - if (show_default) - t = "-"; - else - return; - free_t = 0; - } - else if (signal_is_hard_ignored (i)) - t = (char *)NULL; - else - t = (p == (char *)IGNORE_SIG) ? (char *)NULL : sh_single_quote (p); - - sn = signal_name (i); - /* Make sure that signals whose names are unknown (for whatever reason) - are printed as signal numbers. */ - if (STREQN (sn, "SIGJUNK", 7) || STREQN (sn, "unknown", 7)) - printf ("trap -- %s %d\n", t ? t : "''", i); - else if (posixly_correct) - { - if (STREQN (sn, "SIG", 3)) - printf ("trap -- %s %s\n", t ? t : "''", sn+3); - else - printf ("trap -- %s %s\n", t ? t : "''", sn); - } - else - printf ("trap -- %s %s\n", t ? t : "''", sn); - - if (free_t) - FREE (t); -} - -static int -display_traps (list, show_all) - WORD_LIST *list; - int show_all; -{ - int result, i; - - if (list == 0) - { - for (i = 0; i < BASH_NSIG; i++) - showtrap (i, show_all); - return (EXECUTION_SUCCESS); - } - - for (result = EXECUTION_SUCCESS; list; list = list->next) - { - i = decode_signal (list->word->word, DSIG_NOCASE|DSIG_SIGPREFIX); - if (i == NO_SIG) - { - sh_invalidsig (list->word->word); - result = EXECUTION_FAILURE; - } - else - showtrap (i, show_all); - } - - return (result); -} diff --git a/third_party/bash/builtins_type.c b/third_party/bash/builtins_type.c deleted file mode 100644 index d897d6649..000000000 --- a/third_party/bash/builtins_type.c +++ /dev/null @@ -1,373 +0,0 @@ -/* type.c, created from type.def. */ -#line 22 "./type.def" - -#line 52 "./type.def" - -#include "config.h" - -#include "bashtypes.h" -#include "posixstat.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include -#include "bashansi.h" -#include "bashintl.h" - -#include "shell.h" -#include "parser.h" -#include "execute_cmd.h" -#include "findcmd.h" -#include "hashcmd.h" - -#if defined (ALIAS) -#include "alias.h" -#endif /* ALIAS */ - -#include "common.h" -#include "bashgetopt.h" - -extern int find_reserved_word PARAMS((char *)); - -/* For each word in LIST, find out what the shell is going to do with - it as a simple command. i.e., which file would this shell use to - execve, or if it is a builtin command, or an alias. Possible flag - arguments: - -t Returns the "type" of the object, one of - `alias', `keyword', `function', `builtin', - or `file'. - - -p Returns the pathname of the file if -type is - a file. - - -a Returns all occurrences of words, whether they - be a filename in the path, alias, function, - or builtin. - - -f Suppress shell function lookup, like `command'. - - -P Force a path search even in the presence of other - definitions. - - Order of evaluation: - alias - keyword - function - builtin - file - */ - -int -type_builtin (list) - WORD_LIST *list; -{ - int dflags, any_failed, opt; - WORD_LIST *this; - - if (list == 0) - return (EXECUTION_SUCCESS); - - dflags = CDESC_SHORTDESC; /* default */ - any_failed = 0; - - /* Handle the obsolescent `-type', `-path', and `-all' by prescanning - the arguments and converting those options to the form that - internal_getopt recognizes. Converts `--type', `--path', and `--all' - also. THIS SHOULD REALLY GO AWAY. */ - for (this = list; this && this->word->word[0] == '-'; this = this->next) - { - char *flag = &(this->word->word[1]); - - if (STREQ (flag, "type") || STREQ (flag, "-type")) - { - this->word->word[1] = 't'; - this->word->word[2] = '\0'; - } - else if (STREQ (flag, "path") || STREQ (flag, "-path")) - { - this->word->word[1] = 'p'; - this->word->word[2] = '\0'; - } - else if (STREQ (flag, "all") || STREQ (flag, "-all")) - { - this->word->word[1] = 'a'; - this->word->word[2] = '\0'; - } - } - - reset_internal_getopt (); - while ((opt = internal_getopt (list, "afptP")) != -1) - { - switch (opt) - { - case 'a': - dflags |= CDESC_ALL; - break; - case 'f': - dflags |= CDESC_NOFUNCS; - break; - case 'p': - dflags |= CDESC_PATH_ONLY; - dflags &= ~(CDESC_TYPE|CDESC_SHORTDESC); - break; - case 't': - dflags |= CDESC_TYPE; - dflags &= ~(CDESC_PATH_ONLY|CDESC_SHORTDESC); - break; - case 'P': /* shorthand for type -ap */ - dflags |= (CDESC_PATH_ONLY|CDESC_FORCE_PATH); - dflags &= ~(CDESC_TYPE|CDESC_SHORTDESC); - break; - CASE_HELPOPT; - default: - builtin_usage (); - return (EX_USAGE); - } - } - list = loptend; - - while (list) - { - int found; - - found = describe_command (list->word->word, dflags); - - if (!found && (dflags & (CDESC_PATH_ONLY|CDESC_TYPE)) == 0) - sh_notfound (list->word->word); - - any_failed += found == 0; - list = list->next; - } - - opt = (any_failed == 0) ? EXECUTION_SUCCESS : EXECUTION_FAILURE; - return (sh_chkwrite (opt)); -} - -/* - * Describe COMMAND as required by the type and command builtins. - * - * Behavior is controlled by DFLAGS. Flag values are - * CDESC_ALL print all descriptions of a command - * CDESC_SHORTDESC print the description for type and command -V - * CDESC_REUSABLE print in a format that may be reused as input - * CDESC_TYPE print the type for type -t - * CDESC_PATH_ONLY print the path for type -p - * CDESC_FORCE_PATH force a path search for type -P - * CDESC_NOFUNCS skip function lookup for type -f - * CDESC_ABSPATH convert to absolute path, no ./ prefix - * CDESC_STDPATH command -p standard path list - * - * CDESC_ALL says whether or not to look for all occurrences of COMMAND, or - * return after finding it once. - */ -int -describe_command (command, dflags) - char *command; - int dflags; -{ - int found, i, found_file, f, all; - char *full_path, *x, *pathlist; - SHELL_VAR *func; -#if defined (ALIAS) - alias_t *alias; -#endif - - all = (dflags & CDESC_ALL) != 0; - found = found_file = 0; - full_path = (char *)NULL; - -#if defined (ALIAS) - /* Command is an alias? */ - if (((dflags & CDESC_FORCE_PATH) == 0) && expand_aliases && (alias = find_alias (command))) - { - if (dflags & CDESC_TYPE) - puts ("alias"); - else if (dflags & CDESC_SHORTDESC) - printf (_("%s is aliased to `%s'\n"), command, alias->value); - else if (dflags & CDESC_REUSABLE) - { - x = sh_single_quote (alias->value); - printf ("alias %s=%s\n", command, x); - free (x); - } - - found = 1; - - if (all == 0) - return (1); - } -#endif /* ALIAS */ - - /* Command is a shell reserved word? */ - if (((dflags & CDESC_FORCE_PATH) == 0) && (i = find_reserved_word (command)) >= 0) - { - if (dflags & CDESC_TYPE) - puts ("keyword"); - else if (dflags & CDESC_SHORTDESC) - printf (_("%s is a shell keyword\n"), command); - else if (dflags & CDESC_REUSABLE) - printf ("%s\n", command); - - found = 1; - - if (all == 0) - return (1); - } - - /* Command is a function? */ - if (((dflags & (CDESC_FORCE_PATH|CDESC_NOFUNCS)) == 0) && (func = find_function (command))) - { - if (dflags & CDESC_TYPE) - puts ("function"); - else if (dflags & CDESC_SHORTDESC) - { - char *result; - - printf (_("%s is a function\n"), command); - - /* We're blowing away THE_PRINTED_COMMAND here... */ - - result = named_function_string (command, function_cell (func), FUNC_MULTILINE|FUNC_EXTERNAL); - printf ("%s\n", result); - } - else if (dflags & CDESC_REUSABLE) - printf ("%s\n", command); - - found = 1; - - if (all == 0) - return (1); - } - - /* Command is a builtin? */ - if (((dflags & CDESC_FORCE_PATH) == 0) && find_shell_builtin (command)) - { - if (dflags & CDESC_TYPE) - puts ("builtin"); - else if (dflags & CDESC_SHORTDESC) - { - if (posixly_correct && find_special_builtin (command) != 0) - printf (_("%s is a special shell builtin\n"), command); - else - printf (_("%s is a shell builtin\n"), command); - } - else if (dflags & CDESC_REUSABLE) - printf ("%s\n", command); - - found = 1; - - if (all == 0) - return (1); - } - - /* Command is a disk file? */ - /* If the command name given is already an absolute command, just - check to see if it is executable. */ - if (absolute_program (command)) - { - f = file_status (command); - if (f & FS_EXECABLE) - { - if (dflags & CDESC_TYPE) - puts ("file"); - else if (dflags & CDESC_SHORTDESC) - printf (_("%s is %s\n"), command, command); - else if (dflags & (CDESC_REUSABLE|CDESC_PATH_ONLY)) - printf ("%s\n", command); - - /* There's no use looking in the hash table or in $PATH, - because they're not consulted when an absolute program - name is supplied. */ - return (1); - } - } - - /* If the user isn't doing "-a", then we might care about - whether the file is present in our hash table. */ - if (all == 0 || (dflags & CDESC_FORCE_PATH)) - { - if (full_path = phash_search (command)) - { - if (dflags & CDESC_TYPE) - puts ("file"); - else if (dflags & CDESC_SHORTDESC) - printf (_("%s is hashed (%s)\n"), command, full_path); - else if (dflags & (CDESC_REUSABLE|CDESC_PATH_ONLY)) - printf ("%s\n", full_path); - - free (full_path); - return (1); - } - } - - /* Now search through $PATH. */ - while (1) - { - if (dflags & CDESC_STDPATH) /* command -p, all cannot be non-zero */ - { - pathlist = conf_standard_path (); - full_path = find_in_path (command, pathlist, FS_EXEC_PREFERRED|FS_NODIRS); - free (pathlist); - /* Will only go through this once, since all == 0 if STDPATH set */ - } - else if (all == 0) - full_path = find_user_command (command); - else - full_path = user_command_matches (command, FS_EXEC_ONLY, found_file); /* XXX - should that be FS_EXEC_PREFERRED? */ - - if (full_path == 0) - break; - - /* If we found the command as itself by looking through $PATH, it - probably doesn't exist. Check whether or not the command is an - executable file. If it's not, don't report a match. This is - the default posix mode behavior */ - if (STREQ (full_path, command) || posixly_correct) - { - f = file_status (full_path); - if ((f & FS_EXECABLE) == 0) - { - free (full_path); - full_path = (char *)NULL; - if (all == 0) - break; - } - else if (ABSPATH (full_path)) - ; /* placeholder; don't need to do anything yet */ - else if (dflags & (CDESC_REUSABLE|CDESC_PATH_ONLY|CDESC_SHORTDESC)) - { - f = MP_DOCWD | ((dflags & CDESC_ABSPATH) ? MP_RMDOT : 0); - x = sh_makepath ((char *)NULL, full_path, f); - free (full_path); - full_path = x; - } - } - /* If we require a full path and don't have one, make one */ - else if ((dflags & CDESC_ABSPATH) && ABSPATH (full_path) == 0) - { - x = sh_makepath ((char *)NULL, full_path, MP_DOCWD|MP_RMDOT); - free (full_path); - full_path = x; - } - - found_file++; - found = 1; - - if (dflags & CDESC_TYPE) - puts ("file"); - else if (dflags & CDESC_SHORTDESC) - printf (_("%s is %s\n"), command, full_path); - else if (dflags & (CDESC_REUSABLE|CDESC_PATH_ONLY)) - printf ("%s\n", full_path); - - free (full_path); - full_path = (char *)NULL; - - if (all == 0) - break; - } - - return (found); -} diff --git a/third_party/bash/builtins_ulimit.c b/third_party/bash/builtins_ulimit.c deleted file mode 100644 index 445412b93..000000000 --- a/third_party/bash/builtins_ulimit.c +++ /dev/null @@ -1,741 +0,0 @@ -/* ulimit.c, created from ulimit.def. */ -#line 22 "./ulimit.def" - -#line 73 "./ulimit.def" - -#if !defined (_MINIX) - -#include "config.h" - -#include "bashtypes.h" -#if defined (HAVE_SYS_PARAM_H) -# include -#endif - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include -#include - -#include "bashintl.h" - -#include "shell.h" -#include "common.h" -#include "bashgetopt.h" -#include "pipesize.h" - -#if !defined (errno) -extern int errno; -#endif - -/* For some reason, HPUX chose to make these definitions visible only if - _KERNEL is defined, so we define _KERNEL before including - and #undef it afterward. */ -#if defined (HAVE_RESOURCE) -# include -# if defined (HPUX) && defined (RLIMIT_NEEDS_KERNEL) -# define _KERNEL -# endif -# include -# if defined (HPUX) && defined (RLIMIT_NEEDS_KERNEL) -# undef _KERNEL -# endif -#elif defined (HAVE_SYS_TIMES_H) -# include -#endif - -#if defined (HAVE_LIMITS_H) -# include -#endif - -/* Check for the most basic symbols. If they aren't present, this - system's isn't very useful to us. */ -#if !defined (RLIMIT_FSIZE) || !defined (HAVE_GETRLIMIT) -# undef HAVE_RESOURCE -#endif - -#if !defined (HAVE_RESOURCE) && defined (HAVE_ULIMIT_H) -# include -#endif - -#if !defined (RLIMTYPE) -# define RLIMTYPE long -# define string_to_rlimtype(s) strtol(s, (char **)NULL, 10) -# define print_rlimtype(num, nl) printf ("%ld%s", num, nl ? "\n" : "") -#endif - -/* Alternate names */ - -/* Some systems use RLIMIT_NOFILE, others use RLIMIT_OFILE */ -#if defined (HAVE_RESOURCE) && defined (RLIMIT_OFILE) && !defined (RLIMIT_NOFILE) -# define RLIMIT_NOFILE RLIMIT_OFILE -#endif /* HAVE_RESOURCE && RLIMIT_OFILE && !RLIMIT_NOFILE */ - -#if defined (HAVE_RESOURCE) && defined (RLIMIT_POSIXLOCKS) && !defined (RLIMIT_LOCKS) -# define RLIMIT_LOCKS RLIMIT_POSIXLOCKS -#endif /* HAVE_RESOURCE && RLIMIT_POSIXLOCKS && !RLIMIT_LOCKS */ - -/* Some systems have these, some do not. */ -#ifdef RLIMIT_FSIZE -# define RLIMIT_FILESIZE RLIMIT_FSIZE -#else -# define RLIMIT_FILESIZE 256 -#endif - -#define RLIMIT_PIPESIZE 257 - -#ifdef RLIMIT_NOFILE -# define RLIMIT_OPENFILES RLIMIT_NOFILE -#else -# define RLIMIT_OPENFILES 258 -#endif - -#ifdef RLIMIT_VMEM -# define RLIMIT_VIRTMEM RLIMIT_VMEM -# define RLIMIT_VMBLKSZ 1024 -#else -# ifdef RLIMIT_AS -# define RLIMIT_VIRTMEM RLIMIT_AS -# define RLIMIT_VMBLKSZ 1024 -# else -# define RLIMIT_VIRTMEM 259 -# define RLIMIT_VMBLKSZ 1 -# endif -#endif - -#ifdef RLIMIT_NPROC -# define RLIMIT_MAXUPROC RLIMIT_NPROC -#else -# define RLIMIT_MAXUPROC 260 -#endif - -#if !defined (RLIMIT_PTHREAD) && defined (RLIMIT_NTHR) -# define RLIMIT_PTHREAD RLIMIT_NTHR -#endif - -#if !defined (RLIM_INFINITY) -# define RLIM_INFINITY 0x7fffffff -#endif - -#if !defined (RLIM_SAVED_CUR) -# define RLIM_SAVED_CUR RLIM_INFINITY -#endif - -#if !defined (RLIM_SAVED_MAX) -# define RLIM_SAVED_MAX RLIM_INFINITY -#endif - -#define LIMIT_HARD 0x01 -#define LIMIT_SOFT 0x02 - -/* "Blocks" are defined as 512 bytes when in Posix mode and 1024 bytes - otherwise. */ -#define POSIXBLK -2 - -#define BLOCKSIZE(x) (((x) == POSIXBLK) ? (posixly_correct ? 512 : 1024) : (x)) - -static int _findlim PARAMS((int)); - -static int ulimit_internal PARAMS((int, char *, int, int)); - -static int get_limit PARAMS((int, RLIMTYPE *, RLIMTYPE *)); -static int set_limit PARAMS((int, RLIMTYPE, int)); - -static void printone PARAMS((int, RLIMTYPE, int)); -static void print_all_limits PARAMS((int)); - -static int set_all_limits PARAMS((int, RLIMTYPE)); - -static int filesize PARAMS((RLIMTYPE *)); -static int pipesize PARAMS((RLIMTYPE *)); -static int getmaxuprc PARAMS((RLIMTYPE *)); -static int getmaxvm PARAMS((RLIMTYPE *, RLIMTYPE *)); - -typedef struct { - int option; /* The ulimit option for this limit. */ - int parameter; /* Parameter to pass to get_limit (). */ - int block_factor; /* Blocking factor for specific limit. */ - const char * const description; /* Descriptive string to output. */ - const char * const units; /* scale */ -} RESOURCE_LIMITS; - -static RESOURCE_LIMITS limits[] = { -#ifdef RLIMIT_NPTS - { 'P', RLIMIT_NPTS, 1, "number of pseudoterminals", (char *)NULL }, -#endif -#ifdef RLIMIT_RTTIME - { 'R', RLIMIT_RTTIME, 1, "real-time non-blocking time", "microseconds" }, -#endif -#ifdef RLIMIT_PTHREAD - { 'T', RLIMIT_PTHREAD, 1, "number of threads", (char *)NULL }, -#endif -#ifdef RLIMIT_SBSIZE - { 'b', RLIMIT_SBSIZE, 1, "socket buffer size", "bytes" }, -#endif -#ifdef RLIMIT_CORE - { 'c', RLIMIT_CORE, POSIXBLK, "core file size", "blocks" }, -#endif -#ifdef RLIMIT_DATA - { 'd', RLIMIT_DATA, 1024, "data seg size", "kbytes" }, -#endif -#ifdef RLIMIT_NICE - { 'e', RLIMIT_NICE, 1, "scheduling priority", (char *)NULL }, -#endif - { 'f', RLIMIT_FILESIZE, POSIXBLK, "file size", "blocks" }, -#ifdef RLIMIT_SIGPENDING - { 'i', RLIMIT_SIGPENDING, 1, "pending signals", (char *)NULL }, -#endif -#ifdef RLIMIT_KQUEUES - { 'k', RLIMIT_KQUEUES, 1, "max kqueues", (char *)NULL }, -#endif -#ifdef RLIMIT_MEMLOCK - { 'l', RLIMIT_MEMLOCK, 1024, "max locked memory", "kbytes" }, -#endif -#ifdef RLIMIT_RSS - { 'm', RLIMIT_RSS, 1024, "max memory size", "kbytes" }, -#endif /* RLIMIT_RSS */ - { 'n', RLIMIT_OPENFILES, 1, "open files", (char *)NULL}, - { 'p', RLIMIT_PIPESIZE, 512, "pipe size", "512 bytes" }, -#ifdef RLIMIT_MSGQUEUE - { 'q', RLIMIT_MSGQUEUE, 1, "POSIX message queues", "bytes" }, -#endif -#ifdef RLIMIT_RTPRIO - { 'r', RLIMIT_RTPRIO, 1, "real-time priority", (char *)NULL }, -#endif -#ifdef RLIMIT_STACK - { 's', RLIMIT_STACK, 1024, "stack size", "kbytes" }, -#endif -#ifdef RLIMIT_CPU - { 't', RLIMIT_CPU, 1, "cpu time", "seconds" }, -#endif /* RLIMIT_CPU */ - { 'u', RLIMIT_MAXUPROC, 1, "max user processes", (char *)NULL }, -#if defined (HAVE_RESOURCE) - { 'v', RLIMIT_VIRTMEM, RLIMIT_VMBLKSZ, "virtual memory", "kbytes" }, -#endif -#ifdef RLIMIT_SWAP - { 'w', RLIMIT_SWAP, 1024, "swap size", "kbytes" }, -#endif -#ifdef RLIMIT_LOCKS - { 'x', RLIMIT_LOCKS, 1, "file locks", (char *)NULL }, -#endif - { -1, -1, -1, (char *)NULL, (char *)NULL } -}; -#define NCMDS (sizeof(limits) / sizeof(limits[0])) - -typedef struct _cmd { - int cmd; - char *arg; -} ULCMD; - -static ULCMD *cmdlist; -static int ncmd; -static int cmdlistsz; - -#if !defined (HAVE_RESOURCE) && !defined (HAVE_ULIMIT) -long -ulimit (cmd, newlim) - int cmd; - long newlim; -{ - errno = EINVAL; - return -1; -} -#endif /* !HAVE_RESOURCE && !HAVE_ULIMIT */ - -static int -_findlim (opt) - int opt; -{ - register int i; - - for (i = 0; limits[i].option > 0; i++) - if (limits[i].option == opt) - return i; - return -1; -} - -static char optstring[4 + 2 * NCMDS]; - -/* Report or set limits associated with certain per-process resources. - See the help documentation in builtins.c for a full description. */ -int -ulimit_builtin (list) - register WORD_LIST *list; -{ - register char *s; - int c, limind, mode, opt, all_limits; - - mode = 0; - - all_limits = 0; - - /* Idea stolen from pdksh -- build option string the first time called. */ - if (optstring[0] == 0) - { - s = optstring; - *s++ = 'a'; *s++ = 'S'; *s++ = 'H'; - for (c = 0; limits[c].option > 0; c++) - { - *s++ = limits[c].option; - *s++ = ';'; - } - *s = '\0'; - } - - /* Initialize the command list. */ - if (cmdlistsz == 0) - cmdlist = (ULCMD *)xmalloc ((cmdlistsz = 16) * sizeof (ULCMD)); - ncmd = 0; - - reset_internal_getopt (); - while ((opt = internal_getopt (list, optstring)) != -1) - { - switch (opt) - { - case 'a': - all_limits++; - break; - - /* -S and -H are modifiers, not real options. */ - case 'S': - mode |= LIMIT_SOFT; - break; - - case 'H': - mode |= LIMIT_HARD; - break; - - CASE_HELPOPT; - case '?': - builtin_usage (); - return (EX_USAGE); - - default: - if (ncmd >= cmdlistsz) - cmdlist = (ULCMD *)xrealloc (cmdlist, (cmdlistsz *= 2) * sizeof (ULCMD)); - cmdlist[ncmd].cmd = opt; - cmdlist[ncmd++].arg = list_optarg; - break; - } - } - list = loptend; - - if (all_limits) - { -#ifdef NOTYET - if (list) /* setting */ - { - if (STREQ (list->word->word, "unlimited") == 0) - { - builtin_error (_("%s: invalid limit argument"), list->word->word); - return (EXECUTION_FAILURE); - } - return (set_all_limits (mode == 0 ? LIMIT_SOFT|LIMIT_HARD : mode, RLIM_INFINITY)); - } -#endif - print_all_limits (mode == 0 ? LIMIT_SOFT : mode); - return (sh_chkwrite (EXECUTION_SUCCESS)); - } - - /* default is `ulimit -f' */ - if (ncmd == 0) - { - cmdlist[ncmd].cmd = 'f'; - /* `ulimit something' is same as `ulimit -f something' */ - cmdlist[ncmd++].arg = list ? list->word->word : (char *)NULL; - if (list) - list = list->next; - } - - /* verify each command in the list. */ - for (c = 0; c < ncmd; c++) - { - limind = _findlim (cmdlist[c].cmd); - if (limind == -1) - { - builtin_error (_("`%c': bad command"), cmdlist[c].cmd); - return (EX_USAGE); - } - } - - /* POSIX compatibility. If the last item in cmdlist does not have an option - argument, but there is an operand (list != 0), treat the operand as if - it were an option argument for that last command. */ - if (list && list->word && cmdlist[ncmd - 1].arg == 0) - { - cmdlist[ncmd - 1].arg = list->word->word; - list = list->next; - } - - for (c = 0; c < ncmd; c++) - if (ulimit_internal (cmdlist[c].cmd, cmdlist[c].arg, mode, ncmd > 1) == EXECUTION_FAILURE) - return (EXECUTION_FAILURE); - - return (EXECUTION_SUCCESS); -} - -static int -ulimit_internal (cmd, cmdarg, mode, multiple) - int cmd; - char *cmdarg; - int mode, multiple; -{ - int opt, limind, setting; - int block_factor; - RLIMTYPE soft_limit, hard_limit, real_limit, limit; - - setting = cmdarg != 0; - limind = _findlim (cmd); - if (mode == 0) - mode = setting ? (LIMIT_HARD|LIMIT_SOFT) : LIMIT_SOFT; - opt = get_limit (limind, &soft_limit, &hard_limit); - if (opt < 0) - { - builtin_error (_("%s: cannot get limit: %s"), limits[limind].description, - strerror (errno)); - return (EXECUTION_FAILURE); - } - - if (setting == 0) /* print the value of the specified limit */ - { - printone (limind, (mode & LIMIT_SOFT) ? soft_limit : hard_limit, multiple); - return (EXECUTION_SUCCESS); - } - - /* Setting the limit. */ - if (STREQ (cmdarg, "hard")) - real_limit = hard_limit; - else if (STREQ (cmdarg, "soft")) - real_limit = soft_limit; - else if (STREQ (cmdarg, "unlimited")) - real_limit = RLIM_INFINITY; - else if (all_digits (cmdarg)) - { - limit = string_to_rlimtype (cmdarg); - block_factor = BLOCKSIZE(limits[limind].block_factor); - real_limit = limit * block_factor; - - if ((real_limit / block_factor) != limit) - { - sh_erange (cmdarg, _("limit")); - return (EXECUTION_FAILURE); - } - } - else - { - sh_invalidnum (cmdarg); - return (EXECUTION_FAILURE); - } - - if (set_limit (limind, real_limit, mode) < 0) - { - builtin_error (_("%s: cannot modify limit: %s"), limits[limind].description, - strerror (errno)); - return (EXECUTION_FAILURE); - } - - return (EXECUTION_SUCCESS); -} - -static int -get_limit (ind, softlim, hardlim) - int ind; - RLIMTYPE *softlim, *hardlim; -{ - RLIMTYPE value; -#if defined (HAVE_RESOURCE) - struct rlimit limit; -#endif - - if (limits[ind].parameter >= 256) - { - switch (limits[ind].parameter) - { - case RLIMIT_FILESIZE: - if (filesize (&value) < 0) - return -1; - break; - case RLIMIT_PIPESIZE: - if (pipesize (&value) < 0) - return -1; - break; - case RLIMIT_OPENFILES: - value = (RLIMTYPE)getdtablesize (); - break; - case RLIMIT_VIRTMEM: - return (getmaxvm (softlim, hardlim)); - case RLIMIT_MAXUPROC: - if (getmaxuprc (&value) < 0) - return -1; - break; - default: - errno = EINVAL; - return -1; - } - *softlim = *hardlim = value; - return (0); - } - else - { -#if defined (HAVE_RESOURCE) - if (getrlimit (limits[ind].parameter, &limit) < 0) - return -1; - *softlim = limit.rlim_cur; - *hardlim = limit.rlim_max; -# if defined (HPUX9) - if (limits[ind].parameter == RLIMIT_FILESIZE) - { - *softlim *= 512; - *hardlim *= 512; /* Ugh. */ - } - else -# endif /* HPUX9 */ - return 0; -#else - errno = EINVAL; - return -1; -#endif - } -} - -static int -set_limit (ind, newlim, mode) - int ind; - RLIMTYPE newlim; - int mode; -{ -#if defined (HAVE_RESOURCE) - struct rlimit limit; - RLIMTYPE val; -#endif - - if (limits[ind].parameter >= 256) - switch (limits[ind].parameter) - { - case RLIMIT_FILESIZE: -#if !defined (HAVE_RESOURCE) - return (ulimit (2, newlim / 512L)); -#else - errno = EINVAL; - return -1; -#endif - - case RLIMIT_OPENFILES: -#if defined (HAVE_SETDTABLESIZE) -# if defined (__CYGWIN__) - /* Grrr... Cygwin declares setdtablesize as void. */ - setdtablesize (newlim); - return 0; -# else - return (setdtablesize (newlim)); -# endif -#endif - case RLIMIT_PIPESIZE: - case RLIMIT_VIRTMEM: - case RLIMIT_MAXUPROC: - default: - errno = EINVAL; - return -1; - } - else - { -#if defined (HAVE_RESOURCE) - if (getrlimit (limits[ind].parameter, &limit) < 0) - return -1; -# if defined (HPUX9) - if (limits[ind].parameter == RLIMIT_FILESIZE) - newlim /= 512; /* Ugh. */ -# endif /* HPUX9 */ - val = (current_user.euid != 0 && newlim == RLIM_INFINITY && - (mode & LIMIT_HARD) == 0 && /* XXX -- test */ - (limit.rlim_cur <= limit.rlim_max)) - ? limit.rlim_max : newlim; - if (mode & LIMIT_SOFT) - limit.rlim_cur = val; - if (mode & LIMIT_HARD) - limit.rlim_max = val; - - return (setrlimit (limits[ind].parameter, &limit)); -#else - errno = EINVAL; - return -1; -#endif - } -} - -static int -getmaxvm (softlim, hardlim) - RLIMTYPE *softlim, *hardlim; -{ -#if defined (HAVE_RESOURCE) - struct rlimit datalim, stacklim; - - if (getrlimit (RLIMIT_DATA, &datalim) < 0) - return -1; - - if (getrlimit (RLIMIT_STACK, &stacklim) < 0) - return -1; - - /* Protect against overflow. */ - *softlim = (datalim.rlim_cur / 1024L) + (stacklim.rlim_cur / 1024L); - *hardlim = (datalim.rlim_max / 1024L) + (stacklim.rlim_max / 1024L); - return 0; -#else - errno = EINVAL; - return -1; -#endif /* HAVE_RESOURCE */ -} - -static int -filesize(valuep) - RLIMTYPE *valuep; -{ -#if !defined (HAVE_RESOURCE) - long result; - if ((result = ulimit (1, 0L)) < 0) - return -1; - else - *valuep = (RLIMTYPE) result * 512; - return 0; -#else - errno = EINVAL; - return -1; -#endif -} - -static int -pipesize (valuep) - RLIMTYPE *valuep; -{ -#if defined (PIPE_BUF) - /* This is defined on Posix systems. */ - *valuep = (RLIMTYPE) PIPE_BUF; - return 0; -#else -# if defined (_POSIX_PIPE_BUF) - *valuep = (RLIMTYPE) _POSIX_PIPE_BUF; - return 0; -# else -# if defined (PIPESIZE) - /* This is defined by running a program from the Makefile. */ - *valuep = (RLIMTYPE) PIPESIZE; - return 0; -# else - errno = EINVAL; - return -1; -# endif /* PIPESIZE */ -# endif /* _POSIX_PIPE_BUF */ -#endif /* PIPE_BUF */ -} - -static int -getmaxuprc (valuep) - RLIMTYPE *valuep; -{ - long maxchild; - - maxchild = getmaxchild (); - if (maxchild < 0) - { - errno = EINVAL; - return -1; - } - else - { - *valuep = (RLIMTYPE) maxchild; - return 0; - } -} - -static void -print_all_limits (mode) - int mode; -{ - register int i; - RLIMTYPE softlim, hardlim; - - if (mode == 0) - mode |= LIMIT_SOFT; - - for (i = 0; limits[i].option > 0; i++) - { - if (get_limit (i, &softlim, &hardlim) == 0) - printone (i, (mode & LIMIT_SOFT) ? softlim : hardlim, 1); - else if (errno != EINVAL) - builtin_error ("%s: cannot get limit: %s", limits[i].description, - strerror (errno)); - } -} - -static void -printone (limind, curlim, pdesc) - int limind; - RLIMTYPE curlim; - int pdesc; -{ - char unitstr[64]; - int factor; - - factor = BLOCKSIZE(limits[limind].block_factor); - if (pdesc) - { - if (limits[limind].units) - sprintf (unitstr, "(%s, -%c) ", limits[limind].units, limits[limind].option); - else - sprintf (unitstr, "(-%c) ", limits[limind].option); - - printf ("%-20s %20s", limits[limind].description, unitstr); - } - if (curlim == RLIM_INFINITY) - puts ("unlimited"); - else if (curlim == RLIM_SAVED_MAX) - puts ("hard"); - else if (curlim == RLIM_SAVED_CUR) - puts ("soft"); - else - print_rlimtype ((curlim / factor), 1); -} - -/* Set all limits to NEWLIM. NEWLIM currently must be RLIM_INFINITY, which - causes all limits to be set as high as possible depending on mode (like - csh `unlimit'). Returns -1 if NEWLIM is invalid, 0 if all limits - were set successfully, and 1 if at least one limit could not be set. - - To raise all soft limits to their corresponding hard limits, use - ulimit -S -a unlimited - To attempt to raise all hard limits to infinity (superuser-only), use - ulimit -H -a unlimited - To attempt to raise all soft and hard limits to infinity, use - ulimit -a unlimited -*/ - -static int -set_all_limits (mode, newlim) - int mode; - RLIMTYPE newlim; -{ - register int i; - int retval = 0; - - if (newlim != RLIM_INFINITY) - { - errno = EINVAL; - return -1; - } - - if (mode == 0) - mode = LIMIT_SOFT|LIMIT_HARD; - - for (retval = i = 0; limits[i].option > 0; i++) - if (set_limit (i, newlim, mode) < 0) - { - builtin_error (_("%s: cannot modify limit: %s"), limits[i].description, - strerror (errno)); - retval = 1; - } - return retval; -} - -#endif /* !_MINIX */ diff --git a/third_party/bash/builtins_umask.c b/third_party/bash/builtins_umask.c deleted file mode 100644 index 686053764..000000000 --- a/third_party/bash/builtins_umask.c +++ /dev/null @@ -1,281 +0,0 @@ -/* umask.c, created from umask.def. */ -#line 22 "./umask.def" - -#line 41 "./umask.def" - -#include "config.h" - -#include "bashtypes.h" -#include "filecntl.h" -#if ! defined(_MINIX) && defined (HAVE_SYS_FILE_H) -# include -#endif - -#if defined (HAVE_UNISTD_H) -#include -#endif - -#include -#include "chartypes.h" - -#include "bashintl.h" - -#include "shell.h" -#include "posixstat.h" -#include "common.h" -#include "bashgetopt.h" - -/* **************************************************************** */ -/* */ -/* UMASK Builtin and Helpers */ -/* */ -/* **************************************************************** */ - -static void print_symbolic_umask PARAMS((mode_t)); -static int symbolic_umask PARAMS((WORD_LIST *)); - -/* Set or display the mask used by the system when creating files. Flag - of -S means display the umask in a symbolic mode. */ -int -umask_builtin (list) - WORD_LIST *list; -{ - int print_symbolically, opt, umask_value, pflag; - mode_t umask_arg; - - print_symbolically = pflag = 0; - reset_internal_getopt (); - while ((opt = internal_getopt (list, "Sp")) != -1) - { - switch (opt) - { - case 'S': - print_symbolically++; - break; - case 'p': - pflag++; - break; - CASE_HELPOPT; - default: - builtin_usage (); - return (EX_USAGE); - } - } - - list = loptend; - - if (list) - { - if (DIGIT (*list->word->word)) - { - umask_value = read_octal (list->word->word); - - /* Note that other shells just let you set the umask to zero - by specifying a number out of range. This is a problem - with those shells. We don't change the umask if the input - is lousy. */ - if (umask_value == -1) - { - sh_erange (list->word->word, _("octal number")); - return (EXECUTION_FAILURE); - } - } - else - { - umask_value = symbolic_umask (list); - if (umask_value == -1) - return (EXECUTION_FAILURE); - } - umask_arg = (mode_t)umask_value; - umask (umask_arg); - if (print_symbolically) - print_symbolic_umask (umask_arg); - } - else /* Display the UMASK for this user. */ - { - umask_arg = umask (022); - umask (umask_arg); - - if (pflag) - printf ("umask%s ", (print_symbolically ? " -S" : "")); - if (print_symbolically) - print_symbolic_umask (umask_arg); - else - printf ("%04lo\n", (unsigned long)umask_arg); - } - - return (sh_chkwrite (EXECUTION_SUCCESS)); -} - -/* Print the umask in a symbolic form. In the output, a letter is - printed if the corresponding bit is clear in the umask. */ -static void -#if defined (__STDC__) -print_symbolic_umask (mode_t um) -#else -print_symbolic_umask (um) - mode_t um; -#endif -{ - char ubits[4], gbits[4], obits[4]; /* u=rwx,g=rwx,o=rwx */ - int i; - - i = 0; - if ((um & S_IRUSR) == 0) - ubits[i++] = 'r'; - if ((um & S_IWUSR) == 0) - ubits[i++] = 'w'; - if ((um & S_IXUSR) == 0) - ubits[i++] = 'x'; - ubits[i] = '\0'; - - i = 0; - if ((um & S_IRGRP) == 0) - gbits[i++] = 'r'; - if ((um & S_IWGRP) == 0) - gbits[i++] = 'w'; - if ((um & S_IXGRP) == 0) - gbits[i++] = 'x'; - gbits[i] = '\0'; - - i = 0; - if ((um & S_IROTH) == 0) - obits[i++] = 'r'; - if ((um & S_IWOTH) == 0) - obits[i++] = 'w'; - if ((um & S_IXOTH) == 0) - obits[i++] = 'x'; - obits[i] = '\0'; - - printf ("u=%s,g=%s,o=%s\n", ubits, gbits, obits); -} - -int -parse_symbolic_mode (mode, initial_bits) - char *mode; - int initial_bits; -{ - int who, op, perm, bits, c; - char *s; - - for (s = mode, bits = initial_bits;;) - { - who = op = perm = 0; - - /* Parse the `who' portion of the symbolic mode clause. */ - while (member (*s, "agou")) - { - switch (c = *s++) - { - case 'u': - who |= S_IRWXU; - continue; - case 'g': - who |= S_IRWXG; - continue; - case 'o': - who |= S_IRWXO; - continue; - case 'a': - who |= S_IRWXU | S_IRWXG | S_IRWXO; - continue; - default: - break; - } - } - - /* The operation is now sitting in *s. */ - op = *s++; - switch (op) - { - case '+': - case '-': - case '=': - break; - default: - builtin_error (_("`%c': invalid symbolic mode operator"), op); - return (-1); - } - - /* Parse out the `perm' section of the symbolic mode clause. */ - while (member (*s, "rwx")) - { - c = *s++; - - switch (c) - { - case 'r': - perm |= S_IRUGO; - break; - case 'w': - perm |= S_IWUGO; - break; - case 'x': - perm |= S_IXUGO; - break; - } - } - - /* Now perform the operation or return an error for a - bad permission string. */ - if (!*s || *s == ',') - { - if (who) - perm &= who; - - switch (op) - { - case '+': - bits |= perm; - break; - case '-': - bits &= ~perm; - break; - case '=': - if (who == 0) - who = S_IRWXU | S_IRWXG | S_IRWXO; - bits &= ~who; - bits |= perm; - break; - - /* No other values are possible. */ - } - - if (*s == '\0') - break; - else - s++; /* skip past ',' */ - } - else - { - builtin_error (_("`%c': invalid symbolic mode character"), *s); - return (-1); - } - } - - return (bits); -} - -/* Set the umask from a symbolic mode string similar to that accepted - by chmod. If the -S argument is given, then print the umask in a - symbolic form. */ -static int -symbolic_umask (list) - WORD_LIST *list; -{ - int um, bits; - - /* Get the initial umask. Don't change it yet. */ - um = umask (022); - umask (um); - - /* All work is done with the complement of the umask -- it's - more intuitive and easier to deal with. It is complemented - again before being returned. */ - bits = parse_symbolic_mode (list->word->word, ~um & 0777); - if (bits == -1) - return (-1); - - um = ~bits & 0777; - return (um); -} diff --git a/third_party/bash/builtins_wait.c b/third_party/bash/builtins_wait.c deleted file mode 100644 index ab566d59e..000000000 --- a/third_party/bash/builtins_wait.c +++ /dev/null @@ -1,320 +0,0 @@ -/* wait.c, created from wait.def. */ -#line 51 "./wait.def" - -#line 66 "./wait.def" - -#include "config.h" - -#include "bashtypes.h" -#include - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "chartypes.h" - -#include "bashansi.h" - -#include "shell.h" -#include "execute_cmd.h" -#include "jobs.h" -#include "trap.h" -#include "sig.h" -#include "common.h" -#include "bashgetopt.h" - -extern int wait_signal_received; - -procenv_t wait_intr_buf; -int wait_intr_flag; - -static int set_waitlist PARAMS((WORD_LIST *)); -static void unset_waitlist PARAMS((void)); - -/* Wait for the pid in LIST to stop or die. If no arguments are given, then - wait for all of the active background processes of the shell and return - 0. If a list of pids or job specs are given, return the exit status of - the last one waited for. */ - -#define WAIT_RETURN(s) \ - do \ - { \ - wait_signal_received = 0; \ - wait_intr_flag = 0; \ - return (s);\ - } \ - while (0) - -int -wait_builtin (list) - WORD_LIST *list; -{ - int status, code, opt, nflag, vflags, bindflags; - volatile int wflags; - char *vname; - SHELL_VAR *pidvar; - struct procstat pstat; - - USE_VAR(list); - - nflag = wflags = vflags = 0; - vname = NULL; - pidvar = (SHELL_VAR *)NULL; - reset_internal_getopt (); - while ((opt = internal_getopt (list, "fnp:")) != -1) - { - switch (opt) - { -#if defined (JOB_CONTROL) - case 'n': - nflag = 1; - break; - case 'f': - wflags |= JWAIT_FORCE; - break; - case 'p': - vname = list_optarg; - vflags = list_optflags; - break; -#endif - CASE_HELPOPT; - default: - builtin_usage (); - return (EX_USAGE); - } - } - list = loptend; - - /* Sanity-check variable name if -p supplied. */ - if (vname) - { -#if defined (ARRAY_VARS) - int arrayflags; - - SET_VFLAGS (vflags, arrayflags, bindflags); - if (legal_identifier (vname) == 0 && valid_array_reference (vname, arrayflags) == 0) -#else - bindflags = 0; - if (legal_identifier (vname) == 0) -#endif - { - sh_invalidid (vname); - WAIT_RETURN (EXECUTION_FAILURE); - } - if (builtin_unbind_variable (vname) == -2) - WAIT_RETURN (EXECUTION_FAILURE); - } - - /* POSIX.2 says: When the shell is waiting (by means of the wait utility) - for asynchronous commands to complete, the reception of a signal for - which a trap has been set shall cause the wait utility to return - immediately with an exit status greater than 128, after which the trap - associated with the signal shall be taken. - - We handle SIGINT here; it's the only one that needs to be treated - specially (I think), since it's handled specially in {no,}jobs.c. */ - wait_intr_flag = 1; - code = setjmp_sigs (wait_intr_buf); - - if (code) - { - last_command_exit_signal = wait_signal_received; - status = 128 + wait_signal_received; - wait_sigint_cleanup (); -#if defined (JOB_CONTROL) - if (wflags & JWAIT_WAITING) - unset_waitlist (); -#endif - WAIT_RETURN (status); - } - - opt = first_pending_trap (); -#if defined (SIGCHLD) - /* We special case SIGCHLD when not in posix mode because we don't break - out of the wait even when the signal is trapped; we run the trap after - the wait completes. See how it's handled in jobs.c:waitchld(). */ - if (opt == SIGCHLD && posixly_correct == 0) - opt = next_pending_trap (opt+1); -#endif - if (opt != -1) - { - last_command_exit_signal = wait_signal_received = opt; - status = opt + 128; - WAIT_RETURN (status); - } - - /* We support jobs or pids. - wait [pid-or-job ...] */ - -#if defined (JOB_CONTROL) - if (nflag) - { - if (list) - { - opt = set_waitlist (list); - if (opt == 0) - WAIT_RETURN (127); - wflags |= JWAIT_WAITING; - } - - status = wait_for_any_job (wflags, &pstat); - if (vname && status >= 0) - builtin_bind_var_to_int (vname, pstat.pid, bindflags); - - if (status < 0) - status = 127; - if (list) - unset_waitlist (); - WAIT_RETURN (status); - } -#endif - - /* But wait without any arguments means to wait for all of the shell's - currently active background processes. */ - if (list == 0) - { - opt = wait_for_background_pids (&pstat); -#if 0 - /* Compatibility with NetBSD sh: don't set VNAME since it doesn't - correspond to the return status. */ - if (vname && opt) - builtin_bind_var_to_int (vname, pstat.pid, bindflags); -#endif - WAIT_RETURN (EXECUTION_SUCCESS); - } - - status = EXECUTION_SUCCESS; - while (list) - { - pid_t pid; - char *w; - intmax_t pid_value; - - w = list->word->word; - if (DIGIT (*w)) - { - if (legal_number (w, &pid_value) && pid_value == (pid_t)pid_value) - { - pid = (pid_t)pid_value; - status = wait_for_single_pid (pid, wflags|JWAIT_PERROR); - /* status > 256 means pid error */ - pstat.pid = (status > 256) ? NO_PID : pid; - pstat.status = (status > 256) ? 127 : status; - if (status > 256) - status = 127; - } - else - { - sh_badpid (w); - pstat.pid = NO_PID; - pstat.status = 127; - WAIT_RETURN (EXECUTION_FAILURE); - } - } -#if defined (JOB_CONTROL) - else if (*w && *w == '%') - /* Must be a job spec. Check it out. */ - { - int job; - sigset_t set, oset; - - BLOCK_CHILD (set, oset); - job = get_job_spec (list); - - if (INVALID_JOB (job)) - { - if (job != DUP_JOB) - sh_badjob (list->word->word); - UNBLOCK_CHILD (oset); - status = 127; /* As per Posix.2, section 4.70.2 */ - pstat.pid = NO_PID; - pstat.status = status; - list = list->next; - continue; - } - - /* Job spec used. Wait for the last pid in the pipeline. */ - UNBLOCK_CHILD (oset); - status = wait_for_job (job, wflags, &pstat); - } -#endif /* JOB_CONTROL */ - else - { - sh_badpid (w); - pstat.pid = NO_PID; - pstat.status = 127; - status = EXECUTION_FAILURE; - } - - /* Don't waste time with a longjmp. */ - if (wait_signal_received) - { - last_command_exit_signal = wait_signal_received; - status = 128 + wait_signal_received; - wait_sigint_cleanup (); - WAIT_RETURN (status); - } - - list = list->next; - } - - if (vname && pstat.pid != NO_PID) - builtin_bind_var_to_int (vname, pstat.pid, bindflags); - - WAIT_RETURN (status); -} - -#if defined (JOB_CONTROL) -/* Take each valid pid or jobspec in LIST and mark the corresponding job as - J_WAITING, so wait -n knows which jobs to wait for. Return the number of - jobs we found. */ -static int -set_waitlist (list) - WORD_LIST *list; -{ - sigset_t set, oset; - int job, r, njob; - intmax_t pid; - WORD_LIST *l; - - BLOCK_CHILD (set, oset); - njob = 0; - for (l = list; l; l = l->next) - { - job = NO_JOB; - job = (l && legal_number (l->word->word, &pid) && pid == (pid_t) pid) - ? get_job_by_pid ((pid_t) pid, 0, 0) - : get_job_spec (l); - if (job == NO_JOB || jobs == 0 || INVALID_JOB (job)) - { - sh_badjob (l->word->word); - continue; - } - /* We don't check yet to see if one of the desired jobs has already - terminated, but we could. We wait until wait_for_any_job(). This - has the advantage of validating all the arguments. */ - if ((jobs[job]->flags & J_WAITING) == 0) - { - njob++; - jobs[job]->flags |= J_WAITING; - } - } - UNBLOCK_CHILD (oset); - return (njob); -} - -/* Clean up after a call to wait -n jobs */ -static void -unset_waitlist () -{ - int i; - sigset_t set, oset; - - BLOCK_CHILD (set, oset); - for (i = 0; i < js.j_jobslots; i++) - if (jobs[i] && (jobs[i]->flags & J_WAITING)) - jobs[i]->flags &= ~J_WAITING; - UNBLOCK_CHILD (oset); -} -#endif diff --git a/third_party/bash/casemod.c b/third_party/bash/casemod.c deleted file mode 100644 index 6f3f21c78..000000000 --- a/third_party/bash/casemod.c +++ /dev/null @@ -1,271 +0,0 @@ -/* casemod.c -- functions to change case of strings */ - -/* Copyright (C) 2008-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if defined (HAVE_CONFIG_H) -# include "config.h" -#endif - -#if defined (HAVE_UNISTD_H) -# include -#endif /* HAVE_UNISTD_H */ - -#include "stdc.h" - -#include "bashansi.h" -#include "bashintl.h" -#include "bashtypes.h" - -#include -#include -#include "xmalloc.h" - -#include "shmbchar.h" -#include "shmbutil.h" -#include "chartypes.h" -#include "typemax.h" - -#include "strmatch.h" - -#define _to_wupper(wc) (iswlower (wc) ? towupper (wc) : (wc)) -#define _to_wlower(wc) (iswupper (wc) ? towlower (wc) : (wc)) - -#if !defined (HANDLE_MULTIBYTE) -# define cval(s, i, l) ((s)[(i)]) -# define iswalnum(c) (isalnum(c)) -# define TOGGLE(x) (ISUPPER (x) ? tolower ((unsigned char)x) : (TOUPPER (x))) -#else -# define TOGGLE(x) (iswupper (x) ? towlower (x) : (_to_wupper(x))) -#endif - -/* These must agree with the defines in externs.h */ -#define CASE_NOOP 0x0000 -#define CASE_LOWER 0x0001 -#define CASE_UPPER 0x0002 -#define CASE_CAPITALIZE 0x0004 -#define CASE_UNCAP 0x0008 -#define CASE_TOGGLE 0x0010 -#define CASE_TOGGLEALL 0x0020 -#define CASE_UPFIRST 0x0040 -#define CASE_LOWFIRST 0x0080 - -#define CASE_USEWORDS 0x1000 /* modify behavior to act on words in passed string */ - -extern char *substring PARAMS((char *, int, int)); - -#ifndef UCHAR_MAX -# define UCHAR_MAX TYPE_MAXIMUM(unsigned char) -#endif - -#if defined (HANDLE_MULTIBYTE) -static wchar_t -cval (s, i, l) - char *s; - int i, l; -{ - size_t tmp; - wchar_t wc; - mbstate_t mps; - - if (MB_CUR_MAX == 1 || is_basic (s[i])) - return ((wchar_t)s[i]); - if (i >= (l - 1)) - return ((wchar_t)s[i]); - memset (&mps, 0, sizeof (mbstate_t)); - tmp = mbrtowc (&wc, s + i, l - i, &mps); - if (MB_INVALIDCH (tmp) || MB_NULLWCH (tmp)) - return ((wchar_t)s[i]); - return wc; -} -#endif - -/* Modify the case of characters in STRING matching PAT based on the value of - FLAGS. If PAT is null, modify the case of each character */ -char * -sh_modcase (string, pat, flags) - const char *string; - char *pat; - int flags; -{ - int start, next, end, retind; - int inword, c, nc, nop, match, usewords; - char *ret, *s; - wchar_t wc; - int mb_cur_max; -#if defined (HANDLE_MULTIBYTE) - wchar_t nwc; - char mb[MB_LEN_MAX+1]; - int mlen; - size_t m; - mbstate_t state; -#endif - - if (string == 0 || *string == 0) - { - ret = (char *)xmalloc (1); - ret[0] = '\0'; - return ret; - } - -#if defined (HANDLE_MULTIBYTE) - memset (&state, 0, sizeof (mbstate_t)); -#endif - - start = 0; - end = strlen (string); - mb_cur_max = MB_CUR_MAX; - - ret = (char *)xmalloc (2*end + 1); - retind = 0; - - /* See if we are supposed to split on alphanumerics and operate on each word */ - usewords = (flags & CASE_USEWORDS); - flags &= ~CASE_USEWORDS; - - inword = 0; - while (start < end) - { - wc = cval ((char *)string, start, end); - - if (iswalnum (wc) == 0) - inword = 0; - - if (pat) - { - next = start; - ADVANCE_CHAR (string, end, next); - s = substring ((char *)string, start, next); - match = strmatch (pat, s, FNM_EXTMATCH) != FNM_NOMATCH; - free (s); - if (match == 0) - { - /* copy unmatched portion */ - memcpy (ret + retind, string + start, next - start); - retind += next - start; - start = next; - inword = 1; - continue; - } - } - - /* XXX - for now, the toggling operators work on the individual - words in the string, breaking on alphanumerics. Should I - leave the capitalization operators to do that also? */ - if (flags == CASE_CAPITALIZE) - { - if (usewords) - nop = inword ? CASE_LOWER : CASE_UPPER; - else - nop = (start > 0) ? CASE_LOWER : CASE_UPPER; - inword = 1; - } - else if (flags == CASE_UNCAP) - { - if (usewords) - nop = inword ? CASE_UPPER : CASE_LOWER; - else - nop = (start > 0) ? CASE_UPPER : CASE_LOWER; - inword = 1; - } - else if (flags == CASE_UPFIRST) - { - if (usewords) - nop = inword ? CASE_NOOP : CASE_UPPER; - else - nop = (start > 0) ? CASE_NOOP : CASE_UPPER; - inword = 1; - } - else if (flags == CASE_LOWFIRST) - { - if (usewords) - nop = inword ? CASE_NOOP : CASE_LOWER; - else - nop = (start > 0) ? CASE_NOOP : CASE_LOWER; - inword = 1; - } - else if (flags == CASE_TOGGLE) - { - nop = inword ? CASE_NOOP : CASE_TOGGLE; - inword = 1; - } - else - nop = flags; - - /* Can't short-circuit, some locales have multibyte upper and lower - case equivalents of single-byte ascii characters (e.g., Turkish) */ - if (mb_cur_max == 1) - { -singlebyte: - switch (nop) - { - default: - case CASE_NOOP: nc = wc; break; - case CASE_UPPER: nc = TOUPPER (wc); break; - case CASE_LOWER: nc = TOLOWER (wc); break; - case CASE_TOGGLEALL: - case CASE_TOGGLE: nc = TOGGLE (wc); break; - } - ret[retind++] = nc; - } -#if defined (HANDLE_MULTIBYTE) - else - { - m = mbrtowc (&wc, string + start, end - start, &state); - /* Have to go through wide case conversion even for single-byte - chars, to accommodate single-byte characters where the - corresponding upper or lower case equivalent is multibyte. */ - if (MB_INVALIDCH (m)) - { - wc = (unsigned char)string[start]; - goto singlebyte; - } - else if (MB_NULLWCH (m)) - wc = L'\0'; - switch (nop) - { - default: - case CASE_NOOP: nwc = wc; break; - case CASE_UPPER: nwc = _to_wupper (wc); break; - case CASE_LOWER: nwc = _to_wlower (wc); break; - case CASE_TOGGLEALL: - case CASE_TOGGLE: nwc = TOGGLE (wc); break; - } - - /* We don't have to convert `wide' characters that are in the - unsigned char range back to single-byte `multibyte' characters. */ - if ((int)nwc <= UCHAR_MAX && is_basic ((int)nwc)) - ret[retind++] = nwc; - else - { - mlen = wcrtomb (mb, nwc, &state); - if (mlen > 0) - mb[mlen] = '\0'; - /* Don't assume the same width */ - strncpy (ret + retind, mb, mlen); - retind += mlen; - } - } -#endif - - ADVANCE_CHAR (string, end, start); - } - - ret[retind] = '\0'; - return ret; -} diff --git a/third_party/bash/chartypes.h b/third_party/bash/chartypes.h deleted file mode 100644 index d5be4a3ce..000000000 --- a/third_party/bash/chartypes.h +++ /dev/null @@ -1,109 +0,0 @@ -/* chartypes.h -- extend ctype.h */ - -/* Copyright (C) 2001-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#ifndef _SH_CHARTYPES_H -#define _SH_CHARTYPES_H - -#include - -#ifndef UCHAR_MAX -# define UCHAR_MAX 255 -#endif -#ifndef CHAR_MAX -# define CHAR_MAX 127 -#endif - -/* use this as a proxy for C89 */ -#if defined (HAVE_STDLIB_H) && defined (HAVE_STRING_H) -# define IN_CTYPE_DOMAIN(c) 1 -#else -# define IN_CTYPE_DOMAIN(c) ((c) >= 0 && (c) <= CHAR_MAX) -#endif - -#if !defined (isspace) && !defined (HAVE_ISSPACE) -# define isspace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) == '\f') -#endif - -#if !defined (isprint) && !defined (HAVE_ISPRINT) -# define isprint(c) (isalpha((unsigned char)c) || isdigit((unsigned char)c) || ispunct((unsigned char)c)) -#endif - -#if defined (isblank) || defined (HAVE_ISBLANK) -# define ISBLANK(c) (IN_CTYPE_DOMAIN (c) && isblank ((unsigned char)c)) -#else -# define ISBLANK(c) ((c) == ' ' || (c) == '\t') -#endif - -#if defined (isgraph) || defined (HAVE_ISGRAPH) -# define ISGRAPH(c) (IN_CTYPE_DOMAIN (c) && isgraph (c)) -#else -# define ISGRAPH(c) (IN_CTYPE_DOMAIN (c) && isprint ((unsigned char)c) && !isspace ((unsigned char)c)) -#endif - -#if !defined (isxdigit) && !defined (HAVE_ISXDIGIT) -# define isxdigit(c) (((c) >= '0' && (c) <= '9') || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F')) -#endif - -#undef ISPRINT - -#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint ((unsigned char)c)) -#define ISDIGIT(c) (IN_CTYPE_DOMAIN (c) && isdigit ((unsigned char)c)) -#define ISALNUM(c) (IN_CTYPE_DOMAIN (c) && isalnum ((unsigned char)c)) -#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha ((unsigned char)c)) -#define ISCNTRL(c) (IN_CTYPE_DOMAIN (c) && iscntrl ((unsigned char)c)) -#define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower ((unsigned char)c)) -#define ISPUNCT(c) (IN_CTYPE_DOMAIN (c) && ispunct ((unsigned char)c)) -#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace ((unsigned char)c)) -#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper ((unsigned char)c)) -#define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit ((unsigned char)c)) - -#define ISLETTER(c) (ISALPHA(c)) - -#define DIGIT(c) ((c) >= '0' && (c) <= '9') - -#define ISWORD(c) (ISLETTER(c) || DIGIT(c) || ((c) == '_')) - -#define HEXVALUE(c) \ - (((c) >= 'a' && (c) <= 'f') \ - ? (c)-'a'+10 \ - : (c) >= 'A' && (c) <= 'F' ? (c)-'A'+10 : (c)-'0') - -#ifndef ISOCTAL -# define ISOCTAL(c) ((c) >= '0' && (c) <= '7') -#endif -#define OCTVALUE(c) ((c) - '0') - -#define TODIGIT(c) ((c) - '0') -#define TOCHAR(c) ((c) + '0') - -#define TOLOWER(c) (ISUPPER(c) ? tolower(c) : (c)) -#define TOUPPER(c) (ISLOWER(c) ? toupper(c) : (c)) - -#ifndef TOCTRL - /* letter to control char -- ASCII. The TOUPPER is in there so \ce and - \cE will map to the same character in $'...' expansions. */ -# define TOCTRL(x) ((x) == '?' ? 0x7f : (TOUPPER(x) & 0x1f)) -#endif -#ifndef UNCTRL - /* control char to letter -- ASCII */ -# define UNCTRL(x) (TOUPPER(x ^ 0x40)) -#endif - -#endif /* _SH_CHARTYPES_H */ diff --git a/third_party/bash/clktck.c b/third_party/bash/clktck.c deleted file mode 100644 index 5d370acc1..000000000 --- a/third_party/bash/clktck.c +++ /dev/null @@ -1,61 +0,0 @@ -/* clktck.c - get the value of CLK_TCK. */ - -/* Copyright (C) 1997 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include "bashtypes.h" -#if defined (HAVE_SYS_PARAM_H) -# include -#endif - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#if defined (HAVE_LIMITS_H) -# include -#endif - -#if !defined (HAVE_SYSCONF) || !defined (_SC_CLK_TCK) -# if !defined (CLK_TCK) -# if defined (HZ) -# define CLK_TCK HZ -# else -# define CLK_TCK 60 -# endif -# endif /* !CLK_TCK */ -#endif /* !HAVE_SYSCONF && !_SC_CLK_TCK */ - -long -get_clk_tck () -{ - static long retval = 0; - - if (retval != 0) - return (retval); - -#if defined (HAVE_SYSCONF) && defined (_SC_CLK_TCK) - retval = sysconf (_SC_CLK_TCK); -#else /* !SYSCONF || !_SC_CLK_TCK */ - retval = CLK_TCK; -#endif /* !SYSCONF || !_SC_CLK_TCK */ - - return (retval); -} diff --git a/third_party/bash/clock.c b/third_party/bash/clock.c deleted file mode 100644 index 8b9b5a0cc..000000000 --- a/third_party/bash/clock.c +++ /dev/null @@ -1,87 +0,0 @@ -/* clock.c - operations on struct tms and clock_t's */ - -/* Copyright (C) 1999 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if defined (HAVE_TIMES) - -#include -#include "posixtime.h" - -#if defined (HAVE_SYS_TIMES_H) -# include -#endif - -#include -#include "stdc.h" - -#include "bashintl.h" - -#ifndef locale_decpoint -extern int locale_decpoint PARAMS((void)); -#endif - -extern long get_clk_tck PARAMS((void)); - -void -clock_t_to_secs (t, sp, sfp) - clock_t t; - time_t *sp; - int *sfp; -{ - static long clk_tck = -1; - - if (clk_tck == -1) - clk_tck = get_clk_tck (); - - *sfp = t % clk_tck; - *sfp = (*sfp * 1000) / clk_tck; - - *sp = t / clk_tck; - - /* Sanity check */ - if (*sfp >= 1000) - { - *sp += 1; - *sfp -= 1000; - } -} - -/* Print the time defined by a clock_t (returned by the `times' and `time' - system calls) in a standard way to stdio stream FP. This is scaled in - terms of the value of CLK_TCK, which is what is returned by the - `times' call. */ -void -print_clock_t (fp, t) - FILE *fp; - clock_t t; -{ - time_t timestamp; - long minutes; - int seconds, seconds_fraction; - - clock_t_to_secs (t, ×tamp, &seconds_fraction); - - minutes = timestamp / 60; - seconds = timestamp % 60; - - fprintf (fp, "%ldm%d%c%03ds", minutes, seconds, locale_decpoint(), seconds_fraction); -} -#endif /* HAVE_TIMES */ diff --git a/third_party/bash/collsyms.h b/third_party/bash/collsyms.h deleted file mode 100644 index d56df6113..000000000 --- a/third_party/bash/collsyms.h +++ /dev/null @@ -1,140 +0,0 @@ -/* collsyms.h -- collating symbol names and their corresponding characters - (in ascii) as given by POSIX.2 in table 2.8. */ - -/* Copyright (C) 1997-2002 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -/* The upper-case letters, lower-case letters, and digits are omitted from - this table. The digits are not included in the table in the POSIX.2 - spec. The upper and lower case letters are translated by the code - in smatch.c:collsym(). */ - -typedef struct _COLLSYM { - XCHAR *name; - CHAR code; -} __COLLSYM; - -static __COLLSYM POSIXCOLL [] = -{ - { L("NUL"), L('\0') }, - { L("SOH"), L('\001') }, - { L("STX"), L('\002') }, - { L("ETX"), L('\003') }, - { L("EOT"), L('\004') }, - { L("ENQ"), L('\005') }, - { L("ACK"), L('\006') }, -#ifdef __STDC__ - { L("alert"), L('\a') }, -#else - { L("alert"), L('\007') }, -#endif - { L("BS"), L('\010') }, - { L("backspace"), L('\b') }, - { L("HT"), L('\011') }, - { L("tab"), L('\t') }, - { L("LF"), L('\012') }, - { L("newline"), L('\n') }, - { L("VT"), L('\013') }, - { L("vertical-tab"), L('\v') }, - { L("FF"), L('\014') }, - { L("form-feed"), L('\f') }, - { L("CR"), L('\015') }, - { L("carriage-return"), L('\r') }, - { L("SO"), L('\016') }, - { L("SI"), L('\017') }, - { L("DLE"), L('\020') }, - { L("DC1"), L('\021') }, - { L("DC2"), L('\022') }, - { L("DC3"), L('\023') }, - { L("DC4"), L('\024') }, - { L("NAK"), L('\025') }, - { L("SYN"), L('\026') }, - { L("ETB"), L('\027') }, - { L("CAN"), L('\030') }, - { L("EM"), L('\031') }, - { L("SUB"), L('\032') }, - { L("ESC"), L('\033') }, - { L("IS4"), L('\034') }, - { L("FS"), L('\034') }, - { L("IS3"), L('\035') }, - { L("GS"), L('\035') }, - { L("IS2"), L('\036') }, - { L("RS"), L('\036') }, - { L("IS1"), L('\037') }, - { L("US"), L('\037') }, - { L("space"), L(' ') }, - { L("exclamation-mark"), L('!') }, - { L("quotation-mark"), L('"') }, - { L("number-sign"), L('#') }, - { L("dollar-sign"), L('$') }, - { L("percent-sign"), L('%') }, - { L("ampersand"), L('&') }, - { L("apostrophe"), L('\'') }, - { L("left-parenthesis"), L('(') }, - { L("right-parenthesis"), L(')') }, - { L("asterisk"), L('*') }, - { L("plus-sign"), L('+') }, - { L("comma"), L(',') }, - { L("hyphen"), L('-') }, - { L("hyphen-minus"), L('-') }, - { L("minus"), L('-') }, /* extension from POSIX.2 */ - { L("dash"), L('-') }, /* extension from POSIX.2 */ - { L("period"), L('.') }, - { L("full-stop"), L('.') }, - { L("slash"), L('/') }, - { L("solidus"), L('/') }, /* extension from POSIX.2 */ - { L("zero"), L('0') }, - { L("one"), L('1') }, - { L("two"), L('2') }, - { L("three"), L('3') }, - { L("four"), L('4') }, - { L("five"), L('5') }, - { L("six"), L('6') }, - { L("seven"), L('7') }, - { L("eight"), L('8') }, - { L("nine"), L('9') }, - { L("colon"), L(':') }, - { L("semicolon"), L(';') }, - { L("less-than-sign"), L('<') }, - { L("equals-sign"), L('=') }, - { L("greater-than-sign"), L('>') }, - { L("question-mark"), L('?') }, - { L("commercial-at"), L('@') }, - /* upper-case letters omitted */ - { L("left-square-bracket"), L('[') }, - { L("backslash"), L('\\') }, - { L("reverse-solidus"), L('\\') }, - { L("right-square-bracket"), L(']') }, - { L("circumflex"), L('^') }, - { L("circumflex-accent"), L('^') }, /* extension from POSIX.2 */ - { L("underscore"), L('_') }, - { L("grave-accent"), L('`') }, - /* lower-case letters omitted */ - { L("left-brace"), L('{') }, /* extension from POSIX.2 */ - { L("left-curly-bracket"), L('{') }, - { L("vertical-line"), L('|') }, - { L("right-brace"), L('}') }, /* extension from POSIX.2 */ - { L("right-curly-bracket"), L('}') }, - { L("tilde"), L('~') }, - { L("DEL"), L('\177') }, - { 0, 0 }, -}; - -#undef _COLLSYM -#undef __COLLSYM -#undef POSIXCOLL diff --git a/third_party/bash/command.h b/third_party/bash/command.h deleted file mode 100644 index e0dc2f955..000000000 --- a/third_party/bash/command.h +++ /dev/null @@ -1,409 +0,0 @@ -/* command.h -- The structures used internally to represent commands, and - the extern declarations of the functions used to create them. */ - -/* Copyright (C) 1993-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_COMMAND_H_) -#define _COMMAND_H_ - -#include "stdc.h" - -/* Instructions describing what kind of thing to do for a redirection. */ -enum r_instruction { - r_output_direction, r_input_direction, r_inputa_direction, - r_appending_to, r_reading_until, r_reading_string, - r_duplicating_input, r_duplicating_output, r_deblank_reading_until, - r_close_this, r_err_and_out, r_input_output, r_output_force, - r_duplicating_input_word, r_duplicating_output_word, - r_move_input, r_move_output, r_move_input_word, r_move_output_word, - r_append_err_and_out -}; - -/* Redirection flags; values for rflags */ -#define REDIR_VARASSIGN 0x01 - -/* Redirection errors. */ -#define AMBIGUOUS_REDIRECT -1 -#define NOCLOBBER_REDIRECT -2 -#define RESTRICTED_REDIRECT -3 /* can only happen in restricted shells. */ -#define HEREDOC_REDIRECT -4 /* here-doc temp file can't be created */ -#define BADVAR_REDIRECT -5 /* something wrong with {varname}redir */ - -#define CLOBBERING_REDIRECT(ri) \ - (ri == r_output_direction || ri == r_err_and_out) - -#define OUTPUT_REDIRECT(ri) \ - (ri == r_output_direction || ri == r_input_output || ri == r_err_and_out || ri == r_append_err_and_out) - -#define INPUT_REDIRECT(ri) \ - (ri == r_input_direction || ri == r_inputa_direction || ri == r_input_output) - -#define WRITE_REDIRECT(ri) \ - (ri == r_output_direction || \ - ri == r_input_output || \ - ri == r_err_and_out || \ - ri == r_appending_to || \ - ri == r_append_err_and_out || \ - ri == r_output_force) - -/* redirection needs translation */ -#define TRANSLATE_REDIRECT(ri) \ - (ri == r_duplicating_input_word || ri == r_duplicating_output_word || \ - ri == r_move_input_word || ri == r_move_output_word) - -/* Command Types: */ -enum command_type { cm_for, cm_case, cm_while, cm_if, cm_simple, cm_select, - cm_connection, cm_function_def, cm_until, cm_group, - cm_arith, cm_cond, cm_arith_for, cm_subshell, cm_coproc }; - -/* Possible values for the `flags' field of a WORD_DESC. */ -#define W_HASDOLLAR (1 << 0) /* Dollar sign present. */ -#define W_QUOTED (1 << 1) /* Some form of quote character is present. */ -#define W_ASSIGNMENT (1 << 2) /* This word is a variable assignment. */ -#define W_SPLITSPACE (1 << 3) /* Split this word on " " regardless of IFS */ -#define W_NOSPLIT (1 << 4) /* Do not perform word splitting on this word because ifs is empty string. */ -#define W_NOGLOB (1 << 5) /* Do not perform globbing on this word. */ -#define W_NOSPLIT2 (1 << 6) /* Don't split word except for $@ expansion (using spaces) because context does not allow it. */ -#define W_TILDEEXP (1 << 7) /* Tilde expand this assignment word */ -#define W_DOLLARAT (1 << 8) /* UNUSED - $@ and its special handling */ -#define W_ARRAYREF (1 << 9) /* word is a valid array reference */ -#define W_NOCOMSUB (1 << 10) /* Don't perform command substitution on this word */ -#define W_ASSIGNRHS (1 << 11) /* Word is rhs of an assignment statement */ -#define W_NOTILDE (1 << 12) /* Don't perform tilde expansion on this word */ -#define W_NOASSNTILDE (1 << 13) /* don't do tilde expansion like an assignment statement */ -#define W_EXPANDRHS (1 << 14) /* Expanding word in ${paramOPword} */ -#define W_COMPASSIGN (1 << 15) /* Compound assignment */ -#define W_ASSNBLTIN (1 << 16) /* word is a builtin command that takes assignments */ -#define W_ASSIGNARG (1 << 17) /* word is assignment argument to command */ -#define W_HASQUOTEDNULL (1 << 18) /* word contains a quoted null character */ -#define W_DQUOTE (1 << 19) /* UNUSED - word should be treated as if double-quoted */ -#define W_NOPROCSUB (1 << 20) /* don't perform process substitution */ -#define W_SAWQUOTEDNULL (1 << 21) /* word contained a quoted null that was removed */ -#define W_ASSIGNASSOC (1 << 22) /* word looks like associative array assignment */ -#define W_ASSIGNARRAY (1 << 23) /* word looks like a compound indexed array assignment */ -#define W_ARRAYIND (1 << 24) /* word is an array index being expanded */ -#define W_ASSNGLOBAL (1 << 25) /* word is a global assignment to declare (declare/typeset -g) */ -#define W_NOBRACE (1 << 26) /* Don't perform brace expansion */ -#define W_COMPLETE (1 << 27) /* word is being expanded for completion */ -#define W_CHKLOCAL (1 << 28) /* check for local vars on assignment */ -#define W_FORCELOCAL (1 << 29) /* force assignments to be to local variables, non-fatal on assignment errors */ -/* UNUSED (1 << 30) */ - -/* Flags for the `pflags' argument to param_expand() and various - parameter_brace_expand_xxx functions; also used for string_list_dollar_at */ -#define PF_NOCOMSUB 0x01 /* Do not perform command substitution */ -#define PF_IGNUNBOUND 0x02 /* ignore unbound vars even if -u set */ -#define PF_NOSPLIT2 0x04 /* same as W_NOSPLIT2 */ -#define PF_ASSIGNRHS 0x08 /* same as W_ASSIGNRHS */ -#define PF_COMPLETE 0x10 /* same as W_COMPLETE, sets SX_COMPLETE */ -#define PF_EXPANDRHS 0x20 /* same as W_EXPANDRHS */ -#define PF_ALLINDS 0x40 /* array, act as if [@] was supplied */ - -/* Possible values for subshell_environment */ -#define SUBSHELL_ASYNC 0x01 /* subshell caused by `command &' */ -#define SUBSHELL_PAREN 0x02 /* subshell caused by ( ... ) */ -#define SUBSHELL_COMSUB 0x04 /* subshell caused by `command` or $(command) */ -#define SUBSHELL_FORK 0x08 /* subshell caused by executing a disk command */ -#define SUBSHELL_PIPE 0x10 /* subshell from a pipeline element */ -#define SUBSHELL_PROCSUB 0x20 /* subshell caused by <(command) or >(command) */ -#define SUBSHELL_COPROC 0x40 /* subshell from a coproc pipeline */ -#define SUBSHELL_RESETTRAP 0x80 /* subshell needs to reset trap strings on first call to trap */ -#define SUBSHELL_IGNTRAP 0x100 /* subshell should reset trapped signals from trap_handler */ - -/* A structure which represents a word. */ -typedef struct word_desc { - char *word; /* Zero terminated string. */ - int flags; /* Flags associated with this word. */ -} WORD_DESC; - -/* A linked list of words. */ -typedef struct word_list { - struct word_list *next; - WORD_DESC *word; -} WORD_LIST; - - -/* **************************************************************** */ -/* */ -/* Shell Command Structs */ -/* */ -/* **************************************************************** */ - -/* What a redirection descriptor looks like. If the redirection instruction - is ri_duplicating_input or ri_duplicating_output, use DEST, otherwise - use the file in FILENAME. Out-of-range descriptors are identified by a - negative DEST. */ - -typedef union { - int dest; /* Place to redirect REDIRECTOR to, or ... */ - WORD_DESC *filename; /* filename to redirect to. */ -} REDIRECTEE; - -/* Structure describing a redirection. If REDIRECTOR is negative, the parser - (or translator in redir.c) encountered an out-of-range file descriptor. */ -typedef struct redirect { - struct redirect *next; /* Next element, or NULL. */ - REDIRECTEE redirector; /* Descriptor or varname to be redirected. */ - int rflags; /* Private flags for this redirection */ - int flags; /* Flag value for `open'. */ - enum r_instruction instruction; /* What to do with the information. */ - REDIRECTEE redirectee; /* File descriptor or filename */ - char *here_doc_eof; /* The word that appeared in <flags. */ -#define CMD_WANT_SUBSHELL 0x01 /* User wants a subshell: ( command ) */ -#define CMD_FORCE_SUBSHELL 0x02 /* Shell needs to force a subshell. */ -#define CMD_INVERT_RETURN 0x04 /* Invert the exit value. */ -#define CMD_IGNORE_RETURN 0x08 /* Ignore the exit value. For set -e. */ -#define CMD_NO_FUNCTIONS 0x10 /* Ignore functions during command lookup. */ -#define CMD_INHIBIT_EXPANSION 0x20 /* Do not expand the command words. */ -#define CMD_NO_FORK 0x40 /* Don't fork; just call execve */ -#define CMD_TIME_PIPELINE 0x80 /* Time a pipeline */ -#define CMD_TIME_POSIX 0x100 /* time -p; use POSIX.2 time output spec. */ -#define CMD_AMPERSAND 0x200 /* command & */ -#define CMD_STDIN_REDIR 0x400 /* async command needs implicit . -*/ - -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include -#include "chartypes.h" -#include "bashtypes.h" -#include "posixstat.h" -#include - -#include - -#if defined (PREFER_STDARG) -# include -#else -# include -#endif - -#include "bashansi.h" -#include "bashintl.h" - -#define NEED_FPURGE_DECL - -#include "shell.h" -#include "maxpath.h" -#include "flags.h" -#include "parser.h" -#include "jobs.h" -#include "builtins.h" -#include "input.h" -#include "execute_cmd.h" -#include "trap.h" -#include "bashgetopt.h" -#include "common.h" -#include "builtext.h" -#include "tilde.h" - -#if defined (HISTORY) -# include "bashhist.h" -#endif - -#if !defined (errno) -extern int errno; -#endif /* !errno */ - -extern const char * const bash_getcwd_errstr; - -/* Used by some builtins and the mainline code. */ -sh_builtin_func_t *last_shell_builtin = (sh_builtin_func_t *)NULL; -sh_builtin_func_t *this_shell_builtin = (sh_builtin_func_t *)NULL; - -/* **************************************************************** */ -/* */ -/* Error reporting, usage, and option processing */ -/* */ -/* **************************************************************** */ - -/* This is a lot like report_error (), but it is for shell builtins - instead of shell control structures, and it won't ever exit the - shell. */ - -static void -builtin_error_prolog () -{ - char *name; - - name = get_name_for_error (); - fprintf (stderr, "%s: ", name); - - if (interactive_shell == 0) - fprintf (stderr, _("line %d: "), executing_line_number ()); - - if (this_command_name && *this_command_name) - fprintf (stderr, "%s: ", this_command_name); -} - -void -#if defined (PREFER_STDARG) -builtin_error (const char *format, ...) -#else -builtin_error (format, va_alist) - const char *format; - va_dcl -#endif -{ - va_list args; - - builtin_error_prolog (); - - SH_VA_START (args, format); - - vfprintf (stderr, format, args); - va_end (args); - fprintf (stderr, "\n"); -} - -void -#if defined (PREFER_STDARG) -builtin_warning (const char *format, ...) -#else -builtin_warning (format, va_alist) - const char *format; - va_dcl -#endif -{ - va_list args; - - builtin_error_prolog (); - fprintf (stderr, _("warning: ")); - - SH_VA_START (args, format); - - vfprintf (stderr, format, args); - va_end (args); - fprintf (stderr, "\n"); -} - -/* Print a usage summary for the currently-executing builtin command. */ -void -builtin_usage () -{ - if (this_command_name && *this_command_name) - fprintf (stderr, _("%s: usage: "), this_command_name); - fprintf (stderr, "%s\n", _(current_builtin->short_doc)); - fflush (stderr); -} - -/* Return if LIST is NULL else barf and jump to top_level. Used by some - builtins that do not accept arguments. */ -void -no_args (list) - WORD_LIST *list; -{ - if (list) - { - builtin_error (_("too many arguments")); - top_level_cleanup (); - jump_to_top_level (DISCARD); - } -} - -/* Check that no options were given to the currently-executing builtin, - and return 0 if there were options. */ -int -no_options (list) - WORD_LIST *list; -{ - int opt; - - reset_internal_getopt (); - if ((opt = internal_getopt (list, "")) != -1) - { - if (opt == GETOPT_HELP) - { - builtin_help (); - return (2); - } - builtin_usage (); - return (1); - } - return (0); -} - -void -sh_needarg (s) - char *s; -{ - builtin_error (_("%s: option requires an argument"), s); -} - -void -sh_neednumarg (s) - char *s; -{ - builtin_error (_("%s: numeric argument required"), s); -} - -void -sh_notfound (s) - char *s; -{ - builtin_error (_("%s: not found"), s); -} - -/* Function called when one of the builtin commands detects an invalid - option. */ -void -sh_invalidopt (s) - char *s; -{ - builtin_error (_("%s: invalid option"), s); -} - -void -sh_invalidoptname (s) - char *s; -{ - builtin_error (_("%s: invalid option name"), s); -} - -void -sh_invalidid (s) - char *s; -{ - builtin_error (_("`%s': not a valid identifier"), s); -} - -void -sh_invalidnum (s) - char *s; -{ - char *msg; - - if (*s == '0' && isdigit ((unsigned char)s[1])) - msg = _("invalid octal number"); - else if (*s == '0' && s[1] == 'x') - msg = _("invalid hex number"); - else - msg = _("invalid number"); - builtin_error ("%s: %s", s, msg); -} - -void -sh_invalidsig (s) - char *s; -{ - builtin_error (_("%s: invalid signal specification"), s); -} - -void -sh_badpid (s) - char *s; -{ - builtin_error (_("`%s': not a pid or valid job spec"), s); -} - -void -sh_readonly (s) - const char *s; -{ - builtin_error (_("%s: readonly variable"), s); -} - -void -sh_noassign (s) - const char *s; -{ - internal_error (_("%s: cannot assign"), s); /* XXX */ -} - -void -sh_erange (s, desc) - char *s, *desc; -{ - if (s) - builtin_error (_("%s: %s out of range"), s, desc ? desc : _("argument")); - else - builtin_error (_("%s out of range"), desc ? desc : _("argument")); -} - -#if defined (JOB_CONTROL) -void -sh_badjob (s) - char *s; -{ - builtin_error (_("%s: no such job"), s); -} - -void -sh_nojobs (s) - char *s; -{ - if (s) - builtin_error (_("%s: no job control"), s); - else - builtin_error (_("no job control")); -} -#endif - -#if defined (RESTRICTED_SHELL) -void -sh_restricted (s) - char *s; -{ - if (s) - builtin_error (_("%s: restricted"), s); - else - builtin_error (_("restricted")); -} -#endif - -void -sh_notbuiltin (s) - char *s; -{ - builtin_error (_("%s: not a shell builtin"), s); -} - -void -sh_wrerror () -{ -#if defined (DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS) && defined (EPIPE) - if (errno != EPIPE) -#endif /* DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS && EPIPE */ - builtin_error (_("write error: %s"), strerror (errno)); -} - -void -sh_ttyerror (set) - int set; -{ - if (set) - builtin_error (_("error setting terminal attributes: %s"), strerror (errno)); - else - builtin_error (_("error getting terminal attributes: %s"), strerror (errno)); -} - -int -sh_chkwrite (s) - int s; -{ - QUIT; - fflush (stdout); - QUIT; - if (ferror (stdout)) - { - sh_wrerror (); - fpurge (stdout); - clearerr (stdout); - return (EXECUTION_FAILURE); - } - return (s); -} - -/* **************************************************************** */ -/* */ -/* Shell positional parameter manipulation */ -/* */ -/* **************************************************************** */ - -/* Convert a WORD_LIST into a C-style argv. Return the number of elements - in the list in *IP, if IP is non-null. A convenience function for - loadable builtins; also used by `test'. */ -char ** -make_builtin_argv (list, ip) - WORD_LIST *list; - int *ip; -{ - char **argv; - - argv = strvec_from_word_list (list, 0, 1, ip); - argv[0] = this_command_name; - return argv; -} - -/* Remember LIST in $1 ... $9, and REST_OF_ARGS. If DESTRUCTIVE is - non-zero, then discard whatever the existing arguments are, else - only discard the ones that are to be replaced. Set POSPARAM_COUNT - to the number of args assigned (length of LIST). */ -void -remember_args (list, destructive) - WORD_LIST *list; - int destructive; -{ - register int i; - - posparam_count = 0; - - for (i = 1; i < 10; i++) - { - if ((destructive || list) && dollar_vars[i]) - { - free (dollar_vars[i]); - dollar_vars[i] = (char *)NULL; - } - - if (list) - { - dollar_vars[posparam_count = i] = savestring (list->word->word); - list = list->next; - } - } - - /* If arguments remain, assign them to REST_OF_ARGS. - Note that copy_word_list (NULL) returns NULL, and - that dispose_words (NULL) does nothing. */ - if (destructive || list) - { - dispose_words (rest_of_args); - rest_of_args = copy_word_list (list); - posparam_count += list_length (list); - } - - if (destructive) - set_dollar_vars_changed (); - - invalidate_cached_quoted_dollar_at (); -} - -void -shift_args (times) - int times; -{ - WORD_LIST *temp; - int count; - - if (times <= 0) /* caller should check */ - return; - - while (times-- > 0) - { - if (dollar_vars[1]) - free (dollar_vars[1]); - - for (count = 1; count < 9; count++) - dollar_vars[count] = dollar_vars[count + 1]; - - if (rest_of_args) - { - temp = rest_of_args; - dollar_vars[9] = savestring (temp->word->word); - rest_of_args = rest_of_args->next; - temp->next = (WORD_LIST *)NULL; - dispose_words (temp); - } - else - dollar_vars[9] = (char *)NULL; - - posparam_count--; - } -} - -int -number_of_args () -{ -#if 0 - register WORD_LIST *list; - int n; - - for (n = 0; n < 9 && dollar_vars[n+1]; n++) - ; - for (list = rest_of_args; list; list = list->next) - n++; - -if (n != posparam_count) - itrace("number_of_args: n (%d) != posparam_count (%d)", n, posparam_count); -#else - return posparam_count; -#endif -} - -static int changed_dollar_vars; - -/* Have the dollar variables been reset to new values since we last - checked? */ -int -dollar_vars_changed () -{ - return (changed_dollar_vars); -} - -void -set_dollar_vars_unchanged () -{ - changed_dollar_vars = 0; -} - -void -set_dollar_vars_changed () -{ - if (variable_context) - changed_dollar_vars |= ARGS_FUNC; - else if (this_shell_builtin == set_builtin) - changed_dollar_vars |= ARGS_SETBLTIN; - else - changed_dollar_vars |= ARGS_INVOC; -} - -/* **************************************************************** */ -/* */ -/* Validating numeric input and arguments */ -/* */ -/* **************************************************************** */ - -/* Read a numeric arg for this_command_name, the name of the shell builtin - that wants it. LIST is the word list that the arg is to come from. - Accept only the numeric argument; report an error if other arguments - follow. If FATAL is 1, call throw_to_top_level, which exits the - shell; if it's 2, call jump_to_top_level (DISCARD), which aborts the - current command; if FATAL is 0, return an indication of an invalid - number by setting *NUMOK == 0 and return -1. */ -int -get_numeric_arg (list, fatal, count) - WORD_LIST *list; - int fatal; - intmax_t *count; -{ - char *arg; - - if (count) - *count = 1; - - if (list && list->word && ISOPTION (list->word->word, '-')) - list = list->next; - - if (list) - { - arg = list->word->word; - if (arg == 0 || (legal_number (arg, count) == 0)) - { - sh_neednumarg (list->word->word ? list->word->word : "`'"); - if (fatal == 0) - return 0; - else if (fatal == 1) /* fatal == 1; abort */ - throw_to_top_level (); - else /* fatal == 2; discard current command */ - { - top_level_cleanup (); - jump_to_top_level (DISCARD); - } - } - no_args (list->next); - } - - return (1); -} - -/* Get an eight-bit status value from LIST */ -int -get_exitstat (list) - WORD_LIST *list; -{ - int status; - intmax_t sval; - char *arg; - - if (list && list->word && ISOPTION (list->word->word, '-')) - list = list->next; - - if (list == 0) - { - /* If we're not running the DEBUG trap, the return builtin, when not - given any arguments, uses the value of $? before the trap ran. If - given an argument, return uses it. This means that the trap can't - change $?. The DEBUG trap gets to change $?, though, since that is - part of its reason for existing, and because the extended debug mode - does things with the return value. */ - if (this_shell_builtin == return_builtin && running_trap > 0 && running_trap != DEBUG_TRAP+1) - return (trap_saved_exit_value); - return (last_command_exit_value); - } - - arg = list->word->word; - if (arg == 0 || legal_number (arg, &sval) == 0) - { - sh_neednumarg (list->word->word ? list->word->word : "`'"); - return EX_BADUSAGE; - } - no_args (list->next); - - status = sval & 255; - return status; -} - -/* Return the octal number parsed from STRING, or -1 to indicate - that the string contained a bad number. */ -int -read_octal (string) - char *string; -{ - int result, digits; - - result = digits = 0; - while (*string && ISOCTAL (*string)) - { - digits++; - result = (result * 8) + (*string++ - '0'); - if (result > 07777) - return -1; - } - - if (digits == 0 || *string) - result = -1; - - return (result); -} - -/* **************************************************************** */ -/* */ -/* Manipulating the current working directory */ -/* */ -/* **************************************************************** */ - -/* Return a consed string which is the current working directory. - FOR_WHOM is the name of the caller for error printing. */ -char *the_current_working_directory = (char *)NULL; - -char * -get_working_directory (for_whom) - char *for_whom; -{ - if (no_symbolic_links) - { - FREE (the_current_working_directory); - the_current_working_directory = (char *)NULL; - } - - if (the_current_working_directory == 0) - { -#if defined (GETCWD_BROKEN) - the_current_working_directory = getcwd (0, PATH_MAX); -#else - the_current_working_directory = getcwd (0, 0); -#endif - if (the_current_working_directory == 0) - { - fprintf (stderr, _("%s: error retrieving current directory: %s: %s\n"), - (for_whom && *for_whom) ? for_whom : get_name_for_error (), - _(bash_getcwd_errstr), strerror (errno)); - return (char *)NULL; - } - } - - return (savestring (the_current_working_directory)); -} - -/* Make NAME our internal idea of the current working directory. */ -void -set_working_directory (name) - char *name; -{ - FREE (the_current_working_directory); - the_current_working_directory = savestring (name); -} - -/* **************************************************************** */ -/* */ -/* Job control support functions */ -/* */ -/* **************************************************************** */ - -#if defined (JOB_CONTROL) -int -get_job_by_name (name, flags) - const char *name; - int flags; -{ - register int i, wl, cl, match, job; - register PROCESS *p; - register JOB *j; - - job = NO_JOB; - wl = strlen (name); - for (i = js.j_jobslots - 1; i >= 0; i--) - { - j = get_job_by_jid (i); - if (j == 0 || ((flags & JM_STOPPED) && J_JOBSTATE(j) != JSTOPPED)) - continue; - - p = j->pipe; - do - { - if (flags & JM_EXACT) - { - cl = strlen (p->command); - match = STREQN (p->command, name, cl); - } - else if (flags & JM_SUBSTRING) - match = strcasestr (p->command, name) != (char *)0; - else - match = STREQN (p->command, name, wl); - - if (match == 0) - { - p = p->next; - continue; - } - else if (flags & JM_FIRSTMATCH) - return i; /* return first match */ - else if (job != NO_JOB) - { - if (this_shell_builtin) - builtin_error (_("%s: ambiguous job spec"), name); - else - internal_error (_("%s: ambiguous job spec"), name); - return (DUP_JOB); - } - else - job = i; - } - while (p != j->pipe); - } - - return (job); -} - -/* Return the job spec found in LIST. */ -int -get_job_spec (list) - WORD_LIST *list; -{ - register char *word; - int job, jflags; - - if (list == 0) - return (js.j_current); - - word = list->word->word; - - if (*word == '\0') - return (NO_JOB); - - if (*word == '%') - word++; - - if (DIGIT (*word) && all_digits (word)) - { - job = atoi (word); - return ((job < 0 || job > js.j_jobslots) ? NO_JOB : job - 1); - } - - jflags = 0; - switch (*word) - { - case 0: - case '%': - case '+': - return (js.j_current); - - case '-': - return (js.j_previous); - - case '?': /* Substring search requested. */ - jflags |= JM_SUBSTRING; - word++; - /* FALLTHROUGH */ - - default: - return get_job_by_name (word, jflags); - } -} -#endif /* JOB_CONTROL */ - -/* - * NOTE: `kill' calls this function with forcecols == 0 - */ -int -display_signal_list (list, forcecols) - WORD_LIST *list; - int forcecols; -{ - register int i, column; - char *name; - int result, signum, dflags; - intmax_t lsignum; - - result = EXECUTION_SUCCESS; - if (!list) - { - for (i = 1, column = 0; i < NSIG; i++) - { - name = signal_name (i); - if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7)) - continue; - - if (posixly_correct && !forcecols) - { - /* This is for the kill builtin. POSIX.2 says the signal names - are displayed without the `SIG' prefix. */ - if (STREQN (name, "SIG", 3)) - name += 3; - printf ("%s%s", name, (i == NSIG - 1) ? "" : " "); - } - else - { - printf ("%2d) %s", i, name); - - if (++column < 5) - printf ("\t"); - else - { - printf ("\n"); - column = 0; - } - } - } - - if ((posixly_correct && !forcecols) || column != 0) - printf ("\n"); - return result; - } - - /* List individual signal names or numbers. */ - while (list) - { - if (legal_number (list->word->word, &lsignum)) - { - /* This is specified by Posix.2 so that exit statuses can be - mapped into signal numbers. */ - if (lsignum > 128) - lsignum -= 128; - if (lsignum < 0 || lsignum >= NSIG) - { - sh_invalidsig (list->word->word); - result = EXECUTION_FAILURE; - list = list->next; - continue; - } - - signum = lsignum; - name = signal_name (signum); - if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7)) - { - list = list->next; - continue; - } - /* POSIX.2 says that `kill -l signum' prints the signal name without - the `SIG' prefix. */ - printf ("%s\n", (this_shell_builtin == kill_builtin && signum > 0) ? name + 3 : name); - } - else - { - dflags = DSIG_NOCASE; - if (posixly_correct == 0 || this_shell_builtin != kill_builtin) - dflags |= DSIG_SIGPREFIX; - signum = decode_signal (list->word->word, dflags); - if (signum == NO_SIG) - { - sh_invalidsig (list->word->word); - result = EXECUTION_FAILURE; - list = list->next; - continue; - } - printf ("%d\n", signum); - } - list = list->next; - } - return (result); -} - -/* **************************************************************** */ -/* */ -/* Finding builtin commands and their functions */ -/* */ -/* **************************************************************** */ - -/* Perform a binary search and return the address of the builtin function - whose name is NAME. If the function couldn't be found, or the builtin - is disabled or has no function associated with it, return NULL. - Return the address of the builtin. - DISABLED_OKAY means find it even if the builtin is disabled. */ -struct builtin * -builtin_address_internal (name, disabled_okay) - char *name; - int disabled_okay; -{ - int hi, lo, mid, j; - - hi = num_shell_builtins - 1; - lo = 0; - - while (lo <= hi) - { - mid = (lo + hi) / 2; - - j = shell_builtins[mid].name[0] - name[0]; - - if (j == 0) - j = strcmp (shell_builtins[mid].name, name); - - if (j == 0) - { - /* It must have a function pointer. It must be enabled, or we - must have explicitly allowed disabled functions to be found, - and it must not have been deleted. */ - if (shell_builtins[mid].function && - ((shell_builtins[mid].flags & BUILTIN_DELETED) == 0) && - ((shell_builtins[mid].flags & BUILTIN_ENABLED) || disabled_okay)) - return (&shell_builtins[mid]); - else - return ((struct builtin *)NULL); - } - if (j > 0) - hi = mid - 1; - else - lo = mid + 1; - } - return ((struct builtin *)NULL); -} - -/* Return the pointer to the function implementing builtin command NAME. */ -sh_builtin_func_t * -find_shell_builtin (name) - char *name; -{ - current_builtin = builtin_address_internal (name, 0); - return (current_builtin ? current_builtin->function : (sh_builtin_func_t *)NULL); -} - -/* Return the address of builtin with NAME, whether it is enabled or not. */ -sh_builtin_func_t * -builtin_address (name) - char *name; -{ - current_builtin = builtin_address_internal (name, 1); - return (current_builtin ? current_builtin->function : (sh_builtin_func_t *)NULL); -} - -/* Return the function implementing the builtin NAME, but only if it is a - POSIX.2 special builtin. */ -sh_builtin_func_t * -find_special_builtin (name) - char *name; -{ - current_builtin = builtin_address_internal (name, 0); - return ((current_builtin && (current_builtin->flags & SPECIAL_BUILTIN)) ? - current_builtin->function : - (sh_builtin_func_t *)NULL); -} - -static int -shell_builtin_compare (sbp1, sbp2) - struct builtin *sbp1, *sbp2; -{ - int result; - - if ((result = sbp1->name[0] - sbp2->name[0]) == 0) - result = strcmp (sbp1->name, sbp2->name); - - return (result); -} - -/* Sort the table of shell builtins so that the binary search will work - in find_shell_builtin. */ -void -initialize_shell_builtins () -{ - qsort (shell_builtins, num_shell_builtins, sizeof (struct builtin), - (QSFUNC *)shell_builtin_compare); -} - -#if !defined (HELP_BUILTIN) -void -builtin_help () -{ - printf ("%s: %s\n", this_command_name, _("help not available in this version")); -} -#endif - -/* **************************************************************** */ -/* */ -/* Variable assignments during builtin commands */ -/* */ -/* **************************************************************** */ - -/* Assign NAME=VALUE, passing FLAGS to the assignment functions. */ -SHELL_VAR * -builtin_bind_variable (name, value, flags) - char *name; - char *value; - int flags; -{ - SHELL_VAR *v; - int vflags, bindflags; - -#if defined (ARRAY_VARS) - /* Callers are responsible for calling this with array references that have - already undergone valid_array_reference checks (read, printf). */ - vflags = assoc_expand_once ? (VA_NOEXPAND|VA_ONEWORD) : 0; - bindflags = flags | (assoc_expand_once ? ASS_NOEXPAND : 0) | ASS_ALLOWALLSUB; - if (flags & ASS_NOEXPAND) - vflags |= VA_NOEXPAND; - if (flags & ASS_ONEWORD) - vflags |= VA_ONEWORD; - - if (valid_array_reference (name, vflags) == 0) - v = bind_variable (name, value, flags); - else - v = assign_array_element (name, value, bindflags, (array_eltstate_t *)0); -#else /* !ARRAY_VARS */ - v = bind_variable (name, value, flags); -#endif /* !ARRAY_VARS */ - - if (v && readonly_p (v) == 0 && noassign_p (v) == 0) - VUNSETATTR (v, att_invisible); - - return v; -} - -SHELL_VAR * -builtin_bind_var_to_int (name, val, flags) - char *name; - intmax_t val; - int flags; -{ - SHELL_VAR *v; - - v = bind_var_to_int (name, val, flags|ASS_ALLOWALLSUB); - return v; -} - -#if defined (ARRAY_VARS) -SHELL_VAR * -builtin_find_indexed_array (array_name, flags) - char *array_name; - int flags; -{ - SHELL_VAR *entry; - - if ((flags & 2) && legal_identifier (array_name) == 0) - { - sh_invalidid (array_name); - return (SHELL_VAR *)NULL; - } - - entry = find_or_make_array_variable (array_name, 1); - /* With flags argument & 1, find_or_make_array_variable checks for readonly - and noassign variables and prints error messages. */ - if (entry == 0) - return entry; - else if (array_p (entry) == 0) - { - builtin_error (_("%s: not an indexed array"), array_name); - return (SHELL_VAR *)NULL; - } - else if (invisible_p (entry)) - VUNSETATTR (entry, att_invisible); /* no longer invisible */ - - if (flags & 1) - array_flush (array_cell (entry)); - - return entry; -} -#endif /* ARRAY_VARS */ - -/* Like check_unbind_variable, but for use by builtins (only matters for - error messages). */ -int -builtin_unbind_variable (vname) - const char *vname; -{ - SHELL_VAR *v; - - v = find_variable (vname); - if (v && readonly_p (v)) - { - builtin_error (_("%s: cannot unset: readonly %s"), vname, "variable"); - return -2; - } - else if (v && non_unsettable_p (v)) - { - builtin_error (_("%s: cannot unset"), vname); - return -2; - } - return (unbind_variable (vname)); -} - -int -builtin_arrayref_flags (w, baseflags) - WORD_DESC *w; - int baseflags; -{ - char *t; - int vflags; - - vflags = baseflags; - - /* Don't require assoc_expand_once if we have an argument that's already - passed through valid_array_reference and been expanded once. That - doesn't protect it from normal expansions like word splitting, so - proper quoting is still required. */ - if (w->flags & W_ARRAYREF) - vflags |= VA_ONEWORD|VA_NOEXPAND; - -# if 0 - /* This is a little sketchier but handles quoted arguments. */ - if (assoc_expand_once && (t = strchr (w->word, '[')) && t[strlen(t) - 1] == ']') - vflags |= VA_ONEWORD|VA_NOEXPAND; -# endif - - return vflags; -} - -/* **************************************************************** */ -/* */ -/* External interface to manipulate shell options */ -/* */ -/* **************************************************************** */ - -#if defined (ARRAY_VARS) -int -set_expand_once (nval, uwp) - int nval, uwp; -{ - int oa; - - oa = assoc_expand_once; - if (shell_compatibility_level > 51) /* XXX - internal */ - { - if (uwp) - unwind_protect_int (assoc_expand_once); - assoc_expand_once = nval; - } - return oa; -} -#endif diff --git a/third_party/bash/common.h b/third_party/bash/common.h deleted file mode 100644 index f5cd87f08..000000000 --- a/third_party/bash/common.h +++ /dev/null @@ -1,282 +0,0 @@ -/* common.h -- extern declarations for functions defined in common.c. */ - -/* Copyright (C) 1993-2022 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (__COMMON_H) -# define __COMMON_H - -#include "stdc.h" - -#define ISOPTION(s, c) (s[0] == '-' && s[1] == c && !s[2]) -#define ISHELP(s) (STREQ ((s), "--help")) - -#define CHECK_HELPOPT(l) \ -do { \ - if ((l) && (l)->word && ISHELP((l)->word->word)) \ - { \ - builtin_help (); \ - return (EX_USAGE); \ - } \ -} while (0) - -#define CASE_HELPOPT \ - case GETOPT_HELP: \ - builtin_help (); \ - return (EX_USAGE) - -/* Flag values for parse_and_execute () and parse_string () */ -#define SEVAL_NONINT 0x001 -#define SEVAL_INTERACT 0x002 -#define SEVAL_NOHIST 0x004 -#define SEVAL_NOFREE 0x008 -#define SEVAL_RESETLINE 0x010 -#define SEVAL_PARSEONLY 0x020 -#define SEVAL_NOLONGJMP 0x040 -#define SEVAL_FUNCDEF 0x080 /* only allow function definitions */ -#define SEVAL_ONECMD 0x100 /* only allow a single command */ -#define SEVAL_NOHISTEXP 0x200 /* inhibit history expansion */ - -/* Flags for describe_command, shared between type.def and command.def */ -#define CDESC_ALL 0x001 /* type -a */ -#define CDESC_SHORTDESC 0x002 /* command -V */ -#define CDESC_REUSABLE 0x004 /* command -v */ -#define CDESC_TYPE 0x008 /* type -t */ -#define CDESC_PATH_ONLY 0x010 /* type -p */ -#define CDESC_FORCE_PATH 0x020 /* type -ap or type -P */ -#define CDESC_NOFUNCS 0x040 /* type -f */ -#define CDESC_ABSPATH 0x080 /* convert to absolute path, no ./ */ -#define CDESC_STDPATH 0x100 /* command -p */ - -/* Flags for get_job_by_name */ -#define JM_PREFIX 0x01 /* prefix of job name */ -#define JM_SUBSTRING 0x02 /* substring of job name */ -#define JM_EXACT 0x04 /* match job name exactly */ -#define JM_STOPPED 0x08 /* match stopped jobs only */ -#define JM_FIRSTMATCH 0x10 /* return first matching job */ - -/* Flags for remember_args and value of changed_dollar_vars */ -#define ARGS_NONE 0x0 -#define ARGS_INVOC 0x01 -#define ARGS_FUNC 0x02 -#define ARGS_SETBLTIN 0x04 - -/* Maximum number of attribute letters */ -#define MAX_ATTRIBUTES 16 - -/* Functions from common.c */ -extern void builtin_error PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); -extern void builtin_warning PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); -extern void builtin_usage PARAMS((void)); -extern void no_args PARAMS((WORD_LIST *)); -extern int no_options PARAMS((WORD_LIST *)); - -/* common error message functions */ -extern void sh_needarg PARAMS((char *)); -extern void sh_neednumarg PARAMS((char *)); -extern void sh_notfound PARAMS((char *)); -extern void sh_invalidopt PARAMS((char *)); -extern void sh_invalidoptname PARAMS((char *)); -extern void sh_invalidid PARAMS((char *)); -extern void sh_invalidnum PARAMS((char *)); -extern void sh_invalidsig PARAMS((char *)); -extern void sh_readonly PARAMS((const char *)); -extern void sh_noassign PARAMS((const char *)); -extern void sh_erange PARAMS((char *, char *)); -extern void sh_badpid PARAMS((char *)); -extern void sh_badjob PARAMS((char *)); -extern void sh_nojobs PARAMS((char *)); -extern void sh_restricted PARAMS((char *)); -extern void sh_notbuiltin PARAMS((char *)); -extern void sh_wrerror PARAMS((void)); -extern void sh_ttyerror PARAMS((int)); -extern int sh_chkwrite PARAMS((int)); - -extern char **make_builtin_argv PARAMS((WORD_LIST *, int *)); -extern void remember_args PARAMS((WORD_LIST *, int)); -extern void shift_args PARAMS((int)); -extern int number_of_args PARAMS((void)); - -extern int dollar_vars_changed PARAMS((void)); -extern void set_dollar_vars_unchanged PARAMS((void)); -extern void set_dollar_vars_changed PARAMS((void)); - -extern int get_numeric_arg PARAMS((WORD_LIST *, int, intmax_t *)); -extern int get_exitstat PARAMS((WORD_LIST *)); -extern int read_octal PARAMS((char *)); - -/* Keeps track of the current working directory. */ -extern char *the_current_working_directory; -extern char *get_working_directory PARAMS((char *)); -extern void set_working_directory PARAMS((char *)); - -#if defined (JOB_CONTROL) -extern int get_job_by_name PARAMS((const char *, int)); -extern int get_job_spec PARAMS((WORD_LIST *)); -#endif -extern int display_signal_list PARAMS((WORD_LIST *, int)); - -/* It's OK to declare a function as returning a Function * without - providing a definition of what a `Function' is. */ -extern struct builtin *builtin_address_internal PARAMS((char *, int)); -extern sh_builtin_func_t *find_shell_builtin PARAMS((char *)); -extern sh_builtin_func_t *builtin_address PARAMS((char *)); -extern sh_builtin_func_t *find_special_builtin PARAMS((char *)); -extern void initialize_shell_builtins PARAMS((void)); - -#if defined (ARRAY_VARS) -extern int set_expand_once PARAMS((int, int)); -#endif - -/* Functions from exit.def */ -extern void bash_logout PARAMS((void)); - -/* Functions from getopts.def */ -extern void getopts_reset PARAMS((int)); - -/* Functions from help.def */ -extern void builtin_help PARAMS((void)); - -/* Functions from read.def */ -extern void read_tty_cleanup PARAMS((void)); -extern int read_tty_modified PARAMS((void)); - -extern int read_builtin_timeout PARAMS((int)); -extern void check_read_timeout PARAMS((void)); - -/* Functions from set.def */ -extern int minus_o_option_value PARAMS((char *)); -extern void list_minus_o_opts PARAMS((int, int)); -extern char **get_minus_o_opts PARAMS((void)); -extern int set_minus_o_option PARAMS((int, char *)); - -extern void set_shellopts PARAMS((void)); -extern void parse_shellopts PARAMS((char *)); -extern void initialize_shell_options PARAMS((int)); - -extern void reset_shell_options PARAMS((void)); - -extern char *get_current_options PARAMS((void)); -extern void set_current_options PARAMS((const char *)); - -/* Functions from shopt.def */ -extern void reset_shopt_options PARAMS((void)); -extern char **get_shopt_options PARAMS((void)); - -extern int shopt_setopt PARAMS((char *, int)); -extern int shopt_listopt PARAMS((char *, int)); - -extern int set_login_shell PARAMS((char *, int)); - -extern void set_bashopts PARAMS((void)); -extern void parse_bashopts PARAMS((char *)); -extern void initialize_bashopts PARAMS((int)); - -extern void set_compatibility_opts PARAMS((void)); - -/* Functions from type.def */ -extern int describe_command PARAMS((char *, int)); - -/* Functions from setattr.def */ -extern int set_or_show_attributes PARAMS((WORD_LIST *, int, int)); -extern int show_all_var_attributes PARAMS((int, int)); -extern int show_local_var_attributes PARAMS((int, int)); -extern int show_var_attributes PARAMS((SHELL_VAR *, int, int)); -extern int show_name_attributes PARAMS((char *, int)); -extern int show_localname_attributes PARAMS((char *, int)); -extern int show_func_attributes PARAMS((char *, int)); -extern void set_var_attribute PARAMS((char *, int, int)); -extern int var_attribute_string PARAMS((SHELL_VAR *, int, char *)); - -/* Functions from pushd.def */ -extern char *get_dirstack_from_string PARAMS((char *)); -extern char *get_dirstack_element PARAMS((intmax_t, int)); -extern void set_dirstack_element PARAMS((intmax_t, int, char *)); -extern WORD_LIST *get_directory_stack PARAMS((int)); - -/* Functions from evalstring.c */ -extern int parse_and_execute PARAMS((char *, const char *, int)); -extern int evalstring PARAMS((char *, const char *, int)); -extern void parse_and_execute_cleanup PARAMS((int)); -extern int parse_string PARAMS((char *, const char *, int, COMMAND **, char **)); -extern int should_suppress_fork PARAMS((COMMAND *)); -extern int can_optimize_connection PARAMS((COMMAND *)); -extern int can_optimize_cat_file PARAMS((COMMAND *)); -extern void optimize_connection_fork PARAMS((COMMAND *)); -extern void optimize_subshell_command PARAMS((COMMAND *)); -extern void optimize_shell_function PARAMS((COMMAND *)); - -/* Functions from evalfile.c */ -extern int maybe_execute_file PARAMS((const char *, int)); -extern int force_execute_file PARAMS((const char *, int)); -extern int source_file PARAMS((const char *, int)); -extern int fc_execute_file PARAMS((const char *)); - -/* variables from common.c */ -extern sh_builtin_func_t *this_shell_builtin; -extern sh_builtin_func_t *last_shell_builtin; - -extern SHELL_VAR *builtin_bind_variable PARAMS((char *, char *, int)); -extern SHELL_VAR *builtin_bind_var_to_int PARAMS((char *, intmax_t, int)); -extern int builtin_unbind_variable PARAMS((const char *)); - -extern SHELL_VAR *builtin_find_indexed_array PARAMS((char *, int)); -extern int builtin_arrayref_flags PARAMS((WORD_DESC *, int)); - -/* variables from evalfile.c */ -extern int sourcelevel; - -/* variables from evalstring.c */ -extern int parse_and_execute_level; - -/* variables from break.def/continue.def */ -extern int breaking; -extern int continuing; -extern int loop_level; - -/* variables from shift.def */ -extern int print_shift_error; - -/* variables from shopt.def */ -#if defined (ARRAY_VARS) -extern int expand_once_flag; -#endif - -/* variables from source.def */ -extern int source_searches_cwd; -extern int source_uses_path; - -/* variables from wait.def */ -extern int wait_intr_flag; - -/* common code to set flags for valid_array_reference and builtin_bind_variable */ -#if defined (ARRAY_VARS) -#define SET_VFLAGS(wordflags, vflags, bindflags) \ - do { \ - vflags = assoc_expand_once ? VA_NOEXPAND : 0; \ - bindflags = assoc_expand_once ? ASS_NOEXPAND : 0; \ - if (assoc_expand_once && (wordflags & W_ARRAYREF)) \ - vflags |= VA_ONEWORD|VA_NOEXPAND; \ - if (vflags & VA_NOEXPAND) \ - bindflags |= ASS_NOEXPAND; \ - if (vflags & VA_ONEWORD) \ - bindflags |= ASS_ONEWORD; \ - } while (0) -#endif - -#endif /* !__COMMON_H */ diff --git a/third_party/bash/config-bot.h b/third_party/bash/config-bot.h deleted file mode 100644 index a687e4029..000000000 --- a/third_party/bash/config-bot.h +++ /dev/null @@ -1,207 +0,0 @@ -/* config-bot.h */ -/* modify settings or make new ones based on what autoconf tells us. */ - -/* Copyright (C) 1989-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -/*********************************************************/ -/* Modify or set defines based on the configure results. */ -/*********************************************************/ - -#if !defined (HAVE_VPRINTF) && defined (HAVE_DOPRNT) -# define USE_VFPRINTF_EMULATION -# define HAVE_VPRINTF -#endif - -#if defined (HAVE_SYS_RESOURCE_H) && defined (HAVE_GETRLIMIT) -# define HAVE_RESOURCE -#endif - -#if !defined (GETPGRP_VOID) -# define HAVE_BSD_PGRP -#endif - -/* Try this without testing __STDC__ for the time being. */ -#if defined (HAVE_STDARG_H) -# define PREFER_STDARG -# define USE_VARARGS -#else -# if defined (HAVE_VARARGS_H) -# define PREFER_VARARGS -# define USE_VARARGS -# endif -#endif - -#if defined (HAVE_SYS_SOCKET_H) && defined (HAVE_GETPEERNAME) && defined (HAVE_NETINET_IN_H) -# define HAVE_NETWORK -#endif - -#if defined (HAVE_REGEX_H) && defined (HAVE_REGCOMP) && defined (HAVE_REGEXEC) -# define HAVE_POSIX_REGEXP -#endif - -/* backwards compatibility between different autoconf versions */ -#if HAVE_DECL_SYS_SIGLIST && !defined (SYS_SIGLIST_DECLARED) -# define SYS_SIGLIST_DECLARED -#endif - -/***********************************************************************/ -/* Unset defines based on what configure reports as missing or broken. */ -/***********************************************************************/ - -/* Ultrix botches type-ahead when switching from canonical to - non-canonical mode, at least through version 4.3 */ -#if !defined (HAVE_TERMIOS_H) || !defined (HAVE_TCGETATTR) || defined (ultrix) -# define TERMIOS_MISSING -#endif - -/* If we have a getcwd(3), but one that does not dynamically allocate memory, - #undef HAVE_GETCWD so the replacement in getcwd.c will be built. We do - not do this on Solaris, because their implementation of loopback mounts - breaks the traditional file system assumptions that getcwd uses. */ -#if defined (HAVE_GETCWD) && defined (GETCWD_BROKEN) && !defined (SOLARIS) -# undef HAVE_GETCWD -#endif - -#if !defined (HAVE_DEV_FD) && defined (NAMED_PIPES_MISSING) -# undef PROCESS_SUBSTITUTION -#endif - -#if defined (JOB_CONTROL_MISSING) -# undef JOB_CONTROL -#endif - -#if defined (STRCOLL_BROKEN) -# undef HAVE_STRCOLL -#endif - -#if !defined (HAVE_POSIX_REGEXP) -# undef COND_REGEXP -#endif - -#if !HAVE_MKSTEMP -# undef USE_MKSTEMP -#endif - -#if !HAVE_MKDTEMP -# undef USE_MKDTEMP -#endif - -/* If the shell is called by this name, it will become restricted. */ -#if defined (RESTRICTED_SHELL) -# define RESTRICTED_SHELL_NAME "rbash" -#endif - -/***********************************************************/ -/* Make sure feature defines have necessary prerequisites. */ -/***********************************************************/ - -/* BANG_HISTORY requires HISTORY. */ -#if defined (BANG_HISTORY) && !defined (HISTORY) -# define HISTORY -#endif /* BANG_HISTORY && !HISTORY */ - -#if defined (READLINE) && !defined (HISTORY) -# define HISTORY -#endif - -#if defined (PROGRAMMABLE_COMPLETION) && !defined (READLINE) -# undef PROGRAMMABLE_COMPLETION -#endif - -#if !defined (V9_ECHO) -# undef DEFAULT_ECHO_TO_XPG -#endif - -#if !defined (PROMPT_STRING_DECODE) -# undef PPROMPT -# define PPROMPT "$ " -#endif - -#if !defined (HAVE_SYSLOG) || !defined (HAVE_SYSLOG_H) -# undef SYSLOG_HISTORY -#endif - -/************************************************/ -/* check multibyte capability for I18N code */ -/************************************************/ - -/* For platforms which support the ISO C amendment 1 functionality we - support user defined character classes. */ -/* Solaris 2.5 has a bug: must be included before . */ -#if defined (HAVE_WCTYPE_H) && defined (HAVE_WCHAR_H) && defined (HAVE_LOCALE_H) -# include -# include -# if defined (HAVE_ISWCTYPE) && \ - defined (HAVE_ISWLOWER) && \ - defined (HAVE_ISWUPPER) && \ - defined (HAVE_MBSRTOWCS) && \ - defined (HAVE_MBRTOWC) && \ - defined (HAVE_MBRLEN) && \ - defined (HAVE_TOWLOWER) && \ - defined (HAVE_TOWUPPER) && \ - defined (HAVE_WCHAR_T) && \ - defined (HAVE_WCTYPE_T) && \ - defined (HAVE_WINT_T) && \ - defined (HAVE_WCWIDTH) && \ - defined (HAVE_WCTYPE) - /* system is supposed to support XPG5 */ -# define HANDLE_MULTIBYTE 1 -# endif -#endif - -/* If we don't want multibyte chars even on a system that supports them, let - the configuring user turn multibyte support off. */ -#if defined (NO_MULTIBYTE_SUPPORT) -# undef HANDLE_MULTIBYTE -#endif - -/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ -#if HANDLE_MULTIBYTE && !defined (HAVE_MBSTATE_T) -# define wcsrtombs(dest, src, len, ps) (wcsrtombs) (dest, src, len, 0) -# define mbsrtowcs(dest, src, len, ps) (mbsrtowcs) (dest, src, len, 0) -# define wcrtomb(s, wc, ps) (wcrtomb) (s, wc, 0) -# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) -# define mbrlen(s, n, ps) (mbrlen) (s, n, 0) -# define mbstate_t int -#endif - -/* Make sure MB_LEN_MAX is at least 16 (some systems define - MB_LEN_MAX as 1) */ -#ifdef HANDLE_MULTIBYTE -# include -# if defined(MB_LEN_MAX) && (MB_LEN_MAX < 16) -# undef MB_LEN_MAX -# endif -# if !defined (MB_LEN_MAX) -# define MB_LEN_MAX 16 -# endif -#endif - -/************************************************/ -/* end of multibyte capability checks for I18N */ -/************************************************/ - -/******************************************************************/ -/* Placeholder for builders to #undef any unwanted features from */ -/* config-top.h or created by configure (such as the default mail */ -/* file for mail checking). */ -/******************************************************************/ - -/* If you don't want bash to provide a default mail file to check. */ -/* #undef DEFAULT_MAIL_DIRECTORY */ diff --git a/third_party/bash/config-top.h b/third_party/bash/config-top.h deleted file mode 100644 index db4ab6ee3..000000000 --- a/third_party/bash/config-top.h +++ /dev/null @@ -1,201 +0,0 @@ -/* config-top.h - various user-settable options not under the control of autoconf. */ - -/* Copyright (C) 2002-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -/* Define CONTINUE_AFTER_KILL_ERROR if you want the kill command to - continue processing arguments after one of them fails. This is - what POSIX.2 specifies. */ -#define CONTINUE_AFTER_KILL_ERROR - -/* Define BREAK_COMPLAINS if you want the non-standard, but useful - error messages about `break' and `continue' out of context. */ -#define BREAK_COMPLAINS - -/* Define CD_COMPLAINS if you want the non-standard, but sometimes-desired - error messages about multiple directory arguments to `cd'. */ -#define CD_COMPLAINS - -/* Define BUFFERED_INPUT if you want the shell to do its own input - buffering, rather than using stdio. Do not undefine this; it's - required to preserve semantics required by POSIX. */ -#define BUFFERED_INPUT - -/* Define ONESHOT if you want sh -c 'command' to avoid forking to execute - `command' whenever possible. This is a big efficiency improvement. */ -#define ONESHOT - -/* Define V9_ECHO if you want to give the echo builtin backslash-escape - interpretation using the -e option, in the style of the Bell Labs 9th - Edition version of echo. You cannot emulate the System V echo behavior - without this option. */ -#define V9_ECHO - -/* Define DONT_REPORT_SIGPIPE if you don't want to see `Broken pipe' messages - when a job like `cat jobs.c | exit 1' terminates due to a SIGPIPE. */ -#define DONT_REPORT_SIGPIPE - -/* Define DONT_REPORT_SIGTERM if you don't want to see `Terminates' message - when a job exits due to SIGTERM, since that's the default signal sent - by the kill builtin. */ -#define DONT_REPORT_SIGTERM - -/* Define DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS if you don't want builtins - like `echo' and `printf' to report errors when output does not succeed - due to EPIPE. */ -/* #define DONT_REPORT_BROKEN_PIPE_WRITE_ERRORS */ - -/* The default value of the PATH variable. */ -#ifndef DEFAULT_PATH_VALUE -#define DEFAULT_PATH_VALUE \ - "/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:." -#endif - -/* If you want to unconditionally set a value for PATH in every restricted - shell, set this. */ -/* #define RBASH_STATIC_PATH_VALUE "/rbin:/usr/rbin" */ - -/* The value for PATH when invoking `command -p'. This is only used when - the Posix.2 confstr () function, or CS_PATH define are not present. */ -#ifndef STANDARD_UTILS_PATH -#define STANDARD_UTILS_PATH \ - "/bin:/usr/bin:/sbin:/usr/sbin:/etc:/usr/etc" -#endif - -/* The default path for enable -f */ -#ifndef DEFAULT_LOADABLE_BUILTINS_PATH -#define DEFAULT_LOADABLE_BUILTINS_PATH \ - "/usr/local/lib/bash:/usr/lib/bash:/opt/local/lib/bash:/usr/pkg/lib/bash:/opt/pkg/lib/bash:." -#endif - -/* Default primary and secondary prompt strings. */ -#define PPROMPT "\\s-\\v\\$ " -#define SPROMPT "> " - -/* Undefine this if you don't want the ksh-compatible behavior of reprinting - the select menu after a valid choice is made only if REPLY is set to NULL - in the body of the select command. The menu is always reprinted if the - reply to the select query is an empty line. */ -#define KSH_COMPATIBLE_SELECT - -/* Default interactive shell startup file. */ -#define DEFAULT_BASHRC "~/.bashrc" - -/* System-wide .bashrc file for interactive shells. */ -/* #define SYS_BASHRC "/etc/bash.bashrc" */ - -/* System-wide .bash_logout for login shells. */ -/* #define SYS_BASH_LOGOUT "/etc/bash.bash_logout" */ - -/* Define this to make non-interactive shells begun with argv[0][0] == '-' - run the startup files when not in posix mode. */ -/* #define NON_INTERACTIVE_LOGIN_SHELLS */ - -/* Define this if you want bash to try to check whether it's being run by - sshd and source the .bashrc if so (like the rshd behavior). This checks - for the presence of SSH_CLIENT or SSH2_CLIENT in the initial environment, - which can be fooled under certain not-uncommon circumstances. */ -/* #define SSH_SOURCE_BASHRC */ - -/* Define if you want the case-toggling operators (~[~]) and the - `capcase' variable attribute (declare -c). */ -/* TAG: bash-5.2 disable? */ -#define CASEMOD_TOGGLECASE -#define CASEMOD_CAPCASE - -/* This is used as the name of a shell function to call when a command - name is not found. If you want to name it something other than the - default ("command_not_found_handle"), change it here. */ -/* #define NOTFOUND_HOOK "command_not_found_handle" */ - -/* Define if you want each line saved to the history list in bashhist.c: - bash_add_history() to be sent to syslog(). */ -/* #define SYSLOG_HISTORY */ -#if defined (SYSLOG_HISTORY) -# define SYSLOG_FACILITY LOG_USER -# define SYSLOG_LEVEL LOG_INFO -# define OPENLOG_OPTS LOG_PID -#endif - -/* Define if you want syslogging history to be controllable at runtime via a - shell option; if defined, the value is the default for the syslog_history - shopt option */ -#if defined (SYSLOG_HISTORY) -/* #define SYSLOG_SHOPT 1 */ -#endif - -/* Define if you want to include code in shell.c to support wordexp(3) */ -/* #define WORDEXP_OPTION */ - -/* Define as 1 if you want to enable code that implements multiple coprocs - executing simultaneously */ -#ifndef MULTIPLE_COPROCS -# define MULTIPLE_COPROCS 0 -#endif - -/* Define to 0 if you want the checkwinsize option off by default, 1 if you - want it on. */ -#define CHECKWINSIZE_DEFAULT 1 - -/* Define to 1 if you want to optimize for sequential array assignment when - using indexed arrays, 0 if you want bash-4.2 behavior, which favors - random access but is O(N) for each array assignment. */ -#define OPTIMIZE_SEQUENTIAL_ARRAY_ASSIGNMENT 1 - -/* Define to 1 if you want to be able to export indexed arrays to processes - using the foo=([0]=one [1]=two) and so on */ -/* #define ARRAY_EXPORT 1 */ - -/* Define to 1 if you want the shell to exit if it is running setuid and its - attempt to drop privilege using setuid(getuid()) fails with errno == EAGAIN */ -/* #define EXIT_ON_SETUID_FAILURE 1 */ - -/* Define to 1 if you want the shell to re-check $PATH if a hashed filename - no longer exists. This behavior is the default in Posix mode. */ -#define CHECKHASH_DEFAULT 0 - -/* Define to the maximum level of recursion you want for the eval builtin - and trap handlers (since traps are run as if run by eval). - 0 means the limit is not active. */ -#define EVALNEST_MAX 0 - -/* Define to the maximum level of recursion you want for the source/. builtin. - 0 means the limit is not active. */ -#define SOURCENEST_MAX 0 - -/* Define to use libc mktemp/mkstemp instead of replacements in lib/sh/tmpfile.c */ -#define USE_MKTEMP -#define USE_MKSTEMP -#define USE_MKDTEMP - -/* Define to force the value of OLDPWD inherited from the environment to be a - directory */ -#define OLDPWD_CHECK_DIRECTORY 1 - -/* Define to set the initial size of the history list ($HISTSIZE). This must - be a string. */ -/*#define HISTSIZE_DEFAULT "500"*/ - -/* Define to 0 if you want history expansion to be disabled by default in - interactive shells; define to 1 for the historical behavior of enabling - when the shell is interactive. */ -#define HISTEXPAND_DEFAULT 1 - -/* Undefine or define to 0 if you don't want to allow associative array - assignment using a compound list of key-value pairs. */ -#define ASSOC_KVPAIR_ASSIGNMENT 1 diff --git a/third_party/bash/config.h b/third_party/bash/config.h deleted file mode 100644 index caeab0fa6..000000000 --- a/third_party/bash/config.h +++ /dev/null @@ -1,1235 +0,0 @@ -/* config.h. Generated from config.h.in by configure. */ -/* config.h -- Configuration file for bash. */ - -/* Copyright (C) 1987-2009,2011-2012,2013-2019 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#ifndef _CONFIG_H_ -#define _CONFIG_H_ - -#ifdef _COSMO_SOURCE -#undef _COSMO_SOURCE -#endif - -/* Template settings for autoconf */ - -/* Configuration feature settings controllable by autoconf. */ - -/* Define JOB_CONTROL if your operating system supports - BSD-like job control. */ -#define JOB_CONTROL 1 - -/* Define ALIAS if you want the alias features. */ -#define ALIAS 1 - -/* Define PUSHD_AND_POPD if you want those commands to be compiled in. - (Also the `dirs' commands.) */ -#define PUSHD_AND_POPD 1 - -/* Define BRACE_EXPANSION if you want curly brace expansion a la Csh: - foo{a,b} -> fooa foob. Even if this is compiled in (the default) you - can turn it off at shell startup with `-nobraceexpansion', or during - shell execution with `set +o braceexpand'. */ -#define BRACE_EXPANSION 1 - -/* Define READLINE to get the nifty/glitzy editing features. - This is on by default. You can turn it off interactively - with the -nolineediting flag. */ -#define READLINE 1 - -/* Define BANG_HISTORY if you want to have Csh style "!" history expansion. - This is unrelated to READLINE. */ -#define BANG_HISTORY 1 - -/* Define HISTORY if you want to have access to previously typed commands. - - If both HISTORY and READLINE are defined, you can get at the commands - with line editing commands, and you can directly manipulate the history - from the command line. - - If only HISTORY is defined, the `fc' and `history' builtins are - available. */ -#define HISTORY 1 - -/* Define this if you want completion that puts all alternatives into - a brace expansion shell expression. */ -#if defined (BRACE_EXPANSION) && defined (READLINE) -# define BRACE_COMPLETION -#endif /* BRACE_EXPANSION */ - -/* Define DEFAULT_ECHO_TO_XPG if you want the echo builtin to interpret - the backslash-escape characters by default, like the XPG Single Unix - Specification V2 for echo. - This requires that V9_ECHO be defined. */ -/* #undef DEFAULT_ECHO_TO_XPG */ - -/* Define HELP_BUILTIN if you want the `help' shell builtin and the long - documentation strings compiled into the shell. */ -#define HELP_BUILTIN 1 - -/* Define RESTRICTED_SHELL if you want the generated shell to have the - ability to be a restricted one. The shell thus generated can become - restricted by being run with the name "rbash", or by setting the -r - flag. */ -#define RESTRICTED_SHELL 1 - -/* Define DISABLED_BUILTINS if you want "builtin foo" to always run the - shell builtin "foo", even if it has been disabled with "enable -n foo". */ -/* #undef DISABLED_BUILTINS */ - -/* Define PROCESS_SUBSTITUTION if you want the K*rn shell-like process - substitution features "<(file)". */ -/* Right now, you cannot do this on machines without fully operational - FIFO support. This currently include NeXT and Alliant. */ -#define PROCESS_SUBSTITUTION 1 - -/* Define PROMPT_STRING_DECODE if you want the backslash-escaped special - characters in PS1 and PS2 expanded. Variable expansion will still be - performed. */ -#define PROMPT_STRING_DECODE 1 - -/* Define SELECT_COMMAND if you want the Korn-shell style `select' command: - select word in word_list; do command_list; done */ -#define SELECT_COMMAND 1 - -/* Define COMMAND_TIMING of you want the ksh-style `time' reserved word and - the ability to time pipelines, functions, and builtins. */ -#define COMMAND_TIMING 1 - -/* Define ARRAY_VARS if you want ksh-style one-dimensional array variables. */ -#define ARRAY_VARS 1 - -/* Define DPAREN_ARITHMETIC if you want the ksh-style ((...)) arithmetic - evaluation command. */ -#define DPAREN_ARITHMETIC 1 - -/* Define EXTENDED_GLOB if you want the ksh-style [*+@?!](patlist) extended - pattern matching. */ -#define EXTENDED_GLOB 1 - -/* Define EXTGLOB_DEFAULT to the value you'd like the extglob shell option - to have by default */ -#define EXTGLOB_DEFAULT 0 - -/* Define COND_COMMAND if you want the ksh-style [[...]] conditional - command. */ -#define COND_COMMAND 1 - -/* Define COND_REGEXP if you want extended regular expression matching and the - =~ binary operator in the [[...]] conditional command. */ -#define COND_REGEXP 1 - -/* Define COPROCESS_SUPPORT if you want support for ksh-like coprocesses and - the `coproc' reserved word */ -#define COPROCESS_SUPPORT 1 - -/* Define ARITH_FOR_COMMAND if you want the ksh93-style - for (( init; test; step )) do list; done - arithmetic for command. */ -#define ARITH_FOR_COMMAND 1 - -/* Define NETWORK_REDIRECTIONS if you want /dev/(tcp|udp)/host/port to open - socket connections when used in redirections */ -#define NETWORK_REDIRECTIONS 1 - -/* Define PROGRAMMABLE_COMPLETION for the programmable completion features - and the complete builtin. */ -#define PROGRAMMABLE_COMPLETION 1 - -/* Define NO_MULTIBYTE_SUPPORT to not compile in support for multibyte - characters, even if the OS supports them. */ -/* #undef NO_MULTIBYTE_SUPPORT */ - -/* Define DEBUGGER if you want to compile in some features used only by the - bash debugger. */ -#define DEBUGGER 1 - -/* Define STRICT_POSIX if you want bash to be strictly posix.2 conformant by - default (except for echo; that is controlled separately). */ -/* #undef STRICT_POSIX */ - -/* Define MEMSCRAMBLE if you want the bash malloc and free to scramble - memory contents on malloc() and free(). */ -#define MEMSCRAMBLE 1 - -/* Define for case-modifying variable attributes; variables modified on - assignment */ -#define CASEMOD_ATTRS 1 - -/* Define for case-modifying word expansions */ -#define CASEMOD_EXPANSIONS 1 - -/* Define to make the `direxpand' shopt option enabled by default. */ -/* #undef DIRCOMPLETE_EXPAND_DEFAULT */ - -/* Define to make the `globasciiranges' shopt option enabled by default. */ -#define GLOBASCII_DEFAULT 1 - -/* Define to allow functions to be imported from the environment. */ -#define FUNCTION_IMPORT 1 - -/* Define AFS if you are using Transarc's AFS. */ -/* #undef AFS */ - -/* #undef ENABLE_NLS */ - -/* End of configuration settings controllable by autoconf. */ -/* Other settable options appear in config-top.h. */ - -#include "config-top.h" - -/* Beginning of autoconf additions. */ - -/* Characteristics of the C compiler */ -/* #undef const */ - -/* #undef inline */ - -#define restrict __restrict__ - -/* #undef volatile */ - -/* Define if cpp supports the ANSI-C stringizing `#' operator */ -#define HAVE_STRINGIZE 1 - -/* Define if the compiler supports `long double' variables. */ -#define HAVE_LONG_DOUBLE 1 - -#define PROTOTYPES 1 -#define __PROTOTYPES 1 - -/* #undef __CHAR_UNSIGNED__ */ - -/* Define if the compiler supports `long long int' variables. */ -#define HAVE_LONG_LONG_INT 1 - -#define HAVE_UNSIGNED_LONG_LONG_INT 1 - -/* The number of bytes in a int. */ -#define SIZEOF_INT 4 - -/* The number of bytes in a long. */ -#define SIZEOF_LONG 8 - -/* The number of bytes in a pointer to char. */ -#define SIZEOF_CHAR_P 8 - -/* The number of bytes in a size_t. */ -#define SIZEOF_SIZE_T 8 - -/* The number of bytes in a double (hopefully 8). */ -#define SIZEOF_DOUBLE 8 - -/* The number of bytes in an `intmax_t'. */ -#define SIZEOF_INTMAX_T 8 - -/* The number of bytes in a `long long', if we have one. */ -#define SIZEOF_LONG_LONG 8 - -/* The number of bytes in a `wchar_t', if supported */ -#define SIZEOF_WCHAR_T 4 - -/* System paths */ - -#define DEFAULT_MAIL_DIRECTORY "/var/mail" - -/* Characteristics of the system's header files and libraries that affect - the compilation environment. */ - -/* These are set by AC_USE_SYSTEM_EXTENSIONS */ - -/* Define if the system does not provide POSIX.1 features except - with this defined. */ -/* #undef _POSIX_1_SOURCE */ - -/* Define if you need to in order for stat and other things to work. */ -/* #undef _POSIX_SOURCE */ - -/* Define to use GNU libc extensions. */ -#define _GNU_SOURCE 1 - -/* Define to enable general system extensions on Solaris. */ -#define __EXTENSIONS__ 1 - -/* General system extensions on AIX */ -#define _ALL_SOURCE 1 - -#define _POSIX_PTHREAD_SEMANTICS 1 -#define _TANDEM_SOURCE 1 -/* #undef _MINIX */ - -/* Memory management functions. */ - -/* Define if using the bash version of malloc in lib/malloc/malloc.c */ -/* #undef USING_BASH_MALLOC */ - -/* #undef DISABLE_MALLOC_WRAPPERS */ - -/* Define if using alloca.c. */ -/* #undef C_ALLOCA */ - -/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. - This function is required for alloca.c support on those systems. */ -/* #undef CRAY_STACKSEG_END */ - -/* Define if you have alloca, as a function or macro. */ -#define HAVE_ALLOCA 1 - -/* Define if you have and it should be used (not on Ultrix). */ -#define HAVE_ALLOCA_H 1 - -/* Define if major/minor/makedev is defined in */ -/* #undef MAJOR_IN_MAKEDEV */ - -/* Define if major/minor/makedev is defined in */ -#define MAJOR_IN_SYSMACROS 1 - -/* SYSTEM TYPES */ - -/* Define to `long' if doesn't define. */ -/* #undef off_t */ - -/* Define to `int' if doesn't define. */ -/* #undef mode_t */ - -/* Define to `int' if doesn't define. */ -/* #undef sigset_t */ - -/* Define to `int' if doesn't define. */ -/* #undef pid_t */ - -/* Define to `short' if doesn't define. */ -#define bits16_t short - -/* Define to `unsigned short' if doesn't define. */ -#define u_bits16_t unsigned short - -/* Define to `int' if doesn't define. */ -#define bits32_t int - -/* Define to `unsigned int' if doesn't define. */ -#define u_bits32_t unsigned int - -/* Define to `double' if doesn't define. */ -#define bits64_t char * - -/* Define to `unsigned int' if doesn't define. */ -/* #undef u_int */ - -/* Define to `unsigned long' if doesn't define. */ -/* #undef u_long */ - -/* Define to `int' if doesn't define. */ -/* #undef ptrdiff_t */ - -/* Define to `unsigned' if doesn't define. */ -/* #undef size_t */ - -/* Define to `int' if doesn't define. */ -/* #undef ssize_t */ - -/* Define to `long' if doesn't define. */ -/* #undef intmax_t */ - -/* Define to `unsigned long' if doesn't define. */ -/* #undef uintmax_t */ - -/* Define to integer type wide enough to hold a pointer if doesn't define. */ -/* #undef uintptr_t */ - -/* Define to `int' if doesn't define. */ -/* #undef uid_t */ - -/* Define to `long' if doesn't define. */ -/* #undef clock_t */ - -/* Define to `long' if doesn't define. */ -/* #undef time_t */ - -/* Define to `int' if doesn't define. */ -/* #undef gid_t */ - -/* Define to `unsigned int' if doesn't define. */ -/* #undef socklen_t */ - -/* Define to `int' if doesn't define. */ -/* #undef sig_atomic_t */ - -#define HAVE_MBSTATE_T 1 - -/* Define if you have quad_t in . */ -#define HAVE_QUAD_T 1 - -/* Define if you have wchar_t in . */ -#define HAVE_WCHAR_T 1 - -/* Define if you have wctype_t in . */ -#define HAVE_WCTYPE_T 1 - -/* Define if you have wint_t in . */ -#define HAVE_WINT_T 1 - -#define RLIMTYPE rlim_t - -/* Define to the type of elements in the array set by `getgroups'. - Usually this is either `int' or `gid_t'. */ -#define GETGROUPS_T gid_t - -/* Characteristics of the machine archictecture. */ - -/* If using the C implementation of alloca, define if you know the - direction of stack growth for your system; otherwise it will be - automatically deduced at run-time. - STACK_DIRECTION > 0 => grows toward higher addresses - STACK_DIRECTION < 0 => grows toward lower addresses - STACK_DIRECTION = 0 => direction of growth unknown - */ -/* #undef STACK_DIRECTION */ - -/* Define if the machine architecture is big-endian. */ -/* #undef WORDS_BIGENDIAN */ - -/* Check for the presence of certain non-function symbols in the system - libraries. */ - -/* Define if `sys_siglist' is declared by or . */ -#define HAVE_DECL_SYS_SIGLIST 0 -/* #undef SYS_SIGLIST_DECLARED */ - -/* Define if `_sys_siglist' is declared by or . */ -/* #undef UNDER_SYS_SIGLIST_DECLARED */ - -/* #undef HAVE_SYS_SIGLIST */ - -/* #undef HAVE_UNDER_SYS_SIGLIST */ - -#define HAVE_SYS_ERRLIST 1 - -/* #undef HAVE_TZNAME */ -/* #undef HAVE_DECL_TZNAME */ - -/* Characteristics of some of the system structures. */ - -#define HAVE_STRUCT_DIRENT_D_INO 1 - -/* #undef HAVE_STRUCT_DIRENT_D_FILENO */ - -/* #undef HAVE_STRUCT_DIRENT_D_NAMLEN */ - -/* #undef TIOCSTAT_IN_SYS_IOCTL */ - -#define FIONREAD_IN_SYS_IOCTL 1 - -/* #undef GWINSZ_IN_SYS_IOCTL */ - -#define STRUCT_WINSIZE_IN_SYS_IOCTL 1 - -/* #undef TM_IN_SYS_TIME */ - -/* #undef STRUCT_WINSIZE_IN_TERMIOS */ - -#define SPEED_T_IN_SYS_TYPES 1 - -/* #undef TERMIOS_LDISC */ - -/* #undef TERMIO_LDISC */ - -#define HAVE_STRUCT_STAT_ST_BLOCKS 1 - -#define HAVE_STRUCT_TM_TM_ZONE 1 -#define HAVE_TM_ZONE 1 - -#define HAVE_TIMEVAL 1 - -#define HAVE_STRUCT_TIMEZONE 1 - -#define WEXITSTATUS_OFFSET 8 - -#define HAVE_STRUCT_TIMESPEC 1 -#define TIME_H_DEFINES_STRUCT_TIMESPEC 1 -/* #undef SYS_TIME_H_DEFINES_STRUCT_TIMESPEC */ -/* #undef PTHREAD_H_DEFINES_STRUCT_TIMESPEC */ - -#define HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC 1 -#define TYPEOF_STRUCT_STAT_ST_ATIM_IS_STRUCT_TIMESPEC 1 -/* #undef HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC */ -/* #undef HAVE_STRUCT_STAT_ST_ATIMENSEC */ -/* #undef HAVE_STRUCT_STAT_ST_ATIM_ST__TIM_TV_NSEC */ - -/* Characteristics of definitions in the system header files. */ - -#define HAVE_GETPW_DECLS 1 - -/* #undef HAVE_RESOURCE */ - -/* #undef HAVE_LIBC_FNM_EXTMATCH */ - -/* Define if you have and it defines AUDIT_USER_TTY */ -#define HAVE_DECL_AUDIT_USER_TTY 0 - -#define HAVE_DECL_CONFSTR 1 - -#define HAVE_DECL_PRINTF 1 - -#define HAVE_DECL_SBRK 0 - -#define HAVE_DECL_STRCPY 1 - -#define HAVE_DECL_STRSIGNAL 1 - -#define HAVE_DECL_STRTOLD 1 - -/* #undef PRI_MACROS_BROKEN */ - -/* #undef STRTOLD_BROKEN */ - -/* Define if WCONTINUED is defined in system headers, but rejected by waitpid */ -/* #undef WCONTINUED_BROKEN */ - -/* These are checked with BASH_CHECK_DECL */ - -#define HAVE_DECL_STRTOIMAX 1 -#define HAVE_DECL_STRTOL 1 -#define HAVE_DECL_STRTOLL 1 -#define HAVE_DECL_STRTOUL 1 -#define HAVE_DECL_STRTOULL 1 -#define HAVE_DECL_STRTOUMAX 1 - -/* Characteristics of system calls and C library functions. */ - -/* Define if the `getpgrp' function takes no argument. */ -#define GETPGRP_VOID 1 - -#define NAMED_PIPES_MISSING 1 - -/* #undef OPENDIR_NOT_ROBUST */ - -#define PGRP_PIPE 1 - -/* #undef STAT_MACROS_BROKEN */ - -/* #undef ULIMIT_MAXFDS */ - -#define CAN_REDEFINE_GETENV 1 - -#define HAVE_STD_PUTENV 1 - -#define HAVE_STD_UNSETENV 1 - -#define HAVE_PRINTF_A_FORMAT 1 - -/* Define if you have and nl_langinfo(CODESET). */ -#define HAVE_LANGINFO_CODESET 1 - -/* Characteristics of properties exported by the kernel. */ - -/* Define if the kernel can exec files beginning with #! */ -#define HAVE_HASH_BANG_EXEC 1 - -/* Define if you have the /dev/fd devices to map open files into the file system. */ -#define HAVE_DEV_FD 1 - -/* Defined to /dev/fd or /proc/self/fd (linux). */ -#define DEV_FD_PREFIX "/dev/fd/" - -/* Define if you have the /dev/stdin device. */ -#define HAVE_DEV_STDIN 1 - -/* The type of iconv's `inbuf' argument */ -#define ICONV_CONST - -/* Type and behavior of signal handling functions. */ - -/* #undef MUST_REINSTALL_SIGHANDLERS */ - -/* #undef HAVE_BSD_SIGNALS */ - -#define HAVE_POSIX_SIGNALS 1 - -/* #undef HAVE_USG_SIGHOLD */ - -/* #undef UNUSABLE_RT_SIGNALS */ - -/* Presence of system and C library functions. */ - -/* Define if you have the arc4random function. */ -/* #undef HAVE_ARC4RANDOM */ - -/* Define if you have the asprintf function. */ -#define HAVE_ASPRINTF 1 - -/* Define if you have the bcopy function. */ -#define HAVE_BCOPY 1 - -/* Define if you have the bzero function. */ -#define HAVE_BZERO 1 - -/* Define if you have the chown function. */ -#define HAVE_CHOWN 1 - -/* Define if you have the confstr function. */ -#define HAVE_CONFSTR 1 - -/* Define if you have the dlclose function. */ -/* #undef HAVE_DLCLOSE */ - -/* Define if you have the dlopen function. */ -/* #undef HAVE_DLOPEN */ - -/* Define if you have the dlsym function. */ -/* #undef HAVE_DLSYM */ - -/* Define if you don't have vprintf but do have _doprnt. */ -/* #undef HAVE_DOPRNT */ - -/* Define if you have the dprintf function. */ -#define HAVE_DPRINTF 1 - -/* Define if you have the dup2 function. */ -#define HAVE_DUP2 1 - -/* Define if you have the eaccess function. */ -#define HAVE_EACCESS 1 - -/* Define if you have the faccessat function. */ -#define HAVE_FACCESSAT 1 - -/* Define if you have the fcntl function. */ -#define HAVE_FCNTL 1 - -/* Define if you have the fnmatch function. */ -#define HAVE_FNMATCH 1 - -/* Can fnmatch be used as a fallback to match [=equiv=] with collation weights? */ -#define FNMATCH_EQUIV_FALLBACK 0 - -/* Define if you have the fpurge/__fpurge function. */ -#define HAVE_FPURGE 1 -#define HAVE___FPURGE 1 -#define HAVE_DECL_FPURGE 1 - -/* Define if you have the getaddrinfo function. */ -#define HAVE_GETADDRINFO 1 - -/* Define if you have the getcwd function. */ -#define HAVE_GETCWD 1 - -/* Define if you have the getentropy function. */ -#define HAVE_GETENTROPY 1 - -/* Define if you have the getdtablesize function. */ -#define HAVE_GETDTABLESIZE 1 - -/* Define if you have the getgroups function. */ -#define HAVE_GETGROUPS 1 - -/* Define if you have the gethostbyname function. */ -#define HAVE_GETHOSTBYNAME 1 - -/* Define if you have the gethostname function. */ -#define HAVE_GETHOSTNAME 1 - -/* Define if you have the getpagesize function. */ -#define HAVE_GETPAGESIZE 1 - -/* Define if you have the getpeername function. */ -#define HAVE_GETPEERNAME 1 - -/* Define if you have the getpwent function. */ -#define HAVE_GETPWENT 1 - -/* Define if you have the getpwnam function. */ -#define HAVE_GETPWNAM 1 - -/* Define if you have the getpwuid function. */ -#define HAVE_GETPWUID 1 - -/* Define if you have the getrandom function. */ -#define HAVE_GETRANDOM 1 - -/* Define if you have the getrlimit function. */ -#define HAVE_GETRLIMIT 1 - -/* Define if you have the getrusage function. */ -#define HAVE_GETRUSAGE 1 - -/* Define if you have the getservbyname function. */ -#define HAVE_GETSERVBYNAME 1 - -/* Define if you have the getservent function. */ -#define HAVE_GETSERVENT 1 - -/* Define if you have the gettimeofday function. */ -#define HAVE_GETTIMEOFDAY 1 - -/* Define if you have the getwd function. */ -/* #undef HAVE_GETWD */ - -/* Define if you have the iconv function. */ -#define HAVE_ICONV 1 - -/* Define if you have the imaxdiv function. */ -#define HAVE_IMAXDIV 1 - -/* Define if you have the inet_aton function. */ -#define HAVE_INET_ATON 1 - -/* Define if you have the isascii function. */ -#define HAVE_ISASCII 1 - -/* Define if you have the isblank function. */ -#define HAVE_ISBLANK 1 - -/* Define if you have the isgraph function. */ -#define HAVE_ISGRAPH 1 - -/* Define if you have the isprint function. */ -#define HAVE_ISPRINT 1 - -/* Define if you have the isspace function. */ -#define HAVE_ISSPACE 1 - -/* Define if you have the iswctype function. */ -#define HAVE_ISWCTYPE 1 - -/* Define if you have the iswlower function. */ -#define HAVE_ISWLOWER 1 - -/* Define if you have the iswupper function. */ -#define HAVE_ISWUPPER 1 - -/* Define if you have the isxdigit function. */ -#define HAVE_ISXDIGIT 1 - -/* Define if you have the kill function. */ -#define HAVE_KILL 1 - -/* Define if you have the killpg function. */ -#define HAVE_KILLPG 1 - -/* Define if you have the lstat function. */ -#define HAVE_LSTAT 1 - -/* Define if you have the locale_charset function. */ -/* #undef HAVE_LOCALE_CHARSET */ - -/* Define if you have the mbrlen function. */ -#define HAVE_MBRLEN 1 - -/* Define if you have the mbrtowc function. */ -#define HAVE_MBRTOWC 1 - -/* Define if you have the mbscasecmp function. */ -/* #undef HAVE_MBSCASECMP */ - -/* Define if you have the mbschr function. */ -/* #undef HAVE_MBSCHR */ - -/* Define if you have the mbscmp function. */ -/* #undef HAVE_MBSCMP */ - -/* Define if you have the mbsnrtowcs function. */ -#define HAVE_MBSNRTOWCS 1 - -/* Define if you have the mbsrtowcs function. */ -#define HAVE_MBSRTOWCS 1 - -/* Define if you have the memmove function. */ -#define HAVE_MEMMOVE 1 - -/* Define if you have the memset function. */ -#define HAVE_MEMSET 1 - -/* Define if you have the mkdtemp function. */ -#define HAVE_MKDTEMP 1 - -/* Define if you have the mkfifo function. */ -/* #undef HAVE_MKFIFO */ - -/* Define if you have the mkstemp function. */ -#define HAVE_MKSTEMP 1 - -/* Define if you have the pathconf function. */ -#define HAVE_PATHCONF 1 - -/* Define if you have the pselect function. */ -#define HAVE_PSELECT 1 - -/* Define if you have the putenv function. */ -#define HAVE_PUTENV 1 - -/* Define if you have the raise function. */ -#define HAVE_RAISE 1 - -/* Define if you have the random function. */ -#define HAVE_RANDOM 1 - -/* Define if you have the readlink function. */ -#define HAVE_READLINK 1 - -/* Define if you have the regcomp function. */ -#define HAVE_REGCOMP 1 - -/* Define if you have the regexec function. */ -#define HAVE_REGEXEC 1 - -/* Define if you have the rename function. */ -#define HAVE_RENAME 1 - -/* Define if you have the sbrk function. */ -/* #undef HAVE_SBRK */ - -/* Define if you have the select function. */ -#define HAVE_SELECT 1 - -/* Define if you have the setdtablesize function. */ -/* #undef HAVE_SETDTABLESIZE */ - -/* Define if you have the setenv function. */ -#define HAVE_SETENV 1 - -/* Define if you have the setitimer function. */ -#define HAVE_SETITIMER 1 - -/* Define if you have the setlinebuf function. */ -#define HAVE_SETLINEBUF 1 - -/* Define if you have the setlocale function. */ -#define HAVE_SETLOCALE 1 - -/* Define if you have the setostype function. */ -/* #undef HAVE_SETOSTYPE */ - -/* Define if you have the setregid function. */ -/* #undef HAVE_SETREGID */ -#define HAVE_DECL_SETREGID 1 - -/* Define if you have the setregid function. */ -#define HAVE_SETRESGID 1 -/* #undef HAVE_DECL_SETRESGID */ - -/* Define if you have the setresuid function. */ -#define HAVE_SETRESUID 1 -/* #undef HAVE_DECL_SETRESUID */ - -/* Define if you have the setvbuf function. */ -#define HAVE_SETVBUF 1 - -/* Define if you have the siginterrupt function. */ -#define HAVE_SIGINTERRUPT 1 - -/* Define if you have the POSIX.1-style sigsetjmp function. */ -#define HAVE_POSIX_SIGSETJMP 1 - -/* Define if you have the snprintf function. */ -#define HAVE_SNPRINTF 1 - -/* Define if you have the strcasecmp function. */ -#define HAVE_STRCASECMP 1 - -/* Define if you have the strcasestr function. */ -#define HAVE_STRCASESTR 1 - -/* Define if you have the strchr function. */ -#define HAVE_STRCHR 1 - -/* Define if you have the strchrnul function. */ -#define HAVE_STRCHRNUL 1 - -/* Define if you have the strcoll function. */ -#define HAVE_STRCOLL 1 - -/* Define if you have the strerror function. */ -#define HAVE_STRERROR 1 - -/* Define if you have the strftime function. */ -#define HAVE_STRFTIME 1 - -/* Define if you have the strnlen function. */ -#define HAVE_STRNLEN 1 - -/* Define if you have the strpbrk function. */ -#define HAVE_STRPBRK 1 - -/* Define if you have the strstr function. */ -#define HAVE_STRSTR 1 - -/* Define if you have the strtod function. */ -#define HAVE_STRTOD 1 - -/* Define if you have the strtoimax function. */ -#define HAVE_STRTOIMAX 1 - -/* Define if you have the strtol function. */ -#define HAVE_STRTOL 1 - -/* Define if you have the strtoll function. */ -#define HAVE_STRTOLL 1 - -/* Define if you have the strtoul function. */ -#define HAVE_STRTOUL 1 - -/* Define if you have the strtoull function. */ -#define HAVE_STRTOULL 1 - -/* Define if you have the strtoumax function. */ -#define HAVE_STRTOUMAX 1 - -/* Define if you have the strsignal function or macro. */ -#define HAVE_STRSIGNAL 1 - -/* Define if you have the sysconf function. */ -#define HAVE_SYSCONF 1 - -/* Define if you have the syslog function. */ -#define HAVE_SYSLOG 1 - -/* Define if you have the tcgetattr function. */ -#define HAVE_TCGETATTR 1 - -/* Define if you have the tcgetpgrp function. */ -#define HAVE_TCGETPGRP 1 - -/* Define if you have the times function. */ -#define HAVE_TIMES 1 - -/* Define if you have the towlower function. */ -#define HAVE_TOWLOWER 1 - -/* Define if you have the towupper function. */ -#define HAVE_TOWUPPER 1 - -/* Define if you have the ttyname function. */ -#define HAVE_TTYNAME 1 - -/* Define if you have the tzset function. */ -#define HAVE_TZSET 1 - -/* Define if you have the ulimit function. */ -/* #undef HAVE_ULIMIT */ - -/* Define if you have the uname function. */ -#define HAVE_UNAME 1 - -/* Define if you have the unsetenv function. */ -#define HAVE_UNSETENV 1 - -/* Define if you have the vasprintf function. */ -#define HAVE_VASPRINTF 1 - -/* Define if you have the vprintf function. */ -#define HAVE_VPRINTF 1 - -/* Define if you have the vsnprintf function. */ -#define HAVE_VSNPRINTF 1 - -/* Define if you have the waitpid function. */ -#define HAVE_WAITPID 1 - -/* Define if you have the wait3 function. */ -#define HAVE_WAIT3 1 - -/* Define if you have the wcrtomb function. */ -#define HAVE_WCRTOMB 1 - -/* Define if you have the wcscoll function. */ -#define HAVE_WCSCOLL 1 - -/* Define if you have the wcsdup function. */ -#define HAVE_WCSDUP 1 - -/* Define if you have the wctype function. */ -#define HAVE_WCTYPE 1 - -/* Define if you have the wcswidth function. */ -#define HAVE_WCSWIDTH 1 - -/* Define if you have the wcwidth function. */ -#define HAVE_WCWIDTH 1 - -/* and if it works */ -/* #undef WCWIDTH_BROKEN */ - -/* Presence of certain system include files. */ - -/* Define if you have the header file. */ -#define HAVE_ARPA_INET_H 1 - -/* Define if you have the header file. */ -#define HAVE_DIRENT_H 1 - -/* Define if you have the header file. */ -#define HAVE_DLFCN_H 1 - -/* Define if you have the header file. */ -#define HAVE_GRP_H 1 - -/* Define if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define if you have the header file. */ -#define HAVE_LANGINFO_H 1 - -/* Define if you have the header file. */ -/* #undef HAVE_LIBAUDIT_H */ - -/* Define if you have the header file. */ -/* #undef HAVE_LIBINTL_H */ - -/* Define if you have the header file. */ -#define HAVE_LIMITS_H 1 - -/* Define if you have the header file. */ -#define HAVE_LOCALE_H 1 - -/* Define if you have the header file. */ -/* #undef HAVE_MBSTR_H */ - -/* Define if you have the header file. */ -/* #undef HAVE_NDIR_H */ - -/* Define if you have the header file. */ -#define HAVE_NETDB_H 1 - -/* Define if you have the header file. */ -#define HAVE_NETINET_IN_H 1 - -/* Define if you have the header file. */ -#define HAVE_PWD_H 1 - -/* Define if you have the header file. */ -#define HAVE_REGEX_H 1 - -/* Define if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define if you have the header file. */ -#define HAVE_STDARG_H 1 - -/* Define if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define if you have the header file. */ -#define HAVE_STRINGS_H 1 - -/* Define if you have the header file. */ -#define HAVE_MEMORY_H 1 - -/* Define if you have the header file. */ -#define HAVE_STDBOOL_H 1 - -/* Define if you have the header file. */ -#define HAVE_STDDEF_H 1 - -/* Define if you have the header file. */ -#define HAVE_STDINT_H 1 - -/* Define if you have the header file. */ -#define HAVE_SYSLOG_H 1 - -/* Define if you have the header file. */ -/* #undef HAVE_SYS_DIR_H */ - -/* Define if you have the header file. */ -#define HAVE_SYS_FILE_H 1 - -/* Define if you have the header file. */ -#define HAVE_SYS_IOCTL_H 1 - -/* Define if you have the header file. */ -#define HAVE_SYS_MMAN_H 1 - -/* Define if you have the header file. */ -/* #undef HAVE_SYS_NDIR_H */ - -/* Define if you have the header file. */ -#define HAVE_SYS_PARAM_H 1 - -/* Define if you have the header file. */ -/* #undef HAVE_SYS_PTE_H */ - -/* Define if you have the header file. */ -/* #undef HAVE_SYS_PTEM_H */ - -/* Define if you have the header file. */ -#define HAVE_SYS_RANDOM_H 1 - -/* Define if you have the header file. */ -#define HAVE_SYS_RESOURCE_H 1 - -/* Define if you have the header file. */ -#define HAVE_SYS_SELECT_H 1 - -/* Define if you have the header file. */ -#define HAVE_SYS_SOCKET_H 1 - -/* Define if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define if you have the header file. */ -/* #undef HAVE_SYS_STREAM_H */ - -/* Define if you have */ -#define HAVE_SYS_TIME_H 1 - -/* Define if you have */ -#define HAVE_SYS_TIMES_H 1 - -/* Define if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define if you have that is POSIX.1 compatible. */ -#define HAVE_SYS_WAIT_H 1 - -/* Define if you have the header file. */ -/* #undef HAVE_TERMCAP_H */ - -/* Define if you have the header file. */ -/* #undef HAVE_TERMIO_H */ - -/* Define if you have the header file. */ -#define HAVE_TERMIOS_H 1 - -/* Define if you have the header file. */ -/* #undef HAVE_ULIMIT_H */ - -/* Define if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* Define if you have the header file. */ -/* #undef HAVE_VARARGS_H */ - -/* Define if you have the header file. */ -#define HAVE_WCHAR_H 1 - -/* Define if you have the header file. */ -#define HAVE_WCTYPE_H 1 - -/* Presence of certain system libraries. */ - -/* #undef HAVE_LIBDL */ - -/* #undef HAVE_LIBSUN */ - -/* #undef HAVE_LIBSOCKET */ - -/* Are we running the GNU C library, version 2.1 or later? */ -/* #undef GLIBC21 */ - -/* Are we running SVR5 (UnixWare 7)? */ -/* #undef SVR5 */ - -/* Are we running SVR4.2? */ -/* #undef SVR4_2 */ - -/* Are we running some version of SVR4? */ -/* #undef SVR4 */ - -/* Define if job control is unusable or unsupported. */ -/* #undef JOB_CONTROL_MISSING */ - -/* Do we need to define _KERNEL to get the RLIMIT_* defines from - ? */ -/* #undef RLIMIT_NEEDS_KERNEL */ - -/* Number of bits in a file offset, on hosts where this is settable. */ -/* #undef _FILE_OFFSET_BITS */ - -/* Define for large files on AIX-style hosts. */ -/* #undef _LARGE_FILES */ - -/* Do strcoll(3) and strcmp(3) give different results in the default locale? */ -/* #undef STRCOLL_BROKEN */ - -/* #undef DUP2_BROKEN */ - -/* #undef GETCWD_BROKEN */ - -#define DEV_FD_STAT_BROKEN - -/* An array implementation that prioritizes speed (O(1) access) over space, - in array2.c */ -/* #undef ALT_ARRAY_IMPLEMENTATION */ - -/* Support for $"..." translatable strings. */ -#define TRANSLATABLE_STRINGS 1 - -/* Additional defines for configuring lib/intl, maintained by autoscan/autoheader */ - -/* Define if you have the header file. */ -/* #undef HAVE_ARGZ_H */ - -/* Define if you have the header file. */ -#define HAVE_ERRNO_H 1 - -/* Define if you have the header file. */ -#define HAVE_FCNTL_H 1 - -/* Define if you have the header file. */ -#define HAVE_MALLOC_H 1 - -/* Define if you have the header file. */ -#define HAVE_STDIO_EXT_H 1 - -/* Define if you have the `dcgettext' function. */ -/* #undef HAVE_DCGETTEXT */ - -/* Define if you have the `localeconv' function. */ -#define HAVE_LOCALECONV 1 - -/* Define if your system has a working `malloc' function. */ -/* #undef HAVE_MALLOC */ - -/* Define if you have the `mempcpy' function. */ -#define HAVE_MEMPCPY 1 - -/* Define if you have a working `mmap' system call. */ -/* #undef HAVE_MMAP */ - -/* Define if you have the `mremap' function. */ -/* #undef HAVE_MREMAP */ - -/* Define if you have the `munmap' function. */ -#define HAVE_MUNMAP 1 - -/* Define if you have the `nl_langinfo' function. */ -/* #undef HAVE_NL_LANGINFO */ - -/* Define if you have the `stpcpy' function. */ -#define HAVE_STPCPY 1 - -/* Define if you have the `strcspn' function. */ -#define HAVE_STRCSPN 1 - -/* Define if you have the `strdup' function. */ -#define HAVE_STRDUP 1 - -/* Define if you have the `__argz_count' function. */ -/* #undef HAVE___ARGZ_COUNT */ - -/* Define if you have the `__argz_next' function. */ -/* #undef HAVE___ARGZ_NEXT */ - -/* Define if you have the `__argz_stringify' function. */ -/* #undef HAVE___ARGZ_STRINGIFY */ - -/* End additions for lib/intl */ - -#include "config-bot.h" - -#endif /* _CONFIG_H_ */ diff --git a/third_party/bash/conftypes.h b/third_party/bash/conftypes.h deleted file mode 100644 index 1c8c5480a..000000000 --- a/third_party/bash/conftypes.h +++ /dev/null @@ -1,58 +0,0 @@ -/* conftypes.h -- defines for build and host system. */ - -/* Copyright (C) 2001, 2005, 2008,2009 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_CONFTYPES_H_) -#define _CONFTYPES_H_ - -/* Placeholder for future modifications if cross-compiling or building a - `fat' binary, e.g. on Apple Rhapsody. These values are used in multiple - files, so they appear here. */ -#if !defined (RHAPSODY) && !defined (MACOSX) -# define HOSTTYPE CONF_HOSTTYPE -# define OSTYPE CONF_OSTYPE -# define MACHTYPE CONF_MACHTYPE -#else /* RHAPSODY */ -# if defined(__powerpc__) || defined(__ppc__) -# define HOSTTYPE "powerpc" -# elif defined(__i386__) -# define HOSTTYPE "i386" -# else -# define HOSTTYPE CONF_HOSTTYPE -# endif - -# define OSTYPE CONF_OSTYPE -# define VENDOR CONF_VENDOR - -# define MACHTYPE HOSTTYPE "-" VENDOR "-" OSTYPE -#endif /* RHAPSODY */ - -#ifndef HOSTTYPE -# define HOSTTYPE "unknown" -#endif - -#ifndef OSTYPE -# define OSTYPE "unknown" -#endif - -#ifndef MACHTYPE -# define MACHTYPE "unknown" -#endif - -#endif /* _CONFTYPES_H_ */ diff --git a/third_party/bash/copy_cmd.c b/third_party/bash/copy_cmd.c deleted file mode 100644 index 758ff238a..000000000 --- a/third_party/bash/copy_cmd.c +++ /dev/null @@ -1,459 +0,0 @@ -/* copy_command.c -- copy a COMMAND structure. This is needed - primarily for making function definitions, but I'm not sure - that anyone else will need it. */ - -/* Copyright (C) 1987-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include "bashtypes.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include - -#include "shell.h" - -static PATTERN_LIST *copy_case_clause PARAMS((PATTERN_LIST *)); -static PATTERN_LIST *copy_case_clauses PARAMS((PATTERN_LIST *)); -static FOR_COM *copy_for_command PARAMS((FOR_COM *)); -#if defined (ARITH_FOR_COMMAND) -static ARITH_FOR_COM *copy_arith_for_command PARAMS((ARITH_FOR_COM *)); -#endif -static GROUP_COM *copy_group_command PARAMS((GROUP_COM *)); -static SUBSHELL_COM *copy_subshell_command PARAMS((SUBSHELL_COM *)); -static COPROC_COM *copy_coproc_command PARAMS((COPROC_COM *)); -static CASE_COM *copy_case_command PARAMS((CASE_COM *)); -static WHILE_COM *copy_while_command PARAMS((WHILE_COM *)); -static IF_COM *copy_if_command PARAMS((IF_COM *)); -#if defined (DPAREN_ARITHMETIC) -static ARITH_COM *copy_arith_command PARAMS((ARITH_COM *)); -#endif -#if defined (COND_COMMAND) -static COND_COM *copy_cond_command PARAMS((COND_COM *)); -#endif -static SIMPLE_COM *copy_simple_command PARAMS((SIMPLE_COM *)); - -WORD_DESC * -copy_word (w) - WORD_DESC *w; -{ - WORD_DESC *new_word; - - new_word = make_bare_word (w->word); - new_word->flags = w->flags; - return (new_word); -} - -/* Copy the chain of words in LIST. Return a pointer to - the new chain. */ -WORD_LIST * -copy_word_list (list) - WORD_LIST *list; -{ - WORD_LIST *new_list, *tl; - - for (new_list = tl = (WORD_LIST *)NULL; list; list = list->next) - { - if (new_list == 0) - new_list = tl = make_word_list (copy_word (list->word), new_list); - else - { - tl->next = make_word_list (copy_word (list->word), (WORD_LIST *)NULL); - tl = tl->next; - } - } - - return (new_list); -} - -static PATTERN_LIST * -copy_case_clause (clause) - PATTERN_LIST *clause; -{ - PATTERN_LIST *new_clause; - - new_clause = (PATTERN_LIST *)xmalloc (sizeof (PATTERN_LIST)); - new_clause->patterns = copy_word_list (clause->patterns); - new_clause->action = copy_command (clause->action); - new_clause->flags = clause->flags; - return (new_clause); -} - -static PATTERN_LIST * -copy_case_clauses (clauses) - PATTERN_LIST *clauses; -{ - PATTERN_LIST *new_list, *new_clause; - - for (new_list = (PATTERN_LIST *)NULL; clauses; clauses = clauses->next) - { - new_clause = copy_case_clause (clauses); - new_clause->next = new_list; - new_list = new_clause; - } - return (REVERSE_LIST (new_list, PATTERN_LIST *)); -} - -/* Copy a single redirect. */ -REDIRECT * -copy_redirect (redirect) - REDIRECT *redirect; -{ - REDIRECT *new_redirect; - - new_redirect = (REDIRECT *)xmalloc (sizeof (REDIRECT)); -#if 0 - FASTCOPY ((char *)redirect, (char *)new_redirect, (sizeof (REDIRECT))); -#else - *new_redirect = *redirect; /* let the compiler do the fast structure copy */ -#endif - - if (redirect->rflags & REDIR_VARASSIGN) - new_redirect->redirector.filename = copy_word (redirect->redirector.filename); - - switch (redirect->instruction) - { - case r_reading_until: - case r_deblank_reading_until: - new_redirect->here_doc_eof = redirect->here_doc_eof ? savestring (redirect->here_doc_eof) : 0; - /*FALLTHROUGH*/ - case r_reading_string: - case r_appending_to: - case r_output_direction: - case r_input_direction: - case r_inputa_direction: - case r_err_and_out: - case r_append_err_and_out: - case r_input_output: - case r_output_force: - case r_duplicating_input_word: - case r_duplicating_output_word: - case r_move_input_word: - case r_move_output_word: - new_redirect->redirectee.filename = copy_word (redirect->redirectee.filename); - break; - case r_duplicating_input: - case r_duplicating_output: - case r_move_input: - case r_move_output: - case r_close_this: - break; - } - return (new_redirect); -} - -REDIRECT * -copy_redirects (list) - REDIRECT *list; -{ - REDIRECT *new_list, *temp; - - for (new_list = (REDIRECT *)NULL; list; list = list->next) - { - temp = copy_redirect (list); - temp->next = new_list; - new_list = temp; - } - return (REVERSE_LIST (new_list, REDIRECT *)); -} - -static FOR_COM * -copy_for_command (com) - FOR_COM *com; -{ - FOR_COM *new_for; - - new_for = (FOR_COM *)xmalloc (sizeof (FOR_COM)); - new_for->flags = com->flags; - new_for->line = com->line; - new_for->name = copy_word (com->name); - new_for->map_list = copy_word_list (com->map_list); - new_for->action = copy_command (com->action); - return (new_for); -} - -#if defined (ARITH_FOR_COMMAND) -static ARITH_FOR_COM * -copy_arith_for_command (com) - ARITH_FOR_COM *com; -{ - ARITH_FOR_COM *new_arith_for; - - new_arith_for = (ARITH_FOR_COM *)xmalloc (sizeof (ARITH_FOR_COM)); - new_arith_for->flags = com->flags; - new_arith_for->line = com->line; - new_arith_for->init = copy_word_list (com->init); - new_arith_for->test = copy_word_list (com->test); - new_arith_for->step = copy_word_list (com->step); - new_arith_for->action = copy_command (com->action); - return (new_arith_for); -} -#endif /* ARITH_FOR_COMMAND */ - -static GROUP_COM * -copy_group_command (com) - GROUP_COM *com; -{ - GROUP_COM *new_group; - - new_group = (GROUP_COM *)xmalloc (sizeof (GROUP_COM)); - new_group->command = copy_command (com->command); - return (new_group); -} - -static SUBSHELL_COM * -copy_subshell_command (com) - SUBSHELL_COM *com; -{ - SUBSHELL_COM *new_subshell; - - new_subshell = (SUBSHELL_COM *)xmalloc (sizeof (SUBSHELL_COM)); - new_subshell->command = copy_command (com->command); - new_subshell->flags = com->flags; - new_subshell->line = com->line; - return (new_subshell); -} - -static COPROC_COM * -copy_coproc_command (com) - COPROC_COM *com; -{ - COPROC_COM *new_coproc; - - new_coproc = (COPROC_COM *)xmalloc (sizeof (COPROC_COM)); - new_coproc->name = savestring (com->name); - new_coproc->command = copy_command (com->command); - new_coproc->flags = com->flags; - return (new_coproc); -} - -static CASE_COM * -copy_case_command (com) - CASE_COM *com; -{ - CASE_COM *new_case; - - new_case = (CASE_COM *)xmalloc (sizeof (CASE_COM)); - new_case->flags = com->flags; - new_case->line = com->line; - new_case->word = copy_word (com->word); - new_case->clauses = copy_case_clauses (com->clauses); - return (new_case); -} - -static WHILE_COM * -copy_while_command (com) - WHILE_COM *com; -{ - WHILE_COM *new_while; - - new_while = (WHILE_COM *)xmalloc (sizeof (WHILE_COM)); - new_while->flags = com->flags; - new_while->test = copy_command (com->test); - new_while->action = copy_command (com->action); - return (new_while); -} - -static IF_COM * -copy_if_command (com) - IF_COM *com; -{ - IF_COM *new_if; - - new_if = (IF_COM *)xmalloc (sizeof (IF_COM)); - new_if->flags = com->flags; - new_if->test = copy_command (com->test); - new_if->true_case = copy_command (com->true_case); - new_if->false_case = com->false_case ? copy_command (com->false_case) : com->false_case; - return (new_if); -} - -#if defined (DPAREN_ARITHMETIC) -static ARITH_COM * -copy_arith_command (com) - ARITH_COM *com; -{ - ARITH_COM *new_arith; - - new_arith = (ARITH_COM *)xmalloc (sizeof (ARITH_COM)); - new_arith->flags = com->flags; - new_arith->exp = copy_word_list (com->exp); - new_arith->line = com->line; - - return (new_arith); -} -#endif - -#if defined (COND_COMMAND) -static COND_COM * -copy_cond_command (com) - COND_COM *com; -{ - COND_COM *new_cond; - - new_cond = (COND_COM *)xmalloc (sizeof (COND_COM)); - new_cond->flags = com->flags; - new_cond->line = com->line; - new_cond->type = com->type; - new_cond->op = com->op ? copy_word (com->op) : com->op; - new_cond->left = com->left ? copy_cond_command (com->left) : (COND_COM *)NULL; - new_cond->right = com->right ? copy_cond_command (com->right) : (COND_COM *)NULL; - - return (new_cond); -} -#endif - -static SIMPLE_COM * -copy_simple_command (com) - SIMPLE_COM *com; -{ - SIMPLE_COM *new_simple; - - new_simple = (SIMPLE_COM *)xmalloc (sizeof (SIMPLE_COM)); - new_simple->flags = com->flags; - new_simple->words = copy_word_list (com->words); - new_simple->redirects = com->redirects ? copy_redirects (com->redirects) : (REDIRECT *)NULL; - new_simple->line = com->line; - return (new_simple); -} - -FUNCTION_DEF * -copy_function_def_contents (old, new_def) - FUNCTION_DEF *old, *new_def; -{ - new_def->name = copy_word (old->name); - new_def->command = old->command ? copy_command (old->command) : old->command; - new_def->flags = old->flags; - new_def->line = old->line; - new_def->source_file = old->source_file ? savestring (old->source_file) : old->source_file; - return (new_def); -} - -FUNCTION_DEF * -copy_function_def (com) - FUNCTION_DEF *com; -{ - FUNCTION_DEF *new_def; - - new_def = (FUNCTION_DEF *)xmalloc (sizeof (FUNCTION_DEF)); - new_def = copy_function_def_contents (com, new_def); - return (new_def); -} - -/* Copy the command structure in COMMAND. Return a pointer to the - copy. Don't you forget to dispose_command () on this pointer - later! */ -COMMAND * -copy_command (command) - COMMAND *command; -{ - COMMAND *new_command; - - if (command == NULL) - return (command); - - new_command = (COMMAND *)xmalloc (sizeof (COMMAND)); - FASTCOPY ((char *)command, (char *)new_command, sizeof (COMMAND)); - new_command->flags = command->flags; - new_command->line = command->line; - - if (command->redirects) - new_command->redirects = copy_redirects (command->redirects); - - switch (command->type) - { - case cm_for: - new_command->value.For = copy_for_command (command->value.For); - break; - -#if defined (ARITH_FOR_COMMAND) - case cm_arith_for: - new_command->value.ArithFor = copy_arith_for_command (command->value.ArithFor); - break; -#endif - -#if defined (SELECT_COMMAND) - case cm_select: - new_command->value.Select = - (SELECT_COM *)copy_for_command ((FOR_COM *)command->value.Select); - break; -#endif - - case cm_group: - new_command->value.Group = copy_group_command (command->value.Group); - break; - - case cm_subshell: - new_command->value.Subshell = copy_subshell_command (command->value.Subshell); - break; - - case cm_coproc: - new_command->value.Coproc = copy_coproc_command (command->value.Coproc); - break; - - case cm_case: - new_command->value.Case = copy_case_command (command->value.Case); - break; - - case cm_until: - case cm_while: - new_command->value.While = copy_while_command (command->value.While); - break; - - case cm_if: - new_command->value.If = copy_if_command (command->value.If); - break; - -#if defined (DPAREN_ARITHMETIC) - case cm_arith: - new_command->value.Arith = copy_arith_command (command->value.Arith); - break; -#endif - -#if defined (COND_COMMAND) - case cm_cond: - new_command->value.Cond = copy_cond_command (command->value.Cond); - break; -#endif - - case cm_simple: - new_command->value.Simple = copy_simple_command (command->value.Simple); - break; - - case cm_connection: - { - CONNECTION *new_connection; - - new_connection = (CONNECTION *)xmalloc (sizeof (CONNECTION)); - new_connection->connector = command->value.Connection->connector; - new_connection->first = copy_command (command->value.Connection->first); - new_connection->second = copy_command (command->value.Connection->second); - new_command->value.Connection = new_connection; - break; - } - - case cm_function_def: - new_command->value.Function_def = copy_function_def (command->value.Function_def); - break; - } - return (new_command); -} diff --git a/third_party/bash/dispose_cmd.c b/third_party/bash/dispose_cmd.c deleted file mode 100644 index c624605b5..000000000 --- a/third_party/bash/dispose_cmd.c +++ /dev/null @@ -1,342 +0,0 @@ -/* dispose_command.c -- dispose of a COMMAND structure. */ - -/* Copyright (C) 1987-2009 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include "bashtypes.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "bashansi.h" -#include "shell.h" - -extern sh_obj_cache_t wdcache, wlcache; - -/* Dispose of the command structure passed. */ -void -dispose_command (command) - COMMAND *command; -{ - if (command == 0) - return; - - if (command->redirects) - dispose_redirects (command->redirects); - - switch (command->type) - { - case cm_for: -#if defined (SELECT_COMMAND) - case cm_select: -#endif - { - register FOR_COM *c; -#if defined (SELECT_COMMAND) - if (command->type == cm_select) - c = (FOR_COM *)command->value.Select; - else -#endif - c = command->value.For; - dispose_word (c->name); - dispose_words (c->map_list); - dispose_command (c->action); - free (c); - break; - } - -#if defined (ARITH_FOR_COMMAND) - case cm_arith_for: - { - register ARITH_FOR_COM *c; - - c = command->value.ArithFor; - dispose_words (c->init); - dispose_words (c->test); - dispose_words (c->step); - dispose_command (c->action); - free (c); - break; - } -#endif /* ARITH_FOR_COMMAND */ - - case cm_group: - { - dispose_command (command->value.Group->command); - free (command->value.Group); - break; - } - - case cm_subshell: - { - dispose_command (command->value.Subshell->command); - free (command->value.Subshell); - break; - } - - case cm_coproc: - { - free (command->value.Coproc->name); - dispose_command (command->value.Coproc->command); - free (command->value.Coproc); - break; - } - - case cm_case: - { - register CASE_COM *c; - PATTERN_LIST *t, *p; - - c = command->value.Case; - dispose_word (c->word); - - for (p = c->clauses; p; ) - { - dispose_words (p->patterns); - dispose_command (p->action); - t = p; - p = p->next; - free (t); - } - free (c); - break; - } - - case cm_until: - case cm_while: - { - register WHILE_COM *c; - - c = command->value.While; - dispose_command (c->test); - dispose_command (c->action); - free (c); - break; - } - - case cm_if: - { - register IF_COM *c; - - c = command->value.If; - dispose_command (c->test); - dispose_command (c->true_case); - dispose_command (c->false_case); - free (c); - break; - } - - case cm_simple: - { - register SIMPLE_COM *c; - - c = command->value.Simple; - dispose_words (c->words); - dispose_redirects (c->redirects); - free (c); - break; - } - - case cm_connection: - { - register CONNECTION *c; - - c = command->value.Connection; - dispose_command (c->first); - dispose_command (c->second); - free (c); - break; - } - -#if defined (DPAREN_ARITHMETIC) - case cm_arith: - { - register ARITH_COM *c; - - c = command->value.Arith; - dispose_words (c->exp); - free (c); - break; - } -#endif /* DPAREN_ARITHMETIC */ - -#if defined (COND_COMMAND) - case cm_cond: - { - register COND_COM *c; - - c = command->value.Cond; - dispose_cond_node (c); - break; - } -#endif /* COND_COMMAND */ - - case cm_function_def: - { - register FUNCTION_DEF *c; - - c = command->value.Function_def; - dispose_function_def (c); - break; - } - - default: - command_error ("dispose_command", CMDERR_BADTYPE, command->type, 0); - break; - } - free (command); -} - -#if defined (COND_COMMAND) -/* How to free a node in a conditional command. */ -void -dispose_cond_node (cond) - COND_COM *cond; -{ - if (cond) - { - if (cond->left) - dispose_cond_node (cond->left); - if (cond->right) - dispose_cond_node (cond->right); - if (cond->op) - dispose_word (cond->op); - free (cond); - } -} -#endif /* COND_COMMAND */ - -void -dispose_function_def_contents (c) - FUNCTION_DEF *c; -{ - dispose_word (c->name); - dispose_command (c->command); - FREE (c->source_file); -} - -void -dispose_function_def (c) - FUNCTION_DEF *c; -{ - dispose_function_def_contents (c); - free (c); -} - -/* How to free a WORD_DESC. */ -void -dispose_word (w) - WORD_DESC *w; -{ - FREE (w->word); - ocache_free (wdcache, WORD_DESC, w); -} - -/* Free a WORD_DESC, but not the word contained within. */ -void -dispose_word_desc (w) - WORD_DESC *w; -{ - w->word = 0; - ocache_free (wdcache, WORD_DESC, w); -} - -/* How to get rid of a linked list of words. A WORD_LIST. */ -void -dispose_words (list) - WORD_LIST *list; -{ - WORD_LIST *t; - - while (list) - { - t = list; - list = list->next; - dispose_word (t->word); -#if 0 - free (t); -#else - ocache_free (wlcache, WORD_LIST, t); -#endif - } -} - -#ifdef INCLUDE_UNUSED -/* How to dispose of an array of pointers to char. This is identical to - free_array in stringlib.c. */ -void -dispose_word_array (array) - char **array; -{ - register int count; - - if (array == 0) - return; - - for (count = 0; array[count]; count++) - free (array[count]); - - free (array); -} -#endif - -/* How to dispose of an list of redirections. A REDIRECT. */ -void -dispose_redirects (list) - REDIRECT *list; -{ - register REDIRECT *t; - - while (list) - { - t = list; - list = list->next; - - if (t->rflags & REDIR_VARASSIGN) - dispose_word (t->redirector.filename); - - switch (t->instruction) - { - case r_reading_until: - case r_deblank_reading_until: - free (t->here_doc_eof); - /*FALLTHROUGH*/ - case r_reading_string: - case r_output_direction: - case r_input_direction: - case r_inputa_direction: - case r_appending_to: - case r_err_and_out: - case r_append_err_and_out: - case r_input_output: - case r_output_force: - case r_duplicating_input_word: - case r_duplicating_output_word: - case r_move_input_word: - case r_move_output_word: - dispose_word (t->redirectee.filename); - /* FALLTHROUGH */ - default: - break; - } - free (t); - } -} diff --git a/third_party/bash/dispose_cmd.h b/third_party/bash/dispose_cmd.h deleted file mode 100644 index 6095d44a4..000000000 --- a/third_party/bash/dispose_cmd.h +++ /dev/null @@ -1,40 +0,0 @@ -/* dispose_cmd.h -- Functions appearing in dispose_cmd.c. */ - -/* Copyright (C) 1993-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_DISPOSE_CMD_H_) -#define _DISPOSE_CMD_H_ - -#include "stdc.h" - -extern void dispose_command PARAMS((COMMAND *)); -extern void dispose_word_desc PARAMS((WORD_DESC *)); -extern void dispose_word PARAMS((WORD_DESC *)); -extern void dispose_words PARAMS((WORD_LIST *)); -extern void dispose_word_array PARAMS((char **)); -extern void dispose_redirects PARAMS((REDIRECT *)); - -#if defined (COND_COMMAND) -extern void dispose_cond_node PARAMS((COND_COM *)); -#endif - -extern void dispose_function_def_contents PARAMS((FUNCTION_DEF *)); -extern void dispose_function_def PARAMS((FUNCTION_DEF *)); - -#endif /* !_DISPOSE_CMD_H_ */ diff --git a/third_party/bash/eaccess.c b/third_party/bash/eaccess.c deleted file mode 100644 index 25a114cb2..000000000 --- a/third_party/bash/eaccess.c +++ /dev/null @@ -1,248 +0,0 @@ -#include "libc/dce.h" -/* eaccess.c - eaccess replacement for the shell, plus other access functions. */ - -/* Copyright (C) 2006-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if defined (HAVE_CONFIG_H) -# include "config.h" -#endif - -#include - -#include "bashtypes.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "bashansi.h" - -#include -#if !defined (errno) -extern int errno; -#endif /* !errno */ - -#if !defined (_POSIX_VERSION) && defined (HAVE_SYS_FILE_H) -# include -#endif /* !_POSIX_VERSION */ -#include "posixstat.h" -#include "filecntl.h" - -#include "shell.h" - -#if !defined (R_OK) -#define R_OK 4 -#define W_OK 2 -#define X_OK 1 -#define F_OK 0 -#endif /* R_OK */ - -static int path_is_devfd PARAMS((const char *)); -static int sh_stataccess PARAMS((const char *, int)); -#if HAVE_DECL_SETREGID -static int sh_euidaccess PARAMS((const char *, int)); -#endif - -static int -path_is_devfd (path) - const char *path; -{ - if (path[0] == '/' && path[1] == 'd' && strncmp (path, "/dev/fd/", 8) == 0) - return 1; - else if (STREQN (path, "/dev/std", 8)) - { - if (STREQ (path+8, "in") || STREQ (path+8, "out") || STREQ (path+8, "err")) - return 1; - else - return 0; - } - else - return 0; -} - -/* A wrapper for stat () which disallows pathnames that are empty strings - and handles /dev/fd emulation on systems that don't have it. */ -int -sh_stat (path, finfo) - const char *path; - struct stat *finfo; -{ - static char *pbuf = 0; - - if (*path == '\0') - { - errno = ENOENT; - return (-1); - } - if (path[0] == '/' && path[1] == 'd' && strncmp (path, "/dev/fd/", 8) == 0) - { - /* If stating /dev/fd/n doesn't produce the same results as fstat of - FD N, then define DEV_FD_STAT_BROKEN */ -//#if !defined (HAVE_DEV_FD) || defined (DEV_FD_STAT_BROKEN) -if (IsBsd()) {//[jart] - intmax_t fd; - int r; - - if (legal_number (path + 8, &fd) && fd == (int)fd) - { - r = fstat ((int)fd, finfo); - if (r == 0 || errno != EBADF) - return (r); - } - errno = ENOENT; - return (-1); -//#else -} else {//[jart] - /* If HAVE_DEV_FD is defined, DEV_FD_PREFIX is defined also, and has a - trailing slash. Make sure /dev/fd/xx really uses DEV_FD_PREFIX/xx. - On most systems, with the notable exception of linux, this is - effectively a no-op. */ - pbuf = xrealloc (pbuf, sizeof (DEV_FD_PREFIX) + strlen (path + 8)); - strcpy (pbuf, DEV_FD_PREFIX); - strcat (pbuf, path + 8); - return (stat (pbuf, finfo)); -//#endif /* !HAVE_DEV_FD */ -}//[jart] - } -#if !defined (HAVE_DEV_STDIN) - else if (STREQN (path, "/dev/std", 8)) - { - if (STREQ (path+8, "in")) - return (fstat (0, finfo)); - else if (STREQ (path+8, "out")) - return (fstat (1, finfo)); - else if (STREQ (path+8, "err")) - return (fstat (2, finfo)); - else - return (stat (path, finfo)); - } -#endif /* !HAVE_DEV_STDIN */ - return (stat (path, finfo)); -} - -/* Do the same thing access(2) does, but use the effective uid and gid, - and don't make the mistake of telling root that any file is - executable. This version uses stat(2). */ -static int -sh_stataccess (path, mode) - const char *path; - int mode; -{ - struct stat st; - - if (sh_stat (path, &st) < 0) - return (-1); - - if (current_user.euid == 0) - { - /* Root can read or write any file. */ - if ((mode & X_OK) == 0) - return (0); - - /* Root can execute any file that has any one of the execute - bits set. */ - if (st.st_mode & S_IXUGO) - return (0); - } - - if (st.st_uid == current_user.euid) /* owner */ - mode <<= 6; - else if (group_member (st.st_gid)) - mode <<= 3; - - if (st.st_mode & mode) - return (0); - - errno = EACCES; - return (-1); -} - -#if HAVE_DECL_SETREGID -/* Version to call when uid != euid or gid != egid. We temporarily swap - the effective and real uid and gid as appropriate. */ -static int -sh_euidaccess (path, mode) - const char *path; - int mode; -{ - int r, e; - - if (current_user.uid != current_user.euid) - setreuid (current_user.euid, current_user.uid); - if (current_user.gid != current_user.egid) - setregid (current_user.egid, current_user.gid); - - r = access (path, mode); - e = errno; - - if (current_user.uid != current_user.euid) - setreuid (current_user.uid, current_user.euid); - if (current_user.gid != current_user.egid) - setregid (current_user.gid, current_user.egid); - - errno = e; - return r; -} -#endif - -int -sh_eaccess (path, mode) - const char *path; - int mode; -{ - int ret; - - if (path_is_devfd (path)) - return (sh_stataccess (path, mode)); - -#if (defined (HAVE_FACCESSAT) && defined (AT_EACCESS)) || defined (HAVE_EACCESS) -# if defined (HAVE_FACCESSAT) && defined (AT_EACCESS) - ret = faccessat (AT_FDCWD, path, mode, AT_EACCESS); -# else /* HAVE_EACCESS */ /* FreeBSD */ - ret = eaccess (path, mode); /* XXX -- not always correct for X_OK */ -# endif /* HAVE_EACCESS */ -# if defined (__FreeBSD__) || defined (SOLARIS) || defined (_AIX) - if (ret == 0 && current_user.euid == 0 && mode == X_OK) - return (sh_stataccess (path, mode)); -# endif /* __FreeBSD__ || SOLARIS || _AIX */ - return ret; -#elif defined (EFF_ONLY_OK) /* SVR4(?), SVR4.2 */ - return access (path, mode|EFF_ONLY_OK); -#else - if (mode == F_OK) - return (sh_stataccess (path, mode)); - -# if HAVE_DECL_SETREGID - if (current_user.uid != current_user.euid || current_user.gid != current_user.egid) - return (sh_euidaccess (path, mode)); -# endif - - if (current_user.uid == current_user.euid && current_user.gid == current_user.egid) - { - ret = access (path, mode); -#if defined (__FreeBSD__) || defined (SOLARIS) - if (ret == 0 && current_user.euid == 0 && mode == X_OK) - return (sh_stataccess (path, mode)); -#endif - return ret; - } - - return (sh_stataccess (path, mode)); -#endif -} diff --git a/third_party/bash/error.c b/third_party/bash/error.c deleted file mode 100644 index 3e7a2d617..000000000 --- a/third_party/bash/error.c +++ /dev/null @@ -1,537 +0,0 @@ -/* error.c -- Functions for handling errors. */ - -/* Copyright (C) 1993-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include "bashtypes.h" -#include - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#if defined (PREFER_STDARG) -# include -#else -# include -#endif - -#include - -#include -#if !defined (errno) -extern int errno; -#endif /* !errno */ - -#include "bashansi.h" -#include "bashintl.h" - -#include "shell.h" -#include "execute_cmd.h" -#include "flags.h" -#include "input.h" - -#if defined (HISTORY) -# include "bashhist.h" -#endif - -extern int executing_line_number PARAMS((void)); - -#if defined (JOB_CONTROL) -extern pid_t shell_pgrp; -extern int give_terminal_to PARAMS((pid_t, int)); -#endif /* JOB_CONTROL */ - -#if defined (ARRAY_VARS) -extern const char * const bash_badsub_errmsg; -#endif - -static void error_prolog PARAMS((int)); - -/* The current maintainer of the shell. You change this in the - Makefile. */ -#if !defined (MAINTAINER) -#define MAINTAINER "bash-maintainers@gnu.org" -#endif - -const char * const the_current_maintainer = MAINTAINER; - -int gnu_error_format = 0; - -static void -error_prolog (print_lineno) - int print_lineno; -{ - char *ename; - int line; - - ename = get_name_for_error (); - line = (print_lineno && interactive_shell == 0) ? executing_line_number () : -1; - - if (line > 0) - fprintf (stderr, "%s:%s%d: ", ename, gnu_error_format ? "" : _(" line "), line); - else - fprintf (stderr, "%s: ", ename); -} - -/* Return the name of the shell or the shell script for error reporting. */ -char * -get_name_for_error () -{ - char *name; -#if defined (ARRAY_VARS) - SHELL_VAR *bash_source_v; - ARRAY *bash_source_a; -#endif - - name = (char *)NULL; - if (interactive_shell == 0) - { -#if defined (ARRAY_VARS) - bash_source_v = find_variable ("BASH_SOURCE"); - if (bash_source_v && array_p (bash_source_v) && - (bash_source_a = array_cell (bash_source_v))) - name = array_reference (bash_source_a, 0); - if (name == 0 || *name == '\0') /* XXX - was just name == 0 */ -#endif - name = dollar_vars[0]; - } - if (name == 0 && shell_name && *shell_name) - name = base_pathname (shell_name); - if (name == 0) -#if defined (PROGRAM) - name = PROGRAM; -#else - name = "bash"; -#endif - - return (name); -} - -/* Report an error having to do with FILENAME. This does not use - sys_error so the filename is not interpreted as a printf-style - format string. */ -void -file_error (filename) - const char *filename; -{ - report_error ("%s: %s", filename, strerror (errno)); -} - -void -#if defined (PREFER_STDARG) -programming_error (const char *format, ...) -#else -programming_error (format, va_alist) - const char *format; - va_dcl -#endif -{ - va_list args; - char *h; - -#if defined (JOB_CONTROL) - give_terminal_to (shell_pgrp, 0); -#endif /* JOB_CONTROL */ - - SH_VA_START (args, format); - - vfprintf (stderr, format, args); - fprintf (stderr, "\n"); - va_end (args); - -#if defined (HISTORY) - if (remember_on_history) - { - h = last_history_line (); - fprintf (stderr, _("last command: %s\n"), h ? h : "(null)"); - } -#endif - -#if 0 - fprintf (stderr, "Report this to %s\n", the_current_maintainer); -#endif - - fprintf (stderr, _("Aborting...")); - fflush (stderr); - - abort (); -} - -/* Print an error message and, if `set -e' has been executed, exit the - shell. Used in this file by file_error and programming_error. Used - outside this file mostly to report substitution and expansion errors, - and for bad invocation options. */ -void -#if defined (PREFER_STDARG) -report_error (const char *format, ...) -#else -report_error (format, va_alist) - const char *format; - va_dcl -#endif -{ - va_list args; - - error_prolog (1); - - SH_VA_START (args, format); - - vfprintf (stderr, format, args); - fprintf (stderr, "\n"); - - va_end (args); - if (exit_immediately_on_error) - { - if (last_command_exit_value == 0) - last_command_exit_value = EXECUTION_FAILURE; - exit_shell (last_command_exit_value); - } -} - -void -#if defined (PREFER_STDARG) -fatal_error (const char *format, ...) -#else -fatal_error (format, va_alist) - const char *format; - va_dcl -#endif -{ - va_list args; - - error_prolog (0); - - SH_VA_START (args, format); - - vfprintf (stderr, format, args); - fprintf (stderr, "\n"); - - va_end (args); - sh_exit (2); -} - -void -#if defined (PREFER_STDARG) -internal_error (const char *format, ...) -#else -internal_error (format, va_alist) - const char *format; - va_dcl -#endif -{ - va_list args; - - error_prolog (1); - - SH_VA_START (args, format); - - vfprintf (stderr, format, args); - fprintf (stderr, "\n"); - - va_end (args); -} - -void -#if defined (PREFER_STDARG) -internal_warning (const char *format, ...) -#else -internal_warning (format, va_alist) - const char *format; - va_dcl -#endif -{ - va_list args; - - error_prolog (1); - fprintf (stderr, _("warning: ")); - - SH_VA_START (args, format); - - vfprintf (stderr, format, args); - fprintf (stderr, "\n"); - - va_end (args); -} - -void -#if defined (PREFER_STDARG) -internal_inform (const char *format, ...) -#else -internal_inform (format, va_alist) - const char *format; - va_dcl -#endif -{ - va_list args; - - error_prolog (1); - /* TRANSLATORS: this is a prefix for informational messages. */ - fprintf (stderr, _("INFORM: ")); - - SH_VA_START (args, format); - - vfprintf (stderr, format, args); - fprintf (stderr, "\n"); - - va_end (args); -} - -void -#if defined (PREFER_STDARG) -internal_debug (const char *format, ...) -#else -internal_debug (format, va_alist) - const char *format; - va_dcl -#endif -{ -#ifdef DEBUG - va_list args; - - error_prolog (1); - fprintf (stderr, _("DEBUG warning: ")); - - SH_VA_START (args, format); - - vfprintf (stderr, format, args); - fprintf (stderr, "\n"); - - va_end (args); -#else - return; -#endif -} - -void -#if defined (PREFER_STDARG) -sys_error (const char *format, ...) -#else -sys_error (format, va_alist) - const char *format; - va_dcl -#endif -{ - int e; - va_list args; - - e = errno; - error_prolog (0); - - SH_VA_START (args, format); - - vfprintf (stderr, format, args); - fprintf (stderr, ": %s\n", strerror (e)); - - va_end (args); -} - -/* An error from the parser takes the general form - - shell_name: input file name: line number: message - - The input file name and line number are omitted if the shell is - currently interactive. If the shell is not currently interactive, - the input file name is inserted only if it is different from the - shell name. */ -void -#if defined (PREFER_STDARG) -parser_error (int lineno, const char *format, ...) -#else -parser_error (lineno, format, va_alist) - int lineno; - const char *format; - va_dcl -#endif -{ - va_list args; - char *ename, *iname; - - ename = get_name_for_error (); - iname = yy_input_name (); - - if (interactive) - fprintf (stderr, "%s: ", ename); - else if (interactive_shell) - fprintf (stderr, "%s: %s:%s%d: ", ename, iname, gnu_error_format ? "" : _(" line "), lineno); - else if (STREQ (ename, iname)) - fprintf (stderr, "%s:%s%d: ", ename, gnu_error_format ? "" : _(" line "), lineno); - else - fprintf (stderr, "%s: %s:%s%d: ", ename, iname, gnu_error_format ? "" : _(" line "), lineno); - - SH_VA_START (args, format); - - vfprintf (stderr, format, args); - fprintf (stderr, "\n"); - - va_end (args); - - if (exit_immediately_on_error) - exit_shell (last_command_exit_value = 2); -} - -#ifdef DEBUG -/* This assumes ASCII and is suitable only for debugging */ -char * -strescape (str) - const char *str; -{ - char *r, *result; - unsigned char *s; - - r = result = (char *)xmalloc (strlen (str) * 2 + 1); - - for (s = (unsigned char *)str; s && *s; s++) - { - if (*s < ' ') - { - *r++ = '^'; - *r++ = *s+64; - } - else if (*s == 127) - { - *r++ = '^'; - *r++ = '?'; - } - else - *r++ = *s; - } - - *r = '\0'; - return result; -} - -void -#if defined (PREFER_STDARG) -itrace (const char *format, ...) -#else -itrace (format, va_alist) - const char *format; - va_dcl -#endif -{ - va_list args; - - fprintf(stderr, "TRACE: pid %ld: ", (long)getpid()); - - SH_VA_START (args, format); - - vfprintf (stderr, format, args); - fprintf (stderr, "\n"); - - va_end (args); - - fflush(stderr); -} - -/* A trace function for silent debugging -- doesn't require a control - terminal. */ -void -#if defined (PREFER_STDARG) -trace (const char *format, ...) -#else -trace (format, va_alist) - const char *format; - va_dcl -#endif -{ - va_list args; - static FILE *tracefp = (FILE *)NULL; - - if (tracefp == NULL) - tracefp = fopen("/tmp/bash-trace.log", "a+"); - - if (tracefp == NULL) - tracefp = stderr; - else - fcntl (fileno (tracefp), F_SETFD, 1); /* close-on-exec */ - - fprintf(tracefp, "TRACE: pid %ld: ", (long)getpid()); - - SH_VA_START (args, format); - - vfprintf (tracefp, format, args); - fprintf (tracefp, "\n"); - - va_end (args); - - fflush(tracefp); -} - -#endif /* DEBUG */ - -/* **************************************************************** */ -/* */ -/* Common error reporting */ -/* */ -/* **************************************************************** */ - - -static const char * const cmd_error_table[] = { - N_("unknown command error"), /* CMDERR_DEFAULT */ - N_("bad command type"), /* CMDERR_BADTYPE */ - N_("bad connector"), /* CMDERR_BADCONN */ - N_("bad jump"), /* CMDERR_BADJUMP */ - 0 -}; - -void -command_error (func, code, e, flags) - const char *func; - int code, e, flags; /* flags currently unused */ -{ - if (code > CMDERR_LAST) - code = CMDERR_DEFAULT; - - programming_error ("%s: %s: %d", func, _(cmd_error_table[code]), e); -} - -char * -command_errstr (code) - int code; -{ - if (code > CMDERR_LAST) - code = CMDERR_DEFAULT; - - return (_(cmd_error_table[code])); -} - -#ifdef ARRAY_VARS -void -err_badarraysub (s) - const char *s; -{ - report_error ("%s: %s", s, _(bash_badsub_errmsg)); -} -#endif - -void -err_unboundvar (s) - const char *s; -{ - report_error (_("%s: unbound variable"), s); -} - -void -err_readonly (s) - const char *s; -{ - report_error (_("%s: readonly variable"), s); -} diff --git a/third_party/bash/error.h b/third_party/bash/error.h deleted file mode 100644 index 785c1deb5..000000000 --- a/third_party/bash/error.h +++ /dev/null @@ -1,82 +0,0 @@ -/* error.h -- External declarations of functions appearing in error.c. */ - -/* Copyright (C) 1993-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_ERROR_H_) -#define _ERROR_H_ - -#include "stdc.h" - -/* Get the name of the shell or shell script for an error message. */ -extern char *get_name_for_error PARAMS((void)); - -/* Report an error having to do with FILENAME. */ -extern void file_error PARAMS((const char *)); - -/* Report a programmer's error, and abort. Pass REASON, and ARG1 ... ARG5. */ -extern void programming_error PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); - -/* General error reporting. Pass FORMAT and ARG1 ... ARG5. */ -extern void report_error PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); - -/* Error messages for parts of the parser that don't call report_syntax_error */ -extern void parser_error PARAMS((int, const char *, ...)) __attribute__((__format__ (printf, 2, 3))); - -/* Report an unrecoverable error and exit. Pass FORMAT and ARG1 ... ARG5. */ -extern void fatal_error PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); - -/* Report a system error, like BSD warn(3). */ -extern void sys_error PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); - -/* Report an internal error. */ -extern void internal_error PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); - -/* Report an internal warning. */ -extern void internal_warning PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); - -/* Report an internal warning for debugging purposes. */ -extern void internal_debug PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); - -/* Report an internal informational notice. */ -extern void internal_inform PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); - -/* Debugging functions, not enabled in released version. */ -extern char *strescape PARAMS((const char *)); -extern void itrace PARAMS((const char *, ...)) __attribute__ ((__format__ (printf, 1, 2))); -extern void trace PARAMS((const char *, ...)) __attribute__ ((__format__ (printf, 1, 2))); - -/* Report an error having to do with command parsing or execution. */ -extern void command_error PARAMS((const char *, int, int, int)); - -extern char *command_errstr PARAMS((int)); - -/* Specific error message functions that eventually call report_error or - internal_error. */ - -extern void err_badarraysub PARAMS((const char *)); -extern void err_unboundvar PARAMS((const char *)); -extern void err_readonly PARAMS((const char *)); - -#ifdef DEBUG -# define INTERNAL_DEBUG(x) internal_debug x -#else -# define INTERNAL_DEBUG(x) -#endif - -#endif /* !_ERROR_H_ */ diff --git a/third_party/bash/eval.c b/third_party/bash/eval.c deleted file mode 100644 index 24c5f04eb..000000000 --- a/third_party/bash/eval.c +++ /dev/null @@ -1,401 +0,0 @@ -/* eval.c -- reading and evaluating commands. */ - -/* Copyright (C) 1996-2022 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include "bashansi.h" -#include - -#include - -#include "bashintl.h" - -#include "shell.h" -#include "parser.h" -#include "flags.h" -#include "trap.h" - -#include "common.h" - -#include "input.h" -#include "execute_cmd.h" - -#if defined (HISTORY) -# include "bashhist.h" -#endif - -static void send_pwd_to_eterm PARAMS((void)); -static sighandler alrm_catcher PARAMS((int)); - -/* Read and execute commands until EOF is reached. This assumes that - the input source has already been initialized. */ -int -reader_loop () -{ - int our_indirection_level; - COMMAND * volatile current_command; - - USE_VAR(current_command); - - current_command = (COMMAND *)NULL; - - our_indirection_level = ++indirection_level; - - if (just_one_command) - reset_readahead_token (); - - while (EOF_Reached == 0) - { - int code; - - code = setjmp_nosigs (top_level); - -#if defined (PROCESS_SUBSTITUTION) - unlink_fifo_list (); -#endif /* PROCESS_SUBSTITUTION */ - - /* XXX - why do we set this every time through the loop? And why do - it if SIGINT is trapped in an interactive shell? */ - if (interactive_shell && signal_is_ignored (SIGINT) == 0 && signal_is_trapped (SIGINT) == 0) - set_signal_handler (SIGINT, sigint_sighandler); - - if (code != NOT_JUMPED) - { - indirection_level = our_indirection_level; - - switch (code) - { - /* Some kind of throw to top_level has occurred. */ - case ERREXIT: - if (exit_immediately_on_error) - reset_local_contexts (); /* not in a function */ - case FORCE_EOF: - case EXITPROG: - case EXITBLTIN: - current_command = (COMMAND *)NULL; - EOF_Reached = EOF; - goto exec_done; - - case DISCARD: - /* Make sure the exit status is reset to a non-zero value, but - leave existing non-zero values (e.g., > 128 on signal) - alone. */ - if (last_command_exit_value == 0) - set_exit_status (EXECUTION_FAILURE); - if (subshell_environment) - { - current_command = (COMMAND *)NULL; - EOF_Reached = EOF; - goto exec_done; - } - /* Obstack free command elements, etc. */ - if (current_command) - { - dispose_command (current_command); - current_command = (COMMAND *)NULL; - } - - restore_sigmask (); - break; - - default: - command_error ("reader_loop", CMDERR_BADJUMP, code, 0); - } - } - - executing = 0; - if (temporary_env) - dispose_used_env_vars (); - -#if (defined (ultrix) && defined (mips)) || defined (C_ALLOCA) - /* Attempt to reclaim memory allocated with alloca (). */ - (void) alloca (0); -#endif - - if (read_command () == 0) - { - if (interactive_shell == 0 && read_but_dont_execute) - { - set_exit_status (last_command_exit_value); - dispose_command (global_command); - global_command = (COMMAND *)NULL; - } - else if (current_command = global_command) - { - global_command = (COMMAND *)NULL; - - /* If the shell is interactive, expand and display $PS0 after reading a - command (possibly a list or pipeline) and before executing it. */ - if (interactive && ps0_prompt) - { - char *ps0_string; - - ps0_string = decode_prompt_string (ps0_prompt); - if (ps0_string && *ps0_string) - { - fprintf (stderr, "%s", ps0_string); - fflush (stderr); - } - free (ps0_string); - } - - current_command_number++; - - executing = 1; - stdin_redir = 0; - - execute_command (current_command); - - exec_done: - QUIT; - - if (current_command) - { - dispose_command (current_command); - current_command = (COMMAND *)NULL; - } - } - } - else - { - /* Parse error, maybe discard rest of stream if not interactive. */ - if (interactive == 0) - EOF_Reached = EOF; - } - if (just_one_command) - EOF_Reached = EOF; - } - indirection_level--; - return (last_command_exit_value); -} - -/* Pretty print shell scripts */ -int -pretty_print_loop () -{ - COMMAND *current_command; - char *command_to_print; - int code; - int global_posix_mode, last_was_newline; - - global_posix_mode = posixly_correct; - last_was_newline = 0; - while (EOF_Reached == 0) - { - code = setjmp_nosigs (top_level); - if (code) - return (EXECUTION_FAILURE); - if (read_command() == 0) - { - current_command = global_command; - global_command = 0; - posixly_correct = 1; /* print posix-conformant */ - if (current_command && (command_to_print = make_command_string (current_command))) - { - printf ("%s\n", command_to_print); /* for now */ - last_was_newline = 0; - } - else if (last_was_newline == 0) - { - printf ("\n"); - last_was_newline = 1; - } - posixly_correct = global_posix_mode; - dispose_command (current_command); - } - else - return (EXECUTION_FAILURE); - } - - return (EXECUTION_SUCCESS); -} - -static sighandler -alrm_catcher(i) - int i; -{ - char *msg; - - msg = _("\007timed out waiting for input: auto-logout\n"); - write (1, msg, strlen (msg)); - - bash_logout (); /* run ~/.bash_logout if this is a login shell */ - jump_to_top_level (EXITPROG); - SIGRETURN (0); -} - -/* Send an escape sequence to emacs term mode to tell it the - current working directory. */ -static void -send_pwd_to_eterm () -{ - char *pwd, *f; - - f = 0; - pwd = get_string_value ("PWD"); - if (pwd == 0) - f = pwd = get_working_directory ("eterm"); - fprintf (stderr, "\032/%s\n", pwd); - free (f); -} - -#if defined (ARRAY_VARS) -/* Caller ensures that A has a non-zero number of elements */ -int -execute_array_command (a, v) - ARRAY *a; - void *v; -{ - char *tag; - char **argv; - int argc, i; - - tag = (char *)v; - argc = 0; - argv = array_to_argv (a, &argc); - for (i = 0; i < argc; i++) - { - if (argv[i] && argv[i][0]) - execute_variable_command (argv[i], tag); - } - strvec_dispose (argv); - return 0; -} -#endif - -static void -execute_prompt_command () -{ - char *command_to_execute; - SHELL_VAR *pcv; -#if defined (ARRAY_VARS) - ARRAY *pcmds; -#endif - - pcv = find_variable ("PROMPT_COMMAND"); - if (pcv == 0 || var_isset (pcv) == 0 || invisible_p (pcv)) - return; -#if defined (ARRAY_VARS) - if (array_p (pcv)) - { - if ((pcmds = array_cell (pcv)) && array_num_elements (pcmds) > 0) - execute_array_command (pcmds, "PROMPT_COMMAND"); - return; - } - else if (assoc_p (pcv)) - return; /* currently don't allow associative arrays here */ -#endif - - command_to_execute = value_cell (pcv); - if (command_to_execute && *command_to_execute) - execute_variable_command (command_to_execute, "PROMPT_COMMAND"); -} - -/* Call the YACC-generated parser and return the status of the parse. - Input is read from the current input stream (bash_input). yyparse - leaves the parsed command in the global variable GLOBAL_COMMAND. - This is where PROMPT_COMMAND is executed. */ -int -parse_command () -{ - int r; - - need_here_doc = 0; - run_pending_traps (); - - /* Allow the execution of a random command just before the printing - of each primary prompt. If the shell variable PROMPT_COMMAND - is set then its value (array or string) is the command(s) to execute. */ - /* The tests are a combination of SHOULD_PROMPT() and prompt_again() - from parse.y, which are the conditions under which the prompt is - actually printed. */ - if (interactive && bash_input.type != st_string && parser_expanding_alias() == 0) - { -#if defined (READLINE) - if (no_line_editing || (bash_input.type == st_stdin && parser_will_prompt ())) -#endif - execute_prompt_command (); - - if (running_under_emacs == 2) - send_pwd_to_eterm (); /* Yuck */ - } - - current_command_line_count = 0; - r = yyparse (); - - if (need_here_doc) - gather_here_documents (); - - return (r); -} - -/* Read and parse a command, returning the status of the parse. The command - is left in the globval variable GLOBAL_COMMAND for use by reader_loop. - This is where the shell timeout code is executed. */ -int -read_command () -{ - SHELL_VAR *tmout_var; - int tmout_len, result; - SigHandler *old_alrm; - - set_current_prompt_level (1); - global_command = (COMMAND *)NULL; - - /* Only do timeouts if interactive. */ - tmout_var = (SHELL_VAR *)NULL; - tmout_len = 0; - old_alrm = (SigHandler *)NULL; - - if (interactive) - { - tmout_var = find_variable ("TMOUT"); - - if (tmout_var && var_isset (tmout_var)) - { - tmout_len = atoi (value_cell (tmout_var)); - if (tmout_len > 0) - { - old_alrm = set_signal_handler (SIGALRM, alrm_catcher); - alarm (tmout_len); - } - } - } - - QUIT; - - current_command_line_count = 0; - result = parse_command (); - - if (interactive && tmout_var && (tmout_len > 0)) - { - alarm(0); - set_signal_handler (SIGALRM, old_alrm); - } - - return (result); -} diff --git a/third_party/bash/evalfile.c b/third_party/bash/evalfile.c deleted file mode 100644 index 0479a0e62..000000000 --- a/third_party/bash/evalfile.c +++ /dev/null @@ -1,384 +0,0 @@ -/* evalfile.c - read and evaluate commands from a file or file descriptor */ - -/* Copyright (C) 1996-2017 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "bashtypes.h" -#include "posixstat.h" -#include "filecntl.h" - -#include -#include -#include - -#include "bashansi.h" -#include "bashintl.h" - -#include "shell.h" -#include "parser.h" -#include "jobs.h" -#include "builtins.h" -#include "flags.h" -#include "input.h" -#include "execute_cmd.h" -#include "trap.h" - -#include "y.tab.h" - -#if defined (HISTORY) -# include "bashhist.h" -#endif - -#include "typemax.h" - -#include "common.h" - -#if !defined (errno) -extern int errno; -#endif - -/* Flags for _evalfile() */ -#define FEVAL_ENOENTOK 0x001 -#define FEVAL_BUILTIN 0x002 -#define FEVAL_UNWINDPROT 0x004 -#define FEVAL_NONINT 0x008 -#define FEVAL_LONGJMP 0x010 -#define FEVAL_HISTORY 0x020 -#define FEVAL_CHECKBINARY 0x040 -#define FEVAL_REGFILE 0x080 -#define FEVAL_NOPUSHARGS 0x100 - -/* How many `levels' of sourced files we have. */ -int sourcelevel = 0; - -static int -_evalfile (filename, flags) - const char *filename; - int flags; -{ - volatile int old_interactive; - procenv_t old_return_catch; - int return_val, fd, result, pflags, i, nnull; - ssize_t nr; /* return value from read(2) */ - char *string; - struct stat finfo; - size_t file_size; - sh_vmsg_func_t *errfunc; -#if defined (ARRAY_VARS) - SHELL_VAR *funcname_v, *bash_source_v, *bash_lineno_v; - ARRAY *funcname_a, *bash_source_a, *bash_lineno_a; - struct func_array_state *fa; -# if defined (DEBUGGER) - SHELL_VAR *bash_argv_v, *bash_argc_v; - ARRAY *bash_argv_a, *bash_argc_a; -# endif - char *t, tt[2]; -#endif - - USE_VAR(pflags); - -#if defined (ARRAY_VARS) - GET_ARRAY_FROM_VAR ("FUNCNAME", funcname_v, funcname_a); - GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a); - GET_ARRAY_FROM_VAR ("BASH_LINENO", bash_lineno_v, bash_lineno_a); -# if defined (DEBUGGER) - GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a); - GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a); -# endif -#endif - - fd = open (filename, O_RDONLY); - - if (fd < 0 || (fstat (fd, &finfo) == -1)) - { - i = errno; - if (fd >= 0) - close (fd); - errno = i; - -file_error_and_exit: - if (((flags & FEVAL_ENOENTOK) == 0) || errno != ENOENT) - file_error (filename); - - if (flags & FEVAL_LONGJMP) - { - last_command_exit_value = EXECUTION_FAILURE; - jump_to_top_level (EXITPROG); - } - - return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE - : ((errno == ENOENT && (flags & FEVAL_ENOENTOK) != 0) ? 0 : -1)); - } - - errfunc = ((flags & FEVAL_BUILTIN) ? builtin_error : internal_error); - - if (S_ISDIR (finfo.st_mode)) - { - (*errfunc) (_("%s: is a directory"), filename); - close (fd); - return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1); - } - else if ((flags & FEVAL_REGFILE) && S_ISREG (finfo.st_mode) == 0) - { - (*errfunc) (_("%s: not a regular file"), filename); - close (fd); - return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1); - } - - file_size = (size_t)finfo.st_size; - /* Check for overflow with large files. */ - if (file_size != finfo.st_size || file_size + 1 < file_size) - { - (*errfunc) (_("%s: file is too large"), filename); - close (fd); - return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1); - } - - if (S_ISREG (finfo.st_mode) && file_size <= SSIZE_MAX) - { - string = (char *)xmalloc (1 + file_size); - nr = read (fd, string, file_size); - if (nr >= 0) - string[nr] = '\0'; - } - else - nr = zmapfd (fd, &string, 0); - - return_val = errno; - close (fd); - errno = return_val; - - if (nr < 0) /* XXX was != file_size, not < 0 */ - { - free (string); - goto file_error_and_exit; - } - - if (nr == 0) - { - free (string); - return ((flags & FEVAL_BUILTIN) ? EXECUTION_SUCCESS : 1); - } - - if ((flags & FEVAL_CHECKBINARY) && - check_binary_file (string, (nr > 80) ? 80 : nr)) - { - free (string); - (*errfunc) (_("%s: cannot execute binary file"), filename); - return ((flags & FEVAL_BUILTIN) ? EX_BINARY_FILE : -1); - } - - i = strlen (string); - if (i < nr) - { - for (nnull = i = 0; i < nr; i++) - if (string[i] == '\0') - { - memmove (string+i, string+i+1, nr - i); - nr--; - /* Even if the `check binary' flag is not set, we want to avoid - sourcing files with more than 256 null characters -- that - probably indicates a binary file. */ - if ((flags & FEVAL_BUILTIN) && ++nnull > 256) - { - free (string); - (*errfunc) (_("%s: cannot execute binary file"), filename); - return ((flags & FEVAL_BUILTIN) ? EX_BINARY_FILE : -1); - } - } - } - - if (flags & FEVAL_UNWINDPROT) - { - begin_unwind_frame ("_evalfile"); - - unwind_protect_int (return_catch_flag); - unwind_protect_jmp_buf (return_catch); - if (flags & FEVAL_NONINT) - unwind_protect_int (interactive); - unwind_protect_int (sourcelevel); - } - else - { - COPY_PROCENV (return_catch, old_return_catch); - if (flags & FEVAL_NONINT) - old_interactive = interactive; - } - - if (flags & FEVAL_NONINT) - interactive = 0; - - return_catch_flag++; - sourcelevel++; - -#if defined (ARRAY_VARS) - array_push (bash_source_a, (char *)filename); - t = itos (executing_line_number ()); - array_push (bash_lineno_a, t); - free (t); - array_push (funcname_a, "source"); /* not exactly right */ - - fa = (struct func_array_state *)xmalloc (sizeof (struct func_array_state)); - fa->source_a = bash_source_a; - fa->source_v = bash_source_v; - fa->lineno_a = bash_lineno_a; - fa->lineno_v = bash_lineno_v; - fa->funcname_a = funcname_a; - fa->funcname_v = funcname_v; - if (flags & FEVAL_UNWINDPROT) - add_unwind_protect (restore_funcarray_state, fa); - -# if defined (DEBUGGER) - /* Have to figure out a better way to do this when `source' is supplied - arguments */ - if ((flags & FEVAL_NOPUSHARGS) == 0) - { - if (shell_compatibility_level <= 44) - init_bash_argv (); - array_push (bash_argv_a, (char *)filename); /* XXX - unconditionally? */ - tt[0] = '1'; tt[1] = '\0'; - array_push (bash_argc_a, tt); - if (flags & FEVAL_UNWINDPROT) - add_unwind_protect (pop_args, 0); - } -# endif -#endif - - /* set the flags to be passed to parse_and_execute */ - pflags = SEVAL_RESETLINE; - pflags |= (flags & FEVAL_HISTORY) ? 0 : SEVAL_NOHIST; - - if (flags & FEVAL_BUILTIN) - result = EXECUTION_SUCCESS; - - return_val = setjmp_nosigs (return_catch); - - /* If `return' was seen outside of a function, but in the script, then - force parse_and_execute () to clean up. */ - if (return_val) - { - parse_and_execute_cleanup (-1); - result = return_catch_value; - } - else - result = parse_and_execute (string, filename, pflags); - - if (flags & FEVAL_UNWINDPROT) - run_unwind_frame ("_evalfile"); - else - { - if (flags & FEVAL_NONINT) - interactive = old_interactive; -#if defined (ARRAY_VARS) - restore_funcarray_state (fa); -# if defined (DEBUGGER) - if ((flags & FEVAL_NOPUSHARGS) == 0) - { - /* Don't need to call pop_args here until we do something better - when source is passed arguments (see above). */ - array_pop (bash_argc_a); - array_pop (bash_argv_a); - } -# endif -#endif - return_catch_flag--; - sourcelevel--; - COPY_PROCENV (old_return_catch, return_catch); - } - - /* If we end up with EOF after sourcing a file, which can happen when the file - doesn't end with a newline, pretend that it did. */ - if (current_token == yacc_EOF) - push_token ('\n'); /* XXX */ - - return ((flags & FEVAL_BUILTIN) ? result : 1); -} - -int -maybe_execute_file (fname, force_noninteractive) - const char *fname; - int force_noninteractive; -{ - char *filename; - int result, flags; - - filename = bash_tilde_expand (fname, 0); - flags = FEVAL_ENOENTOK; - if (force_noninteractive) - flags |= FEVAL_NONINT; - result = _evalfile (filename, flags); - free (filename); - return result; -} - -int -force_execute_file (fname, force_noninteractive) - const char *fname; - int force_noninteractive; -{ - char *filename; - int result, flags; - - filename = bash_tilde_expand (fname, 0); - flags = 0; - if (force_noninteractive) - flags |= FEVAL_NONINT; - result = _evalfile (filename, flags); - free (filename); - return result; -} - -#if defined (HISTORY) -int -fc_execute_file (filename) - const char *filename; -{ - int flags; - - /* We want these commands to show up in the history list if - remember_on_history is set. We use FEVAL_BUILTIN to return - the result of parse_and_execute. */ - flags = FEVAL_ENOENTOK|FEVAL_HISTORY|FEVAL_REGFILE|FEVAL_BUILTIN; - return (_evalfile (filename, flags)); -} -#endif /* HISTORY */ - -int -source_file (filename, sflags) - const char *filename; - int sflags; -{ - int flags, rval; - - flags = FEVAL_BUILTIN|FEVAL_UNWINDPROT|FEVAL_NONINT; - if (sflags) - flags |= FEVAL_NOPUSHARGS; - /* POSIX shells exit if non-interactive and file error. */ - if (posixly_correct && interactive_shell == 0 && executing_command_builtin == 0) - flags |= FEVAL_LONGJMP; - rval = _evalfile (filename, flags); - - run_return_trap (); - return rval; -} diff --git a/third_party/bash/evalstring.c b/third_party/bash/evalstring.c deleted file mode 100644 index 046be3c7c..000000000 --- a/third_party/bash/evalstring.c +++ /dev/null @@ -1,818 +0,0 @@ -/* evalstring.c - evaluate a string as one or more shell commands. */ - -/* Copyright (C) 1996-2022 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include -#include - -#include - -#include "filecntl.h" -#include "bashansi.h" - -#include "shell.h" -#include "jobs.h" -#include "builtins.h" -#include "flags.h" -#include "parser.h" -#include "input.h" -#include "execute_cmd.h" -#include "redir.h" -#include "trap.h" -#include "bashintl.h" - -#include "y.tab.h" - -#if defined (HISTORY) -# include "bashhist.h" -#endif - -#include "common.h" -#include "builtext.h" - -#if !defined (errno) -extern int errno; -#endif - -#define IS_BUILTIN(s) (builtin_address_internal(s, 0) != (struct builtin *)NULL) - -int parse_and_execute_level = 0; - -static int cat_file PARAMS((REDIRECT *)); - -#define PE_TAG "parse_and_execute top" -#define PS_TAG "parse_string top" - -#if defined (HISTORY) -static void -set_history_remembering () -{ - remember_on_history = enable_history_list; -} -#endif - -static void -restore_lastcom (x) - char *x; -{ - FREE (the_printed_command_except_trap); - the_printed_command_except_trap = x; -} - -int -should_optimize_fork (command, subshell) - COMMAND *command; - int subshell; -{ - return (running_trap == 0 && - command->type == cm_simple && - signal_is_trapped (EXIT_TRAP) == 0 && - signal_is_trapped (ERROR_TRAP) == 0 && - any_signals_trapped () < 0 && - (subshell || (command->redirects == 0 && command->value.Simple->redirects == 0)) && - ((command->flags & CMD_TIME_PIPELINE) == 0) && - ((command->flags & CMD_INVERT_RETURN) == 0)); -} - -/* This has extra tests to account for STARTUP_STATE == 2, which is for - -c command but has been extended to command and process substitution - (basically any time you call parse_and_execute in a subshell). */ -int -should_suppress_fork (command) - COMMAND *command; -{ - int subshell; - - subshell = subshell_environment & SUBSHELL_PROCSUB; /* salt to taste */ - return (startup_state == 2 && parse_and_execute_level == 1 && - *bash_input.location.string == '\0' && - parser_expanding_alias () == 0 && - should_optimize_fork (command, subshell)); -} - -int -can_optimize_connection (command) - COMMAND *command; -{ - return (*bash_input.location.string == '\0' && - parser_expanding_alias () == 0 && - (command->value.Connection->connector == AND_AND || command->value.Connection->connector == OR_OR || command->value.Connection->connector == ';') && - command->value.Connection->second->type == cm_simple); -} - -void -optimize_connection_fork (command) - COMMAND *command; -{ - if (command->type == cm_connection && - (command->value.Connection->connector == AND_AND || command->value.Connection->connector == OR_OR || command->value.Connection->connector == ';') && - (command->value.Connection->second->flags & CMD_TRY_OPTIMIZING) && - ((startup_state == 2 && should_suppress_fork (command->value.Connection->second)) || - ((subshell_environment & SUBSHELL_PAREN) && should_optimize_fork (command->value.Connection->second, 0)))) - { - command->value.Connection->second->flags |= CMD_NO_FORK; - command->value.Connection->second->value.Simple->flags |= CMD_NO_FORK; - } -} - -void -optimize_subshell_command (command) - COMMAND *command; -{ - if (should_optimize_fork (command, 0)) - { - command->flags |= CMD_NO_FORK; - command->value.Simple->flags |= CMD_NO_FORK; - } - else if (command->type == cm_connection && - (command->value.Connection->connector == AND_AND || command->value.Connection->connector == OR_OR || command->value.Connection->connector == ';') && - command->value.Connection->second->type == cm_simple && - parser_expanding_alias () == 0) - { - command->value.Connection->second->flags |= CMD_TRY_OPTIMIZING; - command->value.Connection->second->value.Simple->flags |= CMD_TRY_OPTIMIZING; - } -} - -void -optimize_shell_function (command) - COMMAND *command; -{ - COMMAND *fc; - - fc = (command->type == cm_group) ? command->value.Group->command : command; - - if (fc->type == cm_simple && should_suppress_fork (fc)) - { - fc->flags |= CMD_NO_FORK; - fc->value.Simple->flags |= CMD_NO_FORK; - } - else if (fc->type == cm_connection && can_optimize_connection (fc) && should_suppress_fork (fc->value.Connection->second)) - { - fc->value.Connection->second->flags |= CMD_NO_FORK; - fc->value.Connection->second->value.Simple->flags |= CMD_NO_FORK; - } -} - -int -can_optimize_cat_file (command) - COMMAND *command; -{ - return (command->type == cm_simple && !command->redirects && - (command->flags & CMD_TIME_PIPELINE) == 0 && - command->value.Simple->words == 0 && - command->value.Simple->redirects && - command->value.Simple->redirects->next == 0 && - command->value.Simple->redirects->instruction == r_input_direction && - command->value.Simple->redirects->redirector.dest == 0); -} - -/* How to force parse_and_execute () to clean up after itself. */ -void -parse_and_execute_cleanup (old_running_trap) - int old_running_trap; -{ - if (running_trap > 0) - { - /* We assume if we have a different value for running_trap than when - we started (the only caller that cares is evalstring()), the - original caller will perform the cleanup, and we should not step - on them. */ - if (running_trap != old_running_trap) - run_trap_cleanup (running_trap - 1); - unfreeze_jobs_list (); - } - - if (have_unwind_protects ()) - run_unwind_frame (PE_TAG); - else - parse_and_execute_level = 0; /* XXX */ -} - -static void -parse_prologue (string, flags, tag) - char *string; - int flags; - char *tag; -{ - char *orig_string, *lastcom; - int x; - - orig_string = string; - /* Unwind protect this invocation of parse_and_execute (). */ - begin_unwind_frame (tag); - unwind_protect_int (parse_and_execute_level); - unwind_protect_jmp_buf (top_level); - unwind_protect_int (indirection_level); - unwind_protect_int (line_number); - unwind_protect_int (line_number_for_err_trap); - unwind_protect_int (loop_level); - unwind_protect_int (executing_list); - unwind_protect_int (comsub_ignore_return); - if (flags & (SEVAL_NONINT|SEVAL_INTERACT)) - unwind_protect_int (interactive); - -#if defined (HISTORY) - if (parse_and_execute_level == 0) - add_unwind_protect (set_history_remembering, (char *)NULL); - else - unwind_protect_int (remember_on_history); /* can be used in scripts */ -# if defined (BANG_HISTORY) - unwind_protect_int (history_expansion_inhibited); -# endif /* BANG_HISTORY */ -#endif /* HISTORY */ - - if (interactive_shell) - { - x = get_current_prompt_level (); - add_unwind_protect (set_current_prompt_level, x); - } - - if (the_printed_command_except_trap) - { - lastcom = savestring (the_printed_command_except_trap); - add_unwind_protect (restore_lastcom, lastcom); - } - - add_unwind_protect (pop_stream, (char *)NULL); - if (parser_expanding_alias ()) - add_unwind_protect (parser_restore_alias, (char *)NULL); - - if (orig_string && ((flags & SEVAL_NOFREE) == 0)) - add_unwind_protect (xfree, orig_string); - end_unwind_frame (); - - if (flags & (SEVAL_NONINT|SEVAL_INTERACT)) - interactive = (flags & SEVAL_NONINT) ? 0 : 1; - -#if defined (HISTORY) - if (flags & SEVAL_NOHIST) - bash_history_disable (); -# if defined (BANG_HISTORY) - if (flags & SEVAL_NOHISTEXP) - history_expansion_inhibited = 1; -# endif /* BANG_HISTORY */ -#endif /* HISTORY */ -} - -/* Parse and execute the commands in STRING. Returns whatever - execute_command () returns. This frees STRING. FLAGS is a - flags word; look in common.h for the possible values. Actions - are: - (flags & SEVAL_NONINT) -> interactive = 0; - (flags & SEVAL_INTERACT) -> interactive = 1; - (flags & SEVAL_NOHIST) -> call bash_history_disable () - (flags & SEVAL_NOFREE) -> don't free STRING when finished - (flags & SEVAL_RESETLINE) -> reset line_number to 1 - (flags & SEVAL_NOHISTEXP) -> history_expansion_inhibited -> 1 -*/ - -int -parse_and_execute (string, from_file, flags) - char *string; - const char *from_file; - int flags; -{ - int code, lreset; - volatile int should_jump_to_top_level, last_result; - COMMAND *volatile command; - volatile sigset_t pe_sigmask; - - parse_prologue (string, flags, PE_TAG); - - parse_and_execute_level++; - - lreset = flags & SEVAL_RESETLINE; - -#if defined (HAVE_POSIX_SIGNALS) - /* If we longjmp and are going to go on, use this to restore signal mask */ - sigemptyset ((sigset_t *)&pe_sigmask); - sigprocmask (SIG_BLOCK, (sigset_t *)NULL, (sigset_t *)&pe_sigmask); -#endif - - /* Reset the line number if the caller wants us to. If we don't reset the - line number, we have to subtract one, because we will add one just - before executing the next command (resetting the line number sets it to - 0; the first line number is 1). */ - push_stream (lreset); - if (parser_expanding_alias ()) - /* push current shell_input_line */ - parser_save_alias (); - - if (lreset == 0) - line_number--; - - indirection_level++; - - code = should_jump_to_top_level = 0; - last_result = EXECUTION_SUCCESS; - - /* We need to reset enough of the token state so we can start fresh. */ - if (current_token == yacc_EOF) - current_token = '\n'; /* reset_parser() ? */ - - with_input_from_string (string, from_file); - clear_shell_input_line (); - while (*(bash_input.location.string) || parser_expanding_alias ()) - { - command = (COMMAND *)NULL; - - if (interrupt_state) - { - last_result = EXECUTION_FAILURE; - break; - } - - /* Provide a location for functions which `longjmp (top_level)' to - jump to. This prevents errors in substitution from restarting - the reader loop directly, for example. */ - code = setjmp_nosigs (top_level); - - if (code) - { - should_jump_to_top_level = 0; - switch (code) - { - case ERREXIT: - /* variable_context -> 0 is what eval.c:reader_loop() does in - these circumstances. Don't bother with cleanup here because - we don't want to run the function execution cleanup stuff - that will cause pop_context and other functions to run. - We call reset_local_contexts() instead, which just frees - context memory. - XXX - change that if we want the function context to be - unwound. */ - if (exit_immediately_on_error && variable_context) - { - discard_unwind_frame ("pe_dispose"); - reset_local_contexts (); /* not in a function */ - } - should_jump_to_top_level = 1; - goto out; - case FORCE_EOF: - case EXITPROG: - if (command) - run_unwind_frame ("pe_dispose"); - /* Remember to call longjmp (top_level) after the old - value for it is restored. */ - should_jump_to_top_level = 1; - goto out; - - case EXITBLTIN: - if (command) - { - if (variable_context && signal_is_trapped (0)) - { - /* Let's make sure we run the exit trap in the function - context, as we do when not running parse_and_execute. - The pe_dispose unwind frame comes before any unwind- - protects installed by the string we're evaluating, so - it will undo the current function scope. */ - dispose_command (command); - discard_unwind_frame ("pe_dispose"); - } - else - run_unwind_frame ("pe_dispose"); - } - should_jump_to_top_level = 1; - goto out; - - case DISCARD: - if (command) - run_unwind_frame ("pe_dispose"); - last_result = last_command_exit_value = EXECUTION_FAILURE; /* XXX */ - set_pipestatus_from_exit (last_command_exit_value); - if (subshell_environment) - { - should_jump_to_top_level = 1; - goto out; - } - else - { -#if 0 - dispose_command (command); /* pe_dispose does this */ -#endif -#if defined (HAVE_POSIX_SIGNALS) - sigprocmask (SIG_SETMASK, (sigset_t *)&pe_sigmask, (sigset_t *)NULL); -#endif - continue; - } - - default: - command_error ("parse_and_execute", CMDERR_BADJUMP, code, 0); - break; - } - } - - if (parse_command () == 0) - { - if ((flags & SEVAL_PARSEONLY) || (interactive_shell == 0 && read_but_dont_execute)) - { - last_result = EXECUTION_SUCCESS; - dispose_command (global_command); - global_command = (COMMAND *)NULL; - } - else if (command = global_command) - { - struct fd_bitmap *bitmap; - - if (flags & SEVAL_FUNCDEF) - { - char *x; - - /* If the command parses to something other than a straight - function definition, or if we have not consumed the entire - string, or if the parser has transformed the function - name (as parsing will if it begins or ends with shell - whitespace, for example), reject the attempt */ - if (command->type != cm_function_def || - ((x = parser_remaining_input ()) && *x) || - (STREQ (from_file, command->value.Function_def->name->word) == 0)) - { - internal_warning (_("%s: ignoring function definition attempt"), from_file); - should_jump_to_top_level = 0; - last_result = last_command_exit_value = EX_BADUSAGE; - set_pipestatus_from_exit (last_command_exit_value); - reset_parser (); - break; - } - } - - bitmap = new_fd_bitmap (FD_BITMAP_SIZE); - begin_unwind_frame ("pe_dispose"); - add_unwind_protect (dispose_fd_bitmap, bitmap); - add_unwind_protect (dispose_command, command); /* XXX */ - - global_command = (COMMAND *)NULL; - - if ((subshell_environment & SUBSHELL_COMSUB) && comsub_ignore_return) - command->flags |= CMD_IGNORE_RETURN; - -#if defined (ONESHOT) - /* - * IF - * we were invoked as `bash -c' (startup_state == 2) AND - * parse_and_execute has not been called recursively AND - * we're not running a trap AND - * we have parsed the full command (string == '\0') AND - * we're not going to run the exit trap AND - * we have a simple command without redirections AND - * the command is not being timed AND - * the command's return status is not being inverted AND - * there aren't any traps in effect - * THEN - * tell the execution code that we don't need to fork - */ - if (should_suppress_fork (command)) - { - command->flags |= CMD_NO_FORK; - command->value.Simple->flags |= CMD_NO_FORK; - } - - /* Can't optimize forks out here execept for simple commands. - This knows that the parser sets up commands as left-side heavy - (&& and || are left-associative) and after the single parse, - if we are at the end of the command string, the last in a - series of connection commands is - command->value.Connection->second. */ - else if (command->type == cm_connection && can_optimize_connection (command)) - { - command->value.Connection->second->flags |= CMD_TRY_OPTIMIZING; - command->value.Connection->second->value.Simple->flags |= CMD_TRY_OPTIMIZING; - } -#endif /* ONESHOT */ - - /* See if this is a candidate for $( value.Simple->redirects); - last_result = (r < 0) ? EXECUTION_FAILURE : EXECUTION_SUCCESS; - } - else - last_result = execute_command_internal - (command, 0, NO_PIPE, NO_PIPE, bitmap); - dispose_command (command); - dispose_fd_bitmap (bitmap); - discard_unwind_frame ("pe_dispose"); - - if (flags & SEVAL_ONECMD) - { - reset_parser (); - break; - } - } - } - else - { - last_result = EX_BADUSAGE; /* was EXECUTION_FAILURE */ - - if (interactive_shell == 0 && this_shell_builtin && - (this_shell_builtin == source_builtin || this_shell_builtin == eval_builtin) && - last_command_exit_value == EX_BADSYNTAX && posixly_correct && executing_command_builtin == 0) - { - should_jump_to_top_level = 1; - code = ERREXIT; - last_command_exit_value = EX_BADUSAGE; - } - - /* Since we are shell compatible, syntax errors in a script - abort the execution of the script. Right? */ - break; - } - } - - out: - - run_unwind_frame (PE_TAG); - - if (interrupt_state && parse_and_execute_level == 0) - { - /* An interrupt during non-interactive execution in an - interactive shell (e.g. via $PROMPT_COMMAND) should - not cause the shell to exit. */ - interactive = interactive_shell; - throw_to_top_level (); - } - - CHECK_TERMSIG; - - if (should_jump_to_top_level) - jump_to_top_level (code); - - return (last_result); -} - -/* Parse a command contained in STRING according to FLAGS and return the - number of characters consumed from the string. If non-NULL, set *ENDP - to the position in the string where the parse ended. Used to validate - command substitutions during parsing to obey Posix rules about finding - the end of the command and balancing parens. */ -int -parse_string (string, from_file, flags, cmdp, endp) - char *string; - const char *from_file; - int flags; - COMMAND **cmdp; - char **endp; -{ - int code, nc; - volatile int should_jump_to_top_level; - COMMAND *volatile command, *oglobal; - char *ostring; - volatile sigset_t ps_sigmask; - - parse_prologue (string, flags, PS_TAG); - -#if defined (HAVE_POSIX_SIGNALS) - /* If we longjmp and are going to go on, use this to restore signal mask */ - sigemptyset ((sigset_t *)&ps_sigmask); - sigprocmask (SIG_BLOCK, (sigset_t *)NULL, (sigset_t *)&ps_sigmask); -#endif - - /* Reset the line number if the caller wants us to. If we don't reset the - line number, we have to subtract one, because we will add one just - before executing the next command (resetting the line number sets it to - 0; the first line number is 1). */ - push_stream (0); - if (parser_expanding_alias ()) - /* push current shell_input_line */ - parser_save_alias (); - - code = should_jump_to_top_level = 0; - oglobal = global_command; - - with_input_from_string (string, from_file); - ostring = bash_input.location.string; - while (*(bash_input.location.string)) /* XXX - parser_expanding_alias () ? */ - { - command = (COMMAND *)NULL; - -#if 0 - if (interrupt_state) - break; -#endif - - /* Provide a location for functions which `longjmp (top_level)' to - jump to. */ - code = setjmp_nosigs (top_level); - - if (code) - { - INTERNAL_DEBUG(("parse_string: longjmp executed: code = %d", code)); - - should_jump_to_top_level = 0; - switch (code) - { - case FORCE_EOF: - case ERREXIT: - case EXITPROG: - case EXITBLTIN: - case DISCARD: /* XXX */ - if (command) - dispose_command (command); - /* Remember to call longjmp (top_level) after the old - value for it is restored. */ - should_jump_to_top_level = 1; - goto out; - - default: -#if defined (HAVE_POSIX_SIGNALS) - sigprocmask (SIG_SETMASK, (sigset_t *)&ps_sigmask, (sigset_t *)NULL); -#endif - command_error ("parse_string", CMDERR_BADJUMP, code, 0); - break; - } - } - - if (parse_command () == 0) - { - if (cmdp) - *cmdp = global_command; - else - dispose_command (global_command); - global_command = (COMMAND *)NULL; - } - else - { - if ((flags & SEVAL_NOLONGJMP) == 0) - { - should_jump_to_top_level = 1; - code = DISCARD; - } - else - reset_parser (); /* XXX - sets token_to_read */ - break; - } - - if (current_token == yacc_EOF || current_token == shell_eof_token) - { - if (current_token == shell_eof_token) - rewind_input_string (); - break; - } - } - -out: - - global_command = oglobal; - nc = bash_input.location.string - ostring; - if (endp) - *endp = bash_input.location.string; - - run_unwind_frame (PS_TAG); - - /* If we return < 0, the caller (xparse_dolparen) will jump_to_top_level for - us, after doing cleanup */ - if (should_jump_to_top_level) - { - if (parse_and_execute_level == 0) - top_level_cleanup (); - if (code == DISCARD) - return -DISCARD; - jump_to_top_level (code); - } - - return (nc); -} - -int -open_redir_file (r, fnp) - REDIRECT *r; - char **fnp; -{ - char *fn; - int fd, rval; - - if (r->instruction != r_input_direction) - return -1; - - /* Get the filename. */ - if (posixly_correct && !interactive_shell) - disallow_filename_globbing++; - fn = redirection_expand (r->redirectee.filename); - if (posixly_correct && !interactive_shell) - disallow_filename_globbing--; - - if (fn == 0) - { - redirection_error (r, AMBIGUOUS_REDIRECT, fn); - return -1; - } - - fd = open(fn, O_RDONLY); - if (fd < 0) - { - file_error (fn); - free (fn); - if (fnp) - *fnp = 0; - return -1; - } - - if (fnp) - *fnp = fn; - return fd; -} - -/* Handle a $( < file ) command substitution. This expands the filename, - returning errors as appropriate, then just cats the file to the standard - output. */ -static int -cat_file (r) - REDIRECT *r; -{ - char *fn; - int fd, rval; - - fd = open_redir_file (r, &fn); - if (fd < 0) - return -1; - - rval = zcatfd (fd, 1, fn); - - free (fn); - close (fd); - - return (rval); -} - -int -evalstring (string, from_file, flags) - char *string; - const char *from_file; - int flags; -{ - volatile int r, rflag, rcatch; - volatile int was_trap; - - /* Are we running a trap when we execute this function? */ - was_trap = running_trap; - - rcatch = 0; - rflag = return_catch_flag; - /* If we are in a place where `return' is valid, we have to catch - `eval "... return"' and make sure parse_and_execute cleans up. Then - we can trampoline to the previous saved return_catch location. */ - if (rflag) - { - begin_unwind_frame ("evalstring"); - - unwind_protect_int (return_catch_flag); - unwind_protect_jmp_buf (return_catch); - - return_catch_flag++; /* increment so we have a counter */ - rcatch = setjmp_nosigs (return_catch); - } - - if (rcatch) - { - /* We care about whether or not we are running the same trap we were - when we entered this function. */ - parse_and_execute_cleanup (was_trap); - r = return_catch_value; - } - else - /* Note that parse_and_execute () frees the string it is passed. */ - r = parse_and_execute (string, from_file, flags); - - if (rflag) - { - run_unwind_frame ("evalstring"); - if (rcatch && return_catch_flag) - { - return_catch_value = r; - sh_longjmp (return_catch, 1); - } - } - - return (r); -} diff --git a/third_party/bash/execute_cmd.c b/third_party/bash/execute_cmd.c deleted file mode 100644 index 665099968..000000000 --- a/third_party/bash/execute_cmd.c +++ /dev/null @@ -1,6229 +0,0 @@ -/* execute_cmd.c -- Execute a COMMAND structure. */ - -/* Copyright (C) 1987-2022 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if !defined (__GNUC__) && !defined (HAVE_ALLOCA_H) && defined (_AIX) - #pragma alloca -#endif /* _AIX && RISC6000 && !__GNUC__ */ - -#include -#include "chartypes.h" -#include "bashtypes.h" -#if !defined (_MINIX) && defined (HAVE_SYS_FILE_H) -# include -#endif -#include "filecntl.h" -#include "posixstat.h" -#include -#if defined (HAVE_SYS_PARAM_H) -# include -#endif - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "posixtime.h" - -#if defined (HAVE_SYS_RESOURCE_H) && !defined (RLIMTYPE) -# include -#endif - -#if defined (HAVE_SYS_TIMES_H) && defined (HAVE_TIMES) -# include -#endif - -#include - -#if !defined (errno) -extern int errno; -#endif - -#define NEED_FPURGE_DECL -#define NEED_SH_SETLINEBUF_DECL - -#include "bashansi.h" -#include "bashintl.h" - -#include "memalloc.h" -#include "shell.h" -#include "y.tab.h" /* use <...> so we pick it up from the build directory */ -#include "parser.h" -#include "flags.h" -#include "builtins.h" -#include "hashlib.h" -#include "jobs.h" -#include "execute_cmd.h" -#include "findcmd.h" -#include "redir.h" -#include "trap.h" -#include "pathexp.h" -#include "hashcmd.h" - -#if defined (COND_COMMAND) -# include "test.h" -#endif - -#include "common.h" -#include "builtext.h" /* list of builtins */ - -#include "getopt.h" - -#include "strmatch.h" -#include "tilde.h" - -#if defined (BUFFERED_INPUT) -# include "input.h" -#endif - -#if defined (ALIAS) -# include "alias.h" -#endif - -#if defined (HISTORY) -# include "bashhist.h" -#endif - -#if defined (HAVE_MBSTR_H) && defined (HAVE_MBSCHR) -# include /* mbschr */ -#endif - -extern int command_string_index; -extern char *the_printed_command; -extern time_t shell_start_time; -#if defined (HAVE_GETTIMEOFDAY) -extern struct timeval shellstart; -#endif -#if 0 -extern char *glob_argv_flags; -#endif - -extern int close PARAMS((int)); - -/* Static functions defined and used in this file. */ -static void close_pipes PARAMS((int, int)); -static void do_piping PARAMS((int, int)); -static void bind_lastarg PARAMS((char *)); -static int shell_control_structure PARAMS((enum command_type)); -static void cleanup_redirects PARAMS((REDIRECT *)); - -#if defined (JOB_CONTROL) -static int restore_signal_mask PARAMS((sigset_t *)); -#endif - -static int builtin_status PARAMS((int)); - -static int execute_for_command PARAMS((FOR_COM *)); -#if defined (SELECT_COMMAND) -static int displen PARAMS((const char *)); -static int print_index_and_element PARAMS((int, int, WORD_LIST *)); -static void indent PARAMS((int, int)); -static void print_select_list PARAMS((WORD_LIST *, int, int, int)); -static char *select_query PARAMS((WORD_LIST *, int, char *, int)); -static int execute_select_command PARAMS((SELECT_COM *)); -#endif -#if defined (DPAREN_ARITHMETIC) -static int execute_arith_command PARAMS((ARITH_COM *)); -#endif -#if defined (COND_COMMAND) -static int execute_cond_node PARAMS((COND_COM *)); -static int execute_cond_command PARAMS((COND_COM *)); -#endif -#if defined (COMMAND_TIMING) -static int mkfmt PARAMS((char *, int, int, time_t, int)); -static void print_formatted_time PARAMS((FILE *, char *, - time_t, int, time_t, int, - time_t, int, int)); -static int time_command PARAMS((COMMAND *, int, int, int, struct fd_bitmap *)); -#endif -#if defined (ARITH_FOR_COMMAND) -static intmax_t eval_arith_for_expr PARAMS((WORD_LIST *, int *)); -static int execute_arith_for_command PARAMS((ARITH_FOR_COM *)); -#endif -static int execute_case_command PARAMS((CASE_COM *)); -static int execute_while_command PARAMS((WHILE_COM *)); -static int execute_until_command PARAMS((WHILE_COM *)); -static int execute_while_or_until PARAMS((WHILE_COM *, int)); -static int execute_if_command PARAMS((IF_COM *)); -static int execute_null_command PARAMS((REDIRECT *, int, int, int)); -static void fix_assignment_words PARAMS((WORD_LIST *)); -static void fix_arrayref_words PARAMS((WORD_LIST *)); -static int execute_simple_command PARAMS((SIMPLE_COM *, int, int, int, struct fd_bitmap *)); -static int execute_builtin PARAMS((sh_builtin_func_t *, WORD_LIST *, int, int)); -static int execute_function PARAMS((SHELL_VAR *, WORD_LIST *, int, struct fd_bitmap *, int, int)); -static int execute_builtin_or_function PARAMS((WORD_LIST *, sh_builtin_func_t *, - SHELL_VAR *, - REDIRECT *, struct fd_bitmap *, int)); -static void execute_subshell_builtin_or_function PARAMS((WORD_LIST *, REDIRECT *, - sh_builtin_func_t *, - SHELL_VAR *, - int, int, int, - struct fd_bitmap *, - int)); -static int execute_disk_command PARAMS((WORD_LIST *, REDIRECT *, char *, - int, int, int, struct fd_bitmap *, int)); - -static char *getinterp PARAMS((char *, int, int *)); -static void initialize_subshell PARAMS((void)); -static int execute_in_subshell PARAMS((COMMAND *, int, int, int, struct fd_bitmap *)); -#if defined (COPROCESS_SUPPORT) -static void coproc_setstatus PARAMS((struct coproc *, int)); -static int execute_coproc PARAMS((COMMAND *, int, int, struct fd_bitmap *)); -#endif - -static int execute_pipeline PARAMS((COMMAND *, int, int, int, struct fd_bitmap *)); - -static int execute_connection PARAMS((COMMAND *, int, int, int, struct fd_bitmap *)); - -static int execute_intern_function PARAMS((WORD_DESC *, FUNCTION_DEF *)); - -/* Set to 1 if fd 0 was the subject of redirection to a subshell. Global - so that reader_loop can set it to zero before executing a command. */ -int stdin_redir; - -/* The name of the command that is currently being executed. - `test' needs this, for example. */ -char *this_command_name; - -/* The printed representation of the currently-executing command (same as - the_printed_command), except when a trap is being executed. Useful for - a debugger to know where exactly the program is currently executing. */ -char *the_printed_command_except_trap; - -/* For catching RETURN in a function. */ -int return_catch_flag; -int return_catch_value; -procenv_t return_catch; - -/* The value returned by the last synchronous command. */ -volatile int last_command_exit_value; - -/* Whether or not the last command (corresponding to last_command_exit_value) - was terminated by a signal, and, if so, which one. */ -int last_command_exit_signal; - -/* Are we currently ignoring the -e option for the duration of a builtin's - execution? */ -int builtin_ignoring_errexit = 0; - -/* The list of redirections to perform which will undo the redirections - that I made in the shell. */ -REDIRECT *redirection_undo_list = (REDIRECT *)NULL; - -/* The list of redirections to perform which will undo the internal - redirections performed by the `exec' builtin. These are redirections - that must be undone even when exec discards redirection_undo_list. */ -REDIRECT *exec_redirection_undo_list = (REDIRECT *)NULL; - -/* When greater than zero, value is the `level' of builtins we are - currently executing (e.g. `eval echo a' would have it set to 2). */ -int executing_builtin = 0; - -/* Non-zero if we are executing a command list (a;b;c, etc.) */ -int executing_list = 0; - -/* Non-zero if failing commands in a command substitution should not exit the - shell even if -e is set. Used to pass the CMD_IGNORE_RETURN flag down to - commands run in command substitutions by parse_and_execute. */ -int comsub_ignore_return = 0; - -/* Non-zero if we have just forked and are currently running in a subshell - environment. */ -int subshell_environment; - -/* Count of nested subshells, like SHLVL. Available via $BASH_SUBSHELL */ -int subshell_level = 0; - -/* Currently-executing shell function. */ -SHELL_VAR *this_shell_function; - -/* If non-zero, matches in case and [[ ... ]] are case-insensitive */ -int match_ignore_case = 0; - -int executing_command_builtin = 0; - -struct stat SB; /* used for debugging */ - -static int special_builtin_failed; - -static COMMAND *currently_executing_command; - -/* The line number that the currently executing function starts on. */ -static int function_line_number; - -/* XXX - set to 1 if we're running the DEBUG trap and we want to show the line - number containing the function name. Used by executing_line_number to - report the correct line number. Kind of a hack. */ -static int showing_function_line; - -static int connection_count; - -/* $LINENO ($BASH_LINENO) for use by an ERR trap. Global so parse_and_execute - can save and restore it. */ -int line_number_for_err_trap; - -/* A convenience macro to avoid resetting line_number_for_err_trap while - running the ERR trap. */ -#define SET_LINE_NUMBER(v) \ -do { \ - line_number = v; \ - if (signal_in_progress (ERROR_TRAP) == 0 && running_trap != (ERROR_TRAP + 1)) \ - line_number_for_err_trap = line_number; \ -} while (0) - -/* This can't be in executing_line_number() because that's used for LINENO - and we want LINENO to reflect the line number of commands run during - the ERR trap. Right now this is only used to push to BASH_LINENO. */ -#define GET_LINE_NUMBER() \ - (signal_in_progress (ERROR_TRAP) && running_trap == ERROR_TRAP+1) \ - ? line_number_for_err_trap \ - : executing_line_number () - -/* A sort of function nesting level counter */ -int funcnest = 0; -int funcnest_max = 0; - -int evalnest = 0; -int evalnest_max = EVALNEST_MAX; - -int sourcenest = 0; -int sourcenest_max = SOURCENEST_MAX; - -volatile int from_return_trap = 0; - -int lastpipe_opt = 0; - -struct fd_bitmap *current_fds_to_close = (struct fd_bitmap *)NULL; - -#define FD_BITMAP_DEFAULT_SIZE 32 - -/* Functions to allocate and deallocate the structures used to pass - information from the shell to its children about file descriptors - to close. */ -struct fd_bitmap * -new_fd_bitmap (size) - int size; -{ - struct fd_bitmap *ret; - - ret = (struct fd_bitmap *)xmalloc (sizeof (struct fd_bitmap)); - - ret->size = size; - - if (size) - { - ret->bitmap = (char *)xmalloc (size); - memset (ret->bitmap, '\0', size); - } - else - ret->bitmap = (char *)NULL; - return (ret); -} - -void -dispose_fd_bitmap (fdbp) - struct fd_bitmap *fdbp; -{ - FREE (fdbp->bitmap); - free (fdbp); -} - -void -close_fd_bitmap (fdbp) - struct fd_bitmap *fdbp; -{ - register int i; - - if (fdbp) - { - for (i = 0; i < fdbp->size; i++) - if (fdbp->bitmap[i]) - { - close (i); - fdbp->bitmap[i] = 0; - } - } -} - -/* Return the line number of the currently executing command. */ -int -executing_line_number () -{ - if (executing && showing_function_line == 0 && - (variable_context == 0 || interactive_shell == 0) && - currently_executing_command) - { -#if defined (COND_COMMAND) - if (currently_executing_command->type == cm_cond) - return currently_executing_command->value.Cond->line; -#endif -#if defined (DPAREN_ARITHMETIC) - if (currently_executing_command->type == cm_arith) - return currently_executing_command->value.Arith->line; -#endif -#if defined (ARITH_FOR_COMMAND) - if (currently_executing_command->type == cm_arith_for) - return currently_executing_command->value.ArithFor->line; -#endif - - return line_number; - } - else - return line_number; -} - -/* Execute the command passed in COMMAND. COMMAND is exactly what - read_command () places into GLOBAL_COMMAND. See "command.h" for the - details of the command structure. - - EXECUTION_SUCCESS or EXECUTION_FAILURE are the only possible - return values. Executing a command with nothing in it returns - EXECUTION_SUCCESS. */ -int -execute_command (command) - COMMAND *command; -{ - struct fd_bitmap *bitmap; - int result; - - current_fds_to_close = (struct fd_bitmap *)NULL; - bitmap = new_fd_bitmap (FD_BITMAP_DEFAULT_SIZE); - begin_unwind_frame ("execute-command"); - add_unwind_protect (dispose_fd_bitmap, (char *)bitmap); - - /* Just do the command, but not asynchronously. */ - result = execute_command_internal (command, 0, NO_PIPE, NO_PIPE, bitmap); - - dispose_fd_bitmap (bitmap); - discard_unwind_frame ("execute-command"); - -#if defined (PROCESS_SUBSTITUTION) - /* don't unlink fifos if we're in a shell function; wait until the function - returns. */ - if (variable_context == 0 && executing_list == 0) - unlink_fifo_list (); -#endif /* PROCESS_SUBSTITUTION */ - - QUIT; - return (result); -} - -/* Return 1 if TYPE is a shell control structure type. */ -static int -shell_control_structure (type) - enum command_type type; -{ - switch (type) - { -#if defined (ARITH_FOR_COMMAND) - case cm_arith_for: -#endif -#if defined (SELECT_COMMAND) - case cm_select: -#endif -#if defined (DPAREN_ARITHMETIC) - case cm_arith: -#endif -#if defined (COND_COMMAND) - case cm_cond: -#endif - case cm_case: - case cm_while: - case cm_until: - case cm_if: - case cm_for: - case cm_group: - case cm_function_def: - return (1); - - default: - return (0); - } -} - -/* A function to use to unwind_protect the redirection undo list - for loops. */ -static void -cleanup_redirects (list) - REDIRECT *list; -{ - do_redirections (list, RX_ACTIVE); - dispose_redirects (list); -} - -void -undo_partial_redirects () -{ - if (redirection_undo_list) - { - cleanup_redirects (redirection_undo_list); - redirection_undo_list = (REDIRECT *)NULL; - } -} - -#if 0 -/* Function to unwind_protect the redirections for functions and builtins. */ -static void -cleanup_func_redirects (list) - REDIRECT *list; -{ - do_redirections (list, RX_ACTIVE); -} -#endif - -void -dispose_exec_redirects () -{ - if (exec_redirection_undo_list) - { - dispose_redirects (exec_redirection_undo_list); - exec_redirection_undo_list = (REDIRECT *)NULL; - } -} - -void -dispose_partial_redirects () -{ - if (redirection_undo_list) - { - dispose_redirects (redirection_undo_list); - redirection_undo_list = (REDIRECT *)NULL; - } -} - -#if defined (JOB_CONTROL) -/* A function to restore the signal mask to its proper value when the shell - is interrupted or errors occur while creating a pipeline. */ -static int -restore_signal_mask (set) - sigset_t *set; -{ - return (sigprocmask (SIG_SETMASK, set, (sigset_t *)NULL)); -} -#endif /* JOB_CONTROL */ - -#ifdef DEBUG -/* A debugging function that can be called from gdb, for instance. */ -void -open_files (void) -{ - register int i; - int f, fd_table_size; - - fd_table_size = getdtablesize (); - - fprintf (stderr, "pid %ld open files:", (long)getpid ()); - for (i = 3; i < fd_table_size; i++) - { - if ((f = fcntl (i, F_GETFD, 0)) != -1) - fprintf (stderr, " %d (%s)", i, f ? "close" : "open"); - } - fprintf (stderr, "\n"); -} -#endif - -void -async_redirect_stdin () -{ - int fd; - - fd = open ("/dev/null", O_RDONLY); - if (fd > 0) - { - dup2 (fd, 0); - close (fd); - } - else if (fd < 0) - internal_error (_("cannot redirect standard input from /dev/null: %s"), strerror (errno)); -} - -#define DESCRIBE_PID(pid) do { if (interactive) describe_pid (pid); } while (0) - -/* Execute the command passed in COMMAND, perhaps doing it asynchronously. - COMMAND is exactly what read_command () places into GLOBAL_COMMAND. - ASYNCHRONOUS, if non-zero, says to do this command in the background. - PIPE_IN and PIPE_OUT are file descriptors saying where input comes - from and where it goes. They can have the value of NO_PIPE, which means - I/O is stdin/stdout. - FDS_TO_CLOSE is a list of file descriptors to close once the child has - been forked. This list often contains the unusable sides of pipes, etc. - - EXECUTION_SUCCESS or EXECUTION_FAILURE are the only possible - return values. Executing a command with nothing in it returns - EXECUTION_SUCCESS. */ -int -execute_command_internal (command, asynchronous, pipe_in, pipe_out, - fds_to_close) - COMMAND *command; - int asynchronous; - int pipe_in, pipe_out; - struct fd_bitmap *fds_to_close; -{ - int exec_result, user_subshell, invert, ignore_return, was_error_trap, fork_flags; - REDIRECT *my_undo_list, *exec_undo_list; - char *tcmd; - volatile int save_line_number; -#if defined (PROCESS_SUBSTITUTION) - volatile int ofifo, nfifo, osize, saved_fifo; - volatile void *ofifo_list; -#endif - - if (breaking || continuing) - return (last_command_exit_value); - if (read_but_dont_execute) - return (last_command_exit_value); - if (command == 0) - return (EXECUTION_SUCCESS); - - QUIT; - run_pending_traps (); - -#if 0 - if (running_trap == 0) -#endif - currently_executing_command = command; - - invert = (command->flags & CMD_INVERT_RETURN) != 0; - - /* If we're inverting the return value and `set -e' has been executed, - we don't want a failing command to inadvertently cause the shell - to exit. */ - if (exit_immediately_on_error && invert) /* XXX */ - command->flags |= CMD_IGNORE_RETURN; /* XXX */ - - exec_result = EXECUTION_SUCCESS; - - /* If a command was being explicitly run in a subshell, or if it is - a shell control-structure, and it has a pipe, then we do the command - in a subshell. */ - if (command->type == cm_subshell && (command->flags & CMD_NO_FORK)) - return (execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close)); - -#if defined (COPROCESS_SUPPORT) - if (command->type == cm_coproc) - return (last_command_exit_value = execute_coproc (command, pipe_in, pipe_out, fds_to_close)); -#endif - - user_subshell = command->type == cm_subshell || ((command->flags & CMD_WANT_SUBSHELL) != 0); - -#if defined (TIME_BEFORE_SUBSHELL) - if ((command->flags & CMD_TIME_PIPELINE) && user_subshell && asynchronous == 0) - { - command->flags |= CMD_FORCE_SUBSHELL; - exec_result = time_command (command, asynchronous, pipe_in, pipe_out, fds_to_close); - currently_executing_command = (COMMAND *)NULL; - return (exec_result); - } -#endif - - if (command->type == cm_subshell || - (command->flags & (CMD_WANT_SUBSHELL|CMD_FORCE_SUBSHELL)) || - (shell_control_structure (command->type) && - (pipe_out != NO_PIPE || pipe_in != NO_PIPE || asynchronous))) - { - pid_t paren_pid; - int s; - char *p; - - /* Fork a subshell, turn off the subshell bit, turn off job - control and call execute_command () on the command again. */ - save_line_number = line_number; - if (command->type == cm_subshell) - SET_LINE_NUMBER (command->value.Subshell->line); /* XXX - save value? */ - /* Otherwise we defer setting line_number */ - tcmd = make_command_string (command); - fork_flags = asynchronous ? FORK_ASYNC : 0; - paren_pid = make_child (p = savestring (tcmd), fork_flags); - - if (user_subshell && signal_is_trapped (ERROR_TRAP) && - signal_in_progress (DEBUG_TRAP) == 0 && running_trap == 0) - { - FREE (the_printed_command_except_trap); - the_printed_command_except_trap = savestring (the_printed_command); - } - - if (paren_pid == 0) - { -#if defined (JOB_CONTROL) - FREE (p); /* child doesn't use pointer */ -#endif - /* We want to run the exit trap for forced {} subshells, and we - want to note this before execute_in_subshell modifies the - COMMAND struct. Need to keep in mind that execute_in_subshell - runs the exit trap for () subshells itself. */ - /* This handles { command; } & */ - s = user_subshell == 0 && command->type == cm_group && pipe_in == NO_PIPE && pipe_out == NO_PIPE && asynchronous; - /* run exit trap for : | { ...; } and { ...; } | : */ - /* run exit trap for : | ( ...; ) and ( ...; ) | : */ - s += user_subshell == 0 && command->type == cm_group && (pipe_in != NO_PIPE || pipe_out != NO_PIPE) && asynchronous == 0; - - last_command_exit_value = execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close); - if (s) - subshell_exit (last_command_exit_value); - else - sh_exit (last_command_exit_value); - /* NOTREACHED */ - } - else - { - close_pipes (pipe_in, pipe_out); - -#if defined (PROCESS_SUBSTITUTION) && defined (HAVE_DEV_FD) - if (variable_context == 0) /* wait until shell function completes */ - unlink_fifo_list (); -#endif - /* If we are part of a pipeline, and not the end of the pipeline, - then we should simply return and let the last command in the - pipe be waited for. If we are not in a pipeline, or are the - last command in the pipeline, then we wait for the subshell - and return its exit status as usual. */ - if (pipe_out != NO_PIPE) - return (EXECUTION_SUCCESS); - - stop_pipeline (asynchronous, (COMMAND *)NULL); - - line_number = save_line_number; - - if (asynchronous == 0) - { - was_error_trap = signal_is_trapped (ERROR_TRAP) && signal_is_ignored (ERROR_TRAP) == 0; - invert = (command->flags & CMD_INVERT_RETURN) != 0; - ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0; - - exec_result = wait_for (paren_pid, 0); - - /* If we have to, invert the return value. */ - if (invert) - exec_result = ((exec_result == EXECUTION_SUCCESS) - ? EXECUTION_FAILURE - : EXECUTION_SUCCESS); - - last_command_exit_value = exec_result; - if (user_subshell && was_error_trap && ignore_return == 0 && invert == 0 && exec_result != EXECUTION_SUCCESS) - { - save_line_number = line_number; - line_number = line_number_for_err_trap; - run_error_trap (); - line_number = save_line_number; - } - - if (user_subshell && ignore_return == 0 && invert == 0 && exit_immediately_on_error && exec_result != EXECUTION_SUCCESS) - { - run_pending_traps (); - jump_to_top_level (ERREXIT); - } - - return (last_command_exit_value); - } - else - { - DESCRIBE_PID (paren_pid); - - run_pending_traps (); - - /* Posix 2013 2.9.3.1: "the exit status of an asynchronous list - shall be zero." */ - last_command_exit_value = 0; - return (EXECUTION_SUCCESS); - } - } - } - -#if defined (COMMAND_TIMING) - if (command->flags & CMD_TIME_PIPELINE) - { - if (asynchronous) - { - command->flags |= CMD_FORCE_SUBSHELL; - exec_result = execute_command_internal (command, 1, pipe_in, pipe_out, fds_to_close); - } - else - { - exec_result = time_command (command, asynchronous, pipe_in, pipe_out, fds_to_close); -#if 0 - if (running_trap == 0) -#endif - currently_executing_command = (COMMAND *)NULL; - } - return (exec_result); - } -#endif /* COMMAND_TIMING */ - - if (shell_control_structure (command->type) && command->redirects) - stdin_redir = stdin_redirects (command->redirects); - -#if defined (PROCESS_SUBSTITUTION) -# if !defined (HAVE_DEV_FD) - reap_procsubs (); -# endif - - /* XXX - also if sourcelevel != 0? */ - if (variable_context != 0 || executing_list) - { - ofifo = num_fifos (); - ofifo_list = copy_fifo_list ((int *)&osize); - begin_unwind_frame ("internal_fifos"); - if (ofifo_list) - add_unwind_protect (xfree, ofifo_list); - saved_fifo = 1; - } - else - saved_fifo = 0; -#endif - - /* Handle WHILE FOR CASE etc. with redirections. (Also '&' input - redirection.) */ - was_error_trap = signal_is_trapped (ERROR_TRAP) && signal_is_ignored (ERROR_TRAP) == 0; - ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0; - - if (do_redirections (command->redirects, RX_ACTIVE|RX_UNDOABLE) != 0) - { - undo_partial_redirects (); - dispose_exec_redirects (); -#if defined (PROCESS_SUBSTITUTION) - if (saved_fifo) - { - free ((void *)ofifo_list); - discard_unwind_frame ("internal_fifos"); - } -#endif - - /* Handle redirection error as command failure if errexit set. */ - last_command_exit_value = EXECUTION_FAILURE; - if (ignore_return == 0 && invert == 0 && pipe_in == NO_PIPE && pipe_out == NO_PIPE) - { - if (was_error_trap) - { - save_line_number = line_number; - line_number = line_number_for_err_trap; - run_error_trap (); - line_number = save_line_number; - } - if (exit_immediately_on_error) - { - run_pending_traps (); - jump_to_top_level (ERREXIT); - } - } - return (last_command_exit_value); - } - - my_undo_list = redirection_undo_list; - redirection_undo_list = (REDIRECT *)NULL; - - exec_undo_list = exec_redirection_undo_list; - exec_redirection_undo_list = (REDIRECT *)NULL; - - if (my_undo_list || exec_undo_list) - begin_unwind_frame ("loop_redirections"); - - if (my_undo_list) - add_unwind_protect ((Function *)cleanup_redirects, my_undo_list); - - if (exec_undo_list) - add_unwind_protect ((Function *)dispose_redirects, exec_undo_list); - - QUIT; - - switch (command->type) - { - case cm_simple: - { - save_line_number = line_number; - /* We can't rely on variables retaining their values across a - call to execute_simple_command if a longjmp occurs as the - result of a `return' builtin. This is true for sure with gcc. */ -#if defined (RECYCLES_PIDS) - last_made_pid = NO_PID; -#endif - was_error_trap = signal_is_trapped (ERROR_TRAP) && signal_is_ignored (ERROR_TRAP) == 0; - - if (ignore_return && command->value.Simple) - command->value.Simple->flags |= CMD_IGNORE_RETURN; - if (command->flags & CMD_STDIN_REDIR) - command->value.Simple->flags |= CMD_STDIN_REDIR; - - SET_LINE_NUMBER (command->value.Simple->line); - exec_result = - execute_simple_command (command->value.Simple, pipe_in, pipe_out, - asynchronous, fds_to_close); - line_number = save_line_number; - - /* The temporary environment should be used for only the simple - command immediately following its definition. */ - dispose_used_env_vars (); - -#if (defined (ultrix) && defined (mips)) || defined (C_ALLOCA) - /* Reclaim memory allocated with alloca () on machines which - may be using the alloca emulation code. */ - (void) alloca (0); -#endif /* (ultrix && mips) || C_ALLOCA */ - - /* If we forked to do the command, then we must wait_for () - the child. */ - - /* XXX - this is something to watch out for if there are problems - when the shell is compiled without job control. Don't worry about - whether or not last_made_pid == last_pid; already_making_children - tells us whether or not there are unwaited-for children to wait - for and reap. */ - if (already_making_children && pipe_out == NO_PIPE) - { - stop_pipeline (asynchronous, (COMMAND *)NULL); - - if (asynchronous) - { - DESCRIBE_PID (last_made_pid); - exec_result = EXECUTION_SUCCESS; - invert = 0; /* async commands always succeed */ - } - else -#if !defined (JOB_CONTROL) - /* Do not wait for asynchronous processes started from - startup files. */ - if (last_made_pid != NO_PID && last_made_pid != last_asynchronous_pid) -#else - if (last_made_pid != NO_PID) -#endif - /* When executing a shell function that executes other - commands, this causes the last simple command in - the function to be waited for twice. This also causes - subshells forked to execute builtin commands (e.g., in - pipelines) to be waited for twice. */ - exec_result = wait_for (last_made_pid, 0); - } - } - - /* 2009/02/13 -- pipeline failure is processed elsewhere. This handles - only the failure of a simple command. We don't want to run the error - trap if the command run by the `command' builtin fails; we want to - defer that until the command builtin itself returns failure. */ - /* 2020/07/14 -- this changes with how the command builtin is handled */ - if (was_error_trap && ignore_return == 0 && invert == 0 && - pipe_in == NO_PIPE && pipe_out == NO_PIPE && - (command->value.Simple->flags & CMD_COMMAND_BUILTIN) == 0 && - exec_result != EXECUTION_SUCCESS) - { - last_command_exit_value = exec_result; - line_number = line_number_for_err_trap; - run_error_trap (); - line_number = save_line_number; - } - - if (ignore_return == 0 && invert == 0 && - ((posixly_correct && interactive == 0 && special_builtin_failed) || - (exit_immediately_on_error && pipe_in == NO_PIPE && pipe_out == NO_PIPE && exec_result != EXECUTION_SUCCESS))) - { - last_command_exit_value = exec_result; - run_pending_traps (); - - /* Undo redirections before running exit trap on the way out of - set -e. Report by Mark Farrell 5/19/2014 */ - if (exit_immediately_on_error && signal_is_trapped (0) && - unwind_protect_tag_on_stack ("saved-redirects")) - run_unwind_frame ("saved-redirects"); - - jump_to_top_level (ERREXIT); - } - - break; - - case cm_for: - if (ignore_return) - command->value.For->flags |= CMD_IGNORE_RETURN; - exec_result = execute_for_command (command->value.For); - break; - -#if defined (ARITH_FOR_COMMAND) - case cm_arith_for: - if (ignore_return) - command->value.ArithFor->flags |= CMD_IGNORE_RETURN; - exec_result = execute_arith_for_command (command->value.ArithFor); - break; -#endif - -#if defined (SELECT_COMMAND) - case cm_select: - if (ignore_return) - command->value.Select->flags |= CMD_IGNORE_RETURN; - exec_result = execute_select_command (command->value.Select); - break; -#endif - - case cm_case: - if (ignore_return) - command->value.Case->flags |= CMD_IGNORE_RETURN; - exec_result = execute_case_command (command->value.Case); - break; - - case cm_while: - if (ignore_return) - command->value.While->flags |= CMD_IGNORE_RETURN; - exec_result = execute_while_command (command->value.While); - break; - - case cm_until: - if (ignore_return) - command->value.While->flags |= CMD_IGNORE_RETURN; - exec_result = execute_until_command (command->value.While); - break; - - case cm_if: - if (ignore_return) - command->value.If->flags |= CMD_IGNORE_RETURN; - exec_result = execute_if_command (command->value.If); - break; - - case cm_group: - - /* This code can be executed from either of two paths: an explicit - '{}' command, or via a function call. If we are executed via a - function call, we have already taken care of the function being - executed in the background (down there in execute_simple_command ()), - and this command should *not* be marked as asynchronous. If we - are executing a regular '{}' group command, and asynchronous == 1, - we must want to execute the whole command in the background, so we - need a subshell, and we want the stuff executed in that subshell - (this group command) to be executed in the foreground of that - subshell (i.e. there will not be *another* subshell forked). - - What we do is to force a subshell if asynchronous, and then call - execute_command_internal again with asynchronous still set to 1, - but with the original group command, so the printed command will - look right. - - The code above that handles forking off subshells will note that - both subshell and async are on, and turn off async in the child - after forking the subshell (but leave async set in the parent, so - the normal call to describe_pid is made). This turning off - async is *crucial*; if it is not done, this will fall into an - infinite loop of executions through this spot in subshell after - subshell until the process limit is exhausted. */ - - if (asynchronous) - { - command->flags |= CMD_FORCE_SUBSHELL; - exec_result = - execute_command_internal (command, 1, pipe_in, pipe_out, - fds_to_close); - } - else - { - if (ignore_return && command->value.Group->command) - command->value.Group->command->flags |= CMD_IGNORE_RETURN; - exec_result = - execute_command_internal (command->value.Group->command, - asynchronous, pipe_in, pipe_out, - fds_to_close); - } - break; - - case cm_connection: - exec_result = execute_connection (command, asynchronous, - pipe_in, pipe_out, fds_to_close); - if (asynchronous) - invert = 0; /* XXX */ - - break; - -#if defined (DPAREN_ARITHMETIC) - case cm_arith: -#endif -#if defined (COND_COMMAND) - case cm_cond: -#endif - case cm_function_def: - was_error_trap = signal_is_trapped (ERROR_TRAP) && signal_is_ignored (ERROR_TRAP) == 0; -#if defined (DPAREN_ARITHMETIC) - if (ignore_return && command->type == cm_arith) - command->value.Arith->flags |= CMD_IGNORE_RETURN; -#endif -#if defined (COND_COMMAND) - if (ignore_return && command->type == cm_cond) - command->value.Cond->flags |= CMD_IGNORE_RETURN; -#endif - - line_number_for_err_trap = save_line_number = line_number; /* XXX */ -#if defined (DPAREN_ARITHMETIC) - if (command->type == cm_arith) - exec_result = execute_arith_command (command->value.Arith); - else -#endif -#if defined (COND_COMMAND) - if (command->type == cm_cond) - exec_result = execute_cond_command (command->value.Cond); - else -#endif - if (command->type == cm_function_def) - exec_result = execute_intern_function (command->value.Function_def->name, - command->value.Function_def); - line_number = save_line_number; - - if (was_error_trap && ignore_return == 0 && invert == 0 && exec_result != EXECUTION_SUCCESS) - { - last_command_exit_value = exec_result; - save_line_number = line_number; - line_number = line_number_for_err_trap; - run_error_trap (); - line_number = save_line_number; - } - - if (ignore_return == 0 && invert == 0 && exit_immediately_on_error && exec_result != EXECUTION_SUCCESS) - { - last_command_exit_value = exec_result; - run_pending_traps (); - jump_to_top_level (ERREXIT); - } - - break; - - default: - command_error ("execute_command", CMDERR_BADTYPE, command->type, 0); - } - - if (my_undo_list) - cleanup_redirects (my_undo_list); - - if (exec_undo_list) - dispose_redirects (exec_undo_list); - - if (my_undo_list || exec_undo_list) - discard_unwind_frame ("loop_redirections"); - -#if defined (PROCESS_SUBSTITUTION) - if (saved_fifo) - { - nfifo = num_fifos (); - if (nfifo > ofifo) - close_new_fifos ((void *)ofifo_list, osize); - free ((void *)ofifo_list); - discard_unwind_frame ("internal_fifos"); - } -#endif - - /* Invert the return value if we have to */ - if (invert) - exec_result = (exec_result == EXECUTION_SUCCESS) - ? EXECUTION_FAILURE - : EXECUTION_SUCCESS; - -#if defined (DPAREN_ARITHMETIC) || defined (COND_COMMAND) - /* This is where we set PIPESTATUS from the exit status of the appropriate - compound commands (the ones that look enough like simple commands to - cause confusion). We might be able to optimize by not doing this if - subshell_environment != 0. */ - switch (command->type) - { -# if defined (DPAREN_ARITHMETIC) - case cm_arith: -# endif -# if defined (COND_COMMAND) - case cm_cond: -# endif - set_pipestatus_from_exit (exec_result); - break; - default: - break; - } -#endif - - last_command_exit_value = exec_result; - run_pending_traps (); - currently_executing_command = (COMMAND *)NULL; - - return (last_command_exit_value); -} - -#if defined (COMMAND_TIMING) - -#if defined (HAVE_GETRUSAGE) && defined (HAVE_GETTIMEOFDAY) -extern struct timeval *difftimeval PARAMS((struct timeval *, struct timeval *, struct timeval *)); -extern struct timeval *addtimeval PARAMS((struct timeval *, struct timeval *, struct timeval *)); -extern int timeval_to_cpu PARAMS((struct timeval *, struct timeval *, struct timeval *)); -#endif - -#define POSIX_TIMEFORMAT "real %2R\nuser %2U\nsys %2S" -#define BASH_TIMEFORMAT "\nreal\t%3lR\nuser\t%3lU\nsys\t%3lS" - -static const int precs[] = { 0, 100, 10, 1 }; - -/* Expand one `%'-prefixed escape sequence from a time format string. */ -static int -mkfmt (buf, prec, lng, sec, sec_fraction) - char *buf; - int prec, lng; - time_t sec; - int sec_fraction; -{ - time_t min; - char abuf[INT_STRLEN_BOUND(time_t) + 1]; - int ind, aind; - - ind = 0; - abuf[sizeof(abuf) - 1] = '\0'; - - /* If LNG is non-zero, we want to decompose SEC into minutes and seconds. */ - if (lng) - { - min = sec / 60; - sec %= 60; - aind = sizeof(abuf) - 2; - do - abuf[aind--] = (min % 10) + '0'; - while (min /= 10); - aind++; - while (abuf[aind]) - buf[ind++] = abuf[aind++]; - buf[ind++] = 'm'; - } - - /* Now add the seconds. */ - aind = sizeof (abuf) - 2; - do - abuf[aind--] = (sec % 10) + '0'; - while (sec /= 10); - aind++; - while (abuf[aind]) - buf[ind++] = abuf[aind++]; - - /* We want to add a decimal point and PREC places after it if PREC is - nonzero. PREC is not greater than 3. SEC_FRACTION is between 0 - and 999. */ - if (prec != 0) - { - buf[ind++] = locale_decpoint (); - for (aind = 1; aind <= prec; aind++) - { - buf[ind++] = (sec_fraction / precs[aind]) + '0'; - sec_fraction %= precs[aind]; - } - } - - if (lng) - buf[ind++] = 's'; - buf[ind] = '\0'; - - return (ind); -} - -/* Interpret the format string FORMAT, interpolating the following escape - sequences: - %[prec][l][RUS] - - where the optional `prec' is a precision, meaning the number of - characters after the decimal point, the optional `l' means to format - using minutes and seconds (MMmNN[.FF]s), like the `times' builtin', - and the last character is one of - - R number of seconds of `real' time - U number of seconds of `user' time - S number of seconds of `system' time - - An occurrence of `%%' in the format string is translated to a `%'. The - result is printed to FP, a pointer to a FILE. The other variables are - the seconds and thousandths of a second of real, user, and system time, - resectively. */ -static void -print_formatted_time (fp, format, rs, rsf, us, usf, ss, ssf, cpu) - FILE *fp; - char *format; - time_t rs; - int rsf; - time_t us; - int usf; - time_t ss; - int ssf, cpu; -{ - int prec, lng, len; - char *str, *s, ts[INT_STRLEN_BOUND (time_t) + sizeof ("mSS.FFFF")]; - time_t sum; - int sum_frac; - int sindex, ssize; - - len = strlen (format); - ssize = (len + 64) - (len % 64); - str = (char *)xmalloc (ssize); - sindex = 0; - - for (s = format; *s; s++) - { - if (*s != '%' || s[1] == '\0') - { - RESIZE_MALLOCED_BUFFER (str, sindex, 1, ssize, 64); - str[sindex++] = *s; - } - else if (s[1] == '%') - { - s++; - RESIZE_MALLOCED_BUFFER (str, sindex, 1, ssize, 64); - str[sindex++] = *s; - } - else if (s[1] == 'P') - { - s++; -#if 0 - /* clamp CPU usage at 100% */ - if (cpu > 10000) - cpu = 10000; -#endif - sum = cpu / 100; - sum_frac = (cpu % 100) * 10; - len = mkfmt (ts, 2, 0, sum, sum_frac); - RESIZE_MALLOCED_BUFFER (str, sindex, len, ssize, 64); - strcpy (str + sindex, ts); - sindex += len; - } - else - { - prec = 3; /* default is three places past the decimal point. */ - lng = 0; /* default is to not use minutes or append `s' */ - s++; - if (DIGIT (*s)) /* `precision' */ - { - prec = *s++ - '0'; - if (prec > 3) prec = 3; - } - if (*s == 'l') /* `length extender' */ - { - lng = 1; - s++; - } - if (*s == 'R' || *s == 'E') - len = mkfmt (ts, prec, lng, rs, rsf); - else if (*s == 'U') - len = mkfmt (ts, prec, lng, us, usf); - else if (*s == 'S') - len = mkfmt (ts, prec, lng, ss, ssf); - else - { - internal_error (_("TIMEFORMAT: `%c': invalid format character"), *s); - free (str); - return; - } - RESIZE_MALLOCED_BUFFER (str, sindex, len, ssize, 64); - strcpy (str + sindex, ts); - sindex += len; - } - } - - str[sindex] = '\0'; - fprintf (fp, "%s\n", str); - fflush (fp); - - free (str); -} - -static int -time_command (command, asynchronous, pipe_in, pipe_out, fds_to_close) - COMMAND *command; - int asynchronous, pipe_in, pipe_out; - struct fd_bitmap *fds_to_close; -{ - int rv, posix_time, old_flags, nullcmd, code; - time_t rs, us, ss; - int rsf, usf, ssf; - int cpu; - char *time_format; - volatile procenv_t save_top_level; - volatile int old_subshell; - -#if defined (HAVE_GETRUSAGE) && defined (HAVE_GETTIMEOFDAY) - struct timeval real, user, sys; - struct timeval before, after; -# if defined (HAVE_STRUCT_TIMEZONE) - struct timezone dtz; /* posix doesn't define this */ -# endif - struct rusage selfb, selfa, kidsb, kidsa; /* a = after, b = before */ -#else -# if defined (HAVE_TIMES) - clock_t tbefore, tafter, real, user, sys; - struct tms before, after; -# endif -#endif - -#if defined (HAVE_GETRUSAGE) && defined (HAVE_GETTIMEOFDAY) -# if defined (HAVE_STRUCT_TIMEZONE) - gettimeofday (&before, &dtz); -# else - gettimeofday (&before, (void *)NULL); -# endif /* !HAVE_STRUCT_TIMEZONE */ - getrusage (RUSAGE_SELF, &selfb); - getrusage (RUSAGE_CHILDREN, &kidsb); -#else -# if defined (HAVE_TIMES) - tbefore = times (&before); -# endif -#endif - - old_subshell = subshell_environment; - posix_time = command && (command->flags & CMD_TIME_POSIX); - - nullcmd = (command == 0) || (command->type == cm_simple && command->value.Simple->words == 0 && command->value.Simple->redirects == 0); - if (posixly_correct && nullcmd) - { -#if defined (HAVE_GETRUSAGE) - selfb.ru_utime.tv_sec = kidsb.ru_utime.tv_sec = selfb.ru_stime.tv_sec = kidsb.ru_stime.tv_sec = 0; - selfb.ru_utime.tv_usec = kidsb.ru_utime.tv_usec = selfb.ru_stime.tv_usec = kidsb.ru_stime.tv_usec = 0; - before = shellstart; -#else - before.tms_utime = before.tms_stime = before.tms_cutime = before.tms_cstime = 0; - tbefore = shell_start_time; -#endif - } - - old_flags = command->flags; - COPY_PROCENV (top_level, save_top_level); - command->flags &= ~(CMD_TIME_PIPELINE|CMD_TIME_POSIX); - code = setjmp_nosigs (top_level); - if (code == NOT_JUMPED) - rv = execute_command_internal (command, asynchronous, pipe_in, pipe_out, fds_to_close); - COPY_PROCENV (save_top_level, top_level); - - command->flags = old_flags; - - /* If we're jumping in a different subshell environment than we started, - don't bother printing timing stats, just keep longjmping back to the - original top level. */ - if (code != NOT_JUMPED && subshell_environment && subshell_environment != old_subshell) - sh_longjmp (top_level, code); - - rs = us = ss = 0; - rsf = usf = ssf = cpu = 0; - -#if defined (HAVE_GETRUSAGE) && defined (HAVE_GETTIMEOFDAY) -# if defined (HAVE_STRUCT_TIMEZONE) - gettimeofday (&after, &dtz); -# else - gettimeofday (&after, (void *)NULL); -# endif /* !HAVE_STRUCT_TIMEZONE */ - getrusage (RUSAGE_SELF, &selfa); - getrusage (RUSAGE_CHILDREN, &kidsa); - - difftimeval (&real, &before, &after); - timeval_to_secs (&real, &rs, &rsf); - - addtimeval (&user, difftimeval(&after, &selfb.ru_utime, &selfa.ru_utime), - difftimeval(&before, &kidsb.ru_utime, &kidsa.ru_utime)); - timeval_to_secs (&user, &us, &usf); - - addtimeval (&sys, difftimeval(&after, &selfb.ru_stime, &selfa.ru_stime), - difftimeval(&before, &kidsb.ru_stime, &kidsa.ru_stime)); - timeval_to_secs (&sys, &ss, &ssf); - - cpu = timeval_to_cpu (&real, &user, &sys); -#else -# if defined (HAVE_TIMES) - tafter = times (&after); - - real = tafter - tbefore; - clock_t_to_secs (real, &rs, &rsf); - - user = (after.tms_utime - before.tms_utime) + (after.tms_cutime - before.tms_cutime); - clock_t_to_secs (user, &us, &usf); - - sys = (after.tms_stime - before.tms_stime) + (after.tms_cstime - before.tms_cstime); - clock_t_to_secs (sys, &ss, &ssf); - - cpu = (real == 0) ? 0 : ((user + sys) * 10000) / real; - -# else - rs = us = ss = 0; - rsf = usf = ssf = cpu = 0; -# endif -#endif - - if (posix_time) - time_format = POSIX_TIMEFORMAT; - else if ((time_format = get_string_value ("TIMEFORMAT")) == 0) - { - if (posixly_correct && nullcmd) - time_format = "user\t%2lU\nsys\t%2lS"; - else - time_format = BASH_TIMEFORMAT; - } - - if (time_format && *time_format) - print_formatted_time (stderr, time_format, rs, rsf, us, usf, ss, ssf, cpu); - - if (code) - sh_longjmp (top_level, code); - - return rv; -} -#endif /* COMMAND_TIMING */ - -/* Execute a command that's supposed to be in a subshell. This must be - called after make_child and we must be running in the child process. - The caller will return or exit() immediately with the value this returns. */ -static int -execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close) - COMMAND *command; - int asynchronous; - int pipe_in, pipe_out; - struct fd_bitmap *fds_to_close; -{ - volatile int user_subshell, user_coproc, invert; - int return_code, function_value, should_redir_stdin, ois, result; - volatile COMMAND *tcom; - - USE_VAR(user_subshell); - USE_VAR(user_coproc); - USE_VAR(invert); - USE_VAR(tcom); - USE_VAR(asynchronous); - - subshell_level++; - should_redir_stdin = (asynchronous && (command->flags & CMD_STDIN_REDIR) && - pipe_in == NO_PIPE && - stdin_redirects (command->redirects) == 0); - - invert = (command->flags & CMD_INVERT_RETURN) != 0; - user_subshell = command->type == cm_subshell || ((command->flags & CMD_WANT_SUBSHELL) != 0); - user_coproc = command->type == cm_coproc; - - command->flags &= ~(CMD_FORCE_SUBSHELL | CMD_WANT_SUBSHELL | CMD_INVERT_RETURN); - - /* If a command is asynchronous in a subshell (like ( foo ) & or - the special case of an asynchronous GROUP command where the - - the subshell bit is turned on down in case cm_group: below), - turn off `asynchronous', so that two subshells aren't spawned. - XXX - asynchronous used to be set to 0 in this block, but that - means that setup_async_signals was never run. Now it's set to - 0 after subshell_environment is set appropriately and setup_async_signals - is run. - - This seems semantically correct to me. For example, - ( foo ) & seems to say ``do the command `foo' in a subshell - environment, but don't wait for that subshell to finish'', - and "{ foo ; bar ; } &" seems to me to be like functions or - builtins in the background, which executed in a subshell - environment. I just don't see the need to fork two subshells. */ - - /* Don't fork again, we are already in a subshell. A `doubly - async' shell is not interactive, however. */ - if (asynchronous) - { -#if defined (JOB_CONTROL) - /* If a construct like ( exec xxx yyy ) & is given while job - control is active, we want to prevent exec from putting the - subshell back into the original process group, carefully - undoing all the work we just did in make_child. */ - original_pgrp = -1; -#endif /* JOB_CONTROL */ - ois = interactive_shell; - interactive_shell = 0; - /* This test is to prevent alias expansion by interactive shells that - run `(command) &' but to allow scripts that have enabled alias - expansion with `shopt -s expand_alias' to continue to expand - aliases. */ - if (ois != interactive_shell) - expand_aliases = 0; - } - - /* Subshells are neither login nor interactive. */ - login_shell = interactive = 0; - - /* And we're no longer in a loop. See Posix interp 842 (we are not in the - "same execution environment"). */ - if (shell_compatibility_level > 44) - loop_level = 0; - - if (user_subshell) - { - subshell_environment = SUBSHELL_PAREN; /* XXX */ - if (asynchronous) - subshell_environment |= SUBSHELL_ASYNC; - } - else - { - subshell_environment = 0; /* XXX */ - if (asynchronous) - subshell_environment |= SUBSHELL_ASYNC; - if (pipe_in != NO_PIPE || pipe_out != NO_PIPE) - subshell_environment |= SUBSHELL_PIPE; - if (user_coproc) - subshell_environment |= SUBSHELL_COPROC; - } - - QUIT; - CHECK_TERMSIG; - - reset_terminating_signals (); /* in sig.c */ - /* Cancel traps, in trap.c. */ - /* Reset the signal handlers in the child, but don't free the - trap strings. Set a flag noting that we have to free the - trap strings if we run trap to change a signal disposition. */ - clear_pending_traps (); - reset_signal_handlers (); - subshell_environment |= SUBSHELL_RESETTRAP; - /* Note that signal handlers have been reset, so we should no longer - reset the handler and resend trapped signals to ourselves. */ - subshell_environment &= ~SUBSHELL_IGNTRAP; - - /* We are in a subshell, so forget that we are running a trap handler or - that the signal handler has changed (we haven't changed it!) */ - /* XXX - maybe do this for `real' signals and not ERR/DEBUG/RETURN/EXIT - traps? */ - if (running_trap > 0) - { - run_trap_cleanup (running_trap - 1); - running_trap = 0; /* XXX - maybe leave this */ - } - - /* Make sure restore_original_signals doesn't undo the work done by - make_child to ensure that asynchronous children are immune to SIGINT - and SIGQUIT. Turn off asynchronous to make sure more subshells are - not spawned. */ - if (asynchronous) - { - setup_async_signals (); - asynchronous = 0; - } - else - set_sigint_handler (); - -#if defined (JOB_CONTROL) - set_sigchld_handler (); -#endif /* JOB_CONTROL */ - - /* Delete all traces that there were any jobs running. This is - only for subshells. */ - without_job_control (); - - if (fds_to_close) - close_fd_bitmap (fds_to_close); - - do_piping (pipe_in, pipe_out); - -#if defined (COPROCESS_SUPPORT) - coproc_closeall (); -#endif - -#if defined (PROCESS_SUBSTITUTION) - clear_fifo_list (); /* XXX- we haven't created any FIFOs */ -#endif - - /* If this is a user subshell, set a flag if stdin was redirected. - This is used later to decide whether to redirect fd 0 to - /dev/null for async commands in the subshell. This adds more - sh compatibility, but I'm not sure it's the right thing to do. - Note that an input pipe to a compound command suffices to inhibit - the implicit /dev/null redirection for asynchronous commands - executed as part of that compound command. */ - if (user_subshell) - { - stdin_redir = stdin_redirects (command->redirects) || pipe_in != NO_PIPE; -#if 0 - restore_default_signal (EXIT_TRAP); /* XXX - reset_signal_handlers above */ -#endif - } - else if (shell_control_structure (command->type) && pipe_in != NO_PIPE) - stdin_redir = 1; - - /* If this is an asynchronous command (command &), we want to - redirect the standard input from /dev/null in the absence of - any specific redirection involving stdin. */ - if (should_redir_stdin && stdin_redir == 0) - async_redirect_stdin (); - -#if defined (BUFFERED_INPUT) - /* In any case, we are not reading our command input from stdin. */ - default_buffered_input = -1; -#endif - - /* We can't optimize away forks if one of the commands executed by the - subshell sets an exit trap, so we set CMD_NO_FORK for simple commands - and set CMD_TRY_OPTIMIZING for simple commands on the right side of an - and-or or `;' list to test for optimizing forks when they are executed. */ - if (user_subshell && command->type == cm_subshell) - optimize_subshell_command (command->value.Subshell->command); - - /* Do redirections, then dispose of them before recursive call. */ - if (command->redirects) - { - if (do_redirections (command->redirects, RX_ACTIVE) != 0) - exit (invert ? EXECUTION_SUCCESS : EXECUTION_FAILURE); - - dispose_redirects (command->redirects); - command->redirects = (REDIRECT *)NULL; - } - - if (command->type == cm_subshell) - tcom = command->value.Subshell->command; - else if (user_coproc) - tcom = command->value.Coproc->command; - else - tcom = command; - - if (command->flags & CMD_TIME_PIPELINE) - tcom->flags |= CMD_TIME_PIPELINE; - if (command->flags & CMD_TIME_POSIX) - tcom->flags |= CMD_TIME_POSIX; - - /* Make sure the subshell inherits any CMD_IGNORE_RETURN flag. */ - if ((command->flags & CMD_IGNORE_RETURN) && tcom != command) - tcom->flags |= CMD_IGNORE_RETURN; - - /* If this is a simple command, tell execute_disk_command that it - might be able to get away without forking and simply exec. - This means things like ( sleep 10 ) will only cause one fork. - If we're timing the command or inverting its return value, however, - we cannot do this optimization. */ - if ((user_subshell || user_coproc) && (tcom->type == cm_simple || tcom->type == cm_subshell) && - ((tcom->flags & CMD_TIME_PIPELINE) == 0) && - ((tcom->flags & CMD_INVERT_RETURN) == 0)) - { - tcom->flags |= CMD_NO_FORK; - if (tcom->type == cm_simple) - tcom->value.Simple->flags |= CMD_NO_FORK; - } - - invert = (tcom->flags & CMD_INVERT_RETURN) != 0; - tcom->flags &= ~CMD_INVERT_RETURN; - - result = setjmp_nosigs (top_level); - - /* If we're inside a function while executing this subshell, we - need to handle a possible `return'. */ - function_value = 0; - if (return_catch_flag) - function_value = setjmp_nosigs (return_catch); - - /* If we're going to exit the shell, we don't want to invert the return - status. */ - if (result == EXITPROG || result == EXITBLTIN) - invert = 0, return_code = last_command_exit_value; - else if (result) - return_code = (last_command_exit_value == EXECUTION_SUCCESS) ? EXECUTION_FAILURE : last_command_exit_value; - else if (function_value) - return_code = return_catch_value; - else - return_code = execute_command_internal ((COMMAND *)tcom, asynchronous, NO_PIPE, NO_PIPE, fds_to_close); - - /* If we are asked to, invert the return value. */ - if (invert) - return_code = (return_code == EXECUTION_SUCCESS) ? EXECUTION_FAILURE - : EXECUTION_SUCCESS; - - - /* If we were explicitly placed in a subshell with (), we need - to do the `shell cleanup' things, such as running traps[0]. */ - if (user_subshell && signal_is_trapped (0)) - { - last_command_exit_value = return_code; - return_code = run_exit_trap (); - } - -#if 0 - subshell_level--; /* don't bother, caller will just exit */ -#endif - return (return_code); - /* NOTREACHED */ -} - -#if defined (COPROCESS_SUPPORT) -#define COPROC_MAX 16 - -typedef struct cpelement - { - struct cpelement *next; - struct coproc *coproc; - } -cpelement_t; - -typedef struct cplist - { - struct cpelement *head; - struct cpelement *tail; - int ncoproc; - int lock; - } -cplist_t; - -static struct cpelement *cpe_alloc PARAMS((struct coproc *)); -static void cpe_dispose PARAMS((struct cpelement *)); -static struct cpelement *cpl_add PARAMS((struct coproc *)); -static struct cpelement *cpl_delete PARAMS((pid_t)); -static void cpl_reap PARAMS((void)); -static void cpl_flush PARAMS((void)); -static void cpl_closeall PARAMS((void)); -static struct cpelement *cpl_search PARAMS((pid_t)); -static struct cpelement *cpl_searchbyname PARAMS((const char *)); -static void cpl_prune PARAMS((void)); - -static void coproc_free PARAMS((struct coproc *)); - -/* Will go away when there is fully-implemented support for multiple coprocs. */ -Coproc sh_coproc = { 0, NO_PID, -1, -1, 0, 0, 0, 0, 0 }; - -cplist_t coproc_list = {0, 0, 0}; - -/* Functions to manage the list of coprocs */ - -static struct cpelement * -cpe_alloc (cp) - Coproc *cp; -{ - struct cpelement *cpe; - - cpe = (struct cpelement *)xmalloc (sizeof (struct cpelement)); - cpe->coproc = cp; - cpe->next = (struct cpelement *)0; - return cpe; -} - -static void -cpe_dispose (cpe) - struct cpelement *cpe; -{ - free (cpe); -} - -static struct cpelement * -cpl_add (cp) - Coproc *cp; -{ - struct cpelement *cpe; - - cpe = cpe_alloc (cp); - - if (coproc_list.head == 0) - { - coproc_list.head = coproc_list.tail = cpe; - coproc_list.ncoproc = 0; /* just to make sure */ - } - else - { - coproc_list.tail->next = cpe; - coproc_list.tail = cpe; - } - coproc_list.ncoproc++; - - return cpe; -} - -static struct cpelement * -cpl_delete (pid) - pid_t pid; -{ - struct cpelement *prev, *p; - - for (prev = p = coproc_list.head; p; prev = p, p = p->next) - if (p->coproc->c_pid == pid) - { - prev->next = p->next; /* remove from list */ - break; - } - - if (p == 0) - return 0; /* not found */ - - INTERNAL_DEBUG (("cpl_delete: deleting %d", pid)); - - /* Housekeeping in the border cases. */ - if (p == coproc_list.head) - coproc_list.head = coproc_list.head->next; - else if (p == coproc_list.tail) - coproc_list.tail = prev; - - coproc_list.ncoproc--; - if (coproc_list.ncoproc == 0) - coproc_list.head = coproc_list.tail = 0; - else if (coproc_list.ncoproc == 1) - coproc_list.tail = coproc_list.head; /* just to make sure */ - - return (p); -} - -static void -cpl_reap () -{ - struct cpelement *p, *next, *nh, *nt; - - /* Build a new list by removing dead coprocs and fix up the coproc_list - pointers when done. */ - nh = nt = next = (struct cpelement *)0; - for (p = coproc_list.head; p; p = next) - { - next = p->next; - if (p->coproc->c_flags & COPROC_DEAD) - { - coproc_list.ncoproc--; /* keep running count, fix up pointers later */ - INTERNAL_DEBUG (("cpl_reap: deleting %d", p->coproc->c_pid)); - coproc_dispose (p->coproc); - cpe_dispose (p); - } - else if (nh == 0) - nh = nt = p; - else - { - nt->next = p; - nt = nt->next; - } - } - - if (coproc_list.ncoproc == 0) - coproc_list.head = coproc_list.tail = 0; - else - { - if (nt) - nt->next = 0; - coproc_list.head = nh; - coproc_list.tail = nt; - if (coproc_list.ncoproc == 1) - coproc_list.tail = coproc_list.head; /* just to make sure */ - } -} - -/* Clear out the list of saved statuses */ -static void -cpl_flush () -{ - struct cpelement *cpe, *p; - - for (cpe = coproc_list.head; cpe; ) - { - p = cpe; - cpe = cpe->next; - - coproc_dispose (p->coproc); - cpe_dispose (p); - } - - coproc_list.head = coproc_list.tail = 0; - coproc_list.ncoproc = 0; -} - -static void -cpl_closeall () -{ - struct cpelement *cpe; - - for (cpe = coproc_list.head; cpe; cpe = cpe->next) - coproc_close (cpe->coproc); -} - -static void -cpl_fdchk (fd) - int fd; -{ - struct cpelement *cpe; - - for (cpe = coproc_list.head; cpe; cpe = cpe->next) - coproc_checkfd (cpe->coproc, fd); -} - -/* Search for PID in the list of coprocs; return the cpelement struct if - found. If not found, return NULL. */ -static struct cpelement * -cpl_search (pid) - pid_t pid; -{ - struct cpelement *cpe; - - for (cpe = coproc_list.head ; cpe; cpe = cpe->next) - if (cpe->coproc->c_pid == pid) - return cpe; - return (struct cpelement *)NULL; -} - -/* Search for the coproc named NAME in the list of coprocs; return the - cpelement struct if found. If not found, return NULL. */ -static struct cpelement * -cpl_searchbyname (name) - const char *name; -{ - struct cpelement *cp; - - for (cp = coproc_list.head ; cp; cp = cp->next) - if (STREQ (cp->coproc->c_name, name)) - return cp; - return (struct cpelement *)NULL; -} - -static pid_t -cpl_firstactive () -{ - struct cpelement *cpe; - - for (cpe = coproc_list.head ; cpe; cpe = cpe->next) - if ((cpe->coproc->c_flags & COPROC_DEAD) == 0) - return cpe->coproc->c_pid; - return (pid_t)NO_PID; -} - -#if 0 -static void -cpl_prune () -{ - struct cpelement *cp; - - while (coproc_list.head && coproc_list.ncoproc > COPROC_MAX) - { - cp = coproc_list.head; - coproc_list.head = coproc_list.head->next; - coproc_dispose (cp->coproc); - cpe_dispose (cp); - coproc_list.ncoproc--; - } -} -#endif - -/* These currently use a single global "shell coproc" but are written in a - way to not preclude additional coprocs later (using the list management - package above). */ - -struct coproc * -getcoprocbypid (pid) - pid_t pid; -{ -#if MULTIPLE_COPROCS - struct cpelement *p; - - p = cpl_search (pid); - return (p ? p->coproc : 0); -#else - return (pid == sh_coproc.c_pid ? &sh_coproc : 0); -#endif -} - -struct coproc * -getcoprocbyname (name) - const char *name; -{ -#if MULTIPLE_COPROCS - struct cpelement *p; - - p = cpl_searchbyname (name); - return (p ? p->coproc : 0); -#else - return ((sh_coproc.c_name && STREQ (sh_coproc.c_name, name)) ? &sh_coproc : 0); -#endif -} - -void -coproc_init (cp) - struct coproc *cp; -{ - cp->c_name = 0; - cp->c_pid = NO_PID; - cp->c_rfd = cp->c_wfd = -1; - cp->c_rsave = cp->c_wsave = -1; - cp->c_flags = cp->c_status = cp->c_lock = 0; -} - -struct coproc * -coproc_alloc (name, pid) - char *name; - pid_t pid; -{ - struct coproc *cp; - -#if MULTIPLE_COPROCS - cp = (struct coproc *)xmalloc (sizeof (struct coproc)); -#else - cp = &sh_coproc; -#endif - coproc_init (cp); - cp->c_lock = 2; - - cp->c_pid = pid; - cp->c_name = savestring (name); -#if MULTIPLE_COPROCS - cpl_add (cp); -#endif - cp->c_lock = 0; - return (cp); -} - -static void -coproc_free (cp) - struct coproc *cp; -{ - free (cp); -} - -void -coproc_dispose (cp) - struct coproc *cp; -{ - sigset_t set, oset; - - if (cp == 0) - return; - - BLOCK_SIGNAL (SIGCHLD, set, oset); - cp->c_lock = 3; - coproc_unsetvars (cp); - FREE (cp->c_name); - coproc_close (cp); -#if MULTIPLE_COPROCS - coproc_free (cp); -#else - coproc_init (cp); - cp->c_lock = 0; -#endif - UNBLOCK_SIGNAL (oset); -} - -/* Placeholder for now. Will require changes for multiple coprocs */ -void -coproc_flush () -{ -#if MULTIPLE_COPROCS - cpl_flush (); -#else - coproc_dispose (&sh_coproc); -#endif -} - -void -coproc_close (cp) - struct coproc *cp; -{ - if (cp->c_rfd >= 0) - { - close (cp->c_rfd); - cp->c_rfd = -1; - } - if (cp->c_wfd >= 0) - { - close (cp->c_wfd); - cp->c_wfd = -1; - } - cp->c_rsave = cp->c_wsave = -1; -} - -void -coproc_closeall () -{ -#if MULTIPLE_COPROCS - cpl_closeall (); -#else - coproc_close (&sh_coproc); /* XXX - will require changes for multiple coprocs */ -#endif -} - -void -coproc_reap () -{ -#if MULTIPLE_COPROCS - cpl_reap (); -#else - struct coproc *cp; - - cp = &sh_coproc; /* XXX - will require changes for multiple coprocs */ - if (cp && (cp->c_flags & COPROC_DEAD)) - coproc_dispose (cp); -#endif -} - -void -coproc_rclose (cp, fd) - struct coproc *cp; - int fd; -{ - if (cp->c_rfd >= 0 && cp->c_rfd == fd) - { - close (cp->c_rfd); - cp->c_rfd = -1; - } -} - -void -coproc_wclose (cp, fd) - struct coproc *cp; - int fd; -{ - if (cp->c_wfd >= 0 && cp->c_wfd == fd) - { - close (cp->c_wfd); - cp->c_wfd = -1; - } -} - -void -coproc_checkfd (cp, fd) - struct coproc *cp; - int fd; -{ - int update; - - update = 0; - if (cp->c_rfd >= 0 && cp->c_rfd == fd) - update = cp->c_rfd = -1; - if (cp->c_wfd >= 0 && cp->c_wfd == fd) - update = cp->c_wfd = -1; - if (update) - coproc_setvars (cp); -} - -void -coproc_fdchk (fd) - int fd; -{ -#if MULTIPLE_COPROCS - cpl_fdchk (fd); -#else - coproc_checkfd (&sh_coproc, fd); -#endif -} - -void -coproc_fdclose (cp, fd) - struct coproc *cp; - int fd; -{ - coproc_rclose (cp, fd); - coproc_wclose (cp, fd); - coproc_setvars (cp); -} - -void -coproc_fdsave (cp) - struct coproc *cp; -{ - cp->c_rsave = cp->c_rfd; - cp->c_wsave = cp->c_wfd; -} - -void -coproc_fdrestore (cp) - struct coproc *cp; -{ - cp->c_rfd = cp->c_rsave; - cp->c_wfd = cp->c_wsave; -} - -static void -coproc_setstatus (cp, status) - struct coproc *cp; - int status; -{ - cp->c_lock = 4; - cp->c_status = status; - cp->c_flags |= COPROC_DEAD; - cp->c_flags &= ~COPROC_RUNNING; - /* Don't dispose the coproc or unset the COPROC_XXX variables because - this is executed in a signal handler context. Wait until coproc_reap - takes care of it. */ - cp->c_lock = 0; -} - -void -coproc_pidchk (pid, status) - pid_t pid; - int status; -{ - struct coproc *cp; - -#if MULTIPLE_COPROCS - struct cpelement *cpe; - - /* We're not disposing the coproc because this is executed in a signal - handler context */ - cpe = cpl_search (pid); - cp = cpe ? cpe->coproc : 0; -#else - cp = getcoprocbypid (pid); -#endif - if (cp) - coproc_setstatus (cp, status); -} - -pid_t -coproc_active () -{ -#if MULTIPLE_COPROCS - return (cpl_firstactive ()); -#else - return ((sh_coproc.c_flags & COPROC_DEAD) ? NO_PID : sh_coproc.c_pid); -#endif -} -void -coproc_setvars (cp) - struct coproc *cp; -{ - SHELL_VAR *v; - char *namevar, *t; - size_t l; - WORD_DESC w; -#if defined (ARRAY_VARS) - arrayind_t ind; -#endif - - if (cp->c_name == 0) - return; - - /* We could do more here but right now we only check the name, warn if it's - not a valid identifier, and refuse to create variables with invalid names - if a coproc with such a name is supplied. */ - w.word = cp->c_name; - w.flags = 0; - if (check_identifier (&w, 1) == 0) - return; - - l = strlen (cp->c_name); - namevar = xmalloc (l + 16); - -#if defined (ARRAY_VARS) - v = find_variable (cp->c_name); - - /* This is the same code as in find_or_make_array_variable */ - if (v == 0) - { - v = find_variable_nameref_for_create (cp->c_name, 1); - if (v == INVALID_NAMEREF_VALUE) - { - free (namevar); - return; - } - if (v && nameref_p (v)) - { - free (cp->c_name); - cp->c_name = savestring (nameref_cell (v)); - v = make_new_array_variable (cp->c_name); - } - } - - if (v && (readonly_p (v) || noassign_p (v))) - { - if (readonly_p (v)) - err_readonly (cp->c_name); - free (namevar); - return; - } - if (v == 0) - v = make_new_array_variable (cp->c_name); - if (array_p (v) == 0) - v = convert_var_to_array (v); - - t = itos (cp->c_rfd); - ind = 0; - v = bind_array_variable (cp->c_name, ind, t, 0); - free (t); - - t = itos (cp->c_wfd); - ind = 1; - v = bind_array_variable (cp->c_name, ind, t, 0); - free (t); -#else - sprintf (namevar, "%s_READ", cp->c_name); - t = itos (cp->c_rfd); - bind_variable (namevar, t, 0); - free (t); - sprintf (namevar, "%s_WRITE", cp->c_name); - t = itos (cp->c_wfd); - bind_variable (namevar, t, 0); - free (t); -#endif - - sprintf (namevar, "%s_PID", cp->c_name); - t = itos (cp->c_pid); - v = bind_variable (namevar, t, 0); - free (t); - - free (namevar); -} - -void -coproc_unsetvars (cp) - struct coproc *cp; -{ - int l; - char *namevar; - - if (cp->c_name == 0) - return; - - l = strlen (cp->c_name); - namevar = xmalloc (l + 16); - - sprintf (namevar, "%s_PID", cp->c_name); - unbind_variable_noref (namevar); - -#if defined (ARRAY_VARS) - check_unbind_variable (cp->c_name); -#else - sprintf (namevar, "%s_READ", cp->c_name); - unbind_variable (namevar); - sprintf (namevar, "%s_WRITE", cp->c_name); - unbind_variable (namevar); -#endif - - free (namevar); -} - -static int -execute_coproc (command, pipe_in, pipe_out, fds_to_close) - COMMAND *command; - int pipe_in, pipe_out; - struct fd_bitmap *fds_to_close; -{ - int rpipe[2], wpipe[2], estat, invert; - pid_t coproc_pid; - Coproc *cp; - char *tcmd, *p, *name; - sigset_t set, oset; - - /* XXX -- can be removed after changes to handle multiple coprocs */ -#if !MULTIPLE_COPROCS - if (sh_coproc.c_pid != NO_PID && (sh_coproc.c_rfd >= 0 || sh_coproc.c_wfd >= 0)) - internal_warning (_("execute_coproc: coproc [%d:%s] still exists"), sh_coproc.c_pid, sh_coproc.c_name); - coproc_init (&sh_coproc); -#endif - - invert = (command->flags & CMD_INVERT_RETURN) != 0; - - /* expand name without splitting - could make this dependent on a shopt option */ - name = expand_string_unsplit_to_string (command->value.Coproc->name, 0); - /* Optional check -- could be relaxed */ - if (legal_identifier (name) == 0) - { - internal_error (_("`%s': not a valid identifier"), name); - free (name); - return (invert ? EXECUTION_SUCCESS : EXECUTION_FAILURE); - } - else - { - free (command->value.Coproc->name); - command->value.Coproc->name = name; - } - - command_string_index = 0; - tcmd = make_command_string (command); - - sh_openpipe ((int *)&rpipe); /* 0 = parent read, 1 = child write */ - sh_openpipe ((int *)&wpipe); /* 0 = child read, 1 = parent write */ - - BLOCK_SIGNAL (SIGCHLD, set, oset); - - coproc_pid = make_child (p = savestring (tcmd), FORK_ASYNC); - - if (coproc_pid == 0) - { - close (rpipe[0]); - close (wpipe[1]); - -#if defined (JOB_CONTROL) - FREE (p); -#endif - - UNBLOCK_SIGNAL (oset); - estat = execute_in_subshell (command, 1, wpipe[0], rpipe[1], fds_to_close); - - fflush (stdout); - fflush (stderr); - - exit (estat); - } - - close (rpipe[1]); - close (wpipe[0]); - - cp = coproc_alloc (command->value.Coproc->name, coproc_pid); - cp->c_rfd = rpipe[0]; - cp->c_wfd = wpipe[1]; - - cp->c_flags |= COPROC_RUNNING; - - SET_CLOSE_ON_EXEC (cp->c_rfd); - SET_CLOSE_ON_EXEC (cp->c_wfd); - - coproc_setvars (cp); - - UNBLOCK_SIGNAL (oset); - -#if 0 - itrace ("execute_coproc (%s): [%d] %s", command->value.Coproc->name, coproc_pid, the_printed_command); -#endif - - close_pipes (pipe_in, pipe_out); -#if defined (PROCESS_SUBSTITUTION) && defined (HAVE_DEV_FD) - unlink_fifo_list (); -#endif - stop_pipeline (1, (COMMAND *)NULL); - DESCRIBE_PID (coproc_pid); - run_pending_traps (); - - return (invert ? EXECUTION_FAILURE : EXECUTION_SUCCESS); -} -#endif - -/* If S == -1, it's a special value saying to close stdin */ -static void -restore_stdin (s) - int s; -{ - if (s == -1) - close (0); - else - { - dup2 (s, 0); - close (s); - } -} - -/* Catch-all cleanup function for lastpipe code for unwind-protects */ -static void -lastpipe_cleanup (s) - int s; -{ - set_jobs_list_frozen (s); -} - -static int -execute_pipeline (command, asynchronous, pipe_in, pipe_out, fds_to_close) - COMMAND *command; - int asynchronous, pipe_in, pipe_out; - struct fd_bitmap *fds_to_close; -{ - int prev, fildes[2], new_bitmap_size, dummyfd, ignore_return, exec_result; - int lstdin, lastpipe_flag, lastpipe_jid, old_frozen, stdin_valid; - COMMAND *cmd; - struct fd_bitmap *fd_bitmap; - pid_t lastpid; - -#if defined (JOB_CONTROL) - sigset_t set, oset; - BLOCK_CHILD (set, oset); -#endif /* JOB_CONTROL */ - - ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0; - - stdin_valid = sh_validfd (0); - - prev = pipe_in; - cmd = command; - - while (cmd && cmd->type == cm_connection && - cmd->value.Connection && cmd->value.Connection->connector == '|') - { - /* Make a pipeline between the two commands. */ - if (pipe (fildes) < 0) - { - sys_error (_("pipe error")); -#if defined (JOB_CONTROL) - terminate_current_pipeline (); - kill_current_pipeline (); - UNBLOCK_CHILD (oset); -#endif /* JOB_CONTROL */ - last_command_exit_value = EXECUTION_FAILURE; - /* The unwind-protects installed below will take care - of closing all of the open file descriptors. */ - throw_to_top_level (); - return (EXECUTION_FAILURE); /* XXX */ - } - - /* Here is a problem: with the new file close-on-exec - code, the read end of the pipe (fildes[0]) stays open - in the first process, so that process will never get a - SIGPIPE. There is no way to signal the first process - that it should close fildes[0] after forking, so it - remains open. No SIGPIPE is ever sent because there - is still a file descriptor open for reading connected - to the pipe. We take care of that here. This passes - around a bitmap of file descriptors that must be - closed after making a child process in execute_simple_command. */ - - /* We need fd_bitmap to be at least as big as fildes[0]. - If fildes[0] is less than fds_to_close->size, then - use fds_to_close->size. */ - new_bitmap_size = (fildes[0] < fds_to_close->size) - ? fds_to_close->size - : fildes[0] + 8; - - fd_bitmap = new_fd_bitmap (new_bitmap_size); - - /* Now copy the old information into the new bitmap. */ - xbcopy ((char *)fds_to_close->bitmap, (char *)fd_bitmap->bitmap, fds_to_close->size); - - /* And mark the pipe file descriptors to be closed. */ - fd_bitmap->bitmap[fildes[0]] = 1; - - /* In case there are pipe or out-of-processes errors, we - want all these file descriptors to be closed when - unwind-protects are run, and the storage used for the - bitmaps freed up. */ - begin_unwind_frame ("pipe-file-descriptors"); - add_unwind_protect (dispose_fd_bitmap, fd_bitmap); - add_unwind_protect (close_fd_bitmap, fd_bitmap); - if (prev >= 0) - add_unwind_protect (close, prev); - dummyfd = fildes[1]; - add_unwind_protect (close, dummyfd); - -#if defined (JOB_CONTROL) - add_unwind_protect (restore_signal_mask, &oset); -#endif /* JOB_CONTROL */ - - if (ignore_return && cmd->value.Connection->first) - cmd->value.Connection->first->flags |= CMD_IGNORE_RETURN; - execute_command_internal (cmd->value.Connection->first, asynchronous, - prev, fildes[1], fd_bitmap); - - if (prev >= 0) - close (prev); - - prev = fildes[0]; - close (fildes[1]); - - dispose_fd_bitmap (fd_bitmap); - discard_unwind_frame ("pipe-file-descriptors"); - - cmd = cmd->value.Connection->second; - } - - lastpid = last_made_pid; - - /* Now execute the rightmost command in the pipeline. */ - if (ignore_return && cmd) - cmd->flags |= CMD_IGNORE_RETURN; - - lastpipe_flag = 0; - - begin_unwind_frame ("lastpipe-exec"); - lstdin = -2; /* -1 is special, meaning fd 0 is closed */ - /* If the `lastpipe' option is set with shopt, and job control is not - enabled, execute the last element of non-async pipelines in the - current shell environment. */ - /* prev can be 0 if fd 0 was closed when this function was executed. prev - will never be 0 at this point if fd 0 was valid when this function was - executed (though we check above). */ - if (lastpipe_opt && job_control == 0 && asynchronous == 0 && pipe_out == NO_PIPE && prev >= 0) - { - /* -1 is a special value meaning to close stdin */ - lstdin = (prev > 0 && stdin_valid) ? move_to_high_fd (0, 1, -1) : -1; - if (lstdin > 0 || lstdin == -1) - { - do_piping (prev, pipe_out); - prev = NO_PIPE; - add_unwind_protect (restore_stdin, lstdin); - lastpipe_flag = 1; - old_frozen = freeze_jobs_list (); - lastpipe_jid = stop_pipeline (0, (COMMAND *)NULL); /* XXX */ - add_unwind_protect (lastpipe_cleanup, old_frozen); -#if defined (JOB_CONTROL) - UNBLOCK_CHILD (oset); /* XXX */ -#endif - } - if (cmd) - cmd->flags |= CMD_LASTPIPE; - } - if (prev >= 0) - add_unwind_protect (close, prev); - - exec_result = execute_command_internal (cmd, asynchronous, prev, pipe_out, fds_to_close); - - if (prev >= 0) - close (prev); - - if (lstdin > 0 || lstdin == -1) - restore_stdin (lstdin); - -#if defined (JOB_CONTROL) - UNBLOCK_CHILD (oset); -#endif - - QUIT; - - if (lastpipe_flag) - { -#if defined (JOB_CONTROL) - if (INVALID_JOB (lastpipe_jid) == 0) - { - append_process (savestring (the_printed_command_except_trap), dollar_dollar_pid, exec_result, lastpipe_jid); - lstdin = wait_for (lastpid, 0); - } - else - { - lstdin = wait_for_single_pid (lastpid, 0); /* checks bgpids list */ - if (lstdin > 256) /* error sentinel */ - lstdin = 127; - } -#else - lstdin = wait_for (lastpid, 0); -#endif - -#if defined (JOB_CONTROL) - /* If wait_for removes the job from the jobs table, use result of last - command as pipeline's exit status as usual. The jobs list can get - frozen and unfrozen at inconvenient times if there are multiple pipelines - running simultaneously. */ - if (INVALID_JOB (lastpipe_jid) == 0) - exec_result = job_exit_status (lastpipe_jid); - else if (pipefail_opt) - exec_result = exec_result | lstdin; /* XXX */ - /* otherwise we use exec_result */ -#endif - - set_jobs_list_frozen (old_frozen); - } - - discard_unwind_frame ("lastpipe-exec"); - - return (exec_result); -} - -static int -execute_connection (command, asynchronous, pipe_in, pipe_out, fds_to_close) - COMMAND *command; - int asynchronous, pipe_in, pipe_out; - struct fd_bitmap *fds_to_close; -{ - COMMAND *tc, *second; - int ignore_return, exec_result, was_error_trap, invert; - volatile int save_line_number; - - ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0; - - switch (command->value.Connection->connector) - { - /* Do the first command asynchronously. */ - case '&': - tc = command->value.Connection->first; - if (tc == 0) - return (EXECUTION_SUCCESS); - - if (ignore_return) - tc->flags |= CMD_IGNORE_RETURN; - tc->flags |= CMD_AMPERSAND; - - /* If this shell was compiled without job control support, - if we are currently in a subshell via `( xxx )', or if job - control is not active then the standard input for an - asynchronous command is forced to /dev/null. */ -#if defined (JOB_CONTROL) - if ((subshell_environment || !job_control) && !stdin_redir) -#else - if (!stdin_redir) -#endif /* JOB_CONTROL */ - tc->flags |= CMD_STDIN_REDIR; - - exec_result = execute_command_internal (tc, 1, pipe_in, pipe_out, fds_to_close); - QUIT; - - if (tc->flags & CMD_STDIN_REDIR) - tc->flags &= ~CMD_STDIN_REDIR; - - second = command->value.Connection->second; - if (second) - { - if (ignore_return) - second->flags |= CMD_IGNORE_RETURN; - - exec_result = execute_command_internal (second, asynchronous, pipe_in, pipe_out, fds_to_close); - } - - break; - - /* Just call execute command on both sides. */ - case ';': - case '\n': /* special case, happens in command substitutions */ - if (ignore_return) - { - if (command->value.Connection->first) - command->value.Connection->first->flags |= CMD_IGNORE_RETURN; - if (command->value.Connection->second) - command->value.Connection->second->flags |= CMD_IGNORE_RETURN; - } - executing_list++; - QUIT; - -#if 1 - execute_command (command->value.Connection->first); -#else - execute_command_internal (command->value.Connection->first, - asynchronous, pipe_in, pipe_out, - fds_to_close); -#endif - - QUIT; - optimize_connection_fork (command); /* XXX */ - exec_result = execute_command_internal (command->value.Connection->second, - asynchronous, pipe_in, pipe_out, - fds_to_close); - executing_list--; - break; - - case '|': - was_error_trap = signal_is_trapped (ERROR_TRAP) && signal_is_ignored (ERROR_TRAP) == 0; - invert = (command->flags & CMD_INVERT_RETURN) != 0; - ignore_return = (command->flags & CMD_IGNORE_RETURN) != 0; - - SET_LINE_NUMBER (line_number); /* XXX - save value? */ - exec_result = execute_pipeline (command, asynchronous, pipe_in, pipe_out, fds_to_close); - - if (asynchronous) - { - exec_result = EXECUTION_SUCCESS; - invert = 0; - } - - if (was_error_trap && ignore_return == 0 && invert == 0 && exec_result != EXECUTION_SUCCESS) - { - last_command_exit_value = exec_result; - save_line_number = line_number; - line_number = line_number_for_err_trap; - run_error_trap (); - line_number = save_line_number; - } - - if (ignore_return == 0 && invert == 0 && exit_immediately_on_error && exec_result != EXECUTION_SUCCESS) - { - last_command_exit_value = exec_result; - run_pending_traps (); - jump_to_top_level (ERREXIT); - } - - break; - - case AND_AND: - case OR_OR: - if (asynchronous) - { - /* If we have something like `a && b &' or `a || b &', run the - && or || stuff in a subshell. Force a subshell and just call - execute_command_internal again. Leave asynchronous on - so that we get a report from the parent shell about the - background job. */ - command->flags |= CMD_FORCE_SUBSHELL; - exec_result = execute_command_internal (command, 1, pipe_in, pipe_out, fds_to_close); - break; - } - - /* Execute the first command. If the result of that is successful - and the connector is AND_AND, or the result is not successful - and the connector is OR_OR, then execute the second command, - otherwise return. */ - - executing_list++; - if (command->value.Connection->first) - command->value.Connection->first->flags |= CMD_IGNORE_RETURN; - -#if 1 - exec_result = execute_command (command->value.Connection->first); -#else - exec_result = execute_command_internal (command->value.Connection->first, 0, NO_PIPE, NO_PIPE, fds_to_close); -#endif - QUIT; - if (((command->value.Connection->connector == AND_AND) && - (exec_result == EXECUTION_SUCCESS)) || - ((command->value.Connection->connector == OR_OR) && - (exec_result != EXECUTION_SUCCESS))) - { - optimize_connection_fork (command); - - second = command->value.Connection->second; - if (ignore_return && second) - second->flags |= CMD_IGNORE_RETURN; - - exec_result = execute_command (second); - } - executing_list--; - break; - - default: - command_error ("execute_connection", CMDERR_BADCONN, command->value.Connection->connector, 0); - jump_to_top_level (DISCARD); - exec_result = EXECUTION_FAILURE; - } - - return exec_result; -} - -/* The test used to be only for interactive_shell, but we don't want to report - job status when the shell is not interactive or when job control isn't - enabled. */ -#define REAP() \ - do \ - { \ - if (job_control == 0 || interactive_shell == 0) \ - reap_dead_jobs (); \ - } \ - while (0) - -/* Execute a FOR command. The syntax is: FOR word_desc IN word_list; - DO command; DONE */ -static int -execute_for_command (for_command) - FOR_COM *for_command; -{ - register WORD_LIST *releaser, *list; - SHELL_VAR *v; - char *identifier; - int retval, save_line_number; -#if 0 - SHELL_VAR *old_value = (SHELL_VAR *)NULL; /* Remember the old value of x. */ -#endif - - save_line_number = line_number; - if (check_identifier (for_command->name, 1) == 0) - { - if (posixly_correct && interactive_shell == 0) - { - last_command_exit_value = EX_BADUSAGE; - jump_to_top_level (ERREXIT); - } - return (EXECUTION_FAILURE); - } - - loop_level++; - identifier = for_command->name->word; - - line_number = for_command->line; /* for expansion error messages */ - list = releaser = expand_words_no_vars (for_command->map_list); - - begin_unwind_frame ("for"); - add_unwind_protect (dispose_words, releaser); - -#if 0 - if (lexical_scoping) - { - old_value = copy_variable (find_variable (identifier)); - if (old_value) - add_unwind_protect (dispose_variable, old_value); - } -#endif - - if (for_command->flags & CMD_IGNORE_RETURN) - for_command->action->flags |= CMD_IGNORE_RETURN; - - for (retval = EXECUTION_SUCCESS; list; list = list->next) - { - QUIT; - - line_number = for_command->line; - - /* Remember what this command looks like, for debugger. */ - command_string_index = 0; - print_for_command_head (for_command); - - if (echo_command_at_execute) - xtrace_print_for_command_head (for_command); - - /* Save this command unless it's a trap command and we're not running - a debug trap. */ - if (signal_in_progress (DEBUG_TRAP) == 0 && running_trap == 0) - { - FREE (the_printed_command_except_trap); - the_printed_command_except_trap = savestring (the_printed_command); - } - - retval = run_debug_trap (); -#if defined (DEBUGGER) - /* In debugging mode, if the DEBUG trap returns a non-zero status, we - skip the command. */ - if (debugging_mode && retval != EXECUTION_SUCCESS) - continue; -#endif - - this_command_name = (char *)NULL; - /* XXX - special ksh93 for command index variable handling */ - v = find_variable_last_nameref (identifier, 1); - if (v && nameref_p (v)) - { - if (valid_nameref_value (list->word->word, 1) == 0) - { - sh_invalidid (list->word->word); - v = 0; - } - else if (readonly_p (v)) - err_readonly (name_cell (v)); - else - v = bind_variable_value (v, list->word->word, ASS_NAMEREF); - } - else - v = bind_variable (identifier, list->word->word, 0); - - if (v == 0 || readonly_p (v) || noassign_p (v)) - { - line_number = save_line_number; - if (v && readonly_p (v) && interactive_shell == 0 && posixly_correct) - { - last_command_exit_value = EXECUTION_FAILURE; - jump_to_top_level (FORCE_EOF); - } - else - { - dispose_words (releaser); - discard_unwind_frame ("for"); - loop_level--; - return (EXECUTION_FAILURE); - } - } - - if (ifsname (identifier)) - setifs (v); - else - stupidly_hack_special_variables (identifier); - - retval = execute_command (for_command->action); - REAP (); - QUIT; - - if (breaking) - { - breaking--; - break; - } - - if (continuing) - { - continuing--; - if (continuing) - break; - } - } - - loop_level--; - line_number = save_line_number; - -#if 0 - if (lexical_scoping) - { - if (!old_value) - unbind_variable (identifier); - else - { - SHELL_VAR *new_value; - - new_value = bind_variable (identifier, value_cell (old_value), 0); - new_value->attributes = old_value->attributes; - dispose_variable (old_value); - } - } -#endif - - dispose_words (releaser); - discard_unwind_frame ("for"); - return (retval); -} - -#if defined (ARITH_FOR_COMMAND) -/* Execute an arithmetic for command. The syntax is - - for (( init ; step ; test )) - do - body - done - - The execution should be exactly equivalent to - - eval \(\( init \)\) - while eval \(\( test \)\) ; do - body; - eval \(\( step \)\) - done -*/ -static intmax_t -eval_arith_for_expr (l, okp) - WORD_LIST *l; - int *okp; -{ - WORD_LIST *new; - intmax_t expresult; - int r, eflag; - char *expr, *temp; - - expr = l->next ? string_list (l) : l->word->word; - temp = expand_arith_string (expr, Q_DOUBLE_QUOTES|Q_ARITH); - if (l->next) - free (expr); - new = make_word_list (make_word (temp), (WORD_LIST *)NULL); - free (temp); - - if (new) - { - if (echo_command_at_execute) - xtrace_print_arith_cmd (new); - - command_string_index = 0; - print_arith_command (new); - if (signal_in_progress (DEBUG_TRAP) == 0 && running_trap == 0) - { - FREE (the_printed_command_except_trap); - the_printed_command_except_trap = savestring (the_printed_command); - } - - r = run_debug_trap (); - /* In debugging mode, if the DEBUG trap returns a non-zero status, we - skip the command. */ - eflag = (shell_compatibility_level > 51) ? 0 : EXP_EXPANDED; - this_command_name = "(("; /* )) for expression error messages */ - -#if defined (DEBUGGER) - if (debugging_mode == 0 || r == EXECUTION_SUCCESS) - expresult = evalexp (new->word->word, eflag, okp); - else - { - expresult = 0; - if (okp) - *okp = 1; - } -#else - expresult = evalexp (new->word->word, eflag, okp); -#endif - dispose_words (new); - } - else - { - expresult = 0; - if (okp) - *okp = 1; - } - return (expresult); -} - -static int -execute_arith_for_command (arith_for_command) - ARITH_FOR_COM *arith_for_command; -{ - intmax_t expresult; - int expok, body_status, arith_lineno, save_lineno; - - body_status = EXECUTION_SUCCESS; - loop_level++; - save_lineno = line_number; - - if (arith_for_command->flags & CMD_IGNORE_RETURN) - arith_for_command->action->flags |= CMD_IGNORE_RETURN; - - this_command_name = "(("; /* )) for expression error messages */ - - /* save the starting line number of the command so we can reset - line_number before executing each expression -- for $LINENO - and the DEBUG trap. */ - line_number = arith_lineno = arith_for_command->line; - if (variable_context && interactive_shell && sourcelevel == 0) - { - /* line numbers in a function start at 1 */ - line_number -= function_line_number - 1; - if (line_number <= 0) - line_number = 1; - } - - /* Evaluate the initialization expression. */ - expresult = eval_arith_for_expr (arith_for_command->init, &expok); - if (expok == 0) - { - line_number = save_lineno; - return (EXECUTION_FAILURE); - } - - while (1) - { - /* Evaluate the test expression. */ - line_number = arith_lineno; - expresult = eval_arith_for_expr (arith_for_command->test, &expok); - line_number = save_lineno; - - if (expok == 0) - { - body_status = EXECUTION_FAILURE; - break; - } - REAP (); - if (expresult == 0) - break; - - /* Execute the body of the arithmetic for command. */ - QUIT; - body_status = execute_command (arith_for_command->action); - QUIT; - - /* Handle any `break' or `continue' commands executed by the body. */ - if (breaking) - { - breaking--; - break; - } - - if (continuing) - { - continuing--; - if (continuing) - break; - } - - /* Evaluate the step expression. */ - line_number = arith_lineno; - expresult = eval_arith_for_expr (arith_for_command->step, &expok); - line_number = save_lineno; - - if (expok == 0) - { - body_status = EXECUTION_FAILURE; - break; - } - } - - loop_level--; - line_number = save_lineno; - - return (body_status); -} -#endif - -#if defined (SELECT_COMMAND) -static int LINES, COLS, tabsize; - -#define RP_SPACE ") " -#define RP_SPACE_LEN 2 - -/* XXX - does not handle numbers > 1000000 at all. */ -#define NUMBER_LEN(s) \ -((s < 10) ? 1 \ - : ((s < 100) ? 2 \ - : ((s < 1000) ? 3 \ - : ((s < 10000) ? 4 \ - : ((s < 100000) ? 5 \ - : 6))))) - -static int -displen (s) - const char *s; -{ -#if defined (HANDLE_MULTIBYTE) - wchar_t *wcstr; - size_t slen; - int wclen; - - wcstr = 0; - slen = mbstowcs (wcstr, s, 0); - if (slen == -1) - slen = 0; - wcstr = (wchar_t *)xmalloc (sizeof (wchar_t) * (slen + 1)); - mbstowcs (wcstr, s, slen + 1); - wclen = wcswidth (wcstr, slen); - free (wcstr); - return (wclen < 0 ? STRLEN(s) : wclen); -#else - return (STRLEN (s)); -#endif -} - -static int -print_index_and_element (len, ind, list) - int len, ind; - WORD_LIST *list; -{ - register WORD_LIST *l; - register int i; - - if (list == 0) - return (0); - for (i = ind, l = list; l && --i; l = l->next) - ; - if (l == 0) /* don't think this can happen */ - return (0); - fprintf (stderr, "%*d%s%s", len, ind, RP_SPACE, l->word->word); - return (displen (l->word->word)); -} - -static void -indent (from, to) - int from, to; -{ - while (from < to) - { - if ((to / tabsize) > (from / tabsize)) - { - putc ('\t', stderr); - from += tabsize - from % tabsize; - } - else - { - putc (' ', stderr); - from++; - } - } -} - -static void -print_select_list (list, list_len, max_elem_len, indices_len) - WORD_LIST *list; - int list_len, max_elem_len, indices_len; -{ - int ind, row, elem_len, pos, cols, rows; - int first_column_indices_len, other_indices_len; - - if (list == 0) - { - putc ('\n', stderr); - return; - } - - cols = max_elem_len ? COLS / max_elem_len : 1; - if (cols == 0) - cols = 1; - rows = list_len ? list_len / cols + (list_len % cols != 0) : 1; - cols = list_len ? list_len / rows + (list_len % rows != 0) : 1; - - if (rows == 1) - { - rows = cols; - cols = 1; - } - - first_column_indices_len = NUMBER_LEN (rows); - other_indices_len = indices_len; - - for (row = 0; row < rows; row++) - { - ind = row; - pos = 0; - while (1) - { - indices_len = (pos == 0) ? first_column_indices_len : other_indices_len; - elem_len = print_index_and_element (indices_len, ind + 1, list); - elem_len += indices_len + RP_SPACE_LEN; - ind += rows; - if (ind >= list_len) - break; - indent (pos + elem_len, pos + max_elem_len); - pos += max_elem_len; - } - putc ('\n', stderr); - } -} - -/* Print the elements of LIST, one per line, preceded by an index from 1 to - LIST_LEN. Then display PROMPT and wait for the user to enter a number. - If the number is between 1 and LIST_LEN, return that selection. If EOF - is read, return a null string. If a blank line is entered, or an invalid - number is entered, the loop is executed again. */ -static char * -select_query (list, list_len, prompt, print_menu) - WORD_LIST *list; - int list_len; - char *prompt; - int print_menu; -{ - int max_elem_len, indices_len, len, r, oe; - intmax_t reply; - WORD_LIST *l; - char *repl_string, *t; - - COLS = default_columns (); - -#if 0 - t = get_string_value ("TABSIZE"); - tabsize = (t && *t) ? atoi (t) : 8; - if (tabsize <= 0) - tabsize = 8; -#else - tabsize = 8; -#endif - - max_elem_len = 0; - for (l = list; l; l = l->next) - { - len = displen (l->word->word); - if (len > max_elem_len) - max_elem_len = len; - } - indices_len = NUMBER_LEN (list_len); - max_elem_len += indices_len + RP_SPACE_LEN + 2; - - while (1) - { - if (print_menu) - print_select_list (list, list_len, max_elem_len, indices_len); - fprintf (stderr, "%s", prompt); - fflush (stderr); - QUIT; - - oe = executing_builtin; - executing_builtin = 1; - r = read_builtin ((WORD_LIST *)NULL); - executing_builtin = oe; - if (r != EXECUTION_SUCCESS) - { - putchar ('\n'); - return ((char *)NULL); - } - repl_string = get_string_value ("REPLY"); - if (repl_string == 0) - return ((char *)NULL); - if (*repl_string == 0) - { - print_menu = 1; - continue; - } - if (legal_number (repl_string, &reply) == 0) - return ""; - if (reply < 1 || reply > list_len) - return ""; - - for (l = list; l && --reply; l = l->next) - ; - return (l->word->word); /* XXX - can't be null? */ - } -} - -/* Execute a SELECT command. The syntax is: - SELECT word IN list DO command_list DONE - Only `break' or `return' in command_list will terminate - the command. */ -static int -execute_select_command (select_command) - SELECT_COM *select_command; -{ - WORD_LIST *releaser, *list; - SHELL_VAR *v; - char *identifier, *ps3_prompt, *selection; - int retval, list_len, show_menu, save_line_number; - - if (check_identifier (select_command->name, 1) == 0) - return (EXECUTION_FAILURE); - - save_line_number = line_number; - line_number = select_command->line; - - command_string_index = 0; - print_select_command_head (select_command); - - if (echo_command_at_execute) - xtrace_print_select_command_head (select_command); - -#if 0 - if (signal_in_progress (DEBUG_TRAP) == 0 && (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0))) -#else - if (signal_in_progress (DEBUG_TRAP) == 0 && running_trap == 0) -#endif - { - FREE (the_printed_command_except_trap); - the_printed_command_except_trap = savestring (the_printed_command); - } - - retval = run_debug_trap (); -#if defined (DEBUGGER) - /* In debugging mode, if the DEBUG trap returns a non-zero status, we - skip the command. */ - if (debugging_mode && retval != EXECUTION_SUCCESS) - return (EXECUTION_SUCCESS); -#endif - - this_command_name = (char *)0; - - loop_level++; - identifier = select_command->name->word; - - /* command and arithmetic substitution, parameter and variable expansion, - word splitting, pathname expansion, and quote removal. */ - list = releaser = expand_words_no_vars (select_command->map_list); - list_len = list_length (list); - if (list == 0 || list_len == 0) - { - if (list) - dispose_words (list); - line_number = save_line_number; - return (EXECUTION_SUCCESS); - } - - begin_unwind_frame ("select"); - add_unwind_protect (dispose_words, releaser); - - if (select_command->flags & CMD_IGNORE_RETURN) - select_command->action->flags |= CMD_IGNORE_RETURN; - - retval = EXECUTION_SUCCESS; - show_menu = 1; - - while (1) - { - line_number = select_command->line; - ps3_prompt = get_string_value ("PS3"); - if (ps3_prompt == 0) - ps3_prompt = "#? "; - - QUIT; - selection = select_query (list, list_len, ps3_prompt, show_menu); - QUIT; - if (selection == 0) - { - /* select_query returns EXECUTION_FAILURE if the read builtin - fails, so we want to return failure in this case. */ - retval = EXECUTION_FAILURE; - break; - } - - v = bind_variable (identifier, selection, 0); - if (v == 0 || readonly_p (v) || noassign_p (v)) - { - if (v && readonly_p (v) && interactive_shell == 0 && posixly_correct) - { - last_command_exit_value = EXECUTION_FAILURE; - jump_to_top_level (FORCE_EOF); - } - else - { - dispose_words (releaser); - discard_unwind_frame ("select"); - loop_level--; - line_number = save_line_number; - return (EXECUTION_FAILURE); - } - } - - stupidly_hack_special_variables (identifier); - - retval = execute_command (select_command->action); - - REAP (); - QUIT; - - if (breaking) - { - breaking--; - break; - } - - if (continuing) - { - continuing--; - if (continuing) - break; - } - -#if defined (KSH_COMPATIBLE_SELECT) - show_menu = 0; - selection = get_string_value ("REPLY"); - if (selection && *selection == '\0') - show_menu = 1; -#endif - } - - loop_level--; - line_number = save_line_number; - - dispose_words (releaser); - discard_unwind_frame ("select"); - return (retval); -} -#endif /* SELECT_COMMAND */ - -/* Execute a CASE command. The syntax is: CASE word_desc IN pattern_list ESAC. - The pattern_list is a linked list of pattern clauses; each clause contains - some patterns to compare word_desc against, and an associated command to - execute. */ -static int -execute_case_command (case_command) - CASE_COM *case_command; -{ - register WORD_LIST *list; - WORD_LIST *wlist, *es; - PATTERN_LIST *clauses; - char *word, *pattern; - int retval, match, ignore_return, save_line_number, qflags; - - save_line_number = line_number; - line_number = case_command->line; - - command_string_index = 0; - print_case_command_head (case_command); - - if (echo_command_at_execute) - xtrace_print_case_command_head (case_command); - -#if 0 - if (signal_in_progress (DEBUG_TRAP) == 0 && (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0))) -#else - if (signal_in_progress (DEBUG_TRAP) == 0 && running_trap == 0) -#endif - { - FREE (the_printed_command_except_trap); - the_printed_command_except_trap = savestring (the_printed_command); - } - - retval = run_debug_trap(); -#if defined (DEBUGGER) - /* In debugging mode, if the DEBUG trap returns a non-zero status, we - skip the command. */ - if (debugging_mode && retval != EXECUTION_SUCCESS) - { - line_number = save_line_number; - return (EXECUTION_SUCCESS); - } -#endif - - /* Use the same expansions (the ones POSIX specifies) as the patterns; - dequote the resulting string (as POSIX specifies) since the quotes in - patterns are handled specially below. We have to do it in this order - because we're not supposed to perform word splitting. */ - wlist = expand_word_leave_quoted (case_command->word, 0); - if (wlist) - { - char *t; - t = string_list (wlist); - word = dequote_string (t); - free (t); - } - else - word = savestring (""); - dispose_words (wlist); - - retval = EXECUTION_SUCCESS; - ignore_return = case_command->flags & CMD_IGNORE_RETURN; - - begin_unwind_frame ("case"); - add_unwind_protect (xfree, word); - -#define EXIT_CASE() goto exit_case_command - - for (clauses = case_command->clauses; clauses; clauses = clauses->next) - { - QUIT; - for (list = clauses->patterns; list; list = list->next) - { - es = expand_word_leave_quoted (list->word, 0); - - if (es && es->word && es->word->word && *(es->word->word)) - { - /* Convert quoted null strings into empty strings. */ - qflags = QGLOB_CVTNULL; - - /* We left CTLESC in place quoting CTLESC and CTLNUL after the - call to expand_word_leave_quoted; tell quote_string_for_globbing - to remove those here. This works for both unquoted portions of - the word (which call quote_escapes) and quoted portions - (which call quote_string). */ - qflags |= QGLOB_CTLESC; - pattern = quote_string_for_globbing (es->word->word, qflags); - } - else - { - pattern = (char *)xmalloc (1); - pattern[0] = '\0'; - } - - /* Since the pattern does not undergo quote removal (as per - Posix.2, section 3.9.4.3), the strmatch () call must be able - to recognize backslashes as escape characters. */ - match = strmatch (pattern, word, FNMATCH_EXTFLAG|FNMATCH_IGNCASE) != FNM_NOMATCH; - free (pattern); - - dispose_words (es); - - if (match) - { - do - { - if (clauses->action && ignore_return) - clauses->action->flags |= CMD_IGNORE_RETURN; - retval = execute_command (clauses->action); - } - while ((clauses->flags & CASEPAT_FALLTHROUGH) && (clauses = clauses->next)); - if (clauses == 0 || (clauses->flags & CASEPAT_TESTNEXT) == 0) - EXIT_CASE (); - else - break; - } - - QUIT; - } - } - -exit_case_command: - free (word); - discard_unwind_frame ("case"); - line_number = save_line_number; - return (retval); -} - -#define CMD_WHILE 0 -#define CMD_UNTIL 1 - -/* The WHILE command. Syntax: WHILE test DO action; DONE. - Repeatedly execute action while executing test produces - EXECUTION_SUCCESS. */ -static int -execute_while_command (while_command) - WHILE_COM *while_command; -{ - return (execute_while_or_until (while_command, CMD_WHILE)); -} - -/* UNTIL is just like WHILE except that the test result is negated. */ -static int -execute_until_command (while_command) - WHILE_COM *while_command; -{ - return (execute_while_or_until (while_command, CMD_UNTIL)); -} - -/* The body for both while and until. The only difference between the - two is that the test value is treated differently. TYPE is - CMD_WHILE or CMD_UNTIL. The return value for both commands should - be EXECUTION_SUCCESS if no commands in the body are executed, and - the status of the last command executed in the body otherwise. */ -static int -execute_while_or_until (while_command, type) - WHILE_COM *while_command; - int type; -{ - int return_value, body_status; - - body_status = EXECUTION_SUCCESS; - loop_level++; - - while_command->test->flags |= CMD_IGNORE_RETURN; - if (while_command->flags & CMD_IGNORE_RETURN) - while_command->action->flags |= CMD_IGNORE_RETURN; - - while (1) - { - return_value = execute_command (while_command->test); - REAP (); - - /* Need to handle `break' in the test when we would break out of the - loop. The job control code will set `breaking' to loop_level - when a job in a loop is stopped with SIGTSTP. If the stopped job - is in the loop test, `breaking' will not be reset unless we do - this, and the shell will cease to execute commands. The same holds - true for `continue'. */ - if (type == CMD_WHILE && return_value != EXECUTION_SUCCESS) - { - if (breaking) - breaking--; - if (continuing) - continuing--; - break; - } - if (type == CMD_UNTIL && return_value == EXECUTION_SUCCESS) - { - if (breaking) - breaking--; - if (continuing) - continuing--; - break; - } - - QUIT; - body_status = execute_command (while_command->action); - QUIT; - - if (breaking) - { - breaking--; - break; - } - - if (continuing) - { - continuing--; - if (continuing) - break; - } - } - loop_level--; - - return (body_status); -} - -/* IF test THEN command [ELSE command]. - IF also allows ELIF in the place of ELSE IF, but - the parser makes *that* stupidity transparent. */ -static int -execute_if_command (if_command) - IF_COM *if_command; -{ - int return_value, save_line_number; - - save_line_number = line_number; - if_command->test->flags |= CMD_IGNORE_RETURN; - return_value = execute_command (if_command->test); - line_number = save_line_number; - - if (return_value == EXECUTION_SUCCESS) - { - QUIT; - - if (if_command->true_case && (if_command->flags & CMD_IGNORE_RETURN)) - if_command->true_case->flags |= CMD_IGNORE_RETURN; - - return (execute_command (if_command->true_case)); - } - else - { - QUIT; - - if (if_command->false_case && (if_command->flags & CMD_IGNORE_RETURN)) - if_command->false_case->flags |= CMD_IGNORE_RETURN; - - return (execute_command (if_command->false_case)); - } -} - -#if defined (DPAREN_ARITHMETIC) -static int -execute_arith_command (arith_command) - ARITH_COM *arith_command; -{ - int expok, save_line_number, retval, eflag; - intmax_t expresult; - WORD_LIST *new; - char *exp, *t; - - expresult = 0; - - save_line_number = line_number; - this_command_name = "(("; /* )) */ - SET_LINE_NUMBER (arith_command->line); - /* If we're in a function, update the line number information. */ - if (variable_context && interactive_shell && sourcelevel == 0) - { - /* line numbers in a function start at 1 */ - line_number -= function_line_number - 1; - if (line_number <= 0) - line_number = 1; - } - - command_string_index = 0; - print_arith_command (arith_command->exp); - - if (signal_in_progress (DEBUG_TRAP) == 0 && running_trap == 0) - { - FREE (the_printed_command_except_trap); - the_printed_command_except_trap = savestring (the_printed_command); - } - - /* Run the debug trap before each arithmetic command, but do it after we - update the line number information and before we expand the various - words in the expression. */ - retval = run_debug_trap (); -#if defined (DEBUGGER) - /* In debugging mode, if the DEBUG trap returns a non-zero status, we - skip the command. */ - if (debugging_mode && retval != EXECUTION_SUCCESS) - { - line_number = save_line_number; - return (EXECUTION_SUCCESS); - } -#endif - - this_command_name = "(("; /* )) */ - t = (char *)NULL; - new = arith_command->exp; - exp = (new->next) ? (t = string_list (new)) : new->word->word; - - exp = expand_arith_string (exp, Q_DOUBLE_QUOTES|Q_ARITH); - FREE (t); - - /* If we're tracing, make a new word list with `((' at the front and `))' - at the back and print it. Change xtrace_print_arith_cmd to take a string - when I change eval_arith_for_expr to use expand_arith_string(). */ - if (echo_command_at_execute) - { - new = make_word_list (make_word (exp ? exp : ""), (WORD_LIST *)NULL); - xtrace_print_arith_cmd (new); - dispose_words (new); - } - - if (exp) - { - eflag = (shell_compatibility_level > 51) ? 0 : EXP_EXPANDED; - expresult = evalexp (exp, eflag, &expok); - line_number = save_line_number; - free (exp); - } - else - { - expresult = 0; - expok = 1; - } - - if (expok == 0) - return (EXECUTION_FAILURE); - - return (expresult == 0 ? EXECUTION_FAILURE : EXECUTION_SUCCESS); -} -#endif /* DPAREN_ARITHMETIC */ - -#if defined (COND_COMMAND) - -static char * const nullstr = ""; - -/* XXX - can COND ever be NULL when this is called? */ -static int -execute_cond_node (cond) - COND_COM *cond; -{ - int result, invert, patmatch, rmatch, arith, mode, mflags, ignore; - char *arg1, *arg2, *op; -#if 0 - char *t1, *t2; -#endif - - invert = (cond->flags & CMD_INVERT_RETURN); - ignore = (cond->flags & CMD_IGNORE_RETURN); - if (ignore) - { - if (cond->left) - cond->left->flags |= CMD_IGNORE_RETURN; - if (cond->right) - cond->right->flags |= CMD_IGNORE_RETURN; - } - - if (cond->type == COND_EXPR) - result = execute_cond_node (cond->left); - else if (cond->type == COND_OR) - { - result = execute_cond_node (cond->left); - if (result != EXECUTION_SUCCESS) - result = execute_cond_node (cond->right); - } - else if (cond->type == COND_AND) - { - result = execute_cond_node (cond->left); - if (result == EXECUTION_SUCCESS) - result = execute_cond_node (cond->right); - } - else if (cond->type == COND_UNARY) - { - int oa, varop, varflag; - - if (ignore) - comsub_ignore_return++; - varop = STREQ (cond->op->word, "-v"); -#if defined (ARRAY_VARS) - varflag = (varop && valid_array_reference (cond->left->op->word, VA_NOEXPAND)) ? TEST_ARRAYEXP : 0; -#else - varflag = 0; -#endif - arg1 = cond_expand_word (cond->left->op, varop ? 3 : 0); - if (ignore) - comsub_ignore_return--; - if (arg1 == 0) - arg1 = nullstr; - if (echo_command_at_execute) - xtrace_print_cond_term (cond->type, invert, cond->op, arg1, (char *)NULL); -#if defined (ARRAY_VARS) - if (varop) - oa = set_expand_once (0, 0); /* no-op for compatibility levels <= 51 */ -#endif - result = unary_test (cond->op->word, arg1, varflag) ? EXECUTION_SUCCESS : EXECUTION_FAILURE; -#if defined (ARRAY_VARS) - if (varop) - assoc_expand_once = oa; -#endif - if (arg1 != nullstr) - free (arg1); - } - else if (cond->type == COND_BINARY) - { - rmatch = 0; - op = cond->op->word; - mode = 0; - patmatch = (((op[1] == '=') && (op[2] == '\0') && - (op[0] == '!' || op[0] == '=')) || - (op[0] == '=' && op[1] == '\0')); -#if defined (COND_REGEXP) - rmatch = (op[0] == '=' && op[1] == '~' && op[2] == '\0'); -#endif - arith = STREQ (op, "-eq") || STREQ (op, "-ne") || STREQ (op, "-lt") || - STREQ (op, "-le") || STREQ (op, "-gt") || STREQ (op, "-ge"); - - if (arith) - mode = 3; - else if (rmatch && shell_compatibility_level > 31) - mode = 2; - else if (patmatch) - mode = 1; - - if (ignore) - comsub_ignore_return++; - arg1 = cond_expand_word (cond->left->op, arith ? mode : 0); - if (ignore) - comsub_ignore_return--; - if (arg1 == 0) - arg1 = nullstr; - if (ignore) - comsub_ignore_return++; - arg2 = cond_expand_word (cond->right->op, mode); - if (ignore) - comsub_ignore_return--; - if (arg2 == 0) - arg2 = nullstr; - - if (echo_command_at_execute) - xtrace_print_cond_term (cond->type, invert, cond->op, arg1, arg2); - -#if defined (COND_REGEXP) - if (rmatch) - { - mflags = SHMAT_PWARN; -#if defined (ARRAY_VARS) - mflags |= SHMAT_SUBEXP; -#endif - -#if 0 - t1 = strescape(arg1); - t2 = strescape(arg2); - itrace("execute_cond_node: sh_regmatch on `%s' and `%s'", t1, t2); - free(t1); - free(t2); -#endif - - result = sh_regmatch (arg1, arg2, mflags); - } - else -#endif /* COND_REGEXP */ - { - int oe; - oe = extended_glob; - extended_glob = 1; - result = binary_test (cond->op->word, arg1, arg2, TEST_PATMATCH|TEST_ARITHEXP|TEST_LOCALE) - ? EXECUTION_SUCCESS - : EXECUTION_FAILURE; - extended_glob = oe; - } - if (arg1 != nullstr) - free (arg1); - if (arg2 != nullstr) - free (arg2); - } - else - { - command_error ("execute_cond_node", CMDERR_BADTYPE, cond->type, 0); - jump_to_top_level (DISCARD); - result = EXECUTION_FAILURE; - } - - if (invert) - result = (result == EXECUTION_SUCCESS) ? EXECUTION_FAILURE : EXECUTION_SUCCESS; - - return result; -} - -static int -execute_cond_command (cond_command) - COND_COM *cond_command; -{ - int retval, save_line_number; - - save_line_number = line_number; - - SET_LINE_NUMBER (cond_command->line); - /* If we're in a function, update the line number information. */ - if (variable_context && interactive_shell && sourcelevel == 0) - { - /* line numbers in a function start at 1 */ - line_number -= function_line_number - 1; - if (line_number <= 0) - line_number = 1; - } - command_string_index = 0; - print_cond_command (cond_command); - - if (signal_in_progress (DEBUG_TRAP) == 0 && running_trap == 0) - { - FREE (the_printed_command_except_trap); - the_printed_command_except_trap = savestring (the_printed_command); - } - - /* Run the debug trap before each conditional command, but do it after we - update the line number information. */ - retval = run_debug_trap (); -#if defined (DEBUGGER) - /* In debugging mode, if the DEBUG trap returns a non-zero status, we - skip the command. */ - if (debugging_mode && retval != EXECUTION_SUCCESS) - { - line_number = save_line_number; - return (EXECUTION_SUCCESS); - } -#endif - - this_command_name = "[["; /* ]] */ - -#if 0 - debug_print_cond_command (cond_command); -#endif - - last_command_exit_value = retval = execute_cond_node (cond_command); - line_number = save_line_number; - return (retval); -} -#endif /* COND_COMMAND */ - -static void -bind_lastarg (arg) - char *arg; -{ - SHELL_VAR *var; - - if (arg == 0) - arg = ""; - var = bind_variable ("_", arg, 0); - if (var) - VUNSETATTR (var, att_exported); -} - -/* Execute a null command. Fork a subshell if the command uses pipes or is - to be run asynchronously. This handles all the side effects that are - supposed to take place. */ -static int -execute_null_command (redirects, pipe_in, pipe_out, async) - REDIRECT *redirects; - int pipe_in, pipe_out, async; -{ - int r; - int forcefork, fork_flags; - REDIRECT *rd; - - for (forcefork = 0, rd = redirects; rd; rd = rd->next) - { - forcefork += rd->rflags & REDIR_VARASSIGN; - /* Safety */ - forcefork += (rd->redirector.dest == 0 || fd_is_bash_input (rd->redirector.dest)) && (INPUT_REDIRECT (rd->instruction) || TRANSLATE_REDIRECT (rd->instruction) || rd->instruction == r_close_this); - } - - if (forcefork || pipe_in != NO_PIPE || pipe_out != NO_PIPE || async) - { - /* We have a null command, but we really want a subshell to take - care of it. Just fork, do piping and redirections, and exit. */ - fork_flags = async ? FORK_ASYNC : 0; - if (make_child ((char *)NULL, fork_flags) == 0) - { - /* Cancel traps, in trap.c. */ - restore_original_signals (); /* XXX */ - - do_piping (pipe_in, pipe_out); - -#if defined (COPROCESS_SUPPORT) - coproc_closeall (); -#endif - - interactive = 0; /* XXX */ - - subshell_environment = 0; - if (async) - subshell_environment |= SUBSHELL_ASYNC; - if (pipe_in != NO_PIPE || pipe_out != NO_PIPE) - subshell_environment |= SUBSHELL_PIPE; - - if (do_redirections (redirects, RX_ACTIVE) == 0) - exit (EXECUTION_SUCCESS); - else - exit (EXECUTION_FAILURE); - } - else - { - close_pipes (pipe_in, pipe_out); -#if defined (PROCESS_SUBSTITUTION) && defined (HAVE_DEV_FD) - if (pipe_out == NO_PIPE) - unlink_fifo_list (); -#endif - return (EXECUTION_SUCCESS); - } - } - else - { - /* Even if there aren't any command names, pretend to do the - redirections that are specified. The user expects the side - effects to take place. If the redirections fail, then return - failure. Otherwise, if a command substitution took place while - expanding the command or a redirection, return the value of that - substitution. Otherwise, return EXECUTION_SUCCESS. */ - - r = do_redirections (redirects, RX_ACTIVE|RX_UNDOABLE); - cleanup_redirects (redirection_undo_list); - redirection_undo_list = (REDIRECT *)NULL; - - if (r != 0) - return (EXECUTION_FAILURE); - else if (last_command_subst_pid != NO_PID) - return (last_command_exit_value); - else - return (EXECUTION_SUCCESS); - } -} - -/* This is a hack to suppress word splitting for assignment statements - given as arguments to builtins with the ASSIGNMENT_BUILTIN flag set. */ -static void -fix_assignment_words (words) - WORD_LIST *words; -{ - WORD_LIST *w, *wcmd; - struct builtin *b; - int assoc, global, array, integer; - - if (words == 0) - return; - - b = 0; - assoc = global = array = integer = 0; - - /* Skip over assignment statements preceding a command name */ - wcmd = words; - for (wcmd = words; wcmd; wcmd = wcmd->next) - if ((wcmd->word->flags & W_ASSIGNMENT) == 0) - break; - /* Posix (post-2008) says that `command' doesn't change whether - or not the builtin it shadows is a `declaration command', even - though it removes other special builtin properties. In Posix - mode, we skip over one or more instances of `command' and - deal with the next word as the assignment builtin. */ - while (posixly_correct && wcmd && wcmd->word && wcmd->word->word && STREQ (wcmd->word->word, "command")) - wcmd = wcmd->next; - - for (w = wcmd; w; w = w->next) - if (w->word->flags & W_ASSIGNMENT) - { - /* Lazy builtin lookup, only do it if we find an assignment */ - if (b == 0) - { - b = builtin_address_internal (wcmd->word->word, 0); - if (b == 0 || (b->flags & ASSIGNMENT_BUILTIN) == 0) - return; - else if (b && (b->flags & ASSIGNMENT_BUILTIN)) - wcmd->word->flags |= W_ASSNBLTIN; - } - w->word->flags |= (W_NOSPLIT|W_NOGLOB|W_TILDEEXP|W_ASSIGNARG); -#if defined (ARRAY_VARS) - if (assoc) - w->word->flags |= W_ASSIGNASSOC; - if (array) - w->word->flags |= W_ASSIGNARRAY; -#endif - if (global) - w->word->flags |= W_ASSNGLOBAL; - - /* If we have an assignment builtin that does not create local variables, - make sure we create global variables even if we internally call - `declare'. The CHKLOCAL flag means to set attributes or values on - an existing local variable, if there is one. */ - if (b && ((b->flags & (ASSIGNMENT_BUILTIN|LOCALVAR_BUILTIN)) == ASSIGNMENT_BUILTIN)) - w->word->flags |= W_ASSNGLOBAL|W_CHKLOCAL; - else if (b && (b->flags & ASSIGNMENT_BUILTIN) && (b->flags & LOCALVAR_BUILTIN) && variable_context) - w->word->flags |= W_FORCELOCAL; - } -#if defined (ARRAY_VARS) - /* Note that we saw an associative array option to a builtin that takes - assignment statements. This is a bit of a kludge. */ - else if (w->word->word[0] == '-' && (strpbrk (w->word->word+1, "Aag") != 0)) -#else - else if (w->word->word[0] == '-' && strchr (w->word->word+1, 'g')) -#endif - { - if (b == 0) - { - b = builtin_address_internal (wcmd->word->word, 0); - if (b == 0 || (b->flags & ASSIGNMENT_BUILTIN) == 0) - return; - else if (b && (b->flags & ASSIGNMENT_BUILTIN)) - wcmd->word->flags |= W_ASSNBLTIN; - } - if ((wcmd->word->flags & W_ASSNBLTIN) && strchr (w->word->word+1, 'A')) - assoc = 1; - else if ((wcmd->word->flags & W_ASSNBLTIN) && strchr (w->word->word+1, 'a')) - array = 1; - if ((wcmd->word->flags & W_ASSNBLTIN) && strchr (w->word->word+1, 'g')) - global = 1; - } -} - -#if defined (ARRAY_VARS) -/* Set W_ARRAYREF on words that are valid array references to a builtin that - accepts them. This is intended to completely replace assoc_expand_once in - time. */ -static void -fix_arrayref_words (words) - WORD_LIST *words; -{ - WORD_LIST *w, *wcmd; - struct builtin *b; - - if (words == 0) - return; - - b = 0; - - /* Skip over assignment statements preceding a command name */ - wcmd = words; - for (wcmd = words; wcmd; wcmd = wcmd->next) - if ((wcmd->word->flags & W_ASSIGNMENT) == 0) - break; - - /* Skip over `command' */ - while (wcmd && wcmd->word && wcmd->word->word && STREQ (wcmd->word->word, "command")) - wcmd = wcmd->next; - - if (wcmd == 0) - return; - - /* If it's not an array reference builtin, we have nothing to do. */ - b = builtin_address_internal (wcmd->word->word, 0); - if (b == 0 || (b->flags & ARRAYREF_BUILTIN) == 0) - return; - - for (w = wcmd->next; w; w = w->next) - { - if (w->word && w->word->word && valid_array_reference (w->word->word, 0)) - w->word->flags |= W_ARRAYREF; - } -} -#endif - -#ifndef ISOPTION -# define ISOPTION(s, c) (s[0] == '-' && s[1] == c && s[2] == 0) -#endif - -#define RETURN_NOT_COMMAND() \ - do { if (typep) *typep = 0; return words; } while (0) - -/* Make sure we have `command [-p] command_name [args]', and handle skipping - over the usual `--' that ends the options. Returns the updated WORDS with - the command and options stripped and sets *TYPEP to a non-zero value. If - any other options are supplied, or there is not a command_name, we punt - and return a zero value in *TYPEP without updating WORDS. */ -static WORD_LIST * -check_command_builtin (words, typep) - WORD_LIST *words; - int *typep; -{ - int type; - WORD_LIST *w; - - w = words->next; - type = 1; - - if (w && ISOPTION (w->word->word, 'p')) /* command -p */ - { -#if defined (RESTRICTED_SHELL) - if (restricted) - RETURN_NOT_COMMAND(); -#endif - w = w->next; - type = 2; - } - - if (w && ISOPTION (w->word->word, '-')) /* command [-p] -- */ - w = w->next; - else if (w && w->word->word[0] == '-') /* any other option */ - RETURN_NOT_COMMAND(); - - if (w == 0 || w->word->word == 0) /* must have a command_name */ - RETURN_NOT_COMMAND(); - - if (typep) - *typep = type; - return w; -} - -/* Return 1 if the file found by searching $PATH for PATHNAME, defaulting - to PATHNAME, is a directory. Used by the autocd code below. */ -static int -is_dirname (pathname) - char *pathname; -{ - char *temp; - int ret; - - temp = search_for_command (pathname, 0); - ret = temp ? file_isdir (temp) : file_isdir (pathname); - free (temp); - return ret; -} - -/* The meaty part of all the executions. We have to start hacking the - real execution of commands here. Fork a process, set things up, - execute the command. */ -static int -execute_simple_command (simple_command, pipe_in, pipe_out, async, fds_to_close) - SIMPLE_COM *simple_command; - int pipe_in, pipe_out, async; - struct fd_bitmap *fds_to_close; -{ - WORD_LIST *words, *lastword; - char *command_line, *lastarg, *temp; - int first_word_quoted, result, builtin_is_special, already_forked, dofork; - int fork_flags, cmdflags; - pid_t old_last_async_pid; - sh_builtin_func_t *builtin; - SHELL_VAR *func; - volatile int old_builtin, old_command_builtin; - - result = EXECUTION_SUCCESS; - special_builtin_failed = builtin_is_special = 0; - command_line = (char *)0; - - QUIT; - - /* If we're in a function, update the line number information. */ - if (variable_context && interactive_shell && sourcelevel == 0) - { - /* line numbers in a function start at 1 */ - line_number -= function_line_number - 1; - if (line_number <= 0) - line_number = 1; - } - - /* Remember what this command line looks like at invocation. */ - command_string_index = 0; - print_simple_command (simple_command); - -#if 0 - if (signal_in_progress (DEBUG_TRAP) == 0 && (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0))) -#else - if (signal_in_progress (DEBUG_TRAP) == 0 && running_trap == 0) -#endif - { - FREE (the_printed_command_except_trap); - the_printed_command_except_trap = the_printed_command ? savestring (the_printed_command) : (char *)0; - } - - /* Run the debug trap before each simple command, but do it after we - update the line number information. */ - result = run_debug_trap (); -#if defined (DEBUGGER) - /* In debugging mode, if the DEBUG trap returns a non-zero status, we - skip the command. */ - if (debugging_mode && result != EXECUTION_SUCCESS) - return (EXECUTION_SUCCESS); -#endif - - cmdflags = simple_command->flags; - - first_word_quoted = - simple_command->words ? (simple_command->words->word->flags & W_QUOTED) : 0; - - last_command_subst_pid = NO_PID; - old_last_async_pid = last_asynchronous_pid; - - already_forked = 0; - - /* If we're in a pipeline or run in the background, set DOFORK so we - make the child early, before word expansion. This keeps assignment - statements from affecting the parent shell's environment when they - should not. */ - dofork = pipe_in != NO_PIPE || pipe_out != NO_PIPE || async; - - /* Something like `%2 &' should restart job 2 in the background, not cause - the shell to fork here. */ - if (dofork && pipe_in == NO_PIPE && pipe_out == NO_PIPE && - simple_command->words && simple_command->words->word && - simple_command->words->word->word && - (simple_command->words->word->word[0] == '%')) - dofork = 0; - - if (dofork) - { - char *p; - - /* Do this now, because execute_disk_command will do it anyway in the - vast majority of cases. */ - maybe_make_export_env (); - - /* Don't let a DEBUG trap overwrite the command string to be saved with - the process/job associated with this child. */ - fork_flags = async ? FORK_ASYNC : 0; - if (make_child (p = savestring (the_printed_command_except_trap), fork_flags) == 0) - { - already_forked = 1; - cmdflags |= CMD_NO_FORK; - - /* We redo some of what make_child() does with SUBSHELL_IGNTRAP */ - subshell_environment = SUBSHELL_FORK|SUBSHELL_IGNTRAP; /* XXX */ - if (pipe_in != NO_PIPE || pipe_out != NO_PIPE) - subshell_environment |= SUBSHELL_PIPE; - if (async) - subshell_environment |= SUBSHELL_ASYNC; - - /* We need to do this before piping to handle some really - pathological cases where one of the pipe file descriptors - is < 2. */ - if (fds_to_close) - close_fd_bitmap (fds_to_close); - - /* If we fork because of an input pipe, note input pipe for later to - inhibit async commands from redirecting stdin from /dev/null */ - stdin_redir |= pipe_in != NO_PIPE; - - do_piping (pipe_in, pipe_out); - pipe_in = pipe_out = NO_PIPE; -#if defined (COPROCESS_SUPPORT) - coproc_closeall (); -#endif - - last_asynchronous_pid = old_last_async_pid; - - if (async) - subshell_level++; /* not for pipes yet */ - -#if defined (JOB_CONTROL) - FREE (p); /* child doesn't use pointer */ -#endif - } - else - { - /* Don't let simple commands that aren't the last command in a - pipeline change $? for the rest of the pipeline (or at all). */ - if (pipe_out != NO_PIPE) - result = last_command_exit_value; - close_pipes (pipe_in, pipe_out); - command_line = (char *)NULL; /* don't free this. */ - return (result); - } - } - - QUIT; /* XXX */ - - /* If we are re-running this as the result of executing the `command' - builtin, do not expand the command words a second time. */ - if ((cmdflags & CMD_INHIBIT_EXPANSION) == 0) - { - current_fds_to_close = fds_to_close; - fix_assignment_words (simple_command->words); -#if defined (ARRAY_VARS) - fix_arrayref_words (simple_command->words); -#endif - /* Pass the ignore return flag down to command substitutions */ - if (cmdflags & CMD_IGNORE_RETURN) /* XXX */ - comsub_ignore_return++; - words = expand_words (simple_command->words); - if (cmdflags & CMD_IGNORE_RETURN) - comsub_ignore_return--; - current_fds_to_close = (struct fd_bitmap *)NULL; - } - else - words = copy_word_list (simple_command->words); - - /* It is possible for WORDS not to have anything left in it. - Perhaps all the words consisted of `$foo', and there was - no variable `$foo'. */ - if (words == 0) - { - this_command_name = 0; - result = execute_null_command (simple_command->redirects, - pipe_in, pipe_out, - already_forked ? 0 : async); - if (already_forked) - sh_exit (result); - else - { - bind_lastarg ((char *)NULL); - set_pipestatus_from_exit (result); - return (result); - } - } - - lastarg = (char *)NULL; - - begin_unwind_frame ("simple-command"); - - if (echo_command_at_execute && (cmdflags & CMD_COMMAND_BUILTIN) == 0) - xtrace_print_word_list (words, 1); - - builtin = (sh_builtin_func_t *)NULL; - func = (SHELL_VAR *)NULL; - - /* This test is still here in case we want to change the command builtin - handler code below to recursively call execute_simple_command (after - modifying the simple_command struct). */ - if ((cmdflags & CMD_NO_FUNCTIONS) == 0) - { - /* Posix.2 says special builtins are found before functions. We - don't set builtin_is_special anywhere other than here, because - this path is followed only when the `command' builtin is *not* - being used, and we don't want to exit the shell if a special - builtin executed with `command builtin' fails. `command' is not - a special builtin. */ - if (posixly_correct) - { - builtin = find_special_builtin (words->word->word); - if (builtin) - builtin_is_special = 1; - } - if (builtin == 0) - func = find_function (words->word->word); - } - - /* What happens in posix mode when an assignment preceding a command name - fails. This should agree with the code in execute_cmd.c: - do_assignment_statements(), even though I don't think it's executed any - more. */ - if (posixly_correct && tempenv_assign_error) - { -#if defined (DEBUG) - /* I don't know if this clause is ever executed, so let's check */ -itrace("execute_simple_command: posix mode tempenv assignment error"); -#endif - last_command_exit_value = EXECUTION_FAILURE; -#if defined (STRICT_POSIX) - jump_to_top_level ((interactive_shell == 0) ? FORCE_EOF : DISCARD); -#else - if (interactive_shell == 0 && builtin_is_special) - jump_to_top_level (FORCE_EOF); - else if (interactive_shell == 0) - jump_to_top_level (DISCARD); /* XXX - maybe change later */ - else - jump_to_top_level (DISCARD); -#endif - } - tempenv_assign_error = 0; /* don't care about this any more */ - - /* This is where we handle the command builtin as a pseudo-reserved word - prefix. This allows us to optimize away forks if we can. */ - old_command_builtin = -1; - if (builtin == 0 && func == 0) - { - WORD_LIST *disposer, *l; - int cmdtype; - - builtin = find_shell_builtin (words->word->word); - while (builtin == command_builtin) - { - disposer = words; - cmdtype = 0; - words = check_command_builtin (words, &cmdtype); - if (cmdtype > 0) /* command -p [--] words */ - { - for (l = disposer; l->next != words; l = l->next) - ; - l->next = 0; - dispose_words (disposer); - cmdflags |= CMD_COMMAND_BUILTIN | CMD_NO_FUNCTIONS; - if (cmdtype == 2) - cmdflags |= CMD_STDPATH; - builtin = find_shell_builtin (words->word->word); - } - else - break; - } - if (cmdflags & CMD_COMMAND_BUILTIN) - { - old_command_builtin = executing_command_builtin; - unwind_protect_int (executing_command_builtin); - executing_command_builtin |= 1; - } - builtin = 0; - } - - add_unwind_protect (dispose_words, words); - QUIT; - - /* Bind the last word in this command to "$_" after execution. */ - for (lastword = words; lastword->next; lastword = lastword->next) - ; - lastarg = lastword->word->word; - -#if defined (JOB_CONTROL) - /* Is this command a job control related thing? */ - if (words->word->word[0] == '%' && already_forked == 0) - { - this_command_name = async ? "bg" : "fg"; - last_shell_builtin = this_shell_builtin; - this_shell_builtin = builtin_address (this_command_name); - result = (*this_shell_builtin) (words); - goto return_result; - } - - /* One other possibililty. The user may want to resume an existing job. - If they do, find out whether this word is a candidate for a running - job. */ - if (job_control && already_forked == 0 && async == 0 && - !first_word_quoted && - !words->next && - words->word->word[0] && - !simple_command->redirects && - pipe_in == NO_PIPE && - pipe_out == NO_PIPE && - (temp = get_string_value ("auto_resume"))) - { - int job, jflags, started_status; - - jflags = JM_STOPPED|JM_FIRSTMATCH; - if (STREQ (temp, "exact")) - jflags |= JM_EXACT; - else if (STREQ (temp, "substring")) - jflags |= JM_SUBSTRING; - else - jflags |= JM_PREFIX; - job = get_job_by_name (words->word->word, jflags); - if (job != NO_JOB) - { - run_unwind_frame ("simple-command"); - this_command_name = "fg"; - last_shell_builtin = this_shell_builtin; - this_shell_builtin = builtin_address ("fg"); - - started_status = start_job (job, 1); - return ((started_status < 0) ? EXECUTION_FAILURE : started_status); - } - } -#endif /* JOB_CONTROL */ - -run_builtin: - /* Remember the name of this command globally. */ - this_command_name = words->word->word; - - QUIT; - - /* This command could be a shell builtin or a user-defined function. - We have already found special builtins by this time, so we do not - set builtin_is_special. If this is a function or builtin, and we - have pipes, then fork a subshell in here. Otherwise, just execute - the command directly. */ - if (func == 0 && builtin == 0) - builtin = find_shell_builtin (this_command_name); - - last_shell_builtin = this_shell_builtin; - this_shell_builtin = builtin; - - if (builtin || func) - { - if (builtin) - { - old_builtin = executing_builtin; - unwind_protect_int (executing_builtin); /* modified in execute_builtin */ - if (old_command_builtin == -1) /* sentinel, can be set above */ - { - old_command_builtin = executing_command_builtin; - unwind_protect_int (executing_command_builtin); /* ditto and set above */ - } - } - if (already_forked) - { - /* reset_terminating_signals (); */ /* XXX */ - /* Reset the signal handlers in the child, but don't free the - trap strings. Set a flag noting that we have to free the - trap strings if we run trap to change a signal disposition. */ - reset_signal_handlers (); - subshell_environment |= SUBSHELL_RESETTRAP; - subshell_environment &= ~SUBSHELL_IGNTRAP; - - if (async) - { - if ((cmdflags & CMD_STDIN_REDIR) && - pipe_in == NO_PIPE && - (stdin_redirects (simple_command->redirects) == 0)) - async_redirect_stdin (); - setup_async_signals (); - } - - if (async == 0) - subshell_level++; - execute_subshell_builtin_or_function - (words, simple_command->redirects, builtin, func, - pipe_in, pipe_out, async, fds_to_close, - cmdflags); - subshell_level--; - } - else - { - result = execute_builtin_or_function - (words, builtin, func, simple_command->redirects, fds_to_close, - cmdflags); - if (builtin) - { - if (result > EX_SHERRBASE) - { - switch (result) - { - case EX_REDIRFAIL: - case EX_BADASSIGN: - case EX_EXPFAIL: - /* These errors cause non-interactive posix mode shells to exit */ - if (posixly_correct && builtin_is_special && interactive_shell == 0) - { - last_command_exit_value = EXECUTION_FAILURE; - jump_to_top_level (ERREXIT); - } - break; - case EX_DISKFALLBACK: - /* XXX - experimental */ - executing_builtin = old_builtin; - executing_command_builtin = old_command_builtin; - builtin = 0; - - /* The redirections have already been `undone', so this - will have to do them again. But piping is forever. */ - pipe_in = pipe_out = -1; - goto execute_from_filesystem; - } - result = builtin_status (result); - if (builtin_is_special) - special_builtin_failed = 1; /* XXX - take command builtin into account? */ - } - /* In POSIX mode, if there are assignment statements preceding - a special builtin, they persist after the builtin - completes. */ - if (posixly_correct && builtin_is_special && temporary_env) - merge_temporary_env (); - } - else /* function */ - { - if (result == EX_USAGE) - result = EX_BADUSAGE; - else if (result > EX_SHERRBASE) - result = builtin_status (result); - } - - set_pipestatus_from_exit (result); - - goto return_result; - } - } - - if (autocd && interactive && words->word && is_dirname (words->word->word)) - { - words = make_word_list (make_word ("--"), words); - words = make_word_list (make_word ("cd"), words); - xtrace_print_word_list (words, 0); - func = find_function ("cd"); - goto run_builtin; - } - -execute_from_filesystem: - if (command_line == 0) - command_line = savestring (the_printed_command_except_trap ? the_printed_command_except_trap : ""); - -#if defined (PROCESS_SUBSTITUTION) - /* The old code did not test already_forked and only did this if - subshell_environment&SUBSHELL_COMSUB != 0 (comsubs and procsubs). Other - uses of the no-fork optimization left FIFOs in $TMPDIR */ - if (already_forked == 0 && (cmdflags & CMD_NO_FORK) && fifos_pending() > 0) - cmdflags &= ~CMD_NO_FORK; -#endif - result = execute_disk_command (words, simple_command->redirects, command_line, - pipe_in, pipe_out, async, fds_to_close, - cmdflags); - - return_result: - bind_lastarg (lastarg); - FREE (command_line); - dispose_words (words); - if (builtin) - { - executing_builtin = old_builtin; - executing_command_builtin = old_command_builtin; - } - discard_unwind_frame ("simple-command"); - this_command_name = (char *)NULL; /* points to freed memory now */ - return (result); -} - -/* Translate the special builtin exit statuses. We don't really need a - function for this; it's a placeholder for future work. */ -static int -builtin_status (result) - int result; -{ - int r; - - switch (result) - { - case EX_USAGE: - case EX_BADSYNTAX: - r = EX_BADUSAGE; - break; - case EX_REDIRFAIL: - case EX_BADASSIGN: - case EX_EXPFAIL: - r = EXECUTION_FAILURE; - break; - default: - /* other special exit statuses not yet defined */ - r = (result > EX_SHERRBASE) ? EXECUTION_FAILURE : EXECUTION_SUCCESS; - break; - } - return (r); -} - -static int -execute_builtin (builtin, words, flags, subshell) - sh_builtin_func_t *builtin; - WORD_LIST *words; - int flags, subshell; -{ - int result, eval_unwind, ignexit_flag; - int isbltinenv, should_keep; - char *error_trap; - - error_trap = 0; - should_keep = 0; - - /* The eval builtin calls parse_and_execute, which does not know about - the setting of flags, and always calls the execution functions with - flags that will exit the shell on an error if -e is set. If the - eval builtin is being called, and we're supposed to ignore the exit - value of the command, we turn the -e flag off ourselves and disable - the ERR trap, then restore them when the command completes. This is - also a problem (as below) for the command and source/. builtins. */ - if (subshell == 0 && (flags & CMD_IGNORE_RETURN) && - (builtin == eval_builtin || (flags & CMD_COMMAND_BUILTIN) || builtin == source_builtin)) - { - begin_unwind_frame ("eval_builtin"); - unwind_protect_int (exit_immediately_on_error); - unwind_protect_int (builtin_ignoring_errexit); - error_trap = TRAP_STRING (ERROR_TRAP); - if (error_trap) - { - error_trap = savestring (error_trap); - add_unwind_protect (xfree, error_trap); - add_unwind_protect (set_error_trap, error_trap); - restore_default_signal (ERROR_TRAP); - } - exit_immediately_on_error = 0; - ignexit_flag = builtin_ignoring_errexit; - builtin_ignoring_errexit = 1; - eval_unwind = 1; - } - else - eval_unwind = 0; - - /* The temporary environment for a builtin is supposed to apply to - all commands executed by that builtin. Currently, this is a - problem only with the `unset', `source' and `eval' builtins. - `mapfile' is a special case because it uses evalstring (same as - eval or source) to run its callbacks. */ - /* SHOULD_KEEP is for the pop_scope call below; it only matters when - posixly_correct is set, but we should propagate the temporary environment - to the enclosing environment only for special builtins. */ - isbltinenv = (builtin == source_builtin || builtin == eval_builtin || builtin == unset_builtin || builtin == mapfile_builtin); - should_keep = isbltinenv && builtin != mapfile_builtin; -#if defined (HISTORY) && defined (READLINE) - if (builtin == fc_builtin || builtin == read_builtin) - { - isbltinenv = 1; - should_keep = 0; - } -#endif - - if (isbltinenv) - { - if (subshell == 0) - begin_unwind_frame ("builtin_env"); - - if (temporary_env) - { - push_scope (VC_BLTNENV, temporary_env); - if (flags & CMD_COMMAND_BUILTIN) - should_keep = 0; - if (subshell == 0) - add_unwind_protect (pop_scope, should_keep ? "1" : 0); - temporary_env = (HASH_TABLE *)NULL; - } - } - - if (subshell == 0 && builtin == eval_builtin) - { - if (evalnest_max > 0 && evalnest >= evalnest_max) - { - internal_error (_("eval: maximum eval nesting level exceeded (%d)"), evalnest); - evalnest = 0; - jump_to_top_level (DISCARD); - } - unwind_protect_int (evalnest); - /* The test for subshell == 0 above doesn't make a difference */ - evalnest++; /* execute_subshell_builtin_or_function sets this to 0 */ - } - else if (subshell == 0 && builtin == source_builtin) - { - if (sourcenest_max > 0 && sourcenest >= sourcenest_max) - { - internal_error (_("%s: maximum source nesting level exceeded (%d)"), this_command_name, sourcenest); - sourcenest = 0; - jump_to_top_level (DISCARD); - } - unwind_protect_int (sourcenest); - /* The test for subshell == 0 above doesn't make a difference */ - sourcenest++; /* execute_subshell_builtin_or_function sets this to 0 */ - } - - /* `return' does a longjmp() back to a saved environment in execute_function. - If a variable assignment list preceded the command, and the shell is - running in POSIX mode, we need to merge that into the shell_variables - table, since `return' is a POSIX special builtin. We don't do this if - it's being run by the `command' builtin, since that's supposed to inhibit - the special builtin properties. */ - if (posixly_correct && subshell == 0 && builtin == return_builtin && (flags & CMD_COMMAND_BUILTIN) == 0 && temporary_env) - { - begin_unwind_frame ("return_temp_env"); - add_unwind_protect (merge_temporary_env, (char *)NULL); - } - - executing_builtin++; - executing_command_builtin |= builtin == command_builtin; - result = ((*builtin) (words->next)); - - /* This shouldn't happen, but in case `return' comes back instead of - longjmp'ing, we need to unwind. */ - if (posixly_correct && subshell == 0 && builtin == return_builtin && temporary_env) - discard_unwind_frame ("return_temp_env"); - - if (subshell == 0 && isbltinenv) - run_unwind_frame ("builtin_env"); - - if (eval_unwind) - { - builtin_ignoring_errexit = ignexit_flag; - exit_immediately_on_error = builtin_ignoring_errexit ? 0 : errexit_flag; - if (error_trap) - { - set_error_trap (error_trap); - free (error_trap); - } - discard_unwind_frame ("eval_builtin"); - } - - return (result); -} - -static void -maybe_restore_getopt_state (gs) - sh_getopt_state_t *gs; -{ - /* If we have a local copy of OPTIND and it's at the right (current) - context, then we restore getopt's internal state. If not, we just - let it go. We know there is a local OPTIND if gs->gs_flags & 1. - This is set below in execute_function() before the context is run. */ - if (gs->gs_flags & 1) - sh_getopt_restore_istate (gs); - else - free (gs); -} - -#if defined (ARRAY_VARS) -void -restore_funcarray_state (fa) - struct func_array_state *fa; -{ - SHELL_VAR *nfv; - ARRAY *funcname_a; - - array_pop (fa->source_a); - array_pop (fa->lineno_a); - - GET_ARRAY_FROM_VAR ("FUNCNAME", nfv, funcname_a); - if (nfv == fa->funcname_v) - array_pop (funcname_a); - - free (fa); -} -#endif - -static int -execute_function (var, words, flags, fds_to_close, async, subshell) - SHELL_VAR *var; - WORD_LIST *words; - int flags; - struct fd_bitmap *fds_to_close; - int async, subshell; -{ - int return_val, result, lineno; - COMMAND *tc, *fc, *save_current; - char *debug_trap, *error_trap, *return_trap; -#if defined (ARRAY_VARS) - SHELL_VAR *funcname_v, *bash_source_v, *bash_lineno_v; - ARRAY *funcname_a; - volatile ARRAY *bash_source_a; - volatile ARRAY *bash_lineno_a; - struct func_array_state *fa; -#endif - FUNCTION_DEF *shell_fn; - char *sfile, *t; - sh_getopt_state_t *gs; - SHELL_VAR *gv; - - USE_VAR(fc); - - if (funcnest_max > 0 && funcnest >= funcnest_max) - { - internal_error (_("%s: maximum function nesting level exceeded (%d)"), var->name, funcnest); - funcnest = 0; /* XXX - should we reset it somewhere else? */ - jump_to_top_level (DISCARD); - } - -#if defined (ARRAY_VARS) - GET_ARRAY_FROM_VAR ("FUNCNAME", funcname_v, funcname_a); - GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a); - GET_ARRAY_FROM_VAR ("BASH_LINENO", bash_lineno_v, bash_lineno_a); -#endif - - tc = (COMMAND *)copy_command (function_cell (var)); - if (tc && (flags & CMD_IGNORE_RETURN)) - tc->flags |= CMD_IGNORE_RETURN; - - /* A limited attempt at optimization: shell functions at the end of command - substitutions that are already marked NO_FORK. */ - if (tc && (flags & CMD_NO_FORK) && (subshell_environment & SUBSHELL_COMSUB)) - optimize_shell_function (tc); - - gs = sh_getopt_save_istate (); - if (subshell == 0) - { - begin_unwind_frame ("function_calling"); - /* If the shell is in posix mode, this will push the variables in - the temporary environment to the "current shell environment" (the - global scope), and dispose the temporary env before setting it to - NULL later. This behavior has disappeared from the latest edition - of the standard, so I will eventually remove it from variables.c: - push_var_context. */ - push_context (var->name, subshell, temporary_env); - /* This has to be before the pop_context(), because the unwinding of - local variables may cause the restore of a local declaration of - OPTIND to force a getopts state reset. */ - add_unwind_protect (maybe_restore_getopt_state, gs); - add_unwind_protect (pop_context, (char *)NULL); - unwind_protect_int (line_number); - unwind_protect_int (line_number_for_err_trap); - unwind_protect_int (function_line_number); - unwind_protect_int (return_catch_flag); - unwind_protect_jmp_buf (return_catch); - add_unwind_protect (dispose_command, (char *)tc); - unwind_protect_pointer (this_shell_function); - unwind_protect_int (funcnest); - unwind_protect_int (loop_level); - } - else - push_context (var->name, subshell, temporary_env); /* don't unwind-protect for subshells */ - - temporary_env = (HASH_TABLE *)NULL; - - this_shell_function = var; - make_funcname_visible (1); - - debug_trap = TRAP_STRING(DEBUG_TRAP); - error_trap = TRAP_STRING(ERROR_TRAP); - return_trap = TRAP_STRING(RETURN_TRAP); - - /* The order of the unwind protects for debug_trap, error_trap and - return_trap is important here! unwind-protect commands are run - in reverse order of registration. If this causes problems, take - out the xfree unwind-protect calls and live with the small memory leak. */ - - /* function_trace_mode != 0 means that all functions inherit the DEBUG trap. - if the function has the trace attribute set, it inherits the DEBUG trap */ - if (debug_trap && ((trace_p (var) == 0) && function_trace_mode == 0)) - { - if (subshell == 0) - { - debug_trap = savestring (debug_trap); - add_unwind_protect (xfree, debug_trap); - add_unwind_protect (maybe_set_debug_trap, debug_trap); - } - restore_default_signal (DEBUG_TRAP); - } - - /* error_trace_mode != 0 means that functions inherit the ERR trap. */ - if (error_trap && error_trace_mode == 0) - { - if (subshell == 0) - { - error_trap = savestring (error_trap); - add_unwind_protect (xfree, error_trap); - add_unwind_protect (maybe_set_error_trap, error_trap); - } - restore_default_signal (ERROR_TRAP); - } - - /* Shell functions inherit the RETURN trap if function tracing is on - globally or on individually for this function. */ - if (return_trap && (signal_in_progress (DEBUG_TRAP) || ((trace_p (var) == 0) && function_trace_mode == 0))) - { - if (subshell == 0) - { - return_trap = savestring (return_trap); - add_unwind_protect (xfree, return_trap); - add_unwind_protect (maybe_set_return_trap, return_trap); - } - restore_default_signal (RETURN_TRAP); - } - - funcnest++; -#if defined (ARRAY_VARS) - /* This is quite similar to the code in shell.c and elsewhere. */ - shell_fn = find_function_def (this_shell_function->name); - sfile = shell_fn ? shell_fn->source_file : ""; - array_push ((ARRAY *)funcname_a, this_shell_function->name); - - array_push ((ARRAY *)bash_source_a, sfile); - lineno = GET_LINE_NUMBER (); - t = itos (lineno); - array_push ((ARRAY *)bash_lineno_a, t); - free (t); -#endif - -#if defined (ARRAY_VARS) - fa = (struct func_array_state *)xmalloc (sizeof (struct func_array_state)); - fa->source_a = (ARRAY *)bash_source_a; - fa->source_v = bash_source_v; - fa->lineno_a = (ARRAY *)bash_lineno_a; - fa->lineno_v = bash_lineno_v; - fa->funcname_a = (ARRAY *)funcname_a; - fa->funcname_v = funcname_v; - if (subshell == 0) - add_unwind_protect (restore_funcarray_state, fa); -#endif - - /* The temporary environment for a function is supposed to apply to - all commands executed within the function body. */ - - /* Initialize BASH_ARGC and BASH_ARGV before we blow away the positional - parameters */ - if (debugging_mode || shell_compatibility_level <= 44) - init_bash_argv (); - - remember_args (words->next, 1); - - /* Update BASH_ARGV and BASH_ARGC */ - if (debugging_mode) - { - push_args (words->next); - if (subshell == 0) - add_unwind_protect (pop_args, 0); - } - - /* Number of the line on which the function body starts. */ - line_number = function_line_number = tc->line; - -#if defined (JOB_CONTROL) - if (subshell) - stop_pipeline (async, (COMMAND *)NULL); -#endif - - if (shell_compatibility_level > 43) - loop_level = 0; - - fc = tc; - - from_return_trap = 0; - - return_catch_flag++; - return_val = setjmp_nosigs (return_catch); - - if (return_val) - { - result = return_catch_value; - /* Run the RETURN trap in the function's context. */ - save_current = currently_executing_command; - if (from_return_trap == 0) - run_return_trap (); - currently_executing_command = save_current; - } - else - { - /* Run the debug trap here so we can trap at the start of a function's - execution rather than the execution of the body's first command. */ - showing_function_line = 1; - save_current = currently_executing_command; - result = run_debug_trap (); -#if defined (DEBUGGER) - /* In debugging mode, if the DEBUG trap returns a non-zero status, we - skip the command. */ - if (debugging_mode == 0 || result == EXECUTION_SUCCESS) - { - showing_function_line = 0; - currently_executing_command = save_current; - result = execute_command_internal (fc, 0, NO_PIPE, NO_PIPE, fds_to_close); - - /* Run the RETURN trap in the function's context */ - save_current = currently_executing_command; - run_return_trap (); - currently_executing_command = save_current; - } -#else - result = execute_command_internal (fc, 0, NO_PIPE, NO_PIPE, fds_to_close); - - save_current = currently_executing_command; - run_return_trap (); - currently_executing_command = save_current; -#endif - showing_function_line = 0; - } - - /* If we have a local copy of OPTIND, note it in the saved getopts state. */ - gv = find_variable ("OPTIND"); - if (gv && gv->context == variable_context) - gs->gs_flags |= 1; - - if (subshell == 0) - run_unwind_frame ("function_calling"); -#if defined (ARRAY_VARS) - else - { - restore_funcarray_state (fa); - /* Restore BASH_ARGC and BASH_ARGV */ - if (debugging_mode) - pop_args (); - } -#endif - - if (variable_context == 0 || this_shell_function == 0) - { - make_funcname_visible (0); -#if defined (PROCESS_SUBSTITUTION) - unlink_fifo_list (); -#endif - } - - return (result); -} - -/* A convenience routine for use by other parts of the shell to execute - a particular shell function. */ -int -execute_shell_function (var, words) - SHELL_VAR *var; - WORD_LIST *words; -{ - int ret; - struct fd_bitmap *bitmap; - - bitmap = new_fd_bitmap (FD_BITMAP_DEFAULT_SIZE); - begin_unwind_frame ("execute-shell-function"); - add_unwind_protect (dispose_fd_bitmap, (char *)bitmap); - - ret = execute_function (var, words, 0, bitmap, 0, 0); - - dispose_fd_bitmap (bitmap); - discard_unwind_frame ("execute-shell-function"); - - return ret; -} - -/* Execute a shell builtin or function in a subshell environment. This - routine does not return; it only calls exit(). If BUILTIN is non-null, - it points to a function to call to execute a shell builtin; otherwise - VAR points at the body of a function to execute. WORDS is the arguments - to the command, REDIRECTS specifies redirections to perform before the - command is executed. */ -static void -execute_subshell_builtin_or_function (words, redirects, builtin, var, - pipe_in, pipe_out, async, fds_to_close, - flags) - WORD_LIST *words; - REDIRECT *redirects; - sh_builtin_func_t *builtin; - SHELL_VAR *var; - int pipe_in, pipe_out, async; - struct fd_bitmap *fds_to_close; - int flags; -{ - int result, r, funcvalue; -#if defined (JOB_CONTROL) - int jobs_hack; - - jobs_hack = (builtin == jobs_builtin) && - ((subshell_environment & SUBSHELL_ASYNC) == 0 || pipe_out != NO_PIPE); -#endif - - /* A subshell is neither a login shell nor interactive. */ - login_shell = interactive = 0; - if (builtin == eval_builtin) - evalnest = 0; - else if (builtin == source_builtin) - sourcenest = 0; - - if (async) - subshell_environment |= SUBSHELL_ASYNC; - if (pipe_in != NO_PIPE || pipe_out != NO_PIPE) - subshell_environment |= SUBSHELL_PIPE; - - maybe_make_export_env (); /* XXX - is this needed? */ - -#if defined (JOB_CONTROL) - /* Eradicate all traces of job control after we fork the subshell, so - all jobs begun by this subshell are in the same process group as - the shell itself. */ - - /* Allow the output of `jobs' to be piped. */ - if (jobs_hack) - kill_current_pipeline (); - else - without_job_control (); - - set_sigchld_handler (); -#else - without_job_control (); -#endif /* JOB_CONTROL */ - - set_sigint_handler (); - - if (fds_to_close) - close_fd_bitmap (fds_to_close); - - do_piping (pipe_in, pipe_out); - - if (do_redirections (redirects, RX_ACTIVE) != 0) - exit (EXECUTION_FAILURE); - - if (builtin) - { - /* Give builtins a place to jump back to on failure, - so we don't go back up to main(). */ - result = setjmp_nosigs (top_level); - - /* Give the return builtin a place to jump to when executed in a subshell - or pipeline */ - funcvalue = 0; - if (return_catch_flag && builtin == return_builtin) - funcvalue = setjmp_nosigs (return_catch); - - if (result == EXITPROG || result == EXITBLTIN) - subshell_exit (last_command_exit_value); - else if (result) - subshell_exit (EXECUTION_FAILURE); - else if (funcvalue) - subshell_exit (return_catch_value); - else - { - r = execute_builtin (builtin, words, flags, 1); - fflush (stdout); - if (r == EX_USAGE) - r = EX_BADUSAGE; - /* XXX - experimental */ - else if (r == EX_DISKFALLBACK) - { - char *command_line; - - command_line = savestring (the_printed_command_except_trap ? the_printed_command_except_trap : ""); - r = execute_disk_command (words, (REDIRECT *)0, command_line, - -1, -1, async, (struct fd_bitmap *)0, flags|CMD_NO_FORK); - } - subshell_exit (r); - } - } - else - { - r = execute_function (var, words, flags, fds_to_close, async, 1); - fflush (stdout); - subshell_exit (r); - } -} - -/* Execute a builtin or function in the current shell context. If BUILTIN - is non-null, it is the builtin command to execute, otherwise VAR points - to the body of a function. WORDS are the command's arguments, REDIRECTS - are the redirections to perform. FDS_TO_CLOSE is the usual bitmap of - file descriptors to close. - - If BUILTIN is exec_builtin, the redirections specified in REDIRECTS are - not undone before this function returns. */ -static int -execute_builtin_or_function (words, builtin, var, redirects, - fds_to_close, flags) - WORD_LIST *words; - sh_builtin_func_t *builtin; - SHELL_VAR *var; - REDIRECT *redirects; - struct fd_bitmap *fds_to_close; - int flags; -{ - int result; - REDIRECT *saved_undo_list; -#if defined (PROCESS_SUBSTITUTION) - int ofifo, nfifo, osize; - void *ofifo_list; -#endif - -#if defined (PROCESS_SUBSTITUTION) - begin_unwind_frame ("saved_fifos"); - /* If we return, we longjmp and don't get a chance to restore the old - fifo list, so we add an unwind protect to free it */ - ofifo = num_fifos (); - ofifo_list = copy_fifo_list (&osize); - if (ofifo_list) - add_unwind_protect (xfree, ofifo_list); -#endif - - if (do_redirections (redirects, RX_ACTIVE|RX_UNDOABLE) != 0) - { - undo_partial_redirects (); - dispose_exec_redirects (); -#if defined (PROCESS_SUBSTITUTION) - free (ofifo_list); -#endif - return (EX_REDIRFAIL); /* was EXECUTION_FAILURE */ - } - - saved_undo_list = redirection_undo_list; - - /* Calling the "exec" builtin changes redirections forever. */ - if (builtin == exec_builtin) - { - dispose_redirects (saved_undo_list); - saved_undo_list = exec_redirection_undo_list; - exec_redirection_undo_list = (REDIRECT *)NULL; - } - else - dispose_exec_redirects (); - - if (saved_undo_list) - { - begin_unwind_frame ("saved-redirects"); - add_unwind_protect (cleanup_redirects, (char *)saved_undo_list); - } - - redirection_undo_list = (REDIRECT *)NULL; - - if (builtin) - result = execute_builtin (builtin, words, flags, 0); - else - result = execute_function (var, words, flags, fds_to_close, 0, 0); - - /* We do this before undoing the effects of any redirections. */ - fflush (stdout); - fpurge (stdout); - if (ferror (stdout)) - clearerr (stdout); - - /* If we are executing the `command' builtin, but this_shell_builtin is - set to `exec_builtin', we know that we have something like - `command exec [redirection]', since otherwise `exec' would have - overwritten the shell and we wouldn't get here. In this case, we - want to behave as if the `command' builtin had not been specified - and preserve the redirections. */ - if (builtin == command_builtin && this_shell_builtin == exec_builtin) - { - int discard; - - discard = 0; - if (saved_undo_list) - { - dispose_redirects (saved_undo_list); - discard = 1; - } - redirection_undo_list = exec_redirection_undo_list; - saved_undo_list = exec_redirection_undo_list = (REDIRECT *)NULL; - if (discard) - discard_unwind_frame ("saved-redirects"); - } - - if (saved_undo_list) - { - redirection_undo_list = saved_undo_list; - discard_unwind_frame ("saved-redirects"); - } - - undo_partial_redirects (); - -#if defined (PROCESS_SUBSTITUTION) - /* Close any FIFOs created by this builtin or function. */ - nfifo = num_fifos (); - if (nfifo > ofifo) - close_new_fifos (ofifo_list, osize); - if (ofifo_list) - free (ofifo_list); - discard_unwind_frame ("saved_fifos"); -#endif - - return (result); -} - -void -setup_async_signals () -{ -#if defined (__BEOS__) - set_signal_handler (SIGHUP, SIG_IGN); /* they want csh-like behavior */ -#endif - -#if defined (JOB_CONTROL) - if (job_control == 0) -#endif - { - /* Make sure we get the original signal dispositions now so we don't - confuse the trap builtin later if the subshell tries to use it to - reset SIGINT/SIGQUIT. Don't call set_signal_ignored; that sets - the value of original_signals to SIG_IGN. Posix interpretation 751. */ - get_original_signal (SIGINT); - set_signal_handler (SIGINT, SIG_IGN); - - get_original_signal (SIGQUIT); - set_signal_handler (SIGQUIT, SIG_IGN); - } -} - -/* Execute a simple command that is hopefully defined in a disk file - somewhere. - - 1) fork () - 2) connect pipes - 3) look up the command - 4) do redirections - 5) execve () - 6) If the execve failed, see if the file has executable mode set. - If so, and it isn't a directory, then execute its contents as - a shell script. - - Note that the filename hashing stuff has to take place up here, - in the parent. This is probably why the Bourne style shells - don't handle it, since that would require them to go through - this gnarly hair, for no good reason. - - NOTE: callers expect this to fork or exit(). */ - -/* Name of a shell function to call when a command name is not found. */ -#ifndef NOTFOUND_HOOK -# define NOTFOUND_HOOK "command_not_found_handle" -#endif - -static int -execute_disk_command (words, redirects, command_line, pipe_in, pipe_out, - async, fds_to_close, cmdflags) - WORD_LIST *words; - REDIRECT *redirects; - char *command_line; - int pipe_in, pipe_out, async; - struct fd_bitmap *fds_to_close; - int cmdflags; -{ - char *pathname, *command, **args, *p; - int nofork, stdpath, result, fork_flags; - pid_t pid; - SHELL_VAR *hookf; - WORD_LIST *wl; - - stdpath = (cmdflags & CMD_STDPATH); /* use command -p path */ - nofork = (cmdflags & CMD_NO_FORK); /* Don't fork, just exec, if no pipes */ - pathname = words->word->word; - - p = 0; - result = EXECUTION_SUCCESS; -#if defined (RESTRICTED_SHELL) - command = (char *)NULL; - if (restricted && mbschr (pathname, '/')) - { - internal_error (_("%s: restricted: cannot specify `/' in command names"), - pathname); - result = last_command_exit_value = EXECUTION_FAILURE; - - /* If we're not going to fork below, we must already be in a child - process or a context in which it's safe to call exit(2). */ - if (nofork && pipe_in == NO_PIPE && pipe_out == NO_PIPE) - exit (last_command_exit_value); - else - goto parent_return; - } -#endif /* RESTRICTED_SHELL */ - - /* If we want to change this so `command -p' (CMD_STDPATH) does not insert - any pathname it finds into the hash table, it should read - command = search_for_command (pathname, stdpath ? CMDSRCH_STDPATH : CMDSRCH_HASH); - */ - command = search_for_command (pathname, CMDSRCH_HASH|(stdpath ? CMDSRCH_STDPATH : 0)); - QUIT; - - if (command) - { - /* If we're optimizing out the fork (implicit `exec'), decrement the - shell level like `exec' would do. Don't do this if we are already - in a pipeline environment, assuming it's already been done. */ - if (nofork && pipe_in == NO_PIPE && pipe_out == NO_PIPE && (subshell_environment & SUBSHELL_PIPE) == 0) - adjust_shell_level (-1); - - maybe_make_export_env (); - put_command_name_into_env (command); - } - - /* We have to make the child before we check for the non-existence - of COMMAND, since we want the error messages to be redirected. */ - /* If we can get away without forking and there are no pipes to deal with, - don't bother to fork, just directly exec the command. */ - if (nofork && pipe_in == NO_PIPE && pipe_out == NO_PIPE) - pid = 0; - else - { - fork_flags = async ? FORK_ASYNC : 0; - pid = make_child (p = savestring (command_line), fork_flags); - } - - if (pid == 0) - { - int old_interactive; - - reset_terminating_signals (); /* XXX */ - /* Cancel traps, in trap.c. */ - restore_original_signals (); - subshell_environment &= ~SUBSHELL_IGNTRAP; - -#if defined (JOB_CONTROL) - FREE (p); -#endif - - /* restore_original_signals may have undone the work done - by make_child to ensure that SIGINT and SIGQUIT are ignored - in asynchronous children. */ - if (async) - { - if ((cmdflags & CMD_STDIN_REDIR) && - pipe_in == NO_PIPE && - (stdin_redirects (redirects) == 0)) - async_redirect_stdin (); - setup_async_signals (); - } - - /* This functionality is now provided by close-on-exec of the - file descriptors manipulated by redirection and piping. - Some file descriptors still need to be closed in all children - because of the way bash does pipes; fds_to_close is a - bitmap of all such file descriptors. */ - if (fds_to_close) - close_fd_bitmap (fds_to_close); - - do_piping (pipe_in, pipe_out); - - old_interactive = interactive; - if (async) - interactive = 0; - - subshell_environment |= SUBSHELL_FORK; /* XXX - was just = */ - -#if defined (PROCESS_SUBSTITUTION) && !defined (HAVE_DEV_FD) - clear_fifo_list (); /* XXX - we haven't created any FIFOs */ -#endif - - /* reset shell_pgrp to pipeline_pgrp here for word expansions performed - by the redirections here? */ - if (redirects && (do_redirections (redirects, RX_ACTIVE) != 0)) - { -#if defined (PROCESS_SUBSTITUTION) - /* Try to remove named pipes that may have been created as the - result of redirections. */ - unlink_all_fifos (); -#endif /* PROCESS_SUBSTITUTION */ - exit (EXECUTION_FAILURE); - } - -#if defined (PROCESS_SUBSTITUTION) && !defined (HAVE_DEV_FD) - /* This should only contain FIFOs created as part of redirection - expansion. */ - unlink_all_fifos (); -#endif - - if (async) - interactive = old_interactive; - - if (command == 0) - { - hookf = find_function (NOTFOUND_HOOK); - if (hookf == 0) - { - /* Make sure filenames are displayed using printable characters */ - pathname = printable_filename (pathname, 0); - internal_error (_("%s: command not found"), pathname); - exit (EX_NOTFOUND); /* Posix.2 says the exit status is 127 */ - } - - /* We don't want to manage process groups for processes we start - from here, so we turn off job control and don't attempt to - manipulate the terminal's process group. */ - without_job_control (); - -#if defined (JOB_CONTROL) - set_sigchld_handler (); -#endif - - wl = make_word_list (make_word (NOTFOUND_HOOK), words); - exit (execute_shell_function (hookf, wl)); - } - - /* Execve expects the command name to be in args[0]. So we - leave it there, in the same format that the user used to - type it in. */ - args = strvec_from_word_list (words, 0, 0, (int *)NULL); - exit (shell_execve (command, args, export_env)); - } - else - { -parent_return: - QUIT; - - /* Make sure that the pipes are closed in the parent. */ - close_pipes (pipe_in, pipe_out); -#if defined (PROCESS_SUBSTITUTION) && defined (HAVE_DEV_FD) -#if 0 - if (variable_context == 0) - unlink_fifo_list (); -#endif -#endif - FREE (command); - return (result); - } -} - -/* CPP defines to decide whether a particular index into the #! line - corresponds to a valid interpreter name or argument character, or - whitespace. The MSDOS define is to allow \r to be treated the same - as \n. */ - -#if !defined (MSDOS) -# define STRINGCHAR(ind) \ - (ind < sample_len && !whitespace (sample[ind]) && sample[ind] != '\n') -# define WHITECHAR(ind) \ - (ind < sample_len && whitespace (sample[ind])) -#else /* MSDOS */ -# define STRINGCHAR(ind) \ - (ind < sample_len && !whitespace (sample[ind]) && sample[ind] != '\n' && sample[ind] != '\r') -# define WHITECHAR(ind) \ - (ind < sample_len && whitespace (sample[ind])) -#endif /* MSDOS */ - -static char * -getinterp (sample, sample_len, endp) - char *sample; - int sample_len, *endp; -{ - register int i; - char *execname; - int start; - - /* Find the name of the interpreter to exec. */ - for (i = 2; i < sample_len && whitespace (sample[i]); i++) - ; - - for (start = i; STRINGCHAR(i); i++) - ; - - execname = substring (sample, start, i); - - if (endp) - *endp = i; - return execname; -} - -#if !defined (HAVE_HASH_BANG_EXEC) -/* If the operating system on which we're running does not handle - the #! executable format, then help out. SAMPLE is the text read - from the file, SAMPLE_LEN characters. COMMAND is the name of - the script; it and ARGS, the arguments given by the user, will - become arguments to the specified interpreter. ENV is the environment - to pass to the interpreter. - - The word immediately following the #! is the interpreter to execute. - A single argument to the interpreter is allowed. */ - -static int -execute_shell_script (sample, sample_len, command, args, env) - char *sample; - int sample_len; - char *command; - char **args, **env; -{ - char *execname, *firstarg; - int i, start, size_increment, larry; - - /* Find the name of the interpreter to exec. */ - execname = getinterp (sample, sample_len, &i); - size_increment = 1; - - /* Now the argument, if any. */ - for (firstarg = (char *)NULL, start = i; WHITECHAR(i); i++) - ; - - /* If there is more text on the line, then it is an argument for the - interpreter. */ - - if (STRINGCHAR(i)) - { - for (start = i; STRINGCHAR(i); i++) - ; - firstarg = substring ((char *)sample, start, i); - size_increment = 2; - } - - larry = strvec_len (args) + size_increment; - args = strvec_resize (args, larry + 1); - - for (i = larry - 1; i; i--) - args[i] = args[i - size_increment]; - - args[0] = execname; - if (firstarg) - { - args[1] = firstarg; - args[2] = command; - } - else - args[1] = command; - - args[larry] = (char *)NULL; - - return (shell_execve (execname, args, env)); -} -#undef STRINGCHAR -#undef WHITECHAR - -#endif /* !HAVE_HASH_BANG_EXEC */ - -static void -initialize_subshell () -{ -#if defined (ALIAS) - /* Forget about any aliases that we knew of. We are in a subshell. */ - delete_all_aliases (); -#endif /* ALIAS */ - -#if defined (HISTORY) - /* Forget about the history lines we have read. This is a non-interactive - subshell. */ - history_lines_this_session = 0; -#endif - - /* Forget about the way job control was working. We are in a subshell. */ - without_job_control (); - -#if defined (JOB_CONTROL) - set_sigchld_handler (); - init_job_stats (); -#endif /* JOB_CONTROL */ - - /* Reset the values of the shell flags and options. */ - reset_shell_flags (); - reset_shell_options (); - reset_shopt_options (); - - /* Zero out builtin_env, since this could be a shell script run from a - sourced file with a temporary environment supplied to the `source/.' - builtin. Such variables are not supposed to be exported (empirical - testing with sh and ksh). Just throw it away; don't worry about a - memory leak. */ - if (vc_isbltnenv (shell_variables)) - shell_variables = shell_variables->down; - - clear_unwind_protect_list (0); - /* XXX -- are there other things we should be resetting here? */ - parse_and_execute_level = 0; /* nothing left to restore it */ - - /* We're no longer inside a shell function. */ - variable_context = return_catch_flag = funcnest = evalnest = sourcenest = 0; - - executing_list = 0; /* XXX */ - - /* If we're not interactive, close the file descriptor from which we're - reading the current shell script. */ - if (interactive_shell == 0) - unset_bash_input (0); -} - -#if defined (HAVE_SETOSTYPE) && defined (_POSIX_SOURCE) -# define SETOSTYPE(x) __setostype(x) -#else -# define SETOSTYPE(x) -#endif - -#define HASH_BANG_BUFSIZ 128 - -#define READ_SAMPLE_BUF(file, buf, len) \ - do \ - { \ - fd = open(file, O_RDONLY); \ - if (fd >= 0) \ - { \ - len = read (fd, buf, HASH_BANG_BUFSIZ); \ - close (fd); \ - } \ - else \ - len = -1; \ - } \ - while (0) - -/* Call execve (), handling interpreting shell scripts, and handling - exec failures. */ -int -shell_execve (command, args, env) - char *command; - char **args, **env; -{ - int larray, i, fd; - char sample[HASH_BANG_BUFSIZ]; - int sample_len; - - SETOSTYPE (0); /* Some systems use for USG/POSIX semantics */ - execve (command, args, env); - i = errno; /* error from execve() */ - CHECK_TERMSIG; - SETOSTYPE (1); - - /* If we get to this point, then start checking out the file. - Maybe it is something we can hack ourselves. */ - if (i != ENOEXEC) - { - /* make sure this is set correctly for file_error/report_error */ - last_command_exit_value = (i == ENOENT) ? EX_NOTFOUND : EX_NOEXEC; /* XXX Posix.2 says that exit status is 126 */ - if (file_isdir (command)) -#if defined (EISDIR) - internal_error (_("%s: %s"), command, strerror (EISDIR)); -#else - internal_error (_("%s: is a directory"), command); -#endif - else if (executable_file (command) == 0) - { - errno = i; - file_error (command); - } - /* errors not involving the path argument to execve. */ - else if (i == E2BIG || i == ENOMEM) - { - errno = i; - file_error (command); - } - else if (i == ENOENT) - { - errno = i; - internal_error (_("%s: cannot execute: required file not found"), command); - } - else - { - /* The file has the execute bits set, but the kernel refuses to - run it for some reason. See why. */ -#if defined (HAVE_HASH_BANG_EXEC) - READ_SAMPLE_BUF (command, sample, sample_len); - if (sample_len > 0) - sample[sample_len - 1] = '\0'; - if (sample_len > 2 && sample[0] == '#' && sample[1] == '!') - { - char *interp; - int ilen; - - interp = getinterp (sample, sample_len, (int *)NULL); - ilen = strlen (interp); - errno = i; - if (interp[ilen - 1] == '\r') - { - interp = xrealloc (interp, ilen + 2); - interp[ilen - 1] = '^'; - interp[ilen] = 'M'; - interp[ilen + 1] = '\0'; - } - sys_error (_("%s: %s: bad interpreter"), command, interp ? interp : ""); - FREE (interp); - return (EX_NOEXEC); - } -#endif - errno = i; - file_error (command); - } - return (last_command_exit_value); - } - - /* This file is executable. - If it begins with #!, then help out people with losing operating - systems. Otherwise, check to see if it is a binary file by seeing - if the contents of the first line (or up to 80 characters) are in the - ASCII set. If it's a text file, execute the contents as shell commands, - otherwise return 126 (EX_BINARY_FILE). */ - READ_SAMPLE_BUF (command, sample, sample_len); - - if (sample_len == 0) - return (EXECUTION_SUCCESS); - - /* Is this supposed to be an executable script? - If so, the format of the line is "#! interpreter [argument]". - A single argument is allowed. The BSD kernel restricts - the length of the entire line to 32 characters (32 bytes - being the size of the BSD exec header), but we allow up to 128 - characters. */ - if (sample_len > 0) - { -#if !defined (HAVE_HASH_BANG_EXEC) - if (sample_len > 2 && sample[0] == '#' && sample[1] == '!') - return (execute_shell_script (sample, sample_len, command, args, env)); - else -#endif - if (check_binary_file (sample, sample_len)) - { - internal_error (_("%s: cannot execute binary file: %s"), command, strerror (i)); - errno = i; - return (EX_BINARY_FILE); - } - } - - /* We have committed to attempting to execute the contents of this file - as shell commands. */ - - reset_parser (); - initialize_subshell (); - - set_sigint_handler (); - - /* Insert the name of this shell into the argument list. */ - larray = strvec_len (args) + 1; - args = strvec_resize (args, larray + 1); - - for (i = larray - 1; i; i--) - args[i] = args[i - 1]; - - args[0] = shell_name; - args[1] = command; - args[larray] = (char *)NULL; - - if (args[0][0] == '-') - args[0]++; - -#if defined (RESTRICTED_SHELL) - if (restricted) - change_flag ('r', FLAG_OFF); -#endif - - if (subshell_argv) - { - /* Can't free subshell_argv[0]; that is shell_name. */ - for (i = 1; i < subshell_argc; i++) - free (subshell_argv[i]); - free (subshell_argv); - } - - dispose_command (currently_executing_command); /* XXX */ - currently_executing_command = (COMMAND *)NULL; - - subshell_argc = larray; - subshell_argv = args; - subshell_envp = env; - - unbind_args (); /* remove the positional parameters */ - -#if defined (PROCESS_SUBSTITUTION) && defined (HAVE_DEV_FD) - clear_fifo_list (); /* pipe fds are what they are now */ -#endif - - sh_longjmp (subshell_top_level, 1); - /*NOTREACHED*/ -} - -static int -execute_intern_function (name, funcdef) - WORD_DESC *name; - FUNCTION_DEF *funcdef; -{ - SHELL_VAR *var; - char *t; - - if (check_identifier (name, posixly_correct) == 0) - { - if (posixly_correct && interactive_shell == 0) - { - last_command_exit_value = EX_BADUSAGE; - jump_to_top_level (ERREXIT); - } - return (EXECUTION_FAILURE); - } - - if (strchr (name->word, CTLESC)) /* WHY? */ - { - t = dequote_escapes (name->word); - free (name->word); - name->word = t; - } - - /* Posix interpretation 383 */ - if (posixly_correct && find_special_builtin (name->word)) - { - internal_error (_("`%s': is a special builtin"), name->word); - last_command_exit_value = EX_BADUSAGE; - jump_to_top_level (interactive_shell ? DISCARD : ERREXIT); - } - - var = find_function (name->word); - if (var && (readonly_p (var) || noassign_p (var))) - { - if (readonly_p (var)) - internal_error (_("%s: readonly function"), var->name); - return (EXECUTION_FAILURE); - } - -#if defined (DEBUGGER) - bind_function_def (name->word, funcdef, 1); -#endif - - bind_function (name->word, funcdef->command); - return (EXECUTION_SUCCESS); -} - -#if defined (INCLUDE_UNUSED) -#if defined (PROCESS_SUBSTITUTION) -void -close_all_files () -{ - register int i, fd_table_size; - - fd_table_size = getdtablesize (); - if (fd_table_size > 256) /* clamp to a reasonable value */ - fd_table_size = 256; - - for (i = 3; i < fd_table_size; i++) - close (i); -} -#endif /* PROCESS_SUBSTITUTION */ -#endif - -static void -close_pipes (in, out) - int in, out; -{ - if (in >= 0) - close (in); - if (out >= 0) - close (out); -} - -static void -dup_error (oldd, newd) - int oldd, newd; -{ - sys_error (_("cannot duplicate fd %d to fd %d"), oldd, newd); -} - -/* Redirect input and output to be from and to the specified pipes. - NO_PIPE and REDIRECT_BOTH are handled correctly. */ -static void -do_piping (pipe_in, pipe_out) - int pipe_in, pipe_out; -{ - if (pipe_in != NO_PIPE) - { - if (dup2 (pipe_in, 0) < 0) - dup_error (pipe_in, 0); - if (pipe_in > 0) - close (pipe_in); -#ifdef __CYGWIN__ - /* Let stdio know the fd may have changed from text to binary mode. */ - freopen (NULL, "r", stdin); -#endif /* __CYGWIN__ */ - } - if (pipe_out != NO_PIPE) - { - if (pipe_out != REDIRECT_BOTH) - { - if (dup2 (pipe_out, 1) < 0) - dup_error (pipe_out, 1); - if (pipe_out == 0 || pipe_out > 1) - close (pipe_out); - } - else - { - if (dup2 (1, 2) < 0) - dup_error (1, 2); - } -#ifdef __CYGWIN__ - /* Let stdio know the fd may have changed from text to binary mode, and - make sure to preserve stdout line buffering. */ - freopen (NULL, "w", stdout); - sh_setlinebuf (stdout); -#endif /* __CYGWIN__ */ - } -} diff --git a/third_party/bash/execute_cmd.h b/third_party/bash/execute_cmd.h deleted file mode 100644 index 465030aef..000000000 --- a/third_party/bash/execute_cmd.h +++ /dev/null @@ -1,123 +0,0 @@ -/* execute_cmd.h - functions from execute_cmd.c. */ - -/* Copyright (C) 1993-2017 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_EXECUTE_CMD_H_) -#define _EXECUTE_CMD_H_ - -#include "stdc.h" - -#if defined (ARRAY_VARS) -struct func_array_state - { - ARRAY *funcname_a; - SHELL_VAR *funcname_v; - ARRAY *source_a; - SHELL_VAR *source_v; - ARRAY *lineno_a; - SHELL_VAR *lineno_v; - }; -#endif - -/* Placeholder for later expansion to include more execution state */ -/* XXX - watch out for pid_t */ -struct execstate - { - pid_t pid; - int subshell_env; - }; - - -/* Variables declared in execute_cmd.c, used by many other files */ -extern int return_catch_flag; -extern int return_catch_value; -extern volatile int last_command_exit_value; -extern int last_command_exit_signal; -extern int builtin_ignoring_errexit; -extern int executing_builtin; -extern int executing_list; -extern int comsub_ignore_return; -extern int subshell_level; -extern int match_ignore_case; -extern int executing_command_builtin; -extern int funcnest, funcnest_max; -extern int evalnest, evalnest_max; -extern int sourcenest, sourcenest_max; -extern int stdin_redir; -extern int line_number_for_err_trap; - -extern char *the_printed_command_except_trap; - -extern char *this_command_name; -extern SHELL_VAR *this_shell_function; - -/* Functions declared in execute_cmd.c, used by many other files */ - -extern struct fd_bitmap *new_fd_bitmap PARAMS((int)); -extern void dispose_fd_bitmap PARAMS((struct fd_bitmap *)); -extern void close_fd_bitmap PARAMS((struct fd_bitmap *)); -extern int executing_line_number PARAMS((void)); -extern int execute_command PARAMS((COMMAND *)); -extern int execute_command_internal PARAMS((COMMAND *, int, int, int, struct fd_bitmap *)); -extern int shell_execve PARAMS((char *, char **, char **)); -extern void setup_async_signals PARAMS((void)); -extern void async_redirect_stdin PARAMS((void)); - -extern void undo_partial_redirects PARAMS((void)); -extern void dispose_partial_redirects PARAMS((void)); -extern void dispose_exec_redirects PARAMS((void)); - -extern int execute_shell_function PARAMS((SHELL_VAR *, WORD_LIST *)); - -extern struct coproc *getcoprocbypid PARAMS((pid_t)); -extern struct coproc *getcoprocbyname PARAMS((const char *)); - -extern void coproc_init PARAMS((struct coproc *)); -extern struct coproc *coproc_alloc PARAMS((char *, pid_t)); -extern void coproc_dispose PARAMS((struct coproc *)); -extern void coproc_flush PARAMS((void)); -extern void coproc_close PARAMS((struct coproc *)); -extern void coproc_closeall PARAMS((void)); -extern void coproc_reap PARAMS((void)); -extern pid_t coproc_active PARAMS((void)); - -extern void coproc_rclose PARAMS((struct coproc *, int)); -extern void coproc_wclose PARAMS((struct coproc *, int)); -extern void coproc_fdclose PARAMS((struct coproc *, int)); - -extern void coproc_checkfd PARAMS((struct coproc *, int)); -extern void coproc_fdchk PARAMS((int)); - -extern void coproc_pidchk PARAMS((pid_t, int)); - -extern void coproc_fdsave PARAMS((struct coproc *)); -extern void coproc_fdrestore PARAMS((struct coproc *)); - -extern void coproc_setvars PARAMS((struct coproc *)); -extern void coproc_unsetvars PARAMS((struct coproc *)); - -#if defined (PROCESS_SUBSTITUTION) -extern void close_all_files PARAMS((void)); -#endif - -#if defined (ARRAY_VARS) -extern void restore_funcarray_state PARAMS((struct func_array_state *)); -#endif - -#endif /* _EXECUTE_CMD_H_ */ diff --git a/third_party/bash/expr.c b/third_party/bash/expr.c deleted file mode 100644 index 5079bd476..000000000 --- a/third_party/bash/expr.c +++ /dev/null @@ -1,1693 +0,0 @@ -/* expr.c -- arithmetic expression evaluation. */ - -/* Copyright (C) 1990-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -/* - All arithmetic is done as intmax_t integers with no checking for overflow - (though division by 0 is caught and flagged as an error). - - The following operators are handled, grouped into a set of levels in - order of decreasing precedence. - - "id++", "id--" [post-increment and post-decrement] - "-", "+" [(unary operators)] - "++id", "--id" [pre-increment and pre-decrement] - "!", "~" - "**" [(exponentiation)] - "*", "/", "%" - "+", "-" - "<<", ">>" - "<=", ">=", "<", ">" - "==", "!=" - "&" - "^" - "|" - "&&" - "||" - "expr ? expr : expr" - "=", "*=", "/=", "%=", "+=", "-=", "<<=", ">>=", "&=", "^=", "|=" - , [comma] - - (Note that most of these operators have special meaning to bash, and an - entire expression should be quoted, e.g. "a=$a+1" or "a=a+1" to ensure - that it is passed intact to the evaluator when using `let'. When using - the $[] or $(( )) forms, the text between the `[' and `]' or `((' and `))' - is treated as if in double quotes.) - - Sub-expressions within parentheses have a precedence level greater than - all of the above levels and are evaluated first. Within a single prece- - dence group, evaluation is left-to-right, except for the arithmetic - assignment operator (`='), which is evaluated right-to-left (as in C). - - The expression evaluator returns the value of the expression (assignment - statements have as a value what is returned by the RHS). The `let' - builtin, on the other hand, returns 0 if the last expression evaluates to - a non-zero, and 1 otherwise. - - Implementation is a recursive-descent parser. - - Chet Ramey - chet@po.cwru.edu -*/ - -#include "config.h" - -#include -#include "bashansi.h" - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include "chartypes.h" -#include "bashintl.h" - -#include "shell.h" -#include "arrayfunc.h" -#include "execute_cmd.h" -#include "flags.h" -#include "subst.h" -#include "typemax.h" /* INTMAX_MAX, INTMAX_MIN */ - -/* Because of the $((...)) construct, expressions may include newlines. - Here is a macro which accepts newlines, tabs and spaces as whitespace. */ -#define cr_whitespace(c) (whitespace(c) || ((c) == '\n')) - -/* Size be which the expression stack grows when necessary. */ -#define EXPR_STACK_GROW_SIZE 10 - -/* Maximum amount of recursion allowed. This prevents a non-integer - variable such as "num=num+2" from infinitely adding to itself when - "let num=num+2" is given. */ -#define MAX_EXPR_RECURSION_LEVEL 1024 - -/* The Tokens. Singing "The Lion Sleeps Tonight". */ - -#define EQEQ 1 /* "==" */ -#define NEQ 2 /* "!=" */ -#define LEQ 3 /* "<=" */ -#define GEQ 4 /* ">=" */ -#define STR 5 /* string */ -#define NUM 6 /* number */ -#define LAND 7 /* "&&" Logical AND */ -#define LOR 8 /* "||" Logical OR */ -#define LSH 9 /* "<<" Left SHift */ -#define RSH 10 /* ">>" Right SHift */ -#define OP_ASSIGN 11 /* op= expassign as in Posix.2 */ -#define COND 12 /* exp1 ? exp2 : exp3 */ -#define POWER 13 /* exp1**exp2 */ -#define PREINC 14 /* ++var */ -#define PREDEC 15 /* --var */ -#define POSTINC 16 /* var++ */ -#define POSTDEC 17 /* var-- */ -#define EQ '=' -#define GT '>' -#define LT '<' -#define PLUS '+' -#define MINUS '-' -#define MUL '*' -#define DIV '/' -#define MOD '%' -#define NOT '!' -#define LPAR '(' -#define RPAR ')' -#define BAND '&' /* Bitwise AND */ -#define BOR '|' /* Bitwise OR. */ -#define BXOR '^' /* Bitwise eXclusive OR. */ -#define BNOT '~' /* Bitwise NOT; Two's complement. */ -#define QUES '?' -#define COL ':' -#define COMMA ',' - -/* This should be the function corresponding to the operator with the - lowest precedence. */ -#define EXP_LOWEST expcomma - -#ifndef MAX_INT_LEN -# define MAX_INT_LEN 32 -#endif - -struct lvalue -{ - char *tokstr; /* possibly-rewritten lvalue if not NULL */ - intmax_t tokval; /* expression evaluated value */ - SHELL_VAR *tokvar; /* variable described by array or var reference */ - intmax_t ind; /* array index if not -1 */ -}; - -/* A structure defining a single expression context. */ -typedef struct { - int curtok, lasttok; - char *expression, *tp, *lasttp; - intmax_t tokval; - char *tokstr; - int noeval; - struct lvalue lval; -} EXPR_CONTEXT; - -static char *expression; /* The current expression */ -static char *tp; /* token lexical position */ -static char *lasttp; /* pointer to last token position */ -static int curtok; /* the current token */ -static int lasttok; /* the previous token */ -static int assigntok; /* the OP in OP= */ -static char *tokstr; /* current token string */ -static intmax_t tokval; /* current token value */ -static int noeval; /* set to 1 if no assignment to be done */ -static procenv_t evalbuf; - -/* set to 1 if the expression has already been run through word expansion */ -static int already_expanded; - -static struct lvalue curlval = {0, 0, 0, -1}; -static struct lvalue lastlval = {0, 0, 0, -1}; - -static int _is_arithop PARAMS((int)); -static void readtok PARAMS((void)); /* lexical analyzer */ - -static void init_lvalue PARAMS((struct lvalue *)); -static struct lvalue *alloc_lvalue PARAMS((void)); -static void free_lvalue PARAMS((struct lvalue *)); - -static intmax_t expr_streval PARAMS((char *, int, struct lvalue *)); -static intmax_t strlong PARAMS((char *)); -static void evalerror PARAMS((const char *)); - -static void pushexp PARAMS((void)); -static void popexp PARAMS((void)); -static void expr_unwind PARAMS((void)); -static void expr_bind_variable PARAMS((char *, char *)); -#if defined (ARRAY_VARS) -static void expr_bind_array_element PARAMS((char *, arrayind_t, char *)); -#endif - -static intmax_t subexpr PARAMS((char *)); - -static intmax_t expcomma PARAMS((void)); -static intmax_t expassign PARAMS((void)); -static intmax_t expcond PARAMS((void)); -static intmax_t explor PARAMS((void)); -static intmax_t expland PARAMS((void)); -static intmax_t expbor PARAMS((void)); -static intmax_t expbxor PARAMS((void)); -static intmax_t expband PARAMS((void)); -static intmax_t exp5 PARAMS((void)); -static intmax_t exp4 PARAMS((void)); -static intmax_t expshift PARAMS((void)); -static intmax_t exp3 PARAMS((void)); -static intmax_t expmuldiv PARAMS((void)); -static intmax_t exppower PARAMS((void)); -static intmax_t exp1 PARAMS((void)); -static intmax_t exp0 PARAMS((void)); - -/* Global var which contains the stack of expression contexts. */ -static EXPR_CONTEXT **expr_stack; -static int expr_depth; /* Location in the stack. */ -static int expr_stack_size; /* Number of slots already allocated. */ - -#if defined (ARRAY_VARS) -extern const char * const bash_badsub_errmsg; -#endif - -#define SAVETOK(X) \ - do { \ - (X)->curtok = curtok; \ - (X)->lasttok = lasttok; \ - (X)->tp = tp; \ - (X)->lasttp = lasttp; \ - (X)->tokval = tokval; \ - (X)->tokstr = tokstr; \ - (X)->noeval = noeval; \ - (X)->lval = curlval; \ - } while (0) - -#define RESTORETOK(X) \ - do { \ - curtok = (X)->curtok; \ - lasttok = (X)->lasttok; \ - tp = (X)->tp; \ - lasttp = (X)->lasttp; \ - tokval = (X)->tokval; \ - tokstr = (X)->tokstr; \ - noeval = (X)->noeval; \ - curlval = (X)->lval; \ - } while (0) - -/* Push and save away the contents of the globals describing the - current expression context. */ -static void -pushexp () -{ - EXPR_CONTEXT *context; - - if (expr_depth >= MAX_EXPR_RECURSION_LEVEL) - evalerror (_("expression recursion level exceeded")); - - if (expr_depth >= expr_stack_size) - { - expr_stack_size += EXPR_STACK_GROW_SIZE; - expr_stack = (EXPR_CONTEXT **)xrealloc (expr_stack, expr_stack_size * sizeof (EXPR_CONTEXT *)); - } - - context = (EXPR_CONTEXT *)xmalloc (sizeof (EXPR_CONTEXT)); - - context->expression = expression; - SAVETOK(context); - - expr_stack[expr_depth++] = context; -} - -/* Pop the the contents of the expression context stack into the - globals describing the current expression context. */ -static void -popexp () -{ - EXPR_CONTEXT *context; - - if (expr_depth <= 0) - { - /* See the comment at the top of evalexp() for an explanation of why - this is done. */ - expression = lasttp = 0; - evalerror (_("recursion stack underflow")); - } - - context = expr_stack[--expr_depth]; - - expression = context->expression; - RESTORETOK (context); - - free (context); -} - -static void -expr_unwind () -{ - while (--expr_depth > 0) - { - if (expr_stack[expr_depth]->tokstr) - free (expr_stack[expr_depth]->tokstr); - - if (expr_stack[expr_depth]->expression) - free (expr_stack[expr_depth]->expression); - - free (expr_stack[expr_depth]); - } - if (expr_depth == 0) - free (expr_stack[expr_depth]); /* free the allocated EXPR_CONTEXT */ - - noeval = 0; /* XXX */ -} - -static void -expr_bind_variable (lhs, rhs) - char *lhs, *rhs; -{ - SHELL_VAR *v; - int aflags; - - if (lhs == 0 || *lhs == 0) - return; /* XXX */ - -#if defined (ARRAY_VARS) - aflags = (assoc_expand_once && already_expanded) ? ASS_NOEXPAND : 0; - aflags |= ASS_ALLOWALLSUB; /* allow assoc[@]=value */ -#else - aflags = 0; -#endif - v = bind_int_variable (lhs, rhs, aflags); - if (v && (readonly_p (v) || noassign_p (v))) - sh_longjmp (evalbuf, 1); /* variable assignment error */ - stupidly_hack_special_variables (lhs); -} - -#if defined (ARRAY_VARS) -/* This is similar to the logic in arrayfunc.c:valid_array_reference when - you pass VA_NOEXPAND. */ -static int -expr_skipsubscript (vp, cp) - char *vp, *cp; -{ - int flags, isassoc; - SHELL_VAR *entry; - - isassoc = 0; - entry = 0; - if (assoc_expand_once & already_expanded) - { - *cp = '\0'; - isassoc = legal_identifier (vp) && (entry = find_variable (vp)) && assoc_p (entry); - *cp = '['; /* ] */ - } - flags = (isassoc && assoc_expand_once && already_expanded) ? VA_NOEXPAND : 0; - return (skipsubscript (cp, 0, flags)); -} - -/* Rewrite tok, which is of the form vname[expression], to vname[ind], where - IND is the already-calculated value of expression. */ -static void -expr_bind_array_element (tok, ind, rhs) - char *tok; - arrayind_t ind; - char *rhs; -{ - char *lhs, *vname; - size_t llen; - char ibuf[INT_STRLEN_BOUND (arrayind_t) + 1], *istr; - - istr = fmtumax (ind, 10, ibuf, sizeof (ibuf), 0); - vname = array_variable_name (tok, 0, (char **)NULL, (int *)NULL); - - llen = strlen (vname) + sizeof (ibuf) + 3; - lhs = xmalloc (llen); - - sprintf (lhs, "%s[%s]", vname, istr); /* XXX */ - -/*itrace("expr_bind_array_element: %s=%s", lhs, rhs);*/ - expr_bind_variable (lhs, rhs); - free (vname); - free (lhs); -} -#endif /* ARRAY_VARS */ - -/* Evaluate EXPR, and return the arithmetic result. If VALIDP is - non-null, a zero is stored into the location to which it points - if the expression is invalid, non-zero otherwise. If a non-zero - value is returned in *VALIDP, the return value of evalexp() may - be used. - - The `while' loop after the longjmp is caught relies on the above - implementation of pushexp and popexp leaving in expr_stack[0] the - values that the variables had when the program started. That is, - the first things saved are the initial values of the variables that - were assigned at program startup or by the compiler. Therefore, it is - safe to let the loop terminate when expr_depth == 0, without freeing up - any of the expr_depth[0] stuff. */ -intmax_t -evalexp (expr, flags, validp) - char *expr; - int flags; - int *validp; -{ - intmax_t val; - int c; - procenv_t oevalbuf; - - val = 0; - noeval = 0; - already_expanded = (flags&EXP_EXPANDED); - - FASTCOPY (evalbuf, oevalbuf, sizeof (evalbuf)); - - c = setjmp_nosigs (evalbuf); - - if (c) - { - FREE (tokstr); - FREE (expression); - tokstr = expression = (char *)NULL; - - expr_unwind (); - expr_depth = 0; /* XXX - make sure */ - - /* We copy in case we've called evalexp recursively */ - FASTCOPY (oevalbuf, evalbuf, sizeof (evalbuf)); - - if (validp) - *validp = 0; - return (0); - } - - val = subexpr (expr); - - if (validp) - *validp = 1; - - FASTCOPY (oevalbuf, evalbuf, sizeof (evalbuf)); - - return (val); -} - -static intmax_t -subexpr (expr) - char *expr; -{ - intmax_t val; - char *p; - - for (p = expr; p && *p && cr_whitespace (*p); p++) - ; - - if (p == NULL || *p == '\0') - return (0); - - pushexp (); - expression = savestring (expr); - tp = expression; - - curtok = lasttok = 0; - tokstr = (char *)NULL; - tokval = 0; - init_lvalue (&curlval); - lastlval = curlval; - - readtok (); - - val = EXP_LOWEST (); - - /*TAG:bash-5.3 make it clear that these are arithmetic syntax errors */ - if (curtok != 0) - evalerror (_("syntax error in expression")); - - FREE (tokstr); - FREE (expression); - - popexp (); - - return val; -} - -static intmax_t -expcomma () -{ - register intmax_t value; - - value = expassign (); - while (curtok == COMMA) - { - readtok (); - value = expassign (); - } - - return value; -} - -static intmax_t -expassign () -{ - register intmax_t value; - char *lhs, *rhs; - arrayind_t lind; -#if defined (HAVE_IMAXDIV) - imaxdiv_t idiv; -#endif - - value = expcond (); - if (curtok == EQ || curtok == OP_ASSIGN) - { - int special, op; - intmax_t lvalue; - - special = curtok == OP_ASSIGN; - - if (lasttok != STR) - evalerror (_("attempted assignment to non-variable")); - - if (special) - { - op = assigntok; /* a OP= b */ - lvalue = value; - } - - if (tokstr == 0) - evalerror (_("syntax error in variable assignment")); - - /* XXX - watch out for pointer aliasing issues here */ - lhs = savestring (tokstr); - /* save ind in case rhs is string var and evaluation overwrites it */ - lind = curlval.ind; - readtok (); - value = expassign (); - - if (special) - { - if ((op == DIV || op == MOD) && value == 0) - { - if (noeval == 0) - evalerror (_("division by 0")); - else - value = 1; - } - - switch (op) - { - case MUL: - /* Handle INTMAX_MIN and INTMAX_MAX * -1 specially here? */ - lvalue *= value; - break; - case DIV: - case MOD: - if (lvalue == INTMAX_MIN && value == -1) - lvalue = (op == DIV) ? INTMAX_MIN : 0; - else -#if HAVE_IMAXDIV - { - idiv = imaxdiv (lvalue, value); - lvalue = (op == DIV) ? idiv.quot : idiv.rem; - } -#else - lvalue = (op == DIV) ? lvalue / value : lvalue % value; -#endif - break; - case PLUS: - lvalue += value; - break; - case MINUS: - lvalue -= value; - break; - case LSH: - lvalue <<= value; - break; - case RSH: - lvalue >>= value; - break; - case BAND: - lvalue &= value; - break; - case BOR: - lvalue |= value; - break; - case BXOR: - lvalue ^= value; - break; - default: - free (lhs); - evalerror (_("bug: bad expassign token")); - break; - } - value = lvalue; - } - - rhs = itos (value); - if (noeval == 0) - { -#if defined (ARRAY_VARS) - if (lind != -1) - expr_bind_array_element (lhs, lind, rhs); - else -#endif - expr_bind_variable (lhs, rhs); - } - if (curlval.tokstr && curlval.tokstr == tokstr) - init_lvalue (&curlval); - - free (rhs); - free (lhs); - FREE (tokstr); - tokstr = (char *)NULL; /* For freeing on errors. */ - } - - return (value); -} - -/* Conditional expression (expr?expr:expr) */ -static intmax_t -expcond () -{ - intmax_t cval, val1, val2, rval; - int set_noeval; - - set_noeval = 0; - rval = cval = explor (); - if (curtok == QUES) /* found conditional expr */ - { - if (cval == 0) - { - set_noeval = 1; - noeval++; - } - - readtok (); - if (curtok == 0 || curtok == COL) - evalerror (_("expression expected")); - - val1 = EXP_LOWEST (); - - if (set_noeval) - noeval--; - if (curtok != COL) - evalerror (_("`:' expected for conditional expression")); - - set_noeval = 0; - if (cval) - { - set_noeval = 1; - noeval++; - } - - readtok (); - if (curtok == 0) - evalerror (_("expression expected")); - val2 = expcond (); - - if (set_noeval) - noeval--; - rval = cval ? val1 : val2; - lasttok = COND; - } - return rval; -} - -/* Logical OR. */ -static intmax_t -explor () -{ - register intmax_t val1, val2; - int set_noeval; - - val1 = expland (); - - while (curtok == LOR) - { - set_noeval = 0; - if (val1 != 0) - { - noeval++; - set_noeval = 1; - } - readtok (); - val2 = expland (); - if (set_noeval) - noeval--; - val1 = val1 || val2; - lasttok = LOR; - } - - return (val1); -} - -/* Logical AND. */ -static intmax_t -expland () -{ - register intmax_t val1, val2; - int set_noeval; - - val1 = expbor (); - - while (curtok == LAND) - { - set_noeval = 0; - if (val1 == 0) - { - set_noeval = 1; - noeval++; - } - readtok (); - val2 = expbor (); - if (set_noeval) - noeval--; - val1 = val1 && val2; - lasttok = LAND; - } - - return (val1); -} - -/* Bitwise OR. */ -static intmax_t -expbor () -{ - register intmax_t val1, val2; - - val1 = expbxor (); - - while (curtok == BOR) - { - readtok (); - val2 = expbxor (); - val1 = val1 | val2; - lasttok = NUM; - } - - return (val1); -} - -/* Bitwise XOR. */ -static intmax_t -expbxor () -{ - register intmax_t val1, val2; - - val1 = expband (); - - while (curtok == BXOR) - { - readtok (); - val2 = expband (); - val1 = val1 ^ val2; - lasttok = NUM; - } - - return (val1); -} - -/* Bitwise AND. */ -static intmax_t -expband () -{ - register intmax_t val1, val2; - - val1 = exp5 (); - - while (curtok == BAND) - { - readtok (); - val2 = exp5 (); - val1 = val1 & val2; - lasttok = NUM; - } - - return (val1); -} - -static intmax_t -exp5 () -{ - register intmax_t val1, val2; - - val1 = exp4 (); - - while ((curtok == EQEQ) || (curtok == NEQ)) - { - int op = curtok; - - readtok (); - val2 = exp4 (); - if (op == EQEQ) - val1 = (val1 == val2); - else if (op == NEQ) - val1 = (val1 != val2); - lasttok = NUM; - } - return (val1); -} - -static intmax_t -exp4 () -{ - register intmax_t val1, val2; - - val1 = expshift (); - while ((curtok == LEQ) || - (curtok == GEQ) || - (curtok == LT) || - (curtok == GT)) - { - int op = curtok; - - readtok (); - val2 = expshift (); - - if (op == LEQ) - val1 = val1 <= val2; - else if (op == GEQ) - val1 = val1 >= val2; - else if (op == LT) - val1 = val1 < val2; - else /* (op == GT) */ - val1 = val1 > val2; - lasttok = NUM; - } - return (val1); -} - -/* Left and right shifts. */ -static intmax_t -expshift () -{ - register intmax_t val1, val2; - - val1 = exp3 (); - - while ((curtok == LSH) || (curtok == RSH)) - { - int op = curtok; - - readtok (); - val2 = exp3 (); - - if (op == LSH) - val1 = val1 << val2; - else - val1 = val1 >> val2; - lasttok = NUM; - } - - return (val1); -} - -static intmax_t -exp3 () -{ - register intmax_t val1, val2; - - val1 = expmuldiv (); - - while ((curtok == PLUS) || (curtok == MINUS)) - { - int op = curtok; - - readtok (); - val2 = expmuldiv (); - - if (op == PLUS) - val1 += val2; - else if (op == MINUS) - val1 -= val2; - lasttok = NUM; - } - return (val1); -} - -static intmax_t -expmuldiv () -{ - register intmax_t val1, val2; -#if defined (HAVE_IMAXDIV) - imaxdiv_t idiv; -#endif - - val1 = exppower (); - - while ((curtok == MUL) || - (curtok == DIV) || - (curtok == MOD)) - { - int op = curtok; - char *stp, *sltp; - - stp = tp; - readtok (); - - val2 = exppower (); - - /* Handle division by 0 and twos-complement arithmetic overflow */ - if (((op == DIV) || (op == MOD)) && (val2 == 0)) - { - if (noeval == 0) - { - sltp = lasttp; - lasttp = stp; - while (lasttp && *lasttp && whitespace (*lasttp)) - lasttp++; - evalerror (_("division by 0")); - lasttp = sltp; - } - else - val2 = 1; - } - else if (op == MOD && val1 == INTMAX_MIN && val2 == -1) - { - val1 = 0; - continue; - } - else if (op == DIV && val1 == INTMAX_MIN && val2 == -1) - val2 = 1; - - if (op == MUL) - val1 *= val2; - else if (op == DIV || op == MOD) -#if defined (HAVE_IMAXDIV) - { - idiv = imaxdiv (val1, val2); - val1 = (op == DIV) ? idiv.quot : idiv.rem; - } -#else - val1 = (op == DIV) ? val1 / val2 : val1 % val2; -#endif - lasttok = NUM; - } - return (val1); -} - -static intmax_t -ipow (base, exp) - intmax_t base, exp; -{ - intmax_t result; - - result = 1; - while (exp) - { - if (exp & 1) - result *= base; - exp >>= 1; - base *= base; - } - return result; -} - -static intmax_t -exppower () -{ - register intmax_t val1, val2, c; - - val1 = exp1 (); - while (curtok == POWER) - { - readtok (); - val2 = exppower (); /* exponentiation is right-associative */ - lasttok = NUM; - if (val2 == 0) - return (1); - if (val2 < 0) - evalerror (_("exponent less than 0")); - val1 = ipow (val1, val2); - } - return (val1); -} - -static intmax_t -exp1 () -{ - register intmax_t val; - - if (curtok == NOT) - { - readtok (); - val = !exp1 (); - lasttok = NUM; - } - else if (curtok == BNOT) - { - readtok (); - val = ~exp1 (); - lasttok = NUM; - } - else if (curtok == MINUS) - { - readtok (); - val = - exp1 (); - lasttok = NUM; - } - else if (curtok == PLUS) - { - readtok (); - val = exp1 (); - lasttok = NUM; - } - else - val = exp0 (); - - return (val); -} - -static intmax_t -exp0 () -{ - register intmax_t val = 0, v2; - char *vincdec; - int stok; - EXPR_CONTEXT ec; - - /* XXX - might need additional logic here to decide whether or not - pre-increment or pre-decrement is legal at this point. */ - if (curtok == PREINC || curtok == PREDEC) - { - stok = lasttok = curtok; - readtok (); - if (curtok != STR) - /* readtok() catches this */ - evalerror (_("identifier expected after pre-increment or pre-decrement")); - - v2 = tokval + ((stok == PREINC) ? 1 : -1); - vincdec = itos (v2); - if (noeval == 0) - { -#if defined (ARRAY_VARS) - if (curlval.ind != -1) - expr_bind_array_element (curlval.tokstr, curlval.ind, vincdec); - else -#endif - if (tokstr) - expr_bind_variable (tokstr, vincdec); - } - free (vincdec); - val = v2; - - curtok = NUM; /* make sure --x=7 is flagged as an error */ - readtok (); - } - else if (curtok == LPAR) - { - /* XXX - save curlval here? Or entire expression context? */ - readtok (); - val = EXP_LOWEST (); - - if (curtok != RPAR) /* ( */ - evalerror (_("missing `)'")); - - /* Skip over closing paren. */ - readtok (); - } - else if ((curtok == NUM) || (curtok == STR)) - { - val = tokval; - if (curtok == STR) - { - SAVETOK (&ec); - tokstr = (char *)NULL; /* keep it from being freed */ - noeval = 1; - readtok (); - stok = curtok; - - /* post-increment or post-decrement */ - if (stok == POSTINC || stok == POSTDEC) - { - /* restore certain portions of EC */ - tokstr = ec.tokstr; - noeval = ec.noeval; - curlval = ec.lval; - lasttok = STR; /* ec.curtok */ - - v2 = val + ((stok == POSTINC) ? 1 : -1); - vincdec = itos (v2); - if (noeval == 0) - { -#if defined (ARRAY_VARS) - if (curlval.ind != -1) - expr_bind_array_element (curlval.tokstr, curlval.ind, vincdec); - else -#endif - expr_bind_variable (tokstr, vincdec); - } - free (vincdec); - curtok = NUM; /* make sure x++=7 is flagged as an error */ - } - else - { - /* XXX - watch out for pointer aliasing issues here */ - if (stok == STR) /* free new tokstr before old one is restored */ - FREE (tokstr); - RESTORETOK (&ec); - } - } - - readtok (); - } - else - evalerror (_("syntax error: operand expected")); - - return (val); -} - -static void -init_lvalue (lv) - struct lvalue *lv; -{ - lv->tokstr = 0; - lv->tokvar = 0; - lv->tokval = lv->ind = -1; -} - -static struct lvalue * -alloc_lvalue () -{ - struct lvalue *lv; - - lv = xmalloc (sizeof (struct lvalue)); - init_lvalue (lv); - return (lv); -} - -static void -free_lvalue (lv) - struct lvalue *lv; -{ - free (lv); /* should be inlined */ -} - -static intmax_t -expr_streval (tok, e, lvalue) - char *tok; - int e; - struct lvalue *lvalue; -{ - SHELL_VAR *v; - char *value; - intmax_t tval; - int initial_depth; -#if defined (ARRAY_VARS) - arrayind_t ind; - int tflag, aflag; - array_eltstate_t es; -#endif - -/*itrace("expr_streval: %s: noeval = %d expanded=%d", tok, noeval, already_expanded);*/ - /* If we are suppressing evaluation, just short-circuit here instead of - going through the rest of the evaluator. */ - if (noeval) - return (0); - - initial_depth = expr_depth; - -#if defined (ARRAY_VARS) - tflag = (assoc_expand_once && already_expanded) ? AV_NOEXPAND : 0; /* for a start */ -#endif - - /* [[[[[ */ -#if defined (ARRAY_VARS) - aflag = tflag; /* use a different variable for now */ - v = (e == ']') ? array_variable_part (tok, tflag, (char **)0, (int *)0) : find_variable (tok); -#else - v = find_variable (tok); -#endif - if (v == 0 && e != ']') - v = find_variable_last_nameref (tok, 0); - - if ((v == 0 || invisible_p (v)) && unbound_vars_is_error) - { -#if defined (ARRAY_VARS) - value = (e == ']') ? array_variable_name (tok, tflag, (char **)0, (int *)0) : tok; -#else - value = tok; -#endif - - set_exit_status (EXECUTION_FAILURE); - err_unboundvar (value); - -#if defined (ARRAY_VARS) - if (e == ']') - FREE (value); /* array_variable_name returns new memory */ -#endif - - if (no_longjmp_on_fatal_error && interactive_shell) - sh_longjmp (evalbuf, 1); - - if (interactive_shell) - { - expr_unwind (); - top_level_cleanup (); - jump_to_top_level (DISCARD); - } - else - jump_to_top_level (FORCE_EOF); - } - -#if defined (ARRAY_VARS) - init_eltstate (&es); - es.ind = -1; - /* If the second argument to get_array_value doesn't include AV_ALLOWALL, - we don't allow references like array[@]. In this case, get_array_value - is just like get_variable_value in that it does not return newly-allocated - memory or quote the results. AFLAG is set above and is either AV_NOEXPAND - or 0. */ - value = (e == ']') ? get_array_value (tok, aflag, &es) : get_variable_value (v); - ind = es.ind; - flush_eltstate (&es); -#else - value = get_variable_value (v); -#endif - - if (expr_depth < initial_depth) - { - if (no_longjmp_on_fatal_error && interactive_shell) - sh_longjmp (evalbuf, 1); - return (0); - } - - tval = (value && *value) ? subexpr (value) : 0; - - if (lvalue) - { - lvalue->tokstr = tok; /* XXX */ - lvalue->tokval = tval; - lvalue->tokvar = v; /* XXX */ -#if defined (ARRAY_VARS) - lvalue->ind = ind; -#else - lvalue->ind = -1; -#endif - } - - return (tval); -} - -static int -_is_multiop (c) - int c; -{ - switch (c) - { - case EQEQ: - case NEQ: - case LEQ: - case GEQ: - case LAND: - case LOR: - case LSH: - case RSH: - case OP_ASSIGN: - case COND: - case POWER: - case PREINC: - case PREDEC: - case POSTINC: - case POSTDEC: - return 1; - default: - return 0; - } -} - -static int -_is_arithop (c) - int c; -{ - switch (c) - { - case EQ: - case GT: - case LT: - case PLUS: - case MINUS: - case MUL: - case DIV: - case MOD: - case NOT: - case LPAR: - case RPAR: - case BAND: - case BOR: - case BXOR: - case BNOT: - return 1; /* operator tokens */ - case QUES: - case COL: - case COMMA: - return 1; /* questionable */ - default: - return 0; /* anything else is invalid */ - } -} - -/* Lexical analyzer/token reader for the expression evaluator. Reads the - next token and puts its value into curtok, while advancing past it. - Updates value of tp. May also set tokval (for number) or tokstr (for - string). */ -static void -readtok () -{ - register char *cp, *xp; - register unsigned char c, c1; - register int e; - struct lvalue lval; - - /* Skip leading whitespace. */ - cp = tp; - c = e = 0; - while (cp && (c = *cp) && (cr_whitespace (c))) - cp++; - - if (c) - cp++; - - if (c == '\0') - { - lasttok = curtok; - curtok = 0; - tp = cp; - return; - } - lasttp = tp = cp - 1; - - if (legal_variable_starter (c)) - { - /* variable names not preceded with a dollar sign are shell variables. */ - char *savecp; - EXPR_CONTEXT ec; - int peektok; - - while (legal_variable_char (c)) - c = *cp++; - - c = *--cp; - -#if defined (ARRAY_VARS) - if (c == '[') - { - e = expr_skipsubscript (tp, cp); /* XXX - was skipsubscript */ - if (cp[e] == ']') - { - cp += e + 1; - c = *cp; - e = ']'; - } - else - evalerror (bash_badsub_errmsg); - } -#endif /* ARRAY_VARS */ - - *cp = '\0'; - /* XXX - watch out for pointer aliasing issues here */ - if (curlval.tokstr && curlval.tokstr == tokstr) - init_lvalue (&curlval); - - FREE (tokstr); - tokstr = savestring (tp); - *cp = c; - - /* XXX - make peektok part of saved token state? */ - SAVETOK (&ec); - tokstr = (char *)NULL; /* keep it from being freed */ - tp = savecp = cp; - noeval = 1; - curtok = STR; - readtok (); - peektok = curtok; - if (peektok == STR) /* free new tokstr before old one is restored */ - FREE (tokstr); - RESTORETOK (&ec); - cp = savecp; - - /* The tests for PREINC and PREDEC aren't strictly correct, but they - preserve old behavior if a construct like --x=9 is given. */ - if (lasttok == PREINC || lasttok == PREDEC || peektok != EQ) - { - lastlval = curlval; - tokval = expr_streval (tokstr, e, &curlval); - } - else - tokval = 0; - - lasttok = curtok; - curtok = STR; - } - else if (DIGIT(c)) - { - while (ISALNUM (c) || c == '#' || c == '@' || c == '_') - c = *cp++; - - c = *--cp; - *cp = '\0'; - - tokval = strlong (tp); - *cp = c; - lasttok = curtok; - curtok = NUM; - } - else - { - c1 = *cp++; - if ((c == EQ) && (c1 == EQ)) - c = EQEQ; - else if ((c == NOT) && (c1 == EQ)) - c = NEQ; - else if ((c == GT) && (c1 == EQ)) - c = GEQ; - else if ((c == LT) && (c1 == EQ)) - c = LEQ; - else if ((c == LT) && (c1 == LT)) - { - if (*cp == '=') /* a <<= b */ - { - assigntok = LSH; - c = OP_ASSIGN; - cp++; - } - else - c = LSH; - } - else if ((c == GT) && (c1 == GT)) - { - if (*cp == '=') - { - assigntok = RSH; /* a >>= b */ - c = OP_ASSIGN; - cp++; - } - else - c = RSH; - } - else if ((c == BAND) && (c1 == BAND)) - c = LAND; - else if ((c == BOR) && (c1 == BOR)) - c = LOR; - else if ((c == '*') && (c1 == '*')) - c = POWER; - else if ((c == '-' || c == '+') && c1 == c && curtok == STR) - c = (c == '-') ? POSTDEC : POSTINC; -#if STRICT_ARITH_PARSING - else if ((c == '-' || c == '+') && c1 == c && curtok == NUM) -#else - else if ((c == '-' || c == '+') && c1 == c && curtok == NUM && (lasttok == PREINC || lasttok == PREDEC)) -#endif - { - /* This catches something like --FOO++ */ - /* TAG:bash-5.3 add gettext calls here or make this a separate function */ - if (c == '-') - evalerror ("--: assignment requires lvalue"); - else - evalerror ("++: assignment requires lvalue"); - } - else if ((c == '-' || c == '+') && c1 == c) - { - /* Quickly scan forward to see if this is followed by optional - whitespace and an identifier. */ - xp = cp; - while (xp && *xp && cr_whitespace (*xp)) - xp++; - if (legal_variable_starter ((unsigned char)*xp)) - c = (c == '-') ? PREDEC : PREINC; - else - /* Could force parsing as preinc or predec and throw an error */ -#if STRICT_ARITH_PARSING - { - /* Posix says unary plus and minus have higher priority than - preinc and predec. */ - /* This catches something like --4++ */ - if (c == '-') - evalerror ("--: assignment requires lvalue"); - else - evalerror ("++: assignment requires lvalue"); - } -#else - cp--; /* not preinc or predec, so unget the character */ -#endif - } - else if (c1 == EQ && member (c, "*/%+-&^|")) - { - assigntok = c; /* a OP= b */ - c = OP_ASSIGN; - } - else if (_is_arithop (c) == 0) - { - cp--; - /* use curtok, since it hasn't been copied to lasttok yet */ - if (curtok == 0 || _is_arithop (curtok) || _is_multiop (curtok)) - evalerror (_("syntax error: operand expected")); - else - evalerror (_("syntax error: invalid arithmetic operator")); - } - else - cp--; /* `unget' the character */ - - /* Should check here to make sure that the current character is one - of the recognized operators and flag an error if not. Could create - a character map the first time through and check it on subsequent - calls. */ - lasttok = curtok; - curtok = c; - } - tp = cp; -} - -static void -evalerror (msg) - const char *msg; -{ - char *name, *t; - - name = this_command_name; - for (t = expression; t && whitespace (*t); t++) - ; - internal_error (_("%s%s%s: %s (error token is \"%s\")"), - name ? name : "", name ? ": " : "", - t ? t : "", msg, (lasttp && *lasttp) ? lasttp : ""); - sh_longjmp (evalbuf, 1); -} - -/* Convert a string to an intmax_t integer, with an arbitrary base. - 0nnn -> base 8 - 0[Xx]nn -> base 16 - Anything else: [base#]number (this is implemented to match ksh93) - - Base may be >=2 and <=64. If base is <= 36, the numbers are drawn - from [0-9][a-zA-Z], and lowercase and uppercase letters may be used - interchangeably. If base is > 36 and <= 64, the numbers are drawn - from [0-9][a-z][A-Z]_@ (a = 10, z = 35, A = 36, Z = 61, @ = 62, _ = 63 -- - you get the picture). */ - -#define VALID_NUMCHAR(c) (ISALNUM(c) || ((c) == '_') || ((c) == '@')) - -static intmax_t -strlong (num) - char *num; -{ - register char *s; - register unsigned char c; - int base, foundbase; - intmax_t val, pval; - - s = num; - - base = 10; - foundbase = 0; - if (*s == '0') - { - s++; - - if (*s == '\0') - return 0; - - /* Base 16? */ - if (*s == 'x' || *s == 'X') - { - base = 16; - s++; -#if STRICT_ARITH_PARSING - if (*s == 0) - evalerror (_("invalid number")); -#endif - } - else - base = 8; - foundbase++; - } - - val = 0; - for (c = *s++; c; c = *s++) - { - if (c == '#') - { - if (foundbase) - evalerror (_("invalid number")); - - /* Illegal base specifications raise an evaluation error. */ - if (val < 2 || val > 64) - evalerror (_("invalid arithmetic base")); - - base = val; - val = 0; - foundbase++; - - /* Make sure a base# is followed by a character that can compose a - valid integer constant. Jeremy Townshend */ - if (VALID_NUMCHAR (*s) == 0) - evalerror (_("invalid integer constant")); - } - else if (VALID_NUMCHAR (c)) - { - if (DIGIT(c)) - c = TODIGIT(c); - else if (c >= 'a' && c <= 'z') - c -= 'a' - 10; - else if (c >= 'A' && c <= 'Z') - c -= 'A' - ((base <= 36) ? 10 : 36); - else if (c == '@') - c = 62; - else if (c == '_') - c = 63; - - if (c >= base) - evalerror (_("value too great for base")); - -#ifdef CHECK_OVERFLOW - pval = val; - val = (val * base) + c; - if (val < 0 || val < pval) /* overflow */ - return INTMAX_MAX; -#else - val = (val * base) + c; -#endif - } - else - break; - } - - return (val); -} - -#if defined (EXPR_TEST) -void * -xmalloc (n) - int n; -{ - return (malloc (n)); -} - -void * -xrealloc (s, n) - char *s; - int n; -{ - return (realloc (s, n)); -} - -SHELL_VAR *find_variable () { return 0;} -SHELL_VAR *bind_variable () { return 0; } - -char *get_string_value () { return 0; } - -procenv_t top_level; - -main (argc, argv) - int argc; - char **argv; -{ - register int i; - intmax_t v; - int expok; - - if (setjmp (top_level)) - exit (0); - - for (i = 1; i < argc; i++) - { - v = evalexp (argv[i], 0, &expok); - if (expok == 0) - fprintf (stderr, _("%s: expression error\n"), argv[i]); - else - printf ("'%s' -> %ld\n", argv[i], v); - } - exit (0); -} - -int -builtin_error (format, arg1, arg2, arg3, arg4, arg5) - char *format; -{ - fprintf (stderr, "expr: "); - fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5); - fprintf (stderr, "\n"); - return 0; -} - -char * -itos (n) - intmax_t n; -{ - return ("42"); -} - -#endif /* EXPR_TEST */ diff --git a/third_party/bash/externs.h b/third_party/bash/externs.h deleted file mode 100644 index 931dba9cd..000000000 --- a/third_party/bash/externs.h +++ /dev/null @@ -1,554 +0,0 @@ -/* externs.h -- extern function declarations which do not appear in their - own header file. */ - -/* Copyright (C) 1993-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -/* Make sure that this is included *after* config.h! */ - -#if !defined (_EXTERNS_H_) -# define _EXTERNS_H_ - -#include "stdc.h" - -/* Functions from expr.c. */ -#define EXP_EXPANDED 0x01 - -extern intmax_t evalexp PARAMS((char *, int, int *)); - -/* Functions from print_cmd.c. */ -#define FUNC_MULTILINE 0x01 -#define FUNC_EXTERNAL 0x02 - -extern char *make_command_string PARAMS((COMMAND *)); -extern char *print_comsub PARAMS((COMMAND *)); -extern char *named_function_string PARAMS((char *, COMMAND *, int)); - -extern void print_command PARAMS((COMMAND *)); -extern void print_simple_command PARAMS((SIMPLE_COM *)); -extern void print_word_list PARAMS((WORD_LIST *, char *)); - -/* debugger support */ -extern void print_for_command_head PARAMS((FOR_COM *)); -#if defined (SELECT_COMMAND) -extern void print_select_command_head PARAMS((SELECT_COM *)); -#endif -extern void print_case_command_head PARAMS((CASE_COM *)); -#if defined (DPAREN_ARITHMETIC) -extern void print_arith_command PARAMS((WORD_LIST *)); -#endif -#if defined (COND_COMMAND) -extern void print_cond_command PARAMS((COND_COM *)); -#endif - -/* set -x support */ -extern void xtrace_init PARAMS((void)); -#ifdef NEED_XTRACE_SET_DECL -extern void xtrace_set PARAMS((int, FILE *)); -#endif -extern void xtrace_fdchk PARAMS((int)); -extern void xtrace_reset PARAMS((void)); -extern char *indirection_level_string PARAMS((void)); -extern void xtrace_print_assignment PARAMS((char *, char *, int, int)); -extern void xtrace_print_word_list PARAMS((WORD_LIST *, int)); -extern void xtrace_print_for_command_head PARAMS((FOR_COM *)); -#if defined (SELECT_COMMAND) -extern void xtrace_print_select_command_head PARAMS((SELECT_COM *)); -#endif -extern void xtrace_print_case_command_head PARAMS((CASE_COM *)); -#if defined (DPAREN_ARITHMETIC) -extern void xtrace_print_arith_cmd PARAMS((WORD_LIST *)); -#endif -#if defined (COND_COMMAND) -extern void xtrace_print_cond_term PARAMS((int, int, WORD_DESC *, char *, char *)); -#endif - -/* Functions from shell.c. */ -extern void exit_shell PARAMS((int)) __attribute__((__noreturn__)); -extern void sh_exit PARAMS((int)) __attribute__((__noreturn__)); -extern void subshell_exit PARAMS((int)) __attribute__((__noreturn__)); -extern void set_exit_status PARAMS((int)); -extern void disable_priv_mode PARAMS((void)); -extern void unbind_args PARAMS((void)); - -#if defined (RESTRICTED_SHELL) -extern int shell_is_restricted PARAMS((char *)); -extern int maybe_make_restricted PARAMS((char *)); -#endif - -extern void unset_bash_input PARAMS((int)); -extern void get_current_user_info PARAMS((void)); - -/* Functions from eval.c. */ -extern int reader_loop PARAMS((void)); -extern int pretty_print_loop PARAMS((void)); -extern int parse_command PARAMS((void)); -extern int read_command PARAMS((void)); - -/* Functions from braces.c. */ -#if defined (BRACE_EXPANSION) -extern char **brace_expand PARAMS((char *)); -#endif - -/* Miscellaneous functions from parse.y */ -extern int yyparse PARAMS((void)); -extern int return_EOF PARAMS((void)); -extern void push_token PARAMS((int)); -extern char *xparse_dolparen PARAMS((char *, char *, int *, int)); -extern COMMAND *parse_string_to_command PARAMS((char *, int)); -extern void reset_parser PARAMS((void)); -extern void reset_readahead_token PARAMS((void)); -extern WORD_LIST *parse_string_to_word_list PARAMS((char *, int, const char *)); - -extern int parser_will_prompt PARAMS((void)); -extern int parser_in_command_position PARAMS((void)); - -extern void free_pushed_string_input PARAMS((void)); - -extern int parser_expanding_alias PARAMS((void)); -extern void parser_save_alias PARAMS((void)); -extern void parser_restore_alias PARAMS((void)); - -extern void clear_shell_input_line PARAMS((void)); - -extern char *decode_prompt_string PARAMS((char *)); - -extern int get_current_prompt_level PARAMS((void)); -extern void set_current_prompt_level PARAMS((int)); - -#if defined (HISTORY) -extern char *history_delimiting_chars PARAMS((const char *)); -#endif - -/* Declarations for functions defined in locale.c */ -extern void set_default_locale PARAMS((void)); -extern void set_default_locale_vars PARAMS((void)); -extern int set_locale_var PARAMS((char *, char *)); -extern int set_lang PARAMS((char *, char *)); -extern void set_default_lang PARAMS((void)); -extern char *get_locale_var PARAMS((char *)); -extern char *localetrans PARAMS((char *, int, int *)); -extern char *mk_msgstr PARAMS((char *, int *)); -extern char *locale_expand PARAMS((char *, int, int, int, int *)); -#ifndef locale_decpoint -extern int locale_decpoint PARAMS((void)); -#endif - -/* Declarations for functions defined in list.c. */ -extern void list_walk PARAMS((GENERIC_LIST *, sh_glist_func_t *)); -extern void wlist_walk PARAMS((WORD_LIST *, sh_icpfunc_t *)); -extern GENERIC_LIST *list_reverse (); -extern int list_length (); -extern GENERIC_LIST *list_append (); -extern GENERIC_LIST *list_remove (); - -/* Declarations for functions defined in stringlib.c */ -extern int find_string_in_alist PARAMS((char *, STRING_INT_ALIST *, int)); -extern char *find_token_in_alist PARAMS((int, STRING_INT_ALIST *, int)); -extern int find_index_in_alist PARAMS((char *, STRING_INT_ALIST *, int)); - -extern char *substring PARAMS((const char *, int, int)); -extern char *strsub PARAMS((char *, char *, char *, int)); -extern char *strcreplace PARAMS((char *, int, const char *, int)); -extern void strip_leading PARAMS((char *)); -extern void strip_trailing PARAMS((char *, int, int)); -extern void xbcopy PARAMS((char *, char *, int)); - -/* Functions from version.c. */ -extern char *shell_version_string PARAMS((void)); -extern void show_shell_version PARAMS((int)); - -/* Functions from the bash library, lib/sh/libsh.a. These should really - go into a separate include file. */ - -/* declarations for functions defined in lib/sh/casemod.c */ -extern char *sh_modcase PARAMS((const char *, char *, int)); - -/* Defines for flags argument to sh_modcase. These need to agree with what's - in lib/sh/casemode.c */ -#define CASE_LOWER 0x0001 -#define CASE_UPPER 0x0002 -#define CASE_CAPITALIZE 0x0004 -#define CASE_UNCAP 0x0008 -#define CASE_TOGGLE 0x0010 -#define CASE_TOGGLEALL 0x0020 -#define CASE_UPFIRST 0x0040 -#define CASE_LOWFIRST 0x0080 - -#define CASE_USEWORDS 0x1000 - -/* declarations for functions defined in lib/sh/clktck.c */ -extern long get_clk_tck PARAMS((void)); - -/* declarations for functions defined in lib/sh/clock.c */ -extern void clock_t_to_secs (); -extern void print_clock_t (); - -/* Declarations for functions defined in lib/sh/dprintf.c */ -#if !defined (HAVE_DPRINTF) -extern void dprintf PARAMS((int, const char *, ...)) __attribute__((__format__ (printf, 2, 3))); -#endif - -/* Declarations for functions defined in lib/sh/fmtulong.c */ -#define FL_PREFIX 0x01 /* add 0x, 0X, or 0 prefix as appropriate */ -#define FL_ADDBASE 0x02 /* add base# prefix to converted value */ -#define FL_HEXUPPER 0x04 /* use uppercase when converting to hex */ -#define FL_UNSIGNED 0x08 /* don't add any sign */ - -extern char *fmtulong PARAMS((unsigned long int, int, char *, size_t, int)); - -/* Declarations for functions defined in lib/sh/fmtulong.c */ -#if defined (HAVE_LONG_LONG_INT) -extern char *fmtullong PARAMS((unsigned long long int, int, char *, size_t, int)); -#endif - -/* Declarations for functions defined in lib/sh/fmtumax.c */ -extern char *fmtumax PARAMS((uintmax_t, int, char *, size_t, int)); - -/* Declarations for functions defined in lib/sh/fnxform.c */ -extern char *fnx_fromfs PARAMS((char *, size_t)); -extern char *fnx_tofs PARAMS((char *, size_t)); - -/* Declarations for functions defined in lib/sh/fpurge.c */ - -#if defined NEED_FPURGE_DECL -#if !HAVE_DECL_FPURGE - -#if HAVE_FPURGE -# define fpurge _bash_fpurge -#endif -extern int fpurge PARAMS((FILE *stream)); - -#endif /* HAVE_DECL_FPURGE */ -#endif /* NEED_FPURGE_DECL */ - -/* Declarations for functions defined in lib/sh/getcwd.c */ -#if !defined (HAVE_GETCWD) -extern char *getcwd PARAMS((char *, size_t)); -#endif - -/* Declarations for functions defined in lib/sh/input_avail.c */ -extern int input_avail PARAMS((int)); - -/* Declarations for functions defined in lib/sh/itos.c */ -extern char *inttostr PARAMS((intmax_t, char *, size_t)); -extern char *itos PARAMS((intmax_t)); -extern char *mitos PARAMS((intmax_t)); -extern char *uinttostr PARAMS((uintmax_t, char *, size_t)); -extern char *uitos PARAMS((uintmax_t)); - -/* declarations for functions defined in lib/sh/makepath.c */ -#define MP_DOTILDE 0x01 -#define MP_DOCWD 0x02 -#define MP_RMDOT 0x04 -#define MP_IGNDOT 0x08 - -extern char *sh_makepath PARAMS((const char *, const char *, int)); - -/* declarations for functions defined in lib/sh/mbscasecmp.c */ -#if !defined (HAVE_MBSCASECMP) -extern char *mbscasecmp PARAMS((const char *, const char *)); -#endif - -/* declarations for functions defined in lib/sh/mbschr.c */ -#if !defined (HAVE_MBSCHR) -extern char *mbschr PARAMS((const char *, int)); -#endif - -/* declarations for functions defined in lib/sh/mbscmp.c */ -#if !defined (HAVE_MBSCMP) -extern char *mbscmp PARAMS((const char *, const char *)); -#endif - -/* declarations for functions defined in lib/sh/netconn.c */ -extern int isnetconn PARAMS((int)); - -/* declarations for functions defined in lib/sh/netopen.c */ -extern int netopen PARAMS((char *)); - -/* Declarations for functions defined in lib/sh/oslib.c */ - -#if !defined (HAVE_DUP2) || defined (DUP2_BROKEN) -extern int dup2 PARAMS((int, int)); -#endif - -#if !defined (HAVE_GETDTABLESIZE) -extern int getdtablesize PARAMS((void)); -#endif /* !HAVE_GETDTABLESIZE */ - -#if !defined (HAVE_GETHOSTNAME) -extern int gethostname PARAMS((char *, int)); -#endif /* !HAVE_GETHOSTNAME */ - -extern int getmaxgroups PARAMS((void)); -extern long getmaxchild PARAMS((void)); - -/* declarations for functions defined in lib/sh/pathcanon.c */ -#define PATH_CHECKDOTDOT 0x0001 -#define PATH_CHECKEXISTS 0x0002 -#define PATH_HARDPATH 0x0004 -#define PATH_NOALLOC 0x0008 - -extern char *sh_canonpath PARAMS((char *, int)); - -/* declarations for functions defined in lib/sh/pathphys.c */ -extern char *sh_physpath PARAMS((char *, int)); -extern char *sh_realpath PARAMS((const char *, char *)); - -/* declarations for functions defined in lib/sh/random.c */ -extern int brand PARAMS((void)); -extern void sbrand PARAMS((unsigned long)); /* set bash random number generator. */ -extern void seedrand PARAMS((void)); /* seed generator randomly */ -extern void seedrand32 PARAMS((void)); -extern u_bits32_t get_urandom32 PARAMS((void)); - -/* declarations for functions defined in lib/sh/setlinebuf.c */ -#ifdef NEED_SH_SETLINEBUF_DECL -extern int sh_setlinebuf PARAMS((FILE *)); -#endif - -/* declarations for functions defined in lib/sh/shaccess.c */ -extern int sh_eaccess PARAMS((const char *, int)); - -/* declarations for functions defined in lib/sh/shmatch.c */ -extern int sh_regmatch PARAMS((const char *, const char *, int)); - -/* defines for flags argument to sh_regmatch. */ -#define SHMAT_SUBEXP 0x001 /* save subexpressions in SH_REMATCH */ -#define SHMAT_PWARN 0x002 /* print a warning message on invalid regexp */ - -/* declarations for functions defined in lib/sh/shmbchar.c */ -extern size_t mbstrlen PARAMS((const char *)); -extern char *mbsmbchar PARAMS((const char *)); -extern int sh_mbsnlen PARAMS((const char *, size_t, int)); - -/* declarations for functions defined in lib/sh/shquote.c */ -extern char *sh_single_quote PARAMS((const char *)); -extern char *sh_double_quote PARAMS((const char *)); -extern char *sh_mkdoublequoted PARAMS((const char *, int, int)); -extern char *sh_un_double_quote PARAMS((char *)); -extern char *sh_backslash_quote PARAMS((char *, const char *, int)); -extern char *sh_backslash_quote_for_double_quotes PARAMS((char *, int)); -extern char *sh_quote_reusable PARAMS((char *, int)); -extern int sh_contains_shell_metas PARAMS((const char *)); -extern int sh_contains_quotes PARAMS((const char *)); - -/* declarations for functions defined in lib/sh/spell.c */ -extern int spname PARAMS((char *, char *)); -extern char *dirspell PARAMS((char *)); - -/* declarations for functions defined in lib/sh/strcasecmp.c */ -#if !defined (HAVE_STRCASECMP) -extern int strncasecmp PARAMS((const char *, const char *, size_t)); -extern int strcasecmp PARAMS((const char *, const char *)); -#endif /* HAVE_STRCASECMP */ - -/* declarations for functions defined in lib/sh/strcasestr.c */ -#if ! HAVE_STRCASESTR -extern char *strcasestr PARAMS((const char *, const char *)); -#endif - -/* declarations for functions defined in lib/sh/strchrnul.c */ -#if ! HAVE_STRCHRNUL -extern char *strchrnul PARAMS((const char *, int)); -#endif - -/* declarations for functions defined in lib/sh/strerror.c */ -#if !defined (HAVE_STRERROR) && !defined (strerror) -extern char *strerror PARAMS((int)); -#endif - -/* declarations for functions defined in lib/sh/strftime.c */ -#if !defined (HAVE_STRFTIME) && defined (NEED_STRFTIME_DECL) -extern size_t strftime PARAMS((char *, size_t, const char *, const struct tm *)); -#endif - -/* declarations for functions and structures defined in lib/sh/stringlist.c */ - -/* This is a general-purpose argv-style array struct. */ -typedef struct _list_of_strings { - char **list; - int list_size; - int list_len; -} STRINGLIST; - -typedef int sh_strlist_map_func_t PARAMS((char *)); - -extern STRINGLIST *strlist_create PARAMS((int)); -extern STRINGLIST *strlist_resize PARAMS((STRINGLIST *, int)); -extern void strlist_flush PARAMS((STRINGLIST *)); -extern void strlist_dispose PARAMS((STRINGLIST *)); -extern int strlist_remove PARAMS((STRINGLIST *, char *)); -extern STRINGLIST *strlist_copy PARAMS((STRINGLIST *)); -extern STRINGLIST *strlist_merge PARAMS((STRINGLIST *, STRINGLIST *)); -extern STRINGLIST *strlist_append PARAMS((STRINGLIST *, STRINGLIST *)); -extern STRINGLIST *strlist_prefix_suffix PARAMS((STRINGLIST *, char *, char *)); -extern void strlist_print PARAMS((STRINGLIST *, char *)); -extern void strlist_walk PARAMS((STRINGLIST *, sh_strlist_map_func_t *)); -extern void strlist_sort PARAMS((STRINGLIST *)); - -/* declarations for functions defined in lib/sh/stringvec.c */ - -extern char **strvec_create PARAMS((int)); -extern char **strvec_resize PARAMS((char **, int)); -extern char **strvec_mcreate PARAMS((int)); -extern char **strvec_mresize PARAMS((char **, int)); -extern void strvec_flush PARAMS((char **)); -extern void strvec_dispose PARAMS((char **)); -extern int strvec_remove PARAMS((char **, char *)); -extern int strvec_len PARAMS((char **)); -extern int strvec_search PARAMS((char **, char *)); -extern char **strvec_copy PARAMS((char **)); -extern int strvec_posixcmp PARAMS((char **, char **)); -extern int strvec_strcmp PARAMS((char **, char **)); -extern void strvec_sort PARAMS((char **, int)); - -extern char **strvec_from_word_list PARAMS((WORD_LIST *, int, int, int *)); -extern WORD_LIST *strvec_to_word_list PARAMS((char **, int, int)); - -/* declarations for functions defined in lib/sh/strnlen.c */ -#if !defined (HAVE_STRNLEN) -extern size_t strnlen PARAMS((const char *, size_t)); -#endif - -/* declarations for functions defined in lib/sh/strpbrk.c */ -#if !defined (HAVE_STRPBRK) -extern char *strpbrk PARAMS((const char *, const char *)); -#endif - -/* declarations for functions defined in lib/sh/strtod.c */ -#if !defined (HAVE_STRTOD) -extern double strtod PARAMS((const char *, char **)); -#endif - -/* declarations for functions defined in lib/sh/strtol.c */ -#if !HAVE_DECL_STRTOL -extern long strtol PARAMS((const char *, char **, int)); -#endif - -/* declarations for functions defined in lib/sh/strtoll.c */ -#if defined (HAVE_LONG_LONG_INT) && !HAVE_DECL_STRTOLL -extern long long strtoll PARAMS((const char *, char **, int)); -#endif - -/* declarations for functions defined in lib/sh/strtoul.c */ -#if !HAVE_DECL_STRTOUL -extern unsigned long strtoul PARAMS((const char *, char **, int)); -#endif - -/* declarations for functions defined in lib/sh/strtoull.c */ -#if defined (HAVE_UNSIGNED_LONG_LONG_INT) && !HAVE_DECL_STRTOULL -extern unsigned long long strtoull PARAMS((const char *, char **, int)); -#endif - -/* declarations for functions defined in lib/sh/strimax.c */ -#if !HAVE_DECL_STRTOIMAX -extern intmax_t strtoimax PARAMS((const char *, char **, int)); -#endif - -/* declarations for functions defined in lib/sh/strumax.c */ -#if !HAVE_DECL_STRTOUMAX -extern uintmax_t strtoumax PARAMS((const char *, char **, int)); -#endif - -/* declarations for functions defined in lib/sh/strtrans.c */ -extern char *ansicstr PARAMS((char *, int, int, int *, int *)); -extern char *ansic_quote PARAMS((char *, int, int *)); -extern int ansic_shouldquote PARAMS((const char *)); -extern char *ansiexpand PARAMS((char *, int, int, int *)); - -/* declarations for functions defined in lib/sh/strvis.c */ -extern int sh_charvis PARAMS((const char *, size_t *, size_t, char *, size_t *)); -extern char *sh_strvis PARAMS((const char *)); - -/* declarations for functions defined in lib/sh/timeval.c. No prototypes - so we don't have to count on having a definition of struct timeval in - scope when this file is included. */ -extern void timeval_to_secs (); -extern void print_timeval (); - -/* declarations for functions defined in lib/sh/tmpfile.c */ -#define MT_USETMPDIR 0x0001 -#define MT_READWRITE 0x0002 -#define MT_USERANDOM 0x0004 -#define MT_TEMPLATE 0x0008 - -extern char *sh_mktmpname PARAMS((char *, int)); -extern int sh_mktmpfd PARAMS((char *, int, char **)); -/* extern FILE *sh_mktmpfp PARAMS((char *, int, char **)); */ -extern char *sh_mktmpdir PARAMS((char *, int)); - -/* declarations for functions defined in lib/sh/uconvert.c */ -extern int uconvert PARAMS((char *, long *, long *, char **)); - -/* declarations for functions defined in lib/sh/ufuncs.c */ -extern unsigned int falarm PARAMS((unsigned int, unsigned int)); -extern unsigned int fsleep PARAMS((unsigned int, unsigned int)); - -/* declarations for functions defined in lib/sh/unicode.c */ -extern int u32cconv PARAMS((unsigned long, char *)); -extern void u32reset PARAMS((void)); - -/* declarations for functions defined in lib/sh/utf8.c */ -extern char *utf8_mbschr PARAMS((const char *, int)); -extern int utf8_mbscmp PARAMS((const char *, const char *)); -extern char *utf8_mbsmbchar PARAMS((const char *)); -extern int utf8_mbsnlen PARAMS((const char *, size_t, int)); -extern int utf8_mblen PARAMS((const char *, size_t)); -extern size_t utf8_mbstrlen PARAMS((const char *)); - -/* declarations for functions defined in lib/sh/wcsnwidth.c */ -#if defined (HANDLE_MULTIBYTE) -extern int wcsnwidth PARAMS((const wchar_t *, size_t, int)); -#endif - -/* declarations for functions defined in lib/sh/winsize.c */ -extern void get_new_window_size PARAMS((int, int *, int *)); - -/* declarations for functions defined in lib/sh/zcatfd.c */ -extern int zcatfd PARAMS((int, int, char *)); - -/* declarations for functions defined in lib/sh/zgetline.c */ -extern ssize_t zgetline PARAMS((int, char **, size_t *, int, int)); - -/* declarations for functions defined in lib/sh/zmapfd.c */ -extern int zmapfd PARAMS((int, char **, char *)); - -/* declarations for functions defined in lib/sh/zread.c */ -extern ssize_t zread PARAMS((int, char *, size_t)); -extern ssize_t zreadretry PARAMS((int, char *, size_t)); -extern ssize_t zreadintr PARAMS((int, char *, size_t)); -extern ssize_t zreadc PARAMS((int, char *)); -extern ssize_t zreadcintr PARAMS((int, char *)); -extern ssize_t zreadn PARAMS((int, char *, size_t)); -extern void zreset PARAMS((void)); -extern void zsyncfd PARAMS((int)); - -/* declarations for functions defined in lib/sh/zwrite.c */ -extern int zwrite PARAMS((int, char *, size_t)); - -/* declarations for functions defined in lib/glob/gmisc.c */ -extern int match_pattern_char PARAMS((char *, char *, int)); -extern int umatchlen PARAMS((char *, size_t)); - -#if defined (HANDLE_MULTIBYTE) -extern int match_pattern_wchar PARAMS((wchar_t *, wchar_t *, int)); -extern int wmatchlen PARAMS((wchar_t *, size_t)); -#endif - -#endif /* _EXTERNS_H_ */ diff --git a/third_party/bash/filecntl.h b/third_party/bash/filecntl.h deleted file mode 100644 index 9bcbab8d5..000000000 --- a/third_party/bash/filecntl.h +++ /dev/null @@ -1,53 +0,0 @@ -/* filecntl.h - Definitions to set file descriptors to close-on-exec. */ - -/* Copyright (C) 1993 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_FILECNTL_H_) -#define _FILECNTL_H_ - -#include - -/* Definitions to set file descriptors to close-on-exec, the Posix way. */ -#if !defined (FD_CLOEXEC) -#define FD_CLOEXEC 1 -#endif - -#define FD_NCLOEXEC 0 - -#define SET_CLOSE_ON_EXEC(fd) (fcntl ((fd), F_SETFD, FD_CLOEXEC)) -#define SET_OPEN_ON_EXEC(fd) (fcntl ((fd), F_SETFD, FD_NCLOEXEC)) - -/* How to open a file in non-blocking mode, the Posix.1 way. */ -#if !defined (O_NONBLOCK) -# if defined (O_NDELAY) -# define O_NONBLOCK O_NDELAY -# else -# define O_NONBLOCK 0 -# endif -#endif - -/* Make sure O_BINARY and O_TEXT are defined to avoid Windows-specific code. */ -#if !defined (O_BINARY) -# define O_BINARY 0 -#endif -#if !defined (O_TEXT) -# define O_TEXT 0 -#endif - -#endif /* ! _FILECNTL_H_ */ diff --git a/third_party/bash/findcmd.c b/third_party/bash/findcmd.c deleted file mode 100644 index 7c3017820..000000000 --- a/third_party/bash/findcmd.c +++ /dev/null @@ -1,696 +0,0 @@ -/* findcmd.c -- Functions to search for commands by name. */ - -/* Copyright (C) 1997-2022 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include -#include "chartypes.h" -#include "bashtypes.h" -#if !defined (_MINIX) && defined (HAVE_SYS_FILE_H) -# include -#endif -#include "filecntl.h" -#include "posixstat.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif -#include - -#include "bashansi.h" - -#include "memalloc.h" -#include "shell.h" -#include "execute_cmd.h" -#include "flags.h" -#include "hashlib.h" -#include "pathexp.h" -#include "hashcmd.h" -#include "findcmd.h" /* matching prototypes and declarations */ - -#include "strmatch.h" - -#if !defined (errno) -extern int errno; -#endif - -/* Static functions defined and used in this file. */ -static char *_find_user_command_internal PARAMS((const char *, int)); -static char *find_user_command_internal PARAMS((const char *, int)); -static char *find_user_command_in_path PARAMS((const char *, char *, int, int *)); -static char *find_in_path_element PARAMS((const char *, char *, int, int, struct stat *, int *)); -static char *find_absolute_program PARAMS((const char *, int)); - -static char *get_next_path_element PARAMS((char *, int *)); - -/* The file name which we would try to execute, except that it isn't - possible to execute it. This is the first file that matches the - name that we are looking for while we are searching $PATH for a - suitable one to execute. If we cannot find a suitable executable - file, then we use this one. */ -static char *file_to_lose_on; - -/* Non-zero if we should stat every command found in the hash table to - make sure it still exists. */ -int check_hashed_filenames = CHECKHASH_DEFAULT; - -/* DOT_FOUND_IN_SEARCH becomes non-zero when find_user_command () - encounters a `.' as the directory pathname while scanning the - list of possible pathnames; i.e., if `.' comes before the directory - containing the file of interest. */ -int dot_found_in_search = 0; - -/* Set up EXECIGNORE; a blacklist of patterns that executable files should not - match. */ -static struct ignorevar execignore = -{ - "EXECIGNORE", - NULL, - 0, - NULL, - NULL -}; - -void -setup_exec_ignore (varname) - char *varname; -{ - setup_ignore_patterns (&execignore); -} - -static int -exec_name_should_ignore (name) - const char *name; -{ - struct ign *p; - - for (p = execignore.ignores; p && p->val; p++) - if (strmatch (p->val, (char *)name, FNMATCH_EXTFLAG|FNM_CASEFOLD) != FNM_NOMATCH) - return 1; - return 0; -} - -/* Return some flags based on information about this file. - The EXISTS bit is non-zero if the file is found. - The EXECABLE bit is non-zero the file is executable. - Zero is returned if the file is not found. */ -int -file_status (name) - const char *name; -{ - struct stat finfo; - int r; - - /* Determine whether this file exists or not. */ - if (stat (name, &finfo) < 0) - return (0); - - /* If the file is a directory, then it is not "executable" in the - sense of the shell. */ - if (S_ISDIR (finfo.st_mode)) - return (FS_EXISTS|FS_DIRECTORY); - - r = FS_EXISTS; - -#if defined (HAVE_EACCESS) - /* Use eaccess(2) if we have it to take things like ACLs and other - file access mechanisms into account. eaccess uses the effective - user and group IDs, not the real ones. We could use sh_eaccess, - but we don't want any special treatment for /dev/fd. */ - if (exec_name_should_ignore (name) == 0 && eaccess (name, X_OK) == 0) - r |= FS_EXECABLE; - if (eaccess (name, R_OK) == 0) - r |= FS_READABLE; - - return r; -#elif defined (AFS) - /* We have to use access(2) to determine access because AFS does not - support Unix file system semantics. This may produce wrong - answers for non-AFS files when ruid != euid. I hate AFS. */ - if (exec_name_should_ignore (name) == 0 && access (name, X_OK) == 0) - r |= FS_EXECABLE; - if (access (name, R_OK) == 0) - r |= FS_READABLE; - - return r; -#else /* !HAVE_EACCESS && !AFS */ - - /* Find out if the file is actually executable. By definition, the - only other criteria is that the file has an execute bit set that - we can use. The same with whether or not a file is readable. */ - - /* Root only requires execute permission for any of owner, group or - others to be able to exec a file, and can read any file. */ - if (current_user.euid == (uid_t)0) - { - r |= FS_READABLE; - if (exec_name_should_ignore (name) == 0 && (finfo.st_mode & S_IXUGO)) - r |= FS_EXECABLE; - return r; - } - - /* If we are the owner of the file, the owner bits apply. */ - if (current_user.euid == finfo.st_uid) - { - if (exec_name_should_ignore (name) == 0 && (finfo.st_mode & S_IXUSR)) - r |= FS_EXECABLE; - if (finfo.st_mode & S_IRUSR) - r |= FS_READABLE; - } - - /* If we are in the owning group, the group permissions apply. */ - else if (group_member (finfo.st_gid)) - { - if (exec_name_should_ignore (name) == 0 && (finfo.st_mode & S_IXGRP)) - r |= FS_EXECABLE; - if (finfo.st_mode & S_IRGRP) - r |= FS_READABLE; - } - - /* Else we check whether `others' have permission to execute the file */ - else - { - if (exec_name_should_ignore (name) == 0 && finfo.st_mode & S_IXOTH) - r |= FS_EXECABLE; - if (finfo.st_mode & S_IROTH) - r |= FS_READABLE; - } - - return r; -#endif /* !AFS */ -} - -/* Return non-zero if FILE exists and is executable. - Note that this function is the definition of what an - executable file is; do not change this unless YOU know - what an executable file is. */ -int -executable_file (file) - const char *file; -{ - int s; - - s = file_status (file); -#if defined (EISDIR) - if (s & FS_DIRECTORY) - errno = EISDIR; /* let's see if we can improve error messages */ -#endif - return ((s & FS_EXECABLE) && ((s & FS_DIRECTORY) == 0)); -} - -int -is_directory (file) - const char *file; -{ - return (file_status (file) & FS_DIRECTORY); -} - -int -executable_or_directory (file) - const char *file; -{ - int s; - - s = file_status (file); - return ((s & FS_EXECABLE) || (s & FS_DIRECTORY)); -} - -/* Locate the executable file referenced by NAME, searching along - the contents of the shell PATH variable. Return a new string - which is the full pathname to the file, or NULL if the file - couldn't be found. If a file is found that isn't executable, - and that is the only match, then return that. */ -char * -find_user_command (name) - const char *name; -{ - return (find_user_command_internal (name, FS_EXEC_PREFERRED|FS_NODIRS)); -} - -/* Locate the file referenced by NAME, searching along the contents - of the shell PATH variable. Return a new string which is the full - pathname to the file, or NULL if the file couldn't be found. This - returns the first readable file found; designed to be used to look - for shell scripts or files to source. */ -char * -find_path_file (name) - const char *name; -{ - return (find_user_command_internal (name, FS_READABLE)); -} - -static char * -_find_user_command_internal (name, flags) - const char *name; - int flags; -{ - char *path_list, *cmd; - SHELL_VAR *var; - - /* Search for the value of PATH in both the temporary environments and - in the regular list of variables. */ - if (var = find_variable_tempenv ("PATH")) /* XXX could be array? */ - path_list = value_cell (var); - else - path_list = (char *)NULL; - - if (path_list == 0 || *path_list == '\0') - return (savestring (name)); - - cmd = find_user_command_in_path (name, path_list, flags, (int *)0); - - return (cmd); -} - -static char * -find_user_command_internal (name, flags) - const char *name; - int flags; -{ -#ifdef __WIN32__ - char *res, *dotexe; - - dotexe = (char *)xmalloc (strlen (name) + 5); - strcpy (dotexe, name); - strcat (dotexe, ".exe"); - res = _find_user_command_internal (dotexe, flags); - free (dotexe); - if (res == 0) - res = _find_user_command_internal (name, flags); - return res; -#else - return (_find_user_command_internal (name, flags)); -#endif -} - -/* Return the next element from PATH_LIST, a colon separated list of - paths. PATH_INDEX_POINTER is the address of an index into PATH_LIST; - the index is modified by this function. - Return the next element of PATH_LIST or NULL if there are no more. */ -static char * -get_next_path_element (path_list, path_index_pointer) - char *path_list; - int *path_index_pointer; -{ - char *path; - - path = extract_colon_unit (path_list, path_index_pointer); - - if (path == 0) - return (path); - - if (*path == '\0') - { - free (path); - path = savestring ("."); - } - - return (path); -} - -/* Look for PATHNAME in $PATH. Returns either the hashed command - corresponding to PATHNAME or the first instance of PATHNAME found - in $PATH. If (FLAGS&CMDSRCH_HASH) is non-zero, insert the instance of - PATHNAME found in $PATH into the command hash table. - If (FLAGS&CMDSRCH_STDPATH) is non-zero, we are running in a `command -p' - environment and should use the Posix standard path. - Returns a newly-allocated string. */ -char * -search_for_command (pathname, flags) - const char *pathname; - int flags; -{ - char *hashed_file, *command, *path_list; - int temp_path, st; - SHELL_VAR *path; - - hashed_file = command = (char *)NULL; - - /* If PATH is in the temporary environment for this command, don't use the - hash table to search for the full pathname. */ - path = find_variable_tempenv ("PATH"); - temp_path = path && tempvar_p (path); - - /* Don't waste time trying to find hashed data for a pathname - that is already completely specified or if we're using a command- - specific value for PATH. */ - if (temp_path == 0 && (flags & CMDSRCH_STDPATH) == 0 && absolute_program (pathname) == 0) - hashed_file = phash_search (pathname); - - /* If a command found in the hash table no longer exists, we need to - look for it in $PATH. Thank you Posix.2. This forces us to stat - every command found in the hash table. */ - - if (hashed_file && (posixly_correct || check_hashed_filenames)) - { - st = file_status (hashed_file); - if ((st & (FS_EXISTS|FS_EXECABLE)) != (FS_EXISTS|FS_EXECABLE)) - { - phash_remove (pathname); - free (hashed_file); - hashed_file = (char *)NULL; - } - } - - if (hashed_file) - command = hashed_file; - else if (absolute_program (pathname)) - /* A command containing a slash is not looked up in PATH or saved in - the hash table. */ - command = savestring (pathname); - else - { - if (flags & CMDSRCH_STDPATH) - path_list = conf_standard_path (); - else if (temp_path || path) - path_list = value_cell (path); - else - path_list = 0; - - command = find_user_command_in_path (pathname, path_list, FS_EXEC_PREFERRED|FS_NODIRS, &st); - - if (command && hashing_enabled && temp_path == 0 && (flags & CMDSRCH_HASH)) - { - /* If we found the full pathname the same as the command name, the - command probably doesn't exist. Don't put it into the hash - table unless it's an executable file in the current directory. */ - if (STREQ (command, pathname)) - { - if (st & FS_EXECABLE) - phash_insert ((char *)pathname, command, dot_found_in_search, 1); - } - /* If we're in posix mode, don't add files without the execute bit - to the hash table. */ - else if (posixly_correct || check_hashed_filenames) - { - if (st & FS_EXECABLE) - phash_insert ((char *)pathname, command, dot_found_in_search, 1); - } - else - phash_insert ((char *)pathname, command, dot_found_in_search, 1); - } - - if (flags & CMDSRCH_STDPATH) - free (path_list); - } - - return (command); -} - -char * -user_command_matches (name, flags, state) - const char *name; - int flags, state; -{ - register int i; - int path_index, name_len; - char *path_list, *path_element, *match; - struct stat dotinfo; - static char **match_list = NULL; - static int match_list_size = 0; - static int match_index = 0; - - if (state == 0) - { - /* Create the list of matches. */ - if (match_list == 0) - { - match_list_size = 5; - match_list = strvec_create (match_list_size); - } - - /* Clear out the old match list. */ - for (i = 0; i < match_list_size; i++) - match_list[i] = 0; - - /* We haven't found any files yet. */ - match_index = 0; - - if (absolute_program (name)) - { - match_list[0] = find_absolute_program (name, flags); - match_list[1] = (char *)NULL; - path_list = (char *)NULL; - } - else - { - name_len = strlen (name); - file_to_lose_on = (char *)NULL; - dot_found_in_search = 0; - if (stat (".", &dotinfo) < 0) - dotinfo.st_dev = dotinfo.st_ino = 0; /* so same_file won't match */ - path_list = get_string_value ("PATH"); - path_index = 0; - } - - while (path_list && path_list[path_index]) - { - path_element = get_next_path_element (path_list, &path_index); - - if (path_element == 0) - break; - - match = find_in_path_element (name, path_element, flags, name_len, &dotinfo, (int *)0); - free (path_element); - - if (match == 0) - continue; - - if (match_index + 1 == match_list_size) - { - match_list_size += 10; - match_list = strvec_resize (match_list, (match_list_size + 1)); - } - - match_list[match_index++] = match; - match_list[match_index] = (char *)NULL; - FREE (file_to_lose_on); - file_to_lose_on = (char *)NULL; - } - - /* We haven't returned any strings yet. */ - match_index = 0; - } - - match = match_list[match_index]; - - if (match) - match_index++; - - return (match); -} - -static char * -find_absolute_program (name, flags) - const char *name; - int flags; -{ - int st; - - st = file_status (name); - - /* If the file doesn't exist, quit now. */ - if ((st & FS_EXISTS) == 0) - return ((char *)NULL); - - /* If we only care about whether the file exists or not, return - this filename. Otherwise, maybe we care about whether this - file is executable. If it is, and that is what we want, return it. */ - if ((flags & FS_EXISTS) || ((flags & FS_EXEC_ONLY) && (st & FS_EXECABLE))) - return (savestring (name)); - - return (NULL); -} - -static char * -find_in_path_element (name, path, flags, name_len, dotinfop, rflagsp) - const char *name; - char *path; - int flags, name_len; - struct stat *dotinfop; - int *rflagsp; -{ - int status; - char *full_path, *xpath; - - xpath = (posixly_correct == 0 && *path == '~') ? bash_tilde_expand (path, 0) : path; - - /* Remember the location of "." in the path, in all its forms - (as long as they begin with a `.', e.g. `./.') */ - /* We could also do this or something similar for all relative pathnames - found while searching PATH. */ - if (dot_found_in_search == 0 && *xpath == '.') - dot_found_in_search = same_file (".", xpath, dotinfop, (struct stat *)NULL); - - full_path = sh_makepath (xpath, name, 0); - - status = file_status (full_path); - - if (xpath != path) - free (xpath); - - if (rflagsp) - *rflagsp = status; - - if ((status & FS_EXISTS) == 0) - { - free (full_path); - return ((char *)NULL); - } - - /* The file exists. If the caller simply wants the first file, here it is. */ - if (flags & FS_EXISTS) - return (full_path); - - /* If we have a readable file, and the caller wants a readable file, this - is it. */ - if ((flags & FS_READABLE) && (status & FS_READABLE)) - return (full_path); - - /* If the file is executable, then it satisfies the cases of - EXEC_ONLY and EXEC_PREFERRED. Return this file unconditionally. */ - if ((status & FS_EXECABLE) && (flags & (FS_EXEC_ONLY|FS_EXEC_PREFERRED)) && - (((flags & FS_NODIRS) == 0) || ((status & FS_DIRECTORY) == 0))) - { - FREE (file_to_lose_on); - file_to_lose_on = (char *)NULL; - return (full_path); - } - - /* The file is not executable, but it does exist. If we prefer - an executable, then remember this one if it is the first one - we have found. */ - if ((flags & FS_EXEC_PREFERRED) && file_to_lose_on == 0 && exec_name_should_ignore (full_path) == 0) - file_to_lose_on = savestring (full_path); - - /* If we want only executable files, or we don't want directories and - this file is a directory, or we want a readable file and this file - isn't readable, fail. */ - if ((flags & (FS_EXEC_ONLY|FS_EXEC_PREFERRED)) || - ((flags & FS_NODIRS) && (status & FS_DIRECTORY)) || - ((flags & FS_READABLE) && (status & FS_READABLE) == 0)) - { - free (full_path); - return ((char *)NULL); - } - else - return (full_path); -} - -/* This does the dirty work for find_user_command_internal () and - user_command_matches (). - NAME is the name of the file to search for. - PATH_LIST is a colon separated list of directories to search. - FLAGS contains bit fields which control the files which are eligible. - Some values are: - FS_EXEC_ONLY: The file must be an executable to be found. - FS_EXEC_PREFERRED: If we can't find an executable, then the - the first file matching NAME will do. - FS_EXISTS: The first file found will do. - FS_NODIRS: Don't find any directories. -*/ -static char * -find_user_command_in_path (name, path_list, flags, rflagsp) - const char *name; - char *path_list; - int flags, *rflagsp; -{ - char *full_path, *path; - int path_index, name_len, rflags; - struct stat dotinfo; - - /* We haven't started looking, so we certainly haven't seen - a `.' as the directory path yet. */ - dot_found_in_search = 0; - - if (rflagsp) - *rflagsp = 0; - - if (absolute_program (name)) - { - full_path = find_absolute_program (name, flags); - return (full_path); - } - - if (path_list == 0 || *path_list == '\0') - return (savestring (name)); /* XXX */ - - file_to_lose_on = (char *)NULL; - name_len = strlen (name); - if (stat (".", &dotinfo) < 0) - dotinfo.st_dev = dotinfo.st_ino = 0; - path_index = 0; - - while (path_list[path_index]) - { - /* Allow the user to interrupt out of a lengthy path search. */ - QUIT; - - path = get_next_path_element (path_list, &path_index); - if (path == 0) - break; - - /* Side effects: sets dot_found_in_search, possibly sets - file_to_lose_on. */ - full_path = find_in_path_element (name, path, flags, name_len, &dotinfo, &rflags); - free (path); - - /* We use the file status flag bits to check whether full_path is a - directory, which we reject here. */ - if (full_path && (rflags & FS_DIRECTORY)) - { - free (full_path); - continue; - } - - if (full_path) - { - if (rflagsp) - *rflagsp = rflags; - FREE (file_to_lose_on); - return (full_path); - } - } - - /* We didn't find exactly what the user was looking for. Return - the contents of FILE_TO_LOSE_ON which is NULL when the search - required an executable, or non-NULL if a file was found and the - search would accept a non-executable as a last resort. If the - caller specified FS_NODIRS, and file_to_lose_on is a directory, - return NULL. */ - if (file_to_lose_on && (flags & FS_NODIRS) && file_isdir (file_to_lose_on)) - { - free (file_to_lose_on); - file_to_lose_on = (char *)NULL; - } - - return (file_to_lose_on); -} - -/* External interface to find a command given a $PATH. Separate from - find_user_command_in_path to allow future customization. */ -char * -find_in_path (name, path_list, flags) - const char *name; - char *path_list; - int flags; -{ - return (find_user_command_in_path (name, path_list, flags, (int *)0)); -} diff --git a/third_party/bash/findcmd.h b/third_party/bash/findcmd.h deleted file mode 100644 index bf457814e..000000000 --- a/third_party/bash/findcmd.h +++ /dev/null @@ -1,47 +0,0 @@ -/* findcmd.h - functions from findcmd.c. */ - -/* Copyright (C) 1997-2015,2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_FINDCMD_H_) -#define _FINDCMD_H_ - -#include "stdc.h" - -/* Flags for search_for_command */ -#define CMDSRCH_HASH 0x01 -#define CMDSRCH_STDPATH 0x02 -#define CMDSRCH_TEMPENV 0x04 - -extern int file_status PARAMS((const char *)); -extern int executable_file PARAMS((const char *)); -extern int is_directory PARAMS((const char *)); -extern int executable_or_directory PARAMS((const char *)); -extern char *find_user_command PARAMS((const char *)); -extern char *find_in_path PARAMS((const char *, char *, int)); -extern char *find_path_file PARAMS((const char *)); -extern char *search_for_command PARAMS((const char *, int)); -extern char *user_command_matches PARAMS((const char *, int, int)); -extern void setup_exec_ignore PARAMS((char *)); - -extern int dot_found_in_search; - -/* variables managed via shopt */ -extern int check_hashed_filenames; - -#endif /* _FINDCMD_H_ */ diff --git a/third_party/bash/flags.c b/third_party/bash/flags.c deleted file mode 100644 index 30f6c13d4..000000000 --- a/third_party/bash/flags.c +++ /dev/null @@ -1,385 +0,0 @@ -/* flags.c -- Everything about flags except the `set' command. That - is in builtins.c */ - -/* Copyright (C) 1987-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "shell.h" -#include "execute_cmd.h" -#include "flags.h" - -#if defined (BANG_HISTORY) -# include "bashhist.h" -#endif - -#if defined (JOB_CONTROL) -extern int set_job_control PARAMS((int)); -#endif - -/* **************************************************************** */ -/* */ -/* The Standard sh Flags. */ -/* */ -/* **************************************************************** */ - -/* Non-zero means automatically mark variables which are modified or created - as auto export variables. */ -int mark_modified_vars = 0; - -/* Non-zero causes asynchronous job notification. Otherwise, job state - notification only takes place just before a primary prompt is printed. */ -int asynchronous_notification = 0; - -/* Non-zero means exit immediately if a command exits with a non-zero - exit status. The first is what controls set -e; the second is what - bash uses internally. */ -int errexit_flag = 0; -int exit_immediately_on_error = 0; - -/* Non-zero means disable filename globbing. */ -int disallow_filename_globbing = 0; - -/* Non-zero means that all keyword arguments are placed into the environment - for a command, not just those that appear on the line before the command - name. */ -int place_keywords_in_env = 0; - -/* Non-zero means read commands, but don't execute them. This is useful - for debugging shell scripts that should do something hairy and possibly - destructive. */ -int read_but_dont_execute = 0; - -/* Non-zero means end of file is after one command. */ -int just_one_command = 0; - -/* Non-zero means don't overwrite existing files while doing redirections. */ -int noclobber = 0; - -/* Non-zero means trying to get the value of $i where $i is undefined - causes an error, instead of a null substitution. */ -int unbound_vars_is_error = 0; - -/* Non-zero means type out input lines after you read them. */ -int echo_input_at_read = 0; -int verbose_flag = 0; - -/* Non-zero means type out the command definition after reading, but - before executing. */ -int echo_command_at_execute = 0; - -/* Non-zero means turn on the job control features. */ -int jobs_m_flag = 0; - -/* Non-zero means this shell is interactive, even if running under a - pipe. */ -int forced_interactive = 0; - -/* By default, follow the symbolic links as if they were real directories - while hacking the `cd' command. This means that `cd ..' moves up in - the string of symbolic links that make up the current directory, instead - of the absolute directory. The shell variable `nolinks' also controls - this flag. */ -int no_symbolic_links = 0; - -/* **************************************************************** */ -/* */ -/* Non-Standard Flags Follow Here. */ -/* */ -/* **************************************************************** */ - -#if 0 -/* Non-zero means do lexical scoping in the body of a FOR command. */ -int lexical_scoping = 0; -#endif - -/* Non-zero means look up and remember command names in a hash table, */ -int hashing_enabled = 1; - -#if defined (BANG_HISTORY) -/* Non-zero means that we are doing history expansion. The default. - This means !22 gets the 22nd line of history. */ -int history_expansion = HISTEXPAND_DEFAULT; -int histexp_flag = 0; -#endif /* BANG_HISTORY */ - -/* Non-zero means that we allow comments to appear in interactive commands. */ -int interactive_comments = 1; - -#if defined (RESTRICTED_SHELL) -/* Non-zero means that this shell is `restricted'. A restricted shell - disallows: changing directories, command or path names containing `/', - unsetting or resetting the values of $PATH and $SHELL, and any type of - output redirection. */ -int restricted = 0; /* currently restricted */ -int restricted_shell = 0; /* shell was started in restricted mode. */ -#endif /* RESTRICTED_SHELL */ - -/* Non-zero means that this shell is running in `privileged' mode. This - is required if the shell is to run setuid. If the `-p' option is - not supplied at startup, and the real and effective uids or gids - differ, disable_priv_mode is called to relinquish setuid status. */ -int privileged_mode = 0; - -#if defined (BRACE_EXPANSION) -/* Zero means to disable brace expansion: foo{a,b} -> fooa foob */ -int brace_expansion = 1; -#endif - -/* Non-zero means that shell functions inherit the DEBUG trap. */ -int function_trace_mode = 0; - -/* Non-zero means that shell functions inherit the ERR trap. */ -int error_trace_mode = 0; - -/* Non-zero means that the rightmost non-zero exit status in a pipeline - is the exit status of the entire pipeline. If each processes exits - with a 0 status, the status of the pipeline is 0. */ -int pipefail_opt = 0; - -/* **************************************************************** */ -/* */ -/* The Flags ALIST. */ -/* */ -/* **************************************************************** */ - -const struct flags_alist shell_flags[] = { - /* Standard sh flags. */ - { 'a', &mark_modified_vars }, -#if defined (JOB_CONTROL) - { 'b', &asynchronous_notification }, -#endif /* JOB_CONTROL */ - { 'e', &errexit_flag }, - { 'f', &disallow_filename_globbing }, - { 'h', &hashing_enabled }, - { 'i', &forced_interactive }, - { 'k', &place_keywords_in_env }, -#if defined (JOB_CONTROL) - { 'm', &jobs_m_flag }, -#endif /* JOB_CONTROL */ - { 'n', &read_but_dont_execute }, - { 'p', &privileged_mode }, -#if defined (RESTRICTED_SHELL) - { 'r', &restricted }, -#endif /* RESTRICTED_SHELL */ - { 't', &just_one_command }, - { 'u', &unbound_vars_is_error }, - { 'v', &verbose_flag }, - { 'x', &echo_command_at_execute }, - - /* New flags that control non-standard things. */ -#if 0 - { 'l', &lexical_scoping }, -#endif -#if defined (BRACE_EXPANSION) - { 'B', &brace_expansion }, -#endif - { 'C', &noclobber }, - { 'E', &error_trace_mode }, -#if defined (BANG_HISTORY) - { 'H', &histexp_flag }, -#endif /* BANG_HISTORY */ - { 'P', &no_symbolic_links }, - { 'T', &function_trace_mode }, - {0, (int *)NULL} -}; - -#define NUM_SHELL_FLAGS (sizeof (shell_flags) / sizeof (struct flags_alist)) - -char optflags[NUM_SHELL_FLAGS+4] = { '+' }; - -int * -find_flag (name) - int name; -{ - int i; - for (i = 0; shell_flags[i].name; i++) - { - if (shell_flags[i].name == name) - return (shell_flags[i].value); - } - return (FLAG_UNKNOWN); -} - -/* Change the state of a flag, and return it's original value, or return - FLAG_ERROR if there is no flag FLAG. ON_OR_OFF must be either - FLAG_ON or FLAG_OFF. */ -int -change_flag (flag, on_or_off) - int flag; - int on_or_off; -{ - int *value, old_value; - -#if defined (RESTRICTED_SHELL) - /* Don't allow "set +r" in a shell which is `restricted'. */ - if (restricted && flag == 'r' && on_or_off == FLAG_OFF) - return (FLAG_ERROR); -#endif /* RESTRICTED_SHELL */ - - value = find_flag (flag); - - if ((value == (int *)FLAG_UNKNOWN) || (on_or_off != FLAG_ON && on_or_off != FLAG_OFF)) - return (FLAG_ERROR); - - old_value = *value; - *value = (on_or_off == FLAG_ON) ? 1 : 0; - - /* Special cases for a few flags. */ - switch (flag) - { -#if defined (BANG_HISTORY) - case 'H': - history_expansion = histexp_flag; - if (on_or_off == FLAG_ON) - bash_initialize_history (); - break; -#endif - -#if defined (JOB_CONTROL) - case 'm': - set_job_control (on_or_off == FLAG_ON); - break; -#endif /* JOB_CONTROL */ - - case 'e': - if (builtin_ignoring_errexit == 0) - exit_immediately_on_error = errexit_flag; - break; - - case 'n': - if (interactive_shell) - read_but_dont_execute = 0; - break; - - case 'p': - if (on_or_off == FLAG_OFF) - disable_priv_mode (); - break; - -#if defined (RESTRICTED_SHELL) - case 'r': - if (on_or_off == FLAG_ON && shell_initialized) - maybe_make_restricted (shell_name); - break; -#endif - - case 'v': - echo_input_at_read = verbose_flag; - break; - } - - return (old_value); -} - -/* Return a string which is the names of all the currently - set shell flags. */ -char * -which_set_flags () -{ - char *temp; - int i, string_index; - - temp = (char *)xmalloc (1 + NUM_SHELL_FLAGS + read_from_stdin + want_pending_command); - for (i = string_index = 0; shell_flags[i].name; i++) - if (*(shell_flags[i].value)) - temp[string_index++] = shell_flags[i].name; - - if (want_pending_command) - temp[string_index++] = 'c'; - if (read_from_stdin) - temp[string_index++] = 's'; - - temp[string_index] = '\0'; - return (temp); -} - -char * -get_current_flags () -{ - char *temp; - int i; - - temp = (char *)xmalloc (1 + NUM_SHELL_FLAGS); - for (i = 0; shell_flags[i].name; i++) - temp[i] = *(shell_flags[i].value); - temp[i] = '\0'; - return (temp); -} - -void -set_current_flags (bitmap) - const char *bitmap; -{ - int i; - - if (bitmap == 0) - return; - for (i = 0; shell_flags[i].name; i++) - *(shell_flags[i].value) = bitmap[i]; -} - -void -reset_shell_flags () -{ - mark_modified_vars = disallow_filename_globbing = 0; - place_keywords_in_env = read_but_dont_execute = just_one_command = 0; - noclobber = unbound_vars_is_error = 0; - echo_command_at_execute = jobs_m_flag = forced_interactive = 0; - no_symbolic_links = 0; - privileged_mode = pipefail_opt = 0; - - error_trace_mode = function_trace_mode = 0; - - exit_immediately_on_error = errexit_flag = 0; - echo_input_at_read = verbose_flag = 0; - - hashing_enabled = interactive_comments = 1; - -#if defined (JOB_CONTROL) - asynchronous_notification = 0; -#endif - -#if defined (BANG_HISTORY) - histexp_flag = 0; -#endif - -#if defined (BRACE_EXPANSION) - brace_expansion = 1; -#endif - -#if defined (RESTRICTED_SHELL) - restricted = 0; -#endif -} - -void -initialize_flags () -{ - register int i; - - for (i = 0; shell_flags[i].name; i++) - optflags[i+1] = shell_flags[i].name; - optflags[++i] = 'o'; - optflags[++i] = ';'; - optflags[i+1] = '\0'; -} diff --git a/third_party/bash/flags.h b/third_party/bash/flags.h deleted file mode 100644 index a3b5daa94..000000000 --- a/third_party/bash/flags.h +++ /dev/null @@ -1,87 +0,0 @@ -/* flags.h -- a list of all the flags that the shell knows about. You add - a flag to this program by adding the name here, and in flags.c. */ - -/* Copyright (C) 1993-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_FLAGS_H_) -#define _FLAGS_H_ - -#include "stdc.h" - -/* Welcome to the world of Un*x, where everything is slightly backwards. */ -#define FLAG_ON '-' -#define FLAG_OFF '+' - -#define FLAG_ERROR -1 -#define FLAG_UNKNOWN (int *)0 - -/* The thing that we build the array of flags out of. */ -struct flags_alist { - char name; - int *value; -}; - -extern const struct flags_alist shell_flags[]; -extern char optflags[]; - -extern int - mark_modified_vars, errexit_flag, exit_immediately_on_error, - disallow_filename_globbing, - place_keywords_in_env, read_but_dont_execute, - just_one_command, unbound_vars_is_error, echo_input_at_read, verbose_flag, - echo_command_at_execute, noclobber, - hashing_enabled, forced_interactive, privileged_mode, jobs_m_flag, - asynchronous_notification, interactive_comments, no_symbolic_links, - function_trace_mode, error_trace_mode, pipefail_opt; - -/* -c, -s invocation options -- not really flags, but they show up in $- */ -extern int want_pending_command, read_from_stdin; - -#if 0 -extern int lexical_scoping; -#endif - -#if defined (BRACE_EXPANSION) -extern int brace_expansion; -#endif - -#if defined (BANG_HISTORY) -extern int history_expansion; -extern int histexp_flag; -#endif /* BANG_HISTORY */ - -#if defined (RESTRICTED_SHELL) -extern int restricted; -extern int restricted_shell; -#endif /* RESTRICTED_SHELL */ - -extern int *find_flag PARAMS((int)); -extern int change_flag PARAMS((int, int)); -extern char *which_set_flags PARAMS((void)); -extern void reset_shell_flags PARAMS((void)); - -extern char *get_current_flags PARAMS((void)); -extern void set_current_flags PARAMS((const char *)); - -extern void initialize_flags PARAMS((void)); - -/* A macro for efficiency. */ -#define change_flag_char(flag, on_or_off) change_flag (flag, on_or_off) - -#endif /* _FLAGS_H_ */ diff --git a/third_party/bash/fmtullong.c b/third_party/bash/fmtullong.c deleted file mode 100644 index 7f385bd45..000000000 --- a/third_party/bash/fmtullong.c +++ /dev/null @@ -1,31 +0,0 @@ -/* fmtullong.c - convert `long long int' to string */ - -/* Copyright (C) 2001-2002 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#ifdef HAVE_LONG_LONG_INT - -#define LONG long long -#define UNSIGNED_LONG unsigned long long -#define fmtulong fmtullong - -#include "fmtulong.c" - -#endif diff --git a/third_party/bash/fmtulong.c b/third_party/bash/fmtulong.c deleted file mode 100644 index d3c7167f8..000000000 --- a/third_party/bash/fmtulong.c +++ /dev/null @@ -1,191 +0,0 @@ -/* fmtulong.c -- Convert unsigned long int to string. */ - -/* Copyright (C) 1998-2011 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#if defined (HAVE_LIMITS_H) -# include -#endif - -#include "bashansi.h" -#ifdef HAVE_STDDEF_H -# include -#endif - -#ifdef HAVE_STDINT_H -# include -#endif -#ifdef HAVE_INTTYPES_H -# include -#endif -#include "chartypes.h" -#include - -#include "bashintl.h" - -#include "stdc.h" - -#include "typemax.h" - -#ifndef errno -extern int errno; -#endif - -#define x_digs "0123456789abcdef" -#define X_digs "0123456789ABCDEF" - -/* XXX -- assumes uppercase letters, lowercase letters, and digits are - contiguous */ -#define FMTCHAR(x) \ - ((x) < 10) ? (x) + '0' \ - : (((x) < 36) ? (x) - 10 + 'a' \ - : (((x) < 62) ? (x) - 36 + 'A' \ - : (((x) == 62) ? '@' : '_'))) - -#ifndef FL_PREFIX -# define FL_PREFIX 0x01 /* add 0x, 0X, or 0 prefix as appropriate */ -# define FL_ADDBASE 0x02 /* add base# prefix to converted value */ -# define FL_HEXUPPER 0x04 /* use uppercase when converting to hex */ -# define FL_UNSIGNED 0x08 /* don't add any sign */ -#endif - -#ifndef LONG -# define LONG long -# define UNSIGNED_LONG unsigned long -#endif - -/* `unsigned long' (or unsigned long long) to string conversion for a given - base. The caller passes the output buffer and the size. This should - check for buffer underflow, but currently does not. */ -char * -fmtulong (ui, base, buf, len, flags) - UNSIGNED_LONG ui; - int base; - char *buf; - size_t len; - int flags; -{ - char *p; - int sign; - LONG si; - - if (base == 0) - base = 10; - - if (base < 2 || base > 64) - { -#if 1 - /* XXX - truncation possible with long translation */ - strncpy (buf, _("invalid base"), len - 1); - buf[len-1] = '\0'; - errno = EINVAL; - return (p = buf); -#else - base = 10; -#endif - } - - sign = 0; - if ((flags & FL_UNSIGNED) == 0 && (LONG)ui < 0) - { - ui = -ui; - sign = '-'; - } - - p = buf + len - 2; - p[1] = '\0'; - - /* handle common cases explicitly */ - switch (base) - { - case 10: - if (ui < 10) - { - *p-- = TOCHAR (ui); - break; - } - /* Favor signed arithmetic over unsigned arithmetic; it is faster on - many machines. */ - if ((LONG)ui < 0) - { - *p-- = TOCHAR (ui % 10); - si = ui / 10; - } - else - si = ui; - do - *p-- = TOCHAR (si % 10); - while (si /= 10); - break; - - case 8: - do - *p-- = TOCHAR (ui & 7); - while (ui >>= 3); - break; - - case 16: - do - *p-- = (flags & FL_HEXUPPER) ? X_digs[ui & 15] : x_digs[ui & 15]; - while (ui >>= 4); - break; - - case 2: - do - *p-- = TOCHAR (ui & 1); - while (ui >>= 1); - break; - - default: - do - *p-- = FMTCHAR (ui % base); - while (ui /= base); - break; - } - - if ((flags & FL_PREFIX) && (base == 8 || base == 16)) - { - if (base == 16) - { - *p-- = (flags & FL_HEXUPPER) ? 'X' : 'x'; - *p-- = '0'; - } - else if (p[1] != '0') - *p-- = '0'; - } - else if ((flags & FL_ADDBASE) && base != 10) - { - *p-- = '#'; - *p-- = TOCHAR (base % 10); - if (base > 10) - *p-- = TOCHAR (base / 10); - } - - if (sign) - *p-- = '-'; - - return (p + 1); -} diff --git a/third_party/bash/fmtumax.c b/third_party/bash/fmtumax.c deleted file mode 100644 index 78a9aef4d..000000000 --- a/third_party/bash/fmtumax.c +++ /dev/null @@ -1,27 +0,0 @@ -/* fmtumax.c -- Convert uintmax_t to string. */ - -/* Copyright (C) 2002 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#define LONG intmax_t -#define UNSIGNED_LONG uintmax_t -#define fmtulong fmtumax - -#include "fmtulong.c" diff --git a/third_party/bash/fnxform.c b/third_party/bash/fnxform.c deleted file mode 100644 index 0a9f0247d..000000000 --- a/third_party/bash/fnxform.c +++ /dev/null @@ -1,199 +0,0 @@ -/* fnxform - use iconv(3) to transform strings to and from "filename" format */ - -/* Copyright (C) 2009-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" -#if defined (HAVE_UNISTD_H) -# include -#endif -#include "bashansi.h" -#include -#include "bashtypes.h" - -#include "stdc.h" -#include "bashintl.h" -#include "xmalloc.h" - -#if defined (HAVE_ICONV) -# include -#endif - -#if defined (HAVE_LOCALE_CHARSET) -extern const char *locale_charset PARAMS((void)); -#else -extern char *get_locale_var PARAMS((char *)); -#endif - -#if defined (HAVE_ICONV) -static iconv_t conv_fromfs = (iconv_t)-1; -static iconv_t conv_tofs = (iconv_t)-1; - -#define OUTLEN_MAX 4096 - -static char *outbuf = 0; -static size_t outlen = 0; - -static char *curencoding PARAMS((void)); -static void init_tofs PARAMS((void)); -static void init_fromfs PARAMS((void)); - -static char * -curencoding () -{ - char *loc; -#if defined (HAVE_LOCALE_CHARSET) - loc = (char *)locale_charset (); - return loc; -#else - char *dot, *mod; - - loc = get_locale_var ("LC_CTYPE"); - if (loc == 0 || *loc == 0) - return ""; - dot = strchr (loc, '.'); - if (dot == 0) - return loc; - mod = strchr (dot, '@'); - if (mod) - *mod = '\0'; - return ++dot; -#endif -} - -static void -init_tofs () -{ - char *cur; - - cur = curencoding (); - conv_tofs = iconv_open ("UTF-8-MAC", cur); -} - -static void -init_fromfs () -{ - char *cur; - - cur = curencoding (); - conv_fromfs = iconv_open (cur, "UTF-8-MAC"); -} - -char * -fnx_tofs (string, len) - char *string; - size_t len; -{ -#ifdef MACOSX - ICONV_CONST char *inbuf; - char *tempbuf; - size_t templen; - - if (conv_tofs == (iconv_t)-1) - init_tofs (); - if (conv_tofs == (iconv_t)-1) - return string; - - /* Free and reallocate outbuf if it's *too* big */ - if (outlen >= OUTLEN_MAX && len < OUTLEN_MAX - 8) - { - free (outbuf); - outbuf = 0; - outlen = 0; - } - - inbuf = string; - if (outbuf == 0 || outlen < len + 8) - { - outlen = len + 8; - outbuf = outbuf ? xrealloc (outbuf, outlen + 1) : xmalloc (outlen + 1); - } - tempbuf = outbuf; - templen = outlen; - - iconv (conv_tofs, NULL, NULL, NULL, NULL); - - if (iconv (conv_tofs, &inbuf, &len, &tempbuf, &templen) == (size_t)-1) - return string; - - *tempbuf = '\0'; - return outbuf; -#else - return string; -#endif -} - -char * -fnx_fromfs (string, len) - char *string; - size_t len; -{ -#ifdef MACOSX - ICONV_CONST char *inbuf; - char *tempbuf; - size_t templen; - - if (conv_fromfs == (iconv_t)-1) - init_fromfs (); - if (conv_fromfs == (iconv_t)-1) - return string; - - /* Free and reallocate outbuf if it's *too* big */ - if (outlen >= OUTLEN_MAX && len < OUTLEN_MAX - 8) - { - free (outbuf); - outbuf = 0; - outlen = 0; - } - - inbuf = string; - if (outbuf == 0 || outlen < (len + 8)) - { - outlen = len + 8; - outbuf = outbuf ? xrealloc (outbuf, outlen + 1) : xmalloc (outlen + 1); - } - tempbuf = outbuf; - templen = outlen; - - iconv (conv_fromfs, NULL, NULL, NULL, NULL); - - if (iconv (conv_fromfs, &inbuf, &len, &tempbuf, &templen) == (size_t)-1) - return string; - - *tempbuf = '\0'; - return outbuf; -#else - return string; -#endif -} - -#else -char * -fnx_tofs (string) - char *string; -{ - return string; -} - -char * -fnx_fromfs (string) - char *string; -{ - return string; -} -#endif diff --git a/third_party/bash/fpurge.c b/third_party/bash/fpurge.c deleted file mode 100644 index 37a5c0d34..000000000 --- a/third_party/bash/fpurge.c +++ /dev/null @@ -1,232 +0,0 @@ -/* fpurge - Flushing buffers of a FILE stream. */ - -/* Copyright (C) 2007-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include "stdc.h" - -#include - -/* Specification. Same as in ../../externs.h. */ -#define NEED_FPURGE_DECL -#if HAVE_FPURGE -# define fpurge _bash_fpurge -#endif -extern int fpurge PARAMS((FILE *stream)); - -#if HAVE___FPURGE /* glibc >= 2.2, Haiku, Solaris >= 7 */ -# include -#endif -#include - -/* Inline contents of gnulib:stdio-impl.h */ - -/* Many stdio implementations have the same logic and therefore can share - the same implementation of stdio extension API, except that some fields - have different naming conventions, or their access requires some casts. */ - -/* BSD stdio derived implementations. */ - -#if defined __NetBSD__ /* NetBSD */ -/* Get __NetBSD_Version__. */ -# include -#endif - -#if defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */ - -# if defined __DragonFly__ /* DragonFly */ - /* See . */ -# define fp_ ((struct { struct __FILE_public pub; \ - struct { unsigned char *_base; int _size; } _bf; \ - void *cookie; \ - void *_close; \ - void *_read; \ - void *_seek; \ - void *_write; \ - struct { unsigned char *_base; int _size; } _ub; \ - int _ur; \ - unsigned char _ubuf[3]; \ - unsigned char _nbuf[1]; \ - struct { unsigned char *_base; int _size; } _lb; \ - int _blksize; \ - fpos_t _offset; \ - /* More fields, not relevant here. */ \ - } *) fp) - /* See . */ -# define _p pub._p -# define _flags pub._flags -# define _r pub._r -# define _w pub._w -# else -# define fp_ fp -# endif - -# if (defined __NetBSD__ && __NetBSD_Version__ >= 105270000) || defined __OpenBSD__ /* NetBSD >= 1.5ZA, OpenBSD */ - /* See - and */ - struct __sfileext - { - struct __sbuf _ub; /* ungetc buffer */ - /* More fields, not relevant here. */ - }; -# define fp_ub ((struct __sfileext *) fp->_ext._base)->_ub -# else /* FreeBSD, NetBSD <= 1.5Z, DragonFly, MacOS X, Cygwin */ -# define fp_ub fp_->_ub -# endif - -# define HASUB(fp) (fp_ub._base != NULL) - -#endif - -/* SystemV derived implementations. */ - -#if defined _IOERR - -# if defined __sun && defined _LP64 /* Solaris/{SPARC,AMD64} 64-bit */ -# define fp_ ((struct { unsigned char *_ptr; \ - unsigned char *_base; \ - unsigned char *_end; \ - long _cnt; \ - int _file; \ - unsigned int _flag; \ - } *) fp) -# else -# define fp_ fp -# endif - -# if defined _SCO_DS /* OpenServer */ -# define _cnt __cnt -# define _ptr __ptr -# define _base __base -# define _flag __flag -# endif - -#endif - -int -fpurge (FILE *fp) -{ -#if HAVE___FPURGE /* glibc >= 2.2, Haiku, Solaris >= 7 */ - - __fpurge (fp); - /* The __fpurge function does not have a return value. */ - return 0; - -#elif HAVE_FPURGE /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin 1.7 */ - - /* Call the system's fpurge function. */ -# undef fpurge -# if !HAVE_DECL_FPURGE - extern int fpurge (FILE *); -# endif - int result = fpurge (fp); -# if defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */ - if (result == 0) - /* Correct the invariants that fpurge broke. - on BSD systems says: - "The following always hold: if _flags & __SRD, _w is 0." - If this invariant is not fulfilled and the stream is read-write but - currently reading, subsequent putc or fputc calls will write directly - into the buffer, although they shouldn't be allowed to. */ - if ((fp_->_flags & __SRD) != 0) - fp_->_w = 0; -# endif - return result; - -#else - - /* Most systems provide FILE as a struct and the necessary bitmask in - , because they need it for implementing getc() and putc() as - fast macros. */ -# if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */ - fp->_IO_read_end = fp->_IO_read_ptr; - fp->_IO_write_ptr = fp->_IO_write_base; - /* Avoid memory leak when there is an active ungetc buffer. */ - if (fp->_IO_save_base != NULL) - { - free (fp->_IO_save_base); - fp->_IO_save_base = NULL; - } - return 0; -# elif defined __sferror || defined __DragonFly__ /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin */ - fp_->_p = fp_->_bf._base; - fp_->_r = 0; - fp_->_w = ((fp_->_flags & (__SLBF | __SNBF | __SRD)) == 0 /* fully buffered and not currently reading? */ - ? fp_->_bf._size - : 0); - /* Avoid memory leak when there is an active ungetc buffer. */ - if (fp_ub._base != NULL) - { - if (fp_ub._base != fp_->_ubuf) - free (fp_ub._base); - fp_ub._base = NULL; - } - return 0; -# elif defined __EMX__ /* emx+gcc */ - fp->_ptr = fp->_buffer; - fp->_rcount = 0; - fp->_wcount = 0; - fp->_ungetc_count = 0; - return 0; -# elif defined _IOERR || defined __TANDEM /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw */ - fp->_ptr = fp->_base; - if (fp->_ptr != NULL) - fp->_cnt = 0; - return 0; -# elif defined __UCLIBC__ /* uClibc */ -# ifdef __STDIO_BUFFERS - if (fp->__modeflags & __FLAG_WRITING) - fp->__bufpos = fp->__bufstart; - else if (fp->__modeflags & (__FLAG_READONLY | __FLAG_READING)) - fp->__bufpos = fp->__bufread; -# endif - return 0; -# elif defined __QNX__ /* QNX */ - fp->_Rback = fp->_Back + sizeof (fp->_Back); - fp->_Rsave = NULL; - if (fp->_Mode & 0x2000 /* _MWRITE */) - /* fp->_Buf <= fp->_Next <= fp->_Wend */ - fp->_Next = fp->_Buf; - else - /* fp->_Buf <= fp->_Next <= fp->_Rend */ - fp->_Rend = fp->_Next; - return 0; -# elif defined __MINT__ /* Atari FreeMiNT */ - if (fp->__pushed_back) - { - fp->__bufp = fp->__pushback_bufp; - fp->__pushed_back = 0; - } - /* Preserve the current file position. */ - if (fp->__target != -1) - fp->__target += fp->__bufp - fp->__buffer; - fp->__bufp = fp->__buffer; - /* Nothing in the buffer, next getc is nontrivial. */ - fp->__get_limit = fp->__bufp; - /* Nothing in the buffer, next putc is nontrivial. */ - fp->__put_limit = fp->__buffer; - return 0; -# else -# warning "Please port gnulib fpurge.c to your platform! Look at the definitions of fflush, setvbuf and ungetc on your system, then report this to bug-gnulib." - return 0; -# endif - -#endif -} diff --git a/third_party/bash/general.c b/third_party/bash/general.c deleted file mode 100644 index b9e43aa4c..000000000 --- a/third_party/bash/general.c +++ /dev/null @@ -1,1450 +0,0 @@ -/* general.c -- Stuff that is used by all files. */ - -/* Copyright (C) 1987-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include "bashtypes.h" -#if defined (HAVE_SYS_PARAM_H) -# include -#endif -#include "posixstat.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "filecntl.h" -#include "bashansi.h" -#include -#include "chartypes.h" -#include - -#include "bashintl.h" - -#include "shell.h" -#include "parser.h" -#include "flags.h" -#include "findcmd.h" -#include "test.h" -#include "trap.h" -#include "pathexp.h" - -#include "common.h" - -#if defined (HAVE_MBSTR_H) && defined (HAVE_MBSCHR) -# include /* mbschr */ -#endif - -#include "tilde.h" - -#if !defined (errno) -extern int errno; -#endif /* !errno */ - -#ifdef __CYGWIN__ -# include -#endif - -static char *bash_special_tilde_expansions PARAMS((char *)); -static int unquoted_tilde_word PARAMS((const char *)); -static void initialize_group_array PARAMS((void)); - -/* A standard error message to use when getcwd() returns NULL. */ -const char * const bash_getcwd_errstr = N_("getcwd: cannot access parent directories"); - -/* Do whatever is necessary to initialize `Posix mode'. This currently - modifies the following variables which are controlled via shopt: - interactive_comments - source_uses_path - expand_aliases - inherit_errexit - print_shift_error - posixglob - - and the following variables which cannot be user-modified: - - source_searches_cwd - - If we add to the first list, we need to change the table and functions - below */ - -static struct { - int *posix_mode_var; -} posix_vars[] = -{ - &interactive_comments, - &source_uses_path, - &expand_aliases, - &inherit_errexit, - &print_shift_error, - 0 -}; - -static char *saved_posix_vars = 0; - -void -posix_initialize (on) - int on; -{ - /* Things that should be turned on when posix mode is enabled. */ - if (on != 0) - { - interactive_comments = source_uses_path = expand_aliases = 1; - inherit_errexit = 1; - source_searches_cwd = 0; - print_shift_error = 1; - } - - /* Things that should be turned on when posix mode is disabled. */ - else if (saved_posix_vars) /* on == 0, restore saved settings */ - { - set_posix_options (saved_posix_vars); - free (saved_posix_vars); - saved_posix_vars = 0; - } - else /* on == 0, restore a default set of settings */ - { - source_searches_cwd = 1; - expand_aliases = interactive_shell; - print_shift_error = 0; - } -} - -int -num_posix_options () -{ - return ((sizeof (posix_vars) / sizeof (posix_vars[0])) - 1); -} - -char * -get_posix_options (bitmap) - char *bitmap; -{ - register int i; - - if (bitmap == 0) - bitmap = (char *)xmalloc (num_posix_options ()); /* no trailing NULL */ - for (i = 0; posix_vars[i].posix_mode_var; i++) - bitmap[i] = *(posix_vars[i].posix_mode_var); - return bitmap; -} - -#undef save_posix_options -void -save_posix_options () -{ - saved_posix_vars = get_posix_options (saved_posix_vars); -} - -void -set_posix_options (bitmap) - const char *bitmap; -{ - register int i; - - for (i = 0; posix_vars[i].posix_mode_var; i++) - *(posix_vars[i].posix_mode_var) = bitmap[i]; -} - -/* **************************************************************** */ -/* */ -/* Functions to convert to and from and display non-standard types */ -/* */ -/* **************************************************************** */ - -#if defined (RLIMTYPE) -RLIMTYPE -string_to_rlimtype (s) - char *s; -{ - RLIMTYPE ret; - int neg; - - ret = 0; - neg = 0; - while (s && *s && whitespace (*s)) - s++; - if (s && (*s == '-' || *s == '+')) - { - neg = *s == '-'; - s++; - } - for ( ; s && *s && DIGIT (*s); s++) - ret = (ret * 10) + TODIGIT (*s); - return (neg ? -ret : ret); -} - -void -print_rlimtype (n, addnl) - RLIMTYPE n; - int addnl; -{ - char s[INT_STRLEN_BOUND (RLIMTYPE) + 1], *p; - - p = s + sizeof(s); - *--p = '\0'; - - if (n < 0) - { - do - *--p = '0' - n % 10; - while ((n /= 10) != 0); - - *--p = '-'; - } - else - { - do - *--p = '0' + n % 10; - while ((n /= 10) != 0); - } - - printf ("%s%s", p, addnl ? "\n" : ""); -} -#endif /* RLIMTYPE */ - -/* **************************************************************** */ -/* */ -/* Input Validation Functions */ -/* */ -/* **************************************************************** */ - -/* Return non-zero if all of the characters in STRING are digits. */ -int -all_digits (string) - const char *string; -{ - register const char *s; - - for (s = string; *s; s++) - if (DIGIT (*s) == 0) - return (0); - - return (1); -} - -/* Return non-zero if the characters pointed to by STRING constitute a - valid number. Stuff the converted number into RESULT if RESULT is - not null. */ -int -legal_number (string, result) - const char *string; - intmax_t *result; -{ - intmax_t value; - char *ep; - - if (result) - *result = 0; - - if (string == 0) - return 0; - - errno = 0; - value = strtoimax (string, &ep, 10); - if (errno || ep == string) - return 0; /* errno is set on overflow or underflow */ - - /* Skip any trailing whitespace, since strtoimax does not. */ - while (whitespace (*ep)) - ep++; - - /* If *string is not '\0' but *ep is '\0' on return, the entire string - is valid. */ - if (*string && *ep == '\0') - { - if (result) - *result = value; - /* The SunOS4 implementation of strtol() will happily ignore - overflow conditions, so this cannot do overflow correctly - on those systems. */ - return 1; - } - - return (0); -} - -/* Return 1 if this token is a legal shell `identifier'; that is, it consists - solely of letters, digits, and underscores, and does not begin with a - digit. */ -int -legal_identifier (name) - const char *name; -{ - register const char *s; - unsigned char c; - - if (!name || !(c = *name) || (legal_variable_starter (c) == 0)) - return (0); - - for (s = name + 1; (c = *s) != 0; s++) - { - if (legal_variable_char (c) == 0) - return (0); - } - return (1); -} - -/* Return 1 if NAME is a valid value that can be assigned to a nameref - variable. FLAGS can be 2, in which case the name is going to be used - to create a variable. Other values are currently unused, but could - be used to allow values to be stored and indirectly referenced, but - not used in assignments. */ -int -valid_nameref_value (name, flags) - const char *name; - int flags; -{ - if (name == 0 || *name == 0) - return 0; - - /* valid identifier */ -#if defined (ARRAY_VARS) - if (legal_identifier (name) || (flags != 2 && valid_array_reference (name, 0))) -#else - if (legal_identifier (name)) -#endif - return 1; - - return 0; -} - -int -check_selfref (name, value, flags) - const char *name; - char *value; - int flags; -{ - char *t; - - if (STREQ (name, value)) - return 1; - -#if defined (ARRAY_VARS) - if (valid_array_reference (value, 0)) - { - t = array_variable_name (value, 0, (char **)NULL, (int *)NULL); - if (t && STREQ (name, t)) - { - free (t); - return 1; - } - free (t); - } -#endif - - return 0; /* not a self reference */ -} - -/* Make sure that WORD is a valid shell identifier, i.e. - does not contain a dollar sign, nor is quoted in any way. - If CHECK_WORD is non-zero, - the word is checked to ensure that it consists of only letters, - digits, and underscores, and does not consist of all digits. */ -int -check_identifier (word, check_word) - WORD_DESC *word; - int check_word; -{ - if (word->flags & (W_HASDOLLAR|W_QUOTED)) /* XXX - HASDOLLAR? */ - { - internal_error (_("`%s': not a valid identifier"), word->word); - return (0); - } - else if (check_word && (all_digits (word->word) || legal_identifier (word->word) == 0)) - { - internal_error (_("`%s': not a valid identifier"), word->word); - return (0); - } - else - return (1); -} - -/* Return 1 if STRING is a function name that the shell will import from - the environment. Currently we reject attempts to import shell functions - containing slashes, beginning with newlines or containing blanks. In - Posix mode, we require that STRING be a valid shell identifier. Not - used yet. */ -int -importable_function_name (string, len) - const char *string; - size_t len; -{ - if (absolute_program (string)) /* don't allow slash */ - return 0; - if (*string == '\n') /* can't start with a newline */ - return 0; - if (shellblank (*string) || shellblank(string[len-1])) - return 0; - return (posixly_correct ? legal_identifier (string) : 1); -} - -int -exportable_function_name (string) - const char *string; -{ - if (absolute_program (string)) - return 0; - if (mbschr (string, '=') != 0) - return 0; - return 1; -} - -/* Return 1 if STRING comprises a valid alias name. The shell accepts - essentially all characters except those which must be quoted to the - parser (which disqualifies them from alias expansion anyway) and `/'. */ -int -legal_alias_name (string, flags) - const char *string; - int flags; -{ - register const char *s; - - for (s = string; *s; s++) - if (shellbreak (*s) || shellxquote (*s) || shellexp (*s) || (*s == '/')) - return 0; - return 1; -} - -/* Returns non-zero if STRING is an assignment statement. The returned value - is the index of the `=' sign. If FLAGS&1 we are expecting a compound assignment - and require an array subscript before the `=' to denote an assignment - statement. */ -int -assignment (string, flags) - const char *string; - int flags; -{ - register unsigned char c; - register int newi, indx; - - c = string[indx = 0]; - -#if defined (ARRAY_VARS) - /* If parser_state includes PST_COMPASSIGN, FLAGS will include 1, so we are - parsing the contents of a compound assignment. If parser_state includes - PST_REPARSE, we are in the middle of an assignment statement and breaking - the words between the parens into words and assignment statements, but - we don't need to check for that right now. Within a compound assignment, - the subscript is required to make the word an assignment statement. If - we don't have a subscript, even if the word is a valid assignment - statement otherwise, we don't want to treat it as one. */ - if ((flags & 1) && c != '[') /* ] */ - return (0); - else if ((flags & 1) == 0 && legal_variable_starter (c) == 0) -#else - if (legal_variable_starter (c) == 0) -#endif - return (0); - - while (c = string[indx]) - { - /* The following is safe. Note that '=' at the start of a word - is not an assignment statement. */ - if (c == '=') - return (indx); - -#if defined (ARRAY_VARS) - if (c == '[') - { - newi = skipsubscript (string, indx, (flags & 2) ? 1 : 0); - /* XXX - why not check for blank subscripts here, if we do in - valid_array_reference? */ - if (string[newi++] != ']') - return (0); - if (string[newi] == '+' && string[newi+1] == '=') - return (newi + 1); - return ((string[newi] == '=') ? newi : 0); - } -#endif /* ARRAY_VARS */ - - /* Check for `+=' */ - if (c == '+' && string[indx+1] == '=') - return (indx + 1); - - /* Variable names in assignment statements may contain only letters, - digits, and `_'. */ - if (legal_variable_char (c) == 0) - return (0); - - indx++; - } - return (0); -} - -int -line_isblank (line) - const char *line; -{ - register int i; - - if (line == 0) - return 0; /* XXX */ - for (i = 0; line[i]; i++) - if (isblank ((unsigned char)line[i]) == 0) - break; - return (line[i] == '\0'); -} - -/* **************************************************************** */ -/* */ -/* Functions to manage files and file descriptors */ -/* */ -/* **************************************************************** */ - -/* A function to unset no-delay mode on a file descriptor. Used in shell.c - to unset it on the fd passed as stdin. Should be called on stdin if - readline gets an EAGAIN or EWOULDBLOCK when trying to read input. */ - -#if !defined (O_NDELAY) -# if defined (FNDELAY) -# define O_NDELAY FNDELAY -# endif -#endif /* O_NDELAY */ - -/* Make sure no-delay mode is not set on file descriptor FD. */ -int -sh_unset_nodelay_mode (fd) - int fd; -{ - int flags, bflags; - - if ((flags = fcntl (fd, F_GETFL, 0)) < 0) - return -1; - - bflags = 0; - - /* This is defined to O_NDELAY in filecntl.h if O_NONBLOCK is not present - and O_NDELAY is defined. */ -#ifdef O_NONBLOCK - bflags |= O_NONBLOCK; -#endif - -#ifdef O_NDELAY - bflags |= O_NDELAY; -#endif - - if (flags & bflags) - { - flags &= ~bflags; - return (fcntl (fd, F_SETFL, flags)); - } - - return 0; -} - -/* Just a wrapper for the define in include/filecntl.h */ -int -sh_setclexec (fd) - int fd; -{ - return (SET_CLOSE_ON_EXEC (fd)); -} - -/* Return 1 if file descriptor FD is valid; 0 otherwise. */ -int -sh_validfd (fd) - int fd; -{ - return (fcntl (fd, F_GETFD, 0) >= 0); -} - -int -fd_ispipe (fd) - int fd; -{ - errno = 0; - return ((lseek (fd, 0L, SEEK_CUR) < 0) && (errno == ESPIPE)); -} - -/* There is a bug in the NeXT 2.1 rlogind that causes opens - of /dev/tty to fail. */ - -#if defined (__BEOS__) -/* On BeOS, opening in non-blocking mode exposes a bug in BeOS, so turn it - into a no-op. This should probably go away in the future. */ -# undef O_NONBLOCK -# define O_NONBLOCK 0 -#endif /* __BEOS__ */ - -void -check_dev_tty () -{ - int tty_fd; - char *tty; - - tty_fd = open ("/dev/tty", O_RDWR|O_NONBLOCK); - - if (tty_fd < 0) - { - tty = (char *)ttyname (fileno (stdin)); - if (tty == 0) - return; - tty_fd = open (tty, O_RDWR|O_NONBLOCK); - } - if (tty_fd >= 0) - close (tty_fd); -} - -/* Return 1 if PATH1 and PATH2 are the same file. This is kind of - expensive. If non-NULL STP1 and STP2 point to stat structures - corresponding to PATH1 and PATH2, respectively. */ -int -same_file (path1, path2, stp1, stp2) - const char *path1, *path2; - struct stat *stp1, *stp2; -{ - struct stat st1, st2; - - if (stp1 == NULL) - { - if (stat (path1, &st1) != 0) - return (0); - stp1 = &st1; - } - - if (stp2 == NULL) - { - if (stat (path2, &st2) != 0) - return (0); - stp2 = &st2; - } - - return ((stp1->st_dev == stp2->st_dev) && (stp1->st_ino == stp2->st_ino)); -} - -/* Move FD to a number close to the maximum number of file descriptors - allowed in the shell process, to avoid the user stepping on it with - redirection and causing us extra work. If CHECK_NEW is non-zero, - we check whether or not the file descriptors are in use before - duplicating FD onto them. MAXFD says where to start checking the - file descriptors. If it's less than 20, we get the maximum value - available from getdtablesize(2). */ -int -move_to_high_fd (fd, check_new, maxfd) - int fd, check_new, maxfd; -{ - int script_fd, nfds, ignore; - - if (maxfd < 20) - { - nfds = getdtablesize (); - if (nfds <= 0) - nfds = 20; - if (nfds > HIGH_FD_MAX) - nfds = HIGH_FD_MAX; /* reasonable maximum */ - } - else - nfds = maxfd; - - for (nfds--; check_new && nfds > 3; nfds--) - if (fcntl (nfds, F_GETFD, &ignore) == -1) - break; - - if (nfds > 3 && fd != nfds && (script_fd = dup2 (fd, nfds)) != -1) - { - if (check_new == 0 || fd != fileno (stderr)) /* don't close stderr */ - close (fd); - return (script_fd); - } - - /* OK, we didn't find one less than our artificial maximum; return the - original file descriptor. */ - return (fd); -} - -/* Return non-zero if the characters from SAMPLE are not all valid - characters to be found in the first line of a shell script. We - check up to the first newline, or SAMPLE_LEN, whichever comes first. - All of the characters must be printable or whitespace. */ - -int -check_binary_file (sample, sample_len) - const char *sample; - int sample_len; -{ - register int i; - unsigned char c; - - if (sample_len >= 4 && sample[0] == 0x7f && sample[1] == 'E' && sample[2] == 'L' && sample[3] == 'F') - return 1; - - /* Generally we check the first line for NULs. If the first line looks like - a `#!' interpreter specifier, we just look for NULs anywhere in the - buffer. */ - if (sample[0] == '#' && sample[1] == '!') - return (memchr (sample, '\0', sample_len) != NULL); - - for (i = 0; i < sample_len; i++) - { - c = sample[i]; - if (c == '\n') - return (0); - if (c == '\0') - return (1); - } - - return (0); -} - -/* **************************************************************** */ -/* */ -/* Functions to manipulate pipes */ -/* */ -/* **************************************************************** */ - -int -sh_openpipe (pv) - int *pv; -{ - int r; - - if ((r = pipe (pv)) < 0) - return r; - - pv[0] = move_to_high_fd (pv[0], 1, 64); - pv[1] = move_to_high_fd (pv[1], 1, 64); - - return 0; -} - -int -sh_closepipe (pv) - int *pv; -{ - if (pv[0] >= 0) - close (pv[0]); - - if (pv[1] >= 0) - close (pv[1]); - - pv[0] = pv[1] = -1; - return 0; -} - -/* **************************************************************** */ -/* */ -/* Functions to inspect pathnames */ -/* */ -/* **************************************************************** */ - -int -file_exists (fn) - const char *fn; -{ - struct stat sb; - - return (stat (fn, &sb) == 0); -} - -int -file_isdir (fn) - const char *fn; -{ - struct stat sb; - - return ((stat (fn, &sb) == 0) && S_ISDIR (sb.st_mode)); -} - -int -file_iswdir (fn) - const char *fn; -{ - return (file_isdir (fn) && sh_eaccess (fn, W_OK) == 0); -} - -/* Return 1 if STRING is "." or "..", optionally followed by a directory - separator */ -int -path_dot_or_dotdot (string) - const char *string; -{ - if (string == 0 || *string == '\0' || *string != '.') - return (0); - - /* string[0] == '.' */ - if (PATHSEP(string[1]) || (string[1] == '.' && PATHSEP(string[2]))) - return (1); - - return (0); -} - -/* Return 1 if STRING contains an absolute pathname, else 0. Used by `cd' - to decide whether or not to look up a directory name in $CDPATH. */ -int -absolute_pathname (string) - const char *string; -{ - if (string == 0 || *string == '\0') - return (0); - - if (ABSPATH(string)) - return (1); - - if (string[0] == '.' && PATHSEP(string[1])) /* . and ./ */ - return (1); - - if (string[0] == '.' && string[1] == '.' && PATHSEP(string[2])) /* .. and ../ */ - return (1); - - return (0); -} - -/* Return 1 if STRING is an absolute program name; it is absolute if it - contains any slashes. This is used to decide whether or not to look - up through $PATH. */ -int -absolute_program (string) - const char *string; -{ - return ((char *)mbschr (string, '/') != (char *)NULL); -} - -/* **************************************************************** */ -/* */ -/* Functions to manipulate pathnames */ -/* */ -/* **************************************************************** */ - -/* Turn STRING (a pathname) into an absolute pathname, assuming that - DOT_PATH contains the symbolic location of `.'. This always - returns a new string, even if STRING was an absolute pathname to - begin with. */ -char * -make_absolute (string, dot_path) - const char *string, *dot_path; -{ - char *result; - - if (dot_path == 0 || ABSPATH(string)) -#ifdef __CYGWIN__ - { - char pathbuf[PATH_MAX + 1]; - - /* WAS cygwin_conv_to_full_posix_path (string, pathbuf); */ - cygwin_conv_path (CCP_WIN_A_TO_POSIX, string, pathbuf, PATH_MAX); - result = savestring (pathbuf); - } -#else - result = savestring (string); -#endif - else - result = sh_makepath (dot_path, string, 0); - - return (result); -} - -/* Return the `basename' of the pathname in STRING (the stuff after the - last '/'). If STRING is `/', just return it. */ -char * -base_pathname (string) - char *string; -{ - char *p; - -#if 0 - if (absolute_pathname (string) == 0) - return (string); -#endif - - if (string[0] == '/' && string[1] == 0) - return (string); - - p = (char *)strrchr (string, '/'); - return (p ? ++p : string); -} - -/* Return the full pathname of FILE. Easy. Filenames that begin - with a '/' are returned as themselves. Other filenames have - the current working directory prepended. A new string is - returned in either case. */ -char * -full_pathname (file) - char *file; -{ - char *ret; - - file = (*file == '~') ? bash_tilde_expand (file, 0) : savestring (file); - - if (ABSPATH(file)) - return (file); - - ret = sh_makepath ((char *)NULL, file, (MP_DOCWD|MP_RMDOT)); - free (file); - - return (ret); -} - -/* A slightly related function. Get the prettiest name of this - directory possible. */ -static char tdir[PATH_MAX]; - -/* Return a pretty pathname. If the first part of the pathname is - the same as $HOME, then replace that with `~'. */ -char * -polite_directory_format (name) - char *name; -{ - char *home; - int l; - - home = get_string_value ("HOME"); - l = home ? strlen (home) : 0; - if (l > 1 && strncmp (home, name, l) == 0 && (!name[l] || name[l] == '/')) - { - strncpy (tdir + 1, name + l, sizeof(tdir) - 2); - tdir[0] = '~'; - tdir[sizeof(tdir) - 1] = '\0'; - return (tdir); - } - else - return (name); -} - -/* Trim NAME. If NAME begins with `~/', skip over tilde prefix. Trim to - keep any tilde prefix and PROMPT_DIRTRIM trailing directory components - and replace the intervening characters with `...' */ -char * -trim_pathname (name, maxlen) - char *name; - int maxlen; -{ - int nlen, ndirs; - intmax_t nskip; - char *nbeg, *nend, *ntail, *v; - - if (name == 0 || (nlen = strlen (name)) == 0) - return name; - nend = name + nlen; - - v = get_string_value ("PROMPT_DIRTRIM"); - if (v == 0 || *v == 0) - return name; - if (legal_number (v, &nskip) == 0 || nskip <= 0) - return name; - - /* Skip over tilde prefix */ - nbeg = name; - if (name[0] == '~') - for (nbeg = name; *nbeg; nbeg++) - if (*nbeg == '/') - { - nbeg++; - break; - } - if (*nbeg == 0) - return name; - - for (ndirs = 0, ntail = nbeg; *ntail; ntail++) - if (*ntail == '/') - ndirs++; - if (ndirs < nskip) - return name; - - for (ntail = (*nend == '/') ? nend : nend - 1; ntail > nbeg; ntail--) - { - if (*ntail == '/') - nskip--; - if (nskip == 0) - break; - } - if (ntail == nbeg) - return name; - - /* Now we want to return name[0..nbeg]+"..."+ntail, modifying name in place */ - nlen = ntail - nbeg; - if (nlen <= 3) - return name; - - *nbeg++ = '.'; - *nbeg++ = '.'; - *nbeg++ = '.'; - - nlen = nend - ntail; - memmove (nbeg, ntail, nlen); - nbeg[nlen] = '\0'; - - return name; -} - -/* Return a printable representation of FN without special characters. The - caller is responsible for freeing memory if this returns something other - than its argument. If FLAGS is non-zero, we are printing for portable - re-input and should single-quote filenames appropriately. */ -char * -printable_filename (fn, flags) - char *fn; - int flags; -{ - char *newf; - - if (ansic_shouldquote (fn)) - newf = ansic_quote (fn, 0, NULL); - else if (flags && sh_contains_shell_metas (fn)) - newf = sh_single_quote (fn); - else - newf = fn; - - return newf; -} - -/* Given a string containing units of information separated by colons, - return the next one pointed to by (P_INDEX), or NULL if there are no more. - Advance (P_INDEX) to the character after the colon. */ -char * -extract_colon_unit (string, p_index) - char *string; - int *p_index; -{ - int i, start, len; - char *value; - - if (string == 0) - return (string); - - len = strlen (string); - if (*p_index >= len) - return ((char *)NULL); - - i = *p_index; - - /* Each call to this routine leaves the index pointing at a colon if - there is more to the path. If I is > 0, then increment past the - `:'. If I is 0, then the path has a leading colon. Trailing colons - are handled OK by the `else' part of the if statement; an empty - string is returned in that case. */ - if (i && string[i] == ':') - i++; - - for (start = i; string[i] && string[i] != ':'; i++) - ; - - *p_index = i; - - if (i == start) - { - if (string[i]) - (*p_index)++; - /* Return "" in the case of a trailing `:'. */ - value = (char *)xmalloc (1); - value[0] = '\0'; - } - else - value = substring (string, start, i); - - return (value); -} - -/* **************************************************************** */ -/* */ -/* Tilde Initialization and Expansion */ -/* */ -/* **************************************************************** */ - -#if defined (PUSHD_AND_POPD) -extern char *get_dirstack_from_string PARAMS((char *)); -#endif - -static char **bash_tilde_prefixes; -static char **bash_tilde_prefixes2; -static char **bash_tilde_suffixes; -static char **bash_tilde_suffixes2; - -/* If tilde_expand hasn't been able to expand the text, perhaps it - is a special shell expansion. This function is installed as the - tilde_expansion_preexpansion_hook. It knows how to expand ~- and ~+. - If PUSHD_AND_POPD is defined, ~[+-]N expands to directories from the - directory stack. */ -static char * -bash_special_tilde_expansions (text) - char *text; -{ - char *result; - - result = (char *)NULL; - - if (text[0] == '+' && text[1] == '\0') - result = get_string_value ("PWD"); - else if (text[0] == '-' && text[1] == '\0') - result = get_string_value ("OLDPWD"); -#if defined (PUSHD_AND_POPD) - else if (DIGIT (*text) || ((*text == '+' || *text == '-') && DIGIT (text[1]))) - result = get_dirstack_from_string (text); -#endif - - return (result ? savestring (result) : (char *)NULL); -} - -/* Initialize the tilde expander. In Bash, we handle `~-' and `~+', as - well as handling special tilde prefixes; `:~" and `=~' are indications - that we should do tilde expansion. */ -void -tilde_initialize () -{ - static int times_called = 0; - - /* Tell the tilde expander that we want a crack first. */ - tilde_expansion_preexpansion_hook = bash_special_tilde_expansions; - - /* Tell the tilde expander about special strings which start a tilde - expansion, and the special strings that end one. Only do this once. - tilde_initialize () is called from within bashline_reinitialize (). */ - if (times_called++ == 0) - { - bash_tilde_prefixes = strvec_create (3); - bash_tilde_prefixes[0] = "=~"; - bash_tilde_prefixes[1] = ":~"; - bash_tilde_prefixes[2] = (char *)NULL; - - bash_tilde_prefixes2 = strvec_create (2); - bash_tilde_prefixes2[0] = ":~"; - bash_tilde_prefixes2[1] = (char *)NULL; - - tilde_additional_prefixes = bash_tilde_prefixes; - - bash_tilde_suffixes = strvec_create (3); - bash_tilde_suffixes[0] = ":"; - bash_tilde_suffixes[1] = "=~"; /* XXX - ?? */ - bash_tilde_suffixes[2] = (char *)NULL; - - tilde_additional_suffixes = bash_tilde_suffixes; - - bash_tilde_suffixes2 = strvec_create (2); - bash_tilde_suffixes2[0] = ":"; - bash_tilde_suffixes2[1] = (char *)NULL; - } -} - -/* POSIX.2, 3.6.1: A tilde-prefix consists of an unquoted tilde character - at the beginning of the word, followed by all of the characters preceding - the first unquoted slash in the word, or all the characters in the word - if there is no slash...If none of the characters in the tilde-prefix are - quoted, the characters in the tilde-prefix following the tilde shell be - treated as a possible login name. */ - -#define TILDE_END(c) ((c) == '\0' || (c) == '/' || (c) == ':') - -static int -unquoted_tilde_word (s) - const char *s; -{ - const char *r; - - for (r = s; TILDE_END(*r) == 0; r++) - { - switch (*r) - { - case '\\': - case '\'': - case '"': - return 0; - } - } - return 1; -} - -/* Find the end of the tilde-prefix starting at S, and return the tilde - prefix in newly-allocated memory. Return the length of the string in - *LENP. FLAGS tells whether or not we're in an assignment context -- - if so, `:' delimits the end of the tilde prefix as well. */ -char * -bash_tilde_find_word (s, flags, lenp) - const char *s; - int flags, *lenp; -{ - const char *r; - char *ret; - int l; - - for (r = s; *r && *r != '/'; r++) - { - /* Short-circuit immediately if we see a quote character. Even though - POSIX says that `the first unquoted slash' (or `:') terminates the - tilde-prefix, in practice, any quoted portion of the tilde prefix - will cause it to not be expanded. */ - if (*r == '\\' || *r == '\'' || *r == '"') - { - ret = savestring (s); - if (lenp) - *lenp = 0; - return ret; - } - else if (flags && *r == ':') - break; - } - l = r - s; - ret = xmalloc (l + 1); - strncpy (ret, s, l); - ret[l] = '\0'; - if (lenp) - *lenp = l; - return ret; -} - -/* Tilde-expand S by running it through the tilde expansion library. - ASSIGN_P is 1 if this is a variable assignment, so the alternate - tilde prefixes should be enabled (`=~' and `:~', see above). If - ASSIGN_P is 2, we are expanding the rhs of an assignment statement, - so `=~' is not valid. */ -char * -bash_tilde_expand (s, assign_p) - const char *s; - int assign_p; -{ - int r; - char *ret; - - tilde_additional_prefixes = assign_p == 0 ? (char **)0 - : (assign_p == 2 ? bash_tilde_prefixes2 : bash_tilde_prefixes); - if (assign_p == 2) - tilde_additional_suffixes = bash_tilde_suffixes2; - - r = (*s == '~') ? unquoted_tilde_word (s) : 1; - ret = r ? tilde_expand (s) : savestring (s); - - QUIT; - - return (ret); -} - -/* **************************************************************** */ -/* */ -/* Functions to manipulate and search the group list */ -/* */ -/* **************************************************************** */ - -static int ngroups, maxgroups; - -/* The set of groups that this user is a member of. */ -static GETGROUPS_T *group_array = (GETGROUPS_T *)NULL; - -#if !defined (NOGROUP) -# define NOGROUP (gid_t) -1 -#endif - -static void -initialize_group_array () -{ - register int i; - - if (maxgroups == 0) - maxgroups = getmaxgroups (); - - ngroups = 0; - group_array = (GETGROUPS_T *)xrealloc (group_array, maxgroups * sizeof (GETGROUPS_T)); - -#if defined (HAVE_GETGROUPS) - ngroups = getgroups (maxgroups, group_array); -#endif - - /* If getgroups returns nothing, or the OS does not support getgroups(), - make sure the groups array includes at least the current gid. */ - if (ngroups == 0) - { - group_array[0] = current_user.gid; - ngroups = 1; - } - - /* If the primary group is not in the groups array, add it as group_array[0] - and shuffle everything else up 1, if there's room. */ - for (i = 0; i < ngroups; i++) - if (current_user.gid == (gid_t)group_array[i]) - break; - if (i == ngroups && ngroups < maxgroups) - { - for (i = ngroups; i > 0; i--) - group_array[i] = group_array[i - 1]; - group_array[0] = current_user.gid; - ngroups++; - } - - /* If the primary group is not group_array[0], swap group_array[0] and - whatever the current group is. The vast majority of systems should - not need this; a notable exception is Linux. */ - if (group_array[0] != current_user.gid) - { - for (i = 0; i < ngroups; i++) - if (group_array[i] == current_user.gid) - break; - if (i < ngroups) - { - group_array[i] = group_array[0]; - group_array[0] = current_user.gid; - } - } -} - -/* Return non-zero if GID is one that we have in our groups list. */ -int -#if defined (__STDC__) || defined ( _MINIX) -group_member (gid_t gid) -#else -group_member (gid) - gid_t gid; -#endif /* !__STDC__ && !_MINIX */ -{ -#if defined (HAVE_GETGROUPS) - register int i; -#endif - - /* Short-circuit if possible, maybe saving a call to getgroups(). */ - if (gid == current_user.gid || gid == current_user.egid) - return (1); - -#if defined (HAVE_GETGROUPS) - if (ngroups == 0) - initialize_group_array (); - - /* In case of error, the user loses. */ - if (ngroups <= 0) - return (0); - - /* Search through the list looking for GID. */ - for (i = 0; i < ngroups; i++) - if (gid == (gid_t)group_array[i]) - return (1); -#endif - - return (0); -} - -char ** -get_group_list (ngp) - int *ngp; -{ - static char **group_vector = (char **)NULL; - register int i; - - if (group_vector) - { - if (ngp) - *ngp = ngroups; - return group_vector; - } - - if (ngroups == 0) - initialize_group_array (); - - if (ngroups <= 0) - { - if (ngp) - *ngp = 0; - return (char **)NULL; - } - - group_vector = strvec_create (ngroups); - for (i = 0; i < ngroups; i++) - group_vector[i] = itos (group_array[i]); - - if (ngp) - *ngp = ngroups; - return group_vector; -} - -int * -get_group_array (ngp) - int *ngp; -{ - int i; - static int *group_iarray = (int *)NULL; - - if (group_iarray) - { - if (ngp) - *ngp = ngroups; - return (group_iarray); - } - - if (ngroups == 0) - initialize_group_array (); - - if (ngroups <= 0) - { - if (ngp) - *ngp = 0; - return (int *)NULL; - } - - group_iarray = (int *)xmalloc (ngroups * sizeof (int)); - for (i = 0; i < ngroups; i++) - group_iarray[i] = (int)group_array[i]; - - if (ngp) - *ngp = ngroups; - return group_iarray; -} - -/* **************************************************************** */ -/* */ -/* Miscellaneous functions */ -/* */ -/* **************************************************************** */ - -/* Return a value for PATH that is guaranteed to find all of the standard - utilities. This uses Posix.2 configuration variables, if present. It - uses a value defined in config.h as a last resort. */ -char * -conf_standard_path () -{ -#if defined (_CS_PATH) && defined (HAVE_CONFSTR) - char *p; - size_t len; - - len = (size_t)confstr (_CS_PATH, (char *)NULL, (size_t)0); - if (len > 0) - { - p = (char *)xmalloc (len + 2); - *p = '\0'; - confstr (_CS_PATH, p, len); - return (p); - } - else - return (savestring (STANDARD_UTILS_PATH)); -#else /* !_CS_PATH || !HAVE_CONFSTR */ -# if defined (CS_PATH) - return (savestring (CS_PATH)); -# else - return (savestring (STANDARD_UTILS_PATH)); -# endif /* !CS_PATH */ -#endif /* !_CS_PATH || !HAVE_CONFSTR */ -} - -int -default_columns () -{ - char *v; - int c; - - c = -1; - v = get_string_value ("COLUMNS"); - if (v && *v) - { - c = atoi (v); - if (c > 0) - return c; - } - - if (check_window_size) - get_new_window_size (0, (int *)0, &c); - - return (c > 0 ? c : 80); -} - - diff --git a/third_party/bash/general.h b/third_party/bash/general.h deleted file mode 100644 index 8064c50eb..000000000 --- a/third_party/bash/general.h +++ /dev/null @@ -1,372 +0,0 @@ -/* general.h -- defines that everybody likes to use. */ - -/* Copyright (C) 1993-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_GENERAL_H_) -#define _GENERAL_H_ - -#include "stdc.h" - -#include "bashtypes.h" -#include "chartypes.h" - -#if defined (HAVE_SYS_RESOURCE_H) && defined (RLIMTYPE) -# if defined (HAVE_SYS_TIME_H) -# include -# endif -# include -#endif - -#if defined (HAVE_STRING_H) -# include -#else -# include -#endif /* !HAVE_STRING_H */ - -#if defined (HAVE_LIMITS_H) -# include -#endif - -#include "xmalloc.h" - -/* NULL pointer type. */ -#if !defined (NULL) -# if defined (__STDC__) -# define NULL ((void *) 0) -# else -# define NULL 0x0 -# endif /* !__STDC__ */ -#endif /* !NULL */ - -/* Hardly used anymore */ -#define pointer_to_int(x) (int)((char *)x - (char *)0) - -#if defined (alpha) && defined (__GNUC__) && !defined (strchr) && !defined (__STDC__) -extern char *strchr (), *strrchr (); -#endif - -#if !defined (strcpy) && (defined (HAVE_DECL_STRCPY) && !HAVE_DECL_STRCPY) -extern char *strcpy PARAMS((char *, const char *)); -#endif - -#if !defined (savestring) -# define savestring(x) (char *)strcpy (xmalloc (1 + strlen (x)), (x)) -#endif - -#ifndef member -# define member(c, s) ((c) ? ((char *)mbschr ((s), (c)) != (char *)NULL) : 0) -#endif - -#ifndef whitespace -#define whitespace(c) (((c) == ' ') || ((c) == '\t')) -#endif - -#ifndef CHAR_MAX -# ifdef __CHAR_UNSIGNED__ -# define CHAR_MAX 0xff -# else -# define CHAR_MAX 0x7f -# endif -#endif - -#ifndef CHAR_BIT -# define CHAR_BIT 8 -#endif - -/* Nonzero if the integer type T is signed. */ -#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) - -/* The width in bits of the integer type or expression T. - Padding bits are not supported; this is checked at compile-time below. */ -#define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT) - -/* Bound on length of the string representing an unsigned integer - value representable in B bits. log10 (2.0) < 146/485. The - smallest value of B where this bound is not tight is 2621. */ -#define INT_BITS_STRLEN_BOUND(b) (((b) * 146 + 484) / 485) - -/* Bound on length of the string representing an integer value of type T. - Subtract one for the sign bit if T is signed; - 302 / 1000 is log10 (2) rounded up; - add one for integer division truncation; - add one more for a minus sign if t is signed. */ -#define INT_STRLEN_BOUND(t) \ - ((TYPE_WIDTH (t) - TYPE_SIGNED (t)) * 302 / 1000 \ - + 1 + TYPE_SIGNED (t)) - -/* Updated version adapted from gnulib/intprops.h, not used right now. - Changes the approximation of log10(2) from 302/1000 to 146/485. */ -#if 0 -#define INT_STRLEN_BOUND(t) \ - (INT_BITS_STRLEN_BOUND (TYPE_WIDTH (t) - TYPE_SIGNED (t)) + TYPE_SIGNED(t)) -#endif - -/* Bound on buffer size needed to represent an integer type or expression T, - including the terminating null. */ -#define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1) - -/* Define exactly what a legal shell identifier consists of. */ -#define legal_variable_starter(c) (ISALPHA(c) || (c == '_')) -#define legal_variable_char(c) (ISALNUM(c) || c == '_') - -/* Definitions used in subst.c and by the `read' builtin for field - splitting. */ -#define spctabnl(c) ((c) == ' ' || (c) == '\t' || (c) == '\n') - -/* All structs which contain a `next' field should have that field - as the first field in the struct. This means that functions - can be written to handle the general case for linked lists. */ -typedef struct g_list { - struct g_list *next; -} GENERIC_LIST; - -/* Here is a generic structure for associating character strings - with integers. It is used in the parser for shell tokenization. */ -typedef struct { - char *word; - int token; -} STRING_INT_ALIST; - -/* A macro to avoid making an unnecessary function call. */ -#define REVERSE_LIST(list, type) \ - ((list && list->next) ? (type)list_reverse ((GENERIC_LIST *)list) \ - : (type)(list)) - -#if __GNUC__ > 1 -# define FASTCOPY(s, d, n) __builtin_memcpy ((d), (s), (n)) -#else /* !__GNUC__ */ -# if !defined (HAVE_BCOPY) -# if !defined (HAVE_MEMMOVE) -# define FASTCOPY(s, d, n) memcpy ((d), (s), (n)) -# else -# define FASTCOPY(s, d, n) memmove ((d), (s), (n)) -# endif /* !HAVE_MEMMOVE */ -# else /* HAVE_BCOPY */ -# define FASTCOPY(s, d, n) bcopy ((s), (d), (n)) -# endif /* HAVE_BCOPY */ -#endif /* !__GNUC__ */ - -/* String comparisons that possibly save a function call each. */ -#define STREQ(a, b) ((a)[0] == (b)[0] && strcmp(a, b) == 0) -#define STREQN(a, b, n) ((n == 0) ? (1) \ - : ((a)[0] == (b)[0] && strncmp(a, b, n) == 0)) - -/* More convenience definitions that possibly save system or libc calls. */ -#define STRLEN(s) (((s) && (s)[0]) ? ((s)[1] ? ((s)[2] ? strlen(s) : 2) : 1) : 0) -#define FREE(s) do { if (s) free (s); } while (0) -#define MEMBER(c, s) (((c) && c == (s)[0] && !(s)[1]) || (member(c, s))) - -/* A fairly hairy macro to check whether an allocated string has more room, - and to resize it using xrealloc if it does not. - STR is the string (char *) - CIND is the current index into the string (int) - ROOM is the amount of additional room we need in the string (int) - CSIZE is the currently-allocated size of STR (int) - SINCR is how much to increment CSIZE before calling xrealloc (int) */ - -#define RESIZE_MALLOCED_BUFFER(str, cind, room, csize, sincr) \ - do { \ - if ((cind) + (room) >= csize) \ - { \ - while ((cind) + (room) >= csize) \ - csize += (sincr); \ - str = xrealloc (str, csize); \ - } \ - } while (0) - -/* Function pointers can be declared as (Function *)foo. */ -#if !defined (_FUNCTION_DEF) -# define _FUNCTION_DEF -typedef int Function (); -typedef void VFunction (); -typedef char *CPFunction (); /* no longer used */ -typedef char **CPPFunction (); /* no longer used */ -#endif /* _FUNCTION_DEF */ - -#ifndef SH_FUNCTION_TYPEDEF -# define SH_FUNCTION_TYPEDEF - -/* Shell function typedefs with prototypes */ -/* `Generic' function pointer typedefs */ - -typedef int sh_intfunc_t PARAMS((int)); -typedef int sh_ivoidfunc_t PARAMS((void)); -typedef int sh_icpfunc_t PARAMS((char *)); -typedef int sh_icppfunc_t PARAMS((char **)); -typedef int sh_iptrfunc_t PARAMS((PTR_T)); - -typedef void sh_voidfunc_t PARAMS((void)); -typedef void sh_vintfunc_t PARAMS((int)); -typedef void sh_vcpfunc_t PARAMS((char *)); -typedef void sh_vcppfunc_t PARAMS((char **)); -typedef void sh_vptrfunc_t PARAMS((PTR_T)); - -typedef int sh_wdesc_func_t PARAMS((WORD_DESC *)); -typedef int sh_wlist_func_t PARAMS((WORD_LIST *)); - -typedef int sh_glist_func_t PARAMS((GENERIC_LIST *)); - -typedef char *sh_string_func_t PARAMS((char *)); /* like savestring, et al. */ - -typedef int sh_msg_func_t PARAMS((const char *, ...)); /* printf(3)-like */ -typedef void sh_vmsg_func_t PARAMS((const char *, ...)); /* printf(3)-like */ - -/* Specific function pointer typedefs. Most of these could be done - with #defines. */ -typedef void sh_sv_func_t PARAMS((char *)); /* sh_vcpfunc_t */ -typedef void sh_free_func_t PARAMS((PTR_T)); /* sh_vptrfunc_t */ -typedef void sh_resetsig_func_t PARAMS((int)); /* sh_vintfunc_t */ - -typedef int sh_ignore_func_t PARAMS((const char *)); /* sh_icpfunc_t */ - -typedef int sh_assign_func_t PARAMS((const char *)); -typedef int sh_wassign_func_t PARAMS((WORD_DESC *, int)); - -typedef int sh_load_func_t PARAMS((char *)); -typedef void sh_unload_func_t PARAMS((char *)); - -typedef int sh_builtin_func_t PARAMS((WORD_LIST *)); /* sh_wlist_func_t */ - -#endif /* SH_FUNCTION_TYPEDEF */ - -#define NOW ((time_t) time ((time_t *) 0)) -#define GETTIME(tv) gettimeofday(&(tv), NULL) - -/* Some defines for calling file status functions. */ -#define FS_EXISTS 0x1 -#define FS_EXECABLE 0x2 -#define FS_EXEC_PREFERRED 0x4 -#define FS_EXEC_ONLY 0x8 -#define FS_DIRECTORY 0x10 -#define FS_NODIRS 0x20 -#define FS_READABLE 0x40 - -/* Default maximum for move_to_high_fd */ -#define HIGH_FD_MAX 256 - -/* The type of function passed as the fourth argument to qsort(3). */ -#ifdef __STDC__ -typedef int QSFUNC (const void *, const void *); -#else -typedef int QSFUNC (); -#endif - -/* Some useful definitions for Unix pathnames. Argument convention: - x == string, c == character */ - -#if !defined (__CYGWIN__) -# define ABSPATH(x) ((x)[0] == '/') -# define RELPATH(x) ((x)[0] != '/') -#else /* __CYGWIN__ */ -# define ABSPATH(x) (((x)[0] && ISALPHA((unsigned char)(x)[0]) && (x)[1] == ':') || ISDIRSEP((x)[0])) -# define RELPATH(x) (ABSPATH(x) == 0) -#endif /* __CYGWIN__ */ - -#define ROOTEDPATH(x) (ABSPATH(x)) - -#define DIRSEP '/' -#if !defined (__CYGWIN__) -# define ISDIRSEP(c) ((c) == '/') -#else -# define ISDIRSEP(c) ((c) == '/' || (c) == '\\') -#endif /* __CYGWIN__ */ -#define PATHSEP(c) (ISDIRSEP(c) || (c) == 0) - -#define DOT_OR_DOTDOT(s) (s[0] == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0))) - -#if defined (HANDLE_MULTIBYTE) -#define WDOT_OR_DOTDOT(w) (w[0] == L'.' && (w[1] == L'\0' || (w[1] == L'.' && w[2] == L'\0'))) -#endif - -#if 0 -/* Declarations for functions defined in xmalloc.c */ -extern PTR_T xmalloc PARAMS((size_t)); -extern PTR_T xrealloc PARAMS((void *, size_t)); -extern void xfree PARAMS((void *)); -#endif - -/* Declarations for functions defined in general.c */ -extern void posix_initialize PARAMS((int)); - -extern int num_posix_options PARAMS((void)); -extern char *get_posix_options PARAMS((char *)); -extern void set_posix_options PARAMS((const char *)); - -extern void save_posix_options PARAMS((void)); - -#if defined (RLIMTYPE) -extern RLIMTYPE string_to_rlimtype PARAMS((char *)); -extern void print_rlimtype PARAMS((RLIMTYPE, int)); -#endif - -extern int all_digits PARAMS((const char *)); -extern int legal_number PARAMS((const char *, intmax_t *)); -extern int legal_identifier PARAMS((const char *)); -extern int importable_function_name PARAMS((const char *, size_t)); -extern int exportable_function_name PARAMS((const char *)); -extern int check_identifier PARAMS((WORD_DESC *, int)); -extern int valid_nameref_value PARAMS((const char *, int)); -extern int check_selfref PARAMS((const char *, char *, int)); -extern int legal_alias_name PARAMS((const char *, int)); -extern int line_isblank PARAMS((const char *)); -extern int assignment PARAMS((const char *, int)); - -extern int sh_unset_nodelay_mode PARAMS((int)); -extern int sh_setclexec PARAMS((int)); -extern int sh_validfd PARAMS((int)); -extern int fd_ispipe PARAMS((int)); -extern void check_dev_tty PARAMS((void)); -extern int move_to_high_fd PARAMS((int, int, int)); -extern int check_binary_file PARAMS((const char *, int)); - -#ifdef _POSIXSTAT_H_ -extern int same_file PARAMS((const char *, const char *, struct stat *, struct stat *)); -#endif - -extern int sh_openpipe PARAMS((int *)); -extern int sh_closepipe PARAMS((int *)); - -extern int file_exists PARAMS((const char *)); -extern int file_isdir PARAMS((const char *)); -extern int file_iswdir PARAMS((const char *)); -extern int path_dot_or_dotdot PARAMS((const char *)); -extern int absolute_pathname PARAMS((const char *)); -extern int absolute_program PARAMS((const char *)); - -extern char *make_absolute PARAMS((const char *, const char *)); -extern char *base_pathname PARAMS((char *)); -extern char *full_pathname PARAMS((char *)); -extern char *polite_directory_format PARAMS((char *)); -extern char *trim_pathname PARAMS((char *, int)); -extern char *printable_filename PARAMS((char *, int)); - -extern char *extract_colon_unit PARAMS((char *, int *)); - -extern void tilde_initialize PARAMS((void)); -extern char *bash_tilde_find_word PARAMS((const char *, int, int *)); -extern char *bash_tilde_expand PARAMS((const char *, int)); - -extern int group_member PARAMS((gid_t)); -extern char **get_group_list PARAMS((int *)); -extern int *get_group_array PARAMS((int *)); - -extern char *conf_standard_path PARAMS((void)); -extern int default_columns PARAMS((void)); - -#endif /* _GENERAL_H_ */ diff --git a/third_party/bash/getenv.c b/third_party/bash/getenv.c deleted file mode 100644 index 1704a3a64..000000000 --- a/third_party/bash/getenv.c +++ /dev/null @@ -1,233 +0,0 @@ -/* getenv.c - get environment variable value from the shell's variable - list. */ - -/* Copyright (C) 1997-2002 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if defined (CAN_REDEFINE_GETENV) - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "bashansi.h" -#include -#include "shell.h" - -#ifndef errno -extern int errno; -#endif - -extern char **environ; - -/* We supply our own version of getenv () because we want library - routines to get the changed values of exported variables. */ - -/* The NeXT C library has getenv () defined and used in the same file. - This screws our scheme. However, Bash will run on the NeXT using - the C library getenv (), since right now the only environment variable - that we care about is HOME, and that is already defined. */ -static char *last_tempenv_value = (char *)NULL; - -char * -getenv (name) - const char *name; -{ - SHELL_VAR *var; - - if (name == 0 || *name == '\0') - return ((char *)NULL); - - var = find_tempenv_variable ((char *)name); - if (var) - { - FREE (last_tempenv_value); - - last_tempenv_value = value_cell (var) ? savestring (value_cell (var)) : (char *)NULL; - return (last_tempenv_value); - } - else if (shell_variables) - { - var = find_variable ((char *)name); - if (var && exported_p (var)) - return (value_cell (var)); - } - else if (environ) - { - register int i, len; - - /* In some cases, s5r3 invokes getenv() before main(); BSD systems - using gprof also exhibit this behavior. This means that - shell_variables will be 0 when this is invoked. We look up the - variable in the real environment in that case. */ - - for (i = 0, len = strlen (name); environ[i]; i++) - { - if ((STREQN (environ[i], name, len)) && (environ[i][len] == '=')) - return (environ[i] + len + 1); - } - } - - return ((char *)NULL); -} - -/* Some versions of Unix use _getenv instead. */ -char * -_getenv (name) - const char *name; -{ - return (getenv (name)); -} - -/* SUSv3 says argument is a `char *'; BSD implementations disagree */ -int -putenv (str) -#ifndef HAVE_STD_PUTENV - const char *str; -#else - char *str; -#endif -{ - SHELL_VAR *var; - char *name, *value; - int offset; - - if (str == 0 || *str == '\0') - { - errno = EINVAL; - return -1; - } - - offset = assignment (str, 0); - if (str[offset] != '=') - { - errno = EINVAL; - return -1; - } - name = savestring (str); - name[offset] = 0; - - value = name + offset + 1; - - /* XXX - should we worry about readonly here? */ - var = bind_variable (name, value, 0); - if (var == 0) - { - errno = EINVAL; - return -1; - } - - VUNSETATTR (var, att_invisible); - VSETATTR (var, att_exported); - - return 0; -} - -#if 0 -int -_putenv (name) -#ifndef HAVE_STD_PUTENV - const char *name; -#else - char *name; -#endif -{ - return putenv (name); -} -#endif - -int -setenv (name, value, rewrite) - const char *name; - const char *value; - int rewrite; -{ - SHELL_VAR *var; - char *v; - - if (name == 0 || *name == '\0' || strchr (name, '=') != 0) - { - errno = EINVAL; - return -1; - } - - var = 0; - v = (char *)value; /* some compilers need explicit cast */ - /* XXX - should we worry about readonly here? */ - if (rewrite == 0) - var = find_variable (name); - - if (var == 0) - var = bind_variable (name, v, 0); - - if (var == 0) - return -1; - - VUNSETATTR (var, att_invisible); - VSETATTR (var, att_exported); - - return 0; -} - -#if 0 -int -_setenv (name, value, rewrite) - const char *name; - const char *value; - int rewrite; -{ - return setenv (name, value, rewrite); -} -#endif - -/* SUSv3 says unsetenv returns int; existing implementations (BSD) disagree. */ - -#ifdef HAVE_STD_UNSETENV -#define UNSETENV_RETURN(N) return(N) -#define UNSETENV_RETTYPE int -#else -#define UNSETENV_RETURN(N) return -#define UNSETENV_RETTYPE void -#endif - -UNSETENV_RETTYPE -unsetenv (name) - const char *name; -{ - if (name == 0 || *name == '\0' || strchr (name, '=') != 0) - { - errno = EINVAL; - UNSETENV_RETURN(-1); - } - - /* XXX - should we just remove the export attribute here? */ -#if 1 - unbind_variable (name); -#else - SHELL_VAR *v; - - v = find_variable (name); - if (v) - VUNSETATTR (v, att_exported); -#endif - - UNSETENV_RETURN(0); -} -#endif /* CAN_REDEFINE_GETENV */ diff --git a/third_party/bash/getopt.c b/third_party/bash/getopt.c deleted file mode 100644 index 25f540cc5..000000000 --- a/third_party/bash/getopt.c +++ /dev/null @@ -1,355 +0,0 @@ -/* getopt.c - getopt for Bash. Used by the getopt builtin. */ - -/* Copyright (C) 1993-2009 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include -#include "memalloc.h" -#include "bashintl.h" -#include "shell.h" -#include "getopt.h" - -/* For communication from `sh_getopt' to the caller. - When `sh_getopt' finds an option that takes an argument, - the argument value is returned here. */ -char *sh_optarg = 0; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `sh_getopt'. - - On entry to `sh_getopt', zero means this is the first call; initialize. - - When `sh_getopt' returns EOF, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `sh_optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -/* XXX 1003.2 says this must be 1 before any call. */ -int sh_optind = 0; - -/* Index of the current argument. */ -static int sh_curopt; - -/* The next char to be scanned in the option-element - in which the last option character we returned was found. - This allows us to pick up the scan where we left off. - - If this is zero, or a null string, it means resume the scan - by advancing to the next ARGV-element. */ - -static char *nextchar; -static int sh_charindex; - -/* Callers store zero here to inhibit the error message - for unrecognized options. */ - -int sh_opterr = 1; - -/* Set to an option character which was unrecognized. - This must be initialized on some systems to avoid linking in the - system's own getopt implementation. */ - -int sh_optopt = '?'; - -/* Set to 1 when we see an invalid option; public so getopts can reset it. */ -int sh_badopt = 0; - -/* Scan elements of ARGV (whose length is ARGC) for option characters - given in OPTSTRING. - - If an element of ARGV starts with '-', and is not exactly "-" or "--", - then it is an option element. The characters of this element - (aside from the initial '-') are option characters. If `sh_getopt' - is called repeatedly, it returns successively each of the option characters - from each of the option elements. - - If `sh_getopt' finds another option character, it returns that character, - updating `sh_optind' and `nextchar' so that the next call to `sh_getopt' can - resume the scan with the following option character or ARGV-element. - - If there are no more option characters, `sh_getopt' returns `EOF'. - Then `sh_optind' is the index in ARGV of the first ARGV-element - that is not an option. - - OPTSTRING is a string containing the legitimate option characters. - If an option character is seen that is not listed in OPTSTRING, - return '?' after printing an error message. If you set `sh_opterr' to - zero, the error message is suppressed but we still return '?'. - - If a char in OPTSTRING is followed by a colon, that means it wants an arg, - so the following text in the same ARGV-element, or the text of the following - ARGV-element, is returned in `sh_optarg'. */ - -/* 1003.2 specifies the format of this message. */ -#define BADOPT(x) fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], x) -#define NEEDARG(x) fprintf (stderr, _("%s: option requires an argument -- %c\n"), argv[0], x) - -int -sh_getopt (argc, argv, optstring) - int argc; - char *const *argv; - const char *optstring; -{ - char c, *temp; - - sh_optarg = 0; - - if (sh_optind >= argc || sh_optind < 0) /* XXX was sh_optind > argc */ - { - sh_optind = argc; - return (EOF); - } - - /* Initialize the internal data when the first call is made. - Start processing options with ARGV-element 1 (since ARGV-element 0 - is the program name); the sequence of previously skipped - non-option ARGV-elements is empty. */ - - if (sh_optind == 0) - { - sh_optind = 1; - nextchar = (char *)NULL; - } - - if (nextchar == 0 || *nextchar == '\0') - { - /* If we have done all the ARGV-elements, stop the scan. */ - if (sh_optind >= argc) - return EOF; - - temp = argv[sh_optind]; - - /* Special ARGV-element `--' means premature end of options. - Skip it like a null option, and return EOF. */ - if (temp[0] == '-' && temp[1] == '-' && temp[2] == '\0') - { - sh_optind++; - return EOF; - } - - /* If we have come to a non-option, either stop the scan or describe - it to the caller and pass it by. This makes the pseudo-option - `-' mean the end of options, but does not skip over it. */ - if (temp[0] != '-' || temp[1] == '\0') - return EOF; - - /* We have found another option-ARGV-element. - Start decoding its characters. */ - nextchar = argv[sh_curopt = sh_optind] + 1; - sh_charindex = 1; - } - - /* Look at and handle the next option-character. */ - - c = *nextchar++; sh_charindex++; - temp = strchr (optstring, c); - - sh_optopt = c; - - /* Increment `sh_optind' when we start to process its last character. */ - if (nextchar == 0 || *nextchar == '\0') - { - sh_optind++; - nextchar = (char *)NULL; - } - - if (sh_badopt = (temp == NULL || c == ':')) - { - if (sh_opterr) - BADOPT (c); - - return '?'; - } - - if (temp[1] == ':') - { - if (nextchar && *nextchar) - { - /* This is an option that requires an argument. */ - sh_optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - sh_optind++; - } - else if (sh_optind == argc) - { - if (sh_opterr) - NEEDARG (c); - - sh_optopt = c; - sh_optarg = ""; /* Needed by getopts. */ - c = (optstring[0] == ':') ? ':' : '?'; - } - else - /* We already incremented `sh_optind' once; - increment it again when taking next ARGV-elt as argument. */ - sh_optarg = argv[sh_optind++]; - nextchar = (char *)NULL; - } - return c; -} - -void -sh_getopt_restore_state (argv) - char **argv; -{ - if (nextchar) - nextchar = argv[sh_curopt] + sh_charindex; -} - -sh_getopt_state_t * -sh_getopt_alloc_istate () -{ - sh_getopt_state_t *ret; - - ret = (sh_getopt_state_t *)xmalloc (sizeof (sh_getopt_state_t)); - return ret; -} - -void -sh_getopt_dispose_istate (gs) - sh_getopt_state_t *gs; -{ - free (gs); -} - -sh_getopt_state_t * -sh_getopt_save_istate () -{ - sh_getopt_state_t *ret; - - ret = sh_getopt_alloc_istate (); - - ret->gs_optarg = sh_optarg; - ret->gs_optind = sh_optind; - ret->gs_curopt = sh_curopt; - ret->gs_nextchar = nextchar; /* XXX */ - ret->gs_charindex = sh_charindex; - ret->gs_flags = 0; /* XXX for later use */ - - return ret; -} - -void -sh_getopt_restore_istate (state) - sh_getopt_state_t *state; -{ - sh_optarg = state->gs_optarg; - sh_optind = state->gs_optind; - sh_curopt = state->gs_curopt; - nextchar = state->gs_nextchar; /* XXX - probably not usable */ - sh_charindex = state->gs_charindex; - - sh_getopt_dispose_istate (state); -} - -#if 0 -void -sh_getopt_debug_restore_state (argv) - char **argv; -{ - if (nextchar && nextchar != argv[sh_curopt] + sh_charindex) - { - itrace("sh_getopt_debug_restore_state: resetting nextchar"); - nextchar = argv[sh_curopt] + sh_charindex; - } -} -#endif - -#ifdef TEST - -/* Compile with -DTEST to make an executable for use in testing - the above definition of `sh_getopt'. */ - -int -main (argc, argv) - int argc; - char **argv; -{ - int c; - int digit_sh_optind = 0; - - while (1) - { - int this_option_sh_optind = sh_optind ? sh_optind : 1; - - c = sh_getopt (argc, argv, "abc:d:0123456789"); - if (c == EOF) - break; - - switch (c) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_sh_optind != 0 && digit_sh_optind != this_option_sh_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_sh_optind = this_option_sh_optind; - printf ("option %c\n", c); - break; - - case 'a': - printf ("option a\n"); - break; - - case 'b': - printf ("option b\n"); - break; - - case 'c': - printf ("option c with value `%s'\n", sh_optarg); - break; - - case '?': - break; - - default: - printf ("?? sh_getopt returned character code 0%o ??\n", c); - } - } - - if (sh_optind < argc) - { - printf ("non-option ARGV-elements: "); - while (sh_optind < argc) - printf ("%s ", argv[sh_optind++]); - printf ("\n"); - } - - exit (0); -} - -#endif /* TEST */ diff --git a/third_party/bash/getopt.h b/third_party/bash/getopt.h deleted file mode 100644 index fd9785975..000000000 --- a/third_party/bash/getopt.h +++ /dev/null @@ -1,82 +0,0 @@ -/* getopt.h - declarations for getopt. */ - -/* Copyright (C) 1989-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -/* XXX THIS HAS BEEN MODIFIED FOR INCORPORATION INTO BASH XXX */ - -#ifndef _SH_GETOPT_H -#define _SH_GETOPT_H 1 - -#include "stdc.h" - -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -extern char *sh_optarg; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns EOF, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `sh_optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -extern int sh_optind; - -/* Callers store zero here to inhibit the error message `getopt' prints - for unrecognized options. */ - -extern int sh_opterr; - -/* Set to an option character which was unrecognized. */ - -extern int sh_optopt; - -/* Set to 1 when an unrecognized option is encountered. */ -extern int sh_badopt; - -extern int sh_getopt PARAMS((int, char *const *, const char *)); - -typedef struct sh_getopt_state -{ - char *gs_optarg; - int gs_optind; - int gs_curopt; - char *gs_nextchar; - int gs_charindex; - int gs_flags; -} sh_getopt_state_t; - -extern void sh_getopt_restore_state PARAMS((char **)); - -extern sh_getopt_state_t *sh_getopt_alloc_istate PARAMS((void)); -extern void sh_getopt_dispose_istate PARAMS((sh_getopt_state_t *)); - -extern sh_getopt_state_t *sh_getopt_save_istate PARAMS((void)); -extern void sh_getopt_restore_istate PARAMS((sh_getopt_state_t *)); - -#endif /* _SH_GETOPT_H */ diff --git a/third_party/bash/gettext.h b/third_party/bash/gettext.h deleted file mode 100644 index 97a1f36d6..000000000 --- a/third_party/bash/gettext.h +++ /dev/null @@ -1,70 +0,0 @@ -/* Convenience header for conditional use of GNU . - Copyright (C) 1995-1998, 2000-2002, 2008,2009 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne-Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#ifndef _LIBGETTEXT_H -#define _LIBGETTEXT_H 1 - -/* NLS can be disabled through the configure --disable-nls option. */ -#if ENABLE_NLS - -/* Get declarations of GNU message catalog functions. */ -# include - -#else - -/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which - chokes if dcgettext is defined as a macro. So include it now, to make - later inclusions of a NOP. We don't include - as well because people using "gettext.h" will not include , - and also including would fail on SunOS 4, whereas - is OK. */ -#if defined(__sun) -# include -#endif - -/* Disabled NLS. - The casts to 'const char *' serve the purpose of producing warnings - for invalid uses of the value returned from these functions. - On pre-ANSI systems without 'const', the config.h file is supposed to - contain "#define const". */ -# define gettext(Msgid) ((const char *) (Msgid)) -# define dgettext(Domainname, Msgid) ((const char *) (Msgid)) -# define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid)) -# define ngettext(Msgid1, Msgid2, N) \ - ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) -# define dngettext(Domainname, Msgid1, Msgid2, N) \ - ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) -# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ - ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) -# define textdomain(Domainname) ((const char *) (Domainname)) -# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname)) -# define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset)) - -#endif - -/* A pseudo function call that serves as a marker for the automated - extraction of messages, but does not call gettext(). The run-time - translation is done at a different place in the code. - The argument, String, should be a literal string. Concatenated strings - and other string expressions won't work. - The macro's expansion is not parenthesized, so that it is suitable as - initializer for static 'char[]' or 'const char[]' variables. */ -#define gettext_noop(String) String - -#endif /* _LIBGETTEXT_H */ diff --git a/third_party/bash/gettimeofday.c b/third_party/bash/gettimeofday.c deleted file mode 100644 index b654c1547..000000000 --- a/third_party/bash/gettimeofday.c +++ /dev/null @@ -1,35 +0,0 @@ -/* gettimeofday.c - gettimeofday replacement using time() */ - -/* Copyright (C) 2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if !defined (HAVE_GETTIMEOFDAY) - -#include "posixtime.h" - -/* A version of gettimeofday that just sets tv_sec from time(3) */ -int -gettimeofday (struct timeval *tv, void *tz) -{ - tv->tv_sec = (time_t) time ((time_t *)0); - tv->tv_usec = 0; - return 0; -} -#endif diff --git a/third_party/bash/glob.c b/third_party/bash/glob.c deleted file mode 100644 index fe80d41ec..000000000 --- a/third_party/bash/glob.c +++ /dev/null @@ -1,1609 +0,0 @@ -/* glob.c -- file-name wildcard pattern matching for Bash. - - Copyright (C) 1985-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne-Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -/* To whomever it may concern: I have never seen the code which most - Unix programs use to perform this function. I wrote this from scratch - based on specifications for the pattern matching. --RMS. */ - -#include "config.h" - -#if !defined (__GNUC__) && !defined (HAVE_ALLOCA_H) && defined (_AIX) - #pragma alloca -#endif /* _AIX && RISC6000 && !__GNUC__ */ - -#include "bashtypes.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "bashansi.h" -#include "posixdir.h" -#include "posixstat.h" -#include "shmbutil.h" -#include "xmalloc.h" - -#include "filecntl.h" -#if !defined (F_OK) -# define F_OK 0 -#endif - -#include "stdc.h" -#include "memalloc.h" - -#include - -#include "shell.h" -#include "general.h" - -#include "glob.h" -#include "strmatch.h" - -#if !defined (HAVE_BCOPY) && !defined (bcopy) -# define bcopy(s, d, n) ((void) memcpy ((d), (s), (n))) -#endif /* !HAVE_BCOPY && !bcopy */ - -#if !defined (NULL) -# if defined (__STDC__) -# define NULL ((void *) 0) -# else -# define NULL 0x0 -# endif /* __STDC__ */ -#endif /* !NULL */ - -#if !defined (FREE) -# define FREE(x) if (x) free (x) -#endif - -/* Don't try to alloca() more than this much memory for `struct globval' - in glob_vector() */ -#ifndef ALLOCA_MAX -# define ALLOCA_MAX 100000 -#endif - -struct globval - { - struct globval *next; - char *name; - }; - -extern void throw_to_top_level PARAMS((void)); -extern int sh_eaccess PARAMS((const char *, int)); -extern char *sh_makepath PARAMS((const char *, const char *, int)); -extern int signal_is_pending PARAMS((int)); -extern void run_pending_traps PARAMS((void)); - -extern int extended_glob; - -/* Global variable which controls whether or not * matches .*. - Non-zero means don't match .*. */ -int noglob_dot_filenames = 1; - -/* Global variable which controls whether or not filename globbing - is done without regard to case. */ -int glob_ignore_case = 0; - -/* Global variable controlling whether globbing ever returns . or .. - regardless of the pattern. If set to 1, no glob pattern will ever - match `.' or `..'. Disabled by default. */ -int glob_always_skip_dot_and_dotdot = 1; - -/* Global variable to return to signify an error in globbing. */ -char *glob_error_return; - -static struct globval finddirs_error_return; - -/* Some forward declarations. */ -static int skipname PARAMS((char *, char *, int)); -#if HANDLE_MULTIBYTE -static int mbskipname PARAMS((char *, char *, int)); -#endif -void udequote_pathname PARAMS((char *)); -#if HANDLE_MULTIBYTE -void wcdequote_pathname PARAMS((wchar_t *)); -static void wdequote_pathname PARAMS((char *)); -static void dequote_pathname PARAMS((char *)); -#else -# define dequote_pathname(p) udequote_pathname(p) -#endif -static int glob_testdir PARAMS((char *, int)); -static char **glob_dir_to_array PARAMS((char *, char **, int)); - -/* Make sure these names continue to agree with what's in smatch.c */ -extern char *glob_patscan PARAMS((char *, char *, int)); -extern wchar_t *glob_patscan_wc PARAMS((wchar_t *, wchar_t *, int)); - -/* And this from gmisc.c/gm_loop.c */ -extern int wextglob_pattern_p PARAMS((wchar_t *)); - -extern char *glob_dirscan PARAMS((char *, int)); - -/* Compile `glob_loop.inc' for single-byte characters. */ -#define GCHAR unsigned char -#define CHAR char -#define INT int -#define L(CS) CS -#define INTERNAL_GLOB_PATTERN_P internal_glob_pattern_p -#include "glob_loop.inc" - -/* Compile `glob_loop.inc' again for multibyte characters. */ -#if HANDLE_MULTIBYTE - -#define GCHAR wchar_t -#define CHAR wchar_t -#define INT wint_t -#define L(CS) L##CS -#define INTERNAL_GLOB_PATTERN_P internal_glob_wpattern_p -#include "glob_loop.inc" - -#endif /* HANDLE_MULTIBYTE */ - -/* And now a function that calls either the single-byte or multibyte version - of internal_glob_pattern_p. */ -int -glob_pattern_p (pattern) - const char *pattern; -{ -#if HANDLE_MULTIBYTE - size_t n; - wchar_t *wpattern; - int r; - - if (MB_CUR_MAX == 1 || mbsmbchar (pattern) == 0) - return (internal_glob_pattern_p ((unsigned char *)pattern)); - - /* Convert strings to wide chars, and call the multibyte version. */ - n = xdupmbstowcs (&wpattern, NULL, pattern); - if (n == (size_t)-1) - /* Oops. Invalid multibyte sequence. Try it as single-byte sequence. */ - return (internal_glob_pattern_p ((unsigned char *)pattern)); - - r = internal_glob_wpattern_p (wpattern); - free (wpattern); - - return r; -#else - return (internal_glob_pattern_p ((unsigned char *)pattern)); -#endif -} - -#if EXTENDED_GLOB - -#if defined (HANDLE_MULTIBYTE) -# define XSKIPNAME(p, d, f) mbskipname(p, d, f) -#else -# define XSKIPNAME(p, d, f) skipname(p, d, f) -#endif - -/* Return 1 if all subpatterns in the extended globbing pattern PAT indicate - that the name should be skipped. XXX - doesn't handle pattern negation, - not sure if it should */ -static int -extglob_skipname (pat, dname, flags) - char *pat, *dname; - int flags; -{ - char *pp, *pe, *t, *se; - int n, r, negate, wild, nullpat, xflags; - - negate = *pat == '!'; - wild = *pat == '*' || *pat == '?'; - pp = pat + 2; - se = pp + strlen (pp); /* end of pattern string */ - pe = glob_patscan (pp, se, 0); /* end of extglob pattern */ - - /* if pe == 0, this is an invalid extglob pattern */ - if (pe == 0) - return 0; - - xflags = flags | ( negate ? GX_NEGATE : 0); - - /* if pe != se we have more of the pattern at the end of the extglob - pattern. Check the easy case first ( */ - if (pe == se && *pe == 0 && pe[-1] == ')' && (t = strchr (pp, '|')) == 0) - { - pe[-1] = '\0'; - /* This is where we check whether the pattern is being negated and - match all files beginning with `.' if the pattern begins with a - literal `.'. */ - r = XSKIPNAME (pp, dname, xflags); /*(*/ - pe[-1] = ')'; - return r; - } - - /* Is the extglob pattern between the parens the null pattern? The null - pattern can match nothing, so should we check any remaining portion of - the pattern? */ - nullpat = pe >= (pat + 2) && pe[-2] == '(' && pe[-1] == ')'; - - /* check every subpattern */ - while (t = glob_patscan (pp, pe, '|')) - { - /* If T == PE and *T == 0 (&& PE[-1] == RPAREN), we have hit the end - of a pattern with no trailing characters. */ - n = t[-1]; /* ( */ - if (extglob_pattern_p (pp) && n == ')') /* nested extglob? */ - t[-1] = n; /* no-op for now */ - else - t[-1] = '\0'; - r = XSKIPNAME (pp, dname, xflags); - t[-1] = n; - if (r == 0) /* if any pattern says not skip, we don't skip */ - return r; - pp = t; - if (pp == pe) - break; - } - - /* glob_patscan might find end of string */ - if (pp == se) - return r; - - /* but if it doesn't then we didn't match a leading dot */ - if (wild && *pe) /* if we can match zero instances, check further */ - return (XSKIPNAME (pe, dname, flags)); - - return 1; -} -#endif - -/* Return 1 if DNAME should be skipped according to PAT. Mostly concerned - with matching leading `.'. */ -static int -skipname (pat, dname, flags) - char *pat; - char *dname; - int flags; -{ - int i; - -#if EXTENDED_GLOB - if (extglob_pattern_p (pat)) /* XXX */ - return (extglob_skipname (pat, dname, flags)); -#endif - - if (glob_always_skip_dot_and_dotdot && DOT_OR_DOTDOT (dname)) - return 1; - - /* If a leading dot need not be explicitly matched, and the pattern - doesn't start with a `.', don't match `.' or `..' */ - if (noglob_dot_filenames == 0 && pat[0] != '.' && - (pat[0] != '\\' || pat[1] != '.') && - DOT_OR_DOTDOT (dname)) - return 1; - -#if 0 - /* This is where we check whether the pattern is being negated and - match all files beginning with `.' if the pattern begins with a - literal `.'. This is the negation of the next clause. */ - else if ((flags & GX_NEGATE) && noglob_dot_filenames == 0 && - dname[0] == '.' && - (pat[0] == '.' || (pat[0] == '\\' && pat[1] == '.'))) - return 0; -#endif - - /* If a dot must be explicitly matched, check to see if they do. */ - else if (noglob_dot_filenames && dname[0] == '.' && - pat[0] != '.' && (pat[0] != '\\' || pat[1] != '.')) - return 1; - - return 0; -} - -#if HANDLE_MULTIBYTE - -static int -wskipname (pat, dname, flags) - wchar_t *pat, *dname; - int flags; -{ - int i; - - if (glob_always_skip_dot_and_dotdot && WDOT_OR_DOTDOT (dname)) - return 1; - - /* If a leading dot need not be explicitly matched, and the - pattern doesn't start with a `.', don't match `.' or `..' */ - if (noglob_dot_filenames == 0 && pat[0] != L'.' && - (pat[0] != L'\\' || pat[1] != L'.') && - WDOT_OR_DOTDOT (dname)) - return 1; - -#if 0 - /* This is where we check whether the pattern is being negated and - match all files beginning with `.' if the pattern begins with a - literal `.'. This is the negation of the next clause. */ - else if ((flags & GX_NEGATE) && noglob_dot_filenames == 0 && - dname[0] == L'.' && - (pat[0] == L'.' || (pat[0] == L'\\' && pat[1] == L'.'))) - return 0; -#endif - - /* If a leading dot must be explicitly matched, check to see if the - pattern and dirname both have one. */ - else if (noglob_dot_filenames && dname[0] == L'.' && - pat[0] != L'.' && (pat[0] != L'\\' || pat[1] != L'.')) - return 1; - - return 0; -} - -static int -wextglob_skipname (pat, dname, flags) - wchar_t *pat, *dname; - int flags; -{ -#if EXTENDED_GLOB - wchar_t *pp, *pe, *t, *se, n; - int r, negate, wild, nullpat, xflags; - - negate = *pat == L'!'; - wild = *pat == L'*' || *pat == L'?'; - pp = pat + 2; - se = pp + wcslen (pp); - pe = glob_patscan_wc (pp, se, 0); - - /* if pe == 0, this is an invalid extglob pattern */ - if (pe == 0) - return 0; - - xflags = flags | ( negate ? GX_NEGATE : 0); - - /* if pe != se we have more of the pattern at the end of the extglob - pattern. Check the easy case first ( */ - if (pe == se && *pe == L'\0' && pe[-1] == L')' && (t = wcschr (pp, L'|')) == 0) - { - pe[-1] = L'\0'; - r = wskipname (pp, dname, xflags); /*(*/ - pe[-1] = L')'; - return r; - } - - /* Is the extglob pattern between the parens the null pattern? The null - pattern can match nothing, so should we check any remaining portion of - the pattern? */ - nullpat = pe >= (pat + 2) && pe[-2] == L'(' && pe[-1] == L')'; - - /* check every subpattern */ - while (t = glob_patscan_wc (pp, pe, '|')) - { - n = t[-1]; /* ( */ - if (wextglob_pattern_p (pp) && n == L')') /* nested extglob? */ - t[-1] = n; /* no-op for now */ - else - t[-1] = L'\0'; - r = wskipname (pp, dname, xflags); - t[-1] = n; - if (r == 0) - return 0; - pp = t; - if (pp == pe) - break; - } - - /* glob_patscan_wc might find end of string */ - if (pp == se) - return r; - - /* but if it doesn't then we didn't match a leading dot */ - if (wild && *pe != L'\0') - return (wskipname (pe, dname, flags)); - - return 1; -#else - return (wskipname (pat, dname, flags)); -#endif -} - -/* Return 1 if DNAME should be skipped according to PAT. Handles multibyte - characters in PAT and DNAME. Mostly concerned with matching leading `.'. */ -static int -mbskipname (pat, dname, flags) - char *pat, *dname; - int flags; -{ - int ret, ext; - wchar_t *pat_wc, *dn_wc; - size_t pat_n, dn_n; - - if (mbsmbchar (dname) == 0 && mbsmbchar (pat) == 0) - return (skipname (pat, dname, flags)); - - ext = 0; -#if EXTENDED_GLOB - ext = extglob_pattern_p (pat); -#endif - - pat_wc = dn_wc = (wchar_t *)NULL; - - pat_n = xdupmbstowcs (&pat_wc, NULL, pat); - if (pat_n != (size_t)-1) - dn_n = xdupmbstowcs (&dn_wc, NULL, dname); - - ret = 0; - if (pat_n != (size_t)-1 && dn_n !=(size_t)-1) - ret = ext ? wextglob_skipname (pat_wc, dn_wc, flags) : wskipname (pat_wc, dn_wc, flags); - else - ret = skipname (pat, dname, flags); - - FREE (pat_wc); - FREE (dn_wc); - - return ret; -} -#endif /* HANDLE_MULTIBYTE */ - -/* Remove backslashes quoting characters in PATHNAME by modifying PATHNAME. */ -void -udequote_pathname (pathname) - char *pathname; -{ - register int i, j; - - for (i = j = 0; pathname && pathname[i]; ) - { - if (pathname[i] == '\\') - i++; - - pathname[j++] = pathname[i++]; - - if (pathname[i - 1] == 0) - break; - } - if (pathname) - pathname[j] = '\0'; -} - -#if HANDLE_MULTIBYTE -/* Remove backslashes quoting characters in PATHNAME by modifying PATHNAME. */ -void -wcdequote_pathname (wpathname) - wchar_t *wpathname; -{ - int i, j; - - for (i = j = 0; wpathname && wpathname[i]; ) - { - if (wpathname[i] == L'\\') - i++; - - wpathname[j++] = wpathname[i++]; - - if (wpathname[i - 1] == L'\0') - break; - } - if (wpathname) - wpathname[j] = L'\0'; -} - -static void -wdequote_pathname (pathname) - char *pathname; -{ - mbstate_t ps; - size_t len, n; - wchar_t *wpathname; - int i, j; - wchar_t *orig_wpathname; - - if (mbsmbchar (pathname) == 0) - { - udequote_pathname (pathname); - return; - } - - len = strlen (pathname); - /* Convert the strings into wide characters. */ - n = xdupmbstowcs (&wpathname, NULL, pathname); - if (n == (size_t) -1) - { - /* Something wrong. Fall back to single-byte */ - udequote_pathname (pathname); - return; - } - orig_wpathname = wpathname; - - wcdequote_pathname (wpathname); - - /* Convert the wide character string into unibyte character set. */ - memset (&ps, '\0', sizeof(mbstate_t)); - n = wcsrtombs(pathname, (const wchar_t **)&wpathname, len, &ps); - if (n == (size_t)-1 || (wpathname && *wpathname != 0)) /* what? now you tell me? */ - { - wpathname = orig_wpathname; - memset (&ps, '\0', sizeof(mbstate_t)); - n = xwcsrtombs (pathname, (const wchar_t **)&wpathname, len, &ps); - } - pathname[len] = '\0'; - - /* Can't just free wpathname here; wcsrtombs changes it in many cases. */ - free (orig_wpathname); -} - -static void -dequote_pathname (pathname) - char *pathname; -{ - if (MB_CUR_MAX > 1) - wdequote_pathname (pathname); - else - udequote_pathname (pathname); -} -#endif /* HANDLE_MULTIBYTE */ - -/* Test whether NAME exists. */ - -#if defined (HAVE_LSTAT) -# define GLOB_TESTNAME(name) (lstat (name, &finfo)) -#else /* !HAVE_LSTAT */ -# if !defined (AFS) -# define GLOB_TESTNAME(name) (sh_eaccess (name, F_OK)) -# else /* AFS */ -# define GLOB_TESTNAME(name) (access (name, F_OK)) -# endif /* AFS */ -#endif /* !HAVE_LSTAT */ - -/* Return 0 if DIR is a directory, -2 if DIR is a symlink, -1 otherwise. */ -static int -glob_testdir (dir, flags) - char *dir; - int flags; -{ - struct stat finfo; - int r; - -/*itrace("glob_testdir: testing %s" flags = %d, dir, flags);*/ -#if defined (HAVE_LSTAT) - r = (flags & GX_ALLDIRS) ? lstat (dir, &finfo) : stat (dir, &finfo); -#else - r = stat (dir, &finfo); -#endif - if (r < 0) - return (-1); - -#if defined (S_ISLNK) - if (S_ISLNK (finfo.st_mode)) - return (-2); -#endif - - if (S_ISDIR (finfo.st_mode) == 0) - return (-1); - - return (0); -} - -/* Recursively scan SDIR for directories matching PAT (PAT is always `**'). - FLAGS is simply passed down to the recursive call to glob_vector. Returns - a list of matching directory names. EP, if non-null, is set to the last - element of the returned list. NP, if non-null, is set to the number of - directories in the returned list. These two variables exist for the - convenience of the caller (always glob_vector). */ -static struct globval * -finddirs (pat, sdir, flags, ep, np) - char *pat; - char *sdir; - int flags; - struct globval **ep; - int *np; -{ - char **r, *n; - int ndirs; - struct globval *ret, *e, *g; - -/*itrace("finddirs: pat = `%s' sdir = `%s' flags = 0x%x", pat, sdir, flags);*/ - e = ret = 0; - r = glob_vector (pat, sdir, flags); - if (r == 0 || r[0] == 0) - { - if (np) - *np = 0; - if (ep) - *ep = 0; - if (r && r != &glob_error_return) - free (r); - return (struct globval *)0; - } - for (ndirs = 0; r[ndirs] != 0; ndirs++) - { - g = (struct globval *) malloc (sizeof (struct globval)); - if (g == 0) - { - while (ret) /* free list built so far */ - { - g = ret->next; - free (ret); - ret = g; - } - - free (r); - if (np) - *np = 0; - if (ep) - *ep = 0; - return (&finddirs_error_return); - } - if (e == 0) - e = g; - - g->next = ret; - ret = g; - - g->name = r[ndirs]; - } - - free (r); - if (ep) - *ep = e; - if (np) - *np = ndirs; - - return ret; -} - -/* Return a vector of names of files in directory DIR - whose names match glob pattern PAT. - The names are not in any particular order. - Wildcards at the beginning of PAT do not match an initial period. - - The vector is terminated by an element that is a null pointer. - - To free the space allocated, first free the vector's elements, - then free the vector. - - Return 0 if cannot get enough memory to hold the pointer - and the names. - - Return -1 if cannot access directory DIR. - Look in errno for more information. */ - -char ** -glob_vector (pat, dir, flags) - char *pat; - char *dir; - int flags; -{ - DIR *d; - register struct dirent *dp; - struct globval *lastlink, *e, *dirlist; - register struct globval *nextlink; - register char *nextname, *npat, *subdir; - unsigned int count; - int lose, skip, ndirs, isdir, sdlen, add_current, patlen; - register char **name_vector; - register unsigned int i; - int mflags; /* Flags passed to strmatch (). */ - int pflags; /* flags passed to sh_makepath () */ - int hasglob; /* return value from glob_pattern_p */ - int nalloca; - struct globval *firstmalloc, *tmplink; - char *convfn; - - lastlink = 0; - count = lose = skip = add_current = 0; - - firstmalloc = 0; - nalloca = 0; - - name_vector = NULL; - -/*itrace("glob_vector: pat = `%s' dir = `%s' flags = 0x%x", pat, dir, flags);*/ - /* If PAT is empty, skip the loop, but return one (empty) filename. */ - if (pat == 0 || *pat == '\0') - { - if (glob_testdir (dir, 0) < 0) - return ((char **) &glob_error_return); - - nextlink = (struct globval *)alloca (sizeof (struct globval)); - if (nextlink == NULL) - return ((char **) NULL); - - nextlink->next = (struct globval *)0; - nextname = (char *) malloc (1); - if (nextname == 0) - lose = 1; - else - { - lastlink = nextlink; - nextlink->name = nextname; - nextname[0] = '\0'; - count = 1; - } - - skip = 1; - } - - patlen = (pat && *pat) ? strlen (pat) : 0; - - /* If the filename pattern (PAT) does not contain any globbing characters, - or contains a pattern with only backslash escapes (hasglob == 2), - we can dispense with reading the directory, and just see if there is - a filename `DIR/PAT'. If there is, and we can access it, just make the - vector to return and bail immediately. */ - hasglob = 0; - if (skip == 0 && ((hasglob = glob_pattern_p (pat)) == 0 || hasglob == 2)) - { - int dirlen; - struct stat finfo; - - if (glob_testdir (dir, 0) < 0) - return ((char **) &glob_error_return); - - dirlen = strlen (dir); - nextname = (char *)malloc (dirlen + patlen + 2); - npat = (char *)malloc (patlen + 1); - if (nextname == 0 || npat == 0) - { - FREE (nextname); - FREE (npat); - lose = 1; - } - else - { - strcpy (npat, pat); - dequote_pathname (npat); - - strcpy (nextname, dir); - nextname[dirlen++] = '/'; - strcpy (nextname + dirlen, npat); - - if (GLOB_TESTNAME (nextname) >= 0) - { - free (nextname); - nextlink = (struct globval *)alloca (sizeof (struct globval)); - if (nextlink) - { - nextlink->next = (struct globval *)0; - lastlink = nextlink; - nextlink->name = npat; - count = 1; - } - else - { - free (npat); - lose = 1; - } - } - else - { - free (nextname); - free (npat); - } - } - - skip = 1; - } - - if (skip == 0) - { - /* Open the directory, punting immediately if we cannot. If opendir - is not robust (i.e., it opens non-directories successfully), test - that DIR is a directory and punt if it's not. */ -#if defined (OPENDIR_NOT_ROBUST) - if (glob_testdir (dir, 0) < 0) - return ((char **) &glob_error_return); -#endif - - d = opendir (dir); - if (d == NULL) - return ((char **) &glob_error_return); - - /* Compute the flags that will be passed to strmatch(). We don't - need to do this every time through the loop. */ - mflags = (noglob_dot_filenames ? FNM_PERIOD : FNM_DOTDOT) | FNM_PATHNAME; - -#ifdef FNM_CASEFOLD - if (glob_ignore_case) - mflags |= FNM_CASEFOLD; -#endif - - if (extended_glob) - mflags |= FNM_EXTMATCH; - - add_current = ((flags & (GX_ALLDIRS|GX_ADDCURDIR)) == (GX_ALLDIRS|GX_ADDCURDIR)); - - /* Scan the directory, finding all names that match For each name that matches, allocate a struct globval - on the stack and store the name in it. - Chain those structs together; lastlink is the front of the chain. */ - while (1) - { - /* Make globbing interruptible in the shell. */ - if (interrupt_state || terminating_signal) - { - lose = 1; - break; - } - else if (signal_is_pending (SIGINT)) /* XXX - make SIGINT traps responsive */ - { - lose = 1; - break; - } - - dp = readdir (d); - if (dp == NULL) - break; - - /* If this directory entry is not to be used, try again. */ - if (REAL_DIR_ENTRY (dp) == 0) - continue; - -#if 0 - if (dp->d_name == 0 || *dp->d_name == 0) - continue; -#endif - -#if HANDLE_MULTIBYTE - if (MB_CUR_MAX > 1 && mbskipname (pat, dp->d_name, flags)) - continue; - else -#endif - if (skipname (pat, dp->d_name, flags)) - continue; - - /* If we're only interested in directories, don't bother with files */ - if (flags & (GX_MATCHDIRS|GX_ALLDIRS)) - { - pflags = (flags & GX_ALLDIRS) ? MP_RMDOT : 0; - if (flags & GX_NULLDIR) - pflags |= MP_IGNDOT; - subdir = sh_makepath (dir, dp->d_name, pflags); - isdir = glob_testdir (subdir, flags); - if (isdir < 0 && (flags & GX_MATCHDIRS)) - { - free (subdir); - continue; - } - } - - if (flags & GX_ALLDIRS) - { - if (isdir == 0) - { - dirlist = finddirs (pat, subdir, (flags & ~GX_ADDCURDIR), &e, &ndirs); - if (dirlist == &finddirs_error_return) - { - free (subdir); - lose = 1; - break; - } - if (ndirs) /* add recursive directories to list */ - { - if (firstmalloc == 0) - firstmalloc = e; - e->next = lastlink; - lastlink = dirlist; - count += ndirs; - } - } - - /* XXX - should we even add this if it's not a directory? */ - nextlink = (struct globval *) malloc (sizeof (struct globval)); - if (firstmalloc == 0) - firstmalloc = nextlink; - sdlen = strlen (subdir); - nextname = (char *) malloc (sdlen + 1); - if (nextlink == 0 || nextname == 0) - { - if (firstmalloc && firstmalloc == nextlink) - firstmalloc = 0; - /* If we reset FIRSTMALLOC we can free this here. */ - FREE (nextlink); - FREE (nextname); - free (subdir); - lose = 1; - break; - } - nextlink->next = lastlink; - lastlink = nextlink; - nextlink->name = nextname; - bcopy (subdir, nextname, sdlen + 1); - free (subdir); - ++count; - continue; - } - else if (flags & GX_MATCHDIRS) - free (subdir); - - convfn = fnx_fromfs (dp->d_name, D_NAMLEN (dp)); - if (strmatch (pat, convfn, mflags) != FNM_NOMATCH) - { - if (nalloca < ALLOCA_MAX) - { - nextlink = (struct globval *) alloca (sizeof (struct globval)); - nalloca += sizeof (struct globval); - } - else - { - nextlink = (struct globval *) malloc (sizeof (struct globval)); - if (firstmalloc == 0) - firstmalloc = nextlink; - } - - nextname = (char *) malloc (D_NAMLEN (dp) + 1); - if (nextlink == 0 || nextname == 0) - { - /* We free NEXTLINK here, since it won't be added to the - LASTLINK chain. If we used malloc, and it returned non- - NULL, firstmalloc will be set to something valid. If it's - NEXTLINK, reset it before we free NEXTLINK to avoid - duplicate frees. If not, it will be taken care of by the - loop below with TMPLINK. */ - if (firstmalloc) - { - if (firstmalloc == nextlink) - firstmalloc = 0; - FREE (nextlink); - } - FREE (nextname); - lose = 1; - break; - } - nextlink->next = lastlink; - lastlink = nextlink; - nextlink->name = nextname; - bcopy (dp->d_name, nextname, D_NAMLEN (dp) + 1); - ++count; - } - } - - (void) closedir (d); - } - - /* compat: if GX_ADDCURDIR, add the passed directory also. Add an empty - directory name as a placeholder if GX_NULLDIR (in which case the passed - directory name is "."). */ - if (add_current && lose == 0) - { - sdlen = strlen (dir); - nextname = (char *)malloc (sdlen + 1); - nextlink = (struct globval *) malloc (sizeof (struct globval)); - if (nextlink == 0 || nextname == 0) - { - FREE (nextlink); - FREE (nextname); - lose = 1; - } - else - { - nextlink->name = nextname; - nextlink->next = lastlink; - lastlink = nextlink; - if (flags & GX_NULLDIR) - nextname[0] = '\0'; - else - bcopy (dir, nextname, sdlen + 1); - ++count; - } - } - - if (lose == 0) - { - name_vector = (char **) malloc ((count + 1) * sizeof (char *)); - lose |= name_vector == NULL; - } - - /* Have we run out of memory or been interrupted? */ - if (lose) - { - tmplink = 0; - - /* Here free the strings we have got. */ - while (lastlink) - { - /* Since we build the list in reverse order, the first N entries - will be allocated with malloc, if firstmalloc is set, from - lastlink to firstmalloc. */ - if (firstmalloc) - { - if (lastlink == firstmalloc) - firstmalloc = 0; - tmplink = lastlink; - } - else - tmplink = 0; - free (lastlink->name); - lastlink = lastlink->next; - FREE (tmplink); - } - - /* Don't call QUIT; here; let higher layers deal with it. */ - - return ((char **)NULL); - } - - /* Copy the name pointers from the linked list into the vector. */ - for (tmplink = lastlink, i = 0; i < count; ++i) - { - name_vector[i] = tmplink->name; - tmplink = tmplink->next; - } - - name_vector[count] = NULL; - - /* If we allocated some of the struct globvals, free them now. */ - if (firstmalloc) - { - tmplink = 0; - while (lastlink) - { - tmplink = lastlink; - if (lastlink == firstmalloc) - lastlink = firstmalloc = 0; - else - lastlink = lastlink->next; - free (tmplink); - } - } - - return (name_vector); -} - -/* Return a new array which is the concatenation of each string in ARRAY - to DIR. This function expects you to pass in an allocated ARRAY, and - it takes care of free()ing that array. Thus, you might think of this - function as side-effecting ARRAY. This should handle GX_MARKDIRS. */ -static char ** -glob_dir_to_array (dir, array, flags) - char *dir, **array; - int flags; -{ - register unsigned int i, l; - int add_slash; - char **result, *new; - struct stat sb; - - l = strlen (dir); - if (l == 0) - { - if (flags & GX_MARKDIRS) - for (i = 0; array[i]; i++) - { - if ((stat (array[i], &sb) == 0) && S_ISDIR (sb.st_mode)) - { - l = strlen (array[i]); - new = (char *)realloc (array[i], l + 2); - if (new == 0) - return NULL; - new[l] = '/'; - new[l+1] = '\0'; - array[i] = new; - } - } - return (array); - } - - add_slash = dir[l - 1] != '/'; - - i = 0; - while (array[i] != NULL) - ++i; - - result = (char **) malloc ((i + 1) * sizeof (char *)); - if (result == NULL) - return (NULL); - - for (i = 0; array[i] != NULL; i++) - { - /* 3 == 1 for NUL, 1 for slash at end of DIR, 1 for GX_MARKDIRS */ - result[i] = (char *) malloc (l + strlen (array[i]) + 3); - - if (result[i] == NULL) - { - int ind; - for (ind = 0; ind < i; ind++) - free (result[ind]); - free (result); - return (NULL); - } - - strcpy (result[i], dir); - if (add_slash) - result[i][l] = '/'; - if (array[i][0]) - { - strcpy (result[i] + l + add_slash, array[i]); - if (flags & GX_MARKDIRS) - { - if ((stat (result[i], &sb) == 0) && S_ISDIR (sb.st_mode)) - { - size_t rlen; - rlen = strlen (result[i]); - result[i][rlen] = '/'; - result[i][rlen+1] = '\0'; - } - } - } - else - result[i][l+add_slash] = '\0'; - } - result[i] = NULL; - - /* Free the input array. */ - for (i = 0; array[i] != NULL; i++) - free (array[i]); - free ((char *) array); - - return (result); -} - -/* Do globbing on PATHNAME. Return an array of pathnames that match, - marking the end of the array with a null-pointer as an element. - If no pathnames match, then the array is empty (first element is null). - If there isn't enough memory, then return NULL. - If a file system error occurs, return -1; `errno' has the error code. */ -char ** -glob_filename (pathname, flags) - char *pathname; - int flags; -{ - char **result, **new_result; - unsigned int result_size; - char *directory_name, *filename, *dname, *fn; - unsigned int directory_len; - int free_dirname; /* flag */ - int dflags, hasglob; - - result = (char **) malloc (sizeof (char *)); - result_size = 1; - if (result == NULL) - return (NULL); - - result[0] = NULL; - - directory_name = NULL; - - /* Find the filename. */ - filename = strrchr (pathname, '/'); -#if defined (EXTENDED_GLOB) - if (filename && extended_glob) - { - fn = glob_dirscan (pathname, '/'); -#if DEBUG_MATCHING - if (fn != filename) - fprintf (stderr, "glob_filename: glob_dirscan: fn (%s) != filename (%s)\n", fn ? fn : "(null)", filename); -#endif - filename = fn; - } -#endif - - if (filename == NULL) - { - filename = pathname; - directory_name = ""; - directory_len = 0; - free_dirname = 0; - } - else - { - directory_len = (filename - pathname) + 1; - directory_name = (char *) malloc (directory_len + 1); - - if (directory_name == 0) /* allocation failed? */ - { - free (result); - return (NULL); - } - - bcopy (pathname, directory_name, directory_len); - directory_name[directory_len] = '\0'; - ++filename; - free_dirname = 1; - } - - hasglob = 0; - /* If directory_name contains globbing characters, then we - have to expand the previous levels. Just recurse. - If glob_pattern_p returns != [0,1] we have a pattern that has backslash - quotes but no unquoted glob pattern characters. We dequote it below. */ - if (directory_len > 0 && (hasglob = glob_pattern_p (directory_name)) == 1) - { - char **directories, *d, *p; - register unsigned int i; - int all_starstar, last_starstar; - - all_starstar = last_starstar = 0; - d = directory_name; - dflags = flags & ~GX_MARKDIRS; - /* Collapse a sequence of ** patterns separated by one or more slashes - to a single ** terminated by a slash or NUL */ - if ((flags & GX_GLOBSTAR) && d[0] == '*' && d[1] == '*' && (d[2] == '/' || d[2] == '\0')) - { - p = d; - while (d[0] == '*' && d[1] == '*' && (d[2] == '/' || d[2] == '\0')) - { - p = d; - if (d[2]) - { - d += 3; - while (*d == '/') - d++; - if (*d == 0) - break; - } - } - if (*d == 0) - all_starstar = 1; - d = p; - dflags |= GX_ALLDIRS|GX_ADDCURDIR; - directory_len = strlen (d); - } - - /* If there is a non [star][star]/ component in directory_name, we - still need to collapse trailing sequences of [star][star]/ into - a single one and note that the directory name ends with [star][star], - so we can compensate if filename is [star][star] */ - if ((flags & GX_GLOBSTAR) && all_starstar == 0) - { - int dl, prev; - prev = dl = directory_len; - while (dl >= 4 && d[dl - 1] == '/' && - d[dl - 2] == '*' && - d[dl - 3] == '*' && - d[dl - 4] == '/') - prev = dl, dl -= 3; - if (dl != directory_len) - last_starstar = 1; - directory_len = prev; - } - - /* If the directory name ends in [star][star]/ but the filename is - [star][star], just remove the final [star][star] from the directory - so we don't have to scan everything twice. */ - if (last_starstar && directory_len > 4 && - filename[0] == '*' && filename[1] == '*' && filename[2] == 0) - { - directory_len -= 3; - } - - if (d[directory_len - 1] == '/') - d[directory_len - 1] = '\0'; - - directories = glob_filename (d, dflags|GX_RECURSE); - - if (free_dirname) - { - free (directory_name); - directory_name = NULL; - } - - if (directories == NULL) - goto memory_error; - else if (directories == (char **)&glob_error_return) - { - free ((char *) result); - return ((char **) &glob_error_return); - } - else if (*directories == NULL) - { - free ((char *) directories); - free ((char *) result); - return ((char **) &glob_error_return); - } - - /* If we have something like [star][star]/[star][star], it's no use to - glob **, then do it again, and throw half the results away. */ - if (all_starstar && filename[0] == '*' && filename[1] == '*' && filename[2] == 0) - { - free ((char *) directories); - free (directory_name); - directory_name = NULL; - directory_len = 0; - goto only_filename; - } - - /* We have successfully globbed the preceding directory name. - For each name in DIRECTORIES, call glob_vector on it and - FILENAME. Concatenate the results together. */ - for (i = 0; directories[i] != NULL; ++i) - { - char **temp_results; - int shouldbreak; - - shouldbreak = 0; - /* XXX -- we've recursively scanned any directories resulting from - a `**', so turn off the flag. We turn it on again below if - filename is `**' */ - /* Scan directory even on a NULL filename. That way, `*h/' - returns only directories ending in `h', instead of all - files ending in `h' with a `/' appended. */ - dname = directories[i]; - dflags = flags & ~(GX_MARKDIRS|GX_ALLDIRS|GX_ADDCURDIR); - /* last_starstar? */ - if ((flags & GX_GLOBSTAR) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0') - dflags |= GX_ALLDIRS|GX_ADDCURDIR; - if (dname[0] == '\0' && filename[0]) - { - dflags |= GX_NULLDIR; - dname = "."; /* treat null directory name and non-null filename as current directory */ - } - - /* Special handling for symlinks to directories with globstar on */ - if (all_starstar && (dflags & GX_NULLDIR) == 0) - { - int dlen; - - /* If we have a directory name that is not null (GX_NULLDIR above) - and is a symlink to a directory, we return the symlink if - we're not `descending' into it (filename[0] == 0) and return - glob_error_return (which causes the code below to skip the - name) otherwise. I should fold this into a test that does both - checks instead of calling stat twice. */ - if (glob_testdir (dname, flags|GX_ALLDIRS) == -2 && glob_testdir (dname, 0) == 0) - { - if (filename[0] != 0) - temp_results = (char **)&glob_error_return; /* skip */ - else - { - /* Construct array to pass to glob_dir_to_array */ - temp_results = (char **)malloc (2 * sizeof (char *)); - if (temp_results == NULL) - goto memory_error; - temp_results[0] = (char *)malloc (1); - if (temp_results[0] == 0) - { - free (temp_results); - goto memory_error; - } - **temp_results = '\0'; - temp_results[1] = NULL; - dflags |= GX_SYMLINK; /* mostly for debugging */ - } - } - else - temp_results = glob_vector (filename, dname, dflags); - } - else - temp_results = glob_vector (filename, dname, dflags); - - /* Handle error cases. */ - if (temp_results == NULL) - goto memory_error; - else if (temp_results == (char **)&glob_error_return) - /* This filename is probably not a directory. Ignore it. */ - ; - else - { - char **array; - register unsigned int l; - - /* If we're expanding **, we don't need to glue the directory - name to the results; we've already done it in glob_vector */ - if ((dflags & GX_ALLDIRS) && filename[0] == '*' && filename[1] == '*' && (filename[2] == '\0' || filename[2] == '/')) - { - /* When do we remove null elements from temp_results? And - how to avoid duplicate elements in the final result? */ - /* If (dflags & GX_NULLDIR) glob_filename potentially left a - NULL placeholder in the temp results just in case - glob_vector/glob_dir_to_array did something with it, but - if it didn't, and we're not supposed to be passing them - through for some reason ((flags & GX_NULLDIR) == 0) we - need to remove all the NULL elements from the beginning - of TEMP_RESULTS. */ - /* If we have a null directory name and ** as the filename, - we have just searched for everything from the current - directory on down. Break now (shouldbreak = 1) to avoid - duplicate entries in the final result. */ -#define NULL_PLACEHOLDER(x) ((x) && *(x) && **(x) == 0) - if ((dflags & GX_NULLDIR) && (flags & GX_NULLDIR) == 0 && - NULL_PLACEHOLDER (temp_results)) -#undef NULL_PLACEHOLDER - { - register int i, n; - for (n = 0; temp_results[n] && *temp_results[n] == 0; n++) - ; - i = n; - do - temp_results[i - n] = temp_results[i]; - while (temp_results[i++] != 0); - array = temp_results; - shouldbreak = 1; - } - else - array = temp_results; - } - else if (dflags & GX_SYMLINK) - array = glob_dir_to_array (directories[i], temp_results, flags); - else - array = glob_dir_to_array (directories[i], temp_results, flags); - l = 0; - while (array[l] != NULL) - ++l; - - new_result = (char **)realloc (result, (result_size + l) * sizeof (char *)); - - if (new_result == NULL) - { - for (l = 0; array[l]; ++l) - free (array[l]); - free ((char *)array); - goto memory_error; - } - result = new_result; - - for (l = 0; array[l] != NULL; ++l) - result[result_size++ - 1] = array[l]; - - result[result_size - 1] = NULL; - - /* Note that the elements of ARRAY are not freed. */ - if (array != temp_results) - free ((char *) array); - else if ((dflags & GX_ALLDIRS) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0') - free (temp_results); /* expanding ** case above */ - - if (shouldbreak) - break; - } - } - /* Free the directories. */ - for (i = 0; directories[i]; i++) - free (directories[i]); - - free ((char *) directories); - - return (result); - } - -only_filename: - /* If there is only a directory name, return it. */ - if (*filename == '\0') - { - result = (char **) realloc ((char *) result, 2 * sizeof (char *)); - if (result == NULL) - { - if (free_dirname) - free (directory_name); - return (NULL); - } - /* If we have a directory name with quoted characters, and we are - being called recursively to glob the directory portion of a pathname, - we need to dequote the directory name before returning it so the - caller can read the directory */ - if (directory_len > 0 && hasglob == 2 && (flags & GX_RECURSE) != 0) - { - dequote_pathname (directory_name); - directory_len = strlen (directory_name); - } - - /* We could check whether or not the dequoted directory_name is a - directory and return it here, returning the original directory_name - if not, but we don't do that. We do return the dequoted directory - name if we're not being called recursively and the dequoted name - corresponds to an actual directory. For better backwards compatibility, - we can return &glob_error_return unconditionally in this case. */ - - if (directory_len > 0 && hasglob == 2 && (flags & GX_RECURSE) == 0) - { - dequote_pathname (directory_name); - if (glob_testdir (directory_name, 0) < 0) - { - if (free_dirname) - free (directory_name); - free ((char *) result); - return ((char **)&glob_error_return); - } - } - - /* Handle GX_MARKDIRS here. */ - result[0] = (char *) malloc (directory_len + 1); - if (result[0] == NULL) - goto memory_error; - bcopy (directory_name, result[0], directory_len + 1); - if (free_dirname) - free (directory_name); - result[1] = NULL; - return (result); - } - else - { - char **temp_results; - - /* There are no unquoted globbing characters in DIRECTORY_NAME. - Dequote it before we try to open the directory since there may - be quoted globbing characters which should be treated verbatim. */ - if (directory_len > 0) - dequote_pathname (directory_name); - - /* We allocated a small array called RESULT, which we won't be using. - Free that memory now. */ - free (result); - - /* Just return what glob_vector () returns appended to the - directory name. */ - /* If flags & GX_ALLDIRS, we're called recursively */ - dflags = flags & ~GX_MARKDIRS; - if (directory_len == 0) - dflags |= GX_NULLDIR; - if ((flags & GX_GLOBSTAR) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0') - { - dflags |= GX_ALLDIRS|GX_ADDCURDIR; -#if 0 - /* If we want all directories (dflags & GX_ALLDIRS) and we're not - being called recursively as something like `echo [star][star]/[star].o' - ((flags & GX_ALLDIRS) == 0), we want to prevent glob_vector from - adding a null directory name to the front of the temp_results - array. We turn off ADDCURDIR if not called recursively and - dlen == 0 */ -#endif - if (directory_len == 0 && (flags & GX_ALLDIRS) == 0) - dflags &= ~GX_ADDCURDIR; - } - temp_results = glob_vector (filename, - (directory_len == 0 ? "." : directory_name), - dflags); - - if (temp_results == NULL || temp_results == (char **)&glob_error_return) - { - if (free_dirname) - free (directory_name); - QUIT; /* XXX - shell */ - run_pending_traps (); - return (temp_results); - } - - result = glob_dir_to_array ((dflags & GX_ALLDIRS) ? "" : directory_name, temp_results, flags); - - if (free_dirname) - free (directory_name); - return (result); - } - - /* We get to memory_error if the program has run out of memory, or - if this is the shell, and we have been interrupted. */ - memory_error: - if (result != NULL) - { - register unsigned int i; - for (i = 0; result[i] != NULL; ++i) - free (result[i]); - free ((char *) result); - } - - if (free_dirname && directory_name) - free (directory_name); - - QUIT; - run_pending_traps (); - - return (NULL); -} - -#if defined (TEST) - -main (argc, argv) - int argc; - char **argv; -{ - unsigned int i; - - for (i = 1; i < argc; ++i) - { - char **value = glob_filename (argv[i], 0); - if (value == NULL) - puts ("Out of memory."); - else if (value == &glob_error_return) - perror (argv[i]); - else - for (i = 0; value[i] != NULL; i++) - puts (value[i]); - } - - exit (0); -} -#endif /* TEST. */ diff --git a/third_party/bash/glob.h b/third_party/bash/glob.h deleted file mode 100644 index 47410577c..000000000 --- a/third_party/bash/glob.h +++ /dev/null @@ -1,47 +0,0 @@ -/* File-name wildcard pattern matching for GNU. - Copyright (C) 1985-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne-Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#ifndef _GLOB_H_ -#define _GLOB_H_ - -#include "stdc.h" - -#define GX_MARKDIRS 0x001 /* mark directory names with trailing `/' */ -#define GX_NOCASE 0x002 /* ignore case */ -#define GX_MATCHDOT 0x004 /* match `.' literally */ -#define GX_MATCHDIRS 0x008 /* match only directory names */ -#define GX_ALLDIRS 0x010 /* match all directory names, no others */ -#define GX_NULLDIR 0x100 /* internal -- no directory preceding pattern */ -#define GX_ADDCURDIR 0x200 /* internal -- add passed directory name */ -#define GX_GLOBSTAR 0x400 /* turn on special handling of ** */ -#define GX_RECURSE 0x800 /* internal -- glob_filename called recursively */ -#define GX_SYMLINK 0x1000 /* internal -- symlink to a directory */ -#define GX_NEGATE 0x2000 /* internal -- extglob pattern being negated */ - -extern int glob_pattern_p PARAMS((const char *)); -extern char **glob_vector PARAMS((char *, char *, int)); -extern char **glob_filename PARAMS((char *, int)); - -extern int extglob_pattern_p PARAMS((const char *)); - -extern char *glob_error_return; -extern int noglob_dot_filenames; -extern int glob_ignore_case; - -#endif /* _GLOB_H_ */ diff --git a/third_party/bash/glob_loop.inc b/third_party/bash/glob_loop.inc deleted file mode 100644 index 467e7ae33..000000000 --- a/third_party/bash/glob_loop.inc +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright (C) 1991-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -static int INTERNAL_GLOB_PATTERN_P PARAMS((const GCHAR *)); - -/* Return nonzero if PATTERN has any special globbing chars in it. - Compiled twice, once each for single-byte and multibyte characters. */ -static int -INTERNAL_GLOB_PATTERN_P (pattern) - const GCHAR *pattern; -{ - register const GCHAR *p; - register GCHAR c; - int bopen, bsquote; - - p = pattern; - bopen = bsquote = 0; - - while ((c = *p++) != L('\0')) - switch (c) - { - case L('?'): - case L('*'): - return 1; - - case L('['): /* Only accept an open brace if there is a close */ - bopen++; /* brace to match it. Bracket expressions must be */ - continue; /* complete, according to Posix.2 */ - case L(']'): - if (bopen) - return 1; - continue; - - case L('+'): /* extended matching operators */ - case L('@'): - case L('!'): - if (*p == L('(')) /*) */ - return 1; - continue; - - case L('\\'): - /* Don't let the pattern end in a backslash (GMATCH returns no match - if the pattern ends in a backslash anyway), but otherwise note that - we have seen this, since the matching engine uses backslash as an - escape character and it can be removed. We return 2 later if we - have seen only backslash-escaped characters, so interested callers - know they can shortcut and just dequote the pathname. */ - if (*p != L('\0')) - { - p++; - bsquote = 1; - continue; - } - else /* (*p == L('\0')) */ - return 0; - } - -#if 0 - return bsquote ? 2 : 0; -#else - return (0); -#endif -} - -#undef INTERNAL_GLOB_PATTERN_P -#undef L -#undef INT -#undef CHAR -#undef GCHAR diff --git a/third_party/bash/gm_loop.inc b/third_party/bash/gm_loop.inc deleted file mode 100644 index ac516f82c..000000000 --- a/third_party/bash/gm_loop.inc +++ /dev/null @@ -1,208 +0,0 @@ -/* Copyright (C) 1991-2017 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if EXTENDED_GLOB -int -EXTGLOB_PATTERN_P (pat) - const CHAR *pat; -{ - switch (pat[0]) - { - case L('*'): - case L('+'): - case L('!'): - case L('@'): - case L('?'): - return (pat[1] == L('(')); /* ) */ - default: - return 0; - } - - return 0; -} -#endif - -/* Return 1 of the first character of STRING could match the first - character of pattern PAT. Compiled to both single and wiide character - versions. FLAGS is a subset of strmatch flags; used to do case-insensitive - matching for now. */ -int -MATCH_PATTERN_CHAR (pat, string, flags) - CHAR *pat, *string; - int flags; -{ - CHAR c; - - if (*string == 0) - return (*pat == L('*')); /* XXX - allow only * to match empty string */ - - switch (c = *pat++) - { - default: - return (FOLD(*string) == FOLD(c)); - case L('\\'): - return (FOLD(*string) == FOLD(*pat)); - case L('?'): - return (*pat == L('(') ? 1 : (*string != L'\0')); - case L('*'): - return (1); - case L('+'): - case L('!'): - case L('@'): - return (*pat == L('(') ? 1 : (FOLD(*string) == FOLD(c))); - case L('['): - return (*string != L('\0')); - } -} - -int -MATCHLEN (pat, max) - CHAR *pat; - size_t max; -{ - CHAR c; - int matlen, bracklen, t, in_cclass, in_collsym, in_equiv; - - if (*pat == 0) - return (0); - - matlen = in_cclass = in_collsym = in_equiv = 0; - while (c = *pat++) - { - switch (c) - { - default: - matlen++; - break; - case L('\\'): - if (*pat == 0) - return ++matlen; - else - { - matlen++; - pat++; - } - break; - case L('?'): - if (*pat == LPAREN) - return (matlen = -1); /* XXX for now */ - else - matlen++; - break; - case L('*'): - return (matlen = -1); - case L('+'): - case L('!'): - case L('@'): - if (*pat == LPAREN) - return (matlen = -1); /* XXX for now */ - else - matlen++; - break; - case L('['): - /* scan for ending `]', skipping over embedded [:...:] */ - bracklen = 1; - c = *pat++; - do - { - if (c == 0) - { - pat--; /* back up to NUL */ - matlen += bracklen; - goto bad_bracket; - } - else if (c == L('\\')) - { - /* *pat == backslash-escaped character */ - bracklen++; - /* If the backslash or backslash-escape ends the string, - bail. The ++pat skips over the backslash escape */ - if (*pat == 0 || *++pat == 0) - { - matlen += bracklen; - goto bad_bracket; - } - } - else if (c == L('[') && *pat == L(':')) /* character class */ - { - pat++; - bracklen++; - in_cclass = 1; - } - else if (in_cclass && c == L(':') && *pat == L(']')) - { - pat++; - bracklen++; - in_cclass = 0; - } - else if (c == L('[') && *pat == L('.')) /* collating symbol */ - { - pat++; - bracklen++; - if (*pat == L(']')) /* right bracket can appear as collating symbol */ - { - pat++; - bracklen++; - } - in_collsym = 1; - } - else if (in_collsym && c == L('.') && *pat == L(']')) - { - pat++; - bracklen++; - in_collsym = 0; - } - else if (c == L('[') && *pat == L('=')) /* equivalence class */ - { - pat++; - bracklen++; - if (*pat == L(']')) /* right bracket can appear as equivalence class */ - { - pat++; - bracklen++; - } - in_equiv = 1; - } - else if (in_equiv && c == L('=') && *pat == L(']')) - { - pat++; - bracklen++; - in_equiv = 0; - } - else - bracklen++; - } - while ((c = *pat++) != L(']')); - matlen++; /* bracket expression can only match one char */ -bad_bracket: - break; - } - } - - return matlen; -} - -#undef EXTGLOB_PATTERN_P -#undef MATCH_PATTERN_CHAR -#undef MATCHLEN -#undef FOLD -#undef L -#undef LPAREN -#undef RPAREN -#undef INT -#undef CHAR diff --git a/third_party/bash/gmisc.c b/third_party/bash/gmisc.c deleted file mode 100644 index 11d3b0294..000000000 --- a/third_party/bash/gmisc.c +++ /dev/null @@ -1,108 +0,0 @@ -/* gmisc.c -- miscellaneous pattern matching utility functions for Bash. - - Copyright (C) 2010-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne-Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include "bashtypes.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "bashansi.h" -#include "shmbutil.h" -#include "chartypes.h" - -#include "stdc.h" - -#ifndef FNM_CASEFOLD -# include "strmatch.h" -#endif -#include "glob.h" - -/* Make sure these names continue to agree with what's in smatch.c */ -extern char *glob_patscan PARAMS((char *, char *, int)); - -/* Compile `gm_loop.inc' for single-byte characters. */ -#define CHAR char -#define INT int -#define L(CS) CS -#define EXTGLOB_PATTERN_P extglob_pattern_p -#define MATCH_PATTERN_CHAR match_pattern_char -#define MATCHLEN umatchlen -#define FOLD(c) ((flags & FNM_CASEFOLD) \ - ? TOLOWER ((unsigned char)c) \ - : ((unsigned char)c)) -#ifndef LPAREN -#define LPAREN '(' -#define RPAREN ')' -#endif -#include "gm_loop.inc" - -/* Compile `gm_loop.inc' again for multibyte characters. */ -#if HANDLE_MULTIBYTE - -#define CHAR wchar_t -#define INT wint_t -#define L(CS) L##CS -#define EXTGLOB_PATTERN_P wextglob_pattern_p -#define MATCH_PATTERN_CHAR match_pattern_wchar -#define MATCHLEN wmatchlen - -#define FOLD(c) ((flags & FNM_CASEFOLD) && iswupper (c) ? towlower (c) : (c)) -#define LPAREN L'(' -#define RPAREN L')' -#include "gm_loop.inc" - -#endif /* HANDLE_MULTIBYTE */ - - -#if defined (EXTENDED_GLOB) -/* Skip characters in PAT and return the final occurrence of DIRSEP. This - is only called when extended_glob is set, so we have to skip over extglob - patterns x(...) */ -char * -glob_dirscan (pat, dirsep) - char *pat; - int dirsep; -{ - char *p, *d, *pe, *se; - - d = pe = se = 0; - for (p = pat; p && *p; p++) - { - if (extglob_pattern_p (p)) - { - if (se == 0) - se = p + strlen (p) - 1; - pe = glob_patscan (p + 2, se, 0); - if (pe == 0) - continue; - else if (*pe == 0) - break; - p = pe - 1; /* will do increment above */ - continue; - } - if (*p == dirsep) - d = p; - } - return d; -} -#endif /* EXTENDED_GLOB */ diff --git a/third_party/bash/hashcmd.c b/third_party/bash/hashcmd.c deleted file mode 100644 index f6e6f11d1..000000000 --- a/third_party/bash/hashcmd.c +++ /dev/null @@ -1,195 +0,0 @@ -/* hashcmd.c - functions for managing a hash table mapping command names to - full pathnames. */ - -/* Copyright (C) 1997-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include "bashtypes.h" -#include "posixstat.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "bashansi.h" - -#include "shell.h" -#include "flags.h" -#include "findcmd.h" -#include "hashcmd.h" - -HASH_TABLE *hashed_filenames = (HASH_TABLE *)NULL; - -static void phash_freedata PARAMS((PTR_T)); - -void -phash_create () -{ - if (hashed_filenames == 0) - hashed_filenames = hash_create (FILENAME_HASH_BUCKETS); -} - -static void -phash_freedata (data) - PTR_T data; -{ - free (((PATH_DATA *)data)->path); - free (data); -} - -void -phash_flush () -{ - if (hashed_filenames) - hash_flush (hashed_filenames, phash_freedata); -} - -/* Remove FILENAME from the table of hashed commands. */ -int -phash_remove (filename) - const char *filename; -{ - register BUCKET_CONTENTS *item; - - if (hashing_enabled == 0 || hashed_filenames == 0) - return 0; - - item = hash_remove (filename, hashed_filenames, 0); - if (item) - { - if (item->data) - phash_freedata (item->data); - free (item->key); - free (item); - return 0; - } - return 1; -} - -/* Place FILENAME (key) and FULL_PATH (data->path) into the - hash table. CHECK_DOT if non-null is for future calls to - phash_search (); it means that this file was found - in a directory in $PATH that is not an absolute pathname. - FOUND is the initial value for times_found. */ -void -phash_insert (filename, full_path, check_dot, found) - char *filename, *full_path; - int check_dot, found; -{ - register BUCKET_CONTENTS *item; - - if (hashing_enabled == 0) - return; - - if (hashed_filenames == 0) - phash_create (); - - item = hash_insert (filename, hashed_filenames, 0); - if (item->data) - free (pathdata(item)->path); - else - { - item->key = savestring (filename); - item->data = xmalloc (sizeof (PATH_DATA)); - } - pathdata(item)->path = savestring (full_path); - pathdata(item)->flags = 0; - if (check_dot) - pathdata(item)->flags |= HASH_CHKDOT; - if (*full_path != '/') - pathdata(item)->flags |= HASH_RELPATH; - item->times_found = found; -} - -/* Return the full pathname that FILENAME hashes to. If FILENAME - is hashed, but (data->flags & HASH_CHKDOT) is non-zero, check - ./FILENAME and return that if it is executable. This always - returns a newly-allocated string; the caller is responsible - for freeing it. */ -char * -phash_search (filename) - const char *filename; -{ - register BUCKET_CONTENTS *item; - char *path, *dotted_filename, *tail; - int same; - - if (hashing_enabled == 0 || hashed_filenames == 0) - return ((char *)NULL); - - item = hash_search (filename, hashed_filenames, 0); - - if (item == NULL) - return ((char *)NULL); - - /* If this filename is hashed, but `.' comes before it in the path, - see if ./filename is executable. If the hashed value is not an - absolute pathname, see if ./`hashed-value' exists. */ - path = pathdata(item)->path; - if (pathdata(item)->flags & (HASH_CHKDOT|HASH_RELPATH)) - { - tail = (pathdata(item)->flags & HASH_RELPATH) ? path : (char *)filename; /* XXX - fix const later */ - /* If the pathname does not start with a `./', add a `./' to it. */ - if (tail[0] != '.' || tail[1] != '/') - { - dotted_filename = (char *)xmalloc (3 + strlen (tail)); - dotted_filename[0] = '.'; dotted_filename[1] = '/'; - strcpy (dotted_filename + 2, tail); - } - else - dotted_filename = savestring (tail); - - if (executable_file (dotted_filename)) - return (dotted_filename); - - free (dotted_filename); - -#if 0 - if (pathdata(item)->flags & HASH_RELPATH) - return ((char *)NULL); -#endif - - /* Watch out. If this file was hashed to "./filename", and - "./filename" is not executable, then return NULL. */ - - /* Since we already know "./filename" is not executable, what - we're really interested in is whether or not the `path' - portion of the hashed filename is equivalent to the current - directory, but only if it starts with a `.'. (This catches - ./. and so on.) same_file () tests general Unix file - equivalence -- same device and inode. */ - if (*path == '.') - { - same = 0; - tail = (char *)strrchr (path, '/'); - - if (tail) - { - *tail = '\0'; - same = same_file (".", path, (struct stat *)NULL, (struct stat *)NULL); - *tail = '/'; - } - - return same ? (char *)NULL : savestring (path); - } - } - - return (savestring (path)); -} diff --git a/third_party/bash/hashcmd.h b/third_party/bash/hashcmd.h deleted file mode 100644 index 2459f2004..000000000 --- a/third_party/bash/hashcmd.h +++ /dev/null @@ -1,43 +0,0 @@ -/* hashcmd.h - Common defines for hashing filenames. */ - -/* Copyright (C) 1993-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "stdc.h" -#include "hashlib.h" - -#define FILENAME_HASH_BUCKETS 256 /* must be power of two */ - -extern HASH_TABLE *hashed_filenames; - -typedef struct _pathdata { - char *path; /* The full pathname of the file. */ - int flags; -} PATH_DATA; - -#define HASH_RELPATH 0x01 /* this filename is a relative pathname. */ -#define HASH_CHKDOT 0x02 /* check `.' since it was earlier in $PATH */ - -#define pathdata(x) ((PATH_DATA *)(x)->data) - -extern void phash_create PARAMS((void)); -extern void phash_flush PARAMS((void)); - -extern void phash_insert PARAMS((char *, char *, int, int)); -extern int phash_remove PARAMS((const char *)); -extern char *phash_search PARAMS((const char *)); diff --git a/third_party/bash/hashlib.c b/third_party/bash/hashlib.c deleted file mode 100644 index a3c896051..000000000 --- a/third_party/bash/hashlib.c +++ /dev/null @@ -1,545 +0,0 @@ -/* hashlib.c -- functions to manage and access hash tables for bash. */ - -/* Copyright (C) 1987,1989,1991,1995,1998,2001,2003,2005,2006,2008,2009 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include "bashansi.h" - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include - -#include "shell.h" -#include "hashlib.h" - -/* tunable constants for rehashing */ -#define HASH_REHASH_MULTIPLIER 4 -#define HASH_REHASH_FACTOR 2 - -#define HASH_SHOULDGROW(table) \ - ((table)->nentries >= (table)->nbuckets * HASH_REHASH_FACTOR) - -/* an initial approximation */ -#define HASH_SHOULDSHRINK(table) \ - (((table)->nbuckets > DEFAULT_HASH_BUCKETS) && \ - ((table)->nentries < (table)->nbuckets / HASH_REHASH_MULTIPLIER)) - -/* Rely on properties of unsigned division (unsigned/int -> unsigned) and - don't discard the upper 32 bits of the value, if present. */ -#define HASH_BUCKET(s, t, h) (((h) = hash_string (s)) & ((t)->nbuckets - 1)) - -static BUCKET_CONTENTS *copy_bucket_array PARAMS((BUCKET_CONTENTS *, sh_string_func_t *)); - -static void hash_rehash PARAMS((HASH_TABLE *, int)); -static void hash_grow PARAMS((HASH_TABLE *)); -static void hash_shrink PARAMS((HASH_TABLE *)); - -/* Make a new hash table with BUCKETS number of buckets. Initialize - each slot in the table to NULL. */ -HASH_TABLE * -hash_create (buckets) - int buckets; -{ - HASH_TABLE *new_table; - register int i; - - new_table = (HASH_TABLE *)xmalloc (sizeof (HASH_TABLE)); - if (buckets == 0) - buckets = DEFAULT_HASH_BUCKETS; - - new_table->bucket_array = - (BUCKET_CONTENTS **)xmalloc (buckets * sizeof (BUCKET_CONTENTS *)); - new_table->nbuckets = buckets; - new_table->nentries = 0; - - for (i = 0; i < buckets; i++) - new_table->bucket_array[i] = (BUCKET_CONTENTS *)NULL; - - return (new_table); -} - -int -hash_size (table) - HASH_TABLE *table; -{ - return (HASH_ENTRIES(table)); -} - -static BUCKET_CONTENTS * -copy_bucket_array (ba, cpdata) - BUCKET_CONTENTS *ba; - sh_string_func_t *cpdata; /* data copy function */ -{ - BUCKET_CONTENTS *new_bucket, *n, *e; - - if (ba == 0) - return ((BUCKET_CONTENTS *)0); - - for (n = (BUCKET_CONTENTS *)0, e = ba; e; e = e->next) - { - if (n == 0) - { - new_bucket = (BUCKET_CONTENTS *)xmalloc (sizeof (BUCKET_CONTENTS)); - n = new_bucket; - } - else - { - n->next = (BUCKET_CONTENTS *)xmalloc (sizeof (BUCKET_CONTENTS)); - n = n->next; - } - - n->key = savestring (e->key); - n->data = e->data ? (cpdata ? (*cpdata) (e->data) : savestring (e->data)) - : NULL; - n->khash = e->khash; - n->times_found = e->times_found; - n->next = (BUCKET_CONTENTS *)NULL; - } - - return new_bucket; -} - -static void -hash_rehash (table, nsize) - HASH_TABLE *table; - int nsize; -{ - int osize, i, j; - BUCKET_CONTENTS **old_bucket_array, *item, *next; - - if (table == NULL || nsize == table->nbuckets) - return; - - osize = table->nbuckets; - old_bucket_array = table->bucket_array; - - table->nbuckets = nsize; - table->bucket_array = (BUCKET_CONTENTS **)xmalloc (table->nbuckets * sizeof (BUCKET_CONTENTS *)); - for (i = 0; i < table->nbuckets; i++) - table->bucket_array[i] = (BUCKET_CONTENTS *)NULL; - - for (j = 0; j < osize; j++) - { - for (item = old_bucket_array[j]; item; item = next) - { - next = item->next; - i = item->khash & (table->nbuckets - 1); - item->next = table->bucket_array[i]; - table->bucket_array[i] = item; - } - } - - free (old_bucket_array); -} - -static void -hash_grow (table) - HASH_TABLE *table; -{ - int nsize; - - nsize = table->nbuckets * HASH_REHASH_MULTIPLIER; - if (nsize > 0) /* overflow */ - hash_rehash (table, nsize); -} - -static void -hash_shrink (table) - HASH_TABLE *table; -{ - int nsize; - - nsize = table->nbuckets / HASH_REHASH_MULTIPLIER; - hash_rehash (table, nsize); -} - -HASH_TABLE * -hash_copy (table, cpdata) - HASH_TABLE *table; - sh_string_func_t *cpdata; -{ - HASH_TABLE *new_table; - int i; - - if (table == 0) - return ((HASH_TABLE *)NULL); - - new_table = hash_create (table->nbuckets); - - for (i = 0; i < table->nbuckets; i++) - new_table->bucket_array[i] = copy_bucket_array (table->bucket_array[i], cpdata); - - new_table->nentries = table->nentries; - return new_table; -} - -/* This is the best 32-bit string hash function I found. It's one of the - Fowler-Noll-Vo family (FNV-1). - - The magic is in the interesting relationship between the special prime - 16777619 (2^24 + 403) and 2^32 and 2^8. */ - -#define FNV_OFFSET 2166136261 -#define FNV_PRIME 16777619 - -/* If you want to use 64 bits, use -FNV_OFFSET 14695981039346656037 -FNV_PRIME 1099511628211 -*/ - -/* The `khash' check below requires that strings that compare equally with - strcmp hash to the same value. */ -unsigned int -hash_string (s) - const char *s; -{ - register unsigned int i; - - for (i = FNV_OFFSET; *s; s++) - { - /* FNV-1a has the XOR first, traditional FNV-1 has the multiply first */ - - /* was i *= FNV_PRIME */ - i += (i<<1) + (i<<4) + (i<<7) + (i<<8) + (i<<24); - i ^= *s; - } - - return i; -} - -/* Return the location of the bucket which should contain the data - for STRING. TABLE is a pointer to a HASH_TABLE. */ - -int -hash_bucket (string, table) - const char *string; - HASH_TABLE *table; -{ - unsigned int h; - - return (HASH_BUCKET (string, table, h)); -} - -/* Return a pointer to the hashed item. If the HASH_CREATE flag is passed, - create a new hash table entry for STRING, otherwise return NULL. */ -BUCKET_CONTENTS * -hash_search (string, table, flags) - const char *string; - HASH_TABLE *table; - int flags; -{ - BUCKET_CONTENTS *list; - int bucket; - unsigned int hv; - - if (table == 0 || ((flags & HASH_CREATE) == 0 && HASH_ENTRIES (table) == 0)) - return (BUCKET_CONTENTS *)NULL; - - bucket = HASH_BUCKET (string, table, hv); - - for (list = table->bucket_array ? table->bucket_array[bucket] : 0; list; list = list->next) - { - /* This is the comparison function */ - if (hv == list->khash && STREQ (list->key, string)) - { - list->times_found++; - return (list); - } - } - - if (flags & HASH_CREATE) - { - if (HASH_SHOULDGROW (table)) - { - hash_grow (table); - bucket = HASH_BUCKET (string, table, hv); - } - - list = (BUCKET_CONTENTS *)xmalloc (sizeof (BUCKET_CONTENTS)); - list->next = table->bucket_array[bucket]; - table->bucket_array[bucket] = list; - - list->data = NULL; - list->key = (char *)string; /* XXX fix later */ - list->khash = hv; - list->times_found = 0; - - table->nentries++; - return (list); - } - - return (BUCKET_CONTENTS *)NULL; -} - -/* Remove the item specified by STRING from the hash table TABLE. - The item removed is returned, so you can free its contents. If - the item isn't in this table NULL is returned. */ -BUCKET_CONTENTS * -hash_remove (string, table, flags) - const char *string; - HASH_TABLE *table; - int flags; -{ - int bucket; - BUCKET_CONTENTS *prev, *temp; - unsigned int hv; - - if (table == 0 || HASH_ENTRIES (table) == 0) - return (BUCKET_CONTENTS *)NULL; - - bucket = HASH_BUCKET (string, table, hv); - prev = (BUCKET_CONTENTS *)NULL; - for (temp = table->bucket_array[bucket]; temp; temp = temp->next) - { - if (hv == temp->khash && STREQ (temp->key, string)) - { - if (prev) - prev->next = temp->next; - else - table->bucket_array[bucket] = temp->next; - - table->nentries--; - return (temp); - } - prev = temp; - } - return ((BUCKET_CONTENTS *) NULL); -} - -/* Create an entry for STRING, in TABLE. If the entry already - exists, then return it (unless the HASH_NOSRCH flag is set). */ -BUCKET_CONTENTS * -hash_insert (string, table, flags) - char *string; - HASH_TABLE *table; - int flags; -{ - BUCKET_CONTENTS *item; - int bucket; - unsigned int hv; - - if (table == 0) - table = hash_create (0); - - item = (flags & HASH_NOSRCH) ? (BUCKET_CONTENTS *)NULL - : hash_search (string, table, 0); - - if (item == 0) - { - if (HASH_SHOULDGROW (table)) - hash_grow (table); - - bucket = HASH_BUCKET (string, table, hv); - - item = (BUCKET_CONTENTS *)xmalloc (sizeof (BUCKET_CONTENTS)); - item->next = table->bucket_array[bucket]; - table->bucket_array[bucket] = item; - - item->data = NULL; - item->key = string; - item->khash = hv; - item->times_found = 0; - - table->nentries++; - } - - return (item); -} - -/* Remove and discard all entries in TABLE. If FREE_DATA is non-null, it - is a function to call to dispose of a hash item's data. Otherwise, - free() is called. */ -void -hash_flush (table, free_data) - HASH_TABLE *table; - sh_free_func_t *free_data; -{ - int i; - register BUCKET_CONTENTS *bucket, *item; - - if (table == 0 || HASH_ENTRIES (table) == 0) - return; - - for (i = 0; i < table->nbuckets; i++) - { - bucket = table->bucket_array[i]; - - while (bucket) - { - item = bucket; - bucket = bucket->next; - - if (free_data) - (*free_data) (item->data); - else - free (item->data); - free (item->key); - free (item); - } - table->bucket_array[i] = (BUCKET_CONTENTS *)NULL; - } - - table->nentries = 0; -} - -/* Free the hash table pointed to by TABLE. */ -void -hash_dispose (table) - HASH_TABLE *table; -{ - free (table->bucket_array); - free (table); -} - -void -hash_walk (table, func) - HASH_TABLE *table; - hash_wfunc *func; -{ - register int i; - BUCKET_CONTENTS *item; - - if (table == 0 || HASH_ENTRIES (table) == 0) - return; - - for (i = 0; i < table->nbuckets; i++) - { - for (item = hash_items (i, table); item; item = item->next) - if ((*func) (item) < 0) - return; - } -} - -#if defined (DEBUG) || defined (TEST_HASHING) -void -hash_pstats (table, name) - HASH_TABLE *table; - char *name; -{ - register int slot, bcount; - register BUCKET_CONTENTS *bc; - - if (name == 0) - name = "unknown hash table"; - - fprintf (stderr, "%s: %d buckets; %d items\n", name, table->nbuckets, table->nentries); - - /* Print out a count of how many strings hashed to each bucket, so we can - see how even the distribution is. */ - for (slot = 0; slot < table->nbuckets; slot++) - { - bc = hash_items (slot, table); - - fprintf (stderr, "\tslot %3d: ", slot); - for (bcount = 0; bc; bc = bc->next) - bcount++; - - fprintf (stderr, "%d\n", bcount); - } -} -#endif - -#ifdef TEST_HASHING - -/* link with xmalloc.o and lib/malloc/libmalloc.a */ -#undef NULL -#include - -#ifndef NULL -#define NULL 0 -#endif - -HASH_TABLE *table, *ntable; - -int interrupt_immediately = 0; -int running_trap = 0; - -int -signal_is_trapped (s) - int s; -{ - return (0); -} - -void -programming_error (const char *format, ...) -{ - abort(); -} - -void -fatal_error (const char *format, ...) -{ - abort(); -} - -void -internal_warning (const char *format, ...) -{ -} - -int -main () -{ - char string[256]; - int count = 0; - BUCKET_CONTENTS *tt; - -#if defined (TEST_NBUCKETS) - table = hash_create (TEST_NBUCKETS); -#else - table = hash_create (0); -#endif - - for (;;) - { - char *temp_string; - if (fgets (string, sizeof (string), stdin) == 0) - break; - if (!*string) - break; - temp_string = savestring (string); - tt = hash_insert (temp_string, table, 0); - if (tt->times_found) - { - fprintf (stderr, "You have already added item `%s'\n", string); - free (temp_string); - } - else - { - count++; - } - } - - hash_pstats (table, "hash test"); - - ntable = hash_copy (table, (sh_string_func_t *)NULL); - hash_flush (table, (sh_free_func_t *)NULL); - hash_pstats (ntable, "hash copy test"); - - exit (0); -} - -#endif /* TEST_HASHING */ diff --git a/third_party/bash/hashlib.h b/third_party/bash/hashlib.h deleted file mode 100644 index cf2de9884..000000000 --- a/third_party/bash/hashlib.h +++ /dev/null @@ -1,92 +0,0 @@ -/* hashlib.h -- the data structures used in hashing in Bash. */ - -/* Copyright (C) 1993-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_HASHLIB_H_) -#define _HASHLIB_H_ - -#include "stdc.h" - -#ifndef PTR_T -# ifdef __STDC__ -# define PTR_T void * -# else -# define PTR_T char * -# endif -#endif - -typedef struct bucket_contents { - struct bucket_contents *next; /* Link to next hashed key in this bucket. */ - char *key; /* What we look up. */ - PTR_T data; /* What we really want. */ - unsigned int khash; /* What key hashes to */ - int times_found; /* Number of times this item has been found. */ -} BUCKET_CONTENTS; - -typedef struct hash_table { - BUCKET_CONTENTS **bucket_array; /* Where the data is kept. */ - int nbuckets; /* How many buckets does this table have. */ - int nentries; /* How many entries does this table have. */ -} HASH_TABLE; - -typedef int hash_wfunc PARAMS((BUCKET_CONTENTS *)); - -/* Operations on tables as a whole */ -extern HASH_TABLE *hash_create PARAMS((int)); -extern HASH_TABLE *hash_copy PARAMS((HASH_TABLE *, sh_string_func_t *)); -extern void hash_flush PARAMS((HASH_TABLE *, sh_free_func_t *)); -extern void hash_dispose PARAMS((HASH_TABLE *)); -extern void hash_walk PARAMS((HASH_TABLE *, hash_wfunc *)); - -/* Operations to extract information from or pieces of tables */ -extern int hash_bucket PARAMS((const char *, HASH_TABLE *)); -extern int hash_size PARAMS((HASH_TABLE *)); - -/* Operations on hash table entries */ -extern BUCKET_CONTENTS *hash_search PARAMS((const char *, HASH_TABLE *, int)); -extern BUCKET_CONTENTS *hash_insert PARAMS((char *, HASH_TABLE *, int)); -extern BUCKET_CONTENTS *hash_remove PARAMS((const char *, HASH_TABLE *, int)); - -/* Miscellaneous */ -extern unsigned int hash_string PARAMS((const char *)); - -/* Redefine the function as a macro for speed. */ -#define hash_items(bucket, table) \ - ((table && (bucket < table->nbuckets)) ? \ - table->bucket_array[bucket] : \ - (BUCKET_CONTENTS *)NULL) - -/* Default number of buckets in the hash table. */ -#define DEFAULT_HASH_BUCKETS 128 /* must be power of two */ - -#define HASH_ENTRIES(ht) ((ht) ? (ht)->nentries : 0) - -/* flags for hash_search and hash_insert */ -#define HASH_NOSRCH 0x01 -#define HASH_CREATE 0x02 - -#if !defined (NULL) -# if defined (__STDC__) -# define NULL ((void *) 0) -# else -# define NULL 0x0 -# endif /* !__STDC__ */ -#endif /* !NULL */ - -#endif /* _HASHLIB_H */ diff --git a/third_party/bash/input.c b/third_party/bash/input.c deleted file mode 100644 index 7b439f8c8..000000000 --- a/third_party/bash/input.c +++ /dev/null @@ -1,677 +0,0 @@ -/* input.c -- functions to perform buffered input with synchronization. */ - -/* Copyright (C) 1992-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include "bashtypes.h" -#if !defined (_MINIX) && defined (HAVE_SYS_FILE_H) -# include -#endif -#include "filecntl.h" -#include "posixstat.h" -#include -#include - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "bashansi.h" -#include "bashintl.h" - -#include "shell.h" -#include "input.h" -#include "externs.h" -#include "trap.h" - -#if !defined (errno) -extern int errno; -#endif /* !errno */ - -#if defined (EAGAIN) -# define X_EAGAIN EAGAIN -#else -# define X_EAGAIN -99 -#endif - -#if defined (EWOULDBLOCK) -# define X_EWOULDBLOCK EWOULDBLOCK -#else -# define X_EWOULDBLOCK -99 -#endif - -extern void termsig_handler PARAMS((int)); - -/* Functions to handle reading input on systems that don't restart read(2) - if a signal is received. */ - -static char localbuf[1024]; -static int local_index = 0, local_bufused = 0; - -/* Posix and USG systems do not guarantee to restart read () if it is - interrupted by a signal. We do the read ourselves, and restart it - if it returns EINTR. */ -int -getc_with_restart (stream) - FILE *stream; -{ - unsigned char uc; - - CHECK_TERMSIG; - - /* Try local buffering to reduce the number of read(2) calls. */ - if (local_index == local_bufused || local_bufused == 0) - { - while (1) - { - QUIT; - run_pending_traps (); - - local_bufused = read (fileno (stream), localbuf, sizeof(localbuf)); - if (local_bufused > 0) - break; - else if (local_bufused == 0) - { - local_index = 0; - return EOF; - } - else if (errno == X_EAGAIN || errno == X_EWOULDBLOCK) - { - if (sh_unset_nodelay_mode (fileno (stream)) < 0) - { - sys_error (_("cannot reset nodelay mode for fd %d"), fileno (stream)); - local_index = local_bufused = 0; - return EOF; - } - continue; - } - else if (errno != EINTR) - { - local_index = local_bufused = 0; - return EOF; - } - else if (interrupt_state || terminating_signal) /* QUIT; */ - local_index = local_bufused = 0; - } - local_index = 0; - } - uc = localbuf[local_index++]; - return uc; -} - -int -ungetc_with_restart (c, stream) - int c; - FILE *stream; -{ - if (local_index == 0 || c == EOF) - return EOF; - localbuf[--local_index] = c; - return c; -} - -#if defined (BUFFERED_INPUT) - -/* A facility similar to stdio, but input-only. */ - -#if defined (USING_BASH_MALLOC) -# define MAX_INPUT_BUFFER_SIZE 8172 -#else -# define MAX_INPUT_BUFFER_SIZE 8192 -#endif - -#if !defined (SEEK_CUR) -# define SEEK_CUR 1 -#endif /* !SEEK_CUR */ - -#ifdef max -# undef max -#endif -#define max(a, b) (((a) > (b)) ? (a) : (b)) -#ifdef min -# undef min -#endif -#define min(a, b) ((a) > (b) ? (b) : (a)) - -int bash_input_fd_changed; - -/* This provides a way to map from a file descriptor to the buffer - associated with that file descriptor, rather than just the other - way around. This is needed so that buffers are managed properly - in constructs like 3<&4. buffers[x]->b_fd == x -- that is how the - correspondence is maintained. */ -static BUFFERED_STREAM **buffers = (BUFFERED_STREAM **)NULL; -static int nbuffers; - -#define ALLOCATE_BUFFERS(n) \ - do { if ((n) >= nbuffers) allocate_buffers (n); } while (0) - -/* Make sure `buffers' has at least N elements. */ -static void -allocate_buffers (n) - int n; -{ - register int i, orig_nbuffers; - - orig_nbuffers = nbuffers; - nbuffers = n + 20; - buffers = (BUFFERED_STREAM **)xrealloc - (buffers, nbuffers * sizeof (BUFFERED_STREAM *)); - - /* Zero out the new buffers. */ - for (i = orig_nbuffers; i < nbuffers; i++) - buffers[i] = (BUFFERED_STREAM *)NULL; -} - -/* Construct and return a BUFFERED_STREAM corresponding to file descriptor - FD, using BUFFER. */ -static BUFFERED_STREAM * -make_buffered_stream (fd, buffer, bufsize) - int fd; - char *buffer; - size_t bufsize; -{ - BUFFERED_STREAM *bp; - - bp = (BUFFERED_STREAM *)xmalloc (sizeof (BUFFERED_STREAM)); - ALLOCATE_BUFFERS (fd); - buffers[fd] = bp; - bp->b_fd = fd; - bp->b_buffer = buffer; - bp->b_size = bufsize; - bp->b_used = bp->b_inputp = bp->b_flag = 0; - if (bufsize == 1) - bp->b_flag |= B_UNBUFF; - if (O_TEXT && (fcntl (fd, F_GETFL) & O_TEXT) != 0) - bp->b_flag |= B_TEXT; - return (bp); -} - -/* Allocate a new BUFFERED_STREAM, copy BP to it, and return the new copy. */ -static BUFFERED_STREAM * -copy_buffered_stream (bp) - BUFFERED_STREAM *bp; -{ - BUFFERED_STREAM *nbp; - - if (!bp) - return ((BUFFERED_STREAM *)NULL); - - nbp = (BUFFERED_STREAM *)xmalloc (sizeof (BUFFERED_STREAM)); - xbcopy ((char *)bp, (char *)nbp, sizeof (BUFFERED_STREAM)); - return (nbp); -} - -int -set_bash_input_fd (fd) - int fd; -{ - if (bash_input.type == st_bstream) - bash_input.location.buffered_fd = fd; - else if (interactive_shell == 0) - default_buffered_input = fd; - return 0; -} - -int -fd_is_bash_input (fd) - int fd; -{ - if (bash_input.type == st_bstream && bash_input.location.buffered_fd == fd) - return 1; - else if (interactive_shell == 0 && default_buffered_input == fd) - return 1; - return 0; -} - -/* Save the buffered stream corresponding to file descriptor FD (which bash - is using to read input) to a buffered stream associated with NEW_FD. If - NEW_FD is -1, a new file descriptor is allocated with fcntl. The new - file descriptor is returned on success, -1 on error. */ -int -save_bash_input (fd, new_fd) - int fd, new_fd; -{ - int nfd; - - /* Sync the stream so we can re-read from the new file descriptor. We - might be able to avoid this by copying the buffered stream verbatim - to the new file descriptor. */ - if (buffers[fd]) - sync_buffered_stream (fd); - - /* Now take care of duplicating the file descriptor that bash is - using for input, so we can reinitialize it later. */ - nfd = (new_fd == -1) ? fcntl (fd, F_DUPFD, 10) : new_fd; - if (nfd == -1) - { - if (fcntl (fd, F_GETFD, 0) == 0) - sys_error (_("cannot allocate new file descriptor for bash input from fd %d"), fd); - return -1; - } - - if (nfd < nbuffers && buffers[nfd]) - { - /* What's this? A stray buffer without an associated open file - descriptor? Free up the buffer and report the error. */ - internal_error (_("save_bash_input: buffer already exists for new fd %d"), nfd); - if (buffers[nfd]->b_flag & B_SHAREDBUF) - buffers[nfd]->b_buffer = (char *)NULL; - free_buffered_stream (buffers[nfd]); - } - - /* Reinitialize bash_input.location. */ - if (bash_input.type == st_bstream) - { - bash_input.location.buffered_fd = nfd; - fd_to_buffered_stream (nfd); - close_buffered_fd (fd); /* XXX */ - } - else - /* If the current input type is not a buffered stream, but the shell - is not interactive and therefore using a buffered stream to read - input (e.g. with an `eval exec 3>output' inside a script), note - that the input fd has been changed. pop_stream() looks at this - value and adjusts the input fd to the new value of - default_buffered_input accordingly. */ - bash_input_fd_changed++; - - if (default_buffered_input == fd) - default_buffered_input = nfd; - - SET_CLOSE_ON_EXEC (nfd); - return nfd; -} - -/* Check that file descriptor FD is not the one that bash is currently - using to read input from a script. FD is about to be duplicated onto, - which means that the kernel will close it for us. If FD is the bash - input file descriptor, we need to seek backwards in the script (if - possible and necessary -- scripts read from stdin are still unbuffered), - allocate a new file descriptor to use for bash input, and re-initialize - the buffered stream. Make sure the file descriptor used to save bash - input is set close-on-exec. Returns 0 on success, -1 on failure. This - works only if fd is > 0 -- if fd == 0 and bash is reading input from - fd 0, sync_buffered_stream is used instead, to cooperate with input - redirection (look at redir.c:add_undo_redirect()). */ -int -check_bash_input (fd) - int fd; -{ - if (fd_is_bash_input (fd)) - { - if (fd > 0) - return ((save_bash_input (fd, -1) == -1) ? -1 : 0); - else if (fd == 0) - return ((sync_buffered_stream (fd) == -1) ? -1 : 0); - } - return 0; -} - -/* This is the buffered stream analogue of dup2(fd1, fd2). The - BUFFERED_STREAM corresponding to fd2 is deallocated, if one exists. - BUFFERS[fd1] is copied to BUFFERS[fd2]. This is called by the - redirect code for constructs like 4<&0 and 3b_buffer && buffers[fd1]->b_buffer == buffers[fd2]->b_buffer) - buffers[fd2] = (BUFFERED_STREAM *)NULL; - /* If this buffer is shared with another fd, don't free the buffer */ - else if (buffers[fd2]->b_flag & B_SHAREDBUF) - { - buffers[fd2]->b_buffer = (char *)NULL; - free_buffered_stream (buffers[fd2]); - } - else - free_buffered_stream (buffers[fd2]); - } - buffers[fd2] = copy_buffered_stream (buffers[fd1]); - if (buffers[fd2]) - buffers[fd2]->b_fd = fd2; - - if (is_bash_input) - { - if (!buffers[fd2]) - fd_to_buffered_stream (fd2); - buffers[fd2]->b_flag |= B_WASBASHINPUT; - } - - if (fd_is_bash_input (fd1) || (buffers[fd1] && (buffers[fd1]->b_flag & B_SHAREDBUF))) - buffers[fd2]->b_flag |= B_SHAREDBUF; - - return (fd2); -} - -/* Return 1 if a seek on FD will succeed. */ -#define fd_is_seekable(fd) (lseek ((fd), 0L, SEEK_CUR) >= 0) - -/* Take FD, a file descriptor, and create and return a buffered stream - corresponding to it. If something is wrong and the file descriptor - is invalid, return a NULL stream. */ -BUFFERED_STREAM * -fd_to_buffered_stream (fd) - int fd; -{ - char *buffer; - size_t size; - struct stat sb; - - if (fstat (fd, &sb) < 0) - { - close (fd); - return ((BUFFERED_STREAM *)NULL); - } - - size = (fd_is_seekable (fd)) ? min (sb.st_size, MAX_INPUT_BUFFER_SIZE) : 1; - if (size == 0) - size = 1; - buffer = (char *)xmalloc (size); - - return (make_buffered_stream (fd, buffer, size)); -} - -/* Return a buffered stream corresponding to FILE, a file name. */ -BUFFERED_STREAM * -open_buffered_stream (file) - char *file; -{ - int fd; - - fd = open (file, O_RDONLY); - return ((fd >= 0) ? fd_to_buffered_stream (fd) : (BUFFERED_STREAM *)NULL); -} - -/* Deallocate a buffered stream and free up its resources. Make sure we - zero out the slot in BUFFERS that points to BP. */ -void -free_buffered_stream (bp) - BUFFERED_STREAM *bp; -{ - int n; - - if (!bp) - return; - - n = bp->b_fd; - if (bp->b_buffer) - free (bp->b_buffer); - free (bp); - buffers[n] = (BUFFERED_STREAM *)NULL; -} - -/* Close the file descriptor associated with BP, a buffered stream, and free - up the stream. Return the status of closing BP's file descriptor. */ -int -close_buffered_stream (bp) - BUFFERED_STREAM *bp; -{ - int fd; - - if (!bp) - return (0); - fd = bp->b_fd; - if (bp->b_flag & B_SHAREDBUF) - bp->b_buffer = (char *)NULL; - free_buffered_stream (bp); - return (close (fd)); -} - -/* Deallocate the buffered stream associated with file descriptor FD, and - close FD. Return the status of the close on FD. */ -int -close_buffered_fd (fd) - int fd; -{ - if (fd < 0) - { - errno = EBADF; - return -1; - } - if (fd >= nbuffers || !buffers || !buffers[fd]) - return (close (fd)); - return (close_buffered_stream (buffers[fd])); -} - -/* Make the BUFFERED_STREAM associated with buffers[FD] be BP, and return - the old BUFFERED_STREAM. */ -BUFFERED_STREAM * -set_buffered_stream (fd, bp) - int fd; - BUFFERED_STREAM *bp; -{ - BUFFERED_STREAM *ret; - - ret = buffers[fd]; - buffers[fd] = bp; - return ret; -} - -/* Read a buffer full of characters from BP, a buffered stream. */ -static int -b_fill_buffer (bp) - BUFFERED_STREAM *bp; -{ - ssize_t nr; - off_t o; - - CHECK_TERMSIG; - /* In an environment where text and binary files are treated differently, - compensate for lseek() on text files returning an offset different from - the count of characters read() returns. Text-mode streams have to be - treated as unbuffered. */ - if ((bp->b_flag & (B_TEXT | B_UNBUFF)) == B_TEXT) - { - o = lseek (bp->b_fd, 0, SEEK_CUR); - nr = zread (bp->b_fd, bp->b_buffer, bp->b_size); - if (nr > 0 && nr < lseek (bp->b_fd, 0, SEEK_CUR) - o) - { - lseek (bp->b_fd, o, SEEK_SET); - bp->b_flag |= B_UNBUFF; - bp->b_size = 1; - nr = zread (bp->b_fd, bp->b_buffer, bp->b_size); - } - } - else - nr = zread (bp->b_fd, bp->b_buffer, bp->b_size); - if (nr <= 0) - { - bp->b_used = bp->b_inputp = 0; - bp->b_buffer[0] = 0; - if (nr == 0) - bp->b_flag |= B_EOF; - else - bp->b_flag |= B_ERROR; - return (EOF); - } - - bp->b_used = nr; - bp->b_inputp = 0; - return (bp->b_buffer[bp->b_inputp++] & 0xFF); -} - -/* Get a character from buffered stream BP. */ -#define bufstream_getc(bp) \ - (bp->b_inputp == bp->b_used || !bp->b_used) \ - ? b_fill_buffer (bp) \ - : bp->b_buffer[bp->b_inputp++] & 0xFF - -/* Push C back onto buffered stream BP. */ -static int -bufstream_ungetc(c, bp) - int c; - BUFFERED_STREAM *bp; -{ - if (c == EOF || bp == 0 || bp->b_inputp == 0) - return (EOF); - - bp->b_buffer[--bp->b_inputp] = c; - return (c); -} - -/* Seek backwards on file BFD to synchronize what we've read so far - with the underlying file pointer. */ -int -sync_buffered_stream (bfd) - int bfd; -{ - BUFFERED_STREAM *bp; - off_t chars_left; - - if (buffers == 0 || (bp = buffers[bfd]) == 0) - return (-1); - - chars_left = bp->b_used - bp->b_inputp; - if (chars_left) - lseek (bp->b_fd, -chars_left, SEEK_CUR); - bp->b_used = bp->b_inputp = 0; - return (0); -} - -int -buffered_getchar () -{ - CHECK_TERMSIG; - - if (bash_input.location.buffered_fd < 0 || buffers[bash_input.location.buffered_fd] == 0) - return EOF; - -#if !defined (DJGPP) - return (bufstream_getc (buffers[bash_input.location.buffered_fd])); -#else - /* On DJGPP, ignore \r. */ - int ch; - while ((ch = bufstream_getc (buffers[bash_input.location.buffered_fd])) == '\r') - ; - return ch; -#endif -} - -int -buffered_ungetchar (c) - int c; -{ - return (bufstream_ungetc (c, buffers[bash_input.location.buffered_fd])); -} - -/* Make input come from file descriptor BFD through a buffered stream. */ -void -with_input_from_buffered_stream (bfd, name) - int bfd; - char *name; -{ - INPUT_STREAM location; - BUFFERED_STREAM *bp; - - location.buffered_fd = bfd; - /* Make sure the buffered stream exists. */ - bp = fd_to_buffered_stream (bfd); - init_yy_io (bp == 0 ? return_EOF : buffered_getchar, - buffered_ungetchar, st_bstream, name, location); -} - -#if defined (TEST) -void * -xmalloc(s) -int s; -{ - return (malloc (s)); -} - -void * -xrealloc(s, size) -char *s; -int size; -{ - if (!s) - return(malloc (size)); - else - return(realloc (s, size)); -} - -void -init_yy_io () -{ -} - -process(bp) -BUFFERED_STREAM *bp; -{ - int c; - - while ((c = bufstream_getc(bp)) != EOF) - putchar(c); -} - -BASH_INPUT bash_input; - -struct stat dsb; /* can be used from gdb */ - -/* imitate /bin/cat */ -main(argc, argv) -int argc; -char **argv; -{ - register int i; - BUFFERED_STREAM *bp; - - if (argc == 1) { - bp = fd_to_buffered_stream (0); - process(bp); - exit(0); - } - for (i = 1; i < argc; i++) { - if (argv[i][0] == '-' && argv[i][1] == '\0') { - bp = fd_to_buffered_stream (0); - if (!bp) - continue; - process(bp); - free_buffered_stream (bp); - } else { - bp = open_buffered_stream (argv[i]); - if (!bp) - continue; - process(bp); - close_buffered_stream (bp); - } - } - exit(0); -} -#endif /* TEST */ -#endif /* BUFFERED_INPUT */ diff --git a/third_party/bash/input.h b/third_party/bash/input.h deleted file mode 100644 index cb3eee425..000000000 --- a/third_party/bash/input.h +++ /dev/null @@ -1,135 +0,0 @@ -/* input.h -- Structures and unions used for reading input. */ - -/* Copyright (C) 1993-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_INPUT_H_) -#define _INPUT_H_ - -#include "stdc.h" - -/* Function pointers can be declared as (Function *)foo. */ -#if !defined (_FUNCTION_DEF) -# define _FUNCTION_DEF -typedef int Function (); -typedef void VFunction (); -typedef char *CPFunction (); /* no longer used */ -typedef char **CPPFunction (); /* no longer used */ -#endif /* _FUNCTION_DEF */ - -typedef int sh_cget_func_t PARAMS((void)); /* sh_ivoidfunc_t */ -typedef int sh_cunget_func_t PARAMS((int)); /* sh_intfunc_t */ - -enum stream_type {st_none, st_stdin, st_stream, st_string, st_bstream}; - -#if defined (BUFFERED_INPUT) - -/* Possible values for b_flag. */ -#undef B_EOF -#undef B_ERROR /* There are some systems with this define */ -#undef B_UNBUFF - -#define B_EOF 0x01 -#define B_ERROR 0x02 -#define B_UNBUFF 0x04 -#define B_WASBASHINPUT 0x08 -#define B_TEXT 0x10 -#define B_SHAREDBUF 0x20 /* shared input buffer */ - -/* A buffered stream. Like a FILE *, but with our own buffering and - synchronization. Look in input.c for the implementation. */ -typedef struct BSTREAM -{ - int b_fd; - char *b_buffer; /* The buffer that holds characters read. */ - size_t b_size; /* How big the buffer is. */ - size_t b_used; /* How much of the buffer we're using, */ - int b_flag; /* Flag values. */ - size_t b_inputp; /* The input pointer, index into b_buffer. */ -} BUFFERED_STREAM; - -#if 0 -extern BUFFERED_STREAM **buffers; -#endif - -extern int default_buffered_input; -extern int bash_input_fd_changed; - -#endif /* BUFFERED_INPUT */ - -typedef union { - FILE *file; - char *string; -#if defined (BUFFERED_INPUT) - int buffered_fd; -#endif -} INPUT_STREAM; - -typedef struct { - enum stream_type type; - char *name; - INPUT_STREAM location; - sh_cget_func_t *getter; - sh_cunget_func_t *ungetter; -} BASH_INPUT; - -extern BASH_INPUT bash_input; - -/* Functions from parse.y whose use directly or indirectly depends on the - definitions in this file. */ -extern void initialize_bash_input PARAMS((void)); -extern void init_yy_io PARAMS((sh_cget_func_t *, sh_cunget_func_t *, enum stream_type, const char *, INPUT_STREAM)); -extern char *yy_input_name PARAMS((void)); -extern void with_input_from_stdin PARAMS((void)); -extern void with_input_from_string PARAMS((char *, const char *)); -extern void with_input_from_stream PARAMS((FILE *, const char *)); -extern void push_stream PARAMS((int)); -extern void pop_stream PARAMS((void)); -extern int stream_on_stack PARAMS((enum stream_type)); -extern char *read_secondary_line PARAMS((int)); -extern int find_reserved_word PARAMS((char *)); -extern void gather_here_documents PARAMS((void)); -extern void execute_variable_command PARAMS((char *, char *)); - -extern int *save_token_state PARAMS((void)); -extern void restore_token_state PARAMS((int *)); - -/* Functions from input.c */ -extern int getc_with_restart PARAMS((FILE *)); -extern int ungetc_with_restart PARAMS((int, FILE *)); - -#if defined (BUFFERED_INPUT) -/* Functions from input.c. */ -extern int fd_is_bash_input PARAMS((int)); -extern int set_bash_input_fd PARAMS((int)); -extern int save_bash_input PARAMS((int, int)); -extern int check_bash_input PARAMS((int)); -extern int duplicate_buffered_stream PARAMS((int, int)); -extern BUFFERED_STREAM *fd_to_buffered_stream PARAMS((int)); -extern BUFFERED_STREAM *set_buffered_stream PARAMS((int, BUFFERED_STREAM *)); -extern BUFFERED_STREAM *open_buffered_stream PARAMS((char *)); -extern void free_buffered_stream PARAMS((BUFFERED_STREAM *)); -extern int close_buffered_stream PARAMS((BUFFERED_STREAM *)); -extern int close_buffered_fd PARAMS((int)); -extern int sync_buffered_stream PARAMS((int)); -extern int buffered_getchar PARAMS((void)); -extern int buffered_ungetchar PARAMS((int)); -extern void with_input_from_buffered_stream PARAMS((int, char *)); -#endif /* BUFFERED_INPUT */ - -#endif /* _INPUT_H_ */ diff --git a/third_party/bash/input_avail.c b/third_party/bash/input_avail.c deleted file mode 100644 index 36981cf26..000000000 --- a/third_party/bash/input_avail.c +++ /dev/null @@ -1,165 +0,0 @@ -/* input_avail.c -- check whether or not data is available for reading on a - specified file descriptor. */ - -/* Copyright (C) 2008,2009-2019 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if defined (__TANDEM) -# include -#endif - -#if defined (HAVE_CONFIG_H) -# include "config.h" -#endif - -#include -#include -#if defined (HAVE_SYS_FILE_H) -# include -#endif /* HAVE_SYS_FILE_H */ - -#if defined (HAVE_PSELECT) -# include -#endif - -#if defined (HAVE_UNISTD_H) -# include -#endif /* HAVE_UNISTD_H */ - -#include "bashansi.h" - -#include "posixselect.h" - -#if defined (FIONREAD_IN_SYS_IOCTL) -# include -#endif - -#include -#include - -#if !defined (errno) -extern int errno; -#endif /* !errno */ - -#if !defined (O_NDELAY) && defined (O_NONBLOCK) -# define O_NDELAY O_NONBLOCK /* Posix style */ -#endif - -/* Return >= 1 if select/FIONREAD indicates data available for reading on - file descriptor FD; 0 if no data available. Return -1 on error. */ -int -input_avail (fd) - int fd; -{ - int result, chars_avail; -#if defined(HAVE_SELECT) - fd_set readfds, exceptfds; - struct timeval timeout; -#endif - - if (fd < 0) - return -1; - - chars_avail = 0; - -#if defined (HAVE_SELECT) - FD_ZERO (&readfds); - FD_ZERO (&exceptfds); - FD_SET (fd, &readfds); - FD_SET (fd, &exceptfds); - timeout.tv_sec = 0; - timeout.tv_usec = 0; - result = select (fd + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout); - return ((result <= 0) ? 0 : 1); -#endif - -#if defined (FIONREAD) - errno = 0; - result = ioctl (fd, FIONREAD, &chars_avail); - if (result == -1 && errno == EIO) - return -1; - return (chars_avail); -#endif - - return 0; -} - -/* Wait until NCHARS are available for reading on file descriptor FD. - This can wait indefinitely. Return -1 on error. */ -int -nchars_avail (fd, nchars) - int fd; - int nchars; -{ - int result, chars_avail; -#if defined(HAVE_SELECT) - fd_set readfds, exceptfds; -#endif -#if defined (HAVE_PSELECT) || defined (HAVE_SELECT) - sigset_t set, oset; -#endif - - if (fd < 0 || nchars < 0) - return -1; - if (nchars == 0) - return (input_avail (fd)); - - chars_avail = 0; - -#if defined (HAVE_SELECT) - FD_ZERO (&readfds); - FD_ZERO (&exceptfds); - FD_SET (fd, &readfds); - FD_SET (fd, &exceptfds); -#endif -#if defined (HAVE_SELECT) || defined (HAVE_PSELECT) - sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set); -# ifdef SIGCHLD - sigaddset (&set, SIGCHLD); -# endif - sigemptyset (&oset); -#endif - - while (1) - { - result = 0; -#if defined (HAVE_PSELECT) - /* XXX - use pselect(2) to block SIGCHLD atomically */ - result = pselect (fd + 1, &readfds, (fd_set *)NULL, &exceptfds, (struct timespec *)NULL, &set); -#elif defined (HAVE_SELECT) - sigprocmask (SIG_BLOCK, &set, &oset); - result = select (fd + 1, &readfds, (fd_set *)NULL, &exceptfds, (struct timeval *)NULL); - sigprocmask (SIG_BLOCK, &oset, (sigset_t *)NULL); -#endif - if (result < 0) - return -1; - -#if defined (FIONREAD) - errno = 0; - result = ioctl (fd, FIONREAD, &chars_avail); - if (result == -1 && errno == EIO) - return -1; - if (chars_avail >= nchars) - break; -#else - break; -#endif - } - - return 0; -} diff --git a/third_party/bash/itos.c b/third_party/bash/itos.c deleted file mode 100644 index ecdc99686..000000000 --- a/third_party/bash/itos.c +++ /dev/null @@ -1,84 +0,0 @@ -/* itos.c -- Convert integer to string. */ - -/* Copyright (C) 1998-2002 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "bashansi.h" -#include "shell.h" - -char * -inttostr (i, buf, len) - intmax_t i; - char *buf; - size_t len; -{ - return (fmtumax (i, 10, buf, len, 0)); -} - -/* Integer to string conversion. This conses the string; the - caller should free it. */ -char * -itos (i) - intmax_t i; -{ - char *p, lbuf[INT_STRLEN_BOUND(intmax_t) + 1]; - - p = fmtumax (i, 10, lbuf, sizeof(lbuf), 0); - return (savestring (p)); -} - -/* Integer to string conversion. This conses the string using strdup; - caller should free it and be prepared to deal with NULL return. */ -char * -mitos (i) - intmax_t i; -{ - char *p, lbuf[INT_STRLEN_BOUND(intmax_t) + 1]; - - p = fmtumax (i, 10, lbuf, sizeof(lbuf), 0); - return (strdup (p)); -} - -char * -uinttostr (i, buf, len) - uintmax_t i; - char *buf; - size_t len; -{ - return (fmtumax (i, 10, buf, len, FL_UNSIGNED)); -} - -/* Integer to string conversion. This conses the string; the - caller should free it. */ -char * -uitos (i) - uintmax_t i; -{ - char *p, lbuf[INT_STRLEN_BOUND(uintmax_t) + 1]; - - p = fmtumax (i, 10, lbuf, sizeof(lbuf), FL_UNSIGNED); - return (savestring (p)); -} diff --git a/third_party/bash/jobs.c b/third_party/bash/jobs.c deleted file mode 100644 index c6e9eaf3f..000000000 --- a/third_party/bash/jobs.c +++ /dev/null @@ -1,5119 +0,0 @@ -/* jobs.c - functions that make children, remember them, and handle their termination. */ - -/* This file works with both POSIX and BSD systems. It implements job - control. */ - -/* Copyright (C) 1989-2022 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include "bashtypes.h" -#include "trap.h" -#include -#include -#include - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "posixtime.h" - -#if defined (HAVE_SYS_RESOURCE_H) && defined (HAVE_WAIT3) && !defined (_POSIX_VERSION) && !defined (RLIMTYPE) -# include -#endif /* !_POSIX_VERSION && HAVE_SYS_RESOURCE_H && HAVE_WAIT3 && !RLIMTYPE */ - -#if defined (HAVE_SYS_FILE_H) -# include -#endif - -#include "filecntl.h" -#include -#if defined (HAVE_SYS_PARAM_H) -#include -#endif - -#if defined (BUFFERED_INPUT) -# include "input.h" -#endif - -/* Need to include this up here for *_TTY_DRIVER definitions. */ -#include "shtty.h" - -/* Define this if your output is getting swallowed. It's a no-op on - machines with the termio or termios tty drivers. */ -/* #define DRAIN_OUTPUT */ - -/* For the TIOCGPGRP and TIOCSPGRP ioctl parameters on HP-UX */ -#if defined (hpux) && !defined (TERMIOS_TTY_DRIVER) -# include -#endif /* hpux && !TERMIOS_TTY_DRIVER */ - -#include "bashansi.h" -#include "bashintl.h" -#include "shell.h" -#include "parser.h" -#include "jobs.h" -#include "execute_cmd.h" -#include "flags.h" - -#include "typemax.h" - -#include "builtext.h" -#include "common.h" - -#if defined (READLINE) -# include "third_party/readline/readline.h" -#endif - -#if !defined (errno) -extern int errno; -#endif /* !errno */ - -#if !defined (HAVE_KILLPG) -extern int killpg PARAMS((pid_t, int)); -#endif - -#if !DEFAULT_CHILD_MAX -# define DEFAULT_CHILD_MAX 4096 -#endif - -#if !MAX_CHILD_MAX -# define MAX_CHILD_MAX 32768 -#endif - -#if !defined (DEBUG) -#define MAX_JOBS_IN_ARRAY 4096 /* production */ -#else -#define MAX_JOBS_IN_ARRAY 128 /* testing */ -#endif - -/* XXX for now */ -#define PIDSTAT_TABLE_SZ 4096 -#define BGPIDS_TABLE_SZ 512 - -/* Flag values for second argument to delete_job */ -#define DEL_WARNSTOPPED 1 /* warn about deleting stopped jobs */ -#define DEL_NOBGPID 2 /* don't add pgrp leader to bgpids */ - -/* Take care of system dependencies that must be handled when waiting for - children. The arguments to the WAITPID macro match those to the Posix.1 - waitpid() function. */ - -#if defined (ultrix) && defined (mips) && defined (_POSIX_VERSION) -# define WAITPID(pid, statusp, options) \ - wait3 ((union wait *)statusp, options, (struct rusage *)0) -#else -# if defined (_POSIX_VERSION) || defined (HAVE_WAITPID) -# define WAITPID(pid, statusp, options) \ - waitpid ((pid_t)pid, statusp, options) -# else -# if defined (HAVE_WAIT3) -# define WAITPID(pid, statusp, options) \ - wait3 (statusp, options, (struct rusage *)0) -# else -# define WAITPID(pid, statusp, options) \ - wait3 (statusp, options, (int *)0) -# endif /* HAVE_WAIT3 */ -# endif /* !_POSIX_VERSION && !HAVE_WAITPID*/ -#endif /* !(Ultrix && mips && _POSIX_VERSION) */ - -/* getpgrp () varies between systems. Even systems that claim to be - Posix.1 compatible lie sometimes (Ultrix, SunOS4, apollo). */ -#if defined (GETPGRP_VOID) -# define getpgid(p) getpgrp () -#else -# define getpgid(p) getpgrp (p) -#endif /* !GETPGRP_VOID */ - -/* If the system needs it, REINSTALL_SIGCHLD_HANDLER will reinstall the - handler for SIGCHLD. */ -#if defined (MUST_REINSTALL_SIGHANDLERS) -# define REINSTALL_SIGCHLD_HANDLER signal (SIGCHLD, sigchld_handler) -#else -# define REINSTALL_SIGCHLD_HANDLER -#endif /* !MUST_REINSTALL_SIGHANDLERS */ - -/* Some systems let waitpid(2) tell callers about stopped children. */ -#if !defined (WCONTINUED) || defined (WCONTINUED_BROKEN) -# undef WCONTINUED -# define WCONTINUED 0 -#endif -#if !defined (WIFCONTINUED) -# define WIFCONTINUED(s) (0) -#endif - -/* The number of additional slots to allocate when we run out. */ -#define JOB_SLOTS 8 - -typedef int sh_job_map_func_t PARAMS((JOB *, int, int, int)); - -/* Variables used here but defined in other files. */ -extern WORD_LIST *subst_assign_varlist; - -extern SigHandler **original_signals; - -extern void set_original_signal PARAMS((int, SigHandler *)); - -static struct jobstats zerojs = { -1L, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NO_JOB, NO_JOB, 0, 0 }; -struct jobstats js = { -1L, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NO_JOB, NO_JOB, 0, 0 }; - -ps_index_t pidstat_table[PIDSTAT_TABLE_SZ]; -struct bgpids bgpids = { 0, 0, 0, 0 }; - -struct procchain procsubs = { 0, 0, 0 }; - -/* The array of known jobs. */ -JOB **jobs = (JOB **)NULL; - -#if 0 -/* The number of slots currently allocated to JOBS. */ -int job_slots = 0; -#endif - -/* The controlling tty for this shell. */ -int shell_tty = -1; - -/* The shell's process group. */ -pid_t shell_pgrp = NO_PID; - -/* The terminal's process group. */ -pid_t terminal_pgrp = NO_PID; - -/* The process group of the shell's parent. */ -pid_t original_pgrp = NO_PID; - -/* The process group of the pipeline currently being made. */ -pid_t pipeline_pgrp = (pid_t)0; - -#if defined (PGRP_PIPE) -/* Pipes which each shell uses to communicate with the process group leader - until all of the processes in a pipeline have been started. Then the - process leader is allowed to continue. */ -int pgrp_pipe[2] = { -1, -1 }; -#endif - -/* Last child made by the shell. */ -volatile pid_t last_made_pid = NO_PID; - -/* Pid of the last asynchronous child. */ -volatile pid_t last_asynchronous_pid = NO_PID; - -/* The pipeline currently being built. */ -PROCESS *the_pipeline = (PROCESS *)NULL; - -/* If this is non-zero, do job control. */ -int job_control = 1; - -/* Are we running in background? (terminal_pgrp != shell_pgrp) */ -int running_in_background = 0; - -/* Call this when you start making children. */ -int already_making_children = 0; - -/* If this is non-zero, $LINES and $COLUMNS are reset after every process - exits from get_tty_state(). */ -int check_window_size = CHECKWINSIZE_DEFAULT; - -PROCESS *last_procsub_child = (PROCESS *)NULL; - -/* Functions local to this file. */ - -void debug_print_pgrps (void); - -static sighandler wait_sigint_handler PARAMS((int)); -static sighandler sigchld_handler PARAMS((int)); -static sighandler sigcont_sighandler PARAMS((int)); -static sighandler sigstop_sighandler PARAMS((int)); - -static int waitchld PARAMS((pid_t, int)); - -static PROCESS *find_pid_in_pipeline PARAMS((pid_t, PROCESS *, int)); -static PROCESS *find_pipeline PARAMS((pid_t, int, int *)); -static PROCESS *find_process PARAMS((pid_t, int, int *)); - -static char *current_working_directory PARAMS((void)); -static char *job_working_directory PARAMS((void)); -static char *j_strsignal PARAMS((int)); -static char *printable_job_status PARAMS((int, PROCESS *, int)); - -static PROCESS *find_last_proc PARAMS((int, int)); -static pid_t find_last_pid PARAMS((int, int)); - -static int set_new_line_discipline PARAMS((int)); -static int map_over_jobs PARAMS((sh_job_map_func_t *, int, int)); -static int job_last_stopped PARAMS((int)); -static int job_last_running PARAMS((int)); -static int most_recent_job_in_state PARAMS((int, JOB_STATE)); -static int find_job PARAMS((pid_t, int, PROCESS **)); -static int print_job PARAMS((JOB *, int, int, int)); -static int process_exit_status PARAMS((WAIT)); -static int process_exit_signal PARAMS((WAIT)); -static int set_job_status_and_cleanup PARAMS((int)); - -static WAIT job_signal_status PARAMS((int)); -static WAIT raw_job_exit_status PARAMS((int)); - -static void notify_of_job_status PARAMS((void)); -static void reset_job_indices PARAMS((void)); -static void cleanup_dead_jobs PARAMS((void)); -static int processes_in_job PARAMS((int)); -static void realloc_jobs_list PARAMS((void)); -static int compact_jobs_list PARAMS((int)); -static void add_process PARAMS((char *, pid_t)); -static void print_pipeline PARAMS((PROCESS *, int, int, FILE *)); -static void pretty_print_job PARAMS((int, int, FILE *)); -static void set_current_job PARAMS((int)); -static void reset_current PARAMS((void)); -static void set_job_running PARAMS((int)); -static void setjstatus PARAMS((int)); -static int maybe_give_terminal_to PARAMS((pid_t, pid_t, int)); -static void mark_all_jobs_as_dead PARAMS((void)); -static void mark_dead_jobs_as_notified PARAMS((int)); -static void restore_sigint_handler PARAMS((void)); -#if defined (PGRP_PIPE) -static void pipe_read PARAMS((int *)); -#endif - -/* Hash table manipulation */ - -static ps_index_t *pshash_getbucket PARAMS((pid_t)); -static void pshash_delindex PARAMS((ps_index_t)); - -/* Saved background process status management */ -static struct pidstat *bgp_add PARAMS((pid_t, int)); -static int bgp_delete PARAMS((pid_t)); -static void bgp_clear PARAMS((void)); -static int bgp_search PARAMS((pid_t)); - -static struct pipeline_saver *alloc_pipeline_saver PARAMS((void)); - -static ps_index_t bgp_getindex PARAMS((void)); -static void bgp_resize PARAMS((void)); /* XXX */ - -#if defined (ARRAY_VARS) -static int *pstatuses; /* list of pipeline statuses */ -static int statsize; -#endif - -/* Used to synchronize between wait_for and other functions and the SIGCHLD - signal handler. */ -static int sigchld; -static int queue_sigchld; - -#define QUEUE_SIGCHLD(os) (os) = sigchld, queue_sigchld++ - -/* We set queue_sigchld around the call to waitchld to protect data structures - from a SIGCHLD arriving while waitchld is executing. */ -#define UNQUEUE_SIGCHLD(os) \ - do { \ - queue_sigchld--; \ - if (queue_sigchld == 0 && os != sigchld) \ - { \ - queue_sigchld = 1; \ - waitchld (-1, 0); \ - queue_sigchld = 0; \ - } \ - } while (0) - -static SigHandler *old_tstp, *old_ttou, *old_ttin; -static SigHandler *old_cont = (SigHandler *)SIG_DFL; - -/* A place to temporarily save the current pipeline. */ -static struct pipeline_saver *saved_pipeline; -static int saved_already_making_children; - -/* Set this to non-zero whenever you don't want the jobs list to change at - all: no jobs deleted and no status change notifications. This is used, - for example, when executing SIGCHLD traps, which may run arbitrary - commands. */ -static int jobs_list_frozen; - -static char retcode_name_buffer[64]; - -#if !defined (_POSIX_VERSION) - -/* These are definitions to map POSIX 1003.1 functions onto existing BSD - library functions and system calls. */ -#define setpgid(pid, pgrp) setpgrp (pid, pgrp) -#define tcsetpgrp(fd, pgrp) ioctl ((fd), TIOCSPGRP, &(pgrp)) - -pid_t -tcgetpgrp (fd) - int fd; -{ - pid_t pgrp; - - /* ioctl will handle setting errno correctly. */ - if (ioctl (fd, TIOCGPGRP, &pgrp) < 0) - return (-1); - return (pgrp); -} - -#endif /* !_POSIX_VERSION */ - -/* Initialize the global job stats structure and other bookkeeping variables */ -void -init_job_stats () -{ - js = zerojs; -} - -/* Return the working directory for the current process. Unlike - job_working_directory, this does not call malloc (), nor do any - of the functions it calls. This is so that it can safely be called - from a signal handler. */ -static char * -current_working_directory () -{ - char *dir; - static char d[PATH_MAX]; - - dir = get_string_value ("PWD"); - - if (dir == 0 && the_current_working_directory && no_symbolic_links) - dir = the_current_working_directory; - - if (dir == 0) - { - dir = getcwd (d, sizeof(d)); - if (dir) - dir = d; - } - - return (dir == 0) ? "" : dir; -} - -/* Return the working directory for the current process. */ -static char * -job_working_directory () -{ - char *dir; - - dir = get_string_value ("PWD"); - if (dir) - return (savestring (dir)); - - dir = get_working_directory ("job-working-directory"); - if (dir) - return (dir); - - return (savestring ("")); -} - -void -making_children () -{ - if (already_making_children) - return; - - already_making_children = 1; - start_pipeline (); -} - -void -stop_making_children () -{ - already_making_children = 0; -} - -void -cleanup_the_pipeline () -{ - PROCESS *disposer; - sigset_t set, oset; - - BLOCK_CHILD (set, oset); - disposer = the_pipeline; - the_pipeline = (PROCESS *)NULL; - UNBLOCK_CHILD (oset); - - if (disposer) - discard_pipeline (disposer); -} - -/* Not used right now */ -void -discard_last_procsub_child () -{ - PROCESS *disposer; - sigset_t set, oset; - - BLOCK_CHILD (set, oset); - disposer = last_procsub_child; - last_procsub_child = (PROCESS *)NULL; - UNBLOCK_CHILD (oset); - - if (disposer) - discard_pipeline (disposer); -} - -static struct pipeline_saver * -alloc_pipeline_saver () -{ - struct pipeline_saver *ret; - - ret = (struct pipeline_saver *)xmalloc (sizeof (struct pipeline_saver)); - ret->pipeline = 0; - ret->next = 0; - return ret; -} - -void -save_pipeline (clear) - int clear; -{ - sigset_t set, oset; - struct pipeline_saver *saver; - - BLOCK_CHILD (set, oset); - saver = alloc_pipeline_saver (); - saver->pipeline = the_pipeline; - saver->next = saved_pipeline; - saved_pipeline = saver; - if (clear) - the_pipeline = (PROCESS *)NULL; - saved_already_making_children = already_making_children; - UNBLOCK_CHILD (oset); -} - -PROCESS * -restore_pipeline (discard) - int discard; -{ - PROCESS *old_pipeline; - sigset_t set, oset; - struct pipeline_saver *saver; - - BLOCK_CHILD (set, oset); - old_pipeline = the_pipeline; - the_pipeline = saved_pipeline->pipeline; - saver = saved_pipeline; - saved_pipeline = saved_pipeline->next; - free (saver); - already_making_children = saved_already_making_children; - UNBLOCK_CHILD (oset); - - if (discard && old_pipeline) - { - discard_pipeline (old_pipeline); - return ((PROCESS *)NULL); - } - return old_pipeline; -} - -/* Start building a pipeline. */ -void -start_pipeline () -{ - if (the_pipeline) - { - cleanup_the_pipeline (); - /* If job_control == 0, pipeline_pgrp will always be equal to shell_pgrp; - if job_control != 0, pipeline_pgrp == shell_pgrp for command and - process substitution, in which case we want it to be the same as - shell_pgrp for the lifetime of this shell instance. */ - if (pipeline_pgrp != shell_pgrp) - pipeline_pgrp = 0; -#if defined (PGRP_PIPE) - sh_closepipe (pgrp_pipe); -#endif - } - -#if defined (PGRP_PIPE) - if (job_control) - { - if (pipe (pgrp_pipe) == -1) - sys_error (_("start_pipeline: pgrp pipe")); - } -#endif -} - -/* Stop building a pipeline. Install the process list in the job array. - This returns the index of the newly installed job. - DEFERRED is a command structure to be executed upon satisfactory - execution exit of this pipeline. */ -int -stop_pipeline (async, deferred) - int async; - COMMAND *deferred; -{ - register int i, j; - JOB *newjob; - sigset_t set, oset; - - BLOCK_CHILD (set, oset); - -#if defined (PGRP_PIPE) - /* The parent closes the process group synchronization pipe. */ - sh_closepipe (pgrp_pipe); -#endif - - cleanup_dead_jobs (); - - if (js.j_jobslots == 0) - { - js.j_jobslots = JOB_SLOTS; - jobs = (JOB **)xmalloc (js.j_jobslots * sizeof (JOB *)); - - /* Now blank out these new entries. */ - for (i = 0; i < js.j_jobslots; i++) - jobs[i] = (JOB *)NULL; - - js.j_firstj = js.j_lastj = js.j_njobs = 0; - } - - /* Scan from the last slot backward, looking for the next free one. */ - /* XXX - revisit this interactive assumption */ - /* XXX - this way for now */ - if (interactive) - { - for (i = js.j_jobslots; i; i--) - if (jobs[i - 1]) - break; - } - else - { -#if 0 - /* This wraps around, but makes it inconvenient to extend the array */ - for (i = js.j_lastj+1; i != js.j_lastj; i++) - { - if (i >= js.j_jobslots) - i = 0; - if (jobs[i] == 0) - break; - } - if (i == js.j_lastj) - i = js.j_jobslots; -#else - /* This doesn't wrap around yet. */ - for (i = js.j_lastj ? js.j_lastj + 1 : js.j_lastj; i < js.j_jobslots; i++) - if (jobs[i] == 0) - break; -#endif - } - - /* Do we need more room? */ - - /* First try compaction */ - if ((interactive_shell == 0 || subshell_environment) && i == js.j_jobslots && js.j_jobslots >= MAX_JOBS_IN_ARRAY) - i = compact_jobs_list (0); - - /* If we can't compact, reallocate */ - if (i == js.j_jobslots) - { - js.j_jobslots += JOB_SLOTS; - jobs = (JOB **)xrealloc (jobs, (js.j_jobslots * sizeof (JOB *))); - - for (j = i; j < js.j_jobslots; j++) - jobs[j] = (JOB *)NULL; - } - - /* Add the current pipeline to the job list. */ - if (the_pipeline) - { - register PROCESS *p; - int any_running, any_stopped, n; - - newjob = (JOB *)xmalloc (sizeof (JOB)); - - for (n = 1, p = the_pipeline; p->next != the_pipeline; n++, p = p->next) - ; - p->next = (PROCESS *)NULL; - newjob->pipe = REVERSE_LIST (the_pipeline, PROCESS *); - for (p = newjob->pipe; p->next; p = p->next) - ; - p->next = newjob->pipe; - - the_pipeline = (PROCESS *)NULL; - newjob->pgrp = pipeline_pgrp; - - /* Invariant: if the shell is executing a command substitution, - pipeline_pgrp == shell_pgrp. Other parts of the shell assume this. */ - if (pipeline_pgrp != shell_pgrp) - pipeline_pgrp = 0; - - newjob->flags = 0; - if (pipefail_opt) - newjob->flags |= J_PIPEFAIL; - - /* Flag to see if in another pgrp. */ - if (job_control) - newjob->flags |= J_JOBCONTROL; - - /* Set the state of this pipeline. */ - p = newjob->pipe; - any_running = any_stopped = 0; - do - { - any_running |= PRUNNING (p); - any_stopped |= PSTOPPED (p); - p = p->next; - } - while (p != newjob->pipe); - - newjob->state = any_running ? JRUNNING : (any_stopped ? JSTOPPED : JDEAD); - newjob->wd = job_working_directory (); - newjob->deferred = deferred; - - newjob->j_cleanup = (sh_vptrfunc_t *)NULL; - newjob->cleanarg = (PTR_T) NULL; - - jobs[i] = newjob; - if (newjob->state == JDEAD && (newjob->flags & J_FOREGROUND)) - setjstatus (i); - if (newjob->state == JDEAD) - { - js.c_reaped += n; /* wouldn't have been done since this was not part of a job */ - js.j_ndead++; - } - js.c_injobs += n; - - js.j_lastj = i; - js.j_njobs++; - } - else - newjob = (JOB *)NULL; - - if (newjob) - js.j_lastmade = newjob; - - if (async) - { - if (newjob) - { - newjob->flags &= ~J_FOREGROUND; - newjob->flags |= J_ASYNC; - js.j_lastasync = newjob; - } - reset_current (); - } - else - { - if (newjob) - { - newjob->flags |= J_FOREGROUND; - /* - * !!!!! NOTE !!!!! (chet@po.cwru.edu) - * - * The currently-accepted job control wisdom says to set the - * terminal's process group n+1 times in an n-step pipeline: - * once in the parent and once in each child. This is where - * the parent gives it away. - * - * Don't give the terminal away if this shell is an asynchronous - * subshell or if we're a (presumably non-interactive) shell running - * in the background. - * - */ - if (job_control && newjob->pgrp && (subshell_environment&SUBSHELL_ASYNC) == 0 && running_in_background == 0) - maybe_give_terminal_to (shell_pgrp, newjob->pgrp, 0); - } - } - - stop_making_children (); - UNBLOCK_CHILD (oset); - return (newjob ? i : js.j_current); -} - -/* Functions to manage the list of exited background pids whose status has - been saved. - - pidstat_table: - - The current implementation is a hash table using a single (separate) arena - for storage that can be allocated and freed as a unit. The size of the hash - table is a multiple of PIDSTAT_TABLE_SZ (4096) and multiple PIDs that hash - to the same value are chained through the bucket_next and bucket_prev - pointers (basically coalesced hashing for collision resolution). - - bgpids.storage: - - All pid/status storage is done using the circular buffer bgpids.storage. - This must contain at least js.c_childmax entries. The circular buffer is - used to supply the ordered list Posix requires ("the last CHILD_MAX - processes"). To avoid searching the entire storage table for a given PID, - the hash table (pidstat_table) holds pointers into the storage arena and - uses a doubly-linked list of cells (bucket_next/bucket_prev, also pointers - into the arena) to implement collision resolution. */ - -/* The number of elements in bgpids.storage always has to be > js.c_childmax for - the circular buffer to work right. */ -static void -bgp_resize () -{ - ps_index_t nsize, nsize_cur, nsize_max; - ps_index_t psi; - - if (bgpids.nalloc == 0) - { - /* invalidate hash table when bgpids table is reallocated */ - for (psi = 0; psi < PIDSTAT_TABLE_SZ; psi++) - pidstat_table[psi] = NO_PIDSTAT; - nsize = BGPIDS_TABLE_SZ; /* should be power of 2 */ - bgpids.head = 0; - } - else - nsize = bgpids.nalloc; - - nsize_max = TYPE_MAXIMUM (ps_index_t); - nsize_cur = (ps_index_t)js.c_childmax; - if (nsize_cur < 0) /* overflow */ - nsize_cur = MAX_CHILD_MAX; - - while (nsize > 0 && nsize < nsize_cur) /* > 0 should catch overflow */ - nsize <<= 1; - if (nsize > nsize_max || nsize <= 0) /* overflow? */ - nsize = nsize_max; - if (nsize > MAX_CHILD_MAX) - nsize = nsize_max = MAX_CHILD_MAX; /* hard cap */ - - if (bgpids.nalloc < nsize_cur && bgpids.nalloc < nsize_max) - { - bgpids.storage = (struct pidstat *)xrealloc (bgpids.storage, nsize * sizeof (struct pidstat)); - - for (psi = bgpids.nalloc; psi < nsize; psi++) - bgpids.storage[psi].pid = NO_PID; - - bgpids.nalloc = nsize; - - } - else if (bgpids.head >= bgpids.nalloc) /* wrap around */ - bgpids.head = 0; -} - -static ps_index_t -bgp_getindex () -{ - if (bgpids.nalloc < (ps_index_t)js.c_childmax || bgpids.head >= bgpids.nalloc) - bgp_resize (); - - pshash_delindex (bgpids.head); /* XXX - clear before reusing */ - return bgpids.head++; -} - -static ps_index_t * -pshash_getbucket (pid) - pid_t pid; -{ - unsigned long hash; /* XXX - u_bits32_t */ - - hash = pid * 0x9e370001UL; - return (&pidstat_table[hash % PIDSTAT_TABLE_SZ]); -} - -static struct pidstat * -bgp_add (pid, status) - pid_t pid; - int status; -{ - ps_index_t *bucket, psi; - struct pidstat *ps; - - /* bucket == existing chain of pids hashing to same value - psi = where were going to put this pid/status */ - - bucket = pshash_getbucket (pid); /* index into pidstat_table */ - psi = bgp_getindex (); /* bgpids.head, index into storage */ - - /* XXX - what if psi == *bucket? */ - if (psi == *bucket) - { - internal_debug ("hashed pid %d (pid %d) collides with bgpids.head, skipping", psi, pid); - bgpids.storage[psi].pid = NO_PID; /* make sure */ - psi = bgp_getindex (); /* skip to next one */ - } - - ps = &bgpids.storage[psi]; - - ps->pid = pid; - ps->status = status; - ps->bucket_next = *bucket; - ps->bucket_prev = NO_PIDSTAT; - - bgpids.npid++; - -#if 0 - if (bgpids.npid > js.c_childmax) - bgp_prune (); -#endif - - if (ps->bucket_next != NO_PIDSTAT) - bgpids.storage[ps->bucket_next].bucket_prev = psi; - - *bucket = psi; /* set chain head in hash table */ - - return ps; -} - -static void -pshash_delindex (psi) - ps_index_t psi; -{ - struct pidstat *ps; - ps_index_t *bucket; - - ps = &bgpids.storage[psi]; - if (ps->pid == NO_PID) - return; - - if (ps->bucket_next != NO_PIDSTAT) - bgpids.storage[ps->bucket_next].bucket_prev = ps->bucket_prev; - if (ps->bucket_prev != NO_PIDSTAT) - bgpids.storage[ps->bucket_prev].bucket_next = ps->bucket_next; - else - { - bucket = pshash_getbucket (ps->pid); - *bucket = ps->bucket_next; /* deleting chain head in hash table */ - } - - /* clear out this cell, in case it gets reused. */ - ps->pid = NO_PID; - ps->bucket_next = ps->bucket_prev = NO_PIDSTAT; -} - -static int -bgp_delete (pid) - pid_t pid; -{ - ps_index_t psi, orig_psi; - - if (bgpids.storage == 0 || bgpids.nalloc == 0 || bgpids.npid == 0) - return 0; - - /* Search chain using hash to find bucket in pidstat_table */ - for (orig_psi = psi = *(pshash_getbucket (pid)); psi != NO_PIDSTAT; psi = bgpids.storage[psi].bucket_next) - { - if (bgpids.storage[psi].pid == pid) - break; - if (orig_psi == bgpids.storage[psi].bucket_next) /* catch reported bug */ - { - internal_warning (_("bgp_delete: LOOP: psi (%d) == storage[psi].bucket_next"), psi); - return 0; - } - } - - if (psi == NO_PIDSTAT) - return 0; /* not found */ - -#if 0 - itrace("bgp_delete: deleting %d", pid); -#endif - - pshash_delindex (psi); /* hash table management */ - - bgpids.npid--; - return 1; -} - -/* Clear out the list of saved statuses */ -static void -bgp_clear () -{ - if (bgpids.storage == 0 || bgpids.nalloc == 0) - return; - - free (bgpids.storage); - - bgpids.storage = 0; - bgpids.nalloc = 0; - bgpids.head = 0; - - bgpids.npid = 0; -} - -/* Search for PID in the list of saved background pids; return its status if - found. If not found, return -1. We hash to the right spot in pidstat_table - and follow the bucket chain to the end. */ -static int -bgp_search (pid) - pid_t pid; -{ - ps_index_t psi, orig_psi; - - if (bgpids.storage == 0 || bgpids.nalloc == 0 || bgpids.npid == 0) - return -1; - - /* Search chain using hash to find bucket in pidstat_table */ - for (orig_psi = psi = *(pshash_getbucket (pid)); psi != NO_PIDSTAT; psi = bgpids.storage[psi].bucket_next) - { - if (bgpids.storage[psi].pid == pid) - return (bgpids.storage[psi].status); - if (orig_psi == bgpids.storage[psi].bucket_next) /* catch reported bug */ - { - internal_warning (_("bgp_search: LOOP: psi (%d) == storage[psi].bucket_next"), psi); - return -1; - } - } - - return -1; -} - -#if 0 -static void -bgp_prune () -{ - return; -} -#endif - -/* External interface to bgp_add; takes care of blocking and unblocking - SIGCHLD. Not really used. */ -void -save_proc_status (pid, status) - pid_t pid; - int status; -{ - sigset_t set, oset; - - BLOCK_CHILD (set, oset); - bgp_add (pid, status); - UNBLOCK_CHILD (oset); -} - -#if defined (PROCESS_SUBSTITUTION) -/* Functions to add and remove PROCESS * children from the list of running - asynchronous process substitutions. The list is currently a simple singly - linked list of PROCESS *, so it works with the set of callers that want - a child. subst.c:process_substitute adds to the list, the various wait* - functions manipulate child->running and child->status, and processes are - eventually removed from the list and added to the bgpids table. */ - -static void -procsub_free (p) - PROCESS *p; -{ - FREE (p->command); - free (p); -} - -PROCESS * -procsub_add (p) - PROCESS *p; -{ - sigset_t set, oset; - - BLOCK_CHILD (set, oset); - if (procsubs.head == 0) - { - procsubs.head = procsubs.end = p; - procsubs.nproc = 0; - } - else - { - procsubs.end->next = p; - procsubs.end = p; - } - procsubs.nproc++; - UNBLOCK_CHILD (oset); - - return p; -} - -PROCESS * -procsub_search (pid) - pid_t pid; -{ - PROCESS *p; - sigset_t set, oset; - - BLOCK_CHILD (set, oset); - for (p = procsubs.head; p; p = p->next) - if (p->pid == pid) - break; - UNBLOCK_CHILD (oset); - - return p; -} - -PROCESS * -procsub_delete (pid) - pid_t pid; -{ - PROCESS *p, *prev; - sigset_t set, oset; - - BLOCK_CHILD (set, oset); - for (p = prev = procsubs.head; p; prev = p, p = p->next) - if (p->pid == pid) - { - prev->next = p->next; - break; - } - - if (p == 0) - { - UNBLOCK_CHILD (oset); - return p; - } - - if (p == procsubs.head) - procsubs.head = procsubs.head->next; - else if (p == procsubs.end) - procsubs.end = prev; - - procsubs.nproc--; - if (procsubs.nproc == 0) - procsubs.head = procsubs.end = 0; - else if (procsubs.nproc == 1) /* XXX */ - procsubs.end = procsubs.head; - - /* this can't be called anywhere in a signal handling path */ - bgp_add (p->pid, process_exit_status (p->status)); - UNBLOCK_CHILD (oset); - return (p); -} - -int -procsub_waitpid (pid) - pid_t pid; -{ - PROCESS *p; - int r; - - p = procsub_search (pid); - if (p == 0) - return -1; - if (p->running == PS_DONE) - return (p->status); - r = wait_for (p->pid, 0); - return (r); /* defer removing until later */ -} - -void -procsub_waitall () -{ - PROCESS *p; - int r; - - for (p = procsubs.head; p; p = p->next) - { - if (p->running == PS_DONE) - continue; - r = wait_for (p->pid, 0); - } -} - -void -procsub_clear () -{ - PROCESS *p, *ps; - sigset_t set, oset; - - BLOCK_CHILD (set, oset); - - for (ps = procsubs.head; ps; ) - { - p = ps; - ps = ps->next; - procsub_free (p); - } - procsubs.head = procsubs.end = 0; - procsubs.nproc = 0; - UNBLOCK_CHILD (oset); -} - -/* Must be called with SIGCHLD blocked. */ -void -procsub_prune () -{ - PROCESS *ohead, *oend, *ps, *p; - int onproc; - - if (procsubs.nproc == 0) - return; - - ohead = procsubs.head; - oend = procsubs.end; - onproc = procsubs.nproc; - - procsubs.head = procsubs.end = 0; - procsubs.nproc = 0; - - for (p = ohead; p; ) - { - ps = p->next; - p->next = 0; - if (p->running == PS_DONE) - { - bgp_add (p->pid, process_exit_status (p->status)); - procsub_free (p); - } - else - procsub_add (p); - p = ps; - } -} -#endif - -/* Reset the values of js.j_lastj and js.j_firstj after one or both have - been deleted. The caller should check whether js.j_njobs is 0 before - calling this. This wraps around, but the rest of the code does not. At - this point, it should not matter. */ -static void -reset_job_indices () -{ - int old; - - if (jobs[js.j_firstj] == 0) - { - old = js.j_firstj++; - if (old >= js.j_jobslots) - old = js.j_jobslots - 1; - while (js.j_firstj != old) - { - if (js.j_firstj >= js.j_jobslots) - js.j_firstj = 0; - if (jobs[js.j_firstj] || js.j_firstj == old) /* needed if old == 0 */ - break; - js.j_firstj++; - } - if (js.j_firstj == old) - js.j_firstj = js.j_lastj = js.j_njobs = 0; - } - if (jobs[js.j_lastj] == 0) - { - old = js.j_lastj--; - if (old < 0) - old = 0; - while (js.j_lastj != old) - { - if (js.j_lastj < 0) - js.j_lastj = js.j_jobslots - 1; - if (jobs[js.j_lastj] || js.j_lastj == old) /* needed if old == js.j_jobslots */ - break; - js.j_lastj--; - } - if (js.j_lastj == old) - js.j_firstj = js.j_lastj = js.j_njobs = 0; - } -} - -/* Delete all DEAD jobs that the user had received notification about. */ -static void -cleanup_dead_jobs () -{ - register int i; - int os; - PROCESS *discard; - - if (js.j_jobslots == 0 || jobs_list_frozen) - return; - - QUEUE_SIGCHLD(os); - - /* XXX could use js.j_firstj and js.j_lastj here */ - for (i = 0; i < js.j_jobslots; i++) - { - if (i < js.j_firstj && jobs[i]) - INTERNAL_DEBUG (("cleanup_dead_jobs: job %d non-null before js.j_firstj (%d)", i, js.j_firstj)); - if (i > js.j_lastj && jobs[i]) - INTERNAL_DEBUG(("cleanup_dead_jobs: job %d non-null after js.j_lastj (%d)", i, js.j_lastj)); - - if (jobs[i] && DEADJOB (i) && IS_NOTIFIED (i)) - delete_job (i, 0); - } - -#if defined (PROCESS_SUBSTITUTION) - procsub_prune (); - last_procsub_child = (PROCESS *)NULL; -#endif - -#if defined (COPROCESS_SUPPORT) - coproc_reap (); -#endif - - UNQUEUE_SIGCHLD(os); -} - -static int -processes_in_job (job) - int job; -{ - int nproc; - register PROCESS *p; - - nproc = 0; - p = jobs[job]->pipe; - do - { - p = p->next; - nproc++; - } - while (p != jobs[job]->pipe); - - return nproc; -} - -static void -delete_old_job (pid) - pid_t pid; -{ - PROCESS *p; - int job; - - job = find_job (pid, 0, &p); - if (job != NO_JOB) - { - INTERNAL_DEBUG (("delete_old_job: found pid %d in job %d with state %d", pid, job, jobs[job]->state)); - if (JOBSTATE (job) == JDEAD) - delete_job (job, DEL_NOBGPID); - else - { - internal_debug (_("forked pid %d appears in running job %d"), pid, job+1); - if (p) - p->pid = 0; - } - } -} - -/* Reallocate and compress the jobs list. This returns with a jobs array - whose size is a multiple of JOB_SLOTS and can hold the current number of - jobs. Heuristics are used to minimize the number of new reallocs. */ -static void -realloc_jobs_list () -{ - sigset_t set, oset; - int nsize, i, j, ncur, nprev; - JOB **nlist; - - ncur = nprev = NO_JOB; - nsize = ((js.j_njobs + JOB_SLOTS - 1) / JOB_SLOTS); - nsize *= JOB_SLOTS; - i = js.j_njobs % JOB_SLOTS; - if (i == 0 || i > (JOB_SLOTS >> 1)) - nsize += JOB_SLOTS; - - BLOCK_CHILD (set, oset); - nlist = (js.j_jobslots == nsize) ? jobs : (JOB **) xmalloc (nsize * sizeof (JOB *)); - - js.c_reaped = js.j_ndead = 0; - for (i = j = 0; i < js.j_jobslots; i++) - if (jobs[i]) - { - if (i == js.j_current) - ncur = j; - if (i == js.j_previous) - nprev = j; - nlist[j++] = jobs[i]; - if (jobs[i]->state == JDEAD) - { - js.j_ndead++; - js.c_reaped += processes_in_job (i); - } - } - -#if 0 - itrace ("realloc_jobs_list: resize jobs list from %d to %d", js.j_jobslots, nsize); - itrace ("realloc_jobs_list: j_lastj changed from %d to %d", js.j_lastj, (j > 0) ? j - 1 : 0); - itrace ("realloc_jobs_list: j_njobs changed from %d to %d", js.j_njobs, j); - itrace ("realloc_jobs_list: js.j_ndead %d js.c_reaped %d", js.j_ndead, js.c_reaped); -#endif - - js.j_firstj = 0; - js.j_lastj = (j > 0) ? j - 1 : 0; - js.j_njobs = j; - js.j_jobslots = nsize; - - /* Zero out remaining slots in new jobs list */ - for ( ; j < nsize; j++) - nlist[j] = (JOB *)NULL; - - if (jobs != nlist) - { - free (jobs); - jobs = nlist; - } - - if (ncur != NO_JOB) - js.j_current = ncur; - if (nprev != NO_JOB) - js.j_previous = nprev; - - /* Need to reset these */ - if (js.j_current == NO_JOB || js.j_previous == NO_JOB || js.j_current > js.j_lastj || js.j_previous > js.j_lastj) - reset_current (); - -#if 0 - itrace ("realloc_jobs_list: reset js.j_current (%d) and js.j_previous (%d)", js.j_current, js.j_previous); -#endif - - UNBLOCK_CHILD (oset); -} - -/* Compact the jobs list by removing dead jobs. Assume that we have filled - the jobs array to some predefined maximum. Called when the shell is not - the foreground process (subshell_environment != 0). Returns the first - available slot in the compacted list. If that value is js.j_jobslots, then - the list needs to be reallocated. The jobs array may be in new memory if - this returns > 0 and < js.j_jobslots. FLAGS is reserved for future use. */ -static int -compact_jobs_list (flags) - int flags; -{ - if (js.j_jobslots == 0 || jobs_list_frozen) - return js.j_jobslots; - - reap_dead_jobs (); - realloc_jobs_list (); - -#if 0 - itrace("compact_jobs_list: returning %d", (js.j_lastj || jobs[js.j_lastj]) ? js.j_lastj + 1 : 0); -#endif - - return ((js.j_lastj || jobs[js.j_lastj]) ? js.j_lastj + 1 : 0); -} - -/* Delete the job at INDEX from the job list. Must be called - with SIGCHLD blocked. */ -void -delete_job (job_index, dflags) - int job_index, dflags; -{ - register JOB *temp; - PROCESS *proc; - int ndel; - - if (js.j_jobslots == 0 || jobs_list_frozen) - return; - - if ((dflags & DEL_WARNSTOPPED) && subshell_environment == 0 && STOPPED (job_index)) - internal_warning (_("deleting stopped job %d with process group %ld"), job_index+1, (long)jobs[job_index]->pgrp); - temp = jobs[job_index]; - if (temp == 0) - return; - - if ((dflags & DEL_NOBGPID) == 0 && (temp->flags & (J_ASYNC|J_FOREGROUND)) == J_ASYNC) - { - proc = find_last_proc (job_index, 0); - if (proc) - bgp_add (proc->pid, process_exit_status (proc->status)); - } - - jobs[job_index] = (JOB *)NULL; - if (temp == js.j_lastmade) - js.j_lastmade = 0; - else if (temp == js.j_lastasync) - js.j_lastasync = 0; - - free (temp->wd); - ndel = discard_pipeline (temp->pipe); - - js.c_injobs -= ndel; - if (temp->state == JDEAD) - { - /* XXX - save_pipeline and restore_pipeline (e.g., for DEBUG trap) can - mess with this total. */ - js.c_reaped -= ndel; /* assumes proc hadn't been reaped earlier */ - js.j_ndead--; - if (js.c_reaped < 0) - { - INTERNAL_DEBUG (("delete_job (%d pgrp %d): js.c_reaped (%d) < 0 ndel = %d js.j_ndead = %d", job_index, temp->pgrp, js.c_reaped, ndel, js.j_ndead)); - js.c_reaped = 0; - } - } - - if (temp->deferred) - dispose_command (temp->deferred); - - free (temp); - - js.j_njobs--; - if (js.j_njobs == 0) - js.j_firstj = js.j_lastj = 0; - else if (jobs[js.j_firstj] == 0 || jobs[js.j_lastj] == 0) - reset_job_indices (); - - if (job_index == js.j_current || job_index == js.j_previous) - reset_current (); -} - -/* Must be called with SIGCHLD blocked. */ -void -nohup_job (job_index) - int job_index; -{ - register JOB *temp; - - if (js.j_jobslots == 0) - return; - - if (temp = jobs[job_index]) - temp->flags |= J_NOHUP; -} - -/* Get rid of the data structure associated with a process chain. */ -int -discard_pipeline (chain) - register PROCESS *chain; -{ - register PROCESS *this, *next; - int n; - - this = chain; - n = 0; - do - { - next = this->next; - FREE (this->command); - free (this); - n++; - this = next; - } - while (this != chain); - - return n; -} - -/* Add this process to the chain being built in the_pipeline. - NAME is the command string that will be exec'ed later. - PID is the process id of the child. */ -static void -add_process (name, pid) - char *name; - pid_t pid; -{ - PROCESS *t, *p; - -#if defined (RECYCLES_PIDS) - int j; - p = find_process (pid, 0, &j); - if (p) - { - if (j == NO_JOB) - internal_debug ("add_process: process %5ld (%s) in the_pipeline", (long)p->pid, p->command); - if (PALIVE (p)) - internal_warning (_("add_process: pid %5ld (%s) marked as still alive"), (long)p->pid, p->command); - p->running = PS_RECYCLED; /* mark as recycled */ - } -#endif - - t = (PROCESS *)xmalloc (sizeof (PROCESS)); - t->next = the_pipeline; - t->pid = pid; - WSTATUS (t->status) = 0; - t->running = PS_RUNNING; - t->command = name; - the_pipeline = t; - - if (t->next == 0) - t->next = t; - else - { - p = t->next; - while (p->next != t->next) - p = p->next; - p->next = t; - } -} - -/* Create a (dummy) PROCESS with NAME, PID, and STATUS, and make it the last - process in jobs[JID]->pipe. Used by the lastpipe code. */ -void -append_process (name, pid, status, jid) - char *name; - pid_t pid; - int status; - int jid; -{ - PROCESS *t, *p; - - t = (PROCESS *)xmalloc (sizeof (PROCESS)); - t->next = (PROCESS *)NULL; - t->pid = pid; - /* set process exit status using offset discovered by configure */ - t->status = (status & 0xff) << WEXITSTATUS_OFFSET; - t->running = PS_DONE; - t->command = name; - - js.c_reaped++; /* XXX */ - - for (p = jobs[jid]->pipe; p->next != jobs[jid]->pipe; p = p->next) - ; - p->next = t; - t->next = jobs[jid]->pipe; -} - -#if 0 -/* Take the last job and make it the first job. Must be called with - SIGCHLD blocked. */ -int -rotate_the_pipeline () -{ - PROCESS *p; - - if (the_pipeline->next == the_pipeline) - return; - for (p = the_pipeline; p->next != the_pipeline; p = p->next) - ; - the_pipeline = p; -} - -/* Reverse the order of the processes in the_pipeline. Must be called with - SIGCHLD blocked. */ -int -reverse_the_pipeline () -{ - PROCESS *p, *n; - - if (the_pipeline->next == the_pipeline) - return; - - for (p = the_pipeline; p->next != the_pipeline; p = p->next) - ; - p->next = (PROCESS *)NULL; - - n = REVERSE_LIST (the_pipeline, PROCESS *); - - the_pipeline = n; - for (p = the_pipeline; p->next; p = p->next) - ; - p->next = the_pipeline; -} -#endif - -/* Map FUNC over the list of jobs. If FUNC returns non-zero, - then it is time to stop mapping, and that is the return value - for map_over_jobs. FUNC is called with a JOB, arg1, arg2, - and INDEX. */ -static int -map_over_jobs (func, arg1, arg2) - sh_job_map_func_t *func; - int arg1, arg2; -{ - register int i; - int result; - sigset_t set, oset; - - if (js.j_jobslots == 0) - return 0; - - BLOCK_CHILD (set, oset); - - /* XXX could use js.j_firstj here */ - for (i = result = 0; i < js.j_jobslots; i++) - { - if (i < js.j_firstj && jobs[i]) - INTERNAL_DEBUG (("map_over_jobs: job %d non-null before js.j_firstj (%d)", i, js.j_firstj)); - if (i > js.j_lastj && jobs[i]) - INTERNAL_DEBUG (("map_over_jobs: job %d non-null after js.j_lastj (%d)", i, js.j_lastj)); - - if (jobs[i]) - { - result = (*func)(jobs[i], arg1, arg2, i); - if (result) - break; - } - } - - UNBLOCK_CHILD (oset); - - return (result); -} - -/* Cause all the jobs in the current pipeline to exit. */ -void -terminate_current_pipeline () -{ - if (pipeline_pgrp && pipeline_pgrp != shell_pgrp) - { - killpg (pipeline_pgrp, SIGTERM); - killpg (pipeline_pgrp, SIGCONT); - } -} - -/* Cause all stopped jobs to exit. */ -void -terminate_stopped_jobs () -{ - register int i; - - /* XXX could use js.j_firstj here */ - for (i = 0; i < js.j_jobslots; i++) - { - if (jobs[i] && STOPPED (i)) - { - killpg (jobs[i]->pgrp, SIGTERM); - killpg (jobs[i]->pgrp, SIGCONT); - } - } -} - -/* Cause all jobs, running or stopped, to receive a hangup signal. If - a job is marked J_NOHUP, don't send the SIGHUP. */ -void -hangup_all_jobs () -{ - register int i; - - /* XXX could use js.j_firstj here */ - for (i = 0; i < js.j_jobslots; i++) - { - if (jobs[i]) - { - if (jobs[i]->flags & J_NOHUP) - continue; - killpg (jobs[i]->pgrp, SIGHUP); - if (STOPPED (i)) - killpg (jobs[i]->pgrp, SIGCONT); - } - } -} - -void -kill_current_pipeline () -{ - stop_making_children (); - start_pipeline (); -} - -static PROCESS * -find_pid_in_pipeline (pid, pipeline, alive_only) - pid_t pid; - PROCESS *pipeline; - int alive_only; -{ - PROCESS *p; - - p = pipeline; - do - { - /* Return it if we found it. Don't ever return a recycled pid. */ - if (p->pid == pid && ((alive_only == 0 && PRECYCLED(p) == 0) || PALIVE(p))) - return (p); - - p = p->next; - } - while (p != pipeline); - return ((PROCESS *)NULL); -} - -/* Return the pipeline that PID belongs to. Note that the pipeline - doesn't have to belong to a job. Must be called with SIGCHLD blocked. - If JOBP is non-null, return the index of the job containing PID. */ -static PROCESS * -find_pipeline (pid, alive_only, jobp) - pid_t pid; - int alive_only; - int *jobp; /* index into jobs list or NO_JOB */ -{ - int job; - PROCESS *p; - struct pipeline_saver *save; - - /* See if this process is in the pipeline that we are building. */ - p = (PROCESS *)NULL; - if (jobp) - *jobp = NO_JOB; - - if (the_pipeline && (p = find_pid_in_pipeline (pid, the_pipeline, alive_only))) - return (p); - - /* Is this process in a saved pipeline? */ - for (save = saved_pipeline; save; save = save->next) - if (save->pipeline && (p = find_pid_in_pipeline (pid, save->pipeline, alive_only))) - return (p); - -#if defined (PROCESS_SUBSTITUTION) - if (procsubs.nproc > 0 && (p = procsub_search (pid)) && ((alive_only == 0 && PRECYCLED(p) == 0) || PALIVE(p))) - return (p); -#endif - - job = find_job (pid, alive_only, &p); - if (jobp) - *jobp = job; - return (job == NO_JOB) ? (PROCESS *)NULL : jobs[job]->pipe; -} - -/* Return the PROCESS * describing PID. If JOBP is non-null return the index - into the jobs array of the job containing PID. Must be called with - SIGCHLD blocked. */ -static PROCESS * -find_process (pid, alive_only, jobp) - pid_t pid; - int alive_only; - int *jobp; /* index into jobs list or NO_JOB */ -{ - PROCESS *p; - - p = find_pipeline (pid, alive_only, jobp); - while (p && p->pid != pid) - p = p->next; - return p; -} - -/* Return the job index that PID belongs to, or NO_JOB if it doesn't - belong to any job. Must be called with SIGCHLD blocked. */ -static int -find_job (pid, alive_only, procp) - pid_t pid; - int alive_only; - PROCESS **procp; -{ - register int i; - PROCESS *p; - - /* XXX could use js.j_firstj here, and should check js.j_lastj */ - for (i = 0; i < js.j_jobslots; i++) - { - if (i < js.j_firstj && jobs[i]) - INTERNAL_DEBUG (("find_job: job %d non-null before js.j_firstj (%d)", i, js.j_firstj)); - if (i > js.j_lastj && jobs[i]) - INTERNAL_DEBUG (("find_job: job %d non-null after js.j_lastj (%d)", i, js.j_lastj)); - - if (jobs[i]) - { - p = jobs[i]->pipe; - - do - { - if (p->pid == pid && ((alive_only == 0 && PRECYCLED(p) == 0) || PALIVE(p))) - { - if (procp) - *procp = p; - return (i); - } - - p = p->next; - } - while (p != jobs[i]->pipe); - } - } - - return (NO_JOB); -} - -/* Find a job given a PID. If BLOCK is non-zero, block SIGCHLD as - required by find_job. */ -int -get_job_by_pid (pid, block, procp) - pid_t pid; - int block; - PROCESS **procp; -{ - int job; - sigset_t set, oset; - - if (block) - BLOCK_CHILD (set, oset); - - job = find_job (pid, 0, procp); - - if (block) - UNBLOCK_CHILD (oset); - - return job; -} - -/* Print descriptive information about the job with leader pid PID. */ -void -describe_pid (pid) - pid_t pid; -{ - int job; - sigset_t set, oset; - - BLOCK_CHILD (set, oset); - - job = find_job (pid, 0, NULL); - - if (job != NO_JOB) - fprintf (stderr, "[%d] %ld\n", job + 1, (long)pid); - else - programming_error (_("describe_pid: %ld: no such pid"), (long)pid); - - UNBLOCK_CHILD (oset); -} - -static char * -j_strsignal (s) - int s; -{ - char *x; - - x = strsignal (s); - if (x == 0) - { - x = retcode_name_buffer; - snprintf (x, sizeof(retcode_name_buffer), _("Signal %d"), s); - } - return x; -} - -static char * -printable_job_status (j, p, format) - int j; - PROCESS *p; - int format; -{ - static char *temp; - int es; - - temp = _("Done"); - - if (STOPPED (j) && format == 0) - { - if (posixly_correct == 0 || p == 0 || (WIFSTOPPED (p->status) == 0)) - temp = _("Stopped"); - else - { - temp = retcode_name_buffer; - snprintf (temp, sizeof(retcode_name_buffer), _("Stopped(%s)"), signal_name (WSTOPSIG (p->status))); - } - } - else if (RUNNING (j)) - temp = _("Running"); - else - { - if (WIFSTOPPED (p->status)) - temp = j_strsignal (WSTOPSIG (p->status)); - else if (WIFSIGNALED (p->status)) - temp = j_strsignal (WTERMSIG (p->status)); - else if (WIFEXITED (p->status)) - { - temp = retcode_name_buffer; - es = WEXITSTATUS (p->status); - if (es == 0) - { - strncpy (temp, _("Done"), sizeof (retcode_name_buffer) - 1); - temp[sizeof (retcode_name_buffer) - 1] = '\0'; - } - else if (posixly_correct) - snprintf (temp, sizeof(retcode_name_buffer), _("Done(%d)"), es); - else - snprintf (temp, sizeof(retcode_name_buffer), _("Exit %d"), es); - } - else - temp = _("Unknown status"); - } - - return temp; -} - -/* This is the way to print out information on a job if you - know the index. FORMAT is: - - JLIST_NORMAL) [1]+ Running emacs - JLIST_LONG ) [1]+ 2378 Running emacs - -1 ) [1]+ 2378 emacs - - JLIST_NORMAL) [1]+ Stopped ls | more - JLIST_LONG ) [1]+ 2369 Stopped ls - 2367 | more - JLIST_PID_ONLY) - Just list the pid of the process group leader (really - the process group). - JLIST_CHANGED_ONLY) - Use format JLIST_NORMAL, but list only jobs about which - the user has not been notified. */ - -/* Print status for pipeline P. If JOB_INDEX is >= 0, it is the index into - the JOBS array corresponding to this pipeline. FORMAT is as described - above. Must be called with SIGCHLD blocked. - - If you're printing a pipeline that's not in the jobs array, like the - current pipeline as it's being created, pass -1 for JOB_INDEX */ -static void -print_pipeline (p, job_index, format, stream) - PROCESS *p; - int job_index, format; - FILE *stream; -{ - PROCESS *first, *last, *show; - int es, name_padding; - char *temp; - - if (p == 0) - return; - - first = last = p; - while (last->next != first) - last = last->next; - - for (;;) - { - if (p != first) - fprintf (stream, format ? " " : " |"); - - if (format != JLIST_STANDARD) - fprintf (stream, "%5ld", (long)p->pid); - - fprintf (stream, " "); - - if (format > -1 && job_index >= 0) - { - show = format ? p : last; - temp = printable_job_status (job_index, show, format); - - if (p != first) - { - if (format) - { - if (show->running == first->running && - WSTATUS (show->status) == WSTATUS (first->status)) - temp = ""; - } - else - temp = (char *)NULL; - } - - if (temp) - { - fprintf (stream, "%s", temp); - - es = STRLEN (temp); - if (es == 0) - es = 2; /* strlen ("| ") */ - name_padding = LONGEST_SIGNAL_DESC - es; - - fprintf (stream, "%*s", name_padding, ""); - - if ((WIFSTOPPED (show->status) == 0) && - (WIFCONTINUED (show->status) == 0) && - WIFCORED (show->status)) - fprintf (stream, _("(core dumped) ")); - } - } - - if (p != first && format) - fprintf (stream, "| "); - - if (p->command) - fprintf (stream, "%s", p->command); - - if (p == last && job_index >= 0) - { - temp = current_working_directory (); - - if (RUNNING (job_index) && (IS_FOREGROUND (job_index) == 0)) - fprintf (stream, " &"); - - if (strcmp (temp, jobs[job_index]->wd) != 0) - fprintf (stream, - _(" (wd: %s)"), polite_directory_format (jobs[job_index]->wd)); - } - - if (format || (p == last)) - { - /* We need to add a CR only if this is an interactive shell, and - we're reporting the status of a completed job asynchronously. - We can't really check whether this particular job is being - reported asynchronously, so just add the CR if the shell is - currently interactive and asynchronous notification is enabled. */ - if (asynchronous_notification && interactive) - putc ('\r', stream); - fprintf (stream, "\n"); - } - - if (p == last) - break; - p = p->next; - } - fflush (stream); -} - -/* Print information to STREAM about jobs[JOB_INDEX] according to FORMAT. - Must be called with SIGCHLD blocked or queued with queue_sigchld */ -static void -pretty_print_job (job_index, format, stream) - int job_index, format; - FILE *stream; -{ - register PROCESS *p; - - /* Format only pid information about the process group leader? */ - if (format == JLIST_PID_ONLY) - { - fprintf (stream, "%ld\n", (long)jobs[job_index]->pipe->pid); - return; - } - - if (format == JLIST_CHANGED_ONLY) - { - if (IS_NOTIFIED (job_index)) - return; - format = JLIST_STANDARD; - } - - if (format != JLIST_NONINTERACTIVE) - fprintf (stream, "[%d]%c ", job_index + 1, - (job_index == js.j_current) ? '+': - (job_index == js.j_previous) ? '-' : ' '); - - if (format == JLIST_NONINTERACTIVE) - format = JLIST_LONG; - - p = jobs[job_index]->pipe; - - print_pipeline (p, job_index, format, stream); - - /* We have printed information about this job. When the job's - status changes, waitchld () sets the notification flag to 0. */ - jobs[job_index]->flags |= J_NOTIFIED; -} - -static int -print_job (job, format, state, job_index) - JOB *job; - int format, state, job_index; -{ - if (state == -1 || (JOB_STATE)state == job->state) - pretty_print_job (job_index, format, stdout); - return (0); -} - -void -list_one_job (job, format, ignore, job_index) - JOB *job; - int format, ignore, job_index; -{ - pretty_print_job (job_index, format, stdout); - cleanup_dead_jobs (); -} - -void -list_stopped_jobs (format) - int format; -{ - cleanup_dead_jobs (); - map_over_jobs (print_job, format, (int)JSTOPPED); -} - -void -list_running_jobs (format) - int format; -{ - cleanup_dead_jobs (); - map_over_jobs (print_job, format, (int)JRUNNING); -} - -/* List jobs. If FORMAT is non-zero, then the long form of the information - is printed, else just a short version. */ -void -list_all_jobs (format) - int format; -{ - cleanup_dead_jobs (); - map_over_jobs (print_job, format, -1); -} - -/* Fork, handling errors. Returns the pid of the newly made child, or 0. - COMMAND is just for remembering the name of the command; we don't do - anything else with it. ASYNC_P says what to do with the tty. If - non-zero, then don't give it away. */ -pid_t -make_child (command, flags) - char *command; - int flags; -{ - int async_p, forksleep; - sigset_t set, oset, termset, chldset, oset_copy; - pid_t pid; - SigHandler *oterm; - - sigemptyset (&oset_copy); - sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &oset_copy); - sigaddset (&oset_copy, SIGTERM); - - /* Block SIGTERM here and unblock in child after fork resets the - set of pending signals. */ - sigemptyset (&set); - sigaddset (&set, SIGCHLD); - sigaddset (&set, SIGINT); - sigaddset (&set, SIGTERM); - - sigemptyset (&oset); - sigprocmask (SIG_BLOCK, &set, &oset); - - /* Blocked in the parent, child will receive it after unblocking SIGTERM */ - if (interactive_shell) - oterm = set_signal_handler (SIGTERM, SIG_DFL); - - making_children (); - - async_p = (flags & FORK_ASYNC); - forksleep = 1; - -#if defined (BUFFERED_INPUT) - /* If default_buffered_input is active, we are reading a script. If - the command is asynchronous, we have already duplicated /dev/null - as fd 0, but have not changed the buffered stream corresponding to - the old fd 0. We don't want to sync the stream in this case. */ - if (default_buffered_input != -1 && - (!async_p || default_buffered_input > 0)) - sync_buffered_stream (default_buffered_input); -#endif /* BUFFERED_INPUT */ - - /* Create the child, handle severe errors. Retry on EAGAIN. */ - while ((pid = fork ()) < 0 && errno == EAGAIN && forksleep < FORKSLEEP_MAX) - { - /* bash-4.2 */ - /* keep SIGTERM blocked until we reset the handler to SIG_IGN */ - sigprocmask (SIG_SETMASK, &oset_copy, (sigset_t *)NULL); - /* If we can't create any children, try to reap some dead ones. */ - waitchld (-1, 0); - - errno = EAGAIN; /* restore errno */ - sys_error ("fork: retry"); - - if (sleep (forksleep) != 0) - break; - forksleep <<= 1; - - if (interrupt_state) - break; - sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL); - } - - if (pid != 0) - if (interactive_shell) - set_signal_handler (SIGTERM, oterm); - - if (pid < 0) - { - sys_error ("fork"); - - /* Kill all of the processes in the current pipeline. */ - terminate_current_pipeline (); - - /* Discard the current pipeline, if any. */ - if (the_pipeline) - kill_current_pipeline (); - - set_exit_status (EX_NOEXEC); - throw_to_top_level (); /* Reset signals, etc. */ - } - - if (pid == 0) - { - /* In the child. Give this child the right process group, set the - signals to the default state for a new process. */ - pid_t mypid; - - subshell_environment |= SUBSHELL_IGNTRAP; - - /* If this ends up being changed to modify or use `command' in the - child process, go back and change callers who free `command' in - the child process when this returns. */ - mypid = getpid (); -#if defined (BUFFERED_INPUT) - /* Close default_buffered_input if it's > 0. We don't close it if it's - 0 because that's the file descriptor used when redirecting input, - and it's wrong to close the file in that case. */ - unset_bash_input (0); -#endif /* BUFFERED_INPUT */ - - CLRINTERRUPT; /* XXX - children have their own interrupt state */ - - /* Restore top-level signal mask, including unblocking SIGTERM */ - restore_sigmask (); - - if (job_control) - { - /* All processes in this pipeline belong in the same - process group. */ - - if (pipeline_pgrp == 0) /* This is the first child. */ - pipeline_pgrp = mypid; - - /* Check for running command in backquotes. */ - if (pipeline_pgrp == shell_pgrp) - ignore_tty_job_signals (); - else - default_tty_job_signals (); - - /* Set the process group before trying to mess with the terminal's - process group. This is mandated by POSIX. */ - /* This is in accordance with the Posix 1003.1 standard, - section B.7.2.4, which says that trying to set the terminal - process group with tcsetpgrp() to an unused pgrp value (like - this would have for the first child) is an error. Section - B.4.3.3, p. 237 also covers this, in the context of job control - shells. */ - if (setpgid (mypid, pipeline_pgrp) < 0) - sys_error (_("child setpgid (%ld to %ld)"), (long)mypid, (long)pipeline_pgrp); - - /* By convention (and assumption above), if - pipeline_pgrp == shell_pgrp, we are making a child for - command substitution. - In this case, we don't want to give the terminal to the - shell's process group (we could be in the middle of a - pipeline, for example). */ - if ((flags & FORK_NOTERM) == 0 && async_p == 0 && pipeline_pgrp != shell_pgrp && ((subshell_environment&(SUBSHELL_ASYNC|SUBSHELL_PIPE)) == 0) && running_in_background == 0) - give_terminal_to (pipeline_pgrp, 0); - -#if defined (PGRP_PIPE) - if (pipeline_pgrp == mypid) - pipe_read (pgrp_pipe); -#endif - } - else /* Without job control... */ - { - if (pipeline_pgrp == 0) - pipeline_pgrp = shell_pgrp; - - /* If these signals are set to SIG_DFL, we encounter the curious - situation of an interactive ^Z to a running process *working* - and stopping the process, but being unable to do anything with - that process to change its state. On the other hand, if they - are set to SIG_IGN, jobs started from scripts do not stop when - the shell running the script gets a SIGTSTP and stops. */ - - default_tty_job_signals (); - } - -#if defined (PGRP_PIPE) - /* Release the process group pipe, since our call to setpgid () - is done. The last call to sh_closepipe is done in stop_pipeline. */ - sh_closepipe (pgrp_pipe); -#endif /* PGRP_PIPE */ - - /* Don't set last_asynchronous_pid in the child */ - -#if defined (RECYCLES_PIDS) - if (last_asynchronous_pid == mypid) - /* Avoid pid aliasing. 1 seems like a safe, unusual pid value. */ - last_asynchronous_pid = 1; -#endif - } - else - { - /* In the parent. Remember the pid of the child just created - as the proper pgrp if this is the first child. */ - - if (job_control) - { - if (pipeline_pgrp == 0) - { - pipeline_pgrp = pid; - /* Don't twiddle terminal pgrps in the parent! This is the bug, - not the good thing of twiddling them in the child! */ - /* give_terminal_to (pipeline_pgrp, 0); */ - } - /* This is done on the recommendation of the Rationale section of - the POSIX 1003.1 standard, where it discusses job control and - shells. It is done to avoid possible race conditions. (Ref. - 1003.1 Rationale, section B.4.3.3, page 236). */ - setpgid (pid, pipeline_pgrp); - } - else - { - if (pipeline_pgrp == 0) - pipeline_pgrp = shell_pgrp; - } - - /* Place all processes into the jobs array regardless of the - state of job_control. */ - add_process (command, pid); - - if (async_p) - last_asynchronous_pid = pid; -#if defined (RECYCLES_PIDS) - else if (last_asynchronous_pid == pid) - /* Avoid pid aliasing. 1 seems like a safe, unusual pid value. */ - last_asynchronous_pid = 1; -#endif - - /* Delete the saved status for any job containing this PID in case it's - been reused. */ - delete_old_job (pid); - - /* Perform the check for pid reuse unconditionally. Some systems reuse - PIDs before giving a process CHILD_MAX/_SC_CHILD_MAX unique ones. */ - bgp_delete (pid); /* new process, discard any saved status */ - - last_made_pid = pid; - - /* keep stats */ - js.c_totforked++; - js.c_living++; - - /* Unblock SIGTERM, SIGINT, and SIGCHLD unless creating a pipeline, in - which case SIGCHLD remains blocked until all commands in the pipeline - have been created (execute_cmd.c:execute_pipeline()). */ - sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL); - } - - return (pid); -} - -/* These two functions are called only in child processes. */ -void -ignore_tty_job_signals () -{ - set_signal_handler (SIGTSTP, SIG_IGN); - set_signal_handler (SIGTTIN, SIG_IGN); - set_signal_handler (SIGTTOU, SIG_IGN); -} - -/* Reset the tty-generated job control signals to SIG_DFL unless that signal - was ignored at entry to the shell, in which case we need to set it to - SIG_IGN in the child. We can't rely on resetting traps, since the hard - ignored signals can't be trapped. */ -void -default_tty_job_signals () -{ - if (signal_is_trapped (SIGTSTP) == 0 && signal_is_hard_ignored (SIGTSTP)) - set_signal_handler (SIGTSTP, SIG_IGN); - else - set_signal_handler (SIGTSTP, SIG_DFL); - - if (signal_is_trapped (SIGTTIN) == 0 && signal_is_hard_ignored (SIGTTIN)) - set_signal_handler (SIGTTIN, SIG_IGN); - else - set_signal_handler (SIGTTIN, SIG_DFL); - - if (signal_is_trapped (SIGTTOU) == 0 && signal_is_hard_ignored (SIGTTOU)) - set_signal_handler (SIGTTOU, SIG_IGN); - else - set_signal_handler (SIGTTOU, SIG_DFL); -} - -/* Called once in a parent process. */ -void -get_original_tty_job_signals () -{ - static int fetched = 0; - - if (fetched == 0) - { - if (interactive_shell) - { - set_original_signal (SIGTSTP, SIG_DFL); - set_original_signal (SIGTTIN, SIG_DFL); - set_original_signal (SIGTTOU, SIG_DFL); - } - else - { - get_original_signal (SIGTSTP); - get_original_signal (SIGTTIN); - get_original_signal (SIGTTOU); - } - fetched = 1; - } -} - -/* When we end a job abnormally, or if we stop a job, we set the tty to the - state kept in here. When a job ends normally, we set the state in here - to the state of the tty. */ - -static TTYSTRUCT shell_tty_info; - -#if defined (NEW_TTY_DRIVER) -static struct tchars shell_tchars; -static struct ltchars shell_ltchars; -#endif /* NEW_TTY_DRIVER */ - -#if defined (NEW_TTY_DRIVER) && defined (DRAIN_OUTPUT) -/* Since the BSD tty driver does not allow us to change the tty modes - while simultaneously waiting for output to drain and preserving - typeahead, we have to drain the output ourselves before calling - ioctl. We cheat by finding the length of the output queue, and - using select to wait for an appropriate length of time. This is - a hack, and should be labeled as such (it's a hastily-adapted - mutation of a `usleep' implementation). It's only reason for - existing is the flaw in the BSD tty driver. */ - -static int ttspeeds[] = -{ - 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, - 1800, 2400, 4800, 9600, 19200, 38400 -}; - -static void -draino (fd, ospeed) - int fd, ospeed; -{ - register int delay = ttspeeds[ospeed]; - int n; - - if (!delay) - return; - - while ((ioctl (fd, TIOCOUTQ, &n) == 0) && n) - { - if (n > (delay / 100)) - { - struct timeval tv; - - n *= 10; /* 2 bits more for conservativeness. */ - tv.tv_sec = n / delay; - tv.tv_usec = ((n % delay) * 1000000) / delay; - select (fd, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tv); - } - else - break; - } -} -#endif /* NEW_TTY_DRIVER && DRAIN_OUTPUT */ - -/* Return the fd from which we are actually getting input. */ -#define input_tty() (shell_tty != -1) ? shell_tty : fileno (stderr) - -/* Fill the contents of shell_tty_info with the current tty info. */ -int -get_tty_state () -{ - int tty; - - tty = input_tty (); - if (tty != -1) - { -#if defined (NEW_TTY_DRIVER) - ioctl (tty, TIOCGETP, &shell_tty_info); - ioctl (tty, TIOCGETC, &shell_tchars); - ioctl (tty, TIOCGLTC, &shell_ltchars); -#endif /* NEW_TTY_DRIVER */ - -#if defined (TERMIO_TTY_DRIVER) - ioctl (tty, TCGETA, &shell_tty_info); -#endif /* TERMIO_TTY_DRIVER */ - -#if defined (TERMIOS_TTY_DRIVER) - if (tcgetattr (tty, &shell_tty_info) < 0) - { -#if 0 - /* Only print an error message if we're really interactive at - this time. */ - if (interactive) - sys_error ("[%ld: %d (%d)] tcgetattr", (long)getpid (), shell_level, tty); -#endif - return -1; - } -#endif /* TERMIOS_TTY_DRIVER */ - if (check_window_size) - get_new_window_size (0, (int *)0, (int *)0); - } - return 0; -} - -/* Make the current tty use the state in shell_tty_info. */ -int -set_tty_state () -{ - int tty; - - tty = input_tty (); - if (tty != -1) - { -#if defined (NEW_TTY_DRIVER) -# if defined (DRAIN_OUTPUT) - draino (tty, shell_tty_info.sg_ospeed); -# endif /* DRAIN_OUTPUT */ - ioctl (tty, TIOCSETN, &shell_tty_info); - ioctl (tty, TIOCSETC, &shell_tchars); - ioctl (tty, TIOCSLTC, &shell_ltchars); -#endif /* NEW_TTY_DRIVER */ - -#if defined (TERMIO_TTY_DRIVER) - ioctl (tty, TCSETAW, &shell_tty_info); -#endif /* TERMIO_TTY_DRIVER */ - -#if defined (TERMIOS_TTY_DRIVER) - if (tcsetattr (tty, TCSADRAIN, &shell_tty_info) < 0) - { - /* Only print an error message if we're really interactive at - this time. */ - if (interactive) - sys_error ("[%ld: %d (%d)] tcsetattr", (long)getpid (), shell_level, tty); - return -1; - } -#endif /* TERMIOS_TTY_DRIVER */ - } - return 0; -} - -/* Given an index into the jobs array JOB, return the PROCESS struct of the last - process in that job's pipeline. This is the one whose exit status - counts. Must be called with SIGCHLD blocked or queued. */ -static PROCESS * -find_last_proc (job, block) - int job; - int block; -{ - register PROCESS *p; - sigset_t set, oset; - - if (block) - BLOCK_CHILD (set, oset); - - p = jobs[job]->pipe; - while (p && p->next != jobs[job]->pipe) - p = p->next; - - if (block) - UNBLOCK_CHILD (oset); - - return (p); -} - -static pid_t -find_last_pid (job, block) - int job; - int block; -{ - PROCESS *p; - - p = find_last_proc (job, block); - /* Possible race condition here. */ - return p->pid; -} - -/* Wait for a particular child of the shell to finish executing. - This low-level function prints an error message if PID is not - a child of this shell. It returns -1 if it fails, or whatever - wait_for returns otherwise. If the child is not found in the - jobs table, it returns 127. If FLAGS doesn't include JWAIT_PERROR, - we suppress the error message if PID isn't found. */ - -int -wait_for_single_pid (pid, flags) - pid_t pid; - int flags; -{ - register PROCESS *child; - sigset_t set, oset; - int r, job, alive; - - BLOCK_CHILD (set, oset); - child = find_pipeline (pid, 0, (int *)NULL); - UNBLOCK_CHILD (oset); - - if (child == 0) - { - r = bgp_search (pid); - if (r >= 0) - return r; - } - - if (child == 0) - { - if (flags & JWAIT_PERROR) - internal_error (_("wait: pid %ld is not a child of this shell"), (long)pid); - return (257); - } - - alive = 0; - do - { - r = wait_for (pid, 0); - if ((flags & JWAIT_FORCE) == 0) - break; - - BLOCK_CHILD (set, oset); - alive = PALIVE (child); - UNBLOCK_CHILD (oset); - } - while (alive); - - /* POSIX.2: if we just waited for a job, we can remove it from the jobs - table. */ - BLOCK_CHILD (set, oset); - job = find_job (pid, 0, NULL); - if (job != NO_JOB && jobs[job] && DEADJOB (job)) - jobs[job]->flags |= J_NOTIFIED; - UNBLOCK_CHILD (oset); - - /* If running in posix mode, remove the job from the jobs table immediately */ - if (posixly_correct) - { - cleanup_dead_jobs (); - bgp_delete (pid); - } - - /* Check for a trapped signal interrupting the wait builtin and jump out */ - CHECK_WAIT_INTR; - - return r; -} - -/* Wait for all of the background processes started by this shell to finish. */ -int -wait_for_background_pids (ps) - struct procstat *ps; -{ - register int i, r; - int any_stopped, check_async, njobs; - sigset_t set, oset; - pid_t pid; - - for (njobs = any_stopped = 0, check_async = 1;;) - { - BLOCK_CHILD (set, oset); - - /* find first running job; if none running in foreground, break */ - /* XXX could use js.j_firstj and js.j_lastj here */ - for (i = 0; i < js.j_jobslots; i++) - { - if (i < js.j_firstj && jobs[i]) - INTERNAL_DEBUG (("wait_for_background_pids: job %d non-null before js.j_firstj (%d)", i, js.j_firstj)); - if (i > js.j_lastj && jobs[i]) - INTERNAL_DEBUG (("wait_for_background_pids: job %d non-null after js.j_lastj (%d)", i, js.j_lastj)); - - if (jobs[i] && STOPPED (i)) - { - builtin_warning ("job %d[%d] stopped", i+1, find_last_pid (i, 0)); - any_stopped = 1; - } - - if (jobs[i] && RUNNING (i) && IS_FOREGROUND (i) == 0) - break; - } - if (i == js.j_jobslots) - { - UNBLOCK_CHILD (oset); - break; - } - - /* now wait for the last pid in that job. */ - pid = find_last_pid (i, 0); - UNBLOCK_CHILD (oset); - QUIT; - errno = 0; /* XXX */ - r = wait_for_single_pid (pid, JWAIT_PERROR); - if (ps) - { - ps->pid = pid; - ps->status = (r < 0 || r > 256) ? 127 : r; - } - if (r == -1 && errno == ECHILD) - { - /* If we're mistaken about job state, compensate. */ - check_async = 0; - mark_all_jobs_as_dead (); - } - njobs++; - } - -#if defined (PROCESS_SUBSTITUTION) - procsub_waitall (); -#endif - - /* POSIX.2 says the shell can discard the statuses of all completed jobs if - `wait' is called with no arguments. */ - mark_dead_jobs_as_notified (1); - cleanup_dead_jobs (); - bgp_clear (); - - return njobs; -} - -/* Make OLD_SIGINT_HANDLER the SIGINT signal handler. */ -#define INVALID_SIGNAL_HANDLER (SigHandler *)wait_for_background_pids -static SigHandler *old_sigint_handler = INVALID_SIGNAL_HANDLER; - -static int wait_sigint_received; -static int child_caught_sigint; - -int waiting_for_child; - -/* Clean up state after longjmp to wait_intr_buf */ -void -wait_sigint_cleanup () -{ - queue_sigchld = 0; - waiting_for_child = 0; - restore_sigint_handler (); -} - -static void -restore_sigint_handler () -{ - if (old_sigint_handler != INVALID_SIGNAL_HANDLER) - { - set_signal_handler (SIGINT, old_sigint_handler); - old_sigint_handler = INVALID_SIGNAL_HANDLER; - waiting_for_child = 0; - } -} - -/* Handle SIGINT while we are waiting for children in a script to exit. - The `wait' builtin should be interruptible, but all others should be - effectively ignored (i.e. not cause the shell to exit). */ -static sighandler -wait_sigint_handler (sig) - int sig; -{ - SigHandler *sigint_handler; - - if (this_shell_builtin && this_shell_builtin == wait_builtin) - { - set_exit_status (128+SIGINT); - restore_sigint_handler (); - /* If we got a SIGINT while in `wait', and SIGINT is trapped, do - what POSIX.2 says (see builtins/wait.def for more info). */ - if (this_shell_builtin && this_shell_builtin == wait_builtin && - signal_is_trapped (SIGINT) && - ((sigint_handler = trap_to_sighandler (SIGINT)) == trap_handler)) - { - trap_handler (SIGINT); /* set pending_traps[SIGINT] */ - wait_signal_received = SIGINT; - if (wait_intr_flag) - sh_longjmp (wait_intr_buf, 1); - else - /* Let CHECK_WAIT_INTR handle it in wait_for/waitchld */ - SIGRETURN (0); - } - else /* wait_builtin but signal not trapped, treat as interrupt */ - kill (getpid (), SIGINT); - } - - /* XXX - should this be interrupt_state? If it is, the shell will act - as if it got the SIGINT interrupt. */ - if (waiting_for_child) - wait_sigint_received = 1; - else - { - set_exit_status (128+SIGINT); - restore_sigint_handler (); - kill (getpid (), SIGINT); - } - - /* Otherwise effectively ignore the SIGINT and allow the running job to - be killed. */ - SIGRETURN (0); -} - -static int -process_exit_signal (status) - WAIT status; -{ - return (WIFSIGNALED (status) ? WTERMSIG (status) : 0); -} - -static int -process_exit_status (status) - WAIT status; -{ - if (WIFSIGNALED (status)) - return (128 + WTERMSIG (status)); - else if (WIFSTOPPED (status) == 0) - return (WEXITSTATUS (status)); - else - return (EXECUTION_SUCCESS); -} - -static WAIT -job_signal_status (job) - int job; -{ - register PROCESS *p; - WAIT s; - - p = jobs[job]->pipe; - do - { - s = p->status; - if (WIFSIGNALED(s) || WIFSTOPPED(s)) - break; - p = p->next; - } - while (p != jobs[job]->pipe); - - return s; -} - -/* Return the exit status of the last process in the pipeline for job JOB. - This is the exit status of the entire job. */ -static WAIT -raw_job_exit_status (job) - int job; -{ - register PROCESS *p; - int fail; - WAIT ret; - - if (jobs[job]->flags & J_PIPEFAIL) - { - fail = 0; - p = jobs[job]->pipe; - do - { - if (WSTATUS (p->status) != EXECUTION_SUCCESS) - fail = WSTATUS(p->status); - p = p->next; - } - while (p != jobs[job]->pipe); - WSTATUS (ret) = fail; - return ret; - } - - for (p = jobs[job]->pipe; p->next != jobs[job]->pipe; p = p->next) - ; - return (p->status); -} - -/* Return the exit status of job JOB. This is the exit status of the last - (rightmost) process in the job's pipeline, modified if the job was killed - by a signal or stopped. */ -int -job_exit_status (job) - int job; -{ - return (process_exit_status (raw_job_exit_status (job))); -} - -int -job_exit_signal (job) - int job; -{ - return (process_exit_signal (raw_job_exit_status (job))); -} - -#define FIND_CHILD(pid, child) \ - do \ - { \ - child = find_pipeline (pid, 0, (int *)NULL); \ - if (child == 0) \ - { \ - give_terminal_to (shell_pgrp, 0); \ - UNBLOCK_CHILD (oset); \ - internal_error (_("wait_for: No record of process %ld"), (long)pid); \ - restore_sigint_handler (); \ - return (termination_state = 127); \ - } \ - } \ - while (0) - -/* Wait for pid (one of our children) to terminate, then - return the termination state. Returns 127 if PID is not found in - the jobs table. Returns -1 if waitchld() returns -1, indicating - that there are no unwaited-for child processes. */ -int -wait_for (pid, flags) - pid_t pid; - int flags; -{ - int job, termination_state, r; - WAIT s; - register PROCESS *child; - sigset_t set, oset; - - /* In the case that this code is interrupted, and we longjmp () out of it, - we are relying on the code in throw_to_top_level () to restore the - top-level signal mask. */ - child = 0; - BLOCK_CHILD (set, oset); - - /* Ignore interrupts while waiting for a job run without job control - to finish. We don't want the shell to exit if an interrupt is - received, only if one of the jobs run is killed via SIGINT. If - job control is not set, the job will be run in the same pgrp as - the shell, and the shell will see any signals the job gets. In - fact, we want this set every time the waiting shell and the waited- - for process are in the same process group, including command - substitution. */ - - /* This is possibly a race condition -- should it go in stop_pipeline? */ - wait_sigint_received = child_caught_sigint = 0; - if (job_control == 0 || (subshell_environment&SUBSHELL_COMSUB)) - { - SigHandler *temp_sigint_handler; - - temp_sigint_handler = set_signal_handler (SIGINT, wait_sigint_handler); - if (temp_sigint_handler == wait_sigint_handler) - internal_debug ("wait_for: recursively setting old_sigint_handler to wait_sigint_handler: running_trap = %d", running_trap); - else - old_sigint_handler = temp_sigint_handler; - waiting_for_child = 0; - if (old_sigint_handler == SIG_IGN) - set_signal_handler (SIGINT, old_sigint_handler); - } - - termination_state = last_command_exit_value; - - if (interactive && job_control == 0) - QUIT; - /* Check for terminating signals and exit the shell if we receive one */ - CHECK_TERMSIG; - - /* Check for a trapped signal interrupting the wait builtin and jump out */ - CHECK_WAIT_INTR; - - /* If we say wait_for (), then we have a record of this child somewhere. - If it and none of its peers are running, don't call waitchld(). */ - - job = NO_JOB; - do - { - if (pid != ANY_PID) - FIND_CHILD (pid, child); - - /* If this child is part of a job, then we are really waiting for the - job to finish. Otherwise, we are waiting for the child to finish. - We check for JDEAD in case the job state has been set by waitchld - after receipt of a SIGCHLD. */ - if (job == NO_JOB && pid != ANY_PID) /* XXX -- && pid != ANY_PID ? */ - job = find_job (pid, 0, NULL); - - /* waitchld() takes care of setting the state of the job. If the job - has already exited before this is called, sigchld_handler will have - called waitchld and the state will be set to JDEAD. */ - - if (pid == ANY_PID || PRUNNING(child) || (job != NO_JOB && RUNNING (job))) - { - int old_waiting; - - queue_sigchld = 1; - old_waiting = waiting_for_child; - waiting_for_child = 1; - /* XXX - probably not strictly necessary but we want to catch - everything that happened before we switch the behavior of - trap_handler to longjmp on a trapped signal (waiting_for_child) */ - CHECK_WAIT_INTR; - r = waitchld (pid, 1); /* XXX */ - waiting_for_child = old_waiting; -#if 0 -itrace("wait_for: blocking wait for %d returns %d child = %p", (int)pid, r, child); -#endif - queue_sigchld = 0; - if (r == -1 && errno == ECHILD && this_shell_builtin == wait_builtin) - { - termination_state = -1; - /* XXX - restore sigint handler here */ - restore_sigint_handler (); - goto wait_for_return; - } - - /* If child is marked as running, but waitpid() returns -1/ECHILD, - there is something wrong. Somewhere, wait should have returned - that child's pid. Mark the child as not running and the job, - if it exists, as JDEAD. */ - if (r == -1 && errno == ECHILD) - { - if (child) - { - child->running = PS_DONE; - WSTATUS (child->status) = 0; /* XXX -- can't find true status */ - } - js.c_living = 0; /* no living child processes */ - if (job != NO_JOB) - { - jobs[job]->state = JDEAD; - js.c_reaped++; - js.j_ndead++; - } - if (pid == ANY_PID) - { - termination_state = -1; - break; - } - } - } - - /* If the shell is interactive, and job control is disabled, see - if the foreground process has died due to SIGINT and jump out - of the wait loop if it has. waitchld has already restored the - old SIGINT signal handler. */ - if (interactive && job_control == 0) - QUIT; - /* Check for terminating signals and exit the shell if we receive one */ - CHECK_TERMSIG; - - /* Check for a trapped signal interrupting the wait builtin and jump out */ - CHECK_WAIT_INTR; - - if (pid == ANY_PID) - { - /* XXX - could set child but we don't have a handle on what waitchld - reaps. Leave termination_state alone. */ - restore_sigint_handler (); - goto wait_for_return; - } - } - while (PRUNNING (child) || (job != NO_JOB && RUNNING (job))); - - /* Restore the original SIGINT signal handler before we return. */ - restore_sigint_handler (); - - /* The exit state of the command is either the termination state of the - child, or the termination state of the job. If a job, the status - of the last child in the pipeline is the significant one. If the command - or job was terminated by a signal, note that value also. */ - termination_state = (job != NO_JOB) ? job_exit_status (job) - : (child ? process_exit_status (child->status) : EXECUTION_SUCCESS); - last_command_exit_signal = (job != NO_JOB) ? job_exit_signal (job) - : (child ? process_exit_signal (child->status) : 0); - - /* XXX */ - if ((job != NO_JOB && JOBSTATE (job) == JSTOPPED) || (child && WIFSTOPPED (child->status))) - termination_state = 128 + WSTOPSIG (child->status); - - if (job == NO_JOB || IS_JOBCONTROL (job)) - { - /* XXX - under what circumstances is a job not present in the jobs - table (job == NO_JOB)? - 1. command substitution - - In the case of command substitution, at least, it's probably not - the right thing to give the terminal to the shell's process group, - even though there is code in subst.c:command_substitute to work - around it. - - Things that don't: - $PROMPT_COMMAND execution - process substitution - */ -#if 0 -if (job == NO_JOB) - itrace("wait_for: job == NO_JOB, giving the terminal to shell_pgrp (%ld)", (long)shell_pgrp); -#endif - /* Don't modify terminal pgrp if we are running in background or a - subshell. Make sure subst.c:command_substitute uses the same - conditions to determine whether or not it should undo this and - give the terminal to pipeline_pgrp. */ - - if ((flags & JWAIT_NOTERM) == 0 && running_in_background == 0 && - (subshell_environment & (SUBSHELL_ASYNC|SUBSHELL_PIPE)) == 0) - give_terminal_to (shell_pgrp, 0); - } - - /* If the command did not exit cleanly, or the job is just - being stopped, then reset the tty state back to what it - was before this command. Reset the tty state and notify - the user of the job termination only if the shell is - interactive. Clean up any dead jobs in either case. */ - if (job != NO_JOB) - { - if (interactive_shell && subshell_environment == 0) - { - /* This used to use `child->status'. That's wrong, however, for - pipelines. `child' is the first process in the pipeline. It's - likely that the process we want to check for abnormal termination - or stopping is the last process in the pipeline, especially if - it's long-lived and the first process is short-lived. Since we - know we have a job here, we can check all the processes in this - job's pipeline and see if one of them stopped or terminated due - to a signal. We might want to change this later to just check - the last process in the pipeline. If no process exits due to a - signal, S is left as the status of the last job in the pipeline. */ - s = job_signal_status (job); - - if (WIFSIGNALED (s) || WIFSTOPPED (s)) - { - set_tty_state (); - - /* If the current job was stopped or killed by a signal, and - the user has requested it, get a possibly new window size */ - if (check_window_size && (job == js.j_current || IS_FOREGROUND (job))) - get_new_window_size (0, (int *)0, (int *)0); - } - else -#if defined (READLINE) - /* We don't want to do this if we are running a process during - programmable completion or a command bound to `bind -x'. */ - if (RL_ISSTATE (RL_STATE_COMPLETING|RL_STATE_DISPATCHING|RL_STATE_TERMPREPPED) == 0) -#endif - get_tty_state (); - - /* If job control is enabled, the job was started with job - control, the job was the foreground job, and it was killed - by SIGINT, then print a newline to compensate for the kernel - printing the ^C without a trailing newline. */ - if (job_control && IS_JOBCONTROL (job) && IS_FOREGROUND (job) && - WIFSIGNALED (s) && WTERMSIG (s) == SIGINT) - { - /* If SIGINT is not trapped and the shell is in a for, while, - or until loop, act as if the shell received SIGINT as - well, so the loop can be broken. This doesn't call the - SIGINT signal handler; maybe it should. */ - if (signal_is_trapped (SIGINT) == 0 && (loop_level || (shell_compatibility_level > 32 && executing_list))) - ADDINTERRUPT; - /* Call any SIGINT trap handler if the shell is running a loop, so - the loop can be broken. This seems more useful and matches the - behavior when the shell is running a builtin command in a loop - when it is interrupted. Change ADDINTERRUPT to - trap_handler (SIGINT) to run the trap without interrupting the - loop. */ - else if (signal_is_trapped (SIGINT) && loop_level) - ADDINTERRUPT; - /* If an interactive shell with job control enabled is sourcing - a file, allow the interrupt to terminate the file sourcing. */ - else if (interactive_shell && signal_is_trapped (SIGINT) == 0 && sourcelevel) - ADDINTERRUPT; - else - { - putchar ('\n'); - fflush (stdout); - } - } - } - else if ((subshell_environment & (SUBSHELL_COMSUB|SUBSHELL_PIPE)) && wait_sigint_received) - { - /* If waiting for a job in a subshell started to do command - substitution or to run a pipeline element that consists of - something like a while loop or a for loop, simulate getting - and being killed by the SIGINT to pass the status back to our - parent. */ - if (child_caught_sigint == 0 && signal_is_trapped (SIGINT) == 0) - { - UNBLOCK_CHILD (oset); - old_sigint_handler = set_signal_handler (SIGINT, SIG_DFL); - if (old_sigint_handler == SIG_IGN) - restore_sigint_handler (); - else - kill (getpid (), SIGINT); - } - } - else if (interactive_shell == 0 && subshell_environment == 0 && IS_FOREGROUND (job)) - { - s = job_signal_status (job); - - /* If we are non-interactive, but job control is enabled, and the job - died due to SIGINT, pretend we got the SIGINT */ - if (job_control && IS_JOBCONTROL (job) && WIFSIGNALED (s) && WTERMSIG (s) == SIGINT) - { - ADDINTERRUPT; /* For now */ - } - - if (check_window_size) - get_new_window_size (0, (int *)0, (int *)0); - } - - /* Moved here from set_job_status_and_cleanup, which is in the SIGCHLD - signal handler path */ - if (DEADJOB (job) && IS_FOREGROUND (job) /*&& subshell_environment == 0*/) - setjstatus (job); - - /* If this job is dead, notify the user of the status. If the shell - is interactive, this will display a message on the terminal. If - the shell is not interactive, make sure we turn on the notify bit - so we don't get an unwanted message about the job's termination, - and so delete_job really clears the slot in the jobs table. */ - notify_and_cleanup (); - } - -wait_for_return: - - UNBLOCK_CHILD (oset); - - return (termination_state); -} - -/* Wait for the last process in the pipeline for JOB. Returns whatever - wait_for returns: the last process's termination state or -1 if there - are no unwaited-for child processes or an error occurs. If FLAGS - includes JWAIT_FORCE, we wait for the job to terminate, no just change - state */ -int -wait_for_job (job, flags, ps) - int job, flags; - struct procstat *ps; -{ - pid_t pid; - int r, state; - sigset_t set, oset; - - BLOCK_CHILD(set, oset); - state = JOBSTATE (job); - if (state == JSTOPPED) - internal_warning (_("wait_for_job: job %d is stopped"), job+1); - - pid = find_last_pid (job, 0); - UNBLOCK_CHILD(oset); - - do - { - r = wait_for (pid, 0); - if (r == -1 && errno == ECHILD) - mark_all_jobs_as_dead (); - - CHECK_WAIT_INTR; - - if ((flags & JWAIT_FORCE) == 0) - break; - - BLOCK_CHILD (set, oset); - state = (job != NO_JOB && jobs[job]) ? JOBSTATE (job) : JDEAD; - UNBLOCK_CHILD (oset); - } - while (state != JDEAD); - - /* POSIX.2: we can remove the job from the jobs table if we just waited - for it. */ - BLOCK_CHILD (set, oset); - if (job != NO_JOB && jobs[job] && DEADJOB (job)) - jobs[job]->flags |= J_NOTIFIED; - UNBLOCK_CHILD (oset); - - if (ps) - { - ps->pid = pid; - ps->status = (r < 0) ? 127 : r; - } - return r; -} - -/* Wait for any background job started by this shell to finish. Very - similar to wait_for_background_pids(). Returns the exit status of - the next exiting job, -1 if there are no background jobs. The caller - is responsible for translating -1 into the right return value. RPID, - if non-null, gets the pid of the job's process leader. */ -int -wait_for_any_job (flags, ps) - int flags; - struct procstat *ps; -{ - pid_t pid; - int i, r; - sigset_t set, oset; - - if (jobs_list_frozen) - return -1; - - /* First see if there are any unnotified dead jobs that we can report on */ - BLOCK_CHILD (set, oset); - for (i = 0; i < js.j_jobslots; i++) - { - if ((flags & JWAIT_WAITING) && jobs[i] && IS_WAITING (i) == 0) - continue; /* if we don't want it, skip it */ - if (jobs[i] && DEADJOB (i) && IS_NOTIFIED (i) == 0) - { -return_job: - r = job_exit_status (i); - pid = find_last_pid (i, 0); - if (ps) - { - ps->pid = pid; - ps->status = r; - } - notify_of_job_status (); /* XXX */ - delete_job (i, 0); -#if defined (COPROCESS_SUPPORT) - coproc_reap (); -#endif - UNBLOCK_CHILD (oset); - return r; - } - } - UNBLOCK_CHILD (oset); - - /* At this point, we have no dead jobs in the jobs table. Wait until we - get one, even if it takes multiple pids exiting. */ - for (;;) - { - /* Make sure there is a background job to wait for */ - BLOCK_CHILD (set, oset); - for (i = 0; i < js.j_jobslots; i++) - if (jobs[i] && RUNNING (i) && IS_FOREGROUND (i) == 0) - break; - if (i == js.j_jobslots) - { - UNBLOCK_CHILD (oset); - return -1; - } - - UNBLOCK_CHILD (oset); - - QUIT; - CHECK_TERMSIG; - CHECK_WAIT_INTR; - - errno = 0; - r = wait_for (ANY_PID, 0); /* special sentinel value for wait_for */ - if (r == -1 && errno == ECHILD) - mark_all_jobs_as_dead (); - - /* Now we see if we have any dead jobs and return the first one */ - BLOCK_CHILD (set, oset); - for (i = 0; i < js.j_jobslots; i++) - { - if ((flags & JWAIT_WAITING) && jobs[i] && IS_WAITING (i) == 0) - continue; /* if we don't want it, skip it */ - if (jobs[i] && DEADJOB (i)) - goto return_job; - } - UNBLOCK_CHILD (oset); - } - - return -1; -} - -/* Print info about dead jobs, and then delete them from the list - of known jobs. This does not actually delete jobs when the - shell is not interactive, because the dead jobs are not marked - as notified. */ -void -notify_and_cleanup () -{ - if (jobs_list_frozen) - return; - - if (interactive || interactive_shell == 0 || sourcelevel) - notify_of_job_status (); - - cleanup_dead_jobs (); -} - -/* Make dead jobs disappear from the jobs array without notification. - This is used when the shell is not interactive. */ -void -reap_dead_jobs () -{ - mark_dead_jobs_as_notified (0); - cleanup_dead_jobs (); -} - -/* Return the next closest (chronologically) job to JOB which is in - STATE. STATE can be JSTOPPED, JRUNNING. NO_JOB is returned if - there is no next recent job. */ -static int -most_recent_job_in_state (job, state) - int job; - JOB_STATE state; -{ - register int i, result; - sigset_t set, oset; - - BLOCK_CHILD (set, oset); - - for (result = NO_JOB, i = job - 1; i >= 0; i--) - { - if (jobs[i] && (JOBSTATE (i) == state)) - { - result = i; - break; - } - } - - UNBLOCK_CHILD (oset); - - return (result); -} - -/* Return the newest *stopped* job older than JOB, or NO_JOB if not - found. */ -static int -job_last_stopped (job) - int job; -{ - return (most_recent_job_in_state (job, JSTOPPED)); -} - -/* Return the newest *running* job older than JOB, or NO_JOB if not - found. */ -static int -job_last_running (job) - int job; -{ - return (most_recent_job_in_state (job, JRUNNING)); -} - -/* Make JOB be the current job, and make previous be useful. Must be - called with SIGCHLD blocked. */ -static void -set_current_job (job) - int job; -{ - int candidate; - - if (js.j_current != job) - { - js.j_previous = js.j_current; - js.j_current = job; - } - - /* First choice for previous job is the old current job. */ - if (js.j_previous != js.j_current && - js.j_previous != NO_JOB && - jobs[js.j_previous] && - STOPPED (js.j_previous)) - return; - - /* Second choice: Newest stopped job that is older than - the current job. */ - candidate = NO_JOB; - if (STOPPED (js.j_current)) - { - candidate = job_last_stopped (js.j_current); - - if (candidate != NO_JOB) - { - js.j_previous = candidate; - return; - } - } - - /* If we get here, there is either only one stopped job, in which case it is - the current job and the previous job should be set to the newest running - job, or there are only running jobs and the previous job should be set to - the newest running job older than the current job. We decide on which - alternative to use based on whether or not JOBSTATE(js.j_current) is - JSTOPPED. */ - - candidate = RUNNING (js.j_current) ? job_last_running (js.j_current) - : job_last_running (js.j_jobslots); - - if (candidate != NO_JOB) - { - js.j_previous = candidate; - return; - } - - /* There is only a single job, and it is both `+' and `-'. */ - js.j_previous = js.j_current; -} - -/* Make current_job be something useful, if it isn't already. */ - -/* Here's the deal: The newest non-running job should be `+', and the - next-newest non-running job should be `-'. If there is only a single - stopped job, the js.j_previous is the newest non-running job. If there - are only running jobs, the newest running job is `+' and the - next-newest running job is `-'. Must be called with SIGCHLD blocked. */ - -static void -reset_current () -{ - int candidate; - - if (js.j_jobslots && js.j_current != NO_JOB && jobs[js.j_current] && STOPPED (js.j_current)) - candidate = js.j_current; - else - { - candidate = NO_JOB; - - /* First choice: the previous job. */ - if (js.j_previous != NO_JOB && jobs[js.j_previous] && STOPPED (js.j_previous)) - candidate = js.j_previous; - - /* Second choice: the most recently stopped job. */ - if (candidate == NO_JOB) - candidate = job_last_stopped (js.j_jobslots); - - /* Third choice: the newest running job. */ - if (candidate == NO_JOB) - candidate = job_last_running (js.j_jobslots); - } - - /* If we found a job to use, then use it. Otherwise, there - are no jobs period. */ - if (candidate != NO_JOB) - set_current_job (candidate); - else - js.j_current = js.j_previous = NO_JOB; -} - -/* Set up the job structures so we know the job and its processes are - all running. */ -static void -set_job_running (job) - int job; -{ - register PROCESS *p; - - /* Each member of the pipeline is now running. */ - p = jobs[job]->pipe; - - do - { - if (WIFSTOPPED (p->status)) - p->running = PS_RUNNING; /* XXX - could be PS_STOPPED */ - p = p->next; - } - while (p != jobs[job]->pipe); - - /* This means that the job is running. */ - JOBSTATE (job) = JRUNNING; -} - -/* Start a job. FOREGROUND if non-zero says to do that. Otherwise, - start the job in the background. JOB is a zero-based index into - JOBS. Returns -1 if it is unable to start a job, and the return - status of the job otherwise. */ -int -start_job (job, foreground) - int job, foreground; -{ - register PROCESS *p; - int already_running; - sigset_t set, oset; - char *wd, *s; - static TTYSTRUCT save_stty; - - BLOCK_CHILD (set, oset); - - if ((subshell_environment & SUBSHELL_COMSUB) && (pipeline_pgrp == shell_pgrp)) - { - internal_error (_("%s: no current jobs"), this_command_name); - UNBLOCK_CHILD (oset); - return (-1); - } - - if (DEADJOB (job)) - { - internal_error (_("%s: job has terminated"), this_command_name); - UNBLOCK_CHILD (oset); - return (-1); - } - - already_running = RUNNING (job); - - if (foreground == 0 && already_running) - { - internal_error (_("%s: job %d already in background"), this_command_name, job + 1); - UNBLOCK_CHILD (oset); - return (0); /* XPG6/SUSv3 says this is not an error */ - } - - wd = current_working_directory (); - - /* You don't know about the state of this job. Do you? */ - jobs[job]->flags &= ~J_NOTIFIED; - - if (foreground) - { - set_current_job (job); - jobs[job]->flags |= J_FOREGROUND; - } - - /* Tell the outside world what we're doing. */ - p = jobs[job]->pipe; - - if (foreground == 0) - { - /* POSIX.2 says `bg' doesn't give any indication about current or - previous job. */ - if (posixly_correct == 0) - s = (job == js.j_current) ? "+ ": ((job == js.j_previous) ? "- " : " "); - else - s = " "; - printf ("[%d]%s", job + 1, s); - } - - do - { - printf ("%s%s", - p->command ? p->command : "", - p->next != jobs[job]->pipe? " | " : ""); - p = p->next; - } - while (p != jobs[job]->pipe); - - if (foreground == 0) - printf (" &"); - - if (strcmp (wd, jobs[job]->wd) != 0) - printf (" (wd: %s)", polite_directory_format (jobs[job]->wd)); - - printf ("\n"); - - /* Run the job. */ - if (already_running == 0) - set_job_running (job); - - /* Save the tty settings before we start the job in the foreground. */ - if (foreground) - { - get_tty_state (); - save_stty = shell_tty_info; - /* Give the terminal to this job. */ - if (IS_JOBCONTROL (job)) - give_terminal_to (jobs[job]->pgrp, 0); - } - else - jobs[job]->flags &= ~J_FOREGROUND; - - /* If the job is already running, then don't bother jump-starting it. */ - if (already_running == 0) - { - jobs[job]->flags |= J_NOTIFIED; - killpg (jobs[job]->pgrp, SIGCONT); - } - - if (foreground) - { - pid_t pid; - int st; - - pid = find_last_pid (job, 0); - UNBLOCK_CHILD (oset); - st = wait_for (pid, 0); - shell_tty_info = save_stty; - set_tty_state (); - return (st); - } - else - { - reset_current (); - UNBLOCK_CHILD (oset); - return (0); - } -} - -/* Give PID SIGNAL. This determines what job the pid belongs to (if any). - If PID does belong to a job, and the job is stopped, then CONTinue the - job after giving it SIGNAL. Returns -1 on failure. If GROUP is non-null, - then kill the process group associated with PID. */ -int -kill_pid (pid, sig, group) - pid_t pid; - int sig, group; -{ - register PROCESS *p; - int job, result, negative; - sigset_t set, oset; - - if (pid < -1) - { - pid = -pid; - group = negative = 1; - } - else - negative = 0; - - result = EXECUTION_SUCCESS; - if (group) - { - BLOCK_CHILD (set, oset); - p = find_pipeline (pid, 0, &job); - - if (job != NO_JOB) - { - jobs[job]->flags &= ~J_NOTIFIED; - - /* Kill process in backquotes or one started without job control? */ - - /* If we're passed a pid < -1, just call killpg and see what happens */ - if (negative && jobs[job]->pgrp == shell_pgrp) - result = killpg (pid, sig); - /* If we're killing using job control notification, for example, - without job control active, we have to do things ourselves. */ - else if (jobs[job]->pgrp == shell_pgrp) /* XXX - IS_JOBCONTROL(job) == 0? */ - { - p = jobs[job]->pipe; - do - { - if (PALIVE (p) == 0) - continue; /* avoid pid recycling problem */ - kill (p->pid, sig); - if (PEXITED (p) && (sig == SIGTERM || sig == SIGHUP)) - kill (p->pid, SIGCONT); - p = p->next; - } - while (p != jobs[job]->pipe); - } - else - { - result = killpg (jobs[job]->pgrp, sig); - if (p && STOPPED (job) && (sig == SIGTERM || sig == SIGHUP)) - killpg (jobs[job]->pgrp, SIGCONT); - /* If we're continuing a stopped job via kill rather than bg or - fg, emulate the `bg' behavior. */ - if (p && STOPPED (job) && (sig == SIGCONT)) - { - set_job_running (job); - jobs[job]->flags &= ~J_FOREGROUND; - jobs[job]->flags |= J_NOTIFIED; - } - } - } - else - result = killpg (pid, sig); - - UNBLOCK_CHILD (oset); - } - else - result = kill (pid, sig); - - return (result); -} - -/* sigchld_handler () flushes at least one of the children that we are - waiting for. It gets run when we have gotten a SIGCHLD signal. */ -static sighandler -sigchld_handler (sig) - int sig; -{ - int n, oerrno; - - oerrno = errno; - REINSTALL_SIGCHLD_HANDLER; - sigchld++; - n = 0; - if (queue_sigchld == 0) - n = waitchld (-1, 0); - errno = oerrno; - SIGRETURN (n); -} - -/* waitchld() reaps dead or stopped children. It's called by wait_for and - sigchld_handler, and runs until there aren't any children terminating any - more. - If BLOCK is 1, this is to be a blocking wait for a single child, although - an arriving SIGCHLD could cause the wait to be non-blocking. It returns - the number of children reaped, or -1 if there are no unwaited-for child - processes. */ -static int -waitchld (wpid, block) - pid_t wpid; - int block; -{ - WAIT status; - PROCESS *child; - pid_t pid; - int ind; - - int call_set_current, last_stopped_job, job, children_exited, waitpid_flags; - static int wcontinued = WCONTINUED; /* run-time fix for glibc problem */ - - call_set_current = children_exited = 0; - last_stopped_job = NO_JOB; - - do - { - /* We don't want to be notified about jobs stopping if job control - is not active. XXX - was interactive_shell instead of job_control */ - waitpid_flags = (job_control && subshell_environment == 0) - ? (WUNTRACED|wcontinued) - : 0; - if (sigchld || block == 0) - waitpid_flags |= WNOHANG; - - /* Check for terminating signals and exit the shell if we receive one */ - CHECK_TERMSIG; - /* Check for a trapped signal interrupting the wait builtin and jump out */ - CHECK_WAIT_INTR; - - if (block == 1 && queue_sigchld == 0 && (waitpid_flags & WNOHANG) == 0) - { - internal_warning (_("waitchld: turning on WNOHANG to avoid indefinite block")); - waitpid_flags |= WNOHANG; - } - - pid = WAITPID (-1, &status, waitpid_flags); - -#if 0 -if (wpid != -1 && block) - itrace("waitchld: blocking waitpid returns %d", pid); -#endif -#if 0 -if (wpid != -1) - itrace("waitchld: %s waitpid returns %d", block?"blocking":"non-blocking", pid); -#endif - /* WCONTINUED may be rejected by waitpid as invalid even when defined */ - if (wcontinued && pid < 0 && errno == EINVAL) - { - wcontinued = 0; - continue; /* jump back to the test and retry without WCONTINUED */ - } - - /* The check for WNOHANG is to make sure we decrement sigchld only - if it was non-zero before we called waitpid. */ - if (sigchld > 0 && (waitpid_flags & WNOHANG)) - sigchld--; - - /* If waitpid returns -1 with errno == ECHILD, there are no more - unwaited-for child processes of this shell. */ - if (pid < 0 && errno == ECHILD) - { - if (children_exited == 0) - return -1; - else - break; - } - -#if 0 -itrace("waitchld: waitpid returns %d block = %d children_exited = %d", pid, block, children_exited); -#endif - /* If waitpid returns 0, there are running children. If it returns -1, - the only other error POSIX says it can return is EINTR. */ - CHECK_TERMSIG; - CHECK_WAIT_INTR; - - /* If waitpid returns -1/EINTR and the shell saw a SIGINT, then we - assume the child has blocked or handled SIGINT. In that case, we - require the child to actually die due to SIGINT to act on the - SIGINT we received; otherwise we assume the child handled it and - let it go. */ - if (pid < 0 && errno == EINTR && wait_sigint_received) - child_caught_sigint = 1; - - if (pid <= 0) - continue; /* jumps right to the test */ - - /* Linux kernels appear to signal the parent but not interrupt the - waitpid() (or restart it even without SA_RESTART) on SIGINT, so if - we saw a SIGINT and the process exited or died due to some other - signal, assume the child caught the SIGINT. */ - if (wait_sigint_received && (WIFSIGNALED (status) == 0 || WTERMSIG (status) != SIGINT)) - child_caught_sigint = 1; - - /* If the child process did die due to SIGINT, forget our assumption - that it caught or otherwise handled it. */ - if (WIFSIGNALED (status) && WTERMSIG (status) == SIGINT) - child_caught_sigint = 0; - - /* children_exited is used to run traps on SIGCHLD. We don't want to - run the trap if a process is just being continued. */ - if (WIFCONTINUED(status) == 0) - { - children_exited++; - js.c_living--; - } - - /* Locate our PROCESS for this pid. */ - child = find_process (pid, 1, &job); /* want living procs only */ - -#if defined (COPROCESS_SUPPORT) - coproc_pidchk (pid, WSTATUS(status)); -#endif - -#if defined (PROCESS_SUBSTITUTION) - /* Only manipulate the list of process substitutions while SIGCHLD - is blocked. We only use this as a hint that we can remove FIFOs - or close file descriptors corresponding to terminated process - substitutions. */ - if ((ind = find_procsub_child (pid)) >= 0) - set_procsub_status (ind, pid, WSTATUS (status)); -#endif - - /* It is not an error to have a child terminate that we did - not have a record of. This child could have been part of - a pipeline in backquote substitution. Even so, I'm not - sure child is ever non-zero. */ - if (child == 0) - { - if (WIFEXITED (status) || WIFSIGNALED (status)) - js.c_reaped++; - continue; - } - - /* Remember status, and whether or not the process is running. */ - child->status = status; - child->running = WIFCONTINUED(status) ? PS_RUNNING : PS_DONE; - - if (PEXITED (child)) - { - js.c_totreaped++; - if (job != NO_JOB) - js.c_reaped++; - } - - if (job == NO_JOB) - continue; - - call_set_current += set_job_status_and_cleanup (job); - - if (STOPPED (job)) - last_stopped_job = job; - else if (DEADJOB (job) && last_stopped_job == job) - last_stopped_job = NO_JOB; - } - while ((sigchld || block == 0) && pid > (pid_t)0); - - /* If a job was running and became stopped, then set the current - job. Otherwise, don't change a thing. */ - if (call_set_current) - { - if (last_stopped_job != NO_JOB) - set_current_job (last_stopped_job); - else - reset_current (); - } - - /* Call a SIGCHLD trap handler for each child that exits, if one is set. */ - if (children_exited && - (signal_is_trapped (SIGCHLD) || trap_list[SIGCHLD] == (char *)IMPOSSIBLE_TRAP_HANDLER) && - trap_list[SIGCHLD] != (char *)IGNORE_SIG) - { - if (posixly_correct && this_shell_builtin && this_shell_builtin == wait_builtin) - { - /* This was trap_handler (SIGCHLD) but that can lose traps if - children_exited > 1 */ - queue_sigchld_trap (children_exited); - wait_signal_received = SIGCHLD; - /* If we're in a signal handler, let CHECK_WAIT_INTR pick it up; - run_pending_traps will call run_sigchld_trap later */ - if (sigchld == 0 && wait_intr_flag) - sh_longjmp (wait_intr_buf, 1); - } - /* If not in posix mode and not executing the wait builtin, queue the - signal for later handling. Run the trap immediately if we are - executing the wait builtin, but don't break out of `wait'. */ - else if (sigchld) /* called from signal handler */ - queue_sigchld_trap (children_exited); - else if (signal_in_progress (SIGCHLD)) - queue_sigchld_trap (children_exited); - else if (trap_list[SIGCHLD] == (char *)IMPOSSIBLE_TRAP_HANDLER) - queue_sigchld_trap (children_exited); - else if (running_trap) - queue_sigchld_trap (children_exited); - else if (this_shell_builtin == wait_builtin) - run_sigchld_trap (children_exited); /* XXX */ - else - queue_sigchld_trap (children_exited); - } - - /* We have successfully recorded the useful information about this process - that has just changed state. If we notify asynchronously, and the job - that this process belongs to is no longer running, then notify the user - of that fact now. */ - if (asynchronous_notification && interactive && executing_builtin == 0) - notify_of_job_status (); - - return (children_exited); -} - -/* Set the status of JOB and perform any necessary cleanup if the job is - marked as JDEAD. - - Currently, the cleanup activity is restricted to handling any SIGINT - received while waiting for a foreground job to finish. */ -static int -set_job_status_and_cleanup (job) - int job; -{ - PROCESS *child; - int tstatus, job_state, any_stopped, any_tstped, call_set_current; - SigHandler *temp_handler; - - child = jobs[job]->pipe; - jobs[job]->flags &= ~J_NOTIFIED; - - call_set_current = 0; - - /* - * COMPUTE JOB STATUS - */ - - /* If all children are not running, but any of them is stopped, then - the job is stopped, not dead. */ - job_state = any_stopped = any_tstped = 0; - do - { - job_state |= PRUNNING (child); -#if 0 - if (PEXITED (child) && (WIFSTOPPED (child->status))) -#else - /* Only checking for WIFSTOPPED now, not for PS_DONE */ - if (PSTOPPED (child)) -#endif - { - any_stopped = 1; - any_tstped |= job_control && (WSTOPSIG (child->status) == SIGTSTP); - } - child = child->next; - } - while (child != jobs[job]->pipe); - - /* If job_state != 0, the job is still running, so don't bother with - setting the process exit status and job state unless we're - transitioning from stopped to running. */ - if (job_state != 0 && JOBSTATE(job) != JSTOPPED) - return 0; - - /* - * SET JOB STATUS - */ - - /* The job is either stopped or dead. Set the state of the job accordingly. */ - if (any_stopped) - { - jobs[job]->state = JSTOPPED; - jobs[job]->flags &= ~J_FOREGROUND; - call_set_current++; - /* Suspending a job with SIGTSTP breaks all active loops. */ - if (any_tstped && loop_level) - breaking = loop_level; - } - else if (job_state != 0) /* was stopped, now running */ - { - jobs[job]->state = JRUNNING; - call_set_current++; - } - else - { - jobs[job]->state = JDEAD; - js.j_ndead++; - -#if 0 - if (IS_FOREGROUND (job)) - setjstatus (job); -#endif - - /* If this job has a cleanup function associated with it, call it - with `cleanarg' as the single argument, then set the function - pointer to NULL so it is not inadvertently called twice. The - cleanup function is responsible for deallocating cleanarg. */ - if (jobs[job]->j_cleanup) - { - (*jobs[job]->j_cleanup) (jobs[job]->cleanarg); - jobs[job]->j_cleanup = (sh_vptrfunc_t *)NULL; - } - } - - /* - * CLEANUP - * - * Currently, we just do special things if we got a SIGINT while waiting - * for a foreground job to complete - */ - - if (JOBSTATE (job) == JDEAD) - { - /* If we're running a shell script and we get a SIGINT with a - SIGINT trap handler, but the foreground job handles it and - does not exit due to SIGINT, run the trap handler but do not - otherwise act as if we got the interrupt. */ - if (wait_sigint_received && interactive_shell == 0 && - child_caught_sigint && IS_FOREGROUND (job) && - signal_is_trapped (SIGINT)) - { - int old_frozen; - wait_sigint_received = 0; - last_command_exit_value = process_exit_status (child->status); - - old_frozen = jobs_list_frozen; - jobs_list_frozen = 1; - tstatus = maybe_call_trap_handler (SIGINT); - jobs_list_frozen = old_frozen; - } - - /* If the foreground job is killed by SIGINT when job control is not - active, we need to perform some special handling. - - The check of wait_sigint_received is a way to determine if the - SIGINT came from the keyboard (in which case the shell has already - seen it, and wait_sigint_received is non-zero, because keyboard - signals are sent to process groups) or via kill(2) to the foreground - process by another process (or itself). If the shell did receive the - SIGINT, it needs to perform normal SIGINT processing. XXX - should - this change its behavior depending on whether the last command in an - pipeline exited due to SIGINT, or any process in the pipeline? Right - now it does this if any process in the pipeline exits due to SIGINT. */ - else if (wait_sigint_received && - child_caught_sigint == 0 && - IS_FOREGROUND (job) && IS_JOBCONTROL (job) == 0) - { - int old_frozen; - - wait_sigint_received = 0; - - /* If SIGINT is trapped, set the exit status so that the trap - handler can see it. */ - if (signal_is_trapped (SIGINT)) - last_command_exit_value = process_exit_status (child->status); - - /* If the signal is trapped, let the trap handler get it no matter - what and simply return if the trap handler returns. - maybe_call_trap_handler() may cause dead jobs to be removed from - the job table because of a call to execute_command. We work - around this by setting JOBS_LIST_FROZEN. */ - old_frozen = jobs_list_frozen; - jobs_list_frozen = 1; - tstatus = maybe_call_trap_handler (SIGINT); - jobs_list_frozen = old_frozen; - if (tstatus == 0 && old_sigint_handler != INVALID_SIGNAL_HANDLER) - { - /* wait_sigint_handler () has already seen SIGINT and - allowed the wait builtin to jump out. We need to - call the original SIGINT handler, if necessary. If - the original handler is SIG_DFL, we need to resend - the signal to ourselves. */ - - temp_handler = old_sigint_handler; - - /* Bogus. If we've reset the signal handler as the result - of a trap caught on SIGINT, then old_sigint_handler - will point to trap_handler, which now knows nothing about - SIGINT (if we reset the sighandler to the default). - In this case, we have to fix things up. What a crock. */ - if (temp_handler == trap_handler && signal_is_trapped (SIGINT) == 0) - temp_handler = trap_to_sighandler (SIGINT); - restore_sigint_handler (); - if (temp_handler == SIG_DFL) - termsig_handler (SIGINT); /* XXX */ - else if (temp_handler != SIG_IGN) - (*temp_handler) (SIGINT); - } - } - } - - return call_set_current; -} - -/* Build the array of values for the $PIPESTATUS variable from the set of - exit statuses of all processes in the job J. */ -static void -setjstatus (j) - int j; -{ -#if defined (ARRAY_VARS) - register int i; - register PROCESS *p; - - for (i = 1, p = jobs[j]->pipe; p->next != jobs[j]->pipe; p = p->next, i++) - ; - i++; - if (statsize < i) - { - pstatuses = (int *)xrealloc (pstatuses, i * sizeof (int)); - statsize = i; - } - i = 0; - p = jobs[j]->pipe; - do - { - pstatuses[i++] = process_exit_status (p->status); - p = p->next; - } - while (p != jobs[j]->pipe); - - pstatuses[i] = -1; /* sentinel */ - set_pipestatus_array (pstatuses, i); -#endif -} - -void -run_sigchld_trap (nchild) - int nchild; -{ - char *trap_command; - int i; - - /* Turn off the trap list during the call to parse_and_execute () - to avoid potentially infinite recursive calls. Preserve the - values of last_command_exit_value, last_made_pid, and the_pipeline - around the execution of the trap commands. */ - trap_command = savestring (trap_list[SIGCHLD]); - - begin_unwind_frame ("SIGCHLD trap"); - unwind_protect_int (last_command_exit_value); - unwind_protect_int (last_command_exit_signal); - unwind_protect_var (last_made_pid); - unwind_protect_int (jobs_list_frozen); - unwind_protect_pointer (the_pipeline); - unwind_protect_pointer (subst_assign_varlist); - unwind_protect_pointer (this_shell_builtin); - unwind_protect_pointer (temporary_env); - - /* We have to add the commands this way because they will be run - in reverse order of adding. We don't want maybe_set_sigchld_trap () - to reference freed memory. */ - add_unwind_protect (xfree, trap_command); - add_unwind_protect (maybe_set_sigchld_trap, trap_command); - - subst_assign_varlist = (WORD_LIST *)NULL; - the_pipeline = (PROCESS *)NULL; - temporary_env = 0; /* traps should not run with temporary env */ - - running_trap = SIGCHLD + 1; - - set_impossible_sigchld_trap (); - jobs_list_frozen = 1; - for (i = 0; i < nchild; i++) - { - parse_and_execute (savestring (trap_command), "trap", SEVAL_NOHIST|SEVAL_RESETLINE); - } - - run_unwind_frame ("SIGCHLD trap"); - running_trap = 0; -} - -/* Function to call when you want to notify people of changes - in job status. This prints out all jobs which are pending - notification to stderr, and marks those printed as already - notified, thus making them candidates for cleanup. */ -static void -notify_of_job_status () -{ - register int job, termsig; - char *dir; - sigset_t set, oset; - WAIT s; - - if (jobs == 0 || js.j_jobslots == 0) - return; - - if (old_ttou != 0) - { - sigemptyset (&set); - sigaddset (&set, SIGCHLD); - sigaddset (&set, SIGTTOU); - sigemptyset (&oset); - sigprocmask (SIG_BLOCK, &set, &oset); - } - else - queue_sigchld++; - - /* XXX could use js.j_firstj here */ - for (job = 0, dir = (char *)NULL; job < js.j_jobslots; job++) - { - if (jobs[job] && IS_NOTIFIED (job) == 0) - { - s = raw_job_exit_status (job); - termsig = WTERMSIG (s); - - /* POSIX.2 says we have to hang onto the statuses of at most the - last CHILD_MAX background processes if the shell is running a - script. If the shell is running a script, either from a file - or standard input, don't print anything unless the job was - killed by a signal. */ - if (startup_state == 0 && WIFSIGNALED (s) == 0 && - ((DEADJOB (job) && IS_FOREGROUND (job) == 0) || STOPPED (job))) - continue; - - /* If job control is disabled, don't print the status messages. - Mark dead jobs as notified so that they get cleaned up. If - startup_state == 2 and subshell_environment has the - SUBSHELL_COMSUB bit turned on, we were started to run a command - substitution, so don't print anything. - Otherwise, if the shell is not interactive, POSIX says that `jobs' - is the only way to notify of job status. */ - if ((job_control == 0 && interactive_shell) || - (startup_state == 2 && (subshell_environment & SUBSHELL_COMSUB)) || - (startup_state == 2 && posixly_correct && (subshell_environment & SUBSHELL_COMSUB) == 0)) - { - /* POSIX.2 compatibility: if the shell is not interactive, - hang onto the job corresponding to the last asynchronous - pid until the user has been notified of its status or does - a `wait'. */ - if (DEADJOB (job) && (interactive_shell || (find_last_pid (job, 0) != last_asynchronous_pid))) - jobs[job]->flags |= J_NOTIFIED; - continue; - } - - /* Print info on jobs that are running in the background, - and on foreground jobs that were killed by anything - except SIGINT (and possibly SIGPIPE). */ - switch (JOBSTATE (job)) - { - case JDEAD: - if (interactive_shell == 0 && termsig && WIFSIGNALED (s) && - termsig != SIGINT && -#if defined (DONT_REPORT_SIGTERM) - termsig != SIGTERM && -#endif -#if defined (DONT_REPORT_SIGPIPE) - termsig != SIGPIPE && -#endif - signal_is_trapped (termsig) == 0) - { - /* Don't print `0' for a line number. */ - fprintf (stderr, _("%s: line %d: "), get_name_for_error (), (line_number == 0) ? 1 : line_number); - pretty_print_job (job, JLIST_NONINTERACTIVE, stderr); - } - else if (IS_FOREGROUND (job)) - { -#if !defined (DONT_REPORT_SIGPIPE) - if (termsig && WIFSIGNALED (s) && termsig != SIGINT) -#else - if (termsig && WIFSIGNALED (s) && termsig != SIGINT && termsig != SIGPIPE) -#endif - { - fprintf (stderr, "%s", j_strsignal (termsig)); - - if (WIFCORED (s)) - fprintf (stderr, _(" (core dumped)")); - - fprintf (stderr, "\n"); - } - } - else if (job_control) /* XXX job control test added */ - { - if (dir == 0) - dir = current_working_directory (); - pretty_print_job (job, JLIST_STANDARD, stderr); - if (dir && strcmp (dir, jobs[job]->wd) != 0) - fprintf (stderr, - _("(wd now: %s)\n"), polite_directory_format (dir)); - } - - jobs[job]->flags |= J_NOTIFIED; - break; - - case JSTOPPED: - fprintf (stderr, "\n"); - if (dir == 0) - dir = current_working_directory (); - pretty_print_job (job, JLIST_STANDARD, stderr); - if (dir && (strcmp (dir, jobs[job]->wd) != 0)) - fprintf (stderr, - _("(wd now: %s)\n"), polite_directory_format (dir)); - jobs[job]->flags |= J_NOTIFIED; - break; - - case JRUNNING: - case JMIXED: - break; - - default: - programming_error ("notify_of_job_status"); - } - } - } - if (old_ttou != 0) - sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL); - else - queue_sigchld--; -} - -/* Initialize the job control mechanism, and set up the tty stuff. */ -int -initialize_job_control (force) - int force; -{ - pid_t t; - int t_errno, tty_sigs; - - t_errno = -1; - shell_pgrp = getpgid (0); - - if (shell_pgrp == -1) - { - sys_error (_("initialize_job_control: getpgrp failed")); - exit (1); - } - - /* We can only have job control if we are interactive unless we force it. */ - if (interactive == 0 && force == 0) - { - job_control = 0; - original_pgrp = NO_PID; - shell_tty = fileno (stderr); - terminal_pgrp = tcgetpgrp (shell_tty); /* for checking later */ - } - else - { - shell_tty = -1; - - /* If forced_interactive is set, we skip the normal check that stderr - is attached to a tty, so we need to check here. If it's not, we - need to see whether we have a controlling tty by opening /dev/tty, - since trying to use job control tty pgrp manipulations on a non-tty - is going to fail. */ - if (forced_interactive && isatty (fileno (stderr)) == 0) - shell_tty = open ("/dev/tty", O_RDWR|O_NONBLOCK); - - /* Get our controlling terminal. If job_control is set, or - interactive is set, then this is an interactive shell no - matter where fd 2 is directed. */ - if (shell_tty == -1) - shell_tty = dup (fileno (stderr)); /* fd 2 */ - - if (shell_tty != -1) - shell_tty = move_to_high_fd (shell_tty, 1, -1); - - /* Compensate for a bug in systems that compiled the BSD - rlogind with DEBUG defined, like NeXT and Alliant. */ - if (shell_pgrp == 0) - { - shell_pgrp = getpid (); - setpgid (0, shell_pgrp); - if (shell_tty != -1) - tcsetpgrp (shell_tty, shell_pgrp); - } - - tty_sigs = 0; - while ((terminal_pgrp = tcgetpgrp (shell_tty)) != -1) - { - if (shell_pgrp != terminal_pgrp) - { - SigHandler *ottin; - - CHECK_TERMSIG; - ottin = set_signal_handler (SIGTTIN, SIG_DFL); - kill (0, SIGTTIN); - set_signal_handler (SIGTTIN, ottin); - if (tty_sigs++ > 16) - { - sys_error (_("initialize_job_control: no job control in background")); - job_control = 0; - original_pgrp = terminal_pgrp; /* for eventual give_terminal_to */ - goto just_bail; - } - continue; - } - break; - } - - if (terminal_pgrp == -1) - t_errno = errno; - - /* Make sure that we are using the new line discipline. */ - if (set_new_line_discipline (shell_tty) < 0) - { - sys_error (_("initialize_job_control: line discipline")); - job_control = 0; - } - else - { - original_pgrp = shell_pgrp; - shell_pgrp = getpid (); - - if ((original_pgrp != shell_pgrp) && (setpgid (0, shell_pgrp) < 0)) - { - sys_error (_("initialize_job_control: setpgid")); - shell_pgrp = original_pgrp; - } - - job_control = 1; - - /* If (and only if) we just set our process group to our pid, - thereby becoming a process group leader, and the terminal - is not in the same process group as our (new) process group, - then set the terminal's process group to our (new) process - group. If that fails, set our process group back to what it - was originally (so we can still read from the terminal) and - turn off job control. */ - if (shell_pgrp != original_pgrp && shell_pgrp != terminal_pgrp) - { - if (give_terminal_to (shell_pgrp, 0) < 0) - { - t_errno = errno; - setpgid (0, original_pgrp); - shell_pgrp = original_pgrp; - errno = t_errno; - sys_error (_("cannot set terminal process group (%d)"), shell_pgrp); - job_control = 0; - } - } - - if (job_control && ((t = tcgetpgrp (shell_tty)) == -1 || t != shell_pgrp)) - { - if (t_errno != -1) - errno = t_errno; - sys_error (_("cannot set terminal process group (%d)"), t); - job_control = 0; - } - } - if (job_control == 0) - internal_error (_("no job control in this shell")); - } - -just_bail: - running_in_background = terminal_pgrp != shell_pgrp; - - if (shell_tty != fileno (stderr)) - SET_CLOSE_ON_EXEC (shell_tty); - - set_signal_handler (SIGCHLD, sigchld_handler); - - change_flag ('m', job_control ? '-' : '+'); - - if (interactive) - get_tty_state (); - - set_maxchild (0); - - return job_control; -} - -#ifdef DEBUG -void -debug_print_pgrps () -{ - itrace("original_pgrp = %ld shell_pgrp = %ld terminal_pgrp = %ld", - (long)original_pgrp, (long)shell_pgrp, (long)terminal_pgrp); - itrace("tcgetpgrp(%d) -> %ld, getpgid(0) -> %ld", - shell_tty, (long)tcgetpgrp (shell_tty), (long)getpgid(0)); - itrace("pipeline_pgrp -> %ld", (long)pipeline_pgrp); -} -#endif - -/* Set the line discipline to the best this system has to offer. - Return -1 if this is not possible. */ -static int -set_new_line_discipline (tty) - int tty; -{ -#if defined (NEW_TTY_DRIVER) - int ldisc; - - if (ioctl (tty, TIOCGETD, &ldisc) < 0) - return (-1); - - if (ldisc != NTTYDISC) - { - ldisc = NTTYDISC; - - if (ioctl (tty, TIOCSETD, &ldisc) < 0) - return (-1); - } - return (0); -#endif /* NEW_TTY_DRIVER */ - -#if defined (TERMIO_TTY_DRIVER) -# if defined (TERMIO_LDISC) && (NTTYDISC) - if (ioctl (tty, TCGETA, &shell_tty_info) < 0) - return (-1); - - if (shell_tty_info.c_line != NTTYDISC) - { - shell_tty_info.c_line = NTTYDISC; - if (ioctl (tty, TCSETAW, &shell_tty_info) < 0) - return (-1); - } -# endif /* TERMIO_LDISC && NTTYDISC */ - return (0); -#endif /* TERMIO_TTY_DRIVER */ - -#if defined (TERMIOS_TTY_DRIVER) -# if defined (TERMIOS_LDISC) && defined (NTTYDISC) - if (tcgetattr (tty, &shell_tty_info) < 0) - return (-1); - - if (shell_tty_info.c_line != NTTYDISC) - { - shell_tty_info.c_line = NTTYDISC; - if (tcsetattr (tty, TCSADRAIN, &shell_tty_info) < 0) - return (-1); - } -# endif /* TERMIOS_LDISC && NTTYDISC */ - return (0); -#endif /* TERMIOS_TTY_DRIVER */ - -#if !defined (NEW_TTY_DRIVER) && !defined (TERMIO_TTY_DRIVER) && !defined (TERMIOS_TTY_DRIVER) - return (-1); -#endif -} - -/* Setup this shell to handle C-C, etc. */ -void -initialize_job_signals () -{ - if (interactive) - { - set_signal_handler (SIGINT, sigint_sighandler); - set_signal_handler (SIGTSTP, SIG_IGN); - set_signal_handler (SIGTTOU, SIG_IGN); - set_signal_handler (SIGTTIN, SIG_IGN); - } - else if (job_control) - { - old_tstp = set_signal_handler (SIGTSTP, sigstop_sighandler); - old_ttin = set_signal_handler (SIGTTIN, sigstop_sighandler); - old_ttou = set_signal_handler (SIGTTOU, sigstop_sighandler); - } - /* Leave disposition unmodified for non-interactive shells without job - control. */ -} - -/* Here we handle CONT signals. */ -static sighandler -sigcont_sighandler (sig) - int sig; -{ - initialize_job_signals (); - set_signal_handler (SIGCONT, old_cont); - kill (getpid (), SIGCONT); - - SIGRETURN (0); -} - -/* Here we handle stop signals while we are running not as a login shell. */ -static sighandler -sigstop_sighandler (sig) - int sig; -{ - set_signal_handler (SIGTSTP, old_tstp); - set_signal_handler (SIGTTOU, old_ttou); - set_signal_handler (SIGTTIN, old_ttin); - - old_cont = set_signal_handler (SIGCONT, sigcont_sighandler); - - give_terminal_to (shell_pgrp, 0); - - kill (getpid (), sig); - - SIGRETURN (0); -} - -/* Give the terminal to PGRP. */ -int -give_terminal_to (pgrp, force) - pid_t pgrp; - int force; -{ - sigset_t set, oset; - int r, e; - - r = 0; - if (job_control || force) - { - sigemptyset (&set); - sigaddset (&set, SIGTTOU); - sigaddset (&set, SIGTTIN); - sigaddset (&set, SIGTSTP); - sigaddset (&set, SIGCHLD); - sigemptyset (&oset); - sigprocmask (SIG_BLOCK, &set, &oset); - - if (tcsetpgrp (shell_tty, pgrp) < 0) - { - /* Maybe we should print an error message? */ -#if 0 - sys_error ("tcsetpgrp(%d) failed: pid %ld to pgrp %ld", - shell_tty, (long)getpid(), (long)pgrp); -#endif - r = -1; - e = errno; - } - else - terminal_pgrp = pgrp; - sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL); - } - - if (r == -1) - errno = e; - - return r; -} - -/* Give terminal to NPGRP iff it's currently owned by OPGRP. FLAGS are the - flags to pass to give_terminal_to(). */ -static int -maybe_give_terminal_to (opgrp, npgrp, flags) - pid_t opgrp, npgrp; - int flags; -{ - int tpgrp; - - tpgrp = tcgetpgrp (shell_tty); - if (tpgrp < 0 && errno == ENOTTY) - return -1; - if (tpgrp == npgrp) - { - terminal_pgrp = npgrp; - return 0; - } - else if (tpgrp != opgrp) - { - internal_debug ("%d: maybe_give_terminal_to: terminal pgrp == %d shell pgrp = %d new pgrp = %d in_background = %d", (int)getpid(), tpgrp, opgrp, npgrp, running_in_background); - return -1; - } - else - return (give_terminal_to (npgrp, flags)); -} - -/* Clear out any jobs in the job array. This is intended to be used by - children of the shell, who should not have any job structures as baggage - when they start executing (forking subshells for parenthesized execution - and functions with pipes are the two that spring to mind). If RUNNING_ONLY - is nonzero, only running jobs are removed from the table. */ -void -delete_all_jobs (running_only) - int running_only; -{ - register int i; - sigset_t set, oset; - - BLOCK_CHILD (set, oset); - - /* XXX - need to set j_lastj, j_firstj appropriately if running_only != 0. */ - if (js.j_jobslots) - { - js.j_current = js.j_previous = NO_JOB; - - /* XXX could use js.j_firstj here */ - for (i = 0; i < js.j_jobslots; i++) - { - if (i < js.j_firstj && jobs[i]) - INTERNAL_DEBUG (("delete_all_jobs: job %d non-null before js.j_firstj (%d)", i, js.j_firstj)); - if (i > js.j_lastj && jobs[i]) - INTERNAL_DEBUG (("delete_all_jobs: job %d non-null after js.j_lastj (%d)", i, js.j_lastj)); - - if (jobs[i] && (running_only == 0 || (running_only && RUNNING(i)))) - /* We don't want to add any of these pids to bgpids. If running_only - is non-zero, we don't want to add running jobs to the list. - If we are interested in all jobs, not just running jobs, and - we are going to clear the bgpids list below (bgp_clear()), we - don't need to bother. */ - delete_job (i, DEL_WARNSTOPPED|DEL_NOBGPID); - } - if (running_only == 0) - { - free ((char *)jobs); - js.j_jobslots = 0; - js.j_firstj = js.j_lastj = js.j_njobs = 0; - } - } - - if (running_only == 0) - bgp_clear (); - - UNBLOCK_CHILD (oset); -} - -/* Mark all jobs in the job array so that they don't get a SIGHUP when the - shell gets one. If RUNNING_ONLY is nonzero, mark only running jobs. */ -void -nohup_all_jobs (running_only) - int running_only; -{ - register int i; - sigset_t set, oset; - - BLOCK_CHILD (set, oset); - - if (js.j_jobslots) - { - /* XXX could use js.j_firstj here */ - for (i = 0; i < js.j_jobslots; i++) - if (jobs[i] && (running_only == 0 || (running_only && RUNNING(i)))) - nohup_job (i); - } - - UNBLOCK_CHILD (oset); -} - -int -count_all_jobs () -{ - int i, n; - sigset_t set, oset; - - /* This really counts all non-dead jobs. */ - BLOCK_CHILD (set, oset); - /* XXX could use js.j_firstj here */ - for (i = n = 0; i < js.j_jobslots; i++) - { - if (i < js.j_firstj && jobs[i]) - INTERNAL_DEBUG (("count_all_jobs: job %d non-null before js.j_firstj (%d)", i, js.j_firstj)); - if (i > js.j_lastj && jobs[i]) - INTERNAL_DEBUG (("count_all_jobs: job %d non-null after js.j_lastj (%d)", i, js.j_lastj)); - - if (jobs[i] && DEADJOB(i) == 0) - n++; - } - UNBLOCK_CHILD (oset); - return n; -} - -static void -mark_all_jobs_as_dead () -{ - register int i; - sigset_t set, oset; - - if (js.j_jobslots == 0) - return; - - BLOCK_CHILD (set, oset); - - /* XXX could use js.j_firstj here */ - for (i = 0; i < js.j_jobslots; i++) - if (jobs[i]) - { - jobs[i]->state = JDEAD; - js.j_ndead++; - } - - UNBLOCK_CHILD (oset); -} - -/* Mark all dead jobs as notified, so delete_job () cleans them out - of the job table properly. POSIX.2 says we need to save the - status of the last CHILD_MAX jobs, so we count the number of dead - jobs and mark only enough as notified to save CHILD_MAX statuses. */ -static void -mark_dead_jobs_as_notified (force) - int force; -{ - register int i, ndead, ndeadproc; - sigset_t set, oset; - - if (js.j_jobslots == 0) - return; - - BLOCK_CHILD (set, oset); - - /* If FORCE is non-zero, we don't have to keep CHILD_MAX statuses - around; just run through the array. */ - if (force) - { - /* XXX could use js.j_firstj here */ - for (i = 0; i < js.j_jobslots; i++) - { - if (jobs[i] && DEADJOB (i) && (interactive_shell || (find_last_pid (i, 0) != last_asynchronous_pid))) - jobs[i]->flags |= J_NOTIFIED; - } - UNBLOCK_CHILD (oset); - return; - } - - /* Mark enough dead jobs as notified to keep CHILD_MAX processes left in the - array with the corresponding not marked as notified. This is a better - way to avoid pid aliasing and reuse problems than keeping the POSIX- - mandated CHILD_MAX jobs around. delete_job() takes care of keeping the - bgpids list regulated. */ - - /* Count the number of dead jobs */ - /* XXX could use js.j_firstj here */ - for (i = ndead = ndeadproc = 0; i < js.j_jobslots; i++) - { - if (i < js.j_firstj && jobs[i]) - INTERNAL_DEBUG (("mark_dead_jobs_as_notified: job %d non-null before js.j_firstj (%d)", i, js.j_firstj)); - if (i > js.j_lastj && jobs[i]) - INTERNAL_DEBUG (("mark_dead_jobs_as_notified: job %d non-null after js.j_lastj (%d)", i, js.j_lastj)); - - if (jobs[i] && DEADJOB (i)) - { - ndead++; - ndeadproc += processes_in_job (i); - } - } - -# if 0 - if (ndeadproc != js.c_reaped) - itrace("mark_dead_jobs_as_notified: ndeadproc (%d) != js.c_reaped (%d)", ndeadproc, js.c_reaped); -# endif - if (ndead != js.j_ndead) - INTERNAL_DEBUG (("mark_dead_jobs_as_notified: ndead (%d) != js.j_ndead (%d)", ndead, js.j_ndead)); - - if (js.c_childmax < 0) - set_maxchild (0); - - /* Don't do anything if the number of dead processes is less than CHILD_MAX - and we're not forcing a cleanup. */ - if (ndeadproc <= js.c_childmax) - { - UNBLOCK_CHILD (oset); - return; - } - -#if 0 -itrace("mark_dead_jobs_as_notified: child_max = %d ndead = %d ndeadproc = %d", js.c_childmax, ndead, ndeadproc); -#endif - - /* Mark enough dead jobs as notified that we keep CHILD_MAX jobs in - the list. This isn't exactly right yet; changes need to be made - to stop_pipeline so we don't mark the newer jobs after we've - created CHILD_MAX slots in the jobs array. This needs to be - integrated with a way to keep the jobs array from growing without - bound. Maybe we wrap back around to 0 after we reach some max - limit, and there are sufficient job slots free (keep track of total - size of jobs array (js.j_jobslots) and running count of number of jobs - in jobs array. Then keep a job index corresponding to the `oldest job' - and start this loop there, wrapping around as necessary. In effect, - we turn the list into a circular buffer. */ - /* XXX could use js.j_firstj here */ - for (i = 0; i < js.j_jobslots; i++) - { - if (jobs[i] && DEADJOB (i) && (interactive_shell || (find_last_pid (i, 0) != last_asynchronous_pid))) - { - if (i < js.j_firstj && jobs[i]) - INTERNAL_DEBUG (("mark_dead_jobs_as_notified: job %d non-null before js.j_firstj (%d)", i, js.j_firstj)); - if (i > js.j_lastj && jobs[i]) - INTERNAL_DEBUG (("mark_dead_jobs_as_notified: job %d non-null after js.j_lastj (%d)", i, js.j_lastj)); - - /* If marking this job as notified would drop us down below - child_max, don't mark it so we can keep at least child_max - statuses. XXX -- need to check what Posix actually says - about keeping statuses. */ - if ((ndeadproc -= processes_in_job (i)) <= js.c_childmax) - break; - jobs[i]->flags |= J_NOTIFIED; - } - } - - UNBLOCK_CHILD (oset); -} - -/* Here to allow other parts of the shell (like the trap stuff) to - freeze and unfreeze the jobs list. */ -int -freeze_jobs_list () -{ - int o; - - o = jobs_list_frozen; - jobs_list_frozen = 1; - return o; -} - -void -unfreeze_jobs_list () -{ - jobs_list_frozen = 0; -} - -void -set_jobs_list_frozen (s) - int s; -{ - jobs_list_frozen = s; -} - -/* Allow or disallow job control to take place. Returns the old value - of job_control. */ -int -set_job_control (arg) - int arg; -{ - int old; - - old = job_control; - job_control = arg; - - if (terminal_pgrp == NO_PID && shell_tty >= 0) - terminal_pgrp = tcgetpgrp (shell_tty); - - /* If we're turning on job control we're going to want to know the shell's - process group. */ - if (job_control != old && job_control) - shell_pgrp = getpgid (0); - - running_in_background = (terminal_pgrp != shell_pgrp); - -#if 0 - if (interactive_shell == 0 && running_in_background == 0 && job_control != old) - { - if (job_control) - initialize_job_signals (); - else - default_tty_job_signals (); - } -#endif - - /* If we're turning on job control, reset pipeline_pgrp so make_child will - put new child processes into the right pgrp */ - if (job_control != old && job_control) - pipeline_pgrp = 0; - - return (old); -} - -/* Turn off all traces of job control. This is run by children of the shell - which are going to do shellsy things, like wait (), etc. */ -void -without_job_control () -{ - stop_making_children (); - start_pipeline (); -#if defined (PGRP_PIPE) - sh_closepipe (pgrp_pipe); -#endif - delete_all_jobs (0); - set_job_control (0); -} - -/* If this shell is interactive, terminate all stopped jobs and - restore the original terminal process group. This is done - before the `exec' builtin calls shell_execve. */ -void -end_job_control () -{ - if (job_control) - terminate_stopped_jobs (); - - if (original_pgrp >= 0 && terminal_pgrp != original_pgrp) - give_terminal_to (original_pgrp, 1); - - if (original_pgrp >= 0 && setpgid (0, original_pgrp) == 0) - shell_pgrp = original_pgrp; -} - -/* Restart job control by closing shell tty and reinitializing. This is - called after an exec fails in an interactive shell and we do not exit. */ -void -restart_job_control () -{ - if (shell_tty != -1) - close (shell_tty); - initialize_job_control (0); -} - -/* Set the maximum number of background children we keep track of to NCHILD. - If the caller passes NCHILD as 0 or -1, this ends up setting it to - LMAXCHILD, which is initialized the first time through. */ -void -set_maxchild (nchild) - int nchild; -{ - static int lmaxchild = -1; - - /* Initialize once. */ - if (lmaxchild < 0) - { - errno = 0; - lmaxchild = getmaxchild (); - if (lmaxchild < 0 && errno == 0) - lmaxchild = MAX_CHILD_MAX; /* assume unlimited */ - } - if (lmaxchild < 0) - lmaxchild = DEFAULT_CHILD_MAX; - - /* Clamp value we set. Minimum is what Posix requires, maximum is defined - above as MAX_CHILD_MAX. */ - if (nchild < lmaxchild) - nchild = lmaxchild; - else if (nchild > MAX_CHILD_MAX) - nchild = MAX_CHILD_MAX; - - js.c_childmax = nchild; -} - -/* Set the handler to run when the shell receives a SIGCHLD signal. */ -void -set_sigchld_handler () -{ - set_signal_handler (SIGCHLD, sigchld_handler); -} - -#if defined (PGRP_PIPE) -/* Read from the read end of a pipe. This is how the process group leader - blocks until all of the processes in a pipeline have been made. */ -static void -pipe_read (pp) - int *pp; -{ - char ch; - - if (pp[1] >= 0) - { - close (pp[1]); - pp[1] = -1; - } - - if (pp[0] >= 0) - { - while (read (pp[0], &ch, 1) == -1 && errno == EINTR) - ; - } -} - -/* Functional interface closes our local-to-job-control pipes. */ -void -close_pgrp_pipe () -{ - sh_closepipe (pgrp_pipe); -} - -void -save_pgrp_pipe (p, clear) - int *p; - int clear; -{ - p[0] = pgrp_pipe[0]; - p[1] = pgrp_pipe[1]; - if (clear) - pgrp_pipe[0] = pgrp_pipe[1] = -1; -} - -void -restore_pgrp_pipe (p) - int *p; -{ - pgrp_pipe[0] = p[0]; - pgrp_pipe[1] = p[1]; -} - -#endif /* PGRP_PIPE */ diff --git a/third_party/bash/jobs.h b/third_party/bash/jobs.h deleted file mode 100644 index 276204f0c..000000000 --- a/third_party/bash/jobs.h +++ /dev/null @@ -1,325 +0,0 @@ -/* jobs.h -- structures and definitions used by the jobs.c file. */ - -/* Copyright (C) 1993-2022 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_JOBS_H_) -# define _JOBS_H_ - -#include "quit.h" -#include "siglist.h" - -#include "stdc.h" - -#include "posixwait.h" - -/* Defines controlling the fashion in which jobs are listed. */ -#define JLIST_STANDARD 0 -#define JLIST_LONG 1 -#define JLIST_PID_ONLY 2 -#define JLIST_CHANGED_ONLY 3 -#define JLIST_NONINTERACTIVE 4 - -/* I looked it up. For pretty_print_job (). The real answer is 24. */ -#define LONGEST_SIGNAL_DESC 24 - -/* Defines for the wait_for_* functions and for the wait builtin to use */ -#define JWAIT_PERROR (1 << 0) -#define JWAIT_FORCE (1 << 1) -#define JWAIT_NOWAIT (1 << 2) /* don't waitpid(), just return status if already exited */ -#define JWAIT_WAITING (1 << 3) /* wait for jobs marked J_WAITING only */ - -/* flags for wait_for */ -#define JWAIT_NOTERM (1 << 8) /* wait_for doesn't give terminal away */ - -/* The max time to sleep while retrying fork() on EAGAIN failure */ -#define FORKSLEEP_MAX 16 - -/* We keep an array of jobs. Each entry in the array is a linked list - of processes that are piped together. The first process encountered is - the group leader. */ - -/* Values for the `running' field of a struct process. */ -#define PS_DONE 0 -#define PS_RUNNING 1 -#define PS_STOPPED 2 -#define PS_RECYCLED 4 - -/* Each child of the shell is remembered in a STRUCT PROCESS. A circular - chain of such structures is a pipeline. */ -typedef struct process { - struct process *next; /* Next process in the pipeline. A circular chain. */ - pid_t pid; /* Process ID. */ - WAIT status; /* The status of this command as returned by wait. */ - int running; /* Non-zero if this process is running. */ - char *command; /* The particular program that is running. */ -} PROCESS; - -struct pipeline_saver { - struct process *pipeline; - struct pipeline_saver *next; -}; - -/* PALIVE really means `not exited' */ -#define PSTOPPED(p) (WIFSTOPPED((p)->status)) -#define PRUNNING(p) ((p)->running == PS_RUNNING) -#define PALIVE(p) (PRUNNING(p) || PSTOPPED(p)) - -#define PEXITED(p) ((p)->running == PS_DONE) -#if defined (RECYCLES_PIDS) -# define PRECYCLED(p) ((p)->running == PS_RECYCLED) -#else -# define PRECYCLED(p) (0) -#endif -#define PDEADPROC(p) (PEXITED(p) || PRECYCLED(p)) - -#define get_job_by_jid(ind) (jobs[(ind)]) - -/* A description of a pipeline's state. */ -typedef enum { JNONE = -1, JRUNNING = 1, JSTOPPED = 2, JDEAD = 4, JMIXED = 8 } JOB_STATE; -#define JOBSTATE(job) (jobs[(job)]->state) -#define J_JOBSTATE(j) ((j)->state) - -#define STOPPED(j) (jobs[(j)]->state == JSTOPPED) -#define RUNNING(j) (jobs[(j)]->state == JRUNNING) -#define DEADJOB(j) (jobs[(j)]->state == JDEAD) - -#define INVALID_JOB(j) ((j) < 0 || (j) >= js.j_jobslots || get_job_by_jid(j) == 0) - -/* Values for the FLAGS field in the JOB struct below. */ -#define J_FOREGROUND 0x01 /* Non-zero if this is running in the foreground. */ -#define J_NOTIFIED 0x02 /* Non-zero if already notified about job state. */ -#define J_JOBCONTROL 0x04 /* Non-zero if this job started under job control. */ -#define J_NOHUP 0x08 /* Don't send SIGHUP to job if shell gets SIGHUP. */ -#define J_STATSAVED 0x10 /* A process in this job had status saved via $! */ -#define J_ASYNC 0x20 /* Job was started asynchronously */ -#define J_PIPEFAIL 0x40 /* pipefail set when job was started */ -#define J_WAITING 0x80 /* one of a list of jobs for which we are waiting */ - -#define IS_FOREGROUND(j) ((jobs[j]->flags & J_FOREGROUND) != 0) -#define IS_NOTIFIED(j) ((jobs[j]->flags & J_NOTIFIED) != 0) -#define IS_JOBCONTROL(j) ((jobs[j]->flags & J_JOBCONTROL) != 0) -#define IS_ASYNC(j) ((jobs[j]->flags & J_ASYNC) != 0) -#define IS_WAITING(j) ((jobs[j]->flags & J_WAITING) != 0) - -typedef struct job { - char *wd; /* The working directory at time of invocation. */ - PROCESS *pipe; /* The pipeline of processes that make up this job. */ - pid_t pgrp; /* The process ID of the process group (necessary). */ - JOB_STATE state; /* The state that this job is in. */ - int flags; /* Flags word: J_NOTIFIED, J_FOREGROUND, or J_JOBCONTROL. */ -#if defined (JOB_CONTROL) - COMMAND *deferred; /* Commands that will execute when this job is done. */ - sh_vptrfunc_t *j_cleanup; /* Cleanup function to call when job marked JDEAD */ - PTR_T cleanarg; /* Argument passed to (*j_cleanup)() */ -#endif /* JOB_CONTROL */ -} JOB; - -struct jobstats { - /* limits */ - long c_childmax; - /* child process statistics */ - int c_living; /* running or stopped child processes */ - int c_reaped; /* exited child processes still in jobs list */ - int c_injobs; /* total number of child processes in jobs list */ - /* child process totals */ - int c_totforked; /* total number of children this shell has forked */ - int c_totreaped; /* total number of children this shell has reaped */ - /* job counters and indices */ - int j_jobslots; /* total size of jobs array */ - int j_lastj; /* last (newest) job allocated */ - int j_firstj; /* first (oldest) job allocated */ - int j_njobs; /* number of non-NULL jobs in jobs array */ - int j_ndead; /* number of JDEAD jobs in jobs array */ - /* */ - int j_current; /* current job */ - int j_previous; /* previous job */ - /* */ - JOB *j_lastmade; /* last job allocated by stop_pipeline */ - JOB *j_lastasync; /* last async job allocated by stop_pipeline */ -}; - -/* Revised to accommodate new hash table bgpids implementation. */ -typedef pid_t ps_index_t; - -struct pidstat { - ps_index_t bucket_next; - ps_index_t bucket_prev; - - pid_t pid; - bits16_t status; /* only 8 bits really needed */ -}; - -struct bgpids { - struct pidstat *storage; /* storage arena */ - - ps_index_t head; - ps_index_t nalloc; - - int npid; -}; - -#define NO_PIDSTAT (ps_index_t)-1 - -/* standalone process status struct, without bgpids indexes */ -struct procstat { - pid_t pid; - bits16_t status; -}; - -/* A standalone singly-linked list of PROCESS *, used in various places - including keeping track of process substitutions. */ -struct procchain { - PROCESS *head; - PROCESS *end; - int nproc; -}; - -#define NO_JOB -1 /* An impossible job array index. */ -#define DUP_JOB -2 /* A possible return value for get_job_spec (). */ -#define BAD_JOBSPEC -3 /* Bad syntax for job spec. */ - -/* A value which cannot be a process ID. */ -#define NO_PID (pid_t)-1 - -#define ANY_PID (pid_t)-1 - -/* flags for make_child () */ -#define FORK_SYNC 0 /* normal synchronous process */ -#define FORK_ASYNC 1 /* background process */ -#define FORK_NOJOB 2 /* don't put process in separate pgrp */ -#define FORK_NOTERM 4 /* don't give terminal to any pgrp */ - -/* System calls. */ -#if !defined (HAVE_UNISTD_H) -extern pid_t fork (), getpid (), getpgrp (); -#endif /* !HAVE_UNISTD_H */ - -/* Stuff from the jobs.c file. */ -extern struct jobstats js; - -extern pid_t original_pgrp, shell_pgrp, pipeline_pgrp; -extern volatile pid_t last_made_pid, last_asynchronous_pid; -extern int asynchronous_notification; - -extern int already_making_children; -extern int running_in_background; - -extern PROCESS *last_procsub_child; - -extern JOB **jobs; - -extern void making_children PARAMS((void)); -extern void stop_making_children PARAMS((void)); -extern void cleanup_the_pipeline PARAMS((void)); -extern void discard_last_procsub_child PARAMS((void)); -extern void save_pipeline PARAMS((int)); -extern PROCESS *restore_pipeline PARAMS((int)); -extern void start_pipeline PARAMS((void)); -extern int stop_pipeline PARAMS((int, COMMAND *)); -extern int discard_pipeline PARAMS((PROCESS *)); -extern void append_process PARAMS((char *, pid_t, int, int)); - -extern void save_proc_status PARAMS((pid_t, int)); - -extern PROCESS *procsub_add PARAMS((PROCESS *)); -extern PROCESS *procsub_search PARAMS((pid_t)); -extern PROCESS *procsub_delete PARAMS((pid_t)); -extern int procsub_waitpid PARAMS((pid_t)); -extern void procsub_waitall PARAMS((void)); -extern void procsub_clear PARAMS((void)); -extern void procsub_prune PARAMS((void)); - -extern void delete_job PARAMS((int, int)); -extern void nohup_job PARAMS((int)); -extern void delete_all_jobs PARAMS((int)); -extern void nohup_all_jobs PARAMS((int)); - -extern int count_all_jobs PARAMS((void)); - -extern void terminate_current_pipeline PARAMS((void)); -extern void terminate_stopped_jobs PARAMS((void)); -extern void hangup_all_jobs PARAMS((void)); -extern void kill_current_pipeline PARAMS((void)); - -#if defined (__STDC__) && defined (pid_t) -extern int get_job_by_pid PARAMS((int, int, PROCESS **)); -extern void describe_pid PARAMS((int)); -#else -extern int get_job_by_pid PARAMS((pid_t, int, PROCESS **)); -extern void describe_pid PARAMS((pid_t)); -#endif - -extern void list_one_job PARAMS((JOB *, int, int, int)); -extern void list_all_jobs PARAMS((int)); -extern void list_stopped_jobs PARAMS((int)); -extern void list_running_jobs PARAMS((int)); - -extern pid_t make_child PARAMS((char *, int)); - -extern int get_tty_state PARAMS((void)); -extern int set_tty_state PARAMS((void)); - -extern int job_exit_status PARAMS((int)); -extern int job_exit_signal PARAMS((int)); - -extern int wait_for_single_pid PARAMS((pid_t, int)); -extern int wait_for_background_pids PARAMS((struct procstat *)); -extern int wait_for PARAMS((pid_t, int)); -extern int wait_for_job PARAMS((int, int, struct procstat *)); -extern int wait_for_any_job PARAMS((int, struct procstat *)); - -extern void wait_sigint_cleanup PARAMS((void)); - -extern void notify_and_cleanup PARAMS((void)); -extern void reap_dead_jobs PARAMS((void)); -extern int start_job PARAMS((int, int)); -extern int kill_pid PARAMS((pid_t, int, int)); -extern int initialize_job_control PARAMS((int)); -extern void initialize_job_signals PARAMS((void)); -extern int give_terminal_to PARAMS((pid_t, int)); - -extern void run_sigchld_trap PARAMS((int)); - -extern int freeze_jobs_list PARAMS((void)); -extern void unfreeze_jobs_list PARAMS((void)); -extern void set_jobs_list_frozen PARAMS((int)); -extern int set_job_control PARAMS((int)); -extern void without_job_control PARAMS((void)); -extern void end_job_control PARAMS((void)); -extern void restart_job_control PARAMS((void)); -extern void set_sigchld_handler PARAMS((void)); -extern void ignore_tty_job_signals PARAMS((void)); -extern void default_tty_job_signals PARAMS((void)); -extern void get_original_tty_job_signals PARAMS((void)); - -extern void init_job_stats PARAMS((void)); - -extern void close_pgrp_pipe PARAMS((void)); -extern void save_pgrp_pipe PARAMS((int *, int)); -extern void restore_pgrp_pipe PARAMS((int *)); - -extern void set_maxchild PARAMS((int)); - -#ifdef DEBUG -extern void debug_print_pgrps (void); -#endif - -extern int job_control; /* set to 0 in nojobs.c */ - -#endif /* _JOBS_H_ */ diff --git a/third_party/bash/list.c b/third_party/bash/list.c deleted file mode 100644 index 88835f58e..000000000 --- a/third_party/bash/list.c +++ /dev/null @@ -1,136 +0,0 @@ -/* list.c - Functions for manipulating linked lists of objects. */ - -/* Copyright (C) 1996-2009 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include "shell.h" - -/* A global variable which acts as a sentinel for an `error' list return. */ -GENERIC_LIST global_error_list; - -#ifdef INCLUDE_UNUSED -/* Call FUNCTION on every member of LIST, a generic list. */ -void -list_walk (list, function) - GENERIC_LIST *list; - sh_glist_func_t *function; -{ - for ( ; list; list = list->next) - if ((*function) (list) < 0) - return; -} - -/* Call FUNCTION on every string in WORDS. */ -void -wlist_walk (words, function) - WORD_LIST *words; - sh_icpfunc_t *function; -{ - for ( ; words; words = words->next) - if ((*function) (words->word->word) < 0) - return; -} -#endif /* INCLUDE_UNUSED */ - -/* Reverse the chain of structures in LIST. Output the new head - of the chain. You should always assign the output value of this - function to something, or you will lose the chain. */ -GENERIC_LIST * -list_reverse (list) - GENERIC_LIST *list; -{ - register GENERIC_LIST *next, *prev; - - for (prev = (GENERIC_LIST *)NULL; list; ) - { - next = list->next; - list->next = prev; - prev = list; - list = next; - } - return (prev); -} - -/* Return the number of elements in LIST, a generic list. */ -int -list_length (list) - GENERIC_LIST *list; -{ - register int i; - - for (i = 0; list; list = list->next, i++); - return (i); -} - -/* Append TAIL to HEAD. Return the header of the list. */ -GENERIC_LIST * -list_append (head, tail) - GENERIC_LIST *head, *tail; -{ - register GENERIC_LIST *t_head; - - if (head == 0) - return (tail); - - for (t_head = head; t_head->next; t_head = t_head->next) - ; - t_head->next = tail; - return (head); -} - -#ifdef INCLUDE_UNUSED -/* Delete the element of LIST which satisfies the predicate function COMPARER. - Returns the element that was deleted, so you can dispose of it, or -1 if - the element wasn't found. COMPARER is called with the list element and - then ARG. Note that LIST contains the address of a variable which points - to the list. You might call this function like this: - - SHELL_VAR *elt = list_remove (&variable_list, check_var_has_name, "foo"); - dispose_variable (elt); -*/ -GENERIC_LIST * -list_remove (list, comparer, arg) - GENERIC_LIST **list; - Function *comparer; - char *arg; -{ - register GENERIC_LIST *prev, *temp; - - for (prev = (GENERIC_LIST *)NULL, temp = *list; temp; prev = temp, temp = temp->next) - { - if ((*comparer) (temp, arg)) - { - if (prev) - prev->next = temp->next; - else - *list = temp->next; - return (temp); - } - } - return ((GENERIC_LIST *)&global_error_list); -} -#endif diff --git a/third_party/bash/locale.c b/third_party/bash/locale.c deleted file mode 100644 index fabf7b125..000000000 --- a/third_party/bash/locale.c +++ /dev/null @@ -1,645 +0,0 @@ -/* locale.c - Miscellaneous internationalization functions. */ - -/* Copyright (C) 1996-2009,2012,2016-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include "bashtypes.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#if HAVE_LANGINFO_CODESET -# include -#endif - -#include "bashintl.h" -#include "bashansi.h" -#include -#include "chartypes.h" -#include - -#include "shell.h" -#include "input.h" /* For bash_input */ - -#ifndef errno -extern int errno; -#endif - -int locale_utf8locale; -int locale_mb_cur_max; /* value of MB_CUR_MAX for current locale (LC_CTYPE) */ -int locale_shiftstates = 0; - -int singlequote_translations = 0; /* single-quote output of $"..." */ - -extern int dump_translatable_strings, dump_po_strings; - -/* The current locale when the program begins */ -static char *default_locale; - -/* The current domain for textdomain(3). */ -static char *default_domain; -static char *default_dir; - -/* tracks the value of LC_ALL; used to override values for other locale - categories */ -static char *lc_all; - -/* tracks the value of LC_ALL; used to provide defaults for locale - categories */ -static char *lang; - -/* Called to reset all of the locale variables to their appropriate values - if (and only if) LC_ALL has not been assigned a value. */ -static int reset_locale_vars PARAMS((void)); - -static void locale_setblanks PARAMS((void)); -static int locale_isutf8 PARAMS((char *)); - -/* Set the value of default_locale and make the current locale the - system default locale. This should be called very early in main(). */ -void -set_default_locale () -{ -#if defined (HAVE_SETLOCALE) - default_locale = setlocale (LC_ALL, ""); - if (default_locale) - default_locale = savestring (default_locale); -#else - default_locale = savestring ("C"); -#endif /* HAVE_SETLOCALE */ - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); - - locale_mb_cur_max = MB_CUR_MAX; - locale_utf8locale = locale_isutf8 (default_locale); -#if defined (HANDLE_MULTIBYTE) - locale_shiftstates = mblen ((char *)NULL, 0); -#else - locale_shiftstates = 0; -#endif -} - -/* Set default values for LC_CTYPE, LC_COLLATE, LC_MESSAGES, LC_NUMERIC and - LC_TIME if they are not specified in the environment, but LC_ALL is. This - should be called from main() after parsing the environment. */ -void -set_default_locale_vars () -{ - char *val; - -#if defined (HAVE_SETLOCALE) - -# if defined (LC_CTYPE) - val = get_string_value ("LC_CTYPE"); - if (val == 0 && lc_all && *lc_all) - { - setlocale (LC_CTYPE, lc_all); - locale_setblanks (); - locale_mb_cur_max = MB_CUR_MAX; - locale_utf8locale = locale_isutf8 (lc_all); - -# if defined (HANDLE_MULTIBYTE) - locale_shiftstates = mblen ((char *)NULL, 0); -# else - locale_shiftstates = 0; -# endif - - u32reset (); - } -# endif - -# if defined (LC_COLLATE) - val = get_string_value ("LC_COLLATE"); - if (val == 0 && lc_all && *lc_all) - setlocale (LC_COLLATE, lc_all); -# endif /* LC_COLLATE */ - -# if defined (LC_MESSAGES) - val = get_string_value ("LC_MESSAGES"); - if (val == 0 && lc_all && *lc_all) - setlocale (LC_MESSAGES, lc_all); -# endif /* LC_MESSAGES */ - -# if defined (LC_NUMERIC) - val = get_string_value ("LC_NUMERIC"); - if (val == 0 && lc_all && *lc_all) - setlocale (LC_NUMERIC, lc_all); -# endif /* LC_NUMERIC */ - -# if defined (LC_TIME) - val = get_string_value ("LC_TIME"); - if (val == 0 && lc_all && *lc_all) - setlocale (LC_TIME, lc_all); -# endif /* LC_TIME */ - -#endif /* HAVE_SETLOCALE */ - - val = get_string_value ("TEXTDOMAIN"); - if (val && *val) - { - FREE (default_domain); - default_domain = savestring (val); - if (default_dir && *default_dir) - bindtextdomain (default_domain, default_dir); - } - - val = get_string_value ("TEXTDOMAINDIR"); - if (val && *val) - { - FREE (default_dir); - default_dir = savestring (val); - if (default_domain && *default_domain) - bindtextdomain (default_domain, default_dir); - } -} - -/* Set one of the locale categories (specified by VAR) to VALUE. Returns 1 - if successful, 0 otherwise. */ -int -set_locale_var (var, value) - char *var, *value; -{ - int r; - char *x; - - x = ""; - errno = 0; - if (var[0] == 'T' && var[10] == 0) /* TEXTDOMAIN */ - { - FREE (default_domain); - default_domain = value ? savestring (value) : (char *)NULL; - if (default_dir && *default_dir) - bindtextdomain (default_domain, default_dir); - return (1); - } - else if (var[0] == 'T') /* TEXTDOMAINDIR */ - { - FREE (default_dir); - default_dir = value ? savestring (value) : (char *)NULL; - if (default_domain && *default_domain) - bindtextdomain (default_domain, default_dir); - return (1); - } - - /* var[0] == 'L' && var[1] == 'C' && var[2] == '_' */ - - else if (var[3] == 'A') /* LC_ALL */ - { - FREE (lc_all); - if (value) - lc_all = savestring (value); - else - { - lc_all = (char *)xmalloc (1); - lc_all[0] = '\0'; - } -#if defined (HAVE_SETLOCALE) - r = *lc_all ? ((x = setlocale (LC_ALL, lc_all)) != 0) : reset_locale_vars (); - if (x == 0) - { - if (errno == 0) - internal_warning(_("setlocale: LC_ALL: cannot change locale (%s)"), lc_all); - else - internal_warning(_("setlocale: LC_ALL: cannot change locale (%s): %s"), lc_all, strerror (errno)); - } - locale_setblanks (); - locale_mb_cur_max = MB_CUR_MAX; - /* if LC_ALL == "", reset_locale_vars has already called this */ - if (*lc_all && x) - locale_utf8locale = locale_isutf8 (lc_all); -# if defined (HANDLE_MULTIBYTE) - locale_shiftstates = mblen ((char *)NULL, 0); -# else - locale_shiftstates = 0; -# endif - u32reset (); - return r; -#else - return (1); -#endif - } - -#if defined (HAVE_SETLOCALE) - else if (var[3] == 'C' && var[4] == 'T') /* LC_CTYPE */ - { -# if defined (LC_CTYPE) - if (lc_all == 0 || *lc_all == '\0') - { - x = setlocale (LC_CTYPE, get_locale_var ("LC_CTYPE")); - locale_setblanks (); - locale_mb_cur_max = MB_CUR_MAX; - /* if setlocale() returns NULL, the locale is not changed */ - if (x) - locale_utf8locale = locale_isutf8 (x); -#if defined (HANDLE_MULTIBYTE) - locale_shiftstates = mblen ((char *)NULL, 0); -#else - locale_shiftstates = 0; -#endif - u32reset (); - } -# endif - } - else if (var[3] == 'C' && var[4] == 'O') /* LC_COLLATE */ - { -# if defined (LC_COLLATE) - if (lc_all == 0 || *lc_all == '\0') - x = setlocale (LC_COLLATE, get_locale_var ("LC_COLLATE")); -# endif /* LC_COLLATE */ - } - else if (var[3] == 'M' && var[4] == 'E') /* LC_MESSAGES */ - { -# if defined (LC_MESSAGES) - if (lc_all == 0 || *lc_all == '\0') - x = setlocale (LC_MESSAGES, get_locale_var ("LC_MESSAGES")); -# endif /* LC_MESSAGES */ - } - else if (var[3] == 'N' && var[4] == 'U') /* LC_NUMERIC */ - { -# if defined (LC_NUMERIC) - if (lc_all == 0 || *lc_all == '\0') - x = setlocale (LC_NUMERIC, get_locale_var ("LC_NUMERIC")); -# endif /* LC_NUMERIC */ - } - else if (var[3] == 'T' && var[4] == 'I') /* LC_TIME */ - { -# if defined (LC_TIME) - if (lc_all == 0 || *lc_all == '\0') - x = setlocale (LC_TIME, get_locale_var ("LC_TIME")); -# endif /* LC_TIME */ - } -#endif /* HAVE_SETLOCALE */ - - if (x == 0) - { - if (errno == 0) - internal_warning(_("setlocale: %s: cannot change locale (%s)"), var, get_locale_var (var)); - else - internal_warning(_("setlocale: %s: cannot change locale (%s): %s"), var, get_locale_var (var), strerror (errno)); - } - - return (x != 0); -} - -/* Called when LANG is assigned a value. Tracks value in `lang'. Calls - reset_locale_vars() to reset any default values if LC_ALL is unset or - null. */ -int -set_lang (var, value) - char *var, *value; -{ - FREE (lang); - if (value) - lang = savestring (value); - else - { - lang = (char *)xmalloc (1); - lang[0] = '\0'; - } - - return ((lc_all == 0 || *lc_all == 0) ? reset_locale_vars () : 0); -} - -/* Set default values for LANG and LC_ALL. Default values for all other - locale-related variables depend on these. */ -void -set_default_lang () -{ - char *v; - - v = get_string_value ("LC_ALL"); - set_locale_var ("LC_ALL", v); - - v = get_string_value ("LANG"); - set_lang ("LANG", v); -} - -/* Get the value of one of the locale variables (LC_MESSAGES, LC_CTYPE). - The precedence is as POSIX.2 specifies: LC_ALL has precedence over - the specific locale variables, and LANG, if set, is used as the default. */ -char * -get_locale_var (var) - char *var; -{ - char *locale; - - locale = lc_all; - - if (locale == 0 || *locale == 0) - locale = get_string_value (var); /* XXX - no mem leak */ - if (locale == 0 || *locale == 0) - locale = lang; - if (locale == 0 || *locale == 0) -#if 0 - locale = default_locale; /* system-dependent; not really portable. should it be "C"? */ -#else - locale = ""; -#endif - return (locale); -} - -/* Called to reset all of the locale variables to their appropriate values - if (and only if) LC_ALL has not been assigned a value. DO NOT CALL THIS - IF LC_ALL HAS BEEN ASSIGNED A VALUE. */ -static int -reset_locale_vars () -{ - char *t, *x; -#if defined (HAVE_SETLOCALE) - if (lang == 0 || *lang == '\0') - maybe_make_export_env (); /* trust that this will change environment for setlocale */ - if (setlocale (LC_ALL, lang ? lang : "") == 0) - return 0; - - x = 0; -# if defined (LC_CTYPE) - x = setlocale (LC_CTYPE, get_locale_var ("LC_CTYPE")); -# endif -# if defined (LC_COLLATE) - t = setlocale (LC_COLLATE, get_locale_var ("LC_COLLATE")); -# endif -# if defined (LC_MESSAGES) - t = setlocale (LC_MESSAGES, get_locale_var ("LC_MESSAGES")); -# endif -# if defined (LC_NUMERIC) - t = setlocale (LC_NUMERIC, get_locale_var ("LC_NUMERIC")); -# endif -# if defined (LC_TIME) - t = setlocale (LC_TIME, get_locale_var ("LC_TIME")); -# endif - - locale_setblanks (); - locale_mb_cur_max = MB_CUR_MAX; - if (x) - locale_utf8locale = locale_isutf8 (x); -# if defined (HANDLE_MULTIBYTE) - locale_shiftstates = mblen ((char *)NULL, 0); -# else - locale_shiftstates = 0; -# endif - u32reset (); -#endif - return 1; -} - -#if defined (TRANSLATABLE_STRINGS) -/* Translate the contents of STRING, a $"..." quoted string, according - to the current locale. In the `C' or `POSIX' locale, or if gettext() - is not available, the passed string is returned unchanged. The - length of the translated string is returned in LENP, if non-null. */ -char * -localetrans (string, len, lenp) - char *string; - int len, *lenp; -{ - char *locale, *t; - char *translated; - int tlen; - - /* Don't try to translate null strings. */ - if (string == 0 || *string == 0) - { - if (lenp) - *lenp = 0; - return ((char *)NULL); - } - - locale = get_locale_var ("LC_MESSAGES"); - - /* If we don't have setlocale() or the current locale is `C' or `POSIX', - just return the string. If we don't have gettext(), there's no use - doing anything else. */ - if (locale == 0 || locale[0] == '\0' || - (locale[0] == 'C' && locale[1] == '\0') || STREQ (locale, "POSIX")) - { - t = (char *)xmalloc (len + 1); - strcpy (t, string); - if (lenp) - *lenp = len; - return (t); - } - - /* Now try to translate it. */ - if (default_domain && *default_domain) - translated = dgettext (default_domain, string); - else - translated = string; - - if (translated == string) /* gettext returns its argument if untranslatable */ - { - t = (char *)xmalloc (len + 1); - strcpy (t, string); - if (lenp) - *lenp = len; - } - else - { - tlen = strlen (translated); - t = (char *)xmalloc (tlen + 1); - strcpy (t, translated); - if (lenp) - *lenp = tlen; - } - return (t); -} - -/* Change a bash string into a string suitable for inclusion in a `po' file. - This backslash-escapes `"' and `\' and changes newlines into \\\n"\n". */ -char * -mk_msgstr (string, foundnlp) - char *string; - int *foundnlp; -{ - register int c, len; - char *result, *r, *s; - - for (len = 0, s = string; s && *s; s++) - { - len++; - if (*s == '"' || *s == '\\') - len++; - else if (*s == '\n') - len += 5; - } - - r = result = (char *)xmalloc (len + 3); - *r++ = '"'; - - for (s = string; s && (c = *s); s++) - { - if (c == '\n') /* -> \n"" */ - { - *r++ = '\\'; - *r++ = 'n'; - *r++ = '"'; - *r++ = '\n'; - *r++ = '"'; - if (foundnlp) - *foundnlp = 1; - continue; - } - if (c == '"' || c == '\\') - *r++ = '\\'; - *r++ = c; - } - - *r++ = '"'; - *r++ = '\0'; - - return result; -} - -/* $"..." -- Translate the portion of STRING between START and END - according to current locale using gettext (if available) and return - the result. The caller will take care of leaving the quotes intact. - The string will be left without the leading `$' by the caller. - If translation is performed, the translated string will be double-quoted - by the caller. The length of the translated string is returned in LENP, - if non-null. */ -char * -locale_expand (string, start, end, lineno, lenp) - char *string; - int start, end, lineno, *lenp; -{ - int len, tlen, foundnl; - char *temp, *t, *t2; - - temp = (char *)xmalloc (end - start + 1); - for (tlen = 0, len = start; len < end; ) - temp[tlen++] = string[len++]; - temp[tlen] = '\0'; - - /* If we're just dumping translatable strings, don't do anything with the - string itself, but if we're dumping in `po' file format, convert it into - a form more palatable to gettext(3) and friends by quoting `"' and `\' - with backslashes and converting into `\n""'. If we find a - newline in TEMP, we first output a `msgid ""' line and then the - translated string; otherwise we output the `msgid' and translated - string all on one line. */ - if (dump_translatable_strings) - { - if (dump_po_strings) - { - foundnl = 0; - t = mk_msgstr (temp, &foundnl); - t2 = foundnl ? "\"\"\n" : ""; - - printf ("#: %s:%d\nmsgid %s%s\nmsgstr \"\"\n", - yy_input_name (), lineno, t2, t); - free (t); - } - else - printf ("\"%s\"\n", temp); - - if (lenp) - *lenp = tlen; - return (temp); - } - else if (*temp) - { - t = localetrans (temp, tlen, &len); - free (temp); - if (lenp) - *lenp = len; - return (t); - } - else - { - if (lenp) - *lenp = 0; - return (temp); - } -} -#endif - -/* Set every character in the character class to be a shell break - character for the lexical analyzer when the locale changes. */ -static void -locale_setblanks () -{ - int x; - - for (x = 0; x < sh_syntabsiz; x++) - { - if (isblank ((unsigned char)x)) - sh_syntaxtab[x] |= CSHBRK|CBLANK; - else if (member (x, shell_break_chars)) - { - sh_syntaxtab[x] |= CSHBRK; - sh_syntaxtab[x] &= ~CBLANK; - } - else - sh_syntaxtab[x] &= ~(CSHBRK|CBLANK); - } -} - -/* Parse a locale specification - language[_territory][.codeset][@modifier][+special][,[sponsor][_revision]] - and return TRUE if the codeset is UTF-8 or utf8 */ -static int -locale_isutf8 (lspec) - char *lspec; -{ - char *cp, *encoding; - -#if HAVE_LANGINFO_CODESET - cp = nl_langinfo (CODESET); - return (STREQ (cp, "UTF-8") || STREQ (cp, "utf8")); -#elif HAVE_LOCALE_CHARSET - cp = locale_charset (); - return (STREQ (cp, "UTF-8") || STREQ (cp, "utf8")); -#else - /* Take a shot */ - for (cp = lspec; *cp && *cp != '@' && *cp != '+' && *cp != ','; cp++) - { - if (*cp == '.') - { - for (encoding = ++cp; *cp && *cp != '@' && *cp != '+' && *cp != ','; cp++) - ; - /* The encoding (codeset) is the substring between encoding and cp */ - if ((cp - encoding == 5 && STREQN (encoding, "UTF-8", 5)) || - (cp - encoding == 4 && STREQN (encoding, "utf8", 4))) - return 1; - else - return 0; - } - } - return 0; -#endif -} - -#if defined (HAVE_LOCALECONV) -int -locale_decpoint () -{ - struct lconv *lv; - - lv = localeconv (); - return (lv && lv->decimal_point && lv->decimal_point[0]) ? lv->decimal_point[0] : '.'; -} -#else -# undef locale_decpoint -int -locale_decpoint () -{ - return '.'; -} -#endif diff --git a/third_party/bash/mailcheck.c b/third_party/bash/mailcheck.c deleted file mode 100644 index f5bfe8e1a..000000000 --- a/third_party/bash/mailcheck.c +++ /dev/null @@ -1,491 +0,0 @@ -/* mailcheck.c -- The check is in the mail... */ - -/* Copyright (C) 1987-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include -#include "bashtypes.h" -#include "posixstat.h" -#if defined (HAVE_SYS_PARAM_H) -# include -#endif -#if defined (HAVE_UNISTD_H) -# include -#endif -#include "posixtime.h" -#include "bashansi.h" -#include "bashintl.h" - -#include "shell.h" -#include "execute_cmd.h" -#include "mailcheck.h" -#include "tilde.h" - -/* Values for flags word in struct _fileinfo */ -#define MBOX_INITIALIZED 0x01 - -extern time_t shell_start_time; - -extern int mailstat PARAMS((const char *, struct stat *)); - -typedef struct _fileinfo { - char *name; - char *msg; - time_t access_time; - time_t mod_time; - off_t file_size; - int flags; -} FILEINFO; - -/* The list of remembered mail files. */ -static FILEINFO **mailfiles = (FILEINFO **)NULL; - -/* Number of mail files that we have. */ -static int mailfiles_count; - -/* The last known time that mail was checked. */ -static time_t last_time_mail_checked = 0; - -/* Non-zero means warn if a mail file has been read since last checked. */ -int mail_warning; - -static int find_mail_file PARAMS((char *)); -static void init_mail_file PARAMS((int)); -static void update_mail_file PARAMS((int)); -static int add_mail_file PARAMS((char *, char *)); - -static FILEINFO *alloc_mail_file PARAMS((char *, char *)); -static void dispose_mail_file PARAMS((FILEINFO *)); - -static int file_mod_date_changed PARAMS((int)); -static int file_access_date_changed PARAMS((int)); -static int file_has_grown PARAMS((int)); - -static char *parse_mailpath_spec PARAMS((char *)); - -/* Returns non-zero if it is time to check mail. */ -int -time_to_check_mail () -{ - char *temp; - time_t now; - intmax_t seconds; - - temp = get_string_value ("MAILCHECK"); - - /* Negative number, or non-numbers (such as empty string) cause no - checking to take place. */ - if (temp == 0 || legal_number (temp, &seconds) == 0 || seconds < 0) - return (0); - - now = NOW; - /* Time to check if MAILCHECK is explicitly set to zero, or if enough - time has passed since the last check. */ - return (seconds == 0 || ((now - last_time_mail_checked) >= seconds)); -} - -/* Okay, we have checked the mail. Perhaps I should make this function - go away. */ -void -reset_mail_timer () -{ - last_time_mail_checked = NOW; -} - -/* Locate a file in the list. Return index of - entry, or -1 if not found. */ -static int -find_mail_file (file) - char *file; -{ - register int i; - - for (i = 0; i < mailfiles_count; i++) - if (STREQ (mailfiles[i]->name, file)) - return i; - - return -1; -} - -#define RESET_MAIL_FILE(i) \ - do \ - { \ - mailfiles[i]->access_time = mailfiles[i]->mod_time = 0; \ - mailfiles[i]->file_size = 0; \ - mailfiles[i]->flags = 0; \ - } \ - while (0) - -#define UPDATE_MAIL_FILE(i, finfo) \ - do \ - { \ - mailfiles[i]->access_time = finfo.st_atime; \ - mailfiles[i]->mod_time = finfo.st_mtime; \ - mailfiles[i]->file_size = finfo.st_size; \ - mailfiles[i]->flags |= MBOX_INITIALIZED; \ - } \ - while (0) - -static void -init_mail_file (i) - int i; -{ - mailfiles[i]->access_time = mailfiles[i]->mod_time = last_time_mail_checked ? last_time_mail_checked : shell_start_time; - mailfiles[i]->file_size = 0; - mailfiles[i]->flags = 0; -} - -static void -update_mail_file (i) - int i; -{ - char *file; - struct stat finfo; - - file = mailfiles[i]->name; - if (mailstat (file, &finfo) == 0) - UPDATE_MAIL_FILE (i, finfo); - else - RESET_MAIL_FILE (i); -} - -/* Add this file to the list of remembered files and return its index - in the list of mail files. */ -static int -add_mail_file (file, msg) - char *file, *msg; -{ - struct stat finfo; - char *filename; - int i; - - filename = full_pathname (file); - i = find_mail_file (filename); - if (i >= 0) - { - if (mailstat (filename, &finfo) == 0) - UPDATE_MAIL_FILE (i, finfo); - - free (filename); - return i; - } - - i = mailfiles_count++; - mailfiles = (FILEINFO **)xrealloc - (mailfiles, mailfiles_count * sizeof (FILEINFO *)); - - mailfiles[i] = alloc_mail_file (filename, msg); - init_mail_file (i); - - return i; -} - -/* Reset the existing mail files access and modification times to zero. */ -void -reset_mail_files () -{ - register int i; - - for (i = 0; i < mailfiles_count; i++) - RESET_MAIL_FILE (i); -} - -static FILEINFO * -alloc_mail_file (filename, msg) - char *filename, *msg; -{ - FILEINFO *mf; - - mf = (FILEINFO *)xmalloc (sizeof (FILEINFO)); - mf->name = filename; - mf->msg = msg ? savestring (msg) : (char *)NULL; - mf->flags = 0; - - return mf; -} - -static void -dispose_mail_file (mf) - FILEINFO *mf; -{ - free (mf->name); - FREE (mf->msg); - free (mf); -} - -/* Free the information that we have about the remembered mail files. */ -void -free_mail_files () -{ - register int i; - - for (i = 0; i < mailfiles_count; i++) - dispose_mail_file (mailfiles[i]); - - if (mailfiles) - free (mailfiles); - - mailfiles_count = 0; - mailfiles = (FILEINFO **)NULL; -} - -void -init_mail_dates () -{ - if (mailfiles == 0) - remember_mail_dates (); -} - -/* Return non-zero if FILE's mod date has changed and it has not been - accessed since modified. If the size has dropped to zero, reset - the cached mail file info. */ -static int -file_mod_date_changed (i) - int i; -{ - time_t mtime; - struct stat finfo; - char *file; - - file = mailfiles[i]->name; - mtime = mailfiles[i]->mod_time; - - if (mailstat (file, &finfo) != 0) - return (0); - - if (finfo.st_size > 0) - return (mtime < finfo.st_mtime); - - if (finfo.st_size == 0 && mailfiles[i]->file_size > 0) - UPDATE_MAIL_FILE (i, finfo); - - return (0); -} - -/* Return non-zero if FILE's access date has changed. */ -static int -file_access_date_changed (i) - int i; -{ - time_t atime; - struct stat finfo; - char *file; - - file = mailfiles[i]->name; - atime = mailfiles[i]->access_time; - - if (mailstat (file, &finfo) != 0) - return (0); - - if (finfo.st_size > 0) - return (atime < finfo.st_atime); - - return (0); -} - -/* Return non-zero if FILE's size has increased. */ -static int -file_has_grown (i) - int i; -{ - off_t size; - struct stat finfo; - char *file; - - file = mailfiles[i]->name; - size = mailfiles[i]->file_size; - - return ((mailstat (file, &finfo) == 0) && (finfo.st_size > size)); -} - -/* Take an element from $MAILPATH and return the portion from - the first unquoted `?' or `%' to the end of the string. This is the - message to be printed when the file contents change. */ -static char * -parse_mailpath_spec (str) - char *str; -{ - char *s; - int pass_next; - - for (s = str, pass_next = 0; s && *s; s++) - { - if (pass_next) - { - pass_next = 0; - continue; - } - if (*s == '\\') - { - pass_next++; - continue; - } - if (*s == '?' || *s == '%') - return s; - } - return ((char *)NULL); -} - -char * -make_default_mailpath () -{ -#if defined (DEFAULT_MAIL_DIRECTORY) - char *mp; - - get_current_user_info (); - mp = (char *)xmalloc (2 + sizeof (DEFAULT_MAIL_DIRECTORY) + strlen (current_user.user_name)); - strcpy (mp, DEFAULT_MAIL_DIRECTORY); - mp[sizeof(DEFAULT_MAIL_DIRECTORY) - 1] = '/'; - strcpy (mp + sizeof (DEFAULT_MAIL_DIRECTORY), current_user.user_name); - return (mp); -#else - return ((char *)NULL); -#endif -} - -/* Remember the dates of the files specified by MAILPATH, or if there is - no MAILPATH, by the file specified in MAIL. If neither exists, use a - default value, which we randomly concoct from using Unix. */ - -void -remember_mail_dates () -{ - char *mailpaths; - char *mailfile, *mp; - int i = 0; - - mailpaths = get_string_value ("MAILPATH"); - - /* If no $MAILPATH, but $MAIL, use that as a single filename to check. */ - if (mailpaths == 0 && (mailpaths = get_string_value ("MAIL"))) - { - add_mail_file (mailpaths, (char *)NULL); - return; - } - - if (mailpaths == 0) - { - mailpaths = make_default_mailpath (); - if (mailpaths) - { - add_mail_file (mailpaths, (char *)NULL); - free (mailpaths); - } - return; - } - - while (mailfile = extract_colon_unit (mailpaths, &i)) - { - mp = parse_mailpath_spec (mailfile); - if (mp && *mp) - *mp++ = '\0'; - add_mail_file (mailfile, mp); - free (mailfile); - } -} - -/* check_mail () is useful for more than just checking mail. Since it has - the paranoids dream ability of telling you when someone has read your - mail, it can just as easily be used to tell you when someones .profile - file has been read, thus letting one know when someone else has logged - in. Pretty good, huh? */ - -/* Check for mail in some files. If the modification date of any - of the files in MAILPATH has changed since we last did a - remember_mail_dates () then mention that the user has mail. - Special hack: If the variable MAIL_WARNING is non-zero and the - mail file has been accessed since the last time we remembered, then - the message "The mail in has been read" is printed. */ -void -check_mail () -{ - char *current_mail_file, *message; - int i, use_user_notification; - char *dollar_underscore, *temp; - - dollar_underscore = get_string_value ("_"); - if (dollar_underscore) - dollar_underscore = savestring (dollar_underscore); - - for (i = 0; i < mailfiles_count; i++) - { - current_mail_file = mailfiles[i]->name; - - if (*current_mail_file == '\0') - continue; - - if (file_mod_date_changed (i)) - { - int file_is_bigger; - - use_user_notification = mailfiles[i]->msg != (char *)NULL; - message = mailfiles[i]->msg ? mailfiles[i]->msg : _("You have mail in $_"); - - bind_variable ("_", current_mail_file, 0); - -#define atime mailfiles[i]->access_time -#define mtime mailfiles[i]->mod_time - - /* Have to compute this before the call to update_mail_file, which - resets all the information. */ - file_is_bigger = file_has_grown (i); - - update_mail_file (i); - - /* If the user has just run a program which manipulates the - mail file, then don't bother explaining that the mail - file has been manipulated. Since some systems don't change - the access time to be equal to the modification time when - the mail in the file is manipulated, check the size also. If - the file has not grown, continue. */ - if ((atime >= mtime) && !file_is_bigger) - continue; - - /* If the mod time is later than the access time and the file - has grown, note the fact that this is *new* mail. */ - if (use_user_notification == 0 && (atime < mtime) && file_is_bigger) - message = _("You have new mail in $_"); -#undef atime -#undef mtime - - if (temp = expand_string_to_string (message, Q_DOUBLE_QUOTES)) - { - puts (temp); - free (temp); - } - else - putchar ('\n'); - } - - if (mail_warning && file_access_date_changed (i)) - { - update_mail_file (i); - printf (_("The mail in %s has been read\n"), current_mail_file); - } - } - - if (dollar_underscore) - { - bind_variable ("_", dollar_underscore, 0); - free (dollar_underscore); - } - else - unbind_variable ("_"); -} diff --git a/third_party/bash/mailcheck.h b/third_party/bash/mailcheck.h deleted file mode 100644 index e930124c3..000000000 --- a/third_party/bash/mailcheck.h +++ /dev/null @@ -1,34 +0,0 @@ -/* mailcheck.h -- variables and function declarations for mail checking. */ - -/* Copyright (C) 1987-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_MAILCHECK_H_) -#define _MAILCHECK_H_ - -/* Functions from mailcheck.c */ -extern int time_to_check_mail PARAMS((void)); -extern void reset_mail_timer PARAMS((void)); -extern void reset_mail_files PARAMS((void)); -extern void free_mail_files PARAMS((void)); -extern char *make_default_mailpath PARAMS((void)); -extern void remember_mail_dates PARAMS((void)); -extern void init_mail_dates PARAMS((void)); -extern void check_mail PARAMS((void)); - -#endif /* _MAILCHECK_H */ diff --git a/third_party/bash/mailstat.c b/third_party/bash/mailstat.c deleted file mode 100644 index ba971b205..000000000 --- a/third_party/bash/mailstat.c +++ /dev/null @@ -1,159 +0,0 @@ -/* mailstat.c -- stat a mailbox file, handling maildir-type mail directories */ - -/* Copyright (C) 2001 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include -#include - -#include "bashtypes.h" -#include "posixstat.h" -#include "posixdir.h" -#include "bashansi.h" - -#if defined (HAVE_SYS_PARAM_H) -# include -#endif - -#include "maxpath.h" - -/* - * Stat a file. If it's a maildir, check all messages - * in the maildir and present the grand total as a file. - * The fields in the 'struct stat' are from the mail directory. - * The following fields are emulated: - * - * st_nlink always 1, unless st_blocks is not present, in which case it's - * the total number of messages - * st_size total number of bytes in all files - * st_blocks total number of messages, if present in struct stat - * st_atime access time of newest file in maildir - * st_mtime modify time of newest file in maildir - * st_mode S_IFDIR changed to S_IFREG - * - * This is good enough for most mail-checking applications. - */ - -int -mailstat(path, st) - const char *path; - struct stat *st; -{ - static struct stat st_new_last, st_ret_last; - struct stat st_ret, st_tmp; - DIR *dd; - struct dirent *fn; - char dir[PATH_MAX * 2], file[PATH_MAX * 2 + 1]; - int i, l; - time_t atime, mtime; - - atime = mtime = 0; - - /* First see if it's a directory. */ - if ((i = stat(path, st)) != 0 || S_ISDIR(st->st_mode) == 0) - return i; - - if (strlen(path) > sizeof(dir) - 5) - { -#ifdef ENAMETOOLONG - errno = ENAMETOOLONG; -#else - errno = EINVAL; -#endif - return -1; - } - - st_ret = *st; - st_ret.st_nlink = 1; - st_ret.st_size = 0; -#ifdef HAVE_STRUCT_STAT_ST_BLOCKS - st_ret.st_blocks = 0; -#else - st_ret.st_nlink = 0; -#endif - st_ret.st_mode &= ~S_IFDIR; - st_ret.st_mode |= S_IFREG; - - /* See if cur/ is present */ - sprintf(dir, "%s/cur", path); - if (stat(dir, &st_tmp) || S_ISDIR(st_tmp.st_mode) == 0) - return 0; - st_ret.st_atime = st_tmp.st_atime; - - /* See if tmp/ is present */ - sprintf(dir, "%s/tmp", path); - if (stat(dir, &st_tmp) || S_ISDIR(st_tmp.st_mode) == 0) - return 0; - st_ret.st_mtime = st_tmp.st_mtime; - - /* And new/ */ - sprintf(dir, "%s/new", path); - if (stat(dir, &st_tmp) || S_ISDIR(st_tmp.st_mode) == 0) - return 0; - st_ret.st_mtime = st_tmp.st_mtime; - - /* Optimization - if new/ didn't change, nothing else did. */ - if (st_tmp.st_dev == st_new_last.st_dev && - st_tmp.st_ino == st_new_last.st_ino && - st_tmp.st_atime == st_new_last.st_atime && - st_tmp.st_mtime == st_new_last.st_mtime) - { - *st = st_ret_last; - return 0; - } - st_new_last = st_tmp; - - /* Loop over new/ and cur/ */ - for (i = 0; i < 2; i++) - { - sprintf(dir, "%s/%s", path, i ? "cur" : "new"); - sprintf(file, "%s/", dir); - l = strlen(file); - if ((dd = opendir(dir)) == NULL) - return 0; - while ((fn = readdir(dd)) != NULL) - { - if (fn->d_name[0] == '.' || strlen(fn->d_name) + l >= sizeof(file)) - continue; - strcpy(file + l, fn->d_name); - if (stat(file, &st_tmp) != 0) - continue; - st_ret.st_size += st_tmp.st_size; -#ifdef HAVE_STRUCT_STAT_ST_BLOCKS - st_ret.st_blocks++; -#else - st_ret.st_nlink++; -#endif - if (st_tmp.st_atime != st_tmp.st_mtime && st_tmp.st_atime > atime) - atime = st_tmp.st_atime; - if (st_tmp.st_mtime > mtime) - mtime = st_tmp.st_mtime; - } - closedir(dd); - } - -/* if (atime) */ /* Set atime even if cur/ is empty */ - st_ret.st_atime = atime; - if (mtime) - st_ret.st_mtime = mtime; - - *st = st_ret_last = st_ret; - return 0; -} diff --git a/third_party/bash/make_cmd.c b/third_party/bash/make_cmd.c deleted file mode 100644 index 98151a41a..000000000 --- a/third_party/bash/make_cmd.c +++ /dev/null @@ -1,907 +0,0 @@ -/* make_cmd.c -- Functions for making instances of the various - parser constructs. */ - -/* Copyright (C) 1989-2022 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include -#include "bashtypes.h" -#if !defined (_MINIX) && defined (HAVE_SYS_FILE_H) -# include -#endif -#include "filecntl.h" -#include "bashansi.h" -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "bashintl.h" - -#include "shell.h" -#include "execute_cmd.h" -#include "parser.h" -#include "flags.h" -#include "input.h" - -#if defined (JOB_CONTROL) -#include "jobs.h" -#endif - -#include "shmbutil.h" - -int here_doc_first_line = 0; - -/* Object caching */ -sh_obj_cache_t wdcache = {0, 0, 0}; -sh_obj_cache_t wlcache = {0, 0, 0}; - -#define WDCACHESIZE 128 -#define WLCACHESIZE 128 - -static COMMAND *make_for_or_select PARAMS((enum command_type, WORD_DESC *, WORD_LIST *, COMMAND *, int)); -#if defined (ARITH_FOR_COMMAND) -static WORD_LIST *make_arith_for_expr PARAMS((char *)); -#endif -static COMMAND *make_until_or_while PARAMS((enum command_type, COMMAND *, COMMAND *)); - -void -cmd_init () -{ - ocache_create (wdcache, WORD_DESC, WDCACHESIZE); - ocache_create (wlcache, WORD_LIST, WLCACHESIZE); -} - -WORD_DESC * -alloc_word_desc () -{ - WORD_DESC *temp; - - ocache_alloc (wdcache, WORD_DESC, temp); - temp->flags = 0; - temp->word = 0; - return temp; -} - -WORD_DESC * -make_bare_word (string) - const char *string; -{ - WORD_DESC *temp; - - temp = alloc_word_desc (); - - if (*string) - temp->word = savestring (string); - else - { - temp->word = (char *)xmalloc (1); - temp->word[0] = '\0'; - } - - return (temp); -} - -WORD_DESC * -make_word_flags (w, string) - WORD_DESC *w; - const char *string; -{ - register int i; - size_t slen; - DECLARE_MBSTATE; - - i = 0; - slen = strlen (string); - while (i < slen) - { - switch (string[i]) - { - case '$': - w->flags |= W_HASDOLLAR; - break; - case '\\': - break; /* continue the loop */ - case '\'': - case '`': - case '"': - w->flags |= W_QUOTED; - break; - } - - ADVANCE_CHAR (string, slen, i); - } - - return (w); -} - -WORD_DESC * -make_word (string) - const char *string; -{ - WORD_DESC *temp; - - temp = make_bare_word (string); - return (make_word_flags (temp, string)); -} - -WORD_DESC * -make_word_from_token (token) - int token; -{ - char tokenizer[2]; - - tokenizer[0] = token; - tokenizer[1] = '\0'; - - return (make_word (tokenizer)); -} - -WORD_LIST * -make_word_list (word, wlink) - WORD_DESC *word; - WORD_LIST *wlink; -{ - WORD_LIST *temp; - - ocache_alloc (wlcache, WORD_LIST, temp); - - temp->word = word; - temp->next = wlink; - return (temp); -} - -COMMAND * -make_command (type, pointer) - enum command_type type; - SIMPLE_COM *pointer; -{ - COMMAND *temp; - - temp = (COMMAND *)xmalloc (sizeof (COMMAND)); - temp->type = type; - temp->value.Simple = pointer; - temp->value.Simple->flags = temp->flags = 0; - temp->redirects = (REDIRECT *)NULL; - return (temp); -} - -COMMAND * -command_connect (com1, com2, connector) - COMMAND *com1, *com2; - int connector; -{ - CONNECTION *temp; - - temp = (CONNECTION *)xmalloc (sizeof (CONNECTION)); - temp->connector = connector; - temp->first = com1; - temp->second = com2; - return (make_command (cm_connection, (SIMPLE_COM *)temp)); -} - -static COMMAND * -make_for_or_select (type, name, map_list, action, lineno) - enum command_type type; - WORD_DESC *name; - WORD_LIST *map_list; - COMMAND *action; - int lineno; -{ - FOR_COM *temp; - - temp = (FOR_COM *)xmalloc (sizeof (FOR_COM)); - temp->flags = 0; - temp->name = name; - temp->line = lineno; - temp->map_list = map_list; - temp->action = action; - return (make_command (type, (SIMPLE_COM *)temp)); -} - -COMMAND * -make_for_command (name, map_list, action, lineno) - WORD_DESC *name; - WORD_LIST *map_list; - COMMAND *action; - int lineno; -{ - return (make_for_or_select (cm_for, name, map_list, action, lineno)); -} - -COMMAND * -make_select_command (name, map_list, action, lineno) - WORD_DESC *name; - WORD_LIST *map_list; - COMMAND *action; - int lineno; -{ -#if defined (SELECT_COMMAND) - return (make_for_or_select (cm_select, name, map_list, action, lineno)); -#else - set_exit_status (2); - return ((COMMAND *)NULL); -#endif -} - -#if defined (ARITH_FOR_COMMAND) -static WORD_LIST * -make_arith_for_expr (s) - char *s; -{ - WORD_LIST *result; - WORD_DESC *wd; - - if (s == 0 || *s == '\0') - return ((WORD_LIST *)NULL); - wd = make_word (s); - wd->flags |= W_NOGLOB|W_NOSPLIT|W_QUOTED|W_NOTILDE|W_NOPROCSUB; /* no word splitting or globbing */ - result = make_word_list (wd, (WORD_LIST *)NULL); - return result; -} -#endif - -/* Note that this function calls dispose_words on EXPRS, since it doesn't - use the word list directly. We free it here rather than at the caller - because no other function in this file requires that the caller free - any arguments. */ -COMMAND * -make_arith_for_command (exprs, action, lineno) - WORD_LIST *exprs; - COMMAND *action; - int lineno; -{ -#if defined (ARITH_FOR_COMMAND) - ARITH_FOR_COM *temp; - WORD_LIST *init, *test, *step; - char *s, *t, *start; - int nsemi, i; - - init = test = step = (WORD_LIST *)NULL; - /* Parse the string into the three component sub-expressions. */ - start = t = s = exprs->word->word; - for (nsemi = 0; ;) - { - /* skip whitespace at the start of each sub-expression. */ - while (whitespace (*s)) - s++; - start = s; - /* skip to the semicolon or EOS */ - i = skip_to_delim (start, 0, ";", SD_NOJMP|SD_NOPROCSUB); - s = start + i; - - t = (i > 0) ? substring (start, 0, i) : (char *)NULL; - - nsemi++; - switch (nsemi) - { - case 1: - init = make_arith_for_expr (t); - break; - case 2: - test = make_arith_for_expr (t); - break; - case 3: - step = make_arith_for_expr (t); - break; - } - - FREE (t); - if (*s == '\0') - break; - s++; /* skip over semicolon */ - } - - if (nsemi != 3) - { - if (nsemi < 3) - parser_error (lineno, _("syntax error: arithmetic expression required")); - else - parser_error (lineno, _("syntax error: `;' unexpected")); - parser_error (lineno, _("syntax error: `((%s))'"), exprs->word->word); - free (init); - free (test); - free (step); - set_exit_status (2); - return ((COMMAND *)NULL); - } - - temp = (ARITH_FOR_COM *)xmalloc (sizeof (ARITH_FOR_COM)); - temp->flags = 0; - temp->line = lineno; - temp->init = init ? init : make_arith_for_expr ("1"); - temp->test = test ? test : make_arith_for_expr ("1"); - temp->step = step ? step : make_arith_for_expr ("1"); - temp->action = action; - - dispose_words (exprs); - return (make_command (cm_arith_for, (SIMPLE_COM *)temp)); -#else - dispose_words (exprs); - set_exit_status (2); - return ((COMMAND *)NULL); -#endif /* ARITH_FOR_COMMAND */ -} - -COMMAND * -make_group_command (command) - COMMAND *command; -{ - GROUP_COM *temp; - - temp = (GROUP_COM *)xmalloc (sizeof (GROUP_COM)); - temp->command = command; - return (make_command (cm_group, (SIMPLE_COM *)temp)); -} - -COMMAND * -make_case_command (word, clauses, lineno) - WORD_DESC *word; - PATTERN_LIST *clauses; - int lineno; -{ - CASE_COM *temp; - - temp = (CASE_COM *)xmalloc (sizeof (CASE_COM)); - temp->flags = 0; - temp->line = lineno; - temp->word = word; - temp->clauses = REVERSE_LIST (clauses, PATTERN_LIST *); - return (make_command (cm_case, (SIMPLE_COM *)temp)); -} - -PATTERN_LIST * -make_pattern_list (patterns, action) - WORD_LIST *patterns; - COMMAND *action; -{ - PATTERN_LIST *temp; - - temp = (PATTERN_LIST *)xmalloc (sizeof (PATTERN_LIST)); - temp->patterns = REVERSE_LIST (patterns, WORD_LIST *); - temp->action = action; - temp->next = NULL; - temp->flags = 0; - return (temp); -} - -COMMAND * -make_if_command (test, true_case, false_case) - COMMAND *test, *true_case, *false_case; -{ - IF_COM *temp; - - temp = (IF_COM *)xmalloc (sizeof (IF_COM)); - temp->flags = 0; - temp->test = test; - temp->true_case = true_case; - temp->false_case = false_case; - return (make_command (cm_if, (SIMPLE_COM *)temp)); -} - -static COMMAND * -make_until_or_while (which, test, action) - enum command_type which; - COMMAND *test, *action; -{ - WHILE_COM *temp; - - temp = (WHILE_COM *)xmalloc (sizeof (WHILE_COM)); - temp->flags = 0; - temp->test = test; - temp->action = action; - return (make_command (which, (SIMPLE_COM *)temp)); -} - -COMMAND * -make_while_command (test, action) - COMMAND *test, *action; -{ - return (make_until_or_while (cm_while, test, action)); -} - -COMMAND * -make_until_command (test, action) - COMMAND *test, *action; -{ - return (make_until_or_while (cm_until, test, action)); -} - -COMMAND * -make_arith_command (exp) - WORD_LIST *exp; -{ -#if defined (DPAREN_ARITHMETIC) - COMMAND *command; - ARITH_COM *temp; - - command = (COMMAND *)xmalloc (sizeof (COMMAND)); - command->value.Arith = temp = (ARITH_COM *)xmalloc (sizeof (ARITH_COM)); - - temp->flags = 0; - temp->line = line_number; - temp->exp = exp; - - command->type = cm_arith; - command->redirects = (REDIRECT *)NULL; - command->flags = 0; - - return (command); -#else - set_exit_status (2); - return ((COMMAND *)NULL); -#endif -} - -#if defined (COND_COMMAND) -struct cond_com * -make_cond_node (type, op, left, right) - int type; - WORD_DESC *op; - struct cond_com *left, *right; -{ - COND_COM *temp; - - temp = (COND_COM *)xmalloc (sizeof (COND_COM)); - temp->flags = 0; - temp->line = line_number; - temp->type = type; - temp->op = op; - temp->left = left; - temp->right = right; - - return (temp); -} -#endif - -COMMAND * -make_cond_command (cond_node) - COND_COM *cond_node; -{ -#if defined (COND_COMMAND) - COMMAND *command; - - command = (COMMAND *)xmalloc (sizeof (COMMAND)); - command->value.Cond = cond_node; - - command->type = cm_cond; - command->redirects = (REDIRECT *)NULL; - command->flags = 0; - command->line = cond_node ? cond_node->line : 0; - - return (command); -#else - set_exit_status (2); - return ((COMMAND *)NULL); -#endif -} - -COMMAND * -make_bare_simple_command () -{ - COMMAND *command; - SIMPLE_COM *temp; - - command = (COMMAND *)xmalloc (sizeof (COMMAND)); - command->value.Simple = temp = (SIMPLE_COM *)xmalloc (sizeof (SIMPLE_COM)); - - temp->flags = 0; - temp->line = line_number; - temp->words = (WORD_LIST *)NULL; - temp->redirects = (REDIRECT *)NULL; - - command->type = cm_simple; - command->redirects = (REDIRECT *)NULL; - command->flags = 0; - - return (command); -} - -/* Return a command which is the connection of the word or redirection - in ELEMENT, and the command * or NULL in COMMAND. */ -COMMAND * -make_simple_command (element, command) - ELEMENT element; - COMMAND *command; -{ - /* If we are starting from scratch, then make the initial command - structure. Also note that we have to fill in all the slots, since - malloc doesn't return zeroed space. */ - if (command == 0) - { - command = make_bare_simple_command (); - parser_state |= PST_REDIRLIST; - } - - if (element.word) - { - command->value.Simple->words = make_word_list (element.word, command->value.Simple->words); - parser_state &= ~PST_REDIRLIST; - } - else if (element.redirect) - { - REDIRECT *r = element.redirect; - /* Due to the way <> is implemented, there may be more than a single - redirection in element.redirect. We just follow the chain as far - as it goes, and hook onto the end. */ - while (r->next) - r = r->next; - r->next = command->value.Simple->redirects; - command->value.Simple->redirects = element.redirect; - } - - return (command); -} - -/* Because we are Bourne compatible, we read the input for this - << or <<- redirection now, from wherever input is coming from. - We store the input read into a WORD_DESC. Replace the text of - the redirectee.word with the new input text. If <<- is on, - then remove leading TABS from each line. */ -void -make_here_document (temp, lineno) - REDIRECT *temp; - int lineno; -{ - int kill_leading, redir_len; - char *redir_word, *document, *full_line; - int document_index, document_size, delim_unquoted; - - if (temp->instruction != r_deblank_reading_until && - temp->instruction != r_reading_until) - { - internal_error (_("make_here_document: bad instruction type %d"), temp->instruction); - return; - } - - kill_leading = temp->instruction == r_deblank_reading_until; - - full_line = document = (char *)NULL; - document_index = document_size = 0; - - delim_unquoted = (temp->redirectee.filename->flags & W_QUOTED) == 0; - - /* Quote removal is the only expansion performed on the delimiter - for here documents, making it an extremely special case. */ - /* "If any part of word is quoted, the delimiter shall be formed by - performing quote removal on word." */ - if (delim_unquoted == 0) - redir_word = string_quote_removal (temp->redirectee.filename->word, 0); - else - redir_word = savestring (temp->redirectee.filename->word); - - /* redirection_expand will return NULL if the expansion results in - multiple words or no words. Check for that here, and just abort - this here document if it does. */ - if (redir_word) - redir_len = strlen (redir_word); - else - { - temp->here_doc_eof = (char *)xmalloc (1); - temp->here_doc_eof[0] = '\0'; - goto document_done; - } - - free (temp->redirectee.filename->word); - temp->here_doc_eof = redir_word; - - /* Read lines from wherever lines are coming from. - For each line read, if kill_leading, then kill the - leading tab characters. - If the line matches redir_word exactly, then we have - manufactured the document. Otherwise, add the line to the - list of lines in the document. */ - - /* If the here-document delimiter was quoted, the lines should - be read verbatim from the input. If it was not quoted, we - need to perform backslash-quoted newline removal. */ - while (full_line = read_secondary_line (delim_unquoted)) - { - register char *line; - int len; - - here_doc_first_line = 0; - line = full_line; - line_number++; - - /* If set -v is in effect, echo the line read. read_secondary_line/ - read_a_line leaves the newline at the end, so don't print another. */ - if (echo_input_at_read) - fprintf (stderr, "%s", line); - - if (kill_leading && *line) - { - /* Hack: To be compatible with some Bourne shells, we - check the word before stripping the whitespace. This - is a hack, though. */ - if (STREQN (line, redir_word, redir_len) && line[redir_len] == '\n') - break; - - while (*line == '\t') - line++; - } - - if (*line == 0) - continue; - - if (STREQN (line, redir_word, redir_len) && line[redir_len] == '\n') - break; - - /* Backwards compatibility here */ - if (STREQN (line, redir_word, redir_len) && (parser_state & PST_EOFTOKEN) && shell_eof_token && strchr (line+redir_len, shell_eof_token)) - { - shell_ungets (line + redir_len); - full_line = 0; - break; - } - - len = strlen (line); - if (len + document_index >= document_size) - { - document_size = document_size ? 2 * (document_size + len) : len + 2; - document = (char *)xrealloc (document, document_size); - } - - /* len is guaranteed to be > 0 because of the check for line - being an empty string before the call to strlen. */ - FASTCOPY (line, document + document_index, len); - document_index += len; - } - - if (full_line == 0) - internal_warning (_("here-document at line %d delimited by end-of-file (wanted `%s')"), lineno, redir_word); - -document_done: - if (document) - document[document_index] = '\0'; - else - { - document = (char *)xmalloc (1); - document[0] = '\0'; - } - temp->redirectee.filename->word = document; - here_doc_first_line = 0; -} - -/* Generate a REDIRECT from SOURCE, DEST, and INSTRUCTION. - INSTRUCTION is the instruction type, SOURCE is a file descriptor, - and DEST is a file descriptor or a WORD_DESC *. */ -REDIRECT * -make_redirection (source, instruction, dest_and_filename, flags) - REDIRECTEE source; - enum r_instruction instruction; - REDIRECTEE dest_and_filename; - int flags; -{ - REDIRECT *temp; - WORD_DESC *w; - int wlen; - intmax_t lfd; - - temp = (REDIRECT *)xmalloc (sizeof (REDIRECT)); - - /* First do the common cases. */ - temp->redirector = source; - temp->redirectee = dest_and_filename; - temp->here_doc_eof = 0; - temp->instruction = instruction; - temp->flags = 0; - temp->rflags = flags; - temp->next = (REDIRECT *)NULL; - - switch (instruction) - { - - case r_output_direction: /* >foo */ - case r_output_force: /* >| foo */ - case r_err_and_out: /* &>filename */ - temp->flags = O_TRUNC | O_WRONLY | O_CREAT; - break; - - case r_appending_to: /* >>foo */ - case r_append_err_and_out: /* &>> filename */ - temp->flags = O_APPEND | O_WRONLY | O_CREAT; - break; - - case r_input_direction: /* flags = O_RDONLY; - break; - - case r_input_output: /* <>foo */ - temp->flags = O_RDWR | O_CREAT; - break; - - case r_deblank_reading_until: /* <<-foo */ - case r_reading_until: /* << foo */ - case r_reading_string: /* <<< foo */ - case r_close_this: /* <&- */ - case r_duplicating_input: /* 1<&2 */ - case r_duplicating_output: /* 1>&2 */ - break; - - /* the parser doesn't pass these. */ - case r_move_input: /* 1<&2- */ - case r_move_output: /* 1>&2- */ - case r_move_input_word: /* 1<&$foo- */ - case r_move_output_word: /* 1>&$foo- */ - break; - - /* The way the lexer works we have to do this here. */ - case r_duplicating_input_word: /* 1<&$foo */ - case r_duplicating_output_word: /* 1>&$foo */ - w = dest_and_filename.filename; - wlen = strlen (w->word) - 1; - if (w->word[wlen] == '-') /* Yuck */ - { - w->word[wlen] = '\0'; - if (all_digits (w->word) && legal_number (w->word, &lfd) && lfd == (int)lfd) - { - dispose_word (w); - temp->instruction = (instruction == r_duplicating_input_word) ? r_move_input : r_move_output; - temp->redirectee.dest = lfd; - } - else - temp->instruction = (instruction == r_duplicating_input_word) ? r_move_input_word : r_move_output_word; - } - - break; - - default: - programming_error (_("make_redirection: redirection instruction `%d' out of range"), instruction); - abort (); - break; - } - return (temp); -} - -COMMAND * -make_function_def (name, command, lineno, lstart) - WORD_DESC *name; - COMMAND *command; - int lineno, lstart; -{ - FUNCTION_DEF *temp; -#if defined (ARRAY_VARS) - SHELL_VAR *bash_source_v; - ARRAY *bash_source_a; -#endif - - temp = (FUNCTION_DEF *)xmalloc (sizeof (FUNCTION_DEF)); - temp->command = command; - temp->name = name; - temp->line = lineno; - temp->flags = 0; - command->line = lstart; - - /* Information used primarily for debugging. */ - temp->source_file = 0; -#if defined (ARRAY_VARS) - GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a); - if (bash_source_a && array_num_elements (bash_source_a) > 0) - temp->source_file = array_reference (bash_source_a, 0); -#endif - /* Assume that shell functions without a source file before the shell is - initialized come from the environment. Otherwise default to "main" - (usually functions being defined interactively) */ - if (temp->source_file == 0) - temp->source_file = shell_initialized ? "main" : "environment"; - -#if defined (DEBUGGER) - bind_function_def (name->word, temp, 0); -#endif - - temp->source_file = temp->source_file ? savestring (temp->source_file) : 0; - - return (make_command (cm_function_def, (SIMPLE_COM *)temp)); -} - -COMMAND * -make_subshell_command (command) - COMMAND *command; -{ - SUBSHELL_COM *temp; - - temp = (SUBSHELL_COM *)xmalloc (sizeof (SUBSHELL_COM)); - temp->command = command; - temp->flags = CMD_WANT_SUBSHELL; - temp->line = line_number; - return (make_command (cm_subshell, (SIMPLE_COM *)temp)); -} - -COMMAND * -make_coproc_command (name, command) - char *name; - COMMAND *command; -{ - COPROC_COM *temp; - - temp = (COPROC_COM *)xmalloc (sizeof (COPROC_COM)); - temp->name = savestring (name); - temp->command = command; - temp->flags = CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL; - return (make_command (cm_coproc, (SIMPLE_COM *)temp)); -} - -/* Reverse the word list and redirection list in the simple command - has just been parsed. It seems simpler to do this here the one - time then by any other method that I can think of. */ -COMMAND * -clean_simple_command (command) - COMMAND *command; -{ - if (command->type != cm_simple) - command_error ("clean_simple_command", CMDERR_BADTYPE, command->type, 0); - else - { - command->value.Simple->words = - REVERSE_LIST (command->value.Simple->words, WORD_LIST *); - command->value.Simple->redirects = - REVERSE_LIST (command->value.Simple->redirects, REDIRECT *); - } - - parser_state &= ~PST_REDIRLIST; - return (command); -} - -/* The Yacc grammar productions have a problem, in that they take a - list followed by an ampersand (`&') and do a simple command connection, - making the entire list effectively asynchronous, instead of just - the last command. This means that when the list is executed, all - the commands have stdin set to /dev/null when job control is not - active, instead of just the last. This is wrong, and needs fixing - up. This function takes the `&' and applies it to the last command - in the list. This is done only for lists connected by `;'; it makes - `;' bind `tighter' than `&'. */ -COMMAND * -connect_async_list (command, command2, connector) - COMMAND *command, *command2; - int connector; -{ - COMMAND *t, *t1, *t2; - - t1 = command; - t = command->value.Connection->second; - - if (!t || (command->flags & CMD_WANT_SUBSHELL) || - command->value.Connection->connector != ';') - { - t = command_connect (command, command2, connector); - return t; - } - - /* This is just defensive programming. The Yacc precedence rules - will generally hand this function a command where t points directly - to the command we want (e.g. given a ; b ; c ; d &, t1 will point - to the `a ; b ; c' list and t will be the `d'). We only want to do - this if the list is not being executed as a unit in the background - with `( ... )', so we have to check for CMD_WANT_SUBSHELL. That's - the only way to tell. */ - while (((t->flags & CMD_WANT_SUBSHELL) == 0) && t->type == cm_connection && - t->value.Connection->connector == ';') - { - t1 = t; - t = t->value.Connection->second; - } - /* Now we have t pointing to the last command in the list, and - t1->value.Connection->second == t. */ - t2 = command_connect (t, command2, connector); - t1->value.Connection->second = t2; - return command; -} diff --git a/third_party/bash/make_cmd.h b/third_party/bash/make_cmd.h deleted file mode 100644 index bf1fb008d..000000000 --- a/third_party/bash/make_cmd.h +++ /dev/null @@ -1,72 +0,0 @@ -/* make_cmd.h -- Declarations of functions found in make_cmd.c */ - -/* Copyright (C) 1993-2009,2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_MAKE_CMD_H_) -#define _MAKE_CMD_H_ - -#include "stdc.h" - -extern int here_doc_first_line; - -extern void cmd_init PARAMS((void)); - -extern WORD_DESC *alloc_word_desc PARAMS((void)); -extern WORD_DESC *make_bare_word PARAMS((const char *)); -extern WORD_DESC *make_word_flags PARAMS((WORD_DESC *, const char *)); -extern WORD_DESC *make_word PARAMS((const char *)); -extern WORD_DESC *make_word_from_token PARAMS((int)); - -extern WORD_LIST *make_word_list PARAMS((WORD_DESC *, WORD_LIST *)); - -#define add_string_to_list(s, l) make_word_list (make_word(s), (l)) - -extern COMMAND *make_command PARAMS((enum command_type, SIMPLE_COM *)); -extern COMMAND *command_connect PARAMS((COMMAND *, COMMAND *, int)); -extern COMMAND *make_for_command PARAMS((WORD_DESC *, WORD_LIST *, COMMAND *, int)); -extern COMMAND *make_group_command PARAMS((COMMAND *)); -extern COMMAND *make_case_command PARAMS((WORD_DESC *, PATTERN_LIST *, int)); -extern PATTERN_LIST *make_pattern_list PARAMS((WORD_LIST *, COMMAND *)); -extern COMMAND *make_if_command PARAMS((COMMAND *, COMMAND *, COMMAND *)); -extern COMMAND *make_while_command PARAMS((COMMAND *, COMMAND *)); -extern COMMAND *make_until_command PARAMS((COMMAND *, COMMAND *)); -extern COMMAND *make_bare_simple_command PARAMS((void)); -extern COMMAND *make_simple_command PARAMS((ELEMENT, COMMAND *)); -extern void make_here_document PARAMS((REDIRECT *, int)); -extern REDIRECT *make_redirection PARAMS((REDIRECTEE, enum r_instruction, REDIRECTEE, int)); -extern COMMAND *make_function_def PARAMS((WORD_DESC *, COMMAND *, int, int)); -extern COMMAND *clean_simple_command PARAMS((COMMAND *)); - -extern COMMAND *make_arith_command PARAMS((WORD_LIST *)); - -extern COMMAND *make_select_command PARAMS((WORD_DESC *, WORD_LIST *, COMMAND *, int)); - -#if defined (COND_COMMAND) -extern COND_COM *make_cond_node PARAMS((int, WORD_DESC *, COND_COM *, COND_COM *)); -extern COMMAND *make_cond_command PARAMS((COND_COM *)); -#endif - -extern COMMAND *make_arith_for_command PARAMS((WORD_LIST *, COMMAND *, int)); - -extern COMMAND *make_subshell_command PARAMS((COMMAND *)); -extern COMMAND *make_coproc_command PARAMS((char *, COMMAND *)); - -extern COMMAND *connect_async_list PARAMS((COMMAND *, COMMAND *, int)); - -#endif /* !_MAKE_CMD_H */ diff --git a/third_party/bash/makepath.c b/third_party/bash/makepath.c deleted file mode 100644 index b0d661671..000000000 --- a/third_party/bash/makepath.c +++ /dev/null @@ -1,128 +0,0 @@ -/* makepath.c - glue PATH and DIR together into a full pathname. */ - -/* Copyright (C) 1987-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include "bashansi.h" -#include "shell.h" - -#include "tilde.h" - -#ifndef NULL -# define NULL 0 -#endif - -/* MAKE SURE THESE AGREE WITH ../../externs.h. */ - -#ifndef MP_DOTILDE -# define MP_DOTILDE 0x01 -# define MP_DOCWD 0x02 -# define MP_RMDOT 0x04 -# define MP_IGNDOT 0x08 -#endif - -extern char *get_working_directory PARAMS((char *)); - -static char *nullpath = ""; - -/* Take PATH, an element from, e.g., $CDPATH, and DIR, a directory name, - and paste them together into PATH/DIR. Tilde expansion is performed on - PATH if (flags & MP_DOTILDE) is non-zero. If PATH is NULL or the empty - string, it is converted to the current directory. A full pathname is - used if (flags & MP_DOCWD) is non-zero, otherwise `./' is used. If - (flags & MP_RMDOT) is non-zero, any `./' is removed from the beginning - of DIR. If (flags & MP_IGNDOT) is non-zero, a PATH that is "." or "./" - is ignored. */ - -#define MAKEDOT() \ - do { \ - xpath = (char *)xmalloc (2); \ - xpath[0] = '.'; \ - xpath[1] = '\0'; \ - pathlen = 1; \ - } while (0) - -char * -sh_makepath (path, dir, flags) - const char *path, *dir; - int flags; -{ - int dirlen, pathlen; - char *ret, *xpath, *xdir, *r, *s; - - if (path == 0 || *path == '\0') - { - if (flags & MP_DOCWD) - { - xpath = get_working_directory ("sh_makepath"); - if (xpath == 0) - { - ret = get_string_value ("PWD"); - if (ret) - xpath = savestring (ret); - } - if (xpath == 0) - MAKEDOT(); - else - pathlen = strlen (xpath); - } - else - MAKEDOT(); - } - else if ((flags & MP_IGNDOT) && path[0] == '.' && (path[1] == '\0' || - (path[1] == '/' && path[2] == '\0'))) - { - xpath = nullpath; - pathlen = 0; - } - else - { - xpath = ((flags & MP_DOTILDE) && *path == '~') ? bash_tilde_expand (path, 0) : (char *)path; - pathlen = strlen (xpath); - } - - xdir = (char *)dir; - dirlen = strlen (xdir); - if ((flags & MP_RMDOT) && dir[0] == '.' && dir[1] == '/') - { - xdir += 2; - dirlen -= 2; - } - - r = ret = (char *)xmalloc (2 + dirlen + pathlen); - s = xpath; - while (*s) - *r++ = *s++; - if (s > xpath && s[-1] != '/') - *r++ = '/'; - s = xdir; - while (*r++ = *s++) - ; - if (xpath != path && xpath != nullpath) - free (xpath); - return (ret); -} diff --git a/third_party/bash/maxpath.h b/third_party/bash/maxpath.h deleted file mode 100644 index db2e1fb42..000000000 --- a/third_party/bash/maxpath.h +++ /dev/null @@ -1,75 +0,0 @@ -/* maxpath.h - Find out what this system thinks PATH_MAX and NAME_MAX are. */ - -/* Copyright (C) 1993 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_MAXPATH_H_) -#define _MAXPATH_H_ - -/* These values are supposed to be in or one of the files - it includes. */ -#if defined (HAVE_LIMITS_H) -# include -#endif /* !HAVE_LIMITS_H */ - -/* If PATH_MAX is not defined, look for MAXPATHLEN */ -#if !defined (PATH_MAX) -# if defined (HAVE_SYS_PARAM_H) -# include -# define maxpath_param_h -# endif -# if defined (MAXPATHLEN) && !defined (PATH_MAX) -# define PATH_MAX MAXPATHLEN -# endif /* MAXPATHLEN && !PATH_MAX */ -#endif /* !PATH_MAX */ - -/* If NAME_MAX is not defined, look for MAXNAMLEN */ -#if !defined (NAME_MAX) -# if defined (HAVE_SYS_PARAM_H) && !defined (maxpath_param_h) -# include -# endif -# if defined (MAXNAMLEN) && !defined (NAME_MAX) -# define NAME_MAX MAXNAMLEN -# endif /* MAXNAMLEN && !NAME_MAX */ -#endif /* !NAME_MAX */ - -/* Default POSIX values */ -#if !defined (PATH_MAX) && defined (_POSIX_PATH_MAX) -# define PATH_MAX _POSIX_PATH_MAX -#endif - -#if !defined (NAME_MAX) && defined (_POSIX_NAME_MAX) -# define NAME_MAX _POSIX_NAME_MAX -#endif - - -/* Default values */ -#if !defined (PATH_MAX) -# define PATH_MAX 1024 -#endif - -#if !defined (NAME_MAX) -# define NAME_MAX 14 -#endif - -#if PATH_MAX < 1024 -# undef PATH_MAX -# define PATH_MAX 1024 -#endif - -#endif /* _MAXPATH_H_ */ diff --git a/third_party/bash/mbscasecmp.c b/third_party/bash/mbscasecmp.c deleted file mode 100644 index 6f65d79bd..000000000 --- a/third_party/bash/mbscasecmp.c +++ /dev/null @@ -1,79 +0,0 @@ -/* mbscasecmp - case-insensitive multibyte string comparison. */ - -/* Copyright (C) 2009-2015 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if !defined (HAVE_MBSCASECMP) && defined (HANDLE_MULTIBYTE) - -#include -#include -#include - -#include -#include - -/* Compare MBS1 and MBS2 without regard to case. */ -int -mbscasecmp (mbs1, mbs2) - const char *mbs1; - const char *mbs2; -{ - int len1, len2, mb_cur_max; - wchar_t c1, c2, l1, l2; - - len1 = len2 = 0; - /* Reset multibyte characters to their initial state. */ - (void) mblen ((char *) NULL, 0); - - mb_cur_max = MB_CUR_MAX; - do - { - len1 = mbtowc (&c1, mbs1, mb_cur_max); - len2 = mbtowc (&c2, mbs2, mb_cur_max); - - if (len1 == 0) - return len2 == 0 ? 0 : -1; - else if (len2 == 0) - return 1; - else if (len1 > 0 && len2 < 0) - return -1; - else if (len1 < 0 && len2 > 0) - return 1; - else if (len1 < 0 && len2 < 0) - { - len1 = strlen (mbs1); - len2 = strlen (mbs2); - return (len1 == len2 ? memcmp (mbs1, mbs2, len1) - : ((len1 < len2) ? (memcmp (mbs1, mbs2, len1) > 0 ? 1 : -1) - : (memcmp (mbs1, mbs2, len2) >= 0 ? 1 : -1))); - } - - l1 = towlower (c1); - l2 = towlower (c2); - - mbs1 += len1; - mbs2 += len2; - } - while (l1 == l2); - - return l1 - l2; -} - -#endif diff --git a/third_party/bash/mbschr.c b/third_party/bash/mbschr.c deleted file mode 100644 index dced76089..000000000 --- a/third_party/bash/mbschr.c +++ /dev/null @@ -1,91 +0,0 @@ -/* mbschr.c - strchr(3) that handles multibyte characters. */ - -/* Copyright (C) 2002 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#ifdef HAVE_STDLIB_H -# include -#endif - -#include "bashansi.h" -#include "shmbutil.h" - -extern int locale_mb_cur_max; -extern int locale_utf8locale; - -#undef mbschr - -extern char *utf8_mbschr (const char *, int); /* XXX */ - -/* In some locales, the non-first byte of some multibyte characters have - the same value as some ascii character. Faced with these strings, a - legacy strchr() might return the wrong value. */ - -char * -#if defined (PROTOTYPES) -mbschr (const char *s, int c) -#else -mbschr (s, c) - const char *s; - int c; -#endif -{ -#if HANDLE_MULTIBYTE - char *pos; - mbstate_t state; - size_t strlength, mblength; - - if (locale_utf8locale && c < 0x80) - return (utf8_mbschr (s, c)); /* XXX */ - - /* The locale encodings with said weird property are BIG5, BIG5-HKSCS, - GBK, GB18030, SHIFT_JIS, and JOHAB. They exhibit the problem only - when c >= 0x30. We can therefore use the faster bytewise search if - c <= 0x30. */ - if ((unsigned char)c >= '0' && locale_mb_cur_max > 1) - { - pos = (char *)s; - memset (&state, '\0', sizeof(mbstate_t)); - strlength = strlen (s); - - while (strlength > 0) - { - if (is_basic (*pos)) - mblength = 1; - else - { - mblength = mbrlen (pos, strlength, &state); - if (mblength == (size_t)-2 || mblength == (size_t)-1 || mblength == (size_t)0) - mblength = 1; - } - - if (mblength == 1 && c == (unsigned char)*pos) - return pos; - - strlength -= mblength; - pos += mblength; - } - - return ((char *)NULL); - } - else -#endif - return (strchr (s, c)); -} diff --git a/third_party/bash/mbscmp.c b/third_party/bash/mbscmp.c deleted file mode 100644 index 9be01378a..000000000 --- a/third_party/bash/mbscmp.c +++ /dev/null @@ -1,77 +0,0 @@ -/* mbscmp - multibyte string comparison. */ - -/* Copyright (C) 1995-2018 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if !defined (HAVE_MBSCMP) && defined (HANDLE_MULTIBYTE) - -#include -#include -#include - -extern int locale_utf8locale; - -extern int utf8_mbscmp (const char *, const char *); - -/* Compare MBS1 and MBS2. */ -int -mbscmp (mbs1, mbs2) - const char *mbs1; - const char *mbs2; -{ - int len1, len2, mb_cur_max; - wchar_t c1, c2; - - len1 = len2 = 0; - /* Reset multibyte characters to their initial state. */ - (void) mblen ((char *) NULL, 0); - - mb_cur_max = MB_CUR_MAX; - do - { - len1 = mbtowc (&c1, mbs1, mb_cur_max); - len2 = mbtowc (&c2, mbs2, mb_cur_max); - - if (len1 == 0) - return len2 == 0 ? 0 : -1; - else if (len2 == 0) - return 1; - else if (len1 > 0 && len2 < 0) - return -1; - else if (len1 < 0 && len2 > 0) - return 1; - else if (len1 < 0 && len2 < 0) - { - len1 = strlen (mbs1); - len2 = strlen (mbs2); - return (len1 == len2 ? memcmp (mbs1, mbs2, len1) - : ((len1 < len2) ? (memcmp (mbs1, mbs2, len1) > 0 ? 1 : -1) - : (memcmp (mbs1, mbs2, len2) >= 0 ? 1 : -1))); - } - - mbs1 += len1; - mbs2 += len2; - } - while (c1 == c2); - - return c1 - c2; -} - -#endif diff --git a/third_party/bash/memalloc.h b/third_party/bash/memalloc.h deleted file mode 100644 index 57318b9d3..000000000 --- a/third_party/bash/memalloc.h +++ /dev/null @@ -1,62 +0,0 @@ -/* memalloc.h -- consolidate code for including alloca.h or malloc.h and - defining alloca. */ - -/* Copyright (C) 1993 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_MEMALLOC_H_) -# define _MEMALLOC_H_ - -#if defined (sparc) && defined (sun) && !defined (HAVE_ALLOCA_H) -# define HAVE_ALLOCA_H -#endif - -#if defined (__GNUC__) && !defined (HAVE_ALLOCA) -# define HAVE_ALLOCA -#endif - -#if defined (HAVE_ALLOCA_H) && !defined (HAVE_ALLOCA) && !defined (C_ALLOCA) -# define HAVE_ALLOCA -#endif /* HAVE_ALLOCA_H && !HAVE_ALLOCA */ - -#if defined (__GNUC__) && !defined (C_ALLOCA) -# undef alloca -# define alloca __builtin_alloca -#else /* !__GNUC__ || C_ALLOCA */ -# if defined (HAVE_ALLOCA_H) && !defined (C_ALLOCA) -# if defined (IBMESA) -# include -# else /* !IBMESA */ -# include -# endif /* !IBMESA */ -# else /* !HAVE_ALLOCA_H || C_ALLOCA */ -# if defined (__hpux) && defined (__STDC__) && !defined (alloca) -extern void *alloca (); -# else -# if !defined (alloca) -# if defined (__STDC__) -extern void *alloca (size_t); -# else -extern char *alloca (); -# endif /* !__STDC__ */ -# endif /* !alloca */ -# endif /* !__hpux || !__STDC__ && !alloca */ -# endif /* !HAVE_ALLOCA_H || C_ALLOCA */ -#endif /* !__GNUC__ || C_ALLOCA */ - -#endif /* _MEMALLOC_H_ */ diff --git a/third_party/bash/ndir.h b/third_party/bash/ndir.h deleted file mode 100644 index 0aeb3a58c..000000000 --- a/third_party/bash/ndir.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -- definitions for 4.2BSD-compatible directory access. - last edit: 09-Jul-1983 D A Gwyn. */ - -/* Size of directory block. */ -#define DIRBLKSIZ 512 - -/* NOTE: MAXNAMLEN must be one less than a multiple of 4 */ - -#if defined (VMS) -# define MAXNAMLEN (DIR$S_NAME + 7) /* 80 plus room for version #. */ -# define MAXFULLSPEC NAM$C_MAXRSS /* Maximum full spec */ -#else -# define MAXNAMLEN 15 /* Maximum filename length. */ -#endif /* VMS */ - -/* Data from readdir (). */ -struct direct { - long d_ino; /* Inode number of entry. */ - unsigned short d_reclen; /* Length of this record. */ - unsigned short d_namlen; /* Length of string in d_name. */ - char d_name[MAXNAMLEN + 1]; /* Name of file. */ -}; - -/* Stream data from opendir (). */ -typedef struct { - int dd_fd; /* File descriptor. */ - int dd_loc; /* Offset in block. */ - int dd_size; /* Amount of valid data. */ - char dd_buf[DIRBLKSIZ]; /* Directory block. */ -} DIR; - -extern DIR *opendir (); -extern struct direct *readdir (); -extern long telldir (); -extern void seekdir (), closedir (); - -#define rewinddir(dirp) seekdir (dirp, 0L) diff --git a/third_party/bash/netconn.c b/third_party/bash/netconn.c deleted file mode 100644 index a5fc381c1..000000000 --- a/third_party/bash/netconn.c +++ /dev/null @@ -1,82 +0,0 @@ -/* netconn.c -- is a particular file descriptor a network connection?. */ - -/* Copyright (C) 2002-2005 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include "bashtypes.h" -#if ! defined(_MINIX) && defined (HAVE_SYS_FILE_H) -# include -#endif -#include "posixstat.h" -#include "filecntl.h" - -#include - -#if defined (HAVE_UNISTD_H) -# include -#endif - -/* The second and subsequent conditions must match those used to decide - whether or not to call getpeername() in isnetconn(). */ -#if defined (HAVE_SYS_SOCKET_H) && defined (HAVE_GETPEERNAME) && !defined (SVR4_2) -# include -#endif - -/* Is FD a socket or network connection? */ -int -isnetconn (fd) - int fd; -{ -#if defined (HAVE_SYS_SOCKET_H) && defined (HAVE_GETPEERNAME) && !defined (SVR4_2) && !defined (__BEOS__) - int rv; - socklen_t l; - struct sockaddr sa; - - l = sizeof(sa); - rv = getpeername(fd, &sa, &l); - /* Posix.2 says getpeername can return these errors. */ - return ((rv < 0 && (errno == ENOTSOCK || errno == ENOTCONN || errno == EINVAL || errno == EBADF)) ? 0 : 1); -#else /* !HAVE_GETPEERNAME || SVR4_2 || __BEOS__ */ -# if defined (SVR4) || defined (SVR4_2) - /* Sockets on SVR4 and SVR4.2 are character special (streams) devices. */ - struct stat sb; - - if (isatty (fd)) - return (0); - if (fstat (fd, &sb) < 0) - return (0); -# if defined (S_ISFIFO) - if (S_ISFIFO (sb.st_mode)) - return (0); -# endif /* S_ISFIFO */ - return (S_ISCHR (sb.st_mode)); -# else /* !SVR4 && !SVR4_2 */ -# if defined (S_ISSOCK) && !defined (__BEOS__) - struct stat sb; - - if (fstat (fd, &sb) < 0) - return (0); - return (S_ISSOCK (sb.st_mode)); -# else /* !S_ISSOCK || __BEOS__ */ - return (0); -# endif /* !S_ISSOCK || __BEOS__ */ -# endif /* !SVR4 && !SVR4_2 */ -#endif /* !HAVE_GETPEERNAME || SVR4_2 || __BEOS__ */ -} diff --git a/third_party/bash/netopen.c b/third_party/bash/netopen.c deleted file mode 100644 index a2fd760d4..000000000 --- a/third_party/bash/netopen.c +++ /dev/null @@ -1,351 +0,0 @@ -/* - * netopen.c -- functions to make tcp/udp connections - * - * Chet Ramey - * chet@ins.CWRU.Edu - */ - -/* Copyright (C) 1987-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if defined (HAVE_NETWORK) - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include -#include - -#if defined (HAVE_SYS_SOCKET_H) -# include -#endif - -#if defined (HAVE_NETINET_IN_H) -# include -#endif - -#if defined (HAVE_NETDB_H) -# include -#endif - -#if defined (HAVE_ARPA_INET_H) -# include -#endif - -#include "bashansi.h" -#include "bashintl.h" - -#include - -#include "shell.h" -#include "xmalloc.h" - -#ifndef errno -extern int errno; -#endif - -#if !defined (HAVE_INET_ATON) -extern int inet_aton PARAMS((const char *, struct in_addr *)); -#endif - -#ifndef HAVE_GETADDRINFO -static int _getaddr PARAMS((char *, struct in_addr *)); -static int _getserv PARAMS((char *, int, unsigned short *)); -static int _netopen4 PARAMS((char *, char *, int)); -#else /* HAVE_GETADDRINFO */ -static int _netopen6 PARAMS((char *, char *, int)); -#endif - -static int _netopen PARAMS((char *, char *, int)); - -#ifndef HAVE_GETADDRINFO -/* Stuff the internet address corresponding to HOST into AP, in network - byte order. Return 1 on success, 0 on failure. */ - -static int -_getaddr (host, ap) - char *host; - struct in_addr *ap; -{ - struct hostent *h; - int r; - - r = 0; - if (host[0] >= '0' && host[0] <= '9') - { - /* If the first character is a digit, guess that it's an - Internet address and return immediately if inet_aton succeeds. */ - r = inet_aton (host, ap); - if (r) - return r; - } -#if !defined (HAVE_GETHOSTBYNAME) - return 0; -#else - h = gethostbyname (host); - if (h && h->h_addr) - { - bcopy(h->h_addr, (char *)ap, h->h_length); - return 1; - } -#endif - return 0; - -} - -/* Return 1 if SERV is a valid port number and stuff the converted value into - PP in network byte order. */ -static int -_getserv (serv, proto, pp) - char *serv; - int proto; - unsigned short *pp; -{ - intmax_t l; - unsigned short s; - - if (legal_number (serv, &l)) - { - s = (unsigned short)(l & 0xFFFF); - if (s != l) - return (0); - s = htons (s); - if (pp) - *pp = s; - return 1; - } - else -#if defined (HAVE_GETSERVBYNAME) - { - struct servent *se; - - se = getservbyname (serv, (proto == 't') ? "tcp" : "udp"); - if (se == 0) - return 0; - if (pp) - *pp = se->s_port; /* ports returned in network byte order */ - return 1; - } -#else /* !HAVE_GETSERVBYNAME */ - return 0; -#endif /* !HAVE_GETSERVBYNAME */ -} - -/* - * Open a TCP or UDP connection to HOST on port SERV. Uses the - * traditional BSD mechanisms. Returns the connected socket or -1 on error. - */ -static int -_netopen4(host, serv, typ) - char *host, *serv; - int typ; -{ - struct in_addr ina; - struct sockaddr_in sin; - unsigned short p; - int s, e; - - if (_getaddr(host, &ina) == 0) - { - internal_error (_("%s: host unknown"), host); - errno = EINVAL; - return -1; - } - - if (_getserv(serv, typ, &p) == 0) - { - internal_error(_("%s: invalid service"), serv); - errno = EINVAL; - return -1; - } - - memset ((char *)&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - sin.sin_port = p; - sin.sin_addr = ina; - - s = socket(AF_INET, (typ == 't') ? SOCK_STREAM : SOCK_DGRAM, 0); - if (s < 0) - { - sys_error ("socket"); - return (-1); - } - - if (connect (s, (struct sockaddr *)&sin, sizeof (sin)) < 0) - { - e = errno; - sys_error("connect"); - close(s); - errno = e; - return (-1); - } - - return(s); -} -#endif /* ! HAVE_GETADDRINFO */ - -#ifdef HAVE_GETADDRINFO -/* - * Open a TCP or UDP connection to HOST on port SERV. Uses getaddrinfo(3) - * which provides support for IPv6. Returns the connected socket or -1 - * on error. - */ -static int -_netopen6 (host, serv, typ) - char *host, *serv; - int typ; -{ - int s, e; - struct addrinfo hints, *res, *res0; - int gerr; - - memset ((char *)&hints, 0, sizeof (hints)); - /* XXX -- if problems with IPv6, set to PF_INET for IPv4 only */ -#ifdef DEBUG /* PF_INET is the one that works for me */ - hints.ai_family = PF_INET; -#else - hints.ai_family = PF_UNSPEC; -#endif - hints.ai_socktype = (typ == 't') ? SOCK_STREAM : SOCK_DGRAM; - - gerr = getaddrinfo (host, serv, &hints, &res0); - if (gerr) - { - if (gerr == EAI_SERVICE) - internal_error ("%s: %s", serv, gai_strerror (gerr)); - else - internal_error ("%s: %s", host, gai_strerror (gerr)); - errno = EINVAL; - return -1; - } - - for (res = res0; res; res = res->ai_next) - { - if ((s = socket (res->ai_family, res->ai_socktype, res->ai_protocol)) < 0) - { - if (res->ai_next) - continue; - sys_error ("socket"); - freeaddrinfo (res0); - return -1; - } - if (connect (s, res->ai_addr, res->ai_addrlen) < 0) - { - if (res->ai_next) - { - close (s); - continue; - } - e = errno; - sys_error ("connect"); - close (s); - freeaddrinfo (res0); - errno = e; - return -1; - } - freeaddrinfo (res0); - break; - } - return s; -} -#endif /* HAVE_GETADDRINFO */ - -/* - * Open a TCP or UDP connection to HOST on port SERV. Uses getaddrinfo(3) - * if available, falling back to the traditional BSD mechanisms otherwise. - * Returns the connected socket or -1 on error. - */ -static int -_netopen(host, serv, typ) - char *host, *serv; - int typ; -{ -#ifdef HAVE_GETADDRINFO - return (_netopen6 (host, serv, typ)); -#else - return (_netopen4 (host, serv, typ)); -#endif -} - -/* - * Open a TCP or UDP connection given a path like `/dev/tcp/host/port' to - * host `host' on port `port' and return the connected socket. - */ -int -netopen (path) - char *path; -{ - char *np, *s, *t; - int fd; - - np = (char *)xmalloc (strlen (path) + 1); - strcpy (np, path); - - s = np + 9; - t = strchr (s, '/'); - if (t == 0) - { - internal_error (_("%s: bad network path specification"), path); - free (np); - return -1; - } - *t++ = '\0'; - fd = _netopen (s, t, path[5]); - free (np); - - return fd; -} - -#if 0 -/* - * Open a TCP connection to host `host' on the port defined for service - * `serv' and return the connected socket. - */ -int -tcpopen (host, serv) - char *host, *serv; -{ - return (_netopen (host, serv, 't')); -} - -/* - * Open a UDP connection to host `host' on the port defined for service - * `serv' and return the connected socket. - */ -int -udpopen (host, serv) - char *host, *serv; -{ - return _netopen (host, serv, 'u'); -} -#endif - -#else /* !HAVE_NETWORK */ - -int -netopen (path) - char *path; -{ - internal_error (_("network operations not supported")); - return -1; -} - -#endif /* !HAVE_NETWORK */ diff --git a/third_party/bash/ocache.h b/third_party/bash/ocache.h deleted file mode 100644 index c596c2725..000000000 --- a/third_party/bash/ocache.h +++ /dev/null @@ -1,133 +0,0 @@ -/* ocache.h -- a minimal object caching implementation. */ - -/* Copyright (C) 2002 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_OCACHE_H_) -#define _OCACHE_H_ 1 - -#ifndef PTR_T - -#if defined (__STDC__) -# define PTR_T void * -#else -# define PTR_T char * -#endif - -#endif /* PTR_T */ - -#define OC_MEMSET(memp, xch, nbytes) \ -do { \ - if ((nbytes) <= 32) { \ - register char * mzp = (char *)(memp); \ - unsigned long mctmp = (nbytes); \ - register long mcn; \ - if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp &= 7; } \ - switch (mctmp) { \ - case 0: for(;;) { *mzp++ = xch; \ - case 7: *mzp++ = xch; \ - case 6: *mzp++ = xch; \ - case 5: *mzp++ = xch; \ - case 4: *mzp++ = xch; \ - case 3: *mzp++ = xch; \ - case 2: *mzp++ = xch; \ - case 1: *mzp++ = xch; if(mcn <= 0) break; mcn--; } \ - } \ - } else \ - memset ((memp), (xch), (nbytes)); \ -} while(0) - -typedef struct objcache { - PTR_T data; - int cs; /* cache size, number of objects */ - int nc; /* number of cache entries */ -} sh_obj_cache_t; - -/* Create an object cache C of N pointers to OTYPE. */ -#define ocache_create(c, otype, n) \ - do { \ - (c).data = xmalloc((n) * sizeof (otype *)); \ - (c).cs = (n); \ - (c).nc = 0; \ - } while (0) - -/* Destroy an object cache C. */ -#define ocache_destroy(c) \ - do { \ - if ((c).data) \ - xfree ((c).data); \ - (c).data = 0; \ - (c).cs = (c).nc = 0; \ - } while (0) - -/* Free all cached items, which are pointers to OTYPE, in object cache C. */ -#define ocache_flush(c, otype) \ - do { \ - while ((c).nc > 0) \ - xfree (((otype **)((c).data))[--(c).nc]); \ - } while (0) - -/* - * Allocate a new item of type pointer to OTYPE, using data from object - * cache C if any cached items exist, otherwise calling xmalloc. Return - * the object in R. - */ -#define ocache_alloc(c, otype, r) \ - do { \ - if ((c).nc > 0) { \ - (r) = (otype *)((otype **)((c).data))[--(c).nc]; \ - } else \ - (r) = (otype *)xmalloc (sizeof (otype)); \ - } while (0) - -/* - * Free an item R of type pointer to OTYPE, adding to object cache C if - * there is room and calling xfree if the cache is full. If R is added - * to the object cache, the contents are scrambled. - */ -#define ocache_free(c, otype, r) \ - do { \ - if ((c).nc < (c).cs) { \ - OC_MEMSET ((r), 0xdf, sizeof(otype)); \ - ((otype **)((c).data))[(c).nc++] = (r); \ - } else \ - xfree (r); \ - } while (0) - -/* - * One may declare and use an object cache as (for instance): - * - * sh_obj_cache_t wdcache = {0, 0, 0}; - * sh_obj_cache_t wlcache = {0, 0, 0}; - * - * ocache_create(wdcache, WORD_DESC, 30); - * ocache_create(wlcache, WORD_LIST, 30); - * - * WORD_DESC *wd; - * ocache_alloc (wdcache, WORD_DESC, wd); - * - * WORD_LIST *wl; - * ocache_alloc (wlcache, WORD_LIST, wl); - * - * ocache_free(wdcache, WORD_DESC, wd); - * ocache_free(wlcache, WORD_LIST, wl); - * - * The use is almost arbitrary. - */ - -#endif /* _OCACHE_H */ diff --git a/third_party/bash/oslib.c b/third_party/bash/oslib.c deleted file mode 100644 index ab284cb5f..000000000 --- a/third_party/bash/oslib.c +++ /dev/null @@ -1,159 +0,0 @@ -/* oslib.c - functions present only in some unix versions. */ - -/* Copyright (C) 1995,2010 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include "bashtypes.h" -#if defined (HAVE_SYS_PARAM_H) -# include -#endif - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#if defined (HAVE_LIMITS_H) -# include -#endif - -#include "posixstat.h" -#include "filecntl.h" -#include "bashansi.h" - -#if !defined (HAVE_KILLPG) -# include -#endif - -#include -#include -#include "chartypes.h" - -#include "shell.h" - -#if !defined (errno) -extern int errno; -#endif /* !errno */ - -/* - * Return the total number of available file descriptors. - * - * On some systems, like 4.2BSD and its descendants, there is a system call - * that returns the size of the descriptor table: getdtablesize(). There are - * lots of ways to emulate this on non-BSD systems. - * - * On System V.3, this can be obtained via a call to ulimit: - * return (ulimit(4, 0L)); - * - * On other System V systems, NOFILE is defined in /usr/include/sys/param.h - * (this is what we assume below), so we can simply use it: - * return (NOFILE); - * - * On POSIX systems, there are specific functions for retrieving various - * configuration parameters: - * return (sysconf(_SC_OPEN_MAX)); - * - */ - -#if !defined (HAVE_GETDTABLESIZE) -int -getdtablesize () -{ -# if defined (_POSIX_VERSION) && defined (HAVE_SYSCONF) && defined (_SC_OPEN_MAX) - return (sysconf(_SC_OPEN_MAX)); /* Posix systems use sysconf */ -# else /* ! (_POSIX_VERSION && HAVE_SYSCONF && _SC_OPEN_MAX) */ -# if defined (ULIMIT_MAXFDS) - return (ulimit (4, 0L)); /* System V.3 systems use ulimit(4, 0L) */ -# else /* !ULIMIT_MAXFDS */ -# if defined (NOFILE) /* Other systems use NOFILE */ - return (NOFILE); -# else /* !NOFILE */ - return (20); /* XXX - traditional value is 20 */ -# endif /* !NOFILE */ -# endif /* !ULIMIT_MAXFDS */ -# endif /* ! (_POSIX_VERSION && _SC_OPEN_MAX) */ -} -#endif /* !HAVE_GETDTABLESIZE */ - -#if !defined (HAVE_MKFIFO) && defined (PROCESS_SUBSTITUTION) -int -mkfifo (path, mode) - char *path; - mode_t mode; -{ -#if 0 && defined (S_IFIFO) // [jart] cosmo local change - return (mknod (path, (mode | S_IFIFO), 0)); -#else /* !S_IFIFO */ - return (-1); -#endif /* !S_IFIFO */ -} -#endif /* !HAVE_MKFIFO && PROCESS_SUBSTITUTION */ - -#define DEFAULT_MAXGROUPS 64 - -int -getmaxgroups () -{ - static int maxgroups = -1; - - if (maxgroups > 0) - return maxgroups; - -#if defined (HAVE_SYSCONF) && defined (_SC_NGROUPS_MAX) - maxgroups = sysconf (_SC_NGROUPS_MAX); -#else -# if defined (NGROUPS_MAX) - maxgroups = NGROUPS_MAX; -# else /* !NGROUPS_MAX */ -# if defined (NGROUPS) - maxgroups = NGROUPS; -# else /* !NGROUPS */ - maxgroups = DEFAULT_MAXGROUPS; -# endif /* !NGROUPS */ -# endif /* !NGROUPS_MAX */ -#endif /* !HAVE_SYSCONF || !SC_NGROUPS_MAX */ - - if (maxgroups <= 0) - maxgroups = DEFAULT_MAXGROUPS; - - return maxgroups; -} - -long -getmaxchild () -{ - static long maxchild = -1L; - - if (maxchild > 0) - return maxchild; - -#if defined (HAVE_SYSCONF) && defined (_SC_CHILD_MAX) - maxchild = sysconf (_SC_CHILD_MAX); -#else -# if defined (CHILD_MAX) - maxchild = CHILD_MAX; -# else -# if defined (MAXUPRC) - maxchild = MAXUPRC; -# endif /* MAXUPRC */ -# endif /* CHILD_MAX */ -#endif /* !HAVE_SYSCONF || !_SC_CHILD_MAX */ - - return (maxchild); -} diff --git a/third_party/bash/parser.h b/third_party/bash/parser.h deleted file mode 100644 index 59bf0fec4..000000000 --- a/third_party/bash/parser.h +++ /dev/null @@ -1,102 +0,0 @@ -/* parser.h -- Everything you wanted to know about the parser, but were - afraid to ask. */ - -/* Copyright (C) 1995-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_PARSER_H_) -# define _PARSER_H_ - -# include "command.h" -# include "input.h" - -/* Possible states for the parser that require it to do special things. */ -#define PST_CASEPAT 0x000001 /* in a case pattern list */ -#define PST_ALEXPNEXT 0x000002 /* expand next word for aliases */ -#define PST_ALLOWOPNBRC 0x000004 /* allow open brace for function def */ -#define PST_NEEDCLOSBRC 0x000008 /* need close brace */ -#define PST_DBLPAREN 0x000010 /* double-paren parsing - unused */ -#define PST_SUBSHELL 0x000020 /* ( ... ) subshell */ -#define PST_CMDSUBST 0x000040 /* $( ... ) command substitution */ -#define PST_CASESTMT 0x000080 /* parsing a case statement */ -#define PST_CONDCMD 0x000100 /* parsing a [[...]] command */ -#define PST_CONDEXPR 0x000200 /* parsing the guts of [[...]] */ -#define PST_ARITHFOR 0x000400 /* parsing an arithmetic for command - unused */ -#define PST_ALEXPAND 0x000800 /* OK to expand aliases - unused */ -#define PST_EXTPAT 0x001000 /* parsing an extended shell pattern */ -#define PST_COMPASSIGN 0x002000 /* parsing x=(...) compound assignment */ -#define PST_ASSIGNOK 0x004000 /* assignment statement ok in this context */ -#define PST_EOFTOKEN 0x008000 /* yylex checks against shell_eof_token */ -#define PST_REGEXP 0x010000 /* parsing an ERE/BRE as a single word */ -#define PST_HEREDOC 0x020000 /* reading body of here-document */ -#define PST_REPARSE 0x040000 /* re-parsing in parse_string_to_word_list */ -#define PST_REDIRLIST 0x080000 /* parsing a list of redirections preceding a simple command name */ -#define PST_COMMENT 0x100000 /* parsing a shell comment; used by aliases */ -#define PST_ENDALIAS 0x200000 /* just finished expanding and consuming an alias */ -#define PST_NOEXPAND 0x400000 /* don't expand anything in read_token_word; for command substitution */ -#define PST_NOERROR 0x800000 /* don't print error messages in yyerror */ - -/* Definition of the delimiter stack. Needed by parse.y and bashhist.c. */ -struct dstack { -/* DELIMITERS is a stack of the nested delimiters that we have - encountered so far. */ - char *delimiters; - -/* Offset into the stack of delimiters. */ - int delimiter_depth; - -/* How many slots are allocated to DELIMITERS. */ - int delimiter_space; -}; - -/* States we can be in while scanning a ${...} expansion. Shared between - parse.y and subst.c */ -#define DOLBRACE_PARAM 0x01 -#define DOLBRACE_OP 0x02 -#define DOLBRACE_WORD 0x04 - -#define DOLBRACE_QUOTE 0x40 /* single quote is special in double quotes */ -#define DOLBRACE_QUOTE2 0x80 /* single quote is semi-special in double quotes */ - -/* variable declarations from parse.y */ -extern struct dstack dstack; - -extern char *primary_prompt; -extern char *secondary_prompt; - -extern char *current_prompt_string; - -extern char *ps1_prompt; -extern char *ps2_prompt; -extern char *ps0_prompt; - -extern int expand_aliases; -extern int current_command_line_count; -extern int saved_command_line_count; -extern int shell_eof_token; -extern int current_token; -extern int parser_state; -extern int need_here_doc; - -extern int ignoreeof; -extern int eof_encountered; -extern int eof_encountered_limit; - -extern int line_number, line_number_base; - -#endif /* _PARSER_H_ */ diff --git a/third_party/bash/patchlevel.h b/third_party/bash/patchlevel.h deleted file mode 100644 index 165390c15..000000000 --- a/third_party/bash/patchlevel.h +++ /dev/null @@ -1,30 +0,0 @@ -/* patchlevel.h -- current bash patch level */ - -/* Copyright (C) 2001-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_PATCHLEVEL_H_) -#define _PATCHLEVEL_H_ - -/* It's important that there be no other strings in this file that match the - regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh - looks for to find the patch level (for the sccs version string). */ - -#define PATCHLEVEL 0 - -#endif /* _PATCHLEVEL_H_ */ diff --git a/third_party/bash/pathcanon.c b/third_party/bash/pathcanon.c deleted file mode 100644 index 41abbd26c..000000000 --- a/third_party/bash/pathcanon.c +++ /dev/null @@ -1,234 +0,0 @@ -/* pathcanon.c -- canonicalize and manipulate pathnames. */ - -/* Copyright (C) 2000 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include "bashtypes.h" -#if defined (HAVE_SYS_PARAM_H) -# include -#endif -#include "posixstat.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "filecntl.h" -#include "bashansi.h" -#include -#include "chartypes.h" -#include - -#include "shell.h" - -#if !defined (errno) -extern int errno; -#endif - -#if defined (__CYGWIN__) -#include - -static int -_is_cygdrive (path) - char *path; -{ - static char user[MAXPATHLEN]; - static char system[MAXPATHLEN]; - static int first_time = 1; - - /* If the path is the first part of a network path, treat it as - existing. */ - if (path[0] == '/' && path[1] == '/' && !strchr (path + 2, '/')) - return 1; - /* Otherwise check for /cygdrive prefix. */ - if (first_time) - { - char user_flags[MAXPATHLEN]; - char system_flags[MAXPATHLEN]; - /* Get the cygdrive info */ - cygwin_internal (CW_GET_CYGDRIVE_INFO, user, system, user_flags, system_flags); - first_time = 0; - } - return !strcasecmp (path, user) || !strcasecmp (path, system); -} -#endif /* __CYGWIN__ */ - -/* Return 1 if PATH corresponds to a directory. A function for debugging. */ -static int -_path_isdir (path) - char *path; -{ - int l; - struct stat sb; - - /* This should leave errno set to the correct value. */ - errno = 0; - l = stat (path, &sb) == 0 && S_ISDIR (sb.st_mode); -#if defined (__CYGWIN__) - if (l == 0) - l = _is_cygdrive (path); -#endif - return l; -} - -/* Canonicalize PATH, and return a new path. The new path differs from PATH - in that: - Multiple `/'s are collapsed to a single `/'. - Leading `./'s and trailing `/.'s are removed. - Trailing `/'s are removed. - Non-leading `../'s and trailing `..'s are handled by removing - portions of the path. */ - -/* Look for ROOTEDPATH, PATHSEP, DIRSEP, and ISDIRSEP in ../../general.h */ - -#define DOUBLE_SLASH(p) ((p[0] == '/') && (p[1] == '/') && p[2] != '/') - -char * -sh_canonpath (path, flags) - char *path; - int flags; -{ - char stub_char; - char *result, *p, *q, *base, *dotdot; - int rooted, double_slash_path; - - /* The result cannot be larger than the input PATH. */ - result = (flags & PATH_NOALLOC) ? path : savestring (path); - - /* POSIX.2 says to leave a leading `//' alone. On cygwin, we skip over any - leading `x:' (dos drive name). */ - if (rooted = ROOTEDPATH(path)) - { - stub_char = DIRSEP; -#if defined (__CYGWIN__) - base = (ISALPHA((unsigned char)result[0]) && result[1] == ':') ? result + 3 : result + 1; -#else - base = result + 1; -#endif - double_slash_path = DOUBLE_SLASH (path); - base += double_slash_path; - } - else - { - stub_char = '.'; -#if defined (__CYGWIN__) - base = (ISALPHA((unsigned char)result[0]) && result[1] == ':') ? result + 2 : result; -#else - base = result; -#endif - double_slash_path = 0; - } - - /* - * invariants: - * base points to the portion of the path we want to modify - * p points at beginning of path element we're considering. - * q points just past the last path element we wrote (no slash). - * dotdot points just past the point where .. cannot backtrack - * any further (no slash). - */ - p = q = dotdot = base; - - while (*p) - { - if (ISDIRSEP(p[0])) /* null element */ - p++; - else if(p[0] == '.' && PATHSEP(p[1])) /* . and ./ */ - p += 1; /* don't count the separator in case it is nul */ - else if (p[0] == '.' && p[1] == '.' && PATHSEP(p[2])) /* .. and ../ */ - { - p += 2; /* skip `..' */ - if (q > dotdot) /* can backtrack */ - { - if (flags & PATH_CHECKDOTDOT) - { - char c; - - /* Make sure what we have so far corresponds to a valid - path before we chop some of it off. */ - c = *q; - *q = '\0'; - if (_path_isdir (result) == 0) - { - if ((flags & PATH_NOALLOC) == 0) - free (result); - return ((char *)NULL); - } - *q = c; - } - - while (--q > dotdot && ISDIRSEP(*q) == 0) - ; - } - else if (rooted == 0) - { - /* /.. is / but ./../ is .. */ - if (q != base) - *q++ = DIRSEP; - *q++ = '.'; - *q++ = '.'; - dotdot = q; - } - } - else /* real path element */ - { - /* add separator if not at start of work portion of result */ - if (q != base) - *q++ = DIRSEP; - while (*p && (ISDIRSEP(*p) == 0)) - *q++ = *p++; - /* Check here for a valid directory with _path_isdir. */ - if (flags & PATH_CHECKEXISTS) - { - char c; - - /* Make sure what we have so far corresponds to a valid - path before we chop some of it off. */ - c = *q; - *q = '\0'; - if (_path_isdir (result) == 0) - { - if ((flags & PATH_NOALLOC) == 0) - free (result); - return ((char *)NULL); - } - *q = c; - } - } - } - - /* Empty string is really ``.'' or `/', depending on what we started with. */ - if (q == result) - *q++ = stub_char; - *q = '\0'; - - /* If the result starts with `//', but the original path does not, we - can turn the // into /. Because of how we set `base', this should never - be true, but it's a sanity check. */ - if (DOUBLE_SLASH(result) && double_slash_path == 0) - { - if (result[2] == '\0') /* short-circuit for bare `//' */ - result[1] = '\0'; - else - memmove (result, result + 1, strlen (result + 1) + 1); - } - - return (result); -} diff --git a/third_party/bash/pathexp.c b/third_party/bash/pathexp.c deleted file mode 100644 index 9ba07d974..000000000 --- a/third_party/bash/pathexp.c +++ /dev/null @@ -1,637 +0,0 @@ -/* pathexp.c -- The shell interface to the globbing library. */ - -/* Copyright (C) 1995-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include "bashtypes.h" -#include - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "bashansi.h" - -#include "shell.h" -#include "pathexp.h" -#include "flags.h" - -#include "shmbutil.h" -#include "bashintl.h" - -#include "strmatch.h" - -static int glob_name_is_acceptable PARAMS((const char *)); -static void ignore_globbed_names PARAMS((char **, sh_ignore_func_t *)); -static char *split_ignorespec PARAMS((char *, int *)); - -#include "glob.h" - -/* Control whether * matches .files in globbing. */ -int glob_dot_filenames; - -/* Control whether the extended globbing features are enabled. */ -int extended_glob = EXTGLOB_DEFAULT; - -/* Control enabling special handling of `**' */ -int glob_star = 0; - -/* Return nonzero if STRING has any unquoted special globbing chars in it. - This is supposed to be called when pathname expansion is performed, so - it implements the rules in Posix 2.13.3, specifically that an unquoted - slash cannot appear in a bracket expression. */ -int -unquoted_glob_pattern_p (string) - register char *string; -{ - register int c; - char *send; - int open, bsquote; - - DECLARE_MBSTATE; - - open = bsquote = 0; - send = string + strlen (string); - - while (c = *string++) - { - switch (c) - { - case '?': - case '*': - return (1); - - case '[': - open++; - continue; - - case ']': - if (open) /* XXX - if --open == 0? */ - return (1); - continue; - - case '/': - if (open) - open = 0; - - case '+': - case '@': - case '!': - if (*string == '(') /*)*/ - return (1); - continue; - - /* A pattern can't end with a backslash, but a backslash in the pattern - can be special to the matching engine, so we note it in case we - need it later. */ - case '\\': - if (*string != '\0' && *string != '/') - { - bsquote = 1; - string++; - continue; - } - else if (open && *string == '/') - { - string++; /* quoted slashes in bracket expressions are ok */ - continue; - } - else if (*string == 0) - return (0); - - case CTLESC: - if (*string++ == '\0') - return (0); - } - - /* Advance one fewer byte than an entire multibyte character to - account for the auto-increment in the loop above. */ -#ifdef HANDLE_MULTIBYTE - string--; - ADVANCE_CHAR_P (string, send - string); - string++; -#else - ADVANCE_CHAR_P (string, send - string); -#endif - } - -#if 0 - return (bsquote ? 2 : 0); -#else - return (0); -#endif -} - -/* Return 1 if C is a character that is `special' in a POSIX ERE and needs to - be quoted to match itself. */ -static inline int -ere_char (c) - int c; -{ - switch (c) - { - case '.': - case '[': - case '\\': - case '(': - case ')': - case '*': - case '+': - case '?': - case '{': - case '|': - case '^': - case '$': - return 1; - default: - return 0; - } - return (0); -} - -/* This is only used to determine whether to backslash-quote a character. */ -int -glob_char_p (s) - const char *s; -{ - switch (*s) - { - case '*': - case '[': - case ']': - case '?': - case '\\': - return 1; - case '+': - case '@': - case '!': - if (s[1] == '(') /*(*/ - return 1; - break; - } - return 0; -} - -/* PATHNAME can contain characters prefixed by CTLESC; this indicates - that the character is to be quoted. We quote it here in the style - that the glob library recognizes. If flags includes QGLOB_CVTNULL, - we change quoted null strings (pathname[0] == CTLNUL) into empty - strings (pathname[0] == 0). If this is called after quote removal - is performed, (flags & QGLOB_CVTNULL) should be 0; if called when quote - removal has not been done (for example, before attempting to match a - pattern while executing a case statement), flags should include - QGLOB_CVTNULL. If flags includes QGLOB_CTLESC, we need to remove CTLESC - quoting CTLESC or CTLNUL (as if dequote_string were called). If flags - includes QGLOB_FILENAME, appropriate quoting to match a filename should be - performed. QGLOB_REGEXP means we're quoting for a Posix ERE (for - [[ string =~ pat ]]) and that requires some special handling. */ -char * -quote_string_for_globbing (pathname, qflags) - const char *pathname; - int qflags; -{ - char *temp; - register int i, j; - int cclass, collsym, equiv, c, last_was_backslash; - int savei, savej; - - temp = (char *)xmalloc (2 * strlen (pathname) + 1); - - if ((qflags & QGLOB_CVTNULL) && QUOTED_NULL (pathname)) - { - temp[0] = '\0'; - return temp; - } - - cclass = collsym = equiv = last_was_backslash = 0; - for (i = j = 0; pathname[i]; i++) - { - /* Fix for CTLESC at the end of the string? */ - if (pathname[i] == CTLESC && pathname[i+1] == '\0') - { - temp[j++] = pathname[i++]; - break; - } - /* If we are parsing regexp, turn CTLESC CTLESC into CTLESC. It's not an - ERE special character, so we should just be able to pass it through. */ - else if ((qflags & (QGLOB_REGEXP|QGLOB_CTLESC)) && pathname[i] == CTLESC && (pathname[i+1] == CTLESC || pathname[i+1] == CTLNUL)) - { - i++; - temp[j++] = pathname[i]; - continue; - } - else if (pathname[i] == CTLESC) - { -convert_to_backslash: - if ((qflags & QGLOB_FILENAME) && pathname[i+1] == '/') - continue; - /* What to do if preceding char is backslash? */ - if (pathname[i+1] != CTLESC && (qflags & QGLOB_REGEXP) && ere_char (pathname[i+1]) == 0) - continue; - temp[j++] = '\\'; - i++; - if (pathname[i] == '\0') - break; - } - else if ((qflags & QGLOB_REGEXP) && (i == 0 || pathname[i-1] != CTLESC) && pathname[i] == '[') /*]*/ - { - temp[j++] = pathname[i++]; /* open bracket */ - savej = j; - savei = i; - c = pathname[i++]; /* c == char after open bracket */ - if (c == '^') /* ignore pattern negation */ - { - temp[j++] = c; - c = pathname[i++]; - } - if (c == ']') /* ignore right bracket if first char */ - { - temp[j++] = c; - c = pathname[i++]; - } - do - { - if (c == 0) - goto endpat; - else if (c == CTLESC) - { - /* skip c, check for EOS, let assignment at end of loop */ - /* pathname[i] == backslash-escaped character */ - if (pathname[i] == 0) - goto endpat; - temp[j++] = pathname[i++]; - } - else if (c == '[' && pathname[i] == ':') - { - temp[j++] = c; - temp[j++] = pathname[i++]; - cclass = 1; - } - else if (cclass && c == ':' && pathname[i] == ']') - { - temp[j++] = c; - temp[j++] = pathname[i++]; - cclass = 0; - } - else if (c == '[' && pathname[i] == '=') - { - temp[j++] = c; - temp[j++] = pathname[i++]; - if (pathname[i] == ']') - temp[j++] = pathname[i++]; /* right brack can be in equiv */ - equiv = 1; - } - else if (equiv && c == '=' && pathname[i] == ']') - { - temp[j++] = c; - temp[j++] = pathname[i++]; - equiv = 0; - } - else if (c == '[' && pathname[i] == '.') - { - temp[j++] = c; - temp[j++] = pathname[i++]; - if (pathname[i] == ']') - temp[j++] = pathname[i++]; /* right brack can be in collsym */ - collsym = 1; - } - else if (collsym && c == '.' && pathname[i] == ']') - { - temp[j++] = c; - temp[j++] = pathname[i++]; - collsym = 0; - } - else - temp[j++] = c; - } - while (((c = pathname[i++]) != ']') && c != 0); - - /* If we don't find the closing bracket before we hit the end of - the string, rescan string without treating it as a bracket - expression (has implications for backslash and special ERE - chars) */ - if (c == 0) - { - i = savei - 1; /* -1 for autoincrement above */ - j = savej; - continue; - } - - temp[j++] = c; /* closing right bracket */ - i--; /* increment will happen above in loop */ - continue; /* skip double assignment below */ - } - else if (pathname[i] == '\\' && (qflags & QGLOB_REGEXP) == 0) - { - /* XXX - if not quoting regexp, use backslash as quote char. Should - We just pass it through without treating it as special? That is - what ksh93 seems to do. */ - - /* If we want to pass through backslash unaltered, comment out these - lines. */ - temp[j++] = '\\'; - - i++; - if (pathname[i] == '\0') - break; - /* If we are turning CTLESC CTLESC into CTLESC, we need to do that - even when the first CTLESC is preceded by a backslash. */ - if ((qflags & QGLOB_CTLESC) && pathname[i] == CTLESC && (pathname[i+1] == CTLESC || pathname[i+1] == CTLNUL)) - i++; /* skip over the CTLESC */ - else if ((qflags & QGLOB_CTLESC) && pathname[i] == CTLESC) - /* A little more general: if there is an unquoted backslash in the - pattern and we are handling quoted characters in the pattern, - convert the CTLESC to backslash and add the next character on - the theory that the backslash will quote the next character - but it would be inconsistent not to replace the CTLESC with - another backslash here. We can't tell at this point whether the - CTLESC comes from a backslash or other form of quoting in the - original pattern. */ - goto convert_to_backslash; - } - else if (pathname[i] == '\\' && (qflags & QGLOB_REGEXP)) - last_was_backslash = 1; - temp[j++] = pathname[i]; - } -endpat: - temp[j] = '\0'; - - return (temp); -} - -char * -quote_globbing_chars (string) - const char *string; -{ - size_t slen; - char *temp, *t; - const char *s, *send; - DECLARE_MBSTATE; - - slen = strlen (string); - send = string + slen; - - temp = (char *)xmalloc (slen * 2 + 1); - for (t = temp, s = string; *s; ) - { - if (glob_char_p (s)) - *t++ = '\\'; - - /* Copy a single (possibly multibyte) character from s to t, - incrementing both. */ - COPY_CHAR_P (t, s, send); - } - *t = '\0'; - return temp; -} - -/* Call the glob library to do globbing on PATHNAME. */ -char ** -shell_glob_filename (pathname, qflags) - const char *pathname; - int qflags; -{ - char *temp, **results; - int gflags, quoted_pattern; - - noglob_dot_filenames = glob_dot_filenames == 0; - - temp = quote_string_for_globbing (pathname, QGLOB_FILENAME|qflags); - gflags = glob_star ? GX_GLOBSTAR : 0; - results = glob_filename (temp, gflags); - free (temp); - - if (results && ((GLOB_FAILED (results)) == 0)) - { - if (should_ignore_glob_matches ()) - ignore_glob_matches (results); - if (results && results[0]) - strvec_sort (results, 1); /* posix sort */ - else - { - FREE (results); - results = (char **)&glob_error_return; - } - } - - return (results); -} - -/* Stuff for GLOBIGNORE. */ - -static struct ignorevar globignore = -{ - "GLOBIGNORE", - (struct ign *)0, - 0, - (char *)0, - (sh_iv_item_func_t *)0, -}; - -/* Set up to ignore some glob matches because the value of GLOBIGNORE - has changed. If GLOBIGNORE is being unset, we also need to disable - the globbing of filenames beginning with a `.'. */ -void -setup_glob_ignore (name) - char *name; -{ - char *v; - - v = get_string_value (name); - setup_ignore_patterns (&globignore); - - if (globignore.num_ignores) - glob_dot_filenames = 1; - else if (v == 0) - glob_dot_filenames = 0; -} - -int -should_ignore_glob_matches () -{ - return globignore.num_ignores; -} - -/* Return 0 if NAME matches a pattern in the globignore.ignores list. */ -static int -glob_name_is_acceptable (name) - const char *name; -{ - struct ign *p; - char *n; - int flags; - - /* . and .. are never matched. We extend this to the terminal component of a - pathname. */ - n = strrchr (name, '/'); - if (n == 0 || n[1] == 0) - n = (char *)name; - else - n++; - - if (n[0] == '.' && (n[1] == '\0' || (n[1] == '.' && n[2] == '\0'))) - return (0); - - flags = FNM_PATHNAME | FNMATCH_EXTFLAG | FNMATCH_NOCASEGLOB; - for (p = globignore.ignores; p->val; p++) - { - if (strmatch (p->val, (char *)name, flags) != FNM_NOMATCH) - return (0); - } - return (1); -} - -/* Internal function to test whether filenames in NAMES should be - ignored. NAME_FUNC is a pointer to a function to call with each - name. It returns non-zero if the name is acceptable to the particular - ignore function which called _ignore_names; zero if the name should - be removed from NAMES. */ - -static void -ignore_globbed_names (names, name_func) - char **names; - sh_ignore_func_t *name_func; -{ - char **newnames; - int n, i; - - for (i = 0; names[i]; i++) - ; - newnames = strvec_create (i + 1); - - for (n = i = 0; names[i]; i++) - { - if ((*name_func) (names[i])) - newnames[n++] = names[i]; - else - free (names[i]); - } - - newnames[n] = (char *)NULL; - - if (n == 0) - { - names[0] = (char *)NULL; - free (newnames); - return; - } - - /* Copy the acceptable names from NEWNAMES back to NAMES and set the - new array end. */ - for (n = 0; newnames[n]; n++) - names[n] = newnames[n]; - names[n] = (char *)NULL; - free (newnames); -} - -void -ignore_glob_matches (names) - char **names; -{ - if (globignore.num_ignores == 0) - return; - - ignore_globbed_names (names, glob_name_is_acceptable); -} - -static char * -split_ignorespec (s, ip) - char *s; - int *ip; -{ - char *t; - int n, i; - - if (s == 0) - return 0; - - i = *ip; - if (s[i] == 0) - return 0; - - n = skip_to_delim (s, i, ":", SD_NOJMP|SD_EXTGLOB|SD_GLOB); - t = substring (s, i, n); - - if (s[n] == ':') - n++; - *ip = n; - return t; -} - -void -setup_ignore_patterns (ivp) - struct ignorevar *ivp; -{ - int numitems, maxitems, ptr; - char *colon_bit, *this_ignoreval; - struct ign *p; - - this_ignoreval = get_string_value (ivp->varname); - - /* If nothing has changed then just exit now. */ - if ((this_ignoreval && ivp->last_ignoreval && STREQ (this_ignoreval, ivp->last_ignoreval)) || - (!this_ignoreval && !ivp->last_ignoreval)) - return; - - /* Oops. The ignore variable has changed. Re-parse it. */ - ivp->num_ignores = 0; - - if (ivp->ignores) - { - for (p = ivp->ignores; p->val; p++) - free(p->val); - free (ivp->ignores); - ivp->ignores = (struct ign *)NULL; - } - - if (ivp->last_ignoreval) - { - free (ivp->last_ignoreval); - ivp->last_ignoreval = (char *)NULL; - } - - if (this_ignoreval == 0 || *this_ignoreval == '\0') - return; - - ivp->last_ignoreval = savestring (this_ignoreval); - - numitems = maxitems = ptr = 0; - -#if 0 - while (colon_bit = extract_colon_unit (this_ignoreval, &ptr)) -#else - while (colon_bit = split_ignorespec (this_ignoreval, &ptr)) -#endif - { - if (numitems + 1 >= maxitems) - { - maxitems += 10; - ivp->ignores = (struct ign *)xrealloc (ivp->ignores, maxitems * sizeof (struct ign)); - } - ivp->ignores[numitems].val = colon_bit; - ivp->ignores[numitems].len = strlen (colon_bit); - ivp->ignores[numitems].flags = 0; - if (ivp->item_func) - (*ivp->item_func) (&ivp->ignores[numitems]); - numitems++; - } - ivp->ignores[numitems].val = (char *)NULL; - ivp->num_ignores = numitems; -} diff --git a/third_party/bash/pathexp.h b/third_party/bash/pathexp.h deleted file mode 100644 index b96f92af4..000000000 --- a/third_party/bash/pathexp.h +++ /dev/null @@ -1,104 +0,0 @@ -/* pathexp.h -- The shell interface to the globbing library. */ - -/* Copyright (C) 1987-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_PATHEXP_H_) -#define _PATHEXP_H_ - -#define GLOB_FAILED(glist) (glist) == (char **)&glob_error_return - -extern int noglob_dot_filenames; -extern char *glob_error_return; - -/* Flag values for quote_string_for_globbing */ -#define QGLOB_CVTNULL 0x01 /* convert QUOTED_NULL strings to '\0' */ -#define QGLOB_FILENAME 0x02 /* do correct quoting for matching filenames */ -#define QGLOB_REGEXP 0x04 /* quote an ERE for regcomp/regexec */ -#define QGLOB_CTLESC 0x08 /* turn CTLESC CTLESC into CTLESC for BREs */ -#define QGLOB_DEQUOTE 0x10 /* like dequote_string but quote glob chars */ - -#if defined (EXTENDED_GLOB) -/* Flags to OR with other flag args to strmatch() to enabled the extended - pattern matching. */ -# define FNMATCH_EXTFLAG (extended_glob ? FNM_EXTMATCH : 0) -#else -# define FNMATCH_EXTFLAG 0 -#endif /* !EXTENDED_GLOB */ - -#define FNMATCH_IGNCASE (match_ignore_case ? FNM_CASEFOLD : 0) -#define FNMATCH_NOCASEGLOB (glob_ignore_case ? FNM_CASEFOLD : 0) - -extern int glob_dot_filenames; -extern int extended_glob; -extern int glob_star; -extern int match_ignore_case; /* doesn't really belong here */ - -extern int unquoted_glob_pattern_p PARAMS((char *)); - -/* PATHNAME can contain characters prefixed by CTLESC; this indicates - that the character is to be quoted. We quote it here in the style - that the glob library recognizes. If flags includes QGLOB_CVTNULL, - we change quoted null strings (pathname[0] == CTLNUL) into empty - strings (pathname[0] == 0). If this is called after quote removal - is performed, (flags & QGLOB_CVTNULL) should be 0; if called when quote - removal has not been done (for example, before attempting to match a - pattern while executing a case statement), flags should include - QGLOB_CVTNULL. If flags includes QGLOB_FILENAME, appropriate quoting - to match a filename should be performed. */ -extern char *quote_string_for_globbing PARAMS((const char *, int)); - -extern int glob_char_p PARAMS((const char *)); -extern char *quote_globbing_chars PARAMS((const char *)); - -/* Call the glob library to do globbing on PATHNAME. FLAGS is additional - flags to pass to QUOTE_STRING_FOR_GLOBBING, mostly having to do with - whether or not we've already performed quote removal. */ -extern char **shell_glob_filename PARAMS((const char *, int)); - -/* Filename completion ignore. Used to implement the "fignore" facility of - tcsh, GLOBIGNORE (like ksh-93 FIGNORE), and EXECIGNORE. - - It is passed a NULL-terminated array of (char *)'s that must be - free()'d if they are deleted. The first element (names[0]) is the - least-common-denominator string of the matching patterns (i.e. - u produces names[0] = "und", names[1] = "under.c", names[2] = - "undun.c", name[3] = NULL). */ - -struct ign { - char *val; - int len, flags; -}; - -typedef int sh_iv_item_func_t PARAMS((struct ign *)); - -struct ignorevar { - char *varname; /* FIGNORE, GLOBIGNORE, or EXECIGNORE */ - struct ign *ignores; /* Store the ignore strings here */ - int num_ignores; /* How many are there? */ - char *last_ignoreval; /* Last value of variable - cached for speed */ - sh_iv_item_func_t *item_func; /* Called when each item is parsed from $`varname' */ -}; - -extern void setup_ignore_patterns PARAMS((struct ignorevar *)); - -extern void setup_glob_ignore PARAMS((char *)); -extern int should_ignore_glob_matches PARAMS((void)); -extern void ignore_glob_matches PARAMS((char **)); - -#endif diff --git a/third_party/bash/pathnames.h b/third_party/bash/pathnames.h deleted file mode 100644 index f506f3cb4..000000000 --- a/third_party/bash/pathnames.h +++ /dev/null @@ -1,33 +0,0 @@ -/* pathnames.h -- absolute filenames that bash wants for various defaults. */ - -/* Copyright (C) 1987-2009 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_PATHNAMES_H_) -#define _PATHNAMES_H_ - -/* The default file for hostname completion. */ -#define DEFAULT_HOSTS_FILE "/etc/hosts" - -/* The default login shell startup file. */ -#define SYS_PROFILE "/etc/profile" - -/* The default location of the bash debugger initialization/startup file. */ -#define DEBUGGER_START_FILE "/zip/usr/share/bashdb/bashdb-main.inc" - -#endif /* _PATHNAMES_H */ diff --git a/third_party/bash/pathphys.c b/third_party/bash/pathphys.c deleted file mode 100644 index 2b6211d6a..000000000 --- a/third_party/bash/pathphys.c +++ /dev/null @@ -1,296 +0,0 @@ -/* pathphys.c -- return pathname with all symlinks expanded. */ - -/* Copyright (C) 2000-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include "bashtypes.h" -#if defined (HAVE_SYS_PARAM_H) -# include -#endif -#include "posixstat.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "filecntl.h" -#include "bashansi.h" -#include -#include "chartypes.h" -#include - -#include "shell.h" - -#if !defined (MAXSYMLINKS) -# define MAXSYMLINKS 32 -#endif - -#if !defined (errno) -extern int errno; -#endif /* !errno */ - -extern char *get_working_directory PARAMS((char *)); - -static int -_path_readlink (path, buf, bufsiz) - char *path; - char *buf; - int bufsiz; -{ -#ifdef HAVE_READLINK - return readlink (path, buf, bufsiz); -#else - errno = EINVAL; - return -1; -#endif -} - -/* Look for ROOTEDPATH, PATHSEP, DIRSEP, and ISDIRSEP in ../../general.h */ - -#define DOUBLE_SLASH(p) ((p[0] == '/') && (p[1] == '/') && p[2] != '/') - -/* - * Return PATH with all symlinks expanded in newly-allocated memory. - * This always gets an absolute pathname. - */ - -char * -sh_physpath (path, flags) - char *path; - int flags; -{ - char tbuf[PATH_MAX+1], linkbuf[PATH_MAX+1]; - char *result, *p, *q, *qsave, *qbase, *workpath; - int double_slash_path, linklen, nlink; - - linklen = strlen (path); - -#if 0 - /* First sanity check -- punt immediately if the name is too long. */ - if (linklen >= PATH_MAX) - return (savestring (path)); -#endif - - nlink = 0; - q = result = (char *)xmalloc (PATH_MAX + 1); - - /* Even if we get something longer than PATH_MAX, we might be able to - shorten it, so we try. */ - if (linklen >= PATH_MAX) - workpath = savestring (path); - else - { - workpath = (char *)xmalloc (PATH_MAX + 1); - strcpy (workpath, path); - } - - /* This always gets an absolute pathname. */ - - /* POSIX.2 says to leave a leading `//' alone. On cygwin, we skip over any - leading `x:' (dos drive name). */ -#if defined (__CYGWIN__) - qbase = (ISALPHA((unsigned char)workpath[0]) && workpath[1] == ':') ? workpath + 3 : workpath + 1; -#else - qbase = workpath + 1; -#endif - double_slash_path = DOUBLE_SLASH (workpath); - qbase += double_slash_path; - - for (p = workpath; p < qbase; ) - *q++ = *p++; - qbase = q; - - /* - * invariants: - * qbase points to the portion of the result path we want to modify - * p points at beginning of path element we're considering. - * q points just past the last path element we wrote (no slash). - * - * XXX -- need to fix error checking for too-long pathnames - */ - - while (*p) - { - if (ISDIRSEP(p[0])) /* null element */ - p++; - else if(p[0] == '.' && PATHSEP(p[1])) /* . and ./ */ - p += 1; /* don't count the separator in case it is nul */ - else if (p[0] == '.' && p[1] == '.' && PATHSEP(p[2])) /* .. and ../ */ - { - p += 2; /* skip `..' */ - if (q > qbase) - { - while (--q > qbase && ISDIRSEP(*q) == 0) - ; - } - } - else /* real path element */ - { - /* add separator if not at start of work portion of result */ - qsave = q; - if (q != qbase) - *q++ = DIRSEP; - while (*p && (ISDIRSEP(*p) == 0)) - { - if (q - result >= PATH_MAX) - { -#ifdef ENAMETOOLONG - errno = ENAMETOOLONG; -#else - errno = EINVAL; -#endif - goto error; - } - - *q++ = *p++; - } - - *q = '\0'; - - linklen = _path_readlink (result, linkbuf, PATH_MAX); - if (linklen < 0) /* if errno == EINVAL, it's not a symlink */ - { - if (errno != EINVAL) - goto error; - continue; - } - - /* It's a symlink, and the value is in LINKBUF. */ - nlink++; - if (nlink > MAXSYMLINKS) - { -#ifdef ELOOP - errno = ELOOP; -#else - errno = EINVAL; -#endif -error: - free (result); - free (workpath); - return ((char *)NULL); - } - - linkbuf[linklen] = '\0'; - - /* If the new path length would overrun PATH_MAX, punt now. */ - if ((strlen (p) + linklen + 2) >= PATH_MAX) - { -#ifdef ENAMETOOLONG - errno = ENAMETOOLONG; -#else - errno = EINVAL; -#endif - goto error; - } - - /* Form the new pathname by copying the link value to a temporary - buffer and appending the rest of `workpath'. Reset p to point - to the start of the rest of the path. If the link value is an - absolute pathname, reset p, q, and qbase. If not, reset p - and q. */ - strcpy (tbuf, linkbuf); - tbuf[linklen] = '/'; - strcpy (tbuf + linklen, p); - strcpy (workpath, tbuf); - - if (ABSPATH(linkbuf)) - { - q = result; - /* Duplicating some code here... */ -#if defined (__CYGWIN__) - qbase = (ISALPHA((unsigned char)workpath[0]) && workpath[1] == ':') ? workpath + 3 : workpath + 1; -#else - qbase = workpath + 1; -#endif - double_slash_path = DOUBLE_SLASH (workpath); - qbase += double_slash_path; - - for (p = workpath; p < qbase; ) - *q++ = *p++; - qbase = q; - } - else - { - p = workpath; - q = qsave; - } - } - } - - *q = '\0'; - free (workpath); - - /* If the result starts with `//', but the original path does not, we - can turn the // into /. Because of how we set `qbase', this should never - be true, but it's a sanity check. */ - if (DOUBLE_SLASH(result) && double_slash_path == 0) - { - if (result[2] == '\0') /* short-circuit for bare `//' */ - result[1] = '\0'; - else - memmove (result, result + 1, strlen (result + 1) + 1); - } - - return (result); -} - -char * -sh_realpath (pathname, resolved) - const char *pathname; - char *resolved; -{ - char *tdir, *wd; - - if (pathname == 0 || *pathname == '\0') - { - errno = (pathname == 0) ? EINVAL : ENOENT; - return ((char *)NULL); - } - - if (ABSPATH (pathname) == 0) - { - wd = get_working_directory ("sh_realpath"); - if (wd == 0) - return ((char *)NULL); - tdir = sh_makepath (wd, (char *)pathname, 0); - free (wd); - } - else - tdir = savestring (pathname); - - wd = sh_physpath (tdir, 0); - free (tdir); - - if (resolved == 0) - return (wd); - - if (wd) - { - strncpy (resolved, wd, PATH_MAX - 1); - resolved[PATH_MAX - 1] = '\0'; - free (wd); - return resolved; - } - else - { - resolved[0] = '\0'; - return wd; - } -} diff --git a/third_party/bash/pcomplete.c b/third_party/bash/pcomplete.c deleted file mode 100644 index e78b929be..000000000 --- a/third_party/bash/pcomplete.c +++ /dev/null @@ -1,1757 +0,0 @@ -/* pcomplete.c - functions to generate lists of matches for programmable completion. */ - -/* Copyright (C) 1999-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if defined (PROGRAMMABLE_COMPLETION) - -#include "bashtypes.h" -#include "posixstat.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include - -#if defined (PREFER_STDARG) -# include -#else -# include -#endif - -#include "posixtime.h" - -#include -#include "bashansi.h" -#include "bashintl.h" - -#include "shell.h" -#include "pcomplete.h" -#include "alias.h" -#include "bashline.h" -#include "execute_cmd.h" -#include "pathexp.h" - -#if defined (JOB_CONTROL) -# include "jobs.h" -#endif - -#if !defined (NSIG) -# include "trap.h" -#endif - -#include "shmbutil.h" - -#include "builtins.h" -#include "common.h" -#include "builtext.h" - -#include "glob.h" -#include "strmatch.h" - -#include "third_party/readline/rlconf.h" -#include "third_party/readline/readline.h" -#include "third_party/readline/history.h" - -#ifdef STRDUP -# undef STRDUP -#endif -#define STRDUP(x) ((x) ? savestring (x) : (char *)NULL) - -typedef SHELL_VAR **SVFUNC (); - -#ifndef HAVE_STRPBRK -extern char *strpbrk PARAMS((char *, char *)); -#endif - -extern STRING_INT_ALIST word_token_alist[]; -extern char *signal_names[]; - -#if defined (DEBUG) -#if defined (PREFER_STDARG) -static void debug_printf (const char *, ...) __attribute__((__format__ (printf, 1, 2))); -#endif -#endif /* DEBUG */ - -static int it_init_joblist PARAMS((ITEMLIST *, int)); - -static int it_init_aliases PARAMS((ITEMLIST *)); -static int it_init_arrayvars PARAMS((ITEMLIST *)); -static int it_init_bindings PARAMS((ITEMLIST *)); -static int it_init_builtins PARAMS((ITEMLIST *)); -static int it_init_disabled PARAMS((ITEMLIST *)); -static int it_init_enabled PARAMS((ITEMLIST *)); -static int it_init_exported PARAMS((ITEMLIST *)); -static int it_init_functions PARAMS((ITEMLIST *)); -static int it_init_helptopics PARAMS((ITEMLIST *)); -static int it_init_hostnames PARAMS((ITEMLIST *)); -static int it_init_jobs PARAMS((ITEMLIST *)); -static int it_init_running PARAMS((ITEMLIST *)); -static int it_init_stopped PARAMS((ITEMLIST *)); -static int it_init_keywords PARAMS((ITEMLIST *)); -static int it_init_signals PARAMS((ITEMLIST *)); -static int it_init_variables PARAMS((ITEMLIST *)); -static int it_init_setopts PARAMS((ITEMLIST *)); -static int it_init_shopts PARAMS((ITEMLIST *)); - -static int shouldexp_filterpat PARAMS((char *)); -static char *preproc_filterpat PARAMS((char *, const char *)); - -static void init_itemlist_from_varlist PARAMS((ITEMLIST *, SVFUNC *)); - -static STRINGLIST *gen_matches_from_itemlist PARAMS((ITEMLIST *, const char *)); -static STRINGLIST *gen_action_completions PARAMS((COMPSPEC *, const char *)); -static STRINGLIST *gen_globpat_matches PARAMS((COMPSPEC *, const char *)); -static STRINGLIST *gen_wordlist_matches PARAMS((COMPSPEC *, const char *)); -static STRINGLIST *gen_shell_function_matches PARAMS((COMPSPEC *, const char *, - const char *, - char *, int, WORD_LIST *, - int, int, int *)); -static STRINGLIST *gen_command_matches PARAMS((COMPSPEC *, const char *, - const char *, - char *, int, WORD_LIST *, - int, int)); - -static STRINGLIST *gen_progcomp_completions PARAMS((const char *, const char *, - const char *, - int, int, int *, int *, - COMPSPEC **)); - -static char *pcomp_filename_completion_function PARAMS((const char *, int)); - -#if defined (ARRAY_VARS) -static SHELL_VAR *bind_comp_words PARAMS((WORD_LIST *)); -#endif -static void bind_compfunc_variables PARAMS((char *, int, WORD_LIST *, int, int)); -static void unbind_compfunc_variables PARAMS((int)); -static WORD_LIST *build_arg_list PARAMS((char *, const char *, const char *, WORD_LIST *, int)); -static WORD_LIST *command_line_to_word_list PARAMS((char *, int, int, int *, int *)); - -#ifdef DEBUG -static int progcomp_debug = 0; -#endif - -int prog_completion_enabled = 1; - -#ifdef ALIAS -int progcomp_alias = 0; /* unavailable to user code for now */ -#endif - -/* These are used to manage the arrays of strings for possible completions. */ -ITEMLIST it_aliases = { 0, it_init_aliases, (STRINGLIST *)0 }; -ITEMLIST it_arrayvars = { LIST_DYNAMIC, it_init_arrayvars, (STRINGLIST *)0 }; -ITEMLIST it_bindings = { 0, it_init_bindings, (STRINGLIST *)0 }; -ITEMLIST it_builtins = { 0, it_init_builtins, (STRINGLIST *)0 }; -ITEMLIST it_commands = { LIST_DYNAMIC }; /* unused */ -ITEMLIST it_directories = { LIST_DYNAMIC }; /* unused */ -ITEMLIST it_disabled = { 0, it_init_disabled, (STRINGLIST *)0 }; -ITEMLIST it_enabled = { 0, it_init_enabled, (STRINGLIST *)0 }; -ITEMLIST it_exports = { LIST_DYNAMIC, it_init_exported, (STRINGLIST *)0 }; -ITEMLIST it_files = { LIST_DYNAMIC }; /* unused */ -ITEMLIST it_functions = { 0, it_init_functions, (STRINGLIST *)0 }; -ITEMLIST it_helptopics = { 0, it_init_helptopics, (STRINGLIST *)0 }; -ITEMLIST it_hostnames = { LIST_DYNAMIC, it_init_hostnames, (STRINGLIST *)0 }; -ITEMLIST it_groups = { LIST_DYNAMIC }; /* unused */ -ITEMLIST it_jobs = { LIST_DYNAMIC, it_init_jobs, (STRINGLIST *)0 }; -ITEMLIST it_keywords = { 0, it_init_keywords, (STRINGLIST *)0 }; -ITEMLIST it_running = { LIST_DYNAMIC, it_init_running, (STRINGLIST *)0 }; -ITEMLIST it_services = { LIST_DYNAMIC }; /* unused */ -ITEMLIST it_setopts = { 0, it_init_setopts, (STRINGLIST *)0 }; -ITEMLIST it_shopts = { 0, it_init_shopts, (STRINGLIST *)0 }; -ITEMLIST it_signals = { 0, it_init_signals, (STRINGLIST *)0 }; -ITEMLIST it_stopped = { LIST_DYNAMIC, it_init_stopped, (STRINGLIST *)0 }; -ITEMLIST it_users = { LIST_DYNAMIC }; /* unused */ -ITEMLIST it_variables = { LIST_DYNAMIC, it_init_variables, (STRINGLIST *)0 }; - -COMPSPEC *pcomp_curcs; -const char *pcomp_curcmd; -const char *pcomp_curtxt; - -char *pcomp_line; -int pcomp_ind; - -#ifdef DEBUG -/* Debugging code */ -static void -#if defined (PREFER_STDARG) -debug_printf (const char *format, ...) -#else -debug_printf (format, va_alist) - const char *format; - va_dcl -#endif -{ - va_list args; - - if (progcomp_debug == 0) - return; - - SH_VA_START (args, format); - - fprintf (stdout, "DEBUG: "); - vfprintf (stdout, format, args); - fprintf (stdout, "\n"); - - rl_on_new_line (); - - va_end (args); -} -#endif - -/* Functions to manage the item lists */ - -void -set_itemlist_dirty (it) - ITEMLIST *it; -{ - it->flags |= LIST_DIRTY; -} - -void -initialize_itemlist (itp) - ITEMLIST *itp; -{ - (*itp->list_getter) (itp); - itp->flags |= LIST_INITIALIZED; - itp->flags &= ~LIST_DIRTY; -} - -void -clean_itemlist (itp) - ITEMLIST *itp; -{ - STRINGLIST *sl; - - sl = itp->slist; - if (sl) - { - if ((itp->flags & (LIST_DONTFREEMEMBERS|LIST_DONTFREE)) == 0) - strvec_flush (sl->list); - if ((itp->flags & LIST_DONTFREE) == 0) - free (sl->list); - free (sl); - } - itp->slist = (STRINGLIST *)NULL; - itp->flags &= ~(LIST_DONTFREE|LIST_DONTFREEMEMBERS|LIST_INITIALIZED|LIST_DIRTY); -} - - -static int -shouldexp_filterpat (s) - char *s; -{ - register char *p; - - for (p = s; p && *p; p++) - { - if (*p == '\\') - p++; - else if (*p == '&') - return 1; - } - return 0; -} - -/* Replace any instance of `&' in PAT with TEXT. Backslash may be used to - quote a `&' and inhibit substitution. Returns a new string. This just - calls stringlib.c:strcreplace(). */ -static char * -preproc_filterpat (pat, text) - char *pat; - const char *text; -{ - char *ret; - - ret = strcreplace (pat, '&', text, 1); - return ret; -} - -/* Remove any match of FILTERPAT from SL. A `&' in FILTERPAT is replaced by - TEXT. A leading `!' in FILTERPAT negates the pattern; in this case - any member of SL->list that does *not* match will be removed. This returns - a new STRINGLIST with the matching members of SL *copied*. Any - non-matching members of SL->list are *freed*. */ -STRINGLIST * -filter_stringlist (sl, filterpat, text) - STRINGLIST *sl; - char *filterpat; - const char *text; -{ - int i, m, not; - STRINGLIST *ret; - char *npat, *t; - - if (sl == 0 || sl->list == 0 || sl->list_len == 0) - return sl; - - npat = shouldexp_filterpat (filterpat) ? preproc_filterpat (filterpat, text) : filterpat; - -#if defined (EXTENDED_GLOB) - not = (npat[0] == '!' && (extended_glob == 0 || npat[1] != '(')); /*)*/ -#else - not = (npat[0] == '!'); -#endif - t = not ? npat + 1 : npat; - - ret = strlist_create (sl->list_size); - for (i = 0; i < sl->list_len; i++) - { - m = strmatch (t, sl->list[i], FNMATCH_EXTFLAG | FNMATCH_IGNCASE); - if ((not && m == FNM_NOMATCH) || (not == 0 && m != FNM_NOMATCH)) - free (sl->list[i]); - else - ret->list[ret->list_len++] = sl->list[i]; - } - - ret->list[ret->list_len] = (char *)NULL; - if (npat != filterpat) - free (npat); - - return ret; -} - -/* Turn an array of strings returned by rl_completion_matches into a STRINGLIST. - This understands how rl_completion_matches sets matches[0] (the lcd of the - strings in the list, unless it's the only match). */ -STRINGLIST * -completions_to_stringlist (matches) - char **matches; -{ - STRINGLIST *sl; - int mlen, i, n; - - mlen = (matches == 0) ? 0 : strvec_len (matches); - sl = strlist_create (mlen + 1); - - if (matches == 0 || matches[0] == 0) - return sl; - - if (matches[1] == 0) - { - sl->list[0] = STRDUP (matches[0]); - sl->list[sl->list_len = 1] = (char *)NULL; - return sl; - } - - for (i = 1, n = 0; i < mlen; i++, n++) - sl->list[n] = STRDUP (matches[i]); - sl->list_len = n; - sl->list[n] = (char *)NULL; - - return sl; -} - -/* Functions to manage the various ITEMLISTs that we populate internally. - The caller is responsible for setting ITP->flags correctly. */ - -static int -it_init_aliases (itp) - ITEMLIST *itp; -{ -#ifdef ALIAS - alias_t **alias_list; - register int i, n; - STRINGLIST *sl; - - alias_list = all_aliases (); - if (alias_list == 0) - { - itp->slist = (STRINGLIST *)NULL; - return 0; - } - for (n = 0; alias_list[n]; n++) - ; - sl = strlist_create (n+1); - for (i = 0; i < n; i++) - sl->list[i] = STRDUP (alias_list[i]->name); - sl->list[n] = (char *)NULL; - sl->list_size = sl->list_len = n; - itp->slist = sl; -#else - itp->slist = (STRINGLIST *)NULL; -#endif - free (alias_list); - return 1; -} - -static void -init_itemlist_from_varlist (itp, svfunc) - ITEMLIST *itp; - SVFUNC *svfunc; -{ - SHELL_VAR **vlist; - STRINGLIST *sl; - register int i, n; - - vlist = (*svfunc) (); - if (vlist == 0) - { - itp->slist = (STRINGLIST *)NULL; - return; - } - for (n = 0; vlist[n]; n++) - ; - sl = strlist_create (n+1); - for (i = 0; i < n; i++) - sl->list[i] = savestring (vlist[i]->name); - sl->list[sl->list_len = n] = (char *)NULL; - itp->slist = sl; - free (vlist); -} - -static int -it_init_arrayvars (itp) - ITEMLIST *itp; -{ -#if defined (ARRAY_VARS) - init_itemlist_from_varlist (itp, all_array_variables); - return 1; -#else - return 0; -#endif -} - -static int -it_init_bindings (itp) - ITEMLIST *itp; -{ - char **blist; - STRINGLIST *sl; - - /* rl_funmap_names allocates blist, but not its members */ - blist = (char **)rl_funmap_names (); /* XXX fix const later */ - sl = strlist_create (0); - sl->list = blist; - sl->list_size = 0; - sl->list_len = strvec_len (sl->list); - itp->flags |= LIST_DONTFREEMEMBERS; - itp->slist = sl; - - return 0; -} - -static int -it_init_builtins (itp) - ITEMLIST *itp; -{ - STRINGLIST *sl; - register int i, n; - - sl = strlist_create (num_shell_builtins); - for (i = n = 0; i < num_shell_builtins; i++) - if (shell_builtins[i].function) - sl->list[n++] = shell_builtins[i].name; - sl->list[sl->list_len = n] = (char *)NULL; - itp->flags |= LIST_DONTFREEMEMBERS; - itp->slist = sl; - return 0; -} - -static int -it_init_enabled (itp) - ITEMLIST *itp; -{ - STRINGLIST *sl; - register int i, n; - - sl = strlist_create (num_shell_builtins); - for (i = n = 0; i < num_shell_builtins; i++) - { - if (shell_builtins[i].function && (shell_builtins[i].flags & BUILTIN_ENABLED)) - sl->list[n++] = shell_builtins[i].name; - } - sl->list[sl->list_len = n] = (char *)NULL; - itp->flags |= LIST_DONTFREEMEMBERS; - itp->slist = sl; - return 0; -} - -static int -it_init_disabled (itp) - ITEMLIST *itp; -{ - STRINGLIST *sl; - register int i, n; - - sl = strlist_create (num_shell_builtins); - for (i = n = 0; i < num_shell_builtins; i++) - { - if (shell_builtins[i].function && ((shell_builtins[i].flags & BUILTIN_ENABLED) == 0)) - sl->list[n++] = shell_builtins[i].name; - } - sl->list[sl->list_len = n] = (char *)NULL; - itp->flags |= LIST_DONTFREEMEMBERS; - itp->slist = sl; - return 0; -} - -static int -it_init_exported (itp) - ITEMLIST *itp; -{ - init_itemlist_from_varlist (itp, all_exported_variables); - return 0; -} - -static int -it_init_functions (itp) - ITEMLIST *itp; -{ - init_itemlist_from_varlist (itp, all_visible_functions); - return 0; -} - -/* Like it_init_builtins, but includes everything the help builtin looks at, - not just builtins with an active implementing function. */ -static int -it_init_helptopics (itp) - ITEMLIST *itp; -{ - STRINGLIST *sl; - register int i, n; - - sl = strlist_create (num_shell_builtins); - for (i = n = 0; i < num_shell_builtins; i++) - sl->list[n++] = shell_builtins[i].name; - sl->list[sl->list_len = n] = (char *)NULL; - itp->flags |= LIST_DONTFREEMEMBERS; - itp->slist = sl; - return 0; -} - -static int -it_init_hostnames (itp) - ITEMLIST *itp; -{ - STRINGLIST *sl; - - sl = strlist_create (0); - sl->list = get_hostname_list (); - sl->list_len = sl->list ? strvec_len (sl->list) : 0; - sl->list_size = sl->list_len; - itp->slist = sl; - itp->flags |= LIST_DONTFREEMEMBERS|LIST_DONTFREE; - return 0; -} - -static int -it_init_joblist (itp, jstate) - ITEMLIST *itp; - int jstate; -{ -#if defined (JOB_CONTROL) - STRINGLIST *sl; - register int i; - register PROCESS *p; - char *s, *t; - JOB *j; - JOB_STATE ws; /* wanted state */ - - ws = JNONE; - if (jstate == 0) - ws = JRUNNING; - else if (jstate == 1) - ws = JSTOPPED; - - sl = strlist_create (js.j_jobslots); - for (i = js.j_jobslots - 1; i >= 0; i--) - { - j = get_job_by_jid (i); - if (j == 0) - continue; - p = j->pipe; - if (jstate == -1 || JOBSTATE(i) == ws) - { - s = savestring (p->command); - t = strpbrk (s, " \t\n"); - if (t) - *t = '\0'; - sl->list[sl->list_len++] = s; - } - } - itp->slist = sl; -#else - itp->slist = (STRINGLIST *)NULL; -#endif - return 0; -} - -static int -it_init_jobs (itp) - ITEMLIST *itp; -{ - return (it_init_joblist (itp, -1)); -} - -static int -it_init_running (itp) - ITEMLIST *itp; -{ - return (it_init_joblist (itp, 0)); -} - -static int -it_init_stopped (itp) - ITEMLIST *itp; -{ - return (it_init_joblist (itp, 1)); -} - -static int -it_init_keywords (itp) - ITEMLIST *itp; -{ - STRINGLIST *sl; - register int i, n; - - for (n = 0; word_token_alist[n].word; n++) - ; - sl = strlist_create (n); - for (i = 0; i < n; i++) - sl->list[i] = word_token_alist[i].word; - sl->list[sl->list_len = i] = (char *)NULL; - itp->flags |= LIST_DONTFREEMEMBERS; - itp->slist = sl; - return 0; -} - -static int -it_init_signals (itp) - ITEMLIST *itp; -{ - STRINGLIST *sl; - - sl = strlist_create (0); - sl->list = signal_names; - sl->list_len = strvec_len (sl->list); - itp->flags |= LIST_DONTFREE; - itp->slist = sl; - return 0; -} - -static int -it_init_variables (itp) - ITEMLIST *itp; -{ - init_itemlist_from_varlist (itp, all_visible_variables); - return 0; -} - -static int -it_init_setopts (itp) - ITEMLIST *itp; -{ - STRINGLIST *sl; - - sl = strlist_create (0); - sl->list = get_minus_o_opts (); - sl->list_len = strvec_len (sl->list); - itp->slist = sl; - itp->flags |= LIST_DONTFREEMEMBERS; - return 0; -} - -static int -it_init_shopts (itp) - ITEMLIST *itp; -{ - STRINGLIST *sl; - - sl = strlist_create (0); - sl->list = get_shopt_options (); - sl->list_len = strvec_len (sl->list); - itp->slist = sl; - itp->flags |= LIST_DONTFREEMEMBERS; - return 0; -} - -/* Generate a list of all matches for TEXT using the STRINGLIST in itp->slist - as the list of possibilities. If the itemlist has been marked dirty or - it should be regenerated every time, destroy the old STRINGLIST and make a - new one before trying the match. TEXT is dequoted before attempting a - match. */ -static STRINGLIST * -gen_matches_from_itemlist (itp, text) - ITEMLIST *itp; - const char *text; -{ - STRINGLIST *ret, *sl; - int tlen, i, n; - char *ntxt; - - if ((itp->flags & (LIST_DIRTY|LIST_DYNAMIC)) || - (itp->flags & LIST_INITIALIZED) == 0) - { - if (itp->flags & (LIST_DIRTY|LIST_DYNAMIC)) - clean_itemlist (itp); - if ((itp->flags & LIST_INITIALIZED) == 0) - initialize_itemlist (itp); - } - if (itp->slist == 0) - return ((STRINGLIST *)NULL); - ret = strlist_create (itp->slist->list_len+1); - sl = itp->slist; - - ntxt = bash_dequote_text (text); - tlen = STRLEN (ntxt); - - for (i = n = 0; i < sl->list_len; i++) - { - if (tlen == 0 || STREQN (sl->list[i], ntxt, tlen)) - ret->list[n++] = STRDUP (sl->list[i]); - } - ret->list[ret->list_len = n] = (char *)NULL; - - FREE (ntxt); - return ret; -} - -/* A wrapper for rl_filename_completion_function that dequotes the filename - before attempting completions. */ -static char * -pcomp_filename_completion_function (text, state) - const char *text; - int state; -{ - static char *dfn; /* dequoted filename */ - int iscompgen, iscompleting; - - if (state == 0) - { - FREE (dfn); - /* remove backslashes quoting special characters in filenames. */ - /* There are roughly three paths we can follow to get here: - 1. complete -f - 2. compgen -f "$word" from a completion function - 3. compgen -f "$word" from the command line - They all need to be handled. - - In the first two cases, readline will run the filename dequoting - function in rl_filename_completion_function if it found a filename - quoting character in the word to be completed - (rl_completion_found_quote). We run the dequoting function here - if we're running compgen, we're not completing, and the - rl_filename_completion_function won't dequote the filename - (rl_completion_found_quote == 0). */ - iscompgen = this_shell_builtin == compgen_builtin; - iscompleting = RL_ISSTATE (RL_STATE_COMPLETING); - if (iscompgen && iscompleting == 0 && rl_completion_found_quote == 0 - && rl_filename_dequoting_function) - { - /* Use rl_completion_quote_character because any single or - double quotes have been removed by the time TEXT makes it - here, and we don't want to remove backslashes inside - quoted strings. */ - dfn = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character); - } - /* Intended to solve a mismatched assumption by bash-completion. If - the text to be completed is empty, but bash-completion turns it into - a quoted string ('') assuming that this code will dequote it before - calling readline, do the dequoting. */ - else if (iscompgen && iscompleting && - pcomp_curtxt && *pcomp_curtxt == 0 && - text && (*text == '\'' || *text == '"') && text[1] == text[0] && text[2] == 0 && - rl_filename_dequoting_function) - dfn = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character); - /* Another mismatched assumption by bash-completion. If compgen is being - run as part of bash-completion, and the argument to compgen is not - the same as the word originally passed to the programmable completion - code, dequote the argument if it has quote characters. It's an - attempt to detect when bash-completion is quoting its filename - argument before calling compgen. */ - /* We could check whether gen_shell_function_matches is in the call - stack by checking whether the gen-shell-function-matches tag is in - the unwind-protect stack, but there's no function to do that yet. - We could simply check whether we're executing in a function by - checking variable_context, and may end up doing that. */ - else if (iscompgen && iscompleting && rl_filename_dequoting_function && - pcomp_curtxt && text && - STREQ (pcomp_curtxt, text) == 0 && - variable_context && - sh_contains_quotes (text)) /* guess */ - dfn = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character); - else - dfn = savestring (text); - } - - return (rl_filename_completion_function (dfn, state)); -} - -#define GEN_COMPS(bmap, flag, it, text, glist, tlist) \ - do { \ - if (bmap & flag) \ - { \ - tlist = gen_matches_from_itemlist (it, text); \ - if (tlist) \ - { \ - glist = strlist_append (glist, tlist); \ - strlist_dispose (tlist); \ - } \ - } \ - } while (0) - -#define GEN_XCOMPS(bmap, flag, text, func, cmatches, glist, tlist) \ - do { \ - if (bmap & flag) \ - { \ - cmatches = rl_completion_matches (text, func); \ - tlist = completions_to_stringlist (cmatches); \ - glist = strlist_append (glist, tlist); \ - strvec_dispose (cmatches); \ - strlist_dispose (tlist); \ - } \ - } while (0) - -/* Functions to generate lists of matches from the actions member of CS. */ - -static STRINGLIST * -gen_action_completions (cs, text) - COMPSPEC *cs; - const char *text; -{ - STRINGLIST *ret, *tmatches; - char **cmatches; /* from rl_completion_matches ... */ - unsigned long flags; - int t; - - ret = tmatches = (STRINGLIST *)NULL; - flags = cs->actions; - - GEN_COMPS (flags, CA_ALIAS, &it_aliases, text, ret, tmatches); - GEN_COMPS (flags, CA_ARRAYVAR, &it_arrayvars, text, ret, tmatches); - GEN_COMPS (flags, CA_BINDING, &it_bindings, text, ret, tmatches); - GEN_COMPS (flags, CA_BUILTIN, &it_builtins, text, ret, tmatches); - GEN_COMPS (flags, CA_DISABLED, &it_disabled, text, ret, tmatches); - GEN_COMPS (flags, CA_ENABLED, &it_enabled, text, ret, tmatches); - GEN_COMPS (flags, CA_EXPORT, &it_exports, text, ret, tmatches); - GEN_COMPS (flags, CA_FUNCTION, &it_functions, text, ret, tmatches); - GEN_COMPS (flags, CA_HELPTOPIC, &it_helptopics, text, ret, tmatches); - GEN_COMPS (flags, CA_HOSTNAME, &it_hostnames, text, ret, tmatches); - GEN_COMPS (flags, CA_JOB, &it_jobs, text, ret, tmatches); - GEN_COMPS (flags, CA_KEYWORD, &it_keywords, text, ret, tmatches); - GEN_COMPS (flags, CA_RUNNING, &it_running, text, ret, tmatches); - GEN_COMPS (flags, CA_SETOPT, &it_setopts, text, ret, tmatches); - GEN_COMPS (flags, CA_SHOPT, &it_shopts, text, ret, tmatches); - GEN_COMPS (flags, CA_SIGNAL, &it_signals, text, ret, tmatches); - GEN_COMPS (flags, CA_STOPPED, &it_stopped, text, ret, tmatches); - GEN_COMPS (flags, CA_VARIABLE, &it_variables, text, ret, tmatches); - - GEN_XCOMPS(flags, CA_COMMAND, text, command_word_completion_function, cmatches, ret, tmatches); - GEN_XCOMPS(flags, CA_FILE, text, pcomp_filename_completion_function, cmatches, ret, tmatches); - GEN_XCOMPS(flags, CA_USER, text, rl_username_completion_function, cmatches, ret, tmatches); - GEN_XCOMPS(flags, CA_GROUP, text, bash_groupname_completion_function, cmatches, ret, tmatches); - GEN_XCOMPS(flags, CA_SERVICE, text, bash_servicename_completion_function, cmatches, ret, tmatches); - - /* And lastly, the special case for directories */ - if (flags & CA_DIRECTORY) - { - t = rl_filename_completion_desired; - rl_completion_mark_symlink_dirs = 1; /* override user preference */ - cmatches = bash_directory_completion_matches (text); - /* If we did not want filename completion before this, and there are - no matches, turn off rl_filename_completion_desired so whatever - matches we get are not treated as filenames (it gets turned on by - rl_filename_completion_function unconditionally). */ - if (t == 0 && cmatches == 0 && rl_filename_completion_desired == 1) - rl_filename_completion_desired = 0; - tmatches = completions_to_stringlist (cmatches); - ret = strlist_append (ret, tmatches); - strvec_dispose (cmatches); - strlist_dispose (tmatches); - } - - return ret; -} - -/* Generate a list of matches for CS->globpat. Unresolved: should this use - TEXT as a match prefix, or just go without? Currently, the code does not - use TEXT, just globs CS->globpat and returns the results. If we do decide - to use TEXT, we should call quote_string_for_globbing before the call to - glob_filename (in which case we could use shell_glob_filename). */ -static STRINGLIST * -gen_globpat_matches (cs, text) - COMPSPEC *cs; - const char *text; -{ - STRINGLIST *sl; - int gflags; - - sl = strlist_create (0); - gflags = glob_star ? GX_GLOBSTAR : 0; - sl->list = glob_filename (cs->globpat, gflags); - if (GLOB_FAILED (sl->list)) - sl->list = (char **)NULL; - if (sl->list) - sl->list_len = sl->list_size = strvec_len (sl->list); - return sl; -} - -/* Perform the shell word expansions on CS->words and return the results. - Again, this ignores TEXT. */ -static STRINGLIST * -gen_wordlist_matches (cs, text) - COMPSPEC *cs; - const char *text; -{ - WORD_LIST *l, *l2; - STRINGLIST *sl; - int nw, tlen; - char *ntxt; /* dequoted TEXT to use in comparisons */ - - if (cs->words == 0 || cs->words[0] == '\0') - return ((STRINGLIST *)NULL); - - /* This used to be a simple expand_string(cs->words, 0), but that won't - do -- there's no way to split a simple list into individual words - that way, since the shell semantics say that word splitting is done - only on the results of expansion. split_at_delims also handles embedded - quoted strings and preserves the quotes for the expand_words_shellexp - function call that follows. */ - /* XXX - this is where this function spends most of its time */ - l = split_at_delims (cs->words, strlen (cs->words), (char *)NULL, -1, 0, (int *)NULL, (int *)NULL); - if (l == 0) - return ((STRINGLIST *)NULL); - /* This will jump back to the top level if the expansion fails... */ - l2 = expand_words_shellexp (l); - dispose_words (l); - - nw = list_length (l2); - sl = strlist_create (nw + 1); - - ntxt = bash_dequote_text (text); - tlen = STRLEN (ntxt); - - for (nw = 0, l = l2; l; l = l->next) - { - if (tlen == 0 || STREQN (l->word->word, ntxt, tlen)) - sl->list[nw++] = STRDUP (l->word->word); - } - sl->list[sl->list_len = nw] = (char *)NULL; - - dispose_words (l2); - FREE (ntxt); - return sl; -} - -#ifdef ARRAY_VARS - -static SHELL_VAR * -bind_comp_words (lwords) - WORD_LIST *lwords; -{ - SHELL_VAR *v; - - v = find_variable_noref ("COMP_WORDS"); - if (v == 0) - v = make_new_array_variable ("COMP_WORDS"); - if (nameref_p (v)) - VUNSETATTR (v, att_nameref); -#if 0 - if (readonly_p (v)) - VUNSETATTR (v, att_readonly); -#endif - if (array_p (v) == 0) - v = convert_var_to_array (v); - v = assign_array_var_from_word_list (v, lwords, 0); - - VUNSETATTR (v, att_invisible); - return v; -} -#endif /* ARRAY_VARS */ - -static void -bind_compfunc_variables (line, ind, lwords, cw, exported) - char *line; - int ind; - WORD_LIST *lwords; - int cw, exported; -{ - char ibuf[INT_STRLEN_BOUND(int) + 1]; - char *value; - SHELL_VAR *v; - size_t llen; - int c; - - /* Set the variables that the function expects while it executes. Maybe - these should be in the function environment (temporary_env). */ - v = bind_variable ("COMP_LINE", line, 0); - if (v && exported) - VSETATTR(v, att_exported); - - /* Post bash-4.2: COMP_POINT is characters instead of bytes. */ - c = line[ind]; - line[ind] = '\0'; - llen = MB_STRLEN (line); - line[ind] = c; - value = inttostr (llen, ibuf, sizeof(ibuf)); - v = bind_int_variable ("COMP_POINT", value, 0); - if (v && exported) - VSETATTR(v, att_exported); - - value = inttostr (rl_completion_type, ibuf, sizeof (ibuf)); - v = bind_int_variable ("COMP_TYPE", value, 0); - if (v && exported) - VSETATTR(v, att_exported); - - value = inttostr (rl_completion_invoking_key, ibuf, sizeof (ibuf)); - v = bind_int_variable ("COMP_KEY", value, 0); - if (v && exported) - VSETATTR(v, att_exported); - - /* Since array variables can't be exported, we don't bother making the - array of words. */ - if (exported == 0) - { -#ifdef ARRAY_VARS - v = bind_comp_words (lwords); - value = inttostr (cw, ibuf, sizeof(ibuf)); - bind_int_variable ("COMP_CWORD", value, 0); -#endif - } - else - array_needs_making = 1; -} - -static void -unbind_compfunc_variables (exported) - int exported; -{ - unbind_variable_noref ("COMP_LINE"); - unbind_variable_noref ("COMP_POINT"); - unbind_variable_noref ("COMP_TYPE"); - unbind_variable_noref ("COMP_KEY"); -#ifdef ARRAY_VARS - unbind_variable_noref ("COMP_WORDS"); - unbind_variable_noref ("COMP_CWORD"); -#endif - if (exported) - array_needs_making = 1; -} - -/* Build the list of words to pass to a function or external command - as arguments. When the function or command is invoked, - - $0 == function or command being invoked - $1 == command name - $2 == word to be completed (possibly null) - $3 == previous word - - Functions can access all of the words in the current command line - with the COMP_WORDS array. External commands cannot; they have to - make do with the COMP_LINE and COMP_POINT variables. */ - -static WORD_LIST * -build_arg_list (cmd, cname, text, lwords, ind) - char *cmd; - const char *cname; - const char *text; - WORD_LIST *lwords; - int ind; -{ - WORD_LIST *ret, *cl, *l; - WORD_DESC *w; - int i; - - ret = (WORD_LIST *)NULL; - w = make_word (cmd); - ret = make_word_list (w, (WORD_LIST *)NULL); /* $0 */ - - w = make_word (cname); /* $1 */ - cl = ret->next = make_word_list (w, (WORD_LIST *)NULL); - - w = make_word (text); - cl->next = make_word_list (w, (WORD_LIST *)NULL); /* $2 */ - cl = cl->next; - - /* Search lwords for current word */ - for (l = lwords, i = 1; l && i < ind-1; l = l->next, i++) - ; - w = (l && l->word) ? copy_word (l->word) : make_word (""); - cl->next = make_word_list (w, (WORD_LIST *)NULL); - - return ret; -} - -/* Build a command string with - $0 == cs->funcname (function to execute for completion list) - $1 == command name (command being completed) - $2 = word to be completed (possibly null) - $3 = previous word - and run in the current shell. The function should put its completion - list into the array variable COMPREPLY. We build a STRINGLIST - from the results and return it. - - Since the shell function should return its list of matches in an array - variable, this does nothing if arrays are not compiled into the shell. */ - -static STRINGLIST * -gen_shell_function_matches (cs, cmd, text, line, ind, lwords, nw, cw, foundp) - COMPSPEC *cs; - const char *cmd; - const char *text; - char *line; - int ind; - WORD_LIST *lwords; - int nw, cw; - int *foundp; -{ - char *funcname; - STRINGLIST *sl; - SHELL_VAR *f, *v; - WORD_LIST *cmdlist; - int fval, found; - sh_parser_state_t ps; - sh_parser_state_t * restrict pps; -#if defined (ARRAY_VARS) - ARRAY *a; -#endif - - found = 0; - if (foundp) - *foundp = found; - - funcname = cs->funcname; - f = find_function (funcname); - if (f == 0) - { - internal_error (_("completion: function `%s' not found"), funcname); - rl_ding (); - rl_on_new_line (); - return ((STRINGLIST *)NULL); - } - -#if !defined (ARRAY_VARS) - return ((STRINGLIST *)NULL); -#else - - /* We pass cw - 1 because command_line_to_word_list returns indices that are - 1-based, while bash arrays are 0-based. */ - bind_compfunc_variables (line, ind, lwords, cw - 1, 0); - - cmdlist = build_arg_list (funcname, cmd, text, lwords, cw); - - pps = &ps; - save_parser_state (pps); - begin_unwind_frame ("gen-shell-function-matches"); - add_unwind_protect (restore_parser_state, (char *)pps); - add_unwind_protect (dispose_words, (char *)cmdlist); - add_unwind_protect (unbind_compfunc_variables, (char *)0); - - fval = execute_shell_function (f, cmdlist); - - discard_unwind_frame ("gen-shell-function-matches"); - restore_parser_state (pps); - - found = fval != EX_NOTFOUND; - if (fval == EX_RETRYFAIL) - found |= PCOMP_RETRYFAIL; - if (foundp) - *foundp = found; - - /* Now clean up and destroy everything. */ - dispose_words (cmdlist); - unbind_compfunc_variables (0); - - /* The list of completions is returned in the array variable COMPREPLY. */ - v = find_variable ("COMPREPLY"); - if (v == 0) - return ((STRINGLIST *)NULL); - if (array_p (v) == 0 && assoc_p (v) == 0) - v = convert_var_to_array (v); - - VUNSETATTR (v, att_invisible); - - a = array_cell (v); - if (found == 0 || (found & PCOMP_RETRYFAIL) || a == 0 || array_p (v) == 0 || array_empty (a)) - sl = (STRINGLIST *)NULL; - else - { - /* XXX - should we filter the list of completions so only those matching - TEXT are returned? Right now, we do not. */ - sl = strlist_create (0); - sl->list = array_to_argv (a, 0); - sl->list_len = sl->list_size = array_num_elements (a); - } - - /* XXX - should we unbind COMPREPLY here? */ - unbind_variable_noref ("COMPREPLY"); - - return (sl); -#endif -} - -/* Build a command string with - $0 == cs->command (command to execute for completion list) - $1 == command name (command being completed) - $2 == word to be completed (possibly null) - $3 == previous word - and run it with command substitution. Parse the results, one word - per line, with backslashes allowed to escape newlines. Build a - STRINGLIST from the results and return it. */ - -static STRINGLIST * -gen_command_matches (cs, cmd, text, line, ind, lwords, nw, cw) - COMPSPEC *cs; - const char *cmd; - const char *text; - char *line; - int ind; - WORD_LIST *lwords; - int nw, cw; -{ - char *csbuf, *cscmd, *t; - int cmdlen, cmdsize, n, ws, we; - WORD_LIST *cmdlist, *cl; - WORD_DESC *tw; - STRINGLIST *sl; - - bind_compfunc_variables (line, ind, lwords, cw, 1); - cmdlist = build_arg_list (cs->command, cmd, text, lwords, cw); - - /* Estimate the size needed for the buffer. */ - n = strlen (cs->command); - cmdsize = n + 1; - for (cl = cmdlist->next; cl; cl = cl->next) - cmdsize += STRLEN (cl->word->word) + 3; - cmdsize += 2; - - /* allocate the string for the command and fill it in. */ - cscmd = (char *)xmalloc (cmdsize + 1); - - strcpy (cscmd, cs->command); /* $0 */ - cmdlen = n; - cscmd[cmdlen++] = ' '; - for (cl = cmdlist->next; cl; cl = cl->next) /* $1, $2, $3, ... */ - { - t = sh_single_quote (cl->word->word ? cl->word->word : ""); - n = strlen (t); - RESIZE_MALLOCED_BUFFER (cscmd, cmdlen, n + 2, cmdsize, 64); - strcpy (cscmd + cmdlen, t); - cmdlen += n; - if (cl->next) - cscmd[cmdlen++] = ' '; - free (t); - } - cscmd[cmdlen] = '\0'; - - tw = command_substitute (cscmd, 0, 0); - csbuf = tw ? tw->word : (char *)NULL; - if (tw) - dispose_word_desc (tw); - - /* Now clean up and destroy everything. */ - dispose_words (cmdlist); - free (cscmd); - unbind_compfunc_variables (1); - - if (csbuf == 0 || *csbuf == '\0') - { - FREE (csbuf); - return ((STRINGLIST *)NULL); - } - - /* Now break CSBUF up at newlines, with backslash allowed to escape a - newline, and put the individual words into a STRINGLIST. */ - sl = strlist_create (16); - for (ws = 0; csbuf[ws]; ) - { - we = ws; - while (csbuf[we] && csbuf[we] != '\n') - { - if (csbuf[we] == '\\' && csbuf[we+1] == '\n') - we++; - we++; - } - t = substring (csbuf, ws, we); - if (sl->list_len >= sl->list_size - 1) - strlist_resize (sl, sl->list_size + 16); - sl->list[sl->list_len++] = t; - while (csbuf[we] == '\n') we++; - ws = we; - } - sl->list[sl->list_len] = (char *)NULL; - - free (csbuf); - return (sl); -} - -static WORD_LIST * -command_line_to_word_list (line, llen, sentinel, nwp, cwp) - char *line; - int llen, sentinel, *nwp, *cwp; -{ - WORD_LIST *ret; - const char *delims; - -#if 0 - delims = "()<>;&| \t\n"; /* shell metacharacters break words */ -#else - delims = rl_completer_word_break_characters; -#endif - ret = split_at_delims (line, llen, delims, sentinel, SD_NOQUOTEDELIM|SD_COMPLETE, nwp, cwp); - return (ret); -} - -/* Evaluate COMPSPEC *cs and return all matches for WORD. */ - -STRINGLIST * -gen_compspec_completions (cs, cmd, word, start, end, foundp) - COMPSPEC *cs; - const char *cmd; - const char *word; - int start, end; - int *foundp; -{ - STRINGLIST *ret, *tmatches; - char *line; - int llen, nw, cw, found, foundf; - WORD_LIST *lwords; - WORD_DESC *lw; - COMPSPEC *tcs; - - found = 1; - -#ifdef DEBUG - debug_printf ("gen_compspec_completions (%s, %s, %d, %d)", cmd, word, start, end); - debug_printf ("gen_compspec_completions: %s -> %p", cmd, cs); -#endif - ret = gen_action_completions (cs, word); -#ifdef DEBUG - if (ret && progcomp_debug) - { - debug_printf ("gen_action_completions (%p, %s) -->", cs, word); - strlist_print (ret, "\t"); - rl_on_new_line (); - } -#endif - - /* Now we start generating completions based on the other members of CS. */ - if (cs->globpat) - { - tmatches = gen_globpat_matches (cs, word); - if (tmatches) - { -#ifdef DEBUG - if (progcomp_debug) - { - debug_printf ("gen_globpat_matches (%p, %s) -->", cs, word); - strlist_print (tmatches, "\t"); - rl_on_new_line (); - } -#endif - ret = strlist_append (ret, tmatches); - strlist_dispose (tmatches); - rl_filename_completion_desired = 1; - } - } - - if (cs->words) - { - tmatches = gen_wordlist_matches (cs, word); - if (tmatches) - { -#ifdef DEBUG - if (progcomp_debug) - { - debug_printf ("gen_wordlist_matches (%p, %s) -->", cs, word); - strlist_print (tmatches, "\t"); - rl_on_new_line (); - } -#endif - ret = strlist_append (ret, tmatches); - strlist_dispose (tmatches); - } - } - - lwords = (WORD_LIST *)NULL; - line = (char *)NULL; - if (cs->command || cs->funcname) - { - /* If we have a command or function to execute, we need to first break - the command line into individual words, find the number of words, - and find the word in the list containing the word to be completed. */ - line = substring (pcomp_line, start, end); - llen = end - start; - -#ifdef DEBUG - debug_printf ("command_line_to_word_list (%s, %d, %d, %p, %p)", - line, llen, pcomp_ind - start, &nw, &cw); -#endif - lwords = command_line_to_word_list (line, llen, pcomp_ind - start, &nw, &cw); - /* If we skipped a NULL word at the beginning of the line, add it back */ - if (lwords && lwords->word && cmd[0] == 0 && lwords->word->word[0] != 0) - { - lw = make_bare_word (cmd); - lwords = make_word_list (lw, lwords); - nw++; - cw++; - } -#ifdef DEBUG - if (lwords == 0 && llen > 0) - debug_printf ("ERROR: command_line_to_word_list returns NULL"); - else if (progcomp_debug) - { - debug_printf ("command_line_to_word_list -->"); - printf ("\t"); - print_word_list (lwords, "!"); - printf ("\n"); - fflush(stdout); - rl_on_new_line (); - } -#endif - } - - if (cs->funcname) - { - foundf = 0; - tmatches = gen_shell_function_matches (cs, cmd, word, line, pcomp_ind - start, lwords, nw, cw, &foundf); - if (foundf != 0) - found = foundf; - if (tmatches) - { -#ifdef DEBUG - if (progcomp_debug) - { - debug_printf ("gen_shell_function_matches (%p, %s, %s, %p, %d, %d) -->", cs, cmd, word, lwords, nw, cw); - strlist_print (tmatches, "\t"); - rl_on_new_line (); - } -#endif - ret = strlist_append (ret, tmatches); - strlist_dispose (tmatches); - } - } - - if (cs->command) - { - tmatches = gen_command_matches (cs, cmd, word, line, pcomp_ind - start, lwords, nw, cw); - if (tmatches) - { -#ifdef DEBUG - if (progcomp_debug) - { - debug_printf ("gen_command_matches (%p, %s, %s, %p, %d, %d) -->", cs, cmd, word, lwords, nw, cw); - strlist_print (tmatches, "\t"); - rl_on_new_line (); - } -#endif - ret = strlist_append (ret, tmatches); - strlist_dispose (tmatches); - } - } - - if (cs->command || cs->funcname) - { - if (lwords) - dispose_words (lwords); - FREE (line); - } - - if (foundp) - *foundp = found; - - if (found == 0 || (found & PCOMP_RETRYFAIL)) - { - strlist_dispose (ret); - return NULL; - } - - if (cs->filterpat) - { - tmatches = filter_stringlist (ret, cs->filterpat, word); -#ifdef DEBUG - if (progcomp_debug) - { - debug_printf ("filter_stringlist (%p, %s, %s) -->", ret, cs->filterpat, word); - strlist_print (tmatches, "\t"); - rl_on_new_line (); - } -#endif - if (ret && ret != tmatches) - { - FREE (ret->list); - free (ret); - } - ret = tmatches; - } - - if (cs->prefix || cs->suffix) - ret = strlist_prefix_suffix (ret, cs->prefix, cs->suffix); - - /* If no matches have been generated and the user has specified that - directory completion should be done as a default, call - gen_action_completions again to generate a list of matching directory - names. */ - if ((ret == 0 || ret->list_len == 0) && (cs->options & COPT_DIRNAMES)) - { - tcs = compspec_create (); - tcs->actions = CA_DIRECTORY; - FREE (ret); - ret = gen_action_completions (tcs, word); - compspec_dispose (tcs); - } - else if (cs->options & COPT_PLUSDIRS) - { - tcs = compspec_create (); - tcs->actions = CA_DIRECTORY; - tmatches = gen_action_completions (tcs, word); - ret = strlist_append (ret, tmatches); - strlist_dispose (tmatches); - compspec_dispose (tcs); - } - - return (ret); -} - -void -pcomp_set_readline_variables (flags, nval) - int flags, nval; -{ - /* If the user specified that the compspec returns filenames, make - sure that readline knows it. */ - if (flags & COPT_FILENAMES) - rl_filename_completion_desired = nval; - /* If the user doesn't want a space appended, tell readline. */ - if (flags & COPT_NOSPACE) - rl_completion_suppress_append = nval; - /* The value here is inverted, since the default is on and the `noquote' - option is supposed to turn it off */ - if (flags & COPT_NOQUOTE) - rl_filename_quoting_desired = 1 - nval; - if (flags & COPT_NOSORT) - rl_sort_completion_matches = 1 - nval; -} - -/* Set or unset FLAGS in the options word of the current compspec. - SET_OR_UNSET is 1 for setting, 0 for unsetting. */ -void -pcomp_set_compspec_options (cs, flags, set_or_unset) - COMPSPEC *cs; - int flags, set_or_unset; -{ - if (cs == 0 && ((cs = pcomp_curcs) == 0)) - return; - if (set_or_unset) - cs->options |= flags; - else - cs->options &= ~flags; -} - -static STRINGLIST * -gen_progcomp_completions (ocmd, cmd, word, start, end, foundp, retryp, lastcs) - const char *ocmd; - const char *cmd; - const char *word; - int start, end; - int *foundp, *retryp; - COMPSPEC **lastcs; -{ - COMPSPEC *cs, *oldcs; - const char *oldcmd, *oldtxt; - STRINGLIST *ret; - - cs = progcomp_search (ocmd); - - if (cs == 0 || cs == *lastcs) - { -#if 0 - if (foundp) - *foundp = 0; -#endif - return (NULL); - } - - if (*lastcs) - compspec_dispose (*lastcs); - cs->refcount++; /* XXX */ - *lastcs = cs; - - cs = compspec_copy (cs); - - oldcs = pcomp_curcs; - oldcmd = pcomp_curcmd; - oldtxt = pcomp_curtxt; - - pcomp_curcs = cs; - pcomp_curcmd = cmd; - pcomp_curtxt = word; - - ret = gen_compspec_completions (cs, cmd, word, start, end, foundp); - - pcomp_curcs = oldcs; - pcomp_curcmd = oldcmd; - pcomp_curtxt = oldtxt; - - /* We need to conditionally handle setting *retryp here */ - if (retryp) - *retryp = foundp && (*foundp & PCOMP_RETRYFAIL); - - if (foundp) - { - *foundp &= ~PCOMP_RETRYFAIL; - *foundp |= cs->options; - } - - compspec_dispose (cs); - return ret; -} - -/* The driver function for the programmable completion code. Returns a list - of matches for WORD, which is an argument to command CMD. START and END - bound the command currently being completed in pcomp_line (usually - rl_line_buffer). */ -char ** -programmable_completions (cmd, word, start, end, foundp) - const char *cmd; - const char *word; - int start, end, *foundp; -{ - COMPSPEC *lastcs; - STRINGLIST *ret; - char **rmatches, *t; - int found, retry, count; - char *ocmd; - int oend; -#if defined (ALIAS) - alias_t *al; -#endif - - lastcs = 0; - found = count = 0; - - pcomp_line = rl_line_buffer; - pcomp_ind = rl_point; - - ocmd = (char *)cmd; - oend = end; - - do - { - retry = 0; - - /* We look at the basename of CMD if the full command does not have - an associated COMPSPEC. */ - ret = gen_progcomp_completions (ocmd, ocmd, word, start, oend, &found, &retry, &lastcs); - if (found == 0) - { - t = strrchr (ocmd, '/'); - if (t && *(++t)) - ret = gen_progcomp_completions (t, ocmd, word, start, oend, &found, &retry, &lastcs); - } - - if (found == 0) - ret = gen_progcomp_completions (DEFAULTCMD, ocmd, word, start, oend, &found, &retry, &lastcs); - -#if defined (ALIAS) - /* Look up any alias for CMD, try to gen completions for it */ - /* Look up the alias, find the value, build a new line replacing CMD - with that value, offsetting PCOMP_IND and END appropriately, reset - PCOMP_LINE to the new line and OCMD with the new command name, then - call gen_progcomp_completions again. We could use alias_expand for - this, but it does more (and less) than we need right now. */ - if (found == 0 && retry == 0 && progcomp_alias && (al = find_alias (ocmd))) - { - char *ncmd, *nline, *ntxt; - int ind, lendiff; - size_t nlen, olen, llen; - - /* We found an alias for OCMD. Take the value and build a new line */ - ntxt = al->value; - nlen = strlen (ntxt); - if (nlen == 0) - break; - olen = strlen (ocmd); - lendiff = nlen - olen; /* can be negative */ - llen = strlen (pcomp_line); - - nline = (char *)xmalloc (llen + lendiff + 1); - if (start > 0) - strncpy (nline, pcomp_line, start); - strncpy (nline + start, ntxt, nlen); - strcpy (nline + start + nlen, pcomp_line + start + olen); - - /* Find the first word of the alias value and use that as OCMD. We - don't check the alias value to see whether it begins with a valid - command name, so this can be fooled. */ - ind = skip_to_delim (ntxt, 0, "()<>;&| \t\n", SD_NOJMP|SD_COMPLETE); - if (ind > 0) - ncmd = substring (ntxt, 0, ind); - else - { - free (nline); - break; /* will free pcomp_line and ocmd later */ - } - - /* Adjust PCOMP_IND and OEND appropriately */ - pcomp_ind += lendiff; - oend += lendiff; - - /* Set up values with new line. WORD stays the same. */ - if (ocmd != cmd) - free (ocmd); - if (pcomp_line != rl_line_buffer) - free (pcomp_line); - - ocmd = ncmd; - pcomp_line = nline; - - /* And go back and start over. */ - retry = 1; - } -#endif /* ALIAS */ - - count++; - - if (count > 32) - { - internal_warning (_("programmable_completion: %s: possible retry loop"), cmd); - break; - } - } - while (retry); - - if (pcomp_line != rl_line_buffer) - free (pcomp_line); - if (ocmd != cmd) - free (ocmd); - - if (ret) - { - rmatches = ret->list; - free (ret); - } - else - rmatches = (char **)NULL; - - if (foundp) - *foundp = found; - - if (lastcs) /* XXX - should be while? */ - compspec_dispose (lastcs); - - /* XXX restore pcomp_line and pcomp_ind? */ - pcomp_line = rl_line_buffer; - pcomp_ind = rl_point; - - return (rmatches); -} - -#endif /* PROGRAMMABLE_COMPLETION */ diff --git a/third_party/bash/pcomplete.h b/third_party/bash/pcomplete.h deleted file mode 100644 index 2a68e6a3f..000000000 --- a/third_party/bash/pcomplete.h +++ /dev/null @@ -1,177 +0,0 @@ -/* pcomplete.h - structure definitions and other stuff for programmable - completion. */ - -/* Copyright (C) 1999-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_PCOMPLETE_H_) -# define _PCOMPLETE_H_ - -#include "stdc.h" -#include "hashlib.h" - -typedef struct compspec { - int refcount; - unsigned long actions; - unsigned long options; - char *globpat; - char *words; - char *prefix; - char *suffix; - char *funcname; - char *command; - char *lcommand; - char *filterpat; -} COMPSPEC; - -/* Values for COMPSPEC actions. These are things the shell knows how to - build internally. */ -#define CA_ALIAS (1<<0) -#define CA_ARRAYVAR (1<<1) -#define CA_BINDING (1<<2) -#define CA_BUILTIN (1<<3) -#define CA_COMMAND (1<<4) -#define CA_DIRECTORY (1<<5) -#define CA_DISABLED (1<<6) -#define CA_ENABLED (1<<7) -#define CA_EXPORT (1<<8) -#define CA_FILE (1<<9) -#define CA_FUNCTION (1<<10) -#define CA_GROUP (1<<11) -#define CA_HELPTOPIC (1<<12) -#define CA_HOSTNAME (1<<13) -#define CA_JOB (1<<14) -#define CA_KEYWORD (1<<15) -#define CA_RUNNING (1<<16) -#define CA_SERVICE (1<<17) -#define CA_SETOPT (1<<18) -#define CA_SHOPT (1<<19) -#define CA_SIGNAL (1<<20) -#define CA_STOPPED (1<<21) -#define CA_USER (1<<22) -#define CA_VARIABLE (1<<23) - -/* Values for COMPSPEC options field. */ -#define COPT_RESERVED (1<<0) /* reserved for other use */ -#define COPT_DEFAULT (1<<1) -#define COPT_FILENAMES (1<<2) -#define COPT_DIRNAMES (1<<3) -#define COPT_NOQUOTE (1<<4) -#define COPT_NOSPACE (1<<5) -#define COPT_BASHDEFAULT (1<<6) -#define COPT_PLUSDIRS (1<<7) -#define COPT_NOSORT (1<<8) - -#define COPT_LASTUSER COPT_NOSORT - -#define PCOMP_RETRYFAIL (COPT_LASTUSER << 1) -#define PCOMP_NOTFOUND (COPT_LASTUSER << 2) - - -/* List of items is used by the code that implements the programmable - completions. */ -typedef struct _list_of_items { - int flags; - int (*list_getter) PARAMS((struct _list_of_items *)); /* function to call to get the list */ - - STRINGLIST *slist; - - /* These may or may not be used. */ - STRINGLIST *genlist; /* for handing to the completion code one item at a time */ - int genindex; /* index of item last handed to completion code */ - -} ITEMLIST; - -/* Values for ITEMLIST -> flags */ -#define LIST_DYNAMIC 0x001 -#define LIST_DIRTY 0x002 -#define LIST_INITIALIZED 0x004 -#define LIST_MUSTSORT 0x008 -#define LIST_DONTFREE 0x010 -#define LIST_DONTFREEMEMBERS 0x020 - -#define EMPTYCMD "_EmptycmD_" -#define DEFAULTCMD "_DefaultCmD_" -#define INITIALWORD "_InitialWorD_" - -extern HASH_TABLE *prog_completes; - -extern char *pcomp_line; -extern int pcomp_ind; - -extern int prog_completion_enabled; -extern int progcomp_alias; - -/* Not all of these are used yet. */ -extern ITEMLIST it_aliases; -extern ITEMLIST it_arrayvars; -extern ITEMLIST it_bindings; -extern ITEMLIST it_builtins; -extern ITEMLIST it_commands; -extern ITEMLIST it_directories; -extern ITEMLIST it_disabled; -extern ITEMLIST it_enabled; -extern ITEMLIST it_exports; -extern ITEMLIST it_files; -extern ITEMLIST it_functions; -extern ITEMLIST it_groups; -extern ITEMLIST it_helptopics; -extern ITEMLIST it_hostnames; -extern ITEMLIST it_jobs; -extern ITEMLIST it_keywords; -extern ITEMLIST it_running; -extern ITEMLIST it_services; -extern ITEMLIST it_setopts; -extern ITEMLIST it_shopts; -extern ITEMLIST it_signals; -extern ITEMLIST it_stopped; -extern ITEMLIST it_users; -extern ITEMLIST it_variables; - -extern COMPSPEC *pcomp_curcs; -extern const char *pcomp_curcmd; - -/* Functions from pcomplib.c */ -extern COMPSPEC *compspec_create PARAMS((void)); -extern void compspec_dispose PARAMS((COMPSPEC *)); -extern COMPSPEC *compspec_copy PARAMS((COMPSPEC *)); - -extern void progcomp_create PARAMS((void)); -extern void progcomp_flush PARAMS((void)); -extern void progcomp_dispose PARAMS((void)); - -extern int progcomp_size PARAMS((void)); - -extern int progcomp_insert PARAMS((char *, COMPSPEC *)); -extern int progcomp_remove PARAMS((char *)); - -extern COMPSPEC *progcomp_search PARAMS((const char *)); - -extern void progcomp_walk PARAMS((hash_wfunc *)); - -/* Functions from pcomplete.c */ -extern void set_itemlist_dirty PARAMS((ITEMLIST *)); - -extern STRINGLIST *completions_to_stringlist PARAMS((char **)); - -extern STRINGLIST *gen_compspec_completions PARAMS((COMPSPEC *, const char *, const char *, int, int, int *)); -extern char **programmable_completions PARAMS((const char *, const char *, int, int, int *)); - -extern void pcomp_set_readline_variables PARAMS((int, int)); -extern void pcomp_set_compspec_options PARAMS((COMPSPEC *, int, int)); -#endif /* _PCOMPLETE_H_ */ diff --git a/third_party/bash/pcomplib.c b/third_party/bash/pcomplib.c deleted file mode 100644 index f3ecea662..000000000 --- a/third_party/bash/pcomplib.c +++ /dev/null @@ -1,228 +0,0 @@ -/* pcomplib.c - library functions for programmable completion. */ - -/* Copyright (C) 1999-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if defined (PROGRAMMABLE_COMPLETION) - -#include "bashansi.h" -#include - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include "bashintl.h" - -#include "shell.h" -#include "pcomplete.h" - -#define COMPLETE_HASH_BUCKETS 512 /* must be power of two */ - -#define STRDUP(x) ((x) ? savestring (x) : (char *)NULL) - -HASH_TABLE *prog_completes = (HASH_TABLE *)NULL; - -static void free_progcomp PARAMS((PTR_T)); - -COMPSPEC * -compspec_create () -{ - COMPSPEC *ret; - - ret = (COMPSPEC *)xmalloc (sizeof (COMPSPEC)); - ret->refcount = 0; - - ret->actions = (unsigned long)0; - ret->options = (unsigned long)0; - - ret->globpat = (char *)NULL; - ret->words = (char *)NULL; - ret->prefix = (char *)NULL; - ret->suffix = (char *)NULL; - ret->funcname = (char *)NULL; - ret->command = (char *)NULL; - ret->lcommand = (char *)NULL; - ret->filterpat = (char *)NULL; - - return ret; -} - -void -compspec_dispose (cs) - COMPSPEC *cs; -{ - cs->refcount--; - if (cs->refcount == 0) - { - FREE (cs->globpat); - FREE (cs->words); - FREE (cs->prefix); - FREE (cs->suffix); - FREE (cs->funcname); - FREE (cs->command); - FREE (cs->lcommand); - FREE (cs->filterpat); - - free (cs); - } -} - -COMPSPEC * -compspec_copy (cs) - COMPSPEC *cs; -{ - COMPSPEC *new; - - new = (COMPSPEC *)xmalloc (sizeof (COMPSPEC)); - - new->refcount = 1; /* was cs->refcount, but this is a fresh copy */ - new->actions = cs->actions; - new->options = cs->options; - - new->globpat = STRDUP (cs->globpat); - new->words = STRDUP (cs->words); - new->prefix = STRDUP (cs->prefix); - new->suffix = STRDUP (cs->suffix); - new->funcname = STRDUP (cs->funcname); - new->command = STRDUP (cs->command); - new->lcommand = STRDUP (cs->lcommand); - new->filterpat = STRDUP (cs->filterpat); - - return new; -} - -void -progcomp_create () -{ - if (prog_completes == 0) - prog_completes = hash_create (COMPLETE_HASH_BUCKETS); -} - -int -progcomp_size () -{ - return (HASH_ENTRIES (prog_completes)); -} - -static void -free_progcomp (data) - PTR_T data; -{ - COMPSPEC *cs; - - cs = (COMPSPEC *)data; - compspec_dispose (cs); -} - -void -progcomp_flush () -{ - if (prog_completes) - hash_flush (prog_completes, free_progcomp); -} - -void -progcomp_dispose () -{ - if (prog_completes) - hash_dispose (prog_completes); - prog_completes = (HASH_TABLE *)NULL; -} - -int -progcomp_remove (cmd) - char *cmd; -{ - register BUCKET_CONTENTS *item; - - if (prog_completes == 0) - return 1; - - item = hash_remove (cmd, prog_completes, 0); - if (item) - { - if (item->data) - free_progcomp (item->data); - free (item->key); - free (item); - return (1); - } - return (0); -} - -int -progcomp_insert (cmd, cs) - char *cmd; - COMPSPEC *cs; -{ - register BUCKET_CONTENTS *item; - - if (cs == NULL) - programming_error (_("progcomp_insert: %s: NULL COMPSPEC"), cmd); - - if (prog_completes == 0) - progcomp_create (); - - cs->refcount++; - item = hash_insert (cmd, prog_completes, 0); - if (item->data) - free_progcomp (item->data); - else - item->key = savestring (cmd); - item->data = cs; - - return 1; -} - -COMPSPEC * -progcomp_search (cmd) - const char *cmd; -{ - register BUCKET_CONTENTS *item; - COMPSPEC *cs; - - if (prog_completes == 0) - return ((COMPSPEC *)NULL); - - item = hash_search (cmd, prog_completes, 0); - - if (item == NULL) - return ((COMPSPEC *)NULL); - - cs = (COMPSPEC *)item->data; - - return (cs); -} - -void -progcomp_walk (pfunc) - hash_wfunc *pfunc; -{ - if (prog_completes == 0 || pfunc == 0 || HASH_ENTRIES (prog_completes) == 0) - return; - - hash_walk (prog_completes, pfunc); -} - -#endif /* PROGRAMMABLE_COMPLETION */ diff --git a/third_party/bash/pipesize.h b/third_party/bash/pipesize.h deleted file mode 100644 index 816a0b2d1..000000000 --- a/third_party/bash/pipesize.h +++ /dev/null @@ -1,8 +0,0 @@ -/* - * pipesize.h - * - * This file is automatically generated by psize.sh - * Do not edit! - */ - -#define PIPESIZE 65536 diff --git a/third_party/bash/posixdir.h b/third_party/bash/posixdir.h deleted file mode 100644 index b737bd7d1..000000000 --- a/third_party/bash/posixdir.h +++ /dev/null @@ -1,71 +0,0 @@ -/* posixdir.h -- Posix directory reading includes and defines. */ - -/* Copyright (C) 1987,1991,2012,2019,2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -/* This file should be included instead of or . */ - -#if !defined (_POSIXDIR_H_) -#define _POSIXDIR_H_ - -#if defined (HAVE_DIRENT_H) -# include -# if defined (HAVE_STRUCT_DIRENT_D_NAMLEN) -# define D_NAMLEN(d) ((d)->d_namlen) -# else -# define D_NAMLEN(d) (strlen ((d)->d_name)) -# endif /* !HAVE_STRUCT_DIRENT_D_NAMLEN */ -#else -# if defined (HAVE_SYS_NDIR_H) -# include -# endif -# if defined (HAVE_SYS_DIR_H) -# include -# endif -# if defined (HAVE_NDIR_H) -# include -# endif -# if !defined (dirent) -# define dirent direct -# endif /* !dirent */ -# define D_NAMLEN(d) ((d)->d_namlen) -#endif /* !HAVE_DIRENT_H */ - -/* The bash code fairly consistently uses d_fileno; make sure it's available */ -#if defined (HAVE_STRUCT_DIRENT_D_INO) && !defined (HAVE_STRUCT_DIRENT_D_FILENO) -# define d_fileno d_ino -#endif - -/* Posix does not require that the d_ino field be present, and some - systems do not provide it. */ -#if !defined (HAVE_STRUCT_DIRENT_D_INO) || defined (BROKEN_DIRENT_D_INO) -# define REAL_DIR_ENTRY(dp) 1 -#else -# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) -#endif /* _POSIX_SOURCE */ - -#if defined (HAVE_STRUCT_DIRENT_D_INO) && !defined (BROKEN_DIRENT_D_INO) -# define D_INO_AVAILABLE -#endif - -/* Signal the rest of the code that it can safely use dirent.d_fileno */ -#if defined (D_INO_AVAILABLE) || defined (HAVE_STRUCT_DIRENT_D_FILENO) -# define D_FILENO_AVAILABLE 1 -#endif - -#endif /* !_POSIXDIR_H_ */ diff --git a/third_party/bash/posixjmp.h b/third_party/bash/posixjmp.h deleted file mode 100644 index 9c7e99ed4..000000000 --- a/third_party/bash/posixjmp.h +++ /dev/null @@ -1,46 +0,0 @@ -/* posixjmp.h -- wrapper for setjmp.h with changes for POSIX systems. */ - -/* Copyright (C) 1987,1991-2015 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#ifndef _POSIXJMP_H_ -#define _POSIXJMP_H_ - -#include - -/* This *must* be included *after* config.h */ - -#if defined (HAVE_POSIX_SIGSETJMP) -# define procenv_t sigjmp_buf - -# define setjmp_nosigs(x) sigsetjmp((x), 0) -# define setjmp_sigs(x) sigsetjmp((x), 1) - -# define _rl_longjmp(x, n) siglongjmp((x), (n)) -# define sh_longjmp(x, n) siglongjmp((x), (n)) -#else -# define procenv_t jmp_buf - -# define setjmp_nosigs setjmp -# define setjmp_sigs setjmp - -# define _rl_longjmp(x, n) longjmp((x), (n)) -# define sh_longjmp(x, n) longjmp((x), (n)) -#endif - -#endif /* _POSIXJMP_H_ */ diff --git a/third_party/bash/posixselect.h b/third_party/bash/posixselect.h deleted file mode 100644 index da6a1ace0..000000000 --- a/third_party/bash/posixselect.h +++ /dev/null @@ -1,47 +0,0 @@ -/* posixselect.h -- wrapper for select(2) includes and definitions */ - -/* Copyright (C) 2009 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#ifndef _POSIXSELECT_H_ -#define _POSIXSELECT_H_ - -#if defined (FD_SET) && !defined (HAVE_SELECT) -# define HAVE_SELECT 1 -#endif - -#if defined (HAVE_SELECT) -# if !defined (HAVE_SYS_SELECT_H) || !defined (M_UNIX) -# include -# endif -#endif /* HAVE_SELECT */ -#if defined (HAVE_SYS_SELECT_H) -# include -#endif - -#ifndef USEC_PER_SEC -# define USEC_PER_SEC 1000000 -#endif - -#define USEC_TO_TIMEVAL(us, tv) \ -do { \ - (tv).tv_sec = (us) / USEC_PER_SEC; \ - (tv).tv_usec = (us) % USEC_PER_SEC; \ -} while (0) - -#endif /* _POSIXSELECT_H_ */ diff --git a/third_party/bash/posixstat.h b/third_party/bash/posixstat.h deleted file mode 100644 index b60778606..000000000 --- a/third_party/bash/posixstat.h +++ /dev/null @@ -1,162 +0,0 @@ -/* posixstat.h -- Posix stat(2) definitions for systems that - don't have them. */ - -/* Copyright (C) 1987-2019 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -/* This file should be included instead of . - It relies on the local sys/stat.h to work though. */ -#if !defined (_POSIXSTAT_H_) -#define _POSIXSTAT_H_ - -#include - -#if defined (STAT_MACROS_BROKEN) -# undef S_ISBLK -# undef S_ISCHR -# undef S_ISDIR -# undef S_ISFIFO -# undef S_ISREG -# undef S_ISLNK -#endif /* STAT_MACROS_BROKEN */ - -/* These are guaranteed to work only on isc386 */ -#if !defined (S_IFDIR) && !defined (S_ISDIR) -# define S_IFDIR 0040000 -#endif /* !S_IFDIR && !S_ISDIR */ -#if !defined (S_IFMT) -# define S_IFMT 0170000 -#endif /* !S_IFMT */ - -/* Posix 1003.1 5.6.1.1 file types */ - -/* Some Posix-wannabe systems define _S_IF* macros instead of S_IF*, but - do not provide the S_IS* macros that Posix requires. */ - -#if defined (_S_IFMT) && !defined (S_IFMT) -#define S_IFMT _S_IFMT -#endif -#if defined (_S_IFIFO) && !defined (S_IFIFO) -#define S_IFIFO _S_IFIFO -#endif -#if defined (_S_IFCHR) && !defined (S_IFCHR) -#define S_IFCHR _S_IFCHR -#endif -#if defined (_S_IFDIR) && !defined (S_IFDIR) -#define S_IFDIR _S_IFDIR -#endif -#if defined (_S_IFBLK) && !defined (S_IFBLK) -#define S_IFBLK _S_IFBLK -#endif -#if defined (_S_IFREG) && !defined (S_IFREG) -#define S_IFREG _S_IFREG -#endif -#if defined (_S_IFLNK) && !defined (S_IFLNK) -#define S_IFLNK _S_IFLNK -#endif -#if defined (_S_IFSOCK) && !defined (S_IFSOCK) -#define S_IFSOCK _S_IFSOCK -#endif - -/* Test for each symbol individually and define the ones necessary (some - systems claiming Posix compatibility define some but not all). */ - -#if defined (S_IFBLK) && !defined (S_ISBLK) -#define S_ISBLK(m) (((m)&S_IFMT) == S_IFBLK) /* block device */ -#endif - -#if defined (S_IFCHR) && !defined (S_ISCHR) -#define S_ISCHR(m) (((m)&S_IFMT) == S_IFCHR) /* character device */ -#endif - -#if defined (S_IFDIR) && !defined (S_ISDIR) -#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) /* directory */ -#endif - -#if defined (S_IFREG) && !defined (S_ISREG) -#define S_ISREG(m) (((m)&S_IFMT) == S_IFREG) /* file */ -#endif - -#if defined (S_IFIFO) && !defined (S_ISFIFO) -#define S_ISFIFO(m) (((m)&S_IFMT) == S_IFIFO) /* fifo - named pipe */ -#endif - -#if defined (S_IFLNK) && !defined (S_ISLNK) -#define S_ISLNK(m) (((m)&S_IFMT) == S_IFLNK) /* symbolic link */ -#endif - -#if defined (S_IFSOCK) && !defined (S_ISSOCK) -#define S_ISSOCK(m) (((m)&S_IFMT) == S_IFSOCK) /* socket */ -#endif - -/* - * POSIX 1003.1 5.6.1.2 File Modes - */ - -#if !defined (S_IRWXU) -# if !defined (S_IREAD) -# define S_IREAD 00400 -# define S_IWRITE 00200 -# define S_IEXEC 00100 -# endif /* S_IREAD */ - -# if !defined (S_IRUSR) -# define S_IRUSR S_IREAD /* read, owner */ -# define S_IWUSR S_IWRITE /* write, owner */ -# define S_IXUSR S_IEXEC /* execute, owner */ - -# define S_IRGRP (S_IREAD >> 3) /* read, group */ -# define S_IWGRP (S_IWRITE >> 3) /* write, group */ -# define S_IXGRP (S_IEXEC >> 3) /* execute, group */ - -# define S_IROTH (S_IREAD >> 6) /* read, other */ -# define S_IWOTH (S_IWRITE >> 6) /* write, other */ -# define S_IXOTH (S_IEXEC >> 6) /* execute, other */ -# endif /* !S_IRUSR */ - -# define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR) -# define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP) -# define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH) -#else /* !S_IRWXU */ - /* S_IRWXU is defined, but "group" and "other" bits might not be - (happens in certain versions of MinGW). */ -# if !defined (S_IRGRP) -# define S_IRGRP (S_IREAD >> 3) /* read, group */ -# define S_IWGRP (S_IWRITE >> 3) /* write, group */ -# define S_IXGRP (S_IEXEC >> 3) /* execute, group */ -# endif /* !S_IRGRP */ - -# if !defined (S_IROTH) -# define S_IROTH (S_IREAD >> 6) /* read, other */ -# define S_IWOTH (S_IWRITE >> 6) /* write, other */ -# define S_IXOTH (S_IEXEC >> 6) /* execute, other */ -# endif /* !S_IROTH */ -# if !defined (S_IRWXG) -# define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP) -# endif -# if !defined (S_IRWXO) -# define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH) -# endif -#endif /* !S_IRWXU */ - -/* These are non-standard, but are used in builtins.c$symbolic_umask() */ -#define S_IRUGO (S_IRUSR | S_IRGRP | S_IROTH) -#define S_IWUGO (S_IWUSR | S_IWGRP | S_IWOTH) -#define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH) - -#endif /* _POSIXSTAT_H_ */ diff --git a/third_party/bash/posixtime.h b/third_party/bash/posixtime.h deleted file mode 100644 index e70ebec67..000000000 --- a/third_party/bash/posixtime.h +++ /dev/null @@ -1,84 +0,0 @@ -/* posixtime.h -- wrapper for time.h, sys/times.h mess. */ - -/* Copyright (C) 1999-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#ifndef _POSIXTIME_H_ -#define _POSIXTIME_H_ - -/* include this after config.h */ -/* Some systems require this, mostly for the definition of `struct timezone'. - For example, Dynix/ptx has that definition in rather than - sys/time.h */ -#if defined (HAVE_SYS_TIME_H) -# include -#endif -#include - -#if !defined (HAVE_SYSCONF) || !defined (_SC_CLK_TCK) -# if !defined (CLK_TCK) -# if defined (HZ) -# define CLK_TCK HZ -# else -# define CLK_TCK 60 /* 60HZ */ -# endif -# endif /* !CLK_TCK */ -#endif /* !HAVE_SYSCONF && !_SC_CLK_TCK */ - -#if !HAVE_TIMEVAL -struct timeval -{ - time_t tv_sec; - long int tv_usec; -}; -#endif - -#if !HAVE_GETTIMEOFDAY -extern int gettimeofday PARAMS((struct timeval *, void *)); -#endif - -/* These exist on BSD systems, at least. */ -#if !defined (timerclear) -# define timerclear(tvp) do { (tvp)->tv_sec = 0; (tvp)->tv_usec = 0; } while (0) -#endif -#if !defined (timerisset) -# define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) -#endif -#if !defined (timercmp) -# define timercmp(a, b, CMP) \ - (((a)->tv_sec == (b)->tv_sec) ? ((a)->tv_usec CMP (b)->tv_usec) \ - : ((a)->tv_sec CMP (b)->tv_sec)) -#endif - -/* These are non-standard. */ -#if !defined (timerisunset) -# define timerisunset(tvp) ((tvp)->tv_sec == 0 && (tvp)->tv_usec == 0) -#endif -#if !defined (timerset) -# define timerset(tvp, s, u) do { tvp->tv_sec = s; tvp->tv_usec = u; } while (0) -#endif - -#ifndef TIMEVAL_TO_TIMESPEC -# define TIMEVAL_TO_TIMESPEC(tv, ts) \ - do { \ - (ts)->tv_sec = (tv)->tv_sec; \ - (ts)->tv_nsec = (tv)->tv_usec * 1000; \ - } while (0) -#endif - -#endif /* _POSIXTIME_H_ */ diff --git a/third_party/bash/posixwait.h b/third_party/bash/posixwait.h deleted file mode 100644 index 63b59c24a..000000000 --- a/third_party/bash/posixwait.h +++ /dev/null @@ -1,107 +0,0 @@ -/* posixwait.h -- job control definitions from POSIX 1003.1 */ - -/* Copyright (C) 1997 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_POSIXWAIT_H_) -# define _POSIXWAIT_H_ - -/* If _POSIX_VERSION is not defined, we assume that defines - a `union wait' and various macros used to manipulate it. Look in - unionwait.h for the things we expect to find. */ -#if defined (HAVE_SYS_WAIT_H) -# include -#else /* !HAVE_SYS_WAIT_H */ -# if !defined (_POSIX_VERSION) -# include "unionwait.h" -# endif -#endif /* !HAVE_SYS_WAIT_H */ - -/* How to get the status of a job. For Posix, this is just an - int, but for other systems we have to crack the union wait. */ -#if !defined (_POSIX_VERSION) -typedef union wait WAIT; -# define WSTATUS(t) (t.w_status) -#else /* _POSIX_VERSION */ -typedef int WAIT; -# define WSTATUS(t) (t) -#endif /* _POSIX_VERSION */ - -/* Make sure that parameters to wait3 are defined. */ -#if !defined (WNOHANG) -# define WNOHANG 1 -# define WUNTRACED 2 -#endif /* WNOHANG */ - -/* More Posix P1003.1 definitions. In the POSIX versions, the parameter is - passed as an `int', in the non-POSIX version, as `union wait'. */ -#if defined (_POSIX_VERSION) - -# if !defined (WSTOPSIG) -# define WSTOPSIG(s) ((s) >> 8) -# endif /* !WSTOPSIG */ - -# if !defined (WTERMSIG) -# define WTERMSIG(s) ((s) & 0177) -# endif /* !WTERMSIG */ - -# if !defined (WEXITSTATUS) -# define WEXITSTATUS(s) ((s) >> 8) -# endif /* !WEXITSTATUS */ - -# if !defined (WIFSTOPPED) -# define WIFSTOPPED(s) (((s) & 0177) == 0177) -# endif /* !WIFSTOPPED */ - -# if !defined (WIFEXITED) -# define WIFEXITED(s) (((s) & 0377) == 0) -# endif /* !WIFEXITED */ - -# if !defined (WIFSIGNALED) -# define WIFSIGNALED(s) (!WIFSTOPPED(s) && !WIFEXITED(s)) -# endif /* !WIFSIGNALED */ - -# if !defined (WIFCORED) -# if defined (WCOREDUMP) -# define WIFCORED(s) (WCOREDUMP(s)) -# else -# define WIFCORED(s) ((s) & 0200) -# endif -# endif /* !WIFCORED */ - -#else /* !_POSIX_VERSION */ - -# if !defined (WSTOPSIG) -# define WSTOPSIG(s) ((s).w_stopsig) -# endif /* !WSTOPSIG */ - -# if !defined (WTERMSIG) -# define WTERMSIG(s) ((s).w_termsig) -# endif /* !WTERMSIG */ - -# if !defined (WEXITSTATUS) -# define WEXITSTATUS(s) ((s).w_retcode) -# endif /* !WEXITSTATUS */ - -# if !defined (WIFCORED) -# define WIFCORED(s) ((s).w_coredump) -# endif /* !WIFCORED */ - -#endif /* !_POSIX_VERSION */ - -#endif /* !_POSIXWAIT_H_ */ diff --git a/third_party/bash/print_cmd.c b/third_party/bash/print_cmd.c deleted file mode 100644 index e7bffc8cb..000000000 --- a/third_party/bash/print_cmd.c +++ /dev/null @@ -1,1654 +0,0 @@ -/* print_command -- A way to make readable commands from a command tree. */ - -/* Copyright (C) 1989-2022 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#if defined (PREFER_STDARG) -# include -#else -# include -#endif - -#include "bashansi.h" -#include "bashintl.h" - -#define NEED_XTRACE_SET_DECL - -#include "shell.h" -#include "flags.h" -#include "y.tab.h" /* use <...> so we pick it up from the build directory */ -#include "input.h" - -#include "shmbutil.h" - -#include "common.h" - -#if !HAVE_DECL_PRINTF -extern int printf PARAMS((const char *, ...)); /* Yuck. Double yuck. */ -#endif - -static int indentation; -static int indentation_amount = 4; - -#if defined (PREFER_STDARG) -typedef void PFUNC PARAMS((const char *, ...)); - -static void cprintf PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); -static void xprintf PARAMS((const char *, ...)) __attribute__((__format__ (printf, 1, 2))); -#else -#define PFUNC VFunction -static void cprintf (); -static void xprintf (); -#endif - -static void reset_locals PARAMS((void)); -static void newline PARAMS((char *)); -static void indent PARAMS((int)); -static void semicolon PARAMS((void)); -static void the_printed_command_resize PARAMS((int)); - -static void make_command_string_internal PARAMS((COMMAND *)); -static void _print_word_list PARAMS((WORD_LIST *, char *, PFUNC *)); -static void command_print_word_list PARAMS((WORD_LIST *, char *)); -static void print_case_clauses PARAMS((PATTERN_LIST *)); -static void print_redirection_list PARAMS((REDIRECT *)); -static void print_redirection PARAMS((REDIRECT *)); -static void print_heredoc_header PARAMS((REDIRECT *)); -static void print_heredoc_body PARAMS((REDIRECT *)); -static void print_heredocs PARAMS((REDIRECT *)); -static void print_heredoc_bodies PARAMS((REDIRECT *)); -static void print_deferred_heredocs PARAMS((const char *)); - -static void print_for_command PARAMS((FOR_COM *)); -#if defined (ARITH_FOR_COMMAND) -static void print_arith_for_command PARAMS((ARITH_FOR_COM *)); -#endif -#if defined (SELECT_COMMAND) -static void print_select_command PARAMS((SELECT_COM *)); -#endif -static void print_group_command PARAMS((GROUP_COM *)); -static void print_case_command PARAMS((CASE_COM *)); -static void print_while_command PARAMS((WHILE_COM *)); -static void print_until_command PARAMS((WHILE_COM *)); -static void print_until_or_while PARAMS((WHILE_COM *, char *)); -static void print_if_command PARAMS((IF_COM *)); -#if defined (COND_COMMAND) -static void print_cond_node PARAMS((COND_COM *)); -#endif -static void print_function_def PARAMS((FUNCTION_DEF *)); - -#define PRINTED_COMMAND_INITIAL_SIZE 64 -#define PRINTED_COMMAND_GROW_SIZE 128 - -char *the_printed_command = (char *)NULL; -int the_printed_command_size = 0; -int command_string_index = 0; - -int xtrace_fd = -1; -FILE *xtrace_fp = 0; - -#define CHECK_XTRACE_FP xtrace_fp = (xtrace_fp ? xtrace_fp : stderr) - -/* shell expansion characters: used in print_redirection_list */ -#define EXPCHAR(c) ((c) == '{' || (c) == '~' || (c) == '$' || (c) == '`') - -#define PRINT_DEFERRED_HEREDOCS(x) \ - do { \ - if (deferred_heredocs) \ - print_deferred_heredocs (x); \ - } while (0) - -/* Non-zero means the stuff being printed is inside of a function def. */ -static int inside_function_def; -static int skip_this_indent; -static int was_heredoc; -static int printing_connection; -static int printing_comsub; -static REDIRECT *deferred_heredocs; - -/* The depth of the group commands that we are currently printing. This - includes the group command that is a function body. */ -static int group_command_nesting; - -/* A buffer to indicate the indirection level (PS4) when set -x is enabled. */ -static char *indirection_string = 0; -static int indirection_stringsiz = 0; - -/* Print COMMAND (a command tree) on standard output. */ -void -print_command (command) - COMMAND *command; -{ - command_string_index = 0; - printf ("%s", make_command_string (command)); -} - -/* Make a string which is the printed representation of the command - tree in COMMAND. We return this string. However, the string is - not consed, so you have to do that yourself if you want it to - remain around. */ -char * -make_command_string (command) - COMMAND *command; -{ - command_string_index = was_heredoc = 0; - deferred_heredocs = 0; - make_command_string_internal (command); - return (the_printed_command); -} - -/* Print a command substitution after parsing it in parse_comsub to turn it - back into an external representation without turning newlines into `;'. - Placeholder for other changes, if any are necessary. */ -char * -print_comsub (command) - COMMAND *command; -{ - char *ret; - - printing_comsub++; - ret = make_command_string (command); - printing_comsub--; - return ret; -} - -/* The internal function. This is the real workhorse. */ -static void -make_command_string_internal (command) - COMMAND *command; -{ - char s[3]; - - if (command == 0) - cprintf (""); - else - { - if (skip_this_indent) - skip_this_indent--; - else - indent (indentation); - - if (command->flags & CMD_TIME_PIPELINE) - { - cprintf ("time "); - if (command->flags & CMD_TIME_POSIX) - cprintf ("-p "); - } - - if (command->flags & CMD_INVERT_RETURN) - cprintf ("! "); - - switch (command->type) - { - case cm_for: - print_for_command (command->value.For); - break; - -#if defined (ARITH_FOR_COMMAND) - case cm_arith_for: - print_arith_for_command (command->value.ArithFor); - break; -#endif - -#if defined (SELECT_COMMAND) - case cm_select: - print_select_command (command->value.Select); - break; -#endif - - case cm_case: - print_case_command (command->value.Case); - break; - - case cm_while: - print_while_command (command->value.While); - break; - - case cm_until: - print_until_command (command->value.While); - break; - - case cm_if: - print_if_command (command->value.If); - break; - -#if defined (DPAREN_ARITHMETIC) - case cm_arith: - print_arith_command (command->value.Arith->exp); - break; -#endif - -#if defined (COND_COMMAND) - case cm_cond: - print_cond_command (command->value.Cond); - break; -#endif - - case cm_simple: - print_simple_command (command->value.Simple); - break; - - case cm_connection: - - skip_this_indent++; - printing_connection++; - make_command_string_internal (command->value.Connection->first); - - switch (command->value.Connection->connector) - { - case '&': - case '|': - { - char c = command->value.Connection->connector; - - s[0] = ' '; - s[1] = c; - s[2] = '\0'; - - print_deferred_heredocs (s); - - if (c != '&' || command->value.Connection->second) - { - cprintf (" "); - skip_this_indent++; - } - } - break; - - case AND_AND: - print_deferred_heredocs (" && "); - if (command->value.Connection->second) - skip_this_indent++; - break; - - case OR_OR: - print_deferred_heredocs (" || "); - if (command->value.Connection->second) - skip_this_indent++; - break; - - case ';': - case '\n': /* special case this */ - { - char c = command->value.Connection->connector; - - s[0] = printing_comsub ? c : ';'; - s[1] = '\0'; - - if (deferred_heredocs == 0) - { - if (was_heredoc == 0) - cprintf ("%s", s); /* inside_function_def? */ - else - was_heredoc = 0; - } - else - /* print_deferred_heredocs special-cases `;' */ - print_deferred_heredocs (inside_function_def ? "" : ";"); - - if (inside_function_def) - cprintf ("\n"); - else - { - if (c == ';') - cprintf (" "); - if (command->value.Connection->second) - skip_this_indent++; - } - break; - } - - default: - cprintf (_("print_command: bad connector `%d'"), - command->value.Connection->connector); - break; - } - - make_command_string_internal (command->value.Connection->second); - PRINT_DEFERRED_HEREDOCS (""); - printing_connection--; - break; - - case cm_function_def: - print_function_def (command->value.Function_def); - break; - - case cm_group: - print_group_command (command->value.Group); - break; - - case cm_subshell: - cprintf ("( "); - skip_this_indent++; - make_command_string_internal (command->value.Subshell->command); - PRINT_DEFERRED_HEREDOCS (""); - cprintf (" )"); - break; - - case cm_coproc: - cprintf ("coproc %s ", command->value.Coproc->name); - skip_this_indent++; - make_command_string_internal (command->value.Coproc->command); - break; - - default: - command_error ("print_command", CMDERR_BADTYPE, command->type, 0); - break; - } - - - if (command->redirects) - { - cprintf (" "); - print_redirection_list (command->redirects); - } - } -} - -static void -_print_word_list (list, separator, pfunc) - WORD_LIST *list; - char *separator; - PFUNC *pfunc; -{ - WORD_LIST *w; - - for (w = list; w; w = w->next) - (*pfunc) ("%s%s", w->word->word, w->next ? separator : ""); -} - -void -print_word_list (list, separator) - WORD_LIST *list; - char *separator; -{ - _print_word_list (list, separator, xprintf); -} - -void -xtrace_set (fd, fp) - int fd; - FILE *fp; -{ - if (fd >= 0 && sh_validfd (fd) == 0) - { - internal_error (_("xtrace_set: %d: invalid file descriptor"), fd); - return; - } - if (fp == 0) - { - internal_error (_("xtrace_set: NULL file pointer")); - return; - } - if (fd >= 0 && fileno (fp) != fd) - internal_warning (_("xtrace fd (%d) != fileno xtrace fp (%d)"), fd, fileno (fp)); - - xtrace_fd = fd; - xtrace_fp = fp; -} - -void -xtrace_init () -{ - xtrace_set (-1, stderr); -} - -void -xtrace_reset () -{ - if (xtrace_fd >= 0 && xtrace_fp) - { - fflush (xtrace_fp); - fclose (xtrace_fp); - } - else if (xtrace_fd >= 0) - close (xtrace_fd); - - xtrace_fd = -1; - xtrace_fp = stderr; -} - -void -xtrace_fdchk (fd) - int fd; -{ - if (fd == xtrace_fd) - xtrace_reset (); -} - -/* Return a string denoting what our indirection level is. */ - -char * -indirection_level_string () -{ - register int i, j; - char *ps4; - char ps4_firstc[MB_LEN_MAX+1]; - int ps4_firstc_len, ps4_len, ineed, old; - - ps4 = get_string_value ("PS4"); - if (indirection_string == 0) - indirection_string = xmalloc (indirection_stringsiz = 100); - indirection_string[0] = '\0'; - - if (ps4 == 0 || *ps4 == '\0') - return (indirection_string); - - old = change_flag ('x', FLAG_OFF); - ps4 = decode_prompt_string (ps4); - if (old) - change_flag ('x', FLAG_ON); - - if (ps4 == 0 || *ps4 == '\0') - { - FREE (ps4); - return (indirection_string); - } - -#if defined (HANDLE_MULTIBYTE) - ps4_len = strnlen (ps4, MB_CUR_MAX); - ps4_firstc_len = MBLEN (ps4, ps4_len); - if (ps4_firstc_len == 1 || ps4_firstc_len == 0 || ps4_firstc_len < 0) - { - ps4_firstc[0] = ps4[0]; - ps4_firstc[ps4_firstc_len = 1] = '\0'; - } - else - memcpy (ps4_firstc, ps4, ps4_firstc_len); -#else - ps4_firstc[0] = ps4[0]; - ps4_firstc[ps4_firstc_len = 1] = '\0'; -#endif - - /* Dynamically resize indirection_string so we have room for everything - and we don't have to truncate ps4 */ - ineed = (ps4_firstc_len * indirection_level) + strlen (ps4); - if (ineed > indirection_stringsiz - 1) - { - indirection_stringsiz = ineed + 1; - indirection_string = xrealloc (indirection_string, indirection_stringsiz); - } - - for (i = j = 0; ps4_firstc[0] && j < indirection_level && i < indirection_stringsiz - 1; i += ps4_firstc_len, j++) - { - if (ps4_firstc_len == 1) - indirection_string[i] = ps4_firstc[0]; - else - memcpy (indirection_string+i, ps4_firstc, ps4_firstc_len); - } - - for (j = ps4_firstc_len; *ps4 && ps4[j] && i < indirection_stringsiz - 1; i++, j++) - indirection_string[i] = ps4[j]; - - indirection_string[i] = '\0'; - free (ps4); - return (indirection_string); -} - -void -xtrace_print_assignment (name, value, assign_list, xflags) - char *name, *value; - int assign_list, xflags; -{ - char *nval; - - CHECK_XTRACE_FP; - - if (xflags) - fprintf (xtrace_fp, "%s", indirection_level_string ()); - - /* VALUE should not be NULL when this is called. */ - if (*value == '\0' || assign_list) - nval = value; - else if (sh_contains_shell_metas (value)) - nval = sh_single_quote (value); - else if (ansic_shouldquote (value)) - nval = ansic_quote (value, 0, (int *)0); - else - nval = value; - - if (assign_list) - fprintf (xtrace_fp, "%s=(%s)\n", name, nval); - else - fprintf (xtrace_fp, "%s=%s\n", name, nval); - - if (nval != value) - FREE (nval); - - fflush (xtrace_fp); -} - -/* A function to print the words of a simple command when set -x is on. Also used to - print the word list in a for or select command header; in that case, we suppress - quoting the words because they haven't been expanded yet. XTFLAGS&1 means to - print $PS4; XTFLAGS&2 means to suppress quoting the words in LIST. */ -void -xtrace_print_word_list (list, xtflags) - WORD_LIST *list; - int xtflags; -{ - WORD_LIST *w; - char *t, *x; - - CHECK_XTRACE_FP; - - if (xtflags&1) - fprintf (xtrace_fp, "%s", indirection_level_string ()); - - for (w = list; w; w = w->next) - { - t = w->word->word; - if (t == 0 || *t == '\0') - fprintf (xtrace_fp, "''%s", w->next ? " " : ""); - else if (xtflags & 2) - fprintf (xtrace_fp, "%s%s", t, w->next ? " " : ""); - else if (sh_contains_shell_metas (t)) - { - x = sh_single_quote (t); - fprintf (xtrace_fp, "%s%s", x, w->next ? " " : ""); - free (x); - } - else if (ansic_shouldquote (t)) - { - x = ansic_quote (t, 0, (int *)0); - fprintf (xtrace_fp, "%s%s", x, w->next ? " " : ""); - free (x); - } - else - fprintf (xtrace_fp, "%s%s", t, w->next ? " " : ""); - } - fprintf (xtrace_fp, "\n"); - fflush (xtrace_fp); -} - -static void -command_print_word_list (list, separator) - WORD_LIST *list; - char *separator; -{ - _print_word_list (list, separator, cprintf); -} - -void -print_for_command_head (for_command) - FOR_COM *for_command; -{ - cprintf ("for %s in ", for_command->name->word); - command_print_word_list (for_command->map_list, " "); -} - -void -xtrace_print_for_command_head (for_command) - FOR_COM *for_command; -{ - CHECK_XTRACE_FP; - fprintf (xtrace_fp, "%s", indirection_level_string ()); - fprintf (xtrace_fp, "for %s in ", for_command->name->word); - xtrace_print_word_list (for_command->map_list, 2); -} - -static void -print_for_command (for_command) - FOR_COM *for_command; -{ - print_for_command_head (for_command); - cprintf (";"); - newline ("do\n"); - - indentation += indentation_amount; - make_command_string_internal (for_command->action); - PRINT_DEFERRED_HEREDOCS (""); - semicolon (); - indentation -= indentation_amount; - - newline ("done"); -} - -#if defined (ARITH_FOR_COMMAND) -static void -print_arith_for_command (arith_for_command) - ARITH_FOR_COM *arith_for_command; -{ - cprintf ("for (("); - command_print_word_list (arith_for_command->init, " "); - cprintf ("; "); - command_print_word_list (arith_for_command->test, " "); - cprintf ("; "); - command_print_word_list (arith_for_command->step, " "); - cprintf ("))"); - newline ("do\n"); - indentation += indentation_amount; - make_command_string_internal (arith_for_command->action); - PRINT_DEFERRED_HEREDOCS (""); - semicolon (); - indentation -= indentation_amount; - newline ("done"); -} -#endif /* ARITH_FOR_COMMAND */ - -#if defined (SELECT_COMMAND) -void -print_select_command_head (select_command) - SELECT_COM *select_command; -{ - cprintf ("select %s in ", select_command->name->word); - command_print_word_list (select_command->map_list, " "); -} - -void -xtrace_print_select_command_head (select_command) - SELECT_COM *select_command; -{ - CHECK_XTRACE_FP; - fprintf (xtrace_fp, "%s", indirection_level_string ()); - fprintf (xtrace_fp, "select %s in ", select_command->name->word); - xtrace_print_word_list (select_command->map_list, 2); -} - -static void -print_select_command (select_command) - SELECT_COM *select_command; -{ - print_select_command_head (select_command); - - cprintf (";"); - newline ("do\n"); - indentation += indentation_amount; - make_command_string_internal (select_command->action); - PRINT_DEFERRED_HEREDOCS (""); - semicolon (); - indentation -= indentation_amount; - newline ("done"); -} -#endif /* SELECT_COMMAND */ - -static void -print_group_command (group_command) - GROUP_COM *group_command; -{ - group_command_nesting++; - cprintf ("{ "); - - if (inside_function_def == 0) - skip_this_indent++; - else - { - /* This is a group command { ... } inside of a function - definition, and should be printed as a multiline group - command, using the current indentation. */ - cprintf ("\n"); - indentation += indentation_amount; - } - - make_command_string_internal (group_command->command); - PRINT_DEFERRED_HEREDOCS (""); - - if (inside_function_def) - { - cprintf ("\n"); - indentation -= indentation_amount; - indent (indentation); - } - else - { - semicolon (); - cprintf (" "); - } - - cprintf ("}"); - - group_command_nesting--; -} - -void -print_case_command_head (case_command) - CASE_COM *case_command; -{ - cprintf ("case %s in ", case_command->word->word); -} - -void -xtrace_print_case_command_head (case_command) - CASE_COM *case_command; -{ - CHECK_XTRACE_FP; - fprintf (xtrace_fp, "%s", indirection_level_string ()); - fprintf (xtrace_fp, "case %s in\n", case_command->word->word); -} - -static void -print_case_command (case_command) - CASE_COM *case_command; -{ - print_case_command_head (case_command); - - if (case_command->clauses) - print_case_clauses (case_command->clauses); - newline ("esac"); -} - -static void -print_case_clauses (clauses) - PATTERN_LIST *clauses; -{ - indentation += indentation_amount; - while (clauses) - { - newline (""); - command_print_word_list (clauses->patterns, " | "); - cprintf (")\n"); - indentation += indentation_amount; - make_command_string_internal (clauses->action); - indentation -= indentation_amount; - PRINT_DEFERRED_HEREDOCS (""); - if (clauses->flags & CASEPAT_FALLTHROUGH) - newline (";&"); - else if (clauses->flags & CASEPAT_TESTNEXT) - newline (";;&"); - else - newline (";;"); - clauses = clauses->next; - } - indentation -= indentation_amount; -} - -static void -print_while_command (while_command) - WHILE_COM *while_command; -{ - print_until_or_while (while_command, "while"); -} - -static void -print_until_command (while_command) - WHILE_COM *while_command; -{ - print_until_or_while (while_command, "until"); -} - -static void -print_until_or_while (while_command, which) - WHILE_COM *while_command; - char *which; -{ - cprintf ("%s ", which); - skip_this_indent++; - make_command_string_internal (while_command->test); - PRINT_DEFERRED_HEREDOCS (""); - semicolon (); - cprintf (" do\n"); /* was newline ("do\n"); */ - indentation += indentation_amount; - make_command_string_internal (while_command->action); - PRINT_DEFERRED_HEREDOCS (""); - indentation -= indentation_amount; - semicolon (); - newline ("done"); -} - -static void -print_if_command (if_command) - IF_COM *if_command; -{ - cprintf ("if "); - skip_this_indent++; - make_command_string_internal (if_command->test); - semicolon (); - cprintf (" then\n"); - indentation += indentation_amount; - make_command_string_internal (if_command->true_case); - PRINT_DEFERRED_HEREDOCS (""); - indentation -= indentation_amount; - - if (if_command->false_case) - { - semicolon (); - newline ("else\n"); - indentation += indentation_amount; - make_command_string_internal (if_command->false_case); - PRINT_DEFERRED_HEREDOCS (""); - indentation -= indentation_amount; - } - semicolon (); - newline ("fi"); -} - -#if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND) -void -print_arith_command (arith_cmd_list) - WORD_LIST *arith_cmd_list; -{ - cprintf ("(("); - command_print_word_list (arith_cmd_list, " "); - cprintf ("))"); -} -#endif - -#if defined (COND_COMMAND) -static void -print_cond_node (cond) - COND_COM *cond; -{ - if (cond->flags & CMD_INVERT_RETURN) - cprintf ("! "); - - if (cond->type == COND_EXPR) - { - cprintf ("( "); - print_cond_node (cond->left); - cprintf (" )"); - } - else if (cond->type == COND_AND) - { - print_cond_node (cond->left); - cprintf (" && "); - print_cond_node (cond->right); - } - else if (cond->type == COND_OR) - { - print_cond_node (cond->left); - cprintf (" || "); - print_cond_node (cond->right); - } - else if (cond->type == COND_UNARY) - { - cprintf ("%s", cond->op->word); - cprintf (" "); - print_cond_node (cond->left); - } - else if (cond->type == COND_BINARY) - { - print_cond_node (cond->left); - cprintf (" "); - cprintf ("%s", cond->op->word); - cprintf (" "); - print_cond_node (cond->right); - } - else if (cond->type == COND_TERM) - { - cprintf ("%s", cond->op->word); /* need to add quoting here */ - } -} - -void -print_cond_command (cond) - COND_COM *cond; -{ - cprintf ("[[ "); - print_cond_node (cond); - cprintf (" ]]"); -} - -#ifdef DEBUG -void -debug_print_word_list (s, list, sep) - char *s; - WORD_LIST *list; - char *sep; -{ - WORD_LIST *w; - - if (s) - fprintf (stderr, "%s: ", s); - for (w = list; w; w = w->next) - fprintf (stderr, "%s%s", w->word->word, w->next ? sep : ""); - fprintf (stderr, "\n"); -} - -void -debug_print_cond_command (cond) - COND_COM *cond; -{ - fprintf (stderr, "DEBUG: "); - command_string_index = 0; - print_cond_command (cond); - fprintf (stderr, "%s\n", the_printed_command); -} -#endif - -void -xtrace_print_cond_term (type, invert, op, arg1, arg2) - int type, invert; - WORD_DESC *op; - char *arg1, *arg2; -{ - CHECK_XTRACE_FP; - command_string_index = 0; - fprintf (xtrace_fp, "%s", indirection_level_string ()); - fprintf (xtrace_fp, "[[ "); - if (invert) - fprintf (xtrace_fp, "! "); - - if (type == COND_UNARY) - { - fprintf (xtrace_fp, "%s ", op->word); - fprintf (xtrace_fp, "%s", (arg1 && *arg1) ? arg1 : "''"); - } - else if (type == COND_BINARY) - { - fprintf (xtrace_fp, "%s", (arg1 && *arg1) ? arg1 : "''"); - fprintf (xtrace_fp, " %s ", op->word); - fprintf (xtrace_fp, "%s", (arg2 && *arg2) ? arg2 : "''"); - } - - fprintf (xtrace_fp, " ]]\n"); - - fflush (xtrace_fp); -} -#endif /* COND_COMMAND */ - -#if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND) -/* A function to print the words of an arithmetic command when set -x is on. */ -void -xtrace_print_arith_cmd (list) - WORD_LIST *list; -{ - WORD_LIST *w; - - CHECK_XTRACE_FP; - fprintf (xtrace_fp, "%s", indirection_level_string ()); - fprintf (xtrace_fp, "(( "); - for (w = list; w; w = w->next) - fprintf (xtrace_fp, "%s%s", w->word->word, w->next ? " " : ""); - fprintf (xtrace_fp, " ))\n"); - - fflush (xtrace_fp); -} -#endif - -void -print_simple_command (simple_command) - SIMPLE_COM *simple_command; -{ - if (simple_command->words) - command_print_word_list (simple_command->words, " "); - - if (simple_command->redirects) - { - if (simple_command->words) - cprintf (" "); - print_redirection_list (simple_command->redirects); - } -} - -static void -print_heredocs (heredocs) - REDIRECT *heredocs; -{ - REDIRECT *hdtail; - - cprintf (" "); - for (hdtail = heredocs; hdtail; hdtail = hdtail->next) - { - print_redirection (hdtail); - cprintf ("\n"); - } - was_heredoc = 1; -} - -static void -print_heredoc_bodies (heredocs) - REDIRECT *heredocs; -{ - REDIRECT *hdtail; - - cprintf ("\n"); - for (hdtail = heredocs; hdtail; hdtail = hdtail->next) - { - print_heredoc_body (hdtail); - cprintf ("\n"); - } - was_heredoc = 1; -} - -/* Print heredocs that are attached to the command before the connector - represented by CSTRING. The parsing semantics require us to print the - here-doc delimiters, then the connector (CSTRING), then the here-doc - bodies. We print the here-doc delimiters in print_redirection_list - and print the connector and the bodies here. We don't print the connector - if it's a `;', but we use it to note not to print an extra space after the - last heredoc body and newline. */ -static void -print_deferred_heredocs (cstring) - const char *cstring; -{ - /* We now print the heredoc headers in print_redirection_list */ - if (cstring && cstring[0] && (cstring[0] != ';' || cstring[1])) - cprintf ("%s", cstring); - if (deferred_heredocs) - { - print_heredoc_bodies (deferred_heredocs); - if (cstring && cstring[0] && (cstring[0] != ';' || cstring[1])) - cprintf (" "); /* make sure there's at least one space */ - dispose_redirects (deferred_heredocs); - was_heredoc = 1; - } - deferred_heredocs = (REDIRECT *)NULL; -} - -static void -print_redirection_list (redirects) - REDIRECT *redirects; -{ - REDIRECT *heredocs, *hdtail, *newredir; - char *rw; - - heredocs = (REDIRECT *)NULL; - hdtail = heredocs; - - was_heredoc = 0; - while (redirects) - { - /* Defer printing the here document bodiess until we've printed the rest of the - redirections, but print the headers in the order they're given. */ - if (redirects->instruction == r_reading_until || redirects->instruction == r_deblank_reading_until) - { - newredir = copy_redirect (redirects); - newredir->next = (REDIRECT *)NULL; - - print_heredoc_header (newredir); - - if (heredocs) - { - hdtail->next = newredir; - hdtail = newredir; - } - else - hdtail = heredocs = newredir; - } -#if 0 - /* Remove this heuristic now that the command printing code doesn't - unconditionally put in the redirector file descriptor. */ - else if (redirects->instruction == r_duplicating_output_word && (redirects->flags & REDIR_VARASSIGN) == 0 && redirects->redirector.dest == 1) - { - /* Temporarily translate it as the execution code does. */ - rw = redirects->redirectee.filename->word; - if (rw && *rw != '-' && DIGIT (*rw) == 0 && EXPCHAR (*rw) == 0) - redirects->instruction = r_err_and_out; - print_redirection (redirects); - redirects->instruction = r_duplicating_output_word; - } -#endif - else - print_redirection (redirects); - - redirects = redirects->next; - if (redirects) - cprintf (" "); - } - - /* Now that we've printed all the other redirections (on one line), - print the here documents. If we're printing a connection, we wait until - we print the connector symbol, then we print the here document bodies */ - if (heredocs && printing_connection) - deferred_heredocs = heredocs; - else if (heredocs) - { - print_heredoc_bodies (heredocs); - dispose_redirects (heredocs); - } -} - -static void -print_heredoc_header (redirect) - REDIRECT *redirect; -{ - int kill_leading; - char *x; - - kill_leading = redirect->instruction == r_deblank_reading_until; - - /* Here doc header */ - if (redirect->rflags & REDIR_VARASSIGN) - cprintf ("{%s}", redirect->redirector.filename->word); - else if (redirect->redirector.dest != 0) - cprintf ("%d", redirect->redirector.dest); - - /* If the here document delimiter is quoted, single-quote it. */ - if (redirect->redirectee.filename->flags & W_QUOTED) - { - x = sh_single_quote (redirect->here_doc_eof); - cprintf ("<<%s%s", kill_leading ? "-" : "", x); - free (x); - } - else - cprintf ("<<%s%s", kill_leading ? "-" : "", redirect->here_doc_eof); -} - -static void -print_heredoc_body (redirect) - REDIRECT *redirect; -{ - /* Here doc body */ - cprintf ("%s%s", redirect->redirectee.filename->word, redirect->here_doc_eof); -} - -static void -print_redirection (redirect) - REDIRECT *redirect; -{ - int redirector, redir_fd; - WORD_DESC *redirectee, *redir_word; - - redirectee = redirect->redirectee.filename; - redir_fd = redirect->redirectee.dest; - - redir_word = redirect->redirector.filename; - redirector = redirect->redirector.dest; - - switch (redirect->instruction) - { - case r_input_direction: - if (redirect->rflags & REDIR_VARASSIGN) - cprintf ("{%s}", redir_word->word); - else if (redirector != 0) - cprintf ("%d", redirector); - cprintf ("< %s", redirectee->word); - break; - - case r_output_direction: - if (redirect->rflags & REDIR_VARASSIGN) - cprintf ("{%s}", redir_word->word); - else if (redirector != 1) - cprintf ("%d", redirector); - cprintf ("> %s", redirectee->word); - break; - - case r_inputa_direction: /* Redirection created by the shell. */ - cprintf ("&"); - break; - - case r_output_force: - if (redirect->rflags & REDIR_VARASSIGN) - cprintf ("{%s}", redir_word->word); - else if (redirector != 1) - cprintf ("%d", redirector); - cprintf (">| %s", redirectee->word); - break; - - case r_appending_to: - if (redirect->rflags & REDIR_VARASSIGN) - cprintf ("{%s}", redir_word->word); - else if (redirector != 1) - cprintf ("%d", redirector); - cprintf (">> %s", redirectee->word); - break; - - case r_input_output: - if (redirect->rflags & REDIR_VARASSIGN) - cprintf ("{%s}", redir_word->word); - else if (redirector != 1) - cprintf ("%d", redirector); - cprintf ("<> %s", redirectee->word); - break; - - case r_deblank_reading_until: - case r_reading_until: - print_heredoc_header (redirect); - cprintf ("\n"); - print_heredoc_body (redirect); - break; - - case r_reading_string: - if (redirect->rflags & REDIR_VARASSIGN) - cprintf ("{%s}", redir_word->word); - else if (redirector != 0) - cprintf ("%d", redirector); -#if 0 - /* Don't need to check whether or not to requote, since original quotes - are still intact. The only thing that has happened is that $'...' - has been replaced with 'expanded ...'. */ - if (ansic_shouldquote (redirect->redirectee.filename->word)) - { - char *x; - x = ansic_quote (redirect->redirectee.filename->word, 0, (int *)0); - cprintf ("<<< %s", x); - free (x); - } - else -#endif - cprintf ("<<< %s", redirect->redirectee.filename->word); - break; - - case r_duplicating_input: - if (redirect->rflags & REDIR_VARASSIGN) - cprintf ("{%s}<&%d", redir_word->word, redir_fd); - else - cprintf ("%d<&%d", redirector, redir_fd); - break; - - case r_duplicating_output: - if (redirect->rflags & REDIR_VARASSIGN) - cprintf ("{%s}>&%d", redir_word->word, redir_fd); - else - cprintf ("%d>&%d", redirector, redir_fd); - break; - - case r_duplicating_input_word: - if (redirect->rflags & REDIR_VARASSIGN) - cprintf ("{%s}<&%s", redir_word->word, redirectee->word); - else if (redirector == 0) - cprintf ("<&%s", redirectee->word); - else - cprintf ("%d<&%s", redirector, redirectee->word); - break; - - case r_duplicating_output_word: - if (redirect->rflags & REDIR_VARASSIGN) - cprintf ("{%s}>&%s", redir_word->word, redirectee->word); - else if (redirector == 1) - cprintf (">&%s", redirectee->word); - else - cprintf ("%d>&%s", redirector, redirectee->word); - break; - - case r_move_input: - if (redirect->rflags & REDIR_VARASSIGN) - cprintf ("{%s}<&%d-", redir_word->word, redir_fd); - else - cprintf ("%d<&%d-", redirector, redir_fd); - break; - - case r_move_output: - if (redirect->rflags & REDIR_VARASSIGN) - cprintf ("{%s}>&%d-", redir_word->word, redir_fd); - else - cprintf ("%d>&%d-", redirector, redir_fd); - break; - - case r_move_input_word: - if (redirect->rflags & REDIR_VARASSIGN) - cprintf ("{%s}<&%s-", redir_word->word, redirectee->word); - else - cprintf ("%d<&%s-", redirector, redirectee->word); - break; - - case r_move_output_word: - if (redirect->rflags & REDIR_VARASSIGN) - cprintf ("{%s}>&%s-", redir_word->word, redirectee->word); - else - cprintf ("%d>&%s-", redirector, redirectee->word); - break; - - case r_close_this: - if (redirect->rflags & REDIR_VARASSIGN) - cprintf ("{%s}>&-", redir_word->word); - else - cprintf ("%d>&-", redirector); - break; - - case r_err_and_out: - cprintf ("&> %s", redirectee->word); - break; - - case r_append_err_and_out: - cprintf ("&>> %s", redirectee->word); - break; - } -} - -static void -reset_locals () -{ - inside_function_def = 0; - indentation = 0; - printing_connection = 0; - deferred_heredocs = 0; - printing_comsub = 0; -} - -static void -print_function_def (func) - FUNCTION_DEF *func; -{ - COMMAND *cmdcopy; - REDIRECT *func_redirects; - - func_redirects = NULL; - /* When in posix mode, print functions as posix specifies them. */ - if (posixly_correct == 0) - cprintf ("function %s () \n", func->name->word); - else - cprintf ("%s () \n", func->name->word); - add_unwind_protect (reset_locals, 0); - - indent (indentation); - cprintf ("{ \n"); - - inside_function_def++; - indentation += indentation_amount; - - cmdcopy = copy_command (func->command); - if (cmdcopy->type == cm_group) - { - func_redirects = cmdcopy->redirects; - cmdcopy->redirects = (REDIRECT *)NULL; - } - make_command_string_internal (cmdcopy->type == cm_group - ? cmdcopy->value.Group->command - : cmdcopy); - PRINT_DEFERRED_HEREDOCS (""); - - remove_unwind_protect (); - indentation -= indentation_amount; - inside_function_def--; - - if (func_redirects) - { /* { */ - newline ("} "); - print_redirection_list (func_redirects); - cmdcopy->redirects = func_redirects; - } - else - newline ("}"); - - dispose_command (cmdcopy); -} - -/* Return the string representation of the named function. - NAME is the name of the function. - COMMAND is the function body. It should be a GROUP_COM. - flags&FUNC_MULTILINE is non-zero to pretty-print, or zero for all on one line. - flags&FUNC_EXTERNAL means convert from internal to external form - */ -char * -named_function_string (name, command, flags) - char *name; - COMMAND *command; - int flags; -{ - char *result; - int old_indent, old_amount; - COMMAND *cmdcopy; - REDIRECT *func_redirects; - - old_indent = indentation; - old_amount = indentation_amount; - command_string_index = was_heredoc = 0; - deferred_heredocs = 0; - printing_comsub = 0; - - if (name && *name) - { - if (find_reserved_word (name) >= 0) - cprintf ("function "); - cprintf ("%s ", name); - } - - cprintf ("() "); - - if ((flags & FUNC_MULTILINE) == 0) - { - indentation = 1; - indentation_amount = 0; - } - else - { - cprintf ("\n"); - indentation += indentation_amount; - } - - inside_function_def++; - - cprintf ((flags & FUNC_MULTILINE) ? "{ \n" : "{ "); - - cmdcopy = copy_command (command); - /* Take any redirections specified in the function definition (which should - apply to the function as a whole) and save them for printing later. */ - func_redirects = (REDIRECT *)NULL; - if (cmdcopy->type == cm_group) - { - func_redirects = cmdcopy->redirects; - cmdcopy->redirects = (REDIRECT *)NULL; - } - make_command_string_internal (cmdcopy->type == cm_group - ? cmdcopy->value.Group->command - : cmdcopy); - PRINT_DEFERRED_HEREDOCS (""); - - indentation = old_indent; - indentation_amount = old_amount; - inside_function_def--; - - if (func_redirects) - { /* { */ - newline ("} "); - print_redirection_list (func_redirects); - cmdcopy->redirects = func_redirects; - } - else - newline ("}"); - - result = the_printed_command; - - if ((flags & FUNC_MULTILINE) == 0) - { -#if 0 - register int i; - for (i = 0; result[i]; i++) - if (result[i] == '\n') - { - strcpy (result + i, result + i + 1); - --i; - } -#else - if (result[2] == '\n') /* XXX -- experimental */ - memmove (result + 2, result + 3, strlen (result) - 2); -#endif - } - - dispose_command (cmdcopy); - - if (flags & FUNC_EXTERNAL) - result = remove_quoted_escapes (result); - - return (result); -} - -static void -newline (string) - char *string; -{ - cprintf ("\n"); - indent (indentation); - if (string && *string) - cprintf ("%s", string); -} - -static char *indentation_string; -static int indentation_size; - -static void -indent (amount) - int amount; -{ - register int i; - - RESIZE_MALLOCED_BUFFER (indentation_string, 0, amount, indentation_size, 16); - - for (i = 0; amount > 0; amount--) - indentation_string[i++] = ' '; - indentation_string[i] = '\0'; - cprintf ("%s", indentation_string); -} - -static void -semicolon () -{ - if (command_string_index > 0 && - (the_printed_command[command_string_index - 1] == '&' || - the_printed_command[command_string_index - 1] == '\n')) - return; - cprintf (";"); -} - -/* How to make the string. */ -static void -#if defined (PREFER_STDARG) -cprintf (const char *control, ...) -#else -cprintf (control, va_alist) - const char *control; - va_dcl -#endif -{ - register const char *s; - char char_arg[2], *argp, intbuf[INT_STRLEN_BOUND (unsigned int) + 1]; - int digit_arg, arg_len, c; - va_list args; - - SH_VA_START (args, control); - - arg_len = strlen (control); - the_printed_command_resize (arg_len + 1); - - char_arg[1] = '\0'; - s = control; - while (s && *s) - { - c = *s++; - argp = (char *)NULL; - if (c != '%' || !*s) - { - char_arg[0] = c; - argp = char_arg; - arg_len = 1; - } - else - { - c = *s++; - switch (c) - { - case '%': - char_arg[0] = c; - argp = char_arg; - arg_len = 1; - break; - - case 's': - argp = va_arg (args, char *); - arg_len = strlen (argp); - break; - - case 'd': - /* Represent an out-of-range file descriptor with an out-of-range - integer value. We can do this because the only use of `%d' in - the calls to cprintf is to output a file descriptor number for - a redirection. */ - digit_arg = va_arg (args, int); - if (digit_arg < 0) - { - sprintf (intbuf, "%u", (unsigned int)-1); - argp = intbuf; - } - else - argp = inttostr (digit_arg, intbuf, sizeof (intbuf)); - arg_len = strlen (argp); - break; - - case 'c': - char_arg[0] = va_arg (args, int); - argp = char_arg; - arg_len = 1; - break; - - default: - programming_error (_("cprintf: `%c': invalid format character"), c); - /*NOTREACHED*/ - } - } - - if (argp && arg_len) - { - the_printed_command_resize (arg_len + 1); - FASTCOPY (argp, the_printed_command + command_string_index, arg_len); - command_string_index += arg_len; - } - } - - va_end (args); - - the_printed_command[command_string_index] = '\0'; -} - -/* Ensure that there is enough space to stuff LENGTH characters into - THE_PRINTED_COMMAND. */ -static void -the_printed_command_resize (length) - int length; -{ - if (the_printed_command == 0) - { - the_printed_command_size = (length + PRINTED_COMMAND_INITIAL_SIZE - 1) & ~(PRINTED_COMMAND_INITIAL_SIZE - 1); - the_printed_command = (char *)xmalloc (the_printed_command_size); - command_string_index = 0; - } - else if ((command_string_index + length) >= the_printed_command_size) - { - int new; - new = command_string_index + length + 1; - - /* Round up to the next multiple of PRINTED_COMMAND_GROW_SIZE. */ - new = (new + PRINTED_COMMAND_GROW_SIZE - 1) & ~(PRINTED_COMMAND_GROW_SIZE - 1); - the_printed_command_size = new; - - the_printed_command = (char *)xrealloc (the_printed_command, the_printed_command_size); - } -} - -#if defined (HAVE_VPRINTF) -/* ``If vprintf is available, you may assume that vfprintf and vsprintf are - also available.'' */ - -static void -#if defined (PREFER_STDARG) -xprintf (const char *format, ...) -#else -xprintf (format, va_alist) - const char *format; - va_dcl -#endif -{ - va_list args; - - SH_VA_START (args, format); - - vfprintf (stdout, format, args); - va_end (args); -} - -#else - -static void -xprintf (format, arg1, arg2, arg3, arg4, arg5) - const char *format; -{ - printf (format, arg1, arg2, arg3, arg4, arg5); -} - -#endif /* !HAVE_VPRINTF */ diff --git a/third_party/bash/psize.c b/third_party/bash/psize.c deleted file mode 100644 index 66f5f918a..000000000 --- a/third_party/bash/psize.c +++ /dev/null @@ -1,79 +0,0 @@ -/* psize.c - Find pipe size. */ - -/* Copyright (C) 1987, 1991 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -/* Write output in 128-byte chunks until we get a sigpipe or write gets an - EPIPE. Then report how many bytes we wrote. We assume that this is the - pipe size. */ -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include -#ifndef _MINIX -#include "bashtypes.h" -#endif -#include -#include - -#include "command.h" -#include "general.h" -#include "sig.h" - -#ifndef errno -extern int errno; -#endif - -int nw; - -sighandler -sigpipe (sig) - int sig; -{ - fprintf (stderr, "%d\n", nw); - exit (0); -} - -int -main (argc, argv) - int argc; - char **argv; -{ - char buf[128]; - register int i; - - for (i = 0; i < 128; i++) - buf[i] = ' '; - - signal (SIGPIPE, sigpipe); - - nw = 0; - for (;;) - { - int n; - n = write (1, buf, 128); - nw += n; - } - return (0); -} diff --git a/third_party/bash/quit.h b/third_party/bash/quit.h deleted file mode 100644 index 0af1d121f..000000000 --- a/third_party/bash/quit.h +++ /dev/null @@ -1,75 +0,0 @@ -/* quit.h -- How to handle SIGINT gracefully. */ - -/* Copyright (C) 1993-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_QUIT_H_) -#define _QUIT_H_ - -#include "sig.h" /* for sig_atomic_t */ - -/* Non-zero means SIGINT has already occurred. */ -extern volatile sig_atomic_t interrupt_state; -extern volatile sig_atomic_t terminating_signal; - -/* Macro to call a great deal. SIGINT just sets the interrupt_state variable. - When it is safe, put QUIT in the code, and the "interrupt" will take - place. The same scheme is used for terminating signals (e.g., SIGHUP) - and the terminating_signal variable. That calls a function which will - end up exiting the shell. */ -#define QUIT \ - do { \ - if (terminating_signal) termsig_handler (terminating_signal); \ - if (interrupt_state) throw_to_top_level (); \ - } while (0) - -#define SETINTERRUPT interrupt_state = 1 -#define CLRINTERRUPT interrupt_state = 0 - -#define ADDINTERRUPT interrupt_state++ -#define DELINTERRUPT interrupt_state-- - -#define ISINTERRUPT interrupt_state != 0 - -/* The same sort of thing, this time just for signals that would ordinarily - cause the shell to terminate. */ - -#define CHECK_TERMSIG \ - do { \ - if (terminating_signal) termsig_handler (terminating_signal); \ - } while (0) - -#define LASTSIG() \ - (terminating_signal ? terminating_signal : (interrupt_state ? SIGINT : 0)) - -#define CHECK_WAIT_INTR \ - do { \ - if (wait_intr_flag && wait_signal_received && this_shell_builtin && (this_shell_builtin == wait_builtin)) \ - sh_longjmp (wait_intr_buf, 1); \ - } while (0) - -#define RESET_SIGTERM \ - do { \ - sigterm_received = 0; \ - } while (0) - -#define CHECK_SIGTERM \ - do { \ - if (sigterm_received) termsig_handler (SIGTERM); \ - } while (0) -#endif /* _QUIT_H_ */ diff --git a/third_party/bash/random.c b/third_party/bash/random.c deleted file mode 100644 index 1eaa71aac..000000000 --- a/third_party/bash/random.c +++ /dev/null @@ -1,240 +0,0 @@ -/* random.c -- Functions for managing 16-bit and 32-bit random numbers. */ - -/* Copyright (C) 2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include "bashtypes.h" - -#if defined (HAVE_SYS_RANDOM_H) -# include -#endif - -#if defined (HAVE_UNISTD_H) -# include -#endif -#include "filecntl.h" - -#include -#include "bashansi.h" - -#include "shell.h" - -extern time_t shell_start_time; - -extern int last_random_value; - -static u_bits32_t intrand32 PARAMS((u_bits32_t)); -static u_bits32_t genseed PARAMS((void)); - -static u_bits32_t brand32 PARAMS((void)); -static void sbrand32 PARAMS((u_bits32_t)); -static void perturb_rand32 PARAMS((void)); - -/* The random number seed. You can change this by setting RANDOM. */ -static u_bits32_t rseed = 1; - -/* Returns a 32-bit pseudo-random number. */ -static u_bits32_t -intrand32 (last) - u_bits32_t last; -{ - /* Minimal Standard generator from - "Random number generators: good ones are hard to find", - Park and Miller, Communications of the ACM, vol. 31, no. 10, - October 1988, p. 1195. Filtered through FreeBSD. - - x(n+1) = 16807 * x(n) mod (m). - - We split up the calculations to avoid overflow. - - h = last / q; l = x - h * q; t = a * l - h * r - m = 2147483647, a = 16807, q = 127773, r = 2836 - - There are lots of other combinations of constants to use; look at - https://www.gnu.org/software/gsl/manual/html_node/Other-random-number-generators.html#Other-random-number-generators */ - - bits32_t h, l, t; - u_bits32_t ret; - - /* Can't seed with 0. */ - ret = (last == 0) ? 123459876 : last; - h = ret / 127773; - l = ret - (127773 * h); - t = 16807 * l - 2836 * h; - ret = (t < 0) ? t + 0x7fffffff : t; - - return (ret); -} - -static u_bits32_t -genseed () -{ - struct timeval tv; - u_bits32_t iv; - - gettimeofday (&tv, NULL); - iv = (u_bits32_t)seedrand; /* let the compiler truncate */ - iv = tv.tv_sec ^ tv.tv_usec ^ getpid () ^ getppid () ^ current_user.uid ^ iv; - return (iv); -} - -#define BASH_RAND_MAX 32767 /* 0x7fff - 16 bits */ - -/* Returns a pseudo-random number between 0 and 32767. */ -int -brand () -{ - unsigned int ret; - - rseed = intrand32 (rseed); - if (shell_compatibility_level > 50) - ret = (rseed >> 16) ^ (rseed & 65535); - else - ret = rseed; - return (ret & BASH_RAND_MAX); -} - -/* Set the random number generator seed to SEED. */ -void -sbrand (seed) - unsigned long seed; -{ - rseed = seed; - last_random_value = 0; -} - -void -seedrand () -{ - u_bits32_t iv; - - iv = genseed (); - sbrand (iv); -} - -static u_bits32_t rseed32 = 1073741823; -static int last_rand32; - -static int urandfd = -1; - -#define BASH_RAND32_MAX 0x7fffffff /* 32 bits */ - -/* Returns a 32-bit pseudo-random number between 0 and 4294967295. */ -static u_bits32_t -brand32 () -{ - u_bits32_t ret; - - rseed32 = intrand32 (rseed32); - return (rseed32 & BASH_RAND32_MAX); -} - -static void -sbrand32 (seed) - u_bits32_t seed; -{ - last_rand32 = rseed32 = seed; -} - -void -seedrand32 () -{ - u_bits32_t iv; - - iv = genseed (); - sbrand32 (iv); -} - -static void -perturb_rand32 () -{ - rseed32 ^= genseed (); -} - -/* Force another attempt to open /dev/urandom on the next call to get_urandom32 */ -void -urandom_close () -{ - if (urandfd >= 0) - close (urandfd); - urandfd = -1; -} - -#if !defined (HAVE_GETRANDOM) -/* Imperfect emulation of getrandom(2). */ -#ifndef GRND_NONBLOCK -# define GRND_NONBLOCK 1 -# define GRND_RANDOM 2 -#endif - -static ssize_t -getrandom (buf, len, flags) - void *buf; - size_t len; - unsigned int flags; -{ - int oflags; - ssize_t r; - static int urand_unavail = 0; - -#if HAVE_GETENTROPY - r = getentropy (buf, len); - return (r == 0) ? len : -1; -#endif - - if (urandfd == -1 && urand_unavail == 0) - { - oflags = O_RDONLY; - if (flags & GRND_NONBLOCK) - oflags |= O_NONBLOCK; - urandfd = open ("/dev/urandom", oflags, 0); - if (urandfd >= 0) - SET_CLOSE_ON_EXEC (urandfd); - else - { - urand_unavail = 1; - return -1; - } - } - if (urandfd >= 0 && (r = read (urandfd, buf, len)) == len) - return (r); - return -1; -} -#endif - -u_bits32_t -get_urandom32 () -{ - u_bits32_t ret; - - if (getrandom ((void *)&ret, sizeof (ret), GRND_NONBLOCK) == sizeof (ret)) - return (last_rand32 = ret); - -#if defined (HAVE_ARC4RANDOM) - ret = arc4random (); -#else - if (subshell_environment) - perturb_rand32 (); - do - ret = brand32 (); - while (ret == last_rand32); -#endif - return (last_rand32 = ret); -} diff --git a/third_party/bash/read.c b/third_party/bash/read.c deleted file mode 100644 index fc4346dda..000000000 --- a/third_party/bash/read.c +++ /dev/null @@ -1,1205 +0,0 @@ -/* read.c, created from read.def. */ -#line 22 "./read.def" - -#line 70 "./read.def" - -#include "config.h" - -#include "bashtypes.h" -#include "posixstat.h" - -#include - -#include "bashansi.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include -#include - -#ifdef __CYGWIN__ -# include -# include -#endif - -#include "bashintl.h" - -#include "shell.h" -#include "common.h" -#include "bashgetopt.h" -#include "trap.h" - -#include "shtty.h" - -#if defined (READLINE) -#include "bashline.h" -#include "third_party/readline/readline.h" -#endif - -#if defined (BUFFERED_INPUT) -# include "input.h" -#endif - -#include "shmbutil.h" -#include "timer.h" - -#if !defined(errno) -extern int errno; -#endif - -struct ttsave -{ - int fd; - TTYSTRUCT attrs; -}; - -#if defined (READLINE) -static void reset_attempted_completion_function PARAMS((char *)); -static int set_itext PARAMS((void)); -static char *edit_line PARAMS((char *, char *)); -static void set_eol_delim PARAMS((int)); -static void reset_eol_delim PARAMS((char *)); -static void set_readline_timeout PARAMS((sh_timer *t, time_t, long)); -#endif -static SHELL_VAR *bind_read_variable PARAMS((char *, char *, int)); -#if defined (HANDLE_MULTIBYTE) -static int read_mbchar PARAMS((int, char *, int, int, int)); -#endif -static void ttyrestore PARAMS((struct ttsave *)); - -static sighandler sigalrm PARAMS((int)); -static void reset_timeout PARAMS((void)); - -/* Try this to see what the rest of the shell can do with the information. */ -sh_timer *read_timeout; - -static int reading, tty_modified; -static SigHandler *old_alrm; -static unsigned char delim; - -static struct ttsave termsave; - -/* In all cases, SIGALRM just sets a flag that we check periodically. This - avoids problems with the semi-tricky stuff we do with the xfree of - input_string at the top of the unwind-protect list (see below). */ - -/* Set a flag that check_read_timeout can check. This relies on zread or - read_builtin calling trap.c:check_signals() (which calls check_read_timeout()) */ -static sighandler -sigalrm (s) - int s; -{ - /* Display warning if this is called without read_timeout set? */ - if (read_timeout) - read_timeout->alrmflag = 1; -} - -static void -reset_timeout () -{ - /* Cancel alarm before restoring signal handler. */ - if (read_timeout) - shtimer_clear (read_timeout); - read_timeout = 0; -} - -void -check_read_timeout () -{ - if (read_timeout && shtimer_chktimeout (read_timeout)) - sh_longjmp (read_timeout->jmpenv, 1); -} - -int -read_builtin_timeout (fd) - int fd; -{ - if ((read_timeout == 0) || - (read_timeout->fd != fd) || - (read_timeout->tmout.tv_sec == 0 && read_timeout->tmout.tv_usec == 0)) - return 0; - - return ((read_timeout->flags & SHTIMER_ALARM) ? shtimer_alrm (read_timeout) - : shtimer_select (read_timeout)); -} - -/* Read the value of the shell variables whose names follow. - The reading is done from the current input stream, whatever - that may be. Successive words of the input line are assigned - to the variables mentioned in LIST. The last variable in LIST - gets the remainder of the words on the line. If no variables - are mentioned in LIST, then the default variable is $REPLY. */ -int -read_builtin (list) - WORD_LIST *list; -{ - register char *varname; - int size, nr, pass_next, saw_escape, eof, opt, retval, code, print_ps2, nflag; - volatile int i; - int input_is_tty, input_is_pipe, unbuffered_read, skip_ctlesc, skip_ctlnul; - int raw, edit, nchars, silent, have_timeout, ignore_delim, fd; - int lastsig, t_errno; - int mb_cur_max; - unsigned int tmsec, tmusec; - long ival, uval; - intmax_t intval; - char c; - char *input_string, *orig_input_string, *ifs_chars, *prompt, *arrayname; - char *e, *t, *t1, *ps2, *tofree; - struct stat tsb; - SHELL_VAR *var; - TTYSTRUCT ttattrs, ttset; - sigset_t chldset, prevset; -#if defined (ARRAY_VARS) - WORD_LIST *alist; - int vflags; -#endif - int bindflags; -#if defined (READLINE) - char *rlbuf, *itext; - int rlind; - FILE *save_instream; -#endif - - USE_VAR(size); - USE_VAR(i); - USE_VAR(pass_next); - USE_VAR(print_ps2); - USE_VAR(saw_escape); - USE_VAR(input_is_pipe); -/* USE_VAR(raw); */ - USE_VAR(edit); - USE_VAR(tmsec); - USE_VAR(tmusec); - USE_VAR(nchars); - USE_VAR(silent); - USE_VAR(ifs_chars); - USE_VAR(prompt); - USE_VAR(arrayname); -#if defined (READLINE) - USE_VAR(rlbuf); - USE_VAR(rlind); - USE_VAR(itext); -#endif - USE_VAR(list); - USE_VAR(ps2); - USE_VAR(lastsig); - - reading = tty_modified = 0; - read_timeout = 0; - - i = 0; /* Index into the string that we are reading. */ - raw = edit = 0; /* Not reading raw input by default. */ - silent = 0; - arrayname = prompt = (char *)NULL; - fd = 0; /* file descriptor to read from */ - -#if defined (READLINE) - rlbuf = itext = (char *)0; - rlind = 0; -#endif - - mb_cur_max = MB_CUR_MAX; - tmsec = tmusec = 0; /* no timeout */ - nr = nchars = input_is_tty = input_is_pipe = unbuffered_read = have_timeout = 0; - delim = '\n'; /* read until newline */ - ignore_delim = nflag = 0; - - reset_internal_getopt (); - while ((opt = internal_getopt (list, "ersa:d:i:n:p:t:u:N:")) != -1) - { - switch (opt) - { - case 'r': - raw = 1; - break; - case 'p': - prompt = list_optarg; - break; - case 's': - silent = 1; - break; - case 'e': -#if defined (READLINE) - edit = 1; -#endif - break; - case 'i': -#if defined (READLINE) - itext = list_optarg; -#endif - break; -#if defined (ARRAY_VARS) - case 'a': - arrayname = list_optarg; - break; -#endif - case 't': - code = uconvert (list_optarg, &ival, &uval, (char **)NULL); - if (code == 0 || ival < 0 || uval < 0) - { - builtin_error (_("%s: invalid timeout specification"), list_optarg); - return (EXECUTION_FAILURE); - } - else - { - have_timeout = 1; - tmsec = ival; - tmusec = uval; - } - break; - case 'N': - ignore_delim = 1; - delim = -1; - case 'n': - nflag = 1; - code = legal_number (list_optarg, &intval); - if (code == 0 || intval < 0 || intval != (int)intval) - { - sh_invalidnum (list_optarg); - return (EXECUTION_FAILURE); - } - else - nchars = intval; - break; - case 'u': - code = legal_number (list_optarg, &intval); - if (code == 0 || intval < 0 || intval != (int)intval) - { - builtin_error (_("%s: invalid file descriptor specification"), list_optarg); - return (EXECUTION_FAILURE); - } - else - fd = intval; - if (sh_validfd (fd) == 0) - { - builtin_error (_("%d: invalid file descriptor: %s"), fd, strerror (errno)); - return (EXECUTION_FAILURE); - } - break; - case 'd': - delim = *list_optarg; - break; - CASE_HELPOPT; - default: - builtin_usage (); - return (EX_USAGE); - } - } - list = loptend; - - /* `read -t 0 var' tests whether input is available with select/FIONREAD, - and fails if those are unavailable */ - if (have_timeout && tmsec == 0 && tmusec == 0) - return (input_avail (fd) ? EXECUTION_SUCCESS : EXECUTION_FAILURE); - - /* Convenience: check early whether or not the first of possibly several - variable names is a valid identifier, and bail early if so. */ -#if defined (ARRAY_VARS) - if (list) - SET_VFLAGS (list->word->flags, vflags, bindflags); - if (list && legal_identifier (list->word->word) == 0 && valid_array_reference (list->word->word, vflags) == 0) -#else - bindflags = 0; - if (list && legal_identifier (list->word->word) == 0) -#endif - { - sh_invalidid (list->word->word); - return (EXECUTION_FAILURE); - } - - /* If we're asked to ignore the delimiter, make sure we do. */ - if (ignore_delim) - delim = -1; - - /* IF IFS is unset, we use the default of " \t\n". */ - ifs_chars = getifs (); - if (ifs_chars == 0) /* XXX - shouldn't happen */ - ifs_chars = ""; - /* If we want to read exactly NCHARS chars, don't split on IFS */ - if (ignore_delim) - ifs_chars = ""; - for (skip_ctlesc = skip_ctlnul = 0, e = ifs_chars; *e; e++) - skip_ctlesc |= *e == CTLESC, skip_ctlnul |= *e == CTLNUL; - - input_string = (char *)xmalloc (size = 112); /* XXX was 128 */ - input_string[0] = '\0'; - - /* More input and options validation */ - if (nflag == 1 && nchars == 0) - { - retval = read (fd, &c, 0); - retval = (retval >= 0) ? EXECUTION_SUCCESS : EXECUTION_FAILURE; - goto assign_vars; /* bail early if asked to read 0 chars */ - } - - /* $TMOUT, if set, is the default timeout for read. */ - if (have_timeout == 0 && (e = get_string_value ("TMOUT"))) - { - code = uconvert (e, &ival, &uval, (char **)NULL); - if (code == 0 || ival < 0 || uval < 0) - tmsec = tmusec = 0; - else - { - tmsec = ival; - tmusec = uval; - } - } - -#if defined (SIGCHLD) - sigemptyset (&chldset); - sigprocmask (SIG_BLOCK, (sigset_t *)0, &chldset); - sigaddset (&chldset, SIGCHLD); -#endif - - begin_unwind_frame ("read_builtin"); - -#if defined (BUFFERED_INPUT) - if (interactive == 0 && default_buffered_input >= 0 && fd_is_bash_input (fd)) - sync_buffered_stream (default_buffered_input); -#endif - -#if 1 - input_is_tty = isatty (fd); -#else - input_is_tty = 1; -#endif - if (input_is_tty == 0) -#ifndef __CYGWIN__ - input_is_pipe = (lseek (fd, 0L, SEEK_CUR) < 0) && (errno == ESPIPE); -#else - input_is_pipe = 1; -#endif - - /* If the -p, -e or -s flags were given, but input is not coming from the - terminal, turn them off. */ - if ((prompt || edit || silent) && input_is_tty == 0) - { - prompt = (char *)NULL; -#if defined (READLINE) - itext = (char *)NULL; -#endif - edit = silent = 0; - } - -#if defined (READLINE) - if (edit) - add_unwind_protect (xfree, rlbuf); -#endif - - pass_next = 0; /* Non-zero signifies last char was backslash. */ - saw_escape = 0; /* Non-zero signifies that we saw an escape char */ - - if (tmsec > 0 || tmusec > 0) - { - /* Turn off the timeout if stdin is a regular file (e.g. from - input redirection). */ - if ((fstat (fd, &tsb) < 0) || S_ISREG (tsb.st_mode)) - tmsec = tmusec = 0; - } - - if (tmsec > 0 || tmusec > 0) - { - read_timeout = shtimer_alloc (); - read_timeout->flags = SHTIMER_LONGJMP; - -#if defined (HAVE_SELECT) - read_timeout->flags |= (edit || posixly_correct) ? SHTIMER_ALARM : SHTIMER_SELECT; -#else - read_timeout->flags |= SHTIMER_ALARM; -#endif - read_timeout->fd = fd; - - read_timeout->alrm_handler = sigalrm; - } - - if (tmsec > 0 || tmusec > 0) - { - code = setjmp_nosigs (read_timeout->jmpenv); - if (code) - { - reset_timeout (); - sigprocmask (SIG_SETMASK, &prevset, (sigset_t *)0); - - /* Tricky. The top of the unwind-protect stack is the free of - input_string. We want to run all the rest and use input_string, - so we have to save input_string temporarily, run the unwind- - protects, then restore input_string so we can use it later */ - orig_input_string = 0; - input_string[i] = '\0'; /* make sure it's terminated */ - if (i == 0) - { - t = (char *)xmalloc (1); - t[0] = 0; - } - else - t = savestring (input_string); - - run_unwind_frame ("read_builtin"); - input_string = t; - retval = 128+SIGALRM; - goto assign_vars; - } - if (interactive_shell == 0) - initialize_terminating_signals (); - add_unwind_protect (reset_timeout, (char *)NULL); -#if defined (READLINE) - if (edit) - { - add_unwind_protect (reset_attempted_completion_function, (char *)NULL); - add_unwind_protect (bashline_reset_event_hook, (char *)NULL); - set_readline_timeout (read_timeout, tmsec, tmusec); - } - else -#endif - shtimer_set (read_timeout, tmsec, tmusec); - } - - /* If we've been asked to read only NCHARS chars, or we're using some - character other than newline to terminate the line, do the right - thing to readline or the tty. */ - if (nchars > 0 || delim != '\n') - { -#if defined (READLINE) - if (edit) - { - if (nchars > 0) - { - unwind_protect_int (rl_num_chars_to_read); - rl_num_chars_to_read = nchars; - } - if (delim != '\n') - { - set_eol_delim (delim); - add_unwind_protect (reset_eol_delim, (char *)NULL); - } - } - else -#endif - if (input_is_tty) - { - /* ttsave() */ - termsave.fd = fd; - ttgetattr (fd, &ttattrs); - termsave.attrs = ttattrs; - - ttset = ttattrs; - i = silent ? ttfd_cbreak (fd, &ttset) : ttfd_onechar (fd, &ttset); - if (i < 0) - sh_ttyerror (1); - tty_modified = 1; - add_unwind_protect ((Function *)ttyrestore, (char *)&termsave); - if (interactive_shell == 0) - initialize_terminating_signals (); - } - } - else if (silent) /* turn off echo but leave term in canonical mode */ - { - /* ttsave (); */ - termsave.fd = fd; - ttgetattr (fd, &ttattrs); - termsave.attrs = ttattrs; - - ttset = ttattrs; - i = ttfd_noecho (fd, &ttset); /* ttnoecho (); */ - if (i < 0) - sh_ttyerror (1); - - tty_modified = 1; - add_unwind_protect ((Function *)ttyrestore, (char *)&termsave); - if (interactive_shell == 0) - initialize_terminating_signals (); - } - -#if defined (READLINE) - save_instream = 0; - if (edit && fd != 0) - { - if (bash_readline_initialized == 0) - initialize_readline (); - - unwind_protect_var (rl_instream); - save_instream = rl_instream; - rl_instream = fdopen (fd, "r"); - } -#endif - - /* This *must* be the top unwind-protect on the stack, so the manipulation - of the unwind-protect stack after the realloc() works right. */ - add_unwind_protect (xfree, input_string); - - check_read_timeout (); - /* These only matter if edit == 0 */ - if ((nchars > 0) && (input_is_tty == 0) && ignore_delim) /* read -N */ - unbuffered_read = 2; -#if 0 - else if ((nchars > 0) || (delim != '\n') || input_is_pipe) -#else - else if (((nchars > 0 || delim != '\n') && input_is_tty) || input_is_pipe) - unbuffered_read = 1; -#endif - if (prompt && edit == 0) - { - fprintf (stderr, "%s", prompt); - fflush (stderr); - } - -#if defined (__CYGWIN__) && defined (O_TEXT) - setmode (0, O_TEXT); -#endif - - ps2 = 0; - for (print_ps2 = eof = retval = 0;;) - { - check_read_timeout (); - -#if defined (READLINE) - if (edit) - { - /* If we have a null delimiter, don't treat NULL as ending the line */ - if (rlbuf && rlbuf[rlind] == '\0' && delim != '\0') - { - free (rlbuf); - rlbuf = (char *)0; - } -#if defined (SIGCHLD) - if (tmsec > 0 || tmusec > 0) - sigprocmask (SIG_SETMASK, &chldset, &prevset); -#endif - if (rlbuf == 0) - { - reading = 1; - rlbuf = edit_line (prompt ? prompt : "", itext); - reading = 0; - rlind = 0; - } -#if defined (SIGCHLD) - if (tmsec > 0 || tmusec > 0) - sigprocmask (SIG_SETMASK, &prevset, (sigset_t *)0); -#endif - if (rlbuf == 0) - { - eof = 1; - break; - } - c = rlbuf[rlind++]; - } - else - { -#endif - - if (print_ps2) - { - if (ps2 == 0) - ps2 = get_string_value ("PS2"); - fprintf (stderr, "%s", ps2 ? ps2 : ""); - fflush (stderr); - print_ps2 = 0; - } - - reading = 1; - check_read_timeout (); - errno = 0; - -#if defined (SIGCHLD) - if (tmsec > 0 || tmusec > 0) - sigprocmask (SIG_SETMASK, &chldset, &prevset); -#endif - if (unbuffered_read == 2) - retval = posixly_correct ? zreadintr (fd, &c, 1) : zreadn (fd, &c, nchars - nr); - else if (unbuffered_read) - retval = posixly_correct ? zreadintr (fd, &c, 1) : zread (fd, &c, 1); - else - retval = posixly_correct ? zreadcintr (fd, &c) : zreadc (fd, &c); -#if defined (SIGCHLD) - if (tmsec > 0 || tmusec > 0) - sigprocmask (SIG_SETMASK, &prevset, (sigset_t *)0); -#endif - - reading = 0; - - if (retval <= 0) - { - int t; - - t = errno; - if (retval < 0 && errno == EINTR) - { - check_signals (); /* in case we didn't call zread via zreadc */ - lastsig = LASTSIG(); - if (lastsig == 0) - lastsig = trapped_signal_received; -#if 0 - run_pending_traps (); /* because interrupt_immediately is not set */ -#endif - } - else - lastsig = 0; - if (terminating_signal && tty_modified) - ttyrestore (&termsave); /* fix terminal before exiting */ - CHECK_TERMSIG; - eof = 1; - errno = t; /* preserve it for the error message below */ - break; - } - - QUIT; /* in case we didn't call check_signals() */ -#if defined (READLINE) - } -#endif - - if (retval <= 0) /* XXX shouldn't happen */ - check_read_timeout (); - - /* XXX -- use i + mb_cur_max (at least 4) for multibyte/read_mbchar */ - if (i + (mb_cur_max > 4 ? mb_cur_max : 4) >= size) - { - char *t; - t = (char *)xrealloc (input_string, size += 128); - - /* Only need to change unwind-protect if input_string changes */ - if (t != input_string) - { - input_string = t; - remove_unwind_protect (); - add_unwind_protect (xfree, input_string); - } - } - - /* If the next character is to be accepted verbatim, a backslash - newline pair still disappears from the input. */ - if (pass_next) - { - pass_next = 0; - if (c == '\n') - { - if (skip_ctlesc == 0 && i > 0) - i--; /* back up over the CTLESC */ - if (interactive && input_is_tty && raw == 0) - print_ps2 = 1; - } - else - goto add_char; - continue; - } - - /* This may cause problems if IFS contains CTLESC */ - if (c == '\\' && raw == 0) - { - pass_next++; - if (skip_ctlesc == 0) - { - saw_escape++; - input_string[i++] = CTLESC; - } - continue; - } - - if (ignore_delim == 0 && (unsigned char)c == delim) - break; - - if (c == '\0' && delim != '\0') - continue; /* skip NUL bytes in input */ - - if ((skip_ctlesc == 0 && c == CTLESC) || (skip_ctlnul == 0 && c == CTLNUL)) - { - saw_escape++; - input_string[i++] = CTLESC; - } - -add_char: - input_string[i++] = c; - check_read_timeout (); - -#if defined (HANDLE_MULTIBYTE) - /* XXX - what if C == 127? Can DEL introduce a multibyte sequence? */ - if (mb_cur_max > 1 && is_basic (c) == 0) - { - input_string[i] = '\0'; /* for simplicity and debugging */ - /* If we got input from readline, grab the next multibyte char from - rlbuf. */ -# if defined (READLINE) - if (edit) - { - size_t clen; - clen = mbrlen (rlbuf + rlind - 1, mb_cur_max, (mbstate_t *)NULL); - /* We only deal with valid multibyte sequences longer than one - byte. If we get anything else, we leave the one character - copied and move on to the next. */ - if ((int)clen > 1) - { - memcpy (input_string+i, rlbuf+rlind, clen-1); - i += clen - 1; - rlind += clen - 1; - } - } - else -# endif - if (locale_utf8locale == 0 || ((c & 0x80) != 0)) - i += read_mbchar (fd, input_string, i, c, unbuffered_read); - } -#endif - - nr++; - - if (nchars > 0 && nr >= nchars) - break; - } - input_string[i] = '\0'; - check_read_timeout (); - -#if defined (READLINE) - if (edit) - free (rlbuf); -#endif - - if (retval < 0) - { - t_errno = errno; - if (errno != EINTR) - builtin_error (_("read error: %d: %s"), fd, strerror (errno)); - run_unwind_frame ("read_builtin"); - return ((t_errno != EINTR) ? EXECUTION_FAILURE : 128+lastsig); - } - - if (tmsec > 0 || tmusec > 0) - reset_timeout (); - - if (nchars > 0 || delim != '\n') - { -#if defined (READLINE) - if (edit) - { - if (nchars > 0) - rl_num_chars_to_read = 0; - if (delim != '\n') - reset_eol_delim ((char *)NULL); - } - else -#endif - if (input_is_tty) - ttyrestore (&termsave); - } - else if (silent) - ttyrestore (&termsave); - - if (unbuffered_read == 0) - zsyncfd (fd); - -#if defined (READLINE) - if (save_instream) - rl_instream = save_instream; /* can't portably free it */ -#endif - - discard_unwind_frame ("read_builtin"); - - retval = eof ? EXECUTION_FAILURE : EXECUTION_SUCCESS; - -assign_vars: - -#if defined (ARRAY_VARS) - /* If -a was given, take the string read, break it into a list of words, - an assign them to `arrayname' in turn. */ - if (arrayname) - { - /* pass 1 for flags arg to clear the existing array + 2 to check for a - valid identifier. */ - var = builtin_find_indexed_array (arrayname, 3); - if (var == 0) - { - free (input_string); - return EXECUTION_FAILURE; /* readonly or noassign */ - } - - alist = list_string (input_string, ifs_chars, 0); - if (alist) - { - if (saw_escape) - dequote_list (alist); - else - word_list_remove_quoted_nulls (alist); - assign_array_var_from_word_list (var, alist, 0); - dispose_words (alist); - } - free (input_string); - return (retval); - } -#endif /* ARRAY_VARS */ - - /* If there are no variables, save the text of the line read to the - variable $REPLY. ksh93 strips leading and trailing IFS whitespace, - so that `read x ; echo "$x"' and `read ; echo "$REPLY"' behave the - same way, but I believe that the difference in behaviors is useful - enough to not do it. Without the bash behavior, there is no way - to read a line completely without interpretation or modification - unless you mess with $IFS (e.g., setting it to the empty string). - If you disagree, change the occurrences of `#if 0' to `#if 1' below. */ - if (list == 0) - { -#if 0 - orig_input_string = input_string; - for (t = input_string; ifs_chars && *ifs_chars && spctabnl(*t) && isifs(*t); t++) - ; - input_string = t; - input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars, saw_escape); -#endif - - if (saw_escape) - { - t = dequote_string (input_string); - var = bind_variable ("REPLY", t, 0); - free (t); - } - else - var = bind_variable ("REPLY", input_string, 0); - if (var == 0 || readonly_p (var) || noassign_p (var)) - retval = EXECUTION_FAILURE; - else - VUNSETATTR (var, att_invisible); - - free (input_string); - return (retval); - } - - /* This code implements the Posix.2 spec for splitting the words - read and assigning them to variables. */ - orig_input_string = input_string; - - /* Remove IFS white space at the beginning of the input string. If - $IFS is null, no field splitting is performed. */ - for (t = input_string; ifs_chars && *ifs_chars && spctabnl(*t) && isifs(*t); t++) - ; - input_string = t; - for (; list->next; list = list->next) - { - varname = list->word->word; -#if defined (ARRAY_VARS) - SET_VFLAGS (list->word->flags, vflags, bindflags); - if (legal_identifier (varname) == 0 && valid_array_reference (varname, vflags) == 0) -#else - if (legal_identifier (varname) == 0) -#endif - { - sh_invalidid (varname); - free (orig_input_string); - return (EXECUTION_FAILURE); - } - - /* If there are more variables than words read from the input, - the remaining variables are set to the empty string. */ - if (*input_string) - { - /* This call updates INPUT_STRING. */ - t = get_word_from_string (&input_string, ifs_chars, &e); - if (t) - *e = '\0'; - /* Don't bother to remove the CTLESC unless we added one - somewhere while reading the string. */ - if (t && saw_escape) - { - t1 = dequote_string (t); - var = bind_read_variable (varname, t1, bindflags); - free (t1); - } - else - var = bind_read_variable (varname, t ? t : "", bindflags); - } - else - { - t = (char *)0; - var = bind_read_variable (varname, "", bindflags); - } - - FREE (t); - if (var == 0) - { - free (orig_input_string); - return (EXECUTION_FAILURE); - } - - stupidly_hack_special_variables (varname); - VUNSETATTR (var, att_invisible); - } - - /* Now assign the rest of the line to the last variable argument. */ -#if defined (ARRAY_VARS) - SET_VFLAGS (list->word->flags, vflags, bindflags); - if (legal_identifier (list->word->word) == 0 && valid_array_reference (list->word->word, vflags) == 0) -#else - if (legal_identifier (list->word->word) == 0) -#endif - { - sh_invalidid (list->word->word); - free (orig_input_string); - return (EXECUTION_FAILURE); - } - -#if 0 - /* This has to be done this way rather than using string_list - and list_string because Posix.2 says that the last variable gets the - remaining words and their intervening separators. */ - input_string = strip_trailing_ifs_whitespace (input_string, ifs_chars, saw_escape); -#else - /* Check whether or not the number of fields is exactly the same as the - number of variables. */ - tofree = NULL; - if (*input_string) - { - t1 = input_string; - t = get_word_from_string (&input_string, ifs_chars, &e); - if (*input_string == 0) - tofree = input_string = t; - else - { - input_string = strip_trailing_ifs_whitespace (t1, ifs_chars, saw_escape); - tofree = t; - } - } -#endif - - if (saw_escape && input_string && *input_string) - { - t = dequote_string (input_string); - var = bind_read_variable (list->word->word, t, bindflags); - free (t); - } - else - var = bind_read_variable (list->word->word, input_string ? input_string : "", bindflags); - - if (var) - { - stupidly_hack_special_variables (list->word->word); - VUNSETATTR (var, att_invisible); - } - else - retval = EXECUTION_FAILURE; - - FREE (tofree); - free (orig_input_string); - - return (retval); -} - -static SHELL_VAR * -bind_read_variable (name, value, flags) - char *name, *value; - int flags; -{ - SHELL_VAR *v; - - v = builtin_bind_variable (name, value, flags); - return (v == 0 ? v - : ((readonly_p (v) || noassign_p (v)) ? (SHELL_VAR *)NULL : v)); -} - -#if defined (HANDLE_MULTIBYTE) -static int -read_mbchar (fd, string, ind, ch, unbuffered) - int fd; - char *string; - int ind, ch, unbuffered; -{ - char mbchar[MB_LEN_MAX + 1]; - int i, n, r; - char c; - size_t ret; - mbstate_t ps, ps_back; - wchar_t wc; - - memset (&ps, '\0', sizeof (mbstate_t)); - memset (&ps_back, '\0', sizeof (mbstate_t)); - - mbchar[0] = ch; - i = 1; - for (n = 0; n <= MB_LEN_MAX; n++) - { - ps_back = ps; - ret = mbrtowc (&wc, mbchar, i, &ps); - if (ret == (size_t)-2) - { - ps = ps_back; - - /* We don't want to be interrupted during a multibyte char read */ - if (unbuffered == 2) - r = zreadn (fd, &c, 1); - else if (unbuffered) - r = zread (fd, &c, 1); - else - r = zreadc (fd, &c); - if (r <= 0) - goto mbchar_return; - mbchar[i++] = c; - continue; - } - else if (ret == (size_t)-1 || ret == (size_t)0 || ret > (size_t)0) - break; - } - -mbchar_return: - if (i > 1) /* read a multibyte char */ - /* mbchar[0] is already string[ind-1] */ - for (r = 1; r < i; r++) - string[ind+r-1] = mbchar[r]; - return i - 1; -} -#endif - - -static void -ttyrestore (ttp) - struct ttsave *ttp; -{ - ttsetattr (ttp->fd, &(ttp->attrs)); - tty_modified = 0; -} - -void -read_tty_cleanup () -{ - if (tty_modified) - ttyrestore (&termsave); -} - -int -read_tty_modified () -{ - return (tty_modified); -} - -#if defined (READLINE) -static rl_completion_func_t *old_attempted_completion_function = 0; -static rl_hook_func_t *old_startup_hook; -static char *deftext; - -static void -reset_attempted_completion_function (cp) - char *cp; -{ - if (rl_attempted_completion_function == 0 && old_attempted_completion_function) - rl_attempted_completion_function = old_attempted_completion_function; -} - -static int -set_itext () -{ - int r1, r2; - - r1 = r2 = 0; - if (old_startup_hook) - r1 = (*old_startup_hook) (); - if (deftext) - { - r2 = rl_insert_text (deftext); - deftext = (char *)NULL; - rl_startup_hook = old_startup_hook; - old_startup_hook = (rl_hook_func_t *)NULL; - } - return (r1 || r2); -} - -static char * -edit_line (p, itext) - char *p; - char *itext; -{ - char *ret; - int len; - - if (bash_readline_initialized == 0) - initialize_readline (); - - old_attempted_completion_function = rl_attempted_completion_function; - rl_attempted_completion_function = (rl_completion_func_t *)NULL; - bashline_set_event_hook (); - if (itext) - { - old_startup_hook = rl_startup_hook; - rl_startup_hook = set_itext; - deftext = itext; - } - - ret = readline (p); - - rl_attempted_completion_function = old_attempted_completion_function; - old_attempted_completion_function = (rl_completion_func_t *)NULL; - bashline_reset_event_hook (); - - if (ret == 0) - { - if (RL_ISSTATE (RL_STATE_TIMEOUT)) - { - sigalrm (SIGALRM); /* simulate receiving SIGALRM */ - check_read_timeout (); - } - return ret; - } - - len = strlen (ret); - ret = (char *)xrealloc (ret, len + 2); - ret[len++] = delim; - ret[len] = '\0'; - return ret; -} - -static void -set_readline_timeout (t, sec, usec) - sh_timer *t; - time_t sec; - long usec; -{ - t->tmout.tv_sec = sec; - t->tmout.tv_usec = usec; - rl_set_timeout (sec, usec); -} - -static int old_delim_ctype; -static rl_command_func_t *old_delim_func; -static int old_newline_ctype; -static rl_command_func_t *old_newline_func; - -static unsigned char delim_char; - -static void -set_eol_delim (c) - int c; -{ - Keymap cmap; - - if (bash_readline_initialized == 0) - initialize_readline (); - cmap = rl_get_keymap (); - - /* Save the old delimiter char binding */ - old_newline_ctype = cmap[RETURN].type; - old_newline_func = cmap[RETURN].function; - old_delim_ctype = cmap[c].type; - old_delim_func = cmap[c].function; - - /* Change newline to self-insert */ - cmap[RETURN].type = ISFUNC; - cmap[RETURN].function = rl_insert; - - /* Bind the delimiter character to accept-line. */ - cmap[c].type = ISFUNC; - cmap[c].function = rl_newline; - - delim_char = c; -} - -static void -reset_eol_delim (cp) - char *cp; -{ - Keymap cmap; - - cmap = rl_get_keymap (); - - cmap[RETURN].type = old_newline_ctype; - cmap[RETURN].function = old_newline_func; - - cmap[delim_char].type = old_delim_ctype; - cmap[delim_char].function = old_delim_func; -} -#endif diff --git a/third_party/bash/redir.c b/third_party/bash/redir.c deleted file mode 100644 index 6a9feac99..000000000 --- a/third_party/bash/redir.c +++ /dev/null @@ -1,1528 +0,0 @@ -/* redir.c -- Functions to perform input and output redirection. */ - -/* Copyright (C) 1997-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if !defined (__GNUC__) && !defined (HAVE_ALLOCA_H) && defined (_AIX) - #pragma alloca -#endif /* _AIX && RISC6000 && !__GNUC__ */ - -#include -#include "bashtypes.h" -#if !defined (_MINIX) && defined (HAVE_SYS_FILE_H) -# include -#endif -#include "filecntl.h" -#include "posixstat.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include - -#if !defined (errno) -extern int errno; -#endif - -#include "bashansi.h" -#include "bashintl.h" -#include "memalloc.h" - -#define NEED_FPURGE_DECL - -#include "shell.h" -#include "flags.h" -#include "execute_cmd.h" -#include "redir.h" -#include "trap.h" - -#if defined (BUFFERED_INPUT) -# include "input.h" -#endif - -#include "pipesize.h" - -/* FreeBSD 13 can reliably handle atomic writes at this capacity without - hanging. */ -#if __FreeBSD__ && !defined (HEREDOC_PIPESIZE) -# define HEREDOC_PIPESIZE 4096 -#endif - -/* Normally set by a build process command that computes pipe capacity */ -#ifndef PIPESIZE -# ifdef PIPE_BUF -# define PIPESIZE PIPE_BUF -# else -# define PIPESIZE 4096 -# endif -#endif - -#ifndef HEREDOC_PIPESIZE -# define HEREDOC_PIPESIZE PIPESIZE -#endif - -#if defined (HEREDOC_PIPEMAX) -# if HEREDOC_PIPESIZE > HEREDOC_PIPEMAX -# define HEREDOC_PIPESIZE HEREDOC_PIPEMAX -# endif -#endif - -#define SHELL_FD_BASE 10 - -int expanding_redir; -int varassign_redir_autoclose = 0; - -extern REDIRECT *redirection_undo_list; -extern REDIRECT *exec_redirection_undo_list; - -/* Static functions defined and used in this file. */ -static void add_exec_redirect PARAMS((REDIRECT *)); -static int add_undo_redirect PARAMS((int, enum r_instruction, int)); -static int add_undo_close_redirect PARAMS((int)); -static int expandable_redirection_filename PARAMS((REDIRECT *)); -static int stdin_redirection PARAMS((enum r_instruction, int)); -static int undoablefd PARAMS((int)); -static int do_redirection_internal PARAMS((REDIRECT *, int, char **)); - -static char *heredoc_expand PARAMS((WORD_DESC *, enum r_instruction, size_t *)); -static int heredoc_write PARAMS((int, char *, size_t)); -static int here_document_to_fd PARAMS((WORD_DESC *, enum r_instruction)); - -static int redir_special_open PARAMS((int, char *, int, int, enum r_instruction)); -static int noclobber_open PARAMS((char *, int, int, enum r_instruction)); -static int redir_open PARAMS((char *, int, int, enum r_instruction)); - -static int redir_varassign PARAMS((REDIRECT *, int)); -static int redir_varvalue PARAMS((REDIRECT *)); - -/* Spare redirector used when translating [N]>&WORD[-] or [N]<&WORD[-] to - a new redirection and when creating the redirection undo list. */ -static REDIRECTEE rd; - -/* Set to errno when a here document cannot be created for some reason. - Used to print a reasonable error message. */ -static int heredoc_errno; - -#define REDIRECTION_ERROR(r, e, fd) \ -do { \ - if ((r) < 0) \ - { \ - if (fd >= 0) \ - close (fd); \ - set_exit_status (EXECUTION_FAILURE);\ - return ((e) == 0 ? EINVAL : (e));\ - } \ -} while (0) - -void -redirection_error (temp, error, fn) - REDIRECT *temp; - int error; - char *fn; /* already-expanded filename */ -{ - char *filename, *allocname; - int oflags; - - allocname = 0; - if ((temp->rflags & REDIR_VARASSIGN) && error < 0) - filename = allocname = savestring (temp->redirector.filename->word); - else if ((temp->rflags & REDIR_VARASSIGN) == 0 && temp->redirector.dest < 0) - /* This can happen when read_token_word encounters overflow, like in - exec 4294967297>x */ - filename = _("file descriptor out of range"); -#ifdef EBADF - /* This error can never involve NOCLOBBER */ - else if (error != NOCLOBBER_REDIRECT && temp->redirector.dest >= 0 && error == EBADF) - { - /* If we're dealing with two file descriptors, we have to guess about - which one is invalid; in the cases of r_{duplicating,move}_input and - r_{duplicating,move}_output we're here because dup2() failed. */ - switch (temp->instruction) - { - case r_duplicating_input: - case r_duplicating_output: - case r_move_input: - case r_move_output: - filename = allocname = itos (temp->redirectee.dest); - break; - case r_duplicating_input_word: - if (temp->redirector.dest == 0) /* Guess */ - filename = temp->redirectee.filename->word; /* XXX */ - else - filename = allocname = itos (temp->redirector.dest); - break; - case r_duplicating_output_word: - if (temp->redirector.dest == 1) /* Guess */ - filename = temp->redirectee.filename->word; /* XXX */ - else - filename = allocname = itos (temp->redirector.dest); - break; - default: - filename = allocname = itos (temp->redirector.dest); - break; - } - } -#endif - else if (fn) - filename = fn; - else if (expandable_redirection_filename (temp)) - { - oflags = temp->redirectee.filename->flags; - if (posixly_correct && interactive_shell == 0) - temp->redirectee.filename->flags |= W_NOGLOB; - temp->redirectee.filename->flags |= W_NOCOMSUB; - filename = allocname = redirection_expand (temp->redirectee.filename); - temp->redirectee.filename->flags = oflags; - if (filename == 0) - filename = temp->redirectee.filename->word; - } - else if (temp->redirectee.dest < 0) - filename = _("file descriptor out of range"); - else - filename = allocname = itos (temp->redirectee.dest); - - switch (error) - { - case AMBIGUOUS_REDIRECT: - internal_error (_("%s: ambiguous redirect"), filename); - break; - - case NOCLOBBER_REDIRECT: - internal_error (_("%s: cannot overwrite existing file"), filename); - break; - -#if defined (RESTRICTED_SHELL) - case RESTRICTED_REDIRECT: - internal_error (_("%s: restricted: cannot redirect output"), filename); - break; -#endif /* RESTRICTED_SHELL */ - - case HEREDOC_REDIRECT: - internal_error (_("cannot create temp file for here-document: %s"), strerror (heredoc_errno)); - break; - - case BADVAR_REDIRECT: - internal_error (_("%s: cannot assign fd to variable"), filename); - break; - - default: - internal_error ("%s: %s", filename, strerror (error)); - break; - } - - FREE (allocname); -} - -/* Perform the redirections on LIST. If flags & RX_ACTIVE, then actually - make input and output file descriptors, otherwise just do whatever is - necessary for side effecting. flags & RX_UNDOABLE says to remember - how to undo the redirections later, if non-zero. If flags & RX_CLEXEC - is non-zero, file descriptors opened in do_redirection () have their - close-on-exec flag set. */ -int -do_redirections (list, flags) - REDIRECT *list; - int flags; -{ - int error; - REDIRECT *temp; - char *fn; - - if (flags & RX_UNDOABLE) - { - if (redirection_undo_list) - { - dispose_redirects (redirection_undo_list); - redirection_undo_list = (REDIRECT *)NULL; - } - if (exec_redirection_undo_list) - dispose_exec_redirects (); - } - - for (temp = list; temp; temp = temp->next) - { - fn = 0; - error = do_redirection_internal (temp, flags, &fn); - if (error) - { - redirection_error (temp, error, fn); - FREE (fn); - return (error); - } - FREE (fn); - } - return (0); -} - -/* Return non-zero if the redirection pointed to by REDIRECT has a - redirectee.filename that can be expanded. */ -static int -expandable_redirection_filename (redirect) - REDIRECT *redirect; -{ - switch (redirect->instruction) - { - case r_output_direction: - case r_appending_to: - case r_input_direction: - case r_inputa_direction: - case r_err_and_out: - case r_append_err_and_out: - case r_input_output: - case r_output_force: - case r_duplicating_input_word: - case r_duplicating_output_word: - case r_move_input_word: - case r_move_output_word: - return 1; - - default: - return 0; - } -} - -/* Expand the word in WORD returning a string. If WORD expands to - multiple words (or no words), then return NULL. */ -char * -redirection_expand (word) - WORD_DESC *word; -{ - char *result; - WORD_LIST *tlist1, *tlist2; - WORD_DESC *w; - int old; - - w = copy_word (word); - if (posixly_correct) - w->flags |= W_NOSPLIT; - - tlist1 = make_word_list (w, (WORD_LIST *)NULL); - expanding_redir = 1; - /* Now that we've changed the variable search order to ignore the temp - environment, see if we need to change the cached IFS values. */ - sv_ifs ("IFS"); - tlist2 = expand_words_no_vars (tlist1); - expanding_redir = 0; - /* Now we need to change the variable search order back to include the temp - environment. We force the temp environment search by forcing - executing_builtin to 1. This is what makes `read' get the right values - for the IFS-related cached variables, for example. */ - old = executing_builtin; - executing_builtin = 1; - sv_ifs ("IFS"); - executing_builtin = old; - dispose_words (tlist1); - - if (tlist2 == 0 || tlist2->next) - { - /* We expanded to no words, or to more than a single word. - Dispose of the word list and return NULL. */ - if (tlist2) - dispose_words (tlist2); - return ((char *)NULL); - } - result = string_list (tlist2); /* XXX savestring (tlist2->word->word)? */ - dispose_words (tlist2); - return (result); -} - -/* Expand a here-document or here-string (determined by RI) contained in - REDIRECTEE and return the expanded document. If LENP is non-zero, put - the length of the returned string into *LENP. - - This captures everything about expanding here-documents and here-strings: - the returned document should be written directly to whatever file - descriptor is specified. In particular, it adds a newline to the end of - a here-string to preserve previous semantics. */ -static char * -heredoc_expand (redirectee, ri, lenp) - WORD_DESC *redirectee; - enum r_instruction ri; - size_t *lenp; -{ - char *document; - size_t dlen; - int old; - - if (redirectee->word == 0 || redirectee->word[0] == '\0') - { - if (lenp) - *lenp = 0; - return (redirectee->word); - } - - /* Quoted here documents are not expanded */ - if (ri != r_reading_string && (redirectee->flags & W_QUOTED)) - { - if (lenp) - *lenp = STRLEN (redirectee->word); - return (redirectee->word); - } - - expanding_redir = 1; - /* Now that we've changed the variable search order to ignore the temp - environment, see if we need to change the cached IFS values. */ - sv_ifs ("IFS"); - document = (ri == r_reading_string) ? expand_assignment_string_to_string (redirectee->word, 0) - : expand_string_to_string (redirectee->word, Q_HERE_DOCUMENT); - expanding_redir = 0; - /* Now we need to change the variable search order back to include the temp - environment. We force the temp environment search by forcing - executing_builtin to 1. This is what makes `read' get the right values - for the IFS-related cached variables, for example. */ - old = executing_builtin; - executing_builtin = 1; - sv_ifs ("IFS"); - executing_builtin = old; - - dlen = STRLEN (document); - /* XXX - Add trailing newline to here-string */ - if (ri == r_reading_string) - { - document = xrealloc (document, dlen + 2); - document[dlen++] = '\n'; - document[dlen] = '\0'; - } - if (lenp) - *lenp = dlen; - - return document; -} - -/* Write HEREDOC (of length HDLEN) to FD, returning 0 on success and ERRNO on - error. Don't handle interrupts. */ -static int -heredoc_write (fd, heredoc, herelen) - int fd; - char *heredoc; - size_t herelen; -{ - ssize_t nw; - int e; - - errno = 0; - nw = write (fd, heredoc, herelen); - e = errno; - if (nw != herelen) - { - if (e == 0) - e = ENOSPC; - return e; - } - return 0; -} - -/* Create a temporary file or pipe holding the text of the here document - pointed to by REDIRECTEE, and return a file descriptor open for reading - to it. Return -1 on any error, and make sure errno is set appropriately. */ -static int -here_document_to_fd (redirectee, ri) - WORD_DESC *redirectee; - enum r_instruction ri; -{ - char *filename; - int r, fd, fd2, herepipe[2]; - char *document; - size_t document_len; -#if HEREDOC_PARANOID - struct stat st1, st2; -#endif - - /* Expand the here-document/here-string first and then decide what to do. */ - document = heredoc_expand (redirectee, ri, &document_len); - - /* If we have a zero-length document, don't mess with a temp file */ - if (document_len == 0) - { - fd = open ("/dev/null", O_RDONLY); - r = errno; - if (document != redirectee->word) - FREE (document); - errno = r; - return fd; - } - - if (shell_compatibility_level <= 50) - goto use_tempfile; - -#if HEREDOC_PIPESIZE - /* Try to use a pipe internal to this process if the document is shorter - than the system's pipe capacity (computed at build time). We want to - write the entire document without write blocking. */ - if (document_len <= HEREDOC_PIPESIZE) - { - if (pipe (herepipe) < 0) - { - /* XXX - goto use_tempfile; ? */ - r = errno; - if (document != redirectee->word) - free (document); - errno = r; - return (-1); - } - -#if defined (F_GETPIPE_SZ) - if (fcntl (herepipe[1], F_GETPIPE_SZ, 0) < document_len) - goto use_tempfile; -#endif - - r = heredoc_write (herepipe[1], document, document_len); - if (document != redirectee->word) - free (document); - close (herepipe[1]); - if (r) /* write error */ - { - close (herepipe[0]); - errno = r; - return (-1); - } - return (herepipe[0]); - } -#endif - -use_tempfile: - - fd = sh_mktmpfd ("sh-thd", MT_USERANDOM|MT_USETMPDIR, &filename); - - /* If we failed for some reason other than the file existing, abort */ - if (fd < 0) - { - r = errno; - FREE (filename); - if (document != redirectee->word) - FREE (document); - errno = r; - return (fd); - } - - fchmod (fd, S_IRUSR | S_IWUSR); - SET_CLOSE_ON_EXEC (fd); - - errno = r = 0; /* XXX */ - r = heredoc_write (fd, document, document_len); - if (document != redirectee->word) - FREE (document); - - if (r) - { - close (fd); - unlink (filename); - free (filename); - errno = r; - return (-1); - } - - /* In an attempt to avoid races, we close the first fd only after opening - the second. */ - /* Make the document really temporary. Also make it the input. */ - fd2 = open (filename, O_RDONLY|O_BINARY, 0600); - - if (fd2 < 0) - { - r = errno; - unlink (filename); - free (filename); - close (fd); - errno = r; - return -1; - } - -#if HEREDOC_PARANOID - /* We can use same_file here to check whether or not fd and fd2 refer to - the same file, but we don't do that unless HEREDOC_PARANOID is defined. */ - if (fstat (fd, &st1) < 0 || S_ISREG (st1.st_mode) == 0 || - fstat (fd2, &st2) < 0 || S_ISREG (st2.st_mode) == 0 || - same_file (filename, filename, &st1, &st2) == 0) - { - unlink (filename); - free (filename); - close (fd); - close (fd2); - errno = EEXIST; - return -1; - } -#endif - - close (fd); - if (unlink (filename) < 0) - { - r = errno; - close (fd2); - free (filename); - errno = r; - return (-1); - } - - free (filename); - - fchmod (fd2, S_IRUSR); - return (fd2); -} - -#define RF_DEVFD 1 -#define RF_DEVSTDERR 2 -#define RF_DEVSTDIN 3 -#define RF_DEVSTDOUT 4 -#define RF_DEVTCP 5 -#define RF_DEVUDP 6 - -/* A list of pattern/value pairs for filenames that the redirection - code handles specially. */ -static STRING_INT_ALIST _redir_special_filenames[] = { -#if !defined (HAVE_DEV_FD) - { "/dev/fd/[0-9]*", RF_DEVFD }, -#endif -#if !defined (HAVE_DEV_STDIN) - { "/dev/stderr", RF_DEVSTDERR }, - { "/dev/stdin", RF_DEVSTDIN }, - { "/dev/stdout", RF_DEVSTDOUT }, -#endif -#if defined (NETWORK_REDIRECTIONS) - { "/dev/tcp/*/*", RF_DEVTCP }, - { "/dev/udp/*/*", RF_DEVUDP }, -#endif - { (char *)NULL, -1 } -}; - -static int -redir_special_open (spec, filename, flags, mode, ri) - int spec; - char *filename; - int flags, mode; - enum r_instruction ri; -{ - int fd; -#if !defined (HAVE_DEV_FD) - intmax_t lfd; -#endif - - fd = -1; - switch (spec) - { -#if !defined (HAVE_DEV_FD) - case RF_DEVFD: - if (all_digits (filename+8) && legal_number (filename+8, &lfd) && lfd == (int)lfd) - { - fd = lfd; - fd = fcntl (fd, F_DUPFD, SHELL_FD_BASE); - } - else - fd = AMBIGUOUS_REDIRECT; - break; -#endif - -#if !defined (HAVE_DEV_STDIN) - case RF_DEVSTDIN: - fd = fcntl (0, F_DUPFD, SHELL_FD_BASE); - break; - case RF_DEVSTDOUT: - fd = fcntl (1, F_DUPFD, SHELL_FD_BASE); - break; - case RF_DEVSTDERR: - fd = fcntl (2, F_DUPFD, SHELL_FD_BASE); - break; -#endif - -#if defined (NETWORK_REDIRECTIONS) - case RF_DEVTCP: - case RF_DEVUDP: -#if defined (RESTRICTED_SHELL) - if (restricted) - return (RESTRICTED_REDIRECT); -#endif -#if defined (HAVE_NETWORK) - fd = netopen (filename); -#else - internal_warning (_("/dev/(tcp|udp)/host/port not supported without networking")); - fd = open (filename, flags, mode); -#endif - break; -#endif /* NETWORK_REDIRECTIONS */ - } - - return fd; -} - -/* Open FILENAME with FLAGS in noclobber mode, hopefully avoiding most - race conditions and avoiding the problem where the file is replaced - between the stat(2) and open(2). */ -static int -noclobber_open (filename, flags, mode, ri) - char *filename; - int flags, mode; - enum r_instruction ri; -{ - int r, fd; - struct stat finfo, finfo2; - - /* If the file exists and is a regular file, return an error - immediately. */ - r = stat (filename, &finfo); - if (r == 0 && (S_ISREG (finfo.st_mode))) - return (NOCLOBBER_REDIRECT); - - /* If the file was not present (r != 0), make sure we open it - exclusively so that if it is created before we open it, our open - will fail. Make sure that we do not truncate an existing file. - Note that we don't turn on O_EXCL unless the stat failed -- if - the file was not a regular file, we leave O_EXCL off. */ - flags &= ~O_TRUNC; - if (r != 0) - { - fd = open (filename, flags|O_EXCL, mode); - return ((fd < 0 && errno == EEXIST) ? NOCLOBBER_REDIRECT : fd); - } - fd = open (filename, flags, mode); - - /* If the open failed, return the file descriptor right away. */ - if (fd < 0) - return (errno == EEXIST ? NOCLOBBER_REDIRECT : fd); - - /* OK, the open succeeded, but the file may have been changed from a - non-regular file to a regular file between the stat and the open. - We are assuming that the O_EXCL open handles the case where FILENAME - did not exist and is symlinked to an existing file between the stat - and open. */ - - /* If we can open it and fstat the file descriptor, and neither check - revealed that it was a regular file, and the file has not been replaced, - return the file descriptor. */ - if ((fstat (fd, &finfo2) == 0) && (S_ISREG (finfo2.st_mode) == 0) && - r == 0 && (S_ISREG (finfo.st_mode) == 0) && - same_file (filename, filename, &finfo, &finfo2)) - return fd; - - /* The file has been replaced. badness. */ - close (fd); - errno = EEXIST; - return (NOCLOBBER_REDIRECT); -} - -static int -redir_open (filename, flags, mode, ri) - char *filename; - int flags, mode; - enum r_instruction ri; -{ - int fd, r, e; - - r = find_string_in_alist (filename, _redir_special_filenames, 1); - if (r >= 0) - return (redir_special_open (r, filename, flags, mode, ri)); - - /* If we are in noclobber mode, you are not allowed to overwrite - existing files. Check before opening. */ - if (noclobber && CLOBBERING_REDIRECT (ri)) - { - fd = noclobber_open (filename, flags, mode, ri); - if (fd == NOCLOBBER_REDIRECT) - return (NOCLOBBER_REDIRECT); - } - else - { - do - { - fd = open (filename, flags, mode); - e = errno; - if (fd < 0 && e == EINTR) - { - QUIT; - run_pending_traps (); - } - errno = e; - } - while (fd < 0 && errno == EINTR); - -#if defined (AFS) - if ((fd < 0) && (errno == EACCES)) - { - fd = open (filename, flags & ~O_CREAT, mode); - errno = EACCES; /* restore errno */ - } -#endif /* AFS */ - } - - return fd; -} - -static int -undoablefd (fd) - int fd; -{ - int clexec; - - clexec = fcntl (fd, F_GETFD, 0); - if (clexec == -1 || (fd >= SHELL_FD_BASE && clexec == 1)) - return 0; - return 1; -} - -/* Do the specific redirection requested. Returns errno or one of the - special redirection errors (*_REDIRECT) in case of error, 0 on success. - If flags & RX_ACTIVE is zero, then just do whatever is necessary to - produce the appropriate side effects. flags & RX_UNDOABLE, if non-zero, - says to remember how to undo each redirection. If flags & RX_CLEXEC is - non-zero, then we set all file descriptors > 2 that we open to be - close-on-exec. FNP, if non-null is a pointer to a location where the - expanded filename is stored. The caller will free it. */ -static int -do_redirection_internal (redirect, flags, fnp) - REDIRECT *redirect; - int flags; - char **fnp; -{ - WORD_DESC *redirectee; - int redir_fd, fd, redirector, r, oflags; - intmax_t lfd; - char *redirectee_word; - enum r_instruction ri; - REDIRECT *new_redirect; - REDIRECTEE sd; - - redirectee = redirect->redirectee.filename; - redir_fd = redirect->redirectee.dest; - redirector = redirect->redirector.dest; - ri = redirect->instruction; - - if (redirect->flags & RX_INTERNAL) - flags |= RX_INTERNAL; - - if (TRANSLATE_REDIRECT (ri)) - { - /* We have [N]>&WORD[-] or [N]<&WORD[-] (or {V}>&WORD[-] or {V}<&WORD-). - and WORD, then translate the redirection into a new one and - continue. */ - redirectee_word = redirection_expand (redirectee); - - /* XXX - what to do with [N]<&$w- where w is unset or null? ksh93 - turns it into [N]<&- or [N]>&- and closes N. */ - if ((ri == r_move_input_word || ri == r_move_output_word) && redirectee_word == 0) - { - sd = redirect->redirector; - rd.dest = 0; - new_redirect = make_redirection (sd, r_close_this, rd, 0); - } - else if (redirectee_word == 0) - return (AMBIGUOUS_REDIRECT); - else if (redirectee_word[0] == '-' && redirectee_word[1] == '\0') - { - sd = redirect->redirector; - rd.dest = 0; - new_redirect = make_redirection (sd, r_close_this, rd, 0); - } - else if (all_digits (redirectee_word)) - { - sd = redirect->redirector; - if (legal_number (redirectee_word, &lfd) && (int)lfd == lfd) - rd.dest = lfd; - else - rd.dest = -1; /* XXX */ - switch (ri) - { - case r_duplicating_input_word: - new_redirect = make_redirection (sd, r_duplicating_input, rd, 0); - break; - case r_duplicating_output_word: - new_redirect = make_redirection (sd, r_duplicating_output, rd, 0); - break; - case r_move_input_word: - new_redirect = make_redirection (sd, r_move_input, rd, 0); - break; - case r_move_output_word: - new_redirect = make_redirection (sd, r_move_output, rd, 0); - break; - default: - break; /* shut up gcc */ - } - } - else if (ri == r_duplicating_output_word && (redirect->rflags & REDIR_VARASSIGN) == 0 && redirector == 1) - { - sd = redirect->redirector; - rd.filename = make_bare_word (redirectee_word); - new_redirect = make_redirection (sd, r_err_and_out, rd, 0); - } - else - { - free (redirectee_word); - return (AMBIGUOUS_REDIRECT); - } - - free (redirectee_word); - - /* Set up the variables needed by the rest of the function from the - new redirection. */ - if (new_redirect->instruction == r_err_and_out) - { - char *alloca_hack; - - /* Copy the word without allocating any memory that must be - explicitly freed. */ - redirectee = (WORD_DESC *)alloca (sizeof (WORD_DESC)); - xbcopy ((char *)new_redirect->redirectee.filename, - (char *)redirectee, sizeof (WORD_DESC)); - - alloca_hack = (char *) - alloca (1 + strlen (new_redirect->redirectee.filename->word)); - redirectee->word = alloca_hack; - strcpy (redirectee->word, new_redirect->redirectee.filename->word); - } - else - /* It's guaranteed to be an integer, and shouldn't be freed. */ - redirectee = new_redirect->redirectee.filename; - - redir_fd = new_redirect->redirectee.dest; - redirector = new_redirect->redirector.dest; - ri = new_redirect->instruction; - - /* Overwrite the flags element of the old redirect with the new value. */ - redirect->flags = new_redirect->flags; - dispose_redirects (new_redirect); - } - - switch (ri) - { - case r_output_direction: - case r_appending_to: - case r_input_direction: - case r_inputa_direction: - case r_err_and_out: /* command &>filename */ - case r_append_err_and_out: /* command &>> filename */ - case r_input_output: - case r_output_force: - if (posixly_correct && interactive_shell == 0) - { - oflags = redirectee->flags; - redirectee->flags |= W_NOGLOB; - } - redirectee_word = redirection_expand (redirectee); - if (posixly_correct && interactive_shell == 0) - redirectee->flags = oflags; - - if (redirectee_word == 0) - return (AMBIGUOUS_REDIRECT); - -#if defined (RESTRICTED_SHELL) - if (restricted && (WRITE_REDIRECT (ri))) - { - free (redirectee_word); - return (RESTRICTED_REDIRECT); - } -#endif /* RESTRICTED_SHELL */ - - fd = redir_open (redirectee_word, redirect->flags, 0666, ri); - if (fnp) - *fnp = redirectee_word; - else - free (redirectee_word); - - if (fd == NOCLOBBER_REDIRECT || fd == RESTRICTED_REDIRECT) - return (fd); - - if (fd < 0) - return (errno); - - if (flags & RX_ACTIVE) - { - if (redirect->rflags & REDIR_VARASSIGN) - { - redirector = fcntl (fd, F_DUPFD, SHELL_FD_BASE); /* XXX try this for now */ - r = errno; - if (redirector < 0) - sys_error (_("redirection error: cannot duplicate fd")); - REDIRECTION_ERROR (redirector, r, fd); - } - - if ((flags & RX_UNDOABLE) && ((redirect->rflags & REDIR_VARASSIGN) == 0 || varassign_redir_autoclose)) - { - /* Only setup to undo it if the thing to undo is active. We want - to autoclose if we are doing a varassign redirection and the - varredir_close shell option is set, and we can't test - redirector in this case since we just assigned it above. */ - if (fd != redirector && (redirect->rflags & REDIR_VARASSIGN) && varassign_redir_autoclose) - r = add_undo_close_redirect (redirector); - else if ((fd != redirector) && (fcntl (redirector, F_GETFD, 0) != -1)) - r = add_undo_redirect (redirector, ri, -1); - else - r = add_undo_close_redirect (redirector); - REDIRECTION_ERROR (r, errno, fd); - } - -#if defined (BUFFERED_INPUT) - /* inhibit call to sync_buffered_stream() for async processes */ - if (redirector != 0 || (subshell_environment & SUBSHELL_ASYNC) == 0) - check_bash_input (redirector); -#endif - - /* Make sure there is no pending output before we change the state - of the underlying file descriptor, since the builtins use stdio - for output. */ - if (redirector == 1 && fileno (stdout) == redirector) - { - fflush (stdout); - fpurge (stdout); - } - else if (redirector == 2 && fileno (stderr) == redirector) - { - fflush (stderr); - fpurge (stderr); - } - - if (redirect->rflags & REDIR_VARASSIGN) - { - if ((r = redir_varassign (redirect, redirector)) < 0) - { - close (redirector); - close (fd); - return (r); /* XXX */ - } - } - else if ((fd != redirector) && (dup2 (fd, redirector) < 0)) - { - close (fd); /* dup2 failed? must be fd limit issue */ - return (errno); - } - -#if defined (BUFFERED_INPUT) - /* Do not change the buffered stream for an implicit redirection - of /dev/null to fd 0 for asynchronous commands without job - control (r_inputa_direction). */ - if (ri == r_input_direction || ri == r_input_output) - duplicate_buffered_stream (fd, redirector); -#endif /* BUFFERED_INPUT */ - - /* - * If we're remembering, then this is the result of a while, for - * or until loop with a loop redirection, or a function/builtin - * executing in the parent shell with a redirection. In the - * function/builtin case, we want to set all file descriptors > 2 - * to be close-on-exec to duplicate the effect of the old - * for i = 3 to NOFILE close(i) loop. In the case of the loops, - * both sh and ksh leave the file descriptors open across execs. - * The Posix standard mentions only the exec builtin. - */ - if ((flags & RX_CLEXEC) && (redirector > 2)) - SET_CLOSE_ON_EXEC (redirector); - } - - if (fd != redirector) - { -#if defined (BUFFERED_INPUT) - if (INPUT_REDIRECT (ri)) - close_buffered_fd (fd); - else -#endif /* !BUFFERED_INPUT */ - close (fd); /* Don't close what we just opened! */ - } - - /* If we are hacking both stdout and stderr, do the stderr - redirection here. XXX - handle {var} here? */ - if (ri == r_err_and_out || ri == r_append_err_and_out) - { - if (flags & RX_ACTIVE) - { - if (flags & RX_UNDOABLE) - add_undo_redirect (2, ri, -1); - if (dup2 (1, 2) < 0) - return (errno); - } - } - break; - - case r_reading_until: - case r_deblank_reading_until: - case r_reading_string: - /* REDIRECTEE is a pointer to a WORD_DESC containing the text of - the new input. Place it in a temporary file. */ - if (redirectee) - { - fd = here_document_to_fd (redirectee, ri); - - if (fd < 0) - { - heredoc_errno = errno; - return (HEREDOC_REDIRECT); - } - - if (redirect->rflags & REDIR_VARASSIGN) - { - redirector = fcntl (fd, F_DUPFD, SHELL_FD_BASE); /* XXX try this for now */ - r = errno; - if (redirector < 0) - sys_error (_("redirection error: cannot duplicate fd")); - REDIRECTION_ERROR (redirector, r, fd); - } - - if (flags & RX_ACTIVE) - { - if ((flags & RX_UNDOABLE) && ((redirect->rflags & REDIR_VARASSIGN) == 0 || varassign_redir_autoclose)) - { - /* Only setup to undo it if the thing to undo is active. - Close if the right option is set and we are doing a - varassign redirection. */ - if (fd != redirector && (redirect->rflags & REDIR_VARASSIGN) && varassign_redir_autoclose) - r = add_undo_close_redirect (redirector); - else if ((fd != redirector) && (fcntl (redirector, F_GETFD, 0) != -1)) - r = add_undo_redirect (redirector, ri, -1); - else - r = add_undo_close_redirect (redirector); - REDIRECTION_ERROR (r, errno, fd); - } - -#if defined (BUFFERED_INPUT) - check_bash_input (redirector); -#endif - if (redirect->rflags & REDIR_VARASSIGN) - { - if ((r = redir_varassign (redirect, redirector)) < 0) - { - close (redirector); - close (fd); - return (r); /* XXX */ - } - } - else if (fd != redirector && dup2 (fd, redirector) < 0) - { - r = errno; - close (fd); - return (r); - } - -#if defined (BUFFERED_INPUT) - duplicate_buffered_stream (fd, redirector); -#endif - - if ((flags & RX_CLEXEC) && (redirector > 2)) - SET_CLOSE_ON_EXEC (redirector); - } - - if (fd != redirector) -#if defined (BUFFERED_INPUT) - close_buffered_fd (fd); -#else - close (fd); -#endif - } - break; - - case r_duplicating_input: - case r_duplicating_output: - case r_move_input: - case r_move_output: - if ((flags & RX_ACTIVE) && (redirect->rflags & REDIR_VARASSIGN)) - { - redirector = fcntl (redir_fd, F_DUPFD, SHELL_FD_BASE); /* XXX try this for now */ - r = errno; - if (redirector < 0) - sys_error (_("redirection error: cannot duplicate fd")); - REDIRECTION_ERROR (redirector, r, -1); - } - - if ((flags & RX_ACTIVE) && (redir_fd != redirector)) - { - if ((flags & RX_UNDOABLE) && ((redirect->rflags & REDIR_VARASSIGN) == 0 || varassign_redir_autoclose)) - { - /* Only setup to undo it if the thing to undo is active. - Close if the right option is set and we are doing a - varassign redirection. */ - if ((redirect->rflags & REDIR_VARASSIGN) && varassign_redir_autoclose) - r = add_undo_close_redirect (redirector); - else if (fcntl (redirector, F_GETFD, 0) != -1) - r = add_undo_redirect (redirector, ri, redir_fd); - else - r = add_undo_close_redirect (redirector); - REDIRECTION_ERROR (r, errno, -1); - } - if ((flags & RX_UNDOABLE) && (ri == r_move_input || ri == r_move_output)) - { - /* r_move_input and r_move_output add an additional close() - that needs to be undone */ - if (fcntl (redirector, F_GETFD, 0) != -1) - { - r = add_undo_redirect (redir_fd, r_close_this, -1); - REDIRECTION_ERROR (r, errno, -1); - } - } -#if defined (BUFFERED_INPUT) - /* inhibit call to sync_buffered_stream() for async processes */ - if (redirector != 0 || (subshell_environment & SUBSHELL_ASYNC) == 0) - check_bash_input (redirector); -#endif - if (redirect->rflags & REDIR_VARASSIGN) - { - if ((r = redir_varassign (redirect, redirector)) < 0) - { - close (redirector); - return (r); /* XXX */ - } - } - /* This is correct. 2>&1 means dup2 (1, 2); */ - else if (dup2 (redir_fd, redirector) < 0) - return (errno); - -#if defined (BUFFERED_INPUT) - if (ri == r_duplicating_input || ri == r_move_input) - duplicate_buffered_stream (redir_fd, redirector); -#endif /* BUFFERED_INPUT */ - - /* First duplicate the close-on-exec state of redirectee. dup2 - leaves the flag unset on the new descriptor, which means it - stays open. Only set the close-on-exec bit for file descriptors - greater than 2 in any case, since 0-2 should always be open - unless closed by something like `exec 2<&-'. It should always - be safe to set fds > 2 to close-on-exec if they're being used to - save file descriptors < 2, since we don't need to preserve the - state of the close-on-exec flag for those fds -- they should - always be open. */ - /* if ((already_set || set_unconditionally) && (ok_to_set)) - set_it () */ -#if 0 - if (((fcntl (redir_fd, F_GETFD, 0) == 1) || redir_fd < 2 || (flags & RX_CLEXEC)) && - (redirector > 2)) -#else - if (((fcntl (redir_fd, F_GETFD, 0) == 1) || (redir_fd < 2 && (flags & RX_INTERNAL)) || (flags & RX_CLEXEC)) && - (redirector > 2)) -#endif - SET_CLOSE_ON_EXEC (redirector); - - /* When undoing saving of non-standard file descriptors (>=3) using - file descriptors >= SHELL_FD_BASE, we set the saving fd to be - close-on-exec and use a flag to decide how to set close-on-exec - when the fd is restored. */ - if ((redirect->flags & RX_INTERNAL) && (redirect->flags & RX_SAVCLEXEC) && redirector >= 3 && (redir_fd >= SHELL_FD_BASE || (redirect->flags & RX_SAVEFD))) - SET_OPEN_ON_EXEC (redirector); - - /* dup-and-close redirection */ - if (ri == r_move_input || ri == r_move_output) - { - xtrace_fdchk (redir_fd); - - close (redir_fd); -#if defined (COPROCESS_SUPPORT) - coproc_fdchk (redir_fd); /* XXX - loses coproc fds */ -#endif - } - } - break; - - case r_close_this: - if (flags & RX_ACTIVE) - { - if (redirect->rflags & REDIR_VARASSIGN) - { - redirector = redir_varvalue (redirect); - if (redirector < 0) - return AMBIGUOUS_REDIRECT; - } - - r = 0; - if (flags & RX_UNDOABLE) - { - if (fcntl (redirector, F_GETFD, 0) != -1) - r = add_undo_redirect (redirector, ri, -1); - else - r = add_undo_close_redirect (redirector); - REDIRECTION_ERROR (r, errno, redirector); - } - -#if defined (COPROCESS_SUPPORT) - coproc_fdchk (redirector); -#endif - xtrace_fdchk (redirector); - -#if defined (BUFFERED_INPUT) - /* inhibit call to sync_buffered_stream() for async processes */ - if (redirector != 0 || (subshell_environment & SUBSHELL_ASYNC) == 0) - check_bash_input (redirector); - r = close_buffered_fd (redirector); -#else /* !BUFFERED_INPUT */ - r = close (redirector); -#endif /* !BUFFERED_INPUT */ - - if (r < 0 && (flags & RX_INTERNAL) && (errno == EIO || errno == ENOSPC)) - REDIRECTION_ERROR (r, errno, -1); - } - break; - - case r_duplicating_input_word: - case r_duplicating_output_word: - case r_move_input_word: - case r_move_output_word: - break; - } - return (0); -} - -/* Remember the file descriptor associated with the slot FD, - on REDIRECTION_UNDO_LIST. Note that the list will be reversed - before it is executed. Any redirections that need to be undone - even if REDIRECTION_UNDO_LIST is discarded by the exec builtin - are also saved on EXEC_REDIRECTION_UNDO_LIST. FDBASE says where to - start the duplicating. If it's less than SHELL_FD_BASE, we're ok, - and can use SHELL_FD_BASE (-1 == don't care). If it's >= SHELL_FD_BASE, - we have to make sure we don't use fdbase to save a file descriptor, - since we're going to use it later (e.g., make sure we don't save fd 0 - to fd 10 if we have a redirection like 0<&10). If the value of fdbase - puts the process over its fd limit, causing fcntl to fail, we try - again with SHELL_FD_BASE. Return 0 on success, -1 on error. */ -static int -add_undo_redirect (fd, ri, fdbase) - int fd; - enum r_instruction ri; - int fdbase; -{ - int new_fd, clexec_flag, savefd_flag; - REDIRECT *new_redirect, *closer, *dummy_redirect; - REDIRECTEE sd; - - savefd_flag = 0; - new_fd = fcntl (fd, F_DUPFD, (fdbase < SHELL_FD_BASE) ? SHELL_FD_BASE : fdbase+1); - if (new_fd < 0) - new_fd = fcntl (fd, F_DUPFD, SHELL_FD_BASE); - if (new_fd < 0) - { - new_fd = fcntl (fd, F_DUPFD, 0); - savefd_flag = 1; - } - - if (new_fd < 0) - { - sys_error (_("redirection error: cannot duplicate fd")); - return (-1); - } - - clexec_flag = fcntl (fd, F_GETFD, 0); - - sd.dest = new_fd; - rd.dest = 0; - closer = make_redirection (sd, r_close_this, rd, 0); - closer->flags |= RX_INTERNAL; - dummy_redirect = copy_redirects (closer); - - sd.dest = fd; - rd.dest = new_fd; - if (fd == 0) - new_redirect = make_redirection (sd, r_duplicating_input, rd, 0); - else - new_redirect = make_redirection (sd, r_duplicating_output, rd, 0); - new_redirect->flags |= RX_INTERNAL; - if (savefd_flag) - new_redirect->flags |= RX_SAVEFD; - if (clexec_flag == 0 && fd >= 3 && (new_fd >= SHELL_FD_BASE || savefd_flag)) - new_redirect->flags |= RX_SAVCLEXEC; - new_redirect->next = closer; - - closer->next = redirection_undo_list; - redirection_undo_list = new_redirect; - - /* Save redirections that need to be undone even if the undo list - is thrown away by the `exec' builtin. */ - add_exec_redirect (dummy_redirect); - - /* experimental: if we're saving a redirection to undo for a file descriptor - above SHELL_FD_BASE, add a redirection to be undone if the exec builtin - causes redirections to be discarded. There needs to be a difference - between fds that are used to save other fds and then are the target of - user redirections and fds that are just the target of user redirections. - We use the close-on-exec flag to tell the difference; fds > SHELL_FD_BASE - that have the close-on-exec flag set are assumed to be fds used internally - to save others. */ - if (fd >= SHELL_FD_BASE && ri != r_close_this && clexec_flag) - { - sd.dest = fd; - rd.dest = new_fd; - new_redirect = make_redirection (sd, r_duplicating_output, rd, 0); - new_redirect->flags |= RX_INTERNAL; - - add_exec_redirect (new_redirect); - } - - /* File descriptors used only for saving others should always be - marked close-on-exec. Unfortunately, we have to preserve the - close-on-exec state of the file descriptor we are saving, since - fcntl (F_DUPFD) sets the new file descriptor to remain open - across execs. If, however, the file descriptor whose state we - are saving is <= 2, we can just set the close-on-exec flag, - because file descriptors 0-2 should always be open-on-exec, - and the restore above in do_redirection() will take care of it. */ - if (clexec_flag || fd < 3) - SET_CLOSE_ON_EXEC (new_fd); - else if (redirection_undo_list->flags & RX_SAVCLEXEC) - SET_CLOSE_ON_EXEC (new_fd); - - return (0); -} - -/* Set up to close FD when we are finished with the current command - and its redirections. Return 0 on success, -1 on error. */ -static int -add_undo_close_redirect (fd) - int fd; -{ - REDIRECT *closer; - REDIRECTEE sd; - - sd.dest = fd; - rd.dest = 0; - closer = make_redirection (sd, r_close_this, rd, 0); - closer->flags |= RX_INTERNAL; - closer->next = redirection_undo_list; - redirection_undo_list = closer; - - return 0; -} - -static void -add_exec_redirect (dummy_redirect) - REDIRECT *dummy_redirect; -{ - dummy_redirect->next = exec_redirection_undo_list; - exec_redirection_undo_list = dummy_redirect; -} - -/* Return 1 if the redirection specified by RI and REDIRECTOR alters the - standard input. */ -static int -stdin_redirection (ri, redirector) - enum r_instruction ri; - int redirector; -{ - switch (ri) - { - case r_input_direction: - case r_inputa_direction: - case r_input_output: - case r_reading_until: - case r_deblank_reading_until: - case r_reading_string: - return (1); - case r_duplicating_input: - case r_duplicating_input_word: - case r_close_this: - return (redirector == 0); - case r_output_direction: - case r_appending_to: - case r_duplicating_output: - case r_err_and_out: - case r_append_err_and_out: - case r_output_force: - case r_duplicating_output_word: - case r_move_input: - case r_move_output: - case r_move_input_word: - case r_move_output_word: - return (0); - } - return (0); -} - -/* Return non-zero if any of the redirections in REDIRS alter the standard - input. */ -int -stdin_redirects (redirs) - REDIRECT *redirs; -{ - REDIRECT *rp; - int n; - - for (n = 0, rp = redirs; rp; rp = rp->next) - if ((rp->rflags & REDIR_VARASSIGN) == 0) - n += stdin_redirection (rp->instruction, rp->redirector.dest); - return n; -} -/* bind_var_to_int handles array references */ -static int -redir_varassign (redir, fd) - REDIRECT *redir; - int fd; -{ - WORD_DESC *w; - SHELL_VAR *v; - - w = redir->redirector.filename; - v = bind_var_to_int (w->word, fd, 0); - if (v == 0 || readonly_p (v) || noassign_p (v)) - return BADVAR_REDIRECT; - - stupidly_hack_special_variables (w->word); - return 0; -} - -/* Handles {array[ind]} for redirection words */ -static int -redir_varvalue (redir) - REDIRECT *redir; -{ - SHELL_VAR *v; - char *val, *w; - intmax_t vmax; - int i; -#if defined (ARRAY_VARS) - char *sub; - int len, vr; -#endif - - w = redir->redirector.filename->word; /* shorthand */ - /* XXX - handle set -u here? */ -#if defined (ARRAY_VARS) - if (vr = valid_array_reference (w, 0)) - { - v = array_variable_part (w, 0, &sub, &len); - } - else -#endif - { - v = find_variable (w); -#if defined (ARRAY_VARS) - if (v == 0) - { - v = find_variable_last_nameref (w, 0); - if (v && nameref_p (v)) - { - w = nameref_cell (v); - if (vr = valid_array_reference (w, 0)) - v = array_variable_part (w, 0, &sub, &len); - else - v = find_variable (w); - } - } -#endif - } - - if (v == 0 || invisible_p (v)) - return -1; - -#if defined (ARRAY_VARS) - /* get_variable_value handles references to array variables without - subscripts */ - if (vr && (array_p (v) || assoc_p (v))) - val = get_array_value (w, 0, (array_eltstate_t *)NULL); - else -#endif - val = get_variable_value (v); - if (val == 0 || *val == 0) - return -1; - - if (legal_number (val, &vmax) < 0) - return -1; - - i = vmax; /* integer truncation */ - return i; -} diff --git a/third_party/bash/redir.h b/third_party/bash/redir.h deleted file mode 100644 index 340dc1c02..000000000 --- a/third_party/bash/redir.h +++ /dev/null @@ -1,43 +0,0 @@ -/* redir.h - functions from redir.c. */ - -/* Copyright (C) 1997, 2001, 2005, 2008, 2009-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_REDIR_H_) -#define _REDIR_H_ - -#include "stdc.h" - -/* Values for flags argument to do_redirections */ -#define RX_ACTIVE 0x01 /* do it; don't just go through the motions */ -#define RX_UNDOABLE 0x02 /* make a list to undo these redirections */ -#define RX_CLEXEC 0x04 /* set close-on-exec for opened fds > 2 */ -#define RX_INTERNAL 0x08 -#define RX_USER 0x10 -#define RX_SAVCLEXEC 0x20 /* set close-on-exec off in restored fd even though saved on has it on */ -#define RX_SAVEFD 0x40 /* fd used to save another even if < SHELL_FD_BASE */ - -extern void redirection_error PARAMS((REDIRECT *, int, char *)); -extern int do_redirections PARAMS((REDIRECT *, int)); -extern char *redirection_expand PARAMS((WORD_DESC *)); -extern int stdin_redirects PARAMS((REDIRECT *)); - -/* in builtins/evalstring.c for now, could move later */ -extern int open_redir_file PARAMS((REDIRECT *, char **)); - -#endif /* _REDIR_H_ */ diff --git a/third_party/bash/rename.c b/third_party/bash/rename.c deleted file mode 100644 index 1fa90a159..000000000 --- a/third_party/bash/rename.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * rename - rename a file - */ - -/* Copyright (C) 1999 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if !defined (HAVE_RENAME) - -#include "bashtypes.h" -#include "posixstat.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif -#include - -#include "stdc.h" - -#ifndef errno -extern int errno; -#endif - -int -rename (from, to) - const char *from, *to; -{ - struct stat fb, tb; - - if (stat (from, &fb) < 0) - return -1; - - if (stat (to, &tb) < 0) - { - if (errno != ENOENT) - return -1; - } - else - { - if (fb.st_dev == tb.st_dev && fb.st_ino == tb.st_ino) - return 0; /* same file */ - if (unlink (to) < 0 && errno != ENOENT) - return -1; - } - - if (link (from, to) < 0) - return (-1); - - if (unlink (from) < 0 && errno != ENOENT) - { - int e = errno; - unlink (to); - errno = e; - return (-1); - } - - return (0); -} -#endif /* !HAVE_RENAME */ diff --git a/third_party/bash/setlinebuf.c b/third_party/bash/setlinebuf.c deleted file mode 100644 index 3c9afb8c1..000000000 --- a/third_party/bash/setlinebuf.c +++ /dev/null @@ -1,66 +0,0 @@ -/* setlinebuf.c - line-buffer a stdio stream. */ - -/* Copyright (C) 1997,2022 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include - -#include "xmalloc.h" - -#if defined (USING_BASH_MALLOC) -# define LBUF_BUFSIZE 2016 -#else -# define LBUF_BUFSIZE BUFSIZ -#endif - -static char *stdoutbuf = 0; -static char *stderrbuf = 0; - -/* Cause STREAM to buffer lines as opposed to characters or blocks. */ -int -sh_setlinebuf (stream) - FILE *stream; -{ -#if !defined (HAVE_SETLINEBUF) && !defined (HAVE_SETVBUF) - return (0); -#endif - -#if defined (HAVE_SETVBUF) - char *local_linebuf; - -#if defined (USING_BASH_MALLOC) - if (stream == stdout && stdoutbuf == 0) - local_linebuf = stdoutbuf = (char *)xmalloc (LBUF_BUFSIZE); - else if (stream == stderr && stderrbuf == 0) - local_linebuf = stderrbuf = (char *)xmalloc (LBUF_BUFSIZE); - else - local_linebuf = (char *)NULL; /* let stdio handle it */ -#else - local_linebuf = (char *)NULL; -#endif - - return (setvbuf (stream, local_linebuf, _IOLBF, LBUF_BUFSIZE)); -#else /* !HAVE_SETVBUF */ - - setlinebuf (stream); - return (0); - -#endif /* !HAVE_SETVBUF */ -} diff --git a/third_party/bash/shell.c b/third_party/bash/shell.c deleted file mode 100644 index da5ffb58b..000000000 --- a/third_party/bash/shell.c +++ /dev/null @@ -1,2136 +0,0 @@ -/* shell.c -- GNU's idea of the POSIX shell specification. */ - -/* Copyright (C) 1987-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -/* - Birthdate: - Sunday, January 10th, 1988. - Initial author: Brian Fox -*/ -#define INSTALL_DEBUG_MODE - -#include "config.h" - -#include "bashtypes.h" -#if !defined (_MINIX) && defined (HAVE_SYS_FILE_H) -# include -#endif -#include "posixstat.h" -#include "posixtime.h" -#include "bashansi.h" -#include -#include -#include -#include "filecntl.h" -#if defined (HAVE_PWD_H) -# include -#endif - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "bashintl.h" - -#define NEED_SH_SETLINEBUF_DECL /* used in externs.h */ - -#include "shell.h" -#include "parser.h" -#include "flags.h" -#include "trap.h" -#include "mailcheck.h" -#include "builtins.h" -#include "common.h" - -#if defined (JOB_CONTROL) -#include "jobs.h" -#else -extern int running_in_background; -extern int initialize_job_control PARAMS((int)); -extern int get_tty_state PARAMS((void)); -#endif /* JOB_CONTROL */ - -#include "input.h" -#include "execute_cmd.h" -#include "findcmd.h" - -#if defined (USING_BASH_MALLOC) && defined (DEBUG) && !defined (DISABLE_MALLOC_WRAPPERS) -# include -#elif defined (MALLOC_DEBUG) && defined (USING_BASH_MALLOC) -# include -#endif - -#if defined (HISTORY) -# include "bashhist.h" -# include "third_party/readline/history.h" -#endif - -#if defined (READLINE) -# include "third_party/readline/readline.h" -# include "bashline.h" -#endif - -#include "tilde.h" -#include "strmatch.h" - -#if defined (__OPENNT) -# include -#endif - -#if !defined (HAVE_GETPW_DECLS) -extern struct passwd *getpwuid (); -#endif /* !HAVE_GETPW_DECLS */ - -#if !defined (errno) -extern int errno; -#endif - -#if defined (NO_MAIN_ENV_ARG) -extern char **environ; /* used if no third argument to main() */ -#endif - -extern int gnu_error_format; - -/* Non-zero means that this shell has already been run; i.e. you should - call shell_reinitialize () if you need to start afresh. */ -int shell_initialized = 0; -int bash_argv_initialized = 0; - -COMMAND *global_command = (COMMAND *)NULL; - -/* Information about the current user. */ -struct user_info current_user = -{ - (uid_t)-1, (uid_t)-1, (gid_t)-1, (gid_t)-1, - (char *)NULL, (char *)NULL, (char *)NULL -}; - -/* The current host's name. */ -char *current_host_name = (char *)NULL; - -/* Non-zero means that this shell is a login shell. - Specifically: - 0 = not login shell. - 1 = login shell from getty (or equivalent fake out) - -1 = login shell from "--login" (or -l) flag. - -2 = both from getty, and from flag. - */ -int login_shell = 0; - -/* Non-zero means that at this moment, the shell is interactive. In - general, this means that the shell is at this moment reading input - from the keyboard. */ -int interactive = 0; - -/* Non-zero means that the shell was started as an interactive shell. */ -int interactive_shell = 0; - -/* Non-zero means to send a SIGHUP to all jobs when an interactive login - shell exits. */ -int hup_on_exit = 0; - -/* Non-zero means to list status of running and stopped jobs at shell exit */ -int check_jobs_at_exit = 0; - -/* Non-zero means to change to a directory name supplied as a command name */ -int autocd = 0; - -/* Tells what state the shell was in when it started: - 0 = non-interactive shell script - 1 = interactive - 2 = -c command - 3 = wordexp evaluation - This is a superset of the information provided by interactive_shell. -*/ -int startup_state = 0; -int reading_shell_script = 0; - -/* Special debugging helper. */ -int debugging_login_shell = 0; - -/* The environment that the shell passes to other commands. */ -char **shell_environment; - -/* Non-zero when we are executing a top-level command. */ -int executing = 0; - -/* The number of commands executed so far. */ -int current_command_number = 1; - -/* Non-zero is the recursion depth for commands. */ -int indirection_level = 0; - -/* The name of this shell, as taken from argv[0]. */ -char *shell_name = (char *)NULL; - -/* time in seconds when the shell was started */ -time_t shell_start_time; -struct timeval shellstart; - -/* Are we running in an emacs shell window? */ -int running_under_emacs; - -/* Do we have /dev/fd? */ -#ifdef HAVE_DEV_FD -int have_devfd = HAVE_DEV_FD; -#else -int have_devfd = 0; -#endif - -/* The name of the .(shell)rc file. */ -static char *bashrc_file = DEFAULT_BASHRC; - -/* Non-zero means to act more like the Bourne shell on startup. */ -static int act_like_sh; - -/* Non-zero if this shell is being run by `su'. */ -static int su_shell; - -/* Non-zero if we have already expanded and sourced $ENV. */ -static int sourced_env; - -/* Is this shell running setuid? */ -static int running_setuid; - -/* Values for the long-winded argument names. */ -static int debugging; /* Do debugging things. */ -static int no_rc; /* Don't execute ~/.bashrc */ -static int no_profile; /* Don't execute .profile */ -static int do_version; /* Display interesting version info. */ -static int make_login_shell; /* Make this shell be a `-bash' shell. */ -static int want_initial_help; /* --help option */ - -int debugging_mode = 0; /* In debugging mode with --debugger */ -#if defined (READLINE) -int no_line_editing = 0; /* non-zero -> don't do fancy line editing. */ -#else -int no_line_editing = 1; /* can't have line editing without readline */ -#endif -#if defined (TRANSLATABLE_STRINGS) -int dump_translatable_strings; /* Dump strings in $"...", don't execute. */ -int dump_po_strings; /* Dump strings in $"..." in po format */ -#endif -int wordexp_only = 0; /* Do word expansion only */ -int protected_mode = 0; /* No command substitution with --wordexp */ - -int pretty_print_mode = 0; /* pretty-print a shell script */ - -#if defined (STRICT_POSIX) -int posixly_correct = 1; /* Non-zero means posix.2 superset. */ -#else -int posixly_correct = 0; /* Non-zero means posix.2 superset. */ -#endif - -/* Some long-winded argument names. These are obviously new. */ -#define Int 1 -#define Charp 2 -static const struct { - const char *name; - int type; - int *int_value; - char **char_value; -} long_args[] = { - { "debug", Int, &debugging, (char **)0x0 }, -#if defined (DEBUGGER) - { "debugger", Int, &debugging_mode, (char **)0x0 }, -#endif -#if defined (TRANSLATABLE_STRINGS) - { "dump-po-strings", Int, &dump_po_strings, (char **)0x0 }, - { "dump-strings", Int, &dump_translatable_strings, (char **)0x0 }, -#endif - { "help", Int, &want_initial_help, (char **)0x0 }, - { "init-file", Charp, (int *)0x0, &bashrc_file }, - { "login", Int, &make_login_shell, (char **)0x0 }, - { "noediting", Int, &no_line_editing, (char **)0x0 }, - { "noprofile", Int, &no_profile, (char **)0x0 }, - { "norc", Int, &no_rc, (char **)0x0 }, - { "posix", Int, &posixly_correct, (char **)0x0 }, - { "pretty-print", Int, &pretty_print_mode, (char **)0x0 }, -#if defined (WORDEXP_OPTION) - { "protected", Int, &protected_mode, (char **)0x0 }, -#endif - { "rcfile", Charp, (int *)0x0, &bashrc_file }, -#if defined (RESTRICTED_SHELL) - { "restricted", Int, &restricted, (char **)0x0 }, -#endif - { "verbose", Int, &verbose_flag, (char **)0x0 }, - { "version", Int, &do_version, (char **)0x0 }, -#if defined (WORDEXP_OPTION) - { "wordexp", Int, &wordexp_only, (char **)0x0 }, -#endif - { (char *)0x0, Int, (int *)0x0, (char **)0x0 } -}; - -/* These are extern so execute_simple_command can set them, and then - longjmp back to main to execute a shell script, instead of calling - main () again and resulting in indefinite, possibly fatal, stack - growth. */ -procenv_t subshell_top_level; -int subshell_argc; -char **subshell_argv; -char **subshell_envp; - -char *exec_argv0; - -#if defined (BUFFERED_INPUT) -/* The file descriptor from which the shell is reading input. */ -int default_buffered_input = -1; -#endif - -/* The following two variables are not static so they can show up in $-. */ -int read_from_stdin; /* -s flag supplied */ -int want_pending_command; /* -c flag supplied */ - -/* This variable is not static so it can be bound to $BASH_EXECUTION_STRING */ -char *command_execution_string; /* argument to -c option */ -char *shell_script_filename; /* shell script */ - -int malloc_trace_at_exit = 0; - -static int shell_reinitialized = 0; - -static FILE *default_input; - -static STRING_INT_ALIST *shopt_alist; -static int shopt_ind = 0, shopt_len = 0; - -static int parse_long_options PARAMS((char **, int, int)); -static int parse_shell_options PARAMS((char **, int, int)); -static int bind_args PARAMS((char **, int, int, int)); - -static void start_debugger PARAMS((void)); - -static void add_shopt_to_alist PARAMS((char *, int)); -static void run_shopt_alist PARAMS((void)); - -static void execute_env_file PARAMS((char *)); -static void run_startup_files PARAMS((void)); -static int open_shell_script PARAMS((char *)); -static void set_bash_input PARAMS((void)); -static int run_one_command PARAMS((char *)); -#if defined (WORDEXP_OPTION) -static int run_wordexp PARAMS((char *)); -#endif - -static int uidget PARAMS((void)); - -static void set_option_defaults PARAMS((void)); -static void reset_option_defaults PARAMS((void)); - -static void init_interactive PARAMS((void)); -static void init_noninteractive PARAMS((void)); -static void init_interactive_script PARAMS((void)); - -static void set_shell_name PARAMS((char *)); -static void shell_initialize PARAMS((void)); -static void shell_reinitialize PARAMS((void)); - -static void show_shell_usage PARAMS((FILE *, int)); - -#ifdef __CYGWIN__ -static void -_cygwin32_check_tmp () -{ - struct stat sb; - - if (stat ("/tmp", &sb) < 0) - internal_warning (_("could not find /tmp, please create!")); - else - { - if (S_ISDIR (sb.st_mode) == 0) - internal_warning (_("/tmp must be a valid directory name")); - } -} -#endif /* __CYGWIN__ */ - -#if defined (NO_MAIN_ENV_ARG) -/* systems without third argument to main() */ -int -main (argc, argv) - int argc; - char **argv; -#else /* !NO_MAIN_ENV_ARG */ -int -main (argc, argv, env) - int argc; - char **argv, **env; -#endif /* !NO_MAIN_ENV_ARG */ -{ - register int i; - int code, old_errexit_flag; -#if defined (RESTRICTED_SHELL) - int saverst; -#endif - volatile int locally_skip_execution; - volatile int arg_index, top_level_arg_index; -#ifdef __OPENNT - char **env; - - env = environ; -#endif /* __OPENNT */ - - USE_VAR(argc); - USE_VAR(argv); - USE_VAR(env); - USE_VAR(code); - USE_VAR(old_errexit_flag); -#if defined (RESTRICTED_SHELL) - USE_VAR(saverst); -#endif - - /* Catch early SIGINTs. */ - code = setjmp_nosigs (top_level); - if (code) - exit (2); - - xtrace_init (); - -#if defined (USING_BASH_MALLOC) && defined (DEBUG) && !defined (DISABLE_MALLOC_WRAPPERS) - malloc_set_register (1); /* XXX - change to 1 for malloc debugging */ -#endif - - check_dev_tty (); - -#ifdef __CYGWIN__ - _cygwin32_check_tmp (); -#endif /* __CYGWIN__ */ - - /* Wait forever if we are debugging a login shell. */ - while (debugging_login_shell) sleep (3); - - set_default_locale (); - - running_setuid = uidget (); - - if (getenv ("POSIXLY_CORRECT") || getenv ("POSIX_PEDANTIC")) - posixly_correct = 1; - -#if defined (USE_GNU_MALLOC_LIBRARY) - mcheck (programming_error, (void (*) ())0); -#endif /* USE_GNU_MALLOC_LIBRARY */ - - if (setjmp_sigs (subshell_top_level)) - { - argc = subshell_argc; - argv = subshell_argv; - env = subshell_envp; - sourced_env = 0; - } - - shell_reinitialized = 0; - - /* Initialize `local' variables for all `invocations' of main (). */ - arg_index = 1; - if (arg_index > argc) - arg_index = argc; - command_execution_string = shell_script_filename = (char *)NULL; - want_pending_command = locally_skip_execution = read_from_stdin = 0; - default_input = stdin; -#if defined (BUFFERED_INPUT) - default_buffered_input = -1; -#endif - - /* Fix for the `infinite process creation' bug when running shell scripts - from startup files on System V. */ - login_shell = make_login_shell = 0; - - /* If this shell has already been run, then reinitialize it to a - vanilla state. */ - if (shell_initialized || shell_name) - { - /* Make sure that we do not infinitely recurse as a login shell. */ - if (*shell_name == '-') - shell_name++; - - shell_reinitialize (); - if (setjmp_nosigs (top_level)) - exit (2); - } - - shell_environment = env; - set_shell_name (argv[0]); - - gettimeofday (&shellstart, 0); - shell_start_time = shellstart.tv_sec; - - /* Parse argument flags from the input line. */ - - /* Find full word arguments first. */ - arg_index = parse_long_options (argv, arg_index, argc); - - if (want_initial_help) - { - show_shell_usage (stdout, 1); - exit (EXECUTION_SUCCESS); - } - - if (do_version) - { - show_shell_version (1); - exit (EXECUTION_SUCCESS); - } - - echo_input_at_read = verbose_flag; /* --verbose given */ - - /* All done with full word options; do standard shell option parsing.*/ - this_command_name = shell_name; /* for error reporting */ - arg_index = parse_shell_options (argv, arg_index, argc); - - /* If user supplied the "--login" (or -l) flag, then set and invert - LOGIN_SHELL. */ - if (make_login_shell) - { - login_shell++; - login_shell = -login_shell; - } - - set_login_shell ("login_shell", login_shell != 0); - -#if defined (TRANSLATABLE_STRINGS) - if (dump_po_strings) - dump_translatable_strings = 1; - - if (dump_translatable_strings) - read_but_dont_execute = 1; -#endif - - if (running_setuid && privileged_mode == 0) - disable_priv_mode (); - - /* Need to get the argument to a -c option processed in the - above loop. The next arg is a command to execute, and the - following args are $0...$n respectively. */ - if (want_pending_command) - { - command_execution_string = argv[arg_index]; - if (command_execution_string == 0) - { - report_error (_("%s: option requires an argument"), "-c"); - exit (EX_BADUSAGE); - } - arg_index++; - } - this_command_name = (char *)NULL; - - /* First, let the outside world know about our interactive status. - A shell is interactive if the `-i' flag was given, or if all of - the following conditions are met: - no -c command - no arguments remaining or the -s flag given - standard input is a terminal - standard error is a terminal - Refer to Posix.2, the description of the `sh' utility. */ - - if (forced_interactive || /* -i flag */ - (!command_execution_string && /* No -c command and ... */ - wordexp_only == 0 && /* No --wordexp and ... */ - ((arg_index == argc) || /* no remaining args or... */ - read_from_stdin) && /* -s flag with args, and */ - isatty (fileno (stdin)) && /* Input is a terminal and */ - isatty (fileno (stderr)))) /* error output is a terminal. */ - init_interactive (); - else - init_noninteractive (); - - /* - * Some systems have the bad habit of starting login shells with lots of open - * file descriptors. For instance, most systems that have picked up the - * pre-4.0 Sun YP code leave a file descriptor open each time you call one - * of the getpw* functions, and it's set to be open across execs. That - * means one for login, one for xterm, one for shelltool, etc. There are - * also systems that open persistent FDs to other agents or files as part - * of process startup; these need to be set to be close-on-exec. - */ - if (login_shell && interactive_shell) - { - for (i = 3; i < 20; i++) - SET_CLOSE_ON_EXEC (i); - } - - /* If we're in a strict Posix.2 mode, turn on interactive comments, - alias expansion in non-interactive shells, and other Posix.2 things. */ - if (posixly_correct) - { - bind_variable ("POSIXLY_CORRECT", "y", 0); - sv_strict_posix ("POSIXLY_CORRECT"); - } - - /* Now we run the shopt_alist and process the options. */ - if (shopt_alist) - run_shopt_alist (); - - /* From here on in, the shell must be a normal functioning shell. - Variables from the environment are expected to be set, etc. */ - shell_initialize (); - - set_default_lang (); - set_default_locale_vars (); - - /* - * M-x term -> TERM=eterm-color INSIDE_EMACS='251,term:0.96' (eterm) - * M-x shell -> TERM='dumb' INSIDE_EMACS='25.1,comint' (no line editing) - * - * Older versions of Emacs may set EMACS to 't' or to something like - * '22.1 (term:0.96)' instead of (or in addition to) setting INSIDE_EMACS. - * They may set TERM to 'eterm' instead of 'eterm-color'. They may have - * a now-obsolete command that sets neither EMACS nor INSIDE_EMACS: - * M-x terminal -> TERM='emacs-em7955' (line editing) - */ - if (interactive_shell) - { - char *term, *emacs, *inside_emacs; - int emacs_term, in_emacs; - - term = get_string_value ("TERM"); - emacs = get_string_value ("EMACS"); - inside_emacs = get_string_value ("INSIDE_EMACS"); - - if (inside_emacs) - { - emacs_term = strstr (inside_emacs, ",term:") != 0; - in_emacs = 1; - } - else if (emacs) - { - /* Infer whether we are in an older Emacs. */ - emacs_term = strstr (emacs, " (term:") != 0; - in_emacs = emacs_term || STREQ (emacs, "t"); - } - else - in_emacs = emacs_term = 0; - - /* Not sure any emacs terminal emulator sets TERM=emacs any more */ - no_line_editing |= STREQ (term, "emacs"); - no_line_editing |= in_emacs && STREQ (term, "dumb"); - - /* running_under_emacs == 2 for `eterm' */ - running_under_emacs = in_emacs || STREQN (term, "emacs", 5); - running_under_emacs += emacs_term && STREQN (term, "eterm", 5); - - if (running_under_emacs) - gnu_error_format = 1; - } - - top_level_arg_index = arg_index; - old_errexit_flag = exit_immediately_on_error; - - /* Give this shell a place to longjmp to before executing the - startup files. This allows users to press C-c to abort the - lengthy startup. */ - code = setjmp_sigs (top_level); - if (code) - { - if (code == EXITPROG || code == ERREXIT || code == EXITBLTIN) - exit_shell (last_command_exit_value); - else - { -#if defined (JOB_CONTROL) - /* Reset job control, since run_startup_files turned it off. */ - set_job_control (interactive_shell); -#endif - /* Reset value of `set -e', since it's turned off before running - the startup files. */ - exit_immediately_on_error += old_errexit_flag; - locally_skip_execution++; - } - } - - arg_index = top_level_arg_index; - - /* Execute the start-up scripts. */ - - if (interactive_shell == 0) - { - unbind_variable ("PS1"); - unbind_variable ("PS2"); - interactive = 0; -#if 0 - /* This has already been done by init_noninteractive */ - expand_aliases = posixly_correct; -#endif - } - else - { - change_flag ('i', FLAG_ON); - interactive = 1; - } - -#if defined (RESTRICTED_SHELL) - /* Set restricted_shell based on whether the basename of $0 indicates that - the shell should be restricted or if the `-r' option was supplied at - startup. */ - restricted_shell = shell_is_restricted (shell_name); - - /* If the `-r' option is supplied at invocation, make sure that the shell - is not in restricted mode when running the startup files. */ - saverst = restricted; - restricted = 0; -#endif - - /* Set positional parameters before running startup files. top_level_arg_index - holds the index of the current argument before setting the positional - parameters, so any changes performed in the startup files won't affect - later option processing. */ - if (wordexp_only) - ; /* nothing yet */ - else if (command_execution_string) - arg_index = bind_args (argv, arg_index, argc, 0); /* $0 ... $n */ - else if (arg_index != argc && read_from_stdin == 0) - { - shell_script_filename = argv[arg_index++]; - arg_index = bind_args (argv, arg_index, argc, 1); /* $1 ... $n */ - } - else - arg_index = bind_args (argv, arg_index, argc, 1); /* $1 ... $n */ - - /* The startup files are run with `set -e' temporarily disabled. */ - if (locally_skip_execution == 0 && running_setuid == 0) - { - char *t; - - old_errexit_flag = exit_immediately_on_error; - exit_immediately_on_error = 0; - - /* Temporarily set $0 while running startup files, then restore it so - we get better error messages when trying to open script files. */ - if (shell_script_filename) - { - t = dollar_vars[0]; - dollar_vars[0] = exec_argv0 ? savestring (exec_argv0) : savestring (shell_script_filename); - } - run_startup_files (); - if (shell_script_filename) - { - free (dollar_vars[0]); - dollar_vars[0] = t; - } - exit_immediately_on_error += old_errexit_flag; - } - - /* If we are invoked as `sh', turn on Posix mode. */ - if (act_like_sh) - { - bind_variable ("POSIXLY_CORRECT", "y", 0); - sv_strict_posix ("POSIXLY_CORRECT"); - } - -#if defined (RESTRICTED_SHELL) - /* Turn on the restrictions after executing the startup files. This - means that `bash -r' or `set -r' invoked from a startup file will - turn on the restrictions after the startup files are executed. */ - restricted = saverst || restricted; - if (shell_reinitialized == 0) - maybe_make_restricted (shell_name); -#endif /* RESTRICTED_SHELL */ - -#if defined (WORDEXP_OPTION) - if (wordexp_only) - { - startup_state = 3; - last_command_exit_value = run_wordexp (argv[top_level_arg_index]); - exit_shell (last_command_exit_value); - } -#endif - - cmd_init (); /* initialize the command object caches */ - uwp_init (); - - if (command_execution_string) - { - startup_state = 2; - - if (debugging_mode) - start_debugger (); - -#if defined (ONESHOT) - executing = 1; - run_one_command (command_execution_string); - exit_shell (last_command_exit_value); -#else /* ONESHOT */ - with_input_from_string (command_execution_string, "-c"); - goto read_and_execute; -#endif /* !ONESHOT */ - } - - /* Get possible input filename and set up default_buffered_input or - default_input as appropriate. */ - if (shell_script_filename) - open_shell_script (shell_script_filename); - else if (interactive == 0) - { - /* In this mode, bash is reading a script from stdin, which is a - pipe or redirected file. */ -#if defined (BUFFERED_INPUT) - default_buffered_input = fileno (stdin); /* == 0 */ -#else - setbuf (default_input, (char *)NULL); -#endif /* !BUFFERED_INPUT */ - read_from_stdin = 1; - } - else if (top_level_arg_index == argc) /* arg index before startup files */ - /* "If there are no operands and the -c option is not specified, the -s - option shall be assumed." */ - read_from_stdin = 1; - - set_bash_input (); - - if (debugging_mode && locally_skip_execution == 0 && running_setuid == 0 && (reading_shell_script || interactive_shell == 0)) - start_debugger (); - - /* Do the things that should be done only for interactive shells. */ - if (interactive_shell) - { - /* Set up for checking for presence of mail. */ - reset_mail_timer (); - init_mail_dates (); - -#if defined (HISTORY) - /* Initialize the interactive history stuff. */ - bash_initialize_history (); - /* Don't load the history from the history file if we've already - saved some lines in this session (e.g., by putting `history -s xx' - into one of the startup files). */ - if (shell_initialized == 0 && history_lines_this_session == 0) - load_history (); -#endif /* HISTORY */ - - /* Initialize terminal state for interactive shells after the - .bash_profile and .bashrc are interpreted. */ - get_tty_state (); - } - -#if !defined (ONESHOT) - read_and_execute: -#endif /* !ONESHOT */ - - shell_initialized = 1; - - if (pretty_print_mode && interactive_shell) - { - internal_warning (_("pretty-printing mode ignored in interactive shells")); - pretty_print_mode = 0; - } - if (pretty_print_mode) - exit_shell (pretty_print_loop ()); - - /* Read commands until exit condition. */ - reader_loop (); - exit_shell (last_command_exit_value); -} - -static int -parse_long_options (argv, arg_start, arg_end) - char **argv; - int arg_start, arg_end; -{ - int arg_index, longarg, i; - char *arg_string; - - arg_index = arg_start; - while ((arg_index != arg_end) && (arg_string = argv[arg_index]) && - (*arg_string == '-')) - { - longarg = 0; - - /* Make --login equivalent to -login. */ - if (arg_string[1] == '-' && arg_string[2]) - { - longarg = 1; - arg_string++; - } - - for (i = 0; long_args[i].name; i++) - { - if (STREQ (arg_string + 1, long_args[i].name)) - { - if (long_args[i].type == Int) - *long_args[i].int_value = 1; - else if (argv[++arg_index] == 0) - { - report_error (_("%s: option requires an argument"), long_args[i].name); - exit (EX_BADUSAGE); - } - else - *long_args[i].char_value = argv[arg_index]; - - break; - } - } - if (long_args[i].name == 0) - { - if (longarg) - { - report_error (_("%s: invalid option"), argv[arg_index]); - show_shell_usage (stderr, 0); - exit (EX_BADUSAGE); - } - break; /* No such argument. Maybe flag arg. */ - } - - arg_index++; - } - - return (arg_index); -} - -static int -parse_shell_options (argv, arg_start, arg_end) - char **argv; - int arg_start, arg_end; -{ - int arg_index; - int arg_character, on_or_off, next_arg, i; - char *o_option, *arg_string; - - arg_index = arg_start; - while (arg_index != arg_end && (arg_string = argv[arg_index]) && - (*arg_string == '-' || *arg_string == '+')) - { - /* There are flag arguments, so parse them. */ - next_arg = arg_index + 1; - - /* A single `-' signals the end of options. From the 4.3 BSD sh. - An option `--' means the same thing; this is the standard - getopt(3) meaning. */ - if (arg_string[0] == '-' && - (arg_string[1] == '\0' || - (arg_string[1] == '-' && arg_string[2] == '\0'))) - return (next_arg); - - i = 1; - on_or_off = arg_string[0]; - while (arg_character = arg_string[i++]) - { - switch (arg_character) - { - case 'c': - want_pending_command = 1; - break; - - case 'l': - make_login_shell = 1; - break; - - case 's': - read_from_stdin = 1; - break; - - case 'o': - o_option = argv[next_arg]; - if (o_option == 0) - { - set_option_defaults (); - list_minus_o_opts (-1, (on_or_off == '-') ? 0 : 1); - reset_option_defaults (); - break; - } - if (set_minus_o_option (on_or_off, o_option) != EXECUTION_SUCCESS) - exit (EX_BADUSAGE); - next_arg++; - break; - - case 'O': - /* Since some of these can be overridden by the normal - interactive/non-interactive shell initialization or - initializing posix mode, we save the options and process - them after initialization. */ - o_option = argv[next_arg]; - if (o_option == 0) - { - shopt_listopt (o_option, (on_or_off == '-') ? 0 : 1); - break; - } - add_shopt_to_alist (o_option, on_or_off); - next_arg++; - break; - - case 'D': -#if defined (TRANSLATABLE_STRINGS) - dump_translatable_strings = 1; -#endif - break; - - default: - if (change_flag (arg_character, on_or_off) == FLAG_ERROR) - { - report_error (_("%c%c: invalid option"), on_or_off, arg_character); - show_shell_usage (stderr, 0); - exit (EX_BADUSAGE); - } - } - } - /* Can't do just a simple increment anymore -- what about - "bash -abouo emacs ignoreeof -hP"? */ - arg_index = next_arg; - } - - return (arg_index); -} - -/* Exit the shell with status S. */ -void -exit_shell (s) - int s; -{ - fflush (stdout); /* XXX */ - fflush (stderr); - - /* Clean up the terminal if we are in a state where it's been modified. */ -#if defined (READLINE) - if (RL_ISSTATE (RL_STATE_TERMPREPPED) && rl_deprep_term_function) - (*rl_deprep_term_function) (); -#endif - if (read_tty_modified ()) - read_tty_cleanup (); - - /* Do trap[0] if defined. Allow it to override the exit status - passed to us. */ - if (signal_is_trapped (0)) - s = run_exit_trap (); - -#if defined (PROCESS_SUBSTITUTION) - unlink_all_fifos (); -#endif /* PROCESS_SUBSTITUTION */ - -#if defined (HISTORY) - if (remember_on_history) - maybe_save_shell_history (); -#endif /* HISTORY */ - -#if defined (COPROCESS_SUPPORT) - coproc_flush (); -#endif - -#if defined (JOB_CONTROL) - /* If the user has run `shopt -s huponexit', hangup all jobs when we exit - an interactive login shell. ksh does this unconditionally. */ - if (interactive_shell && login_shell && hup_on_exit) - hangup_all_jobs (); - - /* If this shell is interactive, or job control is active, terminate all - stopped jobs and restore the original terminal process group. Don't do - this if we're in a subshell and calling exit_shell after, for example, - a failed word expansion. We want to do this even if the shell is not - interactive because we set the terminal's process group when job control - is enabled regardless of the interactive status. */ - if (subshell_environment == 0) - end_job_control (); -#endif /* JOB_CONTROL */ - - /* Always return the exit status of the last command to our parent. */ - sh_exit (s); -} - -/* A wrapper for exit that (optionally) can do other things, like malloc - statistics tracing. */ -void -sh_exit (s) - int s; -{ -#if defined (MALLOC_DEBUG) && defined (USING_BASH_MALLOC) - if (malloc_trace_at_exit && (subshell_environment & (SUBSHELL_COMSUB|SUBSHELL_PROCSUB)) == 0) - trace_malloc_stats (get_name_for_error (), (char *)NULL); - /* mlocation_write_table (); */ -#endif - - exit (s); -} - -/* Exit a subshell, which includes calling the exit trap. We don't want to - do any more cleanup, since a subshell is created as an exact copy of its - parent. */ -void -subshell_exit (s) - int s; -{ - fflush (stdout); - fflush (stderr); - - /* Do trap[0] if defined. Allow it to override the exit status - passed to us. */ - last_command_exit_value = s; - if (signal_is_trapped (0)) - s = run_exit_trap (); - - sh_exit (s); -} - -void -set_exit_status (s) - int s; -{ - set_pipestatus_from_exit (last_command_exit_value = s); -} - -/* Source the bash startup files. If POSIXLY_CORRECT is non-zero, we obey - the Posix.2 startup file rules: $ENV is expanded, and if the file it - names exists, that file is sourced. The Posix.2 rules are in effect - for interactive shells only. (section 4.56.5.3) */ - -/* Execute ~/.bashrc for most shells. Never execute it if - ACT_LIKE_SH is set, or if NO_RC is set. - - If the executable file "/usr/gnu/src/bash/foo" contains: - - #!/usr/gnu/bin/bash - echo hello - - then: - - COMMAND EXECUTE BASHRC - -------------------------------- - bash -c foo NO - bash foo NO - foo NO - rsh machine ls YES (for rsh, which calls `bash -c') - rsh machine foo YES (for shell started by rsh) NO (for foo!) - echo ls | bash NO - login NO - bash YES -*/ - -static void -execute_env_file (env_file) - char *env_file; -{ - char *fn; - - if (env_file && *env_file) - { - fn = expand_string_unsplit_to_string (env_file, Q_DOUBLE_QUOTES); - if (fn && *fn) - maybe_execute_file (fn, 1); - FREE (fn); - } -} - -static void -run_startup_files () -{ -#if defined (JOB_CONTROL) - int old_job_control; -#endif - int sourced_login, run_by_ssh; - -#if 1 /* TAG:bash-5.3 andrew.gregory.8@gmail.com 2/21/2022 */ - /* get the rshd/sshd case out of the way first. */ - if (interactive_shell == 0 && no_rc == 0 && login_shell == 0 && - act_like_sh == 0 && command_execution_string) - { -#ifdef SSH_SOURCE_BASHRC - run_by_ssh = (find_variable ("SSH_CLIENT") != (SHELL_VAR *)0) || - (find_variable ("SSH2_CLIENT") != (SHELL_VAR *)0); -#else - run_by_ssh = 0; -#endif -#endif - - /* If we were run by sshd or we think we were run by rshd, execute - ~/.bashrc if we are a top-level shell. */ -#if 1 /* TAG:bash-5.3 */ - if ((run_by_ssh || isnetconn (fileno (stdin))) && shell_level < 2) -#else - if (isnetconn (fileno (stdin) && shell_level < 2) -#endif - { -#ifdef SYS_BASHRC -# if defined (__OPENNT) - maybe_execute_file (_prefixInstallPath(SYS_BASHRC, NULL, 0), 1); -# else - maybe_execute_file (SYS_BASHRC, 1); -# endif -#endif - maybe_execute_file (bashrc_file, 1); - return; - } - } - -#if defined (JOB_CONTROL) - /* Startup files should be run without job control enabled. */ - old_job_control = interactive_shell ? set_job_control (0) : 0; -#endif - - sourced_login = 0; - - /* A shell begun with the --login (or -l) flag that is not in posix mode - runs the login shell startup files, no matter whether or not it is - interactive. If NON_INTERACTIVE_LOGIN_SHELLS is defined, run the - startup files if argv[0][0] == '-' as well. */ -#if defined (NON_INTERACTIVE_LOGIN_SHELLS) - if (login_shell && posixly_correct == 0) -#else - if (login_shell < 0 && posixly_correct == 0) -#endif - { - /* We don't execute .bashrc for login shells. */ - no_rc++; - - /* Execute /etc/profile and one of the personal login shell - initialization files. */ - if (no_profile == 0) - { - maybe_execute_file (SYS_PROFILE, 1); - - if (act_like_sh) /* sh */ - maybe_execute_file ("~/.profile", 1); - else if ((maybe_execute_file ("~/.bash_profile", 1) == 0) && - (maybe_execute_file ("~/.bash_login", 1) == 0)) /* bash */ - maybe_execute_file ("~/.profile", 1); - } - - sourced_login = 1; - } - - /* A non-interactive shell not named `sh' and not in posix mode reads and - executes commands from $BASH_ENV. If `su' starts a shell with `-c cmd' - and `-su' as the name of the shell, we want to read the startup files. - No other non-interactive shells read any startup files. */ - if (interactive_shell == 0 && !(su_shell && login_shell)) - { - if (posixly_correct == 0 && act_like_sh == 0 && privileged_mode == 0 && - sourced_env++ == 0) - execute_env_file (get_string_value ("BASH_ENV")); - return; - } - - /* Interactive shell or `-su' shell. */ - if (posixly_correct == 0) /* bash, sh */ - { - if (login_shell && sourced_login++ == 0) - { - /* We don't execute .bashrc for login shells. */ - no_rc++; - - /* Execute /etc/profile and one of the personal login shell - initialization files. */ - if (no_profile == 0) - { - maybe_execute_file (SYS_PROFILE, 1); - - if (act_like_sh) /* sh */ - maybe_execute_file ("~/.profile", 1); - else if ((maybe_execute_file ("~/.bash_profile", 1) == 0) && - (maybe_execute_file ("~/.bash_login", 1) == 0)) /* bash */ - maybe_execute_file ("~/.profile", 1); - } - } - - /* bash */ - if (act_like_sh == 0 && no_rc == 0) - { -#ifdef SYS_BASHRC -# if defined (__OPENNT) - maybe_execute_file (_prefixInstallPath(SYS_BASHRC, NULL, 0), 1); -# else - maybe_execute_file (SYS_BASHRC, 1); -# endif -#endif - maybe_execute_file (bashrc_file, 1); - } - /* sh */ - else if (act_like_sh && privileged_mode == 0 && sourced_env++ == 0) - execute_env_file (get_string_value ("ENV")); - } - else /* bash --posix, sh --posix */ - { - /* bash and sh */ - if (interactive_shell && privileged_mode == 0 && sourced_env++ == 0) - execute_env_file (get_string_value ("ENV")); - } - -#if defined (JOB_CONTROL) - set_job_control (old_job_control); -#endif -} - -#if defined (RESTRICTED_SHELL) -/* Return 1 if the shell should be a restricted one based on NAME or the - value of `restricted'. Don't actually do anything, just return a - boolean value. */ -int -shell_is_restricted (name) - char *name; -{ - char *temp; - - if (restricted) - return 1; - temp = base_pathname (name); - if (*temp == '-') - temp++; - return (STREQ (temp, RESTRICTED_SHELL_NAME)); -} - -/* Perhaps make this shell a `restricted' one, based on NAME. If the - basename of NAME is "rbash", then this shell is restricted. The - name of the restricted shell is a configurable option, see config.h. - In a restricted shell, PATH, SHELL, ENV, and BASH_ENV are read-only - and non-unsettable. - Do this also if `restricted' is already set to 1; maybe the shell was - started with -r. */ -int -maybe_make_restricted (name) - char *name; -{ - char *temp; - - temp = base_pathname (name); - if (*temp == '-') - temp++; - if (restricted || (STREQ (temp, RESTRICTED_SHELL_NAME))) - { -#if defined (RBASH_STATIC_PATH_VALUE) - bind_variable ("PATH", RBASH_STATIC_PATH_VALUE, 0); - stupidly_hack_special_variables ("PATH"); /* clear hash table */ -#endif - set_var_read_only ("PATH"); - set_var_read_only ("SHELL"); - set_var_read_only ("ENV"); - set_var_read_only ("BASH_ENV"); - set_var_read_only ("HISTFILE"); - restricted = 1; - } - return (restricted); -} -#endif /* RESTRICTED_SHELL */ - -/* Fetch the current set of uids and gids and return 1 if we're running - setuid or setgid. */ -static int -uidget () -{ - uid_t u; - - u = getuid (); - if (current_user.uid != u) - { - FREE (current_user.user_name); - FREE (current_user.shell); - FREE (current_user.home_dir); - current_user.user_name = current_user.shell = current_user.home_dir = (char *)NULL; - } - current_user.uid = u; - current_user.gid = getgid (); - current_user.euid = geteuid (); - current_user.egid = getegid (); - - /* See whether or not we are running setuid or setgid. */ - return (current_user.uid != current_user.euid) || - (current_user.gid != current_user.egid); -} - -void -disable_priv_mode () -{ - int e; - -#if HAVE_SETRESUID - if (setresuid (current_user.uid, current_user.uid, current_user.uid) < 0) -#else - if (setuid (current_user.uid) < 0) -#endif - { - e = errno; - sys_error (_("cannot set uid to %d: effective uid %d"), current_user.uid, current_user.euid); -#if defined (EXIT_ON_SETUID_FAILURE) - if (e == EAGAIN) - exit (e); -#endif - } -#if HAVE_SETRESGID - if (setresgid (current_user.gid, current_user.gid, current_user.gid) < 0) -#else - if (setgid (current_user.gid) < 0) -#endif - sys_error (_("cannot set gid to %d: effective gid %d"), current_user.gid, current_user.egid); - - current_user.euid = current_user.uid; - current_user.egid = current_user.gid; -} - -#if defined (WORDEXP_OPTION) -static int -run_wordexp (words) - char *words; -{ - int code, nw, nb; - WORD_LIST *wl, *tl, *result; - - code = setjmp_nosigs (top_level); - - if (code != NOT_JUMPED) - { - switch (code) - { - /* Some kind of throw to top_level has occurred. */ - case FORCE_EOF: - return last_command_exit_value = 127; - case ERREXIT: - case EXITPROG: - case EXITBLTIN: - return last_command_exit_value; - case DISCARD: - return last_command_exit_value = 1; - default: - command_error ("run_wordexp", CMDERR_BADJUMP, code, 0); - } - } - - /* Run it through the parser to get a list of words and expand them */ - if (words && *words) - { - with_input_from_string (words, "--wordexp"); - if (parse_command () != 0) - return (126); - if (global_command == 0) - { - printf ("0\n0\n"); - return (0); - } - if (global_command->type != cm_simple) - return (126); - wl = global_command->value.Simple->words; - if (protected_mode) - for (tl = wl; tl; tl = tl->next) - tl->word->flags |= W_NOCOMSUB|W_NOPROCSUB; - result = wl ? expand_words_no_vars (wl) : (WORD_LIST *)0; - } - else - result = (WORD_LIST *)0; - - last_command_exit_value = 0; - - if (result == 0) - { - printf ("0\n0\n"); - return (0); - } - - /* Count up the number of words and bytes, and print them. Don't count - the trailing NUL byte. */ - for (nw = nb = 0, wl = result; wl; wl = wl->next) - { - nw++; - nb += strlen (wl->word->word); - } - printf ("%u\n%u\n", nw, nb); - /* Print each word on a separate line. This will have to be changed when - the interface to glibc is completed. */ - for (wl = result; wl; wl = wl->next) - printf ("%s\n", wl->word->word); - - return (0); -} -#endif - -#if defined (ONESHOT) -/* Run one command, given as the argument to the -c option. Tell - parse_and_execute not to fork for a simple command. */ -static int -run_one_command (command) - char *command; -{ - int code; - - code = setjmp_nosigs (top_level); - - if (code != NOT_JUMPED) - { -#if defined (PROCESS_SUBSTITUTION) - unlink_fifo_list (); -#endif /* PROCESS_SUBSTITUTION */ - switch (code) - { - /* Some kind of throw to top_level has occurred. */ - case FORCE_EOF: - return last_command_exit_value = 127; - case ERREXIT: - case EXITPROG: - case EXITBLTIN: - return last_command_exit_value; - case DISCARD: - return last_command_exit_value = 1; - default: - command_error ("run_one_command", CMDERR_BADJUMP, code, 0); - } - } - return (parse_and_execute (savestring (command), "-c", SEVAL_NOHIST|SEVAL_RESETLINE)); -} -#endif /* ONESHOT */ - -static int -bind_args (argv, arg_start, arg_end, start_index) - char **argv; - int arg_start, arg_end, start_index; -{ - register int i; - WORD_LIST *args, *tl; - - for (i = arg_start, args = tl = (WORD_LIST *)NULL; i < arg_end; i++) - { - if (args == 0) - args = tl = make_word_list (make_word (argv[i]), args); - else - { - tl->next = make_word_list (make_word (argv[i]), (WORD_LIST *)NULL); - tl = tl->next; - } - } - - if (args) - { - if (start_index == 0) /* bind to $0...$n for sh -c command */ - { - /* Posix.2 4.56.3 says that the first argument after sh -c command - becomes $0, and the rest of the arguments become $1...$n */ - shell_name = savestring (args->word->word); - FREE (dollar_vars[0]); - dollar_vars[0] = savestring (args->word->word); - remember_args (args->next, 1); - if (debugging_mode) - { - push_args (args->next); /* BASH_ARGV and BASH_ARGC */ - bash_argv_initialized = 1; - } - } - else /* bind to $1...$n for shell script */ - { - remember_args (args, 1); - /* We do this unconditionally so something like -O extdebug doesn't - do it first. We're setting the definitive positional params - here. */ - if (debugging_mode) - { - push_args (args); /* BASH_ARGV and BASH_ARGC */ - bash_argv_initialized = 1; - } - } - - dispose_words (args); - } - - return (i); -} - -void -unbind_args () -{ - remember_args ((WORD_LIST *)NULL, 1); - pop_args (); /* Reset BASH_ARGV and BASH_ARGC */ -} - -static void -start_debugger () -{ -#if defined (DEBUGGER) && defined (DEBUGGER_START_FILE) - int old_errexit; - int r; - - old_errexit = exit_immediately_on_error; - exit_immediately_on_error = 0; - - r = force_execute_file (DEBUGGER_START_FILE, 1); - if (r < 0) - { - internal_warning (_("cannot start debugger; debugging mode disabled")); - debugging_mode = 0; - } - error_trace_mode = function_trace_mode = debugging_mode; - - set_shellopts (); - set_bashopts (); - - exit_immediately_on_error += old_errexit; -#endif -} - -static int -open_shell_script (script_name) - char *script_name; -{ - int fd, e, fd_is_tty; - char *filename, *path_filename, *t; - char sample[80]; - int sample_len; - struct stat sb; -#if defined (ARRAY_VARS) - SHELL_VAR *funcname_v, *bash_source_v, *bash_lineno_v; - ARRAY *funcname_a, *bash_source_a, *bash_lineno_a; -#endif - - filename = savestring (script_name); - - fd = open (filename, O_RDONLY); - if ((fd < 0) && (errno == ENOENT) && (absolute_program (filename) == 0)) - { - e = errno; - /* If it's not in the current directory, try looking through PATH - for it. */ - path_filename = find_path_file (script_name); - if (path_filename) - { - free (filename); - filename = path_filename; - fd = open (filename, O_RDONLY); - } - else - errno = e; - } - - if (fd < 0) - { - e = errno; - file_error (filename); -#if defined (JOB_CONTROL) - end_job_control (); /* just in case we were run as bash -i script */ -#endif - sh_exit ((e == ENOENT) ? EX_NOTFOUND : EX_NOINPUT); - } - - free (dollar_vars[0]); - dollar_vars[0] = exec_argv0 ? savestring (exec_argv0) : savestring (script_name); - if (exec_argv0) - { - free (exec_argv0); - exec_argv0 = (char *)NULL; - } - - if (file_isdir (filename)) - { -#if defined (EISDIR) - errno = EISDIR; -#else - errno = EINVAL; -#endif - file_error (filename); -#if defined (JOB_CONTROL) - end_job_control (); /* just in case we were run as bash -i script */ -#endif - sh_exit (EX_NOINPUT); - } - -#if defined (ARRAY_VARS) - GET_ARRAY_FROM_VAR ("FUNCNAME", funcname_v, funcname_a); - GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a); - GET_ARRAY_FROM_VAR ("BASH_LINENO", bash_lineno_v, bash_lineno_a); - - array_push (bash_source_a, filename); - if (bash_lineno_a) - { - t = itos (executing_line_number ()); - array_push (bash_lineno_a, t); - free (t); - } - array_push (funcname_a, "main"); -#endif - -#ifdef HAVE_DEV_FD - fd_is_tty = isatty (fd); -#else - fd_is_tty = 0; -#endif - - /* Only do this with non-tty file descriptors we can seek on. */ - if (fd_is_tty == 0 && (lseek (fd, 0L, 1) != -1)) - { - /* Check to see if the `file' in `bash file' is a binary file - according to the same tests done by execute_simple_command (), - and report an error and exit if it is. */ - sample_len = read (fd, sample, sizeof (sample)); - if (sample_len < 0) - { - e = errno; - if ((fstat (fd, &sb) == 0) && S_ISDIR (sb.st_mode)) - { -#if defined (EISDIR) - errno = EISDIR; - file_error (filename); -#else - internal_error (_("%s: Is a directory"), filename); -#endif - } - else - { - errno = e; - file_error (filename); - } -#if defined (JOB_CONTROL) - end_job_control (); /* just in case we were run as bash -i script */ -#endif - exit (EX_NOEXEC); - } - else if (sample_len > 0 && (check_binary_file (sample, sample_len))) - { - internal_error (_("%s: cannot execute binary file"), filename); -#if defined (JOB_CONTROL) - end_job_control (); /* just in case we were run as bash -i script */ -#endif - exit (EX_BINARY_FILE); - } - /* Now rewind the file back to the beginning. */ - lseek (fd, 0L, 0); - } - - /* Open the script. But try to move the file descriptor to a randomly - large one, in the hopes that any descriptors used by the script will - not match with ours. */ - fd = move_to_high_fd (fd, 1, -1); - -#if defined (BUFFERED_INPUT) - default_buffered_input = fd; - SET_CLOSE_ON_EXEC (default_buffered_input); -#else /* !BUFFERED_INPUT */ - default_input = fdopen (fd, "r"); - - if (default_input == 0) - { - file_error (filename); - exit (EX_NOTFOUND); - } - - SET_CLOSE_ON_EXEC (fd); - if (fileno (default_input) != fd) - SET_CLOSE_ON_EXEC (fileno (default_input)); -#endif /* !BUFFERED_INPUT */ - - /* Just about the only way for this code to be executed is if something - like `bash -i /dev/stdin' is executed. */ - if (interactive_shell && fd_is_tty) - { - dup2 (fd, 0); - close (fd); - fd = 0; -#if defined (BUFFERED_INPUT) - default_buffered_input = 0; -#else - fclose (default_input); - default_input = stdin; -#endif - } - else if (forced_interactive && fd_is_tty == 0) - /* But if a script is called with something like `bash -i scriptname', - we need to do a non-interactive setup here, since we didn't do it - before. */ - init_interactive_script (); - - free (filename); - - reading_shell_script = 1; - return (fd); -} - -/* Initialize the input routines for the parser. */ -static void -set_bash_input () -{ - /* Make sure the fd from which we are reading input is not in - no-delay mode. */ -#if defined (BUFFERED_INPUT) - if (interactive == 0) - sh_unset_nodelay_mode (default_buffered_input); - else -#endif /* !BUFFERED_INPUT */ - sh_unset_nodelay_mode (fileno (stdin)); - - /* with_input_from_stdin really means `with_input_from_readline' */ - if (interactive && no_line_editing == 0) - with_input_from_stdin (); -#if defined (BUFFERED_INPUT) - else if (interactive == 0) - with_input_from_buffered_stream (default_buffered_input, dollar_vars[0]); -#endif /* BUFFERED_INPUT */ - else - with_input_from_stream (default_input, dollar_vars[0]); -} - -/* Close the current shell script input source and forget about it. This is - extern so execute_cmd.c:initialize_subshell() can call it. If CHECK_ZERO - is non-zero, we close default_buffered_input even if it's the standard - input (fd 0). */ -void -unset_bash_input (check_zero) - int check_zero; -{ -#if defined (BUFFERED_INPUT) - if ((check_zero && default_buffered_input >= 0) || - (check_zero == 0 && default_buffered_input > 0)) - { - close_buffered_fd (default_buffered_input); - default_buffered_input = bash_input.location.buffered_fd = -1; - bash_input.type = st_none; /* XXX */ - } -#else /* !BUFFERED_INPUT */ - if (default_input) - { - fclose (default_input); - default_input = (FILE *)NULL; - } -#endif /* !BUFFERED_INPUT */ -} - - -#if !defined (PROGRAM) -# define PROGRAM "bash" -#endif - -static void -set_shell_name (argv0) - char *argv0; -{ - /* Here's a hack. If the name of this shell is "sh", then don't do - any startup files; just try to be more like /bin/sh. */ - shell_name = argv0 ? base_pathname (argv0) : PROGRAM; - - if (argv0 && *argv0 == '-') - { - if (*shell_name == '-') - shell_name++; - login_shell = 1; - } - - if (shell_name[0] == 's' && shell_name[1] == 'h' && shell_name[2] == '\0') - act_like_sh++; - if (shell_name[0] == 's' && shell_name[1] == 'u' && shell_name[2] == '\0') - su_shell++; - - shell_name = argv0 ? argv0 : PROGRAM; - FREE (dollar_vars[0]); - dollar_vars[0] = savestring (shell_name); - - /* A program may start an interactive shell with - "execl ("/bin/bash", "-", NULL)". - If so, default the name of this shell to our name. */ - if (!shell_name || !*shell_name || (shell_name[0] == '-' && !shell_name[1])) - shell_name = PROGRAM; -} - -/* Some options are initialized to -1 so we have a way to determine whether - they were set on the command line. This is an issue when listing the option - values at invocation (`bash -o'), so we set the defaults here and reset - them after the call to list_minus_o_options (). */ -/* XXX - could also do this for histexp_flag, jobs_m_flag */ -static void -set_option_defaults () -{ -#if defined (HISTORY) - enable_history_list = 0; -#endif -} - -static void -reset_option_defaults () -{ -#if defined (HISTORY) - enable_history_list = -1; -#endif -} - -static void -init_interactive () -{ - expand_aliases = interactive_shell = startup_state = 1; - interactive = 1; -#if defined (HISTORY) - if (enable_history_list == -1) - enable_history_list = 1; /* set default */ - remember_on_history = enable_history_list; -# if defined (BANG_HISTORY) - histexp_flag = history_expansion; /* XXX */ -# endif -#endif -} - -static void -init_noninteractive () -{ -#if defined (HISTORY) - if (enable_history_list == -1) /* set default */ - enable_history_list = 0; - bash_history_reinit (0); -#endif /* HISTORY */ - interactive_shell = startup_state = interactive = 0; - expand_aliases = posixly_correct; /* XXX - was 0 not posixly_correct */ - no_line_editing = 1; -#if defined (JOB_CONTROL) - /* Even if the shell is not interactive, enable job control if the -i or - -m option is supplied at startup. */ - set_job_control (forced_interactive||jobs_m_flag); -#endif /* JOB_CONTROL */ -} - -static void -init_interactive_script () -{ -#if defined (HISTORY) - if (enable_history_list == -1) - enable_history_list = 1; -#endif - init_noninteractive (); - expand_aliases = interactive_shell = startup_state = 1; -#if defined (HISTORY) - remember_on_history = enable_history_list; /* XXX */ -#endif -} - -void -get_current_user_info () -{ - struct passwd *entry; - - /* Don't fetch this more than once. */ - if (current_user.user_name == 0) - { -#if defined (__TANDEM) - entry = getpwnam (getlogin ()); -#else - entry = getpwuid (current_user.uid); -#endif - if (entry) - { - current_user.user_name = savestring (entry->pw_name); - current_user.shell = (entry->pw_shell && entry->pw_shell[0]) - ? savestring (entry->pw_shell) - : savestring ("/bin/sh"); - current_user.home_dir = savestring (entry->pw_dir); - } - else - { - current_user.user_name = _("I have no name!"); - current_user.user_name = savestring (current_user.user_name); - current_user.shell = savestring ("/bin/sh"); - current_user.home_dir = savestring ("/"); - } -#if defined (HAVE_GETPWENT) - endpwent (); -#endif - } -} - -/* Do whatever is necessary to initialize the shell. - Put new initializations in here. */ -static void -shell_initialize () -{ - char hostname[256]; - int should_be_restricted; - - /* Line buffer output for stderr and stdout. */ - if (shell_initialized == 0) - { - sh_setlinebuf (stderr); - sh_setlinebuf (stdout); - } - - /* Sort the array of shell builtins so that the binary search in - find_shell_builtin () works correctly. */ - initialize_shell_builtins (); - - /* Initialize the trap signal handlers before installing our own - signal handlers. traps.c:restore_original_signals () is responsible - for restoring the original default signal handlers. That function - is called when we make a new child. */ - initialize_traps (); - initialize_signals (0); - - /* It's highly unlikely that this will change. */ - if (current_host_name == 0) - { - /* Initialize current_host_name. */ - if (gethostname (hostname, 255) < 0) - current_host_name = "??host??"; - else - current_host_name = savestring (hostname); - } - - /* Initialize the stuff in current_user that comes from the password - file. We don't need to do this right away if the shell is not - interactive. */ - if (interactive_shell) - get_current_user_info (); - - /* Initialize our interface to the tilde expander. */ - tilde_initialize (); - -#if defined (RESTRICTED_SHELL) - should_be_restricted = shell_is_restricted (shell_name); -#endif - - /* Initialize internal and environment variables. Don't import shell - functions from the environment if we are running in privileged or - restricted mode or if the shell is running setuid. */ -#if defined (RESTRICTED_SHELL) - initialize_shell_variables (shell_environment, privileged_mode||restricted||should_be_restricted||running_setuid); -#else - initialize_shell_variables (shell_environment, privileged_mode||running_setuid); -#endif - - /* Initialize the data structures for storing and running jobs. */ - initialize_job_control (jobs_m_flag); - - /* Initialize input streams to null. */ - initialize_bash_input (); - - initialize_flags (); - - /* Initialize the shell options. Don't import the shell options - from the environment variables $SHELLOPTS or $BASHOPTS if we are - running in privileged or restricted mode or if the shell is running - setuid. */ -#if defined (RESTRICTED_SHELL) - initialize_shell_options (privileged_mode||restricted||should_be_restricted||running_setuid); - initialize_bashopts (privileged_mode||restricted||should_be_restricted||running_setuid); -#else - initialize_shell_options (privileged_mode||running_setuid); - initialize_bashopts (privileged_mode||running_setuid); -#endif -} - -/* Function called by main () when it appears that the shell has already - had some initialization performed. This is supposed to reset the world - back to a pristine state, as if we had been exec'ed. */ -static void -shell_reinitialize () -{ - /* The default shell prompts. */ - primary_prompt = PPROMPT; - secondary_prompt = SPROMPT; - - /* Things that get 1. */ - current_command_number = 1; - - /* We have decided that the ~/.bashrc file should not be executed - for the invocation of each shell script. If the variable $ENV - (or $BASH_ENV) is set, its value is used as the name of a file - to source. */ - no_rc = no_profile = 1; - - /* Things that get 0. */ - login_shell = make_login_shell = interactive = executing = 0; - debugging = do_version = line_number = last_command_exit_value = 0; - forced_interactive = interactive_shell = 0; - subshell_environment = running_in_background = 0; - expand_aliases = 0; - bash_argv_initialized = 0; - - /* XXX - should we set jobs_m_flag to 0 here? */ - -#if defined (HISTORY) - bash_history_reinit (enable_history_list = 0); -#endif /* HISTORY */ - -#if defined (RESTRICTED_SHELL) - restricted = 0; -#endif /* RESTRICTED_SHELL */ - - /* Ensure that the default startup file is used. (Except that we don't - execute this file for reinitialized shells). */ - bashrc_file = DEFAULT_BASHRC; - - /* Delete all variables and functions. They will be reinitialized when - the environment is parsed. */ - delete_all_contexts (shell_variables); - delete_all_variables (shell_functions); - - reinit_special_variables (); - -#if defined (READLINE) - bashline_reinitialize (); -#endif - - shell_reinitialized = 1; -} - -static void -show_shell_usage (fp, extra) - FILE *fp; - int extra; -{ - int i; - char *set_opts, *s, *t; - - if (extra) - fprintf (fp, _("GNU bash, version %s-(%s)\n"), shell_version_string (), MACHTYPE); - fprintf (fp, _("Usage:\t%s [GNU long option] [option] ...\n\t%s [GNU long option] [option] script-file ...\n"), - shell_name, shell_name); - fputs (_("GNU long options:\n"), fp); - for (i = 0; long_args[i].name; i++) - fprintf (fp, "\t--%s\n", long_args[i].name); - - fputs (_("Shell options:\n"), fp); - fputs (_("\t-ilrsD or -c command or -O shopt_option\t\t(invocation only)\n"), fp); - - for (i = 0, set_opts = 0; shell_builtins[i].name; i++) - if (STREQ (shell_builtins[i].name, "set")) - { - set_opts = savestring (shell_builtins[i].short_doc); - break; - } - - if (set_opts) - { - s = strchr (set_opts, '['); - if (s == 0) - s = set_opts; - while (*++s == '-') - ; - t = strchr (s, ']'); - if (t) - *t = '\0'; - fprintf (fp, _("\t-%s or -o option\n"), s); - free (set_opts); - } - - if (extra) - { - fprintf (fp, _("Type `%s -c \"help set\"' for more information about shell options.\n"), shell_name); - fprintf (fp, _("Type `%s -c help' for more information about shell builtin commands.\n"), shell_name); - fprintf (fp, _("Use the `bashbug' command to report bugs.\n")); - fprintf (fp, "\n"); - fprintf (fp, _("bash home page: \n")); - fprintf (fp, _("General help using GNU software: \n")); - } -} - -static void -add_shopt_to_alist (opt, on_or_off) - char *opt; - int on_or_off; -{ - if (shopt_ind >= shopt_len) - { - shopt_len += 8; - shopt_alist = (STRING_INT_ALIST *)xrealloc (shopt_alist, shopt_len * sizeof (shopt_alist[0])); - } - shopt_alist[shopt_ind].word = opt; - shopt_alist[shopt_ind].token = on_or_off; - shopt_ind++; -} - -static void -run_shopt_alist () -{ - register int i; - - for (i = 0; i < shopt_ind; i++) - if (shopt_setopt (shopt_alist[i].word, (shopt_alist[i].token == '-')) != EXECUTION_SUCCESS) - exit (EX_BADUSAGE); - free (shopt_alist); - shopt_alist = 0; - shopt_ind = shopt_len = 0; -} diff --git a/third_party/bash/shell.h b/third_party/bash/shell.h deleted file mode 100644 index 6e44bca69..000000000 --- a/third_party/bash/shell.h +++ /dev/null @@ -1,240 +0,0 @@ -/* shell.h -- The data structures used by the shell */ - -/* Copyright (C) 1993-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "bashjmp.h" - -#include "command.h" -#include "syntax.h" -#include "general.h" -#include "error.h" -#include "variables.h" -#include "arrayfunc.h" -#include "quit.h" -#include "maxpath.h" -#include "unwind_prot.h" -#include "dispose_cmd.h" -#include "make_cmd.h" -#include "ocache.h" -#include "subst.h" -#include "sig.h" -#include "pathnames.h" -#include "externs.h" - -extern int EOF_Reached; - -#define NO_PIPE -1 -#define REDIRECT_BOTH -2 - -#define NO_VARIABLE -1 - -/* Values that can be returned by execute_command (). */ -#define EXECUTION_FAILURE 1 -#define EXECUTION_SUCCESS 0 - -/* Usage messages by builtins result in a return status of 2. */ -#define EX_BADUSAGE 2 - -#define EX_MISCERROR 2 - -/* Special exit statuses used by the shell, internally and externally. */ -#define EX_RETRYFAIL 124 -#define EX_WEXPCOMSUB 125 -#define EX_BINARY_FILE 126 -#define EX_NOEXEC 126 -#define EX_NOINPUT 126 -#define EX_NOTFOUND 127 - -#define EX_SHERRBASE 256 /* all special error values are > this. */ - -#define EX_BADSYNTAX 257 /* shell syntax error */ -#define EX_USAGE 258 /* syntax error in usage */ -#define EX_REDIRFAIL 259 /* redirection failed */ -#define EX_BADASSIGN 260 /* variable assignment error */ -#define EX_EXPFAIL 261 /* word expansion failed */ -#define EX_DISKFALLBACK 262 /* fall back to disk command from builtin */ - -/* Flag values that control parameter pattern substitution. */ -#define MATCH_ANY 0x000 -#define MATCH_BEG 0x001 -#define MATCH_END 0x002 - -#define MATCH_TYPEMASK 0x003 - -#define MATCH_GLOBREP 0x010 -#define MATCH_QUOTED 0x020 -#define MATCH_ASSIGNRHS 0x040 -#define MATCH_STARSUB 0x080 -#define MATCH_EXPREP 0x100 /* for pattern substitution, expand replacement */ - -/* Some needed external declarations. */ -extern char **shell_environment; -extern WORD_LIST *rest_of_args; - -/* Generalized global variables. */ -extern char *command_execution_string; - -extern int debugging_mode; -extern int executing, login_shell; -extern int interactive, interactive_shell; -extern int startup_state; -extern int reading_shell_script; -extern int shell_initialized; -extern int bash_argv_initialized; -extern int subshell_environment; -extern int current_command_number; -extern int indirection_level; -extern int shell_compatibility_level; -extern int running_under_emacs; - -extern int posixly_correct; -extern int no_line_editing; - -extern char *shell_name; -extern char *current_host_name; - -extern int subshell_argc; -extern char **subshell_argv; -extern char **subshell_envp; - -/* variables managed using shopt */ -extern int hup_on_exit; -extern int check_jobs_at_exit; -extern int autocd; -extern int check_window_size; - -/* from version.c */ -extern int build_version, patch_level; -extern char *dist_version, *release_status; - -extern int locale_mb_cur_max; -extern int locale_utf8locale; - -/* Structure to pass around that holds a bitmap of file descriptors - to close, and the size of that structure. Used in execute_cmd.c. */ -struct fd_bitmap { - int size; - char *bitmap; -}; - -#define FD_BITMAP_SIZE 32 - -#define CTLESC '\001' -#define CTLNUL '\177' - -/* Information about the current user. */ -struct user_info { - uid_t uid, euid; - gid_t gid, egid; - char *user_name; - char *shell; /* shell from the password file */ - char *home_dir; -}; - -extern struct user_info current_user; - -/* Force gcc to not clobber X on a longjmp(). Old versions of gcc mangle - this badly. */ -#if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ > 8) -# define USE_VAR(x) ((void) &(x)) -#else -# define USE_VAR(x) -#endif - -#define HEREDOC_MAX 16 - -/* Structure in which to save partial parsing state when doing things like - PROMPT_COMMAND and bash_execute_unix_command execution. */ - -typedef struct _sh_parser_state_t -{ - /* parsing state */ - int parser_state; - int *token_state; - - char *token; - size_t token_buffer_size; - int eof_token; - - /* input line state -- line number saved elsewhere */ - int input_line_terminator; - int eof_encountered; - int eol_lookahead; - -#if defined (HANDLE_MULTIBYTE) - /* Nothing right now for multibyte state, but might want something later. */ -#endif - - char **prompt_string_pointer; - - /* history state affecting or modified by the parser */ - int current_command_line_count; -#if defined (HISTORY) - int remember_on_history; - int history_expansion_inhibited; -#endif - - /* execution state possibly modified by the parser */ - int last_command_exit_value; -#if defined (ARRAY_VARS) - ARRAY *pipestatus; -#endif - sh_builtin_func_t *last_shell_builtin, *this_shell_builtin; - - /* flags state affecting the parser */ - int expand_aliases; - int echo_input_at_read; - int need_here_doc; - int here_doc_first_line; - - int esacs_needed; - int expecting_in; - - /* structures affecting the parser */ - void *pushed_strings; - REDIRECT *redir_stack[HEREDOC_MAX]; -} sh_parser_state_t; - -typedef struct _sh_input_line_state_t -{ - char *input_line; - size_t input_line_index; - size_t input_line_size; - size_t input_line_len; -#if defined (HANDLE_MULTIBYTE) - char *input_property; - size_t input_propsize; -#endif -} sh_input_line_state_t; - -/* Let's try declaring these here. */ -extern void shell_ungets PARAMS((char *)); -extern void rewind_input_string PARAMS((void)); - -extern char *parser_remaining_input PARAMS((void)); - -extern sh_parser_state_t *save_parser_state PARAMS((sh_parser_state_t *)); -extern void restore_parser_state PARAMS((sh_parser_state_t *)); - -extern sh_input_line_state_t *save_input_line_state PARAMS((sh_input_line_state_t *)); -extern void restore_input_line_state PARAMS((sh_input_line_state_t *)); diff --git a/third_party/bash/shmatch.c b/third_party/bash/shmatch.c deleted file mode 100644 index dd5a2f802..000000000 --- a/third_party/bash/shmatch.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * shmatch.c -- shell interface to posix regular expression matching. - */ - -/* Copyright (C) 2003-2022 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#if defined (HAVE_POSIX_REGEXP) - -#ifdef HAVE_UNISTD_H -# include -#endif - -#include "bashansi.h" - -#include -#include - -#include "shell.h" -#include "variables.h" -#include "externs.h" - -extern int glob_ignore_case, match_ignore_case; - -#if defined (ARRAY_VARS) -extern SHELL_VAR *builtin_find_indexed_array (char *, int); -#endif - -int -sh_regmatch (string, pattern, flags) - const char *string; - const char *pattern; - int flags; -{ - regex_t regex = { 0 }; - regmatch_t *matches; - int rflags; -#if defined (ARRAY_VARS) - SHELL_VAR *rematch; - ARRAY *amatch; - int subexp_ind; - char *subexp_str; - int subexp_len; -#endif - int result; - -#if defined (ARRAY_VARS) - rematch = (SHELL_VAR *)NULL; -#endif - - rflags = REG_EXTENDED; - if (match_ignore_case) - rflags |= REG_ICASE; -#if !defined (ARRAY_VARS) - rflags |= REG_NOSUB; -#endif - - if (regcomp (®ex, pattern, rflags)) - return 2; /* flag for printing a warning here. */ - -#if defined (ARRAY_VARS) - matches = (regmatch_t *)malloc (sizeof (regmatch_t) * (regex.re_nsub + 1)); -#else - matches = NULL; -#endif - - /* man regexec: NULL PMATCH ignored if NMATCH == 0 */ - if (regexec (®ex, string, matches ? regex.re_nsub + 1 : 0, matches, 0)) - result = EXECUTION_FAILURE; - else - result = EXECUTION_SUCCESS; /* match */ - -#if defined (ARRAY_VARS) - subexp_len = strlen (string) + 10; - subexp_str = malloc (subexp_len + 1); - - /* Store the parenthesized subexpressions in the array BASH_REMATCH. - Element 0 is the portion that matched the entire regexp. Element 1 - is the part that matched the first subexpression, and so on. */ -#if 1 - unbind_global_variable_noref ("BASH_REMATCH"); - rematch = make_new_array_variable ("BASH_REMATCH"); -#else - /* TAG:bash-5.3 */ - rematch = builtin_find_indexed_array ("BASH_REMATCH", 1); -#endif - amatch = rematch ? array_cell (rematch) : (ARRAY *)0; - - if (matches && amatch && (flags & SHMAT_SUBEXP) && result == EXECUTION_SUCCESS && subexp_str) - { - for (subexp_ind = 0; subexp_ind <= regex.re_nsub; subexp_ind++) - { - memset (subexp_str, 0, subexp_len); - strncpy (subexp_str, string + matches[subexp_ind].rm_so, - matches[subexp_ind].rm_eo - matches[subexp_ind].rm_so); - array_insert (amatch, subexp_ind, subexp_str); - } - } - -#if 0 - VSETATTR (rematch, att_readonly); -#endif - - free (subexp_str); - free (matches); -#endif /* ARRAY_VARS */ - - regfree (®ex); - - return result; -} - -#endif /* HAVE_POSIX_REGEXP */ diff --git a/third_party/bash/shmbchar.c b/third_party/bash/shmbchar.c deleted file mode 100644 index 827ee6b39..000000000 --- a/third_party/bash/shmbchar.c +++ /dev/null @@ -1,137 +0,0 @@ -/* Copyright (C) 2001, 2006, 2009, 2010, 2012, 2015-2018 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - - -#include "config.h" - -#if defined (HANDLE_MULTIBYTE) -#include -#include - -#include - -#include "shmbutil.h" -#include "shmbchar.h" - -#ifndef errno -extern int errno; -#endif - -#if IS_BASIC_ASCII - -/* Bit table of characters in the ISO C "basic character set". */ -const unsigned int is_basic_table [UCHAR_MAX / 32 + 1] = -{ - 0x00001a00, /* '\t' '\v' '\f' */ - 0xffffffef, /* ' '...'#' '%'...'?' */ - 0xfffffffe, /* 'A'...'Z' '[' '\\' ']' '^' '_' */ - 0x7ffffffe /* 'a'...'z' '{' '|' '}' '~' */ - /* The remaining bits are 0. */ -}; - -#endif /* IS_BASIC_ASCII */ - -extern int locale_utf8locale; - -extern char *utf8_mbsmbchar (const char *); -extern int utf8_mblen (const char *, size_t); - -/* Count the number of characters in S, counting multi-byte characters as a - single character. */ -size_t -mbstrlen (s) - const char *s; -{ - size_t clen, nc; - mbstate_t mbs = { 0 }, mbsbak = { 0 }; - int f, mb_cur_max; - - nc = 0; - mb_cur_max = MB_CUR_MAX; - while (*s && (clen = (f = is_basic (*s)) ? 1 : mbrlen(s, mb_cur_max, &mbs)) != 0) - { - if (MB_INVALIDCH(clen)) - { - clen = 1; /* assume single byte */ - mbs = mbsbak; - } - - if (f == 0) - mbsbak = mbs; - - s += clen; - nc++; - } - return nc; -} - -/* Return pointer to first multibyte char in S, or NULL if none. */ -/* XXX - if we know that the locale is UTF-8, we can just check whether or - not any byte has the eighth bit turned on */ -char * -mbsmbchar (s) - const char *s; -{ - char *t; - size_t clen; - mbstate_t mbs = { 0 }; - int mb_cur_max; - - if (locale_utf8locale) - return (utf8_mbsmbchar (s)); /* XXX */ - - mb_cur_max = MB_CUR_MAX; - for (t = (char *)s; *t; t++) - { - if (is_basic (*t)) - continue; - - if (locale_utf8locale) /* not used if above code active */ - clen = utf8_mblen (t, mb_cur_max); - else - clen = mbrlen (t, mb_cur_max, &mbs); - - if (clen == 0) - return 0; - if (MB_INVALIDCH(clen)) - continue; - - if (clen > 1) - return t; - } - return 0; -} - -int -sh_mbsnlen(src, srclen, maxlen) - const char *src; - size_t srclen; - int maxlen; -{ - int count; - int sind; - DECLARE_MBSTATE; - - for (sind = count = 0; src[sind]; ) - { - count++; /* number of multibyte characters */ - ADVANCE_CHAR (src, srclen, sind); - if (sind > maxlen) - break; - } - - return count; -} -#endif diff --git a/third_party/bash/shmbchar.h b/third_party/bash/shmbchar.h deleted file mode 100644 index 27b0024fb..000000000 --- a/third_party/bash/shmbchar.h +++ /dev/null @@ -1,112 +0,0 @@ -/* Multibyte character data type. - Copyright (C) 2001, 2005-2007, 2009-2010, 2021 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* Written by Bruno Haible . */ - -#ifndef _SHMBCHAR_H -#define _SHMBCHAR_H 1 - -#if defined (HANDLE_MULTIBYTE) - -#include - -/* Tru64 with Desktop Toolkit C has a bug: must be included before - . - BSD/OS 4.1 has a bug: and must be included before - . */ -#include -#include -#include -#include - - -/* is_basic(c) tests whether the single-byte character c is in the - ISO C "basic character set". */ - -#if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ - && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ - && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ - && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ - && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ - && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ - && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ - && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ - && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ - && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ - && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ - && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ - && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ - && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ - && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ - && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ - && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ - && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ - && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ - && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ - && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ - && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ - && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126) -/* The character set is ISO-646, not EBCDIC. */ -# define IS_BASIC_ASCII 1 - -extern const unsigned int is_basic_table[]; - -static inline int -is_basic (char c) -{ - return (is_basic_table [(unsigned char) c >> 5] >> ((unsigned char) c & 31)) - & 1; -} - -#else - -static inline int -is_basic (char c) -{ - switch (c) - { - case '\b': case '\r': case '\n': - case '\t': case '\v': case '\f': - case ' ': case '!': case '"': case '#': case '%': - case '&': case '\'': case '(': case ')': case '*': - case '+': case ',': case '-': case '.': case '/': - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case ':': case ';': case '<': case '=': case '>': - case '?': - case 'A': case 'B': case 'C': case 'D': case 'E': - case 'F': case 'G': case 'H': case 'I': case 'J': - case 'K': case 'L': case 'M': case 'N': case 'O': - case 'P': case 'Q': case 'R': case 'S': case 'T': - case 'U': case 'V': case 'W': case 'X': case 'Y': - case 'Z': - case '[': case '\\': case ']': case '^': case '_': - case 'a': case 'b': case 'c': case 'd': case 'e': - case 'f': case 'g': case 'h': case 'i': case 'j': - case 'k': case 'l': case 'm': case 'n': case 'o': - case 'p': case 'q': case 'r': case 's': case 't': - case 'u': case 'v': case 'w': case 'x': case 'y': - case 'z': case '{': case '|': case '}': case '~': - return 1; - default: - return 0; - } -} - -#endif - -#endif /* HANDLE_MULTIBYTE */ -#endif /* _SHMBCHAR_H */ diff --git a/third_party/bash/shmbutil.h b/third_party/bash/shmbutil.h deleted file mode 100644 index 68c457a2f..000000000 --- a/third_party/bash/shmbutil.h +++ /dev/null @@ -1,559 +0,0 @@ -/* shmbutil.h -- utility functions for multibyte characters. */ - -/* Copyright (C) 2002-2019 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_SH_MBUTIL_H_) -#define _SH_MBUTIL_H_ - -#include "stdc.h" - -/* Include config.h for HANDLE_MULTIBYTE */ -#include "config.h" - -#if defined (HANDLE_MULTIBYTE) -#include "shmbchar.h" - -extern size_t xwcsrtombs PARAMS((char *, const wchar_t **, size_t, mbstate_t *)); -extern size_t xmbsrtowcs PARAMS((wchar_t *, const char **, size_t, mbstate_t *)); -extern size_t xdupmbstowcs PARAMS((wchar_t **, char ***, const char *)); - -extern size_t mbstrlen PARAMS((const char *)); - -extern char *xstrchr PARAMS((const char *, int)); - -extern int locale_mb_cur_max; /* XXX */ -extern int locale_utf8locale; /* XXX */ - -#ifndef MB_INVALIDCH -#define MB_INVALIDCH(x) ((x) == (size_t)-1 || (x) == (size_t)-2) -#define MB_NULLWCH(x) ((x) == 0) -#endif - -#define MBSLEN(s) (((s) && (s)[0]) ? ((s)[1] ? mbstrlen (s) : 1) : 0) -#define MB_STRLEN(s) ((MB_CUR_MAX > 1) ? MBSLEN (s) : STRLEN (s)) - -#define MBLEN(s, n) ((MB_CUR_MAX > 1) ? mblen ((s), (n)) : 1) -#define MBRLEN(s, n, p) ((MB_CUR_MAX > 1) ? mbrlen ((s), (n), (p)) : 1) - -#define UTF8_SINGLEBYTE(c) (((c) & 0x80) == 0) -#define UTF8_MBFIRSTCHAR(c) (((c) & 0xc0) == 0xc0) -#define UTF8_MBCHAR(c) (((c) & 0xc0) == 0x80) - -#else /* !HANDLE_MULTIBYTE */ - -#undef MB_LEN_MAX -#undef MB_CUR_MAX - -#define MB_LEN_MAX 1 -#define MB_CUR_MAX 1 - -#undef xstrchr -#define xstrchr(s, c) strchr(s, c) - -#ifndef MB_INVALIDCH -#define MB_INVALIDCH(x) (0) -#define MB_NULLWCH(x) (0) -#endif - -#define MB_STRLEN(s) (STRLEN(s)) - -#define MBLEN(s, n) 1 -#define MBRLEN(s, n, p) 1 - -#ifndef wchar_t -# define wchar_t int -#endif - -#define UTF8_SINGLEBYTE(c) (1) -#define UTF8_MBFIRSTCHAR(c) (0) - -#endif /* !HANDLE_MULTIBYTE */ - -/* Declare and initialize a multibyte state. Call must be terminated - with `;'. */ -#if defined (HANDLE_MULTIBYTE) -# define DECLARE_MBSTATE \ - mbstate_t state; \ - memset (&state, '\0', sizeof (mbstate_t)) -#else -# define DECLARE_MBSTATE -#endif /* !HANDLE_MULTIBYTE */ - -/* Initialize or reinitialize a multibyte state named `state'. Call must be - terminated with `;'. */ -#if defined (HANDLE_MULTIBYTE) -# define INITIALIZE_MBSTATE memset (&state, '\0', sizeof (mbstate_t)) -#else -# define INITIALIZE_MBSTATE -#endif /* !HANDLE_MULTIBYTE */ - -/* Advance one (possibly multi-byte) character in string _STR of length - _STRSIZE, starting at index _I. STATE must have already been declared. */ -#if defined (HANDLE_MULTIBYTE) -# define ADVANCE_CHAR(_str, _strsize, _i) \ - do \ - { \ - if (locale_mb_cur_max > 1) \ - { \ - mbstate_t state_bak; \ - size_t mblength; \ - int _f; \ -\ - _f = is_basic ((_str)[_i]); \ - if (_f) \ - mblength = 1; \ - else if (locale_utf8locale && (((_str)[_i] & 0x80) == 0)) \ - mblength = (_str)[_i] != 0; \ - else \ - { \ - state_bak = state; \ - mblength = mbrlen ((_str) + (_i), (_strsize) - (_i), &state); \ - } \ -\ - if (mblength == (size_t)-2 || mblength == (size_t)-1) \ - { \ - state = state_bak; \ - (_i)++; \ - } \ - else if (mblength == 0) \ - (_i)++; \ - else \ - (_i) += mblength; \ - } \ - else \ - (_i)++; \ - } \ - while (0) -#else -# define ADVANCE_CHAR(_str, _strsize, _i) (_i)++ -#endif /* !HANDLE_MULTIBYTE */ - -/* Advance one (possibly multibyte) character in the string _STR of length - _STRSIZE. - SPECIAL: assume that _STR will be incremented by 1 after this call. */ -#if defined (HANDLE_MULTIBYTE) -# define ADVANCE_CHAR_P(_str, _strsize) \ - do \ - { \ - if (locale_mb_cur_max > 1) \ - { \ - mbstate_t state_bak; \ - size_t mblength; \ - int _f; \ -\ - _f = is_basic (*(_str)); \ - if (_f) \ - mblength = 1; \ - else if (locale_utf8locale && ((*(_str) & 0x80) == 0)) \ - mblength = *(_str) != 0; \ - else \ - { \ - state_bak = state; \ - mblength = mbrlen ((_str), (_strsize), &state); \ - } \ -\ - if (mblength == (size_t)-2 || mblength == (size_t)-1) \ - { \ - state = state_bak; \ - mblength = 1; \ - } \ - else \ - (_str) += (mblength < 1) ? 0 : (mblength - 1); \ - } \ - } \ - while (0) -#else -# define ADVANCE_CHAR_P(_str, _strsize) -#endif /* !HANDLE_MULTIBYTE */ - -/* Back up one (possibly multi-byte) character in string _STR of length - _STRSIZE, starting at index _I. STATE must have already been declared. */ -#if defined (HANDLE_MULTIBYTE) -# define BACKUP_CHAR(_str, _strsize, _i) \ - do \ - { \ - if (locale_mb_cur_max > 1) \ - { \ - mbstate_t state_bak; \ - size_t mblength; \ - int _x, _p; /* _x == temp index into string, _p == prev index */ \ -\ - _x = _p = 0; \ - while (_x < (_i)) \ - { \ - state_bak = state; \ - mblength = mbrlen ((_str) + (_x), (_strsize) - (_x), &state); \ -\ - if (mblength == (size_t)-2 || mblength == (size_t)-1) \ - { \ - state = state_bak; \ - _x++; \ - } \ - else if (mblength == 0) \ - _x++; \ - else \ - { \ - _p = _x; /* _p == start of prev mbchar */ \ - _x += mblength; \ - } \ - } \ - (_i) = _p; \ - } \ - else \ - (_i)--; \ - } \ - while (0) -#else -# define BACKUP_CHAR(_str, _strsize, _i) (_i)-- -#endif /* !HANDLE_MULTIBYTE */ - -/* Back up one (possibly multibyte) character in the string _BASE of length - _STRSIZE starting at _STR (_BASE <= _STR <= (_BASE + _STRSIZE) ). - SPECIAL: DO NOT assume that _STR will be decremented by 1 after this call. */ -#if defined (HANDLE_MULTIBYTE) -# define BACKUP_CHAR_P(_base, _strsize, _str) \ - do \ - { \ - if (locale_mb_cur_max > 1) \ - { \ - mbstate_t state_bak; \ - size_t mblength; \ - char *_x, _p; /* _x == temp pointer into string, _p == prev pointer */ \ -\ - _x = _p = _base; \ - while (_x < (_str)) \ - { \ - state_bak = state; \ - mblength = mbrlen (_x, (_strsize) - _x, &state); \ -\ - if (mblength == (size_t)-2 || mblength == (size_t)-1) \ - { \ - state = state_bak; \ - _x++; \ - } \ - else if (mblength == 0) \ - _x++; \ - else \ - { \ - _p = _x; /* _p == start of prev mbchar */ \ - _x += mblength; \ - } \ - } \ - (_str) = _p; \ - } \ - else \ - (_str)--; \ - } \ - while (0) -#else -# define BACKUP_CHAR_P(_base, _strsize, _str) (_str)-- -#endif /* !HANDLE_MULTIBYTE */ - -/* Copy a single character from the string _SRC to the string _DST. - _SRCEND is a pointer to the end of _SRC. */ -#if defined (HANDLE_MULTIBYTE) -# define COPY_CHAR_P(_dst, _src, _srcend) \ - do \ - { \ - if (locale_mb_cur_max > 1) \ - { \ - mbstate_t state_bak; \ - size_t mblength; \ - int _k; \ -\ - _k = is_basic (*(_src)); \ - if (_k) \ - mblength = 1; \ - else if (locale_utf8locale && ((*(_src) & 0x80) == 0)) \ - mblength = *(_src) != 0; \ - else \ - { \ - state_bak = state; \ - mblength = mbrlen ((_src), (_srcend) - (_src), &state); \ - } \ - if (mblength == (size_t)-2 || mblength == (size_t)-1) \ - { \ - state = state_bak; \ - mblength = 1; \ - } \ - else \ - mblength = (mblength < 1) ? 1 : mblength; \ -\ - for (_k = 0; _k < mblength; _k++) \ - *(_dst)++ = *(_src)++; \ - } \ - else \ - *(_dst)++ = *(_src)++; \ - } \ - while (0) -#else -# define COPY_CHAR_P(_dst, _src, _srcend) *(_dst)++ = *(_src)++ -#endif /* !HANDLE_MULTIBYTE */ - -/* Copy a single character from the string _SRC at index _SI to the string - _DST at index _DI. _SRCEND is a pointer to the end of _SRC. */ -#if defined (HANDLE_MULTIBYTE) -# define COPY_CHAR_I(_dst, _di, _src, _srcend, _si) \ - do \ - { \ - if (locale_mb_cur_max > 1) \ - { \ - mbstate_t state_bak; \ - size_t mblength; \ - int _k; \ -\ - _k = is_basic ((_src)[(_si)]); \ - if (_k) \ - mblength = 1; \ - else if (locale_utf8locale && ((_src)[(_si)] & 0x80) == 0) \ - mblength = (_src)[(_si)] != 0; \ - else \ - {\ - state_bak = state; \ - mblength = mbrlen ((_src) + (_si), (_srcend) - ((_src)+(_si)), &state); \ - } \ - if (mblength == (size_t)-2 || mblength == (size_t)-1) \ - { \ - state = state_bak; \ - mblength = 1; \ - } \ - else \ - mblength = (mblength < 1) ? 1 : mblength; \ -\ - for (_k = 0; _k < mblength; _k++) \ - _dst[_di++] = _src[_si++]; \ - } \ - else \ - _dst[_di++] = _src[_si++]; \ - } \ - while (0) -#else -# define COPY_CHAR_I(_dst, _di, _src, _srcend, _si) _dst[_di++] = _src[_si++] -#endif /* !HANDLE_MULTIBYTE */ - -/**************************************************************** - * * - * The following are only guaranteed to work in subst.c * - * * - ****************************************************************/ - -#if defined (HANDLE_MULTIBYTE) -# define SCOPY_CHAR_I(_dst, _escchar, _sc, _src, _si, _slen) \ - do \ - { \ - if (locale_mb_cur_max > 1) \ - { \ - mbstate_t state_bak; \ - size_t mblength; \ - int _i; \ -\ - _i = is_basic ((_src)[(_si)]); \ - if (_i) \ - mblength = 1; \ - else if (locale_utf8locale && ((_src)[(_si)] & 0x80) == 0) \ - mblength = (_src)[(_si)] != 0; \ - else \ - { \ - state_bak = state; \ - mblength = mbrlen ((_src) + (_si), (_slen) - (_si), &state); \ - } \ - if (mblength == (size_t)-2 || mblength == (size_t)-1) \ - { \ - state = state_bak; \ - mblength = 1; \ - } \ - else \ - mblength = (mblength < 1) ? 1 : mblength; \ -\ - temp = xmalloc (mblength + 2); \ - temp[0] = _escchar; \ - for (_i = 0; _i < mblength; _i++) \ - temp[_i + 1] = _src[_si++]; \ - temp[mblength + 1] = '\0'; \ -\ - goto add_string; \ - } \ - else \ - { \ - _dst[0] = _escchar; \ - _dst[1] = _sc; \ - } \ - } \ - while (0) -#else -# define SCOPY_CHAR_I(_dst, _escchar, _sc, _src, _si, _slen) \ - _dst[0] = _escchar; \ - _dst[1] = _sc -#endif /* !HANDLE_MULTIBYTE */ - -#if defined (HANDLE_MULTIBYTE) -# define SCOPY_CHAR_M(_dst, _src, _srcend, _si) \ - do \ - { \ - if (locale_mb_cur_max > 1) \ - { \ - mbstate_t state_bak; \ - size_t mblength; \ - int _i; \ -\ - _i = is_basic (*((_src) + (_si))); \ - if (_i) \ - mblength = 1; \ - else if (locale_utf8locale && (((_src)[_si] & 0x80) == 0)) \ - mblength = (_src)[_si] != 0; \ - else \ - { \ - state_bak = state; \ - mblength = mbrlen ((_src) + (_si), (_srcend) - ((_src) + (_si)), &state); \ - } \ - if (mblength == (size_t)-2 || mblength == (size_t)-1) \ - { \ - state = state_bak; \ - mblength = 1; \ - } \ - else \ - mblength = (mblength < 1) ? 1 : mblength; \ -\ - FASTCOPY(((_src) + (_si)), (_dst), mblength); \ -\ - (_dst) += mblength; \ - (_si) += mblength; \ - } \ - else \ - { \ - *(_dst)++ = _src[(_si)]; \ - (_si)++; \ - } \ - } \ - while (0) -#else -# define SCOPY_CHAR_M(_dst, _src, _srcend, _si) \ - *(_dst)++ = _src[(_si)]; \ - (_si)++ -#endif /* !HANDLE_MULTIBYTE */ - -#if HANDLE_MULTIBYTE -# define SADD_MBCHAR(_dst, _src, _si, _srcsize) \ - do \ - { \ - if (locale_mb_cur_max > 1) \ - { \ - int i; \ - mbstate_t state_bak; \ - size_t mblength; \ -\ - i = is_basic (*((_src) + (_si))); \ - if (i) \ - mblength = 1; \ - else if (locale_utf8locale && (((_src)[_si] & 0x80) == 0)) \ - mblength = (_src)[_si] != 0; \ - else \ - { \ - state_bak = state; \ - mblength = mbrlen ((_src) + (_si), (_srcsize) - (_si), &state); \ - } \ - if (mblength == (size_t)-1 || mblength == (size_t)-2) \ - { \ - state = state_bak; \ - mblength = 1; \ - } \ - if (mblength < 1) \ - mblength = 1; \ -\ - _dst = (char *)xmalloc (mblength + 1); \ - for (i = 0; i < mblength; i++) \ - (_dst)[i] = (_src)[(_si)++]; \ - (_dst)[mblength] = '\0'; \ -\ - goto add_string; \ - } \ - } \ - while (0) - -#else -# define SADD_MBCHAR(_dst, _src, _si, _srcsize) -#endif - -/* Watch out when using this -- it's just straight textual substitution */ -#if defined (HANDLE_MULTIBYTE) -# define SADD_MBQCHAR_BODY(_dst, _src, _si, _srcsize) \ -\ - int i; \ - mbstate_t state_bak; \ - size_t mblength; \ -\ - i = is_basic (*((_src) + (_si))); \ - if (i) \ - mblength = 1; \ - else if (locale_utf8locale && (((_src)[_si] & 0x80) == 0)) \ - mblength = (_src)[_si] != 0; \ - else \ - { \ - state_bak = state; \ - mblength = mbrlen ((_src) + (_si), (_srcsize) - (_si), &state); \ - } \ - if (mblength == (size_t)-1 || mblength == (size_t)-2) \ - { \ - state = state_bak; \ - mblength = 1; \ - } \ - if (mblength < 1) \ - mblength = 1; \ -\ - (_dst) = (char *)xmalloc (mblength + 2); \ - (_dst)[0] = CTLESC; \ - for (i = 0; i < mblength; i++) \ - (_dst)[i+1] = (_src)[(_si)++]; \ - (_dst)[mblength+1] = '\0'; \ -\ - goto add_string - -# define SADD_MBCHAR_BODY(_dst, _src, _si, _srcsize) \ -\ - int i; \ - mbstate_t state_bak; \ - size_t mblength; \ -\ - i = is_basic (*((_src) + (_si))); \ - if (i) \ - mblength = 1; \ - else if (locale_utf8locale && (((_src)[_si] & 0x80) == 0)) \ - mblength = (_src)[_si] != 0; \ - else \ - { \ - state_bak = state; \ - mblength = mbrlen ((_src) + (_si), (_srcsize) - (_si), &state); \ - } \ - if (mblength == (size_t)-1 || mblength == (size_t)-2) \ - { \ - state = state_bak; \ - mblength = 1; \ - } \ - if (mblength < 1) \ - mblength = 1; \ -\ - (_dst) = (char *)xmalloc (mblength + 1); \ - for (i = 0; i < mblength; i++) \ - (_dst)[i+1] = (_src)[(_si)++]; \ - (_dst)[mblength+1] = '\0'; \ -\ - goto add_string - -#endif /* HANDLE_MULTIBYTE */ -#endif /* _SH_MBUTIL_H_ */ diff --git a/third_party/bash/shquote.c b/third_party/bash/shquote.c deleted file mode 100644 index 59436c65f..000000000 --- a/third_party/bash/shquote.c +++ /dev/null @@ -1,432 +0,0 @@ -/* shquote - functions to quote and dequote strings */ - -/* Copyright (C) 1999-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include -#include "stdc.h" - -#include "syntax.h" -#include "xmalloc.h" - -#include "shmbchar.h" -#include "shmbutil.h" - -extern char *ansic_quote PARAMS((char *, int, int *)); -extern int ansic_shouldquote PARAMS((const char *)); - -/* Default set of characters that should be backslash-quoted in strings */ -static const char bstab[256] = - { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, 0, /* TAB, NL */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - - 1, 1, 1, 0, 1, 0, 1, 1, /* SPACE, !, DQUOTE, DOL, AMP, SQUOTE */ - 1, 1, 1, 0, 1, 0, 0, 0, /* LPAR, RPAR, STAR, COMMA */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 0, 1, 1, /* SEMI, LESSTHAN, GREATERTHAN, QUEST */ - - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 1, 0, /* LBRACK, BS, RBRACK, CARAT */ - - 1, 0, 0, 0, 0, 0, 0, 0, /* BACKQ */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 0, 0, /* LBRACE, BAR, RBRACE */ - - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }; - -/* **************************************************************** */ -/* */ -/* Functions for quoting strings to be re-read as input */ -/* */ -/* **************************************************************** */ - -/* Return a new string which is the single-quoted version of STRING. - Used by alias and trap, among others. */ -char * -sh_single_quote (string) - const char *string; -{ - register int c; - char *result, *r; - const char *s; - - result = (char *)xmalloc (3 + (4 * strlen (string))); - r = result; - - if (string[0] == '\'' && string[1] == 0) - { - *r++ = '\\'; - *r++ = '\''; - *r++ = 0; - return result; - } - - *r++ = '\''; - - for (s = string; s && (c = *s); s++) - { - *r++ = c; - - if (c == '\'') - { - *r++ = '\\'; /* insert escaped single quote */ - *r++ = '\''; - *r++ = '\''; /* start new quoted string */ - } - } - - *r++ = '\''; - *r = '\0'; - - return (result); -} - -/* Quote STRING using double quotes. Return a new string. */ -char * -sh_double_quote (string) - const char *string; -{ - register unsigned char c; - int mb_cur_max; - char *result, *r; - size_t slen; - const char *s, *send; - DECLARE_MBSTATE; - - slen = strlen (string); - send = string + slen; - mb_cur_max = MB_CUR_MAX; - - result = (char *)xmalloc (3 + (2 * strlen (string))); - r = result; - *r++ = '"'; - - for (s = string; s && (c = *s); s++) - { - /* Backslash-newline disappears within double quotes, so don't add one. */ - if ((sh_syntaxtab[c] & CBSDQUOTE) && c != '\n') - *r++ = '\\'; - -#if defined (HANDLE_MULTIBYTE) - if ((locale_utf8locale && (c & 0x80)) || - (locale_utf8locale == 0 && mb_cur_max > 1 && is_basic (c) == 0)) - { - COPY_CHAR_P (r, s, send); - s--; /* compensate for auto-increment in loop above */ - continue; - } -#endif - - /* Assume that the string will not be further expanded, so no need to - add CTLESC to protect CTLESC or CTLNUL. */ - *r++ = c; - } - - *r++ = '"'; - *r = '\0'; - - return (result); -} - -/* Turn S into a simple double-quoted string. If FLAGS is non-zero, quote - double quote characters in S with backslashes. */ -char * -sh_mkdoublequoted (s, slen, flags) - const char *s; - int slen, flags; -{ - char *r, *ret; - const char *send; - int rlen, mb_cur_max; - DECLARE_MBSTATE; - - send = s + slen; - mb_cur_max = flags ? MB_CUR_MAX : 1; - rlen = (flags == 0) ? slen + 3 : (2 * slen) + 1; - ret = r = (char *)xmalloc (rlen); - - *r++ = '"'; - while (*s) - { - if (flags && *s == '"') - *r++ = '\\'; - -#if defined (HANDLE_MULTIBYTE) - if (flags && ((locale_utf8locale && (*s & 0x80)) || - (locale_utf8locale == 0 && mb_cur_max > 1 && is_basic (*s) == 0))) - { - COPY_CHAR_P (r, s, send); - continue; - } -#endif - *r++ = *s++; - } - *r++ = '"'; - *r = '\0'; - - return ret; -} - -/* Remove backslashes that are quoting characters that are special between - double quotes. Return a new string. XXX - should this handle CTLESC - and CTLNUL? */ -char * -sh_un_double_quote (string) - char *string; -{ - register int c, pass_next; - char *result, *r, *s; - - r = result = (char *)xmalloc (strlen (string) + 1); - - for (pass_next = 0, s = string; s && (c = *s); s++) - { - if (pass_next) - { - *r++ = c; - pass_next = 0; - continue; - } - if (c == '\\' && (sh_syntaxtab[(unsigned char) s[1]] & CBSDQUOTE)) - { - pass_next = 1; - continue; - } - *r++ = c; - } - - *r = '\0'; - return result; -} - -/* Quote special characters in STRING using backslashes. Return a new - string. NOTE: if the string is to be further expanded, we need a - way to protect the CTLESC and CTLNUL characters. As I write this, - the current callers will never cause the string to be expanded without - going through the shell parser, which will protect the internal - quoting characters. TABLE, if set, points to a map of the ascii code - set with char needing to be backslash-quoted if table[char]==1. FLAGS, - if 1, causes tildes to be quoted as well. If FLAGS&2, backslash-quote - other shell blank characters. */ - -char * -sh_backslash_quote (string, table, flags) - char *string; - char *table; - int flags; -{ - int c, mb_cur_max; - size_t slen; - char *result, *r, *s, *backslash_table, *send; - DECLARE_MBSTATE; - - slen = strlen (string); - send = string + slen; - result = (char *)xmalloc (2 * slen + 1); - - backslash_table = table ? table : (char *)bstab; - mb_cur_max = MB_CUR_MAX; - - for (r = result, s = string; s && (c = *s); s++) - { -#if defined (HANDLE_MULTIBYTE) - /* XXX - isascii, even if is_basic(c) == 0 - works in most cases. */ - if (c >= 0 && c <= 127 && backslash_table[(unsigned char)c] == 1) - { - *r++ = '\\'; - *r++ = c; - continue; - } - if ((locale_utf8locale && (c & 0x80)) || - (locale_utf8locale == 0 && mb_cur_max > 1 && is_basic (c) == 0)) - { - COPY_CHAR_P (r, s, send); - s--; /* compensate for auto-increment in loop above */ - continue; - } -#endif - if (backslash_table[(unsigned char)c] == 1) - *r++ = '\\'; - else if (c == '#' && s == string) /* comment char */ - *r++ = '\\'; - else if ((flags&1) && c == '~' && (s == string || s[-1] == ':' || s[-1] == '=')) - /* Tildes are special at the start of a word or after a `:' or `=' - (technically unquoted, but it doesn't make a difference in practice) */ - *r++ = '\\'; - else if ((flags&2) && shellblank((unsigned char)c)) - *r++ = '\\'; - *r++ = c; - } - - *r = '\0'; - return (result); -} - -#if defined (PROMPT_STRING_DECODE) || defined (TRANSLATABLE_STRINGS) -/* Quote characters that get special treatment when in double quotes in STRING - using backslashes. FLAGS is reserved for future use. Return a new string. */ -char * -sh_backslash_quote_for_double_quotes (string, flags) - char *string; - int flags; -{ - unsigned char c; - char *result, *r, *s, *send; - size_t slen; - int mb_cur_max; - DECLARE_MBSTATE; - - slen = strlen (string); - send = string + slen; - mb_cur_max = MB_CUR_MAX; - result = (char *)xmalloc (2 * slen + 1); - - for (r = result, s = string; s && (c = *s); s++) - { - /* Backslash-newline disappears within double quotes, so don't add one. */ - if ((sh_syntaxtab[c] & CBSDQUOTE) && c != '\n') - *r++ = '\\'; - /* I should probably use the CSPECL flag for these in sh_syntaxtab[] */ - else if (c == CTLESC || c == CTLNUL) - *r++ = CTLESC; /* could be '\\'? */ - -#if defined (HANDLE_MULTIBYTE) - if ((locale_utf8locale && (c & 0x80)) || - (locale_utf8locale == 0 && mb_cur_max > 1 && is_basic (c) == 0)) - { - COPY_CHAR_P (r, s, send); - s--; /* compensate for auto-increment in loop above */ - continue; - } -#endif - - *r++ = c; - } - - *r = '\0'; - return (result); -} -#endif /* PROMPT_STRING_DECODE */ - -char * -sh_quote_reusable (s, flags) - char *s; - int flags; -{ - char *ret; - - if (s == 0) - return s; - else if (*s == 0) - { - ret = (char *)xmalloc (3); - ret[0] = ret[1] = '\''; - ret[2] = '\0'; - } - else if (ansic_shouldquote (s)) - ret = ansic_quote (s, 0, (int *)0); - else if (flags) - ret = sh_backslash_quote (s, 0, 1); - else - ret = sh_single_quote (s); - - return ret; -} - -int -sh_contains_shell_metas (string) - const char *string; -{ - const char *s; - - for (s = string; s && *s; s++) - { - switch (*s) - { - case ' ': case '\t': case '\n': /* IFS white space */ - case '\'': case '"': case '\\': /* quoting chars */ - case '|': case '&': case ';': /* shell metacharacters */ - case '(': case ')': case '<': case '>': - case '!': case '{': case '}': /* reserved words */ - case '*': case '[': case '?': case ']': /* globbing chars */ - case '^': - case '$': case '`': /* expansion chars */ - return (1); - case '~': /* tilde expansion */ - if (s == string || s[-1] == '=' || s[-1] == ':') - return (1); - break; - case '#': - if (s == string) /* comment char */ - return (1); - /* FALLTHROUGH */ - default: - break; - } - } - - return (0); -} - -int -sh_contains_quotes (string) - const char *string; -{ - const char *s; - - for (s = string; s && *s; s++) - { - if (*s == '\'' || *s == '"' || *s == '\\') - return 1; - } - return 0; -} diff --git a/third_party/bash/shtty.c b/third_party/bash/shtty.c deleted file mode 100644 index 461e574d4..000000000 --- a/third_party/bash/shtty.c +++ /dev/null @@ -1,330 +0,0 @@ -/* - * shtty.c -- abstract interface to the terminal, focusing on capabilities. - */ - -/* Copyright (C) 1999 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#ifdef HAVE_UNISTD_H -# include -#endif - -#include "shtty.h" - -static TTYSTRUCT ttin, ttout; -static int ttsaved = 0; - -int -ttgetattr(fd, ttp) -int fd; -TTYSTRUCT *ttp; -{ -#ifdef TERMIOS_TTY_DRIVER - return tcgetattr(fd, ttp); -#else -# ifdef TERMIO_TTY_DRIVER - return ioctl(fd, TCGETA, ttp); -# else - return ioctl(fd, TIOCGETP, ttp); -# endif -#endif -} - -int -ttsetattr(fd, ttp) -int fd; -TTYSTRUCT *ttp; -{ -#ifdef TERMIOS_TTY_DRIVER - return tcsetattr(fd, TCSADRAIN, ttp); -#else -# ifdef TERMIO_TTY_DRIVER - return ioctl(fd, TCSETAW, ttp); -# else - return ioctl(fd, TIOCSETN, ttp); -# endif -#endif -} - -void -ttsave() -{ - if (ttsaved) - return; - ttgetattr (0, &ttin); - ttgetattr (1, &ttout); - ttsaved = 1; -} - -void -ttrestore() -{ - if (ttsaved == 0) - return; - ttsetattr (0, &ttin); - ttsetattr (1, &ttout); - ttsaved = 0; -} - -/* Retrieve the internally-saved attributes associated with tty fd FD. */ -TTYSTRUCT * -ttattr (fd) - int fd; -{ - if (ttsaved == 0) - return ((TTYSTRUCT *)0); - if (fd == 0) - return &ttin; - else if (fd == 1) - return &ttout; - else - return ((TTYSTRUCT *)0); -} - -/* - * Change attributes in ttp so that when it is installed using - * ttsetattr, the terminal will be in one-char-at-a-time mode. - */ -int -tt_setonechar(ttp) - TTYSTRUCT *ttp; -{ -#if defined (TERMIOS_TTY_DRIVER) || defined (TERMIO_TTY_DRIVER) - - /* XXX - might not want this -- it disables erase and kill processing. */ - ttp->c_lflag &= ~ICANON; - - ttp->c_lflag |= ISIG; -# ifdef IEXTEN - ttp->c_lflag |= IEXTEN; -# endif - - ttp->c_iflag |= ICRNL; /* make sure we get CR->NL on input */ - ttp->c_iflag &= ~INLCR; /* but no NL->CR */ - -# ifdef OPOST - ttp->c_oflag |= OPOST; -# endif -# ifdef ONLCR - ttp->c_oflag |= ONLCR; -# endif -# ifdef OCRNL - ttp->c_oflag &= ~OCRNL; -# endif -# ifdef ONOCR - ttp->c_oflag &= ~ONOCR; -# endif -# ifdef ONLRET - ttp->c_oflag &= ~ONLRET; -# endif - - ttp->c_cc[VMIN] = 1; - ttp->c_cc[VTIME] = 0; - -#else - - ttp->sg_flags |= CBREAK; - -#endif - - return 0; -} - -/* Set the tty associated with FD and TTP into one-character-at-a-time mode */ -int -ttfd_onechar (fd, ttp) - int fd; - TTYSTRUCT *ttp; -{ - if (tt_setonechar(ttp) < 0) - return -1; - return (ttsetattr (fd, ttp)); -} - -/* Set the terminal into one-character-at-a-time mode */ -int -ttonechar () -{ - TTYSTRUCT tt; - - if (ttsaved == 0) - return -1; - tt = ttin; - return (ttfd_onechar (0, &tt)); -} - -/* - * Change attributes in ttp so that when it is installed using - * ttsetattr, the terminal will be in no-echo mode. - */ -int -tt_setnoecho(ttp) - TTYSTRUCT *ttp; -{ -#if defined (TERMIOS_TTY_DRIVER) || defined (TERMIO_TTY_DRIVER) - ttp->c_lflag &= ~(ECHO|ECHOK|ECHONL); -#else - ttp->sg_flags &= ~ECHO; -#endif - - return 0; -} - -/* Set the tty associated with FD and TTP into no-echo mode */ -int -ttfd_noecho (fd, ttp) - int fd; - TTYSTRUCT *ttp; -{ - if (tt_setnoecho (ttp) < 0) - return -1; - return (ttsetattr (fd, ttp)); -} - -/* Set the terminal into no-echo mode */ -int -ttnoecho () -{ - TTYSTRUCT tt; - - if (ttsaved == 0) - return -1; - tt = ttin; - return (ttfd_noecho (0, &tt)); -} - -/* - * Change attributes in ttp so that when it is installed using - * ttsetattr, the terminal will be in eight-bit mode (pass8). - */ -int -tt_seteightbit (ttp) - TTYSTRUCT *ttp; -{ -#if defined (TERMIOS_TTY_DRIVER) || defined (TERMIO_TTY_DRIVER) - ttp->c_iflag &= ~ISTRIP; - ttp->c_cflag |= CS8; - ttp->c_cflag &= ~PARENB; -#else - ttp->sg_flags |= ANYP; -#endif - - return 0; -} - -/* Set the tty associated with FD and TTP into eight-bit mode */ -int -ttfd_eightbit (fd, ttp) - int fd; - TTYSTRUCT *ttp; -{ - if (tt_seteightbit (ttp) < 0) - return -1; - return (ttsetattr (fd, ttp)); -} - -/* Set the terminal into eight-bit mode */ -int -tteightbit () -{ - TTYSTRUCT tt; - - if (ttsaved == 0) - return -1; - tt = ttin; - return (ttfd_eightbit (0, &tt)); -} - -/* - * Change attributes in ttp so that when it is installed using - * ttsetattr, the terminal will be in non-canonical input mode. - */ -int -tt_setnocanon (ttp) - TTYSTRUCT *ttp; -{ -#if defined (TERMIOS_TTY_DRIVER) || defined (TERMIO_TTY_DRIVER) - ttp->c_lflag &= ~ICANON; -#endif - - return 0; -} - -/* Set the tty associated with FD and TTP into non-canonical mode */ -int -ttfd_nocanon (fd, ttp) - int fd; - TTYSTRUCT *ttp; -{ - if (tt_setnocanon (ttp) < 0) - return -1; - return (ttsetattr (fd, ttp)); -} - -/* Set the terminal into non-canonical mode */ -int -ttnocanon () -{ - TTYSTRUCT tt; - - if (ttsaved == 0) - return -1; - tt = ttin; - return (ttfd_nocanon (0, &tt)); -} - -/* - * Change attributes in ttp so that when it is installed using - * ttsetattr, the terminal will be in cbreak, no-echo mode. - */ -int -tt_setcbreak(ttp) - TTYSTRUCT *ttp; -{ - if (tt_setonechar (ttp) < 0) - return -1; - return (tt_setnoecho (ttp)); -} - -/* Set the tty associated with FD and TTP into cbreak (no-echo, - one-character-at-a-time) mode */ -int -ttfd_cbreak (fd, ttp) - int fd; - TTYSTRUCT *ttp; -{ - if (tt_setcbreak (ttp) < 0) - return -1; - return (ttsetattr (fd, ttp)); -} - -/* Set the terminal into cbreak (no-echo, one-character-at-a-time) mode */ -int -ttcbreak () -{ - TTYSTRUCT tt; - - if (ttsaved == 0) - return -1; - tt = ttin; - return (ttfd_cbreak (0, &tt)); -} diff --git a/third_party/bash/shtty.h b/third_party/bash/shtty.h deleted file mode 100644 index fdf379b89..000000000 --- a/third_party/bash/shtty.h +++ /dev/null @@ -1,112 +0,0 @@ -/* Copyright (C) 1999-2020 Free Software Foundation, Inc. */ - -/* This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -/* - * shtty.h -- include the correct system-dependent files to manipulate the - * tty - */ - -#ifndef __SH_TTY_H_ -#define __SH_TTY_H_ - -#include "stdc.h" - -#if defined (_POSIX_VERSION) && defined (HAVE_TERMIOS_H) && defined (HAVE_TCGETATTR) && !defined (TERMIOS_MISSING) -# define TERMIOS_TTY_DRIVER -#else -# if defined (HAVE_TERMIO_H) -# define TERMIO_TTY_DRIVER -# else -# define NEW_TTY_DRIVER -# endif -#endif - -/* - * The _POSIX_SOURCE define is to avoid multiple symbol definitions - * between sys/ioctl.h and termios.h. Ditto for the test against SunOS4 - * and the undefining of several symbols. - */ - -#ifdef TERMIOS_TTY_DRIVER -# if (defined (SunOS4) || defined (SunOS5)) && !defined (_POSIX_SOURCE) -# define _POSIX_SOURCE -# endif -# if defined (SunOS4) -# undef ECHO -# undef NOFLSH -# undef TOSTOP -# endif /* SunOS4 */ -# include -# define TTYSTRUCT struct termios -#else -# ifdef TERMIO_TTY_DRIVER -# include -# define TTYSTRUCT struct termio -# else /* NEW_TTY_DRIVER */ -# include -# define TTYSTRUCT struct sgttyb -# endif -#endif - -/* Functions imported from lib/sh/shtty.c */ - -/* Get and set terminal attributes for the file descriptor passed as - an argument. */ -extern int ttgetattr PARAMS((int, TTYSTRUCT *)); -extern int ttsetattr PARAMS((int, TTYSTRUCT *)); - -/* Save and restore the terminal's attributes from static storage. */ -extern void ttsave PARAMS((void)); -extern void ttrestore PARAMS((void)); - -/* Return the attributes corresponding to the file descriptor (0 or 1) - passed as an argument. */ -extern TTYSTRUCT *ttattr PARAMS((int)); - -/* These functions only operate on the passed TTYSTRUCT; they don't - actually change anything with the kernel's current tty settings. */ -extern int tt_setonechar PARAMS((TTYSTRUCT *)); -extern int tt_setnoecho PARAMS((TTYSTRUCT *)); -extern int tt_seteightbit PARAMS((TTYSTRUCT *)); -extern int tt_setnocanon PARAMS((TTYSTRUCT *)); -extern int tt_setcbreak PARAMS((TTYSTRUCT *)); - -/* These functions are all generally mutually exclusive. If you call - more than one (bracketed with calls to ttsave and ttrestore, of - course), the right thing will happen, but more system calls will be - executed than absolutely necessary. You can do all of this yourself - with the other functions; these are only conveniences. */ - -/* These functions work with a given file descriptor and set terminal - attributes */ -extern int ttfd_onechar PARAMS((int, TTYSTRUCT *)); -extern int ttfd_noecho PARAMS((int, TTYSTRUCT *)); -extern int ttfd_eightbit PARAMS((int, TTYSTRUCT *)); -extern int ttfd_nocanon PARAMS((int, TTYSTRUCT *)); - -extern int ttfd_cbreak PARAMS((int, TTYSTRUCT *)); - -/* These functions work with fd 0 and the TTYSTRUCT saved with ttsave () */ -extern int ttonechar PARAMS((void)); -extern int ttnoecho PARAMS((void)); -extern int tteightbit PARAMS((void)); -extern int ttnocanon PARAMS((void)); - -extern int ttcbreak PARAMS((void)); - -#endif diff --git a/third_party/bash/sig.c b/third_party/bash/sig.c deleted file mode 100644 index 6c0615d73..000000000 --- a/third_party/bash/sig.c +++ /dev/null @@ -1,817 +0,0 @@ -/* sig.c - interface for shell signal handlers and signal initialization. */ - -/* Copyright (C) 1994-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include "bashtypes.h" - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include -#include - -#include "bashintl.h" - -#include "shell.h" -#include "execute_cmd.h" -#if defined (JOB_CONTROL) -#include "jobs.h" -#endif /* JOB_CONTROL */ -#include "siglist.h" -#include "sig.h" -#include "trap.h" - -#include "common.h" -#include "builtext.h" - -#if defined (READLINE) -# include "bashline.h" -# include "third_party/readline/readline.h" -#endif - -#if defined (HISTORY) -# include "bashhist.h" -#endif - -extern void initialize_siglist PARAMS((void)); -extern void set_original_signal PARAMS((int, SigHandler *)); - -#if !defined (JOB_CONTROL) -extern void initialize_job_signals PARAMS((void)); -#endif - -/* Non-zero after SIGINT. */ -volatile sig_atomic_t interrupt_state = 0; - -/* Non-zero after SIGWINCH */ -volatile sig_atomic_t sigwinch_received = 0; - -/* Non-zero after SIGTERM */ -volatile sig_atomic_t sigterm_received = 0; - -/* Set to the value of any terminating signal received. */ -volatile sig_atomic_t terminating_signal = 0; - -/* The environment at the top-level R-E loop. We use this in - the case of error return. */ -procenv_t top_level; - -#if defined (JOB_CONTROL) || defined (HAVE_POSIX_SIGNALS) -/* The signal masks that this shell runs with. */ -sigset_t top_level_mask; -#endif /* JOB_CONTROL */ - -/* When non-zero, we throw_to_top_level (). */ -int interrupt_immediately = 0; - -/* When non-zero, we call the terminating signal handler immediately. */ -int terminate_immediately = 0; - -#if defined (SIGWINCH) -static SigHandler *old_winch = (SigHandler *)SIG_DFL; -#endif - -static void initialize_shell_signals PARAMS((void)); - -void -initialize_signals (reinit) - int reinit; -{ - initialize_shell_signals (); - initialize_job_signals (); -#if !defined (HAVE_SYS_SIGLIST) && !defined (HAVE_UNDER_SYS_SIGLIST) && !defined (HAVE_STRSIGNAL) - if (reinit == 0) - initialize_siglist (); -#endif /* !HAVE_SYS_SIGLIST && !HAVE_UNDER_SYS_SIGLIST && !HAVE_STRSIGNAL */ -} - -/* A structure describing a signal that terminates the shell if not - caught. The orig_handler member is present so children can reset - these signals back to their original handlers. */ -struct termsig { - int signum; - SigHandler *orig_handler; - int orig_flags; - int core_dump; -}; - -#define NULL_HANDLER (SigHandler *)SIG_DFL - -/* The list of signals that would terminate the shell if not caught. - We catch them, but just so that we can write the history file, - and so forth. */ -static struct termsig terminating_signals[] = { -#ifdef SIGHUP -{ SIGHUP, NULL_HANDLER, 0 }, -#endif - -#ifdef SIGINT -{ SIGINT, NULL_HANDLER, 0 }, -#endif - -#ifdef SIGILL -{ SIGILL, NULL_HANDLER, 0, 1}, -#endif - -#ifdef SIGTRAP -{ SIGTRAP, NULL_HANDLER, 0, 1 }, -#endif - -#ifdef SIGIOT -{ SIGIOT, NULL_HANDLER, 0, 1 }, -#endif - -#ifdef SIGDANGER -{ SIGDANGER, NULL_HANDLER, 0 }, -#endif - -#ifdef SIGEMT -{ SIGEMT, NULL_HANDLER, 0 }, -#endif - -#ifdef SIGFPE -{ SIGFPE, NULL_HANDLER, 0, 1 }, -#endif - -#ifdef SIGBUS -{ SIGBUS, NULL_HANDLER, 0, 1 }, -#endif - -#ifdef SIGSEGV -{ SIGSEGV, NULL_HANDLER, 0, 1 }, -#endif - -#ifdef SIGSYS -{ SIGSYS, NULL_HANDLER, 0, 1 }, -#endif - -#ifdef SIGPIPE -{ SIGPIPE, NULL_HANDLER, 0 }, -#endif - -#ifdef SIGALRM -{ SIGALRM, NULL_HANDLER, 0 }, -#endif - -#ifdef SIGTERM -{ SIGTERM, NULL_HANDLER, 0 }, -#endif - -/* These don't generate core dumps on anything but Linux, but we're doing - this just for Linux anyway. */ -#ifdef SIGXCPU -{ SIGXCPU, NULL_HANDLER, 0, 1 }, -#endif - -#ifdef SIGXFSZ -{ SIGXFSZ, NULL_HANDLER, 0, 1 }, -#endif - -#ifdef SIGVTALRM -{ SIGVTALRM, NULL_HANDLER, 0 }, -#endif - -#if 0 -#ifdef SIGPROF -{ SIGPROF, NULL_HANDLER, 0 }, -#endif -#endif - -#ifdef SIGLOST -{ SIGLOST, NULL_HANDLER, 0 }, -#endif - -#ifdef SIGUSR1 -{ SIGUSR1, NULL_HANDLER, 0 }, -#endif - -#ifdef SIGUSR2 -{ SIGUSR2, NULL_HANDLER, 0 }, -#endif -}; - -#define TERMSIGS_LENGTH (sizeof (terminating_signals) / sizeof (struct termsig)) - -#define XSIG(x) (terminating_signals[x].signum) -#define XHANDLER(x) (terminating_signals[x].orig_handler) -#define XSAFLAGS(x) (terminating_signals[x].orig_flags) -#define XCOREDUMP(x) (terminating_signals[x].core_dump) - -static int termsigs_initialized = 0; - -/* Initialize signals that will terminate the shell to do some - unwind protection. For non-interactive shells, we only call - this when a trap is defined for EXIT (0) or when trap is run - to display signal dispositions. */ -void -initialize_terminating_signals () -{ - register int i; -#if defined (HAVE_POSIX_SIGNALS) - struct sigaction act, oact; -#endif - - if (termsigs_initialized) - return; - - /* The following code is to avoid an expensive call to - set_signal_handler () for each terminating_signals. Fortunately, - this is possible in Posix. Unfortunately, we have to call signal () - on non-Posix systems for each signal in terminating_signals. */ -#if defined (HAVE_POSIX_SIGNALS) - act.sa_handler = termsig_sighandler; - act.sa_flags = 0; - sigemptyset (&act.sa_mask); - sigemptyset (&oact.sa_mask); - for (i = 0; i < TERMSIGS_LENGTH; i++) - sigaddset (&act.sa_mask, XSIG (i)); - for (i = 0; i < TERMSIGS_LENGTH; i++) - { - /* If we've already trapped it, don't do anything. */ - if (signal_is_trapped (XSIG (i))) - continue; - - sigaction (XSIG (i), &act, &oact); - XHANDLER(i) = oact.sa_handler; - XSAFLAGS(i) = oact.sa_flags; - -#if 0 - set_original_signal (XSIG(i), XHANDLER(i)); /* optimization */ -#else - set_original_signal (XSIG(i), act.sa_handler); /* optimization */ -#endif - - /* Don't do anything with signals that are ignored at shell entry - if the shell is not interactive. */ - /* XXX - should we do this for interactive shells, too? */ - if (interactive_shell == 0 && XHANDLER (i) == SIG_IGN) - { - sigaction (XSIG (i), &oact, &act); - set_signal_hard_ignored (XSIG (i)); - } -#if defined (SIGPROF) && !defined (_MINIX) - if (XSIG (i) == SIGPROF && XHANDLER (i) != SIG_DFL && XHANDLER (i) != SIG_IGN) - sigaction (XSIG (i), &oact, (struct sigaction *)NULL); -#endif /* SIGPROF && !_MINIX */ - } -#else /* !HAVE_POSIX_SIGNALS */ - - for (i = 0; i < TERMSIGS_LENGTH; i++) - { - /* If we've already trapped it, don't do anything. */ - if (signal_is_trapped (XSIG (i))) - continue; - - XHANDLER(i) = signal (XSIG (i), termsig_sighandler); - XSAFLAGS(i) = 0; - /* Don't do anything with signals that are ignored at shell entry - if the shell is not interactive. */ - /* XXX - should we do this for interactive shells, too? */ - if (interactive_shell == 0 && XHANDLER (i) == SIG_IGN) - { - signal (XSIG (i), SIG_IGN); - set_signal_hard_ignored (XSIG (i)); - } -#ifdef SIGPROF - if (XSIG (i) == SIGPROF && XHANDLER (i) != SIG_DFL && XHANDLER (i) != SIG_IGN) - signal (XSIG (i), XHANDLER (i)); -#endif - } - -#endif /* !HAVE_POSIX_SIGNALS */ - - termsigs_initialized = 1; -} - -static void -initialize_shell_signals () -{ - if (interactive) - initialize_terminating_signals (); - -#if defined (JOB_CONTROL) || defined (HAVE_POSIX_SIGNALS) - /* All shells use the signal mask they inherit, and pass it along - to child processes. Children will never block SIGCHLD, though. */ - sigemptyset (&top_level_mask); - sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &top_level_mask); -# if defined (SIGCHLD) - if (sigismember (&top_level_mask, SIGCHLD)) - { - sigdelset (&top_level_mask, SIGCHLD); - sigprocmask (SIG_SETMASK, &top_level_mask, (sigset_t *)NULL); - } -# endif -#endif /* JOB_CONTROL || HAVE_POSIX_SIGNALS */ - - /* And, some signals that are specifically ignored by the shell. */ - set_signal_handler (SIGQUIT, SIG_IGN); - - if (interactive) - { - set_signal_handler (SIGINT, sigint_sighandler); - get_original_signal (SIGTERM); - set_signal_handler (SIGTERM, SIG_IGN); - set_sigwinch_handler (); - } -} - -void -reset_terminating_signals () -{ - register int i; -#if defined (HAVE_POSIX_SIGNALS) - struct sigaction act; -#endif - - if (termsigs_initialized == 0) - return; - -#if defined (HAVE_POSIX_SIGNALS) - act.sa_flags = 0; - sigemptyset (&act.sa_mask); - for (i = 0; i < TERMSIGS_LENGTH; i++) - { - /* Skip a signal if it's trapped or handled specially, because the - trap code will restore the correct value. */ - if (signal_is_trapped (XSIG (i)) || signal_is_special (XSIG (i))) - continue; - - act.sa_handler = XHANDLER (i); - act.sa_flags = XSAFLAGS (i); - sigaction (XSIG (i), &act, (struct sigaction *) NULL); - } -#else /* !HAVE_POSIX_SIGNALS */ - for (i = 0; i < TERMSIGS_LENGTH; i++) - { - if (signal_is_trapped (XSIG (i)) || signal_is_special (XSIG (i))) - continue; - - signal (XSIG (i), XHANDLER (i)); - } -#endif /* !HAVE_POSIX_SIGNALS */ - - termsigs_initialized = 0; -} -#undef XHANDLER - -/* Run some of the cleanups that should be performed when we run - jump_to_top_level from a builtin command context. XXX - might want to - also call reset_parser here. */ -void -top_level_cleanup () -{ - /* Clean up string parser environment. */ - while (parse_and_execute_level) - parse_and_execute_cleanup (-1); - -#if defined (PROCESS_SUBSTITUTION) - unlink_fifo_list (); -#endif /* PROCESS_SUBSTITUTION */ - - run_unwind_protects (); - loop_level = continuing = breaking = funcnest = 0; - executing_list = comsub_ignore_return = return_catch_flag = wait_intr_flag = 0; -} - -/* What to do when we've been interrupted, and it is safe to handle it. */ -void -throw_to_top_level () -{ - int print_newline = 0; - - if (interrupt_state) - { - if (last_command_exit_value < 128) - last_command_exit_value = 128 + SIGINT; - set_pipestatus_from_exit (last_command_exit_value); - print_newline = 1; - DELINTERRUPT; - } - - if (interrupt_state) - return; - - last_command_exit_signal = (last_command_exit_value > 128) ? - (last_command_exit_value - 128) : 0; - last_command_exit_value |= 128; - set_pipestatus_from_exit (last_command_exit_value); - - /* Run any traps set on SIGINT, mostly for interactive shells */ - if (signal_is_trapped (SIGINT) && signal_is_pending (SIGINT)) - run_interrupt_trap (1); - - /* Clean up string parser environment. */ - while (parse_and_execute_level) - parse_and_execute_cleanup (-1); - - if (running_trap > 0) - { - run_trap_cleanup (running_trap - 1); - running_trap = 0; - } - -#if defined (JOB_CONTROL) - give_terminal_to (shell_pgrp, 0); -#endif /* JOB_CONTROL */ - - /* This needs to stay because jobs.c:make_child() uses it without resetting - the signal mask. */ - restore_sigmask (); - - reset_parser (); - -#if defined (READLINE) - if (interactive) - bashline_reset (); -#endif /* READLINE */ - -#if defined (PROCESS_SUBSTITUTION) - unlink_fifo_list (); -#endif /* PROCESS_SUBSTITUTION */ - - run_unwind_protects (); - loop_level = continuing = breaking = funcnest = 0; - executing_list = comsub_ignore_return = return_catch_flag = wait_intr_flag = 0; - - if (interactive && print_newline) - { - fflush (stdout); - fprintf (stderr, "\n"); - fflush (stderr); - } - - /* An interrupted `wait' command in a script does not exit the script. */ - if (interactive || (interactive_shell && !shell_initialized) || - (print_newline && signal_is_trapped (SIGINT))) - jump_to_top_level (DISCARD); - else - jump_to_top_level (EXITPROG); -} - -/* This is just here to isolate the longjmp calls. */ -void -jump_to_top_level (value) - int value; -{ - sh_longjmp (top_level, value); -} - -void -restore_sigmask () -{ -#if defined (JOB_CONTROL) || defined (HAVE_POSIX_SIGNALS) - sigprocmask (SIG_SETMASK, &top_level_mask, (sigset_t *)NULL); -#endif -} - -sighandler -termsig_sighandler (sig) - int sig; -{ - /* If we get called twice with the same signal before handling it, - terminate right away. */ - if ( -#ifdef SIGHUP - sig != SIGHUP && -#endif -#ifdef SIGINT - sig != SIGINT && -#endif -#ifdef SIGDANGER - sig != SIGDANGER && -#endif -#ifdef SIGPIPE - sig != SIGPIPE && -#endif -#ifdef SIGALRM - sig != SIGALRM && -#endif -#ifdef SIGTERM - sig != SIGTERM && -#endif -#ifdef SIGXCPU - sig != SIGXCPU && -#endif -#ifdef SIGXFSZ - sig != SIGXFSZ && -#endif -#ifdef SIGVTALRM - sig != SIGVTALRM && -#endif -#ifdef SIGLOST - sig != SIGLOST && -#endif -#ifdef SIGUSR1 - sig != SIGUSR1 && -#endif -#ifdef SIGUSR2 - sig != SIGUSR2 && -#endif - sig == terminating_signal) - terminate_immediately = 1; - - terminating_signal = sig; - - if (terminate_immediately) - { -#if defined (HISTORY) - /* XXX - will inhibit history file being written */ -# if defined (READLINE) - if (interactive_shell == 0 || interactive == 0 || (sig != SIGHUP && sig != SIGTERM) || no_line_editing || (RL_ISSTATE (RL_STATE_READCMD) == 0)) -# endif - history_lines_this_session = 0; -#endif - terminate_immediately = 0; - termsig_handler (sig); - } - -#if defined (READLINE) - /* Set the event hook so readline will call it after the signal handlers - finish executing, so if this interrupted character input we can get - quick response. If readline is active or has modified the terminal we - need to set this no matter what the signal is, though the check for - RL_STATE_TERMPREPPED is possibly redundant. */ - if (RL_ISSTATE (RL_STATE_SIGHANDLER) || RL_ISSTATE (RL_STATE_TERMPREPPED)) - bashline_set_event_hook (); -#endif - - SIGRETURN (0); -} - -void -termsig_handler (sig) - int sig; -{ - static int handling_termsig = 0; - int i, core; - sigset_t mask; - - /* Simple semaphore to keep this function from being executed multiple - times. Since we no longer are running as a signal handler, we don't - block multiple occurrences of the terminating signals while running. */ - if (handling_termsig) - return; - handling_termsig = 1; - terminating_signal = 0; /* keep macro from re-testing true. */ - - /* I don't believe this condition ever tests true. */ - if (sig == SIGINT && signal_is_trapped (SIGINT)) - run_interrupt_trap (0); - -#if defined (HISTORY) - /* If we don't do something like this, the history will not be saved when - an interactive shell is running in a terminal window that gets closed - with the `close' button. We can't test for RL_STATE_READCMD because - readline no longer handles SIGTERM synchronously. */ - if (interactive_shell && interactive && (sig == SIGHUP || sig == SIGTERM) && remember_on_history) - maybe_save_shell_history (); -#endif /* HISTORY */ - - if (this_shell_builtin == read_builtin) - read_tty_cleanup (); - -#if defined (JOB_CONTROL) - if (sig == SIGHUP && (interactive || (subshell_environment & (SUBSHELL_COMSUB|SUBSHELL_PROCSUB)))) - hangup_all_jobs (); - - if ((subshell_environment & (SUBSHELL_COMSUB|SUBSHELL_PROCSUB)) == 0) - end_job_control (); -#endif /* JOB_CONTROL */ - -#if defined (PROCESS_SUBSTITUTION) - unlink_all_fifos (); -# if defined (JOB_CONTROL) - procsub_clear (); -# endif -#endif /* PROCESS_SUBSTITUTION */ - - /* Reset execution context */ - loop_level = continuing = breaking = funcnest = 0; - executing_list = comsub_ignore_return = return_catch_flag = wait_intr_flag = 0; - - run_exit_trap (); /* XXX - run exit trap possibly in signal context? */ - - /* We don't change the set of blocked signals. If a user starts the shell - with a terminating signal blocked, we won't get here (and if by some - magic chance we do, we'll exit below). What we do is to restore the - top-level signal mask, in case this is called from a terminating signal - handler context, in which case the signal is blocked. */ - restore_sigmask (); - - set_signal_handler (sig, SIG_DFL); - - kill (getpid (), sig); - - if (dollar_dollar_pid != 1) - exit (128+sig); /* just in case the kill fails? */ - - /* We get here only under extraordinary circumstances. */ - - /* We are PID 1, and the kill above failed to kill the process. We assume - this means that we are running as an init process in a pid namespace - on Linux. In this case, we can't send ourselves a fatal signal, so we - determine whether or not we should have generated a core dump with the - kill call and attempt to trick the kernel into generating one if - necessary. */ - sigprocmask (SIG_SETMASK, (sigset_t *)NULL, &mask); - for (i = core = 0; i < TERMSIGS_LENGTH; i++) - { - set_signal_handler (XSIG (i), SIG_DFL); - sigdelset (&mask, XSIG (i)); - if (sig == XSIG (i)) - core = XCOREDUMP (i); - } - sigprocmask (SIG_SETMASK, &mask, (sigset_t *)NULL); - - if (core) - *((volatile unsigned long *) NULL) = 0xdead0000 + sig; /* SIGSEGV */ - - exit (128+sig); -} -#undef XSIG - -/* What we really do when SIGINT occurs. */ -sighandler -sigint_sighandler (sig) - int sig; -{ -#if defined (MUST_REINSTALL_SIGHANDLERS) - signal (sig, sigint_sighandler); -#endif - - /* interrupt_state needs to be set for the stack of interrupts to work - right. Should it be set unconditionally? */ - if (interrupt_state == 0) - ADDINTERRUPT; - - /* We will get here in interactive shells with job control active; allow - an interactive wait to be interrupted. wait_intr_flag is only set during - the execution of the wait builtin and when wait_intr_buf is valid. */ - if (wait_intr_flag) - { - last_command_exit_value = 128 + sig; - set_pipestatus_from_exit (last_command_exit_value); - wait_signal_received = sig; - SIGRETURN (0); - } - - /* In interactive shells, we will get here instead of trap_handler() so - note that we have a trap pending. */ - if (signal_is_trapped (sig)) - set_trap_state (sig); - - /* This is no longer used, but this code block remains as a reminder. */ - if (interrupt_immediately) - { - interrupt_immediately = 0; - set_exit_status (128 + sig); - throw_to_top_level (); - } -#if defined (READLINE) - /* Set the event hook so readline will call it after the signal handlers - finish executing, so if this interrupted character input we can get - quick response. */ - else if (RL_ISSTATE (RL_STATE_SIGHANDLER)) - bashline_set_event_hook (); -#endif - - SIGRETURN (0); -} - -#if defined (SIGWINCH) -sighandler -sigwinch_sighandler (sig) - int sig; -{ -#if defined (MUST_REINSTALL_SIGHANDLERS) - set_signal_handler (SIGWINCH, sigwinch_sighandler); -#endif /* MUST_REINSTALL_SIGHANDLERS */ - sigwinch_received = 1; - SIGRETURN (0); -} -#endif /* SIGWINCH */ - -void -set_sigwinch_handler () -{ -#if defined (SIGWINCH) - old_winch = set_signal_handler (SIGWINCH, sigwinch_sighandler); -#endif -} - -void -unset_sigwinch_handler () -{ -#if defined (SIGWINCH) - set_signal_handler (SIGWINCH, old_winch); -#endif -} - -sighandler -sigterm_sighandler (sig) - int sig; -{ - sigterm_received = 1; /* XXX - counter? */ - SIGRETURN (0); -} - -/* Signal functions used by the rest of the code. */ -#if !defined (HAVE_POSIX_SIGNALS) - -/* Perform OPERATION on NEWSET, perhaps leaving information in OLDSET. */ -sigprocmask (operation, newset, oldset) - int operation, *newset, *oldset; -{ - int old, new; - - if (newset) - new = *newset; - else - new = 0; - - switch (operation) - { - case SIG_BLOCK: - old = sigblock (new); - break; - - case SIG_SETMASK: - old = sigsetmask (new); - break; - - default: - internal_error (_("sigprocmask: %d: invalid operation"), operation); - } - - if (oldset) - *oldset = old; -} - -#else - -#if !defined (SA_INTERRUPT) -# define SA_INTERRUPT 0 -#endif - -#if !defined (SA_RESTART) -# define SA_RESTART 0 -#endif - -SigHandler * -set_signal_handler (sig, handler) - int sig; - SigHandler *handler; -{ - struct sigaction act, oact; - - act.sa_handler = handler; - act.sa_flags = 0; - - /* XXX - bash-4.2 */ - /* We don't want a child death to interrupt interruptible system calls, even - if we take the time to reap children */ -#if defined (SIGCHLD) - if (sig == SIGCHLD) - act.sa_flags |= SA_RESTART; /* XXX */ -#endif - /* Let's see if we can keep SIGWINCH from interrupting interruptible system - calls, like open(2)/read(2)/write(2) */ -#if defined (SIGWINCH) - if (sig == SIGWINCH) - act.sa_flags |= SA_RESTART; /* XXX */ -#endif - /* If we're installing a SIGTERM handler for interactive shells, we want - it to be as close to SIG_IGN as possible. */ - if (sig == SIGTERM && handler == sigterm_sighandler) - act.sa_flags |= SA_RESTART; /* XXX */ - - sigemptyset (&act.sa_mask); - sigemptyset (&oact.sa_mask); - if (sigaction (sig, &act, &oact) == 0) - return (oact.sa_handler); - else - return (SIG_DFL); -} -#endif /* HAVE_POSIX_SIGNALS */ diff --git a/third_party/bash/sig.h b/third_party/bash/sig.h deleted file mode 100644 index 0217be53d..000000000 --- a/third_party/bash/sig.h +++ /dev/null @@ -1,136 +0,0 @@ -/* sig.h -- header file for signal handler definitions. */ - -/* Copyright (C) 1994-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -/* Make sure that this is included *after* config.h! */ - -#if !defined (_SIG_H_) -# define _SIG_H_ - -#include "stdc.h" - -#include /* for sig_atomic_t */ - -#if !defined (SIGABRT) && defined (SIGIOT) -# define SIGABRT SIGIOT -#endif - -#define sighandler void -typedef void SigHandler PARAMS((int)); - -#define SIGRETURN(n) return - -/* Here is a definition for set_signal_handler () which simply expands to - a call to signal () for non-Posix systems. The code for set_signal_handler - in the Posix case resides in general.c. */ -#if !defined (HAVE_POSIX_SIGNALS) -# define set_signal_handler(sig, handler) (SigHandler *)signal (sig, handler) -#else -extern SigHandler *set_signal_handler PARAMS((int, SigHandler *)); /* in sig.c */ -#endif /* _POSIX_VERSION */ - -#if !defined (SIGCHLD) && defined (SIGCLD) -# define SIGCHLD SIGCLD -#endif - -#if !defined (HAVE_POSIX_SIGNALS) && !defined (sigmask) -# define sigmask(x) (1 << ((x)-1)) -#endif /* !HAVE_POSIX_SIGNALS && !sigmask */ - -#if !defined (HAVE_POSIX_SIGNALS) -# if !defined (SIG_BLOCK) -# define SIG_BLOCK 2 -# define SIG_SETMASK 3 -# endif /* SIG_BLOCK */ - -/* sigset_t defined in config.h */ - -/* Make sure there is nothing inside the signal set. */ -# define sigemptyset(set) (*(set) = 0) - -/* Initialize the signal set to hold all signals. */ -# define sigfillset(set) (*set) = sigmask (NSIG) - 1 - -/* Add SIG to the contents of SET. */ -# define sigaddset(set, sig) *(set) |= sigmask (sig) - -/* Delete SIG from signal set SET. */ -# define sigdelset(set, sig) *(set) &= ~sigmask (sig) - -/* Is SIG a member of the signal set SET? */ -# define sigismember(set, sig) ((*(set) & sigmask (sig)) != 0) - -/* Suspend the process until the reception of one of the signals - not present in SET. */ -# define sigsuspend(set) sigpause (*(set)) -#endif /* !HAVE_POSIX_SIGNALS */ - -/* These definitions are used both in POSIX and non-POSIX implementations. */ - -#define BLOCK_SIGNAL(sig, nvar, ovar) \ -do { \ - sigemptyset (&nvar); \ - sigaddset (&nvar, sig); \ - sigemptyset (&ovar); \ - sigprocmask (SIG_BLOCK, &nvar, &ovar); \ -} while (0) - -#define UNBLOCK_SIGNAL(ovar) sigprocmask (SIG_SETMASK, &ovar, (sigset_t *) NULL) - -#if defined (HAVE_POSIX_SIGNALS) -# define BLOCK_CHILD(nvar, ovar) BLOCK_SIGNAL (SIGCHLD, nvar, ovar) -# define UNBLOCK_CHILD(ovar) UNBLOCK_SIGNAL(ovar) -#else /* !HAVE_POSIX_SIGNALS */ -# define BLOCK_CHILD(nvar, ovar) ovar = sigblock (sigmask (SIGCHLD)) -# define UNBLOCK_CHILD(ovar) sigsetmask (ovar) -#endif /* !HAVE_POSIX_SIGNALS */ - -/* Extern variables */ -extern volatile sig_atomic_t sigwinch_received; -extern volatile sig_atomic_t sigterm_received; - -extern int interrupt_immediately; /* no longer used */ -extern int terminate_immediately; - -/* Functions from sig.c. */ -extern sighandler termsig_sighandler PARAMS((int)); -extern void termsig_handler PARAMS((int)); -extern sighandler sigint_sighandler PARAMS((int)); -extern void initialize_signals PARAMS((int)); -extern void initialize_terminating_signals PARAMS((void)); -extern void reset_terminating_signals PARAMS((void)); -extern void top_level_cleanup PARAMS((void)); -extern void throw_to_top_level PARAMS((void)); -extern void jump_to_top_level PARAMS((int)) __attribute__((__noreturn__)); -extern void restore_sigmask PARAMS((void)); - -extern sighandler sigwinch_sighandler PARAMS((int)); -extern void set_sigwinch_handler PARAMS((void)); -extern void unset_sigwinch_handler PARAMS((void)); - -extern sighandler sigterm_sighandler PARAMS((int)); - -/* Functions defined in trap.c. */ -extern SigHandler *set_sigint_handler PARAMS((void)); -extern SigHandler *trap_to_sighandler PARAMS((int)); -extern sighandler trap_handler PARAMS((int)); - -extern int block_trapped_signals PARAMS((sigset_t *, sigset_t *)); -extern int unblock_trapped_signals PARAMS((sigset_t *)); -#endif /* _SIG_H_ */ diff --git a/third_party/bash/siglist.h b/third_party/bash/siglist.h deleted file mode 100644 index 321c20c46..000000000 --- a/third_party/bash/siglist.h +++ /dev/null @@ -1,44 +0,0 @@ -/* siglist.h -- encapsulate various definitions for sys_siglist */ - -/* Copyright (C) 1993, 2001, 2005, 2008-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_SIGLIST_H_) -#define _SIGLIST_H_ - -#if !defined (SYS_SIGLIST_DECLARED) && !defined (HAVE_STRSIGNAL) - -#if defined (HAVE_UNDER_SYS_SIGLIST) && !defined (HAVE_SYS_SIGLIST) && !defined (sys_siglist) -# define sys_siglist _sys_siglist -#endif /* HAVE_UNDER_SYS_SIGLIST && !HAVE_SYS_SIGLIST && !sys_siglist */ - -#if !defined (sys_siglist) -extern char *sys_siglist[]; -#endif /* !sys_siglist */ - -#endif /* !SYS_SIGLIST_DECLARED && !HAVE_STRSIGNAL */ - -#if !defined (strsignal) && !defined (HAVE_STRSIGNAL) -# define strsignal(sig) (char *)sys_siglist[sig] -#endif /* !strsignal && !HAVE_STRSIGNAL */ - -#if !defined (strsignal) && !HAVE_DECL_STRSIGNAL -extern char *strsignal PARAMS((int)); -#endif - -#endif /* _SIGLIST_H */ diff --git a/third_party/bash/signames.c b/third_party/bash/signames.c deleted file mode 100644 index 391482893..000000000 --- a/third_party/bash/signames.c +++ /dev/null @@ -1,446 +0,0 @@ -/* signames.c -- Create an array of signal names. */ - -/* Copyright (C) 2006-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include - -#include -#include - -#if defined (HAVE_STDLIB_H) -# include -#else -# include "ansi_stdlib.h" -#endif /* HAVE_STDLIB_H */ - -#if !defined (NSIG) -# define NSIG 64 -#endif - -/* - * Special traps: - * EXIT == 0 - * DEBUG == NSIG - * ERR == NSIG+1 - * RETURN == NSIG+2 - */ -#define LASTSIG NSIG+2 - -char *signal_names[2 * (LASTSIG)]; - -#define signal_names_size (sizeof(signal_names)/sizeof(signal_names[0])) - -/* AIX 4.3 defines SIGRTMIN and SIGRTMAX as 888 and 999 respectively. - I don't want to allocate so much unused space for the intervening signal - numbers, so we just punt if SIGRTMAX is past the bounds of the - signal_names array (handled in configure). */ -#if defined (SIGRTMAX) && defined (UNUSABLE_RT_SIGNALS) -# undef SIGRTMAX -# undef SIGRTMIN -#endif - -#if defined (SIGRTMAX) || defined (SIGRTMIN) -# define RTLEN 14 -# define RTLIM 256 -#endif - -#if defined (BUILDTOOL) -extern char *progname; -#endif - -void -initialize_signames () -{ - register int i; -#if defined (SIGRTMAX) || defined (SIGRTMIN) - int rtmin, rtmax, rtcnt; -#endif - - for (i = 1; i < signal_names_size; i++) - signal_names[i] = (char *)NULL; - - /* `signal' 0 is what we do on exit. */ - signal_names[0] = "EXIT"; - - /* Place signal names which can be aliases for more common signal - names first. This allows (for example) SIGABRT to overwrite SIGLOST. */ - - /* POSIX 1003.1b-1993 real time signals, but take care of incomplete - implementations. According to the standard, both SIGRTMIN and - SIGRTMAX must be defined, SIGRTMIN must be strictly less than - SIGRTMAX, and the difference must be at least 7; that is, there - must be at least eight distinct real time signals. */ - - /* The generated signal names are SIGRTMIN, SIGRTMIN+1, ..., - SIGRTMIN+x, SIGRTMAX-x, ..., SIGRTMAX-1, SIGRTMAX. If the number - of RT signals is odd, there is an extra SIGRTMIN+(x+1). - These names are the ones used by ksh and /usr/xpg4/bin/sh on SunOS5. */ - -#if defined (SIGRTMIN) - rtmin = SIGRTMIN; - signal_names[rtmin] = "SIGRTMIN"; -#endif - -#if defined (SIGRTMAX) - rtmax = SIGRTMAX; - signal_names[rtmax] = "SIGRTMAX"; -#endif - -#if defined (SIGRTMAX) && defined (SIGRTMIN) - if (rtmax > rtmin) - { - rtcnt = (rtmax - rtmin - 1) / 2; - /* croak if there are too many RT signals */ - if (rtcnt >= RTLIM/2) - { - rtcnt = RTLIM/2-1; -#ifdef BUILDTOOL - fprintf(stderr, "%s: error: more than %d real time signals, fix `%s'\n", - progname, RTLIM, progname); -#endif - } - - for (i = 1; i <= rtcnt; i++) - { - signal_names[rtmin+i] = (char *)malloc(RTLEN); - if (signal_names[rtmin+i]) - sprintf (signal_names[rtmin+i], "SIGRTMIN+%d", i); - signal_names[rtmax-i] = (char *)malloc(RTLEN); - if (signal_names[rtmax-i]) - sprintf (signal_names[rtmax-i], "SIGRTMAX-%d", i); - } - - if (rtcnt < RTLIM/2-1 && rtcnt != (rtmax-rtmin)/2) - { - /* Need an extra RTMIN signal */ - signal_names[rtmin+rtcnt+1] = (char *)malloc(RTLEN); - if (signal_names[rtmin+rtcnt+1]) - sprintf (signal_names[rtmin+rtcnt+1], "SIGRTMIN+%d", rtcnt+1); - } - } -#endif /* SIGRTMIN && SIGRTMAX */ - -#if defined (SIGLOST) /* resource lost (eg, record-lock lost) */ - signal_names[SIGLOST] = "SIGLOST"; -#endif - -/* AIX */ -#if defined (SIGMSG) /* HFT input data pending */ - signal_names[SIGMSG] = "SIGMSG"; -#endif - -#if defined (SIGDANGER) /* system crash imminent */ - signal_names[SIGDANGER] = "SIGDANGER"; -#endif - -#if defined (SIGMIGRATE) /* migrate process to another CPU */ - signal_names[SIGMIGRATE] = "SIGMIGRATE"; -#endif - -#if defined (SIGPRE) /* programming error */ - signal_names[SIGPRE] = "SIGPRE"; -#endif - -#if defined (SIGPHONE) /* Phone interrupt */ - signal_names[SIGPHONE] = "SIGPHONE"; -#endif - -#if defined (SIGVIRT) /* AIX virtual time alarm */ - signal_names[SIGVIRT] = "SIGVIRT"; -#endif - -#if defined (SIGTINT) /* Interrupt */ - signal_names[SIGTINT] = "SIGTINT"; -#endif - -#if defined (SIGALRM1) /* m:n condition variables */ - signal_names[SIGALRM1] = "SIGALRM1"; -#endif - -#if defined (SIGWAITING) /* m:n scheduling */ - signal_names[SIGWAITING] = "SIGWAITING"; -#endif - -#if defined (SIGGRANT) /* HFT monitor mode granted */ - signal_names[SIGGRANT] = "SIGGRANT"; -#endif - -#if defined (SIGKAP) /* keep alive poll from native keyboard */ - signal_names[SIGKAP] = "SIGKAP"; -#endif - -#if defined (SIGRETRACT) /* HFT monitor mode retracted */ - signal_names[SIGRETRACT] = "SIGRETRACT"; -#endif - -#if defined (SIGSOUND) /* HFT sound sequence has completed */ - signal_names[SIGSOUND] = "SIGSOUND"; -#endif - -#if defined (SIGSAK) /* Secure Attention Key */ - signal_names[SIGSAK] = "SIGSAK"; -#endif - -#if defined (SIGCPUFAIL) /* Predictive processor deconfiguration */ - signal_names[SIGCPUFAIL] = "SIGCPUFAIL"; -#endif - -#if defined (SIGAIO) /* Asynchronous I/O */ - signal_names[SIGAIO] = "SIGAIO"; -#endif - -#if defined (SIGLAB) /* Security label changed */ - signal_names[SIGLAB] = "SIGLAB"; -#endif - -/* SunOS5 */ -#if defined (SIGLWP) /* Solaris: special signal used by thread library */ - signal_names[SIGLWP] = "SIGLWP"; -#endif - -#if defined (SIGFREEZE) /* Solaris: special signal used by CPR */ - signal_names[SIGFREEZE] = "SIGFREEZE"; -#endif - -#if defined (SIGTHAW) /* Solaris: special signal used by CPR */ - signal_names[SIGTHAW] = "SIGTHAW"; -#endif - -#if defined (SIGCANCEL) /* Solaris: thread cancellation signal used by libthread */ - signal_names[SIGCANCEL] = "SIGCANCEL"; -#endif - -#if defined (SIGXRES) /* Solaris: resource control exceeded */ - signal_names[SIGXRES] = "SIGXRES"; -#endif - -#if defined (SIGJVM1) /* Solaris: Java Virtual Machine 1 */ - signal_names[SIGJVM1] = "SIGJVM1"; -#endif - -#if defined (SIGJVM2) /* Solaris: Java Virtual Machine 2 */ - signal_names[SIGJVM2] = "SIGJVM2"; -#endif - -#if defined (SIGDGTIMER1) - signal_names[SIGDGTIMER1] = "SIGDGTIMER1"; -#endif - -#if defined (SIGDGTIMER2) - signal_names[SIGDGTIMER2] = "SIGDGTIMER2"; -#endif - -#if defined (SIGDGTIMER3) - signal_names[SIGDGTIMER3] = "SIGDGTIMER3"; -#endif - -#if defined (SIGDGTIMER4) - signal_names[SIGDGTIMER4] = "SIGDGTIMER4"; -#endif - -#if defined (SIGDGNOTIFY) - signal_names[SIGDGNOTIFY] = "SIGDGNOTIFY"; -#endif - -/* Apollo */ -#if defined (SIGAPOLLO) - signal_names[SIGAPOLLO] = "SIGAPOLLO"; -#endif - -/* HP-UX */ -#if defined (SIGDIL) /* DIL signal (?) */ - signal_names[SIGDIL] = "SIGDIL"; -#endif - -/* System V */ -#if defined (SIGCLD) /* Like SIGCHLD. */ - signal_names[SIGCLD] = "SIGCLD"; -#endif - -#if defined (SIGPWR) /* power state indication */ - signal_names[SIGPWR] = "SIGPWR"; -#endif - -#if defined (SIGPOLL) /* Pollable event (for streams) */ - signal_names[SIGPOLL] = "SIGPOLL"; -#endif - -/* Unknown */ -#if defined (SIGWINDOW) - signal_names[SIGWINDOW] = "SIGWINDOW"; -#endif - -/* Linux */ -#if defined (SIGSTKFLT) - signal_names[SIGSTKFLT] = "SIGSTKFLT"; -#endif - -/* FreeBSD */ -#if defined (SIGTHR) /* thread interrupt */ - signal_names[SIGTHR] = "SIGTHR"; -#endif - -/* Common */ -#if defined (SIGHUP) /* hangup */ - signal_names[SIGHUP] = "SIGHUP"; -#endif - -#if defined (SIGINT) /* interrupt */ - signal_names[SIGINT] = "SIGINT"; -#endif - -#if defined (SIGQUIT) /* quit */ - signal_names[SIGQUIT] = "SIGQUIT"; -#endif - -#if defined (SIGILL) /* illegal instruction (not reset when caught) */ - signal_names[SIGILL] = "SIGILL"; -#endif - -#if defined (SIGTRAP) /* trace trap (not reset when caught) */ - signal_names[SIGTRAP] = "SIGTRAP"; -#endif - -#if defined (SIGIOT) /* IOT instruction */ - signal_names[SIGIOT] = "SIGIOT"; -#endif - -#if defined (SIGABRT) /* Cause current process to dump core. */ - signal_names[SIGABRT] = "SIGABRT"; -#endif - -#if defined (SIGEMT) /* EMT instruction */ - signal_names[SIGEMT] = "SIGEMT"; -#endif - -#if defined (SIGFPE) /* floating point exception */ - signal_names[SIGFPE] = "SIGFPE"; -#endif - -#if defined (SIGKILL) /* kill (cannot be caught or ignored) */ - signal_names[SIGKILL] = "SIGKILL"; -#endif - -#if defined (SIGBUS) /* bus error */ - signal_names[SIGBUS] = "SIGBUS"; -#endif - -#if defined (SIGSEGV) /* segmentation violation */ - signal_names[SIGSEGV] = "SIGSEGV"; -#endif - -#if defined (SIGSYS) /* bad argument to system call */ - signal_names[SIGSYS] = "SIGSYS"; -#endif - -#if defined (SIGPIPE) /* write on a pipe with no one to read it */ - signal_names[SIGPIPE] = "SIGPIPE"; -#endif - -#if defined (SIGALRM) /* alarm clock */ - signal_names[SIGALRM] = "SIGALRM"; -#endif - -#if defined (SIGTERM) /* software termination signal from kill */ - signal_names[SIGTERM] = "SIGTERM"; -#endif - -#if defined (SIGURG) /* urgent condition on IO channel */ - signal_names[SIGURG] = "SIGURG"; -#endif - -#if defined (SIGSTOP) /* sendable stop signal not from tty */ - signal_names[SIGSTOP] = "SIGSTOP"; -#endif - -#if defined (SIGTSTP) /* stop signal from tty */ - signal_names[SIGTSTP] = "SIGTSTP"; -#endif - -#if defined (SIGCONT) /* continue a stopped process */ - signal_names[SIGCONT] = "SIGCONT"; -#endif - -#if defined (SIGCHLD) /* to parent on child stop or exit */ - signal_names[SIGCHLD] = "SIGCHLD"; -#endif - -#if defined (SIGTTIN) /* to readers pgrp upon background tty read */ - signal_names[SIGTTIN] = "SIGTTIN"; -#endif - -#if defined (SIGTTOU) /* like TTIN for output if (tp->t_local<OSTOP) */ - signal_names[SIGTTOU] = "SIGTTOU"; -#endif - -#if defined (SIGIO) /* input/output possible signal */ - signal_names[SIGIO] = "SIGIO"; -#endif - -#if defined (SIGXCPU) /* exceeded CPU time limit */ - signal_names[SIGXCPU] = "SIGXCPU"; -#endif - -#if defined (SIGXFSZ) /* exceeded file size limit */ - signal_names[SIGXFSZ] = "SIGXFSZ"; -#endif - -#if defined (SIGVTALRM) /* virtual time alarm */ - signal_names[SIGVTALRM] = "SIGVTALRM"; -#endif - -#if defined (SIGPROF) /* profiling time alarm */ - signal_names[SIGPROF] = "SIGPROF"; -#endif - -#if defined (SIGWINCH) /* window changed */ - signal_names[SIGWINCH] = "SIGWINCH"; -#endif - -/* 4.4 BSD */ -#if defined (SIGINFO) && !defined (_SEQUENT_) /* information request */ - signal_names[SIGINFO] = "SIGINFO"; -#endif - -#if defined (SIGUSR1) /* user defined signal 1 */ - signal_names[SIGUSR1] = "SIGUSR1"; -#endif - -#if defined (SIGUSR2) /* user defined signal 2 */ - signal_names[SIGUSR2] = "SIGUSR2"; -#endif - -#if defined (SIGKILLTHR) /* BeOS: Kill Thread */ - signal_names[SIGKILLTHR] = "SIGKILLTHR"; -#endif - - for (i = 0; i < NSIG; i++) - if (signal_names[i] == (char *)NULL) - { - signal_names[i] = (char *)malloc (18); - if (signal_names[i]) - sprintf (signal_names[i], "SIGJUNK(%d)", i); - } - - signal_names[NSIG] = "DEBUG"; - signal_names[NSIG+1] = "ERR"; - signal_names[NSIG+2] = "RETURN"; -} diff --git a/third_party/bash/signames.h b/third_party/bash/signames.h deleted file mode 100644 index 29efbf1ed..000000000 --- a/third_party/bash/signames.h +++ /dev/null @@ -1,2 +0,0 @@ -extern char *signal_names[NSIG + 4]; -void initialize_signames (); diff --git a/third_party/bash/sm_loop.inc b/third_party/bash/sm_loop.inc deleted file mode 100644 index 247ba28aa..000000000 --- a/third_party/bash/sm_loop.inc +++ /dev/null @@ -1,981 +0,0 @@ -/* Copyright (C) 1991-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -extern int interrupt_state, terminating_signal; - -struct STRUCT -{ - CHAR *pattern; - CHAR *string; -}; - -int FCT PARAMS((CHAR *, CHAR *, int)); - -static int GMATCH PARAMS((CHAR *, CHAR *, CHAR *, CHAR *, struct STRUCT *, int)); -static CHAR *PARSE_COLLSYM PARAMS((CHAR *, INT *)); -static CHAR *BRACKMATCH PARAMS((CHAR *, U_CHAR, int)); -static int EXTMATCH PARAMS((INT, CHAR *, CHAR *, CHAR *, CHAR *, int)); - -extern void DEQUOTE_PATHNAME PARAMS((CHAR *)); - -/*static*/ CHAR *PATSCAN PARAMS((CHAR *, CHAR *, INT)); - -int -FCT (pattern, string, flags) - CHAR *pattern; - CHAR *string; - int flags; -{ - CHAR *se, *pe; - - if (string == 0 || pattern == 0) - return FNM_NOMATCH; - - se = string + STRLEN ((XCHAR *)string); - pe = pattern + STRLEN ((XCHAR *)pattern); - - return (GMATCH (string, se, pattern, pe, (struct STRUCT *)NULL, flags)); -} - -/* Match STRING against the filename pattern PATTERN, returning zero if - it matches, FNM_NOMATCH if not. */ -static int -GMATCH (string, se, pattern, pe, ends, flags) - CHAR *string, *se; - CHAR *pattern, *pe; - struct STRUCT *ends; - int flags; -{ - CHAR *p, *n; /* pattern, string */ - INT c; /* current pattern character - XXX U_CHAR? */ - INT sc; /* current string character - XXX U_CHAR? */ - - p = pattern; - n = string; - - if (string == 0 || pattern == 0) - return FNM_NOMATCH; - -#if DEBUG_MATCHING -fprintf(stderr, "gmatch: string = %s; se = %s\n", string, se); -fprintf(stderr, "gmatch: pattern = %s; pe = %s\n", pattern, pe); -#endif - - while (p < pe) - { - c = *p++; - c = FOLD (c); - - sc = n < se ? *n : '\0'; - - if (interrupt_state || terminating_signal) - return FNM_NOMATCH; - -#ifdef EXTENDED_GLOB - /* EXTMATCH () will handle recursively calling GMATCH, so we can - just return what EXTMATCH() returns. */ - if ((flags & FNM_EXTMATCH) && *p == L('(') && - (c == L('+') || c == L('*') || c == L('?') || c == L('@') || c == L('!'))) /* ) */ - { - int lflags; - /* If we're not matching the start of the string, we're not - concerned about the special cases for matching `.' */ - lflags = (n == string) ? flags : (flags & ~(FNM_PERIOD|FNM_DOTDOT)); - return (EXTMATCH (c, n, se, p, pe, lflags)); - } -#endif /* EXTENDED_GLOB */ - - switch (c) - { - case L('?'): /* Match single character */ - if (sc == '\0') - return FNM_NOMATCH; - else if ((flags & FNM_PATHNAME) && sc == L('/')) - /* If we are matching a pathname, `?' can never match a `/'. */ - return FNM_NOMATCH; - else if ((flags & FNM_PERIOD) && sc == L('.') && - (n == string || ((flags & FNM_PATHNAME) && n[-1] == L('/')))) - /* `?' cannot match a `.' if it is the first character of the - string or if it is the first character following a slash and - we are matching a pathname. */ - return FNM_NOMATCH; - - /* `?' cannot match `.' or `..' if it is the first character of the - string or if it is the first character following a slash and - we are matching a pathname. */ - if ((flags & FNM_DOTDOT) && - ((n == string && SDOT_OR_DOTDOT(n)) || - ((flags & FNM_PATHNAME) && n[-1] == L('/') && PDOT_OR_DOTDOT(n)))) - return FNM_NOMATCH; - - break; - - case L('\\'): /* backslash escape removes special meaning */ - if (p == pe && sc == '\\' && (n+1 == se)) - break; - - if (p == pe) - return FNM_NOMATCH; - - if ((flags & FNM_NOESCAPE) == 0) - { - c = *p++; - /* A trailing `\' cannot match. */ - if (p > pe) - return FNM_NOMATCH; - c = FOLD (c); - } - if (FOLD (sc) != (U_CHAR)c) - return FNM_NOMATCH; - break; - - case L('*'): /* Match zero or more characters */ - /* See below for the reason for using this. It avoids backtracking - back to a previous `*'. Picked up from glibc. */ - if (ends != NULL) - { - ends->pattern = p - 1; - ends->string = n; - return (0); - } - - if ((flags & FNM_PERIOD) && sc == L('.') && - (n == string || ((flags & FNM_PATHNAME) && n[-1] == L('/')))) - /* `*' cannot match a `.' if it is the first character of the - string or if it is the first character following a slash and - we are matching a pathname. */ - return FNM_NOMATCH; - - /* `*' cannot match `.' or `..' if it is the first character of the - string or if it is the first character following a slash and - we are matching a pathname. */ - if ((flags & FNM_DOTDOT) && - ((n == string && SDOT_OR_DOTDOT(n)) || - ((flags & FNM_PATHNAME) && n[-1] == L('/') && PDOT_OR_DOTDOT(n)))) - return FNM_NOMATCH; - - if (p == pe) - return 0; - - /* Collapse multiple consecutive `*' and `?', but make sure that - one character of the string is consumed for each `?'. */ - for (c = *p++; (c == L('?') || c == L('*')); c = *p++) - { - if ((flags & FNM_PATHNAME) && sc == L('/')) - /* A slash does not match a wildcard under FNM_PATHNAME. */ - return FNM_NOMATCH; -#ifdef EXTENDED_GLOB - else if ((flags & FNM_EXTMATCH) && c == L('?') && *p == L('(')) /* ) */ - { - CHAR *newn; - - /* We can match 0 or 1 times. If we match, return success */ - if (EXTMATCH (c, n, se, p, pe, flags) == 0) - return (0); - - /* We didn't match the extended glob pattern, but - that's OK, since we can match 0 or 1 occurrences. - We need to skip the glob pattern and see if we - match the rest of the string. */ - newn = PATSCAN (p + 1, pe, 0); - /* If NEWN is 0, we have an ill-formed pattern. */ - p = newn ? newn : pe; - } -#endif - else if (c == L('?')) - { - if (sc == L('\0')) - return FNM_NOMATCH; - /* One character of the string is consumed in matching - this ? wildcard, so *??? won't match if there are - fewer than three characters. */ - n++; - sc = n < se ? *n : '\0'; - } - -#ifdef EXTENDED_GLOB - /* Handle ******(patlist) */ - if ((flags & FNM_EXTMATCH) && c == L('*') && *p == L('(')) /*)*/ - { - CHAR *newn; - /* We need to check whether or not the extended glob - pattern matches the remainder of the string. - If it does, we match the entire pattern. */ - for (newn = n; newn < se; ++newn) - { - if (EXTMATCH (c, newn, se, p, pe, flags) == 0) - return (0); - } - /* We didn't match the extended glob pattern, but - that's OK, since we can match 0 or more occurrences. - We need to skip the glob pattern and see if we - match the rest of the string. */ - newn = PATSCAN (p + 1, pe, 0); - /* If NEWN is 0, we have an ill-formed pattern. */ - p = newn ? newn : pe; - } -#endif - if (p == pe) - break; - } - - /* The wildcards are the last element of the pattern. The name - cannot match completely if we are looking for a pathname and - it contains another slash, unless FNM_LEADING_DIR is set. */ - if (c == L('\0')) - { - int r = (flags & FNM_PATHNAME) == 0 ? 0 : FNM_NOMATCH; - if (flags & FNM_PATHNAME) - { - if (flags & FNM_LEADING_DIR) - r = 0; - else if (MEMCHR (n, L('/'), se - n) == NULL) - r = 0; - } - return r; - } - - /* If we've hit the end of the pattern and the last character of - the pattern was handled by the loop above, we've succeeded. - Otherwise, we need to match that last character. */ - if (p == pe && (c == L('?') || c == L('*'))) - return (0); - - /* If we've hit the end of the string and the rest of the pattern - is something that matches the empty string, we can succeed. */ -#if defined (EXTENDED_GLOB) - if (n == se && ((flags & FNM_EXTMATCH) && (c == L('!') || c == L('?')) && *p == L('('))) - { - --p; - if (EXTMATCH (c, n, se, p, pe, flags) == 0) - return (c == L('!') ? FNM_NOMATCH : 0); - return (c == L('!') ? 0 : FNM_NOMATCH); - } -#endif - - /* If we stop at a slash in the pattern and we are looking for a - pathname ([star]/foo), then consume enough of the string to stop - at any slash and then try to match the rest of the pattern. If - the string doesn't contain a slash, fail */ - if (c == L('/') && (flags & FNM_PATHNAME)) - { - while (n < se && *n != L('/')) - ++n; - if (n < se && *n == L('/') && (GMATCH (n+1, se, p, pe, NULL, flags) == 0)) - return 0; - return FNM_NOMATCH; /* XXX */ - } - - /* General case, use recursion. */ - { - U_CHAR c1; - const CHAR *endp; - struct STRUCT end; - - end.pattern = NULL; - endp = MEMCHR (n, (flags & FNM_PATHNAME) ? L('/') : L('\0'), se - n); - if (endp == 0) - endp = se; - - c1 = ((flags & FNM_NOESCAPE) == 0 && c == L('\\')) ? *p : c; - c1 = FOLD (c1); - for (--p; n < endp; ++n) - { - /* Only call strmatch if the first character indicates a - possible match. We can check the first character if - we're not doing an extended glob match. */ - if ((flags & FNM_EXTMATCH) == 0 && c != L('[') && FOLD (*n) != c1) /*]*/ - continue; - - /* If we're doing an extended glob match and the pattern is not - one of the extended glob patterns, we can check the first - character. */ - if ((flags & FNM_EXTMATCH) && p[1] != L('(') && /*)*/ - STRCHR (L("?*+@!"), *p) == 0 && c != L('[') && FOLD (*n) != c1) /*]*/ - continue; - - /* Otherwise, we just recurse. */ - if (GMATCH (n, se, p, pe, &end, flags & ~(FNM_PERIOD|FNM_DOTDOT)) == 0) - { - if (end.pattern == NULL) - return (0); - break; - } - } - /* This is a clever idea from glibc, used to avoid backtracking - to a `*' that appears earlier in the pattern. We get away - without saving se and pe because they are always the same, - even in the recursive calls to gmatch */ - if (end.pattern != NULL) - { - p = end.pattern; - n = end.string; - continue; - } - - return FNM_NOMATCH; - } - - case L('['): - { - if (sc == L('\0') || n == se) - return FNM_NOMATCH; - - /* A character class cannot match a `.' if it is the first - character of the string or if it is the first character - following a slash and we are matching a pathname. */ - if ((flags & FNM_PERIOD) && sc == L('.') && - (n == string || ((flags & FNM_PATHNAME) && n[-1] == L('/')))) - return (FNM_NOMATCH); - - /* `?' cannot match `.' or `..' if it is the first character of the - string or if it is the first character following a slash and - we are matching a pathname. */ - if ((flags & FNM_DOTDOT) && - ((n == string && SDOT_OR_DOTDOT(n)) || - ((flags & FNM_PATHNAME) && n[-1] == L('/') && PDOT_OR_DOTDOT(n)))) - return FNM_NOMATCH; - - p = BRACKMATCH (p, sc, flags); - if (p == 0) - return FNM_NOMATCH; - } - break; - - default: - if ((U_CHAR)c != FOLD (sc)) - return (FNM_NOMATCH); - } - - ++n; - } - - if (n == se) - return (0); - - if ((flags & FNM_LEADING_DIR) && *n == L('/')) - /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */ - return 0; - - return (FNM_NOMATCH); -} - -/* Parse a bracket expression collating symbol ([.sym.]) starting at P, find - the value of the symbol, and move P past the collating symbol expression. - The value is returned in *VP, if VP is not null. */ -static CHAR * -PARSE_COLLSYM (p, vp) - CHAR *p; - INT *vp; -{ - register int pc; - INT val; - - p++; /* move past the `.' */ - - for (pc = 0; p[pc]; pc++) - if (p[pc] == L('.') && p[pc+1] == L(']')) - break; - if (p[pc] == 0) - { - if (vp) - *vp = INVALID; - return (p + pc); - } - val = COLLSYM (p, pc); - if (vp) - *vp = val; - return (p + pc + 2); -} - -/* Use prototype definition here because of type promotion. */ -static CHAR * -#if defined (PROTOTYPES) -BRACKMATCH (CHAR *p, U_CHAR test, int flags) -#else -BRACKMATCH (p, test, flags) - CHAR *p; - U_CHAR test; - int flags; -#endif -{ - register CHAR cstart, cend, c; - register int not; /* Nonzero if the sense of the character class is inverted. */ - int brcnt, forcecoll, isrange; - INT pc; - CHAR *savep; - CHAR *brchrp; - U_CHAR orig_test; - - orig_test = test; - test = FOLD (orig_test); - - savep = p; - - /* POSIX.2 3.13.1 says that an exclamation mark (`!') shall replace the - circumflex (`^') in its role in a `nonmatching list'. A bracket - expression starting with an unquoted circumflex character produces - unspecified results. This implementation treats the two identically. */ - if (not = (*p == L('!') || *p == L('^'))) - ++p; - - c = *p++; - for (;;) - { - /* Initialize cstart and cend in case `-' is the last - character of the pattern. */ - cstart = cend = c; - forcecoll = 0; - - /* POSIX.2 equivalence class: [=c=]. See POSIX.2 2.8.3.2. Find - the end of the equivalence class, move the pattern pointer past - it, and check for equivalence. XXX - this handles only - single-character equivalence classes, which is wrong, or at - least incomplete. */ - if (c == L('[') && *p == L('=') && p[2] == L('=') && p[3] == L(']')) - { - pc = FOLD (p[1]); - p += 4; - if (COLLEQUIV (test, pc)) - { -/*[*/ /* Move past the closing `]', since the first thing we do at - the `matched:' label is back p up one. */ - p++; - goto matched; - } - else - { - c = *p++; - if (c == L('\0')) - return ((test == L('[')) ? savep : (CHAR *)0); /*]*/ - c = FOLD (c); - continue; - } - } - - /* POSIX.2 character class expression. See POSIX.2 2.8.3.2. */ - if (c == L('[') && *p == L(':')) - { - CHAR *close, *ccname; - - pc = 0; /* make sure invalid char classes don't match. */ - /* Find end of character class name */ - for (close = p + 1; *close != '\0'; close++) - if (*close == L(':') && *(close+1) == L(']')) - break; - - if (*close != L('\0')) - { - ccname = (CHAR *)malloc ((close - p) * sizeof (CHAR)); - if (ccname == 0) - pc = 0; - else - { - bcopy (p + 1, ccname, (close - p - 1) * sizeof (CHAR)); - *(ccname + (close - p - 1)) = L('\0'); - /* As a result of a POSIX discussion, char class names are - allowed to be quoted (?) */ - DEQUOTE_PATHNAME (ccname); - pc = IS_CCLASS (orig_test, (XCHAR *)ccname); - } - if (pc == -1) - { - /* CCNAME is not a valid character class in the current - locale. In addition to noting no match (pc = 0), we have - a choice about what to do with the invalid charclass. - Posix leaves the behavior unspecified, but we're going - to skip over the charclass and keep going instead of - testing ORIG_TEST against each character in the class - string. If we don't want to do that, take out the update - of P. */ - pc = 0; - p = close + 2; - } - else - p = close + 2; /* move past the closing `]' */ - - free (ccname); - } - - if (pc) - { -/*[*/ /* Move past the closing `]', since the first thing we do at - the `matched:' label is back p up one. */ - p++; - goto matched; - } - else - { - /* continue the loop here, since this expression can't be - the first part of a range expression. */ - c = *p++; - if (c == L('\0')) - return ((test == L('[')) ? savep : (CHAR *)0); - else if (c == L(']')) - break; - c = FOLD (c); - continue; - } - } - - /* POSIX.2 collating symbols. See POSIX.2 2.8.3.2. Find the end of - the symbol name, make sure it is terminated by `.]', translate - the name to a character using the external table, and do the - comparison. */ - if (c == L('[') && *p == L('.')) - { - p = PARSE_COLLSYM (p, &pc); - /* An invalid collating symbol cannot be the first point of a - range. If it is, we set cstart to one greater than `test', - so any comparisons later will fail. */ - cstart = (pc == INVALID) ? test + 1 : pc; - forcecoll = 1; - } - - if (!(flags & FNM_NOESCAPE) && c == L('\\')) - { - if (*p == '\0') - return (CHAR *)0; - cstart = cend = *p++; - } - - cstart = cend = FOLD (cstart); - isrange = 0; - - /* POSIX.2 2.8.3.1.2 says: `An expression containing a `[' that - is not preceded by a backslash and is not part of a bracket - expression produces undefined results.' This implementation - treats the `[' as just a character to be matched if there is - not a closing `]'. */ - if (c == L('\0')) - return ((test == L('[')) ? savep : (CHAR *)0); - - c = *p++; - c = FOLD (c); - - if (c == L('\0')) - return ((test == L('[')) ? savep : (CHAR *)0); - - if ((flags & FNM_PATHNAME) && c == L('/')) - /* [/] can never match when matching a pathname. */ - return (CHAR *)0; - - /* This introduces a range, unless the `-' is the last - character of the class. Find the end of the range - and move past it. */ - if (c == L('-') && *p != L(']')) - { - cend = *p++; - if (!(flags & FNM_NOESCAPE) && cend == L('\\')) - cend = *p++; - if (cend == L('\0')) - return (CHAR *)0; - if (cend == L('[') && *p == L('.')) - { - p = PARSE_COLLSYM (p, &pc); - /* An invalid collating symbol cannot be the second part of a - range expression. If we get one, we set cend to one fewer - than the test character to make sure the range test fails. */ - cend = (pc == INVALID) ? test - 1 : pc; - forcecoll = 1; - } - cend = FOLD (cend); - - c = *p++; - - /* POSIX.2 2.8.3.2: ``The ending range point shall collate - equal to or higher than the starting range point; otherwise - the expression shall be treated as invalid.'' Note that this - applies to only the range expression; the rest of the bracket - expression is still checked for matches. */ - if (RANGECMP (cstart, cend, forcecoll) > 0) - { - if (c == L(']')) - break; - c = FOLD (c); - continue; - } - isrange = 1; - } - - if (isrange == 0 && test == cstart) - goto matched; - if (isrange && RANGECMP (test, cstart, forcecoll) >= 0 && RANGECMP (test, cend, forcecoll) <= 0) - goto matched; - - if (c == L(']')) - break; - } - /* No match. */ - return (!not ? (CHAR *)0 : p); - -matched: - /* Skip the rest of the [...] that already matched. */ - c = *--p; - brcnt = 1; - brchrp = 0; - while (brcnt > 0) - { - int oc; - - /* A `[' without a matching `]' is just another character to match. */ - if (c == L('\0')) - return ((test == L('[')) ? savep : (CHAR *)0); - - oc = c; - c = *p++; - if (c == L('[') && (*p == L('=') || *p == L(':') || *p == L('.'))) - { - brcnt++; - brchrp = p++; /* skip over the char after the left bracket */ - if ((c = *p) == L('\0')) - return ((test == L('[')) ? savep : (CHAR *)0); - /* If *brchrp == ':' we should check that the rest of the characters - form a valid character class name. We don't do that yet, but we - keep BRCHRP in case we want to. */ - } - /* We only want to check brchrp if we set it above. */ - else if (c == L(']') && brcnt > 1 && brchrp != 0 && oc == *brchrp) - { - brcnt--; - brchrp = 0; /* just in case */ - } - /* Left bracket loses its special meaning inside a bracket expression. - It is only valid when followed by a `.', `=', or `:', which we check - for above. Technically the right bracket can appear in a collating - symbol, so we check for that here. Otherwise, it terminates the - bracket expression. */ - else if (c == L(']') && (brchrp == 0 || *brchrp != L('.')) && brcnt >= 1) - brcnt = 0; - else if (!(flags & FNM_NOESCAPE) && c == L('\\')) - { - if (*p == '\0') - return (CHAR *)0; - /* XXX 1003.2d11 is unclear if this is right. */ - ++p; - } - } - return (not ? (CHAR *)0 : p); -} - -#if defined (EXTENDED_GLOB) -/* ksh-like extended pattern matching: - - [?*+@!](pat-list) - - where pat-list is a list of one or patterns separated by `|'. Operation - is as follows: - - ?(patlist) match zero or one of the given patterns - *(patlist) match zero or more of the given patterns - +(patlist) match one or more of the given patterns - @(patlist) match exactly one of the given patterns - !(patlist) match anything except one of the given patterns -*/ - -/* Scan a pattern starting at STRING and ending at END, keeping track of - embedded () and []. If DELIM is 0, we scan until a matching `)' - because we're scanning a `patlist'. Otherwise, we scan until we see - DELIM. In all cases, we never scan past END. The return value is the - first character after the matching DELIM or NULL if the pattern is - empty or invalid. */ -/*static*/ CHAR * -PATSCAN (string, end, delim) - CHAR *string, *end; - INT delim; -{ - int pnest, bnest, skip; - INT cchar; - CHAR *s, c, *bfirst; - - pnest = bnest = skip = 0; - cchar = 0; - bfirst = NULL; - - if (string == end) - return (NULL); - - for (s = string; c = *s; s++) - { - if (s >= end) - return (s); - if (skip) - { - skip = 0; - continue; - } - switch (c) - { - case L('\\'): - skip = 1; - break; - - case L('\0'): - return ((CHAR *)NULL); - - /* `[' is not special inside a bracket expression, but it may - introduce one of the special POSIX bracket expressions - ([.SYM.], [=c=], [: ... :]) that needs special handling. */ - case L('['): - if (bnest == 0) - { - bfirst = s + 1; - if (*bfirst == L('!') || *bfirst == L('^')) - bfirst++; - bnest++; - } - else if (s[1] == L(':') || s[1] == L('.') || s[1] == L('=')) - cchar = s[1]; - break; - - /* `]' is not special if it's the first char (after a leading `!' - or `^') in a bracket expression or if it's part of one of the - special POSIX bracket expressions ([.SYM.], [=c=], [: ... :]) */ - case L(']'): - if (bnest) - { - if (cchar && s[-1] == cchar) - cchar = 0; - else if (s != bfirst) - { - bnest--; - bfirst = 0; - } - } - break; - - case L('('): - if (bnest == 0) - pnest++; - break; - - case L(')'): - if (bnest == 0 && pnest-- <= 0) - return ++s; - break; - - case L('|'): - if (bnest == 0 && pnest == 0 && delim == L('|')) - return ++s; - break; - } - } - - return (NULL); -} - -/* Return 0 if dequoted pattern matches S in the current locale. */ -static int -STRCOMPARE (p, pe, s, se) - CHAR *p, *pe, *s, *se; -{ - int ret; - CHAR c1, c2; - int l1, l2; - - l1 = pe - p; - l2 = se - s; - - if (l1 != l2) - return (FNM_NOMATCH); /* unequal lengths, can't be identical */ - - c1 = *pe; - c2 = *se; - - if (c1 != 0) - *pe = '\0'; - if (c2 != 0) - *se = '\0'; - -#if HAVE_MULTIBYTE || defined (HAVE_STRCOLL) - ret = STRCOLL ((XCHAR *)p, (XCHAR *)s); -#else - ret = STRCMP ((XCHAR *)p, (XCHAR *)s); -#endif - - if (c1 != 0) - *pe = c1; - if (c2 != 0) - *se = c2; - - return (ret == 0 ? ret : FNM_NOMATCH); -} - -/* Match a ksh extended pattern specifier. Return FNM_NOMATCH on failure or - 0 on success. This is handed the entire rest of the pattern and string - the first time an extended pattern specifier is encountered, so it calls - gmatch recursively. */ -static int -EXTMATCH (xc, s, se, p, pe, flags) - INT xc; /* select which operation */ - CHAR *s, *se; - CHAR *p, *pe; - int flags; -{ - CHAR *prest; /* pointer to rest of pattern */ - CHAR *psub; /* pointer to sub-pattern */ - CHAR *pnext; /* pointer to next sub-pattern */ - CHAR *srest; /* pointer to rest of string */ - int m1, m2, xflags; /* xflags = flags passed to recursive matches */ - -#if DEBUG_MATCHING -fprintf(stderr, "extmatch: xc = %c\n", xc); -fprintf(stderr, "extmatch: s = %s; se = %s\n", s, se); -fprintf(stderr, "extmatch: p = %s; pe = %s\n", p, pe); -fprintf(stderr, "extmatch: flags = %d\n", flags); -#endif - - prest = PATSCAN (p + (*p == L('(')), pe, 0); /* ) */ - if (prest == 0) - /* If PREST is 0, we failed to scan a valid pattern. In this - case, we just want to compare the two as strings. */ - return (STRCOMPARE (p - 1, pe, s, se)); - - switch (xc) - { - case L('+'): /* match one or more occurrences */ - case L('*'): /* match zero or more occurrences */ - /* If we can get away with no matches, don't even bother. Just - call GMATCH on the rest of the pattern and return success if - it succeeds. */ - if (xc == L('*') && (GMATCH (s, se, prest, pe, NULL, flags) == 0)) - return 0; - - /* OK, we have to do this the hard way. First, we make sure one of - the subpatterns matches, then we try to match the rest of the - string. */ - for (psub = p + 1; ; psub = pnext) - { - pnext = PATSCAN (psub, pe, L('|')); - for (srest = s; srest <= se; srest++) - { - /* Match this substring (S -> SREST) against this - subpattern (psub -> pnext - 1) */ - m1 = GMATCH (s, srest, psub, pnext - 1, NULL, flags) == 0; - /* OK, we matched a subpattern, so make sure the rest of the - string matches the rest of the pattern. Also handle - multiple matches of the pattern. */ - if (m1) - { - /* if srest > s, we are not at start of string */ - xflags = (srest > s) ? (flags & ~(FNM_PERIOD|FNM_DOTDOT)) : flags; - m2 = (GMATCH (srest, se, prest, pe, NULL, xflags) == 0) || - (s != srest && GMATCH (srest, se, p - 1, pe, NULL, xflags) == 0); - } - if (m1 && m2) - return (0); - } - if (pnext == prest) - break; - } - return (FNM_NOMATCH); - - case L('?'): /* match zero or one of the patterns */ - case L('@'): /* match one (or more) of the patterns */ - /* If we can get away with no matches, don't even bother. Just - call gmatch on the rest of the pattern and return success if - it succeeds. */ - if (xc == L('?') && (GMATCH (s, se, prest, pe, NULL, flags) == 0)) - return 0; - - /* OK, we have to do this the hard way. First, we see if one of - the subpatterns matches, then, if it does, we try to match the - rest of the string. */ - for (psub = p + 1; ; psub = pnext) - { - pnext = PATSCAN (psub, pe, L('|')); - srest = (prest == pe) ? se : s; - for ( ; srest <= se; srest++) - { - /* if srest > s, we are not at start of string */ - xflags = (srest > s) ? (flags & ~(FNM_PERIOD|FNM_DOTDOT)) : flags; - if (GMATCH (s, srest, psub, pnext - 1, NULL, flags) == 0 && - GMATCH (srest, se, prest, pe, NULL, xflags) == 0) - return (0); - } - if (pnext == prest) - break; - } - return (FNM_NOMATCH); - - case '!': /* match anything *except* one of the patterns */ - for (srest = s; srest <= se; srest++) - { - m1 = 0; - for (psub = p + 1; ; psub = pnext) - { - pnext = PATSCAN (psub, pe, L('|')); - /* If one of the patterns matches, just bail immediately. */ - if (m1 = (GMATCH (s, srest, psub, pnext - 1, NULL, flags) == 0)) - break; - if (pnext == prest) - break; - } - - /* If nothing matched, but the string starts with a period and we - need to match periods explicitly, don't return this as a match, - even for negation. */ - if (m1 == 0 && (flags & FNM_PERIOD) && *s == '.') - return (FNM_NOMATCH); - - if (m1 == 0 && (flags & FNM_DOTDOT) && - (SDOT_OR_DOTDOT (s) || - ((flags & FNM_PATHNAME) && s[-1] == L('/') && PDOT_OR_DOTDOT(s)))) - return (FNM_NOMATCH); - - /* if srest > s, we are not at start of string */ - xflags = (srest > s) ? (flags & ~(FNM_PERIOD|FNM_DOTDOT)) : flags; - if (m1 == 0 && GMATCH (srest, se, prest, pe, NULL, xflags) == 0) - return (0); - } - return (FNM_NOMATCH); - } - - return (FNM_NOMATCH); -} -#endif /* EXTENDED_GLOB */ - -#undef IS_CCLASS -#undef FOLD -#undef CHAR -#undef U_CHAR -#undef XCHAR -#undef INT -#undef INVALID -#undef FCT -#undef GMATCH -#undef COLLSYM -#undef PARSE_COLLSYM -#undef PATSCAN -#undef STRCOMPARE -#undef EXTMATCH -#undef DEQUOTE_PATHNAME -#undef STRUCT -#undef BRACKMATCH -#undef STRCHR -#undef STRCOLL -#undef STRLEN -#undef STRCMP -#undef MEMCHR -#undef COLLEQUIV -#undef RANGECMP -#undef ISDIRSEP -#undef PATHSEP -#undef PDOT_OR_DOTDOT -#undef SDOT_OR_DOTDOT -#undef L diff --git a/third_party/bash/smatch.c b/third_party/bash/smatch.c deleted file mode 100644 index e265c9571..000000000 --- a/third_party/bash/smatch.c +++ /dev/null @@ -1,638 +0,0 @@ -/* strmatch.c -- ksh-like extended pattern matching for the shell and filename - globbing. */ - -/* Copyright (C) 1991-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include /* for debugging */ - -#include "strmatch.h" -#include "chartypes.h" - -#include "bashansi.h" -#include "shmbutil.h" -#include "xmalloc.h" - -#include - -#if !defined (errno) -extern int errno; -#endif - -#if FNMATCH_EQUIV_FALLBACK -/* We don't include in order to avoid namespace collisions; the - internal strmatch still uses the FNM_ constants. */ -extern int fnmatch (const char *, const char *, int); -#endif - -/* First, compile `sm_loop.c' for single-byte characters. */ -#define CHAR unsigned char -#define U_CHAR unsigned char -#define XCHAR char -#define INT int -#define L(CS) CS -#define INVALID -1 - -#undef STREQ -#undef STREQN -#define STREQ(a, b) ((a)[0] == (b)[0] && strcmp(a, b) == 0) -#define STREQN(a, b, n) ((a)[0] == (b)[0] && strncmp(a, b, n) == 0) - -#ifndef GLOBASCII_DEFAULT -# define GLOBASCII_DEFAULT 0 -#endif - -int glob_asciirange = GLOBASCII_DEFAULT; - -#if FNMATCH_EQUIV_FALLBACK -/* Construct a string w1 = "c1" and a pattern w2 = "[[=c2=]]" and pass them - to fnmatch to see if wide characters c1 and c2 collate as members of the - same equivalence class. We can't really do this portably any other way */ -static int -_fnmatch_fallback (s, p) - int s, p; /* string char, patchar */ -{ - char s1[2]; /* string */ - char s2[8]; /* constructed pattern */ - - s1[0] = (unsigned char)s; - s1[1] = '\0'; - - /* reconstruct the pattern */ - s2[0] = s2[1] = '['; - s2[2] = '='; - s2[3] = (unsigned char)p; - s2[4] = '='; - s2[5] = s2[6] = ']'; - s2[7] = '\0'; - - return (fnmatch ((const char *)s2, (const char *)s1, 0)); -} -#endif - -/* We use strcoll(3) for range comparisons in bracket expressions, - even though it can have unwanted side effects in locales - other than POSIX or US. For instance, in the de locale, [A-Z] matches - all characters. If GLOB_ASCIIRANGE is non-zero, and we're not forcing - the use of strcoll (e.g., for explicit collating symbols), we use - straight ordering as if in the C locale. */ - -#if defined (HAVE_STRCOLL) -/* Helper functions for collating symbol equivalence. */ - -/* Return 0 if C1 == C2 or collates equally if FORCECOLL is non-zero. */ -static int -charcmp (c1, c2, forcecoll) - int c1, c2; - int forcecoll; -{ - static char s1[2] = { ' ', '\0' }; - static char s2[2] = { ' ', '\0' }; - int ret; - - /* Eight bits only. Period. */ - c1 &= 0xFF; - c2 &= 0xFF; - - if (c1 == c2) - return (0); - - if (forcecoll == 0 && glob_asciirange) - return (c1 - c2); - - s1[0] = c1; - s2[0] = c2; - - return (strcoll (s1, s2)); -} - -static int -rangecmp (c1, c2, forcecoll) - int c1, c2; - int forcecoll; -{ - int r; - - r = charcmp (c1, c2, forcecoll); - - /* We impose a total ordering here by returning c1-c2 if charcmp returns 0 */ - if (r != 0) - return r; - return (c1 - c2); /* impose total ordering */ -} -#else /* !HAVE_STRCOLL */ -# define rangecmp(c1, c2, f) ((int)(c1) - (int)(c2)) -#endif /* !HAVE_STRCOLL */ - -#if defined (HAVE_STRCOLL) -/* Returns 1 if chars C and EQUIV collate equally in the current locale. */ -static int -collequiv (c, equiv) - int c, equiv; -{ - if (charcmp (c, equiv, 1) == 0) - return 1; - -#if FNMATCH_EQUIV_FALLBACK - return (_fnmatch_fallback (c, equiv) == 0); -#else - return 0; -#endif - -} -#else -# define collequiv(c, equiv) ((c) == (equiv)) -#endif - -#define _COLLSYM _collsym -#define __COLLSYM __collsym -#define POSIXCOLL posix_collsyms -#include "collsyms.h" - -static int -collsym (s, len) - CHAR *s; - int len; -{ - register struct _collsym *csp; - char *x; - - x = (char *)s; - for (csp = posix_collsyms; csp->name; csp++) - { - if (STREQN(csp->name, x, len) && csp->name[len] == '\0') - return (csp->code); - } - if (len == 1) - return s[0]; - return INVALID; -} - -/* unibyte character classification */ -#if !defined (isascii) && !defined (HAVE_ISASCII) -# define isascii(c) ((unsigned int)(c) <= 0177) -#endif - -enum char_class - { - CC_NO_CLASS = 0, - CC_ASCII, CC_ALNUM, CC_ALPHA, CC_BLANK, CC_CNTRL, CC_DIGIT, CC_GRAPH, - CC_LOWER, CC_PRINT, CC_PUNCT, CC_SPACE, CC_UPPER, CC_WORD, CC_XDIGIT - }; - -static char const *const cclass_name[] = - { - "", - "ascii", "alnum", "alpha", "blank", "cntrl", "digit", "graph", - "lower", "print", "punct", "space", "upper", "word", "xdigit" - }; - -#define N_CHAR_CLASS (sizeof(cclass_name) / sizeof (cclass_name[0])) - -static enum char_class -is_valid_cclass (name) - const char *name; -{ - enum char_class ret; - int i; - - ret = CC_NO_CLASS; - - for (i = 1; i < N_CHAR_CLASS; i++) - { - if (STREQ (name, cclass_name[i])) - { - ret = (enum char_class)i; - break; - } - } - - return ret; -} - -static int -cclass_test (c, char_class) - int c; - enum char_class char_class; -{ - int result; - - switch (char_class) - { - case CC_ASCII: - result = isascii (c); - break; - case CC_ALNUM: - result = ISALNUM (c); - break; - case CC_ALPHA: - result = ISALPHA (c); - break; - case CC_BLANK: - result = ISBLANK (c); - break; - case CC_CNTRL: - result = ISCNTRL (c); - break; - case CC_DIGIT: - result = ISDIGIT (c); - break; - case CC_GRAPH: - result = ISGRAPH (c); - break; - case CC_LOWER: - result = ISLOWER (c); - break; - case CC_PRINT: - result = ISPRINT (c); - break; - case CC_PUNCT: - result = ISPUNCT (c); - break; - case CC_SPACE: - result = ISSPACE (c); - break; - case CC_UPPER: - result = ISUPPER (c); - break; - case CC_WORD: - result = (ISALNUM (c) || c == '_'); - break; - case CC_XDIGIT: - result = ISXDIGIT (c); - break; - default: - result = -1; - break; - } - - return result; -} - -static int -is_cclass (c, name) - int c; - const char *name; -{ - enum char_class char_class; - int result; - - char_class = is_valid_cclass (name); - if (char_class == CC_NO_CLASS) - return -1; - - result = cclass_test (c, char_class); - return (result); -} - -/* Now include `sm_loop.c' for single-byte characters. */ -/* The result of FOLD is an `unsigned char' */ -# define FOLD(c) ((flags & FNM_CASEFOLD) \ - ? TOLOWER ((unsigned char)c) \ - : ((unsigned char)c)) - -#if !defined (__CYGWIN__) -# define ISDIRSEP(c) ((c) == '/') -#else -# define ISDIRSEP(c) ((c) == '/' || (c) == '\\') -#endif /* __CYGWIN__ */ -#define PATHSEP(c) (ISDIRSEP(c) || (c) == 0) - -# define PDOT_OR_DOTDOT(s) (s[0] == '.' && (PATHSEP (s[1]) || (s[1] == '.' && PATHSEP (s[2])))) -# define SDOT_OR_DOTDOT(s) (s[0] == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0))) - -#define FCT internal_strmatch -#define GMATCH gmatch -#define COLLSYM collsym -#define PARSE_COLLSYM parse_collsym -#define BRACKMATCH brackmatch -#define PATSCAN glob_patscan -#define STRCOMPARE strcompare -#define EXTMATCH extmatch -#define DEQUOTE_PATHNAME udequote_pathname -#define STRUCT smat_struct -#define STRCHR(S, C) strchr((S), (C)) -#define MEMCHR(S, C, N) memchr((S), (C), (N)) -#define STRCOLL(S1, S2) strcoll((S1), (S2)) -#define STRLEN(S) strlen(S) -#define STRCMP(S1, S2) strcmp((S1), (S2)) -#define RANGECMP(C1, C2, F) rangecmp((C1), (C2), (F)) -#define COLLEQUIV(C1, C2) collequiv((C1), (C2)) -#define CTYPE_T enum char_class -#define IS_CCLASS(C, S) is_cclass((C), (S)) -#include "sm_loop.inc" - -#if HANDLE_MULTIBYTE - -# define CHAR wchar_t -# define U_CHAR wint_t -# define XCHAR wchar_t -# define INT wint_t -# define L(CS) L##CS -# define INVALID WEOF - -# undef STREQ -# undef STREQN -# define STREQ(s1, s2) ((wcscmp (s1, s2) == 0)) -# define STREQN(a, b, n) ((a)[0] == (b)[0] && wcsncmp(a, b, n) == 0) - -extern char *mbsmbchar PARAMS((const char *)); - -#if FNMATCH_EQUIV_FALLBACK -/* Construct a string w1 = "c1" and a pattern w2 = "[[=c2=]]" and pass them - to fnmatch to see if wide characters c1 and c2 collate as members of the - same equivalence class. We can't really do this portably any other way */ -static int -_fnmatch_fallback_wc (c1, c2) - wchar_t c1, c2; /* string char, patchar */ -{ - char w1[MB_LEN_MAX+1]; /* string */ - char w2[MB_LEN_MAX+8]; /* constructed pattern */ - int l1, l2; - - l1 = wctomb (w1, c1); - if (l1 == -1) - return (2); - w1[l1] = '\0'; - - /* reconstruct the pattern */ - w2[0] = w2[1] = '['; - w2[2] = '='; - l2 = wctomb (w2+3, c2); - if (l2 == -1) - return (2); - w2[l2+3] = '='; - w2[l2+4] = w2[l2+5] = ']'; - w2[l2+6] = '\0'; - - return (fnmatch ((const char *)w2, (const char *)w1, 0)); -} -#endif - -static int -charcmp_wc (c1, c2, forcecoll) - wint_t c1, c2; - int forcecoll; -{ - static wchar_t s1[2] = { L' ', L'\0' }; - static wchar_t s2[2] = { L' ', L'\0' }; - int r; - - if (c1 == c2) - return 0; - - if (forcecoll == 0 && glob_asciirange && c1 <= UCHAR_MAX && c2 <= UCHAR_MAX) - return ((int)(c1 - c2)); - - s1[0] = c1; - s2[0] = c2; - - return (wcscoll (s1, s2)); -} - -static int -rangecmp_wc (c1, c2, forcecoll) - wint_t c1, c2; - int forcecoll; -{ - int r; - - r = charcmp_wc (c1, c2, forcecoll); - - /* We impose a total ordering here by returning c1-c2 if charcmp returns 0, - as we do above in the single-byte case. */ - if (r != 0 || forcecoll) - return r; - return ((int)(c1 - c2)); /* impose total ordering */ -} - -/* Returns 1 if wide chars C and EQUIV collate equally in the current locale. */ -static int -collequiv_wc (c, equiv) - wint_t c, equiv; -{ - wchar_t s, p; - - if (charcmp_wc (c, equiv, 1) == 0) - return 1; - -#if FNMATCH_EQUIV_FALLBACK -/* We check explicitly for success (fnmatch returns 0) to avoid problems if - our local definition of FNM_NOMATCH (strmatch.h) doesn't match the - system's (fnmatch.h). We don't care about error return values here. */ - - s = c; - p = equiv; - return (_fnmatch_fallback_wc (s, p) == 0); -#else - return 0; -#endif -} - -/* Helper function for collating symbol. */ -# define _COLLSYM _collwcsym -# define __COLLSYM __collwcsym -# define POSIXCOLL posix_collwcsyms -# include "collsyms.h" - -static wint_t -collwcsym (s, len) - wchar_t *s; - int len; -{ - register struct _collwcsym *csp; - - for (csp = posix_collwcsyms; csp->name; csp++) - { - if (STREQN(csp->name, s, len) && csp->name[len] == L'\0') - return (csp->code); - } - if (len == 1) - return s[0]; - return INVALID; -} - -static int -is_wcclass (wc, name) - wint_t wc; - wchar_t *name; -{ - char *mbs; - mbstate_t state; - size_t mbslength; - wctype_t desc; - int want_word; - - if ((wctype ("ascii") == (wctype_t)0) && (wcscmp (name, L"ascii") == 0)) - { - int c; - - if ((c = wctob (wc)) == EOF) - return 0; - else - return (c <= 0x7F); - } - - want_word = (wcscmp (name, L"word") == 0); - if (want_word) - name = L"alnum"; - - memset (&state, '\0', sizeof (mbstate_t)); - mbs = (char *) malloc (wcslen(name) * MB_CUR_MAX + 1); - if (mbs == 0) - return -1; - mbslength = wcsrtombs (mbs, (const wchar_t **)&name, (wcslen(name) * MB_CUR_MAX + 1), &state); - - if (mbslength == (size_t)-1 || mbslength == (size_t)-2) - { - free (mbs); - return -1; - } - desc = wctype (mbs); - free (mbs); - - if (desc == (wctype_t)0) - return -1; - - if (want_word) - return (iswctype (wc, desc) || wc == L'_'); - else - return (iswctype (wc, desc)); -} - -/* Return 1 if there are no char class [:class:] expressions (degenerate case) - or only posix-specified (C locale supported) char class expressions in - PATTERN. These are the ones where it's safe to punt to the single-byte - code, since wide character support allows locale-defined char classes. - This only uses single-byte code, but is only needed to support multibyte - locales. */ -static int -posix_cclass_only (pattern) - char *pattern; -{ - char *p, *p1; - char cc[16]; /* sufficient for all valid posix char class names */ - enum char_class valid; - - p = pattern; - while (p = strchr (p, '[')) - { - if (p[1] != ':') - { - p++; - continue; - } - p += 2; /* skip past "[:" */ - /* Find end of char class expression */ - for (p1 = p; *p1; p1++) - if (*p1 == ':' && p1[1] == ']') - break; - if (*p1 == 0) /* no char class expression found */ - break; - /* Find char class name and validate it against posix char classes */ - if ((p1 - p) >= sizeof (cc)) - return 0; - bcopy (p, cc, p1 - p); - cc[p1 - p] = '\0'; - valid = is_valid_cclass (cc); - if (valid == CC_NO_CLASS) - return 0; /* found unrecognized char class name */ - - p = p1 + 2; /* found posix char class name */ - } - - return 1; /* no char class names or only posix */ -} - -/* Now include `sm_loop.c' for multibyte characters. */ -#define FOLD(c) ((flags & FNM_CASEFOLD) && iswupper (c) ? towlower (c) : (c)) - -# if !defined (__CYGWIN__) -# define ISDIRSEP(c) ((c) == L'/') -# else -# define ISDIRSEP(c) ((c) == L'/' || (c) == L'\\') -# endif /* __CYGWIN__ */ -# define PATHSEP(c) (ISDIRSEP(c) || (c) == L'\0') - -# define PDOT_OR_DOTDOT(w) (w[0] == L'.' && (PATHSEP(w[1]) || (w[1] == L'.' && PATHSEP(w[2])))) -# define SDOT_OR_DOTDOT(w) (w[0] == L'.' && (w[1] == L'\0' || (w[1] == L'.' && w[2] == L'\0'))) - -#define FCT internal_wstrmatch -#define GMATCH gmatch_wc -#define COLLSYM collwcsym -#define PARSE_COLLSYM parse_collwcsym -#define BRACKMATCH brackmatch_wc -#define PATSCAN glob_patscan_wc -#define STRCOMPARE wscompare -#define EXTMATCH extmatch_wc -#define DEQUOTE_PATHNAME wcdequote_pathname -#define STRUCT wcsmat_struct -#define STRCHR(S, C) wcschr((S), (C)) -#define MEMCHR(S, C, N) wmemchr((S), (C), (N)) -#define STRCOLL(S1, S2) wcscoll((S1), (S2)) -#define STRLEN(S) wcslen(S) -#define STRCMP(S1, S2) wcscmp((S1), (S2)) -#define RANGECMP(C1, C2, F) rangecmp_wc((C1), (C2), (F)) -#define COLLEQUIV(C1, C2) collequiv_wc((C1), (C2)) -#define CTYPE_T enum char_class -#define IS_CCLASS(C, S) is_wcclass((C), (S)) -#include "sm_loop.inc" - -#endif /* HAVE_MULTIBYTE */ - -int -xstrmatch (pattern, string, flags) - char *pattern; - char *string; - int flags; -{ -#if HANDLE_MULTIBYTE - int ret; - size_t n; - wchar_t *wpattern, *wstring; - size_t plen, slen, mplen, mslen; - - if (MB_CUR_MAX == 1) - return (internal_strmatch ((unsigned char *)pattern, (unsigned char *)string, flags)); - - if (mbsmbchar (string) == 0 && mbsmbchar (pattern) == 0 && posix_cclass_only (pattern)) - return (internal_strmatch ((unsigned char *)pattern, (unsigned char *)string, flags)); - - n = xdupmbstowcs (&wpattern, NULL, pattern); - if (n == (size_t)-1 || n == (size_t)-2) - return (internal_strmatch ((unsigned char *)pattern, (unsigned char *)string, flags)); - - n = xdupmbstowcs (&wstring, NULL, string); - if (n == (size_t)-1 || n == (size_t)-2) - { - free (wpattern); - return (internal_strmatch ((unsigned char *)pattern, (unsigned char *)string, flags)); - } - - ret = internal_wstrmatch (wpattern, wstring, flags); - - free (wpattern); - free (wstring); - - return ret; -#else - return (internal_strmatch ((unsigned char *)pattern, (unsigned char *)string, flags)); -#endif /* !HANDLE_MULTIBYTE */ -} diff --git a/third_party/bash/spell.c b/third_party/bash/spell.c deleted file mode 100644 index 2ad89836b..000000000 --- a/third_party/bash/spell.c +++ /dev/null @@ -1,212 +0,0 @@ -/* spell.c -- spelling correction for pathnames. */ - -/* Copyright (C) 2000-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#include "bashtypes.h" -#include "posixdir.h" -#include "posixstat.h" -#if defined (HAVE_SYS_PARAM_H) -#include -#endif - -#include - -#include "bashansi.h" -#include "maxpath.h" -#include "stdc.h" - -static int mindist PARAMS((char *, char *, char *)); -static int spdist PARAMS((char *, char *)); - -/* - * `spname' and its helpers are inspired by the code in "The UNIX - * Programming Environment", Kernighan & Pike, Prentice-Hall 1984, - * pages 209 - 213. - */ - -/* - * `spname' -- return a correctly spelled filename - * - * int spname(char * oldname, char * newname) - * Returns: -1 if no reasonable match found - * 0 if exact match found - * 1 if corrected - * Stores corrected name in `newname'. - */ -int -spname(oldname, newname) - char *oldname; - char *newname; -{ - char *op, *np, *p; - char guess[PATH_MAX + 1], best[PATH_MAX + 1]; - - op = oldname; - np = newname; - for (;;) - { - while (*op == '/') /* Skip slashes */ - *np++ = *op++; - *np = '\0'; - - if (*op == '\0') /* Exact or corrected */ - { - /* `.' is rarely the right thing. */ - if (oldname[1] == '\0' && newname[1] == '\0' && - oldname[0] != '.' && newname[0] == '.') - return -1; - return strcmp(oldname, newname) != 0; - } - - /* Copy next component into guess */ - for (p = guess; *op != '/' && *op != '\0'; op++) - if (p < guess + PATH_MAX) - *p++ = *op; - *p = '\0'; - - if (mindist(newname, guess, best) >= 3) - return -1; /* Hopeless */ - - /* - * Add to end of newname - */ - for (p = best; *np = *p++; np++) - ; - } -} - -/* - * Search directory for a guess - */ -static int -mindist(dir, guess, best) - char *dir; - char *guess; - char *best; -{ - DIR *fd; - struct dirent *dp; - int dist, x; - - dist = 3; /* Worst distance */ - if (*dir == '\0') - dir = "."; - - if ((fd = opendir(dir)) == NULL) - return dist; - - while ((dp = readdir(fd)) != NULL) - { - /* - * Look for a better guess. If the new guess is as - * good as the current one, we take it. This way, - * any single character match will be a better match - * than ".". - */ - x = spdist(dp->d_name, guess); - if (x <= dist && x != 3) - { - strcpy(best, dp->d_name); - dist = x; - if (dist == 0) /* Exact match */ - break; - } - } - (void)closedir(fd); - - /* Don't return `.' */ - if (best[0] == '.' && best[1] == '\0') - dist = 3; - return dist; -} - -/* - * `spdist' -- return the "distance" between two names. - * - * int spname(char * oldname, char * newname) - * Returns: 0 if strings are identical - * 1 if two characters are transposed - * 2 if one character is wrong, added or deleted - * 3 otherwise - */ -static int -spdist(cur, new) - char *cur, *new; -{ - while (*cur == *new) - { - if (*cur == '\0') - return 0; /* Exact match */ - cur++; - new++; - } - - if (*cur) - { - if (*new) - { - if (cur[1] && new[1] && cur[0] == new[1] && cur[1] == new[0] && strcmp (cur + 2, new + 2) == 0) - return 1; /* Transposition */ - - if (strcmp (cur + 1, new + 1) == 0) - return 2; /* One character mismatch */ - } - - if (strcmp(&cur[1], &new[0]) == 0) - return 2; /* Extra character */ - } - - if (*new && strcmp(cur, new + 1) == 0) - return 2; /* Missing character */ - - return 3; -} - -char * -dirspell (dirname) - char *dirname; -{ - int n; - char *guess; - - n = (strlen (dirname) * 3 + 1) / 2 + 1; - guess = (char *)malloc (n); - if (guess == 0) - return 0; - - switch (spname (dirname, guess)) - { - case -1: - default: - free (guess); - return (char *)NULL; - case 0: - case 1: - return guess; - } -} diff --git a/third_party/bash/stat-time.h b/third_party/bash/stat-time.h deleted file mode 100644 index e04cc619e..000000000 --- a/third_party/bash/stat-time.h +++ /dev/null @@ -1,214 +0,0 @@ -/* stat-related time functions. - - Copyright (C) 2005, 2007, 2009-2012 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* Written by Paul Eggert. */ - -#ifndef STAT_TIME_H -#define STAT_TIME_H 1 - -#include - -#if defined (TIME_H_DEFINES_STRUCT_TIMESPEC) -# include -#elif defined (SYS_TIME_H_DEFINES_STRUCT_TIMESPEC) -# include -#elif defined (PTHREAD_H_DEFINES_STRUCT_TIMESPEC) -# include -#endif - -#ifndef HAVE_STRUCT_TIMESPEC -struct timespec -{ - time_t tv_sec; - long int tv_nsec; -}; -#endif - -/* STAT_TIMESPEC (ST, ST_XTIM) is the ST_XTIM member for *ST of type - struct timespec, if available. If not, then STAT_TIMESPEC_NS (ST, - ST_XTIM) is the nanosecond component of the ST_XTIM member for *ST, - if available. ST_XTIM can be st_atim, st_ctim, st_mtim, or st_birthtim - for access, status change, data modification, or birth (creation) - time respectively. - - These macros are private to stat-time.h. */ -#if defined HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC -# ifdef TYPEOF_STRUCT_STAT_ST_ATIM_IS_STRUCT_TIMESPEC -# define STAT_TIMESPEC(st, st_xtim) ((st)->st_xtim) -# else -# define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim.tv_nsec) -# endif -#elif defined HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC -# define STAT_TIMESPEC(st, st_xtim) ((st)->st_xtim##espec) -#elif defined HAVE_STRUCT_STAT_ST_ATIMENSEC -# define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim##ensec) -#elif defined HAVE_STRUCT_STAT_ST_ATIM_ST__TIM_TV_NSEC -# define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim.st__tim.tv_nsec) -#endif - -/* Return the nanosecond component of *ST's access time. */ -static inline long int -get_stat_atime_ns (struct stat const *st) -{ -# if defined STAT_TIMESPEC - return STAT_TIMESPEC (st, st_atim).tv_nsec; -# elif defined STAT_TIMESPEC_NS - return STAT_TIMESPEC_NS (st, st_atim); -# else - return 0; -# endif -} - -/* Return the nanosecond component of *ST's status change time. */ -static inline long int -get_stat_ctime_ns (struct stat const *st) -{ -# if defined STAT_TIMESPEC - return STAT_TIMESPEC (st, st_ctim).tv_nsec; -# elif defined STAT_TIMESPEC_NS - return STAT_TIMESPEC_NS (st, st_ctim); -# else - return 0; -# endif -} - -/* Return the nanosecond component of *ST's data modification time. */ -static inline long int -get_stat_mtime_ns (struct stat const *st) -{ -# if defined STAT_TIMESPEC - return STAT_TIMESPEC (st, st_mtim).tv_nsec; -# elif defined STAT_TIMESPEC_NS - return STAT_TIMESPEC_NS (st, st_mtim); -# else - return 0; -# endif -} - -/* Return the nanosecond component of *ST's birth time. */ -static inline long int -get_stat_birthtime_ns (struct stat const *st) -{ -# if defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC - return STAT_TIMESPEC (st, st_birthtim).tv_nsec; -# elif defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC - return STAT_TIMESPEC_NS (st, st_birthtim); -# else - /* Avoid a "parameter unused" warning. */ - (void) st; - return 0; -# endif -} - -/* Return *ST's access time. */ -static inline struct timespec -get_stat_atime (struct stat const *st) -{ -#ifdef STAT_TIMESPEC - return STAT_TIMESPEC (st, st_atim); -#else - struct timespec t; - t.tv_sec = st->st_atime; - t.tv_nsec = get_stat_atime_ns (st); - return t; -#endif -} - -/* Return *ST's status change time. */ -static inline struct timespec -get_stat_ctime (struct stat const *st) -{ -#ifdef STAT_TIMESPEC - return STAT_TIMESPEC (st, st_ctim); -#else - struct timespec t; - t.tv_sec = st->st_ctime; - t.tv_nsec = get_stat_ctime_ns (st); - return t; -#endif -} - -/* Return *ST's data modification time. */ -static inline struct timespec -get_stat_mtime (struct stat const *st) -{ -#ifdef STAT_TIMESPEC - return STAT_TIMESPEC (st, st_mtim); -#else - struct timespec t; - t.tv_sec = st->st_mtime; - t.tv_nsec = get_stat_mtime_ns (st); - return t; -#endif -} - -static inline int -timespec_cmp (struct timespec a, struct timespec b) -{ - return (a.tv_sec < b.tv_sec - ? -1 - : (a.tv_sec > b.tv_sec - ? 1 - : (int) (a.tv_nsec - b.tv_nsec))); -} - -/* Return *ST's birth time, if available; otherwise return a value - with tv_sec and tv_nsec both equal to -1. */ -static inline struct timespec -get_stat_birthtime (struct stat const *st) -{ - struct timespec t; - -#if (defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC \ - || defined HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC) - t = STAT_TIMESPEC (st, st_birthtim); -#elif defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC - t.tv_sec = st->st_birthtime; - t.tv_nsec = st->st_birthtimensec; -#elif (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ - /* Native Windows platforms (but not Cygwin) put the "file creation - time" in st_ctime (!). See - . */ - t.tv_sec = st->st_ctime; - t.tv_nsec = 0; -#else - /* Birth time is not supported. */ - t.tv_sec = -1; - t.tv_nsec = -1; - /* Avoid a "parameter unused" warning. */ - (void) st; -#endif - -#if (defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC \ - || defined HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC \ - || defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC) - /* FreeBSD and NetBSD sometimes signal the absence of knowledge by - using zero. Attempt to work around this problem. Alas, this can - report failure even for valid time stamps. Also, NetBSD - sometimes returns junk in the birth time fields; work around this - bug if it is detected. */ - if (! (t.tv_sec && 0 <= t.tv_nsec && t.tv_nsec < 1000000000)) - { - t.tv_sec = -1; - t.tv_nsec = -1; - } -#endif - - return t; -} - -#endif diff --git a/third_party/bash/stdc.h b/third_party/bash/stdc.h deleted file mode 100644 index 38516ae5d..000000000 --- a/third_party/bash/stdc.h +++ /dev/null @@ -1,89 +0,0 @@ -/* stdc.h -- macros to make source compile on both ANSI C and K&R C - compilers. */ - -/* Copyright (C) 1993-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_STDC_H_) -#define _STDC_H_ - -/* Adapted from BSD /usr/include/sys/cdefs.h. */ - -/* A function can be defined using prototypes and compile on both ANSI C - and traditional C compilers with something like this: - extern char *func PARAMS((char *, char *, int)); */ - -#if !defined (PARAMS) -# if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus) || defined (PROTOTYPES) -# define PARAMS(protos) protos -# else -# define PARAMS(protos) () -# endif -#endif - -/* Fortify, at least, has trouble with this definition */ -#if defined (HAVE_STRINGIZE) -# define CPP_STRING(x) #x -#else -# define CPP_STRING(x) "x" -#endif - -#if !defined (__STDC__) - -#if defined (__GNUC__) /* gcc with -traditional */ -# if !defined (signed) -# define signed __signed -# endif -# if !defined (volatile) -# define volatile __volatile -# endif -#else /* !__GNUC__ */ -# if !defined (inline) -# define inline -# endif -# if !defined (signed) -# define signed -# endif -# if !defined (volatile) -# define volatile -# endif -#endif /* !__GNUC__ */ - -#endif /* !__STDC__ */ - -#ifndef __attribute__ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) -# define __attribute__(x) -# endif -#endif - -/* For those situations when gcc handles inlining a particular function but - other compilers complain. */ -#ifdef __GNUC__ -# define INLINE inline -#else -# define INLINE -#endif - -#if defined (PREFER_STDARG) -# define SH_VA_START(va, arg) va_start(va, arg) -#else -# define SH_VA_START(va, arg) va_start(va) -#endif - -#endif /* !_STDC_H_ */ diff --git a/third_party/bash/stringlib.c b/third_party/bash/stringlib.c deleted file mode 100644 index 5f25fffd6..000000000 --- a/third_party/bash/stringlib.c +++ /dev/null @@ -1,295 +0,0 @@ -/* stringlib.c - Miscellaneous string functions. */ - -/* Copyright (C) 1996-2009 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include "bashtypes.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "bashansi.h" -#include -#include "chartypes.h" - -#include "shell.h" -#include "pathexp.h" - -#include "glob.h" - -#if defined (EXTENDED_GLOB) -# include "strmatch.h" -#endif - -/* **************************************************************** */ -/* */ -/* Functions to manage arrays of strings */ -/* */ -/* **************************************************************** */ - -/* Find STRING in ALIST, a list of string key/int value pairs. If FLAGS - is 1, STRING is treated as a pattern and matched using strmatch. */ -int -find_string_in_alist (string, alist, flags) - char *string; - STRING_INT_ALIST *alist; - int flags; -{ - register int i; - int r; - - for (i = r = 0; alist[i].word; i++) - { -#if defined (EXTENDED_GLOB) - if (flags) - r = strmatch (alist[i].word, string, FNM_EXTMATCH) != FNM_NOMATCH; - else -#endif - r = STREQ (string, alist[i].word); - - if (r) - return (alist[i].token); - } - return -1; -} - -/* Find TOKEN in ALIST, a list of string/int value pairs. Return the - corresponding string. Allocates memory for the returned - string. FLAGS is currently ignored, but reserved. */ -char * -find_token_in_alist (token, alist, flags) - int token; - STRING_INT_ALIST *alist; - int flags; -{ - register int i; - - for (i = 0; alist[i].word; i++) - { - if (alist[i].token == token) - return (savestring (alist[i].word)); - } - return ((char *)NULL); -} - -int -find_index_in_alist (string, alist, flags) - char *string; - STRING_INT_ALIST *alist; - int flags; -{ - register int i; - int r; - - for (i = r = 0; alist[i].word; i++) - { -#if defined (EXTENDED_GLOB) - if (flags) - r = strmatch (alist[i].word, string, FNM_EXTMATCH) != FNM_NOMATCH; - else -#endif - r = STREQ (string, alist[i].word); - - if (r) - return (i); - } - - return -1; -} - -/* **************************************************************** */ -/* */ -/* String Management Functions */ -/* */ -/* **************************************************************** */ - -/* Cons a new string from STRING starting at START and ending at END, - not including END. */ -char * -substring (string, start, end) - const char *string; - int start, end; -{ - register int len; - register char *result; - - len = end - start; - result = (char *)xmalloc (len + 1); - memcpy (result, string + start, len); - result[len] = '\0'; - return (result); -} - -/* Replace occurrences of PAT with REP in STRING. If GLOBAL is non-zero, - replace all occurrences, otherwise replace only the first. - This returns a new string; the caller should free it. */ -char * -strsub (string, pat, rep, global) - char *string, *pat, *rep; - int global; -{ - size_t patlen, replen, templen, tempsize, i; - int repl; - char *temp, *r; - - patlen = strlen (pat); - replen = strlen (rep); - for (temp = (char *)NULL, i = templen = tempsize = 0, repl = 1; string[i]; ) - { - if (repl && STREQN (string + i, pat, patlen)) - { - if (replen) - RESIZE_MALLOCED_BUFFER (temp, templen, replen, tempsize, (replen * 2)); - - for (r = rep; *r; ) /* can rep == "" */ - temp[templen++] = *r++; - - i += patlen ? patlen : 1; /* avoid infinite recursion */ - repl = global != 0; - } - else - { - RESIZE_MALLOCED_BUFFER (temp, templen, 1, tempsize, 16); - temp[templen++] = string[i++]; - } - } - if (temp) - temp[templen] = 0; - else - temp = savestring (string); - return (temp); -} - -/* Replace all instances of C in STRING with TEXT. TEXT may be empty or - NULL. If (FLAGS & 1) is non-zero, we quote the replacement text for - globbing. Backslash may be used to quote C. If (FLAGS & 2) we allow - backslash to escape backslash as well. */ -char * -strcreplace (string, c, text, flags) - char *string; - int c; - const char *text; - int flags; -{ - char *ret, *p, *r, *t; - size_t len, rlen, ind, tlen; - int do_glob, escape_backslash; - - do_glob = flags & 1; - escape_backslash = flags & 2; - - len = STRLEN (text); - rlen = len + strlen (string) + 2; - ret = (char *)xmalloc (rlen); - - for (p = string, r = ret; p && *p; ) - { - if (*p == c) - { - if (len) - { - ind = r - ret; - if (do_glob && (glob_pattern_p (text) || strchr (text, '\\'))) - { - t = quote_globbing_chars (text); - tlen = strlen (t); - RESIZE_MALLOCED_BUFFER (ret, ind, tlen, rlen, rlen); - r = ret + ind; /* in case reallocated */ - strcpy (r, t); - r += tlen; - free (t); - } - else - { - RESIZE_MALLOCED_BUFFER (ret, ind, len, rlen, rlen); - r = ret + ind; /* in case reallocated */ - strcpy (r, text); - r += len; - } - } - p++; - continue; - } - - if (*p == '\\' && p[1] == c) - p++; - else if (escape_backslash && *p == '\\' && p[1] == '\\') - p++; - - ind = r - ret; - RESIZE_MALLOCED_BUFFER (ret, ind, 2, rlen, rlen); - r = ret + ind; /* in case reallocated */ - *r++ = *p++; - } - *r = '\0'; - - return ret; -} - -#ifdef INCLUDE_UNUSED -/* Remove all leading whitespace from STRING. This includes - newlines. STRING should be terminated with a zero. */ -void -strip_leading (string) - char *string; -{ - char *start = string; - - while (*string && (whitespace (*string) || *string == '\n')) - string++; - - if (string != start) - { - int len = strlen (string); - FASTCOPY (string, start, len); - start[len] = '\0'; - } -} -#endif - -/* Remove all trailing whitespace from STRING. This includes - newlines. If NEWLINES_ONLY is non-zero, only trailing newlines - are removed. STRING should be terminated with a zero. */ -void -strip_trailing (string, len, newlines_only) - char *string; - int len; - int newlines_only; -{ - while (len >= 0) - { - if ((newlines_only && string[len] == '\n') || - (!newlines_only && whitespace (string[len]))) - len--; - else - break; - } - string[len + 1] = '\0'; -} - -/* A wrapper for bcopy that can be prototyped in general.h */ -void -xbcopy (s, d, n) - char *s, *d; - int n; -{ - FASTCOPY (s, d, n); -} diff --git a/third_party/bash/stringlist.c b/third_party/bash/stringlist.c deleted file mode 100644 index 0ad6177b9..000000000 --- a/third_party/bash/stringlist.c +++ /dev/null @@ -1,297 +0,0 @@ -/* stringlist.c - functions to handle a generic `list of strings' structure */ - -/* Copyright (C) 2000-2019 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include -#include "bashansi.h" - -#include "shell.h" - -#ifdef STRDUP -# undef STRDUP -#endif -#define STRDUP(x) ((x) ? savestring (x) : (char *)NULL) - -/* Allocate a new STRINGLIST, with room for N strings. */ - -STRINGLIST * -strlist_create (n) - int n; -{ - STRINGLIST *ret; - register int i; - - ret = (STRINGLIST *)xmalloc (sizeof (STRINGLIST)); - if (n) - { - ret->list = strvec_create (n+1); - ret->list_size = n; - for (i = 0; i < n; i++) - ret->list[i] = (char *)NULL; - } - else - { - ret->list = (char **)NULL; - ret->list_size = 0; - } - ret->list_len = 0; - return ret; -} - -STRINGLIST * -strlist_resize (sl, n) - STRINGLIST *sl; - int n; -{ - register int i; - - if (sl == 0) - return (sl = strlist_create (n)); - - if (n > sl->list_size) - { - sl->list = strvec_resize (sl->list, n + 1); - for (i = sl->list_size; i <= n; i++) - sl->list[i] = (char *)NULL; - sl->list_size = n; - } - return sl; -} - -void -strlist_flush (sl) - STRINGLIST *sl; -{ - if (sl == 0 || sl->list == 0) - return; - strvec_flush (sl->list); - sl->list_len = 0; -} - -void -strlist_dispose (sl) - STRINGLIST *sl; -{ - if (sl == 0) - return; - if (sl->list) - strvec_dispose (sl->list); - free (sl); -} - -int -strlist_remove (sl, s) - STRINGLIST *sl; - char *s; -{ - int r; - - if (sl == 0 || sl->list == 0 || sl->list_len == 0) - return 0; - - r = strvec_remove (sl->list, s); - if (r) - sl->list_len--; - return r; -} - -STRINGLIST * -strlist_copy (sl) - STRINGLIST *sl; -{ - STRINGLIST *new; - register int i; - - if (sl == 0) - return ((STRINGLIST *)0); - new = strlist_create (sl->list_size); - /* I'd like to use strvec_copy, but that doesn't copy everything. */ - if (sl->list) - { - for (i = 0; i < sl->list_size; i++) - new->list[i] = STRDUP (sl->list[i]); - } - new->list_size = sl->list_size; - new->list_len = sl->list_len; - /* just being careful */ - if (new->list) - new->list[new->list_len] = (char *)NULL; - return new; -} - -/* Return a new STRINGLIST with everything from M1 and M2. */ - -STRINGLIST * -strlist_merge (m1, m2) - STRINGLIST *m1, *m2; -{ - STRINGLIST *sl; - int i, n, l1, l2; - - l1 = m1 ? m1->list_len : 0; - l2 = m2 ? m2->list_len : 0; - - sl = strlist_create (l1 + l2 + 1); - for (i = n = 0; i < l1; i++, n++) - sl->list[n] = STRDUP (m1->list[i]); - for (i = 0; i < l2; i++, n++) - sl->list[n] = STRDUP (m2->list[i]); - sl->list_len = n; - sl->list[n] = (char *)NULL; - return (sl); -} - -/* Make STRINGLIST M1 contain everything in M1 and M2. */ -STRINGLIST * -strlist_append (m1, m2) - STRINGLIST *m1, *m2; -{ - register int i, n, len1, len2; - - if (m1 == 0) - return (m2 ? strlist_copy (m2) : (STRINGLIST *)0); - - len1 = m1->list_len; - len2 = m2 ? m2->list_len : 0; - - if (len2) - { - m1 = strlist_resize (m1, len1 + len2 + 1); - for (i = 0, n = len1; i < len2; i++, n++) - m1->list[n] = STRDUP (m2->list[i]); - m1->list[n] = (char *)NULL; - m1->list_len = n; - } - - return m1; -} - -STRINGLIST * -strlist_prefix_suffix (sl, prefix, suffix) - STRINGLIST *sl; - char *prefix, *suffix; -{ - int plen, slen, tlen, llen, i; - char *t; - - if (sl == 0 || sl->list == 0 || sl->list_len == 0) - return sl; - - plen = STRLEN (prefix); - slen = STRLEN (suffix); - - if (plen == 0 && slen == 0) - return (sl); - - for (i = 0; i < sl->list_len; i++) - { - llen = STRLEN (sl->list[i]); - tlen = plen + llen + slen + 1; - t = (char *)xmalloc (tlen + 1); - if (plen) - strcpy (t, prefix); - strcpy (t + plen, sl->list[i]); - if (slen) - strcpy (t + plen + llen, suffix); - free (sl->list[i]); - sl->list[i] = t; - } - - return (sl); -} - -void -strlist_print (sl, prefix) - STRINGLIST *sl; - char *prefix; -{ - register int i; - - if (sl == 0) - return; - for (i = 0; i < sl->list_len; i++) - printf ("%s%s\n", prefix ? prefix : "", sl->list[i]); -} - -void -strlist_walk (sl, func) - STRINGLIST *sl; - sh_strlist_map_func_t *func; -{ - register int i; - - if (sl == 0) - return; - for (i = 0; i < sl->list_len; i++) - if ((*func)(sl->list[i]) < 0) - break; -} - -void -strlist_sort (sl) - STRINGLIST *sl; -{ - if (sl == 0 || sl->list_len == 0 || sl->list == 0) - return; - strvec_sort (sl->list, 0); -} - -STRINGLIST * -strlist_from_word_list (list, alloc, starting_index, ip) - WORD_LIST *list; - int alloc, starting_index, *ip; -{ - STRINGLIST *ret; - int slen, len; - - if (list == 0) - { - if (ip) - *ip = 0; - return ((STRINGLIST *)0); - } - slen = list_length (list); - ret = (STRINGLIST *)xmalloc (sizeof (STRINGLIST)); - ret->list = strvec_from_word_list (list, alloc, starting_index, &len); - ret->list_size = slen + starting_index; - ret->list_len = len; - if (ip) - *ip = len; - return ret; -} - -WORD_LIST * -strlist_to_word_list (sl, alloc, starting_index) - STRINGLIST *sl; - int alloc, starting_index; -{ - WORD_LIST *list; - - if (sl == 0 || sl->list == 0) - return ((WORD_LIST *)NULL); - - list = strvec_to_word_list (sl->list, alloc, starting_index); - return list; -} diff --git a/third_party/bash/stringvec.c b/third_party/bash/stringvec.c deleted file mode 100644 index 52693c6e3..000000000 --- a/third_party/bash/stringvec.c +++ /dev/null @@ -1,272 +0,0 @@ -/* stringvec.c - functions for managing arrays of strings. */ - -/* Copyright (C) 2000-2002 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include "bashtypes.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "bashansi.h" -#include -#include "chartypes.h" - -#include "shell.h" - -/* Allocate an array of strings with room for N members. */ -char ** -strvec_create (n) - int n; -{ - return ((char **)xmalloc ((n) * sizeof (char *))); -} - -/* Allocate an array of strings with room for N members. */ -char ** -strvec_mcreate (n) - int n; -{ - return ((char **)malloc ((n) * sizeof (char *))); -} - -char ** -strvec_resize (array, nsize) - char **array; - int nsize; -{ - return ((char **)xrealloc (array, nsize * sizeof (char *))); -} - -char ** -strvec_mresize (array, nsize) - char **array; - int nsize; -{ - return ((char **)realloc (array, nsize * sizeof (char *))); -} - -/* Return the length of ARRAY, a NULL terminated array of char *. */ -int -strvec_len (array) - char **array; -{ - register int i; - - for (i = 0; array[i]; i++); - return (i); -} - -/* Free the contents of ARRAY, a NULL terminated array of char *. */ -void -strvec_flush (array) - char **array; -{ - register int i; - - if (array == 0) - return; - - for (i = 0; array[i]; i++) - free (array[i]); -} - -void -strvec_dispose (array) - char **array; -{ - if (array == 0) - return; - - strvec_flush (array); - free (array); -} - -int -strvec_remove (array, name) - char **array, *name; -{ - register int i, j; - char *x; - - if (array == 0) - return 0; - - for (i = 0; array[i]; i++) - if (STREQ (name, array[i])) - { - x = array[i]; - for (j = i; array[j]; j++) - array[j] = array[j + 1]; - free (x); - return 1; - } - return 0; -} - -/* Find NAME in ARRAY. Return the index of NAME, or -1 if not present. - ARRAY should be NULL terminated. */ -int -strvec_search (array, name) - char **array, *name; -{ - int i; - - for (i = 0; array[i]; i++) - if (STREQ (name, array[i])) - return (i); - - return (-1); -} - -/* Allocate and return a new copy of ARRAY and its contents. */ -char ** -strvec_copy (array) - char **array; -{ - register int i; - int len; - char **ret; - - len = strvec_len (array); - - ret = (char **)xmalloc ((len + 1) * sizeof (char *)); - for (i = 0; array[i]; i++) - ret[i] = savestring (array[i]); - ret[i] = (char *)NULL; - - return (ret); -} - -/* Comparison routine for use by qsort that conforms to the new Posix - requirements (http://austingroupbugs.net/view.php?id=1070). - - Perform a bytewise comparison if *S1 and *S2 collate equally. */ -int -strvec_posixcmp (s1, s2) - register char **s1, **s2; -{ - int result; - -#if defined (HAVE_STRCOLL) - result = strcoll (*s1, *s2); - if (result != 0) - return result; -#endif - - if ((result = **s1 - **s2) == 0) - result = strcmp (*s1, *s2); - - return (result); -} - -/* Comparison routine for use with qsort() on arrays of strings. Uses - strcoll(3) if available, otherwise it uses strcmp(3). */ -int -strvec_strcmp (s1, s2) - register char **s1, **s2; -{ -#if defined (HAVE_STRCOLL) - return (strcoll (*s1, *s2)); -#else /* !HAVE_STRCOLL */ - int result; - - if ((result = **s1 - **s2) == 0) - result = strcmp (*s1, *s2); - - return (result); -#endif /* !HAVE_STRCOLL */ -} - -/* Sort ARRAY, a null terminated array of pointers to strings. */ -void -strvec_sort (array, posix) - char **array; - int posix; -{ - if (posix) - qsort (array, strvec_len (array), sizeof (char *), (QSFUNC *)strvec_posixcmp); - else - qsort (array, strvec_len (array), sizeof (char *), (QSFUNC *)strvec_strcmp); -} - -/* Cons up a new array of words. The words are taken from LIST, - which is a WORD_LIST *. If ALLOC is true, everything is malloc'ed, - so you should free everything in this array when you are done. - The array is NULL terminated. If IP is non-null, it gets the - number of words in the returned array. STARTING_INDEX says where - to start filling in the returned array; it can be used to reserve - space at the beginning of the array. */ - -char ** -strvec_from_word_list (list, alloc, starting_index, ip) - WORD_LIST *list; - int alloc, starting_index, *ip; -{ - int count; - char **array; - - count = list_length (list); - array = (char **)xmalloc ((1 + count + starting_index) * sizeof (char *)); - - for (count = 0; count < starting_index; count++) - array[count] = (char *)NULL; - for (count = starting_index; list; count++, list = list->next) - array[count] = alloc ? savestring (list->word->word) : list->word->word; - array[count] = (char *)NULL; - - if (ip) - *ip = count; - return (array); -} - -/* Convert an array of strings into the form used internally by the shell. - ALLOC means to allocate new storage for each WORD_DESC in the returned - list rather than copy the values in ARRAY. STARTING_INDEX says where - in ARRAY to begin. */ - -WORD_LIST * -strvec_to_word_list (array, alloc, starting_index) - char **array; - int alloc, starting_index; -{ - WORD_LIST *list; - WORD_DESC *w; - int i, count; - - if (array == 0 || array[0] == 0) - return (WORD_LIST *)NULL; - - for (count = 0; array[count]; count++) - ; - - for (i = starting_index, list = (WORD_LIST *)NULL; i < count; i++) - { - w = make_bare_word (alloc ? array[i] : ""); - if (alloc == 0) - { - free (w->word); - w->word = array[i]; - } - list = make_word_list (w, list); - } - return (REVERSE_LIST (list, WORD_LIST *)); -} diff --git a/third_party/bash/strmatch.c b/third_party/bash/strmatch.c deleted file mode 100644 index 0de45eb41..000000000 --- a/third_party/bash/strmatch.c +++ /dev/null @@ -1,79 +0,0 @@ -/* strmatch.c -- ksh-like extended pattern matching for the shell and filename - globbing. */ - -/* Copyright (C) 1991-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include "stdc.h" -#include "strmatch.h" - -extern int xstrmatch PARAMS((char *, char *, int)); -#if defined (HANDLE_MULTIBYTE) -extern int internal_wstrmatch PARAMS((wchar_t *, wchar_t *, int)); -#endif - -int -strmatch (pattern, string, flags) - char *pattern; - char *string; - int flags; -{ - if (string == 0 || pattern == 0) - return FNM_NOMATCH; - - return (xstrmatch (pattern, string, flags)); -} - -#if defined (HANDLE_MULTIBYTE) -int -wcsmatch (wpattern, wstring, flags) - wchar_t *wpattern; - wchar_t *wstring; - int flags; -{ - if (wstring == 0 || wpattern == 0) - return (FNM_NOMATCH); - - return (internal_wstrmatch (wpattern, wstring, flags)); -} -#endif - -#ifdef TEST -main (c, v) - int c; - char **v; -{ - char *string, *pat; - - string = v[1]; - pat = v[2]; - - if (strmatch (pat, string, 0) == 0) - { - printf ("%s matches %s\n", string, pat); - exit (0); - } - else - { - printf ("%s does not match %s\n", string, pat); - exit (1); - } -} -#endif diff --git a/third_party/bash/strmatch.h b/third_party/bash/strmatch.h deleted file mode 100644 index b1efad907..000000000 --- a/third_party/bash/strmatch.h +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright (C) 1991-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne-Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#ifndef _STRMATCH_H -#define _STRMATCH_H 1 - -#include "config.h" - -#include "stdc.h" - -/* We #undef these before defining them because some losing systems - (HP-UX A.08.07 for example) define these in . */ -#undef FNM_PATHNAME -#undef FNM_NOESCAPE -#undef FNM_PERIOD - -/* Bits set in the FLAGS argument to `strmatch'. */ - -/* standard flags are like fnmatch(3). */ -#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */ -#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */ -#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */ - -/* extended flags not available in most libc fnmatch versions, but we undef - them to avoid any possible warnings. */ -#undef FNM_LEADING_DIR -#undef FNM_CASEFOLD -#undef FNM_EXTMATCH - -#define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */ -#define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */ -#define FNM_EXTMATCH (1 << 5) /* Use ksh-like extended matching. */ - -#define FNM_FIRSTCHAR (1 << 6) /* Match only the first character */ -#define FNM_DOTDOT (1 << 7) /* force `.' and `..' to match explicitly even if FNM_PERIOD not supplied. */ - -/* Value returned by `strmatch' if STRING does not match PATTERN. */ -#undef FNM_NOMATCH - -#define FNM_NOMATCH 1 - -/* Match STRING against the filename pattern PATTERN, - returning zero if it matches, FNM_NOMATCH if not. */ -extern int strmatch PARAMS((char *, char *, int)); - -#if HANDLE_MULTIBYTE -extern int wcsmatch PARAMS((wchar_t *, wchar_t *, int)); -#endif - -#endif /* _STRMATCH_H */ diff --git a/third_party/bash/strtrans.c b/third_party/bash/strtrans.c deleted file mode 100644 index aae07a82b..000000000 --- a/third_party/bash/strtrans.c +++ /dev/null @@ -1,400 +0,0 @@ -/* strtrans.c - Translate and untranslate strings with ANSI-C escape sequences. */ - -/* Copyright (C) 2000-2015 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "bashansi.h" -#include -#include "chartypes.h" - -#include "shell.h" - -#include "shmbchar.h" -#include "shmbutil.h" - -#ifdef ESC -#undef ESC -#endif -#define ESC '\033' /* ASCII */ - -/* Convert STRING by expanding the escape sequences specified by the - ANSI C standard. If SAWC is non-null, recognize `\c' and use that - as a string terminator. If we see \c, set *SAWC to 1 before - returning. LEN is the length of STRING. If (FLAGS&1) is non-zero, - that we're translating a string for `echo -e', and therefore should not - treat a single quote as a character that may be escaped with a backslash. - If (FLAGS&2) is non-zero, we're expanding for the parser and want to - quote CTLESC and CTLNUL with CTLESC. If (flags&4) is non-zero, we want - to remove the backslash before any unrecognized escape sequence. */ -char * -ansicstr (string, len, flags, sawc, rlen) - char *string; - int len, flags, *sawc, *rlen; -{ - int c, temp; - char *ret, *r, *s; - unsigned long v; - size_t clen; - int b, mb_cur_max; -#if defined (HANDLE_MULTIBYTE) - wchar_t wc; -#endif - - if (string == 0 || *string == '\0') - return ((char *)NULL); - - mb_cur_max = MB_CUR_MAX; -#if defined (HANDLE_MULTIBYTE) - temp = 4*len + 4; - if (temp < 12) - temp = 12; /* ensure enough for eventual u32cesc */ - ret = (char *)xmalloc (temp); -#else - ret = (char *)xmalloc (2*len + 1); /* 2*len for possible CTLESC */ -#endif - for (r = ret, s = string; s && *s; ) - { - c = *s++; - if (c != '\\' || *s == '\0') - { - clen = 1; -#if defined (HANDLE_MULTIBYTE) - if ((locale_utf8locale && (c & 0x80)) || - (locale_utf8locale == 0 && mb_cur_max > 0 && is_basic (c) == 0)) - { - clen = mbrtowc (&wc, s - 1, mb_cur_max, 0); - if (MB_INVALIDCH (clen)) - clen = 1; - } -#endif - *r++ = c; - for (--clen; clen > 0; clen--) - *r++ = *s++; - } - else - { - switch (c = *s++) - { -#if defined (__STDC__) - case 'a': c = '\a'; break; - case 'v': c = '\v'; break; -#else - case 'a': c = (int) 0x07; break; - case 'v': c = (int) 0x0B; break; -#endif - case 'b': c = '\b'; break; - case 'e': case 'E': /* ESC -- non-ANSI */ - c = ESC; break; - case 'f': c = '\f'; break; - case 'n': c = '\n'; break; - case 'r': c = '\r'; break; - case 't': c = '\t'; break; - case '1': case '2': case '3': - case '4': case '5': case '6': - case '7': -#if 1 - if (flags & 1) - { - *r++ = '\\'; - break; - } - /*FALLTHROUGH*/ -#endif - case '0': - /* If (FLAGS & 1), we're translating a string for echo -e (or - the equivalent xpg_echo option), so we obey the SUSv3/ - POSIX-2001 requirement and accept 0-3 octal digits after - a leading `0'. */ - temp = 2 + ((flags & 1) && (c == '0')); - for (c -= '0'; ISOCTAL (*s) && temp--; s++) - c = (c * 8) + OCTVALUE (*s); - c &= 0xFF; - break; - case 'x': /* Hex digit -- non-ANSI */ - if ((flags & 2) && *s == '{') - { - flags |= 16; /* internal flag value */ - s++; - } - /* Consume at least two hex characters */ - for (temp = 2, c = 0; ISXDIGIT ((unsigned char)*s) && temp--; s++) - c = (c * 16) + HEXVALUE (*s); - /* DGK says that after a `\x{' ksh93 consumes ISXDIGIT chars - until a non-xdigit or `}', so potentially more than two - chars are consumed. */ - if (flags & 16) - { - for ( ; ISXDIGIT ((unsigned char)*s); s++) - c = (c * 16) + HEXVALUE (*s); - flags &= ~16; - if (*s == '}') - s++; - } - /* \x followed by non-hex digits is passed through unchanged */ - else if (temp == 2) - { - *r++ = '\\'; - c = 'x'; - } - c &= 0xFF; - break; -#if defined (HANDLE_MULTIBYTE) - case 'u': - case 'U': - temp = (c == 'u') ? 4 : 8; /* \uNNNN \UNNNNNNNN */ - for (v = 0; ISXDIGIT ((unsigned char)*s) && temp--; s++) - v = (v * 16) + HEXVALUE (*s); - if (temp == ((c == 'u') ? 4 : 8)) - { - *r++ = '\\'; /* c remains unchanged */ - break; - } - else if (v <= 0x7f) /* <= 0x7f translates directly */ - { - c = v; - break; - } - else - { - temp = u32cconv (v, r); - r += temp; - continue; - } -#endif - case '\\': - break; - case '\'': case '"': case '?': - if (flags & 1) - *r++ = '\\'; - break; - case 'c': - if (sawc) - { - *sawc = 1; - *r = '\0'; - if (rlen) - *rlen = r - ret; - return ret; - } - else if ((flags & 1) == 0 && *s == 0) - ; /* pass \c through */ - else if ((flags & 1) == 0 && (c = *s)) - { - s++; - if ((flags & 2) && c == '\\' && c == *s) - s++; /* Posix requires $'\c\\' do backslash escaping */ - c = TOCTRL(c); - break; - } - /*FALLTHROUGH*/ - default: - if ((flags & 4) == 0) - *r++ = '\\'; - break; - } - if ((flags & 2) && (c == CTLESC || c == CTLNUL)) - *r++ = CTLESC; - *r++ = c; - } - } - *r = '\0'; - if (rlen) - *rlen = r - ret; - return ret; -} - -/* Take a string STR, possibly containing non-printing characters, and turn it - into a $'...' ANSI-C style quoted string. Returns a new string. */ -char * -ansic_quote (str, flags, rlen) - char *str; - int flags, *rlen; -{ - char *r, *ret, *s; - int l, rsize; - unsigned char c; - size_t clen; - int b; -#if defined (HANDLE_MULTIBYTE) - wchar_t wc; -#endif - - if (str == 0 || *str == 0) - return ((char *)0); - - l = strlen (str); - rsize = 4 * l + 4; - r = ret = (char *)xmalloc (rsize); - - *r++ = '$'; - *r++ = '\''; - - for (s = str; c = *s; s++) - { - b = l = 1; /* 1 == add backslash; 0 == no backslash */ - clen = 1; - - switch (c) - { - case ESC: c = 'E'; break; -#ifdef __STDC__ - case '\a': c = 'a'; break; - case '\v': c = 'v'; break; -#else - case 0x07: c = 'a'; break; - case 0x0b: c = 'v'; break; -#endif - - case '\b': c = 'b'; break; - case '\f': c = 'f'; break; - case '\n': c = 'n'; break; - case '\r': c = 'r'; break; - case '\t': c = 't'; break; - case '\\': - case '\'': - break; - default: -#if defined (HANDLE_MULTIBYTE) - b = is_basic (c); - /* XXX - clen comparison to 0 is dicey */ - if ((b == 0 && ((clen = mbrtowc (&wc, s, MB_CUR_MAX, 0)) < 0 || MB_INVALIDCH (clen) || iswprint (wc) == 0)) || - (b == 1 && ISPRINT (c) == 0)) -#else - if (ISPRINT (c) == 0) -#endif - { - *r++ = '\\'; - *r++ = TOCHAR ((c >> 6) & 07); - *r++ = TOCHAR ((c >> 3) & 07); - *r++ = TOCHAR (c & 07); - continue; - } - l = 0; - break; - } - if (b == 0 && clen == 0) - break; - - if (l) - *r++ = '\\'; - - if (clen == 1) - *r++ = c; - else - { - for (b = 0; b < (int)clen; b++) - *r++ = (unsigned char)s[b]; - s += clen - 1; /* -1 because of the increment above */ - } - } - - *r++ = '\''; - *r = '\0'; - if (rlen) - *rlen = r - ret; - return ret; -} - -#if defined (HANDLE_MULTIBYTE) -int -ansic_wshouldquote (string) - const char *string; -{ - const wchar_t *wcs; - wchar_t wcc; - wchar_t *wcstr = NULL; - size_t slen; - - slen = mbstowcs (wcstr, string, 0); - - if (slen == (size_t)-1) - return 1; - - wcstr = (wchar_t *)xmalloc (sizeof (wchar_t) * (slen + 1)); - mbstowcs (wcstr, string, slen + 1); - - for (wcs = wcstr; wcc = *wcs; wcs++) - if (iswprint(wcc) == 0) - { - free (wcstr); - return 1; - } - - free (wcstr); - return 0; -} -#endif - -/* return 1 if we need to quote with $'...' because of non-printing chars. */ -int -ansic_shouldquote (string) - const char *string; -{ - const char *s; - unsigned char c; - - if (string == 0) - return 0; - - for (s = string; c = *s; s++) - { -#if defined (HANDLE_MULTIBYTE) - if (is_basic (c) == 0) - return (ansic_wshouldquote (s)); -#endif - if (ISPRINT (c) == 0) - return 1; - } - - return 0; -} - -/* $'...' ANSI-C expand the portion of STRING between START and END and - return the result. The result cannot be longer than the input string. */ -char * -ansiexpand (string, start, end, lenp) - char *string; - int start, end, *lenp; -{ - char *temp, *t; - int len, tlen; - - temp = (char *)xmalloc (end - start + 1); - for (tlen = 0, len = start; len < end; ) - temp[tlen++] = string[len++]; - temp[tlen] = '\0'; - - if (*temp) - { - t = ansicstr (temp, tlen, 2, (int *)NULL, lenp); - free (temp); - return (t); - } - else - { - if (lenp) - *lenp = 0; - return (temp); - } -} diff --git a/third_party/bash/strvis.c b/third_party/bash/strvis.c deleted file mode 100644 index 6d8a5f32f..000000000 --- a/third_party/bash/strvis.c +++ /dev/null @@ -1,154 +0,0 @@ -/* strvis.c - make unsafe graphical characters in a string visible. */ - -/* Copyright (C) 2022 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -/* This is a stripped-down version suitable for the shell's use. */ -#include "config.h" - -#include - -#include "bashansi.h" -#include - -#include "chartypes.h" -#include "bashintl.h" -#include "shmbutil.h" - -#define SAFECHAR(c) ((c) == ' ' || (c) == '\t') - -#ifndef RUBOUT -#define RUBOUT 0x7f -#endif - -#ifndef CTRL_CHAR -#define CTRL_CHAR(c) ((c) < 0x20) -#endif - -#ifndef META_CHAR -#define META_CHAR(c) ((c) > 0x7f && (c) <= UCHAR_MAX) -#endif - -#ifndef UNCTRL -#define UNCTRL(c) (TOUPPER ((c) | 0x40)) -#endif - -#ifndef UNMETA -#define UNMETA(c) ((c) & 0x7f) -#endif - -int -sh_charvis (s, sindp, slen, ret, rindp) - const char *s; - size_t *sindp; - size_t slen; - char *ret; - size_t *rindp; -{ - unsigned char c; - size_t si, ri; - const char *send; - DECLARE_MBSTATE; - - si = *sindp; - ri = *rindp; - c = s[*sindp]; - -#if defined (HANDLE_MULTIBYTE) - send = (locale_mb_cur_max > 1) ? s + slen : 0; -#else - send = 0; -#endif - - if (SAFECHAR (c)) - { - ret[ri++] = c; - si++; - } - else if (c == RUBOUT) - { - ret[ri++] = '^'; - ret[ri++] = '?'; - si++; - } - else if (CTRL_CHAR (c)) - { - ret[ri++] = '^'; - ret[ri++] = UNCTRL (c); - si++; - } -#if defined (HANDLE_MULTIBYTE) - else if (locale_utf8locale && (c & 0x80)) - COPY_CHAR_I (ret, ri, s, send, si); - else if (locale_mb_cur_max > 1 && is_basic (c) == 0) - COPY_CHAR_I (ret, ri, s, send, si); -#endif - else if (META_CHAR (c)) - { - ret[ri++] = 'M'; - ret[ri++] = '-'; - ret[ri++] = UNMETA (c); - si++; - } - else - ret[ri++] = s[si++]; - - *sindp = si; - *rindp = ri; - - return si; -} - -/* Return a new string with `unsafe' non-graphical characters in S rendered - in a visible way. */ -char * -sh_strvis (string) - const char *string; -{ - size_t slen, sind; - char *ret; - size_t retind, retsize; - unsigned char c; - DECLARE_MBSTATE; - - if (string == 0) - return 0; - if (*string == '\0') - { - if ((ret = (char *)malloc (1)) == 0) - return 0; - ret[0] = '\0'; - return ret; - } - - slen = strlen (string); - retsize = 3 * slen + 1; - - ret = (char *)malloc (retsize); - if (ret == 0) - return 0; - - retind = 0; - sind = 0; - - while (string[sind]) - sind = sh_charvis (string, &sind, slen, ret, &retind); - - ret[retind] = '\0'; - return ret; -} diff --git a/third_party/bash/subst.c b/third_party/bash/subst.c deleted file mode 100644 index b682a84ca..000000000 --- a/third_party/bash/subst.c +++ /dev/null @@ -1,13006 +0,0 @@ -/* subst.c -- The part of the shell that does parameter, command, arithmetic, - and globbing substitutions. */ - -/* ``Have a little faith, there's magic in the night. You ain't a - beauty, but, hey, you're alright.'' */ - -/* Copyright (C) 1987-2022 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include "bashtypes.h" -#include -#include "chartypes.h" -#if defined (HAVE_PWD_H) -# include -#endif -#include -#include - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#define NEED_FPURGE_DECL - -#include "bashansi.h" -#include "posixstat.h" -#include "bashintl.h" - -#include "shell.h" -#include "parser.h" -#include "redir.h" -#include "flags.h" -#include "jobs.h" -#include "execute_cmd.h" -#include "filecntl.h" -#include "trap.h" -#include "pathexp.h" -#include "mailcheck.h" - -#include "shmbutil.h" -#if defined (HAVE_MBSTR_H) && defined (HAVE_MBSCHR) -# include /* mbschr */ -#endif -#include "typemax.h" - -#include "getopt.h" -#include "common.h" - -#include "builtext.h" - -#include "tilde.h" -#include "strmatch.h" - -#if !defined (errno) -extern int errno; -#endif /* !errno */ - -/* The size that strings change by. */ -#define DEFAULT_INITIAL_ARRAY_SIZE 112 -#define DEFAULT_ARRAY_SIZE 128 - -/* Variable types. */ -#define VT_VARIABLE 0 -#define VT_POSPARMS 1 -#define VT_ARRAYVAR 2 -#define VT_ARRAYMEMBER 3 -#define VT_ASSOCVAR 4 - -#define VT_STARSUB 128 /* $* or ${array[*]} -- used to split */ - -/* Flags for quoted_strchr */ -#define ST_BACKSL 0x01 -#define ST_CTLESC 0x02 -#define ST_SQUOTE 0x04 /* unused yet */ -#define ST_DQUOTE 0x08 /* unused yet */ - -/* These defs make it easier to use the editor. */ -#define LBRACE '{' -#define RBRACE '}' -#define LPAREN '(' -#define RPAREN ')' -#define LBRACK '[' -#define RBRACK ']' - -#if defined (HANDLE_MULTIBYTE) -#define WLPAREN L'(' -#define WRPAREN L')' -#endif - -#define DOLLAR_AT_STAR(c) ((c) == '@' || (c) == '*') -#define STR_DOLLAR_AT_STAR(s) (DOLLAR_AT_STAR ((s)[0]) && (s)[1] == '\0') - -/* Evaluates to 1 if C is one of the shell's special parameters whose length - can be taken, but is also one of the special expansion characters. */ -#define VALID_SPECIAL_LENGTH_PARAM(c) \ - ((c) == '-' || (c) == '?' || (c) == '#' || (c) == '@') - -/* Evaluates to 1 if C is one of the shell's special parameters for which an - indirect variable reference may be made. */ -#define VALID_INDIR_PARAM(c) \ - ((posixly_correct == 0 && (c) == '#') || (posixly_correct == 0 && (c) == '?') || (c) == '@' || (c) == '*') - -/* Evaluates to 1 if C is one of the OP characters that follows the parameter - in ${parameter[:]OPword}. */ -#define VALID_PARAM_EXPAND_CHAR(c) (sh_syntaxtab[(unsigned char)c] & CSUBSTOP) - -/* Evaluates to 1 if this is one of the shell's special variables. */ -#define SPECIAL_VAR(name, wi) \ - (*name && ((DIGIT (*name) && all_digits (name)) || \ - (name[1] == '\0' && (sh_syntaxtab[(unsigned char)*name] & CSPECVAR)) || \ - (wi && name[2] == '\0' && VALID_INDIR_PARAM (name[1])))) - -/* This can be used by all of the *_extract_* functions that have a similar - structure. It can't just be wrapped in a do...while(0) loop because of - the embedded `break'. The dangling else accommodates a trailing semicolon; - we could also put in a do ; while (0) */ - -#define CHECK_STRING_OVERRUN(oind, ind, len, ch) \ - if (ind >= len) \ - { \ - oind = len; \ - ch = 0; \ - break; \ - } \ - else \ - -/* An expansion function that takes a string and a quoted flag and returns - a WORD_LIST *. Used as the type of the third argument to - expand_string_if_necessary(). */ -typedef WORD_LIST *EXPFUNC PARAMS((char *, int)); - -/* Process ID of the last command executed within command substitution. */ -pid_t last_command_subst_pid = NO_PID; -pid_t current_command_subst_pid = NO_PID; - -/* Variables used to keep track of the characters in IFS. */ -SHELL_VAR *ifs_var; -char *ifs_value; -unsigned char ifs_cmap[UCHAR_MAX + 1]; -int ifs_is_set, ifs_is_null; - -#if defined (HANDLE_MULTIBYTE) -unsigned char ifs_firstc[MB_LEN_MAX]; -size_t ifs_firstc_len; -#else -unsigned char ifs_firstc; -#endif - -/* If non-zero, command substitution inherits the value of errexit option */ -int inherit_errexit = 0; - -/* Sentinel to tell when we are performing variable assignments preceding a - command name and putting them into the environment. Used to make sure - we use the temporary environment when looking up variable values. */ -int assigning_in_environment; - -/* Used to hold a list of variable assignments preceding a command. Global - so the SIGCHLD handler in jobs.c can unwind-protect it when it runs a - SIGCHLD trap and so it can be saved and restored by the trap handlers. */ -WORD_LIST *subst_assign_varlist = (WORD_LIST *)NULL; - -/* Tell the expansion functions to not longjmp back to top_level on fatal - errors. Enabled when doing completion and prompt string expansion. */ -int no_longjmp_on_fatal_error = 0; - -/* Non-zero means to allow unmatched globbed filenames to expand to - a null file. */ -int allow_null_glob_expansion; - -/* Non-zero means to throw an error when globbing fails to match anything. */ -int fail_glob_expansion; - -/* If non-zero, perform `&' substitution on the replacement string in the - pattern substitution word expansion. */ -int patsub_replacement = 1; - -/* Extern functions and variables from different files. */ -extern struct fd_bitmap *current_fds_to_close; -extern int wordexp_only; -extern int singlequote_translations; -extern int extended_quote; - -#if defined (JOB_CONTROL) && defined (PROCESS_SUBSTITUTION) -extern PROCESS *last_procsub_child; -#endif - -#if !defined (HAVE_WCSDUP) && defined (HANDLE_MULTIBYTE) -extern wchar_t *wcsdup PARAMS((const wchar_t *)); -#endif - -#if 0 -/* Variables to keep track of which words in an expanded word list (the - output of expand_word_list_internal) are the result of globbing - expansions. GLOB_ARGV_FLAGS is used by execute_cmd.c. - (CURRENTLY UNUSED). */ -char *glob_argv_flags; -static int glob_argv_flags_size; -#endif - -static WORD_LIST *cached_quoted_dollar_at = 0; - -/* Distinguished error values to return from expansion functions */ -static WORD_LIST expand_word_error, expand_word_fatal; -static WORD_DESC expand_wdesc_error, expand_wdesc_fatal; -static char expand_param_error, expand_param_fatal, expand_param_unset; -static char extract_string_error, extract_string_fatal; - -/* Set by expand_word_unsplit and several of the expand_string_XXX functions; - used to inhibit splitting and re-joining $* on $IFS, primarily when doing - assignment statements. The idea is that if we're in a context where this - is set, we're not going to be performing word splitting, so we use the same - rules to expand $* as we would if it appeared within double quotes. */ -static int expand_no_split_dollar_star = 0; - -/* A WORD_LIST of words to be expanded by expand_word_list_internal, - without any leading variable assignments. */ -static WORD_LIST *garglist = (WORD_LIST *)NULL; - -static char *quoted_substring PARAMS((char *, int, int)); -static int quoted_strlen PARAMS((char *)); -static char *quoted_strchr PARAMS((char *, int, int)); - -static char *expand_string_if_necessary PARAMS((char *, int, EXPFUNC *)); -static inline char *expand_string_to_string_internal PARAMS((char *, int, EXPFUNC *)); -static WORD_LIST *call_expand_word_internal PARAMS((WORD_DESC *, int, int, int *, int *)); -static WORD_LIST *expand_string_internal PARAMS((char *, int)); -static WORD_LIST *expand_string_leave_quoted PARAMS((char *, int)); -static WORD_LIST *expand_string_for_rhs PARAMS((char *, int, int, int, int *, int *)); -static WORD_LIST *expand_string_for_pat PARAMS((char *, int, int *, int *)); - -static char *quote_escapes_internal PARAMS((const char *, int)); - -static WORD_LIST *list_quote_escapes PARAMS((WORD_LIST *)); -static WORD_LIST *list_dequote_escapes PARAMS((WORD_LIST *)); - -static char *make_quoted_char PARAMS((int)); -static WORD_LIST *quote_list PARAMS((WORD_LIST *)); - -static int unquoted_substring PARAMS((char *, char *)); -static int unquoted_member PARAMS((int, char *)); - -#if defined (ARRAY_VARS) -static SHELL_VAR *do_compound_assignment PARAMS((char *, char *, int)); -#endif -static int do_assignment_internal PARAMS((const WORD_DESC *, int)); - -static char *string_extract_verbatim PARAMS((char *, size_t, int *, char *, int)); -static char *string_extract PARAMS((char *, int *, char *, int)); -static char *string_extract_double_quoted PARAMS((char *, int *, int)); -static inline char *string_extract_single_quoted PARAMS((char *, int *, int)); -static inline int skip_single_quoted PARAMS((const char *, size_t, int, int)); -static int skip_double_quoted PARAMS((char *, size_t, int, int)); -static char *extract_delimited_string PARAMS((char *, int *, char *, char *, char *, int)); -static char *extract_heredoc_dolbrace_string PARAMS((char *, int *, int, int)); -static char *extract_dollar_brace_string PARAMS((char *, int *, int, int)); -static int skip_matched_pair PARAMS((const char *, int, int, int, int)); - -static char *pos_params PARAMS((char *, int, int, int, int)); - -static unsigned char *mb_getcharlens PARAMS((char *, int)); - -static char *remove_upattern PARAMS((char *, char *, int)); -#if defined (HANDLE_MULTIBYTE) -static wchar_t *remove_wpattern PARAMS((wchar_t *, size_t, wchar_t *, int)); -#endif -static char *remove_pattern PARAMS((char *, char *, int)); - -static int match_upattern PARAMS((char *, char *, int, char **, char **)); -#if defined (HANDLE_MULTIBYTE) -static int match_wpattern PARAMS((wchar_t *, char **, size_t, wchar_t *, int, char **, char **)); -#endif -static int match_pattern PARAMS((char *, char *, int, char **, char **)); -static int getpatspec PARAMS((int, char *)); -static char *getpattern PARAMS((char *, int, int)); -static char *variable_remove_pattern PARAMS((char *, char *, int, int)); -static char *list_remove_pattern PARAMS((WORD_LIST *, char *, int, int, int)); -static char *parameter_list_remove_pattern PARAMS((int, char *, int, int)); -#ifdef ARRAY_VARS -static char *array_remove_pattern PARAMS((SHELL_VAR *, char *, int, int, int)); -#endif -static char *parameter_brace_remove_pattern PARAMS((char *, char *, array_eltstate_t *, char *, int, int, int)); - -static char *string_var_assignment PARAMS((SHELL_VAR *, char *)); -#if defined (ARRAY_VARS) -static char *array_var_assignment PARAMS((SHELL_VAR *, int, int, int)); -#endif -static char *pos_params_assignment PARAMS((WORD_LIST *, int, int)); -static char *string_transform PARAMS((int, SHELL_VAR *, char *)); -static char *list_transform PARAMS((int, SHELL_VAR *, WORD_LIST *, int, int)); -static char *parameter_list_transform PARAMS((int, int, int)); -#if defined ARRAY_VARS -static char *array_transform PARAMS((int, SHELL_VAR *, int, int)); -#endif -static char *parameter_brace_transform PARAMS((char *, char *, array_eltstate_t *, char *, int, int, int, int)); -static int valid_parameter_transform PARAMS((char *)); - -static char *process_substitute PARAMS((char *, int)); - -static char *optimize_cat_file PARAMS((REDIRECT *, int, int, int *)); -static char *read_comsub PARAMS((int, int, int, int *)); - -#ifdef ARRAY_VARS -static arrayind_t array_length_reference PARAMS((char *)); -#endif - -static int valid_brace_expansion_word PARAMS((char *, int)); -static int chk_atstar PARAMS((char *, int, int, int *, int *)); -static int chk_arithsub PARAMS((const char *, int)); - -static WORD_DESC *parameter_brace_expand_word PARAMS((char *, int, int, int, array_eltstate_t *)); -static char *parameter_brace_find_indir PARAMS((char *, int, int, int)); -static WORD_DESC *parameter_brace_expand_indir PARAMS((char *, int, int, int, int *, int *)); -static WORD_DESC *parameter_brace_expand_rhs PARAMS((char *, char *, int, int, int, int *, int *)); -static void parameter_brace_expand_error PARAMS((char *, char *, int)); - -static int valid_length_expression PARAMS((char *)); -static intmax_t parameter_brace_expand_length PARAMS((char *)); - -static char *skiparith PARAMS((char *, int)); -static int verify_substring_values PARAMS((SHELL_VAR *, char *, char *, int, intmax_t *, intmax_t *)); -static int get_var_and_type PARAMS((char *, char *, array_eltstate_t *, int, int, SHELL_VAR **, char **)); -static char *mb_substring PARAMS((char *, int, int)); -static char *parameter_brace_substring PARAMS((char *, char *, array_eltstate_t *, char *, int, int, int)); - -static int shouldexp_replacement PARAMS((char *)); - -static char *pos_params_pat_subst PARAMS((char *, char *, char *, int)); - -static char *expand_string_for_patsub PARAMS((char *, int)); -static char *parameter_brace_patsub PARAMS((char *, char *, array_eltstate_t *, char *, int, int, int)); - -static char *pos_params_casemod PARAMS((char *, char *, int, int)); -static char *parameter_brace_casemod PARAMS((char *, char *, array_eltstate_t *, int, char *, int, int, int)); - -static WORD_DESC *parameter_brace_expand PARAMS((char *, int *, int, int, int *, int *)); -static WORD_DESC *param_expand PARAMS((char *, int *, int, int *, int *, int *, int *, int)); - -static WORD_LIST *expand_word_internal PARAMS((WORD_DESC *, int, int, int *, int *)); - -static WORD_LIST *word_list_split PARAMS((WORD_LIST *)); - -static void exp_jump_to_top_level PARAMS((int)); - -static WORD_LIST *separate_out_assignments PARAMS((WORD_LIST *)); -static WORD_LIST *glob_expand_word_list PARAMS((WORD_LIST *, int)); -#ifdef BRACE_EXPANSION -static WORD_LIST *brace_expand_word_list PARAMS((WORD_LIST *, int)); -#endif -#if defined (ARRAY_VARS) -static int make_internal_declare PARAMS((char *, char *, char *)); -static void expand_compound_assignment_word PARAMS((WORD_LIST *, int)); -static WORD_LIST *expand_declaration_argument PARAMS((WORD_LIST *, WORD_LIST *)); -#endif -static WORD_LIST *shell_expand_word_list PARAMS((WORD_LIST *, int)); -static WORD_LIST *expand_word_list_internal PARAMS((WORD_LIST *, int)); - -static int do_assignment_statements PARAMS((WORD_LIST *, char *, int)); - -/* **************************************************************** */ -/* */ -/* Utility Functions */ -/* */ -/* **************************************************************** */ - -#if defined (DEBUG) -void -dump_word_flags (flags) - int flags; -{ - int f; - - f = flags; - fprintf (stderr, "%d -> ", f); - if (f & W_ARRAYIND) - { - f &= ~W_ARRAYIND; - fprintf (stderr, "W_ARRAYIND%s", f ? "|" : ""); - } - if (f & W_ASSIGNASSOC) - { - f &= ~W_ASSIGNASSOC; - fprintf (stderr, "W_ASSIGNASSOC%s", f ? "|" : ""); - } - if (f & W_ASSIGNARRAY) - { - f &= ~W_ASSIGNARRAY; - fprintf (stderr, "W_ASSIGNARRAY%s", f ? "|" : ""); - } - if (f & W_SAWQUOTEDNULL) - { - f &= ~W_SAWQUOTEDNULL; - fprintf (stderr, "W_SAWQUOTEDNULL%s", f ? "|" : ""); - } - if (f & W_NOPROCSUB) - { - f &= ~W_NOPROCSUB; - fprintf (stderr, "W_NOPROCSUB%s", f ? "|" : ""); - } - if (f & W_DQUOTE) - { - f &= ~W_DQUOTE; - fprintf (stderr, "W_DQUOTE%s", f ? "|" : ""); - } - if (f & W_HASQUOTEDNULL) - { - f &= ~W_HASQUOTEDNULL; - fprintf (stderr, "W_HASQUOTEDNULL%s", f ? "|" : ""); - } - if (f & W_ASSIGNARG) - { - f &= ~W_ASSIGNARG; - fprintf (stderr, "W_ASSIGNARG%s", f ? "|" : ""); - } - if (f & W_ASSNBLTIN) - { - f &= ~W_ASSNBLTIN; - fprintf (stderr, "W_ASSNBLTIN%s", f ? "|" : ""); - } - if (f & W_ASSNGLOBAL) - { - f &= ~W_ASSNGLOBAL; - fprintf (stderr, "W_ASSNGLOBAL%s", f ? "|" : ""); - } - if (f & W_COMPASSIGN) - { - f &= ~W_COMPASSIGN; - fprintf (stderr, "W_COMPASSIGN%s", f ? "|" : ""); - } - if (f & W_EXPANDRHS) - { - f &= ~W_EXPANDRHS; - fprintf (stderr, "W_EXPANDRHS%s", f ? "|" : ""); - } - if (f & W_NOTILDE) - { - f &= ~W_NOTILDE; - fprintf (stderr, "W_NOTILDE%s", f ? "|" : ""); - } - if (f & W_ASSIGNRHS) - { - f &= ~W_ASSIGNRHS; - fprintf (stderr, "W_ASSIGNRHS%s", f ? "|" : ""); - } - if (f & W_NOASSNTILDE) - { - f &= ~W_NOASSNTILDE; - fprintf (stderr, "W_NOASSNTILDE%s", f ? "|" : ""); - } - if (f & W_NOCOMSUB) - { - f &= ~W_NOCOMSUB; - fprintf (stderr, "W_NOCOMSUB%s", f ? "|" : ""); - } - if (f & W_ARRAYREF) - { - f &= ~W_ARRAYREF; - fprintf (stderr, "W_ARRAYREF%s", f ? "|" : ""); - } - if (f & W_DOLLARAT) - { - f &= ~W_DOLLARAT; - fprintf (stderr, "W_DOLLARAT%s", f ? "|" : ""); - } - if (f & W_TILDEEXP) - { - f &= ~W_TILDEEXP; - fprintf (stderr, "W_TILDEEXP%s", f ? "|" : ""); - } - if (f & W_NOSPLIT2) - { - f &= ~W_NOSPLIT2; - fprintf (stderr, "W_NOSPLIT2%s", f ? "|" : ""); - } - if (f & W_NOSPLIT) - { - f &= ~W_NOSPLIT; - fprintf (stderr, "W_NOSPLIT%s", f ? "|" : ""); - } - if (f & W_NOBRACE) - { - f &= ~W_NOBRACE; - fprintf (stderr, "W_NOBRACE%s", f ? "|" : ""); - } - if (f & W_NOGLOB) - { - f &= ~W_NOGLOB; - fprintf (stderr, "W_NOGLOB%s", f ? "|" : ""); - } - if (f & W_SPLITSPACE) - { - f &= ~W_SPLITSPACE; - fprintf (stderr, "W_SPLITSPACE%s", f ? "|" : ""); - } - if (f & W_ASSIGNMENT) - { - f &= ~W_ASSIGNMENT; - fprintf (stderr, "W_ASSIGNMENT%s", f ? "|" : ""); - } - if (f & W_QUOTED) - { - f &= ~W_QUOTED; - fprintf (stderr, "W_QUOTED%s", f ? "|" : ""); - } - if (f & W_HASDOLLAR) - { - f &= ~W_HASDOLLAR; - fprintf (stderr, "W_HASDOLLAR%s", f ? "|" : ""); - } - if (f & W_COMPLETE) - { - f &= ~W_COMPLETE; - fprintf (stderr, "W_COMPLETE%s", f ? "|" : ""); - } - if (f & W_CHKLOCAL) - { - f &= ~W_CHKLOCAL; - fprintf (stderr, "W_CHKLOCAL%s", f ? "|" : ""); - } - if (f & W_FORCELOCAL) - { - f &= ~W_FORCELOCAL; - fprintf (stderr, "W_FORCELOCAL%s", f ? "|" : ""); - } - - fprintf (stderr, "\n"); - fflush (stderr); -} -#endif - -#ifdef INCLUDE_UNUSED -static char * -quoted_substring (string, start, end) - char *string; - int start, end; -{ - register int len, l; - register char *result, *s, *r; - - len = end - start; - - /* Move to string[start], skipping quoted characters. */ - for (s = string, l = 0; *s && l < start; ) - { - if (*s == CTLESC) - { - s++; - continue; - } - l++; - if (*s == 0) - break; - } - - r = result = (char *)xmalloc (2*len + 1); /* save room for quotes */ - - /* Copy LEN characters, including quote characters. */ - s = string + l; - for (l = 0; l < len; s++) - { - if (*s == CTLESC) - *r++ = *s++; - *r++ = *s; - l++; - if (*s == 0) - break; - } - *r = '\0'; - return result; -} -#endif - -#ifdef INCLUDE_UNUSED -/* Return the length of S, skipping over quoted characters */ -static int -quoted_strlen (s) - char *s; -{ - register char *p; - int i; - - i = 0; - for (p = s; *p; p++) - { - if (*p == CTLESC) - { - p++; - if (*p == 0) - return (i + 1); - } - i++; - } - - return i; -} -#endif - -#ifdef INCLUDE_UNUSED -/* Find the first occurrence of character C in string S, obeying shell - quoting rules. If (FLAGS & ST_BACKSL) is non-zero, backslash-escaped - characters are skipped. If (FLAGS & ST_CTLESC) is non-zero, characters - escaped with CTLESC are skipped. */ -static char * -quoted_strchr (s, c, flags) - char *s; - int c, flags; -{ - register char *p; - - for (p = s; *p; p++) - { - if (((flags & ST_BACKSL) && *p == '\\') - || ((flags & ST_CTLESC) && *p == CTLESC)) - { - p++; - if (*p == '\0') - return ((char *)NULL); - continue; - } - else if (*p == c) - return p; - } - return ((char *)NULL); -} - -/* Return 1 if CHARACTER appears in an unquoted portion of - STRING. Return 0 otherwise. CHARACTER must be a single-byte character. */ -static int -unquoted_member (character, string) - int character; - char *string; -{ - size_t slen; - int sindex, c; - DECLARE_MBSTATE; - - slen = strlen (string); - sindex = 0; - while (c = string[sindex]) - { - if (c == character) - return (1); - - switch (c) - { - default: - ADVANCE_CHAR (string, slen, sindex); - break; - - case '\\': - sindex++; - if (string[sindex]) - ADVANCE_CHAR (string, slen, sindex); - break; - - case '\'': - sindex = skip_single_quoted (string, slen, ++sindex, 0); - break; - - case '"': - sindex = skip_double_quoted (string, slen, ++sindex, 0); - break; - } - } - return (0); -} - -/* Return 1 if SUBSTR appears in an unquoted portion of STRING. */ -static int -unquoted_substring (substr, string) - char *substr, *string; -{ - size_t slen; - int sindex, c, sublen; - DECLARE_MBSTATE; - - if (substr == 0 || *substr == '\0') - return (0); - - slen = strlen (string); - sublen = strlen (substr); - for (sindex = 0; c = string[sindex]; ) - { - if (STREQN (string + sindex, substr, sublen)) - return (1); - - switch (c) - { - case '\\': - sindex++; - if (string[sindex]) - ADVANCE_CHAR (string, slen, sindex); - break; - - case '\'': - sindex = skip_single_quoted (string, slen, ++sindex, 0); - break; - - case '"': - sindex = skip_double_quoted (string, slen, ++sindex, 0); - break; - - default: - ADVANCE_CHAR (string, slen, sindex); - break; - } - } - return (0); -} -#endif - -/* Most of the substitutions must be done in parallel. In order - to avoid using tons of unclear goto's, I have some functions - for manipulating malloc'ed strings. They all take INDX, a - pointer to an integer which is the offset into the string - where manipulation is taking place. They also take SIZE, a - pointer to an integer which is the current length of the - character array for this string. */ - -/* Append SOURCE to TARGET at INDEX. SIZE is the current amount - of space allocated to TARGET. SOURCE can be NULL, in which - case nothing happens. Gets rid of SOURCE by freeing it. - Returns TARGET in case the location has changed. */ -INLINE char * -sub_append_string (source, target, indx, size) - char *source, *target; - size_t *indx; - size_t *size; -{ - if (source) - { - size_t n, srclen; - - srclen = STRLEN (source); - if (srclen >= (*size - *indx)) - { - n = srclen + *indx; - n = (n + DEFAULT_ARRAY_SIZE) - (n % DEFAULT_ARRAY_SIZE); - target = (char *)xrealloc (target, (*size = n)); - } - - FASTCOPY (source, target + *indx, srclen); - *indx += srclen; - target[*indx] = '\0'; - - free (source); - } - return (target); -} - -#if 0 -/* UNUSED */ -/* Append the textual representation of NUMBER to TARGET. - INDX and SIZE are as in SUB_APPEND_STRING. */ -char * -sub_append_number (number, target, indx, size) - intmax_t number; - char *target; - size_t *indx; - size_t *size; -{ - char *temp; - - temp = itos (number); - return (sub_append_string (temp, target, indx, size)); -} -#endif - -/* Extract a substring from STRING, starting at SINDEX and ending with - one of the characters in CHARLIST. Don't make the ending character - part of the string. Leave SINDEX pointing at the ending character. - Understand about backslashes in the string. If (flags & SX_VARNAME) - is non-zero, and array variables have been compiled into the shell, - everything between a `[' and a corresponding `]' is skipped over. - If (flags & SX_NOALLOC) is non-zero, don't return the substring, just - update SINDEX. If (flags & SX_REQMATCH) is non-zero, the string must - contain a closing character from CHARLIST. */ -static char * -string_extract (string, sindex, charlist, flags) - char *string; - int *sindex; - char *charlist; - int flags; -{ - register int c, i; - int found; - size_t slen; - char *temp; - DECLARE_MBSTATE; - - slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 0; - i = *sindex; - found = 0; - while (c = string[i]) - { - if (c == '\\') - { - if (string[i + 1]) - i++; - else - break; - } -#if defined (ARRAY_VARS) - else if ((flags & SX_VARNAME) && c == LBRACK) - { - int ni; - /* If this is an array subscript, skip over it and continue. */ - ni = skipsubscript (string, i, 0); - if (string[ni] == RBRACK) - i = ni; - } -#endif - else if (MEMBER (c, charlist)) - { - found = 1; - break; - } - - ADVANCE_CHAR (string, slen, i); - } - - /* If we had to have a matching delimiter and didn't find one, return an - error and let the caller deal with it. */ - if ((flags & SX_REQMATCH) && found == 0) - { - *sindex = i; - return (&extract_string_error); - } - - temp = (flags & SX_NOALLOC) ? (char *)NULL : substring (string, *sindex, i); - *sindex = i; - - return (temp); -} - -/* Extract the contents of STRING as if it is enclosed in double quotes. - SINDEX, when passed in, is the offset of the character immediately - following the opening double quote; on exit, SINDEX is left pointing after - the closing double quote. If STRIPDQ is non-zero, unquoted double - quotes are stripped and the string is terminated by a null byte. - Backslashes between the embedded double quotes are processed. If STRIPDQ - is zero, an unquoted `"' terminates the string. */ -static char * -string_extract_double_quoted (string, sindex, flags) - char *string; - int *sindex, flags; -{ - size_t slen; - char *send; - int j, i, t; - unsigned char c; - char *temp, *ret; /* The new string we return. */ - int pass_next, backquote, si; /* State variables for the machine. */ - int dquote; - int stripdq; - DECLARE_MBSTATE; - - slen = strlen (string + *sindex) + *sindex; - send = string + slen; - - stripdq = (flags & SX_STRIPDQ); - - pass_next = backquote = dquote = 0; - temp = (char *)xmalloc (1 + slen - *sindex); - - j = 0; - i = *sindex; - while (c = string[i]) - { - /* Process a character that was quoted by a backslash. */ - if (pass_next) - { - /* XXX - take another look at this in light of Interp 221 */ - /* Posix.2 sez: - - ``The backslash shall retain its special meaning as an escape - character only when followed by one of the characters: - $ ` " \ ''. - - If STRIPDQ is zero, we handle the double quotes here and let - expand_word_internal handle the rest. If STRIPDQ is non-zero, - we have already been through one round of backslash stripping, - and want to strip these backslashes only if DQUOTE is non-zero, - indicating that we are inside an embedded double-quoted string. */ - - /* If we are in an embedded quoted string, then don't strip - backslashes before characters for which the backslash - retains its special meaning, but remove backslashes in - front of other characters. If we are not in an - embedded quoted string, don't strip backslashes at all. - This mess is necessary because the string was already - surrounded by double quotes (and sh has some really weird - quoting rules). - The returned string will be run through expansion as if - it were double-quoted. */ - if ((stripdq == 0 && c != '"') || - (stripdq && ((dquote && (sh_syntaxtab[c] & CBSDQUOTE)) || dquote == 0))) - temp[j++] = '\\'; - pass_next = 0; - -add_one_character: - COPY_CHAR_I (temp, j, string, send, i); - continue; - } - - /* A backslash protects the next character. The code just above - handles preserving the backslash in front of any character but - a double quote. */ - if (c == '\\') - { - pass_next++; - i++; - continue; - } - - /* Inside backquotes, ``the portion of the quoted string from the - initial backquote and the characters up to the next backquote - that is not preceded by a backslash, having escape characters - removed, defines that command''. */ - if (backquote) - { - if (c == '`') - backquote = 0; - temp[j++] = c; /* COPY_CHAR_I? */ - i++; - continue; - } - - if (c == '`') - { - temp[j++] = c; - backquote++; - i++; - continue; - } - - /* Pass everything between `$(' and the matching `)' or a quoted - ${ ... } pair through according to the Posix.2 specification. */ - if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE))) - { - int free_ret = 1; - - si = i + 2; - if (string[i + 1] == LPAREN) - ret = extract_command_subst (string, &si, (flags & SX_COMPLETE)); - else - ret = extract_dollar_brace_string (string, &si, Q_DOUBLE_QUOTES, 0); - - temp[j++] = '$'; - temp[j++] = string[i + 1]; - - /* Just paranoia; ret will not be 0 unless no_longjmp_on_fatal_error - is set. */ - if (ret == 0 && no_longjmp_on_fatal_error) - { - free_ret = 0; - ret = string + i + 2; - } - - /* XXX - CHECK_STRING_OVERRUN here? */ - for (t = 0; ret[t]; t++, j++) - temp[j] = ret[t]; - temp[j] = string[si]; - - if (si < i + 2) /* we went back? */ - i += 2; - else if (string[si]) - { - j++; - i = si + 1; - } - else - i = si; - - if (free_ret) - free (ret); - continue; - } - - /* Add any character but a double quote to the quoted string we're - accumulating. */ - if (c != '"') - goto add_one_character; - - /* c == '"' */ - if (stripdq) - { - dquote ^= 1; - i++; - continue; - } - - break; - } - temp[j] = '\0'; - - /* Point to after the closing quote. */ - if (c) - i++; - *sindex = i; - - return (temp); -} - -/* This should really be another option to string_extract_double_quoted. */ -static int -skip_double_quoted (string, slen, sind, flags) - char *string; - size_t slen; - int sind; - int flags; -{ - int c, i; - char *ret; - int pass_next, backquote, si; - DECLARE_MBSTATE; - - pass_next = backquote = 0; - i = sind; - while (c = string[i]) - { - if (pass_next) - { - pass_next = 0; - ADVANCE_CHAR (string, slen, i); - continue; - } - else if (c == '\\') - { - pass_next++; - i++; - continue; - } - else if (backquote) - { - if (c == '`') - backquote = 0; - ADVANCE_CHAR (string, slen, i); - continue; - } - else if (c == '`') - { - backquote++; - i++; - continue; - } - else if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE))) - { - si = i + 2; - if (string[i + 1] == LPAREN) - ret = extract_command_subst (string, &si, SX_NOALLOC|(flags&SX_COMPLETE)); - else - ret = extract_dollar_brace_string (string, &si, Q_DOUBLE_QUOTES, SX_NOALLOC); - - /* These can consume the entire string if they are unterminated */ - CHECK_STRING_OVERRUN (i, si, slen, c); - - i = si + 1; - continue; - } - else if (c != '"') - { - ADVANCE_CHAR (string, slen, i); - continue; - } - else - break; - } - - if (c) - i++; - - return (i); -} - -/* Extract the contents of STRING as if it is enclosed in single quotes. - SINDEX, when passed in, is the offset of the character immediately - following the opening single quote; on exit, SINDEX is left pointing after - the closing single quote. ALLOWESC allows the single quote to be quoted by - a backslash; it's not used yet. */ -static inline char * -string_extract_single_quoted (string, sindex, allowesc) - char *string; - int *sindex; - int allowesc; -{ - register int i; - size_t slen; - char *t; - int pass_next; - DECLARE_MBSTATE; - - /* Don't need slen for ADVANCE_CHAR unless multibyte chars possible. */ - slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 0; - i = *sindex; - pass_next = 0; - while (string[i]) - { - if (pass_next) - { - pass_next = 0; - ADVANCE_CHAR (string, slen, i); - continue; - } - if (allowesc && string[i] == '\\') - pass_next++; - else if (string[i] == '\'') - break; - ADVANCE_CHAR (string, slen, i); - } - - t = substring (string, *sindex, i); - - if (string[i]) - i++; - *sindex = i; - - return (t); -} - -/* Skip over a single-quoted string. We overload the SX_COMPLETE flag to mean - that we are splitting out words for completion and have encountered a $'...' - string, which allows backslash-escaped single quotes. */ -static inline int -skip_single_quoted (string, slen, sind, flags) - const char *string; - size_t slen; - int sind; - int flags; -{ - register int c; - DECLARE_MBSTATE; - - c = sind; - while (string[c] && string[c] != '\'') - { - if ((flags & SX_COMPLETE) && string[c] == '\\' && string[c+1] == '\'' && string[c+2]) - ADVANCE_CHAR (string, slen, c); - ADVANCE_CHAR (string, slen, c); - } - - if (string[c]) - c++; - return c; -} - -/* Just like string_extract, but doesn't hack backslashes or any of - that other stuff. Obeys CTLESC quoting. Used to do splitting on $IFS. */ -static char * -string_extract_verbatim (string, slen, sindex, charlist, flags) - char *string; - size_t slen; - int *sindex; - char *charlist; - int flags; -{ - register int i; -#if defined (HANDLE_MULTIBYTE) - wchar_t *wcharlist; -#endif - int c; - char *temp; - DECLARE_MBSTATE; - - if ((flags & SX_NOCTLESC) && charlist[0] == '\'' && charlist[1] == '\0') - { - temp = string_extract_single_quoted (string, sindex, 0); - --*sindex; /* leave *sindex at separator character */ - return temp; - } - - /* This can never be called with charlist == NULL. If *charlist == NULL, - we can skip the loop and just return a copy of the string, updating - *sindex */ - if (*charlist == 0) - { - temp = string + *sindex; - c = (*sindex == 0) ? slen : STRLEN (temp); - temp = savestring (temp); - *sindex += c; - return temp; - } - - i = *sindex; -#if defined (HANDLE_MULTIBYTE) - wcharlist = 0; -#endif - while (c = string[i]) - { -#if defined (HANDLE_MULTIBYTE) - size_t mblength; -#endif - if ((flags & SX_NOCTLESC) == 0 && c == CTLESC) - { - i += 2; - CHECK_STRING_OVERRUN (i, i, slen, c); - continue; - } - /* Even if flags contains SX_NOCTLESC, we let CTLESC quoting CTLNUL - through, to protect the CTLNULs from later calls to - remove_quoted_nulls. */ - else if ((flags & SX_NOESCCTLNUL) == 0 && c == CTLESC && string[i+1] == CTLNUL) - { - i += 2; - CHECK_STRING_OVERRUN (i, i, slen, c); - continue; - } - -#if defined (HANDLE_MULTIBYTE) - if (locale_utf8locale && slen > i && UTF8_SINGLEBYTE (string[i])) - mblength = (string[i] != 0) ? 1 : 0; - else - mblength = MBLEN (string + i, slen - i); - if (mblength > 1) - { - wchar_t wc; - mblength = mbtowc (&wc, string + i, slen - i); - if (MB_INVALIDCH (mblength)) - { - if (MEMBER (c, charlist)) - break; - } - else - { - if (wcharlist == 0) - { - size_t len; - len = mbstowcs (wcharlist, charlist, 0); - if (len == -1) - len = 0; - wcharlist = (wchar_t *)xmalloc (sizeof (wchar_t) * (len + 1)); - mbstowcs (wcharlist, charlist, len + 1); - } - - if (wcschr (wcharlist, wc)) - break; - } - } - else -#endif - if (MEMBER (c, charlist)) - break; - - ADVANCE_CHAR (string, slen, i); - } - -#if defined (HANDLE_MULTIBYTE) - FREE (wcharlist); -#endif - - temp = substring (string, *sindex, i); - *sindex = i; - - return (temp); -} - -/* Extract the $( construct in STRING, and return a new string. - Start extracting at (SINDEX) as if we had just seen "$(". - Make (SINDEX) get the position of the matching ")". ) - XFLAGS is additional flags to pass to other extraction functions. */ -char * -extract_command_subst (string, sindex, xflags) - char *string; - int *sindex; - int xflags; -{ - char *ret; - - if (string[*sindex] == LPAREN || (xflags & SX_COMPLETE)) - return (extract_delimited_string (string, sindex, "$(", "(", ")", xflags|SX_COMMAND)); /*)*/ - else - { - xflags |= (no_longjmp_on_fatal_error ? SX_NOLONGJMP : 0); - ret = xparse_dolparen (string, string+*sindex, sindex, xflags); - return ret; - } -} - -/* Extract the $[ construct in STRING, and return a new string. (]) - Start extracting at (SINDEX) as if we had just seen "$[". - Make (SINDEX) get the position of the matching "]". */ -char * -extract_arithmetic_subst (string, sindex) - char *string; - int *sindex; -{ - return (extract_delimited_string (string, sindex, "$[", "[", "]", 0)); /*]*/ -} - -#if defined (PROCESS_SUBSTITUTION) -/* Extract the <( or >( construct in STRING, and return a new string. - Start extracting at (SINDEX) as if we had just seen "<(". - Make (SINDEX) get the position of the matching ")". */ /*))*/ -char * -extract_process_subst (string, starter, sindex, xflags) - char *string; - char *starter; - int *sindex; - int xflags; -{ -#if 0 - /* XXX - check xflags&SX_COMPLETE here? */ - return (extract_delimited_string (string, sindex, starter, "(", ")", SX_COMMAND)); -#else - xflags |= (no_longjmp_on_fatal_error ? SX_NOLONGJMP : 0); - return (xparse_dolparen (string, string+*sindex, sindex, xflags)); -#endif -} -#endif /* PROCESS_SUBSTITUTION */ - -#if defined (ARRAY_VARS) -/* This can be fooled by unquoted right parens in the passed string. If - each caller verifies that the last character in STRING is a right paren, - we don't even need to call extract_delimited_string. */ -char * -extract_array_assignment_list (string, sindex) - char *string; - int *sindex; -{ - int slen; - char *ret; - - slen = strlen (string); - if (string[slen - 1] == RPAREN) - { - ret = substring (string, *sindex, slen - 1); - *sindex = slen - 1; - return ret; - } - return 0; -} -#endif - -/* Extract and create a new string from the contents of STRING, a - character string delimited with OPENER and CLOSER. SINDEX is - the address of an int describing the current offset in STRING; - it should point to just after the first OPENER found. On exit, - SINDEX gets the position of the last character of the matching CLOSER. - If OPENER is more than a single character, ALT_OPENER, if non-null, - contains a character string that can also match CLOSER and thus - needs to be skipped. */ -static char * -extract_delimited_string (string, sindex, opener, alt_opener, closer, flags) - char *string; - int *sindex; - char *opener, *alt_opener, *closer; - int flags; -{ - int i, c, si; - size_t slen; - char *t, *result; - int pass_character, nesting_level, in_comment; - int len_closer, len_opener, len_alt_opener; - DECLARE_MBSTATE; - - slen = strlen (string + *sindex) + *sindex; - len_opener = STRLEN (opener); - len_alt_opener = STRLEN (alt_opener); - len_closer = STRLEN (closer); - - pass_character = in_comment = 0; - - nesting_level = 1; - i = *sindex; - - while (nesting_level) - { - c = string[i]; - - /* If a recursive call or a call to ADVANCE_CHAR leaves the index beyond - the end of the string, catch it and cut the loop. */ - if (i > slen) - { - i = slen; - c = string[i = slen]; - break; - } - - if (c == 0) - break; - - if (in_comment) - { - if (c == '\n') - in_comment = 0; - ADVANCE_CHAR (string, slen, i); - continue; - } - - if (pass_character) /* previous char was backslash */ - { - pass_character = 0; - ADVANCE_CHAR (string, slen, i); - continue; - } - - /* Not exactly right yet; should handle shell metacharacters and - multibyte characters, too. See COMMENT_BEGIN define in parse.y */ - if ((flags & SX_COMMAND) && c == '#' && (i == 0 || string[i - 1] == '\n' || shellblank (string[i - 1]))) - { - in_comment = 1; - ADVANCE_CHAR (string, slen, i); - continue; - } - - if (c == CTLESC || c == '\\') - { - pass_character++; - i++; - continue; - } - - /* Process a nested command substitution, but only if we're parsing an - arithmetic substitution. */ - if ((flags & SX_COMMAND) && string[i] == '$' && string[i+1] == LPAREN) - { - si = i + 2; - t = extract_command_subst (string, &si, flags|SX_NOALLOC); - CHECK_STRING_OVERRUN (i, si, slen, c); - i = si + 1; - continue; - } - - /* Process a nested OPENER. */ - if (STREQN (string + i, opener, len_opener)) - { - si = i + len_opener; - t = extract_delimited_string (string, &si, opener, alt_opener, closer, flags|SX_NOALLOC); - CHECK_STRING_OVERRUN (i, si, slen, c); - i = si + 1; - continue; - } - - /* Process a nested ALT_OPENER */ - if (len_alt_opener && STREQN (string + i, alt_opener, len_alt_opener)) - { - si = i + len_alt_opener; - t = extract_delimited_string (string, &si, alt_opener, alt_opener, closer, flags|SX_NOALLOC); - CHECK_STRING_OVERRUN (i, si, slen, c); - i = si + 1; - continue; - } - - /* If the current substring terminates the delimited string, decrement - the nesting level. */ - if (STREQN (string + i, closer, len_closer)) - { - i += len_closer - 1; /* move to last byte of the closer */ - nesting_level--; - if (nesting_level == 0) - break; - } - - /* Pass old-style command substitution through verbatim. */ - if (c == '`') - { - si = i + 1; - t = string_extract (string, &si, "`", flags|SX_NOALLOC); - CHECK_STRING_OVERRUN (i, si, slen, c); - i = si + 1; - continue; - } - - /* Pass single-quoted and double-quoted strings through verbatim. */ - if (c == '\'' || c == '"') - { - si = i + 1; - i = (c == '\'') ? skip_single_quoted (string, slen, si, 0) - : skip_double_quoted (string, slen, si, 0); - continue; - } - - /* move past this character, which was not special. */ - ADVANCE_CHAR (string, slen, i); - } - - if (c == 0 && nesting_level) - { - if (no_longjmp_on_fatal_error == 0) - { - last_command_exit_value = EXECUTION_FAILURE; - report_error (_("bad substitution: no closing `%s' in %s"), closer, string); - exp_jump_to_top_level (DISCARD); - } - else - { - *sindex = i; - return (char *)NULL; - } - } - - si = i - *sindex - len_closer + 1; - if (flags & SX_NOALLOC) - result = (char *)NULL; - else - { - result = (char *)xmalloc (1 + si); - strncpy (result, string + *sindex, si); - result[si] = '\0'; - } - *sindex = i; - - return (result); -} - -/* A simplified version of extract_dollar_brace_string that exists to handle - $'...' and $"..." quoting in here-documents, since the here-document read - path doesn't. It's separate because we don't want to mess with the fast - common path. We already know we're going to allocate and return a new - string and quoted == Q_HERE_DOCUMENT. We might be able to cut it down - some more, but extracting strings and adding them as we go adds complexity. - This needs to match the logic in parse.y:parse_matched_pair so we get - consistent behavior between here-documents and double-quoted strings. */ -static char * -extract_heredoc_dolbrace_string (string, sindex, quoted, flags) - char *string; - int *sindex, quoted, flags; -{ - register int i, c; - size_t slen, tlen, result_index, result_size; - int pass_character, nesting_level, si, dolbrace_state; - char *result, *t, *send; - DECLARE_MBSTATE; - - pass_character = 0; - nesting_level = 1; - slen = strlen (string + *sindex) + *sindex; - send = string + slen; - - result_size = slen; - result_index = 0; - result = xmalloc (result_size + 1); - - /* This function isn't called if this condition is not true initially. */ - dolbrace_state = DOLBRACE_QUOTE; - - i = *sindex; - while (c = string[i]) - { - if (pass_character) - { - pass_character = 0; - RESIZE_MALLOCED_BUFFER (result, result_index, locale_mb_cur_max + 1, result_size, 64); - COPY_CHAR_I (result, result_index, string, send, i); - continue; - } - - /* CTLESCs and backslashes quote the next character. */ - if (c == CTLESC || c == '\\') - { - pass_character++; - RESIZE_MALLOCED_BUFFER (result, result_index, 2, result_size, 64); - result[result_index++] = c; - i++; - continue; - } - - /* The entire reason we have this separate function right here. */ - if (c == '$' && string[i+1] == '\'') - { - char *ttrans; - int ttranslen; - - if ((posixly_correct || extended_quote == 0) && dolbrace_state != DOLBRACE_QUOTE && dolbrace_state != DOLBRACE_QUOTE2) - { - RESIZE_MALLOCED_BUFFER (result, result_index, 3, result_size, 64); - result[result_index++] = '$'; - result[result_index++] = '\''; - i += 2; - continue; - } - - si = i + 2; - t = string_extract_single_quoted (string, &si, 1); /* XXX */ - CHECK_STRING_OVERRUN (i, si, slen, c); - - tlen = si - i - 2; /* -2 since si is one after the close quote */ - ttrans = ansiexpand (t, 0, tlen, &ttranslen); - free (t); - - /* needed to correctly quote any embedded single quotes. */ - if (dolbrace_state == DOLBRACE_QUOTE || dolbrace_state == DOLBRACE_QUOTE2) - { - t = sh_single_quote (ttrans); - tlen = strlen (t); - free (ttrans); - } - else if (extended_quote) /* dolbrace_state == DOLBRACE_PARAM */ - { - /* This matches what parse.y:parse_matched_pair() does */ - t = ttrans; - tlen = strlen (t); - } - - RESIZE_MALLOCED_BUFFER (result, result_index, tlen + 1, result_size, 64); - strncpy (result + result_index, t, tlen); - result_index += tlen; - free (t); - i = si; - continue; - } - -#if defined (TRANSLATABLE_STRINGS) - if (c == '$' && string[i+1] == '"') - { - char *ttrans; - int ttranslen; - - si = i + 2; - t = string_extract_double_quoted (string, &si, flags); /* XXX */ - CHECK_STRING_OVERRUN (i, si, slen, c); - - tlen = si - i - 2; /* -2 since si is one after the close quote */ - ttrans = locale_expand (t, 0, tlen, line_number, &ttranslen); - free (t); - - t = singlequote_translations ? sh_single_quote (ttrans) : sh_mkdoublequoted (ttrans, ttranslen, 0); - tlen = strlen (t); - free (ttrans); - - RESIZE_MALLOCED_BUFFER (result, result_index, tlen + 1, result_size, 64); - strncpy (result + result_index, t, tlen); - result_index += tlen; - free (t); - i = si; - continue; - } -#endif /* TRANSLATABLE_STRINGS */ - - if (c == '$' && string[i+1] == LBRACE) - { - nesting_level++; - RESIZE_MALLOCED_BUFFER (result, result_index, 3, result_size, 64); - result[result_index++] = c; - result[result_index++] = string[i+1]; - i += 2; - if (dolbrace_state == DOLBRACE_QUOTE || dolbrace_state == DOLBRACE_QUOTE2 || dolbrace_state == DOLBRACE_WORD) - dolbrace_state = DOLBRACE_PARAM; - continue; - } - - if (c == RBRACE) - { - nesting_level--; - if (nesting_level == 0) - break; - RESIZE_MALLOCED_BUFFER (result, result_index, 2, result_size, 64); - result[result_index++] = c; - i++; - continue; - } - - /* Pass the contents of old-style command substitutions through - verbatim. */ - if (c == '`') - { - si = i + 1; - t = string_extract (string, &si, "`", flags); /* already know (flags & SX_NOALLOC) == 0) */ - CHECK_STRING_OVERRUN (i, si, slen, c); - - tlen = si - i - 1; - RESIZE_MALLOCED_BUFFER (result, result_index, tlen + 3, result_size, 64); - result[result_index++] = c; - strncpy (result + result_index, t, tlen); - result_index += tlen; - result[result_index++] = string[si]; - free (t); - i = si + 1; - continue; - } - - /* Pass the contents of new-style command substitutions and - arithmetic substitutions through verbatim. */ - if (string[i] == '$' && string[i+1] == LPAREN) - { - si = i + 2; - t = extract_command_subst (string, &si, flags); - CHECK_STRING_OVERRUN (i, si, slen, c); - - tlen = si - i - 1; - RESIZE_MALLOCED_BUFFER (result, result_index, tlen + 4, result_size, 64); - result[result_index++] = c; - result[result_index++] = LPAREN; - strncpy (result + result_index, t, tlen); - result_index += tlen; - result[result_index++] = string[si]; - free (t); - i = si + 1; - continue; - } - -#if defined (PROCESS_SUBSTITUTION) - /* Technically this should only work at the start of a word */ - if ((string[i] == '<' || string[i] == '>') && string[i+1] == LPAREN) - { - si = i + 2; - t = extract_process_subst (string, (string[i] == '<' ? "<(" : ">)"), &si, flags); - CHECK_STRING_OVERRUN (i, si, slen, c); - - tlen = si - i - 1; - RESIZE_MALLOCED_BUFFER (result, result_index, tlen + 4, result_size, 64); - result[result_index++] = c; - result[result_index++] = LPAREN; - strncpy (result + result_index, t, tlen); - result_index += tlen; - result[result_index++] = string[si]; - free (t); - i = si + 1; - continue; - } -#endif - - if (c == '\'' && posixly_correct && shell_compatibility_level > 42 && dolbrace_state != DOLBRACE_QUOTE) - { - COPY_CHAR_I (result, result_index, string, send, i); - continue; - } - - /* Pass the contents of single and double-quoted strings through verbatim. */ - if (c == '"' || c == '\'') - { - si = i + 1; - if (c == '"') - t = string_extract_double_quoted (string, &si, flags); - else - t = string_extract_single_quoted (string, &si, 0); - CHECK_STRING_OVERRUN (i, si, slen, c); - - tlen = si - i - 2; /* -2 since si is one after the close quote */ - RESIZE_MALLOCED_BUFFER (result, result_index, tlen + 3, result_size, 64); - result[result_index++] = c; - strncpy (result + result_index, t, tlen); - result_index += tlen; - result[result_index++] = string[si - 1]; - free (t); - i = si; - continue; - } - - /* copy this character, which was not special. */ - COPY_CHAR_I (result, result_index, string, send, i); - - /* This logic must agree with parse.y:parse_matched_pair, since they - share the same defines. */ - if (dolbrace_state == DOLBRACE_PARAM && c == '%' && (i - *sindex) > 1) - dolbrace_state = DOLBRACE_QUOTE; - else if (dolbrace_state == DOLBRACE_PARAM && c == '#' && (i - *sindex) > 1) - dolbrace_state = DOLBRACE_QUOTE; - else if (dolbrace_state == DOLBRACE_PARAM && c == '/' && (i - *sindex) > 1) - dolbrace_state = DOLBRACE_QUOTE2; /* XXX */ - else if (dolbrace_state == DOLBRACE_PARAM && c == '^' && (i - *sindex) > 1) - dolbrace_state = DOLBRACE_QUOTE; - else if (dolbrace_state == DOLBRACE_PARAM && c == ',' && (i - *sindex) > 1) - dolbrace_state = DOLBRACE_QUOTE; - /* This is intended to handle all of the [:]op expansions and the substring/ - length/pattern removal/pattern substitution expansions. */ - else if (dolbrace_state == DOLBRACE_PARAM && strchr ("#%^,~:-=?+/", c) != 0) - dolbrace_state = DOLBRACE_OP; - else if (dolbrace_state == DOLBRACE_OP && strchr ("#%^,~:-=?+/", c) == 0) - dolbrace_state = DOLBRACE_WORD; - } - - if (c == 0 && nesting_level) - { - free (result); - if (no_longjmp_on_fatal_error == 0) - { /* { */ - last_command_exit_value = EXECUTION_FAILURE; - report_error (_("bad substitution: no closing `%s' in %s"), "}", string); - exp_jump_to_top_level (DISCARD); - } - else - { - *sindex = i; - return ((char *)NULL); - } - } - - *sindex = i; - result[result_index] = '\0'; - - return (result); -} - -/* Extract a parameter expansion expression within ${ and } from STRING. - Obey the Posix.2 rules for finding the ending `}': count braces while - skipping over enclosed quoted strings and command substitutions. - SINDEX is the address of an int describing the current offset in STRING; - it should point to just after the first `{' found. On exit, SINDEX - gets the position of the matching `}'. QUOTED is non-zero if this - occurs inside double quotes. */ -/* XXX -- this is very similar to extract_delimited_string -- XXX */ -static char * -extract_dollar_brace_string (string, sindex, quoted, flags) - char *string; - int *sindex, quoted, flags; -{ - register int i, c; - size_t slen; - int pass_character, nesting_level, si, dolbrace_state; - char *result, *t; - DECLARE_MBSTATE; - - /* The handling of dolbrace_state needs to agree with the code in parse.y: - parse_matched_pair(). The different initial value is to handle the - case where this function is called to parse the word in - ${param op word} (SX_WORD). */ - dolbrace_state = (flags & SX_WORD) ? DOLBRACE_WORD : DOLBRACE_PARAM; - if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && (flags & SX_POSIXEXP)) - dolbrace_state = DOLBRACE_QUOTE; - - if (quoted == Q_HERE_DOCUMENT && dolbrace_state == DOLBRACE_QUOTE && (flags & SX_NOALLOC) == 0) - return (extract_heredoc_dolbrace_string (string, sindex, quoted, flags)); - - pass_character = 0; - nesting_level = 1; - slen = strlen (string + *sindex) + *sindex; - - i = *sindex; - while (c = string[i]) - { - if (pass_character) - { - pass_character = 0; - ADVANCE_CHAR (string, slen, i); - continue; - } - - /* CTLESCs and backslashes quote the next character. */ - if (c == CTLESC || c == '\\') - { - pass_character++; - i++; - continue; - } - - if (string[i] == '$' && string[i+1] == LBRACE) - { - nesting_level++; - i += 2; - if (dolbrace_state == DOLBRACE_QUOTE || dolbrace_state == DOLBRACE_WORD) - dolbrace_state = DOLBRACE_PARAM; - continue; - } - - if (c == RBRACE) - { - nesting_level--; - if (nesting_level == 0) - break; - i++; - continue; - } - - /* Pass the contents of old-style command substitutions through - verbatim. */ - if (c == '`') - { - si = i + 1; - t = string_extract (string, &si, "`", flags|SX_NOALLOC); - - CHECK_STRING_OVERRUN (i, si, slen, c); - - i = si + 1; - continue; - } - - /* Pass the contents of new-style command substitutions and - arithmetic substitutions through verbatim. */ - if (string[i] == '$' && string[i+1] == LPAREN) - { - si = i + 2; - t = extract_command_subst (string, &si, flags|SX_NOALLOC); - - CHECK_STRING_OVERRUN (i, si, slen, c); - - i = si + 1; - continue; - } - -#if defined (PROCESS_SUBSTITUTION) - /* Technically this should only work at the start of a word */ - if ((string[i] == '<' || string[i] == '>') && string[i+1] == LPAREN) - { - si = i + 2; - t = extract_process_subst (string, (string[i] == '<' ? "<(" : ">)"), &si, flags|SX_NOALLOC); - - CHECK_STRING_OVERRUN (i, si, slen, c); - - i = si + 1; - continue; - } -#endif - - /* Pass the contents of double-quoted strings through verbatim. */ - if (c == '"') - { - si = i + 1; - i = skip_double_quoted (string, slen, si, 0); - /* skip_XXX_quoted leaves index one past close quote */ - continue; - } - - if (c == '\'') - { -/*itrace("extract_dollar_brace_string: c == single quote flags = %d quoted = %d dolbrace_state = %d", flags, quoted, dolbrace_state);*/ - if (posixly_correct && shell_compatibility_level > 42 && dolbrace_state != DOLBRACE_QUOTE && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))) - ADVANCE_CHAR (string, slen, i); - else - { - si = i + 1; - i = skip_single_quoted (string, slen, si, 0); - } - - continue; - } - -#if defined (ARRAY_VARS) - if (c == LBRACK && dolbrace_state == DOLBRACE_PARAM) - { - si = skipsubscript (string, i, 0); - CHECK_STRING_OVERRUN (i, si, slen, c); - if (string[si] == RBRACK) - c = string[i = si]; - } -#endif - - /* move past this character, which was not special. */ - ADVANCE_CHAR (string, slen, i); - - /* This logic must agree with parse.y:parse_matched_pair, since they - share the same defines. */ - if (dolbrace_state == DOLBRACE_PARAM && c == '%' && (i - *sindex) > 1) - dolbrace_state = DOLBRACE_QUOTE; - else if (dolbrace_state == DOLBRACE_PARAM && c == '#' && (i - *sindex) > 1) - dolbrace_state = DOLBRACE_QUOTE; - else if (dolbrace_state == DOLBRACE_PARAM && c == '/' && (i - *sindex) > 1) - dolbrace_state = DOLBRACE_QUOTE2; /* XXX */ - else if (dolbrace_state == DOLBRACE_PARAM && c == '^' && (i - *sindex) > 1) - dolbrace_state = DOLBRACE_QUOTE; - else if (dolbrace_state == DOLBRACE_PARAM && c == ',' && (i - *sindex) > 1) - dolbrace_state = DOLBRACE_QUOTE; - /* This is intended to handle all of the [:]op expansions and the substring/ - length/pattern removal/pattern substitution expansions. */ - else if (dolbrace_state == DOLBRACE_PARAM && strchr ("#%^,~:-=?+/", c) != 0) - dolbrace_state = DOLBRACE_OP; - else if (dolbrace_state == DOLBRACE_OP && strchr ("#%^,~:-=?+/", c) == 0) - dolbrace_state = DOLBRACE_WORD; - } - - if (c == 0 && nesting_level) - { - if (no_longjmp_on_fatal_error == 0) - { /* { */ - last_command_exit_value = EXECUTION_FAILURE; - report_error (_("bad substitution: no closing `%s' in %s"), "}", string); - exp_jump_to_top_level (DISCARD); - } - else - { - *sindex = i; - return ((char *)NULL); - } - } - - result = (flags & SX_NOALLOC) ? (char *)NULL : substring (string, *sindex, i); - *sindex = i; - - return (result); -} - -/* Remove backslashes which are quoting backquotes from STRING. Modifies - STRING, and returns a pointer to it. */ -char * -de_backslash (string) - char *string; -{ - register size_t slen; - register int i, j, prev_i; - DECLARE_MBSTATE; - - slen = strlen (string); - i = j = 0; - - /* Loop copying string[i] to string[j], i >= j. */ - while (i < slen) - { - if (string[i] == '\\' && (string[i + 1] == '`' || string[i + 1] == '\\' || - string[i + 1] == '$')) - i++; - prev_i = i; - ADVANCE_CHAR (string, slen, i); - if (j < prev_i) - do string[j++] = string[prev_i++]; while (prev_i < i); - else - j = i; - } - string[j] = '\0'; - - return (string); -} - -#if 0 -/*UNUSED*/ -/* Replace instances of \! in a string with !. */ -void -unquote_bang (string) - char *string; -{ - register int i, j; - register char *temp; - - temp = (char *)xmalloc (1 + strlen (string)); - - for (i = 0, j = 0; (temp[j] = string[i]); i++, j++) - { - if (string[i] == '\\' && string[i + 1] == '!') - { - temp[j] = '!'; - i++; - } - } - strcpy (string, temp); - free (temp); -} -#endif - -#define CQ_RETURN(x) do { no_longjmp_on_fatal_error = oldjmp; return (x); } while (0) - -/* When FLAGS & 2 == 0, this function assumes STRING[I] == OPEN; when - FLAGS & 2 != 0, it assumes STRING[I] points to one character past OPEN; - returns with STRING[RET] == close; used to parse array subscripts. - FLAGS & 1 means not to attempt to skip over matched pairs of quotes or - backquotes, or skip word expansions; it is intended to be used after - expansion has been performed and during final assignment parsing (see - arrayfunc.c:assign_compound_array_list()) or during execution by a builtin - which has already undergone word expansion. */ -static int -skip_matched_pair (string, start, open, close, flags) - const char *string; - int start, open, close, flags; -{ - int i, pass_next, backq, si, c, count, oldjmp; - size_t slen; - char *temp, *ss; - DECLARE_MBSTATE; - - slen = strlen (string + start) + start; - oldjmp = no_longjmp_on_fatal_error; - no_longjmp_on_fatal_error = 1; - - /* Move to the first character after a leading OPEN. If FLAGS&2, we assume - that START already points to that character. If not, we need to skip over - it here. */ - i = (flags & 2) ? start : start + 1; - count = 1; - pass_next = backq = 0; - ss = (char *)string; - while (c = string[i]) - { - if (pass_next) - { - pass_next = 0; - if (c == 0) - CQ_RETURN(i); - ADVANCE_CHAR (string, slen, i); - continue; - } - else if ((flags & 1) == 0 && c == '\\') - { - pass_next = 1; - i++; - continue; - } - else if (backq) - { - if (c == '`') - backq = 0; - ADVANCE_CHAR (string, slen, i); - continue; - } - else if ((flags & 1) == 0 && c == '`') - { - backq = 1; - i++; - continue; - } - else if ((flags & 1) == 0 && c == open) - { - count++; - i++; - continue; - } - else if (c == close) - { - count--; - if (count == 0) - break; - i++; - continue; - } - else if ((flags & 1) == 0 && (c == '\'' || c == '"')) - { - i = (c == '\'') ? skip_single_quoted (ss, slen, ++i, 0) - : skip_double_quoted (ss, slen, ++i, 0); - /* no increment, the skip functions increment past the closing quote. */ - } - else if ((flags & 1) == 0 && c == '$' && (string[i+1] == LPAREN || string[i+1] == LBRACE)) - { - si = i + 2; - if (string[si] == '\0') - CQ_RETURN(si); - - /* XXX - extract_command_subst here? */ - if (string[i+1] == LPAREN) - temp = extract_delimited_string (ss, &si, "$(", "(", ")", SX_NOALLOC|SX_COMMAND); /* ) */ - else - temp = extract_dollar_brace_string (ss, &si, 0, SX_NOALLOC); - - CHECK_STRING_OVERRUN (i, si, slen, c); - - i = si; - if (string[i] == '\0') /* don't increment i past EOS in loop */ - break; - i++; - continue; - } - else - ADVANCE_CHAR (string, slen, i); - } - - CQ_RETURN(i); -} - -#if defined (ARRAY_VARS) -/* FLAGS has 1 as a reserved value, since skip_matched_pair uses it for - skipping over quoted strings and taking the first instance of the - closing character. FLAGS & 2 means that STRING[START] points one - character past the open bracket; FLAGS & 2 == 0 means that STRING[START] - points to the open bracket. skip_matched_pair knows how to deal with this. */ -int -skipsubscript (string, start, flags) - const char *string; - int start, flags; -{ - return (skip_matched_pair (string, start, '[', ']', flags)); -} -#endif - -/* Skip characters in STRING until we find a character in DELIMS, and return - the index of that character. START is the index into string at which we - begin. This is similar in spirit to strpbrk, but it returns an index into - STRING and takes a starting index. This little piece of code knows quite - a lot of shell syntax. It's very similar to skip_double_quoted and other - functions of that ilk. */ -int -skip_to_delim (string, start, delims, flags) - char *string; - int start; - char *delims; - int flags; -{ - int i, pass_next, backq, dquote, si, c, oldjmp; - int invert, skipquote, skipcmd, noprocsub, completeflag; - int arithexp, skipcol; - size_t slen; - char *temp, open[3]; - DECLARE_MBSTATE; - - slen = strlen (string + start) + start; - oldjmp = no_longjmp_on_fatal_error; - if (flags & SD_NOJMP) - no_longjmp_on_fatal_error = 1; - invert = (flags & SD_INVERT); - skipcmd = (flags & SD_NOSKIPCMD) == 0; - noprocsub = (flags & SD_NOPROCSUB); - completeflag = (flags & SD_COMPLETE) ? SX_COMPLETE : 0; - - arithexp = (flags & SD_ARITHEXP); - skipcol = 0; - - i = start; - pass_next = backq = dquote = 0; - while (c = string[i]) - { - /* If this is non-zero, we should not let quote characters be delimiters - and the current character is a single or double quote. We should not - test whether or not it's a delimiter until after we skip single- or - double-quoted strings. */ - skipquote = ((flags & SD_NOQUOTEDELIM) && (c == '\'' || c =='"')); - if (pass_next) - { - pass_next = 0; - if (c == 0) - CQ_RETURN(i); - ADVANCE_CHAR (string, slen, i); - continue; - } - else if (c == '\\') - { - pass_next = 1; - i++; - continue; - } - else if (backq) - { - if (c == '`') - backq = 0; - ADVANCE_CHAR (string, slen, i); - continue; - } - else if (c == '`') - { - backq = 1; - i++; - continue; - } - else if (arithexp && skipcol && c == ':') - { - skipcol--; - i++; - continue; - } - else if (arithexp && c == '?') - { - skipcol++; - i++; - continue; - } - else if (skipquote == 0 && invert == 0 && member (c, delims)) - break; - /* the usual case is to use skip_xxx_quoted, but we don't skip over double - quoted strings when looking for the history expansion character as a - delimiter. */ - /* special case for programmable completion which takes place before - parser converts backslash-escaped single quotes between $'...' to - `regular' single-quoted strings. */ - else if (completeflag && i > 0 && string[i-1] == '$' && c == '\'') - i = skip_single_quoted (string, slen, ++i, SX_COMPLETE); - else if (c == '\'') - i = skip_single_quoted (string, slen, ++i, 0); - else if (c == '"') - i = skip_double_quoted (string, slen, ++i, completeflag); - else if (c == LPAREN && arithexp) - { - si = i + 1; - if (string[si] == '\0') - CQ_RETURN(si); - - temp = extract_delimited_string (string, &si, "(", "(", ")", SX_NOALLOC); /* ) */ - i = si; - if (string[i] == '\0') /* don't increment i past EOS in loop */ - break; - i++; - continue; - } - else if (c == '$' && ((skipcmd && string[i+1] == LPAREN) || string[i+1] == LBRACE)) - { - si = i + 2; - if (string[si] == '\0') - CQ_RETURN(si); - - if (string[i+1] == LPAREN) - temp = extract_delimited_string (string, &si, "$(", "(", ")", SX_NOALLOC|SX_COMMAND|completeflag); /* ) */ - else - temp = extract_dollar_brace_string (string, &si, 0, SX_NOALLOC); - CHECK_STRING_OVERRUN (i, si, slen, c); - i = si; - if (string[i] == '\0') /* don't increment i past EOS in loop */ - break; - i++; - continue; - } -#if defined (PROCESS_SUBSTITUTION) - else if (skipcmd && noprocsub == 0 && (c == '<' || c == '>') && string[i+1] == LPAREN) - { - si = i + 2; - if (string[si] == '\0') - CQ_RETURN(si); - - temp = extract_delimited_string (string, &si, (c == '<') ? "<(" : ">(", "(", ")", SX_COMMAND|SX_NOALLOC); /* )) */ - CHECK_STRING_OVERRUN (i, si, slen, c); - i = si; - if (string[i] == '\0') - break; - i++; - continue; - } -#endif /* PROCESS_SUBSTITUTION */ -#if defined (EXTENDED_GLOB) - else if ((flags & SD_EXTGLOB) && extended_glob && string[i+1] == LPAREN && member (c, "?*+!@")) - { - si = i + 2; - if (string[si] == '\0') - CQ_RETURN(si); - - open[0] = c; - open[1] = LPAREN; - open[2] = '\0'; - temp = extract_delimited_string (string, &si, open, "(", ")", SX_NOALLOC); /* ) */ - - CHECK_STRING_OVERRUN (i, si, slen, c); - i = si; - if (string[i] == '\0') /* don't increment i past EOS in loop */ - break; - i++; - continue; - } -#endif - else if ((flags & SD_GLOB) && c == LBRACK) - { - si = i + 1; - if (string[si] == '\0') - CQ_RETURN(si); - - temp = extract_delimited_string (string, &si, "[", "[", "]", SX_NOALLOC); /* ] */ - - i = si; - if (string[i] == '\0') /* don't increment i past EOS in loop */ - break; - i++; - continue; - } - else if ((skipquote || invert) && (member (c, delims) == 0)) - break; - else - ADVANCE_CHAR (string, slen, i); - } - - CQ_RETURN(i); -} - -#if defined (BANG_HISTORY) -/* Skip to the history expansion character (delims[0]), paying attention to - quoted strings and command and process substitution. This is a stripped- - down version of skip_to_delims. The essential difference is that this - resets the quoting state when starting a command substitution */ -int -skip_to_histexp (string, start, delims, flags) - char *string; - int start; - char *delims; - int flags; -{ - int i, pass_next, backq, dquote, c, oldjmp; - int histexp_comsub, histexp_backq, old_dquote; - size_t slen; - DECLARE_MBSTATE; - - slen = strlen (string + start) + start; - oldjmp = no_longjmp_on_fatal_error; - if (flags & SD_NOJMP) - no_longjmp_on_fatal_error = 1; - - histexp_comsub = histexp_backq = old_dquote = 0; - - i = start; - pass_next = backq = dquote = 0; - while (c = string[i]) - { - if (pass_next) - { - pass_next = 0; - if (c == 0) - CQ_RETURN(i); - ADVANCE_CHAR (string, slen, i); - continue; - } - else if (c == '\\') - { - pass_next = 1; - i++; - continue; - } - else if (backq && c == '`') - { - backq = 0; - histexp_backq--; - dquote = old_dquote; - i++; - continue; - } - else if (c == '`') - { - backq = 1; - histexp_backq++; - old_dquote = dquote; /* simple - one level for now */ - dquote = 0; - i++; - continue; - } - /* When in double quotes, act as if the double quote is a member of - history_no_expand_chars, like the history library does */ - else if (dquote && c == delims[0] && string[i+1] == '"') - { - i++; - continue; - } - else if (c == delims[0]) - break; - /* the usual case is to use skip_xxx_quoted, but we don't skip over double - quoted strings when looking for the history expansion character as a - delimiter. */ - else if (dquote && c == '\'') - { - i++; - continue; - } - else if (c == '\'') - i = skip_single_quoted (string, slen, ++i, 0); - /* The posixly_correct test makes posix-mode shells allow double quotes - to quote the history expansion character */ - else if (posixly_correct == 0 && c == '"') - { - dquote = 1 - dquote; - i++; - continue; - } - else if (c == '"') - i = skip_double_quoted (string, slen, ++i, 0); -#if defined (PROCESS_SUBSTITUTION) - else if ((c == '$' || c == '<' || c == '>') && string[i+1] == LPAREN && string[i+2] != LPAREN) -#else - else if (c == '$' && string[i+1] == LPAREN && string[i+2] != LPAREN) -#endif - { - if (string[i+2] == '\0') - CQ_RETURN(i+2); - i += 2; - histexp_comsub++; - old_dquote = dquote; - dquote = 0; - } - else if (histexp_comsub && c == RPAREN) - { - histexp_comsub--; - dquote = old_dquote; - i++; - continue; - } - else if (backq) /* placeholder */ - { - ADVANCE_CHAR (string, slen, i); - continue; - } - else - ADVANCE_CHAR (string, slen, i); - } - - CQ_RETURN(i); -} -#endif /* BANG_HISTORY */ - -#if defined (READLINE) -/* Return 1 if the portion of STRING ending at EINDEX is quoted (there is - an unclosed quoted string), or if the character at EINDEX is quoted - by a backslash. NO_LONGJMP_ON_FATAL_ERROR is used to flag that the various - single and double-quoted string parsing functions should not return an - error if there are unclosed quotes or braces. The characters that this - recognizes need to be the same as the contents of - rl_completer_quote_characters. */ - -int -char_is_quoted (string, eindex) - char *string; - int eindex; -{ - int i, pass_next, c, oldjmp; - size_t slen; - DECLARE_MBSTATE; - - slen = strlen (string); - oldjmp = no_longjmp_on_fatal_error; - no_longjmp_on_fatal_error = 1; - i = pass_next = 0; - - /* If we have an open quoted string from a previous line, see if it's - closed before string[eindex], so we don't interpret that close quote - as starting a new quoted string. */ - if (current_command_line_count > 0 && dstack.delimiter_depth > 0) - { - c = dstack.delimiters[dstack.delimiter_depth - 1]; - if (c == '\'') - i = skip_single_quoted (string, slen, 0, 0); - else if (c == '"') - i = skip_double_quoted (string, slen, 0, SX_COMPLETE); - if (i > eindex) - CQ_RETURN (1); - } - - while (i <= eindex) - { - c = string[i]; - - if (pass_next) - { - pass_next = 0; - if (i >= eindex) /* XXX was if (i >= eindex - 1) */ - CQ_RETURN(1); - ADVANCE_CHAR (string, slen, i); - continue; - } - else if (c == '\\') - { - pass_next = 1; - i++; - continue; - } - else if (c == '$' && string[i+1] == '\'' && string[i+2]) - { - i += 2; - i = skip_single_quoted (string, slen, i, SX_COMPLETE); - if (i > eindex) - CQ_RETURN (i); - } - else if (c == '\'' || c == '"') - { - i = (c == '\'') ? skip_single_quoted (string, slen, ++i, 0) - : skip_double_quoted (string, slen, ++i, SX_COMPLETE); - if (i > eindex) - CQ_RETURN(1); - /* no increment, the skip_xxx functions go one past end */ - } - else - ADVANCE_CHAR (string, slen, i); - } - - CQ_RETURN(0); -} - -int -unclosed_pair (string, eindex, openstr) - char *string; - int eindex; - char *openstr; -{ - int i, pass_next, openc, olen; - size_t slen; - DECLARE_MBSTATE; - - slen = strlen (string); - olen = strlen (openstr); - i = pass_next = openc = 0; - while (i <= eindex) - { - if (pass_next) - { - pass_next = 0; - if (i >= eindex) /* XXX was if (i >= eindex - 1) */ - return 0; - ADVANCE_CHAR (string, slen, i); - continue; - } - else if (string[i] == '\\') - { - pass_next = 1; - i++; - continue; - } - else if (STREQN (string + i, openstr, olen)) - { - openc = 1 - openc; - i += olen; - } - /* XXX - may want to handle $'...' specially here */ - else if (string[i] == '\'' || string[i] == '"') - { - i = (string[i] == '\'') ? skip_single_quoted (string, slen, i, 0) - : skip_double_quoted (string, slen, i, SX_COMPLETE); - if (i > eindex) - return 0; - } - else - ADVANCE_CHAR (string, slen, i); - } - return (openc); -} - -/* Split STRING (length SLEN) at DELIMS, and return a WORD_LIST with the - individual words. If DELIMS is NULL, the current value of $IFS is used - to split the string, and the function follows the shell field splitting - rules. SENTINEL is an index to look for. NWP, if non-NULL, - gets the number of words in the returned list. CWP, if non-NULL, gets - the index of the word containing SENTINEL. Non-whitespace chars in - DELIMS delimit separate fields. This is used by programmable completion. */ -WORD_LIST * -split_at_delims (string, slen, delims, sentinel, flags, nwp, cwp) - char *string; - int slen; - const char *delims; - int sentinel, flags; - int *nwp, *cwp; -{ - int ts, te, i, nw, cw, ifs_split, dflags; - char *token, *d, *d2; - WORD_LIST *ret, *tl; - - if (string == 0 || *string == '\0') - { - if (nwp) - *nwp = 0; - if (cwp) - *cwp = 0; - return ((WORD_LIST *)NULL); - } - - d = (delims == 0) ? ifs_value : (char *)delims; - ifs_split = delims == 0; - - /* Make d2 the non-whitespace characters in delims */ - d2 = 0; - if (delims) - { - size_t slength; -#if defined (HANDLE_MULTIBYTE) - size_t mblength = 1; -#endif - DECLARE_MBSTATE; - - slength = strlen (delims); - d2 = (char *)xmalloc (slength + 1); - i = ts = 0; - while (delims[i]) - { -#if defined (HANDLE_MULTIBYTE) - mbstate_t state_bak; - state_bak = state; - mblength = MBRLEN (delims + i, slength, &state); - if (MB_INVALIDCH (mblength)) - state = state_bak; - else if (mblength > 1) - { - memcpy (d2 + ts, delims + i, mblength); - ts += mblength; - i += mblength; - slength -= mblength; - continue; - } -#endif - if (whitespace (delims[i]) == 0) - d2[ts++] = delims[i]; - - i++; - slength--; - } - d2[ts] = '\0'; - } - - ret = (WORD_LIST *)NULL; - - /* Remove sequences of whitespace characters at the start of the string, as - long as those characters are delimiters. */ - for (i = 0; member (string[i], d) && spctabnl (string[i]); i++) - ; - if (string[i] == '\0') - { - FREE (d2); - return (ret); - } - - ts = i; - nw = 0; - cw = -1; - dflags = flags|SD_NOJMP; - while (1) - { - te = skip_to_delim (string, ts, d, dflags); - - /* If we have a non-whitespace delimiter character, use it to make a - separate field. This is just about what $IFS splitting does and - is closer to the behavior of the shell parser. */ - if (ts == te && d2 && member (string[ts], d2)) - { - te = ts + 1; - /* If we're using IFS splitting, the non-whitespace delimiter char - and any additional IFS whitespace delimits a field. */ - if (ifs_split) - while (member (string[te], d) && spctabnl (string[te]) && ((flags&SD_NOQUOTEDELIM) == 0 || (string[te] != '\'' && string[te] != '"'))) - te++; - else - while (member (string[te], d2) && ((flags&SD_NOQUOTEDELIM) == 0 || (string[te] != '\'' && string[te] != '"'))) - te++; - } - - token = substring (string, ts, te); - - ret = add_string_to_list (token, ret); /* XXX */ - free (token); - nw++; - - if (sentinel >= ts && sentinel <= te) - cw = nw; - - /* If the cursor is at whitespace just before word start, set the - sentinel word to the current word. */ - if (cwp && cw == -1 && sentinel == ts-1) - cw = nw; - - /* If the cursor is at whitespace between two words, make a new, empty - word, add it before (well, after, since the list is in reverse order) - the word we just added, and set the current word to that one. */ - if (cwp && cw == -1 && sentinel < ts) - { - tl = make_word_list (make_word (""), ret->next); - ret->next = tl; - cw = nw; - nw++; - } - - if (string[te] == 0) - break; - - i = te; - /* XXX - honor SD_NOQUOTEDELIM here */ - while (member (string[i], d) && (ifs_split || spctabnl(string[i])) && ((flags&SD_NOQUOTEDELIM) == 0 || (string[te] != '\'' && string[te] != '"'))) - i++; - - if (string[i]) - ts = i; - else - break; - } - - /* Special case for SENTINEL at the end of STRING. If we haven't found - the word containing SENTINEL yet, and the index we're looking for is at - the end of STRING (or past the end of the previously-found token, - possible if the end of the line is composed solely of IFS whitespace) - add an additional null argument and set the current word pointer to that. */ - if (cwp && cw == -1 && (sentinel >= slen || sentinel >= te)) - { - if (whitespace (string[sentinel - 1])) - { - token = ""; - ret = add_string_to_list (token, ret); - nw++; - } - cw = nw; - } - - if (nwp) - *nwp = nw; - if (cwp) - *cwp = cw; - - FREE (d2); - - return (REVERSE_LIST (ret, WORD_LIST *)); -} -#endif /* READLINE */ - -#if 0 -/* UNUSED */ -/* Extract the name of the variable to bind to from the assignment string. */ -char * -assignment_name (string) - char *string; -{ - int offset; - char *temp; - - offset = assignment (string, 0); - if (offset == 0) - return (char *)NULL; - temp = substring (string, 0, offset); - return (temp); -} -#endif - -/* **************************************************************** */ -/* */ -/* Functions to convert strings to WORD_LISTs and vice versa */ -/* */ -/* **************************************************************** */ - -/* Return a single string of all the words in LIST. SEP is the separator - to put between individual elements of LIST in the output string. */ -char * -string_list_internal (list, sep) - WORD_LIST *list; - char *sep; -{ - register WORD_LIST *t; - char *result, *r; - size_t word_len, sep_len, result_size; - - if (list == 0) - return ((char *)NULL); - - /* Short-circuit quickly if we don't need to separate anything. */ - if (list->next == 0) - return (savestring (list->word->word)); - - /* This is nearly always called with either sep[0] == 0 or sep[1] == 0. */ - sep_len = STRLEN (sep); - result_size = 0; - - for (t = list; t; t = t->next) - { - if (t != list) - result_size += sep_len; - result_size += strlen (t->word->word); - } - - r = result = (char *)xmalloc (result_size + 1); - - for (t = list; t; t = t->next) - { - if (t != list && sep_len) - { - if (sep_len > 1) - { - FASTCOPY (sep, r, sep_len); - r += sep_len; - } - else - *r++ = sep[0]; - } - - word_len = strlen (t->word->word); - FASTCOPY (t->word->word, r, word_len); - r += word_len; - } - - *r = '\0'; - return (result); -} - -/* Return a single string of all the words present in LIST, separating - each word with a space. */ -char * -string_list (list) - WORD_LIST *list; -{ - return (string_list_internal (list, " ")); -} - -/* An external interface that can be used by the rest of the shell to - obtain a string containing the first character in $IFS. Handles all - the multibyte complications. If LENP is non-null, it is set to the - length of the returned string. */ -char * -ifs_firstchar (lenp) - int *lenp; -{ - char *ret; - int len; - - ret = xmalloc (MB_LEN_MAX + 1); -#if defined (HANDLE_MULTIBYTE) - if (ifs_firstc_len == 1) - { - ret[0] = ifs_firstc[0]; - ret[1] = '\0'; - len = ret[0] ? 1 : 0; - } - else - { - memcpy (ret, ifs_firstc, ifs_firstc_len); - ret[len = ifs_firstc_len] = '\0'; - } -#else - ret[0] = ifs_firstc; - ret[1] = '\0'; - len = ret[0] ? 0 : 1; -#endif - - if (lenp) - *lenp = len; - - return ret; -} - -/* Return a single string of all the words present in LIST, obeying the - quoting rules for "$*", to wit: (P1003.2, draft 11, 3.5.2) "If the - expansion [of $*] appears within a double quoted string, it expands - to a single field with the value of each parameter separated by the - first character of the IFS variable, or by a if IFS is unset." */ -/* Posix interpretation 888 changes this when IFS is null by specifying - that when unquoted, this expands to separate arguments */ -char * -string_list_dollar_star (list, quoted, flags) - WORD_LIST *list; - int quoted, flags; -{ - char *ret; -#if defined (HANDLE_MULTIBYTE) -# if defined (__GNUC__) - char sep[MB_CUR_MAX + 1]; -# else - char *sep = 0; -# endif -#else - char sep[2]; -#endif - -#if defined (HANDLE_MULTIBYTE) -# if !defined (__GNUC__) - sep = (char *)xmalloc (MB_CUR_MAX + 1); -# endif /* !__GNUC__ */ - if (ifs_firstc_len == 1) - { - sep[0] = ifs_firstc[0]; - sep[1] = '\0'; - } - else - { - memcpy (sep, ifs_firstc, ifs_firstc_len); - sep[ifs_firstc_len] = '\0'; - } -#else - sep[0] = ifs_firstc; - sep[1] = '\0'; -#endif - - ret = string_list_internal (list, sep); -#if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__) - free (sep); -#endif - return ret; -} - -/* Turn $@ into a string. If (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) - is non-zero, the $@ appears within double quotes, and we should quote - the list before converting it into a string. If IFS is unset, and the - word is not quoted, we just need to quote CTLESC and CTLNUL characters - in the words in the list, because the default value of $IFS is - , IFS characters in the words in the list should - also be split. If IFS is null, and the word is not quoted, we need - to quote the words in the list to preserve the positional parameters - exactly. - Valid values for the FLAGS argument are the PF_ flags in command.h, - the only one we care about is PF_ASSIGNRHS. $@ is supposed to expand - to the positional parameters separated by spaces no matter what IFS is - set to if in a context where word splitting is not performed. The only - one that we didn't handle before is assignment statement arguments to - declaration builtins like `declare'. */ -char * -string_list_dollar_at (list, quoted, flags) - WORD_LIST *list; - int quoted; - int flags; -{ - char *ifs, *ret; -#if defined (HANDLE_MULTIBYTE) -# if defined (__GNUC__) - char sep[MB_CUR_MAX + 1]; -# else - char *sep = 0; -# endif /* !__GNUC__ */ -#else - char sep[2]; -#endif - WORD_LIST *tlist; - - /* XXX this could just be ifs = ifs_value; */ - ifs = ifs_var ? value_cell (ifs_var) : (char *)0; - -#if defined (HANDLE_MULTIBYTE) -# if !defined (__GNUC__) - sep = (char *)xmalloc (MB_CUR_MAX + 1); -# endif /* !__GNUC__ */ - /* XXX - testing PF_ASSIGNRHS to make sure positional parameters are - separated with a space even when word splitting will not occur. */ - if (flags & PF_ASSIGNRHS) - { - sep[0] = ' '; - sep[1] = '\0'; - } - else if (ifs && *ifs) - { - if (ifs_firstc_len == 1) - { - sep[0] = ifs_firstc[0]; - sep[1] = '\0'; - } - else - { - memcpy (sep, ifs_firstc, ifs_firstc_len); - sep[ifs_firstc_len] = '\0'; - } - } - else - { - sep[0] = ' '; - sep[1] = '\0'; - } -#else /* !HANDLE_MULTIBYTE */ - /* XXX - PF_ASSIGNRHS means no word splitting, so we want positional - parameters separated by a space. */ - sep[0] = ((flags & PF_ASSIGNRHS) || ifs == 0 || *ifs == 0) ? ' ' : *ifs; - sep[1] = '\0'; -#endif /* !HANDLE_MULTIBYTE */ - - /* XXX -- why call quote_list if ifs == 0? we can get away without doing - it now that quote_escapes quotes spaces */ - tlist = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES|Q_PATQUOTE)) - ? quote_list (list) - : list_quote_escapes (list); - - ret = string_list_internal (tlist, sep); -#if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__) - free (sep); -#endif - return ret; -} - -/* Turn the positional parameters into a string, understanding quoting and - the various subtleties of using the first character of $IFS as the - separator. Calls string_list_dollar_at, string_list_dollar_star, and - string_list as appropriate. */ -/* This needs to fully understand the additional contexts where word - splitting does not occur (W_ASSIGNRHS, etc.) */ -char * -string_list_pos_params (pchar, list, quoted, pflags) - int pchar; - WORD_LIST *list; - int quoted, pflags; -{ - char *ret; - WORD_LIST *tlist; - - if (pchar == '*' && (quoted & Q_DOUBLE_QUOTES)) - { - tlist = quote_list (list); - word_list_remove_quoted_nulls (tlist); - ret = string_list_dollar_star (tlist, 0, 0); - } - else if (pchar == '*' && (quoted & Q_HERE_DOCUMENT)) - { - tlist = quote_list (list); - word_list_remove_quoted_nulls (tlist); - ret = string_list (tlist); - } - else if (pchar == '*' && quoted == 0 && ifs_is_null) /* XXX */ - ret = expand_no_split_dollar_star ? string_list_dollar_star (list, quoted, 0) : string_list_dollar_at (list, quoted, 0); /* Posix interp 888 */ - else if (pchar == '*' && quoted == 0 && (pflags & PF_ASSIGNRHS)) /* XXX */ - ret = expand_no_split_dollar_star ? string_list_dollar_star (list, quoted, 0) : string_list_dollar_at (list, quoted, 0); /* Posix interp 888 */ - else if (pchar == '*') - { - /* Even when unquoted, string_list_dollar_star does the right thing - making sure that the first character of $IFS is used as the - separator. */ - ret = string_list_dollar_star (list, quoted, 0); - } - else if (pchar == '@' && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))) - /* We use string_list_dollar_at, but only if the string is quoted, since - that quotes the escapes if it's not, which we don't want. We could - use string_list (the old code did), but that doesn't do the right - thing if the first character of $IFS is not a space. We use - string_list_dollar_star if the string is unquoted so we make sure that - the elements of $@ are separated by the first character of $IFS for - later splitting. */ - ret = string_list_dollar_at (list, quoted, 0); - else if (pchar == '@' && quoted == 0 && ifs_is_null) /* XXX */ - ret = string_list_dollar_at (list, quoted, 0); /* Posix interp 888 */ - else if (pchar == '@' && quoted == 0 && (pflags & PF_ASSIGNRHS)) - ret = string_list_dollar_at (list, quoted, pflags); /* Posix interp 888 */ - else if (pchar == '@') - ret = string_list_dollar_star (list, quoted, 0); - else - ret = string_list ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? quote_list (list) : list); - - return ret; -} - -/* Return the list of words present in STRING. Separate the string into - words at any of the characters found in SEPARATORS. If QUOTED is - non-zero then word in the list will have its quoted flag set, otherwise - the quoted flag is left as make_word () deemed fit. - - This obeys the P1003.2 word splitting semantics. If `separators' is - exactly , then the splitting algorithm is that of - the Bourne shell, which treats any sequence of characters from `separators' - as a delimiter. If IFS is unset, which results in `separators' being set - to "", no splitting occurs. If separators has some other value, the - following rules are applied (`IFS white space' means zero or more - occurrences of , , or , as long as those characters - are in `separators'): - - 1) IFS white space is ignored at the start and the end of the - string. - 2) Each occurrence of a character in `separators' that is not - IFS white space, along with any adjacent occurrences of - IFS white space delimits a field. - 3) Any nonzero-length sequence of IFS white space delimits a field. - */ - -/* BEWARE! list_string strips null arguments. Don't call it twice and - expect to have "" preserved! */ - -/* This performs word splitting and quoted null character removal on - STRING. */ -#define issep(c) \ - (((separators)[0]) ? ((separators)[1] ? isifs(c) \ - : (c) == (separators)[0]) \ - : 0) - -/* member of the space character class in the current locale */ -#define ifs_whitespace(c) ISSPACE(c) - -/* "adjacent IFS white space" */ -#define ifs_whitesep(c) ((sh_style_split || separators == 0) ? spctabnl (c) \ - : ifs_whitespace (c)) - -WORD_LIST * -list_string (string, separators, quoted) - register char *string, *separators; - int quoted; -{ - WORD_LIST *result; - WORD_DESC *t; - char *current_word, *s; - int sindex, sh_style_split, whitesep, xflags, free_word; - size_t slen; - - if (!string || !*string) - return ((WORD_LIST *)NULL); - - sh_style_split = separators && separators[0] == ' ' && - separators[1] == '\t' && - separators[2] == '\n' && - separators[3] == '\0'; - for (xflags = 0, s = ifs_value; s && *s; s++) - { - if (*s == CTLESC) xflags |= SX_NOCTLESC; - else if (*s == CTLNUL) xflags |= SX_NOESCCTLNUL; - } - - slen = 0; - /* Remove sequences of whitespace at the beginning of STRING, as - long as those characters appear in IFS. Do not do this if - STRING is quoted or if there are no separator characters. We use the - Posix definition of whitespace as a member of the space character - class in the current locale. */ -#if 0 - if (!quoted || !separators || !*separators) -#else - /* issep() requires that separators be non-null, and always returns 0 if - separator is the empty string, so don't bother if we get an empty string - for separators. We already returned NULL above if STRING is empty. */ - if (!quoted && separators && *separators) -#endif - { - for (s = string; *s && issep (*s) && ifs_whitespace (*s); s++); - - if (!*s) - return ((WORD_LIST *)NULL); - - string = s; - } - - /* OK, now STRING points to a word that does not begin with white space. - The splitting algorithm is: - extract a word, stopping at a separator - skip sequences of whitespace characters as long as they are separators - This obeys the field splitting rules in Posix.2. */ - slen = STRLEN (string); - for (result = (WORD_LIST *)NULL, sindex = 0; string[sindex]; ) - { - /* Don't need string length in ADVANCE_CHAR unless multibyte chars are - possible, but need it in string_extract_verbatim for bounds checking */ - current_word = string_extract_verbatim (string, slen, &sindex, separators, xflags); - if (current_word == 0) - break; - - free_word = 1; /* If non-zero, we free current_word */ - - /* If we have a quoted empty string, add a quoted null argument. We - want to preserve the quoted null character iff this is a quoted - empty string; otherwise the quoted null characters are removed - below. */ - if (QUOTED_NULL (current_word)) - { - t = alloc_word_desc (); - t->word = make_quoted_char ('\0'); - t->flags |= W_QUOTED|W_HASQUOTEDNULL; - result = make_word_list (t, result); - } - else if (current_word[0] != '\0') - { - /* If we have something, then add it regardless. However, - perform quoted null character removal on the current word. */ - remove_quoted_nulls (current_word); - - /* We don't want to set the word flags based on the string contents - here -- that's mostly for the parser -- so we just allocate a - WORD_DESC *, assign current_word (noting that we don't want to - free it), and skip all of make_word. */ - t = alloc_word_desc (); - t->word = current_word; - result = make_word_list (t, result); - free_word = 0; - result->word->flags &= ~W_HASQUOTEDNULL; /* just to be sure */ - if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) - result->word->flags |= W_QUOTED; - /* If removing quoted null characters leaves an empty word, note - that we saw this for the caller to act on. */ - if (current_word == 0 || current_word[0] == '\0') - result->word->flags |= W_SAWQUOTEDNULL; - } - - /* If we're not doing sequences of separators in the traditional - Bourne shell style, then add a quoted null argument. */ - else if (!sh_style_split && !ifs_whitespace (string[sindex])) - { - t = alloc_word_desc (); - t->word = make_quoted_char ('\0'); - t->flags |= W_QUOTED|W_HASQUOTEDNULL; - result = make_word_list (t, result); - } - - if (free_word) - free (current_word); - - /* Note whether or not the separator is IFS whitespace, used later. */ - whitesep = string[sindex] && ifs_whitesep (string[sindex]); - - /* Move past the current separator character. */ - if (string[sindex]) - { - DECLARE_MBSTATE; - ADVANCE_CHAR (string, slen, sindex); - } - - /* Now skip sequences of whitespace characters if they are - in the list of separators. */ - while (string[sindex] && ifs_whitesep (string[sindex]) && issep (string[sindex])) - sindex++; - - /* If the first separator was IFS whitespace and the current character - is a non-whitespace IFS character, it should be part of the current - field delimiter, not a separate delimiter that would result in an - empty field. Look at POSIX.2, 3.6.5, (3)(b). */ - if (string[sindex] && whitesep && issep (string[sindex]) && !ifs_whitesep (string[sindex])) - { - sindex++; - /* An IFS character that is not IFS white space, along with any - adjacent IFS white space, shall delimit a field. (SUSv3) */ - while (string[sindex] && ifs_whitesep (string[sindex]) && isifs (string[sindex])) - sindex++; - } - } - return (REVERSE_LIST (result, WORD_LIST *)); -} - -/* Parse a single word from STRING, using SEPARATORS to separate fields. - ENDPTR is set to the first character after the word. This is used by - the `read' builtin. - - This is never called with SEPARATORS != $IFS, and takes advantage of that. - - XXX - this function is very similar to list_string; they should be - combined - XXX */ - -/* character is in $IFS */ -#define islocalsep(c) (local_cmap[(unsigned char)(c)] != 0) - -char * -get_word_from_string (stringp, separators, endptr) - char **stringp, *separators, **endptr; -{ - register char *s; - char *current_word; - int sindex, sh_style_split, whitesep, xflags; - unsigned char local_cmap[UCHAR_MAX+1]; /* really only need single-byte chars here */ - size_t slen; - - if (!stringp || !*stringp || !**stringp) - return ((char *)NULL); - - sh_style_split = separators && separators[0] == ' ' && - separators[1] == '\t' && - separators[2] == '\n' && - separators[3] == '\0'; - memset (local_cmap, '\0', sizeof (local_cmap)); - for (xflags = 0, s = separators; s && *s; s++) - { - if (*s == CTLESC) xflags |= SX_NOCTLESC; - if (*s == CTLNUL) xflags |= SX_NOESCCTLNUL; - local_cmap[(unsigned char)*s] = 1; /* local charmap of separators */ - } - - s = *stringp; - slen = 0; - - /* Remove sequences of whitespace at the beginning of STRING, as - long as those characters appear in SEPARATORS. This happens if - SEPARATORS == $' \t\n' or if IFS is unset. */ - if (sh_style_split || separators == 0) - for (; *s && spctabnl (*s) && islocalsep (*s); s++); - else - for (; *s && ifs_whitespace (*s) && islocalsep (*s); s++); - - /* If the string is nothing but whitespace, update it and return. */ - if (!*s) - { - *stringp = s; - if (endptr) - *endptr = s; - return ((char *)NULL); - } - - /* OK, S points to a word that does not begin with white space. - Now extract a word, stopping at a separator, save a pointer to - the first character after the word, then skip sequences of spc, - tab, or nl as long as they are separators. - - This obeys the field splitting rules in Posix.2. */ - sindex = 0; - /* Don't need string length in ADVANCE_CHAR unless multibyte chars are - possible, but need it in string_extract_verbatim for bounds checking */ - slen = STRLEN (s); - current_word = string_extract_verbatim (s, slen, &sindex, separators, xflags); - - /* Set ENDPTR to the first character after the end of the word. */ - if (endptr) - *endptr = s + sindex; - - /* Note whether or not the separator is IFS whitespace, used later. */ - whitesep = s[sindex] && ifs_whitesep (s[sindex]); - - /* Move past the current separator character. */ - if (s[sindex]) - { - DECLARE_MBSTATE; - ADVANCE_CHAR (s, slen, sindex); - } - - /* Now skip sequences of space, tab, or newline characters if they are - in the list of separators. */ - while (s[sindex] && spctabnl (s[sindex]) && islocalsep (s[sindex])) - sindex++; - - /* If the first separator was IFS whitespace and the current character is - a non-whitespace IFS character, it should be part of the current field - delimiter, not a separate delimiter that would result in an empty field. - Look at POSIX.2, 3.6.5, (3)(b). */ - if (s[sindex] && whitesep && islocalsep (s[sindex]) && !ifs_whitesep (s[sindex])) - { - sindex++; - /* An IFS character that is not IFS white space, along with any adjacent - IFS white space, shall delimit a field. */ - while (s[sindex] && ifs_whitesep (s[sindex]) && islocalsep(s[sindex])) - sindex++; - } - - /* Update STRING to point to the next field. */ - *stringp = s + sindex; - return (current_word); -} - -/* Remove IFS white space at the end of STRING. Start at the end - of the string and walk backwards until the beginning of the string - or we find a character that's not IFS white space and not CTLESC. - Only let CTLESC escape a white space character if SAW_ESCAPE is - non-zero. */ -char * -strip_trailing_ifs_whitespace (string, separators, saw_escape) - char *string, *separators; - int saw_escape; -{ - char *s; - - s = string + STRLEN (string) - 1; - while (s > string && ((spctabnl (*s) && isifs (*s)) || - (saw_escape && *s == CTLESC && spctabnl (s[1])))) - s--; - *++s = '\0'; - return string; -} - -#if 0 -/* UNUSED */ -/* Split STRING into words at whitespace. Obeys shell-style quoting with - backslashes, single and double quotes. */ -WORD_LIST * -list_string_with_quotes (string) - char *string; -{ - WORD_LIST *list; - char *token, *s; - size_t s_len; - int c, i, tokstart, len; - - for (s = string; s && *s && spctabnl (*s); s++) - ; - if (s == 0 || *s == 0) - return ((WORD_LIST *)NULL); - - s_len = strlen (s); - tokstart = i = 0; - list = (WORD_LIST *)NULL; - while (1) - { - c = s[i]; - if (c == '\\') - { - i++; - if (s[i]) - i++; - } - else if (c == '\'') - i = skip_single_quoted (s, s_len, ++i, 0); - else if (c == '"') - i = skip_double_quoted (s, s_len, ++i, 0); - else if (c == 0 || spctabnl (c)) - { - /* We have found the end of a token. Make a word out of it and - add it to the word list. */ - token = substring (s, tokstart, i); - list = add_string_to_list (token, list); - free (token); - while (spctabnl (s[i])) - i++; - if (s[i]) - tokstart = i; - else - break; - } - else - i++; /* normal character */ - } - return (REVERSE_LIST (list, WORD_LIST *)); -} -#endif - -/********************************************************/ -/* */ -/* Functions to perform assignment statements */ -/* */ -/********************************************************/ - -#if defined (ARRAY_VARS) -static SHELL_VAR * -do_compound_assignment (name, value, flags) - char *name, *value; - int flags; -{ - SHELL_VAR *v; - int mklocal, mkassoc, mkglobal, chklocal; - WORD_LIST *list; - char *newname; /* used for local nameref references */ - - mklocal = flags & ASS_MKLOCAL; - mkassoc = flags & ASS_MKASSOC; - mkglobal = flags & ASS_MKGLOBAL; - chklocal = flags & ASS_CHKLOCAL; - - if (mklocal && variable_context) - { - v = find_variable (name); /* follows namerefs */ - newname = (v == 0) ? nameref_transform_name (name, flags) : v->name; - if (v && ((readonly_p (v) && (flags & ASS_FORCE) == 0) || noassign_p (v))) - { - if (readonly_p (v)) - err_readonly (name); - return (v); /* XXX */ - } - list = expand_compound_array_assignment (v, value, flags); - if (mkassoc) - v = make_local_assoc_variable (newname, 0); - else if (v == 0 || (array_p (v) == 0 && assoc_p (v) == 0) || v->context != variable_context) - v = make_local_array_variable (newname, 0); - if (v) - assign_compound_array_list (v, list, flags); - if (list) - dispose_words (list); - } - /* In a function but forcing assignment in global context. CHKLOCAL means to - check for an existing local variable first. */ - else if (mkglobal && variable_context) - { - v = chklocal ? find_variable (name) : 0; - if (v && (local_p (v) == 0 || v->context != variable_context)) - v = 0; - if (v == 0) - v = find_global_variable (name); - if (v && ((readonly_p (v) && (flags & ASS_FORCE) == 0) || noassign_p (v))) - { - if (readonly_p (v)) - err_readonly (name); - return (v); /* XXX */ - } - /* sanity check */ - newname = (v == 0) ? nameref_transform_name (name, flags) : name; - list = expand_compound_array_assignment (v, value, flags); - if (v == 0 && mkassoc) - v = make_new_assoc_variable (newname); - else if (v && mkassoc && assoc_p (v) == 0) - v = convert_var_to_assoc (v); - else if (v == 0) - v = make_new_array_variable (newname); - else if (v && mkassoc == 0 && array_p (v) == 0) - v = convert_var_to_array (v); - if (v) - assign_compound_array_list (v, list, flags); - if (list) - dispose_words (list); - } - else - { - v = assign_array_from_string (name, value, flags); - if (v && ((readonly_p (v) && (flags & ASS_FORCE) == 0) || noassign_p (v))) - { - if (readonly_p (v)) - err_readonly (name); - return (v); /* XXX */ - } - } - - return (v); -} -#endif - -/* Given STRING, an assignment string, get the value of the right side - of the `=', and bind it to the left side. If EXPAND is true, then - perform parameter expansion, command substitution, and arithmetic - expansion on the right-hand side. Perform tilde expansion in any - case. Do not perform word splitting on the result of expansion. */ -static int -do_assignment_internal (word, expand) - const WORD_DESC *word; - int expand; -{ - int offset, appendop, assign_list, aflags, retval; - char *name, *value, *temp; - SHELL_VAR *entry; -#if defined (ARRAY_VARS) - char *t; - int ni; -#endif - const char *string; - - if (word == 0 || word->word == 0) - return 0; - - appendop = assign_list = aflags = 0; - string = word->word; - offset = assignment (string, 0); - name = savestring (string); - value = (char *)NULL; - - if (name[offset] == '=') - { - if (name[offset - 1] == '+') - { - appendop = 1; - name[offset - 1] = '\0'; - } - - name[offset] = 0; /* might need this set later */ - temp = name + offset + 1; - -#if defined (ARRAY_VARS) - if (expand && (word->flags & W_COMPASSIGN)) - { - assign_list = ni = 1; - value = extract_array_assignment_list (temp, &ni); - } - else -#endif - if (expand && temp[0]) - value = expand_string_if_necessary (temp, 0, expand_string_assignment); - else - value = savestring (temp); - } - - if (value == 0) - { - value = (char *)xmalloc (1); - value[0] = '\0'; - } - - if (echo_command_at_execute) - { - if (appendop) - name[offset - 1] = '+'; - xtrace_print_assignment (name, value, assign_list, 1); - if (appendop) - name[offset - 1] = '\0'; - } - -#define ASSIGN_RETURN(r) do { FREE (value); free (name); return (r); } while (0) - - if (appendop) - aflags |= ASS_APPEND; - -#if defined (ARRAY_VARS) - if (t = mbschr (name, LBRACK)) - { - if (assign_list) - { - report_error (_("%s: cannot assign list to array member"), name); - ASSIGN_RETURN (0); - } - aflags |= ASS_ALLOWALLSUB; /* allow a[@]=value for existing associative arrays */ - entry = assign_array_element (name, value, aflags, (array_eltstate_t *)0); - if (entry == 0) - ASSIGN_RETURN (0); - } - else if (assign_list) - { - if ((word->flags & W_ASSIGNARG) && (word->flags & W_CHKLOCAL)) - aflags |= ASS_CHKLOCAL; - if ((word->flags & W_ASSIGNARG) && (word->flags & W_ASSNGLOBAL) == 0) - aflags |= ASS_MKLOCAL; - if ((word->flags & W_ASSIGNARG) && (word->flags & W_ASSNGLOBAL)) - aflags |= ASS_MKGLOBAL; - if (word->flags & W_ASSIGNASSOC) - aflags |= ASS_MKASSOC; - entry = do_compound_assignment (name, value, aflags); - } - else -#endif /* ARRAY_VARS */ - entry = bind_variable (name, value, aflags); - - if (entry) - stupidly_hack_special_variables (entry->name); /* might be a nameref */ - else - stupidly_hack_special_variables (name); - - /* Return 1 if the assignment seems to have been performed correctly. */ - if (entry == 0 || readonly_p (entry)) - retval = 0; /* assignment failure */ - else if (noassign_p (entry)) - { - set_exit_status (EXECUTION_FAILURE); - retval = 1; /* error status, but not assignment failure */ - } - else - retval = 1; - - if (entry && retval != 0 && noassign_p (entry) == 0) - VUNSETATTR (entry, att_invisible); - - ASSIGN_RETURN (retval); -} - -/* Perform the assignment statement in STRING, and expand the - right side by doing tilde, command and parameter expansion. */ -int -do_assignment (string) - char *string; -{ - WORD_DESC td; - - td.flags = W_ASSIGNMENT; - td.word = string; - - return do_assignment_internal (&td, 1); -} - -int -do_word_assignment (word, flags) - WORD_DESC *word; - int flags; -{ - return do_assignment_internal (word, 1); -} - -/* Given STRING, an assignment string, get the value of the right side - of the `=', and bind it to the left side. Do not perform any word - expansions on the right hand side. */ -int -do_assignment_no_expand (string) - char *string; -{ - WORD_DESC td; - - td.flags = W_ASSIGNMENT; - td.word = string; - - return (do_assignment_internal (&td, 0)); -} - -/*************************************************** - * * - * Functions to manage the positional parameters * - * * - ***************************************************/ - -/* Return the word list that corresponds to `$*'. */ -WORD_LIST * -list_rest_of_args () -{ - register WORD_LIST *list, *args; - int i; - - /* Break out of the loop as soon as one of the dollar variables is null. */ - for (i = 1, list = (WORD_LIST *)NULL; i < 10 && dollar_vars[i]; i++) - list = make_word_list (make_bare_word (dollar_vars[i]), list); - - for (args = rest_of_args; args; args = args->next) - list = make_word_list (make_bare_word (args->word->word), list); - - return (REVERSE_LIST (list, WORD_LIST *)); -} - -/* Return the value of a positional parameter. This handles values > 10. */ -char * -get_dollar_var_value (ind) - intmax_t ind; -{ - char *temp; - WORD_LIST *p; - - if (ind < 10) - temp = dollar_vars[ind] ? savestring (dollar_vars[ind]) : (char *)NULL; - else /* We want something like ${11} */ - { - ind -= 10; - for (p = rest_of_args; p && ind--; p = p->next) - ; - temp = p ? savestring (p->word->word) : (char *)NULL; - } - return (temp); -} - -/* Make a single large string out of the dollar digit variables, - and the rest_of_args. If DOLLAR_STAR is 1, then obey the special - case of "$*" with respect to IFS. */ -char * -string_rest_of_args (dollar_star) - int dollar_star; -{ - register WORD_LIST *list; - char *string; - - list = list_rest_of_args (); - string = dollar_star ? string_list_dollar_star (list, 0, 0) : string_list (list); - dispose_words (list); - return (string); -} - -/* Return a string containing the positional parameters from START to - END, inclusive. If STRING[0] == '*', we obey the rules for $*, - which only makes a difference if QUOTED is non-zero. If QUOTED includes - Q_HERE_DOCUMENT or Q_DOUBLE_QUOTES, this returns a quoted list, otherwise - no quoting chars are added. */ -static char * -pos_params (string, start, end, quoted, pflags) - char *string; - int start, end, quoted, pflags; -{ - WORD_LIST *save, *params, *h, *t; - char *ret; - int i; - - /* see if we can short-circuit. if start == end, we want 0 parameters. */ - if (start == end) - return ((char *)NULL); - - save = params = list_rest_of_args (); - if (save == 0 && start > 0) - return ((char *)NULL); - - if (start == 0) /* handle ${@:0[:x]} specially */ - { - t = make_word_list (make_word (dollar_vars[0]), params); - save = params = t; - } - - for (i = start ? 1 : 0; params && i < start; i++) - params = params->next; - if (params == 0) - { - dispose_words (save); - return ((char *)NULL); - } - for (h = t = params; params && i < end; i++) - { - t = params; - params = params->next; - } - t->next = (WORD_LIST *)NULL; - - ret = string_list_pos_params (string[0], h, quoted, pflags); - - if (t != params) - t->next = params; - - dispose_words (save); - return (ret); -} - -/******************************************************************/ -/* */ -/* Functions to expand strings to strings or WORD_LISTs */ -/* */ -/******************************************************************/ - -#if defined (PROCESS_SUBSTITUTION) -#define EXP_CHAR(s) (s == '$' || s == '`' || s == '<' || s == '>' || s == CTLESC || s == '~') -#else -#define EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC || s == '~') -#endif - -/* If there are any characters in STRING that require full expansion, - then call FUNC to expand STRING; otherwise just perform quote - removal if necessary. This returns a new string. */ -static char * -expand_string_if_necessary (string, quoted, func) - char *string; - int quoted; - EXPFUNC *func; -{ - WORD_LIST *list; - size_t slen; - int i, saw_quote; - char *ret; - DECLARE_MBSTATE; - - /* Don't need string length for ADVANCE_CHAR unless multibyte chars possible. */ - slen = (MB_CUR_MAX > 1) ? strlen (string) : 0; - i = saw_quote = 0; - while (string[i]) - { - if (EXP_CHAR (string[i])) - break; - else if (string[i] == '\'' || string[i] == '\\' || string[i] == '"') - saw_quote = 1; - ADVANCE_CHAR (string, slen, i); - } - - if (string[i]) - { - list = (*func) (string, quoted); - if (list) - { - ret = string_list (list); - dispose_words (list); - } - else - ret = (char *)NULL; - } - else if (saw_quote && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0)) - ret = string_quote_removal (string, quoted); - else - ret = savestring (string); - - return ret; -} - -static inline char * -expand_string_to_string_internal (string, quoted, func) - char *string; - int quoted; - EXPFUNC *func; -{ - WORD_LIST *list; - char *ret; - - if (string == 0 || *string == '\0') - return ((char *)NULL); - - list = (*func) (string, quoted); - if (list) - { - ret = string_list (list); - dispose_words (list); - } - else - ret = (char *)NULL; - - return (ret); -} - -char * -expand_string_to_string (string, quoted) - char *string; - int quoted; -{ - return (expand_string_to_string_internal (string, quoted, expand_string)); -} - -char * -expand_string_unsplit_to_string (string, quoted) - char *string; - int quoted; -{ - return (expand_string_to_string_internal (string, quoted, expand_string_unsplit)); -} - -char * -expand_assignment_string_to_string (string, quoted) - char *string; - int quoted; -{ - return (expand_string_to_string_internal (string, quoted, expand_string_assignment)); -} - -/* Kind of like a combination of dequote_string and quote_string_for_globbing; - try to remove CTLESC quoting characters and convert CTLESC escaping a `&' - or a backslash into a backslash. The output of this function must eventually - be processed by strcreplace(). */ -static char * -quote_string_for_repl (string, flags) - char *string; - int flags; -{ - size_t slen; - char *result, *t; - const char *s, *send; - DECLARE_MBSTATE; - - slen = strlen (string); - send = string + slen; - - result = (char *)xmalloc (slen * 2 + 1); - - if (string[0] == CTLESC && string[1] == 0) - { - result[0] = CTLESC; - result[1] = '\0'; - return (result); - } - - /* This is awkward. We want to translate CTLESC-\ to \\ if we will - eventually send this string through strcreplace(), which we will do - only if shouldexp_replacement() determines that there is something - to replace. We can either make sure to escape backslashes here and - have shouldexp_replacement() signal that we should send the string to - strcreplace() if it sees an escaped backslash, or we can scan the - string before copying it and turn CTLESC-\ into \\ only if we encounter - a CTLESC-& or a &. This does the former and changes shouldexp_replacement(). - If we double the backslashes here, we'll get doubled backslashes in any - result that doesn't get passed to strcreplace(). */ - - for (s = string, t = result; *s; ) - { - /* This function's result has to be processed by strcreplace() */ - if (*s == CTLESC && (s[1] == '&' || s[1] == '\\')) - { - *t++ = '\\'; - s++; - *t++ = *s++; - continue; - } - /* Dequote it */ - if (*s == CTLESC) - { - s++; - if (*s == '\0') - break; - } - COPY_CHAR_P (t, s, send); - } - - *t = '\0'; - return (result); -} - -/* This does not perform word splitting on the WORD_LIST it returns and - it treats $* as if it were quoted. It dequotes the WORD_LIST, adds - backslash escapes before CTLESC-quoted backslash and `& if - patsub_replacement is enabled. */ -static char * -expand_string_for_patsub (string, quoted) - char *string; - int quoted; -{ - WORD_LIST *value; - char *ret, *t; - - if (string == 0 || *string == '\0') - return (char *)NULL; - - value = expand_string_for_pat (string, quoted, (int *)0, (int *)0); - - if (value && value->word) - { - remove_quoted_nulls (value->word->word); /* XXX */ - value->word->flags &= ~W_HASQUOTEDNULL; - } - - if (value) - { - t = (value->next) ? string_list (value) : value->word->word; - ret = quote_string_for_repl (t, quoted); - if (t != value->word->word) - free (t); - dispose_words (value); - } - else - ret = (char *)NULL; - - return (ret); -} - -char * -expand_arith_string (string, quoted) - char *string; - int quoted; -{ - WORD_DESC td; - WORD_LIST *list, *tlist; - size_t slen; - int i, saw_quote; - char *ret; - DECLARE_MBSTATE; - - /* Don't need string length for ADVANCE_CHAR unless multibyte chars possible. */ - slen = (MB_CUR_MAX > 1) ? strlen (string) : 0; - i = saw_quote = 0; - while (string[i]) - { - if (EXP_CHAR (string[i])) - break; - else if (string[i] == '\'' || string[i] == '\\' || string[i] == '"') - saw_quote = string[i]; - ADVANCE_CHAR (string, slen, i); - } - - if (string[i]) - { - /* This is expanded version of expand_string_internal as it's called by - expand_string_leave_quoted */ - td.flags = W_NOPROCSUB|W_NOTILDE; /* don't want process substitution or tilde expansion */ -#if 0 /* TAG: bash-5.2 */ - if (quoted & Q_ARRAYSUB) - td.flags |= W_NOCOMSUB; -#endif - td.word = savestring (string); - list = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL); - /* This takes care of the calls from expand_string_leave_quoted and - expand_string */ - if (list) - { - tlist = word_list_split (list); - dispose_words (list); - list = tlist; - if (list) - dequote_list (list); - } - /* This comes from expand_string_if_necessary */ - if (list) - { - ret = string_list (list); - dispose_words (list); - } - else - ret = (char *)NULL; - FREE (td.word); - } - else if (saw_quote && (quoted & Q_ARITH)) - ret = string_quote_removal (string, quoted); - else if (saw_quote && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0)) - ret = string_quote_removal (string, quoted); - else - ret = savestring (string); - - return ret; -} - -#if defined (COND_COMMAND) -/* Just remove backslashes in STRING. Returns a new string. */ -char * -remove_backslashes (string) - char *string; -{ - char *r, *ret, *s; - - r = ret = (char *)xmalloc (strlen (string) + 1); - for (s = string; s && *s; ) - { - if (*s == '\\') - s++; - if (*s == 0) - break; - *r++ = *s++; - } - *r = '\0'; - return ret; -} - -/* This needs better error handling. */ -/* Expand W for use as an argument to a unary or binary operator in a - [[...]] expression. If SPECIAL is 1, this is the rhs argument - to the != or == operator, and should be treated as a pattern. In - this case, we quote the string specially for the globbing code. If - SPECIAL is 2, this is an rhs argument for the =~ operator, and should - be quoted appropriately for regcomp/regexec. If SPECIAL is 3, this is - an array subscript and should be quoted after expansion so it's only - expanded once (Q_ARITH). The caller is responsible - for removing the backslashes if the unquoted word is needed later. In - any case, since we don't perform word splitting, we need to do quoted - null character removal. */ -char * -cond_expand_word (w, special) - WORD_DESC *w; - int special; -{ - char *r, *p; - WORD_LIST *l; - int qflags; - - if (w->word == 0 || w->word[0] == '\0') - return ((char *)NULL); - - expand_no_split_dollar_star = 1; - w->flags |= W_NOSPLIT2; - qflags = (special == 3) ? Q_ARITH : 0; - l = call_expand_word_internal (w, qflags, 0, (int *)0, (int *)0); - expand_no_split_dollar_star = 0; - if (l) - { - if (special == 0) /* LHS */ - { - if (l->word) - word_list_remove_quoted_nulls (l); - dequote_list (l); - r = string_list (l); - } - else if (special == 3) /* arithmetic expression, Q_ARITH */ - { - if (l->word) - word_list_remove_quoted_nulls (l); /* for now */ - dequote_list (l); - r = string_list (l); - } - else - { - /* Need to figure out whether or not we should call dequote_escapes - or a new dequote_ctlnul function here, and under what - circumstances. */ - qflags = QGLOB_CVTNULL|QGLOB_CTLESC; - if (special == 2) - qflags |= QGLOB_REGEXP; - word_list_remove_quoted_nulls (l); - p = string_list (l); - r = quote_string_for_globbing (p, qflags); - free (p); - } - dispose_words (l); - } - else - r = (char *)NULL; - - return r; -} -#endif - -/* Expand $'...' and $"..." in a string for code paths that don't do it. The - FLAGS argument is 1 if this function should treat CTLESC as a quote - character (e.g., for here-documents) or not (e.g., for shell_expand_line). */ -char * -expand_string_dollar_quote (string, flags) - char *string; - int flags; -{ - size_t slen, retind, retsize; - int sindex, c, translen, peekc, news; - char *ret, *trans, *send, *t; - DECLARE_MBSTATE; - - slen = strlen (string); - send = string + slen; - sindex = 0; - - retsize = slen + 1; - ret = xmalloc (retsize); - retind = 0; - - while (c = string[sindex]) - { - switch (c) - { - default: - RESIZE_MALLOCED_BUFFER (ret, retind, locale_mb_cur_max + 1, retsize, 64); - COPY_CHAR_I (ret, retind, string, send, sindex); - break; - - case '\\': - RESIZE_MALLOCED_BUFFER (ret, retind, locale_mb_cur_max + 2, retsize, 64); - ret[retind++] = string[sindex++]; - - if (string[sindex]) - COPY_CHAR_I (ret, retind, string, send, sindex); - break; - - case '\'': - case '"': - if (c == '\'') - news = skip_single_quoted (string, slen, ++sindex, SX_COMPLETE); - else - news = skip_double_quoted (string, slen, ++sindex, SX_COMPLETE); - translen = news - sindex - 1; - RESIZE_MALLOCED_BUFFER (ret, retind, translen + 3, retsize, 64); - ret[retind++] = c; - if (translen > 0) - { - strncpy (ret + retind, string + sindex, translen); - retind += translen; - } - if (news > sindex && string[news - 1] == c) - ret[retind++] = c; - sindex = news; - break; - - case CTLESC: - RESIZE_MALLOCED_BUFFER (ret, retind, locale_mb_cur_max + 2, retsize, 64); - if (flags) - ret[retind++] = string[sindex++]; - if (string[sindex]) - COPY_CHAR_I (ret, retind, string, send, sindex); - break; - - case '$': - peekc = string[++sindex]; -#if defined (TRANSLATABLE_STRINGS) - if (peekc != '\'' && peekc != '"') -#else - if (peekc != '\'') -#endif - { - RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 16); - ret[retind++] = c; - break; - } - if (string[sindex + 1] == '\0') /* don't bother */ - { - RESIZE_MALLOCED_BUFFER (ret, retind, 3, retsize, 16); - ret[retind++] = c; - ret[retind++] = peekc; - sindex++; - break; - } - if (peekc == '\'') - { - /* SX_COMPLETE is the equivalent of ALLOWESC here */ - /* We overload SX_COMPLETE below */ - news = skip_single_quoted (string, slen, ++sindex, SX_COMPLETE); - /* Check for unclosed string and don't bother if so */ - if (news > sindex && string[news] == '\0' && string[news-1] != peekc) - { - RESIZE_MALLOCED_BUFFER (ret, retind, 3, retsize, 16); - ret[retind++] = c; - ret[retind++] = peekc; - continue; - } - t = substring (string, sindex, news - 1); - trans = ansiexpand (t, 0, news-sindex-1, &translen); - free (t); - t = sh_single_quote (trans); - sindex = news; - } -#if defined (TRANSLATABLE_STRINGS) - else - { - news = ++sindex; - t = string_extract_double_quoted (string, &news, SX_COMPLETE); - /* Check for unclosed string and don't bother if so */ - if (news > sindex && string[news] == '\0' && string[news-1] != peekc) - { - RESIZE_MALLOCED_BUFFER (ret, retind, 3, retsize, 16); - ret[retind++] = c; - ret[retind++] = peekc; - free (t); - continue; - } - trans = locale_expand (t, 0, news-sindex, 0, &translen); - free (t); - if (singlequote_translations && - ((news-sindex-1) != translen || STREQN (t, trans, translen) == 0)) - t = sh_single_quote (trans); - else - t = sh_mkdoublequoted (trans, translen, 0); - sindex = news; - } -#endif /* TRANSLATABLE_STRINGS */ - free (trans); - trans = t; - translen = strlen (trans); - - RESIZE_MALLOCED_BUFFER (ret, retind, translen + 1, retsize, 128); - strcpy (ret + retind, trans); - retind += translen; - FREE (trans); - break; - } - } - - ret[retind] = 0; - return ret; -} - -/* Call expand_word_internal to expand W and handle error returns. - A convenience function for functions that don't want to handle - any errors or free any memory before aborting. */ -static WORD_LIST * -call_expand_word_internal (w, q, i, c, e) - WORD_DESC *w; - int q, i, *c, *e; -{ - WORD_LIST *result; - - result = expand_word_internal (w, q, i, c, e); - if (result == &expand_word_error || result == &expand_word_fatal) - { - /* By convention, each time this error is returned, w->word has - already been freed (it sometimes may not be in the fatal case, - but that doesn't result in a memory leak because we're going - to exit in most cases). */ - w->word = (char *)NULL; - last_command_exit_value = EXECUTION_FAILURE; - exp_jump_to_top_level ((result == &expand_word_error) ? DISCARD : FORCE_EOF); - /* NOTREACHED */ - return (NULL); - } - else - return (result); -} - -/* Perform parameter expansion, command substitution, and arithmetic - expansion on STRING, as if it were a word. Leave the result quoted. - Since this does not perform word splitting, it leaves quoted nulls - in the result. */ -static WORD_LIST * -expand_string_internal (string, quoted) - char *string; - int quoted; -{ - WORD_DESC td; - WORD_LIST *tresult; - - if (string == 0 || *string == 0) - return ((WORD_LIST *)NULL); - - td.flags = 0; - td.word = savestring (string); - - tresult = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL); - - FREE (td.word); - return (tresult); -} - -/* Expand STRING by performing parameter expansion, command substitution, - and arithmetic expansion. Dequote the resulting WORD_LIST before - returning it, but do not perform word splitting. The call to - remove_quoted_nulls () is in here because word splitting normally - takes care of quote removal. */ -WORD_LIST * -expand_string_unsplit (string, quoted) - char *string; - int quoted; -{ - WORD_LIST *value; - - if (string == 0 || *string == '\0') - return ((WORD_LIST *)NULL); - - expand_no_split_dollar_star = 1; - value = expand_string_internal (string, quoted); - expand_no_split_dollar_star = 0; - - if (value) - { - if (value->word) - { - remove_quoted_nulls (value->word->word); /* XXX */ - value->word->flags &= ~W_HASQUOTEDNULL; - } - dequote_list (value); - } - return (value); -} - -/* Expand the rhs of an assignment statement */ -WORD_LIST * -expand_string_assignment (string, quoted) - char *string; - int quoted; -{ - WORD_DESC td; - WORD_LIST *value; - - if (string == 0 || *string == '\0') - return ((WORD_LIST *)NULL); - - expand_no_split_dollar_star = 1; - -#if 0 - /* Other shells (ksh93) do it this way, which affects how $@ is expanded - in constructs like bar=${@#0} (preserves the spaces resulting from the - expansion of $@ in a context where you don't do word splitting); Posix - interp 888 makes the expansion of $@ in contexts where word splitting - is not performed unspecified. */ - td.flags = W_ASSIGNRHS|W_NOSPLIT2; /* Posix interp 888 */ -#else - td.flags = W_ASSIGNRHS; -#endif - td.flags |= (W_NOGLOB|W_TILDEEXP); - td.word = savestring (string); - value = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL); - FREE (td.word); - - expand_no_split_dollar_star = 0; - - if (value) - { - if (value->word) - { - remove_quoted_nulls (value->word->word); /* XXX */ - value->word->flags &= ~W_HASQUOTEDNULL; - } - dequote_list (value); - } - return (value); -} - -/* Expand one of the PS? prompt strings. This is a sort of combination of - expand_string_unsplit and expand_string_internal, but returns the - passed string when an error occurs. Might want to trap other calls - to jump_to_top_level here so we don't endlessly loop. */ -WORD_LIST * -expand_prompt_string (string, quoted, wflags) - char *string; - int quoted; - int wflags; -{ - WORD_LIST *value; - WORD_DESC td; - - if (string == 0 || *string == 0) - return ((WORD_LIST *)NULL); - - td.flags = wflags; - td.word = savestring (string); - - no_longjmp_on_fatal_error = 1; - value = expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL); - no_longjmp_on_fatal_error = 0; - - if (value == &expand_word_error || value == &expand_word_fatal) - { - value = make_word_list (make_bare_word (string), (WORD_LIST *)NULL); - return value; - } - FREE (td.word); - if (value) - { - if (value->word) - { - remove_quoted_nulls (value->word->word); /* XXX */ - value->word->flags &= ~W_HASQUOTEDNULL; - } - dequote_list (value); - } - return (value); -} - -/* Expand STRING just as if you were expanding a word, but do not dequote - the resultant WORD_LIST. This is called only from within this file, - and is used to correctly preserve quoted characters when expanding - things like ${1+"$@"}. This does parameter expansion, command - substitution, arithmetic expansion, and word splitting. */ -static WORD_LIST * -expand_string_leave_quoted (string, quoted) - char *string; - int quoted; -{ - WORD_LIST *tlist; - WORD_LIST *tresult; - - if (string == 0 || *string == '\0') - return ((WORD_LIST *)NULL); - - tlist = expand_string_internal (string, quoted); - - if (tlist) - { - tresult = word_list_split (tlist); - dispose_words (tlist); - return (tresult); - } - return ((WORD_LIST *)NULL); -} - -/* This does not perform word splitting or dequote the WORD_LIST - it returns. */ -static WORD_LIST * -expand_string_for_rhs (string, quoted, op, pflags, dollar_at_p, expanded_p) - char *string; - int quoted, op, pflags; - int *dollar_at_p, *expanded_p; -{ - WORD_DESC td; - WORD_LIST *tresult; - int old_nosplit; - - if (string == 0 || *string == '\0') - return (WORD_LIST *)NULL; - - /* We want field splitting to be determined by what is going to be done with - the entire ${parameterOPword} expansion, so we don't want to split the RHS - we expand here. However, the expansion of $* is determined by whether we - are going to eventually perform word splitting, so we want to set this - depending on whether or not are are going to be splitting: if the expansion - is quoted, if the OP is `=', or if IFS is set to the empty string, we - are not going to be splitting, so we set expand_no_split_dollar_star to - note this to callees. - We pass through PF_ASSIGNRHS as W_ASSIGNRHS if this is on the RHS of an - assignment statement. */ - /* The updated treatment of $* is the result of Posix interp 888 */ - /* This was further clarified on the austin-group list in March, 2017 and - in Posix bug 1129 */ - old_nosplit = expand_no_split_dollar_star; - expand_no_split_dollar_star = (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || op == '=' || ifs_is_null == 0; /* XXX - was 1 */ - td.flags = W_EXPANDRHS; /* expanding RHS of ${paramOPword} */ - td.flags |= W_NOSPLIT2; /* no splitting, remove "" and '' */ - if (pflags & PF_ASSIGNRHS) /* pass through */ - td.flags |= W_ASSIGNRHS; - if (op == '=') -#if 0 - td.flags |= W_ASSIGNRHS; /* expand b in ${a=b} like assignment */ -#else - td.flags |= W_ASSIGNRHS|W_NOASSNTILDE; /* expand b in ${a=b} like assignment */ -#endif - td.word = savestring (string); - tresult = call_expand_word_internal (&td, quoted, 1, dollar_at_p, expanded_p); - expand_no_split_dollar_star = old_nosplit; - free (td.word); - - return (tresult); -} - -/* This does not perform word splitting or dequote the WORD_LIST - it returns and it treats $* as if it were quoted. */ -static WORD_LIST * -expand_string_for_pat (string, quoted, dollar_at_p, expanded_p) - char *string; - int quoted, *dollar_at_p, *expanded_p; -{ - WORD_DESC td; - WORD_LIST *tresult; - int oexp; - - if (string == 0 || *string == '\0') - return (WORD_LIST *)NULL; - - oexp = expand_no_split_dollar_star; - expand_no_split_dollar_star = 1; - td.flags = W_NOSPLIT2; /* no splitting, remove "" and '' */ - td.word = savestring (string); - tresult = call_expand_word_internal (&td, quoted, 1, dollar_at_p, expanded_p); - expand_no_split_dollar_star = oexp; - free (td.word); - - return (tresult); -} - -/* Expand STRING just as if you were expanding a word. This also returns - a list of words. Note that filename globbing is *NOT* done for word - or string expansion, just when the shell is expanding a command. This - does parameter expansion, command substitution, arithmetic expansion, - and word splitting. Dequote the resultant WORD_LIST before returning. */ -WORD_LIST * -expand_string (string, quoted) - char *string; - int quoted; -{ - WORD_LIST *result; - - if (string == 0 || *string == '\0') - return ((WORD_LIST *)NULL); - - result = expand_string_leave_quoted (string, quoted); - return (result ? dequote_list (result) : result); -} - -/******************************************* - * * - * Functions to expand WORD_DESCs * - * * - *******************************************/ - -/* Expand WORD, performing word splitting on the result. This does - parameter expansion, command substitution, arithmetic expansion, - word splitting, and quote removal. */ - -WORD_LIST * -expand_word (word, quoted) - WORD_DESC *word; - int quoted; -{ - WORD_LIST *result, *tresult; - - tresult = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL); - result = word_list_split (tresult); - dispose_words (tresult); - return (result ? dequote_list (result) : result); -} - -/* Expand WORD, but do not perform word splitting on the result. This - does parameter expansion, command substitution, arithmetic expansion, - and quote removal. */ -WORD_LIST * -expand_word_unsplit (word, quoted) - WORD_DESC *word; - int quoted; -{ - WORD_LIST *result; - - result = expand_word_leave_quoted (word, quoted); - return (result ? dequote_list (result) : result); -} - -/* Perform shell expansions on WORD, but do not perform word splitting or - quote removal on the result. Virtually identical to expand_word_unsplit; - could be combined if implementations don't diverge. */ -WORD_LIST * -expand_word_leave_quoted (word, quoted) - WORD_DESC *word; - int quoted; -{ - WORD_LIST *result; - - expand_no_split_dollar_star = 1; - if (ifs_is_null) - word->flags |= W_NOSPLIT; - word->flags |= W_NOSPLIT2; - result = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL); - expand_no_split_dollar_star = 0; - - return result; -} - -/*************************************************** - * * - * Functions to handle quoting chars * - * * - ***************************************************/ - -/* Conventions: - - A string with s[0] == CTLNUL && s[1] == 0 is a quoted null string. - The parser passes CTLNUL as CTLESC CTLNUL. */ - -/* Quote escape characters in string s, but no other characters. This is - used to protect CTLESC and CTLNUL in variable values from the rest of - the word expansion process after the variable is expanded (word splitting - and filename generation). If IFS is null, we quote spaces as well, just - in case we split on spaces later (in the case of unquoted $@, we will - eventually attempt to split the entire word on spaces). Corresponding - code exists in dequote_escapes. Even if we don't end up splitting on - spaces, quoting spaces is not a problem. This should never be called on - a string that is quoted with single or double quotes or part of a here - document (effectively double-quoted). - FLAGS says whether or not we are going to split the result. If we are not, - and there is a CTLESC or CTLNUL in IFS, we need to quote CTLESC and CTLNUL, - respectively, to prevent them from being removed as part of dequoting. */ -static char * -quote_escapes_internal (string, flags) - const char *string; - int flags; -{ - const char *s, *send; - char *t, *result; - size_t slen; - int quote_spaces, skip_ctlesc, skip_ctlnul, nosplit; - DECLARE_MBSTATE; - - slen = strlen (string); - send = string + slen; - - quote_spaces = (ifs_value && *ifs_value == 0); - nosplit = (flags & PF_NOSPLIT2); - - for (skip_ctlesc = skip_ctlnul = 0, s = ifs_value; s && *s; s++) - { - skip_ctlesc |= (nosplit == 0 && *s == CTLESC); - skip_ctlnul |= (nosplit == 0 && *s == CTLNUL); - } - - t = result = (char *)xmalloc ((slen * 2) + 1); - s = string; - - while (*s) - { - if ((skip_ctlesc == 0 && *s == CTLESC) || (skip_ctlnul == 0 && *s == CTLNUL) || (quote_spaces && *s == ' ')) - *t++ = CTLESC; - COPY_CHAR_P (t, s, send); - } - *t = '\0'; - - return (result); -} - -char * -quote_escapes (string) - const char *string; -{ - return (quote_escapes_internal (string, 0)); -} - -char * -quote_rhs (string) - const char *string; -{ - return (quote_escapes_internal (string, PF_NOSPLIT2)); -} - -static WORD_LIST * -list_quote_escapes (list) - WORD_LIST *list; -{ - register WORD_LIST *w; - char *t; - - for (w = list; w; w = w->next) - { - t = w->word->word; - w->word->word = quote_escapes (t); - free (t); - } - return list; -} - -/* Inverse of quote_escapes; remove CTLESC protecting CTLESC or CTLNUL. - - The parser passes us CTLESC as CTLESC CTLESC and CTLNUL as CTLESC CTLNUL. - This is necessary to make unquoted CTLESC and CTLNUL characters in the - data stream pass through properly. - - We need to remove doubled CTLESC characters inside quoted strings before - quoting the entire string, so we do not double the number of CTLESC - characters. - - Also used by parts of the pattern substitution code. */ -char * -dequote_escapes (string) - const char *string; -{ - const char *s, *send; - char *t, *result; - size_t slen; - int quote_spaces; - DECLARE_MBSTATE; - - if (string == 0) - return (char *)0; - - slen = strlen (string); - send = string + slen; - - t = result = (char *)xmalloc (slen + 1); - - if (strchr (string, CTLESC) == 0) - return (strcpy (result, string)); - - quote_spaces = (ifs_value && *ifs_value == 0); - - s = string; - while (*s) - { - if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL || (quote_spaces && s[1] == ' '))) - { - s++; - if (*s == '\0') - break; - } - COPY_CHAR_P (t, s, send); - } - *t = '\0'; - - return result; -} - -#if defined (INCLUDE_UNUSED) -static WORD_LIST * -list_dequote_escapes (list) - WORD_LIST *list; -{ - register WORD_LIST *w; - char *t; - - for (w = list; w; w = w->next) - { - t = w->word->word; - w->word->word = dequote_escapes (t); - free (t); - } - return list; -} -#endif - -/* Return a new string with the quoted representation of character C. - This turns "" into QUOTED_NULL, so the W_HASQUOTEDNULL flag needs to be - set in any resultant WORD_DESC where this value is the word. */ -static char * -make_quoted_char (c) - int c; -{ - char *temp; - - temp = (char *)xmalloc (3); - if (c == 0) - { - temp[0] = CTLNUL; - temp[1] = '\0'; - } - else - { - temp[0] = CTLESC; - temp[1] = c; - temp[2] = '\0'; - } - return (temp); -} - -/* Quote STRING, returning a new string. This turns "" into QUOTED_NULL, so - the W_HASQUOTEDNULL flag needs to be set in any resultant WORD_DESC where - this value is the word. */ -char * -quote_string (string) - char *string; -{ - register char *t; - size_t slen; - char *result, *send; - - if (*string == 0) - { - result = (char *)xmalloc (2); - result[0] = CTLNUL; - result[1] = '\0'; - } - else - { - DECLARE_MBSTATE; - - slen = strlen (string); - send = string + slen; - - result = (char *)xmalloc ((slen * 2) + 1); - - for (t = result; string < send; ) - { - *t++ = CTLESC; - COPY_CHAR_P (t, string, send); - } - *t = '\0'; - } - return (result); -} - -/* De-quote quoted characters in STRING. */ -char * -dequote_string (string) - char *string; -{ - register char *s, *t; - size_t slen; - char *result, *send; - DECLARE_MBSTATE; - - if (string[0] == CTLESC && string[1] == 0) - internal_debug ("dequote_string: string with bare CTLESC"); - - slen = STRLEN (string); - - t = result = (char *)xmalloc (slen + 1); - - if (QUOTED_NULL (string)) - { - result[0] = '\0'; - return (result); - } - - /* A string consisting of only a single CTLESC should pass through unchanged */ - if (string[0] == CTLESC && string[1] == 0) - { - result[0] = CTLESC; - result[1] = '\0'; - return (result); - } - - /* If no character in the string can be quoted, don't bother examining - each character. Just return a copy of the string passed to us. */ - if (strchr (string, CTLESC) == NULL) - return (strcpy (result, string)); - - send = string + slen; - s = string; - while (*s) - { - if (*s == CTLESC) - { - s++; - if (*s == '\0') - break; - } - COPY_CHAR_P (t, s, send); - } - - *t = '\0'; - return (result); -} - -/* Quote the entire WORD_LIST list. */ -static WORD_LIST * -quote_list (list) - WORD_LIST *list; -{ - register WORD_LIST *w; - char *t; - - for (w = list; w; w = w->next) - { - t = w->word->word; - w->word->word = quote_string (t); - if (*t == 0) - w->word->flags |= W_HASQUOTEDNULL; /* XXX - turn on W_HASQUOTEDNULL here? */ - w->word->flags |= W_QUOTED; - free (t); - } - return list; -} - -WORD_DESC * -dequote_word (word) - WORD_DESC *word; -{ - register char *s; - - s = dequote_string (word->word); - if (QUOTED_NULL (word->word)) - word->flags &= ~W_HASQUOTEDNULL; - free (word->word); - word->word = s; - - return word; -} - -/* De-quote quoted characters in each word in LIST. */ -WORD_LIST * -dequote_list (list) - WORD_LIST *list; -{ - register char *s; - register WORD_LIST *tlist; - - for (tlist = list; tlist; tlist = tlist->next) - { - s = dequote_string (tlist->word->word); - if (QUOTED_NULL (tlist->word->word)) - tlist->word->flags &= ~W_HASQUOTEDNULL; - free (tlist->word->word); - tlist->word->word = s; - } - return list; -} - -/* Remove CTLESC protecting a CTLESC or CTLNUL in place. Return the passed - string. */ -char * -remove_quoted_escapes (string) - char *string; -{ - char *t; - - if (string) - { - t = dequote_escapes (string); - strcpy (string, t); - free (t); - } - - return (string); -} - -/* Remove quoted $IFS characters from STRING. Quoted IFS characters are - added to protect them from word splitting, but we need to remove them - if no word splitting takes place. This returns newly-allocated memory, - so callers can use it to replace savestring(). */ -char * -remove_quoted_ifs (string) - char *string; -{ - register size_t slen; - register int i, j; - char *ret, *send; - DECLARE_MBSTATE; - - slen = strlen (string); - send = string + slen; - - i = j = 0; - ret = (char *)xmalloc (slen + 1); - - while (i < slen) - { - if (string[i] == CTLESC) - { - i++; - if (string[i] == 0 || isifs (string[i]) == 0) - ret[j++] = CTLESC; - if (i == slen) - break; - } - - COPY_CHAR_I (ret, j, string, send, i); - } - ret[j] = '\0'; - - return (ret); -} - -char * -remove_quoted_nulls (string) - char *string; -{ - register size_t slen; - register int i, j, prev_i; - DECLARE_MBSTATE; - - if (strchr (string, CTLNUL) == 0) /* XXX */ - return string; /* XXX */ - - slen = strlen (string); - i = j = 0; - - while (i < slen) - { - if (string[i] == CTLESC) - { - /* Old code had j++, but we cannot assume that i == j at this - point -- what if a CTLNUL has already been removed from the - string? We don't want to drop the CTLESC or recopy characters - that we've already copied down. */ - i++; - string[j++] = CTLESC; - if (i == slen) - break; - } - else if (string[i] == CTLNUL) - { - i++; - continue; - } - - prev_i = i; - ADVANCE_CHAR (string, slen, i); /* COPY_CHAR_I? */ - if (j < prev_i) - { - do string[j++] = string[prev_i++]; while (prev_i < i); - } - else - j = i; - } - string[j] = '\0'; - - return (string); -} - -/* Perform quoted null character removal on each element of LIST. - This modifies LIST. */ -void -word_list_remove_quoted_nulls (list) - WORD_LIST *list; -{ - register WORD_LIST *t; - - for (t = list; t; t = t->next) - { - remove_quoted_nulls (t->word->word); - t->word->flags &= ~W_HASQUOTEDNULL; - } -} - -/* **************************************************************** */ -/* */ -/* Functions for Matching and Removing Patterns */ -/* */ -/* **************************************************************** */ - -#if defined (HANDLE_MULTIBYTE) -# ifdef INCLUDE_UNUSED -static unsigned char * -mb_getcharlens (string, len) - char *string; - int len; -{ - int i, offset, last; - unsigned char *ret; - char *p; - DECLARE_MBSTATE; - - i = offset = 0; - last = 0; - ret = (unsigned char *)xmalloc (len); - memset (ret, 0, len); - while (string[last]) - { - ADVANCE_CHAR (string, len, offset); - ret[last] = offset - last; - last = offset; - } - return ret; -} -# endif -#endif - -/* Remove the portion of PARAM matched by PATTERN according to OP, where OP - can have one of 4 values: - RP_LONG_LEFT remove longest matching portion at start of PARAM - RP_SHORT_LEFT remove shortest matching portion at start of PARAM - RP_LONG_RIGHT remove longest matching portion at end of PARAM - RP_SHORT_RIGHT remove shortest matching portion at end of PARAM -*/ - -#define RP_LONG_LEFT 1 -#define RP_SHORT_LEFT 2 -#define RP_LONG_RIGHT 3 -#define RP_SHORT_RIGHT 4 - -/* Returns its first argument if nothing matched; new memory otherwise */ -static char * -remove_upattern (param, pattern, op) - char *param, *pattern; - int op; -{ - register size_t len; - register char *end; - register char *p, *ret, c; - - len = STRLEN (param); - end = param + len; - - switch (op) - { - case RP_LONG_LEFT: /* remove longest match at start */ - for (p = end; p >= param; p--) - { - c = *p; *p = '\0'; - if (strmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH) - { - *p = c; - return (savestring (p)); - } - *p = c; - - } - break; - - case RP_SHORT_LEFT: /* remove shortest match at start */ - for (p = param; p <= end; p++) - { - c = *p; *p = '\0'; - if (strmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH) - { - *p = c; - return (savestring (p)); - } - *p = c; - } - break; - - case RP_LONG_RIGHT: /* remove longest match at end */ - for (p = param; p <= end; p++) - { - if (strmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH) - { - c = *p; *p = '\0'; - ret = savestring (param); - *p = c; - return (ret); - } - } - break; - - case RP_SHORT_RIGHT: /* remove shortest match at end */ - for (p = end; p >= param; p--) - { - if (strmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH) - { - c = *p; *p = '\0'; - ret = savestring (param); - *p = c; - return (ret); - } - } - break; - } - - return (param); /* no match, return original string */ -} - -#if defined (HANDLE_MULTIBYTE) -/* Returns its first argument if nothing matched; new memory otherwise */ -static wchar_t * -remove_wpattern (wparam, wstrlen, wpattern, op) - wchar_t *wparam; - size_t wstrlen; - wchar_t *wpattern; - int op; -{ - wchar_t wc, *ret; - int n; - - switch (op) - { - case RP_LONG_LEFT: /* remove longest match at start */ - for (n = wstrlen; n >= 0; n--) - { - wc = wparam[n]; wparam[n] = L'\0'; - if (wcsmatch (wpattern, wparam, FNMATCH_EXTFLAG) != FNM_NOMATCH) - { - wparam[n] = wc; - return (wcsdup (wparam + n)); - } - wparam[n] = wc; - } - break; - - case RP_SHORT_LEFT: /* remove shortest match at start */ - for (n = 0; n <= wstrlen; n++) - { - wc = wparam[n]; wparam[n] = L'\0'; - if (wcsmatch (wpattern, wparam, FNMATCH_EXTFLAG) != FNM_NOMATCH) - { - wparam[n] = wc; - return (wcsdup (wparam + n)); - } - wparam[n] = wc; - } - break; - - case RP_LONG_RIGHT: /* remove longest match at end */ - for (n = 0; n <= wstrlen; n++) - { - if (wcsmatch (wpattern, wparam + n, FNMATCH_EXTFLAG) != FNM_NOMATCH) - { - wc = wparam[n]; wparam[n] = L'\0'; - ret = wcsdup (wparam); - wparam[n] = wc; - return (ret); - } - } - break; - - case RP_SHORT_RIGHT: /* remove shortest match at end */ - for (n = wstrlen; n >= 0; n--) - { - if (wcsmatch (wpattern, wparam + n, FNMATCH_EXTFLAG) != FNM_NOMATCH) - { - wc = wparam[n]; wparam[n] = L'\0'; - ret = wcsdup (wparam); - wparam[n] = wc; - return (ret); - } - } - break; - } - - return (wparam); /* no match, return original string */ -} -#endif /* HANDLE_MULTIBYTE */ - -static char * -remove_pattern (param, pattern, op) - char *param, *pattern; - int op; -{ - char *xret; - - if (param == NULL) - return (param); - if (*param == '\0' || pattern == NULL || *pattern == '\0') /* minor optimization */ - return (savestring (param)); - -#if defined (HANDLE_MULTIBYTE) - if (MB_CUR_MAX > 1) - { - wchar_t *ret, *oret; - size_t n; - wchar_t *wparam, *wpattern; - mbstate_t ps; - - /* XXX - could optimize here by checking param and pattern for multibyte - chars with mbsmbchar and calling remove_upattern. */ - - n = xdupmbstowcs (&wpattern, NULL, pattern); - if (n == (size_t)-1) - { - xret = remove_upattern (param, pattern, op); - return ((xret == param) ? savestring (param) : xret); - } - n = xdupmbstowcs (&wparam, NULL, param); - - if (n == (size_t)-1) - { - free (wpattern); - xret = remove_upattern (param, pattern, op); - return ((xret == param) ? savestring (param) : xret); - } - oret = ret = remove_wpattern (wparam, n, wpattern, op); - /* Don't bother to convert wparam back to multibyte string if nothing - matched; just return copy of original string */ - if (ret == wparam) - { - free (wparam); - free (wpattern); - return (savestring (param)); - } - - free (wparam); - free (wpattern); - - n = strlen (param); - xret = (char *)xmalloc (n + 1); - memset (&ps, '\0', sizeof (mbstate_t)); - n = wcsrtombs (xret, (const wchar_t **)&ret, n, &ps); - xret[n] = '\0'; /* just to make sure */ - free (oret); - return xret; - } - else -#endif - { - xret = remove_upattern (param, pattern, op); - return ((xret == param) ? savestring (param) : xret); - } -} - -/* Match PAT anywhere in STRING and return the match boundaries. - This returns 1 in case of a successful match, 0 otherwise. SP - and EP are pointers into the string where the match begins and - ends, respectively. MTYPE controls what kind of match is attempted. - MATCH_BEG and MATCH_END anchor the match at the beginning and end - of the string, respectively. The longest match is returned. */ -static int -match_upattern (string, pat, mtype, sp, ep) - char *string, *pat; - int mtype; - char **sp, **ep; -{ - int c, mlen; - size_t len; - register char *p, *p1, *npat; - char *end; - - /* If the pattern doesn't match anywhere in the string, go ahead and - short-circuit right away. A minor optimization, saves a bunch of - unnecessary calls to strmatch (up to N calls for a string of N - characters) if the match is unsuccessful. To preserve the semantics - of the substring matches below, we make sure that the pattern has - `*' as first and last character, making a new pattern if necessary. */ - /* XXX - check this later if I ever implement `**' with special meaning, - since this will potentially result in `**' at the beginning or end */ - len = STRLEN (pat); - if (pat[0] != '*' || (pat[0] == '*' && pat[1] == LPAREN && extended_glob) || pat[len - 1] != '*') - { - int unescaped_backslash; - char *pp; - - p = npat = (char *)xmalloc (len + 3); - p1 = pat; - if ((mtype != MATCH_BEG) && (*p1 != '*' || (*p1 == '*' && p1[1] == LPAREN && extended_glob))) - *p++ = '*'; - while (*p1) - *p++ = *p1++; -#if 1 - /* Need to also handle a pattern that ends with an unescaped backslash. - For right now, we ignore it because the pattern matching code will - fail the match anyway */ - /* If the pattern ends with a `*' we leave it alone if it's preceded by - an even number of backslashes, but if it's escaped by a backslash - we need to add another `*'. */ - if ((mtype != MATCH_END) && (p1[-1] == '*' && (unescaped_backslash = p1[-2] == '\\'))) - { - pp = p1 - 3; - while (pp >= pat && *pp-- == '\\') - unescaped_backslash = 1 - unescaped_backslash; - if (unescaped_backslash) - *p++ = '*'; - } - else if (mtype != MATCH_END && p1[-1] != '*') - *p++ = '*'; -#else - if (p1[-1] != '*' || p1[-2] == '\\') - *p++ = '*'; -#endif - *p = '\0'; - } - else - npat = pat; - c = strmatch (npat, string, FNMATCH_EXTFLAG | FNMATCH_IGNCASE); - if (npat != pat) - free (npat); - if (c == FNM_NOMATCH) - return (0); - - len = STRLEN (string); - end = string + len; - - mlen = umatchlen (pat, len); - if (mlen > (int)len) - return (0); - - switch (mtype) - { - case MATCH_ANY: - for (p = string; p <= end; p++) - { - if (match_pattern_char (pat, p, FNMATCH_IGNCASE)) - { - p1 = (mlen == -1) ? end : p + mlen; - /* p1 - p = length of portion of string to be considered - p = current position in string - mlen = number of characters consumed by match (-1 for entire string) - end = end of string - we want to break immediately if the potential match len - is greater than the number of characters remaining in the - string - */ - if (p1 > end) - break; - for ( ; p1 >= p; p1--) - { - c = *p1; *p1 = '\0'; - if (strmatch (pat, p, FNMATCH_EXTFLAG | FNMATCH_IGNCASE) == 0) - { - *p1 = c; - *sp = p; - *ep = p1; - return 1; - } - *p1 = c; -#if 1 - /* If MLEN != -1, we have a fixed length pattern. */ - if (mlen != -1) - break; -#endif - } - } - } - - return (0); - - case MATCH_BEG: - if (match_pattern_char (pat, string, FNMATCH_IGNCASE) == 0) - return (0); - - for (p = (mlen == -1) ? end : string + mlen; p >= string; p--) - { - c = *p; *p = '\0'; - if (strmatch (pat, string, FNMATCH_EXTFLAG | FNMATCH_IGNCASE) == 0) - { - *p = c; - *sp = string; - *ep = p; - return 1; - } - *p = c; - /* If MLEN != -1, we have a fixed length pattern. */ - if (mlen != -1) - break; - } - - return (0); - - case MATCH_END: - for (p = end - ((mlen == -1) ? len : mlen); p <= end; p++) - { - if (strmatch (pat, p, FNMATCH_EXTFLAG | FNMATCH_IGNCASE) == 0) - { - *sp = p; - *ep = end; - return 1; - } - /* If MLEN != -1, we have a fixed length pattern. */ - if (mlen != -1) - break; - } - - return (0); - } - - return (0); -} - -#if defined (HANDLE_MULTIBYTE) - -#define WFOLD(c) (match_ignore_case && iswupper (c) ? towlower (c) : (c)) - -/* Match WPAT anywhere in WSTRING and return the match boundaries. - This returns 1 in case of a successful match, 0 otherwise. Wide - character version. */ -static int -match_wpattern (wstring, indices, wstrlen, wpat, mtype, sp, ep) - wchar_t *wstring; - char **indices; - size_t wstrlen; - wchar_t *wpat; - int mtype; - char **sp, **ep; -{ - wchar_t wc, *wp, *nwpat, *wp1; - size_t len; - int mlen; - int n, n1, n2, simple; - - simple = (wpat[0] != L'\\' && wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'['); -#if defined (EXTENDED_GLOB) - if (extended_glob) - simple &= (wpat[1] != L'(' || (wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'+' && wpat[0] != L'!' && wpat[0] != L'@')); /*)*/ -#endif - - /* If the pattern doesn't match anywhere in the string, go ahead and - short-circuit right away. A minor optimization, saves a bunch of - unnecessary calls to strmatch (up to N calls for a string of N - characters) if the match is unsuccessful. To preserve the semantics - of the substring matches below, we make sure that the pattern has - `*' as first and last character, making a new pattern if necessary. */ - len = wcslen (wpat); - if (wpat[0] != L'*' || (wpat[0] == L'*' && wpat[1] == WLPAREN && extended_glob) || wpat[len - 1] != L'*') - { - int unescaped_backslash; - wchar_t *wpp; - - wp = nwpat = (wchar_t *)xmalloc ((len + 3) * sizeof (wchar_t)); - wp1 = wpat; - if (*wp1 != L'*' || (*wp1 == '*' && wp1[1] == WLPAREN && extended_glob)) - *wp++ = L'*'; - while (*wp1 != L'\0') - *wp++ = *wp1++; -#if 1 - /* See comments above in match_upattern. */ - if (wp1[-1] == L'*' && (unescaped_backslash = wp1[-2] == L'\\')) - { - wpp = wp1 - 3; - while (wpp >= wpat && *wpp-- == L'\\') - unescaped_backslash = 1 - unescaped_backslash; - if (unescaped_backslash) - *wp++ = L'*'; - } - else if (wp1[-1] != L'*') - *wp++ = L'*'; -#else - if (wp1[-1] != L'*' || wp1[-2] == L'\\') - *wp++ = L'*'; -#endif - *wp = '\0'; - } - else - nwpat = wpat; - len = wcsmatch (nwpat, wstring, FNMATCH_EXTFLAG | FNMATCH_IGNCASE); - if (nwpat != wpat) - free (nwpat); - if (len == FNM_NOMATCH) - return (0); - - mlen = wmatchlen (wpat, wstrlen); - if (mlen > (int)wstrlen) - return (0); - -/* itrace("wmatchlen (%ls) -> %d", wpat, mlen); */ - switch (mtype) - { - case MATCH_ANY: - for (n = 0; n <= wstrlen; n++) - { - n2 = simple ? (WFOLD(*wpat) == WFOLD(wstring[n])) : match_pattern_wchar (wpat, wstring + n, FNMATCH_IGNCASE); - if (n2) - { - n1 = (mlen == -1) ? wstrlen : n + mlen; - if (n1 > wstrlen) - break; - - for ( ; n1 >= n; n1--) - { - wc = wstring[n1]; wstring[n1] = L'\0'; - if (wcsmatch (wpat, wstring + n, FNMATCH_EXTFLAG | FNMATCH_IGNCASE) == 0) - { - wstring[n1] = wc; - *sp = indices[n]; - *ep = indices[n1]; - return 1; - } - wstring[n1] = wc; - /* If MLEN != -1, we have a fixed length pattern. */ - if (mlen != -1) - break; - } - } - } - - return (0); - - case MATCH_BEG: - if (match_pattern_wchar (wpat, wstring, FNMATCH_IGNCASE) == 0) - return (0); - - for (n = (mlen == -1) ? wstrlen : mlen; n >= 0; n--) - { - wc = wstring[n]; wstring[n] = L'\0'; - if (wcsmatch (wpat, wstring, FNMATCH_EXTFLAG | FNMATCH_IGNCASE) == 0) - { - wstring[n] = wc; - *sp = indices[0]; - *ep = indices[n]; - return 1; - } - wstring[n] = wc; - /* If MLEN != -1, we have a fixed length pattern. */ - if (mlen != -1) - break; - } - - return (0); - - case MATCH_END: - for (n = wstrlen - ((mlen == -1) ? wstrlen : mlen); n <= wstrlen; n++) - { - if (wcsmatch (wpat, wstring + n, FNMATCH_EXTFLAG | FNMATCH_IGNCASE) == 0) - { - *sp = indices[n]; - *ep = indices[wstrlen]; - return 1; - } - /* If MLEN != -1, we have a fixed length pattern. */ - if (mlen != -1) - break; - } - - return (0); - } - - return (0); -} -#undef WFOLD -#endif /* HANDLE_MULTIBYTE */ - -static int -match_pattern (string, pat, mtype, sp, ep) - char *string, *pat; - int mtype; - char **sp, **ep; -{ -#if defined (HANDLE_MULTIBYTE) - int ret; - size_t n; - wchar_t *wstring, *wpat; - char **indices; -#endif - - if (string == 0 || pat == 0 || *pat == 0) - return (0); - -#if defined (HANDLE_MULTIBYTE) - if (MB_CUR_MAX > 1) - { - if (mbsmbchar (string) == 0 && mbsmbchar (pat) == 0) - return (match_upattern (string, pat, mtype, sp, ep)); - - n = xdupmbstowcs (&wpat, NULL, pat); - if (n == (size_t)-1) - return (match_upattern (string, pat, mtype, sp, ep)); - n = xdupmbstowcs (&wstring, &indices, string); - if (n == (size_t)-1) - { - free (wpat); - return (match_upattern (string, pat, mtype, sp, ep)); - } - ret = match_wpattern (wstring, indices, n, wpat, mtype, sp, ep); - - free (wpat); - free (wstring); - free (indices); - - return (ret); - } - else -#endif - return (match_upattern (string, pat, mtype, sp, ep)); -} - -static int -getpatspec (c, value) - int c; - char *value; -{ - if (c == '#') - return ((*value == '#') ? RP_LONG_LEFT : RP_SHORT_LEFT); - else /* c == '%' */ - return ((*value == '%') ? RP_LONG_RIGHT : RP_SHORT_RIGHT); -} - -/* Posix.2 says that the WORD should be run through tilde expansion, - parameter expansion, command substitution and arithmetic expansion. - This leaves the result quoted, so quote_string_for_globbing () has - to be called to fix it up for strmatch (). If QUOTED is non-zero, - it means that the entire expression was enclosed in double quotes. - This means that quoting characters in the pattern do not make any - special pattern characters quoted. For example, the `*' in the - following retains its special meaning: "${foo#'*'}". */ -static char * -getpattern (value, quoted, expandpat) - char *value; - int quoted, expandpat; -{ - char *pat, *tword; - WORD_LIST *l; -#if 0 - int i; -#endif - /* There is a problem here: how to handle single or double quotes in the - pattern string when the whole expression is between double quotes? - POSIX.2 says that enclosing double quotes do not cause the pattern to - be quoted, but does that leave us a problem with @ and array[@] and their - expansions inside a pattern? */ -#if 0 - if (expandpat && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *tword) - { - i = 0; - pat = string_extract_double_quoted (tword, &i, SX_STRIPDQ); - free (tword); - tword = pat; - } -#endif - - /* expand_string_for_pat () leaves WORD quoted and does not perform - word splitting. */ - l = *value ? expand_string_for_pat (value, - (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? Q_PATQUOTE : quoted, - (int *)NULL, (int *)NULL) - : (WORD_LIST *)0; - if (l) - word_list_remove_quoted_nulls (l); - pat = string_list (l); - dispose_words (l); - if (pat) - { - tword = quote_string_for_globbing (pat, QGLOB_CVTNULL); - free (pat); - pat = tword; - } - return (pat); -} - -#if 0 -/* Handle removing a pattern from a string as a result of ${name%[%]value} - or ${name#[#]value}. */ -static char * -variable_remove_pattern (value, pattern, patspec, quoted) - char *value, *pattern; - int patspec, quoted; -{ - char *tword; - - tword = remove_pattern (value, pattern, patspec); - - return (tword); -} -#endif - -static char * -list_remove_pattern (list, pattern, patspec, itype, quoted) - WORD_LIST *list; - char *pattern; - int patspec, itype, quoted; -{ - WORD_LIST *new, *l; - WORD_DESC *w; - char *tword; - - for (new = (WORD_LIST *)NULL, l = list; l; l = l->next) - { - tword = remove_pattern (l->word->word, pattern, patspec); - w = alloc_word_desc (); - w->word = tword ? tword : savestring (""); - new = make_word_list (w, new); - } - - l = REVERSE_LIST (new, WORD_LIST *); - tword = string_list_pos_params (itype, l, quoted, 0); - dispose_words (l); - - return (tword); -} - -static char * -parameter_list_remove_pattern (itype, pattern, patspec, quoted) - int itype; - char *pattern; - int patspec, quoted; -{ - char *ret; - WORD_LIST *list; - - list = list_rest_of_args (); - if (list == 0) - return ((char *)NULL); - ret = list_remove_pattern (list, pattern, patspec, itype, quoted); - dispose_words (list); - return (ret); -} - -#if defined (ARRAY_VARS) -static char * -array_remove_pattern (var, pattern, patspec, starsub, quoted) - SHELL_VAR *var; - char *pattern; - int patspec; - int starsub; /* so we can figure out how it's indexed */ - int quoted; -{ - ARRAY *a; - HASH_TABLE *h; - int itype; - char *ret; - WORD_LIST *list; - SHELL_VAR *v; - - v = var; /* XXX - for now */ - - itype = starsub ? '*' : '@'; - - a = (v && array_p (v)) ? array_cell (v) : 0; - h = (v && assoc_p (v)) ? assoc_cell (v) : 0; - - list = a ? array_to_word_list (a) : (h ? assoc_to_word_list (h) : 0); - if (list == 0) - return ((char *)NULL); - ret = list_remove_pattern (list, pattern, patspec, itype, quoted); - dispose_words (list); - - return ret; -} -#endif /* ARRAY_VARS */ - -static char * -parameter_brace_remove_pattern (varname, value, estatep, patstr, rtype, quoted, flags) - char *varname, *value; - array_eltstate_t *estatep; - char *patstr; - int rtype, quoted, flags; -{ - int vtype, patspec, starsub; - char *temp1, *val, *pattern, *oname; - SHELL_VAR *v; - - if (value == 0) - return ((char *)NULL); - - oname = this_command_name; - this_command_name = varname; - - vtype = get_var_and_type (varname, value, estatep, quoted, flags, &v, &val); - if (vtype == -1) - { - this_command_name = oname; - return ((char *)NULL); - } - - starsub = vtype & VT_STARSUB; - vtype &= ~VT_STARSUB; - - patspec = getpatspec (rtype, patstr); - if (patspec == RP_LONG_LEFT || patspec == RP_LONG_RIGHT) - patstr++; - - /* Need to pass getpattern newly-allocated memory in case of expansion -- - the expansion code will free the passed string on an error. */ - temp1 = savestring (patstr); - pattern = getpattern (temp1, quoted, 1); - free (temp1); - - temp1 = (char *)NULL; /* shut up gcc */ - switch (vtype) - { - case VT_VARIABLE: - case VT_ARRAYMEMBER: - temp1 = remove_pattern (val, pattern, patspec); - if (vtype == VT_VARIABLE) - FREE (val); - if (temp1) - { - val = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) - ? quote_string (temp1) - : quote_escapes (temp1); - free (temp1); - temp1 = val; - } - break; -#if defined (ARRAY_VARS) - case VT_ARRAYVAR: - temp1 = array_remove_pattern (v, pattern, patspec, starsub, quoted); - if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0)) - { - val = quote_escapes (temp1); - free (temp1); - temp1 = val; - } - break; -#endif - case VT_POSPARMS: - temp1 = parameter_list_remove_pattern (varname[0], pattern, patspec, quoted); - if (temp1 && quoted == 0 && ifs_is_null) - { - /* Posix interp 888 */ - } - else if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0)) - { - val = quote_escapes (temp1); - free (temp1); - temp1 = val; - } - break; - } - - this_command_name = oname; - - FREE (pattern); - return temp1; -} - -#if defined (PROCESS_SUBSTITUTION) - -static void reap_some_procsubs PARAMS((int)); - -/*****************************************************************/ -/* */ -/* Hacking Process Substitution */ -/* */ -/*****************************************************************/ - -#if !defined (HAVE_DEV_FD) -/* Named pipes must be removed explicitly with `unlink'. This keeps a list - of FIFOs the shell has open. unlink_fifo_list will walk the list and - unlink the ones that don't have a living process on the other end. - unlink_all_fifos will walk the list and unconditionally unlink them, trying - to open and close the FIFO first to release any child processes sleeping on - the FIFO. add_fifo_list adds the name of an open FIFO to the list. - NFIFO is a count of the number of FIFOs in the list. */ -#define FIFO_INCR 20 - -/* PROC value of -1 means the process has been reaped and the FIFO needs to - be removed. PROC value of 0 means the slot is unused. */ -struct temp_fifo { - char *file; - pid_t proc; -}; - -static struct temp_fifo *fifo_list = (struct temp_fifo *)NULL; -static int nfifo; -static int fifo_list_size; - -void -clear_fifo_list () -{ - int i; - - for (i = 0; i < fifo_list_size; i++) - { - if (fifo_list[i].file) - free (fifo_list[i].file); - fifo_list[i].file = NULL; - fifo_list[i].proc = 0; - } - nfifo = 0; -} - -void * -copy_fifo_list (sizep) - int *sizep; -{ - if (sizep) - *sizep = 0; - return (void *)NULL; -} - -static void -add_fifo_list (pathname) - char *pathname; -{ - int osize, i; - - if (nfifo >= fifo_list_size - 1) - { - osize = fifo_list_size; - fifo_list_size += FIFO_INCR; - fifo_list = (struct temp_fifo *)xrealloc (fifo_list, - fifo_list_size * sizeof (struct temp_fifo)); - for (i = osize; i < fifo_list_size; i++) - { - fifo_list[i].file = (char *)NULL; - fifo_list[i].proc = 0; /* unused */ - } - } - - fifo_list[nfifo].file = savestring (pathname); - nfifo++; -} - -void -unlink_fifo (i) - int i; -{ - if ((fifo_list[i].proc == (pid_t)-1) || (fifo_list[i].proc > 0 && (kill(fifo_list[i].proc, 0) == -1))) - { - unlink (fifo_list[i].file); - free (fifo_list[i].file); - fifo_list[i].file = (char *)NULL; - fifo_list[i].proc = 0; - } -} - -void -unlink_fifo_list () -{ - int saved, i, j; - - if (nfifo == 0) - return; - - for (i = saved = 0; i < nfifo; i++) - { - if ((fifo_list[i].proc == (pid_t)-1) || (fifo_list[i].proc > 0 && (kill(fifo_list[i].proc, 0) == -1))) - { - unlink (fifo_list[i].file); - free (fifo_list[i].file); - fifo_list[i].file = (char *)NULL; - fifo_list[i].proc = 0; - } - else - saved++; - } - - /* If we didn't remove some of the FIFOs, compact the list. */ - if (saved) - { - for (i = j = 0; i < nfifo; i++) - if (fifo_list[i].file) - { - if (i != j) - { - fifo_list[j].file = fifo_list[i].file; - fifo_list[j].proc = fifo_list[i].proc; - fifo_list[i].file = (char *)NULL; - fifo_list[i].proc = 0; - } - j++; - } - nfifo = j; - } - else - nfifo = 0; -} - -void -unlink_all_fifos () -{ - int i, fd; - - if (nfifo == 0) - return; - - for (i = 0; i < nfifo; i++) - { - fifo_list[i].proc = (pid_t)-1; -#if defined (O_NONBLOCK) - fd = open (fifo_list[i].file, O_RDWR|O_NONBLOCK); -#else - fd = -1; -#endif - unlink_fifo (i); - if (fd >= 0) - close (fd); - } - - nfifo = 0; -} - -/* Take LIST, which is a bitmap denoting active FIFOs in fifo_list - from some point in the past, and close all open FIFOs in fifo_list - that are not marked as active in LIST. If LIST is NULL, close - everything in fifo_list. LSIZE is the number of elements in LIST, in - case it's larger than fifo_list_size (size of fifo_list). */ -void -close_new_fifos (list, lsize) - void *list; - int lsize; -{ - int i; - char *plist; - - if (list == 0) - { - unlink_fifo_list (); - return; - } - - for (plist = (char *)list, i = 0; i < lsize; i++) - if (plist[i] == 0 && i < fifo_list_size && fifo_list[i].proc != -1) - unlink_fifo (i); - - for (i = lsize; i < fifo_list_size; i++) - unlink_fifo (i); -} - -int -find_procsub_child (pid) - pid_t pid; -{ - int i; - - for (i = 0; i < nfifo; i++) - if (fifo_list[i].proc == pid) - return i; - return -1; -} - -void -set_procsub_status (ind, pid, status) - int ind; - pid_t pid; - int status; -{ - if (ind >= 0 && ind < nfifo) - fifo_list[ind].proc = (pid_t)-1; /* sentinel */ -} - -/* If we've marked the process for this procsub as dead, close the - associated file descriptor and delete the FIFO. */ -static void -reap_some_procsubs (max) - int max; -{ - int i; - - for (i = 0; i < max; i++) - if (fifo_list[i].proc == (pid_t)-1) /* reaped */ - unlink_fifo (i); -} - -void -reap_procsubs () -{ - reap_some_procsubs (nfifo); -} - -#if 0 -/* UNUSED */ -void -wait_procsubs () -{ - int i, r; - - for (i = 0; i < nfifo; i++) - { - if (fifo_list[i].proc != (pid_t)-1 && fifo_list[i].proc > 0) - { - r = wait_for (fifo_list[i].proc, 0); - save_proc_status (fifo_list[i].proc, r); - fifo_list[i].proc = (pid_t)-1; - } - } -} -#endif - -int -fifos_pending () -{ - return nfifo; -} - -int -num_fifos () -{ - return nfifo; -} - -static char * -make_named_pipe () -{ - char *tname; - - tname = sh_mktmpname ("sh-np", MT_USERANDOM|MT_USETMPDIR); - if (mkfifo (tname, 0600) < 0) - { - free (tname); - return ((char *)NULL); - } - - add_fifo_list (tname); - return (tname); -} - -#else /* HAVE_DEV_FD */ - -/* DEV_FD_LIST is a bitmap of file descriptors attached to pipes the shell - has open to children. NFDS is a count of the number of bits currently - set in DEV_FD_LIST. TOTFDS is a count of the highest possible number - of open files. */ -/* dev_fd_list[I] value of -1 means the process has been reaped and file - descriptor I needs to be closed. Value of 0 means the slot is unused. */ - -static pid_t *dev_fd_list = (pid_t *)NULL; -static int nfds; -static int totfds; /* The highest possible number of open files. */ - -void -clear_fifo (i) - int i; -{ - if (dev_fd_list[i]) - { - dev_fd_list[i] = 0; - nfds--; - } -} - -void -clear_fifo_list () -{ - register int i; - - if (nfds == 0) - return; - - for (i = 0; nfds && i < totfds; i++) - clear_fifo (i); - - nfds = 0; -} - -void * -copy_fifo_list (sizep) - int *sizep; -{ - void *ret; - - if (nfds == 0 || totfds == 0) - { - if (sizep) - *sizep = 0; - return (void *)NULL; - } - - if (sizep) - *sizep = totfds; - ret = xmalloc (totfds * sizeof (pid_t)); - return (memcpy (ret, dev_fd_list, totfds * sizeof (pid_t))); -} - -static void -add_fifo_list (fd) - int fd; -{ - if (dev_fd_list == 0 || fd >= totfds) - { - int ofds; - - ofds = totfds; - totfds = getdtablesize (); - if (totfds < 0 || totfds > 256) - totfds = 256; - if (fd >= totfds) - totfds = fd + 2; - - dev_fd_list = (pid_t *)xrealloc (dev_fd_list, totfds * sizeof (dev_fd_list[0])); - /* XXX - might need a loop for this */ - memset (dev_fd_list + ofds, '\0', (totfds - ofds) * sizeof (pid_t)); - } - - dev_fd_list[fd] = 1; /* marker; updated later */ - nfds++; -} - -int -fifos_pending () -{ - return 0; /* used for cleanup; not needed with /dev/fd */ -} - -int -num_fifos () -{ - return nfds; -} - -void -unlink_fifo (fd) - int fd; -{ - if (dev_fd_list[fd]) - { - close (fd); - dev_fd_list[fd] = 0; - nfds--; - } -} - -void -unlink_fifo_list () -{ - register int i; - - if (nfds == 0) - return; - - for (i = totfds-1; nfds && i >= 0; i--) - unlink_fifo (i); - - nfds = 0; -} - -void -unlink_all_fifos () -{ - unlink_fifo_list (); -} - -/* Take LIST, which is a snapshot copy of dev_fd_list from some point in - the past, and close all open fds in dev_fd_list that are not marked - as open in LIST. If LIST is NULL, close everything in dev_fd_list. - LSIZE is the number of elements in LIST, in case it's larger than - totfds (size of dev_fd_list). */ -void -close_new_fifos (list, lsize) - void *list; - int lsize; -{ - int i; - pid_t *plist; - - if (list == 0) - { - unlink_fifo_list (); - return; - } - - for (plist = (pid_t *)list, i = 0; i < lsize; i++) - if (plist[i] == 0 && i < totfds && dev_fd_list[i]) - unlink_fifo (i); - - for (i = lsize; i < totfds; i++) - unlink_fifo (i); -} - -int -find_procsub_child (pid) - pid_t pid; -{ - int i; - - if (nfds == 0) - return -1; - - for (i = 0; i < totfds; i++) - if (dev_fd_list[i] == pid) - return i; - - return -1; -} - -void -set_procsub_status (ind, pid, status) - int ind; - pid_t pid; - int status; -{ - if (ind >= 0 && ind < totfds) - dev_fd_list[ind] = (pid_t)-1; /* sentinel */ -} - -/* If we've marked the process for this procsub as dead, close the - associated file descriptor. */ -static void -reap_some_procsubs (max) - int max; -{ - int i; - - for (i = 0; nfds > 0 && i < max; i++) - if (dev_fd_list[i] == (pid_t)-1) - unlink_fifo (i); -} - -void -reap_procsubs () -{ - reap_some_procsubs (totfds); -} - -#if 0 -/* UNUSED */ -void -wait_procsubs () -{ - int i, r; - - for (i = 0; nfds > 0 && i < totfds; i++) - { - if (dev_fd_list[i] != (pid_t)-1 && dev_fd_list[i] > 0) - { - r = wait_for (dev_fd_list[i], 0); - save_proc_status (dev_fd_list[i], r); - dev_fd_list[i] = (pid_t)-1; - } - } -} -#endif - -#if defined (NOTDEF) -print_dev_fd_list () -{ - register int i; - - fprintf (stderr, "pid %ld: dev_fd_list:", (long)getpid ()); - fflush (stderr); - - for (i = 0; i < totfds; i++) - { - if (dev_fd_list[i]) - fprintf (stderr, " %d", i); - } - fprintf (stderr, "\n"); -} -#endif /* NOTDEF */ - -static char * -make_dev_fd_filename (fd) - int fd; -{ - char *ret, intbuf[INT_STRLEN_BOUND (int) + 1], *p; - - ret = (char *)xmalloc (sizeof (DEV_FD_PREFIX) + 8); - - strcpy (ret, DEV_FD_PREFIX); - p = inttostr (fd, intbuf, sizeof (intbuf)); - strcpy (ret + sizeof (DEV_FD_PREFIX) - 1, p); - - add_fifo_list (fd); - return (ret); -} - -#endif /* HAVE_DEV_FD */ - -/* Return a filename that will open a connection to the process defined by - executing STRING. HAVE_DEV_FD, if defined, means open a pipe and return - a filename in /dev/fd corresponding to a descriptor that is one of the - ends of the pipe. If not defined, we use named pipes on systems that have - them. Systems without /dev/fd and named pipes are out of luck. - - OPEN_FOR_READ_IN_CHILD, if 1, means open the named pipe for reading or - use the read end of the pipe and dup that file descriptor to fd 0 in - the child. If OPEN_FOR_READ_IN_CHILD is 0, we open the named pipe for - writing or use the write end of the pipe in the child, and dup that - file descriptor to fd 1 in the child. The parent does the opposite. */ - -static char * -process_substitute (string, open_for_read_in_child) - char *string; - int open_for_read_in_child; -{ - char *pathname; - int fd, result, rc, function_value; - pid_t old_pid, pid; -#if defined (HAVE_DEV_FD) - int parent_pipe_fd, child_pipe_fd; - int fildes[2]; -#endif /* HAVE_DEV_FD */ -#if defined (JOB_CONTROL) - pid_t old_pipeline_pgrp; -#endif - - if (!string || !*string || wordexp_only) - return ((char *)NULL); - -#if !defined (HAVE_DEV_FD) - pathname = make_named_pipe (); -#else /* HAVE_DEV_FD */ - if (pipe (fildes) < 0) - { - sys_error ("%s", _("cannot make pipe for process substitution")); - return ((char *)NULL); - } - /* If OPEN_FOR_READ_IN_CHILD == 1, we want to use the write end of - the pipe in the parent, otherwise the read end. */ - parent_pipe_fd = fildes[open_for_read_in_child]; - child_pipe_fd = fildes[1 - open_for_read_in_child]; - /* Move the parent end of the pipe to some high file descriptor, to - avoid clashes with FDs used by the script. */ - parent_pipe_fd = move_to_high_fd (parent_pipe_fd, 1, 64); - - pathname = make_dev_fd_filename (parent_pipe_fd); -#endif /* HAVE_DEV_FD */ - - if (pathname == 0) - { - sys_error ("%s", _("cannot make pipe for process substitution")); - return ((char *)NULL); - } - - old_pid = last_made_pid; - -#if defined (JOB_CONTROL) - old_pipeline_pgrp = pipeline_pgrp; - if (pipeline_pgrp == 0 || (subshell_environment & (SUBSHELL_PIPE|SUBSHELL_FORK|SUBSHELL_ASYNC)) == 0) - pipeline_pgrp = shell_pgrp; - save_pipeline (1); -#endif /* JOB_CONTROL */ - - pid = make_child ((char *)NULL, FORK_ASYNC); - if (pid == 0) - { -#if 0 - int old_interactive; - - old_interactive = interactive; -#endif - /* The currently-executing shell is not interactive */ - interactive = 0; - - reset_terminating_signals (); /* XXX */ - free_pushed_string_input (); - /* Cancel traps, in trap.c. */ - restore_original_signals (); /* XXX - what about special builtins? bash-4.2 */ - subshell_environment &= ~SUBSHELL_IGNTRAP; - QUIT; /* catch any interrupts we got post-fork */ - setup_async_signals (); -#if 0 - if (open_for_read_in_child == 0 && old_interactive && (bash_input.type == st_stdin || bash_input.type == st_stream)) - async_redirect_stdin (); -#endif - - subshell_environment |= SUBSHELL_COMSUB|SUBSHELL_PROCSUB|SUBSHELL_ASYNC; - - /* We don't inherit the verbose option for command substitutions now, so - let's try it for process substitutions. */ - change_flag ('v', FLAG_OFF); - - /* if we're expanding a redirection, we shouldn't have access to the - temporary environment, but commands in the subshell should have - access to their own temporary environment. */ - if (expanding_redir) - flush_temporary_env (); - } - -#if defined (JOB_CONTROL) - set_sigchld_handler (); - stop_making_children (); - /* XXX - should we only do this in the parent? (as in command subst) */ - pipeline_pgrp = old_pipeline_pgrp; -#else - stop_making_children (); -#endif /* JOB_CONTROL */ - - if (pid < 0) - { - sys_error ("%s", _("cannot make child for process substitution")); - free (pathname); -#if defined (HAVE_DEV_FD) - close (parent_pipe_fd); - close (child_pipe_fd); -#endif /* HAVE_DEV_FD */ -#if defined (JOB_CONTROL) - restore_pipeline (1); -#endif - return ((char *)NULL); - } - - if (pid > 0) - { -#if defined (JOB_CONTROL) - last_procsub_child = restore_pipeline (0); - /* We assume that last_procsub_child->next == last_procsub_child because - of how jobs.c:add_process() works. */ - last_procsub_child->next = 0; - procsub_add (last_procsub_child); -#endif - -#if defined (HAVE_DEV_FD) - dev_fd_list[parent_pipe_fd] = pid; -#else - fifo_list[nfifo-1].proc = pid; -#endif - - last_made_pid = old_pid; - -#if defined (JOB_CONTROL) && defined (PGRP_PIPE) - close_pgrp_pipe (); -#endif /* JOB_CONTROL && PGRP_PIPE */ - -#if defined (HAVE_DEV_FD) - close (child_pipe_fd); -#endif /* HAVE_DEV_FD */ - - return (pathname); - } - - set_sigint_handler (); - -#if defined (JOB_CONTROL) - /* make sure we don't have any job control */ - set_job_control (0); - - /* Clear out any existing list of process substitutions */ - procsub_clear (); - - /* The idea is that we want all the jobs we start from an async process - substitution to be in the same process group, but not the same pgrp - as our parent shell, since we don't want to affect our parent shell's - jobs if we get a SIGHUP and end up calling hangup_all_jobs, for example. - If pipeline_pgrp != shell_pgrp, we assume that there is a job control - shell somewhere in our parent process chain (since make_child initializes - pipeline_pgrp to shell_pgrp if job_control == 0). What we do in this - case is to set pipeline_pgrp to our PID, so all jobs started by this - process have that same pgrp and we are basically the process group leader. - This should not have negative effects on child processes surviving - after we exit, since we wait for the children we create, but that is - something to watch for. */ - - if (pipeline_pgrp != shell_pgrp) - pipeline_pgrp = getpid (); -#endif /* JOB_CONTROL */ - -#if !defined (HAVE_DEV_FD) - /* Open the named pipe in the child. */ - fd = open (pathname, open_for_read_in_child ? O_RDONLY : O_WRONLY); - if (fd < 0) - { - /* Two separate strings for ease of translation. */ - if (open_for_read_in_child) - sys_error (_("cannot open named pipe %s for reading"), pathname); - else - sys_error (_("cannot open named pipe %s for writing"), pathname); - - exit (127); - } - if (open_for_read_in_child) - { - if (sh_unset_nodelay_mode (fd) < 0) - { - sys_error (_("cannot reset nodelay mode for fd %d"), fd); - exit (127); - } - } -#else /* HAVE_DEV_FD */ - fd = child_pipe_fd; -#endif /* HAVE_DEV_FD */ - - /* Discard buffered stdio output before replacing the underlying file - descriptor. */ - if (open_for_read_in_child == 0) - fpurge (stdout); - - if (dup2 (fd, open_for_read_in_child ? 0 : 1) < 0) - { - sys_error (_("cannot duplicate named pipe %s as fd %d"), pathname, - open_for_read_in_child ? 0 : 1); - exit (127); - } - - if (fd != (open_for_read_in_child ? 0 : 1)) - close (fd); - - /* Need to close any files that this process has open to pipes inherited - from its parent. */ - if (current_fds_to_close) - { - close_fd_bitmap (current_fds_to_close); - current_fds_to_close = (struct fd_bitmap *)NULL; - } - -#if defined (HAVE_DEV_FD) - /* Make sure we close the parent's end of the pipe and clear the slot - in the fd list so it is not closed later, if reallocated by, for - instance, pipe(2). */ - close (parent_pipe_fd); - dev_fd_list[parent_pipe_fd] = 0; -#endif /* HAVE_DEV_FD */ - - /* subshells shouldn't have this flag, which controls using the temporary - environment for variable lookups. We have already flushed the temporary - environment above in the case we're expanding a redirection, so processes - executed by this command need to be able to set it independently of their - parent. */ - expanding_redir = 0; - - remove_quoted_escapes (string); - - startup_state = 2; /* see if we can avoid a fork */ - parse_and_execute_level = 0; - - /* Give process substitution a place to jump back to on failure, - so we don't go back up to main (). */ - result = setjmp_nosigs (top_level); - - /* If we're running a process substitution inside a shell function, - trap `return' so we don't return from the function in the subshell - and go off to never-never land. */ - if (result == 0 && return_catch_flag) - function_value = setjmp_nosigs (return_catch); - else - function_value = 0; - - if (result == ERREXIT) - rc = last_command_exit_value; - else if (result == EXITPROG || result == EXITBLTIN) - rc = last_command_exit_value; - else if (result) - rc = EXECUTION_FAILURE; - else if (function_value) - rc = return_catch_value; - else - { - subshell_level++; - rc = parse_and_execute (string, "process substitution", (SEVAL_NONINT|SEVAL_NOHIST)); - /* leave subshell level intact for any exit trap */ - } - -#if !defined (HAVE_DEV_FD) - /* Make sure we close the named pipe in the child before we exit. */ - close (open_for_read_in_child ? 0 : 1); -#endif /* !HAVE_DEV_FD */ - - last_command_exit_value = rc; - rc = run_exit_trap (); - exit (rc); - /*NOTREACHED*/ -} -#endif /* PROCESS_SUBSTITUTION */ - -/***********************************/ -/* */ -/* Command Substitution */ -/* */ -/***********************************/ - -#define COMSUB_PIPEBUF 4096 - -static char * -optimize_cat_file (r, quoted, flags, flagp) - REDIRECT *r; - int quoted, flags, *flagp; -{ - char *ret; - int fd; - - fd = open_redir_file (r, (char **)0); - if (fd < 0) - return &expand_param_error; - - ret = read_comsub (fd, quoted, flags, flagp); - close (fd); - - return ret; -} - -static char * -read_comsub (fd, quoted, flags, rflag) - int fd, quoted, flags; - int *rflag; -{ - char *istring, buf[COMSUB_PIPEBUF], *bufp; - int c, tflag, skip_ctlesc, skip_ctlnul; - int mb_cur_max; - size_t istring_index; - size_t istring_size; - ssize_t bufn; - int nullbyte; -#if defined (HANDLE_MULTIBYTE) - mbstate_t ps; - wchar_t wc; - size_t mblen; - int i; -#endif - - istring = (char *)NULL; - istring_index = istring_size = bufn = tflag = 0; - - skip_ctlesc = ifs_cmap[CTLESC]; - skip_ctlnul = ifs_cmap[CTLNUL]; - - mb_cur_max = MB_CUR_MAX; - nullbyte = 0; - - /* Read the output of the command through the pipe. */ - while (1) - { - if (fd < 0) - break; - if (--bufn <= 0) - { - bufn = zread (fd, buf, sizeof (buf)); - if (bufn <= 0) - break; - bufp = buf; - } - c = *bufp++; - - if (c == 0) - { -#if 1 - if (nullbyte == 0) - { - internal_warning ("%s", _("command substitution: ignored null byte in input")); - nullbyte = 1; - } -#endif - continue; - } - - /* Add the character to ISTRING, possibly after resizing it. */ - RESIZE_MALLOCED_BUFFER (istring, istring_index, mb_cur_max+1, istring_size, 512); - - /* This is essentially quote_string inline */ - if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) /* || c == CTLESC || c == CTLNUL */) - istring[istring_index++] = CTLESC; - else if ((flags & PF_ASSIGNRHS) && skip_ctlesc && c == CTLESC) - istring[istring_index++] = CTLESC; - /* Escape CTLESC and CTLNUL in the output to protect those characters - from the rest of the word expansions (word splitting and globbing.) - This is essentially quote_escapes inline. */ - else if (skip_ctlesc == 0 && c == CTLESC) - istring[istring_index++] = CTLESC; - else if ((skip_ctlnul == 0 && c == CTLNUL) || (c == ' ' && (ifs_value && *ifs_value == 0))) - istring[istring_index++] = CTLESC; - -#if defined (HANDLE_MULTIBYTE) - if ((locale_utf8locale && (c & 0x80)) || - (locale_utf8locale == 0 && mb_cur_max > 1 && (unsigned char)c > 127)) - { - /* read a multibyte character from buf */ - /* punt on the hard case for now */ - memset (&ps, '\0', sizeof (mbstate_t)); - mblen = mbrtowc (&wc, bufp-1, bufn, &ps); - if (MB_INVALIDCH (mblen) || mblen == 0 || mblen == 1) - istring[istring_index++] = c; - else - { - istring[istring_index++] = c; - for (i = 0; i < mblen-1; i++) - istring[istring_index++] = *bufp++; - bufn -= mblen - 1; - } - continue; - } -#endif - - istring[istring_index++] = c; - } - - if (istring) - istring[istring_index] = '\0'; - - /* If we read no output, just return now and save ourselves some - trouble. */ - if (istring_index == 0) - { - FREE (istring); - if (rflag) - *rflag = tflag; - return (char *)NULL; - } - - /* Strip trailing newlines from the output of the command. */ - if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) - { - while (istring_index > 0) - { - if (istring[istring_index - 1] == '\n') - { - --istring_index; - - /* If the newline was quoted, remove the quoting char. */ - if (istring[istring_index - 1] == CTLESC) - --istring_index; - } - else - break; - } - istring[istring_index] = '\0'; - } - else - strip_trailing (istring, istring_index - 1, 1); - - if (rflag) - *rflag = tflag; - return istring; -} - -/* Perform command substitution on STRING. This returns a WORD_DESC * with the - contained string possibly quoted. */ -WORD_DESC * -command_substitute (string, quoted, flags) - char *string; - int quoted; - int flags; -{ - pid_t pid, old_pid, old_pipeline_pgrp, old_async_pid; - char *istring, *s; - int result, fildes[2], function_value, pflags, rc, tflag, fork_flags; - WORD_DESC *ret; - sigset_t set, oset; - - istring = (char *)NULL; - - /* Don't fork () if there is no need to. In the case of no command to - run, just return NULL. */ - for (s = string; s && *s && (shellblank (*s) || *s == '\n'); s++) - ; - if (s == 0 || *s == 0) - return ((WORD_DESC *)NULL); - - if (*s == '<' && (s[1] != '<' && s[1] != '>' && s[1] != '&')) - { - COMMAND *cmd; - - cmd = parse_string_to_command (string, 0); /* XXX - flags */ - if (cmd && can_optimize_cat_file (cmd)) - { - tflag = 0; - istring = optimize_cat_file (cmd->value.Simple->redirects, quoted, flags, &tflag); - if (istring == &expand_param_error) - { - last_command_exit_value = EXECUTION_FAILURE; - istring = 0; - } - else - last_command_exit_value = EXECUTION_SUCCESS; /* compat */ - last_command_subst_pid = dollar_dollar_pid; - - dispose_command (cmd); - ret = alloc_word_desc (); - ret->word = istring; - ret->flags = tflag; - - return ret; - } - dispose_command (cmd); - } - - if (wordexp_only && read_but_dont_execute) - { - last_command_exit_value = EX_WEXPCOMSUB; - jump_to_top_level (EXITPROG); - } - - /* We're making the assumption here that the command substitution will - eventually run a command from the file system. Since we'll run - maybe_make_export_env in this subshell before executing that command, - the parent shell and any other shells it starts will have to remake - the environment. If we make it before we fork, other shells won't - have to. Don't bother if we have any temporary variable assignments, - though, because the export environment will be remade after this - command completes anyway, but do it if all the words to be expanded - are variable assignments. */ - if (subst_assign_varlist == 0 || garglist == 0) - maybe_make_export_env (); /* XXX */ - - /* Flags to pass to parse_and_execute() */ - pflags = (interactive && sourcelevel == 0) ? SEVAL_RESETLINE : 0; - - old_pid = last_made_pid; - - /* Pipe the output of executing STRING into the current shell. */ - if (pipe (fildes) < 0) - { - sys_error ("%s", _("cannot make pipe for command substitution")); - goto error_exit; - } - -#if defined (JOB_CONTROL) - old_pipeline_pgrp = pipeline_pgrp; - /* Don't reset the pipeline pgrp if we're already a subshell in a pipeline or - we've already forked to run a disk command (and are expanding redirections, - for example). */ - if ((subshell_environment & (SUBSHELL_FORK|SUBSHELL_PIPE)) == 0) - pipeline_pgrp = shell_pgrp; - cleanup_the_pipeline (); -#endif /* JOB_CONTROL */ - - old_async_pid = last_asynchronous_pid; - fork_flags = (subshell_environment&SUBSHELL_ASYNC) ? FORK_ASYNC : 0; - pid = make_child ((char *)NULL, fork_flags|FORK_NOTERM); - last_asynchronous_pid = old_async_pid; - - if (pid == 0) - { - /* Reset the signal handlers in the child, but don't free the - trap strings. Set a flag noting that we have to free the - trap strings if we run trap to change a signal disposition. */ - reset_signal_handlers (); - if (ISINTERRUPT) - { - kill (getpid (), SIGINT); - CLRINTERRUPT; /* if we're ignoring SIGINT somehow */ - } - QUIT; /* catch any interrupts we got post-fork */ - subshell_environment |= SUBSHELL_RESETTRAP; - subshell_environment &= ~SUBSHELL_IGNTRAP; - } - -#if defined (JOB_CONTROL) - /* XXX DO THIS ONLY IN PARENT ? XXX */ - set_sigchld_handler (); - stop_making_children (); - if (pid != 0) - pipeline_pgrp = old_pipeline_pgrp; -#else - stop_making_children (); -#endif /* JOB_CONTROL */ - - if (pid < 0) - { - sys_error (_("cannot make child for command substitution")); - error_exit: - - last_made_pid = old_pid; - - FREE (istring); - close (fildes[0]); - close (fildes[1]); - return ((WORD_DESC *)NULL); - } - - if (pid == 0) - { - /* The currently executing shell is not interactive. */ - interactive = 0; - -#if defined (JOB_CONTROL) - /* Invariant: in child processes started to run command substitutions, - pipeline_pgrp == shell_pgrp. Other parts of the shell assume this. */ - if (pipeline_pgrp > 0 && pipeline_pgrp != shell_pgrp) - shell_pgrp = pipeline_pgrp; -#endif - - set_sigint_handler (); /* XXX */ - - free_pushed_string_input (); - - /* Discard buffered stdio output before replacing the underlying file - descriptor. */ - fpurge (stdout); - - if (dup2 (fildes[1], 1) < 0) - { - sys_error ("%s", _("command_substitute: cannot duplicate pipe as fd 1")); - exit (EXECUTION_FAILURE); - } - - /* If standard output is closed in the parent shell - (such as after `exec >&-'), file descriptor 1 will be - the lowest available file descriptor, and end up in - fildes[0]. This can happen for stdin and stderr as well, - but stdout is more important -- it will cause no output - to be generated from this command. */ - if ((fildes[1] != fileno (stdin)) && - (fildes[1] != fileno (stdout)) && - (fildes[1] != fileno (stderr))) - close (fildes[1]); - - if ((fildes[0] != fileno (stdin)) && - (fildes[0] != fileno (stdout)) && - (fildes[0] != fileno (stderr))) - close (fildes[0]); - -#ifdef __CYGWIN__ - /* Let stdio know the fd may have changed from text to binary mode, and - make sure to preserve stdout line buffering. */ - freopen (NULL, "w", stdout); - sh_setlinebuf (stdout); -#endif /* __CYGWIN__ */ - - /* This is a subshell environment. */ - subshell_environment |= SUBSHELL_COMSUB; - - /* Many shells do not appear to inherit the -v option for command - substitutions. */ - change_flag ('v', FLAG_OFF); - - /* When inherit_errexit option is not enabled, command substitution does - not inherit the -e flag. It is enabled when Posix mode is enabled */ - if (inherit_errexit == 0) - { - builtin_ignoring_errexit = 0; - change_flag ('e', FLAG_OFF); - } - set_shellopts (); - - /* If we are expanding a redirection, we can dispose of any temporary - environment we received, since redirections are not supposed to have - access to the temporary environment. We will have to see whether this - affects temporary environments supplied to `eval', but the temporary - environment gets copied to builtin_env at some point. */ - if (expanding_redir) - { - flush_temporary_env (); - expanding_redir = 0; - } - - remove_quoted_escapes (string); - - /* We want to expand aliases on this pass if we are not in posix mode - for backwards compatibility. */ - if (expand_aliases) - expand_aliases = posixly_correct == 0; - - startup_state = 2; /* see if we can avoid a fork */ - parse_and_execute_level = 0; - - /* Give command substitution a place to jump back to on failure, - so we don't go back up to main (). */ - result = setjmp_nosigs (top_level); - - /* If we're running a command substitution inside a shell function, - trap `return' so we don't return from the function in the subshell - and go off to never-never land. */ - if (result == 0 && return_catch_flag) - function_value = setjmp_nosigs (return_catch); - else - function_value = 0; - - if (result == ERREXIT) - rc = last_command_exit_value; - else if (result == EXITPROG || result == EXITBLTIN) - rc = last_command_exit_value; - else if (result) - rc = EXECUTION_FAILURE; - else if (function_value) - rc = return_catch_value; - else - { - subshell_level++; - rc = parse_and_execute (string, "command substitution", pflags|SEVAL_NOHIST); - /* leave subshell level intact for any exit trap */ - } - - last_command_exit_value = rc; - rc = run_exit_trap (); -#if defined (PROCESS_SUBSTITUTION) - unlink_fifo_list (); -#endif - exit (rc); - } - else - { - int dummyfd; - -#if defined (JOB_CONTROL) && defined (PGRP_PIPE) - close_pgrp_pipe (); -#endif /* JOB_CONTROL && PGRP_PIPE */ - - close (fildes[1]); - - begin_unwind_frame ("read-comsub"); - dummyfd = fildes[0]; - add_unwind_protect (close, dummyfd); - - /* Block SIGINT while we're reading from the pipe. If the child - process gets a SIGINT, it will either handle it or die, and the - read will return. */ - BLOCK_SIGNAL (SIGINT, set, oset); - tflag = 0; - istring = read_comsub (fildes[0], quoted, flags, &tflag); - - close (fildes[0]); - discard_unwind_frame ("read-comsub"); - UNBLOCK_SIGNAL (oset); - - current_command_subst_pid = pid; - last_command_exit_value = wait_for (pid, JWAIT_NOTERM); - last_command_subst_pid = pid; - last_made_pid = old_pid; - -#if defined (JOB_CONTROL) - /* If last_command_exit_value > 128, then the substituted command - was terminated by a signal. If that signal was SIGINT, then send - SIGINT to ourselves. This will break out of loops, for instance. */ - if (last_command_exit_value == (128 + SIGINT) && last_command_exit_signal == SIGINT) - kill (getpid (), SIGINT); -#endif /* JOB_CONTROL */ - - ret = alloc_word_desc (); - ret->word = istring; - ret->flags = tflag; - - return ret; - } -} - -/******************************************************** - * * - * Utility functions for parameter expansion * - * * - ********************************************************/ - -#if defined (ARRAY_VARS) - -static arrayind_t -array_length_reference (s) - char *s; -{ - int len; - arrayind_t ind; - char *akey; - char *t, c; - ARRAY *array; - HASH_TABLE *h; - SHELL_VAR *var; - - var = array_variable_part (s, 0, &t, &len); - - /* If unbound variables should generate an error, report one and return - failure. */ - if ((var == 0 || invisible_p (var) || (assoc_p (var) == 0 && array_p (var) == 0)) && unbound_vars_is_error) - { - c = *--t; - *t = '\0'; - set_exit_status (EXECUTION_FAILURE); - err_unboundvar (s); - *t = c; - return (-1); - } - else if (var == 0 || invisible_p (var)) - return 0; - - /* We support a couple of expansions for variables that are not arrays. - We'll return the length of the value for v[0], and 1 for v[@] or - v[*]. Return 0 for everything else. */ - - array = array_p (var) ? array_cell (var) : (ARRAY *)NULL; - h = assoc_p (var) ? assoc_cell (var) : (HASH_TABLE *)NULL; - - if (ALL_ELEMENT_SUB (t[0]) && t[1] == RBRACK) - { - if (assoc_p (var)) - return (h ? assoc_num_elements (h) : 0); - else if (array_p (var)) - return (array ? array_num_elements (array) : 0); - else - return (var_isset (var) ? 1 : 0); - } - - if (assoc_p (var)) - { - t[len - 1] = '\0'; - akey = expand_subscript_string (t, 0); /* [ */ - t[len - 1] = RBRACK; - if (akey == 0 || *akey == 0) - { - err_badarraysub (t); - FREE (akey); - return (-1); - } - t = assoc_reference (assoc_cell (var), akey); - free (akey); - } - else - { - ind = array_expand_index (var, t, len, 0); - /* negative subscripts to indexed arrays count back from end */ - if (var && array_p (var) && ind < 0) - ind = array_max_index (array_cell (var)) + 1 + ind; - if (ind < 0) - { - err_badarraysub (t); - return (-1); - } - if (array_p (var)) - t = array_reference (array, ind); - else - t = (ind == 0) ? value_cell (var) : (char *)NULL; - } - - len = MB_STRLEN (t); - return (len); -} -#endif /* ARRAY_VARS */ - -static int -valid_brace_expansion_word (name, var_is_special) - char *name; - int var_is_special; -{ - if (DIGIT (*name) && all_digits (name)) - return 1; - else if (var_is_special) - return 1; -#if defined (ARRAY_VARS) - else if (valid_array_reference (name, 0)) - return 1; -#endif /* ARRAY_VARS */ - else if (legal_identifier (name)) - return 1; - else - return 0; -} - -static int -chk_atstar (name, quoted, pflags, quoted_dollar_atp, contains_dollar_at) - char *name; - int quoted, pflags; - int *quoted_dollar_atp, *contains_dollar_at; -{ - char *temp1; - - if (name == 0) - { - if (quoted_dollar_atp) - *quoted_dollar_atp = 0; - if (contains_dollar_at) - *contains_dollar_at = 0; - return 0; - } - - /* check for $@ and $* */ - if (name[0] == '@' && name[1] == 0) - { - if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp) - *quoted_dollar_atp = 1; - if (contains_dollar_at) - *contains_dollar_at = 1; - return 1; - } - else if (name[0] == '*' && name[1] == '\0' && quoted == 0) - { - /* Need more checks here that parallel what string_list_pos_params and - param_expand do. Check expand_no_split_dollar_star and ??? */ - if (contains_dollar_at && expand_no_split_dollar_star == 0) - *contains_dollar_at = 1; - return 1; - } - - /* Now check for ${array[@]} and ${array[*]} */ -#if defined (ARRAY_VARS) - else if (valid_array_reference (name, 0)) - { - temp1 = mbschr (name, LBRACK); - if (temp1 && temp1[1] == '@' && temp1[2] == RBRACK) - { - if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp) - *quoted_dollar_atp = 1; - if (contains_dollar_at) - *contains_dollar_at = 1; - return 1; - } - /* ${array[*]}, when unquoted, should be treated like ${array[@]}, - which should result in separate words even when IFS is unset. */ - if (temp1 && temp1[1] == '*' && temp1[2] == RBRACK && quoted == 0) - { - if (contains_dollar_at) - *contains_dollar_at = 1; - return 1; - } - } -#endif - return 0; -} - -/* Parameter expand NAME, and return a new string which is the expansion, - or NULL if there was no expansion. NAME is as given in ${NAMEcWORD}. - VAR_IS_SPECIAL is non-zero if NAME is one of the special variables in - the shell, e.g., "@", "$", "*", etc. QUOTED, if non-zero, means that - NAME was found inside of a double-quoted expression. */ -static WORD_DESC * -parameter_brace_expand_word (name, var_is_special, quoted, pflags, estatep) - char *name; - int var_is_special, quoted, pflags; - array_eltstate_t *estatep; -{ - WORD_DESC *ret; - char *temp, *tt; - intmax_t arg_index; - SHELL_VAR *var; - int rflags; - array_eltstate_t es; - - ret = 0; - temp = 0; - rflags = 0; - -#if defined (ARRAY_VARS) - if (estatep) - es = *estatep; /* structure copy */ - else - { - init_eltstate (&es); - es.ind = INTMAX_MIN; - } -#endif - - /* Handle multiple digit arguments, as in ${11}. */ - if (legal_number (name, &arg_index)) - { - tt = get_dollar_var_value (arg_index); - if (tt) - temp = (*tt && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) - ? quote_string (tt) - : quote_escapes (tt); - else - temp = (char *)NULL; - FREE (tt); - } - else if (var_is_special) /* ${@} */ - { - int sindex; - tt = (char *)xmalloc (2 + strlen (name)); - tt[sindex = 0] = '$'; - strcpy (tt + 1, name); - - ret = param_expand (tt, &sindex, quoted, (int *)NULL, (int *)NULL, - (int *)NULL, (int *)NULL, pflags); - - /* Make sure we note that we saw a quoted null string and pass the flag back - to the caller in addition to the value. */ - if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) && STR_DOLLAR_AT_STAR (name) && - ret && ret->word && QUOTED_NULL (ret->word)) - ret->flags |= W_HASQUOTEDNULL; - - free (tt); - } -#if defined (ARRAY_VARS) - else if (valid_array_reference (name, 0)) - { -expand_arrayref: - var = array_variable_part (name, 0, &tt, (int *)0); - /* These are the cases where word splitting will not be performed */ - if (pflags & PF_ASSIGNRHS) - { - if (ALL_ELEMENT_SUB (tt[0]) && tt[1] == RBRACK) - { - /* Only treat as double quoted if array variable */ - if (var && (array_p (var) || assoc_p (var))) - temp = array_value (name, quoted|Q_DOUBLE_QUOTES, AV_ASSIGNRHS, &es); - else - temp = array_value (name, quoted, 0, &es); - } - else - temp = array_value (name, quoted, 0, &es); - } - /* Posix interp 888 */ - else if (pflags & PF_NOSPLIT2) - { - /* Special cases, then general case, for each of A[@], A[*], A[n] */ -#if defined (HANDLE_MULTIBYTE) - if (tt[0] == '@' && tt[1] == RBRACK && var && quoted == 0 && ifs_is_set && ifs_is_null == 0 && ifs_firstc[0] != ' ') -#else - if (tt[0] == '@' && tt[1] == RBRACK && var && quoted == 0 && ifs_is_set && ifs_is_null == 0 && ifs_firstc != ' ') -#endif - temp = array_value (name, Q_DOUBLE_QUOTES, AV_ASSIGNRHS, &es); - else if (tt[0] == '@' && tt[1] == RBRACK) - temp = array_value (name, quoted, 0, &es); - else if (tt[0] == '*' && tt[1] == RBRACK && expand_no_split_dollar_star && ifs_is_null) - temp = array_value (name, Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT, 0, &es); - else if (tt[0] == '*' && tt[1] == RBRACK) - temp = array_value (name, quoted, 0, &es); - else - temp = array_value (name, quoted, 0, &es); - } - else if (tt[0] == '*' && tt[1] == RBRACK && expand_no_split_dollar_star && ifs_is_null) - temp = array_value (name, Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT, 0, &es); - else - temp = array_value (name, quoted, 0, &es); - if (es.subtype == 0 && temp) - { - temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) - ? quote_string (temp) - : quote_escapes (temp); - rflags |= W_ARRAYIND; - if (estatep) - *estatep = es; /* structure copy */ - } - /* Note that array[*] and array[@] expanded to a quoted null string by - returning the W_HASQUOTEDNULL flag to the caller in addition to TEMP. */ - else if (es.subtype == 1 && temp && QUOTED_NULL (temp) && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) - rflags |= W_HASQUOTEDNULL; - else if (es.subtype == 2 && temp && QUOTED_NULL (temp) && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) - rflags |= W_HASQUOTEDNULL; - - if (estatep == 0) - flush_eltstate (&es); - } -#endif - else if (var = find_variable (name)) - { - if (var_isset (var) && invisible_p (var) == 0) - { -#if defined (ARRAY_VARS) - /* We avoid a memory leak by saving TT as the memory allocated by - assoc_to_string or array_to_string and leaving it 0 otherwise, - then freeing TT after quoting temp. */ - tt = (char *)NULL; - if ((pflags & PF_ALLINDS) && assoc_p (var)) - tt = temp = assoc_empty (assoc_cell (var)) ? (char *)NULL : assoc_to_string (assoc_cell (var), " ", quoted); - else if ((pflags & PF_ALLINDS) && array_p (var)) - tt = temp = array_empty (array_cell (var)) ? (char *)NULL : array_to_string (array_cell (var), " ", quoted); - else if (assoc_p (var)) - temp = assoc_reference (assoc_cell (var), "0"); - else if (array_p (var)) - temp = array_reference (array_cell (var), 0); - else - temp = value_cell (var); -#else - temp = value_cell (var); -#endif - - if (temp) - temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) - ? quote_string (temp) - : ((pflags & PF_ASSIGNRHS) ? quote_rhs (temp) - : quote_escapes (temp)); - FREE (tt); - } - else - temp = (char *)NULL; - } - else if (var = find_variable_last_nameref (name, 0)) - { - temp = nameref_cell (var); -#if defined (ARRAY_VARS) - /* Handle expanding nameref whose value is x[n] */ - if (temp && *temp && valid_array_reference (temp, 0)) - { - name = temp; - goto expand_arrayref; - } - else -#endif - /* y=2 ; typeset -n x=y; echo ${x} is not the same as echo ${2} in ksh */ - if (temp && *temp && legal_identifier (temp) == 0) - { - set_exit_status (EXECUTION_FAILURE); - report_error (_("%s: invalid variable name for name reference"), temp); - temp = &expand_param_error; - } - else - temp = (char *)NULL; - } - else - temp = (char *)NULL; - - if (ret == 0) - { - ret = alloc_word_desc (); - ret->word = temp; - ret->flags |= rflags; - } - return ret; -} - -static char * -parameter_brace_find_indir (name, var_is_special, quoted, find_nameref) - char *name; - int var_is_special, quoted, find_nameref; -{ - char *temp, *t; - WORD_DESC *w; - SHELL_VAR *v; - int pflags, oldex; - - if (find_nameref && var_is_special == 0 && (v = find_variable_last_nameref (name, 0)) && - nameref_p (v) && (t = nameref_cell (v)) && *t) - return (savestring (t)); - - /* If var_is_special == 0, and name is not an array reference, this does - more expansion than necessary. It should really look up the variable's - value and not try to expand it. */ - pflags = PF_IGNUNBOUND; - /* Note that we're not going to be doing word splitting here */ - if (var_is_special) - { - pflags |= PF_ASSIGNRHS; /* suppresses word splitting */ - oldex = expand_no_split_dollar_star; - expand_no_split_dollar_star = 1; - } - w = parameter_brace_expand_word (name, var_is_special, quoted, pflags, 0); - if (var_is_special) - expand_no_split_dollar_star = oldex; - - t = w->word; - /* Have to dequote here if necessary */ - if (t) - { - temp = ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || var_is_special) - ? dequote_string (t) - : dequote_escapes (t); - free (t); - t = temp; - } - dispose_word_desc (w); - - return t; -} - -/* Expand an indirect reference to a variable: ${!NAME} expands to the - value of the variable whose name is the value of NAME. */ -static WORD_DESC * -parameter_brace_expand_indir (name, var_is_special, quoted, pflags, quoted_dollar_atp, contains_dollar_at) - char *name; - int var_is_special, quoted, pflags; - int *quoted_dollar_atp, *contains_dollar_at; -{ - char *t; - WORD_DESC *w; - SHELL_VAR *v; - - /* See if it's a nameref first, behave in ksh93-compatible fashion. - There is at least one incompatibility: given ${!foo[0]} where foo=bar, - bash performs an indirect lookup on foo[0] and expands the result; - ksh93 expands bar[0]. We could do that here -- there are enough usable - primitives to do that -- but do not at this point. */ - if (var_is_special == 0 && (v = find_variable_last_nameref (name, 0))) - { - if (nameref_p (v) && (t = nameref_cell (v)) && *t) - { - w = alloc_word_desc (); - w->word = savestring (t); - w->flags = 0; - return w; - } - } - - /* An indirect reference to a positional parameter or a special parameter - is ok. Indirect references to array references, as explained above, are - ok (currently). Only references to unset variables are errors at this - point. */ - if (legal_identifier (name) && v == 0) - { - report_error (_("%s: invalid indirect expansion"), name); - w = alloc_word_desc (); - w->word = &expand_param_error; - w->flags = 0; - return (w); - } - - t = parameter_brace_find_indir (name, var_is_special, quoted, 0); - - chk_atstar (t, quoted, pflags, quoted_dollar_atp, contains_dollar_at); - -#if defined (ARRAY_VARS) - /* Array references to unset variables are also an error */ - if (t == 0 && valid_array_reference (name, 0)) - { - v = array_variable_part (name, 0, (char **)0, (int *)0); - if (v == 0) - { - report_error (_("%s: invalid indirect expansion"), name); - w = alloc_word_desc (); - w->word = &expand_param_error; - w->flags = 0; - return (w); - } - else - return (WORD_DESC *)NULL; - } -#endif - - if (t == 0) - return (WORD_DESC *)NULL; - - if (valid_brace_expansion_word (t, SPECIAL_VAR (t, 0)) == 0) - { - report_error (_("%s: invalid variable name"), t); - free (t); - w = alloc_word_desc (); - w->word = &expand_param_error; - w->flags = 0; - return (w); - } - - w = parameter_brace_expand_word (t, SPECIAL_VAR(t, 0), quoted, pflags, 0); - free (t); - - return w; -} - -/* Expand the right side of a parameter expansion of the form ${NAMEcVALUE}, - depending on the value of C, the separating character. C can be one of - "-", "+", or "=". QUOTED is true if the entire brace expression occurs - between double quotes. */ -static WORD_DESC * -parameter_brace_expand_rhs (name, value, op, quoted, pflags, qdollaratp, hasdollarat) - char *name, *value; - int op, quoted, pflags, *qdollaratp, *hasdollarat; -{ - WORD_DESC *w; - WORD_LIST *l, *tl; - char *t, *t1, *temp, *vname, *newval; - int l_hasdollat, sindex, arrayref; - SHELL_VAR *v; - array_eltstate_t es; - -/*itrace("parameter_brace_expand_rhs: %s:%s pflags = %d", name, value, pflags);*/ - /* If the entire expression is between double quotes, we want to treat - the value as a double-quoted string, with the exception that we strip - embedded unescaped double quotes (for sh backwards compatibility). */ - if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *value) - { - sindex = 0; - temp = string_extract_double_quoted (value, &sindex, SX_STRIPDQ); - } - else - temp = value; - - w = alloc_word_desc (); - l_hasdollat = 0; - l = *temp ? expand_string_for_rhs (temp, quoted, op, pflags, &l_hasdollat, (int *)NULL) - : (WORD_LIST *)0; - if (hasdollarat) - *hasdollarat = l_hasdollat || (l && l->next); - if (temp != value) - free (temp); - - /* list_string takes multiple CTLNULs and turns them into an empty word - with W_SAWQUOTEDNULL set. Turn it back into a single CTLNUL for the - rest of this function and the caller. */ - for (tl = l; tl; tl = tl->next) - { - if (tl->word && (tl->word->word == 0 || tl->word->word[0] == 0) && - (tl->word->flags | W_SAWQUOTEDNULL)) - { - t = make_quoted_char ('\0'); - FREE (tl->word->word); - tl->word->word = t; - tl->word->flags |= W_QUOTED|W_HASQUOTEDNULL; - tl->word->flags &= ~W_SAWQUOTEDNULL; - } - } - - if (l) - { - /* If l->next is not null, we know that TEMP contained "$@", since that - is the only expansion that creates more than one word. */ - if (qdollaratp && ((l_hasdollat && quoted) || l->next)) - { -/*itrace("parameter_brace_expand_rhs: %s:%s: l != NULL, set *qdollaratp", name, value);*/ - *qdollaratp = 1; - } - - /* The expansion of TEMP returned something. We need to treat things - slightly differently if L_HASDOLLAT is non-zero. If we have "$@", - the individual words have already been quoted. We need to turn them - into a string with the words separated by the first character of - $IFS without any additional quoting, so string_list_dollar_at won't - do the right thing. If IFS is null, we want "$@" to split into - separate arguments, not be concatenated, so we use string_list_internal - and mark the word to be split on spaces later. We use - string_list_dollar_star for "$@" otherwise. */ - if (l->next && ifs_is_null) - { - temp = string_list_internal (l, " "); - w->flags |= W_SPLITSPACE; - } - else if (l_hasdollat || l->next) - temp = string_list_dollar_star (l, quoted, 0); - else - { - temp = string_list (l); - if (temp && (QUOTED_NULL (temp) == 0) && (l->word->flags & W_SAWQUOTEDNULL)) - w->flags |= W_SAWQUOTEDNULL; /* XXX */ - } - - /* If we have a quoted null result (QUOTED_NULL(temp)) and the word is - a quoted null (l->next == 0 && QUOTED_NULL(l->word->word)), the - flags indicate it (l->word->flags & W_HASQUOTEDNULL), and the - expansion is quoted (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) - (which is more paranoia than anything else), we need to return the - quoted null string and set the flags to indicate it. */ - if (l->next == 0 && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && QUOTED_NULL (temp) && QUOTED_NULL (l->word->word) && (l->word->flags & W_HASQUOTEDNULL)) - { - w->flags |= W_HASQUOTEDNULL; -/*itrace("parameter_brace_expand_rhs (%s:%s): returning quoted null, turning off qdollaratp", name, value);*/ - /* If we return a quoted null with L_HASDOLLARAT, we either have a - construct like "${@-$@}" or "${@-${@-$@}}" with no positional - parameters or a quoted expansion of "$@" with $1 == ''. In either - case, we don't want to enable special handling of $@. */ - if (qdollaratp && l_hasdollat) - *qdollaratp = 0; - } - dispose_words (l); - } - else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && l_hasdollat) - { - /* Posix interp 221 changed the rules on this. The idea is that - something like "$xxx$@" should expand the same as "${foo-$xxx$@}" - when foo and xxx are unset. The problem is that it's not in any - way backwards compatible and few other shells do it. We're eventually - going to try and split the difference (heh) a little bit here. */ - /* l_hasdollat == 1 means we saw a quoted dollar at. */ - - /* The brace expansion occurred between double quotes and there was - a $@ in TEMP. It does not matter if the $@ is quoted, as long as - it does not expand to anything. In this case, we want to return - a quoted empty string. Posix interp 888 */ - temp = make_quoted_char ('\0'); - w->flags |= W_HASQUOTEDNULL; -/*itrace("parameter_brace_expand_rhs (%s:%s): returning quoted null", name, value);*/ - } - else - temp = (char *)NULL; - - if (op == '-' || op == '+') - { - w->word = temp; - return w; - } - - /* op == '=' */ - t1 = temp ? dequote_string (temp) : savestring (""); - free (temp); - - /* bash-4.4/5.0 */ - vname = name; - if (*name == '!' && - (legal_variable_starter ((unsigned char)name[1]) || DIGIT (name[1]) || VALID_INDIR_PARAM (name[1]))) - { - vname = parameter_brace_find_indir (name + 1, SPECIAL_VAR (name, 1), quoted, 1); - if (vname == 0 || *vname == 0) - { - report_error (_("%s: invalid indirect expansion"), name); - free (vname); - free (t1); - dispose_word (w); - return &expand_wdesc_error; - } - if (legal_identifier (vname) == 0) - { - report_error (_("%s: invalid variable name"), vname); - free (vname); - free (t1); - dispose_word (w); - return &expand_wdesc_error; - } - } - - arrayref = 0; -#if defined (ARRAY_VARS) - if (valid_array_reference (vname, 0)) - { - init_eltstate (&es); - v = assign_array_element (vname, t1, ASS_ALLOWALLSUB, &es); - arrayref = 1; - newval = es.value; - } - else -#endif /* ARRAY_VARS */ - v = bind_variable (vname, t1, 0); - - if (v == 0 || readonly_p (v) || noassign_p (v)) /* expansion error */ - { - if ((v == 0 || readonly_p (v)) && interactive_shell == 0 && posixly_correct) - { - last_command_exit_value = EXECUTION_FAILURE; - exp_jump_to_top_level (FORCE_EOF); - } - else - { - if (vname != name) - free (vname); - last_command_exit_value = EX_BADUSAGE; - exp_jump_to_top_level (DISCARD); - } - } - - stupidly_hack_special_variables (vname); - - /* "In all cases, the final value of parameter shall be substituted." */ - if (shell_compatibility_level > 51) - { - FREE (t1); -#if defined (ARRAY_VARS) - if (arrayref) - { - t1 = newval; - flush_eltstate (&es); - } - else - t1 = get_variable_value (v); -#else - t1 = value_cell (v); -#endif - } - - if (vname != name) - free (vname); - - /* From Posix group discussion Feb-March 2010. Issue 7 0000221 */ - - /* If we are double-quoted or if we are not going to be performing word - splitting, we want to quote the value we return appropriately, like - the other expansions this function handles. */ - w->word = (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) ? quote_string (t1) : quote_escapes (t1); - /* If we have something that's non-null, but not a quoted null string, - and we're not going to be performing word splitting (we know we're not - because the operator is `='), we can forget we saw a quoted null. */ - if (w->word && w->word[0] && QUOTED_NULL (w->word) == 0) - w->flags &= ~W_SAWQUOTEDNULL; - - /* If we convert a null string into a quoted null, make sure the caller - knows it. */ - if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) && QUOTED_NULL (w->word)) - w->flags |= W_HASQUOTEDNULL; - - return w; -} - -/* Deal with the right hand side of a ${name:?value} expansion in the case - that NAME is null or not set. If VALUE is non-null it is expanded and - used as the error message to print, otherwise a standard message is - printed. */ -static void -parameter_brace_expand_error (name, value, check_null) - char *name, *value; - int check_null; -{ - WORD_LIST *l; - char *temp; - - set_exit_status (EXECUTION_FAILURE); /* ensure it's non-zero */ - if (value && *value) - { - l = expand_string (value, 0); - temp = string_list (l); - report_error ("%s: %s", name, temp ? temp : ""); /* XXX was value not "" */ - FREE (temp); - dispose_words (l); - } - else if (check_null == 0) - report_error (_("%s: parameter not set"), name); - else - report_error (_("%s: parameter null or not set"), name); - - /* Free the data we have allocated during this expansion, since we - are about to longjmp out. */ - free (name); - FREE (value); -} - -/* Return 1 if NAME is something for which parameter_brace_expand_length is - OK to do. */ -static int -valid_length_expression (name) - char *name; -{ - return (name[1] == '\0' || /* ${#} */ - ((sh_syntaxtab[(unsigned char) name[1]] & CSPECVAR) && name[2] == '\0') || /* special param */ - (DIGIT (name[1]) && all_digits (name + 1)) || /* ${#11} */ -#if defined (ARRAY_VARS) - valid_array_reference (name + 1, 0) || /* ${#a[7]} */ -#endif - legal_identifier (name + 1)); /* ${#PS1} */ -} - -/* Handle the parameter brace expansion that requires us to return the - length of a parameter. */ -static intmax_t -parameter_brace_expand_length (name) - char *name; -{ - char *t, *newname; - intmax_t number, arg_index; - WORD_LIST *list; - SHELL_VAR *var; - - var = (SHELL_VAR *)NULL; - - if (name[1] == '\0') /* ${#} */ - number = number_of_args (); - else if (DOLLAR_AT_STAR (name[1]) && name[2] == '\0') /* ${#@}, ${#*} */ - number = number_of_args (); - else if ((sh_syntaxtab[(unsigned char) name[1]] & CSPECVAR) && name[2] == '\0') - { - /* Take the lengths of some of the shell's special parameters. */ - switch (name[1]) - { - case '-': - t = which_set_flags (); - break; - case '?': - t = itos (last_command_exit_value); - break; - case '$': - t = itos (dollar_dollar_pid); - break; - case '!': - if (last_asynchronous_pid == NO_PID) - t = (char *)NULL; /* XXX - error if set -u set? */ - else - t = itos (last_asynchronous_pid); - break; - case '#': - t = itos (number_of_args ()); - break; - } - number = STRLEN (t); - FREE (t); - } -#if defined (ARRAY_VARS) - else if (valid_array_reference (name + 1, 0)) - number = array_length_reference (name + 1); -#endif /* ARRAY_VARS */ - else - { - number = 0; - - if (legal_number (name + 1, &arg_index)) /* ${#1} */ - { - t = get_dollar_var_value (arg_index); - if (t == 0 && unbound_vars_is_error) - return INTMAX_MIN; - number = MB_STRLEN (t); - FREE (t); - } -#if defined (ARRAY_VARS) - else if ((var = find_variable (name + 1)) && (invisible_p (var) == 0) && (array_p (var) || assoc_p (var))) - { - if (assoc_p (var)) - t = assoc_reference (assoc_cell (var), "0"); - else - t = array_reference (array_cell (var), 0); - if (t == 0 && unbound_vars_is_error) - return INTMAX_MIN; - number = MB_STRLEN (t); - } -#endif - /* Fast path for the common case of taking the length of a non-dynamic - scalar variable value. */ - else if ((var || (var = find_variable (name + 1))) && - invisible_p (var) == 0 && - array_p (var) == 0 && assoc_p (var) == 0 && - var->dynamic_value == 0) - number = value_cell (var) ? MB_STRLEN (value_cell (var)) : 0; - else if (var == 0 && unbound_vars_is_error == 0) - number = 0; - else /* ${#PS1} */ - { - newname = savestring (name); - newname[0] = '$'; - list = expand_string (newname, Q_DOUBLE_QUOTES); - t = list ? string_list (list) : (char *)NULL; - free (newname); - if (list) - dispose_words (list); - - number = t ? MB_STRLEN (t) : 0; - FREE (t); - } - } - - return (number); -} - -/* Skip characters in SUBSTR until DELIM. SUBSTR is an arithmetic expression, - so we do some ad-hoc parsing of an arithmetic expression to find - the first DELIM, instead of using strchr(3). Two rules: - 1. If the substring contains a `(', read until closing `)'. - 2. If the substring contains a `?', read past one `:' for each `?'. - The SD_ARITHEXP flag to skip_to_delim takes care of doing this. -*/ - -static char * -skiparith (substr, delim) - char *substr; - int delim; -{ - int i; - char delims[2]; - - delims[0] = delim; - delims[1] = '\0'; - - i = skip_to_delim (substr, 0, delims, SD_ARITHEXP); - return (substr + i); -} - -/* Verify and limit the start and end of the desired substring. If - VTYPE == 0, a regular shell variable is being used; if it is 1, - then the positional parameters are being used; if it is 2, then - VALUE is really a pointer to an array variable that should be used. - Return value is 1 if both values were OK, 0 if there was a problem - with an invalid expression, or -1 if the values were out of range. */ -static int -verify_substring_values (v, value, substr, vtype, e1p, e2p) - SHELL_VAR *v; - char *value, *substr; - int vtype; - intmax_t *e1p, *e2p; -{ - char *t, *temp1, *temp2; - arrayind_t len; - int expok, eflag; -#if defined (ARRAY_VARS) - ARRAY *a; - HASH_TABLE *h; -#endif - - /* duplicate behavior of strchr(3) */ - t = skiparith (substr, ':'); - if (*t && *t == ':') - *t = '\0'; - else - t = (char *)0; - - temp1 = expand_arith_string (substr, Q_DOUBLE_QUOTES|Q_ARITH); - eflag = (shell_compatibility_level > 51) ? 0 : EXP_EXPANDED; - - *e1p = evalexp (temp1, eflag, &expok); - free (temp1); - if (expok == 0) - return (0); - - len = -1; /* paranoia */ - switch (vtype) - { - case VT_VARIABLE: - case VT_ARRAYMEMBER: - len = MB_STRLEN (value); - break; - case VT_POSPARMS: - len = number_of_args () + 1; - if (*e1p == 0) - len++; /* add one arg if counting from $0 */ - break; -#if defined (ARRAY_VARS) - case VT_ARRAYVAR: - /* For arrays, the first value deals with array indices. Negative - offsets count from one past the array's maximum index. Associative - arrays treat the number of elements as the maximum index. */ - if (assoc_p (v)) - { - h = assoc_cell (v); - len = assoc_num_elements (h) + (*e1p < 0); - } - else - { - a = (ARRAY *)value; - len = array_max_index (a) + (*e1p < 0); /* arrays index from 0 to n - 1 */ - } - break; -#endif - } - - if (len == -1) /* paranoia */ - return -1; - - if (*e1p < 0) /* negative offsets count from end */ - *e1p += len; - - if (*e1p > len || *e1p < 0) - return (-1); - -#if defined (ARRAY_VARS) - /* For arrays, the second offset deals with the number of elements. */ - if (vtype == VT_ARRAYVAR) - len = assoc_p (v) ? assoc_num_elements (h) : array_num_elements (a); -#endif - - if (t) - { - t++; - temp2 = savestring (t); - temp1 = expand_arith_string (temp2, Q_DOUBLE_QUOTES|Q_ARITH); - free (temp2); - t[-1] = ':'; - *e2p = evalexp (temp1, eflag, &expok); - free (temp1); - if (expok == 0) - return (0); - - /* Should we allow positional parameter length < 0 to count backwards - from end of positional parameters? */ -#if 1 - if ((vtype == VT_ARRAYVAR || vtype == VT_POSPARMS) && *e2p < 0) -#else /* XXX - postponed; this isn't really a valuable feature */ - if (vtype == VT_ARRAYVAR && *e2p < 0) -#endif - { - internal_error (_("%s: substring expression < 0"), t); - return (0); - } -#if defined (ARRAY_VARS) - /* In order to deal with sparse arrays, push the intelligence about how - to deal with the number of elements desired down to the array- - specific functions. */ - if (vtype != VT_ARRAYVAR) -#endif - { - if (*e2p < 0) - { - *e2p += len; - if (*e2p < 0 || *e2p < *e1p) - { - internal_error (_("%s: substring expression < 0"), t); - return (0); - } - } - else - *e2p += *e1p; /* want E2 chars starting at E1 */ - if (*e2p > len) - *e2p = len; - } - } - else - *e2p = len; - - return (1); -} - -/* Return the type of variable specified by VARNAME (simple variable, - positional param, or array variable). Also return the value specified - by VARNAME (value of a variable or a reference to an array element). - QUOTED is the standard description of quoting state, using Q_* defines. - FLAGS is currently a set of flags to pass to array_value. If IND is - not INTMAX_MIN, and FLAGS includes AV_USEIND, IND is - passed to array_value so the array index is not computed again. - If this returns VT_VARIABLE, the caller assumes that CTLESC and CTLNUL - characters in the value are quoted with CTLESC and takes appropriate - steps. For convenience, *VALP is set to the dequoted VALUE. */ -static int -get_var_and_type (varname, value, estatep, quoted, flags, varp, valp) - char *varname, *value; - array_eltstate_t *estatep; - int quoted, flags; - SHELL_VAR **varp; - char **valp; -{ - int vtype, want_indir; - char *temp, *vname; - SHELL_VAR *v; - - want_indir = *varname == '!' && - (legal_variable_starter ((unsigned char)varname[1]) || DIGIT (varname[1]) - || VALID_INDIR_PARAM (varname[1])); - if (want_indir) - vname = parameter_brace_find_indir (varname+1, SPECIAL_VAR (varname, 1), quoted, 1); - /* XXX - what if vname == 0 || *vname == 0 ? */ - else - vname = varname; - - if (vname == 0) - { - vtype = VT_VARIABLE; - *varp = (SHELL_VAR *)NULL; - *valp = (char *)NULL; - return (vtype); - } - - /* This sets vtype to VT_VARIABLE or VT_POSPARMS */ - vtype = STR_DOLLAR_AT_STAR (vname); - if (vtype == VT_POSPARMS && vname[0] == '*') - vtype |= VT_STARSUB; - *varp = (SHELL_VAR *)NULL; - -#if defined (ARRAY_VARS) - if (valid_array_reference (vname, 0)) - { - v = array_variable_part (vname, 0, &temp, (int *)0); - /* If we want to signal array_value to use an already-computed index, - the caller will set ESTATEP->IND to that index and pass AV_USEIND in - FLAGS. */ - if (estatep && (flags & AV_USEIND) == 0) - estatep->ind = INTMAX_MIN; - - if (v && invisible_p (v)) - { - vtype = VT_ARRAYMEMBER; - *varp = (SHELL_VAR *)NULL; - *valp = (char *)NULL; - } - if (v && (array_p (v) || assoc_p (v))) - { - if (ALL_ELEMENT_SUB (temp[0]) && temp[1] == RBRACK) - { - /* Callers have to differentiate between indexed and associative */ - vtype = VT_ARRAYVAR; - if (temp[0] == '*') - vtype |= VT_STARSUB; - *valp = array_p (v) ? (char *)array_cell (v) : (char *)assoc_cell (v); - } - else - { - vtype = VT_ARRAYMEMBER; - *valp = array_value (vname, Q_DOUBLE_QUOTES, flags, estatep); - } - *varp = v; - } - else if (v && (ALL_ELEMENT_SUB (temp[0]) && temp[1] == RBRACK)) - { - vtype = VT_VARIABLE; - *varp = v; - if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) - *valp = value ? dequote_string (value) : (char *)NULL; - else - *valp = value ? dequote_escapes (value) : (char *)NULL; - } - else - { - vtype = VT_ARRAYMEMBER; - *varp = v; - *valp = array_value (vname, Q_DOUBLE_QUOTES, flags, estatep); - } - } - else if ((v = find_variable (vname)) && (invisible_p (v) == 0) && (assoc_p (v) || array_p (v))) - { - vtype = VT_ARRAYMEMBER; - *varp = v; - *valp = assoc_p (v) ? assoc_reference (assoc_cell (v), "0") : array_reference (array_cell (v), 0); - } - else -#endif - { - if (value && vtype == VT_VARIABLE) - { - *varp = find_variable (vname); - if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) - *valp = dequote_string (value); - else - *valp = dequote_escapes (value); - } - else - *valp = value; - } - - if (want_indir) - free (vname); - - return vtype; -} - -/***********************************************************/ -/* */ -/* Functions to perform transformations on variable values */ -/* */ -/***********************************************************/ - -static char * -string_var_assignment (v, s) - SHELL_VAR *v; - char *s; -{ - char flags[MAX_ATTRIBUTES], *ret, *val; - int i; - - val = (v && (invisible_p (v) || var_isset (v) == 0)) ? (char *)NULL : sh_quote_reusable (s, 0); - i = var_attribute_string (v, 0, flags); - if (i == 0 && val == 0) - return (char *)NULL; - - ret = (char *)xmalloc (i + STRLEN (val) + strlen (v->name) + 16 + MAX_ATTRIBUTES); - if (i > 0 && val == 0) - sprintf (ret, "declare -%s %s", flags, v->name); - else if (i > 0) - sprintf (ret, "declare -%s %s=%s", flags, v->name, val); - else - sprintf (ret, "%s=%s", v->name, val); - free (val); - return ret; -} - -#if defined (ARRAY_VARS) -static char * -array_var_assignment (v, itype, quoted, atype) - SHELL_VAR *v; - int itype, quoted, atype; -{ - char *ret, *val, flags[MAX_ATTRIBUTES]; - int i; - - if (v == 0) - return (char *)NULL; - if (atype == 2) - val = array_p (v) ? array_to_kvpair (array_cell (v), 0) - : assoc_to_kvpair (assoc_cell (v), 0); - else - val = array_p (v) ? array_to_assign (array_cell (v), 0) - : assoc_to_assign (assoc_cell (v), 0); - - if (val == 0 && (invisible_p (v) || var_isset (v) == 0)) - ; /* placeholder */ - else if (val == 0) - { - val = (char *)xmalloc (3); - val[0] = LPAREN; - val[1] = RPAREN; - val[2] = 0; - } - else - { - ret = (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) ? quote_string (val) : quote_escapes (val); - free (val); - val = ret; - } - - if (atype == 2) - return val; - - i = var_attribute_string (v, 0, flags); - ret = (char *)xmalloc (i + STRLEN (val) + strlen (v->name) + 16); - if (val) - sprintf (ret, "declare -%s %s=%s", flags, v->name, val); - else - sprintf (ret, "declare -%s %s", flags, v->name); - free (val); - return ret; -} -#endif - -static char * -pos_params_assignment (list, itype, quoted) - WORD_LIST *list; - int itype; - int quoted; -{ - char *temp, *ret; - - /* first, we transform the list to quote each word. */ - temp = list_transform ('Q', (SHELL_VAR *)0, list, itype, quoted); - ret = (char *)xmalloc (strlen (temp) + 8); - strcpy (ret, "set -- "); - strcpy (ret + 7, temp); - free (temp); - return ret; -} - -static char * -string_transform (xc, v, s) - int xc; - SHELL_VAR *v; - char *s; -{ - char *ret, flags[MAX_ATTRIBUTES], *t; - int i; - - if (((xc == 'A' || xc == 'a') && v == 0)) - return (char *)NULL; - else if (xc != 'a' && xc != 'A' && s == 0) - return (char *)NULL; - - switch (xc) - { - /* Transformations that interrogate the variable */ - case 'a': - i = var_attribute_string (v, 0, flags); - ret = (i > 0) ? savestring (flags) : (char *)NULL; - break; - case 'A': - ret = string_var_assignment (v, s); - break; - case 'K': - case 'k': - ret = sh_quote_reusable (s, 0); - break; - /* Transformations that modify the variable's value */ - case 'E': - t = ansiexpand (s, 0, strlen (s), (int *)0); - ret = dequote_escapes (t); - free (t); - break; - case 'P': - ret = decode_prompt_string (s); - break; - case 'Q': - ret = sh_quote_reusable (s, 0); - break; - case 'U': - ret = sh_modcase (s, 0, CASE_UPPER); - break; - case 'u': - ret = sh_modcase (s, 0, CASE_UPFIRST); /* capitalize */ - break; - case 'L': - ret = sh_modcase (s, 0, CASE_LOWER); - break; - default: - ret = (char *)NULL; - break; - } - return ret; -} - -static char * -list_transform (xc, v, list, itype, quoted) - int xc; - SHELL_VAR *v; - WORD_LIST *list; - int itype, quoted; -{ - WORD_LIST *new, *l; - WORD_DESC *w; - char *tword; - int qflags; - - for (new = (WORD_LIST *)NULL, l = list; l; l = l->next) - { - tword = string_transform (xc, v, l->word->word); - w = alloc_word_desc (); - w->word = tword ? tword : savestring (""); /* XXX */ - new = make_word_list (w, new); - } - l = REVERSE_LIST (new, WORD_LIST *); - - qflags = quoted; - /* If we are expanding in a context where word splitting will not be - performed, treat as quoted. This changes how $* will be expanded. */ - if (itype == '*' && expand_no_split_dollar_star && ifs_is_null) - qflags |= Q_DOUBLE_QUOTES; /* Posix interp 888 */ - - tword = string_list_pos_params (itype, l, qflags, 0); - dispose_words (l); - - return (tword); -} - -static char * -parameter_list_transform (xc, itype, quoted) - int xc; - int itype; - int quoted; -{ - char *ret; - WORD_LIST *list; - - list = list_rest_of_args (); - if (list == 0) - return ((char *)NULL); - if (xc == 'A') - ret = pos_params_assignment (list, itype, quoted); - else - ret = list_transform (xc, (SHELL_VAR *)0, list, itype, quoted); - dispose_words (list); - return (ret); -} - -#if defined (ARRAY_VARS) -static char * -array_transform (xc, var, starsub, quoted) - int xc; - SHELL_VAR *var; - int starsub; /* so we can figure out how it's indexed */ - int quoted; -{ - ARRAY *a; - HASH_TABLE *h; - int itype, qflags; - char *ret; - WORD_LIST *list; - SHELL_VAR *v; - - v = var; /* XXX - for now */ - - itype = starsub ? '*' : '@'; - - if (xc == 'A') - return (array_var_assignment (v, itype, quoted, 1)); - else if (xc == 'K') - return (array_var_assignment (v, itype, quoted, 2)); - - /* special case for unset arrays and attributes */ - if (xc == 'a' && (invisible_p (v) || var_isset (v) == 0)) - { - char flags[MAX_ATTRIBUTES]; - int i; - - i = var_attribute_string (v, 0, flags); - return ((i > 0) ? savestring (flags) : (char *)NULL); - } - - a = (v && array_p (v)) ? array_cell (v) : 0; - h = (v && assoc_p (v)) ? assoc_cell (v) : 0; - - /* XXX - for now */ - if (xc == 'k') - { - if (v == 0) - return ((char *)NULL); - list = array_p (v) ? array_to_kvpair_list (a) : assoc_to_kvpair_list (h); - qflags = quoted; - /* If we are expanding in a context where word splitting will not be - performed, treat as quoted. This changes how $* will be expanded. */ - if (itype == '*' && expand_no_split_dollar_star && ifs_is_null) - qflags |= Q_DOUBLE_QUOTES; /* Posix interp 888 */ - - ret = string_list_pos_params (itype, list, qflags, 0); - dispose_words (list); - return ret; - } - - list = a ? array_to_word_list (a) : (h ? assoc_to_word_list (h) : 0); - if (list == 0) - return ((char *)NULL); - ret = list_transform (xc, v, list, itype, quoted); - dispose_words (list); - - return ret; -} -#endif /* ARRAY_VARS */ - -static int -valid_parameter_transform (xform) - char *xform; -{ - if (xform[1]) - return 0; - - /* check for valid values of xform[0] */ - switch (xform[0]) - { - case 'a': /* expand to a string with just attributes */ - case 'A': /* expand as an assignment statement with attributes */ - case 'K': /* expand assoc array to list of key/value pairs */ - case 'k': /* XXX - for now */ - case 'E': /* expand like $'...' */ - case 'P': /* expand like prompt string */ - case 'Q': /* quote reusably */ - case 'U': /* transform to uppercase */ - case 'u': /* transform by capitalizing */ - case 'L': /* transform to lowercase */ - return 1; - default: - return 0; - } -} - -static char * -parameter_brace_transform (varname, value, estatep, xform, rtype, quoted, pflags, flags) - char *varname, *value; - array_eltstate_t *estatep; - char *xform; - int rtype, quoted, pflags, flags; -{ - int vtype, xc, starsub; - char *temp1, *val, *oname; - SHELL_VAR *v; - - xc = xform[0]; - if (value == 0 && xc != 'A' && xc != 'a') - return ((char *)NULL); - - oname = this_command_name; - this_command_name = varname; - - vtype = get_var_and_type (varname, value, estatep, quoted, flags, &v, &val); - if (vtype == -1) - { - this_command_name = oname; - return ((char *)NULL); - } - - if (xform[0] == 0 || valid_parameter_transform (xform) == 0) - { - this_command_name = oname; - if (vtype == VT_VARIABLE) - FREE (val); - return (interactive_shell ? &expand_param_error : &expand_param_fatal); - } - - starsub = vtype & VT_STARSUB; - vtype &= ~VT_STARSUB; - - /* If we are asked to display the attributes of an unset variable, V will - be NULL after the call to get_var_and_type. Double-check here. */ - if ((xc == 'a' || xc == 'A') && vtype == VT_VARIABLE && varname && v == 0) - v = find_variable (varname); - - temp1 = (char *)NULL; /* shut up gcc */ - switch (vtype) - { - case VT_VARIABLE: - case VT_ARRAYMEMBER: - temp1 = string_transform (xc, v, val); - if (vtype == VT_VARIABLE) - FREE (val); - if (temp1) - { - val = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) - ? quote_string (temp1) - : quote_escapes (temp1); - free (temp1); - temp1 = val; - } - break; -#if defined (ARRAY_VARS) - case VT_ARRAYVAR: - temp1 = array_transform (xc, v, starsub, quoted); - if (temp1 && quoted == 0 && ifs_is_null) - { - /* Posix interp 888 */ - } - else if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0)) - { - val = quote_escapes (temp1); - free (temp1); - temp1 = val; - } - break; -#endif - case VT_POSPARMS: - temp1 = parameter_list_transform (xc, varname[0], quoted); - if (temp1 && quoted == 0 && ifs_is_null) - { - /* Posix interp 888 */ - } - else if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0)) - { - val = quote_escapes (temp1); - free (temp1); - temp1 = val; - } - break; - } - - this_command_name = oname; - return temp1; -} - -/******************************************************/ -/* */ -/* Functions to extract substrings of variable values */ -/* */ -/******************************************************/ - -#if defined (HANDLE_MULTIBYTE) -/* Character-oriented rather than strictly byte-oriented substrings. S and - E, rather being strict indices into STRING, indicate character (possibly - multibyte character) positions that require calculation. - Used by the ${param:offset[:length]} expansion. */ -static char * -mb_substring (string, s, e) - char *string; - int s, e; -{ - char *tt; - int start, stop, i; - size_t slen; - DECLARE_MBSTATE; - - start = 0; - /* Don't need string length in ADVANCE_CHAR unless multibyte chars possible. */ - slen = (MB_CUR_MAX > 1) ? STRLEN (string) : 0; - - i = s; - while (string[start] && i--) - ADVANCE_CHAR (string, slen, start); - stop = start; - i = e - s; - while (string[stop] && i--) - ADVANCE_CHAR (string, slen, stop); - tt = substring (string, start, stop); - return tt; -} -#endif - -/* Process a variable substring expansion: ${name:e1[:e2]}. If VARNAME - is `@', use the positional parameters; otherwise, use the value of - VARNAME. If VARNAME is an array variable, use the array elements. */ - -static char * -parameter_brace_substring (varname, value, estatep, substr, quoted, pflags, flags) - char *varname, *value; - array_eltstate_t *estatep; - char *substr; - int quoted, pflags, flags; -{ - intmax_t e1, e2; - int vtype, r, starsub; - char *temp, *val, *tt, *oname; - SHELL_VAR *v; - - if (value == 0 && ((varname[0] != '@' && varname[0] != '*') || varname[1])) - return ((char *)NULL); - - oname = this_command_name; - this_command_name = varname; - - vtype = get_var_and_type (varname, value, estatep, quoted, flags, &v, &val); - if (vtype == -1) - { - this_command_name = oname; - return ((char *)NULL); - } - - starsub = vtype & VT_STARSUB; - vtype &= ~VT_STARSUB; - - r = verify_substring_values (v, val, substr, vtype, &e1, &e2); - this_command_name = oname; - if (r <= 0) - { - if (vtype == VT_VARIABLE) - FREE (val); - return ((r == 0) ? &expand_param_error : (char *)NULL); - } - - switch (vtype) - { - case VT_VARIABLE: - case VT_ARRAYMEMBER: -#if defined (HANDLE_MULTIBYTE) - if (MB_CUR_MAX > 1) - tt = mb_substring (val, e1, e2); - else -#endif - tt = substring (val, e1, e2); - - if (vtype == VT_VARIABLE) - FREE (val); - if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) - temp = quote_string (tt); - else - temp = tt ? quote_escapes (tt) : (char *)NULL; - FREE (tt); - break; - case VT_POSPARMS: - case VT_ARRAYVAR: - if (vtype == VT_POSPARMS) - tt = pos_params (varname, e1, e2, quoted, pflags); -#if defined (ARRAY_VARS) - /* assoc_subrange and array_subrange both call string_list_pos_params, - so we can treat this case just like VT_POSPARAMS. */ - else if (assoc_p (v)) - /* we convert to list and take first e2 elements starting at e1th - element -- officially undefined for now */ - tt = assoc_subrange (assoc_cell (v), e1, e2, starsub, quoted, pflags); - else - /* We want E2 to be the number of elements desired (arrays can be - sparse, so verify_substring_values just returns the numbers - specified and we rely on array_subrange to understand how to - deal with them). */ - tt = array_subrange (array_cell (v), e1, e2, starsub, quoted, pflags); -#endif - /* We want to leave this alone in every case where pos_params/ - string_list_pos_params quotes the list members */ - if (tt && quoted == 0 && ifs_is_null) - { - temp = tt; /* Posix interp 888 */ - } - else if (tt && quoted == 0 && (pflags & PF_ASSIGNRHS)) - { - temp = tt; /* Posix interp 888 */ - } - else if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0) - { - temp = tt ? quote_escapes (tt) : (char *)NULL; - FREE (tt); - } - else - temp = tt; - break; - - default: - temp = (char *)NULL; - } - - return temp; -} - -/****************************************************************/ -/* */ -/* Functions to perform pattern substitution on variable values */ -/* */ -/****************************************************************/ - -static int -shouldexp_replacement (s) - char *s; -{ - size_t slen; - int sindex, c; - DECLARE_MBSTATE; - - sindex = 0; - slen = STRLEN (s); - while (c = s[sindex]) - { - if (c == '\\') - { - sindex++; - if (s[sindex] == 0) - return 0; - /* We want to remove this backslash because we treat it as special - in this context. THIS ASSUMES THE STRING IS PROCESSED BY - strcreplace() OR EQUIVALENT that handles removing backslashes - preceding the special character. */ - if (s[sindex] == '&') - return 1; - if (s[sindex] == '\\') - return 1; - } - else if (c == '&') - return 1; - ADVANCE_CHAR (s, slen, sindex); - } - return 0; -} - -char * -pat_subst (string, pat, rep, mflags) - char *string, *pat, *rep; - int mflags; -{ - char *ret, *s, *e, *str, *rstr, *mstr, *send; - int rptr, mtype, rxpand, mlen; - size_t rsize, l, replen, rslen; - DECLARE_MBSTATE; - - if (string == 0) - return (savestring ("")); - - mtype = mflags & MATCH_TYPEMASK; - rxpand = mflags & MATCH_EXPREP; - - /* Special cases: - * 1. A null pattern with mtype == MATCH_BEG means to prefix STRING - * with REP and return the result. - * 2. A null pattern with mtype == MATCH_END means to append REP to - * STRING and return the result. - * 3. A null STRING with a matching pattern means to append REP to - * STRING and return the result. - * - * These process `&' in the replacement string, like `sed' does when - * presented with a BRE of `^' or `$'. - */ - if ((pat == 0 || *pat == 0) && (mtype == MATCH_BEG || mtype == MATCH_END)) - { - rstr = (mflags & MATCH_EXPREP) ? strcreplace (rep, '&', "", 2) : rep; - rslen = STRLEN (rstr); - l = STRLEN (string); - ret = (char *)xmalloc (rslen + l + 2); - if (rslen == 0) - strcpy (ret, string); - else if (mtype == MATCH_BEG) - { - strcpy (ret, rstr); - strcpy (ret + rslen, string); - } - else - { - strcpy (ret, string); - strcpy (ret + l, rstr); - } - if (rstr != rep) - free (rstr); - return (ret); - } - else if (*string == 0 && (match_pattern (string, pat, mtype, &s, &e) != 0)) - return ((mflags & MATCH_EXPREP) ? strcreplace (rep, '&', "", 2) : savestring (rep)); - - ret = (char *)xmalloc (rsize = 64); - ret[0] = '\0'; - send = string + strlen (string); - - for (replen = STRLEN (rep), rptr = 0, str = string; *str;) - { - if (match_pattern (str, pat, mtype, &s, &e) == 0) - break; - l = s - str; - - if (rep && rxpand) - { - int x; - mlen = e - s; - mstr = xmalloc (mlen + 1); - for (x = 0; x < mlen; x++) - mstr[x] = s[x]; - mstr[mlen] = '\0'; - rstr = strcreplace (rep, '&', mstr, 2); - free (mstr); - rslen = strlen (rstr); - } - else - { - rstr = rep; - rslen = replen; - } - - RESIZE_MALLOCED_BUFFER (ret, rptr, (l + rslen), rsize, 64); - - /* OK, now copy the leading unmatched portion of the string (from - str to s) to ret starting at rptr (the current offset). Then copy - the replacement string at ret + rptr + (s - str). Increment - rptr (if necessary) and str and go on. */ - if (l) - { - strncpy (ret + rptr, str, l); - rptr += l; - } - if (replen) - { - strncpy (ret + rptr, rstr, rslen); - rptr += rslen; - } - str = e; /* e == end of match */ - - if (rstr != rep) - free (rstr); - - if (((mflags & MATCH_GLOBREP) == 0) || mtype != MATCH_ANY) - break; - - if (s == e) - { - /* On a zero-length match, make sure we copy one character, since - we increment one character to avoid infinite recursion. */ - char *p, *origp, *origs; - size_t clen; - - RESIZE_MALLOCED_BUFFER (ret, rptr, locale_mb_cur_max, rsize, 64); -#if defined (HANDLE_MULTIBYTE) - p = origp = ret + rptr; - origs = str; - COPY_CHAR_P (p, str, send); - rptr += p - origp; - e += str - origs; -#else - ret[rptr++] = *str++; - e++; /* avoid infinite recursion on zero-length match */ -#endif - } - } - - /* Now copy the unmatched portion of the input string */ - if (str && *str) - { - l = send - str + 1; - RESIZE_MALLOCED_BUFFER (ret, rptr, l, rsize, 64); - strcpy (ret + rptr, str); - } - else - ret[rptr] = '\0'; - - return ret; -} - -/* Do pattern match and replacement on the positional parameters. */ -static char * -pos_params_pat_subst (string, pat, rep, mflags) - char *string, *pat, *rep; - int mflags; -{ - WORD_LIST *save, *params; - WORD_DESC *w; - char *ret; - int pchar, qflags, pflags; - - save = params = list_rest_of_args (); - if (save == 0) - return ((char *)NULL); - - for ( ; params; params = params->next) - { - ret = pat_subst (params->word->word, pat, rep, mflags); - w = alloc_word_desc (); - w->word = ret ? ret : savestring (""); - dispose_word (params->word); - params->word = w; - } - - pchar = (mflags & MATCH_STARSUB) == MATCH_STARSUB ? '*' : '@'; - qflags = (mflags & MATCH_QUOTED) == MATCH_QUOTED ? Q_DOUBLE_QUOTES : 0; - pflags = (mflags & MATCH_ASSIGNRHS) == MATCH_ASSIGNRHS ? PF_ASSIGNRHS : 0; - - /* If we are expanding in a context where word splitting will not be - performed, treat as quoted. This changes how $* will be expanded. */ - if (pchar == '*' && (mflags & MATCH_ASSIGNRHS) && expand_no_split_dollar_star && ifs_is_null) - qflags |= Q_DOUBLE_QUOTES; /* Posix interp 888 */ - - ret = string_list_pos_params (pchar, save, qflags, pflags); - dispose_words (save); - - return (ret); -} - -/* Perform pattern substitution on VALUE, which is the expansion of - VARNAME. PATSUB is an expression supplying the pattern to match - and the string to substitute. QUOTED is a flags word containing - the type of quoting currently in effect. */ -static char * -parameter_brace_patsub (varname, value, estatep, patsub, quoted, pflags, flags) - char *varname, *value; - array_eltstate_t *estatep; - char *patsub; - int quoted, pflags, flags; -{ - int vtype, mflags, starsub, delim; - char *val, *temp, *pat, *rep, *p, *lpatsub, *tt, *oname; - SHELL_VAR *v; - - if (value == 0) - return ((char *)NULL); - - oname = this_command_name; - this_command_name = varname; /* error messages */ - - vtype = get_var_and_type (varname, value, estatep, quoted, flags, &v, &val); - if (vtype == -1) - { - this_command_name = oname; - return ((char *)NULL); - } - - starsub = vtype & VT_STARSUB; - vtype &= ~VT_STARSUB; - - mflags = 0; - /* PATSUB is never NULL when this is called. */ - if (*patsub == '/') - { - mflags |= MATCH_GLOBREP; - patsub++; - } - - /* Malloc this because expand_string_if_necessary or one of the expansion - functions in its call chain may free it on a substitution error. */ - lpatsub = savestring (patsub); - - if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) - mflags |= MATCH_QUOTED; - - if (starsub) - mflags |= MATCH_STARSUB; - - if (pflags & PF_ASSIGNRHS) - mflags |= MATCH_ASSIGNRHS; - - /* If the pattern starts with a `/', make sure we skip over it when looking - for the replacement delimiter. */ - delim = skip_to_delim (lpatsub, ((*patsub == '/') ? 1 : 0), "/", 0); - if (lpatsub[delim] == '/') - { - lpatsub[delim] = 0; - rep = lpatsub + delim + 1; - } - else - rep = (char *)NULL; - - if (rep && *rep == '\0') - rep = (char *)NULL; - - /* Perform the same expansions on the pattern as performed by the - pattern removal expansions. */ - pat = getpattern (lpatsub, quoted, 1); - - if (rep) - { - /* We want to perform quote removal on the expanded replacement even if - the entire expansion is double-quoted because the parser and string - extraction functions treated quotes in the replacement string as - special. THIS IS NOT BACKWARDS COMPATIBLE WITH BASH-4.2. */ - if (shell_compatibility_level > 42 && patsub_replacement == 0) - rep = expand_string_if_necessary (rep, quoted & ~(Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT), expand_string_unsplit); - else if (shell_compatibility_level > 42 && patsub_replacement) - rep = expand_string_for_patsub (rep, quoted & ~(Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)); - /* This is the bash-4.2 code. */ - else if ((mflags & MATCH_QUOTED) == 0) - rep = expand_string_if_necessary (rep, quoted, expand_string_unsplit); - else - rep = expand_string_to_string_internal (rep, quoted, expand_string_unsplit); - - /* Check whether or not to replace `&' in the replacement string after - expanding it, since we want to treat backslashes quoting the `&' - consistently. */ - if (patsub_replacement && rep && *rep && shouldexp_replacement (rep)) - mflags |= MATCH_EXPREP; - - } - - /* ksh93 doesn't allow the match specifier to be a part of the expanded - pattern. This is an extension. Make sure we don't anchor the pattern - at the beginning or end of the string if we're doing global replacement, - though. */ - p = pat; - if (mflags & MATCH_GLOBREP) - mflags |= MATCH_ANY; - else if (pat && pat[0] == '#') - { - mflags |= MATCH_BEG; - p++; - } - else if (pat && pat[0] == '%') - { - mflags |= MATCH_END; - p++; - } - else - mflags |= MATCH_ANY; - - /* OK, we now want to substitute REP for PAT in VAL. If - flags & MATCH_GLOBREP is non-zero, the substitution is done - everywhere, otherwise only the first occurrence of PAT is - replaced. The pattern matching code doesn't understand - CTLESC quoting CTLESC and CTLNUL so we use the dequoted variable - values passed in (VT_VARIABLE) so the pattern substitution - code works right. We need to requote special chars after - we're done for VT_VARIABLE and VT_ARRAYMEMBER, and for the - other cases if QUOTED == 0, since the posparams and arrays - indexed by * or @ do special things when QUOTED != 0. */ - - switch (vtype) - { - case VT_VARIABLE: - case VT_ARRAYMEMBER: - temp = pat_subst (val, p, rep, mflags); - if (vtype == VT_VARIABLE) - FREE (val); - if (temp) - { - tt = (mflags & MATCH_QUOTED) ? quote_string (temp) : quote_escapes (temp); - free (temp); - temp = tt; - } - break; - case VT_POSPARMS: - /* This does the right thing for the case where we are not performing - word splitting. MATCH_STARSUB restricts it to ${* /foo/bar}, and - pos_params_pat_subst/string_list_pos_params will do the right thing - in turn for the case where ifs_is_null. Posix interp 888 */ - if ((pflags & PF_NOSPLIT2) && (mflags & MATCH_STARSUB)) - mflags |= MATCH_ASSIGNRHS; - temp = pos_params_pat_subst (val, p, rep, mflags); - if (temp && quoted == 0 && ifs_is_null) - { - /* Posix interp 888 */ - } - else if (temp && quoted == 0 && (pflags & PF_ASSIGNRHS)) - { - /* Posix interp 888 */ - } - else if (temp && (mflags & MATCH_QUOTED) == 0) - { - tt = quote_escapes (temp); - free (temp); - temp = tt; - } - break; -#if defined (ARRAY_VARS) - case VT_ARRAYVAR: - /* If we are expanding in a context where word splitting will not be - performed, treat as quoted. This changes how ${A[*]} will be - expanded to make it identical to $*. */ - if ((mflags & MATCH_STARSUB) && (mflags & MATCH_ASSIGNRHS) && ifs_is_null) - mflags |= MATCH_QUOTED; /* Posix interp 888 */ - - /* these eventually call string_list_pos_params */ - if (assoc_p (v)) - temp = assoc_patsub (assoc_cell (v), p, rep, mflags); - else - temp = array_patsub (array_cell (v), p, rep, mflags); - - if (temp && quoted == 0 && ifs_is_null) - { - /* Posix interp 888 */ - } - else if (temp && (mflags & MATCH_QUOTED) == 0) - { - tt = quote_escapes (temp); - free (temp); - temp = tt; - } - break; -#endif - } - - FREE (pat); - FREE (rep); - free (lpatsub); - - this_command_name = oname; - - return temp; -} - -/****************************************************************/ -/* */ -/* Functions to perform case modification on variable values */ -/* */ -/****************************************************************/ - -/* Do case modification on the positional parameters. */ - -static char * -pos_params_modcase (string, pat, modop, mflags) - char *string, *pat; - int modop; - int mflags; -{ - WORD_LIST *save, *params; - WORD_DESC *w; - char *ret; - int pchar, qflags, pflags; - - save = params = list_rest_of_args (); - if (save == 0) - return ((char *)NULL); - - for ( ; params; params = params->next) - { - ret = sh_modcase (params->word->word, pat, modop); - w = alloc_word_desc (); - w->word = ret ? ret : savestring (""); - dispose_word (params->word); - params->word = w; - } - - pchar = (mflags & MATCH_STARSUB) == MATCH_STARSUB ? '*' : '@'; - qflags = (mflags & MATCH_QUOTED) == MATCH_QUOTED ? Q_DOUBLE_QUOTES : 0; - pflags = (mflags & MATCH_ASSIGNRHS) == MATCH_ASSIGNRHS ? PF_ASSIGNRHS : 0; - - /* If we are expanding in a context where word splitting will not be - performed, treat as quoted. This changes how $* will be expanded. */ - if (pchar == '*' && (mflags & MATCH_ASSIGNRHS) && ifs_is_null) - qflags |= Q_DOUBLE_QUOTES; /* Posix interp 888 */ - - ret = string_list_pos_params (pchar, save, qflags, pflags); - dispose_words (save); - - return (ret); -} - -/* Perform case modification on VALUE, which is the expansion of - VARNAME. MODSPEC is an expression supplying the type of modification - to perform. QUOTED is a flags word containing the type of quoting - currently in effect. */ -static char * -parameter_brace_casemod (varname, value, estatep, modspec, patspec, quoted, pflags, flags) - char *varname, *value; - array_eltstate_t *estatep; - int modspec; - char *patspec; - int quoted, pflags, flags; -{ - int vtype, starsub, modop, mflags, x; - char *val, *temp, *pat, *p, *lpat, *tt, *oname; - SHELL_VAR *v; - - if (value == 0) - return ((char *)NULL); - - oname = this_command_name; - this_command_name = varname; - - vtype = get_var_and_type (varname, value, estatep, quoted, flags, &v, &val); - if (vtype == -1) - { - this_command_name = oname; - return ((char *)NULL); - } - - starsub = vtype & VT_STARSUB; - vtype &= ~VT_STARSUB; - - modop = 0; - mflags = 0; - if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) - mflags |= MATCH_QUOTED; - if (starsub) - mflags |= MATCH_STARSUB; - if (pflags & PF_ASSIGNRHS) - mflags |= MATCH_ASSIGNRHS; - - p = patspec; - if (modspec == '^') - { - x = p && p[0] == modspec; - modop = x ? CASE_UPPER : CASE_UPFIRST; - p += x; - } - else if (modspec == ',') - { - x = p && p[0] == modspec; - modop = x ? CASE_LOWER : CASE_LOWFIRST; - p += x; - } - else if (modspec == '~') - { - x = p && p[0] == modspec; - modop = x ? CASE_TOGGLEALL : CASE_TOGGLE; - p += x; - } - - lpat = p ? savestring (p) : 0; - /* Perform the same expansions on the pattern as performed by the - pattern removal expansions. */ - pat = lpat ? getpattern (lpat, quoted, 1) : 0; - - /* OK, now we do the case modification. */ - switch (vtype) - { - case VT_VARIABLE: - case VT_ARRAYMEMBER: - temp = sh_modcase (val, pat, modop); - if (vtype == VT_VARIABLE) - FREE (val); - if (temp) - { - tt = (mflags & MATCH_QUOTED) ? quote_string (temp) : quote_escapes (temp); - free (temp); - temp = tt; - } - break; - - case VT_POSPARMS: - temp = pos_params_modcase (val, pat, modop, mflags); - if (temp && quoted == 0 && ifs_is_null) - { - /* Posix interp 888 */ - } - else if (temp && (mflags & MATCH_QUOTED) == 0) - { - tt = quote_escapes (temp); - free (temp); - temp = tt; - } - break; - -#if defined (ARRAY_VARS) - case VT_ARRAYVAR: - /* If we are expanding in a context where word splitting will not be - performed, treat as quoted. This changes how ${A[*]} will be - expanded to make it identical to $*. */ - if ((mflags & MATCH_STARSUB) && (mflags & MATCH_ASSIGNRHS) && ifs_is_null) - mflags |= MATCH_QUOTED; /* Posix interp 888 */ - - temp = assoc_p (v) ? assoc_modcase (assoc_cell (v), pat, modop, mflags) - : array_modcase (array_cell (v), pat, modop, mflags); - - if (temp && quoted == 0 && ifs_is_null) - { - /* Posix interp 888 */ - } - else if (temp && (mflags & MATCH_QUOTED) == 0) - { - tt = quote_escapes (temp); - free (temp); - temp = tt; - } - - break; -#endif - } - - FREE (pat); - free (lpat); - - this_command_name = oname; - - return temp; -} - -/* Check for unbalanced parens in S, which is the contents of $(( ... )). If - any occur, this must be a nested command substitution, so return 0. - Otherwise, return 1. A valid arithmetic expression must always have a - ( before a matching ), so any cases where there are more right parens - means that this must not be an arithmetic expression, though the parser - will not accept it without a balanced total number of parens. */ -static int -chk_arithsub (s, len) - const char *s; - int len; -{ - int i, count; - DECLARE_MBSTATE; - - i = count = 0; - while (i < len) - { - if (s[i] == LPAREN) - count++; - else if (s[i] == RPAREN) - { - count--; - if (count < 0) - return 0; - } - - switch (s[i]) - { - default: - ADVANCE_CHAR (s, len, i); - break; - - case '\\': - i++; - if (s[i]) - ADVANCE_CHAR (s, len, i); - break; - - case '\'': - i = skip_single_quoted (s, len, ++i, 0); - break; - - case '"': - i = skip_double_quoted ((char *)s, len, ++i, 0); - break; - } - } - - return (count == 0); -} - -/****************************************************************/ -/* */ -/* Functions to perform parameter expansion on a string */ -/* */ -/****************************************************************/ - -/* ${[#][!]name[[:][^[^]][,[,]]#[#]%[%]-=?+[word][:e1[:e2]]]} */ -static WORD_DESC * -parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, contains_dollar_at) - char *string; - int *indexp, quoted, pflags, *quoted_dollar_atp, *contains_dollar_at; -{ - int check_nullness, var_is_set, var_is_null, var_is_special; - int want_substring, want_indir, want_patsub, want_casemod, want_attributes; - char *name, *value, *temp, *temp1; - WORD_DESC *tdesc, *ret; - int t_index, sindex, c, tflag, modspec, local_pflags, all_element_arrayref; - intmax_t number; - array_eltstate_t es; - - temp = temp1 = value = (char *)NULL; - var_is_set = var_is_null = var_is_special = check_nullness = 0; - want_substring = want_indir = want_patsub = want_casemod = want_attributes = 0; - - local_pflags = 0; - all_element_arrayref = 0; - - sindex = *indexp; - t_index = ++sindex; - /* ${#var} doesn't have any of the other parameter expansions on it. */ - if (string[t_index] == '#' && legal_variable_starter (string[t_index+1])) /* {{ */ - name = string_extract (string, &t_index, "}", SX_VARNAME); - else -#if defined (CASEMOD_EXPANSIONS) - /* To enable case-toggling expansions using the `~' operator character - define CASEMOD_TOGGLECASE in config-top.h */ -# if defined (CASEMOD_TOGGLECASE) - name = string_extract (string, &t_index, "#%^,~:-=?+/@}", SX_VARNAME); -# else - name = string_extract (string, &t_index, "#%^,:-=?+/@}", SX_VARNAME); -# endif /* CASEMOD_TOGGLECASE */ -#else - name = string_extract (string, &t_index, "#%:-=?+/@}", SX_VARNAME); -#endif /* CASEMOD_EXPANSIONS */ - - /* Handle ${@[stuff]} now that @ is a word expansion operator. Not exactly - the cleanest code ever. */ - if (*name == 0 && sindex == t_index && string[sindex] == '@') - { - name = (char *)xrealloc (name, 2); - name[0] = '@'; - name[1] = '\0'; - t_index++; - } - else if (*name == '!' && t_index > sindex && string[t_index] == '@' && string[t_index+1] == RBRACE) - { - name = (char *)xrealloc (name, t_index - sindex + 2); - name[t_index - sindex] = '@'; - name[t_index - sindex + 1] = '\0'; - t_index++; - } - - ret = 0; - tflag = 0; - -#if defined (ARRAY_VARS) - init_eltstate (&es); -#endif - es.ind = INTMAX_MIN; /* XXX */ - - /* If the name really consists of a special variable, then make sure - that we have the entire name. We don't allow indirect references - to special variables except `#', `?', `@' and `*'. This clause is - designed to handle ${#SPECIAL} and ${!SPECIAL}, not anything more - general. */ - if ((sindex == t_index && VALID_SPECIAL_LENGTH_PARAM (string[t_index])) || - (sindex == t_index && string[sindex] == '#' && VALID_SPECIAL_LENGTH_PARAM (string[sindex + 1])) || - (sindex == t_index - 1 && string[sindex] == '!' && VALID_INDIR_PARAM (string[t_index]))) - { - t_index++; - temp1 = string_extract (string, &t_index, "#%:-=?+/@}", 0); - name = (char *)xrealloc (name, 3 + (strlen (temp1))); - *name = string[sindex]; - if (string[sindex] == '!') - { - /* indirect reference of $#, $?, $@, or $* */ - name[1] = string[sindex + 1]; - strcpy (name + 2, temp1); - } - else - strcpy (name + 1, temp1); - free (temp1); - } - sindex = t_index; - - /* Find out what character ended the variable name. Then - do the appropriate thing. */ - if (c = string[sindex]) - sindex++; - - /* If c is followed by one of the valid parameter expansion - characters, move past it as normal. If not, assume that - a substring specification is being given, and do not move - past it. */ - if (c == ':' && VALID_PARAM_EXPAND_CHAR (string[sindex])) - { - check_nullness++; - if (c = string[sindex]) - sindex++; - } - else if (c == ':' && string[sindex] != RBRACE) - want_substring = 1; - else if (c == '/' /* && string[sindex] != RBRACE */) /* XXX */ - want_patsub = 1; -#if defined (CASEMOD_EXPANSIONS) - else if (c == '^' || c == ',' || c == '~') - { - modspec = c; - want_casemod = 1; - } -#endif - else if (c == '@' && (string[sindex] == 'a' || string[sindex] == 'A') && string[sindex+1] == RBRACE) - { - /* special case because we do not want to shortcut foo as foo[0] here */ - want_attributes = 1; - local_pflags |= PF_ALLINDS; - } - - /* Catch the valid and invalid brace expressions that made it through the - tests above. */ - /* ${#-} is a valid expansion and means to take the length of $-. - Similarly for ${#?} and ${##}... */ - if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 && - VALID_SPECIAL_LENGTH_PARAM (c) && string[sindex] == RBRACE) - { - name = (char *)xrealloc (name, 3); - name[1] = c; - name[2] = '\0'; - c = string[sindex++]; - } - - /* ...but ${#%}, ${#:}, ${#=}, ${#+}, and ${#/} are errors. */ - if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 && - member (c, "%:=+/") && string[sindex] == RBRACE) - { - temp = (char *)NULL; - goto bad_substitution; /* XXX - substitution error */ - } - - /* Indirect expansion begins with a `!'. A valid indirect expansion is - either a variable name, one of the positional parameters or a special - variable that expands to one of the positional parameters. */ - want_indir = *name == '!' && - (legal_variable_starter ((unsigned char)name[1]) || DIGIT (name[1]) - || VALID_INDIR_PARAM (name[1])); - - /* Determine the value of this variable whose name is NAME. */ - - /* Check for special variables, directly referenced. */ - if (SPECIAL_VAR (name, want_indir)) - var_is_special++; - - /* Check for special expansion things, like the length of a parameter */ - if (*name == '#' && name[1]) - { - /* If we are not pointing at the character just after the - closing brace, then we haven't gotten all of the name. - Since it begins with a special character, this is a bad - substitution. Also check NAME for validity before trying - to go on. */ - if (string[sindex - 1] != RBRACE || (valid_length_expression (name) == 0)) - { - temp = (char *)NULL; - goto bad_substitution; /* substitution error */ - } - - number = parameter_brace_expand_length (name); - if (number == INTMAX_MIN && unbound_vars_is_error) - { - set_exit_status (EXECUTION_FAILURE); - err_unboundvar (name+1); - free (name); - return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal); - } - free (name); - - *indexp = sindex; - if (number < 0) - return (&expand_wdesc_error); - else - { - ret = alloc_word_desc (); - ret->word = itos (number); - return ret; - } - } - - /* ${@} is identical to $@. */ - if (name[0] == '@' && name[1] == '\0') - { - if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp) - *quoted_dollar_atp = 1; - - if (contains_dollar_at) - *contains_dollar_at = 1; - - tflag |= W_DOLLARAT; - } - - /* Process ${!PREFIX*} expansion. */ - if (want_indir && string[sindex - 1] == RBRACE && - (string[sindex - 2] == '*' || string[sindex - 2] == '@') && - legal_variable_starter ((unsigned char) name[1])) - { - char **x; - WORD_LIST *xlist; - - temp1 = savestring (name + 1); - number = strlen (temp1); - temp1[number - 1] = '\0'; - x = all_variables_matching_prefix (temp1); - xlist = strvec_to_word_list (x, 0, 0); - if (string[sindex - 2] == '*') - temp = string_list_dollar_star (xlist, quoted, 0); - else - { - temp = string_list_dollar_at (xlist, quoted, 0); - if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp) - *quoted_dollar_atp = 1; - if (contains_dollar_at) - *contains_dollar_at = 1; - - tflag |= W_DOLLARAT; - } - free (x); - dispose_words (xlist); - free (temp1); - *indexp = sindex; - - free (name); - - ret = alloc_word_desc (); - ret->word = temp; - ret->flags = tflag; /* XXX */ - return ret; - } - -#if defined (ARRAY_VARS) - /* Process ${!ARRAY[@]} and ${!ARRAY[*]} expansion. */ - if (want_indir && string[sindex - 1] == RBRACE && - string[sindex - 2] == RBRACK && valid_array_reference (name+1, 0)) - { - char *x, *x1; - - temp1 = savestring (name + 1); - x = array_variable_name (temp1, 0, &x1, (int *)0); - FREE (x); - if (ALL_ELEMENT_SUB (x1[0]) && x1[1] == RBRACK) - { - temp = array_keys (temp1, quoted, pflags); /* handles assoc vars too */ - if (x1[0] == '@') - { - if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp) - *quoted_dollar_atp = 1; - if (contains_dollar_at) - *contains_dollar_at = 1; - - tflag |= W_DOLLARAT; - } - - free (name); - free (temp1); - *indexp = sindex; - - ret = alloc_word_desc (); - ret->word = temp; - ret->flags = tflag; /* XXX */ - return ret; - } - - free (temp1); - } -#endif /* ARRAY_VARS */ - - /* Make sure that NAME is valid before trying to go on. */ - if (valid_brace_expansion_word (want_indir ? name + 1 : name, - var_is_special) == 0) - { - temp = (char *)NULL; - goto bad_substitution; /* substitution error */ - } - - if (want_indir) - { - tdesc = parameter_brace_expand_indir (name + 1, var_is_special, quoted, pflags|local_pflags, quoted_dollar_atp, contains_dollar_at); - if (tdesc == &expand_wdesc_error || tdesc == &expand_wdesc_fatal) - { - temp = (char *)NULL; - goto bad_substitution; - } - - /* Turn off the W_ARRAYIND flag because there is no way for this function - to return the index we're supposed to be using. */ - if (tdesc && tdesc->flags) - tdesc->flags &= ~W_ARRAYIND; - - /* If the indir expansion contains $@/$*, extend the special treatment - of the case of no positional parameters and `set -u' to it. */ - if (contains_dollar_at && *contains_dollar_at) - all_element_arrayref = 1; - } - else - { - local_pflags |= PF_IGNUNBOUND|(pflags&(PF_NOSPLIT2|PF_ASSIGNRHS)); - tdesc = parameter_brace_expand_word (name, var_is_special, quoted, local_pflags, &es); - } - - if (tdesc == &expand_wdesc_error || tdesc == &expand_wdesc_fatal) - { - tflag = 0; - tdesc = 0; - } - - if (tdesc) - { - temp = tdesc->word; - tflag = tdesc->flags; - dispose_word_desc (tdesc); - } - else - temp = (char *)0; - - if (temp == &expand_param_error || temp == &expand_param_fatal) - { - FREE (name); - FREE (value); - return (temp == &expand_param_error ? &expand_wdesc_error : &expand_wdesc_fatal); - } - -#if defined (ARRAY_VARS) - if (valid_array_reference (name, 0)) - { - int qflags; - char *t; - - qflags = quoted; - /* If in a context where word splitting will not take place, treat as - if double-quoted. Has effects with $* and ${array[*]} */ - - if (pflags & PF_ASSIGNRHS) - qflags |= Q_DOUBLE_QUOTES; - /* We duplicate a little code here */ - t = mbschr (name, LBRACK); - if (t && ALL_ELEMENT_SUB (t[1]) && t[2] == RBRACK) - { - all_element_arrayref = 1; - if (expand_no_split_dollar_star && t[1] == '*') /* XXX */ - qflags |= Q_DOUBLE_QUOTES; - } - chk_atstar (name, qflags, pflags, quoted_dollar_atp, contains_dollar_at); - } -#endif - - var_is_set = temp != (char *)0; - var_is_null = check_nullness && (var_is_set == 0 || *temp == 0); - /* XXX - this may not need to be restricted to special variables */ - if (check_nullness) - var_is_null |= var_is_set && var_is_special && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && QUOTED_NULL (temp); -#if defined (ARRAY_VARS) - if (check_nullness) - var_is_null |= var_is_set && - (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && - QUOTED_NULL (temp) && - valid_array_reference (name, 0) && - chk_atstar (name, 0, 0, (int *)0, (int *)0); -#endif - - /* Get the rest of the stuff inside the braces. */ - if (c && c != RBRACE) - { - /* Extract the contents of the ${ ... } expansion - according to the Posix.2 rules. */ - value = extract_dollar_brace_string (string, &sindex, quoted, (c == '%' || c == '#' || c =='/' || c == '^' || c == ',' || c ==':') ? SX_POSIXEXP|SX_WORD : SX_WORD); - if (string[sindex] == RBRACE) - sindex++; - else - goto bad_substitution; /* substitution error */ - } - else - value = (char *)NULL; - - *indexp = sindex; - - /* All the cases where an expansion can possibly generate an unbound - variable error. */ - if (want_substring || want_patsub || want_casemod || c == '@' || c == '#' || c == '%' || c == RBRACE) - { - if (var_is_set == 0 && unbound_vars_is_error && ((name[0] != '@' && name[0] != '*') || name[1]) && all_element_arrayref == 0) - { - set_exit_status (EXECUTION_FAILURE); - err_unboundvar (name); - FREE (value); - FREE (temp); - free (name); - return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal); - } - } - - /* If this is a substring spec, process it and add the result. */ - if (want_substring) - { - temp1 = parameter_brace_substring (name, temp, &es, value, quoted, pflags, (tflag & W_ARRAYIND) ? AV_USEIND : 0); - FREE (value); - FREE (temp); -#if defined (ARRAY_VARS) - flush_eltstate (&es); -#endif - - if (temp1 == &expand_param_error || temp1 == &expand_param_fatal) - { - FREE (name); - return (temp1 == &expand_param_error ? &expand_wdesc_error : &expand_wdesc_fatal); - } - - ret = alloc_word_desc (); - ret->word = temp1; - /* We test quoted_dollar_atp because we want variants with double-quoted - "$@" to take a different code path. In fact, we make sure at the end - of expand_word_internal that we're only looking at these flags if - quoted_dollar_at == 0. */ - if (temp1 && - (quoted_dollar_atp == 0 || *quoted_dollar_atp == 0) && - QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))) - ret->flags |= W_QUOTED|W_HASQUOTEDNULL; - else if (temp1 && (name[0] == '*' && name[1] == 0) && quoted == 0 && - (pflags & PF_ASSIGNRHS)) - ret->flags |= W_SPLITSPACE; /* Posix interp 888 */ - /* Special handling for $* when unquoted and $IFS is null. Posix interp 888 */ - else if (temp1 && (name[0] == '*' && name[1] == 0) && quoted == 0 && ifs_is_null) - ret->flags |= W_SPLITSPACE; /* Posix interp 888 */ - - FREE (name); - return ret; - } - else if (want_patsub) - { - temp1 = parameter_brace_patsub (name, temp, &es, value, quoted, pflags, (tflag & W_ARRAYIND) ? AV_USEIND : 0); - FREE (value); - FREE (temp); -#if defined (ARRAY_VARS) - flush_eltstate (&es); -#endif - - if (temp1 == &expand_param_error || temp1 == &expand_param_fatal) - { - FREE (name); - return (temp1 == &expand_param_error ? &expand_wdesc_error : &expand_wdesc_fatal); - } - - ret = alloc_word_desc (); - ret->word = temp1; - if (temp1 && - (quoted_dollar_atp == 0 || *quoted_dollar_atp == 0) && - QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))) - ret->flags |= W_QUOTED|W_HASQUOTEDNULL; - /* Special handling for $* when unquoted and $IFS is null. Posix interp 888 */ - else if (temp1 && (name[0] == '*' && name[1] == 0) && quoted == 0 && ifs_is_null) - ret->flags |= W_SPLITSPACE; /* Posix interp 888 */ - - FREE (name); - return ret; - } -#if defined (CASEMOD_EXPANSIONS) - else if (want_casemod) - { - temp1 = parameter_brace_casemod (name, temp, &es, modspec, value, quoted, pflags, (tflag & W_ARRAYIND) ? AV_USEIND : 0); - FREE (value); - FREE (temp); -#if defined (ARRAY_VARS) - flush_eltstate (&es); -#endif - - if (temp1 == &expand_param_error || temp1 == &expand_param_fatal) - { - FREE (name); - return (temp1 == &expand_param_error ? &expand_wdesc_error : &expand_wdesc_fatal); - } - - ret = alloc_word_desc (); - ret->word = temp1; - if (temp1 && - (quoted_dollar_atp == 0 || *quoted_dollar_atp == 0) && - QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))) - ret->flags |= W_QUOTED|W_HASQUOTEDNULL; - /* Special handling for $* when unquoted and $IFS is null. Posix interp 888 */ - else if (temp1 && (name[0] == '*' && name[1] == 0) && quoted == 0 && ifs_is_null) - ret->flags |= W_SPLITSPACE; /* Posix interp 888 */ - - FREE (name); - return ret; - } -#endif - - /* Do the right thing based on which character ended the variable name. */ - switch (c) - { - default: - case '\0': -bad_substitution: - set_exit_status (EXECUTION_FAILURE); - report_error (_("%s: bad substitution"), string ? string : "??"); - FREE (value); - FREE (temp); - free (name); -#if defined (ARRAY_VARS) - flush_eltstate (&es); -#endif - if (shell_compatibility_level <= 43) - return &expand_wdesc_error; - else - return ((posixly_correct && interactive_shell == 0) ? &expand_wdesc_fatal : &expand_wdesc_error); - - case RBRACE: - break; - - case '@': - temp1 = parameter_brace_transform (name, temp, &es, value, c, quoted, pflags, (tflag & W_ARRAYIND) ? AV_USEIND : 0); - free (temp); - free (value); -#if defined (ARRAY_VARS) - flush_eltstate (&es); -#endif - - if (temp1 == &expand_param_error || temp1 == &expand_param_fatal) - { - free (name); - set_exit_status (EXECUTION_FAILURE); - report_error (_("%s: bad substitution"), string ? string : "??"); - return (temp1 == &expand_param_error ? &expand_wdesc_error : &expand_wdesc_fatal); - } - - ret = alloc_word_desc (); - ret->word = temp1; - if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))) - ret->flags |= W_QUOTED|W_HASQUOTEDNULL; - /* Special handling for $* when unquoted and $IFS is null. Posix interp 888 */ - else if (temp1 && (name[0] == '*' && name[1] == 0) && quoted == 0 && ifs_is_null) - ret->flags |= W_SPLITSPACE; /* Posix interp 888 */ - - free (name); - return ret; - - case '#': /* ${param#[#]pattern} */ - case '%': /* ${param%[%]pattern} */ - if (value == 0 || *value == '\0' || temp == 0 || *temp == '\0') - { - FREE (value); - break; - } - temp1 = parameter_brace_remove_pattern (name, temp, &es, value, c, quoted, (tflag & W_ARRAYIND) ? AV_USEIND : 0); - free (temp); - free (value); -#if defined (ARRAY_VARS) - flush_eltstate (&es); -#endif - - ret = alloc_word_desc (); - ret->word = temp1; - if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))) - ret->flags |= W_QUOTED|W_HASQUOTEDNULL; - /* Special handling for $* when unquoted and $IFS is null. Posix interp 888 */ - else if (temp1 && (name[0] == '*' && name[1] == 0) && quoted == 0 && ifs_is_null) - ret->flags |= W_SPLITSPACE; /* Posix interp 888 */ - - free (name); - return ret; - - case '-': - case '=': - case '?': - case '+': - if (var_is_set && var_is_null == 0) - { - /* If the operator is `+', we don't want the value of the named - variable for anything, just the value of the right hand side. */ - if (c == '+') - { - /* XXX -- if we're double-quoted and the named variable is "$@", - we want to turn off any special handling of "$@" -- - we're not using it, so whatever is on the rhs applies. */ - if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp) - *quoted_dollar_atp = 0; - if (contains_dollar_at) - *contains_dollar_at = 0; - - FREE (temp); - if (value) - { - /* From Posix discussion on austin-group list. Issue 221 - requires that backslashes escaping `}' inside - double-quoted ${...} be removed. */ - if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) - quoted |= Q_DOLBRACE; - ret = parameter_brace_expand_rhs (name, value, c, - quoted, - pflags, - quoted_dollar_atp, - contains_dollar_at); - /* XXX - fix up later, esp. noting presence of - W_HASQUOTEDNULL in ret->flags */ - free (value); - } - else - temp = (char *)NULL; - } - else - { - FREE (value); - } - /* Otherwise do nothing; just use the value in TEMP. */ - } - else /* VAR not set or VAR is NULL. */ - { - /* If we're freeing a quoted null here, we need to remember we saw - it so we can restore it later if needed, or the caller can note it. - The check against `+' doesn't really matter, since the other cases - don't use or return TFLAG, but it's good for clarity. */ - if (c == '+' && temp && QUOTED_NULL (temp) && - (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) - tflag |= W_HASQUOTEDNULL; - - FREE (temp); - temp = (char *)NULL; - if (c == '=' && var_is_special) - { - set_exit_status (EXECUTION_FAILURE); - report_error (_("$%s: cannot assign in this way"), name); - free (name); - free (value); -#if defined (ARRAY_VARS) - flush_eltstate (&es); -#endif - return &expand_wdesc_error; - } - else if (c == '?') - { - parameter_brace_expand_error (name, value, check_nullness); -#if defined (ARRAY_VARS) - flush_eltstate (&es); -#endif - return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal); - } - else if (c != '+') - { - /* XXX -- if we're double-quoted and the named variable is "$@", - we want to turn off any special handling of "$@" -- - we're not using it, so whatever is on the rhs applies. */ - if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp) - *quoted_dollar_atp = 0; - if (contains_dollar_at) - *contains_dollar_at = 0; - - /* From Posix discussion on austin-group list. Issue 221 requires - that backslashes escaping `}' inside double-quoted ${...} be - removed. */ - if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) - quoted |= Q_DOLBRACE; - ret = parameter_brace_expand_rhs (name, value, c, quoted, pflags, - quoted_dollar_atp, - contains_dollar_at); - /* XXX - fix up later, esp. noting presence of - W_HASQUOTEDNULL in tdesc->flags */ - } - free (value); - } - - break; - } - free (name); -#if defined (ARRAY_VARS) - flush_eltstate (&es); -#endif - - if (ret == 0) - { - ret = alloc_word_desc (); - ret->flags = tflag; - ret->word = temp; - } - return (ret); -} - -/* Expand a single ${xxx} expansion. The braces are optional. When - the braces are used, parameter_brace_expand() does the work, - possibly calling param_expand recursively. */ -static WORD_DESC * -param_expand (string, sindex, quoted, expanded_something, - contains_dollar_at, quoted_dollar_at_p, had_quoted_null_p, - pflags) - char *string; - int *sindex, quoted, *expanded_something, *contains_dollar_at; - int *quoted_dollar_at_p, *had_quoted_null_p, pflags; -{ - char *temp, *temp1, uerror[3], *savecmd; - int zindex, t_index, expok, eflag; - unsigned char c; - intmax_t number; - SHELL_VAR *var; - WORD_LIST *list, *l; - WORD_DESC *tdesc, *ret; - int tflag, nullarg; - -/*itrace("param_expand: `%s' pflags = %d", string+*sindex, pflags);*/ - zindex = *sindex; - c = string[++zindex]; - - temp = (char *)NULL; - ret = tdesc = (WORD_DESC *)NULL; - tflag = 0; - - /* Do simple cases first. Switch on what follows '$'. */ - switch (c) - { - /* $0 .. $9? */ - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - temp1 = dollar_vars[TODIGIT (c)]; - /* This doesn't get called when (pflags&PF_IGNUNBOUND) != 0 */ - if (unbound_vars_is_error && temp1 == (char *)NULL) - { - uerror[0] = '$'; - uerror[1] = c; - uerror[2] = '\0'; - set_exit_status (EXECUTION_FAILURE); - err_unboundvar (uerror); - return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal); - } - if (temp1) - temp = (*temp1 && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))) - ? quote_string (temp1) - : quote_escapes (temp1); - else - temp = (char *)NULL; - - break; - - /* $$ -- pid of the invoking shell. */ - case '$': - temp = itos (dollar_dollar_pid); - break; - - /* $# -- number of positional parameters. */ - case '#': - temp = itos (number_of_args ()); - break; - - /* $? -- return value of the last synchronous command. */ - case '?': - temp = itos (last_command_exit_value); - break; - - /* $- -- flags supplied to the shell on invocation or by `set'. */ - case '-': - temp = which_set_flags (); - break; - - /* $! -- Pid of the last asynchronous command. */ - case '!': - /* If no asynchronous pids have been created, expand to nothing. - If `set -u' has been executed, and no async processes have - been created, this is an expansion error. */ - if (last_asynchronous_pid == NO_PID) - { - if (expanded_something) - *expanded_something = 0; - temp = (char *)NULL; - if (unbound_vars_is_error && (pflags & PF_IGNUNBOUND) == 0) - { - uerror[0] = '$'; - uerror[1] = c; - uerror[2] = '\0'; - set_exit_status (EXECUTION_FAILURE); - err_unboundvar (uerror); - return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal); - } - } - else - temp = itos (last_asynchronous_pid); - break; - - /* The only difference between this and $@ is when the arg is quoted. */ - case '*': /* `$*' */ - list = list_rest_of_args (); - -#if 0 - /* According to austin-group posix proposal by Geoff Clare in - <20090505091501.GA10097@squonk.masqnet> of 5 May 2009: - - "The shell shall write a message to standard error and - immediately exit when it tries to expand an unset parameter - other than the '@' and '*' special parameters." - */ - - if (list == 0 && unbound_vars_is_error && (pflags & PF_IGNUNBOUND) == 0) - { - uerror[0] = '$'; - uerror[1] = '*'; - uerror[2] = '\0'; - set_exit_status (EXECUTION_FAILURE); - err_unboundvar (uerror); - return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal); - } -#endif - - /* If there are no command-line arguments, this should just - disappear if there are other characters in the expansion, - even if it's quoted. */ - if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && list == 0) - temp = (char *)NULL; - else if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES|Q_PATQUOTE)) - { - /* If we have "$*" we want to make a string of the positional - parameters, separated by the first character of $IFS, and - quote the whole string, including the separators. If IFS - is unset, the parameters are separated by ' '; if $IFS is - null, the parameters are concatenated. */ - temp = (quoted & (Q_DOUBLE_QUOTES|Q_PATQUOTE)) ? string_list_dollar_star (list, quoted, 0) : string_list (list); - if (temp) - { - temp1 = (quoted & Q_DOUBLE_QUOTES) ? quote_string (temp) : temp; - if (*temp == 0) - tflag |= W_HASQUOTEDNULL; - if (temp != temp1) - free (temp); - temp = temp1; - } - } - else - { - /* We check whether or not we're eventually going to split $* here, - for example when IFS is empty and we are processing the rhs of - an assignment statement. In that case, we don't separate the - arguments at all. Otherwise, if the $* is not quoted it is - identical to $@ */ - if (expand_no_split_dollar_star && quoted == 0 && ifs_is_set == 0 && (pflags & PF_ASSIGNRHS)) - { - /* Posix interp 888: RHS of assignment, IFS unset: no splitting, - separate with space */ - temp1 = string_list_dollar_star (list, quoted, pflags); - temp = temp1 ? quote_string (temp1) : temp1; - /* XXX - tentative - note that we saw a quoted null here */ - if (temp1 && *temp1 == 0 && QUOTED_NULL (temp)) - tflag |= W_SAWQUOTEDNULL; - FREE (temp1); - } - else if (expand_no_split_dollar_star && quoted == 0 && ifs_is_null && (pflags & PF_ASSIGNRHS)) - { - /* Posix interp 888: RHS of assignment, IFS set to '' */ - temp1 = string_list_dollar_star (list, quoted, pflags); - temp = temp1 ? quote_escapes (temp1) : temp1; - FREE (temp1); - } - else if (expand_no_split_dollar_star && quoted == 0 && ifs_is_set && ifs_is_null == 0 && (pflags & PF_ASSIGNRHS)) - { - /* Posix interp 888: RHS of assignment, IFS set to non-null value */ - temp1 = string_list_dollar_star (list, quoted, pflags); - temp = temp1 ? quote_string (temp1) : temp1; - - /* XXX - tentative - note that we saw a quoted null here */ - if (temp1 && *temp1 == 0 && QUOTED_NULL (temp)) - tflag |= W_SAWQUOTEDNULL; - FREE (temp1); - } - /* XXX - should we check ifs_is_set here as well? */ -# if defined (HANDLE_MULTIBYTE) - else if (expand_no_split_dollar_star && ifs_firstc[0] == 0) -# else - else if (expand_no_split_dollar_star && ifs_firstc == 0) -# endif - /* Posix interp 888: not RHS, no splitting, IFS set to '' */ - temp = string_list_dollar_star (list, quoted, 0); - else - { - temp = string_list_dollar_at (list, quoted, 0); - /* Set W_SPLITSPACE to make sure the individual positional - parameters are split into separate arguments */ -#if 0 - if (quoted == 0 && (ifs_is_set == 0 || ifs_is_null)) -#else /* change with bash-5.0 */ - if (quoted == 0 && ifs_is_null) -#endif - tflag |= W_SPLITSPACE; - /* If we're not quoted but we still don't want word splitting, make - we quote the IFS characters to protect them from splitting (e.g., - when $@ is in the string as well). */ - else if (temp && quoted == 0 && ifs_is_set && (pflags & PF_ASSIGNRHS)) - { - temp1 = quote_string (temp); - free (temp); - temp = temp1; - } - } - - if (expand_no_split_dollar_star == 0 && contains_dollar_at) - *contains_dollar_at = 1; - } - - dispose_words (list); - break; - - /* When we have "$@" what we want is "$1" "$2" "$3" ... This - means that we have to turn quoting off after we split into - the individually quoted arguments so that the final split - on the first character of $IFS is still done. */ - case '@': /* `$@' */ - list = list_rest_of_args (); - -#if 0 - /* According to austin-group posix proposal by Geoff Clare in - <20090505091501.GA10097@squonk.masqnet> of 5 May 2009: - - "The shell shall write a message to standard error and - immediately exit when it tries to expand an unset parameter - other than the '@' and '*' special parameters." - */ - - if (list == 0 && unbound_vars_is_error && (pflags & PF_IGNUNBOUND) == 0) - { - uerror[0] = '$'; - uerror[1] = '@'; - uerror[2] = '\0'; - set_exit_status (EXECUTION_FAILURE); - err_unboundvar (uerror); - return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal); - } -#endif - - for (nullarg = 0, l = list; l; l = l->next) - { - if (l->word && (l->word->word == 0 || l->word->word[0] == 0)) - nullarg = 1; - } - - /* We want to flag the fact that we saw this. We can't turn - off quoting entirely, because other characters in the - string might need it (consider "\"$@\""), but we need some - way to signal that the final split on the first character - of $IFS should be done, even though QUOTED is 1. */ - /* XXX - should this test include Q_PATQUOTE? */ - if (quoted_dollar_at_p && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))) - *quoted_dollar_at_p = 1; - if (contains_dollar_at) - *contains_dollar_at = 1; - - /* We want to separate the positional parameters with the first - character of $IFS in case $IFS is something other than a space. - We also want to make sure that splitting is done no matter what -- - according to POSIX.2, this expands to a list of the positional - parameters no matter what IFS is set to. */ - /* XXX - what to do when in a context where word splitting is not - performed? Even when IFS is not the default, posix seems to imply - that we have to expand $@ to all the positional parameters and - separate them with spaces, which are preserved because word splitting - doesn't take place. See below for how we use PF_NOSPLIT2 here. */ - - /* These are the cases where word splitting will not be performed. */ - if (pflags & PF_ASSIGNRHS) - { - temp = string_list_dollar_at (list, (quoted|Q_DOUBLE_QUOTES), pflags); - if (nullarg) - tflag |= W_HASQUOTEDNULL; /* we know quoting produces quoted nulls */ - } - - /* This needs to match what expand_word_internal does with non-quoted $@ - does with separating with spaces. Passing Q_DOUBLE_QUOTES means that - the characters in LIST will be quoted, and PF_ASSIGNRHS ensures that - they will separated by spaces. After doing this, we need the special - handling for PF_NOSPLIT2 in expand_word_internal to remove the CTLESC - quotes. */ - else if (pflags & PF_NOSPLIT2) - { -#if defined (HANDLE_MULTIBYTE) - if (quoted == 0 && ifs_is_set && ifs_is_null == 0 && ifs_firstc[0] != ' ') -#else - if (quoted == 0 && ifs_is_set && ifs_is_null == 0 && ifs_firstc != ' ') -#endif - /* Posix interp 888 */ - temp = string_list_dollar_at (list, Q_DOUBLE_QUOTES, pflags); - else - temp = string_list_dollar_at (list, quoted, pflags); - } - else - temp = string_list_dollar_at (list, quoted, pflags); - - tflag |= W_DOLLARAT; - dispose_words (list); - break; - - case LBRACE: - tdesc = parameter_brace_expand (string, &zindex, quoted, pflags, - quoted_dollar_at_p, - contains_dollar_at); - - if (tdesc == &expand_wdesc_error || tdesc == &expand_wdesc_fatal) - return (tdesc); - temp = tdesc ? tdesc->word : (char *)0; - - /* XXX */ - /* Quoted nulls should be removed if there is anything else - in the string. */ - /* Note that we saw the quoted null so we can add one back at - the end of this function if there are no other characters - in the string, discard TEMP, and go on. The exception to - this is when we have "${@}" and $1 is '', since $@ needs - special handling. */ - if (tdesc && tdesc->word && (tdesc->flags & W_HASQUOTEDNULL) && QUOTED_NULL (temp)) - { - if (had_quoted_null_p) - *had_quoted_null_p = 1; - if (*quoted_dollar_at_p == 0) - { - free (temp); - tdesc->word = temp = (char *)NULL; - } - - } - - ret = tdesc; - goto return0; - - /* Do command or arithmetic substitution. */ - case LPAREN: - /* We have to extract the contents of this paren substitution. */ - t_index = zindex + 1; - /* XXX - might want to check for string[t_index+2] == LPAREN and parse - as arithmetic substitution immediately. */ - temp = extract_command_subst (string, &t_index, (pflags&PF_COMPLETE) ? SX_COMPLETE : 0); - zindex = t_index; - - /* For Posix.2-style `$(( ))' arithmetic substitution, - extract the expression and pass it to the evaluator. */ - if (temp && *temp == LPAREN) - { - char *temp2; - temp1 = temp + 1; - temp2 = savestring (temp1); - t_index = strlen (temp2) - 1; - - if (temp2[t_index] != RPAREN) - { - free (temp2); - goto comsub; - } - - /* Cut off ending `)' */ - temp2[t_index] = '\0'; - - if (chk_arithsub (temp2, t_index) == 0) - { - free (temp2); -#if 0 - internal_warning (_("future versions of the shell will force evaluation as an arithmetic substitution")); -#endif - goto comsub; - } - - /* Expand variables found inside the expression. */ - temp1 = expand_arith_string (temp2, Q_DOUBLE_QUOTES|Q_ARITH); - free (temp2); - -arithsub: - /* No error messages. */ - savecmd = this_command_name; - this_command_name = (char *)NULL; - - eflag = (shell_compatibility_level > 51) ? 0 : EXP_EXPANDED; - number = evalexp (temp1, eflag, &expok); - this_command_name = savecmd; - free (temp); - free (temp1); - if (expok == 0) - { - if (interactive_shell == 0 && posixly_correct) - { - set_exit_status (EXECUTION_FAILURE); - return (&expand_wdesc_fatal); - } - else - return (&expand_wdesc_error); - } - temp = itos (number); - break; - } - -comsub: - if (pflags & PF_NOCOMSUB) - /* we need zindex+1 because string[zindex] == RPAREN */ - temp1 = substring (string, *sindex, zindex+1); - else - { - tdesc = command_substitute (temp, quoted, pflags&PF_ASSIGNRHS); - temp1 = tdesc ? tdesc->word : (char *)NULL; - if (tdesc) - dispose_word_desc (tdesc); - } - FREE (temp); - temp = temp1; - break; - - /* Do POSIX.2d9-style arithmetic substitution. This will probably go - away in a future bash release. */ - case '[': /*]*/ - /* Extract the contents of this arithmetic substitution. */ - t_index = zindex + 1; - temp = extract_arithmetic_subst (string, &t_index); - zindex = t_index; - if (temp == 0) - { - temp = savestring (string); - if (expanded_something) - *expanded_something = 0; - goto return0; - } - - /* Do initial variable expansion. */ - temp1 = expand_arith_string (temp, Q_DOUBLE_QUOTES|Q_ARITH); - - goto arithsub; - - default: - /* Find the variable in VARIABLE_LIST. */ - temp = (char *)NULL; - - for (t_index = zindex; (c = string[zindex]) && legal_variable_char (c); zindex++) - ; - temp1 = (zindex > t_index) ? substring (string, t_index, zindex) : (char *)NULL; - - /* If this isn't a variable name, then just output the `$'. */ - if (temp1 == 0 || *temp1 == '\0') - { - FREE (temp1); - temp = (char *)xmalloc (2); - temp[0] = '$'; - temp[1] = '\0'; - if (expanded_something) - *expanded_something = 0; - goto return0; - } - - /* If the variable exists, return its value cell. */ - var = find_variable (temp1); - - if (var && invisible_p (var) == 0 && var_isset (var)) - { -#if defined (ARRAY_VARS) - if (assoc_p (var) || array_p (var)) - { - temp = array_p (var) ? array_reference (array_cell (var), 0) - : assoc_reference (assoc_cell (var), "0"); - if (temp) - temp = (*temp && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))) - ? quote_string (temp) - : quote_escapes (temp); - else if (unbound_vars_is_error) - goto unbound_variable; - } - else -#endif - { - temp = value_cell (var); - - temp = (*temp && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))) - ? quote_string (temp) - : ((pflags & PF_ASSIGNRHS) ? quote_rhs (temp) - : quote_escapes (temp)); - } - - free (temp1); - - goto return0; - } - else if (var && (invisible_p (var) || var_isset (var) == 0)) - temp = (char *)NULL; - else if ((var = find_variable_last_nameref (temp1, 0)) && var_isset (var) && invisible_p (var) == 0) - { - temp = nameref_cell (var); -#if defined (ARRAY_VARS) - if (temp && *temp && valid_array_reference (temp, 0)) - { - chk_atstar (temp, quoted, pflags, quoted_dollar_at_p, contains_dollar_at); - tdesc = parameter_brace_expand_word (temp, SPECIAL_VAR (temp, 0), quoted, pflags, 0); - if (tdesc == &expand_wdesc_error || tdesc == &expand_wdesc_fatal) - return (tdesc); - ret = tdesc; - goto return0; - } - else -#endif - /* y=2 ; typeset -n x=y; echo $x is not the same as echo $2 in ksh */ - if (temp && *temp && legal_identifier (temp) == 0) - { - set_exit_status (EXECUTION_FAILURE); - report_error (_("%s: invalid variable name for name reference"), temp); - return (&expand_wdesc_error); /* XXX */ - } - else - temp = (char *)NULL; - } - - temp = (char *)NULL; - -unbound_variable: - if (unbound_vars_is_error) - { - set_exit_status (EXECUTION_FAILURE); - err_unboundvar (temp1); - } - else - { - free (temp1); - goto return0; - } - - free (temp1); - set_exit_status (EXECUTION_FAILURE); - return ((unbound_vars_is_error && interactive_shell == 0) - ? &expand_wdesc_fatal - : &expand_wdesc_error); - } - - if (string[zindex]) - zindex++; - -return0: - *sindex = zindex; - - if (ret == 0) - { - ret = alloc_word_desc (); - ret->flags = tflag; /* XXX */ - ret->word = temp; - } - return ret; -} - -#if defined (ARRAY_VARS) -/* Characters that need to be backslash-quoted after expanding array subscripts */ -static char abstab[256] = { '\1' }; - -/* Run an array subscript through the appropriate word expansions. */ -char * -expand_subscript_string (string, quoted) - char *string; - int quoted; -{ - WORD_DESC td; - WORD_LIST *tlist; - int oe; - char *ret; - - if (string == 0 || *string == 0) - return (char *)NULL; - - oe = expand_no_split_dollar_star; - ret = (char *)NULL; - - td.flags = W_NOPROCSUB|W_NOTILDE|W_NOSPLIT2; /* XXX - W_NOCOMSUB? */ - td.word = savestring (string); /* in case it's freed on error */ - - expand_no_split_dollar_star = 1; - tlist = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL); - expand_no_split_dollar_star = oe; - - if (tlist) - { - if (tlist->word) - { - remove_quoted_nulls (tlist->word->word); - tlist->word->flags &= ~W_HASQUOTEDNULL; - } - dequote_list (tlist); - ret = string_list (tlist); - dispose_words (tlist); - } - - free (td.word); - return (ret); -} - -/* Expand the subscript in STRING, which is an array reference. To ensure we - only expand it once, we quote the characters that would start another - expansion and the bracket characters that are special to array subscripts. */ -static char * -expand_array_subscript (string, sindex, quoted, flags) - char *string; - int *sindex; - int quoted, flags; -{ - char *ret, *exp, *t; - size_t slen; - int si, ni; - - si = *sindex; - slen = STRLEN (string); - - if (abstab[0] == '\1') - { - /* These are basically the characters that start shell expansions plus - the characters that delimit subscripts. */ - memset (abstab, '\0', sizeof (abstab)); - abstab[LBRACK] = abstab[RBRACK] = 1; - abstab['$'] = abstab['`'] = abstab['~'] = 1; - abstab['\\'] = abstab['\''] = 1; - abstab['"'] = 1; /* XXX */ - /* We don't quote `@' or `*' in the subscript at all. */ - } - - /* string[si] == LBRACK */ - ni = skipsubscript (string, si, 0); - /* These checks mirror the ones in valid_array_reference. The check for - (ni - si) == 1 checks for empty subscripts. We don't check that the - subscript is a separate word if we're parsing an arithmetic expression. */ - if (ni >= slen || string[ni] != RBRACK || (ni - si) == 1 || - (string[ni+1] != '\0' && (quoted & Q_ARITH) == 0)) - { - /* let's check and see what fails this check */ - INTERNAL_DEBUG (("expand_array_subscript: bad subscript string: `%s'", string+si)); - ret = (char *)xmalloc (2); /* badly-formed subscript */ - ret[0] = string[si]; - ret[1] = '\0'; - *sindex = si + 1; - return ret; - } - - /* STRING[ni] == RBRACK */ - exp = substring (string, si+1, ni); - t = expand_subscript_string (exp, quoted & ~(Q_ARITH|Q_DOUBLE_QUOTES)); - free (exp); - exp = sh_backslash_quote (t, abstab, 0); - free (t); - - slen = STRLEN (exp); - ret = xmalloc (slen + 2 + 1); - ret[0] ='['; - strcpy (ret + 1, exp); - ret[slen + 1] = ']'; - ret[slen + 2] = '\0'; - - free (exp); - *sindex = ni + 1; - - return ret; -} -#endif - -void -invalidate_cached_quoted_dollar_at () -{ - dispose_words (cached_quoted_dollar_at); - cached_quoted_dollar_at = 0; -} - -/* Make a word list which is the result of parameter and variable - expansion, command substitution, arithmetic substitution, and - quote removal of WORD. Return a pointer to a WORD_LIST which is - the result of the expansion. If WORD contains a null word, the - word list returned is also null. - - QUOTED contains flag values defined in shell.h. - - ISEXP is used to tell expand_word_internal that the word should be - treated as the result of an expansion. This has implications for - how IFS characters in the word are treated. - - CONTAINS_DOLLAR_AT and EXPANDED_SOMETHING are return values; when non-null - they point to an integer value which receives information about expansion. - CONTAINS_DOLLAR_AT gets non-zero if WORD contained "$@", else zero. - EXPANDED_SOMETHING get non-zero if WORD contained any parameter expansions, - else zero. - - This only does word splitting in the case of $@ expansion. In that - case, we split on ' '. */ - -/* Values for the local variable quoted_state. */ -#define UNQUOTED 0 -#define PARTIALLY_QUOTED 1 -#define WHOLLY_QUOTED 2 - -static WORD_LIST * -expand_word_internal (word, quoted, isexp, contains_dollar_at, expanded_something) - WORD_DESC *word; - int quoted, isexp; - int *contains_dollar_at; - int *expanded_something; -{ - WORD_LIST *list; - WORD_DESC *tword; - - /* The intermediate string that we build while expanding. */ - char *istring; - - /* The current size of the above object. */ - size_t istring_size; - - /* Index into ISTRING. */ - size_t istring_index; - - /* Temporary string storage. */ - char *temp, *temp1; - - /* The text of WORD. */ - register char *string; - - /* The size of STRING. */ - size_t string_size; - - /* The index into STRING. */ - int sindex; - - /* This gets 1 if we see a $@ while quoted. */ - int quoted_dollar_at; - - /* One of UNQUOTED, PARTIALLY_QUOTED, or WHOLLY_QUOTED, depending on - whether WORD contains no quoting characters, a partially quoted - string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */ - int quoted_state; - - /* State flags */ - int had_quoted_null; - int has_quoted_ifs; /* did we add a quoted $IFS character here? */ - int has_dollar_at, temp_has_dollar_at; - int internal_tilde; - int split_on_spaces; - int local_expanded; - int tflag; - int pflags; /* flags passed to param_expand */ - int mb_cur_max; - - int assignoff; /* If assignment, offset of `=' */ - - register unsigned char c; /* Current character. */ - int t_index; /* For calls to string_extract_xxx. */ - - char twochars[2]; - - DECLARE_MBSTATE; - - /* OK, let's see if we can optimize a common idiom: "$@". This needs to make sure - that all of the flags callers care about (e.g., W_HASQUOTEDNULL) are set in - list->flags. */ - if (STREQ (word->word, "\"$@\"") && - (word->flags == (W_HASDOLLAR|W_QUOTED)) && - dollar_vars[1]) /* XXX - check IFS here as well? */ - { - if (contains_dollar_at) - *contains_dollar_at = 1; - if (expanded_something) - *expanded_something = 1; - if (cached_quoted_dollar_at) - return (copy_word_list (cached_quoted_dollar_at)); - list = list_rest_of_args (); - list = quote_list (list); - cached_quoted_dollar_at = copy_word_list (list); - return (list); - } - - istring = (char *)xmalloc (istring_size = DEFAULT_INITIAL_ARRAY_SIZE); - istring[istring_index = 0] = '\0'; - quoted_dollar_at = had_quoted_null = has_dollar_at = 0; - has_quoted_ifs = 0; - split_on_spaces = 0; - internal_tilde = 0; /* expanding =~ or :~ */ - quoted_state = UNQUOTED; - - string = word->word; - if (string == 0) - goto finished_with_string; - mb_cur_max = MB_CUR_MAX; - - /* Don't need the string length for the SADD... and COPY_ macros unless - multibyte characters are possible, but do need it for bounds checking. */ - string_size = (mb_cur_max > 1) ? strlen (string) : 1; - - if (contains_dollar_at) - *contains_dollar_at = 0; - - assignoff = -1; - - /* Begin the expansion. */ - - for (sindex = 0; ;) - { - c = string[sindex]; - - /* Case on top-level character. */ - switch (c) - { - case '\0': - goto finished_with_string; - - case CTLESC: - sindex++; -#if HANDLE_MULTIBYTE - if (mb_cur_max > 1 && string[sindex]) - { - SADD_MBQCHAR_BODY(temp, string, sindex, string_size); - } - else -#endif - { - temp = (char *)xmalloc (3); - temp[0] = CTLESC; - temp[1] = c = string[sindex]; - temp[2] = '\0'; - } - -dollar_add_string: - if (string[sindex]) - sindex++; - -add_string: - if (temp) - { - istring = sub_append_string (temp, istring, &istring_index, &istring_size); - temp = (char *)0; - } - - break; - -#if defined (PROCESS_SUBSTITUTION) - /* Process substitution. */ - case '<': - case '>': - { - /* XXX - technically this should only be expanded at the start - of a word */ - if (string[++sindex] != LPAREN || (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (word->flags & W_NOPROCSUB)) - { - sindex--; /* add_character: label increments sindex */ - goto add_character; - } - else - t_index = sindex + 1; /* skip past both '<' and LPAREN */ - - temp1 = extract_process_subst (string, (c == '<') ? "<(" : ">(", &t_index, 0); /*))*/ - sindex = t_index; - - /* If the process substitution specification is `<()', we want to - open the pipe for writing in the child and produce output; if - it is `>()', we want to open the pipe for reading in the child - and consume input. */ - temp = temp1 ? process_substitute (temp1, (c == '>')) : (char *)0; - - FREE (temp1); - - goto dollar_add_string; - } -#endif /* PROCESS_SUBSTITUTION */ - -#if defined (ARRAY_VARS) - case '[': /*]*/ - if ((quoted & Q_ARITH) == 0 || shell_compatibility_level <= 51) - { - if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c) && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0) - goto add_ifs_character; - else - goto add_character; - } - else - { - temp = expand_array_subscript (string, &sindex, quoted, word->flags); - goto add_string; - } -#endif - - case '=': - /* Posix.2 section 3.6.1 says that tildes following `=' in words - which are not assignment statements are not expanded. If the - shell isn't in posix mode, though, we perform tilde expansion - on `likely candidate' unquoted assignment statements (flags - include W_ASSIGNMENT but not W_QUOTED). A likely candidate - contains an unquoted :~ or =~. Something to think about: we - now have a flag that says to perform tilde expansion on arguments - to `assignment builtins' like declare and export that look like - assignment statements. We now do tilde expansion on such words - even in POSIX mode. */ - if (word->flags & (W_ASSIGNRHS|W_NOTILDE)) - { - if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c)) - goto add_ifs_character; - else - goto add_character; - } - /* If we're not in posix mode or forcing assignment-statement tilde - expansion, note where the first `=' appears in the word and prepare - to do tilde expansion following the first `='. We have to keep - track of the first `=' (using assignoff) to avoid being confused - by an `=' in the rhs of the assignment statement. */ - if ((word->flags & W_ASSIGNMENT) && - (posixly_correct == 0 || (word->flags & W_TILDEEXP)) && - assignoff == -1 && sindex > 0) - assignoff = sindex; - if (sindex == assignoff && string[sindex+1] == '~') /* XXX */ - internal_tilde = 1; - - if (word->flags & W_ASSIGNARG) - word->flags |= W_ASSIGNRHS; /* affects $@ */ - - if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c)) - { - has_quoted_ifs++; - goto add_ifs_character; - } - else - goto add_character; - - case ':': - if (word->flags & (W_NOTILDE|W_NOASSNTILDE)) - { - if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c)) - goto add_ifs_character; - else - goto add_character; - } - - if ((word->flags & (W_ASSIGNMENT|W_ASSIGNRHS)) && - (posixly_correct == 0 || (word->flags & W_TILDEEXP)) && - string[sindex+1] == '~') - internal_tilde = 1; - - if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c)) - goto add_ifs_character; - else - goto add_character; - - case '~': - /* If the word isn't supposed to be tilde expanded, or we're not - at the start of a word or after an unquoted : or = in an - assignment statement, we don't do tilde expansion. We don't - do tilde expansion if quoted or in an arithmetic context. */ - - if ((word->flags & W_NOTILDE) || - (sindex > 0 && (internal_tilde == 0)) || - (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) - { - internal_tilde = 0; - if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c) && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0) - goto add_ifs_character; - else - goto add_character; - } - - if (word->flags & W_ASSIGNRHS) - tflag = 2; - else if (word->flags & (W_ASSIGNMENT|W_TILDEEXP)) - tflag = 1; - else - tflag = 0; - - temp = bash_tilde_find_word (string + sindex, tflag, &t_index); - - internal_tilde = 0; - - if (temp && *temp && t_index > 0) - { - temp1 = bash_tilde_expand (temp, tflag); - if (temp1 && *temp1 == '~' && STREQ (temp, temp1)) - { - FREE (temp); - FREE (temp1); - goto add_character; /* tilde expansion failed */ - } - free (temp); - temp = temp1; - sindex += t_index; - goto add_quoted_string; /* XXX was add_string */ - } - else - { - FREE (temp); - goto add_character; - } - - case '$': - if (expanded_something) - *expanded_something = 1; - local_expanded = 1; - - temp_has_dollar_at = 0; - pflags = (word->flags & W_NOCOMSUB) ? PF_NOCOMSUB : 0; - if (word->flags & W_NOSPLIT2) - pflags |= PF_NOSPLIT2; - if (word->flags & W_ASSIGNRHS) - pflags |= PF_ASSIGNRHS; - if (word->flags & W_COMPLETE) - pflags |= PF_COMPLETE; - - tword = param_expand (string, &sindex, quoted, expanded_something, - &temp_has_dollar_at, "ed_dollar_at, - &had_quoted_null, pflags); - has_dollar_at += temp_has_dollar_at; - split_on_spaces += (tword->flags & W_SPLITSPACE); - - if (tword == &expand_wdesc_error || tword == &expand_wdesc_fatal) - { - free (string); - free (istring); - return ((tword == &expand_wdesc_error) ? &expand_word_error - : &expand_word_fatal); - } - if (contains_dollar_at && has_dollar_at) - *contains_dollar_at = 1; - - if (tword && (tword->flags & W_HASQUOTEDNULL)) - had_quoted_null = 1; /* note for later */ - if (tword && (tword->flags & W_SAWQUOTEDNULL)) - had_quoted_null = 1; /* XXX */ - - temp = tword ? tword->word : (char *)NULL; - dispose_word_desc (tword); - - /* Kill quoted nulls; we will add them back at the end of - expand_word_internal if nothing else in the string */ - if (had_quoted_null && temp && QUOTED_NULL (temp)) - { - FREE (temp); - temp = (char *)NULL; - } - - goto add_string; - break; - - case '`': /* Backquoted command substitution. */ - { - t_index = sindex++; - - temp = string_extract (string, &sindex, "`", (word->flags & W_COMPLETE) ? SX_COMPLETE : SX_REQMATCH); - /* The test of sindex against t_index is to allow bare instances of - ` to pass through, for backwards compatibility. */ - if (temp == &extract_string_error || temp == &extract_string_fatal) - { - if (sindex - 1 == t_index) - { - sindex = t_index; - goto add_character; - } - set_exit_status (EXECUTION_FAILURE); - report_error (_("bad substitution: no closing \"`\" in %s") , string+t_index); - free (string); - free (istring); - return ((temp == &extract_string_error) ? &expand_word_error - : &expand_word_fatal); - } - - if (expanded_something) - *expanded_something = 1; - local_expanded = 1; - - if (word->flags & W_NOCOMSUB) - /* sindex + 1 because string[sindex] == '`' */ - temp1 = substring (string, t_index, sindex + 1); - else - { - de_backslash (temp); - tword = command_substitute (temp, quoted, 0); - temp1 = tword ? tword->word : (char *)NULL; - if (tword) - dispose_word_desc (tword); - } - FREE (temp); - temp = temp1; - goto dollar_add_string; - } - - case '\\': - if (string[sindex + 1] == '\n') - { - sindex += 2; - continue; - } - - c = string[++sindex]; - - /* "However, the double-quote character ( '"' ) shall not be treated - specially within a here-document, except when the double-quote - appears within "$()", "``", or "${}"." */ - if ((quoted & Q_HERE_DOCUMENT) && (quoted & Q_DOLBRACE) && c == '"') - tflag = CBSDQUOTE; /* special case */ - else if (quoted & Q_HERE_DOCUMENT) - tflag = CBSHDOC; - else if (quoted & Q_DOUBLE_QUOTES) - tflag = CBSDQUOTE; - else - tflag = 0; - - /* From Posix discussion on austin-group list: Backslash escaping - a } in ${...} is removed. Issue 0000221 */ - if ((quoted & Q_DOLBRACE) && c == RBRACE) - { - SCOPY_CHAR_I (twochars, CTLESC, c, string, sindex, string_size); - } - /* This is the fix for " $@\ " */ - else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && ((sh_syntaxtab[c] & tflag) == 0) && isexp == 0 && isifs (c)) - { - RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size, - DEFAULT_ARRAY_SIZE); - istring[istring_index++] = CTLESC; - istring[istring_index++] = '\\'; - istring[istring_index] = '\0'; - - SCOPY_CHAR_I (twochars, CTLESC, c, string, sindex, string_size); - } - else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && c == 0) - { - RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size, - DEFAULT_ARRAY_SIZE); - istring[istring_index++] = CTLESC; - istring[istring_index++] = '\\'; - istring[istring_index] = '\0'; - break; - } - else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && ((sh_syntaxtab[c] & tflag) == 0)) - { - SCOPY_CHAR_I (twochars, '\\', c, string, sindex, string_size); - } - else if (c == 0) - { - c = CTLNUL; - sindex--; /* add_character: label increments sindex */ - goto add_character; - } - else - { - SCOPY_CHAR_I (twochars, CTLESC, c, string, sindex, string_size); - } - - sindex++; -add_twochars: - /* BEFORE jumping here, we need to increment sindex if appropriate */ - RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size, - DEFAULT_ARRAY_SIZE); - istring[istring_index++] = twochars[0]; - istring[istring_index++] = twochars[1]; - istring[istring_index] = '\0'; - - break; - - case '"': - /* XXX - revisit this */ - if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) && ((quoted & Q_ARITH) == 0)) - goto add_character; - - t_index = ++sindex; - temp = string_extract_double_quoted (string, &sindex, (word->flags & W_COMPLETE) ? SX_COMPLETE : 0); - - /* If the quotes surrounded the entire string, then the - whole word was quoted. */ - quoted_state = (t_index == 1 && string[sindex] == '\0') - ? WHOLLY_QUOTED - : PARTIALLY_QUOTED; - - if (temp && *temp) - { - tword = alloc_word_desc (); - tword->word = temp; - - if (word->flags & W_ASSIGNARG) - tword->flags |= word->flags & (W_ASSIGNARG|W_ASSIGNRHS); /* affects $@ */ - if (word->flags & W_COMPLETE) - tword->flags |= W_COMPLETE; /* for command substitutions */ - if (word->flags & W_NOCOMSUB) - tword->flags |= W_NOCOMSUB; - if (word->flags & W_NOPROCSUB) - tword->flags |= W_NOPROCSUB; - - if (word->flags & W_ASSIGNRHS) - tword->flags |= W_ASSIGNRHS; - - temp = (char *)NULL; - - temp_has_dollar_at = 0; /* does this quoted (sub)string include $@? */ - /* Need to get W_HASQUOTEDNULL flag through this function. */ - /* XXX - preserve Q_ARITH here? */ - list = expand_word_internal (tword, Q_DOUBLE_QUOTES|(quoted&Q_ARITH), 0, &temp_has_dollar_at, (int *)NULL); - has_dollar_at += temp_has_dollar_at; - - if (list == &expand_word_error || list == &expand_word_fatal) - { - free (istring); - free (string); - /* expand_word_internal has already freed temp_word->word - for us because of the way it prints error messages. */ - tword->word = (char *)NULL; - dispose_word (tword); - return list; - } - - dispose_word (tword); - - /* "$@" (a double-quoted dollar-at) expands into nothing, - not even a NULL word, when there are no positional - parameters. Posix interp 888 says that other parts of the - word that expand to quoted nulls result in quoted nulls, so - we can't just throw the entire word away if we have "$@" - anywhere in it. We use had_quoted_null to keep track */ - if (list == 0 && temp_has_dollar_at) /* XXX - was has_dollar_at */ - { - quoted_dollar_at++; - break; - } - - /* If this list comes back with a quoted null from expansion, - we have either "$x" or "$@" with $1 == ''. In either case, - we need to make sure we add a quoted null argument and - disable the special handling that "$@" gets. */ - if (list && list->word && list->next == 0 && (list->word->flags & W_HASQUOTEDNULL)) - { - if (had_quoted_null && temp_has_dollar_at) - quoted_dollar_at++; - had_quoted_null = 1; /* XXX */ - } - - /* If we get "$@", we know we have expanded something, so we - need to remember it for the final split on $IFS. This is - a special case; it's the only case where a quoted string - can expand into more than one word. It's going to come back - from the above call to expand_word_internal as a list with - multiple words. */ - if (list) - dequote_list (list); - - if (temp_has_dollar_at) /* XXX - was has_dollar_at */ - { - quoted_dollar_at++; - if (contains_dollar_at) - *contains_dollar_at = 1; - if (expanded_something) - *expanded_something = 1; - local_expanded = 1; - } - } - else - { - /* What we have is "". This is a minor optimization. */ - FREE (temp); - list = (WORD_LIST *)NULL; - had_quoted_null = 1; /* note for later */ - } - - /* The code above *might* return a list (consider the case of "$@", - where it returns "$1", "$2", etc.). We can't throw away the - rest of the list, and we have to make sure each word gets added - as quoted. We test on tresult->next: if it is non-NULL, we - quote the whole list, save it to a string with string_list, and - add that string. We don't need to quote the results of this - (and it would be wrong, since that would quote the separators - as well), so we go directly to add_string. */ - if (list) - { - if (list->next) - { - /* Testing quoted_dollar_at makes sure that "$@" is - split correctly when $IFS does not contain a space. */ - temp = quoted_dollar_at - ? string_list_dollar_at (list, Q_DOUBLE_QUOTES, 0) - : string_list (quote_list (list)); - dispose_words (list); - goto add_string; - } - else - { - temp = savestring (list->word->word); - tflag = list->word->flags; - dispose_words (list); - - /* If the string is not a quoted null string, we want - to remove any embedded unquoted CTLNUL characters. - We do not want to turn quoted null strings back into - the empty string, though. We do this because we - want to remove any quoted nulls from expansions that - contain other characters. For example, if we have - x"$*"y or "x$*y" and there are no positional parameters, - the $* should expand into nothing. */ - /* We use the W_HASQUOTEDNULL flag to differentiate the - cases: a quoted null character as above and when - CTLNUL is contained in the (non-null) expansion - of some variable. We use the had_quoted_null flag to - pass the value through this function to its caller. */ - if ((tflag & W_HASQUOTEDNULL) && QUOTED_NULL (temp) == 0) - remove_quoted_nulls (temp); /* XXX */ - } - } - else - temp = (char *)NULL; - - if (temp == 0 && quoted_state == PARTIALLY_QUOTED) - had_quoted_null = 1; /* note for later */ - - /* We do not want to add quoted nulls to strings that are only - partially quoted; we can throw them away. The exception to - this is when we are going to be performing word splitting, - since we have to preserve a null argument if the next character - will cause word splitting. */ - if (temp == 0 && quoted_state == PARTIALLY_QUOTED && quoted == 0 && (word->flags & (W_NOSPLIT|W_EXPANDRHS|W_ASSIGNRHS)) == W_EXPANDRHS) - { - c = CTLNUL; - sindex--; - had_quoted_null = 1; - goto add_character; - } - if (temp == 0 && quoted_state == PARTIALLY_QUOTED && (word->flags & (W_NOSPLIT|W_NOSPLIT2))) - continue; - - add_quoted_string: - - if (temp) - { - temp1 = temp; - temp = quote_string (temp); - free (temp1); - goto add_string; - } - else - { - /* Add NULL arg. */ - c = CTLNUL; - sindex--; /* add_character: label increments sindex */ - had_quoted_null = 1; /* note for later */ - goto add_character; - } - - /* break; */ - - case '\'': - if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) - goto add_character; - - t_index = ++sindex; - temp = string_extract_single_quoted (string, &sindex, 0); - - /* If the entire STRING was surrounded by single quotes, - then the string is wholly quoted. */ - quoted_state = (t_index == 1 && string[sindex] == '\0') - ? WHOLLY_QUOTED - : PARTIALLY_QUOTED; - - /* If all we had was '', it is a null expansion. */ - if (*temp == '\0') - { - free (temp); - temp = (char *)NULL; - } - else - remove_quoted_escapes (temp); /* ??? */ - - if (temp == 0 && quoted_state == PARTIALLY_QUOTED) - had_quoted_null = 1; /* note for later */ - - /* We do not want to add quoted nulls to strings that are only - partially quoted; such nulls are discarded. See above for the - exception, which is when the string is going to be split. - Posix interp 888/1129 */ - if (temp == 0 && quoted_state == PARTIALLY_QUOTED && quoted == 0 && (word->flags & (W_NOSPLIT|W_EXPANDRHS|W_ASSIGNRHS)) == W_EXPANDRHS) - { - c = CTLNUL; - sindex--; - goto add_character; - } - - if (temp == 0 && (quoted_state == PARTIALLY_QUOTED) && (word->flags & (W_NOSPLIT|W_NOSPLIT2))) - continue; - - /* If we have a quoted null expansion, add a quoted NULL to istring. */ - if (temp == 0) - { - c = CTLNUL; - sindex--; /* add_character: label increments sindex */ - goto add_character; - } - else - goto add_quoted_string; - - /* break; */ - - case ' ': - /* If we are in a context where the word is not going to be split, but - we need to account for $@ and $* producing one word for each - positional parameter, add quoted spaces so the spaces in the - expansion of "$@", if any, behave correctly. We still may need to - split if we are expanding the rhs of a word expansion. */ - if (ifs_is_null || split_on_spaces || ((word->flags & (W_NOSPLIT|W_NOSPLIT2|W_ASSIGNRHS)) && (word->flags & W_EXPANDRHS) == 0)) - { - if (string[sindex]) - sindex++; - twochars[0] = CTLESC; - twochars[1] = c; - goto add_twochars; - } - /* FALLTHROUGH */ - - default: - /* This is the fix for " $@ " */ -add_ifs_character: - if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (isexp == 0 && isifs (c) && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0)) - { - if ((quoted&(Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0) - has_quoted_ifs++; -add_quoted_character: - if (string[sindex]) /* from old goto dollar_add_string */ - sindex++; - if (c == 0) - { - c = CTLNUL; - goto add_character; - } - else - { -#if HANDLE_MULTIBYTE - /* XXX - should make sure that c is actually multibyte, - otherwise we can use the twochars branch */ - if (mb_cur_max > 1) - sindex--; - - if (mb_cur_max > 1) - { - SADD_MBQCHAR_BODY(temp, string, sindex, string_size); - } - else -#endif - { - twochars[0] = CTLESC; - twochars[1] = c; - goto add_twochars; - } - } - } - - SADD_MBCHAR (temp, string, sindex, string_size); - -add_character: - RESIZE_MALLOCED_BUFFER (istring, istring_index, 1, istring_size, - DEFAULT_ARRAY_SIZE); - istring[istring_index++] = c; - istring[istring_index] = '\0'; - - /* Next character. */ - sindex++; - } - } - -finished_with_string: - /* OK, we're ready to return. If we have a quoted string, and - quoted_dollar_at is not set, we do no splitting at all; otherwise - we split on ' '. The routines that call this will handle what to - do if nothing has been expanded. */ - - /* Partially and wholly quoted strings which expand to the empty - string are retained as an empty arguments. Unquoted strings - which expand to the empty string are discarded. The single - exception is the case of expanding "$@" when there are no - positional parameters. In that case, we discard the expansion. */ - - /* Because of how the code that handles "" and '' in partially - quoted strings works, we need to make ISTRING into a QUOTED_NULL - if we saw quoting characters, but the expansion was empty. - "" and '' are tossed away before we get to this point when - processing partially quoted strings. This makes "" and $xxx"" - equivalent when xxx is unset. We also look to see whether we - saw a quoted null from a ${} expansion and add one back if we - need to. */ - - /* If we expand to nothing and there were no single or double quotes - in the word, we throw it away. Otherwise, we return a NULL word. - The single exception is for $@ surrounded by double quotes when - there are no positional parameters. In that case, we also throw - the word away. */ - - if (*istring == '\0') - { -#if 0 - if (quoted_dollar_at == 0 && (had_quoted_null || quoted_state == PARTIALLY_QUOTED)) -#else - if (had_quoted_null || (quoted_dollar_at == 0 && quoted_state == PARTIALLY_QUOTED)) -#endif - { - istring[0] = CTLNUL; - istring[1] = '\0'; - tword = alloc_word_desc (); - tword->word = istring; - istring = 0; /* avoid later free() */ - tword->flags |= W_HASQUOTEDNULL; /* XXX */ - list = make_word_list (tword, (WORD_LIST *)NULL); - if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) - tword->flags |= W_QUOTED; - } - /* According to sh, ksh, and Posix.2, if a word expands into nothing - and a double-quoted "$@" appears anywhere in it, then the entire - word is removed. */ - /* XXX - exception appears to be that quoted null strings result in - null arguments */ - else if (quoted_state == UNQUOTED || quoted_dollar_at) - list = (WORD_LIST *)NULL; - else - list = (WORD_LIST *)NULL; - } - else if (word->flags & W_NOSPLIT) - { - tword = alloc_word_desc (); - tword->word = istring; - if (had_quoted_null && QUOTED_NULL (istring)) - tword->flags |= W_HASQUOTEDNULL; - istring = 0; /* avoid later free() */ - if (word->flags & W_ASSIGNMENT) - tword->flags |= W_ASSIGNMENT; /* XXX */ - if (word->flags & W_COMPASSIGN) - tword->flags |= W_COMPASSIGN; /* XXX */ - if (word->flags & W_NOGLOB) - tword->flags |= W_NOGLOB; /* XXX */ - if (word->flags & W_NOBRACE) - tword->flags |= W_NOBRACE; /* XXX */ - if (word->flags & W_ARRAYREF) - tword->flags |= W_ARRAYREF; - if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) - tword->flags |= W_QUOTED; - list = make_word_list (tword, (WORD_LIST *)NULL); - } - else if (word->flags & W_ASSIGNRHS) - { - list = list_string (istring, "", quoted); - tword = list->word; - if (had_quoted_null && QUOTED_NULL (istring)) - tword->flags |= W_HASQUOTEDNULL; - free (list); - free (istring); - istring = 0; /* avoid later free() */ - goto set_word_flags; - } - else - { - char *ifs_chars; - - ifs_chars = (quoted_dollar_at || has_dollar_at) ? ifs_value : (char *)NULL; - - /* If we have $@, we need to split the results no matter what. If - IFS is unset or NULL, string_list_dollar_at has separated the - positional parameters with a space, so we split on space (we have - set ifs_chars to " \t\n" above if ifs is unset). If IFS is set, - string_list_dollar_at has separated the positional parameters - with the first character of $IFS, so we split on $IFS. If - SPLIT_ON_SPACES is set, we expanded $* (unquoted) with IFS either - unset or null, and we want to make sure that we split on spaces - regardless of what else has happened to IFS since the expansion, - or we expanded "$@" with IFS null and we need to split the positional - parameters into separate words. */ - if (split_on_spaces) - { - /* If IFS is not set, and the word is not quoted, we want to split - the individual words on $' \t\n'. We rely on previous steps to - quote the portions of the word that should not be split */ - if (ifs_is_set == 0) - list = list_string (istring, " \t\n", 1); /* XXX quoted == 1? */ - else - list = list_string (istring, " ", 1); /* XXX quoted == 1? */ - } - - /* If we have $@ (has_dollar_at != 0) and we are in a context where we - don't want to split the result (W_NOSPLIT2), and we are not quoted, - we have already separated the arguments with the first character of - $IFS. In this case, we want to return a list with a single word - with the separator possibly replaced with a space (it's what other - shells seem to do). - quoted_dollar_at is internal to this function and is set if we are - passed an argument that is unquoted (quoted == 0) but we encounter a - double-quoted $@ while expanding it. */ - else if (has_dollar_at && quoted_dollar_at == 0 && ifs_chars && quoted == 0 && (word->flags & W_NOSPLIT2)) - { - tword = alloc_word_desc (); - /* Only split and rejoin if we have to */ - if (*ifs_chars && *ifs_chars != ' ') - { - /* list_string dequotes CTLESCs in the string it's passed, so we - need it to get the space separation right if space isn't the - first character in IFS (but is present) and to remove the - quoting we added back in param_expand(). */ - list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1); - /* This isn't exactly right in the case where we're expanding - the RHS of an expansion like ${var-$@} where IFS=: (for - example). The W_NOSPLIT2 means we do the separation with :; - the list_string removes the quotes and breaks the string into - a list, and the string_list rejoins it on spaces. When we - return, we expect to be able to split the results, but the - space separation means the right split doesn't happen. */ - tword->word = string_list (list); - } - else - tword->word = istring; - if (had_quoted_null && QUOTED_NULL (istring)) - tword->flags |= W_HASQUOTEDNULL; /* XXX */ - if (tword->word != istring) - free (istring); - istring = 0; /* avoid later free() */ - goto set_word_flags; - } - else if (has_dollar_at && ifs_chars) - list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1); - else - { - tword = alloc_word_desc (); - if (expanded_something && *expanded_something == 0 && has_quoted_ifs) - tword->word = remove_quoted_ifs (istring); - else - tword->word = istring; - if (had_quoted_null && QUOTED_NULL (istring)) /* should check for more than one */ - tword->flags |= W_HASQUOTEDNULL; /* XXX */ - else if (had_quoted_null) - tword->flags |= W_SAWQUOTEDNULL; /* XXX */ - if (tword->word != istring) - free (istring); - istring = 0; /* avoid later free() */ -set_word_flags: - if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (quoted_state == WHOLLY_QUOTED)) - tword->flags |= W_QUOTED; - if (word->flags & W_ASSIGNMENT) - tword->flags |= W_ASSIGNMENT; - if (word->flags & W_COMPASSIGN) - tword->flags |= W_COMPASSIGN; - if (word->flags & W_NOGLOB) - tword->flags |= W_NOGLOB; - if (word->flags & W_NOBRACE) - tword->flags |= W_NOBRACE; - if (word->flags & W_ARRAYREF) - tword->flags |= W_ARRAYREF; - list = make_word_list (tword, (WORD_LIST *)NULL); - } - } - - free (istring); - return (list); -} - -/* **************************************************************** */ -/* */ -/* Functions for Quote Removal */ -/* */ -/* **************************************************************** */ - -/* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the - backslash quoting rules for within double quotes or a here document. */ -char * -string_quote_removal (string, quoted) - char *string; - int quoted; -{ - size_t slen; - char *r, *result_string, *temp, *send; - int sindex, tindex, dquote; - unsigned char c; - DECLARE_MBSTATE; - - /* The result can be no longer than the original string. */ - slen = strlen (string); - send = string + slen; - - r = result_string = (char *)xmalloc (slen + 1); - - for (dquote = sindex = 0; c = string[sindex];) - { - switch (c) - { - case '\\': - c = string[++sindex]; - if (c == 0) - { - *r++ = '\\'; - break; - } - if (((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote) && (sh_syntaxtab[c] & CBSDQUOTE) == 0) - *r++ = '\\'; - /* FALLTHROUGH */ - - default: - SCOPY_CHAR_M (r, string, send, sindex); - break; - - case '\'': - if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote) - { - *r++ = c; - sindex++; - break; - } - tindex = sindex + 1; - temp = string_extract_single_quoted (string, &tindex, 0); - if (temp) - { - strcpy (r, temp); - r += strlen (r); - free (temp); - } - sindex = tindex; - break; - - case '"': - dquote = 1 - dquote; - sindex++; - break; - } - } - *r = '\0'; - return (result_string); -} - -#if 0 -/* UNUSED */ -/* Perform quote removal on word WORD. This allocates and returns a new - WORD_DESC *. */ -WORD_DESC * -word_quote_removal (word, quoted) - WORD_DESC *word; - int quoted; -{ - WORD_DESC *w; - char *t; - - t = string_quote_removal (word->word, quoted); - w = alloc_word_desc (); - w->word = t ? t : savestring (""); - return (w); -} - -/* Perform quote removal on all words in LIST. If QUOTED is non-zero, - the members of the list are treated as if they are surrounded by - double quotes. Return a new list, or NULL if LIST is NULL. */ -WORD_LIST * -word_list_quote_removal (list, quoted) - WORD_LIST *list; - int quoted; -{ - WORD_LIST *result, *t, *tresult, *e; - - for (t = list, result = (WORD_LIST *)NULL; t; t = t->next) - { - tresult = make_word_list (word_quote_removal (t->word, quoted), (WORD_LIST *)NULL); -#if 0 - result = (WORD_LIST *) list_append (result, tresult); -#else - if (result == 0) - result = e = tresult; - else - { - e->next = tresult; - while (e->next) - e = e->next; - } -#endif - } - return (result); -} -#endif - -/******************************************* - * * - * Functions to perform word splitting * - * * - *******************************************/ - -void -setifs (v) - SHELL_VAR *v; -{ - char *t; - unsigned char uc; - - ifs_var = v; - ifs_value = (v && value_cell (v)) ? value_cell (v) : " \t\n"; - - ifs_is_set = ifs_var != 0; - ifs_is_null = ifs_is_set && (*ifs_value == 0); - - /* Should really merge ifs_cmap with sh_syntaxtab. XXX - doesn't yet - handle multibyte chars in IFS */ - memset (ifs_cmap, '\0', sizeof (ifs_cmap)); - for (t = ifs_value ; t && *t; t++) - { - uc = *t; - ifs_cmap[uc] = 1; - } - -#if defined (HANDLE_MULTIBYTE) - if (ifs_value == 0) - { - ifs_firstc[0] = '\0'; /* XXX - ? */ - ifs_firstc_len = 1; - } - else - { - if (locale_utf8locale && UTF8_SINGLEBYTE (*ifs_value)) - ifs_firstc_len = (*ifs_value != 0) ? 1 : 0; - else - { - size_t ifs_len; - ifs_len = strnlen (ifs_value, MB_CUR_MAX); - ifs_firstc_len = MBLEN (ifs_value, ifs_len); - } - if (ifs_firstc_len == 1 || ifs_firstc_len == 0 || MB_INVALIDCH (ifs_firstc_len)) - { - ifs_firstc[0] = ifs_value[0]; - ifs_firstc[1] = '\0'; - ifs_firstc_len = 1; - } - else - memcpy (ifs_firstc, ifs_value, ifs_firstc_len); - } -#else - ifs_firstc = ifs_value ? *ifs_value : 0; -#endif -} - -char * -getifs () -{ - return ifs_value; -} - -/* This splits a single word into a WORD LIST on $IFS, but only if the word - is not quoted. list_string () performs quote removal for us, even if we - don't do any splitting. */ -WORD_LIST * -word_split (w, ifs_chars) - WORD_DESC *w; - char *ifs_chars; -{ - WORD_LIST *result; - - if (w) - { - char *xifs; - - xifs = ((w->flags & W_QUOTED) || ifs_chars == 0) ? "" : ifs_chars; - result = list_string (w->word, xifs, w->flags & W_QUOTED); - } - else - result = (WORD_LIST *)NULL; - - return (result); -} - -/* Perform word splitting on LIST and return the RESULT. It is possible - to return (WORD_LIST *)NULL. */ -static WORD_LIST * -word_list_split (list) - WORD_LIST *list; -{ - WORD_LIST *result, *t, *tresult, *e; - WORD_DESC *w; - - for (t = list, result = (WORD_LIST *)NULL; t; t = t->next) - { - tresult = word_split (t->word, ifs_value); - /* POSIX 2.6: "If the complete expansion appropriate for a word results - in an empty field, that empty field shall be deleted from the list - of fields that form the completely expanded command, unless the - original word contained single-quote or double-quote characters." - This is where we handle these words that contain quoted null strings - and other characters that expand to nothing after word splitting. */ - if (tresult == 0 && t->word && (t->word->flags & W_SAWQUOTEDNULL)) /* XXX */ - { - w = alloc_word_desc (); - w->word = (char *)xmalloc (1); - w->word[0] = '\0'; - tresult = make_word_list (w, (WORD_LIST *)NULL); - } -#if defined (ARRAY_VARS) - /* pass W_ARRAYREF through for words that are not split and are - identical to the original word. */ - if (tresult && tresult->next == 0 && t->next == 0 && (t->word->flags & W_ARRAYREF) && STREQ (t->word->word, tresult->word->word)) - tresult->word->flags |= W_ARRAYREF; -#endif - if (result == 0) - result = e = tresult; - else - { - e->next = tresult; - while (e->next) - e = e->next; - } - } - return (result); -} - -/************************************************** - * * - * Functions to expand an entire WORD_LIST * - * * - **************************************************/ - -/* Do any word-expansion-specific cleanup and jump to top_level */ -static void -exp_jump_to_top_level (v) - int v; -{ - set_pipestatus_from_exit (last_command_exit_value); - - /* Cleanup code goes here. */ - expand_no_split_dollar_star = 0; /* XXX */ - if (expanding_redir) - undo_partial_redirects (); - expanding_redir = 0; - assigning_in_environment = 0; - - if (parse_and_execute_level == 0) - top_level_cleanup (); /* from sig.c */ - - jump_to_top_level (v); -} - -/* Put NLIST (which is a WORD_LIST * of only one element) at the front of - ELIST, and set ELIST to the new list. */ -#define PREPEND_LIST(nlist, elist) \ - do { nlist->next = elist; elist = nlist; } while (0) - -/* Separate out any initial variable assignments from TLIST. If set -k has - been executed, remove all assignment statements from TLIST. Initial - variable assignments and other environment assignments are placed - on SUBST_ASSIGN_VARLIST. */ -static WORD_LIST * -separate_out_assignments (tlist) - WORD_LIST *tlist; -{ - register WORD_LIST *vp, *lp; - - if (tlist == 0) - return ((WORD_LIST *)NULL); - - if (subst_assign_varlist) - dispose_words (subst_assign_varlist); /* Clean up after previous error */ - - subst_assign_varlist = (WORD_LIST *)NULL; - vp = lp = tlist; - - /* Separate out variable assignments at the start of the command. - Loop invariant: vp->next == lp - Loop postcondition: - lp = list of words left after assignment statements skipped - tlist = original list of words - */ - while (lp && (lp->word->flags & W_ASSIGNMENT)) - { - vp = lp; - lp = lp->next; - } - - /* If lp != tlist, we have some initial assignment statements. - We make SUBST_ASSIGN_VARLIST point to the list of assignment - words and TLIST point to the remaining words. */ - if (lp != tlist) - { - subst_assign_varlist = tlist; - /* ASSERT(vp->next == lp); */ - vp->next = (WORD_LIST *)NULL; /* terminate variable list */ - tlist = lp; /* remainder of word list */ - } - - /* vp == end of variable list */ - /* tlist == remainder of original word list without variable assignments */ - if (!tlist) - /* All the words in tlist were assignment statements */ - return ((WORD_LIST *)NULL); - - /* ASSERT(tlist != NULL); */ - /* ASSERT((tlist->word->flags & W_ASSIGNMENT) == 0); */ - - /* If the -k option is in effect, we need to go through the remaining - words, separate out the assignment words, and place them on - SUBST_ASSIGN_VARLIST. */ - if (place_keywords_in_env) - { - WORD_LIST *tp; /* tp == running pointer into tlist */ - - tp = tlist; - lp = tlist->next; - - /* Loop Invariant: tp->next == lp */ - /* Loop postcondition: tlist == word list without assignment statements */ - while (lp) - { - if (lp->word->flags & W_ASSIGNMENT) - { - /* Found an assignment statement, add this word to end of - subst_assign_varlist (vp). */ - if (!subst_assign_varlist) - subst_assign_varlist = vp = lp; - else - { - vp->next = lp; - vp = lp; - } - - /* Remove the word pointed to by LP from TLIST. */ - tp->next = lp->next; - /* ASSERT(vp == lp); */ - lp->next = (WORD_LIST *)NULL; - lp = tp->next; - } - else - { - tp = lp; - lp = lp->next; - } - } - } - return (tlist); -} - -#define WEXP_VARASSIGN 0x001 -#define WEXP_BRACEEXP 0x002 -#define WEXP_TILDEEXP 0x004 -#define WEXP_PARAMEXP 0x008 -#define WEXP_PATHEXP 0x010 - -/* All of the expansions, including variable assignments at the start of - the list. */ -#define WEXP_ALL (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP) - -/* All of the expansions except variable assignments at the start of - the list. */ -#define WEXP_NOVARS (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP) - -/* All of the `shell expansions': brace expansion, tilde expansion, parameter - expansion, command substitution, arithmetic expansion, word splitting, and - quote removal. */ -#define WEXP_SHELLEXP (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP) - -/* Take the list of words in LIST and do the various substitutions. Return - a new list of words which is the expanded list, and without things like - variable assignments. */ - -WORD_LIST * -expand_words (list) - WORD_LIST *list; -{ - return (expand_word_list_internal (list, WEXP_ALL)); -} - -/* Same as expand_words (), but doesn't hack variable or environment - variables. */ -WORD_LIST * -expand_words_no_vars (list) - WORD_LIST *list; -{ - return (expand_word_list_internal (list, WEXP_NOVARS)); -} - -WORD_LIST * -expand_words_shellexp (list) - WORD_LIST *list; -{ - return (expand_word_list_internal (list, WEXP_SHELLEXP)); -} - -static WORD_LIST * -glob_expand_word_list (tlist, eflags) - WORD_LIST *tlist; - int eflags; -{ - char **glob_array, *temp_string; - register int glob_index; - WORD_LIST *glob_list, *output_list, *disposables, *next; - WORD_DESC *tword; - int x; - - output_list = disposables = (WORD_LIST *)NULL; - glob_array = (char **)NULL; - while (tlist) - { - /* For each word, either globbing is attempted or the word is - added to orig_list. If globbing succeeds, the results are - added to orig_list and the word (tlist) is added to the list - of disposable words. If globbing fails and failed glob - expansions are left unchanged (the shell default), the - original word is added to orig_list. If globbing fails and - failed glob expansions are removed, the original word is - added to the list of disposable words. orig_list ends up - in reverse order and requires a call to REVERSE_LIST to - be set right. After all words are examined, the disposable - words are freed. */ - next = tlist->next; - - /* If the word isn't an assignment and contains an unquoted - pattern matching character, then glob it. */ - if ((tlist->word->flags & W_NOGLOB) == 0 && - unquoted_glob_pattern_p (tlist->word->word)) - { - glob_array = shell_glob_filename (tlist->word->word, QGLOB_CTLESC); /* XXX */ - - /* Handle error cases. - I don't think we should report errors like "No such file - or directory". However, I would like to report errors - like "Read failed". */ - - if (glob_array == 0 || GLOB_FAILED (glob_array)) - { - glob_array = (char **)xmalloc (sizeof (char *)); - glob_array[0] = (char *)NULL; - } - - /* Dequote the current word in case we have to use it. */ - if (glob_array[0] == NULL) - { - temp_string = dequote_string (tlist->word->word); - free (tlist->word->word); - tlist->word->word = temp_string; - } - - /* Make the array into a word list. */ - glob_list = (WORD_LIST *)NULL; - for (glob_index = 0; glob_array[glob_index]; glob_index++) - { - tword = make_bare_word (glob_array[glob_index]); - glob_list = make_word_list (tword, glob_list); - } - - if (glob_list) - { - output_list = (WORD_LIST *)list_append (glob_list, output_list); - PREPEND_LIST (tlist, disposables); - } - else if (fail_glob_expansion != 0) - { - last_command_exit_value = EXECUTION_FAILURE; - report_error (_("no match: %s"), tlist->word->word); - exp_jump_to_top_level (DISCARD); - } - else if (allow_null_glob_expansion == 0) - { - /* Failed glob expressions are left unchanged. */ - PREPEND_LIST (tlist, output_list); - } - else - { - /* Failed glob expressions are removed. */ - PREPEND_LIST (tlist, disposables); - } - } - else - { - /* Dequote the string. */ - temp_string = dequote_string (tlist->word->word); - free (tlist->word->word); - tlist->word->word = temp_string; - PREPEND_LIST (tlist, output_list); - } - - strvec_dispose (glob_array); - glob_array = (char **)NULL; - - tlist = next; - } - - if (disposables) - dispose_words (disposables); - - if (output_list) - output_list = REVERSE_LIST (output_list, WORD_LIST *); - - return (output_list); -} - -#if defined (BRACE_EXPANSION) -static WORD_LIST * -brace_expand_word_list (tlist, eflags) - WORD_LIST *tlist; - int eflags; -{ - register char **expansions; - char *temp_string; - WORD_LIST *disposables, *output_list, *next; - WORD_DESC *w; - int eindex; - - for (disposables = output_list = (WORD_LIST *)NULL; tlist; tlist = next) - { - next = tlist->next; - - if (tlist->word->flags & W_NOBRACE) - { -/*itrace("brace_expand_word_list: %s: W_NOBRACE", tlist->word->word);*/ - PREPEND_LIST (tlist, output_list); - continue; - } - - if ((tlist->word->flags & (W_COMPASSIGN|W_ASSIGNARG)) == (W_COMPASSIGN|W_ASSIGNARG)) - { -/*itrace("brace_expand_word_list: %s: W_COMPASSIGN|W_ASSIGNARG", tlist->word->word);*/ - PREPEND_LIST (tlist, output_list); - continue; - } - - /* Only do brace expansion if the word has a brace character. If - not, just add the word list element to BRACES and continue. In - the common case, at least when running shell scripts, this will - degenerate to a bunch of calls to `mbschr', and then what is - basically a reversal of TLIST into BRACES, which is corrected - by a call to REVERSE_LIST () on BRACES when the end of TLIST - is reached. */ - if (mbschr (tlist->word->word, LBRACE)) - { - expansions = brace_expand (tlist->word->word); - - for (eindex = 0; temp_string = expansions[eindex]; eindex++) - { - w = alloc_word_desc (); - w->word = temp_string; - - /* If brace expansion didn't change the word, preserve - the flags. We may want to preserve the flags - unconditionally someday -- XXX */ - if (STREQ (temp_string, tlist->word->word)) - w->flags = tlist->word->flags; - else - w = make_word_flags (w, temp_string); - - output_list = make_word_list (w, output_list); - } - free (expansions); - - /* Add TLIST to the list of words to be freed after brace - expansion has been performed. */ - PREPEND_LIST (tlist, disposables); - } - else - PREPEND_LIST (tlist, output_list); - } - - if (disposables) - dispose_words (disposables); - - if (output_list) - output_list = REVERSE_LIST (output_list, WORD_LIST *); - - return (output_list); -} -#endif - -#if defined (ARRAY_VARS) -/* Take WORD, a compound array assignment, and internally run (for example), - 'declare -A w', where W is the variable name portion of WORD. OPTION is - the list of options to supply to `declare'. CMD is the declaration command - we are expanding right now; it's unused currently. */ -static int -make_internal_declare (word, option, cmd) - char *word; - char *option; - char *cmd; -{ - int t, r; - WORD_LIST *wl; - WORD_DESC *w; - - w = make_word (word); - - t = assignment (w->word, 0); - if (w->word[t] == '=') - { - w->word[t] = '\0'; - if (w->word[t - 1] == '+') /* cut off any append op */ - w->word[t - 1] = '\0'; - } - - wl = make_word_list (w, (WORD_LIST *)NULL); - wl = make_word_list (make_word (option), wl); - - r = declare_builtin (wl); - - dispose_words (wl); - return r; -} - -/* Expand VALUE in NAME[+]=( VALUE ) to a list of words. FLAGS is 1 if NAME - is an associative array. - - If we are processing an indexed array, expand_compound_array_assignment - will expand all the individual words and quote_compound_array_list will - single-quote them. If we are processing an associative array, we use - parse_string_to_word_list to split VALUE into a list of words instead of - faking up a shell variable and calling expand_compound_array_assignment. - expand_and_quote_assoc_word expands and single-quotes each word in VALUE - together so we don't have problems finding the end of the subscript when - quoting it. - - Words in VALUE can be individual words, which are expanded and single-quoted, - or words of the form [IND]=VALUE, which end up as explained below, as - ['expanded-ind']='expanded-value'. */ - -static WORD_LIST * -expand_oneword (value, flags) - char *value; - int flags; -{ - WORD_LIST *l, *nl; - char *t; - int kvpair; - - if (flags == 0) - { - /* Indexed array */ - l = expand_compound_array_assignment ((SHELL_VAR *)NULL, value, flags); - /* Now we quote the results of the expansion above to prevent double - expansion. */ - quote_compound_array_list (l, flags); - return l; - } - else - { - /* Associative array */ - l = parse_string_to_word_list (value, 1, "array assign"); -#if ASSOC_KVPAIR_ASSIGNMENT - kvpair = kvpair_assignment_p (l); -#endif - - /* For associative arrays, with their arbitrary subscripts, we have to - expand and quote in one step so we don't have to search for the - closing right bracket more than once. */ - for (nl = l; nl; nl = nl->next) - { -#if ASSOC_KVPAIR_ASSIGNMENT - if (kvpair) - /* keys and values undergo the same set of expansions */ - t = expand_and_quote_kvpair_word (nl->word->word); - else -#endif - if ((nl->word->flags & W_ASSIGNMENT) == 0) - t = sh_single_quote (nl->word->word ? nl->word->word : ""); - else - t = expand_and_quote_assoc_word (nl->word->word, flags); - free (nl->word->word); - nl->word->word = t; - } - return l; - } -} - -/* Expand a single compound assignment argument to a declaration builtin. - This word takes the form NAME[+]=( VALUE ). The NAME[+]= is passed through - unchanged. The VALUE is expanded and each word in the result is single- - quoted. Words of the form [key]=value end up as - ['expanded-key']='expanded-value'. Associative arrays have special - handling, see expand_oneword() above. The return value is - NAME[+]=( expanded-and-quoted-VALUE ). */ -static void -expand_compound_assignment_word (tlist, flags) - WORD_LIST *tlist; - int flags; -{ - WORD_LIST *l; - int wlen, oind, t; - char *value, *temp; - -/*itrace("expand_compound_assignment_word: original word = -%s-", tlist->word->word);*/ - t = assignment (tlist->word->word, 0); - - /* value doesn't have the open and close parens */ - oind = 1; - value = extract_array_assignment_list (tlist->word->word + t + 1, &oind); - /* This performs one round of expansion on the index/key and value and - single-quotes each word in the result. */ - l = expand_oneword (value, flags); - free (value); - - value = string_list (l); - dispose_words (l); - - wlen = STRLEN (value); - - /* Now, let's rebuild the string */ - temp = xmalloc (t + 3 + wlen + 1); /* name[+]=(value) */ - memcpy (temp, tlist->word->word, ++t); - temp[t++] = '('; - if (value) - memcpy (temp + t, value, wlen); - t += wlen; - temp[t++] = ')'; - temp[t] = '\0'; -/*itrace("expand_compound_assignment_word: reconstructed word = -%s-", temp);*/ - - free (tlist->word->word); - tlist->word->word = temp; - - free (value); -} - -/* Expand and process an argument to a declaration command. We have already - set flags in TLIST->word->flags depending on the declaration command - (declare, local, etc.) and the options supplied to it (-a, -A, etc.). - TLIST->word->word is of the form NAME[+]=( VALUE ). - - This does several things, all using pieces of other functions to get the - evaluation sequence right. It's called for compound array assignments with - the W_ASSIGNMENT flag set (basically, valid identifier names on the lhs). - It parses out which flags need to be set for declare to create the variable - correctly, then calls declare internally (make_internal_declare) to make - sure the variable exists with the correct attributes. Before the variable - is created, it calls expand_compound_assignment_word to expand VALUE to a - list of words, appropriately quoted for further evaluation. This preserves - the semantics of word-expansion-before-calling-builtins. Finally, it calls - do_word_assignment to perform the expansion and assignment with the same - expansion semantics as a standalone assignment statement (no word splitting, - etc.) even though the word is single-quoted so all that needs to happen is - quote removal. */ -static WORD_LIST * -expand_declaration_argument (tlist, wcmd) - WORD_LIST *tlist, *wcmd; -{ - char opts[16], omap[128]; - int t, opti, oind, skip, inheriting; - WORD_LIST *l; - - inheriting = localvar_inherit; - opti = 0; - if (tlist->word->flags & (W_ASSIGNASSOC|W_ASSNGLOBAL|W_CHKLOCAL|W_ASSIGNARRAY)) - opts[opti++] = '-'; - - if ((tlist->word->flags & (W_ASSIGNASSOC|W_ASSNGLOBAL)) == (W_ASSIGNASSOC|W_ASSNGLOBAL)) - { - opts[opti++] = 'g'; - opts[opti++] = 'A'; - } - else if (tlist->word->flags & W_ASSIGNASSOC) - { - opts[opti++] = 'A'; - } - else if ((tlist->word->flags & (W_ASSIGNARRAY|W_ASSNGLOBAL)) == (W_ASSIGNARRAY|W_ASSNGLOBAL)) - { - opts[opti++] = 'g'; - opts[opti++] = 'a'; - } - else if (tlist->word->flags & W_ASSIGNARRAY) - { - opts[opti++] = 'a'; - } - else if (tlist->word->flags & W_ASSNGLOBAL) - opts[opti++] = 'g'; - - if (tlist->word->flags & W_CHKLOCAL) - opts[opti++] = 'G'; - - /* If we have special handling note the integer attribute and others - that transform the value upon assignment. What we do is take all - of the option arguments and scan through them looking for options - that cause such transformations, and add them to the `opts' array. */ - - memset (omap, '\0', sizeof (omap)); - for (l = wcmd->next; l != tlist; l = l->next) - { - int optchar; - - if (l->word->word[0] != '-' && l->word->word[0] != '+') - break; /* non-option argument */ - if (l->word->word[0] == '-' && l->word->word[1] == '-' && l->word->word[2] == 0) - break; /* -- signals end of options */ - optchar = l->word->word[0]; - for (oind = 1; l->word->word[oind]; oind++) - switch (l->word->word[oind]) - { - case 'I': - inheriting = 1; - case 'i': - case 'l': - case 'u': - case 'c': - omap[l->word->word[oind]] = 1; - if (opti == 0) - opts[opti++] = optchar; - break; - default: - break; - } - } - - for (oind = 0; oind < sizeof (omap); oind++) - if (omap[oind]) - opts[opti++] = oind; - - /* If there are no -a/-A options, but we have a compound assignment, - we have a choice: we can set opts[0]='-', opts[1]='a', since the - default is to create an indexed array, and call - make_internal_declare with that, or we can just skip the -a and let - declare_builtin deal with it. Once we're here, we're better set - up for the latter, since we don't want to deal with looking up - any existing variable here -- better to let declare_builtin do it. - We need the variable created, though, especially if it's local, so - we get the scoping right before we call do_word_assignment. - To ensure that make_local_declare gets called, we add `--' if there - aren't any options. */ - if ((tlist->word->flags & (W_ASSIGNASSOC|W_ASSIGNARRAY)) == 0) - { - if (opti == 0) - { - opts[opti++] = '-'; - opts[opti++] = '-'; - } - } - opts[opti] = '\0'; - - /* This isn't perfect, but it's a start. Improvements later. We expand - tlist->word->word and single-quote the results to avoid multiple - expansions by, say, do_assignment_internal(). We have to weigh the - cost of reconstructing the compound assignment string with its single - quoting and letting the declare builtin handle it. The single quotes - will prevent any unwanted additional expansion or word splitting. */ - expand_compound_assignment_word (tlist, (tlist->word->flags & W_ASSIGNASSOC) ? 1 : 0); - - skip = 0; - if (opti > 0) - { - t = make_internal_declare (tlist->word->word, opts, wcmd ? wcmd->word->word : (char *)0); - if (t != EXECUTION_SUCCESS) - { - last_command_exit_value = t; - if (tlist->word->flags & W_FORCELOCAL) /* non-fatal error */ - skip = 1; - else - exp_jump_to_top_level (DISCARD); - } - } - - if (skip == 0) - { - t = do_word_assignment (tlist->word, 0); - if (t == 0) - { - last_command_exit_value = EXECUTION_FAILURE; - exp_jump_to_top_level (DISCARD); - } - } - - /* Now transform the word as ksh93 appears to do and go on */ - t = assignment (tlist->word->word, 0); - tlist->word->word[t] = '\0'; - if (tlist->word->word[t - 1] == '+') - tlist->word->word[t - 1] = '\0'; /* cut off append op */ - tlist->word->flags &= ~(W_ASSIGNMENT|W_NOSPLIT|W_COMPASSIGN|W_ASSIGNARG|W_ASSIGNASSOC|W_ASSIGNARRAY); - - return (tlist); -} -#endif /* ARRAY_VARS */ - -static WORD_LIST * -shell_expand_word_list (tlist, eflags) - WORD_LIST *tlist; - int eflags; -{ - WORD_LIST *expanded, *orig_list, *new_list, *next, *temp_list, *wcmd; - int expanded_something, has_dollar_at; - - /* We do tilde expansion all the time. This is what 1003.2 says. */ - wcmd = new_list = (WORD_LIST *)NULL; - - for (orig_list = tlist; tlist; tlist = next) - { - if (wcmd == 0 && (tlist->word->flags & W_ASSNBLTIN)) - wcmd = tlist; - - next = tlist->next; - -#if defined (ARRAY_VARS) - /* If this is a compound array assignment to a builtin that accepts - such assignments (e.g., `declare'), take the assignment and perform - it separately, handling the semantics of declarations inside shell - functions. This avoids the double-evaluation of such arguments, - because `declare' does some evaluation of compound assignments on - its own. */ - if ((tlist->word->flags & (W_COMPASSIGN|W_ASSIGNARG)) == (W_COMPASSIGN|W_ASSIGNARG)) - expand_declaration_argument (tlist, wcmd); -#endif - - expanded_something = 0; - expanded = expand_word_internal - (tlist->word, 0, 0, &has_dollar_at, &expanded_something); - - if (expanded == &expand_word_error || expanded == &expand_word_fatal) - { - /* By convention, each time this error is returned, - tlist->word->word has already been freed. */ - tlist->word->word = (char *)NULL; - - /* Dispose our copy of the original list. */ - dispose_words (orig_list); - /* Dispose the new list we're building. */ - dispose_words (new_list); - - last_command_exit_value = EXECUTION_FAILURE; - if (expanded == &expand_word_error) - exp_jump_to_top_level (DISCARD); - else - exp_jump_to_top_level (FORCE_EOF); - } - - /* Don't split words marked W_NOSPLIT. */ - if (expanded_something && (tlist->word->flags & W_NOSPLIT) == 0) - { - temp_list = word_list_split (expanded); - dispose_words (expanded); - } - else - { - /* If no parameter expansion, command substitution, process - substitution, or arithmetic substitution took place, then - do not do word splitting. We still have to remove quoted - null characters from the result. */ - word_list_remove_quoted_nulls (expanded); - temp_list = expanded; - } - - expanded = REVERSE_LIST (temp_list, WORD_LIST *); - new_list = (WORD_LIST *)list_append (expanded, new_list); - } - - if (orig_list) - dispose_words (orig_list); - - if (new_list) - new_list = REVERSE_LIST (new_list, WORD_LIST *); - - return (new_list); -} - -/* Perform assignment statements optionally preceding a command name COMMAND. - If COMMAND == NULL, is_nullcmd usually == 1. Follow the POSIX rules for - variable assignment errors. */ -static int -do_assignment_statements (varlist, command, is_nullcmd) - WORD_LIST *varlist; - char *command; - int is_nullcmd; -{ - WORD_LIST *temp_list; - char *savecmd; - sh_wassign_func_t *assign_func; - int is_special_builtin, is_builtin_or_func, tint; - - /* If the remainder of the words expand to nothing, Posix.2 requires - that the variable and environment assignments affect the shell's - environment (do_word_assignment). */ - assign_func = is_nullcmd ? do_word_assignment : assign_in_env; - tempenv_assign_error = 0; - - is_builtin_or_func = command && (find_shell_builtin (command) || find_function (command)); - /* Posix says that special builtins exit if a variable assignment error - occurs in an assignment preceding it. (XXX - this is old -- current Posix - says that any variable assignment error causes a non-interactive shell - to exit. See the STRICT_POSIX checks below. */ - is_special_builtin = posixly_correct && command && find_special_builtin (command); - - savecmd = this_command_name; - for (temp_list = varlist; temp_list; temp_list = temp_list->next) - { - this_command_name = (char *)NULL; - assigning_in_environment = is_nullcmd == 0; - tint = (*assign_func) (temp_list->word, is_builtin_or_func); - assigning_in_environment = 0; - this_command_name = savecmd; - - /* Variable assignment errors in non-interactive shells running - in posix mode cause the shell to exit. */ - if (tint == 0) - { - if (is_nullcmd) /* assignment statement */ - { - last_command_exit_value = EXECUTION_FAILURE; -#if defined (STRICT_POSIX) - if (posixly_correct && interactive_shell == 0) -#else - if (posixly_correct && interactive_shell == 0 && executing_command_builtin == 0) -#endif - exp_jump_to_top_level (FORCE_EOF); - else - exp_jump_to_top_level (DISCARD); - } - /* In posix mode, assignment errors in the temporary environment - cause a non-interactive shell executing a special builtin to - exit and a non-interactive shell to otherwise jump back to the - top level. This is what POSIX says to do for variable assignment - errors, and POSIX says errors in assigning to the temporary - environment are treated as variable assignment errors. - (XXX - this is not what current POSIX says - look at the - STRICT_POSIX defines. */ - else if (posixly_correct) - { - last_command_exit_value = EXECUTION_FAILURE; -#if defined (STRICT_POSIX) - exp_jump_to_top_level ((interactive_shell == 0) ? FORCE_EOF : DISCARD); -#else - if (interactive_shell == 0 && is_special_builtin) - exp_jump_to_top_level (FORCE_EOF); - else if (interactive_shell == 0) - exp_jump_to_top_level (DISCARD); /* XXX - maybe change later */ - else - exp_jump_to_top_level (DISCARD); -#endif - } - else - tempenv_assign_error++; - } - } - return (tempenv_assign_error); -} - -/* The workhorse for expand_words () and expand_words_no_vars (). - First arg is LIST, a WORD_LIST of words. - Second arg EFLAGS is a flags word controlling which expansions are - performed. - - This does all of the substitutions: brace expansion, tilde expansion, - parameter expansion, command substitution, arithmetic expansion, - process substitution, word splitting, and pathname expansion, according - to the bits set in EFLAGS. Words with the W_QUOTED or W_NOSPLIT bits - set, or for which no expansion is done, do not undergo word splitting. - Words with the W_NOGLOB bit set do not undergo pathname expansion; words - with W_NOBRACE set do not undergo brace expansion (see - brace_expand_word_list above). */ -static WORD_LIST * -expand_word_list_internal (list, eflags) - WORD_LIST *list; - int eflags; -{ - WORD_LIST *new_list, *temp_list; - - tempenv_assign_error = 0; - if (list == 0) - return ((WORD_LIST *)NULL); - - garglist = new_list = copy_word_list (list); - if (eflags & WEXP_VARASSIGN) - { - garglist = new_list = separate_out_assignments (new_list); - if (new_list == 0) - { - if (subst_assign_varlist) - do_assignment_statements (subst_assign_varlist, (char *)NULL, 1); - - dispose_words (subst_assign_varlist); - subst_assign_varlist = (WORD_LIST *)NULL; - - return ((WORD_LIST *)NULL); - } - } - - /* Begin expanding the words that remain. The expansions take place on - things that aren't really variable assignments. */ - -#if defined (BRACE_EXPANSION) - /* Do brace expansion on this word if there are any brace characters - in the string. */ - if ((eflags & WEXP_BRACEEXP) && brace_expansion && new_list) - new_list = brace_expand_word_list (new_list, eflags); -#endif /* BRACE_EXPANSION */ - - /* Perform the `normal' shell expansions: tilde expansion, parameter and - variable substitution, command substitution, arithmetic expansion, - and word splitting. */ - new_list = shell_expand_word_list (new_list, eflags); - - /* Okay, we're almost done. Now let's just do some filename - globbing. */ - if (new_list) - { - if ((eflags & WEXP_PATHEXP) && disallow_filename_globbing == 0) - /* Glob expand the word list unless globbing has been disabled. */ - new_list = glob_expand_word_list (new_list, eflags); - else - /* Dequote the words, because we're not performing globbing. */ - new_list = dequote_list (new_list); - } - - if ((eflags & WEXP_VARASSIGN) && subst_assign_varlist) - { - do_assignment_statements (subst_assign_varlist, (new_list && new_list->word) ? new_list->word->word : (char *)NULL, new_list == 0); - - dispose_words (subst_assign_varlist); - subst_assign_varlist = (WORD_LIST *)NULL; - } - - return (new_list); -} diff --git a/third_party/bash/subst.h b/third_party/bash/subst.h deleted file mode 100644 index 28cc92031..000000000 --- a/third_party/bash/subst.h +++ /dev/null @@ -1,362 +0,0 @@ -/* subst.h -- Names of externally visible functions in subst.c. */ - -/* Copyright (C) 1993-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_SUBST_H_) -#define _SUBST_H_ - -#include "stdc.h" - -/* Constants which specify how to handle backslashes and quoting in - expand_word_internal (). Q_DOUBLE_QUOTES means to use the function - slashify_in_quotes () to decide whether the backslash should be - retained. Q_HERE_DOCUMENT means slashify_in_here_document () to - decide whether to retain the backslash. Q_KEEP_BACKSLASH means - to unconditionally retain the backslash. Q_PATQUOTE means that we're - expanding a pattern ${var%#[#%]pattern} in an expansion surrounded - by double quotes. Q_DOLBRACE means we are expanding a ${...} word, so - backslashes should also escape { and } and be removed. */ -#define Q_DOUBLE_QUOTES 0x001 -#define Q_HERE_DOCUMENT 0x002 -#define Q_KEEP_BACKSLASH 0x004 -#define Q_PATQUOTE 0x008 -#define Q_QUOTED 0x010 -#define Q_ADDEDQUOTES 0x020 -#define Q_QUOTEDNULL 0x040 -#define Q_DOLBRACE 0x080 -#define Q_ARITH 0x100 /* expanding string for arithmetic evaluation */ -#define Q_ARRAYSUB 0x200 /* expanding indexed array subscript */ - -/* Flag values controlling how assignment statements are treated. */ -#define ASS_APPEND 0x0001 -#define ASS_MKLOCAL 0x0002 -#define ASS_MKASSOC 0x0004 -#define ASS_MKGLOBAL 0x0008 /* force global assignment */ -#define ASS_NAMEREF 0x0010 /* assigning to nameref variable */ -#define ASS_FORCE 0x0020 /* force assignment even to readonly variable */ -#define ASS_CHKLOCAL 0x0040 /* check local variable before assignment */ -#define ASS_NOEXPAND 0x0080 /* don't expand associative array subscripts */ -#define ASS_NOEVAL 0x0100 /* don't evaluate value as expression */ -#define ASS_NOLONGJMP 0x0200 /* don't longjmp on fatal assignment error */ -#define ASS_NOINVIS 0x0400 /* don't resolve local invisible variables */ -#define ASS_ALLOWALLSUB 0x0800 /* allow * and @ as associative array keys */ -#define ASS_ONEWORD 0x1000 /* don't check array subscripts, assume higher level has done that */ - -/* Flags for the string extraction functions. */ -#define SX_NOALLOC 0x0001 /* just skip; don't return substring */ -#define SX_VARNAME 0x0002 /* variable name; for string_extract () */ -#define SX_REQMATCH 0x0004 /* closing/matching delimiter required */ -#define SX_COMMAND 0x0008 /* extracting a shell script/command */ -#define SX_NOCTLESC 0x0010 /* don't honor CTLESC quoting */ -#define SX_NOESCCTLNUL 0x0020 /* don't let CTLESC quote CTLNUL */ -#define SX_NOLONGJMP 0x0040 /* don't longjmp on fatal error */ -#define SX_ARITHSUB 0x0080 /* extracting $(( ... )) (currently unused) */ -#define SX_POSIXEXP 0x0100 /* extracting new Posix pattern removal expansions in extract_dollar_brace_string */ -#define SX_WORD 0x0200 /* extracting word in ${param op word} */ -#define SX_COMPLETE 0x0400 /* extracting word for completion */ -#define SX_STRIPDQ 0x0800 /* strip double quotes when extracting double-quoted string */ -#define SX_NOERROR 0x1000 /* don't print parser error messages */ - -/* Remove backslashes which are quoting backquotes from STRING. Modifies - STRING, and returns a pointer to it. */ -extern char * de_backslash PARAMS((char *)); - -/* Replace instances of \! in a string with !. */ -extern void unquote_bang PARAMS((char *)); - -/* Extract the $( construct in STRING, and return a new string. - Start extracting at (SINDEX) as if we had just seen "$(". - Make (SINDEX) get the position just after the matching ")". - XFLAGS is additional flags to pass to other extraction functions, */ -extern char *extract_command_subst PARAMS((char *, int *, int)); - -/* Extract the $[ construct in STRING, and return a new string. - Start extracting at (SINDEX) as if we had just seen "$[". - Make (SINDEX) get the position just after the matching "]". */ -extern char *extract_arithmetic_subst PARAMS((char *, int *)); - -#if defined (PROCESS_SUBSTITUTION) -/* Extract the <( or >( construct in STRING, and return a new string. - Start extracting at (SINDEX) as if we had just seen "<(". - Make (SINDEX) get the position just after the matching ")". */ -extern char *extract_process_subst PARAMS((char *, char *, int *, int)); -#endif /* PROCESS_SUBSTITUTION */ - -/* Extract the name of the variable to bind to from the assignment string. */ -extern char *assignment_name PARAMS((char *)); - -/* Return a single string of all the words present in LIST, separating - each word with SEP. */ -extern char *string_list_internal PARAMS((WORD_LIST *, char *)); - -/* Return a single string of all the words present in LIST, separating - each word with a space. */ -extern char *string_list PARAMS((WORD_LIST *)); - -/* Turn $* into a single string, obeying POSIX rules. */ -extern char *string_list_dollar_star PARAMS((WORD_LIST *, int, int)); - -/* Expand $@ into a single string, obeying POSIX rules. */ -extern char *string_list_dollar_at PARAMS((WORD_LIST *, int, int)); - -/* Turn the positional parameters into a string, understanding quoting and - the various subtleties of using the first character of $IFS as the - separator. Calls string_list_dollar_at, string_list_dollar_star, and - string_list as appropriate. */ -extern char *string_list_pos_params PARAMS((int, WORD_LIST *, int, int)); - -/* Perform quoted null character removal on each element of LIST. - This modifies LIST. */ -extern void word_list_remove_quoted_nulls PARAMS((WORD_LIST *)); - -/* This performs word splitting and quoted null character removal on - STRING. */ -extern WORD_LIST *list_string PARAMS((char *, char *, int)); - -extern char *ifs_firstchar PARAMS((int *)); -extern char *get_word_from_string PARAMS((char **, char *, char **)); -extern char *strip_trailing_ifs_whitespace PARAMS((char *, char *, int)); - -/* Given STRING, an assignment string, get the value of the right side - of the `=', and bind it to the left side. If EXPAND is true, then - perform tilde expansion, parameter expansion, command substitution, - and arithmetic expansion on the right-hand side. Do not perform word - splitting on the result of expansion. */ -extern int do_assignment PARAMS((char *)); -extern int do_assignment_no_expand PARAMS((char *)); -extern int do_word_assignment PARAMS((WORD_DESC *, int)); - -/* Append SOURCE to TARGET at INDEX. SIZE is the current amount - of space allocated to TARGET. SOURCE can be NULL, in which - case nothing happens. Gets rid of SOURCE by free ()ing it. - Returns TARGET in case the location has changed. */ -extern char *sub_append_string PARAMS((char *, char *, size_t *, size_t *)); - -/* Append the textual representation of NUMBER to TARGET. - INDEX and SIZE are as in SUB_APPEND_STRING. */ -extern char *sub_append_number PARAMS((intmax_t, char *, int *, int *)); - -/* Return the word list that corresponds to `$*'. */ -extern WORD_LIST *list_rest_of_args PARAMS((void)); - -/* Make a single large string out of the dollar digit variables, - and the rest_of_args. If DOLLAR_STAR is 1, then obey the special - case of "$*" with respect to IFS. */ -extern char *string_rest_of_args PARAMS((int)); - -/* Expand STRING by performing parameter expansion, command substitution, - and arithmetic expansion. Dequote the resulting WORD_LIST before - returning it, but do not perform word splitting. The call to - remove_quoted_nulls () is made here because word splitting normally - takes care of quote removal. */ -extern WORD_LIST *expand_string_unsplit PARAMS((char *, int)); - -/* Expand the rhs of an assignment statement. */ -extern WORD_LIST *expand_string_assignment PARAMS((char *, int)); - -/* Expand a prompt string. */ -extern WORD_LIST *expand_prompt_string PARAMS((char *, int, int)); - -/* Expand STRING just as if you were expanding a word. This also returns - a list of words. Note that filename globbing is *NOT* done for word - or string expansion, just when the shell is expanding a command. This - does parameter expansion, command substitution, arithmetic expansion, - and word splitting. Dequote the resultant WORD_LIST before returning. */ -extern WORD_LIST *expand_string PARAMS((char *, int)); - -/* Convenience functions that expand strings to strings, taking care of - converting the WORD_LIST * returned by the expand_string* functions - to a string and deallocating the WORD_LIST *. */ -extern char *expand_string_to_string PARAMS((char *, int)); -extern char *expand_string_unsplit_to_string PARAMS((char *, int)); -extern char *expand_assignment_string_to_string PARAMS((char *, int)); -extern char *expand_subscript_string PARAMS((char *, int)); - -/* Expand an arithmetic expression string */ -extern char *expand_arith_string PARAMS((char *, int)); - -/* Expand $'...' and $"..." in a string for code paths that do not. */ -extern char *expand_string_dollar_quote PARAMS((char *, int)); - -/* De-quote quoted characters in STRING. */ -extern char *dequote_string PARAMS((char *)); - -/* De-quote CTLESC-escaped CTLESC or CTLNUL characters in STRING. */ -extern char *dequote_escapes PARAMS((const char *)); - -extern WORD_DESC *dequote_word PARAMS((WORD_DESC *)); - -/* De-quote quoted characters in each word in LIST. */ -extern WORD_LIST *dequote_list PARAMS((WORD_LIST *)); - -/* Expand WORD, performing word splitting on the result. This does - parameter expansion, command substitution, arithmetic expansion, - word splitting, and quote removal. */ -extern WORD_LIST *expand_word PARAMS((WORD_DESC *, int)); - -/* Expand WORD, but do not perform word splitting on the result. This - does parameter expansion, command substitution, arithmetic expansion, - and quote removal. */ -extern WORD_LIST *expand_word_unsplit PARAMS((WORD_DESC *, int)); -extern WORD_LIST *expand_word_leave_quoted PARAMS((WORD_DESC *, int)); - -/* Return the value of a positional parameter. This handles values > 10. */ -extern char *get_dollar_var_value PARAMS((intmax_t)); - -/* Quote a string to protect it from word splitting. */ -extern char *quote_string PARAMS((char *)); - -/* Quote escape characters (characters special to internals of expansion) - in a string. */ -extern char *quote_escapes PARAMS((const char *)); - -/* And remove such quoted special characters. */ -extern char *remove_quoted_escapes PARAMS((char *)); - -/* Remove CTLNUL characters from STRING unless they are quoted with CTLESC. */ -extern char *remove_quoted_nulls PARAMS((char *)); - -/* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the - backslash quoting rules for within double quotes. */ -extern char *string_quote_removal PARAMS((char *, int)); - -/* Perform quote removal on word WORD. This allocates and returns a new - WORD_DESC *. */ -extern WORD_DESC *word_quote_removal PARAMS((WORD_DESC *, int)); - -/* Perform quote removal on all words in LIST. If QUOTED is non-zero, - the members of the list are treated as if they are surrounded by - double quotes. Return a new list, or NULL if LIST is NULL. */ -extern WORD_LIST *word_list_quote_removal PARAMS((WORD_LIST *, int)); - -/* Called when IFS is changed to maintain some private variables. */ -extern void setifs PARAMS((SHELL_VAR *)); - -/* Return the value of $IFS, or " \t\n" if IFS is unset. */ -extern char *getifs PARAMS((void)); - -/* This splits a single word into a WORD LIST on $IFS, but only if the word - is not quoted. list_string () performs quote removal for us, even if we - don't do any splitting. */ -extern WORD_LIST *word_split PARAMS((WORD_DESC *, char *)); - -/* Take the list of words in LIST and do the various substitutions. Return - a new list of words which is the expanded list, and without things like - variable assignments. */ -extern WORD_LIST *expand_words PARAMS((WORD_LIST *)); - -/* Same as expand_words (), but doesn't hack variable or environment - variables. */ -extern WORD_LIST *expand_words_no_vars PARAMS((WORD_LIST *)); - -/* Perform the `normal shell expansions' on a WORD_LIST. These are - brace expansion, tilde expansion, parameter and variable substitution, - command substitution, arithmetic expansion, and word splitting. */ -extern WORD_LIST *expand_words_shellexp PARAMS((WORD_LIST *)); - -extern WORD_DESC *command_substitute PARAMS((char *, int, int)); -extern char *pat_subst PARAMS((char *, char *, char *, int)); - -#if defined (PROCESS_SUBSTITUTION) -extern int fifos_pending PARAMS((void)); -extern int num_fifos PARAMS((void)); -extern void unlink_fifo_list PARAMS((void)); -extern void unlink_all_fifos PARAMS((void)); -extern void unlink_fifo PARAMS((int)); - -extern void *copy_fifo_list PARAMS((int *)); -extern void close_new_fifos PARAMS((void *, int)); - -extern void clear_fifo_list PARAMS((void)); - -extern int find_procsub_child PARAMS((pid_t)); -extern void set_procsub_status PARAMS((int, pid_t, int)); - -extern void wait_procsubs PARAMS((void)); -extern void reap_procsubs PARAMS((void)); -#endif - -extern WORD_LIST *list_string_with_quotes PARAMS((char *)); - -#if defined (ARRAY_VARS) -extern char *extract_array_assignment_list PARAMS((char *, int *)); -#endif - -#if defined (COND_COMMAND) -extern char *remove_backslashes PARAMS((char *)); -extern char *cond_expand_word PARAMS((WORD_DESC *, int)); -#endif - -/* Flags for skip_to_delim */ -#define SD_NOJMP 0x001 /* don't longjmp on fatal error. */ -#define SD_INVERT 0x002 /* look for chars NOT in passed set */ -#define SD_NOQUOTEDELIM 0x004 /* don't let single or double quotes act as delimiters */ -#define SD_NOSKIPCMD 0x008 /* don't skip over $(, <(, or >( command/process substitution; parse them as commands */ -#define SD_EXTGLOB 0x010 /* skip over extended globbing patterns if appropriate */ -#define SD_IGNOREQUOTE 0x020 /* single and double quotes are not special */ -#define SD_GLOB 0x040 /* skip over glob patterns like bracket expressions */ -#define SD_NOPROCSUB 0x080 /* don't parse process substitutions as commands */ -#define SD_COMPLETE 0x100 /* skip_to_delim during completion */ -#define SD_HISTEXP 0x200 /* skip_to_delim during history expansion */ -#define SD_ARITHEXP 0x400 /* skip_to_delim during arithmetic expansion */ -#define SD_NOERROR 0x800 /* don't print error messages */ - -extern int skip_to_delim PARAMS((char *, int, char *, int)); - -#if defined (BANG_HISTORY) -extern int skip_to_histexp PARAMS((char *, int, char *, int)); -#endif - -#if defined (READLINE) -extern int char_is_quoted PARAMS((char *, int)); -extern int unclosed_pair PARAMS((char *, int, char *)); -extern WORD_LIST *split_at_delims PARAMS((char *, int, const char *, int, int, int *, int *)); -#endif - -/* Variables used to keep track of the characters in IFS. */ -extern SHELL_VAR *ifs_var; -extern char *ifs_value; -extern unsigned char ifs_cmap[]; -extern int ifs_is_set, ifs_is_null; - -#if defined (HANDLE_MULTIBYTE) -extern unsigned char ifs_firstc[]; -extern size_t ifs_firstc_len; -#else -extern unsigned char ifs_firstc; -#endif - -extern int assigning_in_environment; -extern int expanding_redir; -extern int inherit_errexit; - -extern pid_t last_command_subst_pid; - -/* Evaluates to 1 if C is a character in $IFS. */ -#define isifs(c) (ifs_cmap[(unsigned char)(c)] != 0) - -/* How to determine the quoted state of the character C. */ -#define QUOTED_CHAR(c) ((c) == CTLESC) - -/* Is the first character of STRING a quoted NULL character? */ -#define QUOTED_NULL(string) ((string)[0] == CTLNUL && (string)[1] == '\0') - -extern void invalidate_cached_quoted_dollar_at PARAMS((void)); - -#endif /* !_SUBST_H_ */ diff --git a/third_party/bash/syntax.c b/third_party/bash/syntax.c deleted file mode 100644 index c14e068f3..000000000 --- a/third_party/bash/syntax.c +++ /dev/null @@ -1,269 +0,0 @@ -/* - * This file was generated by mksyntax. DO NOT EDIT. - */ - - -#include "config.h" -#include "stdc.h" -#include "syntax.h" - - -int sh_syntabsiz = 256; -int sh_syntaxtab[256] = { - CWORD, /* 0 */ - CSPECL, /* CTLESC */ - CWORD, /* 2 */ - CWORD, /* 3 */ - CWORD, /* 4 */ - CWORD, /* 5 */ - CWORD, /* 6 */ - CWORD, /* \a */ - CWORD, /* \b */ - CSHBRK|CBLANK, /* \t */ - CSHBRK|CBSDQUOTE, /* \n */ - CWORD, /* \v */ - CWORD, /* \f */ - CWORD, /* \r */ - CWORD, /* 14 */ - CWORD, /* 15 */ - CWORD, /* 16 */ - CWORD, /* 17 */ - CWORD, /* 18 */ - CWORD, /* 19 */ - CWORD, /* 20 */ - CWORD, /* 21 */ - CWORD, /* 22 */ - CWORD, /* 23 */ - CWORD, /* 24 */ - CWORD, /* 25 */ - CWORD, /* 26 */ - CWORD, /* ESC */ - CWORD, /* 28 */ - CWORD, /* 29 */ - CWORD, /* 30 */ - CWORD, /* 31 */ - CSHBRK|CBLANK, /* SPC */ - CXGLOB|CSPECVAR, /* ! */ - CQUOTE|CBSDQUOTE|CXQUOTE, /* " */ - CSPECVAR, /* # */ - CEXP|CBSDQUOTE|CBSHDOC|CSPECVAR, /* $ */ - CWORD, /* % */ - CSHMETA|CSHBRK, /* & */ - CQUOTE|CXQUOTE, /* ' */ - CSHMETA|CSHBRK, /* ( */ - CSHMETA|CSHBRK, /* ) */ - CGLOB|CXGLOB|CSPECVAR, /* * */ - CXGLOB|CSUBSTOP, /* + */ - CWORD, /* , */ - CSPECVAR|CSUBSTOP, /* - */ - CWORD, /* . */ - CWORD, /* / */ - CWORD, /* 0 */ - CWORD, /* 1 */ - CWORD, /* 2 */ - CWORD, /* 3 */ - CWORD, /* 4 */ - CWORD, /* 5 */ - CWORD, /* 6 */ - CWORD, /* 7 */ - CWORD, /* 8 */ - CWORD, /* 9 */ - CWORD, /* : */ - CSHMETA|CSHBRK, /* ; */ - CSHMETA|CSHBRK|CEXP, /* < */ - CSUBSTOP, /* = */ - CSHMETA|CSHBRK|CEXP, /* > */ - CGLOB|CXGLOB|CSPECVAR|CSUBSTOP, /* ? */ - CXGLOB|CSPECVAR, /* @ */ - CWORD, /* A */ - CWORD, /* B */ - CWORD, /* C */ - CWORD, /* D */ - CWORD, /* E */ - CWORD, /* F */ - CWORD, /* G */ - CWORD, /* H */ - CWORD, /* I */ - CWORD, /* J */ - CWORD, /* K */ - CWORD, /* L */ - CWORD, /* M */ - CWORD, /* N */ - CWORD, /* O */ - CWORD, /* P */ - CWORD, /* Q */ - CWORD, /* R */ - CWORD, /* S */ - CWORD, /* T */ - CWORD, /* U */ - CWORD, /* V */ - CWORD, /* W */ - CWORD, /* X */ - CWORD, /* Y */ - CWORD, /* Z */ - CGLOB, /* [ */ - CBSDQUOTE|CBSHDOC|CXQUOTE, /* \ */ - CGLOB, /* ] */ - CGLOB, /* ^ */ - CWORD, /* _ */ - CBACKQ|CQUOTE|CBSDQUOTE|CBSHDOC|CXQUOTE, /* ` */ - CWORD, /* a */ - CWORD, /* b */ - CWORD, /* c */ - CWORD, /* d */ - CWORD, /* e */ - CWORD, /* f */ - CWORD, /* g */ - CWORD, /* h */ - CWORD, /* i */ - CWORD, /* j */ - CWORD, /* k */ - CWORD, /* l */ - CWORD, /* m */ - CWORD, /* n */ - CWORD, /* o */ - CWORD, /* p */ - CWORD, /* q */ - CWORD, /* r */ - CWORD, /* s */ - CWORD, /* t */ - CWORD, /* u */ - CWORD, /* v */ - CWORD, /* w */ - CWORD, /* x */ - CWORD, /* y */ - CWORD, /* z */ - CWORD, /* { */ - CSHMETA|CSHBRK, /* | */ - CWORD, /* } */ - CWORD, /* ~ */ - CSPECL, /* CTLNUL */ - CWORD, /* 128 */ - CWORD, /* 129 */ - CWORD, /* 130 */ - CWORD, /* 131 */ - CWORD, /* 132 */ - CWORD, /* 133 */ - CWORD, /* 134 */ - CWORD, /* 135 */ - CWORD, /* 136 */ - CWORD, /* 137 */ - CWORD, /* 138 */ - CWORD, /* 139 */ - CWORD, /* 140 */ - CWORD, /* 141 */ - CWORD, /* 142 */ - CWORD, /* 143 */ - CWORD, /* 144 */ - CWORD, /* 145 */ - CWORD, /* 146 */ - CWORD, /* 147 */ - CWORD, /* 148 */ - CWORD, /* 149 */ - CWORD, /* 150 */ - CWORD, /* 151 */ - CWORD, /* 152 */ - CWORD, /* 153 */ - CWORD, /* 154 */ - CWORD, /* 155 */ - CWORD, /* 156 */ - CWORD, /* 157 */ - CWORD, /* 158 */ - CWORD, /* 159 */ - CWORD, /* 160 */ - CWORD, /* 161 */ - CWORD, /* 162 */ - CWORD, /* 163 */ - CWORD, /* 164 */ - CWORD, /* 165 */ - CWORD, /* 166 */ - CWORD, /* 167 */ - CWORD, /* 168 */ - CWORD, /* 169 */ - CWORD, /* 170 */ - CWORD, /* 171 */ - CWORD, /* 172 */ - CWORD, /* 173 */ - CWORD, /* 174 */ - CWORD, /* 175 */ - CWORD, /* 176 */ - CWORD, /* 177 */ - CWORD, /* 178 */ - CWORD, /* 179 */ - CWORD, /* 180 */ - CWORD, /* 181 */ - CWORD, /* 182 */ - CWORD, /* 183 */ - CWORD, /* 184 */ - CWORD, /* 185 */ - CWORD, /* 186 */ - CWORD, /* 187 */ - CWORD, /* 188 */ - CWORD, /* 189 */ - CWORD, /* 190 */ - CWORD, /* 191 */ - CWORD, /* 192 */ - CWORD, /* 193 */ - CWORD, /* 194 */ - CWORD, /* 195 */ - CWORD, /* 196 */ - CWORD, /* 197 */ - CWORD, /* 198 */ - CWORD, /* 199 */ - CWORD, /* 200 */ - CWORD, /* 201 */ - CWORD, /* 202 */ - CWORD, /* 203 */ - CWORD, /* 204 */ - CWORD, /* 205 */ - CWORD, /* 206 */ - CWORD, /* 207 */ - CWORD, /* 208 */ - CWORD, /* 209 */ - CWORD, /* 210 */ - CWORD, /* 211 */ - CWORD, /* 212 */ - CWORD, /* 213 */ - CWORD, /* 214 */ - CWORD, /* 215 */ - CWORD, /* 216 */ - CWORD, /* 217 */ - CWORD, /* 218 */ - CWORD, /* 219 */ - CWORD, /* 220 */ - CWORD, /* 221 */ - CWORD, /* 222 */ - CWORD, /* 223 */ - CWORD, /* 224 */ - CWORD, /* 225 */ - CWORD, /* 226 */ - CWORD, /* 227 */ - CWORD, /* 228 */ - CWORD, /* 229 */ - CWORD, /* 230 */ - CWORD, /* 231 */ - CWORD, /* 232 */ - CWORD, /* 233 */ - CWORD, /* 234 */ - CWORD, /* 235 */ - CWORD, /* 236 */ - CWORD, /* 237 */ - CWORD, /* 238 */ - CWORD, /* 239 */ - CWORD, /* 240 */ - CWORD, /* 241 */ - CWORD, /* 242 */ - CWORD, /* 243 */ - CWORD, /* 244 */ - CWORD, /* 245 */ - CWORD, /* 246 */ - CWORD, /* 247 */ - CWORD, /* 248 */ - CWORD, /* 249 */ - CWORD, /* 250 */ - CWORD, /* 251 */ - CWORD, /* 252 */ - CWORD, /* 253 */ - CWORD, /* 254 */ - CWORD, /* 255 */ -}; diff --git a/third_party/bash/syntax.h b/third_party/bash/syntax.h deleted file mode 100644 index 34f549647..000000000 --- a/third_party/bash/syntax.h +++ /dev/null @@ -1,106 +0,0 @@ -/* syntax.h -- Syntax definitions for the shell */ - -/* Copyright (C) 2000, 2001, 2005, 2008, 2009-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#ifndef _SYNTAX_H_ -#define _SYNTAX_H_ - -/* Defines for use by mksyntax.c */ - -#define slashify_in_quotes "\\`$\"\n" -#define slashify_in_here_document "\\`$" - -#define shell_meta_chars "()<>;&|" -#define shell_break_chars "()<>;&| \t\n" - -#define shell_quote_chars "\"`'" - -#if defined (PROCESS_SUBSTITUTION) -# define shell_exp_chars "$<>" -#else -# define shell_exp_chars "$" -#endif - -#if defined (EXTENDED_GLOB) -# define ext_glob_chars "@*+?!" -#else -# define ext_glob_chars "" -#endif -#define shell_glob_chars "*?[]^" - -/* Defines shared by mksyntax.c and the rest of the shell code. */ - -/* Values for character flags in syntax tables */ - -#define CWORD 0x0000 /* nothing special; an ordinary character */ -#define CSHMETA 0x0001 /* shell meta character */ -#define CSHBRK 0x0002 /* shell break character */ -#define CBACKQ 0x0004 /* back quote */ -#define CQUOTE 0x0008 /* shell quote character */ -#define CSPECL 0x0010 /* special character that needs quoting */ -#define CEXP 0x0020 /* shell expansion character */ -#define CBSDQUOTE 0x0040 /* characters escaped by backslash in double quotes */ -#define CBSHDOC 0x0080 /* characters escaped by backslash in here doc */ -#define CGLOB 0x0100 /* globbing characters */ -#define CXGLOB 0x0200 /* extended globbing characters */ -#define CXQUOTE 0x0400 /* cquote + backslash */ -#define CSPECVAR 0x0800 /* single-character shell variable name */ -#define CSUBSTOP 0x1000 /* values of OP for ${word[:]OPstuff} */ -#define CBLANK 0x2000 /* whitespace (blank) character */ - -/* Defines for use by the rest of the shell. */ -extern int sh_syntaxtab[]; -extern int sh_syntabsiz; - -#define shellmeta(c) (sh_syntaxtab[(unsigned char)(c)] & CSHMETA) -#define shellbreak(c) (sh_syntaxtab[(unsigned char)(c)] & CSHBRK) -#define shellquote(c) (sh_syntaxtab[(unsigned char)(c)] & CQUOTE) -#define shellxquote(c) (sh_syntaxtab[(unsigned char)(c)] & CXQUOTE) - -#define shellblank(c) (sh_syntaxtab[(unsigned char)(c)] & CBLANK) - -#define parserblank(c) ((c) == ' ' || (c) == '\t') - -#define issyntype(c, t) ((sh_syntaxtab[(unsigned char)(c)] & (t)) != 0) -#define notsyntype(c,t) ((sh_syntaxtab[(unsigned char)(c)] & (t)) == 0) - -#if defined (PROCESS_SUBSTITUTION) -# define shellexp(c) ((c) == '$' || (c) == '<' || (c) == '>') -#else -# define shellexp(c) ((c) == '$') -#endif - -#if defined (EXTENDED_GLOB) -# define PATTERN_CHAR(c) \ - ((c) == '@' || (c) == '*' || (c) == '+' || (c) == '?' || (c) == '!') -#else -# define PATTERN_CHAR(c) 0 -#endif - -#define GLOB_CHAR(c) \ - ((c) == '*' || (c) == '?' || (c) == '[' || (c) == ']' || (c) == '^') - -#define CTLESC '\001' -#define CTLNUL '\177' - -#if !defined (HAVE_ISBLANK) && !defined (isblank) -# define isblank(x) ((x) == ' ' || (x) == '\t') -#endif - -#endif /* _SYNTAX_H_ */ diff --git a/third_party/bash/systimes.h b/third_party/bash/systimes.h deleted file mode 100644 index 27cdb3e53..000000000 --- a/third_party/bash/systimes.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (C) 1991-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -/* - * POSIX Standard: 4.5.2 Process Times - */ - -/* - * If we don't have a standard system clock_t type, this must be included - * after config.h - */ - -#ifndef _BASH_SYSTIMES_H -#define _BASH_SYSTIMES_H 1 - -#if defined (HAVE_SYS_TIMES_H) -# include -#else /* !HAVE_SYS_TIMES_H */ - -#include "stdc.h" - -/* Structure describing CPU time used by a process and its children. */ -struct tms - { - clock_t tms_utime; /* User CPU time. */ - clock_t tms_stime; /* System CPU time. */ - - clock_t tms_cutime; /* User CPU time of dead children. */ - clock_t tms_cstime; /* System CPU time of dead children. */ - }; - -/* Store the CPU time used by this process and all its - dead descendants in BUFFER. - Return the elapsed real time from an arbitrary point in the - past (the bash emulation uses the epoch), or (clock_t) -1 for - errors. All times are in CLK_TCKths of a second. */ -extern clock_t times PARAMS((struct tms *buffer)); - -#endif /* !HAVE_SYS_TIMES_H */ -#endif /* _BASH_SYSTIMES_H */ diff --git a/third_party/bash/test.c b/third_party/bash/test.c deleted file mode 100644 index b058922c7..000000000 --- a/third_party/bash/test.c +++ /dev/null @@ -1,921 +0,0 @@ -/* test.c - GNU test program (ksb and mjb) */ - -/* Modified to run with the GNU shell Apr 25, 1988 by bfox. */ - -/* Copyright (C) 1987-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -/* Define PATTERN_MATCHING to get the csh-like =~ and !~ pattern-matching - binary operators. */ -/* #define PATTERN_MATCHING */ - -#if defined (HAVE_CONFIG_H) -# include "config.h" -#endif - -#include - -#include "bashtypes.h" - -#if !defined (HAVE_LIMITS_H) && defined (HAVE_SYS_PARAM_H) -# include -#endif - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include -#if !defined (errno) -extern int errno; -#endif /* !errno */ - -#if !defined (_POSIX_VERSION) && defined (HAVE_SYS_FILE_H) -# include -#endif /* !_POSIX_VERSION */ -#include "posixstat.h" -#include "filecntl.h" -#include "stat-time.h" - -#include "bashintl.h" - -#include "shell.h" -#include "pathexp.h" -#include "test.h" -#include "common.h" - -#include "strmatch.h" - -#if !defined (STRLEN) -# define STRLEN(s) ((s)[0] ? ((s)[1] ? ((s)[2] ? strlen(s) : 2) : 1) : 0) -#endif - -#if !defined (STREQ) -# define STREQ(a, b) ((a)[0] == (b)[0] && strcmp ((a), (b)) == 0) -#endif /* !STREQ */ -#define STRCOLLEQ(a, b) ((a)[0] == (b)[0] && strcoll ((a), (b)) == 0) - -#if !defined (R_OK) -#define R_OK 4 -#define W_OK 2 -#define X_OK 1 -#define F_OK 0 -#endif /* R_OK */ - -#define EQ 0 -#define NE 1 -#define LT 2 -#define GT 3 -#define LE 4 -#define GE 5 - -#define NT 0 -#define OT 1 -#define EF 2 - -/* The following few defines control the truth and false output of each stage. - TRUE and FALSE are what we use to compute the final output value. - SHELL_BOOLEAN is the form which returns truth or falseness in shell terms. - Default is TRUE = 1, FALSE = 0, SHELL_BOOLEAN = (!value). */ -#define TRUE 1 -#define FALSE 0 -#define SHELL_BOOLEAN(value) (!(value)) - -#define TEST_ERREXIT_STATUS 2 - -static procenv_t test_exit_buf; -static int test_error_return; -#define test_exit(val) \ - do { test_error_return = val; sh_longjmp (test_exit_buf, 1); } while (0) - -extern int sh_stat PARAMS((const char *, struct stat *)); - -static int pos; /* The offset of the current argument in ARGV. */ -static int argc; /* The number of arguments present in ARGV. */ -static char **argv; /* The argument list. */ -static int noeval; - -static void test_syntax_error PARAMS((char *, char *)) __attribute__((__noreturn__)); -static void beyond PARAMS((void)) __attribute__((__noreturn__)); -static void integer_expected_error PARAMS((char *)) __attribute__((__noreturn__)); - -static int unary_operator PARAMS((void)); -static int binary_operator PARAMS((void)); -static int two_arguments PARAMS((void)); -static int three_arguments PARAMS((void)); -static int posixtest PARAMS((void)); - -static int expr PARAMS((void)); -static int term PARAMS((void)); -static int and PARAMS((void)); -static int or PARAMS((void)); - -static int filecomp PARAMS((char *, char *, int)); -static int arithcomp PARAMS((char *, char *, int, int)); -static int patcomp PARAMS((char *, char *, int)); - -static void -test_syntax_error (format, arg) - char *format, *arg; -{ - builtin_error (format, arg); - test_exit (TEST_ERREXIT_STATUS); -} - -/* - * beyond - call when we're beyond the end of the argument list (an - * error condition) - */ -static void -beyond () -{ - test_syntax_error (_("argument expected"), (char *)NULL); -} - -/* Syntax error for when an integer argument was expected, but - something else was found. */ -static void -integer_expected_error (pch) - char *pch; -{ - test_syntax_error (_("%s: integer expression expected"), pch); -} - -/* Increment our position in the argument list. Check that we're not - past the end of the argument list. This check is suppressed if the - argument is FALSE. Made a macro for efficiency. */ -#define advance(f) do { ++pos; if (f && pos >= argc) beyond (); } while (0) -#define unary_advance() do { advance (1); ++pos; } while (0) - -/* - * expr: - * or - */ -static int -expr () -{ - if (pos >= argc) - beyond (); - - return (FALSE ^ or ()); /* Same with this. */ -} - -/* - * or: - * and - * and '-o' or - */ -static int -or () -{ - int value, v2; - - value = and (); - if (pos < argc && argv[pos][0] == '-' && argv[pos][1] == 'o' && !argv[pos][2]) - { - advance (0); - v2 = or (); - return (value || v2); - } - - return (value); -} - -/* - * and: - * term - * term '-a' and - */ -static int -and () -{ - int value, v2; - - value = term (); - if (pos < argc && argv[pos][0] == '-' && argv[pos][1] == 'a' && !argv[pos][2]) - { - advance (0); - v2 = and (); - return (value && v2); - } - return (value); -} - -/* - * term - parse a term and return 1 or 0 depending on whether the term - * evaluates to true or false, respectively. - * - * term ::= - * '-'('a'|'b'|'c'|'d'|'e'|'f'|'g'|'h'|'k'|'p'|'r'|'s'|'u'|'w'|'x') filename - * '-'('G'|'L'|'O'|'S'|'N') filename - * '-t' [int] - * '-'('z'|'n') string - * '-'('v'|'R') varname - * '-o' option - * string - * string ('!='|'='|'==') string - * '-'(eq|ne|le|lt|ge|gt) - * file '-'(nt|ot|ef) file - * '(' ')' - * int ::= - * positive and negative integers - */ -static int -term () -{ - int value; - - if (pos >= argc) - beyond (); - - /* Deal with leading `not's. */ - if (argv[pos][0] == '!' && argv[pos][1] == '\0') - { - value = 0; - while (pos < argc && argv[pos][0] == '!' && argv[pos][1] == '\0') - { - advance (1); - value = 1 - value; - } - - return (value ? !term() : term()); - } - - /* A paren-bracketed argument. */ - if (argv[pos][0] == '(' && argv[pos][1] == '\0') /* ) */ - { - advance (1); - value = expr (); - if (argv[pos] == 0) /* ( */ - test_syntax_error (_("`)' expected"), (char *)NULL); - else if (argv[pos][0] != ')' || argv[pos][1]) /* ( */ - test_syntax_error (_("`)' expected, found %s"), argv[pos]); - advance (0); - return (value); - } - - /* are there enough arguments left that this could be dyadic? */ - if ((pos + 3 <= argc) && test_binop (argv[pos + 1])) - value = binary_operator (); - - /* Might be a switch type argument -- make sure we have enough arguments for - the unary operator and argument */ - else if ((pos + 2) <= argc && test_unop (argv[pos])) - value = unary_operator (); - - else - { - value = argv[pos][0] != '\0'; - advance (0); - } - - return (value); -} - -static int -stat_mtime (fn, st, ts) - char *fn; - struct stat *st; - struct timespec *ts; -{ - int r; - - r = sh_stat (fn, st); - if (r < 0) - return r; - *ts = get_stat_mtime (st); - return 0; -} - -static int -filecomp (s, t, op) - char *s, *t; - int op; -{ - struct stat st1, st2; - struct timespec ts1, ts2; - int r1, r2; - - if ((r1 = stat_mtime (s, &st1, &ts1)) < 0) - { - if (op == EF) - return (FALSE); - } - if ((r2 = stat_mtime (t, &st2, &ts2)) < 0) - { - if (op == EF) - return (FALSE); - } - - switch (op) - { - case OT: return (r1 < r2 || (r2 == 0 && timespec_cmp (ts1, ts2) < 0)); - case NT: return (r1 > r2 || (r1 == 0 && timespec_cmp (ts1, ts2) > 0)); - case EF: return (same_file (s, t, &st1, &st2)); - } - return (FALSE); -} - -static int -arithcomp (s, t, op, flags) - char *s, *t; - int op, flags; -{ - intmax_t l, r; - int expok; - - if (flags & TEST_ARITHEXP) /* conditional command */ - { - int eflag; - - eflag = (shell_compatibility_level > 51) ? 0 : EXP_EXPANDED; - l = evalexp (s, eflag, &expok); - if (expok == 0) - return (FALSE); /* should probably longjmp here */ - r = evalexp (t, eflag, &expok); - if (expok == 0) - return (FALSE); /* ditto */ - } - else - { - if (legal_number (s, &l) == 0) - integer_expected_error (s); - if (legal_number (t, &r) == 0) - integer_expected_error (t); - } - - switch (op) - { - case EQ: return (l == r); - case NE: return (l != r); - case LT: return (l < r); - case GT: return (l > r); - case LE: return (l <= r); - case GE: return (l >= r); - } - - return (FALSE); -} - -static int -patcomp (string, pat, op) - char *string, *pat; - int op; -{ - int m; - - m = strmatch (pat, string, FNMATCH_EXTFLAG|FNMATCH_IGNCASE); - return ((op == EQ) ? (m == 0) : (m != 0)); -} - -int -binary_test (op, arg1, arg2, flags) - char *op, *arg1, *arg2; - int flags; -{ - int patmatch; - - patmatch = (flags & TEST_PATMATCH); - - if (op[0] == '=' && (op[1] == '\0' || (op[1] == '=' && op[2] == '\0'))) - return (patmatch ? patcomp (arg1, arg2, EQ) : STREQ (arg1, arg2)); - else if ((op[0] == '>' || op[0] == '<') && op[1] == '\0') - { -#if defined (HAVE_STRCOLL) - if (shell_compatibility_level > 40 && flags & TEST_LOCALE) - return ((op[0] == '>') ? (strcoll (arg1, arg2) > 0) : (strcoll (arg1, arg2) < 0)); - else -#endif - return ((op[0] == '>') ? (strcmp (arg1, arg2) > 0) : (strcmp (arg1, arg2) < 0)); - } - else if (op[0] == '!' && op[1] == '=' && op[2] == '\0') - return (patmatch ? patcomp (arg1, arg2, NE) : (STREQ (arg1, arg2) == 0)); - - - else if (op[2] == 't') - { - switch (op[1]) - { - case 'n': return (filecomp (arg1, arg2, NT)); /* -nt */ - case 'o': return (filecomp (arg1, arg2, OT)); /* -ot */ - case 'l': return (arithcomp (arg1, arg2, LT, flags)); /* -lt */ - case 'g': return (arithcomp (arg1, arg2, GT, flags)); /* -gt */ - } - } - else if (op[1] == 'e') - { - switch (op[2]) - { - case 'f': return (filecomp (arg1, arg2, EF)); /* -ef */ - case 'q': return (arithcomp (arg1, arg2, EQ, flags)); /* -eq */ - } - } - else if (op[2] == 'e') - { - switch (op[1]) - { - case 'n': return (arithcomp (arg1, arg2, NE, flags)); /* -ne */ - case 'g': return (arithcomp (arg1, arg2, GE, flags)); /* -ge */ - case 'l': return (arithcomp (arg1, arg2, LE, flags)); /* -le */ - } - } - - return (FALSE); /* should never get here */ -} - - -static int -binary_operator () -{ - int value; - char *w; - - w = argv[pos + 1]; - if ((w[0] == '=' && (w[1] == '\0' || (w[1] == '=' && w[2] == '\0'))) || /* =, == */ - ((w[0] == '>' || w[0] == '<') && w[1] == '\0') || /* <, > */ - (w[0] == '!' && w[1] == '=' && w[2] == '\0')) /* != */ - { - value = binary_test (w, argv[pos], argv[pos + 2], 0); - pos += 3; - return (value); - } - -#if defined (PATTERN_MATCHING) - if ((w[0] == '=' || w[0] == '!') && w[1] == '~' && w[2] == '\0') - { - value = patcomp (argv[pos], argv[pos + 2], w[0] == '=' ? EQ : NE); - pos += 3; - return (value); - } -#endif - - if ((w[0] != '-' || w[3] != '\0') || test_binop (w) == 0) - { - test_syntax_error (_("%s: binary operator expected"), w); - /* NOTREACHED */ - return (FALSE); - } - - value = binary_test (w, argv[pos], argv[pos + 2], 0); - pos += 3; - return value; -} - -static int -unary_operator () -{ - char *op; - intmax_t r; - - op = argv[pos]; - if (test_unop (op) == 0) - return (FALSE); - - /* the only tricky case is `-t', which may or may not take an argument. */ - if (op[1] == 't') - { - advance (0); - if (pos < argc) - { - if (legal_number (argv[pos], &r)) - { - advance (0); - return (unary_test (op, argv[pos - 1], 0)); - } - else - return (FALSE); - } - else - return (unary_test (op, "1", 0)); - } - - /* All of the unary operators take an argument, so we first call - unary_advance (), which checks to make sure that there is an - argument, and then advances pos right past it. This means that - pos - 1 is the location of the argument. */ - unary_advance (); - return (unary_test (op, argv[pos - 1], 0)); -} - -int -unary_test (op, arg, flags) - char *op, *arg; - int flags; -{ - intmax_t r; - struct stat stat_buf; - struct timespec mtime, atime; - SHELL_VAR *v; - int aflags; - - switch (op[1]) - { - case 'a': /* file exists in the file system? */ - case 'e': - return (sh_stat (arg, &stat_buf) == 0); - - case 'r': /* file is readable? */ - return (sh_eaccess (arg, R_OK) == 0); - - case 'w': /* File is writeable? */ - return (sh_eaccess (arg, W_OK) == 0); - - case 'x': /* File is executable? */ - return (sh_eaccess (arg, X_OK) == 0); - - case 'O': /* File is owned by you? */ - return (sh_stat (arg, &stat_buf) == 0 && - (uid_t) current_user.euid == (uid_t) stat_buf.st_uid); - - case 'G': /* File is owned by your group? */ - return (sh_stat (arg, &stat_buf) == 0 && - (gid_t) current_user.egid == (gid_t) stat_buf.st_gid); - - case 'N': - if (sh_stat (arg, &stat_buf) < 0) - return (FALSE); - atime = get_stat_atime (&stat_buf); - mtime = get_stat_mtime (&stat_buf); - return (timespec_cmp (mtime, atime) > 0); - - case 'f': /* File is a file? */ - if (sh_stat (arg, &stat_buf) < 0) - return (FALSE); - - /* -f is true if the given file exists and is a regular file. */ -#if defined (S_IFMT) - return (S_ISREG (stat_buf.st_mode) || (stat_buf.st_mode & S_IFMT) == 0); -#else - return (S_ISREG (stat_buf.st_mode)); -#endif /* !S_IFMT */ - - case 'd': /* File is a directory? */ - return (sh_stat (arg, &stat_buf) == 0 && (S_ISDIR (stat_buf.st_mode))); - - case 's': /* File has something in it? */ - return (sh_stat (arg, &stat_buf) == 0 && stat_buf.st_size > (off_t) 0); - - case 'S': /* File is a socket? */ -#if !defined (S_ISSOCK) - return (FALSE); -#else - return (sh_stat (arg, &stat_buf) == 0 && S_ISSOCK (stat_buf.st_mode)); -#endif /* S_ISSOCK */ - - case 'c': /* File is character special? */ - return (sh_stat (arg, &stat_buf) == 0 && S_ISCHR (stat_buf.st_mode)); - - case 'b': /* File is block special? */ - return (sh_stat (arg, &stat_buf) == 0 && S_ISBLK (stat_buf.st_mode)); - - case 'p': /* File is a named pipe? */ -#ifndef S_ISFIFO - return (FALSE); -#else - return (sh_stat (arg, &stat_buf) == 0 && S_ISFIFO (stat_buf.st_mode)); -#endif /* S_ISFIFO */ - - case 'L': /* Same as -h */ - case 'h': /* File is a symbolic link? */ -#if !defined (S_ISLNK) || !defined (HAVE_LSTAT) - return (FALSE); -#else - return ((arg[0] != '\0') && - (lstat (arg, &stat_buf) == 0) && S_ISLNK (stat_buf.st_mode)); -#endif /* S_IFLNK && HAVE_LSTAT */ - - case 'u': /* File is setuid? */ - return (sh_stat (arg, &stat_buf) == 0 && (stat_buf.st_mode & S_ISUID) != 0); - - case 'g': /* File is setgid? */ - return (sh_stat (arg, &stat_buf) == 0 && (stat_buf.st_mode & S_ISGID) != 0); - - case 'k': /* File has sticky bit set? */ -#if !defined (S_ISVTX) - /* This is not Posix, and is not defined on some Posix systems. */ - return (FALSE); -#else - return (sh_stat (arg, &stat_buf) == 0 && (stat_buf.st_mode & S_ISVTX) != 0); -#endif - - case 't': /* File fd is a terminal? */ - if (legal_number (arg, &r) == 0) - return (FALSE); - return ((r == (int)r) && isatty ((int)r)); - - case 'n': /* True if arg has some length. */ - return (arg[0] != '\0'); - - case 'z': /* True if arg has no length. */ - return (arg[0] == '\0'); - - case 'o': /* True if option `arg' is set. */ - return (minus_o_option_value (arg) == 1); - - case 'v': -#if defined (ARRAY_VARS) - aflags = assoc_expand_once ? AV_NOEXPAND : 0; - if (valid_array_reference (arg, aflags)) - { - char *t; - int ret; - array_eltstate_t es; - - /* Let's assume that this has already been expanded once. */ - /* XXX - TAG:bash-5.2 fix with corresponding fix to execute_cmd.c: - execute_cond_node() that passes TEST_ARRAYEXP in FLAGS */ - - if (shell_compatibility_level > 51) - /* Allow associative arrays to use `test -v array[@]' to look for - a key named `@'. */ - aflags |= AV_ATSTARKEYS; /* XXX */ - init_eltstate (&es); - t = get_array_value (arg, aflags|AV_ALLOWALL, &es); - ret = t ? TRUE : FALSE; - if (es.subtype > 0) /* subscript is * or @ */ - free (t); - flush_eltstate (&es); - return ret; - } - else if (legal_number (arg, &r)) /* -v n == is $n set? */ - return ((r >= 0 && r <= number_of_args()) ? TRUE : FALSE); - v = find_variable (arg); - if (v && invisible_p (v) == 0 && array_p (v)) - { - char *t; - /* [[ -v foo ]] == [[ -v foo[0] ]] */ - t = array_reference (array_cell (v), 0); - return (t ? TRUE : FALSE); - } - else if (v && invisible_p (v) == 0 && assoc_p (v)) - { - char *t; - t = assoc_reference (assoc_cell (v), "0"); - return (t ? TRUE : FALSE); - } -#else - v = find_variable (arg); -#endif - return (v && invisible_p (v) == 0 && var_isset (v) ? TRUE : FALSE); - - case 'R': - v = find_variable_noref (arg); - return ((v && invisible_p (v) == 0 && var_isset (v) && nameref_p (v)) ? TRUE : FALSE); - } - - /* We can't actually get here, but this shuts up gcc. */ - return (FALSE); -} - -/* Return TRUE if OP is one of the test command's binary operators. */ -int -test_binop (op) - char *op; -{ - if (op[0] == '=' && op[1] == '\0') - return (1); /* '=' */ - else if ((op[0] == '<' || op[0] == '>') && op[1] == '\0') /* string <, > */ - return (1); - else if ((op[0] == '=' || op[0] == '!') && op[1] == '=' && op[2] == '\0') - return (1); /* `==' and `!=' */ -#if defined (PATTERN_MATCHING) - else if (op[2] == '\0' && op[1] == '~' && (op[0] == '=' || op[0] == '!')) - return (1); -#endif - else if (op[0] != '-' || op[1] == '\0' || op[2] == '\0' || op[3] != '\0') - return (0); - else - { - if (op[2] == 't') - switch (op[1]) - { - case 'n': /* -nt */ - case 'o': /* -ot */ - case 'l': /* -lt */ - case 'g': /* -gt */ - return (1); - default: - return (0); - } - else if (op[1] == 'e') - switch (op[2]) - { - case 'q': /* -eq */ - case 'f': /* -ef */ - return (1); - default: - return (0); - } - else if (op[2] == 'e') - switch (op[1]) - { - case 'n': /* -ne */ - case 'g': /* -ge */ - case 'l': /* -le */ - return (1); - default: - return (0); - } - else - return (0); - } -} - -/* Return non-zero if OP is one of the test command's unary operators. */ -int -test_unop (op) - char *op; -{ - if (op[0] != '-' || (op[1] && op[2] != 0)) - return (0); - - switch (op[1]) - { - case 'a': case 'b': case 'c': case 'd': case 'e': - case 'f': case 'g': case 'h': case 'k': case 'n': - case 'o': case 'p': case 'r': case 's': case 't': - case 'u': case 'v': case 'w': case 'x': case 'z': - case 'G': case 'L': case 'O': case 'S': case 'N': - case 'R': - return (1); - } - - return (0); -} - -static int -two_arguments () -{ - if (argv[pos][0] == '!' && argv[pos][1] == '\0') - return (argv[pos + 1][0] == '\0'); - else if (argv[pos][0] == '-' && argv[pos][1] && argv[pos][2] == '\0') - { - if (test_unop (argv[pos])) - return (unary_operator ()); - else - test_syntax_error (_("%s: unary operator expected"), argv[pos]); - } - else - test_syntax_error (_("%s: unary operator expected"), argv[pos]); - - return (0); -} - -#define ANDOR(s) (s[0] == '-' && (s[1] == 'a' || s[1] == 'o') && s[2] == 0) - -/* This could be augmented to handle `-t' as equivalent to `-t 1', but - POSIX requires that `-t' be given an argument. */ -#define ONE_ARG_TEST(s) ((s)[0] != '\0') - -static int -three_arguments () -{ - int value; - - if (test_binop (argv[pos+1])) - { - value = binary_operator (); - pos = argc; - } - else if (ANDOR (argv[pos+1])) - { - if (argv[pos+1][1] == 'a') - value = ONE_ARG_TEST(argv[pos]) && ONE_ARG_TEST(argv[pos+2]); - else - value = ONE_ARG_TEST(argv[pos]) || ONE_ARG_TEST(argv[pos+2]); - pos = argc; - } - else if (argv[pos][0] == '!' && argv[pos][1] == '\0') - { - advance (1); - value = !two_arguments (); - pos = argc; - } - else if (argv[pos][0] == '(' && argv[pos+2][0] == ')') - { - value = ONE_ARG_TEST(argv[pos+1]); - pos = argc; - } - else - test_syntax_error (_("%s: binary operator expected"), argv[pos+1]); - - return (value); -} - -/* This is an implementation of a Posix.2 proposal by David Korn. */ -static int -posixtest () -{ - int value; - - switch (argc - 1) /* one extra passed in */ - { - case 0: - value = FALSE; - pos = argc; - break; - - case 1: - value = ONE_ARG_TEST(argv[1]); - pos = argc; - break; - - case 2: - value = two_arguments (); - pos = argc; - break; - - case 3: - value = three_arguments (); - break; - - case 4: - if (argv[pos][0] == '!' && argv[pos][1] == '\0') - { - advance (1); - value = !three_arguments (); - break; - } - else if (argv[pos][0] == '(' && argv[pos][1] == '\0' && argv[argc-1][0] == ')' && argv[argc-1][1] == '\0') - { - advance (1); - value = two_arguments (); - pos = argc; - break; - } - /* FALLTHROUGH */ - default: - value = expr (); - } - - return (value); -} - -/* - * [: - * '[' expr ']' - * test: - * test expr - */ -int -test_command (margc, margv) - int margc; - char **margv; -{ - int value; - int code; - - USE_VAR(margc); - - code = setjmp_nosigs (test_exit_buf); - - if (code) - return (test_error_return); - - argv = margv; - - if (margv[0] && margv[0][0] == '[' && margv[0][1] == '\0') - { - --margc; - - if (margv[margc] && (margv[margc][0] != ']' || margv[margc][1])) - test_syntax_error (_("missing `]'"), (char *)NULL); - - if (margc < 2) - test_exit (SHELL_BOOLEAN (FALSE)); - } - - argc = margc; - pos = 1; - - if (pos >= argc) - test_exit (SHELL_BOOLEAN (FALSE)); - - noeval = 0; - value = posixtest (); - - if (pos != argc) - { - if (pos < argc && argv[pos][0] == '-') - test_syntax_error (_("syntax error: `%s' unexpected"), argv[pos]); - else - test_syntax_error (_("too many arguments"), (char *)NULL); - } - - test_exit (SHELL_BOOLEAN (value)); -} diff --git a/third_party/bash/test.h b/third_party/bash/test.h deleted file mode 100644 index ffd79e5e0..000000000 --- a/third_party/bash/test.h +++ /dev/null @@ -1,40 +0,0 @@ -/* test.h -- external interface to the conditional command code. */ - -/* Copyright (C) 1997-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#ifndef _TEST_H_ -#define _TEST_H_ - -#include "stdc.h" - -/* Values for the flags argument to binary_test */ -#define TEST_PATMATCH 0x01 -#define TEST_ARITHEXP 0x02 -#define TEST_LOCALE 0x04 -#define TEST_ARRAYEXP 0x08 /* array subscript expansion */ - -extern int test_unop PARAMS((char *)); -extern int test_binop PARAMS((char *)); - -extern int unary_test PARAMS((char *, char *, int)); -extern int binary_test PARAMS((char *, char *, char *, int)); - -extern int test_command PARAMS((int, char **)); - -#endif /* _TEST_H_ */ diff --git a/third_party/bash/tilde.c b/third_party/bash/tilde.c deleted file mode 100644 index 5bafbb214..000000000 --- a/third_party/bash/tilde.c +++ /dev/null @@ -1,493 +0,0 @@ -/* tilde.c -- Tilde expansion code (~/foo := $HOME/foo). */ - -/* Copyright (C) 1988-2020 Free Software Foundation, Inc. - - This file is part of the GNU Readline Library (Readline), a library - for reading lines of text with interactive input and history editing. - - Readline is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Readline is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Readline. If not, see . -*/ - -#if defined (HAVE_CONFIG_H) -# include "config.h" -#endif - -#if defined (HAVE_UNISTD_H) -# ifdef _MINIX -# include -# endif -# include -#endif - -#if defined (HAVE_STRING_H) -# include -#else /* !HAVE_STRING_H */ -# include -#endif /* !HAVE_STRING_H */ - -#if defined (HAVE_STDLIB_H) -# include -#else -# include "ansi_stdlib.h" -#endif /* HAVE_STDLIB_H */ - -#include -#if defined (HAVE_PWD_H) -#include -#endif - -#include "tilde.h" - -#if defined (TEST) || defined (STATIC_MALLOC) -static void *xmalloc (), *xrealloc (); -#else -# include "xmalloc.h" -#endif /* TEST || STATIC_MALLOC */ - -#if !defined (HAVE_GETPW_DECLS) -# if defined (HAVE_GETPWUID) -extern struct passwd *getpwuid (uid_t); -# endif -# if defined (HAVE_GETPWNAM) -extern struct passwd *getpwnam (const char *); -# endif -#endif /* !HAVE_GETPW_DECLS */ - -#if !defined (savestring) -#define savestring(x) strcpy ((char *)xmalloc (1 + strlen (x)), (x)) -#endif /* !savestring */ - -#if !defined (NULL) -# if defined (__STDC__) -# define NULL ((void *) 0) -# else -# define NULL 0x0 -# endif /* !__STDC__ */ -#endif /* !NULL */ - -/* If being compiled as part of bash, these will be satisfied from - variables.o. If being compiled as part of readline, they will - be satisfied from shell.o. */ -extern char *sh_get_home_dir (void); -extern char *sh_get_env_value (const char *); - -/* The default value of tilde_additional_prefixes. This is set to - whitespace preceding a tilde so that simple programs which do not - perform any word separation get desired behaviour. */ -static const char *default_prefixes[] = - { " ~", "\t~", (const char *)NULL }; - -/* The default value of tilde_additional_suffixes. This is set to - whitespace or newline so that simple programs which do not - perform any word separation get desired behaviour. */ -static const char *default_suffixes[] = - { " ", "\n", (const char *)NULL }; - -/* If non-null, this contains the address of a function that the application - wants called before trying the standard tilde expansions. The function - is called with the text sans tilde, and returns a malloc()'ed string - which is the expansion, or a NULL pointer if the expansion fails. */ -tilde_hook_func_t *tilde_expansion_preexpansion_hook = (tilde_hook_func_t *)NULL; - -/* If non-null, this contains the address of a function to call if the - standard meaning for expanding a tilde fails. The function is called - with the text (sans tilde, as in "foo"), and returns a malloc()'ed string - which is the expansion, or a NULL pointer if there is no expansion. */ -tilde_hook_func_t *tilde_expansion_failure_hook = (tilde_hook_func_t *)NULL; - -/* When non-null, this is a NULL terminated array of strings which - are duplicates for a tilde prefix. Bash uses this to expand - `=~' and `:~'. */ -char **tilde_additional_prefixes = (char **)default_prefixes; - -/* When non-null, this is a NULL terminated array of strings which match - the end of a username, instead of just "/". Bash sets this to - `:' and `=~'. */ -char **tilde_additional_suffixes = (char **)default_suffixes; - -static int tilde_find_prefix (const char *, int *); -static int tilde_find_suffix (const char *); -static char *isolate_tilde_prefix (const char *, int *); -static char *glue_prefix_and_suffix (char *, const char *, int); - -/* Find the start of a tilde expansion in STRING, and return the index of - the tilde which starts the expansion. Place the length of the text - which identified this tilde starter in LEN, excluding the tilde itself. */ -static int -tilde_find_prefix (const char *string, int *len) -{ - register int i, j, string_len; - register char **prefixes; - - prefixes = tilde_additional_prefixes; - - string_len = strlen (string); - *len = 0; - - if (*string == '\0' || *string == '~') - return (0); - - if (prefixes) - { - for (i = 0; i < string_len; i++) - { - for (j = 0; prefixes[j]; j++) - { - if (strncmp (string + i, prefixes[j], strlen (prefixes[j])) == 0) - { - *len = strlen (prefixes[j]) - 1; - return (i + *len); - } - } - } - } - return (string_len); -} - -/* Find the end of a tilde expansion in STRING, and return the index of - the character which ends the tilde definition. */ -static int -tilde_find_suffix (const char *string) -{ - register int i, j, string_len; - register char **suffixes; - - suffixes = tilde_additional_suffixes; - string_len = strlen (string); - - for (i = 0; i < string_len; i++) - { -#if defined (__MSDOS__) - if (string[i] == '/' || string[i] == '\\' /* || !string[i] */) -#else - if (string[i] == '/' /* || !string[i] */) -#endif - break; - - for (j = 0; suffixes && suffixes[j]; j++) - { - if (strncmp (string + i, suffixes[j], strlen (suffixes[j])) == 0) - return (i); - } - } - return (i); -} - -/* Return a new string which is the result of tilde expanding STRING. */ -char * -tilde_expand (const char *string) -{ - char *result; - int result_size, result_index; - - result_index = result_size = 0; - if (result = strchr (string, '~')) - result = (char *)xmalloc (result_size = (strlen (string) + 16)); - else - result = (char *)xmalloc (result_size = (strlen (string) + 1)); - - /* Scan through STRING expanding tildes as we come to them. */ - while (1) - { - register int start, end; - char *tilde_word, *expansion; - int len; - - /* Make START point to the tilde which starts the expansion. */ - start = tilde_find_prefix (string, &len); - - /* Copy the skipped text into the result. */ - if ((result_index + start + 1) > result_size) - result = (char *)xrealloc (result, 1 + (result_size += (start + 20))); - - strncpy (result + result_index, string, start); - result_index += start; - - /* Advance STRING to the starting tilde. */ - string += start; - - /* Make END be the index of one after the last character of the - username. */ - end = tilde_find_suffix (string); - - /* If both START and END are zero, we are all done. */ - if (!start && !end) - break; - - /* Expand the entire tilde word, and copy it into RESULT. */ - tilde_word = (char *)xmalloc (1 + end); - strncpy (tilde_word, string, end); - tilde_word[end] = '\0'; - string += end; - - expansion = tilde_expand_word (tilde_word); - - if (expansion == 0) - expansion = tilde_word; - else - xfree (tilde_word); - - len = strlen (expansion); -#ifdef __CYGWIN__ - /* Fix for Cygwin to prevent ~user/xxx from expanding to //xxx when - $HOME for `user' is /. On cygwin, // denotes a network drive. */ - if (len > 1 || *expansion != '/' || *string != '/') -#endif - { - if ((result_index + len + 1) > result_size) - result = (char *)xrealloc (result, 1 + (result_size += (len + 20))); - - strcpy (result + result_index, expansion); - result_index += len; - } - xfree (expansion); - } - - result[result_index] = '\0'; - - return (result); -} - -/* Take FNAME and return the tilde prefix we want expanded. If LENP is - non-null, the index of the end of the prefix into FNAME is returned in - the location it points to. */ -static char * -isolate_tilde_prefix (const char *fname, int *lenp) -{ - char *ret; - int i; - - ret = (char *)xmalloc (strlen (fname)); -#if defined (__MSDOS__) - for (i = 1; fname[i] && fname[i] != '/' && fname[i] != '\\'; i++) -#else - for (i = 1; fname[i] && fname[i] != '/'; i++) -#endif - ret[i - 1] = fname[i]; - ret[i - 1] = '\0'; - if (lenp) - *lenp = i; - return ret; -} - -#if 0 -/* Public function to scan a string (FNAME) beginning with a tilde and find - the portion of the string that should be passed to the tilde expansion - function. Right now, it just calls tilde_find_suffix and allocates new - memory, but it can be expanded to do different things later. */ -char * -tilde_find_word (const char *fname, int flags, int *lenp) -{ - int x; - char *r; - - x = tilde_find_suffix (fname); - if (x == 0) - { - r = savestring (fname); - if (lenp) - *lenp = 0; - } - else - { - r = (char *)xmalloc (1 + x); - strncpy (r, fname, x); - r[x] = '\0'; - if (lenp) - *lenp = x; - } - - return r; -} -#endif - -/* Return a string that is PREFIX concatenated with SUFFIX starting at - SUFFIND. */ -static char * -glue_prefix_and_suffix (char *prefix, const char *suffix, int suffind) -{ - char *ret; - int plen, slen; - - plen = (prefix && *prefix) ? strlen (prefix) : 0; - slen = strlen (suffix + suffind); - ret = (char *)xmalloc (plen + slen + 1); - if (plen) - strcpy (ret, prefix); - strcpy (ret + plen, suffix + suffind); - return ret; -} - -/* Do the work of tilde expansion on FILENAME. FILENAME starts with a - tilde. If there is no expansion, call tilde_expansion_failure_hook. - This always returns a newly-allocated string, never static storage. */ -char * -tilde_expand_word (const char *filename) -{ - char *dirname, *expansion, *username; - int user_len; - struct passwd *user_entry; - - if (filename == 0) - return ((char *)NULL); - - if (*filename != '~') - return (savestring (filename)); - - /* A leading `~/' or a bare `~' is *always* translated to the value of - $HOME or the home directory of the current user, regardless of any - preexpansion hook. */ - if (filename[1] == '\0' || filename[1] == '/') - { - /* Prefix $HOME to the rest of the string. */ - expansion = sh_get_env_value ("HOME"); -#if defined (_WIN32) - if (expansion == 0) - expansion = sh_get_env_value ("APPDATA"); -#endif - - /* If there is no HOME variable, look up the directory in - the password database. */ - if (expansion == 0) - expansion = sh_get_home_dir (); - - return (glue_prefix_and_suffix (expansion, filename, 1)); - } - - username = isolate_tilde_prefix (filename, &user_len); - - if (tilde_expansion_preexpansion_hook) - { - expansion = (*tilde_expansion_preexpansion_hook) (username); - if (expansion) - { - dirname = glue_prefix_and_suffix (expansion, filename, user_len); - xfree (username); - xfree (expansion); - return (dirname); - } - } - - /* No preexpansion hook, or the preexpansion hook failed. Look in the - password database. */ - dirname = (char *)NULL; -#if defined (HAVE_GETPWNAM) - user_entry = getpwnam (username); -#else - user_entry = 0; -#endif - if (user_entry == 0) - { - /* If the calling program has a special syntax for expanding tildes, - and we couldn't find a standard expansion, then let them try. */ - if (tilde_expansion_failure_hook) - { - expansion = (*tilde_expansion_failure_hook) (username); - if (expansion) - { - dirname = glue_prefix_and_suffix (expansion, filename, user_len); - xfree (expansion); - } - } - /* If we don't have a failure hook, or if the failure hook did not - expand the tilde, return a copy of what we were passed. */ - if (dirname == 0) - dirname = savestring (filename); - } -#if defined (HAVE_GETPWENT) - else - dirname = glue_prefix_and_suffix (user_entry->pw_dir, filename, user_len); -#endif - - xfree (username); -#if defined (HAVE_GETPWENT) - endpwent (); -#endif - return (dirname); -} - - -#if defined (TEST) -#undef NULL -#include - -main (int argc, char **argv) -{ - char *result, line[512]; - int done = 0; - - while (!done) - { - printf ("~expand: "); - fflush (stdout); - - if (!gets (line)) - strcpy (line, "done"); - - if ((strcmp (line, "done") == 0) || - (strcmp (line, "quit") == 0) || - (strcmp (line, "exit") == 0)) - { - done = 1; - break; - } - - result = tilde_expand (line); - printf (" --> %s\n", result); - free (result); - } - exit (0); -} - -static void memory_error_and_abort (void); - -static void * -xmalloc (size_t bytes) -{ - void *temp = (char *)malloc (bytes); - - if (!temp) - memory_error_and_abort (); - return (temp); -} - -static void * -xrealloc (void *pointer, int bytes) -{ - void *temp; - - if (!pointer) - temp = malloc (bytes); - else - temp = realloc (pointer, bytes); - - if (!temp) - memory_error_and_abort (); - - return (temp); -} - -static void -memory_error_and_abort (void) -{ - fprintf (stderr, "readline: out of virtual memory\n"); - abort (); -} - -/* - * Local variables: - * compile-command: "gcc -g -DTEST -o tilde tilde.c" - * end: - */ -#endif /* TEST */ diff --git a/third_party/bash/tilde.h b/third_party/bash/tilde.h deleted file mode 100644 index bc8022afc..000000000 --- a/third_party/bash/tilde.h +++ /dev/null @@ -1,68 +0,0 @@ -/* tilde.h: Externally available variables and function in libtilde.a. */ - -/* Copyright (C) 1992-2009,2021 Free Software Foundation, Inc. - - This file contains the Readline Library (Readline), a set of - routines for providing Emacs style line input to programs that ask - for it. - - Readline is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Readline is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Readline. If not, see . -*/ - -#if !defined (_TILDE_H_) -# define _TILDE_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef char *tilde_hook_func_t (char *); - -/* If non-null, this contains the address of a function that the application - wants called before trying the standard tilde expansions. The function - is called with the text sans tilde, and returns a malloc()'ed string - which is the expansion, or a NULL pointer if the expansion fails. */ -extern tilde_hook_func_t *tilde_expansion_preexpansion_hook; - -/* If non-null, this contains the address of a function to call if the - standard meaning for expanding a tilde fails. The function is called - with the text (sans tilde, as in "foo"), and returns a malloc()'ed string - which is the expansion, or a NULL pointer if there is no expansion. */ -extern tilde_hook_func_t *tilde_expansion_failure_hook; - -/* When non-null, this is a NULL terminated array of strings which - are duplicates for a tilde prefix. Bash uses this to expand - `=~' and `:~'. */ -extern char **tilde_additional_prefixes; - -/* When non-null, this is a NULL terminated array of strings which match - the end of a username, instead of just "/". Bash sets this to - `:' and `=~'. */ -extern char **tilde_additional_suffixes; - -/* Return a new string which is the result of tilde expanding STRING. */ -extern char *tilde_expand (const char *); - -/* Do the work of tilde expansion on FILENAME. FILENAME starts with a - tilde. If there is no expansion, call tilde_expansion_failure_hook. */ -extern char *tilde_expand_word (const char *); - -/* Find the portion of the string beginning with ~ that should be expanded. */ -extern char *tilde_find_word (const char *, int, int *); - -#ifdef __cplusplus -} -#endif - -#endif /* _TILDE_H_ */ diff --git a/third_party/bash/timer.h b/third_party/bash/timer.h deleted file mode 100644 index 277947563..000000000 --- a/third_party/bash/timer.h +++ /dev/null @@ -1,64 +0,0 @@ -/* timer.h -- data structures used by the shell timers in lib/sh/timers.c */ - -/* Copyright (C) 2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "bashjmp.h" -typedef struct _shtimer -{ - struct timeval tmout; - - int fd; - int flags; - - int alrmflag; /* should be set by alrm_handler */ - - SigHandler *alrm_handler; - SigHandler *old_handler; - - procenv_t jmpenv; - - int (*tm_handler) (struct _shtimer *); /* called on timeout if set */ - PTR_T *data; /* reserved */ -} sh_timer; - -#define SHTIMER_ALARM 0x01 /* mutually exclusive */ -#define SHTIMER_SELECT 0x02 -#define SHTIMER_LONGJMP 0x04 - -#define SHTIMER_SIGSET 0x100 -#define SHTIMER_ALRMSET 0x200 - -extern sh_timer *shtimer_alloc (void); -extern void shtimer_flush (sh_timer *); -extern void shtimer_dispose (sh_timer *); - -extern void shtimer_set (sh_timer *, time_t, long); -extern void shtimer_unset (sh_timer *); - -extern void shtimer_cleanup (sh_timer *); -extern void shtimer_clear (sh_timer *); - -extern int shtimer_chktimeout (sh_timer *); - -extern int shtimer_select (sh_timer *); -extern int shtimer_alrm (sh_timer *); diff --git a/third_party/bash/timers.c b/third_party/bash/timers.c deleted file mode 100644 index 69b754c97..000000000 --- a/third_party/bash/timers.c +++ /dev/null @@ -1,262 +0,0 @@ -/* timers - functions to manage shell timers */ - -/* Copyright (C) 2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include "bashtypes.h" -#include "posixtime.h" - -#if defined (HAVE_UNISTD_H) -#include -#endif - -#if defined (HAVE_SELECT) -# include "posixselect.h" -# include "stat-time.h" -#endif - -#include "sig.h" -#include "bashjmp.h" -#include "xmalloc.h" - -#include "timer.h" - -#include -#if !defined (errno) -extern int errno; -#endif /* !errno */ - -#ifndef FREE -#define FREE(s) do { if (s) free (s); } while (0) -#endif - -extern unsigned int falarm (unsigned int, unsigned int); - -static void shtimer_zero (sh_timer *); - -static void -shtimer_zero (sh_timer *t) -{ - t->tmout.tv_sec = 0; - t->tmout.tv_usec = 0; - - t->fd = -1; - t->flags = t->alrmflag = 0; - - t->alrm_handler = t->old_handler = 0; - - memset (t->jmpenv, '\0', sizeof (t->jmpenv)); - - t->tm_handler = 0; - t->data = 0; -} - -sh_timer * -shtimer_alloc (void) -{ - sh_timer *t; - - t = (sh_timer *)xmalloc (sizeof (sh_timer)); - shtimer_zero (t); - return t; -} - -void -shtimer_flush (sh_timer *t) -{ - /* The caller can manage t->data arbitrarily as long as it frees and sets - t->data to 0 before calling this function. Otherwise, we do what we can - to avoid memleaks. */ - FREE (t->data); - shtimer_zero (t); -} - -void -shtimer_dispose (sh_timer *t) -{ - free (t); -} - -/* We keep the timer as an offset into the future from the time it's set. */ -void -shtimer_set (sh_timer *t, time_t sec, long usec) -{ - struct timeval now; - - if (t->flags & SHTIMER_ALARM) - { - t->alrmflag = 0; /* just paranoia */ - t->old_handler = set_signal_handler (SIGALRM, t->alrm_handler); - t->flags |= SHTIMER_SIGSET; - falarm (t->tmout.tv_sec = sec, t->tmout.tv_usec = usec); - t->flags |= SHTIMER_ALRMSET; - return; - } - - if (gettimeofday (&now, 0) < 0) - timerclear (&now); - - t->tmout.tv_sec = now.tv_sec + sec; - t->tmout.tv_usec = now.tv_usec + usec; - if (t->tmout.tv_usec > USEC_PER_SEC) - { - t->tmout.tv_sec++; - t->tmout.tv_usec -= USEC_PER_SEC; - } -} - -void -shtimer_unset (sh_timer *t) -{ - t->tmout.tv_sec = 0; - t->tmout.tv_usec = 0; - - if (t->flags & SHTIMER_ALARM) - { - t->alrmflag = 0; - if (t->flags & SHTIMER_ALRMSET) - falarm (0, 0); - if (t->old_handler && (t->flags & SHTIMER_SIGSET)) - { - set_signal_handler (SIGALRM, t->old_handler); - t->flags &= ~SHTIMER_SIGSET; - t->old_handler = 0; - } - } -} - -void -shtimer_cleanup (sh_timer *t) -{ - shtimer_unset (t); -} - -void -shtimer_clear (sh_timer *t) -{ - shtimer_unset (t); - shtimer_dispose (t); -} - -int -shtimer_chktimeout (sh_timer *t) -{ - struct timeval now; - int r; - - /* Use the flag to avoid returning sigalrm_seen here */ - if (t->flags & SHTIMER_ALARM) - return t->alrmflag; - - /* Could check a flag for this */ - if (t->tmout.tv_sec == 0 && t->tmout.tv_usec == 0) - return 0; - - if (gettimeofday (&now, 0) < 0) - return 0; - r = ((now.tv_sec > t->tmout.tv_sec) || - (now.tv_sec == t->tmout.tv_sec && now.tv_usec >= t->tmout.tv_usec)); - - return r; -} - -#if defined (HAVE_SELECT) || defined (HAVE_PSELECT) -int -shtimer_select (sh_timer *t) -{ - int r, nfd; - sigset_t blocked_sigs, prevmask; - struct timeval now, tv; - fd_set readfds; -#if defined (HAVE_PSELECT) - struct timespec ts; -#endif - - /* We don't want a SIGCHLD to interrupt this */ - sigemptyset (&blocked_sigs); -# if defined (SIGCHLD) - sigaddset (&blocked_sigs, SIGCHLD); -# endif - - if (gettimeofday (&now, 0) < 0) - { - if (t->flags & SHTIMER_LONGJMP) - sh_longjmp (t->jmpenv, 1); - else - return -1; - } - - /* If the timer has already expired, return immediately */ - if ((now.tv_sec > t->tmout.tv_sec) || - (now.tv_sec == t->tmout.tv_sec && now.tv_usec >= t->tmout.tv_usec)) - { - if (t->flags & SHTIMER_LONGJMP) - sh_longjmp (t->jmpenv, 1); - else if (t->tm_handler) - return ((*t->tm_handler) (t)); - else - return 0; - } - - /* compute timeout */ - tv.tv_sec = t->tmout.tv_sec - now.tv_sec; - tv.tv_usec = t->tmout.tv_usec - now.tv_usec; - if (tv.tv_usec < 0) - { - tv.tv_sec--; - tv.tv_usec += USEC_PER_SEC; - } - -#if defined (HAVE_PSELECT) - ts.tv_sec = tv.tv_sec; - ts.tv_nsec = tv.tv_usec * 1000; -#else - sigemptyset (&prevmask); -#endif /* !HAVE_PSELECT */ - - nfd = (t->fd >= 0) ? t->fd + 1 : 0; - FD_ZERO (&readfds); - if (t->fd >= 0) - FD_SET (t->fd, &readfds); - -#if defined (HAVE_PSELECT) - r = pselect(nfd, &readfds, (fd_set *)0, (fd_set *)0, &ts, &blocked_sigs); -#else - sigprocmask (SIG_SETMASK, &blocked_sigs, &prevmask); - r = select(nfd, &readfds, (fd_set *)0, (fd_set *)0, &tv); - sigprocmask (SIG_SETMASK, &prevmask, NULL); -#endif - - if (r < 0) - return r; /* caller will handle */ - else if (r == 0 && (t->flags & SHTIMER_LONGJMP)) - sh_longjmp (t->jmpenv, 1); - else if (r == 0 && t->tm_handler) - return ((*t->tm_handler) (t)); - else - return r; -} -#endif /* !HAVE_TIMEVAL || !HAVE_SELECT */ - -int -shtimer_alrm (sh_timer *t) -{ - return 0; -} diff --git a/third_party/bash/timeval.c b/third_party/bash/timeval.c deleted file mode 100644 index a5a5bc946..000000000 --- a/third_party/bash/timeval.c +++ /dev/null @@ -1,179 +0,0 @@ -/* timeval.c - functions to perform operations on struct timevals */ - -/* Copyright (C) 1999 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if defined (HAVE_TIMEVAL) - -#include -#include "posixtime.h" - -#include "bashintl.h" -#include "stdc.h" - -#ifndef locale_decpoint -extern int locale_decpoint PARAMS((void)); -#endif - -#include - -struct timeval * -difftimeval (d, t1, t2) - struct timeval *d, *t1, *t2; -{ - d->tv_sec = t2->tv_sec - t1->tv_sec; - d->tv_usec = t2->tv_usec - t1->tv_usec; - if (d->tv_usec < 0) - { - d->tv_usec += 1000000; - d->tv_sec -= 1; - if (d->tv_sec < 0) /* ??? -- BSD/OS does this */ - { - d->tv_sec = 0; - d->tv_usec = 0; - } - } - return d; -} - -struct timeval * -addtimeval (d, t1, t2) - struct timeval *d, *t1, *t2; -{ - d->tv_sec = t1->tv_sec + t2->tv_sec; - d->tv_usec = t1->tv_usec + t2->tv_usec; - if (d->tv_usec >= 1000000) - { - d->tv_usec -= 1000000; - d->tv_sec += 1; - } - return d; -} - -struct timeval * -multimeval (d, m) - struct timeval *d; - int m; -{ - time_t t; - - t = d->tv_usec * m; - d->tv_sec = d->tv_sec * m + t / 1000000; - d->tv_usec = t % 1000000; - return d; -} - -struct timeval * -divtimeval (d, m) - struct timeval *d; - int m; -{ - time_t t; - - t = d->tv_sec; - d->tv_sec = t / m; - d->tv_usec = (d->tv_usec + 1000000 * (t % m)) / m; - return d; -} - -/* Do "cpu = ((user + sys) * 10000) / real;" with timevals. - Barely-tested code from Deven T. Corzine . */ -int -timeval_to_cpu (rt, ut, st) - struct timeval *rt, *ut, *st; /* real, user, sys */ -{ - struct timeval t1, t2; - register int i; - - addtimeval (&t1, ut, st); - t2.tv_sec = rt->tv_sec; - t2.tv_usec = rt->tv_usec; - - for (i = 0; i < 6; i++) - { - if ((t1.tv_sec > 99999999) || (t2.tv_sec > 99999999)) - break; - t1.tv_sec *= 10; - t1.tv_sec += t1.tv_usec / 100000; - t1.tv_usec *= 10; - t1.tv_usec %= 1000000; - t2.tv_sec *= 10; - t2.tv_sec += t2.tv_usec / 100000; - t2.tv_usec *= 10; - t2.tv_usec %= 1000000; - } - for (i = 0; i < 4; i++) - { - if (t1.tv_sec < 100000000) - t1.tv_sec *= 10; - else - t2.tv_sec /= 10; - } - - return ((t2.tv_sec == 0) ? 0 : t1.tv_sec / t2.tv_sec); -} - -/* Convert a pointer to a struct timeval to seconds and thousandths of a - second, returning the values in *SP and *SFP, respectively. This does - rounding on the fractional part, not just truncation to three places. */ -void -timeval_to_secs (tvp, sp, sfp) - struct timeval *tvp; - time_t *sp; - int *sfp; -{ - int rest; - - *sp = tvp->tv_sec; - - *sfp = tvp->tv_usec % 1000000; /* pretty much a no-op */ - rest = *sfp % 1000; - *sfp = (*sfp * 1000) / 1000000; - if (rest >= 500) - *sfp += 1; - - /* Sanity check */ - if (*sfp >= 1000) - { - *sp += 1; - *sfp -= 1000; - } -} - -/* Print the contents of a struct timeval * in a standard way to stdio - stream FP. */ -void -print_timeval (fp, tvp) - FILE *fp; - struct timeval *tvp; -{ - time_t timestamp; - long minutes; - int seconds, seconds_fraction; - - timeval_to_secs (tvp, ×tamp, &seconds_fraction); - - minutes = timestamp / 60; - seconds = timestamp % 60; - - fprintf (fp, "%ldm%d%c%03ds", minutes, seconds, locale_decpoint (), seconds_fraction); -} - -#endif /* HAVE_TIMEVAL */ diff --git a/third_party/bash/tmpfile.c b/third_party/bash/tmpfile.c deleted file mode 100644 index 8f5cf3f11..000000000 --- a/third_party/bash/tmpfile.c +++ /dev/null @@ -1,311 +0,0 @@ -/* - * tmpfile.c - functions to create and safely open temp files for the shell. - */ - -/* Copyright (C) 2000-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include "bashtypes.h" -#include "posixstat.h" -#include "posixtime.h" -#include "filecntl.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "bashansi.h" - -#include -#include - -#include "shell.h" - -#ifndef errno -extern int errno; -#endif - -#define BASEOPENFLAGS (O_CREAT | O_TRUNC | O_EXCL | O_BINARY) - -#define DEFAULT_TMPDIR "." /* bogus default, should be changed */ -#define DEFAULT_NAMEROOT "shtmp" - -/* Use ANSI-C rand() interface if random(3) is not available */ -#if !HAVE_RANDOM -#define random() rand() -#endif - -extern pid_t dollar_dollar_pid; - -static char *get_sys_tmpdir PARAMS((void)); -static char *get_tmpdir PARAMS((int)); - -static char *sys_tmpdir = (char *)NULL; -static int ntmpfiles; -static int tmpnamelen = -1; -static unsigned long filenum = 1L; - -static char * -get_sys_tmpdir () -{ - if (sys_tmpdir) - return sys_tmpdir; - -#ifdef P_tmpdir - sys_tmpdir = P_tmpdir; - if (file_iswdir (sys_tmpdir)) - return sys_tmpdir; -#endif - - sys_tmpdir = "/tmp"; - if (file_iswdir (sys_tmpdir)) - return sys_tmpdir; - - sys_tmpdir = "/var/tmp"; - if (file_iswdir (sys_tmpdir)) - return sys_tmpdir; - - sys_tmpdir = "/usr/tmp"; - if (file_iswdir (sys_tmpdir)) - return sys_tmpdir; - - sys_tmpdir = DEFAULT_TMPDIR; - - return sys_tmpdir; -} - -static char * -get_tmpdir (flags) - int flags; -{ - char *tdir; - - tdir = (flags & MT_USETMPDIR) ? get_string_value ("TMPDIR") : (char *)NULL; - if (tdir && (file_iswdir (tdir) == 0 || strlen (tdir) > PATH_MAX)) - tdir = 0; - - if (tdir == 0) - tdir = get_sys_tmpdir (); - -#if defined (HAVE_PATHCONF) && defined (_PC_NAME_MAX) - if (tmpnamelen == -1) - tmpnamelen = pathconf (tdir, _PC_NAME_MAX); -#else - tmpnamelen = 0; -#endif - - return tdir; -} - -static void -sh_seedrand () -{ -#if HAVE_RANDOM - int d; - static int seeded = 0; - if (seeded == 0) - { - struct timeval tv; - - gettimeofday (&tv, NULL); - srandom (tv.tv_sec ^ tv.tv_usec ^ (getpid () << 16) ^ (uintptr_t)&d); - seeded = 1; - } -#endif -} - -char * -sh_mktmpname (nameroot, flags) - char *nameroot; - int flags; -{ - char *filename, *tdir, *lroot; - struct stat sb; - int r, tdlen; - static int seeded = 0; - - filename = (char *)xmalloc (PATH_MAX + 1); - tdir = get_tmpdir (flags); - tdlen = strlen (tdir); - - lroot = nameroot ? nameroot : DEFAULT_NAMEROOT; - if (nameroot == 0) - flags &= ~MT_TEMPLATE; - - if ((flags & MT_TEMPLATE) && strlen (nameroot) > PATH_MAX) - flags &= ~MT_TEMPLATE; - -#ifdef USE_MKTEMP - if (flags & MT_TEMPLATE) - strcpy (filename, nameroot); - else - sprintf (filename, "%s/%s.XXXXXX", tdir, lroot); - if (mktemp (filename) == 0) - { - free (filename); - filename = NULL; - } -#else /* !USE_MKTEMP */ - sh_seedrand (); - while (1) - { - filenum = (filenum << 1) ^ - (unsigned long) time ((time_t *)0) ^ - (unsigned long) dollar_dollar_pid ^ - (unsigned long) ((flags & MT_USERANDOM) ? random () : ntmpfiles++); - sprintf (filename, "%s/%s-%lu", tdir, lroot, filenum); - if (tmpnamelen > 0 && tmpnamelen < 32) - filename[tdlen + 1 + tmpnamelen] = '\0'; -# ifdef HAVE_LSTAT - r = lstat (filename, &sb); -# else - r = stat (filename, &sb); -# endif - if (r < 0 && errno == ENOENT) - break; - } -#endif /* !USE_MKTEMP */ - - return filename; -} - -int -sh_mktmpfd (nameroot, flags, namep) - char *nameroot; - int flags; - char **namep; -{ - char *filename, *tdir, *lroot; - int fd, tdlen; - - filename = (char *)xmalloc (PATH_MAX + 1); - tdir = get_tmpdir (flags); - tdlen = strlen (tdir); - - lroot = nameroot ? nameroot : DEFAULT_NAMEROOT; - if (nameroot == 0) - flags &= ~MT_TEMPLATE; - - if ((flags & MT_TEMPLATE) && strlen (nameroot) > PATH_MAX) - flags &= ~MT_TEMPLATE; - -#ifdef USE_MKSTEMP - if (flags & MT_TEMPLATE) - strcpy (filename, nameroot); - else - sprintf (filename, "%s/%s.XXXXXX", tdir, lroot); - fd = mkstemp (filename); - if (fd < 0 || namep == 0) - { - free (filename); - filename = NULL; - } - if (namep) - *namep = filename; - return fd; -#else /* !USE_MKSTEMP */ - sh_seedrand (); - do - { - filenum = (filenum << 1) ^ - (unsigned long) time ((time_t *)0) ^ - (unsigned long) dollar_dollar_pid ^ - (unsigned long) ((flags & MT_USERANDOM) ? random () : ntmpfiles++); - sprintf (filename, "%s/%s-%lu", tdir, lroot, filenum); - if (tmpnamelen > 0 && tmpnamelen < 32) - filename[tdlen + 1 + tmpnamelen] = '\0'; - fd = open (filename, BASEOPENFLAGS | ((flags & MT_READWRITE) ? O_RDWR : O_WRONLY), 0600); - } - while (fd < 0 && errno == EEXIST); - - if (namep) - *namep = filename; - else - free (filename); - - return fd; -#endif /* !USE_MKSTEMP */ -} - -FILE * -sh_mktmpfp (nameroot, flags, namep) - char *nameroot; - int flags; - char **namep; -{ - int fd; - FILE *fp; - - fd = sh_mktmpfd (nameroot, flags, namep); - if (fd < 0) - return ((FILE *)NULL); - fp = fdopen (fd, (flags & MT_READWRITE) ? "w+" : "w"); - if (fp == 0) - close (fd); - return fp; -} - -char * -sh_mktmpdir (nameroot, flags) - char *nameroot; - int flags; -{ - char *filename, *tdir, *lroot, *dirname; - int fd, tdlen; - -#ifdef USE_MKDTEMP - filename = (char *)xmalloc (PATH_MAX + 1); - tdir = get_tmpdir (flags); - tdlen = strlen (tdir); - - lroot = nameroot ? nameroot : DEFAULT_NAMEROOT; - if (nameroot == 0) - flags &= ~MT_TEMPLATE; - - if ((flags & MT_TEMPLATE) && strlen (nameroot) > PATH_MAX) - flags &= ~MT_TEMPLATE; - - if (flags & MT_TEMPLATE) - strcpy (filename, nameroot); - else - sprintf (filename, "%s/%s.XXXXXX", tdir, lroot); - dirname = mkdtemp (filename); - if (dirname == 0) - { - free (filename); - filename = NULL; - } - return dirname; -#else /* !USE_MKDTEMP */ - filename = (char *)NULL; - do - { - filename = sh_mktmpname (nameroot, flags); - fd = mkdir (filename, 0700); - if (fd == 0) - break; - free (filename); - filename = (char *)NULL; - } - while (fd < 0 && errno == EEXIST); - - return (filename); -#endif /* !USE_MKDTEMP */ -} diff --git a/third_party/bash/trap.c b/third_party/bash/trap.c deleted file mode 100644 index 40afd9a78..000000000 --- a/third_party/bash/trap.c +++ /dev/null @@ -1,1575 +0,0 @@ -/* trap.c -- Not the trap command, but useful functions for manipulating - those objects. The trap command is in builtins/trap.def. */ - -/* Copyright (C) 1987-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include "bashtypes.h" -#include "bashansi.h" - -#include -#include - -#include "bashintl.h" - -#include - -#include "trap.h" - -#include "shell.h" -#include "execute_cmd.h" -#include "flags.h" -#include "parser.h" -#include "input.h" /* for save_token_state, restore_token_state */ -#include "jobs.h" -#include "signames.h" -#include "builtins.h" -#include "common.h" -#include "builtext.h" - -#if defined (READLINE) -# include "third_party/readline/readline.h" -# include "bashline.h" -#endif - -#ifndef errno -extern int errno; -#endif - -/* Flags which describe the current handling state of a signal. */ -#define SIG_INHERITED 0x0 /* Value inherited from parent. */ -#define SIG_TRAPPED 0x1 /* Currently trapped. */ -#define SIG_HARD_IGNORE 0x2 /* Signal was ignored on shell entry. */ -#define SIG_SPECIAL 0x4 /* Treat this signal specially. */ -#define SIG_NO_TRAP 0x8 /* Signal cannot be trapped. */ -#define SIG_INPROGRESS 0x10 /* Signal handler currently executing. */ -#define SIG_CHANGED 0x20 /* Trap value changed in trap handler. */ -#define SIG_IGNORED 0x40 /* The signal is currently being ignored. */ - -#define SPECIAL_TRAP(s) ((s) == EXIT_TRAP || (s) == DEBUG_TRAP || (s) == ERROR_TRAP || (s) == RETURN_TRAP) - -/* An array of such flags, one for each signal, describing what the - shell will do with a signal. DEBUG_TRAP == NSIG; some code below - assumes this. */ -static int sigmodes[BASH_NSIG]; - -static void free_trap_command (int); -static void change_signal (int, char *); - -static int _run_trap_internal (int, char *); - -static void free_trap_string (int); -static void reset_signal (int); -static void restore_signal (int); -static void reset_or_restore_signal_handlers (sh_resetsig_func_t *); -static void reinit_trap (int); - -static void trap_if_untrapped (int, char *); - -/* Variables used here but defined in other files. */ - -extern volatile int from_return_trap; -extern int waiting_for_child; - -extern WORD_LIST *subst_assign_varlist; - -/* The list of things to do originally, before we started trapping. */ -SigHandler *original_signals[NSIG]; - -/* For each signal, a slot for a string, which is a command to be - executed when that signal is received. The slot can also contain - DEFAULT_SIG, which means do whatever you were going to do before - you were so rudely interrupted, or IGNORE_SIG, which says ignore - this signal. */ -char *trap_list[BASH_NSIG]; - -/* A bitmap of signals received for which we have trap handlers. */ -int pending_traps[NSIG]; - -/* Set to the number of the signal we're running the trap for + 1. - Used in execute_cmd.c and builtins/common.c to clean up when - parse_and_execute does not return normally after executing the - trap command (e.g., when `return' is executed in the trap command). */ -int running_trap; - -/* Set to last_command_exit_value before running a trap. */ -int trap_saved_exit_value; - -/* The (trapped) signal received while executing in the `wait' builtin */ -int wait_signal_received; - -int trapped_signal_received; - -/* Set to 1 to suppress the effect of `set v' in the DEBUG trap. */ -int suppress_debug_trap_verbose = 0; - -#define GETORIGSIG(sig) \ - do { \ - original_signals[sig] = (SigHandler *)set_signal_handler (sig, SIG_DFL); \ - set_signal_handler (sig, original_signals[sig]); \ - if (original_signals[sig] == SIG_IGN) \ - sigmodes[sig] |= SIG_HARD_IGNORE; \ - } while (0) - -#define SETORIGSIG(sig,handler) \ - do { \ - original_signals[sig] = handler; \ - if (original_signals[sig] == SIG_IGN) \ - sigmodes[sig] |= SIG_HARD_IGNORE; \ - } while (0) - -#define GET_ORIGINAL_SIGNAL(sig) \ - if (sig && sig < NSIG && original_signals[sig] == IMPOSSIBLE_TRAP_HANDLER) \ - GETORIGSIG(sig) - -void -initialize_traps () -{ - register int i; - - initialize_signames(); - - trap_list[EXIT_TRAP] = trap_list[DEBUG_TRAP] = trap_list[ERROR_TRAP] = trap_list[RETURN_TRAP] = (char *)NULL; - sigmodes[EXIT_TRAP] = sigmodes[DEBUG_TRAP] = sigmodes[ERROR_TRAP] = sigmodes[RETURN_TRAP] = SIG_INHERITED; - original_signals[EXIT_TRAP] = IMPOSSIBLE_TRAP_HANDLER; - - for (i = 1; i < NSIG; i++) - { - pending_traps[i] = 0; - trap_list[i] = (char *)DEFAULT_SIG; - sigmodes[i] = SIG_INHERITED; /* XXX - only set, not used */ - original_signals[i] = IMPOSSIBLE_TRAP_HANDLER; - } - - /* Show which signals are treated specially by the shell. */ -#if defined (SIGCHLD) - GETORIGSIG (SIGCHLD); - sigmodes[SIGCHLD] |= (SIG_SPECIAL | SIG_NO_TRAP); -#endif /* SIGCHLD */ - - GETORIGSIG (SIGINT); - sigmodes[SIGINT] |= SIG_SPECIAL; - -#if defined (__BEOS__) - /* BeOS sets SIGINT to SIG_IGN! */ - original_signals[SIGINT] = SIG_DFL; - sigmodes[SIGINT] &= ~SIG_HARD_IGNORE; -#endif - - GETORIGSIG (SIGQUIT); - sigmodes[SIGQUIT] |= SIG_SPECIAL; - - if (interactive) - { - GETORIGSIG (SIGTERM); - sigmodes[SIGTERM] |= SIG_SPECIAL; - } - - get_original_tty_job_signals (); -} - -#ifdef DEBUG -/* Return a printable representation of the trap handler for SIG. */ -static char * -trap_handler_string (sig) - int sig; -{ - if (trap_list[sig] == (char *)DEFAULT_SIG) - return "DEFAULT_SIG"; - else if (trap_list[sig] == (char *)IGNORE_SIG) - return "IGNORE_SIG"; - else if (trap_list[sig] == (char *)IMPOSSIBLE_TRAP_HANDLER) - return "IMPOSSIBLE_TRAP_HANDLER"; - else if (trap_list[sig]) - return trap_list[sig]; - else - return "NULL"; -} -#endif - -/* Return the print name of this signal. */ -char * -signal_name (sig) - int sig; -{ - char *ret; - - /* on cygwin32, signal_names[sig] could be null */ - ret = (sig >= BASH_NSIG || sig < 0 || signal_names[sig] == NULL) - ? _("invalid signal number") - : signal_names[sig]; - - return ret; -} - -/* Turn a string into a signal number, or a number into - a signal number. If STRING is "2", "SIGINT", or "INT", - then (int)2 is returned. Return NO_SIG if STRING doesn't - contain a valid signal descriptor. */ -int -decode_signal (string, flags) - char *string; - int flags; -{ - intmax_t sig; - char *name; - - if (legal_number (string, &sig)) - return ((sig >= 0 && sig < NSIG) ? (int)sig : NO_SIG); - -#if defined (SIGRTMIN) && defined (SIGRTMAX) - if (STREQN (string, "SIGRTMIN+", 9) || ((flags & DSIG_NOCASE) && strncasecmp (string, "SIGRTMIN+", 9) == 0)) - { - if (legal_number (string+9, &sig) && sig >= 0 && sig <= SIGRTMAX - SIGRTMIN) - return (SIGRTMIN + sig); - else - return NO_SIG; - } - else if (STREQN (string, "RTMIN+", 6) || ((flags & DSIG_NOCASE) && strncasecmp (string, "RTMIN+", 6) == 0)) - { - if (legal_number (string+6, &sig) && sig >= 0 && sig <= SIGRTMAX - SIGRTMIN) - return (SIGRTMIN + sig); - else - return NO_SIG; - } -#endif /* SIGRTMIN && SIGRTMAX */ - - /* A leading `SIG' may be omitted. */ - for (sig = 0; sig < BASH_NSIG; sig++) - { - name = signal_names[sig]; - if (name == 0 || name[0] == '\0') - continue; - - /* Check name without the SIG prefix first case sensitively or - insensitively depending on whether flags includes DSIG_NOCASE */ - if (STREQN (name, "SIG", 3)) - { - name += 3; - - if ((flags & DSIG_NOCASE) && strcasecmp (string, name) == 0) - return ((int)sig); - else if ((flags & DSIG_NOCASE) == 0 && strcmp (string, name) == 0) - return ((int)sig); - /* If we can't use the `SIG' prefix to match, punt on this - name now. */ - else if ((flags & DSIG_SIGPREFIX) == 0) - continue; - } - - /* Check name with SIG prefix case sensitively or insensitively - depending on whether flags includes DSIG_NOCASE */ - name = signal_names[sig]; - if ((flags & DSIG_NOCASE) && strcasecmp (string, name) == 0) - return ((int)sig); - else if ((flags & DSIG_NOCASE) == 0 && strcmp (string, name) == 0) - return ((int)sig); - } - - return (NO_SIG); -} - -/* Non-zero when we catch a trapped signal. */ -static int catch_flag; - -void -run_pending_traps () -{ - register int sig; - int x; - volatile int old_exit_value, old_running; - WORD_LIST *save_subst_varlist; - HASH_TABLE *save_tempenv; - sh_parser_state_t pstate; - volatile int save_return_catch_flag, function_code; - procenv_t save_return_catch; -#if defined (ARRAY_VARS) - ARRAY *ps; -#endif - - if (catch_flag == 0) /* simple optimization */ - return; - - if (running_trap > 0) - { - internal_debug ("run_pending_traps: recursive invocation while running trap for signal %d", running_trap-1); -#if defined (SIGWINCH) - if (running_trap == SIGWINCH+1 && pending_traps[SIGWINCH]) - return; /* no recursive SIGWINCH trap invocations */ -#endif - /* could check for running the trap handler for the same signal here - (running_trap == sig+1) */ - if (evalnest_max > 0 && evalnest > evalnest_max) - { - internal_error (_("trap handler: maximum trap handler level exceeded (%d)"), evalnest_max); - evalnest = 0; - jump_to_top_level (DISCARD); - } - } - - catch_flag = trapped_signal_received = 0; - - /* Preserve $? when running trap. */ - trap_saved_exit_value = old_exit_value = last_command_exit_value; -#if defined (ARRAY_VARS) - ps = save_pipestatus_array (); -#endif - old_running = running_trap; - - for (sig = 1; sig < NSIG; sig++) - { - /* XXX this could be made into a counter by using - while (pending_traps[sig]--) instead of the if statement. */ - if (pending_traps[sig]) - { - /* XXX - set last_command_exit_value = trap_saved_exit_value here? */ - running_trap = sig + 1; - - if (sig == SIGINT) - { - pending_traps[sig] = 0; /* XXX */ - /* We don't modify evalnest here, since run_interrupt_trap() calls - _run_trap_internal, which does. */ - run_interrupt_trap (0); - CLRINTERRUPT; /* interrupts don't stack */ - } -#if defined (JOB_CONTROL) && defined (SIGCHLD) - else if (sig == SIGCHLD && - trap_list[SIGCHLD] != (char *)IMPOSSIBLE_TRAP_HANDLER && - (sigmodes[SIGCHLD] & SIG_INPROGRESS) == 0) - { - sigmodes[SIGCHLD] |= SIG_INPROGRESS; - /* We modify evalnest here even though run_sigchld_trap can run - the trap action more than once */ - evalnest++; - x = pending_traps[sig]; - pending_traps[sig] = 0; - run_sigchld_trap (x); /* use as counter */ - running_trap = 0; - evalnest--; - sigmodes[SIGCHLD] &= ~SIG_INPROGRESS; - /* continue here rather than reset pending_traps[SIGCHLD] below in - case there are recursive calls to run_pending_traps and children - have been reaped while run_sigchld_trap was running. */ - continue; - } - else if (sig == SIGCHLD && - trap_list[SIGCHLD] == (char *)IMPOSSIBLE_TRAP_HANDLER && - (sigmodes[SIGCHLD] & SIG_INPROGRESS) != 0) - { - /* This can happen when run_pending_traps is called while - running a SIGCHLD trap handler. */ - running_trap = 0; - /* want to leave pending_traps[SIGCHLD] alone here */ - continue; /* XXX */ - } - else if (sig == SIGCHLD && (sigmodes[SIGCHLD] & SIG_INPROGRESS)) - { - /* whoops -- print warning? */ - running_trap = 0; /* XXX */ - /* want to leave pending_traps[SIGCHLD] alone here */ - continue; - } -#endif - else if (trap_list[sig] == (char *)DEFAULT_SIG || - trap_list[sig] == (char *)IGNORE_SIG || - trap_list[sig] == (char *)IMPOSSIBLE_TRAP_HANDLER) - { - /* This is possible due to a race condition. Say a bash - process has SIGTERM trapped. A subshell is spawned - using { list; } & and the parent does something and kills - the subshell with SIGTERM. It's possible for the subshell - to set pending_traps[SIGTERM] to 1 before the code in - execute_cmd.c eventually calls restore_original_signals - to reset the SIGTERM signal handler in the subshell. The - next time run_pending_traps is called, pending_traps[SIGTERM] - will be 1, but the trap handler in trap_list[SIGTERM] will - be invalid (probably DEFAULT_SIG, but it could be IGNORE_SIG). - Unless we catch this, the subshell will dump core when - trap_list[SIGTERM] == DEFAULT_SIG, because DEFAULT_SIG is - usually 0x0. */ - internal_warning (_("run_pending_traps: bad value in trap_list[%d]: %p"), - sig, trap_list[sig]); - if (trap_list[sig] == (char *)DEFAULT_SIG) - { - internal_warning (_("run_pending_traps: signal handler is SIG_DFL, resending %d (%s) to myself"), sig, signal_name (sig)); - kill (getpid (), sig); - } - } - else - { - save_parser_state (&pstate); - save_subst_varlist = subst_assign_varlist; - subst_assign_varlist = 0; - save_tempenv = temporary_env; - temporary_env = 0; /* traps should not run with temporary env */ - -#if defined (JOB_CONTROL) - save_pipeline (1); /* XXX only provides one save level */ -#endif - /* XXX - set pending_traps[sig] = 0 here? */ - pending_traps[sig] = 0; - evalnest++; - - function_code = 0; - save_return_catch_flag = return_catch_flag; - if (return_catch_flag) - { - COPY_PROCENV (return_catch, save_return_catch); - function_code = setjmp_nosigs (return_catch); - } - - if (function_code == 0) - x = parse_and_execute (savestring (trap_list[sig]), "trap", SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE); - else - { - parse_and_execute_cleanup (sig + 1); /* XXX - could use -1 */ - x = return_catch_value; - } - - evalnest--; -#if defined (JOB_CONTROL) - restore_pipeline (1); -#endif - - subst_assign_varlist = save_subst_varlist; - restore_parser_state (&pstate); - temporary_env = save_tempenv; - - if (save_return_catch_flag) - { - return_catch_flag = save_return_catch_flag; - return_catch_value = x; - COPY_PROCENV (save_return_catch, return_catch); - if (function_code) - { - running_trap = old_running; /* XXX */ - /* caller will set last_command_exit_value */ - sh_longjmp (return_catch, 1); - } - } - } - - pending_traps[sig] = 0; /* XXX - move before evalstring? */ - running_trap = old_running; - } - } - -#if defined (ARRAY_VARS) - restore_pipestatus_array (ps); -#endif - last_command_exit_value = old_exit_value; -} - -/* Set the private state variables noting that we received a signal SIG - for which we have a trap set. */ -void -set_trap_state (sig) - int sig; -{ - catch_flag = 1; - pending_traps[sig]++; - trapped_signal_received = sig; -} - -sighandler -trap_handler (sig) - int sig; -{ - int oerrno; - - if ((sigmodes[sig] & SIG_TRAPPED) == 0) - { - internal_debug ("trap_handler: signal %d: signal not trapped", sig); - SIGRETURN (0); - } - - /* This means we're in a subshell, but have not yet reset the handler for - trapped signals. We're not supposed to execute the trap in this situation; - we should restore the original signal and resend the signal to ourselves - to preserve the Posix "signal traps that are not being ignored shall be - set to the default action" semantics. */ - if ((subshell_environment & SUBSHELL_IGNTRAP) && trap_list[sig] != (char *)IGNORE_SIG) - { - sigset_t mask; - - /* Paranoia */ - if (original_signals[sig] == IMPOSSIBLE_TRAP_HANDLER) - original_signals[sig] = SIG_DFL; - - restore_signal (sig); - - /* Make sure we let the signal we just caught through */ - sigemptyset (&mask); - sigprocmask (SIG_SETMASK, (sigset_t *)NULL, &mask); - sigdelset (&mask, sig); - sigprocmask (SIG_SETMASK, &mask, (sigset_t *)NULL); - - kill (getpid (), sig); - - SIGRETURN (0); - } - - if ((sig >= NSIG) || - (trap_list[sig] == (char *)DEFAULT_SIG) || - (trap_list[sig] == (char *)IGNORE_SIG)) - programming_error (_("trap_handler: bad signal %d"), sig); - else - { - oerrno = errno; -#if defined (MUST_REINSTALL_SIGHANDLERS) -# if defined (JOB_CONTROL) && defined (SIGCHLD) - if (sig != SIGCHLD) -# endif /* JOB_CONTROL && SIGCHLD */ - set_signal_handler (sig, trap_handler); -#endif /* MUST_REINSTALL_SIGHANDLERS */ - - set_trap_state (sig); - - if (this_shell_builtin && (this_shell_builtin == wait_builtin)) - { - wait_signal_received = sig; - if (waiting_for_child && wait_intr_flag) - sh_longjmp (wait_intr_buf, 1); - } - -#if defined (READLINE) - /* Set the event hook so readline will call it after the signal handlers - finish executing, so if this interrupted character input we can get - quick response. */ - if (RL_ISSTATE (RL_STATE_SIGHANDLER)) - bashline_set_event_hook (); -#endif - - errno = oerrno; - } - - SIGRETURN (0); -} - -int -next_pending_trap (start) - int start; -{ - register int i; - - for (i = start; i < NSIG; i++) - if (pending_traps[i]) - return i; - return -1; -} - -int -first_pending_trap () -{ - return (next_pending_trap (1)); -} - -/* Return > 0 if any of the "real" signals (not fake signals like EXIT) are - trapped. */ -int -any_signals_trapped () -{ - register int i; - - for (i = 1; i < NSIG; i++) - if ((sigmodes[i] & SIG_TRAPPED) && (sigmodes[i] & SIG_IGNORED) == 0) - return i; - return -1; -} - -void -clear_pending_traps () -{ - register int i; - - for (i = 1; i < NSIG; i++) - pending_traps[i] = 0; -} - -void -check_signals () -{ - /* Add any other shell timeouts here */ - check_read_timeout (); /* set by the read builtin */ - QUIT; -} - -/* Convenience functions the rest of the shell can use */ -void -check_signals_and_traps () -{ - check_signals (); - - run_pending_traps (); -} - -#if defined (JOB_CONTROL) && defined (SIGCHLD) - -#ifdef INCLUDE_UNUSED -/* Make COMMAND_STRING be executed when SIGCHLD is caught. */ -void -set_sigchld_trap (command_string) - char *command_string; -{ - set_signal (SIGCHLD, command_string); -} -#endif - -/* Make COMMAND_STRING be executed when SIGCHLD is caught iff SIGCHLD - is not already trapped. IMPOSSIBLE_TRAP_HANDLER is used as a sentinel - to make sure that a SIGCHLD trap handler run via run_sigchld_trap can - reset the disposition to the default and not have the original signal - accidentally restored, undoing the user's command. */ -void -maybe_set_sigchld_trap (command_string) - char *command_string; -{ - if ((sigmodes[SIGCHLD] & SIG_TRAPPED) == 0 && trap_list[SIGCHLD] == (char *)IMPOSSIBLE_TRAP_HANDLER) - set_signal (SIGCHLD, command_string); -} - -/* Temporarily set the SIGCHLD trap string to IMPOSSIBLE_TRAP_HANDLER. Used - as a sentinel in run_sigchld_trap and maybe_set_sigchld_trap to see whether - or not a SIGCHLD trap handler reset SIGCHLD disposition to the default. */ -void -set_impossible_sigchld_trap () -{ - restore_default_signal (SIGCHLD); - change_signal (SIGCHLD, (char *)IMPOSSIBLE_TRAP_HANDLER); - sigmodes[SIGCHLD] &= ~SIG_TRAPPED; /* maybe_set_sigchld_trap checks this */ -} - -/* Act as if we received SIGCHLD NCHILD times and increment - pending_traps[SIGCHLD] by that amount. This allows us to still run the - SIGCHLD trap once for each exited child. */ -void -queue_sigchld_trap (nchild) - int nchild; -{ - if (nchild > 0) - { - catch_flag = 1; - pending_traps[SIGCHLD] += nchild; - trapped_signal_received = SIGCHLD; - } -} -#endif /* JOB_CONTROL && SIGCHLD */ - -/* Set a trap for SIG only if SIG is not already trapped. */ -static inline void -trap_if_untrapped (sig, command) - int sig; - char *command; -{ - if ((sigmodes[sig] & SIG_TRAPPED) == 0) - set_signal (sig, command); -} - -void -set_debug_trap (command) - char *command; -{ - set_signal (DEBUG_TRAP, command); -} - -/* Separate function to call when functions and sourced files want to restore - the original version of the DEBUG trap before returning. Unless the -T - option is set, source and shell function execution save the old debug trap - and unset the trap. If the function or sourced file changes the DEBUG trap, - SIG_TRAPPED will be set and we don't bother restoring the original trap string. - This is used by both functions and the source builtin. */ -void -maybe_set_debug_trap (command) - char *command; -{ - trap_if_untrapped (DEBUG_TRAP, command); -} - -void -set_error_trap (command) - char *command; -{ - set_signal (ERROR_TRAP, command); -} - -void -maybe_set_error_trap (command) - char *command; -{ - trap_if_untrapped (ERROR_TRAP, command); -} - -void -set_return_trap (command) - char *command; -{ - set_signal (RETURN_TRAP, command); -} - -void -maybe_set_return_trap (command) - char *command; -{ - trap_if_untrapped (RETURN_TRAP, command); -} - -#ifdef INCLUDE_UNUSED -void -set_sigint_trap (command) - char *command; -{ - set_signal (SIGINT, command); -} -#endif - -/* Reset the SIGINT handler so that subshells that are doing `shellsy' - things, like waiting for command substitution or executing commands - in explicit subshells ( ( cmd ) ), can catch interrupts properly. */ -SigHandler * -set_sigint_handler () -{ - if (sigmodes[SIGINT] & SIG_HARD_IGNORE) - return ((SigHandler *)SIG_IGN); - - else if (sigmodes[SIGINT] & SIG_IGNORED) - return ((SigHandler *)set_signal_handler (SIGINT, SIG_IGN)); /* XXX */ - - else if (sigmodes[SIGINT] & SIG_TRAPPED) - return ((SigHandler *)set_signal_handler (SIGINT, trap_handler)); - - /* The signal is not trapped, so set the handler to the shell's special - interrupt handler. */ - else if (interactive) /* XXX - was interactive_shell */ - return (set_signal_handler (SIGINT, sigint_sighandler)); - else - return (set_signal_handler (SIGINT, termsig_sighandler)); -} - -/* Return the correct handler for signal SIG according to the values in - sigmodes[SIG]. */ -SigHandler * -trap_to_sighandler (sig) - int sig; -{ - if (sigmodes[sig] & (SIG_IGNORED|SIG_HARD_IGNORE)) - return (SIG_IGN); - else if (sigmodes[sig] & SIG_TRAPPED) - return (trap_handler); - else - return (SIG_DFL); -} - -/* Set SIG to call STRING as a command. */ -void -set_signal (sig, string) - int sig; - char *string; -{ - sigset_t set, oset; - - if (SPECIAL_TRAP (sig)) - { - change_signal (sig, savestring (string)); - if (sig == EXIT_TRAP && interactive == 0) - initialize_terminating_signals (); - return; - } - - /* A signal ignored on entry to the shell cannot be trapped or reset, but - no error is reported when attempting to do so. -- Posix.2 */ - if (sigmodes[sig] & SIG_HARD_IGNORE) - return; - - /* Make sure we have original_signals[sig] if the signal has not yet - been trapped. */ - if ((sigmodes[sig] & SIG_TRAPPED) == 0) - { - /* If we aren't sure of the original value, check it. */ - if (original_signals[sig] == IMPOSSIBLE_TRAP_HANDLER) - GETORIGSIG (sig); - if (original_signals[sig] == SIG_IGN) - return; - } - - /* Only change the system signal handler if SIG_NO_TRAP is not set. - The trap command string is changed in either case. The shell signal - handlers for SIGINT and SIGCHLD run the user specified traps in an - environment in which it is safe to do so. */ - if ((sigmodes[sig] & SIG_NO_TRAP) == 0) - { - BLOCK_SIGNAL (sig, set, oset); - change_signal (sig, savestring (string)); - set_signal_handler (sig, trap_handler); - UNBLOCK_SIGNAL (oset); - } - else - change_signal (sig, savestring (string)); -} - -static void -free_trap_command (sig) - int sig; -{ - if ((sigmodes[sig] & SIG_TRAPPED) && trap_list[sig] && - (trap_list[sig] != (char *)IGNORE_SIG) && - (trap_list[sig] != (char *)DEFAULT_SIG) && - (trap_list[sig] != (char *)IMPOSSIBLE_TRAP_HANDLER)) - free (trap_list[sig]); -} - -/* If SIG has a string assigned to it, get rid of it. Then give it - VALUE. */ -static void -change_signal (sig, value) - int sig; - char *value; -{ - if ((sigmodes[sig] & SIG_INPROGRESS) == 0) - free_trap_command (sig); - trap_list[sig] = value; - - sigmodes[sig] |= SIG_TRAPPED; - if (value == (char *)IGNORE_SIG) - sigmodes[sig] |= SIG_IGNORED; - else - sigmodes[sig] &= ~SIG_IGNORED; - if (sigmodes[sig] & SIG_INPROGRESS) - sigmodes[sig] |= SIG_CHANGED; -} - -void -get_original_signal (sig) - int sig; -{ - /* If we aren't sure the of the original value, then get it. */ - if (sig > 0 && sig < NSIG && original_signals[sig] == (SigHandler *)IMPOSSIBLE_TRAP_HANDLER) - GETORIGSIG (sig); -} - -void -get_all_original_signals () -{ - register int i; - - for (i = 1; i < NSIG; i++) - GET_ORIGINAL_SIGNAL (i); -} - -void -set_original_signal (sig, handler) - int sig; - SigHandler *handler; -{ - if (sig > 0 && sig < NSIG && original_signals[sig] == (SigHandler *)IMPOSSIBLE_TRAP_HANDLER) - SETORIGSIG (sig, handler); -} - -/* Restore the default action for SIG; i.e., the action the shell - would have taken before you used the trap command. This is called - from trap_builtin (), which takes care to restore the handlers for - the signals the shell treats specially. */ -void -restore_default_signal (sig) - int sig; -{ - if (SPECIAL_TRAP (sig)) - { - if ((sig != DEBUG_TRAP && sig != ERROR_TRAP && sig != RETURN_TRAP) || - (sigmodes[sig] & SIG_INPROGRESS) == 0) - free_trap_command (sig); - trap_list[sig] = (char *)NULL; - sigmodes[sig] &= ~SIG_TRAPPED; - if (sigmodes[sig] & SIG_INPROGRESS) - sigmodes[sig] |= SIG_CHANGED; - return; - } - - GET_ORIGINAL_SIGNAL (sig); - - /* A signal ignored on entry to the shell cannot be trapped or reset, but - no error is reported when attempting to do so. Thanks Posix.2. */ - if (sigmodes[sig] & SIG_HARD_IGNORE) - return; - - /* If we aren't trapping this signal, don't bother doing anything else. */ - /* We special-case SIGCHLD and IMPOSSIBLE_TRAP_HANDLER (see above) as a - sentinel to determine whether or not disposition is reset to the default - while the trap handler is executing. */ - if (((sigmodes[sig] & SIG_TRAPPED) == 0) && - (sig != SIGCHLD || (sigmodes[sig] & SIG_INPROGRESS) == 0 || trap_list[sig] != (char *)IMPOSSIBLE_TRAP_HANDLER)) - return; - - /* Only change the signal handler for SIG if it allows it. */ - if ((sigmodes[sig] & SIG_NO_TRAP) == 0) - set_signal_handler (sig, original_signals[sig]); - - /* Change the trap command in either case. */ - change_signal (sig, (char *)DEFAULT_SIG); - - /* Mark the signal as no longer trapped. */ - sigmodes[sig] &= ~SIG_TRAPPED; -} - -/* Make this signal be ignored. */ -void -ignore_signal (sig) - int sig; -{ - if (SPECIAL_TRAP (sig) && ((sigmodes[sig] & SIG_IGNORED) == 0)) - { - change_signal (sig, (char *)IGNORE_SIG); - return; - } - - GET_ORIGINAL_SIGNAL (sig); - - /* A signal ignored on entry to the shell cannot be trapped or reset. - No error is reported when the user attempts to do so. */ - if (sigmodes[sig] & SIG_HARD_IGNORE) - return; - - /* If already trapped and ignored, no change necessary. */ - if (sigmodes[sig] & SIG_IGNORED) - return; - - /* Only change the signal handler for SIG if it allows it. */ - if ((sigmodes[sig] & SIG_NO_TRAP) == 0) - set_signal_handler (sig, SIG_IGN); - - /* Change the trap command in either case. */ - change_signal (sig, (char *)IGNORE_SIG); -} - -/* Handle the calling of "trap 0". The only sticky situation is when - the command to be executed includes an "exit". This is why we have - to provide our own place for top_level to jump to. */ -int -run_exit_trap () -{ - char *trap_command; - int code, function_code, retval; -#if defined (ARRAY_VARS) - ARRAY *ps; -#endif - - trap_saved_exit_value = last_command_exit_value; -#if defined (ARRAY_VARS) - ps = save_pipestatus_array (); -#endif - function_code = 0; - - /* Run the trap only if signal 0 is trapped and not ignored, and we are not - currently running in the trap handler (call to exit in the list of - commands given to trap 0). */ - if ((sigmodes[EXIT_TRAP] & SIG_TRAPPED) && - (sigmodes[EXIT_TRAP] & (SIG_IGNORED|SIG_INPROGRESS)) == 0) - { - trap_command = savestring (trap_list[EXIT_TRAP]); - sigmodes[EXIT_TRAP] &= ~SIG_TRAPPED; - sigmodes[EXIT_TRAP] |= SIG_INPROGRESS; - - retval = trap_saved_exit_value; - running_trap = 1; - - code = setjmp_nosigs (top_level); - - /* If we're in a function, make sure return longjmps come here, too. */ - if (return_catch_flag) - function_code = setjmp_nosigs (return_catch); - - if (code == 0 && function_code == 0) - { - reset_parser (); - parse_and_execute (trap_command, "exit trap", SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE); - } - else if (code == ERREXIT) - retval = last_command_exit_value; - else if (code == EXITPROG || code == EXITBLTIN) - retval = last_command_exit_value; - else if (function_code != 0) - retval = return_catch_value; - else - retval = trap_saved_exit_value; - - running_trap = 0; -#if defined (ARRAY_VARS) - array_dispose (ps); -#endif - - return retval; - } - -#if defined (ARRAY_VARS) - restore_pipestatus_array (ps); -#endif - return (trap_saved_exit_value); -} - -void -run_trap_cleanup (sig) - int sig; -{ - /* XXX - should we clean up trap_list[sig] == IMPOSSIBLE_TRAP_HANDLER? */ - sigmodes[sig] &= ~(SIG_INPROGRESS|SIG_CHANGED); -} - -#define RECURSIVE_SIG(s) (SPECIAL_TRAP(s) == 0) - -/* Run a trap command for SIG. SIG is one of the signals the shell treats - specially. Returns the exit status of the executed trap command list. */ -static int -_run_trap_internal (sig, tag) - int sig; - char *tag; -{ - char *trap_command, *old_trap; - int trap_exit_value; - volatile int save_return_catch_flag, function_code; - int old_modes, old_running, old_int; - int flags; - procenv_t save_return_catch; - WORD_LIST *save_subst_varlist; - HASH_TABLE *save_tempenv; - sh_parser_state_t pstate; -#if defined (ARRAY_VARS) - ARRAY *ps; -#endif - - old_modes = old_running = -1; - - trap_exit_value = function_code = 0; - trap_saved_exit_value = last_command_exit_value; - /* Run the trap only if SIG is trapped and not ignored, and we are not - currently executing in the trap handler. */ - if ((sigmodes[sig] & SIG_TRAPPED) && ((sigmodes[sig] & SIG_IGNORED) == 0) && - (trap_list[sig] != (char *)IMPOSSIBLE_TRAP_HANDLER) && -#if 1 - /* Uncomment this to allow some special signals to recursively execute - trap handlers. */ - (RECURSIVE_SIG (sig) || (sigmodes[sig] & SIG_INPROGRESS) == 0)) -#else - ((sigmodes[sig] & SIG_INPROGRESS) == 0)) -#endif - { - old_trap = trap_list[sig]; - old_modes = sigmodes[sig]; - old_running = running_trap; - - sigmodes[sig] |= SIG_INPROGRESS; - sigmodes[sig] &= ~SIG_CHANGED; /* just to be sure */ - trap_command = savestring (old_trap); - - running_trap = sig + 1; - - old_int = interrupt_state; /* temporarily suppress pending interrupts */ - CLRINTERRUPT; - -#if defined (ARRAY_VARS) - ps = save_pipestatus_array (); -#endif - - save_parser_state (&pstate); - save_subst_varlist = subst_assign_varlist; - subst_assign_varlist = 0; - save_tempenv = temporary_env; - temporary_env = 0; /* traps should not run with temporary env */ - -#if defined (JOB_CONTROL) - if (sig != DEBUG_TRAP) /* run_debug_trap does this */ - save_pipeline (1); /* XXX only provides one save level */ -#endif - - /* If we're in a function, make sure return longjmps come here, too. */ - save_return_catch_flag = return_catch_flag; - if (return_catch_flag) - { - COPY_PROCENV (return_catch, save_return_catch); - function_code = setjmp_nosigs (return_catch); - } - - flags = SEVAL_NONINT|SEVAL_NOHIST; - if (sig != DEBUG_TRAP && sig != RETURN_TRAP && sig != ERROR_TRAP) - flags |= SEVAL_RESETLINE; - evalnest++; - if (function_code == 0) - { - parse_and_execute (trap_command, tag, flags); - trap_exit_value = last_command_exit_value; - } - else - trap_exit_value = return_catch_value; - evalnest--; - -#if defined (JOB_CONTROL) - if (sig != DEBUG_TRAP) /* run_debug_trap does this */ - restore_pipeline (1); -#endif - - subst_assign_varlist = save_subst_varlist; - restore_parser_state (&pstate); - -#if defined (ARRAY_VARS) - restore_pipestatus_array (ps); -#endif - - temporary_env = save_tempenv; - - if ((old_modes & SIG_INPROGRESS) == 0) - sigmodes[sig] &= ~SIG_INPROGRESS; - - running_trap = old_running; - interrupt_state = old_int; - - if (sigmodes[sig] & SIG_CHANGED) - { -#if 0 - /* Special traps like EXIT, DEBUG, RETURN are handled explicitly in - the places where they can be changed using unwind-protects. For - example, look at execute_cmd.c:execute_function(). */ - if (SPECIAL_TRAP (sig) == 0) -#endif - free (old_trap); - sigmodes[sig] &= ~SIG_CHANGED; - - CHECK_TERMSIG; /* some pathological conditions lead here */ - } - - if (save_return_catch_flag) - { - return_catch_flag = save_return_catch_flag; - return_catch_value = trap_exit_value; - COPY_PROCENV (save_return_catch, return_catch); - if (function_code) - { -#if 0 - from_return_trap = sig == RETURN_TRAP; -#endif - sh_longjmp (return_catch, 1); - } - } - } - - return trap_exit_value; -} - -int -run_debug_trap () -{ - int trap_exit_value, old_verbose; - pid_t save_pgrp; -#if defined (PGRP_PIPE) - int save_pipe[2]; -#endif - - /* XXX - question: should the DEBUG trap inherit the RETURN trap? */ - trap_exit_value = 0; - if ((sigmodes[DEBUG_TRAP] & SIG_TRAPPED) && ((sigmodes[DEBUG_TRAP] & SIG_IGNORED) == 0) && ((sigmodes[DEBUG_TRAP] & SIG_INPROGRESS) == 0)) - { -#if defined (JOB_CONTROL) - save_pgrp = pipeline_pgrp; - pipeline_pgrp = 0; - save_pipeline (1); -# if defined (PGRP_PIPE) - save_pgrp_pipe (save_pipe, 1); -# endif - stop_making_children (); -#endif - - old_verbose = echo_input_at_read; - echo_input_at_read = suppress_debug_trap_verbose ? 0 : echo_input_at_read; - - trap_exit_value = _run_trap_internal (DEBUG_TRAP, "debug trap"); - - echo_input_at_read = old_verbose; - -#if defined (JOB_CONTROL) - pipeline_pgrp = save_pgrp; - restore_pipeline (1); -# if defined (PGRP_PIPE) - close_pgrp_pipe (); - restore_pgrp_pipe (save_pipe); -# endif - if (pipeline_pgrp > 0 && ((subshell_environment & (SUBSHELL_ASYNC|SUBSHELL_PIPE)) == 0)) - give_terminal_to (pipeline_pgrp, 1); - - notify_and_cleanup (); -#endif - -#if defined (DEBUGGER) - /* If we're in the debugger and the DEBUG trap returns 2 while we're in - a function or sourced script, we force a `return'. */ - if (debugging_mode && trap_exit_value == 2 && return_catch_flag) - { - return_catch_value = trap_exit_value; - sh_longjmp (return_catch, 1); - } -#endif - } - return trap_exit_value; -} - -void -run_error_trap () -{ - if ((sigmodes[ERROR_TRAP] & SIG_TRAPPED) && ((sigmodes[ERROR_TRAP] & SIG_IGNORED) == 0) && (sigmodes[ERROR_TRAP] & SIG_INPROGRESS) == 0) - _run_trap_internal (ERROR_TRAP, "error trap"); -} - -void -run_return_trap () -{ - int old_exit_value; - -#if 0 - if ((sigmodes[DEBUG_TRAP] & SIG_TRAPPED) && (sigmodes[DEBUG_TRAP] & SIG_INPROGRESS)) - return; -#endif - - if ((sigmodes[RETURN_TRAP] & SIG_TRAPPED) && ((sigmodes[RETURN_TRAP] & SIG_IGNORED) == 0) && (sigmodes[RETURN_TRAP] & SIG_INPROGRESS) == 0) - { - old_exit_value = last_command_exit_value; - _run_trap_internal (RETURN_TRAP, "return trap"); - last_command_exit_value = old_exit_value; - } -} - -/* Run a trap set on SIGINT. This is called from throw_to_top_level (), and - declared here to localize the trap functions. */ -void -run_interrupt_trap (will_throw) - int will_throw; /* from throw_to_top_level? */ -{ - if (will_throw && running_trap > 0) - run_trap_cleanup (running_trap - 1); - pending_traps[SIGINT] = 0; /* run_pending_traps does this */ - catch_flag = 0; - _run_trap_internal (SIGINT, "interrupt trap"); -} - -/* Free all the allocated strings in the list of traps and reset the trap - values to the default. Intended to be called from subshells that want - to complete work done by reset_signal_handlers upon execution of a - subsequent `trap' command that changes a signal's disposition. We need - to make sure that we duplicate the behavior of - reset_or_restore_signal_handlers and not change the disposition of signals - that are set to be ignored. */ -void -free_trap_strings () -{ - register int i; - - for (i = 0; i < NSIG; i++) - { - if (trap_list[i] != (char *)IGNORE_SIG) - free_trap_string (i); - } - for (i = NSIG; i < BASH_NSIG; i++) - { - /* Don't free the trap string if the subshell inherited the trap */ - if ((sigmodes[i] & SIG_TRAPPED) == 0) - { - free_trap_string (i); - trap_list[i] = (char *)NULL; - } - } -} - -/* Free a trap command string associated with SIG without changing signal - disposition. Intended to be called from free_trap_strings() */ -static void -free_trap_string (sig) - int sig; -{ - change_signal (sig, (char *)DEFAULT_SIG); - sigmodes[sig] &= ~SIG_TRAPPED; /* XXX - SIG_INPROGRESS? */ -} - -/* Reset the handler for SIG to the original value but leave the trap string - in place. */ -static void -reset_signal (sig) - int sig; -{ - set_signal_handler (sig, original_signals[sig]); - sigmodes[sig] &= ~SIG_TRAPPED; /* XXX - SIG_INPROGRESS? */ -} - -/* Set the handler signal SIG to the original and free any trap - command associated with it. */ -static void -restore_signal (sig) - int sig; -{ - set_signal_handler (sig, original_signals[sig]); - change_signal (sig, (char *)DEFAULT_SIG); - sigmodes[sig] &= ~SIG_TRAPPED; -} - -static void -reset_or_restore_signal_handlers (reset) - sh_resetsig_func_t *reset; -{ - register int i; - - /* Take care of the exit trap first */ - if (sigmodes[EXIT_TRAP] & SIG_TRAPPED) - { - sigmodes[EXIT_TRAP] &= ~SIG_TRAPPED; /* XXX - SIG_INPROGRESS? */ - if (reset != reset_signal) - { - free_trap_command (EXIT_TRAP); - trap_list[EXIT_TRAP] = (char *)NULL; - } - } - - for (i = 1; i < NSIG; i++) - { - if (sigmodes[i] & SIG_TRAPPED) - { - if (trap_list[i] == (char *)IGNORE_SIG) - set_signal_handler (i, SIG_IGN); - else - (*reset) (i); - } - else if (sigmodes[i] & SIG_SPECIAL) - (*reset) (i); - pending_traps[i] = 0; /* XXX */ - } - - /* Command substitution and other child processes don't inherit the - debug, error, or return traps. If we're in the debugger, and the - `functrace' or `errtrace' options have been set, then let command - substitutions inherit them. Let command substitution inherit the - RETURN trap if we're in the debugger and tracing functions. */ - if (function_trace_mode == 0) - { - sigmodes[DEBUG_TRAP] &= ~SIG_TRAPPED; - sigmodes[RETURN_TRAP] &= ~SIG_TRAPPED; - } - if (error_trace_mode == 0) - sigmodes[ERROR_TRAP] &= ~SIG_TRAPPED; -} - -/* Reset trapped signals to their original values, but don't free the - trap strings. Called by the command substitution code and other places - that create a "subshell environment". */ -void -reset_signal_handlers () -{ - reset_or_restore_signal_handlers (reset_signal); -} - -/* Reset all trapped signals to their original values. Signals set to be - ignored with trap '' SIGNAL should be ignored, so we make sure that they - are. Called by child processes after they are forked. */ -void -restore_original_signals () -{ - reset_or_restore_signal_handlers (restore_signal); -} - -/* Change the flags associated with signal SIG without changing the trap - string. The string is TRAP_LIST[SIG] if we need it. */ -static void -reinit_trap (sig) - int sig; -{ - sigmodes[sig] |= SIG_TRAPPED; - if (trap_list[sig] == (char *)IGNORE_SIG) - sigmodes[sig] |= SIG_IGNORED; - else - sigmodes[sig] &= ~SIG_IGNORED; - if (sigmodes[sig] & SIG_INPROGRESS) - sigmodes[sig] |= SIG_CHANGED; -} - -/* Undo the effects of reset_signal_handlers(), which unsets the traps but - leaves the trap strings in place. This understands how reset_signal_handlers - works. */ -void -restore_traps () -{ - char *trapstr; - int i; - - /* Take care of the exit trap first. If TRAP_LIST[0] is non-null, the trap - has been set. */ - trapstr = trap_list[EXIT_TRAP]; - if (trapstr) - reinit_trap (EXIT_TRAP); - - /* Then DEBUG, RETURN, and ERROR. TRAP_LIST[N] == 0 if these signals are - not trapped. This knows what reset_signal_handlers does for these traps */ - trapstr = trap_list[DEBUG_TRAP]; - if (trapstr && function_trace_mode == 0) - reinit_trap (DEBUG_TRAP); - trapstr = trap_list[RETURN_TRAP]; - if (trapstr && function_trace_mode == 0) - reinit_trap (RETURN_TRAP); - trapstr = trap_list[ERROR_TRAP]; - if (trapstr && error_trace_mode == 0) - reinit_trap (ERROR_TRAP); - - /* And finally all the `real' signals. reset_signal_handlers just changes the - signal handler for these signals, leaving the trap value in place. We - intuit what to do based on that value. We assume that signals marked as - SIG_SPECIAL are reinitialized by initialize_signals (), so we don't - change the signal handler unless the signal is supposed to be ignored. */ - for (i = 1; i < NSIG; i++) - { - trapstr = trap_list[i]; - if (sigmodes[i] & SIG_SPECIAL) - { - if (trapstr && trapstr != (char *)DEFAULT_SIG) - reinit_trap (i); - if (trapstr == (char *)IGNORE_SIG && (sigmodes[i] & SIG_NO_TRAP) == 0) - set_signal_handler (i, SIG_IGN); - } - else if (trapstr == (char *)IGNORE_SIG) - { - reinit_trap (i); - if ((sigmodes[i] & SIG_NO_TRAP) == 0) - set_signal_handler (i, SIG_IGN); - } - else if (trapstr != (char *)DEFAULT_SIG) - /* set_signal duplicates the string argument before freeing it. */ - set_signal (i, trapstr); - - pending_traps[i] = 0; /* XXX */ - } -} - -/* If a trap handler exists for signal SIG, then call it; otherwise just - return failure. Returns 1 if it called the trap handler. */ -int -maybe_call_trap_handler (sig) - int sig; -{ - /* Call the trap handler for SIG if the signal is trapped and not ignored. */ - if ((sigmodes[sig] & SIG_TRAPPED) && ((sigmodes[sig] & SIG_IGNORED) == 0)) - { - switch (sig) - { - case SIGINT: - run_interrupt_trap (0); - break; - case EXIT_TRAP: - run_exit_trap (); - break; - case DEBUG_TRAP: - run_debug_trap (); - break; - case ERROR_TRAP: - run_error_trap (); - break; - default: - trap_handler (sig); - break; - } - return (1); - } - else - return (0); -} - -int -signal_is_trapped (sig) - int sig; -{ - return (sigmodes[sig] & SIG_TRAPPED); -} - -int -signal_is_pending (sig) - int sig; -{ - return (pending_traps[sig]); -} - -int -signal_is_special (sig) - int sig; -{ - return (sigmodes[sig] & SIG_SPECIAL); -} - -int -signal_is_ignored (sig) - int sig; -{ - return (sigmodes[sig] & SIG_IGNORED); -} - -int -signal_is_hard_ignored (sig) - int sig; -{ - return (sigmodes[sig] & SIG_HARD_IGNORE); -} - -void -set_signal_hard_ignored (sig) - int sig; -{ - sigmodes[sig] |= SIG_HARD_IGNORE; - original_signals[sig] = SIG_IGN; -} - -void -set_signal_ignored (sig) - int sig; -{ - original_signals[sig] = SIG_IGN; -} - -int -signal_in_progress (sig) - int sig; -{ - return (sigmodes[sig] & SIG_INPROGRESS); -} - -#if 0 /* unused */ -int -block_trapped_signals (maskp, omaskp) - sigset_t *maskp; - sigset_t *omaskp; -{ - int i; - - sigemptyset (maskp); - for (i = 1; i < NSIG; i++) - if (sigmodes[i] & SIG_TRAPPED) - sigaddset (maskp, i); - return (sigprocmask (SIG_BLOCK, maskp, omaskp)); -} - -int -unblock_trapped_signals (maskp) - sigset_t *maskp; -{ - return (sigprocmask (SIG_SETMASK, maskp, 0)); -} -#endif diff --git a/third_party/bash/trap.h b/third_party/bash/trap.h deleted file mode 100644 index 89402a1bc..000000000 --- a/third_party/bash/trap.h +++ /dev/null @@ -1,129 +0,0 @@ -/* trap.h -- data structures used in the trap mechanism. */ - -/* Copyright (C) 1993-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_TRAP_H_) -#define _TRAP_H_ - -#include "stdc.h" - -#if !defined (SIG_DFL) -#include "bashtypes.h" -#include -#endif /* SIG_DFL */ - -#if !defined (NSIG) -#define NSIG 64 -#endif /* !NSIG */ - -#define NO_SIG -1 -#define DEFAULT_SIG SIG_DFL -#define IGNORE_SIG SIG_IGN - -/* Special shell trap names. */ -#define DEBUG_TRAP NSIG -#define ERROR_TRAP NSIG+1 -#define RETURN_TRAP NSIG+2 -#define EXIT_TRAP 0 - -/* system signals plus special bash traps */ -#define BASH_NSIG NSIG+3 - -/* Flags values for decode_signal() */ -#define DSIG_SIGPREFIX 0x01 /* don't allow `SIG' PREFIX */ -#define DSIG_NOCASE 0x02 /* case-insensitive comparison */ - -/* A value which can never be the target of a trap handler. */ -#define IMPOSSIBLE_TRAP_HANDLER (SigHandler *)initialize_traps - -#define signal_object_p(x,f) (decode_signal (x,f) != NO_SIG) - -#define TRAP_STRING(s) \ - (signal_is_trapped (s) && signal_is_ignored (s) == 0) ? trap_list[s] \ - : (char *)NULL - -extern char *trap_list[]; - -extern int trapped_signal_received; -extern int wait_signal_received; -extern int running_trap; -extern int trap_saved_exit_value; -extern int suppress_debug_trap_verbose; - -/* Externally-visible functions declared in trap.c. */ -extern void initialize_traps PARAMS((void)); - -extern void run_pending_traps PARAMS((void)); - -extern void queue_sigchld_trap PARAMS((int)); -extern void maybe_set_sigchld_trap PARAMS((char *)); -extern void set_impossible_sigchld_trap PARAMS((void)); -extern void set_sigchld_trap PARAMS((char *)); - -extern void set_debug_trap PARAMS((char *)); -extern void set_error_trap PARAMS((char *)); -extern void set_return_trap PARAMS((char *)); - -extern void maybe_set_debug_trap PARAMS((char *)); -extern void maybe_set_error_trap PARAMS((char *)); -extern void maybe_set_return_trap PARAMS((char *)); - -extern void set_sigint_trap PARAMS((char *)); -extern void set_signal PARAMS((int, char *)); - -extern void restore_default_signal PARAMS((int)); -extern void ignore_signal PARAMS((int)); -extern int run_exit_trap PARAMS((void)); -extern void run_trap_cleanup PARAMS((int)); -extern int run_debug_trap PARAMS((void)); -extern void run_error_trap PARAMS((void)); -extern void run_return_trap PARAMS((void)); - -extern void free_trap_strings PARAMS((void)); -extern void reset_signal_handlers PARAMS((void)); -extern void restore_original_signals PARAMS((void)); -extern void restore_traps PARAMS((void)); - -extern void get_original_signal PARAMS((int)); -extern void get_all_original_signals PARAMS((void)); - -extern char *signal_name PARAMS((int)); - -extern int decode_signal PARAMS((char *, int)); -extern void run_interrupt_trap PARAMS((int)); -extern int maybe_call_trap_handler PARAMS((int)); -extern int signal_is_special PARAMS((int)); -extern int signal_is_trapped PARAMS((int)); -extern int signal_is_pending PARAMS((int)); -extern int signal_is_ignored PARAMS((int)); -extern int signal_is_hard_ignored PARAMS((int)); -extern void set_signal_hard_ignored PARAMS((int)); -extern void set_signal_ignored PARAMS((int)); -extern int signal_in_progress PARAMS((int)); - -extern void set_trap_state PARAMS((int)); - -extern int next_pending_trap PARAMS((int)); -extern int first_pending_trap PARAMS((void)); -extern void clear_pending_traps PARAMS((void)); -extern int any_signals_trapped PARAMS((void)); -extern void check_signals PARAMS((void)); -extern void check_signals_and_traps PARAMS((void)); - -#endif /* _TRAP_H_ */ diff --git a/third_party/bash/typemax.h b/third_party/bash/typemax.h deleted file mode 100644 index e3b98f472..000000000 --- a/third_party/bash/typemax.h +++ /dev/null @@ -1,141 +0,0 @@ -/* typemax.h -- encapsulate max values for long, long long, etc. */ - -/* Copyright (C) 2001-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -/* - * NOTE: This should be included after config.h, limits.h, stdint.h, and - * inttypes.h - */ - -#ifndef _SH_TYPEMAX_H -#define _SH_TYPEMAX_H - -#ifndef CHAR_BIT -# define CHAR_BIT 8 -#endif - -/* Nonzero if the integer type T is signed. */ -#ifndef TYPE_SIGNED -# define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) -#endif - -#ifndef TYPE_SIGNED_MAGNITUDE -# define TYPE_SIGNED_MAGNITUDE(t) ((t) ~ (t) 0 < (t) -1) -#endif - -#ifndef TYPE_WIDTH -# define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT) -#endif - -#ifndef TYPE_MINIMUM -# define TYPE_MINIMUM(t) ((t) ~ TYPE_MAXIMUM (t)) -#endif - -#ifndef TYPE_MAXIMUM -# define TYPE_MAXIMUM(t) \ - ((t) (! TYPE_SIGNED (t) \ - ? (t) -1 \ - : ((((t) 1 << (TYPE_WIDTH (t) - 2)) - 1) * 2 + 1))) -#endif - -#ifdef HAVE_LONG_LONG_INT -# ifndef LLONG_MAX -# define LLONG_MAX TYPE_MAXIMUM(long long int) -# define LLONG_MIN TYPE_MINIMUM(long long int) -# endif -# ifndef ULLONG_MAX -# define ULLONG_MAX TYPE_MAXIMUM(unsigned long long int) -# endif -#endif - -#ifndef ULONG_MAX -# define ULONG_MAX ((unsigned long) ~(unsigned long) 0) -#endif - -#ifndef LONG_MAX -# define LONG_MAX ((long int) (ULONG_MAX >> 1)) -# define LONG_MIN ((long int) (-LONG_MAX - 1L)) -#endif - -#ifndef INT_MAX /* ouch */ -# define INT_MAX TYPE_MAXIMUM(int) -# define INT_MIN TYPE_MINIMUM(int) -# define UINT_MAX ((unsigned int) ~(unsigned int)0) -#endif - -#ifndef SHRT_MAX -# define SHRT_MAX TYPE_MAXIMUM(short) -# define SHRT_MIN TYPE_MINIMUM(short) -# define USHRT_MAX ((unsigned short) ~(unsigned short)0) -#endif - -#ifndef UCHAR_MAX -# define UCHAR_MAX 255 -#endif - -/* workaround for gcc bug in versions < 2.7 */ -#if defined (HAVE_LONG_LONG_INT) && __GNUC__ == 2 && __GNUC_MINOR__ < 7 -static const unsigned long long int maxquad = ULLONG_MAX; -# undef ULLONG_MAX -# define ULLONG_MAX maxquad -#endif - -#if !defined (INTMAX_MAX) || !defined (INTMAX_MIN) - -#if SIZEOF_INTMAX_T == SIZEOF_LONG_LONG -# define INTMAX_MAX LLONG_MAX -# define INTMAX_MIN LLONG_MIN -#elif SIZEOF_INTMAX_T == SIZEOF_LONG -# define INTMAX_MAX LONG_MAX -# define INTMAX_MIN LONG_MIN -#else -# define INTMAX_MAX INT_MAX -# define INTMAX_MIN INT_MIN -#endif - -#endif - -#ifndef SSIZE_MAX -# define SSIZE_MAX INT_MAX -#endif - -#ifndef SIZE_MAX -# define SIZE_MAX ((size_t) ~(size_t)0) -#endif - -#ifndef sh_imaxabs -# define sh_imaxabs(x) (((x) >= 0) ? (x) : -(x)) -#endif - -/* Handle signed arithmetic overflow and underflow. Have to do it this way - to avoid compilers optimizing out simpler overflow checks. */ - -/* Make sure that a+b does not exceed MAXV or is smaller than MINV (if b < 0). - Assumes that b > 0 if a > 0 and b < 0 if a < 0 */ -#define ADDOVERFLOW(a,b,minv,maxv) \ - ((((a) > 0) && ((b) > ((maxv) - (a)))) || \ - (((a) < 0) && ((b) < ((minv) - (a))))) - -/* Make sure that a-b is not smaller than MINV or exceeds MAXV (if b < 0). - Assumes that b > 0 if a > 0 and b < 0 if a < 0 */ -#define SUBOVERFLOW(a,b,minv,maxv) \ - ((((b) > 0) && ((a) < ((minv) + (b)))) || \ - (((b) < 0) && ((a) > ((maxv) + (b))))) - -#endif /* _SH_TYPEMAX_H */ diff --git a/third_party/bash/uconvert.c b/third_party/bash/uconvert.c deleted file mode 100644 index 457552eb4..000000000 --- a/third_party/bash/uconvert.c +++ /dev/null @@ -1,124 +0,0 @@ -/* uconvert - convert string representations of decimal numbers into whole - number/fractional value pairs. */ - -/* Copyright (C) 2008,2009,2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include "bashtypes.h" - -#include "posixtime.h" - -#if defined (HAVE_UNISTD_H) -#include -#endif - -#include -#include "chartypes.h" - -#include "shell.h" -#include "builtins.h" - -#define DECIMAL '.' /* XXX - should use locale */ - -#define RETURN(x) \ -do { \ - if (ip) *ip = ipart * mult; \ - if (up) *up = upart; \ - if (ep) *ep = p; \ - return (x); \ -} while (0) - -/* - * An incredibly simplistic floating point converter. - */ -static int multiplier[7] = { 1, 100000, 10000, 1000, 100, 10, 1 }; - -/* Take a decimal number int-part[.[micro-part]] and convert it to the whole - and fractional portions. The fractional portion is returned in - millionths (micro); callers are responsible for multiplying appropriately. - EP, if non-null, gets the address of the character where conversion stops. - Return 1 if value converted; 0 if invalid integer for either whole or - fractional parts. */ -int -uconvert(s, ip, up, ep) - char *s; - long *ip, *up; - char **ep; -{ - int n, mult; - long ipart, upart; - char *p; - - ipart = upart = 0; - mult = 1; - - if (s && (*s == '-' || *s == '+')) - { - mult = (*s == '-') ? -1 : 1; - p = s + 1; - } - else - p = s; - - for ( ; p && *p; p++) - { - if (*p == DECIMAL) /* decimal point */ - break; - if (DIGIT(*p) == 0) - RETURN(0); - ipart = (ipart * 10) + (*p - '0'); - } - - if (p == 0 || *p == 0) /* callers ensure p can never be 0; this is to shut up clang */ - RETURN(1); - - if (*p == DECIMAL) - p++; - - /* Look for up to six digits past a decimal point. */ - for (n = 0; n < 6 && p[n]; n++) - { - if (DIGIT(p[n]) == 0) - { - if (ep) - { - upart *= multiplier[n]; - p += n; /* To set EP */ - } - RETURN(0); - } - upart = (upart * 10) + (p[n] - '0'); - } - - /* Now convert to millionths */ - upart *= multiplier[n]; - - if (n == 6 && p[6] >= '5' && p[6] <= '9') - upart++; /* round up 1 */ - - if (ep) - { - p += n; - while (DIGIT(*p)) - p++; - } - - RETURN(1); -} diff --git a/third_party/bash/ufuncs.c b/third_party/bash/ufuncs.c deleted file mode 100644 index 4dc4853b1..000000000 --- a/third_party/bash/ufuncs.c +++ /dev/null @@ -1,140 +0,0 @@ -/* ufuncs - sleep and alarm functions that understand fractional values */ - -/* Copyright (C) 2008,2009-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include "bashtypes.h" - -#include "posixtime.h" - -#if defined (HAVE_UNISTD_H) -#include -#endif - -#include -#if !defined (errno) -extern int errno; -#endif /* !errno */ - -#if defined (HAVE_SELECT) -# include "posixselect.h" -# include "quit.h" -# include "trap.h" -# include "stat-time.h" -#endif - -/* A version of `alarm' using setitimer if it's available. */ - -#if defined (HAVE_SETITIMER) -unsigned int -falarm(secs, usecs) - unsigned int secs, usecs; -{ - struct itimerval it, oit; - - it.it_interval.tv_sec = 0; - it.it_interval.tv_usec = 0; - - it.it_value.tv_sec = secs; - it.it_value.tv_usec = usecs; - - if (setitimer(ITIMER_REAL, &it, &oit) < 0) - return (-1); /* XXX will be converted to unsigned */ - - /* Backwards compatibility with alarm(3) */ - if (oit.it_value.tv_usec) - oit.it_value.tv_sec++; - return (oit.it_value.tv_sec); -} -#else -int -falarm (secs, usecs) - unsigned int secs, usecs; -{ - if (secs == 0 && usecs == 0) - return (alarm (0)); - - if (secs == 0 || usecs >= 500000) - { - secs++; - usecs = 0; - } - return (alarm (secs)); -} -#endif /* !HAVE_SETITIMER */ - -/* A version of sleep using fractional seconds and select. I'd like to use - `usleep', but it's already taken */ - -#if defined (HAVE_TIMEVAL) && (defined (HAVE_SELECT) || defined (HAVE_PSELECT)) -int -fsleep(sec, usec) - unsigned int sec, usec; -{ - int e, r; - sigset_t blocked_sigs, prevmask; -#if defined (HAVE_PSELECT) - struct timespec ts; -#else - struct timeval tv; -#endif - - sigemptyset (&blocked_sigs); -# if defined (SIGCHLD) - sigaddset (&blocked_sigs, SIGCHLD); -# endif - -#if defined (HAVE_PSELECT) - ts.tv_sec = sec; - ts.tv_nsec = usec * 1000; -#else - sigemptyset (&prevmask); - tv.tv_sec = sec; - tv.tv_usec = usec; -#endif /* !HAVE_PSELECT */ - - do - { -#if defined (HAVE_PSELECT) - r = pselect(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &ts, &blocked_sigs); -#else - sigprocmask (SIG_SETMASK, &blocked_sigs, &prevmask); - r = select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tv); - sigprocmask (SIG_SETMASK, &prevmask, NULL); -#endif - e = errno; - if (r < 0 && errno == EINTR) - return -1; /* caller will handle */ - errno = e; - } - while (r < 0 && errno == EINTR); - - return r; -} -#else /* !HAVE_TIMEVAL || !HAVE_SELECT */ -int -fsleep(sec, usec) - long sec, usec; -{ - if (usec >= 500000) /* round */ - sec++; - return (sleep(sec)); -} -#endif /* !HAVE_TIMEVAL || !HAVE_SELECT */ diff --git a/third_party/bash/unicode.c b/third_party/bash/unicode.c deleted file mode 100644 index a79ec4aab..000000000 --- a/third_party/bash/unicode.c +++ /dev/null @@ -1,339 +0,0 @@ -/* unicode.c - functions to convert unicode characters */ - -/* Copyright (C) 2010-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#if defined (HANDLE_MULTIBYTE) - -#include "stdc.h" -#include -#include "bashansi.h" -#ifdef HAVE_UNISTD_H -#include -#endif -#include -#include - -#if HAVE_ICONV -# include -#endif - -#include "xmalloc.h" - -#ifndef USHORT_MAX -# ifdef USHRT_MAX -# define USHORT_MAX USHRT_MAX -# else -# define USHORT_MAX ((unsigned short) ~(unsigned short)0) -# endif -#endif - -#if !defined (STREQ) -# define STREQ(a, b) ((a)[0] == (b)[0] && strcmp ((a), (b)) == 0) -#endif /* !STREQ */ - -#if defined (HAVE_LOCALE_CHARSET) -extern const char *locale_charset PARAMS((void)); -#else -extern char *get_locale_var PARAMS((char *)); -#endif - -extern int locale_utf8locale; - -static int u32init = 0; -static int utf8locale = 0; -#if defined (HAVE_ICONV) -static iconv_t localconv; -#endif - -#ifndef HAVE_LOCALE_CHARSET -static char charsetbuf[40]; - -static char * -stub_charset () -{ - char *locale, *s, *t; - - locale = get_locale_var ("LC_CTYPE"); - if (locale == 0 || *locale == 0) - { - strcpy (charsetbuf, "ASCII"); - return charsetbuf; - } - s = strrchr (locale, '.'); - if (s) - { - strncpy (charsetbuf, s+1, sizeof (charsetbuf) - 1); - charsetbuf[sizeof (charsetbuf) - 1] = '\0'; - t = strchr (charsetbuf, '@'); - if (t) - *t = 0; - return charsetbuf; - } - strncpy (charsetbuf, locale, sizeof (charsetbuf) - 1); - charsetbuf[sizeof (charsetbuf) - 1] = '\0'; - return charsetbuf; -} -#endif - -void -u32reset () -{ -#if defined (HAVE_ICONV) - if (u32init && localconv != (iconv_t)-1) - { - iconv_close (localconv); - localconv = (iconv_t)-1; - } -#endif - u32init = 0; - utf8locale = 0; -} - -/* u32toascii ? */ -int -u32tochar (x, s) - unsigned long x; - char *s; -{ - int l; - - l = (x <= UCHAR_MAX) ? 1 : ((x <= USHORT_MAX) ? 2 : 4); - - if (x <= UCHAR_MAX) - s[0] = x & 0xFF; - else if (x <= USHORT_MAX) /* assume unsigned short = 16 bits */ - { - s[0] = (x >> 8) & 0xFF; - s[1] = x & 0xFF; - } - else - { - s[0] = (x >> 24) & 0xFF; - s[1] = (x >> 16) & 0xFF; - s[2] = (x >> 8) & 0xFF; - s[3] = x & 0xFF; - } - s[l] = '\0'; - return l; -} - -int -u32tocesc (wc, s) - u_bits32_t wc; - char *s; -{ - int l; - - if (wc < 0x10000) - l = sprintf (s, "\\u%04X", wc); - else - l = sprintf (s, "\\U%08X", wc); - return l; -} - -/* Convert unsigned 32-bit int to utf-8 character string */ -int -u32toutf8 (wc, s) - u_bits32_t wc; - char *s; -{ - int l; - - if (wc < 0x0080) - { - s[0] = (char)wc; - l = 1; - } - else if (wc < 0x0800) - { - s[0] = (wc >> 6) | 0xc0; - s[1] = (wc & 0x3f) | 0x80; - l = 2; - } - else if (wc < 0x10000) - { - /* Technically, we could return 0 here if 0xd800 <= wc <= 0x0dfff */ - s[0] = (wc >> 12) | 0xe0; - s[1] = ((wc >> 6) & 0x3f) | 0x80; - s[2] = (wc & 0x3f) | 0x80; - l = 3; - } - else if (wc < 0x200000) - { - s[0] = (wc >> 18) | 0xf0; - s[1] = ((wc >> 12) & 0x3f) | 0x80; - s[2] = ((wc >> 6) & 0x3f) | 0x80; - s[3] = (wc & 0x3f) | 0x80; - l = 4; - } - /* Strictly speaking, UTF-8 doesn't have characters longer than 4 bytes */ - else if (wc < 0x04000000) - { - s[0] = (wc >> 24) | 0xf8; - s[1] = ((wc >> 18) & 0x3f) | 0x80; - s[2] = ((wc >> 12) & 0x3f) | 0x80; - s[3] = ((wc >> 6) & 0x3f) | 0x80; - s[4] = (wc & 0x3f) | 0x80; - l = 5; - } - else if (wc < 0x080000000) - { - s[0] = (wc >> 30) | 0xfc; - s[1] = ((wc >> 24) & 0x3f) | 0x80; - s[2] = ((wc >> 18) & 0x3f) | 0x80; - s[3] = ((wc >> 12) & 0x3f) | 0x80; - s[4] = ((wc >> 6) & 0x3f) | 0x80; - s[5] = (wc & 0x3f) | 0x80; - l = 6; - } - else - l = 0; - - s[l] = '\0'; - return l; -} - -/* Convert a 32-bit unsigned int (unicode) to a UTF-16 string. Rarely used, - only if sizeof(wchar_t) == 2. */ -int -u32toutf16 (c, s) - u_bits32_t c; - wchar_t *s; -{ - int l; - - l = 0; - if (c < 0x0d800 || (c >= 0x0e000 && c <= 0x0ffff)) - { - s[0] = (wchar_t) (c & 0xFFFF); - l = 1; - } - else if (c >= 0x10000 && c <= 0x010ffff) - { - c -= 0x010000; - s[0] = (wchar_t)((c >> 10) + 0xd800); - s[1] = (wchar_t)((c & 0x3ff) + 0xdc00); - l = 2; - } - s[l] = 0; - return l; -} - -/* convert a single unicode-32 character into a multibyte string and put the - result in S, which must be large enough (at least max(10,MB_LEN_MAX) bytes) */ -int -u32cconv (c, s) - unsigned long c; - char *s; -{ - wchar_t wc; - wchar_t ws[3]; - int n; -#if HAVE_ICONV - const char *charset; - char obuf[25], *optr; - size_t obytesleft; - const char *iptr; - size_t sn; -#endif - -#if __STDC_ISO_10646__ - wc = c; - if (sizeof (wchar_t) == 4 && c <= 0x7fffffff) - n = wctomb (s, wc); - else if (sizeof (wchar_t) == 2 && c <= 0x10ffff && u32toutf16 (c, ws)) - n = wcstombs (s, ws, MB_LEN_MAX); - else - n = -1; - if (n != -1) - return n; -#endif - -#if HAVE_ICONV - /* this is mostly from coreutils-8.5/lib/unicodeio.c */ - if (u32init == 0) - { - utf8locale = locale_utf8locale; - localconv = (iconv_t)-1; - if (utf8locale == 0) - { -#if HAVE_LOCALE_CHARSET - charset = locale_charset (); -#elif HAVE_NL_LANGINFO - charset = nl_langinfo (CODESET); -#else - charset = stub_charset (); -#endif - localconv = iconv_open (charset, "UTF-8"); - if (localconv == (iconv_t)-1) - /* We assume ASCII when presented with an unknown encoding. */ - localconv = iconv_open ("ASCII", "UTF-8"); - } - u32init = 1; - } - - /* NL_LANGINFO and locale_charset used when setting locale_utf8locale */ - - /* If we have a UTF-8 locale, convert to UTF-8 and return converted value. */ - n = u32toutf8 (c, s); - if (utf8locale) - return n; - - /* If the conversion is not supported, even the ASCII requested above, we - bail now. Currently we return the UTF-8 conversion. We could return - u32tocesc(). */ - if (localconv == (iconv_t)-1) - return n; - - optr = obuf; - obytesleft = sizeof (obuf); - iptr = s; - sn = n; - - iconv (localconv, NULL, NULL, NULL, NULL); - - if (iconv (localconv, (ICONV_CONST char **)&iptr, &sn, &optr, &obytesleft) == (size_t)-1) - { - /* You get ISO C99 escape sequences if iconv fails */ - n = u32tocesc (c, s); - return n; - } - - *optr = '\0'; - - /* number of chars to be copied is optr - obuf if we want to do bounds - checking */ - strcpy (s, obuf); - return (optr - obuf); -#endif /* HAVE_ICONV */ - - if (locale_utf8locale) - n = u32toutf8 (c, s); - else - n = u32tocesc (c, s); /* fallback is ISO C99 escape sequences */ - return n; -} -#else -void -u32reset () -{ -} -#endif /* HANDLE_MULTIBYTE */ diff --git a/third_party/bash/unionwait.h b/third_party/bash/unionwait.h deleted file mode 100644 index b1b4dfaff..000000000 --- a/third_party/bash/unionwait.h +++ /dev/null @@ -1,98 +0,0 @@ -/* unionwait.h -- definitions for using a `union wait' on systems without - one. */ - -/* Copyright (C) 1996 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#ifndef _UNIONWAIT_H -#define _UNIONWAIT_H - -#if !defined (WORDS_BIGENDIAN) -union wait - { - int w_status; /* used in syscall */ - - /* Terminated process status. */ - struct - { - unsigned short - w_Termsig : 7, /* termination signal */ - w_Coredump : 1, /* core dump indicator */ - w_Retcode : 8, /* exit code if w_termsig==0 */ - w_Fill1 : 16; /* high 16 bits unused */ - } w_T; - - /* Stopped process status. Returned - only for traced children unless requested - with the WUNTRACED option bit. */ - struct - { - unsigned short - w_Stopval : 8, /* == W_STOPPED if stopped */ - w_Stopsig : 8, /* actually zero on XENIX */ - w_Fill2 : 16; /* high 16 bits unused */ - } w_S; - }; - -#else /* WORDS_BIGENDIAN */ - -/* This is for big-endian machines like the IBM RT, HP 9000, or Sun-3 */ - -union wait - { - int w_status; /* used in syscall */ - - /* Terminated process status. */ - struct - { - unsigned short w_Fill1 : 16; /* high 16 bits unused */ - unsigned w_Retcode : 8; /* exit code if w_termsig==0 */ - unsigned w_Coredump : 1; /* core dump indicator */ - unsigned w_Termsig : 7; /* termination signal */ - } w_T; - - /* Stopped process status. Returned - only for traced children unless requested - with the WUNTRACED option bit. */ - struct - { - unsigned short w_Fill2 : 16; /* high 16 bits unused */ - unsigned w_Stopsig : 8; /* signal that stopped us */ - unsigned w_Stopval : 8; /* == W_STOPPED if stopped */ - } w_S; - }; - -#endif /* WORDS_BIGENDIAN */ - -#define w_termsig w_T.w_Termsig -#define w_coredump w_T.w_Coredump -#define w_retcode w_T.w_Retcode -#define w_stopval w_S.w_Stopval -#define w_stopsig w_S.w_Stopsig - -#define WSTOPPED 0177 -#define WIFSTOPPED(x) ((x).w_stopval == WSTOPPED) -#define WIFEXITED(x) ((x).w_stopval != WSTOPPED && (x).w_termsig == 0) -#define WIFSIGNALED(x) ((x).w_stopval != WSTOPPED && (x).w_termsig != 0) - -#define WTERMSIG(x) ((x).w_termsig) -#define WSTOPSIG(x) ((x).w_stopsig) -#define WEXITSTATUS(x) ((x).w_retcode) -#define WIFCORED(x) ((x).w_coredump) - -#endif /* _UNIONWAIT_H */ diff --git a/third_party/bash/unwind_prot.c b/third_party/bash/unwind_prot.c deleted file mode 100644 index ec82393d5..000000000 --- a/third_party/bash/unwind_prot.c +++ /dev/null @@ -1,383 +0,0 @@ -/* unwind_prot.c - a simple unwind-protect system for internal variables */ - -/* I can't stand it anymore! Please can't we just write the - whole Unix system in lisp or something? */ - -/* Copyright (C) 1987-2021 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -/* **************************************************************** */ -/* */ -/* Unwind Protection Scheme for Bash */ -/* */ -/* **************************************************************** */ -#include "config.h" - -#include "bashtypes.h" -#include "bashansi.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#if defined (HAVE_STDDEF_H) -# include -#endif - -#ifndef offsetof -# define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) -#endif - -#include "command.h" -#include "general.h" -#include "unwind_prot.h" -#include "sig.h" -#include "quit.h" -#include "bashintl.h" /* for _() */ -#include "error.h" /* for internal_warning */ -#include "ocache.h" - -/* Structure describing a saved variable and the value to restore it to. */ -typedef struct { - char *variable; - int size; - char desired_setting[1]; /* actual size is `size' */ -} SAVED_VAR; - -/* If HEAD.CLEANUP is null, then ARG.V contains a tag to throw back to. - If HEAD.CLEANUP is restore_variable, then SV.V contains the saved - variable. Otherwise, call HEAD.CLEANUP (ARG.V) to clean up. */ -typedef union uwp { - struct uwp_head { - union uwp *next; - Function *cleanup; - } head; - struct { - struct uwp_head uwp_head; - char *v; - } arg; - struct { - struct uwp_head uwp_head; - SAVED_VAR v; - } sv; -} UNWIND_ELT; - -static void without_interrupts PARAMS((VFunction *, char *, char *)); -static void unwind_frame_discard_internal PARAMS((char *, char *)); -static void unwind_frame_run_internal PARAMS((char *, char *)); -static void add_unwind_protect_internal PARAMS((Function *, char *)); -static void remove_unwind_protect_internal PARAMS((char *, char *)); -static void run_unwind_protects_internal PARAMS((char *, char *)); -static void clear_unwind_protects_internal PARAMS((char *, char *)); -static inline void restore_variable PARAMS((SAVED_VAR *)); -static void unwind_protect_mem_internal PARAMS((char *, char *)); - -static UNWIND_ELT *unwind_protect_list = (UNWIND_ELT *)NULL; - -/* Allocating from a cache of unwind-protect elements */ -#define UWCACHESIZE 128 - -sh_obj_cache_t uwcache = {0, 0, 0}; - -#if 0 -#define uwpalloc(elt) (elt) = (UNWIND_ELT *)xmalloc (sizeof (UNWIND_ELT)) -#define uwpfree(elt) free(elt) -#else -#define uwpalloc(elt) ocache_alloc (uwcache, UNWIND_ELT, elt) -#define uwpfree(elt) ocache_free (uwcache, UNWIND_ELT, elt) -#endif - -void -uwp_init () -{ - ocache_create (uwcache, UNWIND_ELT, UWCACHESIZE); -} - -/* Run a function without interrupts. This relies on the fact that the - FUNCTION cannot call QUIT (). */ -static void -without_interrupts (function, arg1, arg2) - VFunction *function; - char *arg1, *arg2; -{ - (*function)(arg1, arg2); -} - -/* Start the beginning of a region. */ -void -begin_unwind_frame (tag) - char *tag; -{ - add_unwind_protect ((Function *)NULL, tag); -} - -/* Discard the unwind protects back to TAG. */ -void -discard_unwind_frame (tag) - char *tag; -{ - if (unwind_protect_list) - without_interrupts (unwind_frame_discard_internal, tag, (char *)NULL); -} - -/* Run the unwind protects back to TAG. */ -void -run_unwind_frame (tag) - char *tag; -{ - if (unwind_protect_list) - without_interrupts (unwind_frame_run_internal, tag, (char *)NULL); -} - -/* Add the function CLEANUP with ARG to the list of unwindable things. */ -void -add_unwind_protect (cleanup, arg) - Function *cleanup; - char *arg; -{ - without_interrupts (add_unwind_protect_internal, (char *)cleanup, arg); -} - -/* Remove the top unwind protect from the list. */ -void -remove_unwind_protect () -{ - if (unwind_protect_list) - without_interrupts - (remove_unwind_protect_internal, (char *)NULL, (char *)NULL); -} - -/* Run the list of cleanup functions in unwind_protect_list. */ -void -run_unwind_protects () -{ - if (unwind_protect_list) - without_interrupts - (run_unwind_protects_internal, (char *)NULL, (char *)NULL); -} - -/* Erase the unwind-protect list. If flags is 1, free the elements. */ -void -clear_unwind_protect_list (flags) - int flags; -{ - char *flag; - - if (unwind_protect_list) - { - flag = flags ? "" : (char *)NULL; - without_interrupts - (clear_unwind_protects_internal, flag, (char *)NULL); - } -} - -int -have_unwind_protects () -{ - return (unwind_protect_list != 0); -} - -int -unwind_protect_tag_on_stack (tag) - const char *tag; -{ - UNWIND_ELT *elt; - - elt = unwind_protect_list; - while (elt) - { - if (elt->head.cleanup == 0 && STREQ (elt->arg.v, tag)) - return 1; - elt = elt->head.next; - } - return 0; -} - -/* **************************************************************** */ -/* */ -/* The Actual Functions */ -/* */ -/* **************************************************************** */ - -static void -add_unwind_protect_internal (cleanup, arg) - Function *cleanup; - char *arg; -{ - UNWIND_ELT *elt; - - uwpalloc (elt); - elt->head.next = unwind_protect_list; - elt->head.cleanup = cleanup; - elt->arg.v = arg; - unwind_protect_list = elt; -} - -static void -remove_unwind_protect_internal (ignore1, ignore2) - char *ignore1, *ignore2; -{ - UNWIND_ELT *elt; - - elt = unwind_protect_list; - if (elt) - { - unwind_protect_list = unwind_protect_list->head.next; - uwpfree (elt); - } -} - -static void -run_unwind_protects_internal (ignore1, ignore2) - char *ignore1, *ignore2; -{ - unwind_frame_run_internal ((char *) NULL, (char *) NULL); -} - -static void -clear_unwind_protects_internal (flag, ignore) - char *flag, *ignore; -{ - if (flag) - { - while (unwind_protect_list) - remove_unwind_protect_internal ((char *)NULL, (char *)NULL); - } - unwind_protect_list = (UNWIND_ELT *)NULL; -} - -static void -unwind_frame_discard_internal (tag, ignore) - char *tag, *ignore; -{ - UNWIND_ELT *elt; - int found; - - found = 0; - while (elt = unwind_protect_list) - { - unwind_protect_list = unwind_protect_list->head.next; - if (elt->head.cleanup == 0 && (STREQ (elt->arg.v, tag))) - { - uwpfree (elt); - found = 1; - break; - } - else - uwpfree (elt); - } - - if (found == 0) - internal_warning (_("unwind_frame_discard: %s: frame not found"), tag); -} - -/* Restore the value of a variable, based on the contents of SV. - sv->desired_setting is a block of memory SIZE bytes long holding the - value itself. This block of memory is copied back into the variable. */ -static inline void -restore_variable (sv) - SAVED_VAR *sv; -{ - FASTCOPY (sv->desired_setting, sv->variable, sv->size); -} - -static void -unwind_frame_run_internal (tag, ignore) - char *tag, *ignore; -{ - UNWIND_ELT *elt; - int found; - - found = 0; - while (elt = unwind_protect_list) - { - unwind_protect_list = elt->head.next; - - /* If tag, then compare. */ - if (elt->head.cleanup == 0) - { - if (tag && STREQ (elt->arg.v, tag)) - { - uwpfree (elt); - found = 1; - break; - } - } - else - { - if (elt->head.cleanup == (Function *) restore_variable) - restore_variable (&elt->sv.v); - else - (*(elt->head.cleanup)) (elt->arg.v); - } - - uwpfree (elt); - } - if (tag && found == 0) - internal_warning (_("unwind_frame_run: %s: frame not found"), tag); -} - -static void -unwind_protect_mem_internal (var, psize) - char *var; - char *psize; -{ - int size, allocated; - UNWIND_ELT *elt; - - size = *(int *) psize; - allocated = size + offsetof (UNWIND_ELT, sv.v.desired_setting[0]); - if (allocated < sizeof (UNWIND_ELT)) - allocated = sizeof (UNWIND_ELT); - elt = (UNWIND_ELT *)xmalloc (allocated); - elt->head.next = unwind_protect_list; - elt->head.cleanup = (Function *) restore_variable; - elt->sv.v.variable = var; - elt->sv.v.size = size; - FASTCOPY (var, elt->sv.v.desired_setting, size); - unwind_protect_list = elt; -} - -/* Save the value of a variable so it will be restored when unwind-protects - are run. VAR is a pointer to the variable. SIZE is the size in - bytes of VAR. */ -void -unwind_protect_mem (var, size) - char *var; - int size; -{ - without_interrupts (unwind_protect_mem_internal, var, (char *) &size); -} - -#if defined (DEBUG) -#include - -void -print_unwind_protect_tags () -{ - UNWIND_ELT *elt; - - elt = unwind_protect_list; - while (elt) - { - if (elt->head.cleanup == 0) - fprintf(stderr, "tag: %s\n", elt->arg.v); - elt = elt->head.next; - } -} -#endif diff --git a/third_party/bash/unwind_prot.h b/third_party/bash/unwind_prot.h deleted file mode 100644 index 97b3af902..000000000 --- a/third_party/bash/unwind_prot.h +++ /dev/null @@ -1,52 +0,0 @@ -/* unwind_prot.h - Macros and functions for hacking unwind protection. */ - -/* Copyright (C) 1993-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_UNWIND_PROT_H) -#define _UNWIND_PROT_H - -extern void uwp_init PARAMS((void)); - -/* Run a function without interrupts. */ -extern void begin_unwind_frame PARAMS((char *)); -extern void discard_unwind_frame PARAMS((char *)); -extern void run_unwind_frame PARAMS((char *)); -extern void add_unwind_protect (); /* Not portable to arbitrary C99 hosts. */ -extern void remove_unwind_protect PARAMS((void)); -extern void run_unwind_protects PARAMS((void)); -extern void clear_unwind_protect_list PARAMS((int)); -extern int have_unwind_protects PARAMS((void)); -extern int unwind_protect_tag_on_stack PARAMS((const char *)); -extern void uwp_init PARAMS((void)); - -/* Define for people who like their code to look a certain way. */ -#define end_unwind_frame() - -/* How to protect a variable. */ -#define unwind_protect_var(X) unwind_protect_mem ((char *)&(X), sizeof (X)) -extern void unwind_protect_mem PARAMS((char *, int)); - -/* Backwards compatibility */ -#define unwind_protect_int unwind_protect_var -#define unwind_protect_short unwind_protect_var -#define unwind_protect_string unwind_protect_var -#define unwind_protect_pointer unwind_protect_var -#define unwind_protect_jmp_buf unwind_protect_var - -#endif /* _UNWIND_PROT_H */ diff --git a/third_party/bash/utf8.c b/third_party/bash/utf8.c deleted file mode 100644 index 88eaa4f42..000000000 --- a/third_party/bash/utf8.c +++ /dev/null @@ -1,196 +0,0 @@ -/* utf8.c - UTF-8 character handling functions */ - -/* Copyright (C) 2018 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#ifdef HAVE_STDLIB_H -# include -#endif - -#include "bashansi.h" -#include "shmbutil.h" - -extern int locale_mb_cur_max; -extern int locale_utf8locale; - -#if defined (HANDLE_MULTIBYTE) - -char * -utf8_mbschr (s, c) - const char *s; - int c; -{ - return strchr (s, c); /* for now */ -} - -int -utf8_mbscmp (s1, s2) - const char *s1, *s2; -{ - /* Use the fact that the UTF-8 encoding preserves lexicographic order. */ - return strcmp (s1, s2); -} - -char * -utf8_mbsmbchar (str) - const char *str; -{ - register char *s; - - for (s = (char *)str; *s; s++) - if ((*s & 0xc0) == 0x80) - return s; - return (0); -} - -int -utf8_mbsnlen(src, srclen, maxlen) - const char *src; - size_t srclen; - int maxlen; -{ - register int sind, count; - - for (sind = count = 0; src[sind] && sind <= maxlen; sind++) - { - if ((src[sind] & 0xc0) != 0x80) - count++; - } - return (count); -} - -/* Adapted from GNU gnulib. Handles UTF-8 characters up to 4 bytes long */ -int -utf8_mblen (s, n) - const char *s; - size_t n; -{ - unsigned char c, c1, c2, c3; - - if (s == 0) - return (0); /* no shift states */ - if (n <= 0) - return (-1); - - c = (unsigned char)*s; - if (c < 0x80) - return (c != 0); - if (c >= 0xc2) - { - c1 = (unsigned char)s[1]; - if (c < 0xe0) - { - if (n == 1) - return -2; - - /* - * c c1 - * - * U+0080..U+07FF C2..DF 80..BF - */ - - if (n >= 2 && (c1 ^ 0x80) < 0x40) /* 0x80..0xbf */ - return 2; - } - else if (c < 0xf0) - { - if (n == 1) - return -2; - - /* - * c c1 c2 - * - * U+0800..U+0FFF E0 A0..BF 80..BF - * U+1000..U+CFFF E1..EC 80..BF 80..BF - * U+D000..U+D7FF ED 80..9F 80..BF - * U+E000..U+FFFF EE..EF 80..BF 80..BF - */ - - if ((c1 ^ 0x80) < 0x40 - && (c >= 0xe1 || c1 >= 0xa0) - && (c != 0xed || c1 < 0xa0)) - { - if (n == 2) - return -2; /* incomplete */ - - c2 = (unsigned char)s[2]; - if ((c2 ^ 0x80) < 0x40) - return 3; - } - } - else if (c <= 0xf4) - { - if (n == 1) - return -2; - - /* - * c c1 c2 c3 - * - * U+10000..U+3FFFF F0 90..BF 80..BF 80..BF - * U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF - * U+100000..U+10FFFF F4 80..8F 80..BF 80..BF - */ - if (((c1 ^ 0x80) < 0x40) - && (c >= 0xf1 || c1 >= 0x90) - && (c < 0xf4 || (c == 0xf4 && c1 < 0x90))) - { - if (n == 2) - return -2; /* incomplete */ - - c2 = (unsigned char)s[2]; - if ((c2 ^ 0x80) < 0x40) - { - if (n == 3) - return -2; - - c3 = (unsigned char)s[3]; - if ((c3 ^ 0x80) < 0x40) - return 4; - } - } - } - } - /* invalid or incomplete multibyte character */ - return -1; -} - -/* We can optimize this if we know the locale is UTF-8, but needs to handle - malformed byte sequences. */ -size_t -utf8_mbstrlen(s) - const char *s; -{ - size_t clen, nc; - int mb_cur_max; - - nc = 0; - mb_cur_max = MB_CUR_MAX; - while (*s && (clen = (size_t)utf8_mblen(s, mb_cur_max)) != 0) - { - if (MB_INVALIDCH(clen)) - clen = 1; /* assume single byte */ - - s += clen; - nc++; - } - return nc; -} - -#endif diff --git a/third_party/bash/variables.c b/third_party/bash/variables.c deleted file mode 100644 index 58abd5b86..000000000 --- a/third_party/bash/variables.c +++ /dev/null @@ -1,6590 +0,0 @@ -/* variables.c -- Functions for hacking shell variables. */ - -/* Copyright (C) 1987-2022 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include "bashtypes.h" -#include "posixstat.h" -#include "posixtime.h" - -#if defined (__QNX__) -# if defined (__QNXNTO__) -# include -# else -# include -# endif /* !__QNXNTO__ */ -#endif /* __QNX__ */ - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include -#include "chartypes.h" -#if defined (HAVE_PWD_H) -# include -#endif -#include "bashansi.h" -#include "bashintl.h" -#include "filecntl.h" - -#define NEED_XTRACE_SET_DECL - -#include "shell.h" -#include "parser.h" -#include "flags.h" -#include "execute_cmd.h" -#include "findcmd.h" -#include "mailcheck.h" -#include "input.h" -#include "hashcmd.h" -#include "pathexp.h" -#include "alias.h" -#include "jobs.h" - -#include "version.h" - -#include "getopt.h" -#include "common.h" -#include "builtext.h" - -#if defined (READLINE) -# include "bashline.h" -# include "third_party/readline/readline.h" -#else -# include "tilde.h" -#endif - -#if defined (HISTORY) -# include "bashhist.h" -# include "third_party/readline/history.h" -#endif /* HISTORY */ - -#if defined (PROGRAMMABLE_COMPLETION) -# include "pcomplete.h" -#endif - -#define VARIABLES_HASH_BUCKETS 1024 /* must be power of two */ -#define FUNCTIONS_HASH_BUCKETS 512 -#define TEMPENV_HASH_BUCKETS 4 /* must be power of two */ - -#define BASHFUNC_PREFIX "BASH_FUNC_" -#define BASHFUNC_PREFLEN 10 /* == strlen(BASHFUNC_PREFIX */ -#define BASHFUNC_SUFFIX "%%" -#define BASHFUNC_SUFFLEN 2 /* == strlen(BASHFUNC_SUFFIX) */ - -#if ARRAY_EXPORT -#define BASHARRAY_PREFIX "BASH_ARRAY_" -#define BASHARRAY_PREFLEN 11 -#define BASHARRAY_SUFFIX "%%" -#define BASHARRAY_SUFFLEN 2 - -#define BASHASSOC_PREFIX "BASH_ASSOC_" -#define BASHASSOC_PREFLEN 11 -#define BASHASSOC_SUFFIX "%%" /* needs to be the same as BASHARRAY_SUFFIX */ -#define BASHASSOC_SUFFLEN 2 -#endif - -/* flags for find_variable_internal */ - -#define FV_FORCETEMPENV 0x01 -#define FV_SKIPINVISIBLE 0x02 -#define FV_NODYNAMIC 0x04 - -extern char **environ; - -/* Variables used here and defined in other files. */ -extern time_t shell_start_time; -extern struct timeval shellstart; - -/* The list of shell variables that the user has created at the global - scope, or that came from the environment. */ -VAR_CONTEXT *global_variables = (VAR_CONTEXT *)NULL; - -/* The current list of shell variables, including function scopes */ -VAR_CONTEXT *shell_variables = (VAR_CONTEXT *)NULL; - -/* The list of shell functions that the user has created, or that came from - the environment. */ -HASH_TABLE *shell_functions = (HASH_TABLE *)NULL; - -HASH_TABLE *invalid_env = (HASH_TABLE *)NULL; - -#if defined (DEBUGGER) -/* The table of shell function definitions that the user defined or that - came from the environment. */ -HASH_TABLE *shell_function_defs = (HASH_TABLE *)NULL; -#endif - -/* The current variable context. This is really a count of how deep into - executing functions we are. */ -int variable_context = 0; - -/* If non-zero, local variables inherit values and attributes from a variable - with the same name at a previous scope. */ -int localvar_inherit = 0; - -/* If non-zero, calling `unset' on local variables in previous scopes marks - them as invisible so lookups find them unset. This is the same behavior - as local variables in the current local scope. */ -int localvar_unset = 0; - -/* The set of shell assignments which are made only in the environment - for a single command. */ -HASH_TABLE *temporary_env = (HASH_TABLE *)NULL; - -/* Set to non-zero if an assignment error occurs while putting variables - into the temporary environment. */ -int tempenv_assign_error; - -/* Some funky variables which are known about specially. Here is where - "$*", "$1", and all the cruft is kept. */ -char *dollar_vars[10]; -WORD_LIST *rest_of_args = (WORD_LIST *)NULL; -int posparam_count = 0; - -/* The value of $$. */ -pid_t dollar_dollar_pid; - -/* Non-zero means that we have to remake EXPORT_ENV. */ -int array_needs_making = 1; - -/* The number of times BASH has been executed. This is set - by initialize_variables (). */ -int shell_level = 0; - -/* An array which is passed to commands as their environment. It is - manufactured from the union of the initial environment and the - shell variables that are marked for export. */ -char **export_env = (char **)NULL; -static int export_env_index; -static int export_env_size; - -#if defined (READLINE) -static int winsize_assignment; /* currently assigning to LINES or COLUMNS */ -#endif - -SHELL_VAR nameref_invalid_value; -static SHELL_VAR nameref_maxloop_value; - -static HASH_TABLE *last_table_searched; /* hash_lookup sets this */ -static VAR_CONTEXT *last_context_searched; - -/* Some forward declarations. */ -static void create_variable_tables PARAMS((void)); - -static void set_machine_vars PARAMS((void)); -static void set_home_var PARAMS((void)); -static void set_shell_var PARAMS((void)); -static char *get_bash_name PARAMS((void)); -static void initialize_shell_level PARAMS((void)); -static void uidset PARAMS((void)); -#if defined (ARRAY_VARS) -static void make_vers_array PARAMS((void)); -#endif - -static SHELL_VAR *null_assign PARAMS((SHELL_VAR *, char *, arrayind_t, char *)); -#if defined (ARRAY_VARS) -static SHELL_VAR *null_array_assign PARAMS((SHELL_VAR *, char *, arrayind_t, char *)); -#endif -static SHELL_VAR *get_self PARAMS((SHELL_VAR *)); - -#if defined (ARRAY_VARS) -static SHELL_VAR *init_dynamic_array_var PARAMS((char *, sh_var_value_func_t *, sh_var_assign_func_t *, int)); -static SHELL_VAR *init_dynamic_assoc_var PARAMS((char *, sh_var_value_func_t *, sh_var_assign_func_t *, int)); -#endif - -static inline SHELL_VAR *set_int_value (SHELL_VAR *, intmax_t, int); -static inline SHELL_VAR *set_string_value (SHELL_VAR *, const char *, int); - -static SHELL_VAR *assign_seconds PARAMS((SHELL_VAR *, char *, arrayind_t, char *)); -static SHELL_VAR *get_seconds PARAMS((SHELL_VAR *)); -static SHELL_VAR *init_seconds_var PARAMS((void)); - -static SHELL_VAR *assign_random PARAMS((SHELL_VAR *, char *, arrayind_t, char *)); -static SHELL_VAR *get_random PARAMS((SHELL_VAR *)); - -static SHELL_VAR *get_urandom PARAMS((SHELL_VAR *)); - -static SHELL_VAR *assign_lineno PARAMS((SHELL_VAR *, char *, arrayind_t, char *)); -static SHELL_VAR *get_lineno PARAMS((SHELL_VAR *)); - -static SHELL_VAR *assign_subshell PARAMS((SHELL_VAR *, char *, arrayind_t, char *)); -static SHELL_VAR *get_subshell PARAMS((SHELL_VAR *)); - -static SHELL_VAR *get_epochseconds PARAMS((SHELL_VAR *)); -static SHELL_VAR *get_epochrealtime PARAMS((SHELL_VAR *)); - -static SHELL_VAR *get_bashpid PARAMS((SHELL_VAR *)); - -static SHELL_VAR *get_bash_argv0 PARAMS((SHELL_VAR *)); -static SHELL_VAR *assign_bash_argv0 PARAMS((SHELL_VAR *, char *, arrayind_t, char *)); -static void set_argv0 PARAMS((void)); - -#if defined (HISTORY) -static SHELL_VAR *get_histcmd PARAMS((SHELL_VAR *)); -#endif - -#if defined (READLINE) -static SHELL_VAR *get_comp_wordbreaks PARAMS((SHELL_VAR *)); -static SHELL_VAR *assign_comp_wordbreaks PARAMS((SHELL_VAR *, char *, arrayind_t, char *)); -#endif - -#if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS) -static SHELL_VAR *assign_dirstack PARAMS((SHELL_VAR *, char *, arrayind_t, char *)); -static SHELL_VAR *get_dirstack PARAMS((SHELL_VAR *)); -#endif - -#if defined (ARRAY_VARS) -static SHELL_VAR *get_groupset PARAMS((SHELL_VAR *)); -# if defined (DEBUGGER) -static SHELL_VAR *get_bashargcv PARAMS((SHELL_VAR *)); -# endif -static SHELL_VAR *build_hashcmd PARAMS((SHELL_VAR *)); -static SHELL_VAR *get_hashcmd PARAMS((SHELL_VAR *)); -static SHELL_VAR *assign_hashcmd PARAMS((SHELL_VAR *, char *, arrayind_t, char *)); -# if defined (ALIAS) -static SHELL_VAR *build_aliasvar PARAMS((SHELL_VAR *)); -static SHELL_VAR *get_aliasvar PARAMS((SHELL_VAR *)); -static SHELL_VAR *assign_aliasvar PARAMS((SHELL_VAR *, char *, arrayind_t, char *)); -# endif -#endif - -static SHELL_VAR *get_funcname PARAMS((SHELL_VAR *)); -static SHELL_VAR *init_funcname_var PARAMS((void)); - -static void initialize_dynamic_variables PARAMS((void)); - -static SHELL_VAR *bind_invalid_envvar PARAMS((const char *, char *, int)); - -static int var_sametype PARAMS((SHELL_VAR *, SHELL_VAR *)); - -static SHELL_VAR *hash_lookup PARAMS((const char *, HASH_TABLE *)); -static SHELL_VAR *new_shell_variable PARAMS((const char *)); -static SHELL_VAR *make_new_variable PARAMS((const char *, HASH_TABLE *)); -static SHELL_VAR *bind_variable_internal PARAMS((const char *, char *, HASH_TABLE *, int, int)); - -static void dispose_variable_value PARAMS((SHELL_VAR *)); -static void free_variable_hash_data PARAMS((PTR_T)); - -static VARLIST *vlist_alloc PARAMS((int)); -static VARLIST *vlist_realloc PARAMS((VARLIST *, int)); -static void vlist_add PARAMS((VARLIST *, SHELL_VAR *, int)); - -static void flatten PARAMS((HASH_TABLE *, sh_var_map_func_t *, VARLIST *, int)); - -static int qsort_var_comp PARAMS((SHELL_VAR **, SHELL_VAR **)); - -static SHELL_VAR **vapply PARAMS((sh_var_map_func_t *)); -static SHELL_VAR **fapply PARAMS((sh_var_map_func_t *)); - -static int visible_var PARAMS((SHELL_VAR *)); -static int visible_and_exported PARAMS((SHELL_VAR *)); -static int export_environment_candidate PARAMS((SHELL_VAR *)); -static int local_and_exported PARAMS((SHELL_VAR *)); -static int visible_variable_in_context PARAMS((SHELL_VAR *)); -static int variable_in_context PARAMS((SHELL_VAR *)); -#if defined (ARRAY_VARS) -static int visible_array_vars PARAMS((SHELL_VAR *)); -#endif - -static SHELL_VAR *find_variable_internal PARAMS((const char *, int)); - -static SHELL_VAR *find_nameref_at_context PARAMS((SHELL_VAR *, VAR_CONTEXT *)); -static SHELL_VAR *find_variable_nameref_context PARAMS((SHELL_VAR *, VAR_CONTEXT *, VAR_CONTEXT **)); -static SHELL_VAR *find_variable_last_nameref_context PARAMS((SHELL_VAR *, VAR_CONTEXT *, VAR_CONTEXT **)); - -static SHELL_VAR *bind_tempenv_variable PARAMS((const char *, char *)); -static void push_posix_temp_var PARAMS((PTR_T)); -static void push_temp_var PARAMS((PTR_T)); -static void propagate_temp_var PARAMS((PTR_T)); -static void dispose_temporary_env PARAMS((sh_free_func_t *)); - -static inline char *mk_env_string PARAMS((const char *, const char *, int)); -static char **make_env_array_from_var_list PARAMS((SHELL_VAR **)); -static char **make_var_export_array PARAMS((VAR_CONTEXT *)); -static char **make_func_export_array PARAMS((void)); -static void add_temp_array_to_env PARAMS((char **, int, int)); - -static int n_shell_variables PARAMS((void)); -static int set_context PARAMS((SHELL_VAR *)); - -static void push_func_var PARAMS((PTR_T)); -static void push_builtin_var PARAMS((PTR_T)); -static void push_exported_var PARAMS((PTR_T)); - -static void delete_local_contexts PARAMS((VAR_CONTEXT *)); - -/* This needs to be looked at again. */ -static inline void push_posix_tempvar_internal PARAMS((SHELL_VAR *, int)); - -static inline int find_special_var PARAMS((const char *)); - -static void -create_variable_tables () -{ - if (shell_variables == 0) - { - shell_variables = global_variables = new_var_context ((char *)NULL, 0); - shell_variables->scope = 0; - shell_variables->table = hash_create (VARIABLES_HASH_BUCKETS); - } - - if (shell_functions == 0) - shell_functions = hash_create (FUNCTIONS_HASH_BUCKETS); - -#if defined (DEBUGGER) - if (shell_function_defs == 0) - shell_function_defs = hash_create (FUNCTIONS_HASH_BUCKETS); -#endif -} - -/* Initialize the shell variables from the current environment. - If PRIVMODE is nonzero, don't import functions from ENV or - parse $SHELLOPTS. */ -void -initialize_shell_variables (env, privmode) - char **env; - int privmode; -{ - char *name, *string, *temp_string; - int c, char_index, string_index, string_length, ro; - SHELL_VAR *temp_var; - - create_variable_tables (); - - for (string_index = 0; env && (string = env[string_index++]); ) - { - char_index = 0; - name = string; - while ((c = *string++) && c != '=') - ; - if (string[-1] == '=') - char_index = string - name - 1; - - /* If there are weird things in the environment, like `=xxx' or a - string without an `=', just skip them. */ - if (char_index == 0) - continue; - - /* ASSERT(name[char_index] == '=') */ - name[char_index] = '\0'; - /* Now, name = env variable name, string = env variable value, and - char_index == strlen (name) */ - - temp_var = (SHELL_VAR *)NULL; - -#if defined (FUNCTION_IMPORT) - /* If exported function, define it now. Don't import functions from - the environment in privileged mode. */ - if (privmode == 0 && read_but_dont_execute == 0 && - STREQN (BASHFUNC_PREFIX, name, BASHFUNC_PREFLEN) && - STREQ (BASHFUNC_SUFFIX, name + char_index - BASHFUNC_SUFFLEN) && - STREQN ("() {", string, 4)) - { - size_t namelen; - char *tname; /* desired imported function name */ - - namelen = char_index - BASHFUNC_PREFLEN - BASHFUNC_SUFFLEN; - - tname = name + BASHFUNC_PREFLEN; /* start of func name */ - tname[namelen] = '\0'; /* now tname == func name */ - - string_length = strlen (string); - temp_string = (char *)xmalloc (namelen + string_length + 2); - - memcpy (temp_string, tname, namelen); - temp_string[namelen] = ' '; - memcpy (temp_string + namelen + 1, string, string_length + 1); - - /* Don't import function names that are invalid identifiers from the - environment in posix mode, though we still allow them to be defined as - shell variables. */ - if (absolute_program (tname) == 0 && (posixly_correct == 0 || legal_identifier (tname))) - parse_and_execute (temp_string, tname, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_FUNCDEF|SEVAL_ONECMD); - else - free (temp_string); /* parse_and_execute does this */ - - if (temp_var = find_function (tname)) - { - VSETATTR (temp_var, (att_exported|att_imported)); - array_needs_making = 1; - } - else - { - if (temp_var = bind_invalid_envvar (name, string, 0)) - { - VSETATTR (temp_var, (att_exported | att_imported | att_invisible)); - array_needs_making = 1; - } - last_command_exit_value = EXECUTION_FAILURE; - report_error (_("error importing function definition for `%s'"), tname); - } - - /* Restore original suffix */ - tname[namelen] = BASHFUNC_SUFFIX[0]; - } - else -#endif /* FUNCTION_IMPORT */ -#if defined (ARRAY_VARS) -# if ARRAY_EXPORT - /* Array variables may not yet be exported. */ - if (STREQN (BASHARRAY_PREFIX, name, BASHARRAY_PREFLEN) && - STREQN (BASHARRAY_SUFFIX, name + char_index - BASHARRAY_SUFFLEN, BASHARRAY_SUFFLEN) && - *string == '(' && string[1] == '[' && string[strlen (string) - 1] == ')') - { - size_t namelen; - char *tname; /* desired imported array variable name */ - - namelen = char_index - BASHARRAY_PREFLEN - BASHARRAY_SUFFLEN; - - tname = name + BASHARRAY_PREFLEN; /* start of variable name */ - tname[namelen] = '\0'; /* now tname == varname */ - - string_length = 1; - temp_string = extract_array_assignment_list (string, &string_length); - temp_var = assign_array_from_string (tname, temp_string, 0); - FREE (temp_string); - if (temp_var) - { - VSETATTR (temp_var, (att_exported | att_imported)); - array_needs_making = 1; - } - } - else if (STREQN (BASHASSOC_PREFIX, name, BASHASSOC_PREFLEN) && - STREQN (BASHASSOC_SUFFIX, name + char_index - BASHASSOC_SUFFLEN, BASHASSOC_SUFFLEN) && - *string == '(' && string[1] == '[' && string[strlen (string) - 1] == ')') - { - size_t namelen; - char *tname; /* desired imported assoc variable name */ - - namelen = char_index - BASHASSOC_PREFLEN - BASHASSOC_SUFFLEN; - - tname = name + BASHASSOC_PREFLEN; /* start of variable name */ - tname[namelen] = '\0'; /* now tname == varname */ - - /* need to make sure it exists as an associative array first */ - temp_var = find_or_make_array_variable (tname, 2); - if (temp_var) - { - string_length = 1; - temp_string = extract_array_assignment_list (string, &string_length); - temp_var = assign_array_var_from_string (temp_var, temp_string, 0); - } - FREE (temp_string); - if (temp_var) - { - VSETATTR (temp_var, (att_exported | att_imported)); - array_needs_making = 1; - } - } - else -# endif /* ARRAY_EXPORT */ -#endif - { - ro = 0; - /* If we processed a command-line option that caused SHELLOPTS to be - set, it may already be set (and read-only) by the time we process - the shell's environment. */ - if (/* posixly_correct &&*/ STREQ (name, "SHELLOPTS")) - { - temp_var = find_variable ("SHELLOPTS"); - ro = temp_var && readonly_p (temp_var); - if (temp_var) - VUNSETATTR (temp_var, att_readonly); - } - if (legal_identifier (name)) - { - temp_var = bind_variable (name, string, 0); - if (temp_var) - { - VSETATTR (temp_var, (att_exported | att_imported)); - if (ro) - VSETATTR (temp_var, att_readonly); - } - } - else - { - temp_var = bind_invalid_envvar (name, string, 0); - if (temp_var) - VSETATTR (temp_var, (att_exported | att_imported | att_invisible)); - } - if (temp_var) - array_needs_making = 1; - } - - name[char_index] = '='; - /* temp_var can be NULL if it was an exported function with a syntax - error (a different bug, but it still shouldn't dump core). */ - if (temp_var && function_p (temp_var) == 0) /* XXX not yet */ - { - CACHE_IMPORTSTR (temp_var, name); - } - } - - set_pwd (); - - /* Set up initial value of $_ */ - temp_var = set_if_not ("_", dollar_vars[0]); - - /* Remember this pid. */ - dollar_dollar_pid = getpid (); - - /* Now make our own defaults in case the vars that we think are - important are missing. */ - temp_var = set_if_not ("PATH", DEFAULT_PATH_VALUE); - temp_var = set_if_not ("TERM", "dumb"); - -#if defined (__QNX__) - /* set node id -- don't import it from the environment */ - { - char node_name[22]; -# if defined (__QNXNTO__) - netmgr_ndtostr(ND2S_LOCAL_STR, ND_LOCAL_NODE, node_name, sizeof(node_name)); -# else - qnx_nidtostr (getnid (), node_name, sizeof (node_name)); -# endif - temp_var = bind_variable ("NODE", node_name, 0); - if (temp_var) - set_auto_export (temp_var); - } -#endif - - /* set up the prompts. */ - if (interactive_shell) - { -#if defined (PROMPT_STRING_DECODE) - set_if_not ("PS1", primary_prompt); -#else - if (current_user.uid == -1) - get_current_user_info (); - set_if_not ("PS1", current_user.euid == 0 ? "# " : primary_prompt); -#endif - set_if_not ("PS2", secondary_prompt); - } - - if (current_user.euid == 0) - bind_variable ("PS4", "+ ", 0); - else - set_if_not ("PS4", "+ "); - - /* Don't allow IFS to be imported from the environment. */ - temp_var = bind_variable ("IFS", " \t\n", 0); - setifs (temp_var); - - /* Magic machine types. Pretty convenient. */ - set_machine_vars (); - - /* Default MAILCHECK for interactive shells. Defer the creation of a - default MAILPATH until the startup files are read, because MAIL - names a mail file if MAILPATH is not set, and we should provide a - default only if neither is set. */ - if (interactive_shell) - { - temp_var = set_if_not ("MAILCHECK", posixly_correct ? "600" : "60"); - VSETATTR (temp_var, att_integer); - } - - /* Do some things with shell level. */ - initialize_shell_level (); - - set_ppid (); - - set_argv0 (); - - /* Initialize the `getopts' stuff. */ - temp_var = bind_variable ("OPTIND", "1", 0); - VSETATTR (temp_var, att_integer); - getopts_reset (0); - bind_variable ("OPTERR", "1", 0); - sh_opterr = 1; - - if (login_shell == 1 && posixly_correct == 0) - set_home_var (); - - /* Get the full pathname to THIS shell, and set the BASH variable - to it. */ - name = get_bash_name (); - temp_var = bind_variable ("BASH", name, 0); - free (name); - - /* Make the exported environment variable SHELL be the user's login - shell. Note that the `tset' command looks at this variable - to determine what style of commands to output; if it ends in "csh", - then C-shell commands are output, else Bourne shell commands. */ - set_shell_var (); - - /* Make a variable called BASH_VERSION which contains the version info. */ - bind_variable ("BASH_VERSION", shell_version_string (), 0); -#if defined (ARRAY_VARS) - make_vers_array (); -#endif - - if (command_execution_string) - bind_variable ("BASH_EXECUTION_STRING", command_execution_string, 0); - - /* Find out if we're supposed to be in Posix.2 mode via an - environment variable. */ - temp_var = find_variable ("POSIXLY_CORRECT"); - if (!temp_var) - temp_var = find_variable ("POSIX_PEDANTIC"); - if (temp_var && imported_p (temp_var)) - sv_strict_posix (temp_var->name); - -#if defined (HISTORY) - /* Set history variables to defaults, and then do whatever we would - do if the variable had just been set. Do this only in the case - that we are remembering commands on the history list. */ - if (remember_on_history) - { - name = bash_tilde_expand (posixly_correct ? "~/.sh_history" : "~/.bash_history", 0); - - set_if_not ("HISTFILE", name); - free (name); - } -#endif /* HISTORY */ - - /* Seed the random number generators. */ - seedrand (); - seedrand32 (); - - /* Handle some "special" variables that we may have inherited from a - parent shell. */ - if (interactive_shell) - { - temp_var = find_variable ("IGNOREEOF"); - if (!temp_var) - temp_var = find_variable ("ignoreeof"); - if (temp_var && imported_p (temp_var)) - sv_ignoreeof (temp_var->name); - } - -#if defined (HISTORY) - if (interactive_shell && remember_on_history) - { - sv_history_control ("HISTCONTROL"); - sv_histignore ("HISTIGNORE"); - sv_histtimefmt ("HISTTIMEFORMAT"); - } -#endif /* HISTORY */ - -#if defined (READLINE) && defined (STRICT_POSIX) - /* POSIXLY_CORRECT will be 1 here if the shell was compiled - -DSTRICT_POSIX or if POSIXLY_CORRECT was supplied in the shell's - environment */ - if (interactive_shell && posixly_correct && no_line_editing == 0) - rl_prefer_env_winsize = 1; -#endif /* READLINE && STRICT_POSIX */ - - /* Get the user's real and effective user ids. */ - uidset (); - - temp_var = set_if_not ("BASH_LOADABLES_PATH", DEFAULT_LOADABLE_BUILTINS_PATH); - - temp_var = find_variable ("BASH_XTRACEFD"); - if (temp_var && imported_p (temp_var)) - sv_xtracefd (temp_var->name); - - sv_shcompat ("BASH_COMPAT"); - - /* Allow FUNCNEST to be inherited from the environment. */ - sv_funcnest ("FUNCNEST"); - - /* Initialize the dynamic variables, and seed their values. */ - initialize_dynamic_variables (); -} - -/* **************************************************************** */ -/* */ -/* Setting values for special shell variables */ -/* */ -/* **************************************************************** */ - -static void -set_machine_vars () -{ - SHELL_VAR *temp_var; - - temp_var = set_if_not ("HOSTTYPE", HOSTTYPE); - temp_var = set_if_not ("OSTYPE", OSTYPE); - temp_var = set_if_not ("MACHTYPE", MACHTYPE); - - temp_var = set_if_not ("HOSTNAME", current_host_name); -} - -/* Set $HOME to the information in the password file if we didn't get - it from the environment. */ - -/* This function is not static so the tilde and readline libraries can - use it. */ -char * -sh_get_home_dir () -{ - if (current_user.home_dir == 0) - get_current_user_info (); - return current_user.home_dir; -} - -static void -set_home_var () -{ - SHELL_VAR *temp_var; - - temp_var = find_variable ("HOME"); - if (temp_var == 0) - temp_var = bind_variable ("HOME", sh_get_home_dir (), 0); -#if 0 - VSETATTR (temp_var, att_exported); -#endif -} - -/* Set $SHELL to the user's login shell if it is not already set. Call - get_current_user_info if we haven't already fetched the shell. */ -static void -set_shell_var () -{ - SHELL_VAR *temp_var; - - temp_var = find_variable ("SHELL"); - if (temp_var == 0) - { - if (current_user.shell == 0) - get_current_user_info (); - temp_var = bind_variable ("SHELL", current_user.shell, 0); - } -#if 0 - VSETATTR (temp_var, att_exported); -#endif -} - -static char * -get_bash_name () -{ - char *name; - - if ((login_shell == 1) && RELPATH(shell_name)) - { - if (current_user.shell == 0) - get_current_user_info (); - name = savestring (current_user.shell); - } - else if (ABSPATH(shell_name)) - name = savestring (shell_name); - else if (shell_name[0] == '.' && shell_name[1] == '/') - { - /* Fast path for common case. */ - char *cdir; - int len; - - cdir = get_string_value ("PWD"); - if (cdir) - { - len = strlen (cdir); - name = (char *)xmalloc (len + strlen (shell_name) + 1); - strcpy (name, cdir); - strcpy (name + len, shell_name + 1); - } - else - name = savestring (shell_name); - } - else - { - char *tname; - int s; - - tname = find_user_command (shell_name); - - if (tname == 0) - { - /* Try the current directory. If there is not an executable - there, just punt and use the login shell. */ - s = file_status (shell_name); - if (s & FS_EXECABLE) - { - tname = make_absolute (shell_name, get_string_value ("PWD")); - if (*shell_name == '.') - { - name = sh_canonpath (tname, PATH_CHECKDOTDOT|PATH_CHECKEXISTS); - if (name == 0) - name = tname; - else - free (tname); - } - else - name = tname; - } - else - { - if (current_user.shell == 0) - get_current_user_info (); - name = savestring (current_user.shell); - } - } - else - { - name = full_pathname (tname); - free (tname); - } - } - - return (name); -} - -void -adjust_shell_level (change) - int change; -{ - char new_level[5], *old_SHLVL; - intmax_t old_level; - SHELL_VAR *temp_var; - - old_SHLVL = get_string_value ("SHLVL"); - if (old_SHLVL == 0 || *old_SHLVL == '\0' || legal_number (old_SHLVL, &old_level) == 0) - old_level = 0; - - shell_level = old_level + change; - if (shell_level < 0) - shell_level = 0; - else if (shell_level >= 1000) - { - internal_warning (_("shell level (%d) too high, resetting to 1"), shell_level); - shell_level = 1; - } - - /* We don't need the full generality of itos here. */ - if (shell_level < 10) - { - new_level[0] = shell_level + '0'; - new_level[1] = '\0'; - } - else if (shell_level < 100) - { - new_level[0] = (shell_level / 10) + '0'; - new_level[1] = (shell_level % 10) + '0'; - new_level[2] = '\0'; - } - else if (shell_level < 1000) - { - new_level[0] = (shell_level / 100) + '0'; - old_level = shell_level % 100; - new_level[1] = (old_level / 10) + '0'; - new_level[2] = (old_level % 10) + '0'; - new_level[3] = '\0'; - } - - temp_var = bind_variable ("SHLVL", new_level, 0); - set_auto_export (temp_var); -} - -static void -initialize_shell_level () -{ - adjust_shell_level (1); -} - -/* If we got PWD from the environment, update our idea of the current - working directory. In any case, make sure that PWD exists before - checking it. It is possible for getcwd () to fail on shell startup, - and in that case, PWD would be undefined. If this is an interactive - login shell, see if $HOME is the current working directory, and if - that's not the same string as $PWD, set PWD=$HOME. */ - -void -set_pwd () -{ - SHELL_VAR *temp_var, *home_var; - char *temp_string, *home_string, *current_dir; - - home_var = find_variable ("HOME"); - home_string = home_var ? value_cell (home_var) : (char *)NULL; - - temp_var = find_variable ("PWD"); - /* Follow posix rules for importing PWD */ - if (temp_var && imported_p (temp_var) && - (temp_string = value_cell (temp_var)) && - temp_string[0] == '/' && - same_file (temp_string, ".", (struct stat *)NULL, (struct stat *)NULL)) - { - current_dir = sh_canonpath (temp_string, PATH_CHECKDOTDOT|PATH_CHECKEXISTS); - if (current_dir == 0) - current_dir = get_working_directory ("shell_init"); - else - set_working_directory (current_dir); - if (posixly_correct && current_dir) - { - temp_var = bind_variable ("PWD", current_dir, 0); - set_auto_export (temp_var); - } - free (current_dir); - } - else if (home_string && interactive_shell && login_shell && - same_file (home_string, ".", (struct stat *)NULL, (struct stat *)NULL)) - { - set_working_directory (home_string); - temp_var = bind_variable ("PWD", home_string, 0); - set_auto_export (temp_var); - } - else - { - temp_string = get_working_directory ("shell-init"); - if (temp_string) - { - temp_var = bind_variable ("PWD", temp_string, 0); - set_auto_export (temp_var); - free (temp_string); - } - } - - /* According to the Single Unix Specification, v2, $OLDPWD is an - `environment variable' and therefore should be auto-exported. If we - don't find OLDPWD in the environment, or it doesn't name a directory, - make a dummy invisible variable for OLDPWD, and mark it as exported. */ - temp_var = find_variable ("OLDPWD"); -#if defined (OLDPWD_CHECK_DIRECTORY) - if (temp_var == 0 || value_cell (temp_var) == 0 || file_isdir (value_cell (temp_var)) == 0) -#else - if (temp_var == 0 || value_cell (temp_var) == 0) -#endif - { - temp_var = bind_variable ("OLDPWD", (char *)NULL, 0); - VSETATTR (temp_var, (att_exported | att_invisible)); - } -} - -/* Make a variable $PPID, which holds the pid of the shell's parent. */ -void -set_ppid () -{ - char namebuf[INT_STRLEN_BOUND(pid_t) + 1], *name; - SHELL_VAR *temp_var; - - name = inttostr (getppid (), namebuf, sizeof(namebuf)); - temp_var = find_variable ("PPID"); - if (temp_var) - VUNSETATTR (temp_var, (att_readonly | att_exported)); - temp_var = bind_variable ("PPID", name, 0); - VSETATTR (temp_var, (att_readonly | att_integer)); -} - -static void -uidset () -{ - char buff[INT_STRLEN_BOUND(uid_t) + 1], *b; - register SHELL_VAR *v; - - b = inttostr (current_user.uid, buff, sizeof (buff)); - v = find_variable ("UID"); - if (v == 0) - { - v = bind_variable ("UID", b, 0); - VSETATTR (v, (att_readonly | att_integer)); - } - - if (current_user.euid != current_user.uid) - b = inttostr (current_user.euid, buff, sizeof (buff)); - - v = find_variable ("EUID"); - if (v == 0) - { - v = bind_variable ("EUID", b, 0); - VSETATTR (v, (att_readonly | att_integer)); - } -} - -#if defined (ARRAY_VARS) -static void -make_vers_array () -{ - SHELL_VAR *vv; - ARRAY *av; - char *s, d[32], b[INT_STRLEN_BOUND(int) + 1]; - - unbind_variable_noref ("BASH_VERSINFO"); - - vv = make_new_array_variable ("BASH_VERSINFO"); - av = array_cell (vv); - strcpy (d, dist_version); - s = strchr (d, '.'); - if (s) - *s++ = '\0'; - array_insert (av, 0, d); - array_insert (av, 1, s); - s = inttostr (patch_level, b, sizeof (b)); - array_insert (av, 2, s); - s = inttostr (build_version, b, sizeof (b)); - array_insert (av, 3, s); - array_insert (av, 4, release_status); - array_insert (av, 5, MACHTYPE); - - VSETATTR (vv, att_readonly); -} -#endif /* ARRAY_VARS */ - -/* Set the environment variables $LINES and $COLUMNS in response to - a window size change. */ -void -sh_set_lines_and_columns (lines, cols) - int lines, cols; -{ - char val[INT_STRLEN_BOUND(int) + 1], *v; - -#if defined (READLINE) - /* If we are currently assigning to LINES or COLUMNS, don't do anything. */ - if (winsize_assignment) - return; -#endif - - v = inttostr (lines, val, sizeof (val)); - bind_variable ("LINES", v, 0); - - v = inttostr (cols, val, sizeof (val)); - bind_variable ("COLUMNS", v, 0); -} - -/* **************************************************************** */ -/* */ -/* Printing variables and values */ -/* */ -/* **************************************************************** */ - -/* Print LIST (a list of shell variables) to stdout in such a way that - they can be read back in. */ -void -print_var_list (list) - register SHELL_VAR **list; -{ - register int i; - register SHELL_VAR *var; - - for (i = 0; list && (var = list[i]); i++) - if (invisible_p (var) == 0) - print_assignment (var); -} - -/* Print LIST (a list of shell functions) to stdout in such a way that - they can be read back in. */ -void -print_func_list (list) - register SHELL_VAR **list; -{ - register int i; - register SHELL_VAR *var; - - for (i = 0; list && (var = list[i]); i++) - { - printf ("%s ", var->name); - print_var_function (var); - printf ("\n"); - } -} - -/* Print the value of a single SHELL_VAR. No newline is - output, but the variable is printed in such a way that - it can be read back in. */ -void -print_assignment (var) - SHELL_VAR *var; -{ - if (var_isset (var) == 0) - return; - - if (function_p (var)) - { - printf ("%s", var->name); - print_var_function (var); - printf ("\n"); - } -#if defined (ARRAY_VARS) - else if (array_p (var)) - print_array_assignment (var, 0); - else if (assoc_p (var)) - print_assoc_assignment (var, 0); -#endif /* ARRAY_VARS */ - else - { - printf ("%s=", var->name); - print_var_value (var, 1); - printf ("\n"); - } -} - -/* Print the value cell of VAR, a shell variable. Do not print - the name, nor leading/trailing newline. If QUOTE is non-zero, - and the value contains shell metacharacters, quote the value - in such a way that it can be read back in. */ -void -print_var_value (var, quote) - SHELL_VAR *var; - int quote; -{ - char *t; - - if (var_isset (var) == 0) - return; - - if (quote && posixly_correct == 0 && ansic_shouldquote (value_cell (var))) - { - t = ansic_quote (value_cell (var), 0, (int *)0); - printf ("%s", t); - free (t); - } - else if (quote && sh_contains_shell_metas (value_cell (var))) - { - t = sh_single_quote (value_cell (var)); - printf ("%s", t); - free (t); - } - else - printf ("%s", value_cell (var)); -} - -/* Print the function cell of VAR, a shell variable. Do not - print the name, nor leading/trailing newline. */ -void -print_var_function (var) - SHELL_VAR *var; -{ - char *x; - - if (function_p (var) && var_isset (var)) - { - x = named_function_string ((char *)NULL, function_cell(var), FUNC_MULTILINE|FUNC_EXTERNAL); - printf ("%s", x); - } -} - -/* **************************************************************** */ -/* */ -/* Dynamic Variables */ -/* */ -/* **************************************************************** */ - -/* DYNAMIC VARIABLES - - These are variables whose values are generated anew each time they are - referenced. These are implemented using a pair of function pointers - in the struct variable: assign_func, which is called from bind_variable - and, if arrays are compiled into the shell, some of the functions in - arrayfunc.c, and dynamic_value, which is called from find_variable. - - assign_func is called from bind_variable_internal, if - bind_variable_internal discovers that the variable being assigned to - has such a function. The function is called as - SHELL_VAR *temp = (*(entry->assign_func)) (entry, value, ind) - and the (SHELL_VAR *)temp is returned as the value of bind_variable. It - is usually ENTRY (self). IND is an index for an array variable, and - unused otherwise. - - dynamic_value is called from find_variable_internal to return a `new' - value for the specified dynamic variable. If this function is NULL, - the variable is treated as a `normal' shell variable. If it is not, - however, then this function is called like this: - tempvar = (*(var->dynamic_value)) (var); - - Sometimes `tempvar' will replace the value of `var'. Other times, the - shell will simply use the string value. Pretty object-oriented, huh? - - Be warned, though: if you `unset' a special variable, it loses its - special meaning, even if you subsequently set it. - - The special assignment code would probably have been better put in - subst.c: do_assignment_internal, in the same style as - stupidly_hack_special_variables, but I wanted the changes as - localized as possible. */ - -#define INIT_DYNAMIC_VAR(var, val, gfunc, afunc) \ - do \ - { \ - v = bind_variable (var, (val), 0); \ - v->dynamic_value = gfunc; \ - v->assign_func = afunc; \ - } \ - while (0) - -#define INIT_DYNAMIC_ARRAY_VAR(var, gfunc, afunc) \ - do \ - { \ - v = make_new_array_variable (var); \ - v->dynamic_value = gfunc; \ - v->assign_func = afunc; \ - } \ - while (0) - -#define INIT_DYNAMIC_ASSOC_VAR(var, gfunc, afunc) \ - do \ - { \ - v = make_new_assoc_variable (var); \ - v->dynamic_value = gfunc; \ - v->assign_func = afunc; \ - } \ - while (0) - -static SHELL_VAR * -null_assign (self, value, unused, key) - SHELL_VAR *self; - char *value; - arrayind_t unused; - char *key; -{ - return (self); -} - -#if defined (ARRAY_VARS) -static SHELL_VAR * -null_array_assign (self, value, ind, key) - SHELL_VAR *self; - char *value; - arrayind_t ind; - char *key; -{ - return (self); -} -#endif - -/* Degenerate `dynamic_value' function; just returns what's passed without - manipulation. */ -static SHELL_VAR * -get_self (self) - SHELL_VAR *self; -{ - return (self); -} - -#if defined (ARRAY_VARS) -/* A generic dynamic array variable initializer. Initialize array variable - NAME with dynamic value function GETFUNC and assignment function SETFUNC. */ -static SHELL_VAR * -init_dynamic_array_var (name, getfunc, setfunc, attrs) - char *name; - sh_var_value_func_t *getfunc; - sh_var_assign_func_t *setfunc; - int attrs; -{ - SHELL_VAR *v; - - v = find_variable (name); - if (v) - return (v); - INIT_DYNAMIC_ARRAY_VAR (name, getfunc, setfunc); - if (attrs) - VSETATTR (v, attrs); - return v; -} - -static SHELL_VAR * -init_dynamic_assoc_var (name, getfunc, setfunc, attrs) - char *name; - sh_var_value_func_t *getfunc; - sh_var_assign_func_t *setfunc; - int attrs; -{ - SHELL_VAR *v; - - v = find_variable (name); - if (v) - return (v); - INIT_DYNAMIC_ASSOC_VAR (name, getfunc, setfunc); - if (attrs) - VSETATTR (v, attrs); - return v; -} -#endif - -/* Set the string value of VAR to the string representation of VALUE. - Right now this takes an INTMAX_T because that's what itos needs. If - FLAGS&1, we force the integer attribute on. */ -static inline SHELL_VAR * -set_int_value (SHELL_VAR *var, intmax_t value, int flags) -{ - char *p; - - p = itos (value); - FREE (value_cell (var)); - var_setvalue (var, p); - if (flags & 1) - VSETATTR (var, att_integer); - return (var); -} - -static inline SHELL_VAR * -set_string_value (SHELL_VAR *var, const char *value, int flags) -{ - char *p; - - if (value && *value) - p = savestring (value); - else - { - p = (char *)xmalloc (1); - p[0] = '\0'; - } - FREE (value_cell (var)); - var_setvalue (var, p); - return (var); -} - -/* The value of $SECONDS. This is the number of seconds since shell - invocation, or, the number of seconds since the last assignment + the - value of the last assignment. */ -static intmax_t seconds_value_assigned; - -static SHELL_VAR * -assign_seconds (self, value, unused, key) - SHELL_VAR *self; - char *value; - arrayind_t unused; - char *key; -{ - intmax_t nval; - int expok; - - if (integer_p (self)) - nval = evalexp (value, 0, &expok); - else - expok = legal_number (value, &nval); - seconds_value_assigned = expok ? nval : 0; - gettimeofday (&shellstart, NULL); - shell_start_time = shellstart.tv_sec; - return (set_int_value (self, nval, integer_p (self) != 0)); -} - -static SHELL_VAR * -get_seconds (var) - SHELL_VAR *var; -{ - time_t time_since_start; - struct timeval tv; - - gettimeofday(&tv, NULL); - time_since_start = tv.tv_sec - shell_start_time; - return (set_int_value (var, seconds_value_assigned + time_since_start, 1)); -} - -static SHELL_VAR * -init_seconds_var () -{ - SHELL_VAR *v; - - v = find_variable ("SECONDS"); - if (v) - { - if (legal_number (value_cell(v), &seconds_value_assigned) == 0) - seconds_value_assigned = 0; - } - INIT_DYNAMIC_VAR ("SECONDS", (v ? value_cell (v) : (char *)NULL), get_seconds, assign_seconds); - return v; -} - -/* Functions for $RANDOM and $SRANDOM */ - -int last_random_value; -static int seeded_subshell = 0; - -static SHELL_VAR * -assign_random (self, value, unused, key) - SHELL_VAR *self; - char *value; - arrayind_t unused; - char *key; -{ - intmax_t seedval; - int expok; - - if (integer_p (self)) - seedval = evalexp (value, 0, &expok); - else - expok = legal_number (value, &seedval); - if (expok == 0) - return (self); - sbrand (seedval); - if (subshell_environment) - seeded_subshell = getpid (); - return (set_int_value (self, seedval, integer_p (self) != 0)); -} - -int -get_random_number () -{ - int rv, pid; - - /* Reset for command and process substitution. */ - pid = getpid (); - if (subshell_environment && seeded_subshell != pid) - { - seedrand (); - seeded_subshell = pid; - } - - do - rv = brand (); - while (rv == last_random_value); - - return (last_random_value = rv); -} - -static SHELL_VAR * -get_random (var) - SHELL_VAR *var; -{ - int rv; - - rv = get_random_number (); - return (set_int_value (var, rv, 1)); -} - -static SHELL_VAR * -get_urandom (var) - SHELL_VAR *var; -{ - u_bits32_t rv; - - rv = get_urandom32 (); - return (set_int_value (var, rv, 1)); -} - -static SHELL_VAR * -assign_lineno (var, value, unused, key) - SHELL_VAR *var; - char *value; - arrayind_t unused; - char *key; -{ - intmax_t new_value; - - if (value == 0 || *value == '\0' || legal_number (value, &new_value) == 0) - new_value = 0; - line_number = line_number_base = new_value; - return (set_int_value (var, line_number, integer_p (var) != 0)); -} - -/* Function which returns the current line number. */ -static SHELL_VAR * -get_lineno (var) - SHELL_VAR *var; -{ - int ln; - - ln = executing_line_number (); - return (set_int_value (var, ln, 0)); -} - -static SHELL_VAR * -assign_subshell (var, value, unused, key) - SHELL_VAR *var; - char *value; - arrayind_t unused; - char *key; -{ - intmax_t new_value; - - if (value == 0 || *value == '\0' || legal_number (value, &new_value) == 0) - new_value = 0; - subshell_level = new_value; - return var; -} - -static SHELL_VAR * -get_subshell (var) - SHELL_VAR *var; -{ - return (set_int_value (var, subshell_level, 0)); -} - -static SHELL_VAR * -get_epochseconds (var) - SHELL_VAR *var; -{ - intmax_t now; - - now = NOW; - return (set_int_value (var, now, 0)); -} - -static SHELL_VAR * -get_epochrealtime (var) - SHELL_VAR *var; -{ - char buf[32]; - struct timeval tv; - - gettimeofday (&tv, NULL); - snprintf (buf, sizeof (buf), "%u%c%06u", (unsigned)tv.tv_sec, - locale_decpoint (), - (unsigned)tv.tv_usec); - - return (set_string_value (var, buf, 0)); -} - -static SHELL_VAR * -get_bashpid (var) - SHELL_VAR *var; -{ - int pid; - - pid = getpid (); - return (set_int_value (var, pid, 1)); -} - -static SHELL_VAR * -get_bash_argv0 (var) - SHELL_VAR *var; -{ - return (set_string_value (var, dollar_vars[0], 0)); -} - -static char *static_shell_name = 0; - -static SHELL_VAR * -assign_bash_argv0 (var, value, unused, key) - SHELL_VAR *var; - char *value; - arrayind_t unused; - char *key; -{ - size_t vlen; - - if (value == 0) - return var; - - FREE (dollar_vars[0]); - dollar_vars[0] = savestring (value); - - /* Need these gyrations because shell_name isn't dynamically allocated */ - vlen = STRLEN (value); - static_shell_name = xrealloc (static_shell_name, vlen + 1); - strcpy (static_shell_name, value); - - shell_name = static_shell_name; - return var; -} - -static void -set_argv0 () -{ - SHELL_VAR *v; - - v = find_variable ("BASH_ARGV0"); - if (v && imported_p (v)) - assign_bash_argv0 (v, value_cell (v), 0, 0); -} - -static SHELL_VAR * -get_bash_command (var) - SHELL_VAR *var; -{ - char *p; - - p = the_printed_command_except_trap ? the_printed_command_except_trap : ""; - return (set_string_value (var, p, 0)); -} - -#if defined (HISTORY) -static SHELL_VAR * -get_histcmd (var) - SHELL_VAR *var; -{ - int n; - - /* Do the same adjustment here we do in parse.y:prompt_history_number, - assuming that we are in one of two states: decoding this as part of - the prompt string, in which case we do not want to assume that the - command has been saved to the history and the history number incremented, - or the expansion is part of the current command being executed and has - already been saved to history and the history number incremented. - Right now we use EXECUTING as the determinant. */ - n = history_number () - executing; - return (set_int_value (var, n, 0)); -} -#endif - -#if defined (READLINE) -/* When this function returns, VAR->value points to malloced memory. */ -static SHELL_VAR * -get_comp_wordbreaks (var) - SHELL_VAR *var; -{ - /* If we don't have anything yet, assign a default value. */ - if (rl_completer_word_break_characters == 0 && bash_readline_initialized == 0) - enable_hostname_completion (perform_hostname_completion); - - return (set_string_value (var, rl_completer_word_break_characters, 0)); -} - -/* When this function returns, rl_completer_word_break_characters points to - malloced memory. */ -static SHELL_VAR * -assign_comp_wordbreaks (self, value, unused, key) - SHELL_VAR *self; - char *value; - arrayind_t unused; - char *key; -{ - if (rl_completer_word_break_characters && - rl_completer_word_break_characters != rl_basic_word_break_characters) - free ((void *)rl_completer_word_break_characters); - - rl_completer_word_break_characters = savestring (value); - return self; -} -#endif /* READLINE */ - -#if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS) -static SHELL_VAR * -assign_dirstack (self, value, ind, key) - SHELL_VAR *self; - char *value; - arrayind_t ind; - char *key; -{ - set_dirstack_element (ind, 1, value); - return self; -} - -static SHELL_VAR * -get_dirstack (self) - SHELL_VAR *self; -{ - ARRAY *a; - WORD_LIST *l; - - l = get_directory_stack (0); - a = array_from_word_list (l); - array_dispose (array_cell (self)); - dispose_words (l); - var_setarray (self, a); - return self; -} -#endif /* PUSHD AND POPD && ARRAY_VARS */ - -#if defined (ARRAY_VARS) -/* We don't want to initialize the group set with a call to getgroups() - unless we're asked to, but we only want to do it once. */ -static SHELL_VAR * -get_groupset (self) - SHELL_VAR *self; -{ - register int i; - int ng; - ARRAY *a; - static char **group_set = (char **)NULL; - - if (group_set == 0) - { - group_set = get_group_list (&ng); - a = array_cell (self); - for (i = 0; i < ng; i++) - array_insert (a, i, group_set[i]); - } - return (self); -} - -# if defined (DEBUGGER) -static SHELL_VAR * -get_bashargcv (self) - SHELL_VAR *self; -{ - static int self_semaphore = 0; - - /* Backwards compatibility: if we refer to BASH_ARGV or BASH_ARGC at the - top level without enabling debug mode, and we don't have an instance - of the variable set, initialize the arg arrays. - This will already have been done if debugging_mode != 0. */ - if (self_semaphore == 0 && variable_context == 0 && debugging_mode == 0) /* don't do it for shell functions */ - { - self_semaphore = 1; - init_bash_argv (); - self_semaphore = 0; - } - return self; -} -# endif - -static SHELL_VAR * -build_hashcmd (self) - SHELL_VAR *self; -{ - HASH_TABLE *h; - int i; - char *k, *v; - BUCKET_CONTENTS *item; - - h = assoc_cell (self); - if (h) - assoc_dispose (h); - - if (hashed_filenames == 0 || HASH_ENTRIES (hashed_filenames) == 0) - { - var_setvalue (self, (char *)NULL); - return self; - } - - h = assoc_create (hashed_filenames->nbuckets); - for (i = 0; i < hashed_filenames->nbuckets; i++) - { - for (item = hash_items (i, hashed_filenames); item; item = item->next) - { - k = savestring (item->key); - v = pathdata(item)->path; - assoc_insert (h, k, v); - } - } - - var_setvalue (self, (char *)h); - return self; -} - -static SHELL_VAR * -get_hashcmd (self) - SHELL_VAR *self; -{ - build_hashcmd (self); - return (self); -} - -static SHELL_VAR * -assign_hashcmd (self, value, ind, key) - SHELL_VAR *self; - char *value; - arrayind_t ind; - char *key; -{ -#if defined (RESTRICTED_SHELL) - char *full_path; - - if (restricted) - { - if (strchr (value, '/')) - { - sh_restricted (value); - return (SHELL_VAR *)NULL; - } - /* If we are changing the hash table in a restricted shell, make sure the - target pathname can be found using a $PATH search. */ - full_path = find_user_command (value); - if (full_path == 0 || *full_path == 0 || executable_file (full_path) == 0) - { - sh_notfound (value); - free (full_path); - return ((SHELL_VAR *)NULL); - } - free (full_path); - } -#endif - phash_insert (key, value, 0, 0); - return (build_hashcmd (self)); -} - -#if defined (ALIAS) -static SHELL_VAR * -build_aliasvar (self) - SHELL_VAR *self; -{ - HASH_TABLE *h; - int i; - char *k, *v; - BUCKET_CONTENTS *item; - - h = assoc_cell (self); - if (h) - assoc_dispose (h); - - if (aliases == 0 || HASH_ENTRIES (aliases) == 0) - { - var_setvalue (self, (char *)NULL); - return self; - } - - h = assoc_create (aliases->nbuckets); - for (i = 0; i < aliases->nbuckets; i++) - { - for (item = hash_items (i, aliases); item; item = item->next) - { - k = savestring (item->key); - v = ((alias_t *)(item->data))->value; - assoc_insert (h, k, v); - } - } - - var_setvalue (self, (char *)h); - return self; -} - -static SHELL_VAR * -get_aliasvar (self) - SHELL_VAR *self; -{ - build_aliasvar (self); - return (self); -} - -static SHELL_VAR * -assign_aliasvar (self, value, ind, key) - SHELL_VAR *self; - char *value; - arrayind_t ind; - char *key; -{ - if (legal_alias_name (key, 0) == 0) - { - report_error (_("`%s': invalid alias name"), key); - return (self); - } - add_alias (key, value); - return (build_aliasvar (self)); -} -#endif /* ALIAS */ - -#endif /* ARRAY_VARS */ - -/* If ARRAY_VARS is not defined, this just returns the name of any - currently-executing function. If we have arrays, it's a call stack. */ -static SHELL_VAR * -get_funcname (self) - SHELL_VAR *self; -{ -#if ! defined (ARRAY_VARS) - if (variable_context && this_shell_function) - return (set_string_value (self, this_shell_function->name, 0)); -#endif - return (self); -} - -void -make_funcname_visible (on_or_off) - int on_or_off; -{ - SHELL_VAR *v; - - v = find_variable ("FUNCNAME"); - if (v == 0 || v->dynamic_value == 0) - return; - - if (on_or_off) - VUNSETATTR (v, att_invisible); - else - VSETATTR (v, att_invisible); -} - -static SHELL_VAR * -init_funcname_var () -{ - SHELL_VAR *v; - - v = find_variable ("FUNCNAME"); - if (v) - return v; -#if defined (ARRAY_VARS) - INIT_DYNAMIC_ARRAY_VAR ("FUNCNAME", get_funcname, null_array_assign); -#else - INIT_DYNAMIC_VAR ("FUNCNAME", (char *)NULL, get_funcname, null_assign); -#endif - VSETATTR (v, att_invisible|att_noassign); - return v; -} - -static void -initialize_dynamic_variables () -{ - SHELL_VAR *v; - - v = init_seconds_var (); - - INIT_DYNAMIC_VAR ("BASH_ARGV0", (char *)NULL, get_bash_argv0, assign_bash_argv0); - - INIT_DYNAMIC_VAR ("BASH_COMMAND", (char *)NULL, get_bash_command, (sh_var_assign_func_t *)NULL); - INIT_DYNAMIC_VAR ("BASH_SUBSHELL", (char *)NULL, get_subshell, assign_subshell); - - INIT_DYNAMIC_VAR ("RANDOM", (char *)NULL, get_random, assign_random); - VSETATTR (v, att_integer); - INIT_DYNAMIC_VAR ("SRANDOM", (char *)NULL, get_urandom, (sh_var_assign_func_t *)NULL); - VSETATTR (v, att_integer); - INIT_DYNAMIC_VAR ("LINENO", (char *)NULL, get_lineno, assign_lineno); - VSETATTR (v, att_regenerate); - - INIT_DYNAMIC_VAR ("BASHPID", (char *)NULL, get_bashpid, null_assign); - VSETATTR (v, att_integer); - - INIT_DYNAMIC_VAR ("EPOCHSECONDS", (char *)NULL, get_epochseconds, null_assign); - VSETATTR (v, att_regenerate); - INIT_DYNAMIC_VAR ("EPOCHREALTIME", (char *)NULL, get_epochrealtime, null_assign); - VSETATTR (v, att_regenerate); - -#if defined (HISTORY) - INIT_DYNAMIC_VAR ("HISTCMD", (char *)NULL, get_histcmd, (sh_var_assign_func_t *)NULL); - VSETATTR (v, att_integer); -#endif - -#if defined (READLINE) - INIT_DYNAMIC_VAR ("COMP_WORDBREAKS", (char *)NULL, get_comp_wordbreaks, assign_comp_wordbreaks); -#endif - -#if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS) - v = init_dynamic_array_var ("DIRSTACK", get_dirstack, assign_dirstack, 0); -#endif /* PUSHD_AND_POPD && ARRAY_VARS */ - -#if defined (ARRAY_VARS) - v = init_dynamic_array_var ("GROUPS", get_groupset, null_array_assign, att_noassign); - -# if defined (DEBUGGER) - v = init_dynamic_array_var ("BASH_ARGC", get_bashargcv, null_array_assign, att_noassign|att_nounset); - v = init_dynamic_array_var ("BASH_ARGV", get_bashargcv, null_array_assign, att_noassign|att_nounset); -# endif /* DEBUGGER */ - v = init_dynamic_array_var ("BASH_SOURCE", get_self, null_array_assign, att_noassign|att_nounset); - v = init_dynamic_array_var ("BASH_LINENO", get_self, null_array_assign, att_noassign|att_nounset); - - v = init_dynamic_assoc_var ("BASH_CMDS", get_hashcmd, assign_hashcmd, att_nofree); -# if defined (ALIAS) - v = init_dynamic_assoc_var ("BASH_ALIASES", get_aliasvar, assign_aliasvar, att_nofree); -# endif -#endif - - v = init_funcname_var (); -} - -/* **************************************************************** */ -/* */ -/* Retrieving variables and values */ -/* */ -/* **************************************************************** */ - -#if 0 /* not yet */ -int -var_isset (var) - SHELL_VAR *var; -{ - return (var->value != 0); -} - -int -var_isunset (var) - SHELL_VAR *var; -{ - return (var->value == 0); -} -#endif - -/* How to get a pointer to the shell variable or function named NAME. - HASHED_VARS is a pointer to the hash table containing the list - of interest (either variables or functions). */ - -static SHELL_VAR * -hash_lookup (name, hashed_vars) - const char *name; - HASH_TABLE *hashed_vars; -{ - BUCKET_CONTENTS *bucket; - - bucket = hash_search (name, hashed_vars, 0); - /* If we find the name in HASHED_VARS, set LAST_TABLE_SEARCHED to that - table. */ - if (bucket) - last_table_searched = hashed_vars; - return (bucket ? (SHELL_VAR *)bucket->data : (SHELL_VAR *)NULL); -} - -SHELL_VAR * -var_lookup (name, vcontext) - const char *name; - VAR_CONTEXT *vcontext; -{ - VAR_CONTEXT *vc; - SHELL_VAR *v; - - v = (SHELL_VAR *)NULL; - for (vc = vcontext; vc; vc = vc->down) - if (v = hash_lookup (name, vc->table)) - break; - - return v; -} - -/* Look up the variable entry named NAME. If SEARCH_TEMPENV is non-zero, - then also search the temporarily built list of exported variables. - The lookup order is: - temporary_env - shell_variables list -*/ - -SHELL_VAR * -find_variable_internal (name, flags) - const char *name; - int flags; -{ - SHELL_VAR *var; - int search_tempenv, force_tempenv; - VAR_CONTEXT *vc; - - var = (SHELL_VAR *)NULL; - - force_tempenv = (flags & FV_FORCETEMPENV); - - /* If explicitly requested, first look in the temporary environment for - the variable. This allows constructs such as "foo=x eval 'echo $foo'" - to get the `exported' value of $foo. This happens if we are executing - a function or builtin, or if we are looking up a variable in a - "subshell environment". */ - search_tempenv = force_tempenv || (expanding_redir == 0 && subshell_environment); - - if (search_tempenv && temporary_env) - var = hash_lookup (name, temporary_env); - - if (var == 0) - { - if ((flags & FV_SKIPINVISIBLE) == 0) - var = var_lookup (name, shell_variables); - else - { - /* essentially var_lookup expanded inline so we can check for - att_invisible */ - for (vc = shell_variables; vc; vc = vc->down) - { - var = hash_lookup (name, vc->table); - if (var && invisible_p (var)) - var = 0; - if (var) - break; - } - } - } - - if (var == 0) - return ((SHELL_VAR *)NULL); - - return (var->dynamic_value ? (*(var->dynamic_value)) (var) : var); -} - -/* Look up and resolve the chain of nameref variables starting at V all the - way to NULL or non-nameref. */ -SHELL_VAR * -find_variable_nameref (v) - SHELL_VAR *v; -{ - int level, flags; - char *newname; - SHELL_VAR *orig, *oldv; - - level = 0; - orig = v; - while (v && nameref_p (v)) - { - level++; - if (level > NAMEREF_MAX) - return ((SHELL_VAR *)0); /* error message here? */ - newname = nameref_cell (v); - if (newname == 0 || *newname == '\0') - return ((SHELL_VAR *)0); - oldv = v; - flags = 0; - if (expanding_redir == 0 && (assigning_in_environment || executing_builtin)) - flags |= FV_FORCETEMPENV; - /* We don't handle array subscripts here. */ - v = find_variable_internal (newname, flags); - if (v == orig || v == oldv) - { - internal_warning (_("%s: circular name reference"), orig->name); -#if 1 - /* XXX - provisional change - circular refs go to - global scope for resolution, without namerefs. */ - if (variable_context && v->context) - return (find_global_variable_noref (v->name)); - else -#endif - return ((SHELL_VAR *)0); - } - } - return v; -} - -/* Resolve the chain of nameref variables for NAME. XXX - could change later */ -SHELL_VAR * -find_variable_last_nameref (name, vflags) - const char *name; - int vflags; -{ - SHELL_VAR *v, *nv; - char *newname; - int level, flags; - - nv = v = find_variable_noref (name); - level = 0; - while (v && nameref_p (v)) - { - level++; - if (level > NAMEREF_MAX) - return ((SHELL_VAR *)0); /* error message here? */ - newname = nameref_cell (v); - if (newname == 0 || *newname == '\0') - return ((vflags && invisible_p (v)) ? v : (SHELL_VAR *)0); - nv = v; - flags = 0; - if (expanding_redir == 0 && (assigning_in_environment || executing_builtin)) - flags |= FV_FORCETEMPENV; - /* We don't accommodate array subscripts here. */ - v = find_variable_internal (newname, flags); - } - return nv; -} - -/* Resolve the chain of nameref variables for NAME. XXX - could change later */ -SHELL_VAR * -find_global_variable_last_nameref (name, vflags) - const char *name; - int vflags; -{ - SHELL_VAR *v, *nv; - char *newname; - int level; - - nv = v = find_global_variable_noref (name); - level = 0; - while (v && nameref_p (v)) - { - level++; - if (level > NAMEREF_MAX) - return ((SHELL_VAR *)0); /* error message here? */ - newname = nameref_cell (v); - if (newname == 0 || *newname == '\0') - return ((vflags && invisible_p (v)) ? v : (SHELL_VAR *)0); - nv = v; - /* We don't accommodate array subscripts here. */ - v = find_global_variable_noref (newname); - } - return nv; -} - -static SHELL_VAR * -find_nameref_at_context (v, vc) - SHELL_VAR *v; - VAR_CONTEXT *vc; -{ - SHELL_VAR *nv, *nv2; - char *newname; - int level; - - nv = v; - level = 1; - while (nv && nameref_p (nv)) - { - level++; - if (level > NAMEREF_MAX) - return (&nameref_maxloop_value); - newname = nameref_cell (nv); - if (newname == 0 || *newname == '\0') - return ((SHELL_VAR *)NULL); - nv2 = hash_lookup (newname, vc->table); - if (nv2 == 0) - break; - nv = nv2; - } - return nv; -} - -/* Do nameref resolution from the VC, which is the local context for some - function or builtin, `up' the chain to the global variables context. If - NVCP is not NULL, return the variable context where we finally ended the - nameref resolution (so the bind_variable_internal can use the correct - variable context and hash table). */ -static SHELL_VAR * -find_variable_nameref_context (v, vc, nvcp) - SHELL_VAR *v; - VAR_CONTEXT *vc; - VAR_CONTEXT **nvcp; -{ - SHELL_VAR *nv, *nv2; - VAR_CONTEXT *nvc; - - /* Look starting at the current context all the way `up' */ - for (nv = v, nvc = vc; nvc; nvc = nvc->down) - { - nv2 = find_nameref_at_context (nv, nvc); - if (nv2 == &nameref_maxloop_value) - return (nv2); /* XXX */ - if (nv2 == 0) - continue; - nv = nv2; - if (*nvcp) - *nvcp = nvc; - if (nameref_p (nv) == 0) - break; - } - return (nameref_p (nv) ? (SHELL_VAR *)NULL : nv); -} - -/* Do nameref resolution from the VC, which is the local context for some - function or builtin, `up' the chain to the global variables context. If - NVCP is not NULL, return the variable context where we finally ended the - nameref resolution (so the bind_variable_internal can use the correct - variable context and hash table). */ -static SHELL_VAR * -find_variable_last_nameref_context (v, vc, nvcp) - SHELL_VAR *v; - VAR_CONTEXT *vc; - VAR_CONTEXT **nvcp; -{ - SHELL_VAR *nv, *nv2; - VAR_CONTEXT *nvc; - - /* Look starting at the current context all the way `up' */ - for (nv = v, nvc = vc; nvc; nvc = nvc->down) - { - nv2 = find_nameref_at_context (nv, nvc); - if (nv2 == &nameref_maxloop_value) - return (nv2); /* XXX */ - if (nv2 == 0) - continue; - nv = nv2; - if (*nvcp) - *nvcp = nvc; - } - return (nameref_p (nv) ? nv : (SHELL_VAR *)NULL); -} - -SHELL_VAR * -find_variable_nameref_for_create (name, flags) - const char *name; - int flags; -{ - SHELL_VAR *var; - - /* See if we have a nameref pointing to a variable that hasn't been - created yet. */ - var = find_variable_last_nameref (name, 1); - if ((flags&1) && var && nameref_p (var) && invisible_p (var)) - { - internal_warning (_("%s: removing nameref attribute"), name); - VUNSETATTR (var, att_nameref); - } - if (var && nameref_p (var)) - { - if (legal_identifier (nameref_cell (var)) == 0) - { - sh_invalidid (nameref_cell (var) ? nameref_cell (var) : ""); - return ((SHELL_VAR *)INVALID_NAMEREF_VALUE); - } - } - return (var); -} - -SHELL_VAR * -find_variable_nameref_for_assignment (name, flags) - const char *name; - int flags; -{ - SHELL_VAR *var; - - /* See if we have a nameref pointing to a variable that hasn't been - created yet. */ - var = find_variable_last_nameref (name, 1); - if (var && nameref_p (var) && invisible_p (var)) /* XXX - flags */ - { - internal_warning (_("%s: removing nameref attribute"), name); - VUNSETATTR (var, att_nameref); - } - if (var && nameref_p (var)) - { - if (valid_nameref_value (nameref_cell (var), 1) == 0) - { - sh_invalidid (nameref_cell (var) ? nameref_cell (var) : ""); - return ((SHELL_VAR *)INVALID_NAMEREF_VALUE); - } - } - return (var); -} - -/* If find_variable (name) returns NULL, check that it's not a nameref - referencing a variable that doesn't exist. If it is, return the new - name. If not, return the original name. Kind of like the previous - function, but dealing strictly with names. This takes assignment flags - so it can deal with the various assignment modes used by `declare'. */ -char * -nameref_transform_name (name, flags) - char *name; - int flags; -{ - SHELL_VAR *v; - char *newname; - - v = 0; - if (flags & ASS_MKLOCAL) - { - v = find_variable_last_nameref (name, 1); - /* If we're making local variables, only follow namerefs that point to - non-existent variables at the same variable context. */ - if (v && v->context != variable_context) - v = 0; - } - else if (flags & ASS_MKGLOBAL) - v = (flags & ASS_CHKLOCAL) ? find_variable_last_nameref (name, 1) - : find_global_variable_last_nameref (name, 1); - if (v && nameref_p (v) && valid_nameref_value (nameref_cell (v), 1)) - return nameref_cell (v); - return name; -} - -/* Find a variable, forcing a search of the temporary environment first */ -SHELL_VAR * -find_variable_tempenv (name) - const char *name; -{ - SHELL_VAR *var; - - var = find_variable_internal (name, FV_FORCETEMPENV); - if (var && nameref_p (var)) - var = find_variable_nameref (var); - return (var); -} - -/* Find a variable, not forcing a search of the temporary environment first */ -SHELL_VAR * -find_variable_notempenv (name) - const char *name; -{ - SHELL_VAR *var; - - var = find_variable_internal (name, 0); - if (var && nameref_p (var)) - var = find_variable_nameref (var); - return (var); -} - -SHELL_VAR * -find_global_variable (name) - const char *name; -{ - SHELL_VAR *var; - - var = var_lookup (name, global_variables); - if (var && nameref_p (var)) - var = find_variable_nameref (var); /* XXX - find_global_variable_noref? */ - - if (var == 0) - return ((SHELL_VAR *)NULL); - - return (var->dynamic_value ? (*(var->dynamic_value)) (var) : var); -} - -SHELL_VAR * -find_global_variable_noref (name) - const char *name; -{ - SHELL_VAR *var; - - var = var_lookup (name, global_variables); - - if (var == 0) - return ((SHELL_VAR *)NULL); - - return (var->dynamic_value ? (*(var->dynamic_value)) (var) : var); -} - -SHELL_VAR * -find_shell_variable (name) - const char *name; -{ - SHELL_VAR *var; - - var = var_lookup (name, shell_variables); - if (var && nameref_p (var)) - var = find_variable_nameref (var); - - if (var == 0) - return ((SHELL_VAR *)NULL); - - return (var->dynamic_value ? (*(var->dynamic_value)) (var) : var); -} - -/* Look up the variable entry named NAME. Returns the entry or NULL. */ -SHELL_VAR * -find_variable (name) - const char *name; -{ - SHELL_VAR *v; - int flags; - - last_table_searched = 0; - flags = 0; - if (expanding_redir == 0 && (assigning_in_environment || executing_builtin)) - flags |= FV_FORCETEMPENV; - v = find_variable_internal (name, flags); - if (v && nameref_p (v)) - v = find_variable_nameref (v); - return v; -} - -/* Find the first instance of NAME in the variable context chain; return first - one found without att_invisible set; return 0 if no non-invisible instances - found. */ -SHELL_VAR * -find_variable_no_invisible (name) - const char *name; -{ - SHELL_VAR *v; - int flags; - - last_table_searched = 0; - flags = FV_SKIPINVISIBLE; - if (expanding_redir == 0 && (assigning_in_environment || executing_builtin)) - flags |= FV_FORCETEMPENV; - v = find_variable_internal (name, flags); - if (v && nameref_p (v)) - v = find_variable_nameref (v); - return v; -} - -/* Find the first instance of NAME in the variable context chain; return first - one found even if att_invisible set. */ -SHELL_VAR * -find_variable_for_assignment (name) - const char *name; -{ - SHELL_VAR *v; - int flags; - - last_table_searched = 0; - flags = 0; - if (expanding_redir == 0 && (assigning_in_environment || executing_builtin)) - flags |= FV_FORCETEMPENV; - v = find_variable_internal (name, flags); - if (v && nameref_p (v)) - v = find_variable_nameref (v); - return v; -} - -SHELL_VAR * -find_variable_noref (name) - const char *name; -{ - SHELL_VAR *v; - int flags; - - flags = 0; - if (expanding_redir == 0 && (assigning_in_environment || executing_builtin)) - flags |= FV_FORCETEMPENV; - v = find_variable_internal (name, flags); - return v; -} - -/* Look up the function entry whose name matches STRING. - Returns the entry or NULL. */ -SHELL_VAR * -find_function (name) - const char *name; -{ - return (hash_lookup (name, shell_functions)); -} - -/* Find the function definition for the shell function named NAME. Returns - the entry or NULL. */ -FUNCTION_DEF * -find_function_def (name) - const char *name; -{ -#if defined (DEBUGGER) - return ((FUNCTION_DEF *)hash_lookup (name, shell_function_defs)); -#else - return ((FUNCTION_DEF *)0); -#endif -} - -/* Return the value of VAR. VAR is assumed to have been the result of a - lookup without any subscript, if arrays are compiled into the shell. */ -char * -get_variable_value (var) - SHELL_VAR *var; -{ - if (var == 0) - return ((char *)NULL); -#if defined (ARRAY_VARS) - else if (array_p (var)) - return (array_reference (array_cell (var), 0)); - else if (assoc_p (var)) - return (assoc_reference (assoc_cell (var), "0")); -#endif - else - return (value_cell (var)); -} - -/* Return the string value of a variable. Return NULL if the variable - doesn't exist. Don't cons a new string. This is a potential memory - leak if the variable is found in the temporary environment, but doesn't - leak in practice. Since functions and variables have separate name - spaces, returns NULL if var_name is a shell function only. */ -char * -get_string_value (var_name) - const char *var_name; -{ - SHELL_VAR *var; - - var = find_variable (var_name); - return ((var) ? get_variable_value (var) : (char *)NULL); -} - -/* This is present for use by the tilde and readline libraries. */ -char * -sh_get_env_value (v) - const char *v; -{ - return get_string_value (v); -} - -/* **************************************************************** */ -/* */ -/* Creating and setting variables */ -/* */ -/* **************************************************************** */ - -static int -var_sametype (v1, v2) - SHELL_VAR *v1; - SHELL_VAR *v2; -{ - if (v1 == 0 || v2 == 0) - return 0; -#if defined (ARRAY_VARS) - else if (assoc_p (v1) && assoc_p (v2)) - return 1; - else if (array_p (v1) && array_p (v2)) - return 1; - else if (array_p (v1) || array_p (v2)) - return 0; - else if (assoc_p (v1) || assoc_p (v2)) - return 0; -#endif - else - return 1; -} - -int -validate_inherited_value (var, type) - SHELL_VAR *var; - int type; -{ -#if defined (ARRAY_VARS) - if (type == att_array && assoc_p (var)) - return 0; - else if (type == att_assoc && array_p (var)) - return 0; - else -#endif - return 1; /* should we run convert_var_to_array here or let the caller? */ -} - -/* Set NAME to VALUE if NAME has no value. */ -SHELL_VAR * -set_if_not (name, value) - char *name, *value; -{ - SHELL_VAR *v; - - if (shell_variables == 0) - create_variable_tables (); - - v = find_variable (name); - if (v == 0) - v = bind_variable_internal (name, value, global_variables->table, HASH_NOSRCH, 0); - return (v); -} - -/* Create a local variable referenced by NAME. */ -SHELL_VAR * -make_local_variable (name, flags) - const char *name; - int flags; -{ - SHELL_VAR *new_var, *old_var, *old_ref; - VAR_CONTEXT *vc; - int was_tmpvar; - char *old_value; - - /* We don't want to follow the nameref chain when making local variables; we - just want to create them. */ - old_ref = find_variable_noref (name); - if (old_ref && nameref_p (old_ref) == 0) - old_ref = 0; - /* local foo; local foo; is a no-op. */ - old_var = find_variable (name); - if (old_ref == 0 && old_var && local_p (old_var) && old_var->context == variable_context) - return (old_var); - - /* local -n foo; local -n foo; is a no-op. */ - if (old_ref && local_p (old_ref) && old_ref->context == variable_context) - return (old_ref); - - /* From here on, we want to use the refvar, not the variable it references */ - if (old_ref) - old_var = old_ref; - - was_tmpvar = old_var && tempvar_p (old_var); - /* If we're making a local variable in a shell function, the temporary env - has already been merged into the function's variable context stack. We - can assume that a temporary var in the same context appears in the same - VAR_CONTEXT and can safely be returned without creating a new variable - (which results in duplicate names in the same VAR_CONTEXT->table */ - /* We can't just test tmpvar_p because variables in the temporary env given - to a shell function appear in the function's local variable VAR_CONTEXT - but retain their tempvar attribute. We want temporary variables that are - found in temporary_env, hence the test for last_table_searched, which is - set in hash_lookup and only (so far) checked here. */ - if (was_tmpvar && old_var->context == variable_context && last_table_searched != temporary_env) - { - VUNSETATTR (old_var, att_invisible); /* XXX */ - /* We still want to flag this variable as local, though, and set things - up so that it gets treated as a local variable. */ - new_var = old_var; - /* Since we found the variable in a temporary environment, this will - succeed. */ - for (vc = shell_variables; vc; vc = vc->down) - if (vc_isfuncenv (vc) && vc->scope == variable_context) - break; - goto set_local_var_flags; - - return (old_var); - } - - /* If we want to change to "inherit the old variable's value" semantics, - here is where to save the old value. */ - old_value = was_tmpvar ? value_cell (old_var) : (char *)NULL; - - for (vc = shell_variables; vc; vc = vc->down) - if (vc_isfuncenv (vc) && vc->scope == variable_context) - break; - - if (vc == 0) - { - internal_error (_("make_local_variable: no function context at current scope")); - return ((SHELL_VAR *)NULL); - } - else if (vc->table == 0) - vc->table = hash_create (TEMPENV_HASH_BUCKETS); - - /* Since this is called only from the local/declare/typeset code, we can - call builtin_error here without worry (of course, it will also work - for anything that sets this_command_name). Variables with the `noassign' - attribute may not be made local. The test against old_var's context - level is to disallow local copies of readonly global variables (since I - believe that this could be a security hole). Readonly copies of calling - function local variables are OK. */ - if (old_var && (noassign_p (old_var) || - (readonly_p (old_var) && old_var->context == 0))) - { - if (readonly_p (old_var)) - sh_readonly (name); - else if (noassign_p (old_var)) - builtin_error (_("%s: variable may not be assigned value"), name); -#if 0 - /* Let noassign variables through with a warning */ - if (readonly_p (old_var)) -#endif - return ((SHELL_VAR *)NULL); - } - - if (old_var == 0) - new_var = make_new_variable (name, vc->table); - else - { - new_var = make_new_variable (name, vc->table); - - /* If we found this variable in one of the temporary environments, - inherit its value. Watch to see if this causes problems with - things like `x=4 local x'. XXX - see above for temporary env - variables with the same context level as variable_context */ - /* XXX - we should only do this if the variable is not an array. */ - /* If we want to change the local variable semantics to "inherit - the old variable's value" here is where to set it. And we would - need to use copy_variable (currently unused) to do it for all - possible variable values. */ - if (was_tmpvar) - var_setvalue (new_var, savestring (old_value)); - else if (localvar_inherit || (flags & MKLOC_INHERIT)) - { - /* This may not make sense for nameref variables that are shadowing - variables with the same name, but we don't know that yet. */ -#if defined (ARRAY_VARS) - if (assoc_p (old_var)) - var_setassoc (new_var, assoc_copy (assoc_cell (old_var))); - else if (array_p (old_var)) - var_setarray (new_var, array_copy (array_cell (old_var))); - else if (value_cell (old_var)) -#else - if (value_cell (old_var)) -#endif - var_setvalue (new_var, savestring (value_cell (old_var))); - else - var_setvalue (new_var, (char *)NULL); - } - - if (localvar_inherit || (flags & MKLOC_INHERIT)) - { - /* It doesn't make sense to inherit the nameref attribute */ - new_var->attributes = old_var->attributes & ~att_nameref; - new_var->dynamic_value = old_var->dynamic_value; - new_var->assign_func = old_var->assign_func; - } - else - /* We inherit the export attribute, but no others. */ - new_var->attributes = exported_p (old_var) ? att_exported : 0; - } - -set_local_var_flags: - vc->flags |= VC_HASLOCAL; - - new_var->context = variable_context; - VSETATTR (new_var, att_local); - - if (ifsname (name)) - setifs (new_var); - - /* value_cell will be 0 if localvar_inherit == 0 or there was no old variable - with the same name or the old variable was invisible */ - if (was_tmpvar == 0 && value_cell (new_var) == 0) - VSETATTR (new_var, att_invisible); /* XXX */ - return (new_var); -} - -/* Create a new shell variable with name NAME. */ -static SHELL_VAR * -new_shell_variable (name) - const char *name; -{ - SHELL_VAR *entry; - - entry = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR)); - - entry->name = savestring (name); - var_setvalue (entry, (char *)NULL); - CLEAR_EXPORTSTR (entry); - - entry->dynamic_value = (sh_var_value_func_t *)NULL; - entry->assign_func = (sh_var_assign_func_t *)NULL; - - entry->attributes = 0; - - /* Always assume variables are to be made at toplevel! - make_local_variable has the responsibility of changing the - variable context. */ - entry->context = 0; - - return (entry); -} - -/* Create a new shell variable with name NAME and add it to the hash table - TABLE. */ -static SHELL_VAR * -make_new_variable (name, table) - const char *name; - HASH_TABLE *table; -{ - SHELL_VAR *entry; - BUCKET_CONTENTS *elt; - - entry = new_shell_variable (name); - - /* Make sure we have a shell_variables hash table to add to. */ - if (shell_variables == 0) - create_variable_tables (); - - elt = hash_insert (savestring (name), table, HASH_NOSRCH); - elt->data = (PTR_T)entry; - - return entry; -} - -#if defined (ARRAY_VARS) -SHELL_VAR * -make_new_array_variable (name) - char *name; -{ - SHELL_VAR *entry; - ARRAY *array; - - entry = make_new_variable (name, global_variables->table); - array = array_create (); - - var_setarray (entry, array); - VSETATTR (entry, att_array); - return entry; -} - -SHELL_VAR * -make_local_array_variable (name, flags) - char *name; - int flags; -{ - SHELL_VAR *var; - ARRAY *array; - int assoc_ok; - - assoc_ok = flags & MKLOC_ASSOCOK; - - var = make_local_variable (name, flags & MKLOC_INHERIT); /* XXX for now */ - /* If ASSOC_OK is non-zero, assume that we are ok with letting an assoc - variable return to the caller without converting it. The caller will - either flag an error or do the conversion itself. */ - if (var == 0 || array_p (var) || (assoc_ok && assoc_p (var))) - return var; - - /* Validate any value we inherited from a variable instance at a previous - scope and discard anything that's invalid. */ - if (localvar_inherit && assoc_p (var)) - { - internal_warning (_("%s: cannot inherit value from incompatible type"), name); - VUNSETATTR (var, att_assoc); - dispose_variable_value (var); - array = array_create (); - var_setarray (var, array); - } - else if (localvar_inherit) - var = convert_var_to_array (var); /* XXX */ - else - { - dispose_variable_value (var); - array = array_create (); - var_setarray (var, array); - } - - VSETATTR (var, att_array); - return var; -} - -SHELL_VAR * -make_new_assoc_variable (name) - char *name; -{ - SHELL_VAR *entry; - HASH_TABLE *hash; - - entry = make_new_variable (name, global_variables->table); - hash = assoc_create (ASSOC_HASH_BUCKETS); - - var_setassoc (entry, hash); - VSETATTR (entry, att_assoc); - return entry; -} - -SHELL_VAR * -make_local_assoc_variable (name, flags) - char *name; - int flags; -{ - SHELL_VAR *var; - HASH_TABLE *hash; - int array_ok; - - array_ok = flags & MKLOC_ARRAYOK; - - var = make_local_variable (name, flags & MKLOC_INHERIT); /* XXX for now */ - /* If ARRAY_OK is non-zero, assume that we are ok with letting an array - variable return to the caller without converting it. The caller will - either flag an error or do the conversion itself. */ - if (var == 0 || assoc_p (var) || (array_ok && array_p (var))) - return var; - - /* Validate any value we inherited from a variable instance at a previous - scope and discard anything that's invalid. */ - if (localvar_inherit && array_p (var)) - { - internal_warning (_("%s: cannot inherit value from incompatible type"), name); - VUNSETATTR (var, att_array); - dispose_variable_value (var); - hash = assoc_create (ASSOC_HASH_BUCKETS); - var_setassoc (var, hash); - } - else if (localvar_inherit) - var = convert_var_to_assoc (var); /* XXX */ - else - { - dispose_variable_value (var); - hash = assoc_create (ASSOC_HASH_BUCKETS); - var_setassoc (var, hash); - } - - VSETATTR (var, att_assoc); - return var; -} -#endif - -char * -make_variable_value (var, value, flags) - SHELL_VAR *var; - char *value; - int flags; -{ - char *retval, *oval; - intmax_t lval, rval; - int expok, olen, op; - - /* If this variable has had its type set to integer (via `declare -i'), - then do expression evaluation on it and store the result. The - functions in expr.c (evalexp()) and bind_int_variable() are responsible - for turning off the integer flag if they don't want further - evaluation done. Callers that find it inconvenient to do this can set - the ASS_NOEVAL flag. For the special case of arithmetic expression - evaluation, the caller can set ASS_NOLONGJMP to avoid jumping out to - top_level. */ - if ((flags & ASS_NOEVAL) == 0 && integer_p (var)) - { - if (flags & ASS_APPEND) - { - oval = value_cell (var); - lval = evalexp (oval, 0, &expok); /* ksh93 seems to do this */ - if (expok == 0) - { - if (flags & ASS_NOLONGJMP) - goto make_value; - else - { - top_level_cleanup (); - jump_to_top_level (DISCARD); - } - } - } - rval = evalexp (value, 0, &expok); - if (expok == 0) - { - if (flags & ASS_NOLONGJMP) - goto make_value; - else - { - top_level_cleanup (); - jump_to_top_level (DISCARD); - } - } - /* This can be fooled if the variable's value changes while evaluating - `rval'. We can change it if we move the evaluation of lval to here. */ - if (flags & ASS_APPEND) - rval += lval; - retval = itos (rval); - } -#if defined (CASEMOD_ATTRS) - else if ((flags & ASS_NOEVAL) == 0 && (capcase_p (var) || uppercase_p (var) || lowercase_p (var))) - { - if (flags & ASS_APPEND) - { - oval = get_variable_value (var); - if (oval == 0) /* paranoia */ - oval = ""; - olen = STRLEN (oval); - retval = (char *)xmalloc (olen + (value ? STRLEN (value) : 0) + 1); - strcpy (retval, oval); - if (value) - strcpy (retval+olen, value); - } - else if (*value) - retval = savestring (value); - else - { - retval = (char *)xmalloc (1); - retval[0] = '\0'; - } - op = capcase_p (var) ? CASE_CAPITALIZE - : (uppercase_p (var) ? CASE_UPPER : CASE_LOWER); - oval = sh_modcase (retval, (char *)0, op); - free (retval); - retval = oval; - } -#endif /* CASEMOD_ATTRS */ - else if (value) - { -make_value: - if (flags & ASS_APPEND) - { - oval = get_variable_value (var); - if (oval == 0) /* paranoia */ - oval = ""; - olen = STRLEN (oval); - retval = (char *)xmalloc (olen + (value ? STRLEN (value) : 0) + 1); - strcpy (retval, oval); - if (value) - strcpy (retval+olen, value); - } - else if (*value) - retval = savestring (value); - else - { - retval = (char *)xmalloc (1); - retval[0] = '\0'; - } - } - else - retval = (char *)NULL; - - return retval; -} - -/* If we can optimize appending to string variables, say so */ -static int -can_optimize_assignment (entry, value, aflags) - SHELL_VAR *entry; - char *value; - int aflags; -{ - if ((aflags & ASS_APPEND) == 0) - return 0; -#if defined (ARRAY_VARS) - if (array_p (entry) || assoc_p (entry)) - return 0; -#endif - if (integer_p (entry) || uppercase_p (entry) || lowercase_p (entry) || capcase_p (entry)) - return 0; - if (readonly_p (entry) || noassign_p (entry)) - return 0; - return 1; -} - -/* right now we optimize appends to string variables */ -static SHELL_VAR * -optimized_assignment (entry, value, aflags) - SHELL_VAR *entry; - char *value; - int aflags; -{ - size_t len, vlen; - char *v, *new; - - v = value_cell (entry); - len = STRLEN (v); - vlen = STRLEN (value); - - new = (char *)xrealloc (v, len + vlen + 8); /* for now */ - if (vlen == 1) - { - new[len] = *value; - new[len+1] = '\0'; - } - else - strcpy (new + len, value); - var_setvalue (entry, new); - return entry; -} - -/* Bind a variable NAME to VALUE in the HASH_TABLE TABLE, which may be the - temporary environment (but usually is not). HFLAGS controls how NAME - is looked up in TABLE; AFLAGS controls how VALUE is assigned */ -static SHELL_VAR * -bind_variable_internal (name, value, table, hflags, aflags) - const char *name; - char *value; - HASH_TABLE *table; - int hflags, aflags; -{ - char *newval, *tname; - SHELL_VAR *entry, *tentry; - - entry = (hflags & HASH_NOSRCH) ? (SHELL_VAR *)NULL : hash_lookup (name, table); - /* Follow the nameref chain here if this is the global variables table */ - if (entry && nameref_p (entry) && (invisible_p (entry) == 0) && table == global_variables->table) - { - entry = find_global_variable (entry->name); - /* Let's see if we have a nameref referencing a variable that hasn't yet - been created. */ - if (entry == 0) - entry = find_variable_last_nameref (name, 0); /* XXX */ - if (entry == 0) /* just in case */ - return (entry); - } - - /* The first clause handles `declare -n ref; ref=x;' or `declare -n ref; - declare -n ref' */ - if (entry && invisible_p (entry) && nameref_p (entry)) - { - if ((aflags & ASS_FORCE) == 0 && value && valid_nameref_value (value, 0) == 0) - { - sh_invalidid (value); - return ((SHELL_VAR *)NULL); - } - goto assign_value; - } - else if (entry && nameref_p (entry)) - { - newval = nameref_cell (entry); /* XXX - newval can't be NULL here */ - if (valid_nameref_value (newval, 0) == 0) - { - sh_invalidid (newval); - return ((SHELL_VAR *)NULL); - } -#if defined (ARRAY_VARS) - /* declare -n foo=x[2] ; foo=bar */ - if (valid_array_reference (newval, 0)) - { - tname = array_variable_name (newval, 0, (char **)0, (int *)0); - if (tname && (tentry = find_variable_noref (tname)) && nameref_p (tentry)) - { - /* nameref variables can't be arrays */ - internal_warning (_("%s: removing nameref attribute"), name_cell (tentry)); - FREE (value_cell (tentry)); /* XXX - bash-4.3 compat */ - var_setvalue (tentry, (char *)NULL); - VUNSETATTR (tentry, att_nameref); - } - free (tname); - - /* entry == nameref variable; tentry == array variable; - newval == x[2]; value = bar - We don't need to call make_variable_value here, since - assign_array_element will eventually do it itself based on - newval and aflags. */ - - entry = assign_array_element (newval, value, aflags|ASS_NAMEREF, (array_eltstate_t *)0); - if (entry == 0) - return entry; - } - else -#endif - { - entry = make_new_variable (newval, table); - var_setvalue (entry, make_variable_value (entry, value, aflags)); - } - } - else if (entry == 0) - { - entry = make_new_variable (name, table); - var_setvalue (entry, make_variable_value (entry, value, aflags)); /* XXX */ - } - else if (entry->assign_func) /* array vars have assign functions now */ - { - if ((readonly_p (entry) && (aflags & ASS_FORCE) == 0) || noassign_p (entry)) - { - if (readonly_p (entry)) - err_readonly (name_cell (entry)); - return (entry); - } - - INVALIDATE_EXPORTSTR (entry); - newval = (aflags & ASS_APPEND) ? make_variable_value (entry, value, aflags) : value; - if (assoc_p (entry)) - entry = (*(entry->assign_func)) (entry, newval, -1, savestring ("0")); - else if (array_p (entry)) - entry = (*(entry->assign_func)) (entry, newval, 0, 0); - else - entry = (*(entry->assign_func)) (entry, newval, -1, 0); - if (newval != value) - free (newval); - return (entry); - } - else - { -assign_value: - if ((readonly_p (entry) && (aflags & ASS_FORCE) == 0) || noassign_p (entry)) - { - if (readonly_p (entry)) - err_readonly (name_cell (entry)); - return (entry); - } - - /* Variables which are bound are visible. */ - VUNSETATTR (entry, att_invisible); - - /* If we can optimize the assignment, do so and return. Right now, we - optimize appends to string variables. */ - if (can_optimize_assignment (entry, value, aflags)) - { - INVALIDATE_EXPORTSTR (entry); - optimized_assignment (entry, value, aflags); - - if (mark_modified_vars) - VSETATTR (entry, att_exported); - - if (exported_p (entry)) - array_needs_making = 1; - - return (entry); - } - -#if defined (ARRAY_VARS) - if (assoc_p (entry) || array_p (entry)) - newval = make_array_variable_value (entry, 0, "0", value, aflags); - else -#endif - newval = make_variable_value (entry, value, aflags); /* XXX */ - - /* Invalidate any cached export string */ - INVALIDATE_EXPORTSTR (entry); - -#if defined (ARRAY_VARS) - /* XXX -- this bears looking at again -- XXX */ - /* If an existing array variable x is being assigned to with x=b or - `read x' or something of that nature, silently convert it to - x[0]=b or `read x[0]'. */ - if (assoc_p (entry)) - { - assoc_insert (assoc_cell (entry), savestring ("0"), newval); - free (newval); - } - else if (array_p (entry)) - { - array_insert (array_cell (entry), 0, newval); - free (newval); - } - else -#endif - { - FREE (value_cell (entry)); - var_setvalue (entry, newval); - } - } - - if (mark_modified_vars) - VSETATTR (entry, att_exported); - - if (exported_p (entry)) - array_needs_making = 1; - - return (entry); -} - -/* Bind a variable NAME to VALUE. This conses up the name - and value strings. If we have a temporary environment, we bind there - first, then we bind into shell_variables. */ - -SHELL_VAR * -bind_variable (name, value, flags) - const char *name; - char *value; - int flags; -{ - SHELL_VAR *v, *nv; - VAR_CONTEXT *vc, *nvc; - - if (shell_variables == 0) - create_variable_tables (); - - /* If we have a temporary environment, look there first for the variable, - and, if found, modify the value there before modifying it in the - shell_variables table. This allows sourced scripts to modify values - given to them in a temporary environment while modifying the variable - value that the caller sees. */ - if (temporary_env && value) /* XXX - can value be null here? */ - bind_tempenv_variable (name, value); - - /* XXX -- handle local variables here. */ - for (vc = shell_variables; vc; vc = vc->down) - { - if (vc_isfuncenv (vc) || vc_isbltnenv (vc)) - { - v = hash_lookup (name, vc->table); - nvc = vc; - if (v && nameref_p (v)) - { - /* This starts at the context where we found the nameref. If we - want to start the name resolution over again at the original - context, this is where we need to change it */ - nv = find_variable_nameref_context (v, vc, &nvc); - if (nv == 0) - { - nv = find_variable_last_nameref_context (v, vc, &nvc); - if (nv && nameref_p (nv)) - { - /* If this nameref variable doesn't have a value yet, - set the value. Otherwise, assign using the value as - normal. */ - if (nameref_cell (nv) == 0) - return (bind_variable_internal (nv->name, value, nvc->table, 0, flags)); -#if defined (ARRAY_VARS) - else if (valid_array_reference (nameref_cell (nv), 0)) - return (assign_array_element (nameref_cell (nv), value, flags, (array_eltstate_t *)0)); - else -#endif - return (bind_variable_internal (nameref_cell (nv), value, nvc->table, 0, flags)); - } - else if (nv == &nameref_maxloop_value) - { - internal_warning (_("%s: circular name reference"), v->name); - return (bind_global_variable (v->name, value, flags)); - } - else - v = nv; - } - else if (nv == &nameref_maxloop_value) - { - internal_warning (_("%s: circular name reference"), v->name); - return (bind_global_variable (v->name, value, flags)); - } - else - v = nv; - } - if (v) - return (bind_variable_internal (v->name, value, nvc->table, 0, flags)); - } - } - /* bind_variable_internal will handle nameref resolution in this case */ - return (bind_variable_internal (name, value, global_variables->table, 0, flags)); -} - -SHELL_VAR * -bind_global_variable (name, value, flags) - const char *name; - char *value; - int flags; -{ - if (shell_variables == 0) - create_variable_tables (); - - /* bind_variable_internal will handle nameref resolution in this case */ - return (bind_variable_internal (name, value, global_variables->table, 0, flags)); -} - -static SHELL_VAR * -bind_invalid_envvar (name, value, flags) - const char *name; - char *value; - int flags; -{ - if (invalid_env == 0) - invalid_env = hash_create (64); /* XXX */ - return (bind_variable_internal (name, value, invalid_env, HASH_NOSRCH, flags)); -} - -/* Make VAR, a simple shell variable, have value VALUE. Once assigned a - value, variables are no longer invisible. This is a duplicate of part - of the internals of bind_variable. If the variable is exported, or - all modified variables should be exported, mark the variable for export - and note that the export environment needs to be recreated. */ -SHELL_VAR * -bind_variable_value (var, value, aflags) - SHELL_VAR *var; - char *value; - int aflags; -{ - char *t; - int invis; - - invis = invisible_p (var); - VUNSETATTR (var, att_invisible); - - if (var->assign_func) - { - /* If we're appending, we need the old value, so use - make_variable_value */ - t = (aflags & ASS_APPEND) ? make_variable_value (var, value, aflags) : value; - (*(var->assign_func)) (var, t, -1, 0); - if (t != value && t) - free (t); - } - else - { - t = make_variable_value (var, value, aflags); - if ((aflags & (ASS_NAMEREF|ASS_FORCE)) == ASS_NAMEREF && check_selfref (name_cell (var), t, 0)) - { - if (variable_context) - internal_warning (_("%s: circular name reference"), name_cell (var)); - else - { - internal_error (_("%s: nameref variable self references not allowed"), name_cell (var)); - free (t); - if (invis) - VSETATTR (var, att_invisible); /* XXX */ - return ((SHELL_VAR *)NULL); - } - } - if ((aflags & ASS_NAMEREF) && (valid_nameref_value (t, 0) == 0)) - { - free (t); - if (invis) - VSETATTR (var, att_invisible); /* XXX */ - return ((SHELL_VAR *)NULL); - } - FREE (value_cell (var)); - var_setvalue (var, t); - } - - INVALIDATE_EXPORTSTR (var); - - if (mark_modified_vars) - VSETATTR (var, att_exported); - - if (exported_p (var)) - array_needs_making = 1; - - return (var); -} - -/* Bind/create a shell variable with the name LHS to the RHS. - This creates or modifies a variable such that it is an integer. - - This used to be in expr.c, but it is here so that all of the - variable binding stuff is localized. Since we don't want any - recursive evaluation from bind_variable() (possible without this code, - since bind_variable() calls the evaluator for variables with the integer - attribute set), we temporarily turn off the integer attribute for each - variable we set here, then turn it back on after binding as necessary. */ - -SHELL_VAR * -bind_int_variable (lhs, rhs, flags) - char *lhs, *rhs; - int flags; -{ - register SHELL_VAR *v; - int isint, isarr, implicitarray, vflags, avflags; - - isint = isarr = implicitarray = 0; -#if defined (ARRAY_VARS) - /* Don't rely on VA_NOEXPAND being 1, set it explicitly */ - vflags = (flags & ASS_NOEXPAND) ? VA_NOEXPAND : 0; - if (flags & ASS_ONEWORD) - vflags |= VA_ONEWORD; - if (valid_array_reference (lhs, vflags)) - { - isarr = 1; - avflags = 0; - /* Common code to translate between assignment and reference flags. */ - if (flags & ASS_NOEXPAND) - avflags |= AV_NOEXPAND; - if (flags & ASS_ONEWORD) - avflags |= AV_ONEWORD; - v = array_variable_part (lhs, avflags, (char **)0, (int *)0); - } - else if (legal_identifier (lhs) == 0) - { - sh_invalidid (lhs); - return ((SHELL_VAR *)NULL); - } - else -#endif - v = find_variable (lhs); - - if (v) - { - isint = integer_p (v); - VUNSETATTR (v, att_integer); -#if defined (ARRAY_VARS) - if (array_p (v) && isarr == 0) - implicitarray = 1; -#endif - } - -#if defined (ARRAY_VARS) - if (isarr) - v = assign_array_element (lhs, rhs, flags, (array_eltstate_t *)0); - else if (implicitarray) - v = bind_array_variable (lhs, 0, rhs, 0); /* XXX - check on flags */ - else -#endif - v = bind_variable (lhs, rhs, 0); /* why not use bind_variable_value? */ - - if (v) - { - if (isint) - VSETATTR (v, att_integer); - VUNSETATTR (v, att_invisible); - } - - if (v && nameref_p (v)) - internal_warning (_("%s: assigning integer to name reference"), lhs); - - return (v); -} - -SHELL_VAR * -bind_var_to_int (var, val, flags) - char *var; - intmax_t val; - int flags; -{ - char ibuf[INT_STRLEN_BOUND (intmax_t) + 1], *p; - - p = fmtulong (val, 10, ibuf, sizeof (ibuf), 0); - return (bind_int_variable (var, p, flags)); -} - -/* Do a function binding to a variable. You pass the name and - the command to bind to. This conses the name and command. */ -SHELL_VAR * -bind_function (name, value) - const char *name; - COMMAND *value; -{ - SHELL_VAR *entry; - - entry = find_function (name); - if (entry == 0) - { - BUCKET_CONTENTS *elt; - - elt = hash_insert (savestring (name), shell_functions, HASH_NOSRCH); - entry = new_shell_variable (name); - elt->data = (PTR_T)entry; - } - else - INVALIDATE_EXPORTSTR (entry); - - if (var_isset (entry)) - dispose_command (function_cell (entry)); - - if (value) - var_setfunc (entry, copy_command (value)); - else - var_setfunc (entry, 0); - - VSETATTR (entry, att_function); - - if (mark_modified_vars) - VSETATTR (entry, att_exported); - - VUNSETATTR (entry, att_invisible); /* Just to be sure */ - - if (exported_p (entry)) - array_needs_making = 1; - -#if defined (PROGRAMMABLE_COMPLETION) - set_itemlist_dirty (&it_functions); -#endif - - return (entry); -} - -#if defined (DEBUGGER) -/* Bind a function definition, which includes source file and line number - information in addition to the command, into the FUNCTION_DEF hash table. - If (FLAGS & 1), overwrite any existing definition. If FLAGS == 0, leave - any existing definition alone. */ -void -bind_function_def (name, value, flags) - const char *name; - FUNCTION_DEF *value; - int flags; -{ - FUNCTION_DEF *entry; - BUCKET_CONTENTS *elt; - COMMAND *cmd; - - entry = find_function_def (name); - if (entry && (flags & 1)) - { - dispose_function_def_contents (entry); - entry = copy_function_def_contents (value, entry); - } - else if (entry) - return; - else - { - cmd = value->command; - value->command = 0; - entry = copy_function_def (value); - value->command = cmd; - - elt = hash_insert (savestring (name), shell_function_defs, HASH_NOSRCH); - elt->data = (PTR_T *)entry; - } -} -#endif /* DEBUGGER */ - -/* Add STRING, which is of the form foo=bar, to the temporary environment - HASH_TABLE (temporary_env). The functions in execute_cmd.c are - responsible for moving the main temporary env to one of the other - temporary environments. The expansion code in subst.c calls this. */ -int -assign_in_env (word, flags) - WORD_DESC *word; - int flags; -{ - int offset, aflags; - char *name, *temp, *value, *newname; - SHELL_VAR *var; - const char *string; - - string = word->word; - - aflags = 0; - offset = assignment (string, 0); - newname = name = savestring (string); - value = (char *)NULL; - - if (name[offset] == '=') - { - name[offset] = 0; - - /* don't ignore the `+' when assigning temporary environment */ - if (name[offset - 1] == '+') - { - name[offset - 1] = '\0'; - aflags |= ASS_APPEND; - } - - if (legal_identifier (name) == 0) - { - sh_invalidid (name); - free (name); - return (0); - } - - var = find_variable (name); - if (var == 0) - { - var = find_variable_last_nameref (name, 1); - /* If we're assigning a value to a nameref variable in the temp - environment, and the value of the nameref is valid for assignment, - but the variable does not already exist, assign to the nameref - target and add the target to the temporary environment. This is - what ksh93 does */ - /* We use 2 in the call to valid_nameref_value because we don't want - to allow array references here at all (newname will be used to - create a variable directly below) */ - if (var && nameref_p (var) && valid_nameref_value (nameref_cell (var), 2)) - { - newname = nameref_cell (var); - var = 0; /* don't use it for append */ - } - } - else - newname = name_cell (var); /* no-op if not nameref */ - - if (var && (readonly_p (var) || noassign_p (var))) - { - if (readonly_p (var)) - err_readonly (name); - free (name); - return (0); - } - temp = name + offset + 1; - - value = expand_assignment_string_to_string (temp, 0); - - if (var && (aflags & ASS_APPEND)) - { - if (value == 0) - { - value = (char *)xmalloc (1); /* like do_assignment_internal */ - value[0] = '\0'; - } - temp = make_variable_value (var, value, aflags); - FREE (value); - value = temp; - } - } - - if (temporary_env == 0) - temporary_env = hash_create (TEMPENV_HASH_BUCKETS); - - var = hash_lookup (newname, temporary_env); - if (var == 0) - var = make_new_variable (newname, temporary_env); - else - FREE (value_cell (var)); - - if (value == 0) - { - value = (char *)xmalloc (1); /* see above */ - value[0] = '\0'; - } - - var_setvalue (var, value); - var->attributes |= (att_exported|att_tempvar); - var->context = variable_context; /* XXX */ - - INVALIDATE_EXPORTSTR (var); - var->exportstr = mk_env_string (newname, value, 0); - - array_needs_making = 1; - - if (flags) - { - if (STREQ (newname, "POSIXLY_CORRECT") || STREQ (newname, "POSIX_PEDANDTIC")) - save_posix_options (); /* XXX one level of saving right now */ - stupidly_hack_special_variables (newname); - } - - if (echo_command_at_execute) - /* The Korn shell prints the `+ ' in front of assignment statements, - so we do too. */ - xtrace_print_assignment (name, value, 0, 1); - - free (name); - return 1; -} - -/* **************************************************************** */ -/* */ -/* Copying variables */ -/* */ -/* **************************************************************** */ - -#ifdef INCLUDE_UNUSED -/* Copy VAR to a new data structure and return that structure. */ -SHELL_VAR * -copy_variable (var) - SHELL_VAR *var; -{ - SHELL_VAR *copy = (SHELL_VAR *)NULL; - - if (var) - { - copy = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR)); - - copy->attributes = var->attributes; - copy->name = savestring (var->name); - - if (function_p (var)) - var_setfunc (copy, copy_command (function_cell (var))); -#if defined (ARRAY_VARS) - else if (array_p (var)) - var_setarray (copy, array_copy (array_cell (var))); - else if (assoc_p (var)) - var_setassoc (copy, assoc_copy (assoc_cell (var))); -#endif - else if (nameref_cell (var)) /* XXX - nameref */ - var_setref (copy, savestring (nameref_cell (var))); - else if (value_cell (var)) /* XXX - nameref */ - var_setvalue (copy, savestring (value_cell (var))); - else - var_setvalue (copy, (char *)NULL); - - copy->dynamic_value = var->dynamic_value; - copy->assign_func = var->assign_func; - - copy->exportstr = COPY_EXPORTSTR (var); - - copy->context = var->context; - } - return (copy); -} -#endif - -/* **************************************************************** */ -/* */ -/* Deleting and unsetting variables */ -/* */ -/* **************************************************************** */ - -/* Dispose of the information attached to VAR. */ -static void -dispose_variable_value (var) - SHELL_VAR *var; -{ - if (function_p (var)) - dispose_command (function_cell (var)); -#if defined (ARRAY_VARS) - else if (array_p (var)) - array_dispose (array_cell (var)); - else if (assoc_p (var)) - assoc_dispose (assoc_cell (var)); -#endif - else if (nameref_p (var)) - FREE (nameref_cell (var)); - else - FREE (value_cell (var)); -} - -void -dispose_variable (var) - SHELL_VAR *var; -{ - if (var == 0) - return; - - if (nofree_p (var) == 0) - dispose_variable_value (var); - - FREE_EXPORTSTR (var); - - free (var->name); - - if (exported_p (var)) - array_needs_making = 1; - - free (var); -} - -/* Unset the shell variable referenced by NAME. Unsetting a nameref variable - unsets the variable it resolves to but leaves the nameref alone. */ -int -unbind_variable (name) - const char *name; -{ - SHELL_VAR *v, *nv; - int r; - - v = var_lookup (name, shell_variables); - nv = (v && nameref_p (v)) ? find_variable_nameref (v) : (SHELL_VAR *)NULL; - - r = nv ? makunbound (nv->name, shell_variables) : makunbound (name, shell_variables); - return r; -} - -/* Unbind NAME, where NAME is assumed to be a nameref variable */ -int -unbind_nameref (name) - const char *name; -{ - SHELL_VAR *v; - - v = var_lookup (name, shell_variables); - if (v && nameref_p (v)) - return makunbound (name, shell_variables); - return 0; -} - -/* Unbind the first instance of NAME, whether it's a nameref or not */ -int -unbind_variable_noref (name) - const char *name; -{ - SHELL_VAR *v; - - v = var_lookup (name, shell_variables); - if (v) - return makunbound (name, shell_variables); - return 0; -} - -int -unbind_global_variable (name) - const char *name; -{ - SHELL_VAR *v, *nv; - int r; - - v = var_lookup (name, global_variables); - /* This starts at the current scope, just like find_global_variable; should we - use find_global_variable_nameref here? */ - nv = (v && nameref_p (v)) ? find_variable_nameref (v) : (SHELL_VAR *)NULL; - - r = nv ? makunbound (nv->name, shell_variables) : makunbound (name, global_variables); - return r; -} - -int -unbind_global_variable_noref (name) - const char *name; -{ - SHELL_VAR *v; - - v = var_lookup (name, global_variables); - if (v) - return makunbound (name, global_variables); - return 0; -} - -int -check_unbind_variable (name) - const char *name; -{ - SHELL_VAR *v; - - v = find_variable (name); - if (v && readonly_p (v)) - { - internal_error (_("%s: cannot unset: readonly %s"), name, "variable"); - return -2; - } - else if (v && non_unsettable_p (v)) - { - internal_error (_("%s: cannot unset"), name); - return -2; - } - return (unbind_variable (name)); -} - -/* Unset the shell function named NAME. */ -int -unbind_func (name) - const char *name; -{ - BUCKET_CONTENTS *elt; - SHELL_VAR *func; - - elt = hash_remove (name, shell_functions, 0); - - if (elt == 0) - return -1; - -#if defined (PROGRAMMABLE_COMPLETION) - set_itemlist_dirty (&it_functions); -#endif - - func = (SHELL_VAR *)elt->data; - if (func) - { - if (exported_p (func)) - array_needs_making++; - dispose_variable (func); - } - - free (elt->key); - free (elt); - - return 0; -} - -#if defined (DEBUGGER) -int -unbind_function_def (name) - const char *name; -{ - BUCKET_CONTENTS *elt; - FUNCTION_DEF *funcdef; - - elt = hash_remove (name, shell_function_defs, 0); - - if (elt == 0) - return -1; - - funcdef = (FUNCTION_DEF *)elt->data; - if (funcdef) - dispose_function_def (funcdef); - - free (elt->key); - free (elt); - - return 0; -} -#endif /* DEBUGGER */ - -int -delete_var (name, vc) - const char *name; - VAR_CONTEXT *vc; -{ - BUCKET_CONTENTS *elt; - SHELL_VAR *old_var; - VAR_CONTEXT *v; - - for (elt = (BUCKET_CONTENTS *)NULL, v = vc; v; v = v->down) - if (elt = hash_remove (name, v->table, 0)) - break; - - if (elt == 0) - return (-1); - - old_var = (SHELL_VAR *)elt->data; - free (elt->key); - free (elt); - - dispose_variable (old_var); - return (0); -} - -/* Make the variable associated with NAME go away. HASH_LIST is the - hash table from which this variable should be deleted (either - shell_variables or shell_functions). - Returns non-zero if the variable couldn't be found. */ -int -makunbound (name, vc) - const char *name; - VAR_CONTEXT *vc; -{ - BUCKET_CONTENTS *elt, *new_elt; - SHELL_VAR *old_var; - VAR_CONTEXT *v; - char *t; - - for (elt = (BUCKET_CONTENTS *)NULL, v = vc; v; v = v->down) - if (elt = hash_remove (name, v->table, 0)) - break; - - if (elt == 0) - return (-1); - - old_var = (SHELL_VAR *)elt->data; - - if (old_var && exported_p (old_var)) - array_needs_making++; - - /* If we're unsetting a local variable and we're still executing inside - the function, just mark the variable as invisible. The function - eventually called by pop_var_context() will clean it up later. This - must be done so that if the variable is subsequently assigned a new - value inside the function, the `local' attribute is still present. - We also need to add it back into the correct hash table. */ - if (old_var && local_p (old_var) && - (old_var->context == variable_context || (localvar_unset && old_var->context < variable_context))) - { - if (nofree_p (old_var)) - var_setvalue (old_var, (char *)NULL); -#if defined (ARRAY_VARS) - else if (array_p (old_var)) - array_dispose (array_cell (old_var)); - else if (assoc_p (old_var)) - assoc_dispose (assoc_cell (old_var)); -#endif - else if (nameref_p (old_var)) - FREE (nameref_cell (old_var)); - else - FREE (value_cell (old_var)); - /* Reset the attributes. Preserve the export attribute if the variable - came from a temporary environment. Make sure it stays local, and - make it invisible. */ - old_var->attributes = (exported_p (old_var) && tempvar_p (old_var)) ? att_exported : 0; - VSETATTR (old_var, att_local); - VSETATTR (old_var, att_invisible); - var_setvalue (old_var, (char *)NULL); - INVALIDATE_EXPORTSTR (old_var); - - new_elt = hash_insert (savestring (old_var->name), v->table, 0); - new_elt->data = (PTR_T)old_var; - stupidly_hack_special_variables (old_var->name); - - free (elt->key); - free (elt); - return (0); - } - - /* Have to save a copy of name here, because it might refer to - old_var->name. If so, stupidly_hack_special_variables will - reference freed memory. */ - t = savestring (name); - - free (elt->key); - free (elt); - - dispose_variable (old_var); - stupidly_hack_special_variables (t); - free (t); - - return (0); -} - -/* Get rid of all of the variables in the current context. */ -void -kill_all_local_variables () -{ - VAR_CONTEXT *vc; - - for (vc = shell_variables; vc; vc = vc->down) - if (vc_isfuncenv (vc) && vc->scope == variable_context) - break; - if (vc == 0) - return; /* XXX */ - - if (vc->table && vc_haslocals (vc)) - { - delete_all_variables (vc->table); - hash_dispose (vc->table); - } - vc->table = (HASH_TABLE *)NULL; -} - -static void -free_variable_hash_data (data) - PTR_T data; -{ - SHELL_VAR *var; - - var = (SHELL_VAR *)data; - dispose_variable (var); -} - -/* Delete the entire contents of the hash table. */ -void -delete_all_variables (hashed_vars) - HASH_TABLE *hashed_vars; -{ - hash_flush (hashed_vars, free_variable_hash_data); -} - -/* **************************************************************** */ -/* */ -/* Setting variable attributes */ -/* */ -/* **************************************************************** */ - -#define FIND_OR_MAKE_VARIABLE(name, entry) \ - do \ - { \ - entry = find_variable (name); \ - if (!entry) \ - { \ - entry = bind_variable (name, "", 0); \ - if (entry) entry->attributes |= att_invisible; \ - } \ - } \ - while (0) - -/* Make the variable associated with NAME be readonly. - If NAME does not exist yet, create it. */ -void -set_var_read_only (name) - char *name; -{ - SHELL_VAR *entry; - - FIND_OR_MAKE_VARIABLE (name, entry); - VSETATTR (entry, att_readonly); -} - -#ifdef INCLUDE_UNUSED -/* Make the function associated with NAME be readonly. - If NAME does not exist, we just punt, like auto_export code below. */ -void -set_func_read_only (name) - const char *name; -{ - SHELL_VAR *entry; - - entry = find_function (name); - if (entry) - VSETATTR (entry, att_readonly); -} - -/* Make the variable associated with NAME be auto-exported. - If NAME does not exist yet, create it. */ -void -set_var_auto_export (name) - char *name; -{ - SHELL_VAR *entry; - - FIND_OR_MAKE_VARIABLE (name, entry); - set_auto_export (entry); -} - -/* Make the function associated with NAME be auto-exported. */ -void -set_func_auto_export (name) - const char *name; -{ - SHELL_VAR *entry; - - entry = find_function (name); - if (entry) - set_auto_export (entry); -} -#endif - -/* **************************************************************** */ -/* */ -/* Creating lists of variables */ -/* */ -/* **************************************************************** */ - -static VARLIST * -vlist_alloc (nentries) - int nentries; -{ - VARLIST *vlist; - - vlist = (VARLIST *)xmalloc (sizeof (VARLIST)); - vlist->list = (SHELL_VAR **)xmalloc ((nentries + 1) * sizeof (SHELL_VAR *)); - vlist->list_size = nentries; - vlist->list_len = 0; - vlist->list[0] = (SHELL_VAR *)NULL; - - return vlist; -} - -static VARLIST * -vlist_realloc (vlist, n) - VARLIST *vlist; - int n; -{ - if (vlist == 0) - return (vlist = vlist_alloc (n)); - if (n > vlist->list_size) - { - vlist->list_size = n; - vlist->list = (SHELL_VAR **)xrealloc (vlist->list, (vlist->list_size + 1) * sizeof (SHELL_VAR *)); - } - return vlist; -} - -static void -vlist_add (vlist, var, flags) - VARLIST *vlist; - SHELL_VAR *var; - int flags; -{ - register int i; - - for (i = 0; i < vlist->list_len; i++) - if (STREQ (var->name, vlist->list[i]->name)) - break; - if (i < vlist->list_len) - return; - - if (i >= vlist->list_size) - vlist = vlist_realloc (vlist, vlist->list_size + 16); - - vlist->list[vlist->list_len++] = var; - vlist->list[vlist->list_len] = (SHELL_VAR *)NULL; -} - -/* Map FUNCTION over the variables in VAR_HASH_TABLE. Return an array of the - variables for which FUNCTION returns a non-zero value. A NULL value - for FUNCTION means to use all variables. */ -SHELL_VAR ** -map_over (function, vc) - sh_var_map_func_t *function; - VAR_CONTEXT *vc; -{ - VAR_CONTEXT *v; - VARLIST *vlist; - SHELL_VAR **ret; - int nentries; - - for (nentries = 0, v = vc; v; v = v->down) - nentries += HASH_ENTRIES (v->table); - - if (nentries == 0) - return (SHELL_VAR **)NULL; - - vlist = vlist_alloc (nentries); - - for (v = vc; v; v = v->down) - flatten (v->table, function, vlist, 0); - - ret = vlist->list; - free (vlist); - return ret; -} - -SHELL_VAR ** -map_over_funcs (function) - sh_var_map_func_t *function; -{ - VARLIST *vlist; - SHELL_VAR **ret; - - if (shell_functions == 0 || HASH_ENTRIES (shell_functions) == 0) - return ((SHELL_VAR **)NULL); - - vlist = vlist_alloc (HASH_ENTRIES (shell_functions)); - - flatten (shell_functions, function, vlist, 0); - - ret = vlist->list; - free (vlist); - return ret; -} - -/* Flatten VAR_HASH_TABLE, applying FUNC to each member and adding those - elements for which FUNC succeeds to VLIST->list. FLAGS is reserved - for future use. Only unique names are added to VLIST. If FUNC is - NULL, each variable in VAR_HASH_TABLE is added to VLIST. If VLIST is - NULL, FUNC is applied to each SHELL_VAR in VAR_HASH_TABLE. If VLIST - and FUNC are both NULL, nothing happens. */ -static void -flatten (var_hash_table, func, vlist, flags) - HASH_TABLE *var_hash_table; - sh_var_map_func_t *func; - VARLIST *vlist; - int flags; -{ - register int i; - register BUCKET_CONTENTS *tlist; - int r; - SHELL_VAR *var; - - if (var_hash_table == 0 || (HASH_ENTRIES (var_hash_table) == 0) || (vlist == 0 && func == 0)) - return; - - for (i = 0; i < var_hash_table->nbuckets; i++) - { - for (tlist = hash_items (i, var_hash_table); tlist; tlist = tlist->next) - { - var = (SHELL_VAR *)tlist->data; - - r = func ? (*func) (var) : 1; - if (r && vlist) - vlist_add (vlist, var, flags); - } - } -} - -void -sort_variables (array) - SHELL_VAR **array; -{ - qsort (array, strvec_len ((char **)array), sizeof (SHELL_VAR *), (QSFUNC *)qsort_var_comp); -} - -static int -qsort_var_comp (var1, var2) - SHELL_VAR **var1, **var2; -{ - int result; - - if ((result = (*var1)->name[0] - (*var2)->name[0]) == 0) - result = strcmp ((*var1)->name, (*var2)->name); - - return (result); -} - -/* Apply FUNC to each variable in SHELL_VARIABLES, adding each one for - which FUNC succeeds to an array of SHELL_VAR *s. Returns the array. */ -static SHELL_VAR ** -vapply (func) - sh_var_map_func_t *func; -{ - SHELL_VAR **list; - - list = map_over (func, shell_variables); - if (list /* && posixly_correct */) - sort_variables (list); - return (list); -} - -/* Apply FUNC to each variable in SHELL_FUNCTIONS, adding each one for - which FUNC succeeds to an array of SHELL_VAR *s. Returns the array. */ -static SHELL_VAR ** -fapply (func) - sh_var_map_func_t *func; -{ - SHELL_VAR **list; - - list = map_over_funcs (func); - if (list /* && posixly_correct */) - sort_variables (list); - return (list); -} - -/* Create a NULL terminated array of all the shell variables. */ -SHELL_VAR ** -all_shell_variables () -{ - return (vapply ((sh_var_map_func_t *)NULL)); -} - -/* Create a NULL terminated array of all the shell functions. */ -SHELL_VAR ** -all_shell_functions () -{ - return (fapply ((sh_var_map_func_t *)NULL)); -} - -static int -visible_var (var) - SHELL_VAR *var; -{ - return (invisible_p (var) == 0); -} - -SHELL_VAR ** -all_visible_functions () -{ - return (fapply (visible_var)); -} - -SHELL_VAR ** -all_visible_variables () -{ - return (vapply (visible_var)); -} - -/* Return non-zero if the variable VAR is visible and exported. Array - variables cannot be exported. */ -static int -visible_and_exported (var) - SHELL_VAR *var; -{ - return (invisible_p (var) == 0 && exported_p (var)); -} - -/* Candidate variables for the export environment are either valid variables - with the export attribute or invalid variables inherited from the initial - environment and simply passed through. */ -static int -export_environment_candidate (var) - SHELL_VAR *var; -{ - return (exported_p (var) && (invisible_p (var) == 0 || imported_p (var))); -} - -/* Return non-zero if VAR is a local variable in the current context and - is exported. */ -static int -local_and_exported (var) - SHELL_VAR *var; -{ - return (invisible_p (var) == 0 && local_p (var) && var->context == variable_context && exported_p (var)); -} - -SHELL_VAR ** -all_exported_variables () -{ - return (vapply (visible_and_exported)); -} - -SHELL_VAR ** -local_exported_variables () -{ - return (vapply (local_and_exported)); -} - -static int -variable_in_context (var) - SHELL_VAR *var; -{ - return (local_p (var) && var->context == variable_context); -} - -static int -visible_variable_in_context (var) - SHELL_VAR *var; -{ - return (invisible_p (var) == 0 && local_p (var) && var->context == variable_context); -} - -SHELL_VAR ** -all_local_variables (visible_only) - int visible_only; -{ - VARLIST *vlist; - SHELL_VAR **ret; - VAR_CONTEXT *vc; - - vc = shell_variables; - for (vc = shell_variables; vc; vc = vc->down) - if (vc_isfuncenv (vc) && vc->scope == variable_context) - break; - - if (vc == 0) - { - internal_error (_("all_local_variables: no function context at current scope")); - return (SHELL_VAR **)NULL; - } - if (vc->table == 0 || HASH_ENTRIES (vc->table) == 0 || vc_haslocals (vc) == 0) - return (SHELL_VAR **)NULL; - - vlist = vlist_alloc (HASH_ENTRIES (vc->table)); - - if (visible_only) - flatten (vc->table, visible_variable_in_context, vlist, 0); - else - flatten (vc->table, variable_in_context, vlist, 0); - - ret = vlist->list; - free (vlist); - if (ret) - sort_variables (ret); - return ret; -} - -#if defined (ARRAY_VARS) -/* Return non-zero if the variable VAR is visible and an array. */ -static int -visible_array_vars (var) - SHELL_VAR *var; -{ - return (invisible_p (var) == 0 && (array_p (var) || assoc_p (var))); -} - -SHELL_VAR ** -all_array_variables () -{ - return (vapply (visible_array_vars)); -} -#endif /* ARRAY_VARS */ - -char ** -all_variables_matching_prefix (prefix) - const char *prefix; -{ - SHELL_VAR **varlist; - char **rlist; - int vind, rind, plen; - - plen = STRLEN (prefix); - varlist = all_visible_variables (); - for (vind = 0; varlist && varlist[vind]; vind++) - ; - if (varlist == 0 || vind == 0) - return ((char **)NULL); - rlist = strvec_create (vind + 1); - for (vind = rind = 0; varlist[vind]; vind++) - { - if (plen == 0 || STREQN (prefix, varlist[vind]->name, plen)) - rlist[rind++] = savestring (varlist[vind]->name); - } - rlist[rind] = (char *)0; - free (varlist); - - return rlist; -} - -/* **************************************************************** */ -/* */ -/* Managing temporary variable scopes */ -/* */ -/* **************************************************************** */ - -/* Make variable NAME have VALUE in the temporary environment. */ -static SHELL_VAR * -bind_tempenv_variable (name, value) - const char *name; - char *value; -{ - SHELL_VAR *var; - - var = temporary_env ? hash_lookup (name, temporary_env) : (SHELL_VAR *)NULL; - - if (var) - { - FREE (value_cell (var)); - var_setvalue (var, savestring (value)); - INVALIDATE_EXPORTSTR (var); - } - - return (var); -} - -/* Find a variable in the temporary environment that is named NAME. - Return the SHELL_VAR *, or NULL if not found. */ -SHELL_VAR * -find_tempenv_variable (name) - const char *name; -{ - return (temporary_env ? hash_lookup (name, temporary_env) : (SHELL_VAR *)NULL); -} - -char **tempvar_list; -int tvlist_ind; - -/* Take a variable from an assignment statement preceding a posix special - builtin (including `return') and create a global variable from it. This - is called from merge_temporary_env, which is only called when in posix - mode. */ -static void -push_posix_temp_var (data) - PTR_T data; -{ - SHELL_VAR *var, *v; - HASH_TABLE *binding_table; - - var = (SHELL_VAR *)data; - - /* Just like do_assignment_internal(). This makes assignments preceding - special builtins act like standalone assignment statements when in - posix mode, satisfying the posix requirement that this affect the - "current execution environment." */ - v = bind_variable (var->name, value_cell (var), ASS_FORCE|ASS_NOLONGJMP); - - /* XXX - do we need to worry about array variables here? */ - - /* If this modifies an existing local variable, v->context will be non-zero. - If it comes back with v->context == 0, we bound at the global context. - Set binding_table appropriately. It doesn't matter whether it's correct - if the variable is local, only that it's not global_variables->table */ - binding_table = v->context ? shell_variables->table : global_variables->table; - - /* global variables are no longer temporary and don't need propagating. */ - if (v->context == 0) - var->attributes &= ~(att_tempvar|att_propagate); - - if (v) - { - v->attributes |= var->attributes; /* preserve tempvar attribute if appropriate */ - /* If we don't bind a local variable, propagate the value. If we bind a - local variable (the "current execution environment"), keep it as local - and don't propagate it to the calling environment. */ - if (v->context > 0 && local_p (v) == 0) - v->attributes |= att_propagate; - else - v->attributes &= ~att_propagate; - } - - if (find_special_var (var->name) >= 0) - tempvar_list[tvlist_ind++] = savestring (var->name); - - dispose_variable (var); -} - -/* Push the variable described by (SHELL_VAR *)DATA down to the next - variable context from the temporary environment. This can be called - from one context: - 1. propagate_temp_var: which is called to propagate variables in - assignments like `var=value declare -x var' to the surrounding - scope. - - In this case, the variable should have the att_propagate flag set and - we can create variables in the current scope. -*/ -static void -push_temp_var (data) - PTR_T data; -{ - SHELL_VAR *var, *v; - HASH_TABLE *binding_table; - - var = (SHELL_VAR *)data; - - binding_table = shell_variables->table; - if (binding_table == 0) - { - if (shell_variables == global_variables) - /* shouldn't happen */ - binding_table = shell_variables->table = global_variables->table = hash_create (VARIABLES_HASH_BUCKETS); - else - binding_table = shell_variables->table = hash_create (TEMPENV_HASH_BUCKETS); - } - - v = bind_variable_internal (var->name, value_cell (var), binding_table, 0, ASS_FORCE|ASS_NOLONGJMP); - - /* XXX - should we set the context here? It shouldn't matter because of how - assign_in_env works, but we do it anyway. */ - if (v) - v->context = shell_variables->scope; - - if (binding_table == global_variables->table) /* XXX */ - var->attributes &= ~(att_tempvar|att_propagate); - else - { - var->attributes |= att_propagate; /* XXX - propagate more than once? */ - if (binding_table == shell_variables->table) - shell_variables->flags |= VC_HASTMPVAR; - } - if (v) - v->attributes |= var->attributes; - - if (find_special_var (var->name) >= 0) - tempvar_list[tvlist_ind++] = savestring (var->name); - - dispose_variable (var); -} - -/* Take a variable described by DATA and push it to the surrounding scope if - the PROPAGATE attribute is set. That gets set by push_temp_var if we are - taking a variable like `var=value declare -x var' and propagating it to - the enclosing scope. */ -static void -propagate_temp_var (data) - PTR_T data; -{ - SHELL_VAR *var; - - var = (SHELL_VAR *)data; - if (tempvar_p (var) && (var->attributes & att_propagate)) - push_temp_var (data); - else - { - if (find_special_var (var->name) >= 0) - tempvar_list[tvlist_ind++] = savestring (var->name); - dispose_variable (var); - } -} - -/* Free the storage used in the hash table for temporary - environment variables. PUSHF is a function to be called - to free each hash table entry. It takes care of pushing variables - to previous scopes if appropriate. PUSHF stores names of variables - that require special handling (e.g., IFS) on tempvar_list, so this - function can call stupidly_hack_special_variables on all the - variables in the list when the temporary hash table is destroyed. */ -static void -dispose_temporary_env (pushf) - sh_free_func_t *pushf; -{ - int i; - HASH_TABLE *disposer; - - tempvar_list = strvec_create (HASH_ENTRIES (temporary_env) + 1); - tempvar_list[tvlist_ind = 0] = 0; - - disposer = temporary_env; - temporary_env = (HASH_TABLE *)NULL; - - hash_flush (disposer, pushf); - hash_dispose (disposer); - - tempvar_list[tvlist_ind] = 0; - - array_needs_making = 1; - - for (i = 0; i < tvlist_ind; i++) - stupidly_hack_special_variables (tempvar_list[i]); - - strvec_dispose (tempvar_list); - tempvar_list = 0; - tvlist_ind = 0; -} - -void -dispose_used_env_vars () -{ - if (temporary_env) - { - dispose_temporary_env (propagate_temp_var); - maybe_make_export_env (); - } -} - -/* Take all of the shell variables in the temporary environment HASH_TABLE - and make shell variables from them at the current variable context. - Right now, this is only called in Posix mode to implement the historical - accident of creating global variables from assignment statements preceding - special builtins, but we check in case this acquires another caller later. */ -void -merge_temporary_env () -{ - if (temporary_env) - dispose_temporary_env (posixly_correct ? push_posix_temp_var : push_temp_var); -} - -/* Temporary function to use if we want to separate function and special - builtin behavior. */ -void -merge_function_temporary_env () -{ - if (temporary_env) - dispose_temporary_env (push_temp_var); -} - -void -flush_temporary_env () -{ - if (temporary_env) - { - hash_flush (temporary_env, free_variable_hash_data); - hash_dispose (temporary_env); - temporary_env = (HASH_TABLE *)NULL; - } -} - -/* **************************************************************** */ -/* */ -/* Creating and manipulating the environment */ -/* */ -/* **************************************************************** */ - -static inline char * -mk_env_string (name, value, attributes) - const char *name, *value; - int attributes; -{ - size_t name_len, value_len; - char *p, *q, *t; - int isfunc, isarray; - - name_len = strlen (name); - value_len = STRLEN (value); - - isfunc = attributes & att_function; -#if defined (ARRAY_VARS) && defined (ARRAY_EXPORT) - isarray = attributes & (att_array|att_assoc); -#endif - - /* If we are exporting a shell function, construct the encoded function - name. */ - if (isfunc && value) - { - p = (char *)xmalloc (BASHFUNC_PREFLEN + name_len + BASHFUNC_SUFFLEN + value_len + 2); - q = p; - memcpy (q, BASHFUNC_PREFIX, BASHFUNC_PREFLEN); - q += BASHFUNC_PREFLEN; - memcpy (q, name, name_len); - q += name_len; - memcpy (q, BASHFUNC_SUFFIX, BASHFUNC_SUFFLEN); - q += BASHFUNC_SUFFLEN; - } -#if defined (ARRAY_VARS) && defined (ARRAY_EXPORT) - else if (isarray && value) - { - if (attributes & att_assoc) - p = (char *)xmalloc (BASHASSOC_PREFLEN + name_len + BASHASSOC_SUFFLEN + value_len + 2); - else - p = (char *)xmalloc (BASHARRAY_PREFLEN + name_len + BASHARRAY_SUFFLEN + value_len + 2); - q = p; - if (attributes & att_assoc) - { - memcpy (q, BASHASSOC_PREFIX, BASHASSOC_PREFLEN); - q += BASHASSOC_PREFLEN; - } - else - { - memcpy (q, BASHARRAY_PREFIX, BASHARRAY_PREFLEN); - q += BASHARRAY_PREFLEN; - } - memcpy (q, name, name_len); - q += name_len; - /* These are actually the same currently */ - if (attributes & att_assoc) - { - memcpy (q, BASHASSOC_SUFFIX, BASHASSOC_SUFFLEN); - q += BASHARRAY_SUFFLEN; - } - else - { - memcpy (q, BASHARRAY_SUFFIX, BASHARRAY_SUFFLEN); - q += BASHARRAY_SUFFLEN; - } - } -#endif - else - { - p = (char *)xmalloc (2 + name_len + value_len); - memcpy (p, name, name_len); - q = p + name_len; - } - - q[0] = '='; - if (value && *value) - { - if (isfunc) - { - t = dequote_escapes (value); - value_len = STRLEN (t); - memcpy (q + 1, t, value_len + 1); - free (t); - } - else - memcpy (q + 1, value, value_len + 1); - } - else - q[1] = '\0'; - - return (p); -} - -#ifdef DEBUG -/* Debugging */ -static int -valid_exportstr (v) - SHELL_VAR *v; -{ - char *s; - - s = v->exportstr; - if (s == 0) - { - internal_error (_("%s has null exportstr"), v->name); - return (0); - } - if (legal_variable_starter ((unsigned char)*s) == 0) - { - internal_error (_("invalid character %d in exportstr for %s"), *s, v->name); - return (0); - } - for (s = v->exportstr + 1; s && *s; s++) - { - if (*s == '=') - break; - if (legal_variable_char ((unsigned char)*s) == 0) - { - internal_error (_("invalid character %d in exportstr for %s"), *s, v->name); - return (0); - } - } - if (*s != '=') - { - internal_error (_("no `=' in exportstr for %s"), v->name); - return (0); - } - return (1); -} -#endif - -#if defined (ARRAY_VARS) -# define USE_EXPORTSTR (value == var->exportstr && array_p (var) == 0 && assoc_p (var) == 0) -#else -# define USE_EXPORTSTR (value == var->exportstr) -#endif - -static char ** -make_env_array_from_var_list (vars) - SHELL_VAR **vars; -{ - register int i, list_index; - register SHELL_VAR *var; - char **list, *value; - - list = strvec_create ((1 + strvec_len ((char **)vars))); - - for (i = 0, list_index = 0; var = vars[i]; i++) - { -#if defined (__CYGWIN__) - /* We don't use the exportstr stuff on Cygwin at all. */ - INVALIDATE_EXPORTSTR (var); -#endif - - /* If the value is generated dynamically, generate it here. */ - if (regen_p (var) && var->dynamic_value) - { - var = (*(var->dynamic_value)) (var); - INVALIDATE_EXPORTSTR (var); - } - - if (var->exportstr) - value = var->exportstr; - else if (function_p (var)) - value = named_function_string ((char *)NULL, function_cell (var), 0); -#if defined (ARRAY_VARS) - else if (array_p (var)) -# if ARRAY_EXPORT - value = array_to_assign (array_cell (var), 0); -# else - continue; /* XXX array vars cannot yet be exported */ -# endif /* ARRAY_EXPORT */ - else if (assoc_p (var)) -# if ARRAY_EXPORT - value = assoc_to_assign (assoc_cell (var), 0); -# else - continue; /* XXX associative array vars cannot yet be exported */ -# endif /* ARRAY_EXPORT */ -#endif - else - value = value_cell (var); - - if (value) - { - /* Gee, I'd like to get away with not using savestring() if we're - using the cached exportstr... */ - list[list_index] = USE_EXPORTSTR ? savestring (value) - : mk_env_string (var->name, value, var->attributes); - - if (USE_EXPORTSTR == 0) - SAVE_EXPORTSTR (var, list[list_index]); - - list_index++; -#undef USE_EXPORTSTR - -#if defined (ARRAY_VARS) && defined (ARRAY_EXPORT) - if (array_p (var) || assoc_p (var)) - free (value); -#endif - } - } - - list[list_index] = (char *)NULL; - return (list); -} - -/* Make an array of assignment statements from the hash table - HASHED_VARS which contains SHELL_VARs. Only visible, exported - variables are eligible. */ -static char ** -make_var_export_array (vcxt) - VAR_CONTEXT *vcxt; -{ - char **list; - SHELL_VAR **vars; - -#if 0 - vars = map_over (visible_and_exported, vcxt); -#else - vars = map_over (export_environment_candidate, vcxt); -#endif - - if (vars == 0) - return (char **)NULL; - - list = make_env_array_from_var_list (vars); - - free (vars); - return (list); -} - -static char ** -make_func_export_array () -{ - char **list; - SHELL_VAR **vars; - - vars = map_over_funcs (visible_and_exported); - if (vars == 0) - return (char **)NULL; - - list = make_env_array_from_var_list (vars); - - free (vars); - return (list); -} - -/* Add ENVSTR to the end of the exported environment, EXPORT_ENV. */ -#define add_to_export_env(envstr,do_alloc) \ -do \ - { \ - if (export_env_index >= (export_env_size - 1)) \ - { \ - export_env_size += 16; \ - export_env = strvec_resize (export_env, export_env_size); \ - environ = export_env; \ - } \ - export_env[export_env_index++] = (do_alloc) ? savestring (envstr) : envstr; \ - export_env[export_env_index] = (char *)NULL; \ - } while (0) - -/* Add ASSIGN to EXPORT_ENV, or supersede a previous assignment in the - array with the same left-hand side. Return the new EXPORT_ENV. */ -char ** -add_or_supercede_exported_var (assign, do_alloc) - char *assign; - int do_alloc; -{ - register int i; - int equal_offset; - - equal_offset = assignment (assign, 0); - if (equal_offset == 0) - return (export_env); - - /* If this is a function, then only supersede the function definition. - We do this by including the `=() {' in the comparison, like - initialize_shell_variables does. */ - if (assign[equal_offset + 1] == '(' && - strncmp (assign + equal_offset + 2, ") {", 3) == 0) /* } */ - equal_offset += 4; - - for (i = 0; i < export_env_index; i++) - { - if (STREQN (assign, export_env[i], equal_offset + 1)) - { - free (export_env[i]); - export_env[i] = do_alloc ? savestring (assign) : assign; - return (export_env); - } - } - add_to_export_env (assign, do_alloc); - return (export_env); -} - -static void -add_temp_array_to_env (temp_array, do_alloc, do_supercede) - char **temp_array; - int do_alloc, do_supercede; -{ - register int i; - - if (temp_array == 0) - return; - - for (i = 0; temp_array[i]; i++) - { - if (do_supercede) - export_env = add_or_supercede_exported_var (temp_array[i], do_alloc); - else - add_to_export_env (temp_array[i], do_alloc); - } - - free (temp_array); -} - -/* Make the environment array for the command about to be executed, if the - array needs making. Otherwise, do nothing. If a shell action could - change the array that commands receive for their environment, then the - code should `array_needs_making++'. - - The order to add to the array is: - temporary_env - list of var contexts whose head is shell_variables - shell_functions - - This is the shell variable lookup order. We add only new variable - names at each step, which allows local variables and variables in - the temporary environments to shadow variables in the global (or - any previous) scope. -*/ - -static int -n_shell_variables () -{ - VAR_CONTEXT *vc; - int n; - - for (n = 0, vc = shell_variables; vc; vc = vc->down) - n += HASH_ENTRIES (vc->table); - return n; -} - -int -chkexport (name) - char *name; -{ - SHELL_VAR *v; - - v = find_variable (name); - if (v && exported_p (v)) - { - array_needs_making = 1; - maybe_make_export_env (); - return 1; - } - return 0; -} - -void -maybe_make_export_env () -{ - register char **temp_array; - int new_size; - VAR_CONTEXT *tcxt, *icxt; - - if (array_needs_making) - { - if (export_env) - strvec_flush (export_env); - - /* Make a guess based on how many shell variables and functions we - have. Since there will always be array variables, and array - variables are not (yet) exported, this will always be big enough - for the exported variables and functions. */ - new_size = n_shell_variables () + HASH_ENTRIES (shell_functions) + 1 + - HASH_ENTRIES (temporary_env) + HASH_ENTRIES (invalid_env); - if (new_size > export_env_size) - { - export_env_size = new_size; - export_env = strvec_resize (export_env, export_env_size); - environ = export_env; - } - export_env[export_env_index = 0] = (char *)NULL; - - /* Make a dummy variable context from the temporary_env, stick it on - the front of shell_variables, call make_var_export_array on the - whole thing to flatten it, and convert the list of SHELL_VAR *s - to the form needed by the environment. */ - if (temporary_env) - { - tcxt = new_var_context ((char *)NULL, 0); - tcxt->table = temporary_env; - tcxt->down = shell_variables; - } - else - tcxt = shell_variables; - - if (invalid_env) - { - icxt = new_var_context ((char *)NULL, 0); - icxt->table = invalid_env; - icxt->down = tcxt; - } - else - icxt = tcxt; - - temp_array = make_var_export_array (icxt); - if (temp_array) - add_temp_array_to_env (temp_array, 0, 0); - - if (icxt != tcxt) - free (icxt); - - if (tcxt != shell_variables) - free (tcxt); - -#if defined (RESTRICTED_SHELL) - /* Restricted shells may not export shell functions. */ - temp_array = restricted ? (char **)0 : make_func_export_array (); -#else - temp_array = make_func_export_array (); -#endif - if (temp_array) - add_temp_array_to_env (temp_array, 0, 0); - - array_needs_making = 0; - } -} - -/* This is an efficiency hack. PWD and OLDPWD are auto-exported, so - we will need to remake the exported environment every time we - change directories. `_' is always put into the environment for - every external command, so without special treatment it will always - cause the environment to be remade. - - If there is no other reason to make the exported environment, we can - just update the variables in place and mark the exported environment - as no longer needing a remake. */ -void -update_export_env_inplace (env_prefix, preflen, value) - char *env_prefix; - int preflen; - char *value; -{ - char *evar; - - evar = (char *)xmalloc (STRLEN (value) + preflen + 1); - strcpy (evar, env_prefix); - if (value) - strcpy (evar + preflen, value); - export_env = add_or_supercede_exported_var (evar, 0); -} - -/* We always put _ in the environment as the name of this command. */ -void -put_command_name_into_env (command_name) - char *command_name; -{ - update_export_env_inplace ("_=", 2, command_name); -} - -/* **************************************************************** */ -/* */ -/* Managing variable contexts */ -/* */ -/* **************************************************************** */ - -/* Allocate and return a new variable context with NAME and FLAGS. - NAME can be NULL. */ - -VAR_CONTEXT * -new_var_context (name, flags) - char *name; - int flags; -{ - VAR_CONTEXT *vc; - - vc = (VAR_CONTEXT *)xmalloc (sizeof (VAR_CONTEXT)); - vc->name = name ? savestring (name) : (char *)NULL; - vc->scope = variable_context; - vc->flags = flags; - - vc->up = vc->down = (VAR_CONTEXT *)NULL; - vc->table = (HASH_TABLE *)NULL; - - return vc; -} - -/* Free a variable context and its data, including the hash table. Dispose - all of the variables. */ -void -dispose_var_context (vc) - VAR_CONTEXT *vc; -{ - FREE (vc->name); - - if (vc->table) - { - delete_all_variables (vc->table); - hash_dispose (vc->table); - } - - free (vc); -} - -/* Set VAR's scope level to the current variable context. */ -static int -set_context (var) - SHELL_VAR *var; -{ - return (var->context = variable_context); -} - -/* Make a new variable context with NAME and FLAGS and a HASH_TABLE of - temporary variables, and push it onto shell_variables. This is - for shell functions. */ -VAR_CONTEXT * -push_var_context (name, flags, tempvars) - char *name; - int flags; - HASH_TABLE *tempvars; -{ - VAR_CONTEXT *vc; - int posix_func_behavior; - - /* As of IEEE Std 1003.1-2017, assignment statements preceding shell - functions no longer behave like assignment statements preceding - special builtins, and do not persist in the current shell environment. - This is austin group interp #654, though nobody implements it yet. */ - posix_func_behavior = 0; - - vc = new_var_context (name, flags); - /* Posix interp 1009, temporary assignments preceding function calls modify - the current environment *before* the command is executed. */ - if (posix_func_behavior && (flags & VC_FUNCENV) && tempvars == temporary_env) - merge_temporary_env (); - else if (tempvars) - { - vc->table = tempvars; - /* Have to do this because the temp environment was created before - variable_context was incremented. */ - /* XXX - only need to do it if flags&VC_FUNCENV */ - flatten (tempvars, set_context, (VARLIST *)NULL, 0); - vc->flags |= VC_HASTMPVAR; - } - vc->down = shell_variables; - shell_variables->up = vc; - - return (shell_variables = vc); -} - -/* This can be called from one of two code paths: - 1. pop_scope, which implements the posix rules for propagating variable - assignments preceding special builtins to the surrounding scope - (push_builtin_var -- isbltin == 1); - 2. pop_var_context, which is called from pop_context and implements the - posix rules for propagating variable assignments preceding function - calls to the surrounding scope (push_func_var -- isbltin == 0) - - It takes variables out of a temporary environment hash table. We take the - variable in data. -*/ - -static inline void -push_posix_tempvar_internal (var, isbltin) - SHELL_VAR *var; - int isbltin; -{ - SHELL_VAR *v; - int posix_var_behavior; - - /* As of IEEE Std 1003.1-2017, assignment statements preceding shell - functions no longer behave like assignment statements preceding - special builtins, and do not persist in the current shell environment. - This is austin group interp #654, though nobody implements it yet. */ - posix_var_behavior = posixly_correct && isbltin; - v = 0; - - if (local_p (var) && STREQ (var->name, "-")) - { - set_current_options (value_cell (var)); - set_shellopts (); - } - /* This takes variable assignments preceding special builtins that can execute - multiple commands (source, eval, etc.) and performs the equivalent of - an assignment statement to modify the closest enclosing variable (the - posix "current execution environment"). This makes the behavior the same - as push_posix_temp_var; but the circumstances of calling are slightly - different. */ - else if (tempvar_p (var) && posix_var_behavior) - { - /* similar to push_posix_temp_var */ - v = bind_variable (var->name, value_cell (var), ASS_FORCE|ASS_NOLONGJMP); - if (v) - { - v->attributes |= var->attributes; - if (v->context == 0) - v->attributes &= ~(att_tempvar|att_propagate); - /* XXX - set att_propagate here if v->context > 0? */ - } - } - else if (tempvar_p (var) && propagate_p (var)) - { - /* Make sure we have a hash table to store the variable in while it is - being propagated down to the global variables table. Create one if - we have to */ - if ((vc_isfuncenv (shell_variables) || vc_istempenv (shell_variables)) && shell_variables->table == 0) - shell_variables->table = hash_create (VARIABLES_HASH_BUCKETS); - v = bind_variable_internal (var->name, value_cell (var), shell_variables->table, 0, 0); - /* XXX - should we set v->context here? */ - if (v) - v->context = shell_variables->scope; - if (shell_variables == global_variables) - var->attributes &= ~(att_tempvar|att_propagate); - else - shell_variables->flags |= VC_HASTMPVAR; - if (v) - v->attributes |= var->attributes; - } - else - stupidly_hack_special_variables (var->name); /* XXX */ - -#if defined (ARRAY_VARS) - if (v && (array_p (var) || assoc_p (var))) - { - FREE (value_cell (v)); - if (array_p (var)) - var_setarray (v, array_copy (array_cell (var))); - else - var_setassoc (v, assoc_copy (assoc_cell (var))); - } -#endif - - dispose_variable (var); -} - -static void -push_func_var (data) - PTR_T data; -{ - SHELL_VAR *var; - - var = (SHELL_VAR *)data; - push_posix_tempvar_internal (var, 0); -} - -static void -push_builtin_var (data) - PTR_T data; -{ - SHELL_VAR *var; - - var = (SHELL_VAR *)data; - push_posix_tempvar_internal (var, 1); -} - -/* Pop the top context off of VCXT and dispose of it, returning the rest of - the stack. */ -void -pop_var_context () -{ - VAR_CONTEXT *ret, *vcxt; - - vcxt = shell_variables; - if (vc_isfuncenv (vcxt) == 0) - { - internal_error (_("pop_var_context: head of shell_variables not a function context")); - return; - } - - if (ret = vcxt->down) - { - ret->up = (VAR_CONTEXT *)NULL; - shell_variables = ret; - if (vcxt->table) - hash_flush (vcxt->table, push_func_var); - dispose_var_context (vcxt); - } - else - internal_error (_("pop_var_context: no global_variables context")); -} - -static void -delete_local_contexts (vcxt) - VAR_CONTEXT *vcxt; -{ - VAR_CONTEXT *v, *t; - - for (v = vcxt; v != global_variables; v = t) - { - t = v->down; - dispose_var_context (v); - } -} - -/* Delete the HASH_TABLEs for all variable contexts beginning at VCXT, and - all of the VAR_CONTEXTs except GLOBAL_VARIABLES. */ -void -delete_all_contexts (vcxt) - VAR_CONTEXT *vcxt; -{ - delete_local_contexts (vcxt); - delete_all_variables (global_variables->table); - shell_variables = global_variables; -} - -/* Reset the context so we are not executing in a shell function. Only call - this if you are getting ready to exit the shell. */ -void -reset_local_contexts () -{ - delete_local_contexts (shell_variables); - shell_variables = global_variables; - variable_context = 0; -} - -/* **************************************************************** */ -/* */ -/* Pushing and Popping temporary variable scopes */ -/* */ -/* **************************************************************** */ - -VAR_CONTEXT * -push_scope (flags, tmpvars) - int flags; - HASH_TABLE *tmpvars; -{ - return (push_var_context ((char *)NULL, flags, tmpvars)); -} - -static void -push_exported_var (data) - PTR_T data; -{ - SHELL_VAR *var, *v; - - var = (SHELL_VAR *)data; - - /* If a temp var had its export attribute set, or it's marked to be - propagated, bind it in the previous scope before disposing it. */ - /* XXX - This isn't exactly right, because all tempenv variables have the - export attribute set. */ - if (tempvar_p (var) && exported_p (var) && (var->attributes & att_propagate)) - { - var->attributes &= ~att_tempvar; /* XXX */ - v = bind_variable_internal (var->name, value_cell (var), shell_variables->table, 0, 0); - if (shell_variables == global_variables) - var->attributes &= ~att_propagate; - if (v) - { - v->attributes |= var->attributes; - v->context = shell_variables->scope; - } - } - else - stupidly_hack_special_variables (var->name); /* XXX */ - - dispose_variable (var); -} - -/* This is called to propagate variables in the temporary environment of a - special builtin (if IS_SPECIAL != 0) or exported variables that are the - result of a builtin like `source' or `command' that can operate on the - variables in its temporary environment. In the first case, we call - push_builtin_var, which does the right thing. */ -void -pop_scope (is_special) - int is_special; -{ - VAR_CONTEXT *vcxt, *ret; - int is_bltinenv; - - vcxt = shell_variables; - if (vc_istempscope (vcxt) == 0) - { - internal_error (_("pop_scope: head of shell_variables not a temporary environment scope")); - return; - } - is_bltinenv = vc_isbltnenv (vcxt); /* XXX - for later */ - - ret = vcxt->down; - if (ret) - ret->up = (VAR_CONTEXT *)NULL; - - shell_variables = ret; - - /* Now we can take care of merging variables in VCXT into set of scopes - whose head is RET (shell_variables). */ - FREE (vcxt->name); - if (vcxt->table) - { - if (is_special) - hash_flush (vcxt->table, push_builtin_var); - else - hash_flush (vcxt->table, push_exported_var); - hash_dispose (vcxt->table); - } - free (vcxt); - - sv_ifs ("IFS"); /* XXX here for now */ -} - -/* **************************************************************** */ -/* */ -/* Pushing and Popping function contexts */ -/* */ -/* **************************************************************** */ - -struct saved_dollar_vars { - char **first_ten; - WORD_LIST *rest; - int count; -}; - -static struct saved_dollar_vars *dollar_arg_stack = (struct saved_dollar_vars *)NULL; -static int dollar_arg_stack_slots; -static int dollar_arg_stack_index; - -/* Functions to manipulate dollar_vars array. Need to keep these in sync with - whatever remember_args() does. */ -static char ** -save_dollar_vars () -{ - char **ret; - int i; - - ret = strvec_create (10); - for (i = 1; i < 10; i++) - { - ret[i] = dollar_vars[i]; - dollar_vars[i] = (char *)NULL; - } - return ret; -} - -static void -restore_dollar_vars (args) - char **args; -{ - int i; - - for (i = 1; i < 10; i++) - dollar_vars[i] = args[i]; -} - -static void -free_dollar_vars () -{ - int i; - - for (i = 1; i < 10; i++) - { - FREE (dollar_vars[i]); - dollar_vars[i] = (char *)NULL; - } -} - -static void -free_saved_dollar_vars (args) - char **args; -{ - int i; - - for (i = 1; i < 10; i++) - FREE (args[i]); -} - -/* Do what remember_args (xxx, 1) would have done. */ -void -clear_dollar_vars () -{ - free_dollar_vars (); - dispose_words (rest_of_args); - - rest_of_args = (WORD_LIST *)NULL; - posparam_count = 0; -} - -/* XXX - should always be followed by remember_args () */ -void -push_context (name, is_subshell, tempvars) - char *name; /* function name */ - int is_subshell; - HASH_TABLE *tempvars; -{ - if (is_subshell == 0) - push_dollar_vars (); - variable_context++; - push_var_context (name, VC_FUNCENV, tempvars); -} - -/* Only called when subshell == 0, so we don't need to check, and can - unconditionally pop the dollar vars off the stack. */ -void -pop_context () -{ - pop_dollar_vars (); - variable_context--; - pop_var_context (); - - sv_ifs ("IFS"); /* XXX here for now */ -} - -/* Save the existing positional parameters on a stack. */ -void -push_dollar_vars () -{ - if (dollar_arg_stack_index + 2 > dollar_arg_stack_slots) - { - dollar_arg_stack = (struct saved_dollar_vars *) - xrealloc (dollar_arg_stack, (dollar_arg_stack_slots += 10) - * sizeof (struct saved_dollar_vars)); - } - - dollar_arg_stack[dollar_arg_stack_index].count = posparam_count; - dollar_arg_stack[dollar_arg_stack_index].first_ten = save_dollar_vars (); - dollar_arg_stack[dollar_arg_stack_index++].rest = rest_of_args; - rest_of_args = (WORD_LIST *)NULL; - posparam_count = 0; - - dollar_arg_stack[dollar_arg_stack_index].first_ten = (char **)NULL; - dollar_arg_stack[dollar_arg_stack_index].rest = (WORD_LIST *)NULL; -} - -/* Restore the positional parameters from our stack. */ -void -pop_dollar_vars () -{ - if (dollar_arg_stack == 0 || dollar_arg_stack_index == 0) - return; - - /* Wipe out current values */ - clear_dollar_vars (); - - rest_of_args = dollar_arg_stack[--dollar_arg_stack_index].rest; - restore_dollar_vars (dollar_arg_stack[dollar_arg_stack_index].first_ten); - free (dollar_arg_stack[dollar_arg_stack_index].first_ten); - posparam_count = dollar_arg_stack[dollar_arg_stack_index].count; - - dollar_arg_stack[dollar_arg_stack_index].first_ten = (char **)NULL; - dollar_arg_stack[dollar_arg_stack_index].rest = (WORD_LIST *)NULL; - dollar_arg_stack[dollar_arg_stack_index].count = 0; - - set_dollar_vars_unchanged (); - invalidate_cached_quoted_dollar_at (); -} - -void -dispose_saved_dollar_vars () -{ - if (dollar_arg_stack == 0 || dollar_arg_stack_index == 0) - return; - - dispose_words (dollar_arg_stack[--dollar_arg_stack_index].rest); - free_saved_dollar_vars (dollar_arg_stack[dollar_arg_stack_index].first_ten); - free (dollar_arg_stack[dollar_arg_stack_index].first_ten); - - dollar_arg_stack[dollar_arg_stack_index].first_ten = (char **)NULL; - dollar_arg_stack[dollar_arg_stack_index].rest = (WORD_LIST *)NULL; - dollar_arg_stack[dollar_arg_stack_index].count = 0; -} - -/* Initialize BASH_ARGV and BASH_ARGC after turning on extdebug after the - shell is initialized */ -void -init_bash_argv () -{ - if (bash_argv_initialized == 0) - { - save_bash_argv (); - bash_argv_initialized = 1; - } -} - -void -save_bash_argv () -{ - WORD_LIST *list; - - list = list_rest_of_args (); - push_args (list); - dispose_words (list); -} - -/* Manipulate the special BASH_ARGV and BASH_ARGC variables. */ - -void -push_args (list) - WORD_LIST *list; -{ -#if defined (ARRAY_VARS) && defined (DEBUGGER) - SHELL_VAR *bash_argv_v, *bash_argc_v; - ARRAY *bash_argv_a, *bash_argc_a; - WORD_LIST *l; - arrayind_t i; - char *t; - - GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a); - GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a); - - for (l = list, i = 0; l; l = l->next, i++) - array_push (bash_argv_a, l->word->word); - - t = itos (i); - array_push (bash_argc_a, t); - free (t); -#endif /* ARRAY_VARS && DEBUGGER */ -} - -/* Remove arguments from BASH_ARGV array. Pop top element off BASH_ARGC - array and use that value as the count of elements to remove from - BASH_ARGV. */ -void -pop_args () -{ -#if defined (ARRAY_VARS) && defined (DEBUGGER) - SHELL_VAR *bash_argv_v, *bash_argc_v; - ARRAY *bash_argv_a, *bash_argc_a; - ARRAY_ELEMENT *ce; - intmax_t i; - - GET_ARRAY_FROM_VAR ("BASH_ARGV", bash_argv_v, bash_argv_a); - GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a); - - ce = array_unshift_element (bash_argc_a); - if (ce == 0 || legal_number (element_value (ce), &i) == 0) - i = 0; - - for ( ; i > 0; i--) - array_pop (bash_argv_a); - array_dispose_element (ce); -#endif /* ARRAY_VARS && DEBUGGER */ -} - -/************************************************* - * * - * Functions to manage special variables * - * * - *************************************************/ - -/* Extern declarations for variables this code has to manage. */ - -/* An alist of name.function for each special variable. Most of the - functions don't do much, and in fact, this would be faster with a - switch statement, but by the end of this file, I am sick of switch - statements. */ - -#define SET_INT_VAR(name, intvar) intvar = find_variable (name) != 0 - -/* This table will be sorted with qsort() the first time it's accessed. */ -struct name_and_function { - char *name; - sh_sv_func_t *function; -}; - -static struct name_and_function special_vars[] = { - { "BASH_COMPAT", sv_shcompat }, - { "BASH_XTRACEFD", sv_xtracefd }, - -#if defined (JOB_CONTROL) - { "CHILD_MAX", sv_childmax }, -#endif - -#if defined (READLINE) -# if defined (STRICT_POSIX) - { "COLUMNS", sv_winsize }, -# endif - { "COMP_WORDBREAKS", sv_comp_wordbreaks }, -#endif - - { "EXECIGNORE", sv_execignore }, - - { "FUNCNEST", sv_funcnest }, - - { "GLOBIGNORE", sv_globignore }, - -#if defined (HISTORY) - { "HISTCONTROL", sv_history_control }, - { "HISTFILESIZE", sv_histsize }, - { "HISTIGNORE", sv_histignore }, - { "HISTSIZE", sv_histsize }, - { "HISTTIMEFORMAT", sv_histtimefmt }, -#endif - -#if defined (__CYGWIN__) - { "HOME", sv_home }, -#endif - -#if defined (READLINE) - { "HOSTFILE", sv_hostfile }, -#endif - - { "IFS", sv_ifs }, - { "IGNOREEOF", sv_ignoreeof }, - - { "LANG", sv_locale }, - { "LC_ALL", sv_locale }, - { "LC_COLLATE", sv_locale }, - { "LC_CTYPE", sv_locale }, - { "LC_MESSAGES", sv_locale }, - { "LC_NUMERIC", sv_locale }, - { "LC_TIME", sv_locale }, - -#if defined (READLINE) && defined (STRICT_POSIX) - { "LINES", sv_winsize }, -#endif - - { "MAIL", sv_mail }, - { "MAILCHECK", sv_mail }, - { "MAILPATH", sv_mail }, - - { "OPTERR", sv_opterr }, - { "OPTIND", sv_optind }, - - { "PATH", sv_path }, - { "POSIXLY_CORRECT", sv_strict_posix }, - -#if defined (READLINE) - { "TERM", sv_terminal }, - { "TERMCAP", sv_terminal }, - { "TERMINFO", sv_terminal }, -#endif /* READLINE */ - - { "TEXTDOMAIN", sv_locale }, - { "TEXTDOMAINDIR", sv_locale }, - -#if defined (HAVE_TZSET) - { "TZ", sv_tz }, -#endif - -#if defined (HISTORY) && defined (BANG_HISTORY) - { "histchars", sv_histchars }, -#endif /* HISTORY && BANG_HISTORY */ - - { "ignoreeof", sv_ignoreeof }, - - { (char *)0, (sh_sv_func_t *)0 } -}; - -#define N_SPECIAL_VARS (sizeof (special_vars) / sizeof (special_vars[0]) - 1) - -static int -sv_compare (sv1, sv2) - struct name_and_function *sv1, *sv2; -{ - int r; - - if ((r = sv1->name[0] - sv2->name[0]) == 0) - r = strcmp (sv1->name, sv2->name); - return r; -} - -static inline int -find_special_var (name) - const char *name; -{ - register int i, r; - - for (i = 0; special_vars[i].name; i++) - { - r = special_vars[i].name[0] - name[0]; - if (r == 0) - r = strcmp (special_vars[i].name, name); - if (r == 0) - return i; - else if (r > 0) - /* Can't match any of rest of elements in sorted list. Take this out - if it causes problems in certain environments. */ - break; - } - return -1; -} - -/* The variable in NAME has just had its state changed. Check to see if it - is one of the special ones where something special happens. */ -void -stupidly_hack_special_variables (name) - char *name; -{ - static int sv_sorted = 0; - int i; - - if (sv_sorted == 0) /* shouldn't need, but it's fairly cheap. */ - { - qsort (special_vars, N_SPECIAL_VARS, sizeof (special_vars[0]), - (QSFUNC *)sv_compare); - sv_sorted = 1; - } - - i = find_special_var (name); - if (i != -1) - (*(special_vars[i].function)) (name); -} - -/* Special variables that need hooks to be run when they are unset as part - of shell reinitialization should have their sv_ functions run here. */ -void -reinit_special_variables () -{ -#if defined (READLINE) - sv_comp_wordbreaks ("COMP_WORDBREAKS"); -#endif - sv_globignore ("GLOBIGNORE"); - sv_opterr ("OPTERR"); -} - -void -sv_ifs (name) - char *name; -{ - SHELL_VAR *v; - - v = find_variable ("IFS"); - setifs (v); -} - -/* What to do just after the PATH variable has changed. */ -void -sv_path (name) - char *name; -{ - /* hash -r */ - phash_flush (); -} - -/* What to do just after one of the MAILxxxx variables has changed. NAME - is the name of the variable. This is called with NAME set to one of - MAIL, MAILCHECK, or MAILPATH. */ -void -sv_mail (name) - char *name; -{ - /* If the time interval for checking the files has changed, then - reset the mail timer. Otherwise, one of the pathname vars - to the users mailbox has changed, so rebuild the array of - filenames. */ - if (name[4] == 'C') /* if (strcmp (name, "MAILCHECK") == 0) */ - reset_mail_timer (); - else - { - free_mail_files (); - remember_mail_dates (); - } -} - -void -sv_funcnest (name) - char *name; -{ - SHELL_VAR *v; - intmax_t num; - - v = find_variable (name); - if (v == 0) - funcnest_max = 0; - else if (legal_number (value_cell (v), &num) == 0) - funcnest_max = 0; - else - funcnest_max = num; -} - -/* What to do when EXECIGNORE changes. */ -void -sv_execignore (name) - char *name; -{ - setup_exec_ignore (name); -} - -/* What to do when GLOBIGNORE changes. */ -void -sv_globignore (name) - char *name; -{ - if (privileged_mode == 0) - setup_glob_ignore (name); -} - -#if defined (READLINE) -void -sv_comp_wordbreaks (name) - char *name; -{ - SHELL_VAR *sv; - - sv = find_variable (name); - if (sv == 0) - reset_completer_word_break_chars (); -} - -/* What to do just after one of the TERMxxx variables has changed. - If we are an interactive shell, then try to reset the terminal - information in readline. */ -void -sv_terminal (name) - char *name; -{ - if (interactive_shell && no_line_editing == 0) - rl_reset_terminal (get_string_value ("TERM")); -} - -void -sv_hostfile (name) - char *name; -{ - SHELL_VAR *v; - - v = find_variable (name); - if (v == 0) - clear_hostname_list (); - else - hostname_list_initialized = 0; -} - -#if defined (STRICT_POSIX) -/* In strict posix mode, we allow assignments to LINES and COLUMNS (and values - found in the initial environment) to override the terminal size reported by - the kernel. */ -void -sv_winsize (name) - char *name; -{ - SHELL_VAR *v; - intmax_t xd; - int d; - - if (posixly_correct == 0 || interactive_shell == 0 || no_line_editing) - return; - - v = find_variable (name); - if (v == 0 || var_isset (v) == 0) - rl_reset_screen_size (); - else - { - if (legal_number (value_cell (v), &xd) == 0) - return; - winsize_assignment = 1; - d = xd; /* truncate */ - if (name[0] == 'L') /* LINES */ - rl_set_screen_size (d, -1); - else /* COLUMNS */ - rl_set_screen_size (-1, d); - winsize_assignment = 0; - } -} -#endif /* STRICT_POSIX */ -#endif /* READLINE */ - -/* Update the value of HOME in the export environment so tilde expansion will - work on cygwin. */ -#if defined (__CYGWIN__) -sv_home (name) - char *name; -{ - array_needs_making = 1; - maybe_make_export_env (); -} -#endif - -#if defined (HISTORY) -/* What to do after the HISTSIZE or HISTFILESIZE variables change. - If there is a value for this HISTSIZE (and it is numeric), then stifle - the history. Otherwise, if there is NO value for this variable, - unstifle the history. If name is HISTFILESIZE, and its value is - numeric, truncate the history file to hold no more than that many - lines. */ -void -sv_histsize (name) - char *name; -{ - char *temp; - intmax_t num; - int hmax; - - temp = get_string_value (name); - - if (temp && *temp) - { - if (legal_number (temp, &num)) - { - hmax = num; - if (hmax < 0 && name[4] == 'S') - unstifle_history (); /* unstifle history if HISTSIZE < 0 */ - else if (name[4] == 'S') - { - stifle_history (hmax); - hmax = where_history (); - if (history_lines_this_session > hmax) - history_lines_this_session = hmax; - } - else if (hmax >= 0) /* truncate HISTFILE if HISTFILESIZE >= 0 */ - { - history_truncate_file (get_string_value ("HISTFILE"), hmax); - /* If we just shrank the history file to fewer lines than we've - already read, make sure we adjust our idea of how many lines - we have read from the file. */ - if (hmax < history_lines_in_file) - history_lines_in_file = hmax; - } - } - } - else if (name[4] == 'S') - unstifle_history (); -} - -/* What to do after the HISTIGNORE variable changes. */ -void -sv_histignore (name) - char *name; -{ - setup_history_ignore (name); -} - -/* What to do after the HISTCONTROL variable changes. */ -void -sv_history_control (name) - char *name; -{ - char *temp; - char *val; - int tptr; - - history_control = 0; - temp = get_string_value (name); - - if (temp == 0 || *temp == 0) - return; - - tptr = 0; - while (val = extract_colon_unit (temp, &tptr)) - { - if (STREQ (val, "ignorespace")) - history_control |= HC_IGNSPACE; - else if (STREQ (val, "ignoredups")) - history_control |= HC_IGNDUPS; - else if (STREQ (val, "ignoreboth")) - history_control |= HC_IGNBOTH; - else if (STREQ (val, "erasedups")) - history_control |= HC_ERASEDUPS; - - free (val); - } -} - -#if defined (BANG_HISTORY) -/* Setting/unsetting of the history expansion character. */ -void -sv_histchars (name) - char *name; -{ - char *temp; - - temp = get_string_value (name); - if (temp) - { - history_expansion_char = *temp; - if (temp[0] && temp[1]) - { - history_subst_char = temp[1]; - if (temp[2]) - history_comment_char = temp[2]; - } - } - else - { - history_expansion_char = '!'; - history_subst_char = '^'; - history_comment_char = '#'; - } -} -#endif /* BANG_HISTORY */ - -void -sv_histtimefmt (name) - char *name; -{ - SHELL_VAR *v; - - if (v = find_variable (name)) - { - if (history_comment_char == 0) - history_comment_char = '#'; - } - history_write_timestamps = (v != 0); -} -#endif /* HISTORY */ - -#if defined (HAVE_TZSET) -void -sv_tz (name) - char *name; -{ - SHELL_VAR *v; - - v = find_variable (name); - if (v && exported_p (v)) - array_needs_making = 1; - else if (v == 0) - array_needs_making = 1; - - if (array_needs_making) - { - maybe_make_export_env (); - tzset (); - } -} -#endif - -/* If the variable exists, then the value of it can be the number - of times we actually ignore the EOF. The default is small, - (smaller than csh, anyway). */ -void -sv_ignoreeof (name) - char *name; -{ - SHELL_VAR *tmp_var; - char *temp; - - eof_encountered = 0; - - tmp_var = find_variable (name); - ignoreeof = tmp_var && var_isset (tmp_var); - temp = tmp_var ? value_cell (tmp_var) : (char *)NULL; - if (temp) - eof_encountered_limit = (*temp && all_digits (temp)) ? atoi (temp) : 10; - set_shellopts (); /* make sure `ignoreeof' is/is not in $SHELLOPTS */ -} - -void -sv_optind (name) - char *name; -{ - SHELL_VAR *var; - char *tt; - int s; - - var = find_variable ("OPTIND"); - tt = var ? get_variable_value (var) : (char *)NULL; - - /* Assume that if var->context < variable_context and variable_context > 0 - then we are restoring the variables's previous state while returning - from a function. */ - if (tt && *tt) - { - s = atoi (tt); - - /* According to POSIX, setting OPTIND=1 resets the internal state - of getopt (). */ - if (s < 0 || s == 1) - s = 0; - } - else - s = 0; - getopts_reset (s); -} - -void -sv_opterr (name) - char *name; -{ - char *tt; - - tt = get_string_value ("OPTERR"); - sh_opterr = (tt && *tt) ? atoi (tt) : 1; -} - -void -sv_strict_posix (name) - char *name; -{ - SHELL_VAR *var; - - var = find_variable (name); - posixly_correct = var && var_isset (var); - posix_initialize (posixly_correct); -#if defined (READLINE) - if (interactive_shell) - posix_readline_initialize (posixly_correct); -#endif /* READLINE */ - set_shellopts (); /* make sure `posix' is/is not in $SHELLOPTS */ -} - -void -sv_locale (name) - char *name; -{ - char *v; - int r; - - v = get_string_value (name); - if (name[0] == 'L' && name[1] == 'A') /* LANG */ - r = set_lang (name, v); - else - r = set_locale_var (name, v); /* LC_*, TEXTDOMAIN* */ - -#if 1 - if (r == 0 && posixly_correct) - set_exit_status (EXECUTION_FAILURE); -#endif -} - -#if defined (ARRAY_VARS) -void -set_pipestatus_array (ps, nproc) - int *ps; - int nproc; -{ - SHELL_VAR *v; - ARRAY *a; - ARRAY_ELEMENT *ae; - register int i; - char *t, tbuf[INT_STRLEN_BOUND(int) + 1]; - - v = find_variable ("PIPESTATUS"); - if (v == 0) - v = make_new_array_variable ("PIPESTATUS"); - if (array_p (v) == 0) - return; /* Do nothing if not an array variable. */ - a = array_cell (v); - - if (a == 0 || array_num_elements (a) == 0) - { - for (i = 0; i < nproc; i++) /* was ps[i] != -1, not i < nproc */ - { - t = inttostr (ps[i], tbuf, sizeof (tbuf)); - array_insert (a, i, t); - } - return; - } - - /* Fast case */ - if (array_num_elements (a) == nproc && nproc == 1) - { -#ifndef ALT_ARRAY_IMPLEMENTATION - ae = element_forw (a->head); -#else - ae = a->elements[0]; -#endif - ARRAY_ELEMENT_REPLACE (ae, itos (ps[0])); - } - else if (array_num_elements (a) <= nproc) - { - /* modify in array_num_elements members in place, then add */ -#ifndef ALT_ARRAY_IMPLEMENTATION - ae = a->head; -#endif - for (i = 0; i < array_num_elements (a); i++) - { -#ifndef ALT_ARRAY_IMPLEMENTATION - ae = element_forw (ae); -#else - ae = a->elements[i]; -#endif - ARRAY_ELEMENT_REPLACE (ae, itos (ps[i])); - } - /* add any more */ - for ( ; i < nproc; i++) - { - t = inttostr (ps[i], tbuf, sizeof (tbuf)); - array_insert (a, i, t); - } - } - else - { -#ifndef ALT_ARRAY_IMPLEMENTATION - /* deleting elements. it's faster to rebuild the array. */ - array_flush (a); - for (i = 0; i < nproc; i++) - { - t = inttostr (ps[i], tbuf, sizeof (tbuf)); - array_insert (a, i, t); - } -#else - /* deleting elements. replace the first NPROC, free the rest */ - for (i = 0; i < nproc; i++) - { - ae = a->elements[i]; - ARRAY_ELEMENT_REPLACE (ae, itos (ps[i])); - } - for ( ; i <= array_max_index (a); i++) - { - array_dispose_element (a->elements[i]); - a->elements[i] = (ARRAY_ELEMENT *)NULL; - } - - /* bookkeeping usually taken care of by array_insert */ - set_max_index (a, nproc - 1); - set_first_index (a, 0); - set_num_elements (a, nproc); -#endif /* ALT_ARRAY_IMPLEMENTATION */ - } -} - -ARRAY * -save_pipestatus_array () -{ - SHELL_VAR *v; - ARRAY *a; - - v = find_variable ("PIPESTATUS"); - if (v == 0 || array_p (v) == 0 || array_cell (v) == 0) - return ((ARRAY *)NULL); - - a = array_copy (array_cell (v)); - - return a; -} - -void -restore_pipestatus_array (a) - ARRAY *a; -{ - SHELL_VAR *v; - ARRAY *a2; - - v = find_variable ("PIPESTATUS"); - /* XXX - should we still assign even if existing value is NULL? */ - if (v == 0 || array_p (v) == 0 || array_cell (v) == 0) - return; - - a2 = array_cell (v); - var_setarray (v, a); - - array_dispose (a2); -} -#endif - -void -set_pipestatus_from_exit (s) - int s; -{ -#if defined (ARRAY_VARS) - static int v[2] = { 0, -1 }; - - v[0] = s; - set_pipestatus_array (v, 1); -#endif -} - -void -sv_xtracefd (name) - char *name; -{ - SHELL_VAR *v; - char *t, *e; - int fd; - FILE *fp; - - v = find_variable (name); - if (v == 0) - { - xtrace_reset (); - return; - } - - t = value_cell (v); - if (t == 0 || *t == 0) - xtrace_reset (); - else - { - fd = (int)strtol (t, &e, 10); - if (e != t && *e == '\0' && sh_validfd (fd)) - { - fp = fdopen (fd, "w"); - if (fp == 0) - internal_error (_("%s: %s: cannot open as FILE"), name, value_cell (v)); - else - xtrace_set (fd, fp); - } - else - internal_error (_("%s: %s: invalid value for trace file descriptor"), name, value_cell (v)); - } -} - -#define MIN_COMPAT_LEVEL 31 - -void -sv_shcompat (name) - char *name; -{ - SHELL_VAR *v; - char *val; - int tens, ones, compatval; - - v = find_variable (name); - if (v == 0) - { - shell_compatibility_level = DEFAULT_COMPAT_LEVEL; - set_compatibility_opts (); - return; - } - val = value_cell (v); - if (val == 0 || *val == '\0') - { - shell_compatibility_level = DEFAULT_COMPAT_LEVEL; - set_compatibility_opts (); - return; - } - /* Handle decimal-like compatibility version specifications: 4.2 */ - if (ISDIGIT (val[0]) && val[1] == '.' && ISDIGIT (val[2]) && val[3] == 0) - { - tens = val[0] - '0'; - ones = val[2] - '0'; - compatval = tens*10 + ones; - } - /* Handle integer-like compatibility version specifications: 42 */ - else if (ISDIGIT (val[0]) && ISDIGIT (val[1]) && val[2] == 0) - { - tens = val[0] - '0'; - ones = val[1] - '0'; - compatval = tens*10 + ones; - } - else - { -compat_error: - internal_error (_("%s: %s: compatibility value out of range"), name, val); - shell_compatibility_level = DEFAULT_COMPAT_LEVEL; - set_compatibility_opts (); - return; - } - - if (compatval < MIN_COMPAT_LEVEL || compatval > DEFAULT_COMPAT_LEVEL) - goto compat_error; - - shell_compatibility_level = compatval; - set_compatibility_opts (); -} - -#if defined (JOB_CONTROL) -void -sv_childmax (name) - char *name; -{ - char *tt; - int s; - - tt = get_string_value (name); - s = (tt && *tt) ? atoi (tt) : 0; - set_maxchild (s); -} -#endif diff --git a/third_party/bash/variables.h b/third_party/bash/variables.h deleted file mode 100644 index 55f497de0..000000000 --- a/third_party/bash/variables.h +++ /dev/null @@ -1,462 +0,0 @@ -/* variables.h -- data structures for shell variables. */ - -/* Copyright (C) 1987-2022 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_VARIABLES_H_) -#define _VARIABLES_H_ - -#include "stdc.h" -#include "array.h" -#include "assoc.h" - -/* Shell variables and functions are stored in hash tables. */ -#include "hashlib.h" - -#include "conftypes.h" - -/* A variable context. */ -typedef struct var_context { - char *name; /* empty or NULL means global context */ - int scope; /* 0 means global context */ - int flags; - struct var_context *up; /* previous function calls */ - struct var_context *down; /* down towards global context */ - HASH_TABLE *table; /* variables at this scope */ -} VAR_CONTEXT; - -/* Flags for var_context->flags */ -#define VC_HASLOCAL 0x01 -#define VC_HASTMPVAR 0x02 -#define VC_FUNCENV 0x04 /* also function if name != NULL */ -#define VC_BLTNENV 0x08 /* builtin_env */ -#define VC_TEMPENV 0x10 /* temporary_env */ - -#define VC_TEMPFLAGS (VC_FUNCENV|VC_BLTNENV|VC_TEMPENV) - -/* Accessing macros */ -#define vc_isfuncenv(vc) (((vc)->flags & VC_FUNCENV) != 0) -#define vc_isbltnenv(vc) (((vc)->flags & VC_BLTNENV) != 0) -#define vc_istempenv(vc) (((vc)->flags & (VC_TEMPFLAGS)) == VC_TEMPENV) - -#define vc_istempscope(vc) (((vc)->flags & (VC_TEMPENV|VC_BLTNENV)) != 0) - -#define vc_haslocals(vc) (((vc)->flags & VC_HASLOCAL) != 0) -#define vc_hastmpvars(vc) (((vc)->flags & VC_HASTMPVAR) != 0) - -/* What a shell variable looks like. */ - -typedef struct variable *sh_var_value_func_t PARAMS((struct variable *)); -typedef struct variable *sh_var_assign_func_t PARAMS((struct variable *, char *, arrayind_t, char *)); - -/* For the future */ -union _value { - char *s; /* string value */ - intmax_t i; /* int value */ - COMMAND *f; /* function */ - ARRAY *a; /* array */ - HASH_TABLE *h; /* associative array */ - double d; /* floating point number */ -#if defined (HAVE_LONG_DOUBLE) - long double ld; /* long double */ -#endif - struct variable *v; /* possible indirect variable use */ - void *opaque; /* opaque data for future use */ -}; - -typedef struct variable { - char *name; /* Symbol that the user types. */ - char *value; /* Value that is returned. */ - char *exportstr; /* String for the environment. */ - sh_var_value_func_t *dynamic_value; /* Function called to return a `dynamic' - value for a variable, like $SECONDS - or $RANDOM. */ - sh_var_assign_func_t *assign_func; /* Function called when this `special - variable' is assigned a value in - bind_variable. */ - int attributes; /* export, readonly, array, invisible... */ - int context; /* Which context this variable belongs to. */ -} SHELL_VAR; - -typedef struct _vlist { - SHELL_VAR **list; - int list_size; /* allocated size */ - int list_len; /* current number of entries */ -} VARLIST; - -/* The various attributes that a given variable can have. */ -/* First, the user-visible attributes */ -#define att_exported 0x0000001 /* export to environment */ -#define att_readonly 0x0000002 /* cannot change */ -#define att_array 0x0000004 /* value is an array */ -#define att_function 0x0000008 /* value is a function */ -#define att_integer 0x0000010 /* internal representation is int */ -#define att_local 0x0000020 /* variable is local to a function */ -#define att_assoc 0x0000040 /* variable is an associative array */ -#define att_trace 0x0000080 /* function is traced with DEBUG trap */ -#define att_uppercase 0x0000100 /* word converted to uppercase on assignment */ -#define att_lowercase 0x0000200 /* word converted to lowercase on assignment */ -#define att_capcase 0x0000400 /* word capitalized on assignment */ -#define att_nameref 0x0000800 /* word is a name reference */ - -#define user_attrs (att_exported|att_readonly|att_integer|att_local|att_trace|att_uppercase|att_lowercase|att_capcase|att_nameref) - -#define attmask_user 0x0000fff - -/* Internal attributes used for bookkeeping */ -#define att_invisible 0x0001000 /* cannot see */ -#define att_nounset 0x0002000 /* cannot unset */ -#define att_noassign 0x0004000 /* assignment not allowed */ -#define att_imported 0x0008000 /* came from environment */ -#define att_special 0x0010000 /* requires special handling */ -#define att_nofree 0x0020000 /* do not free value on unset */ -#define att_regenerate 0x0040000 /* regenerate when exported */ - -#define attmask_int 0x00ff000 - -/* Internal attributes used for variable scoping. */ -#define att_tempvar 0x0100000 /* variable came from the temp environment */ -#define att_propagate 0x0200000 /* propagate to previous scope */ - -#define attmask_scope 0x0f00000 - -#define exported_p(var) ((((var)->attributes) & (att_exported))) -#define readonly_p(var) ((((var)->attributes) & (att_readonly))) -#define array_p(var) ((((var)->attributes) & (att_array))) -#define function_p(var) ((((var)->attributes) & (att_function))) -#define integer_p(var) ((((var)->attributes) & (att_integer))) -#define local_p(var) ((((var)->attributes) & (att_local))) -#define assoc_p(var) ((((var)->attributes) & (att_assoc))) -#define trace_p(var) ((((var)->attributes) & (att_trace))) -#define uppercase_p(var) ((((var)->attributes) & (att_uppercase))) -#define lowercase_p(var) ((((var)->attributes) & (att_lowercase))) -#define capcase_p(var) ((((var)->attributes) & (att_capcase))) -#define nameref_p(var) ((((var)->attributes) & (att_nameref))) - -#define invisible_p(var) ((((var)->attributes) & (att_invisible))) -#define non_unsettable_p(var) ((((var)->attributes) & (att_nounset))) -#define noassign_p(var) ((((var)->attributes) & (att_noassign))) -#define imported_p(var) ((((var)->attributes) & (att_imported))) -#define specialvar_p(var) ((((var)->attributes) & (att_special))) -#define nofree_p(var) ((((var)->attributes) & (att_nofree))) -#define regen_p(var) ((((var)->attributes) & (att_regenerate))) - -#define tempvar_p(var) ((((var)->attributes) & (att_tempvar))) -#define propagate_p(var) ((((var)->attributes) & (att_propagate))) - -/* Variable names: lvalues */ -#define name_cell(var) ((var)->name) - -/* Accessing variable values: rvalues */ -#define value_cell(var) ((var)->value) -#define function_cell(var) (COMMAND *)((var)->value) -#define array_cell(var) (ARRAY *)((var)->value) -#define assoc_cell(var) (HASH_TABLE *)((var)->value) -#define nameref_cell(var) ((var)->value) /* so it can change later */ - -#define NAMEREF_MAX 8 /* only 8 levels of nameref indirection */ - -#define var_isset(var) ((var)->value != 0) -#define var_isunset(var) ((var)->value == 0) -#define var_isnull(var) ((var)->value && *(var)->value == 0) - -/* Assigning variable values: lvalues */ -#define var_setvalue(var, str) ((var)->value = (str)) -#define var_setfunc(var, func) ((var)->value = (char *)(func)) -#define var_setarray(var, arr) ((var)->value = (char *)(arr)) -#define var_setassoc(var, arr) ((var)->value = (char *)(arr)) -#define var_setref(var, str) ((var)->value = (str)) - -/* Make VAR be auto-exported. */ -#define set_auto_export(var) \ - do { (var)->attributes |= att_exported; array_needs_making = 1; } while (0) - -#define SETVARATTR(var, attr, undo) \ - ((undo == 0) ? ((var)->attributes |= (attr)) \ - : ((var)->attributes &= ~(attr))) - -#define VSETATTR(var, attr) ((var)->attributes |= (attr)) -#define VUNSETATTR(var, attr) ((var)->attributes &= ~(attr)) - -#define VGETFLAGS(var) ((var)->attributes) - -#define VSETFLAGS(var, flags) ((var)->attributes = (flags)) -#define VCLRFLAGS(var) ((var)->attributes = 0) - -/* Macros to perform various operations on `exportstr' member of a SHELL_VAR. */ -#define CLEAR_EXPORTSTR(var) (var)->exportstr = (char *)NULL -#define COPY_EXPORTSTR(var) ((var)->exportstr) ? savestring ((var)->exportstr) : (char *)NULL -#define SET_EXPORTSTR(var, value) (var)->exportstr = (value) -#define SAVE_EXPORTSTR(var, value) (var)->exportstr = (value) ? savestring (value) : (char *)NULL - -#define FREE_EXPORTSTR(var) \ - do { if ((var)->exportstr) free ((var)->exportstr); } while (0) - -#define CACHE_IMPORTSTR(var, value) \ - (var)->exportstr = savestring (value) - -#define INVALIDATE_EXPORTSTR(var) \ - do { \ - if ((var)->exportstr) \ - { \ - free ((var)->exportstr); \ - (var)->exportstr = (char *)NULL; \ - } \ - } while (0) - -#define ifsname(s) ((s)[0] == 'I' && (s)[1] == 'F' && (s)[2] == 'S' && (s)[3] == '\0') - -/* Flag values for make_local_variable and its array counterparts */ -#define MKLOC_ASSOCOK 0x01 -#define MKLOC_ARRAYOK 0x02 -#define MKLOC_INHERIT 0x04 - -/* Special value for nameref with invalid value for creation or assignment */ -extern SHELL_VAR nameref_invalid_value; -#define INVALID_NAMEREF_VALUE (void *)&nameref_invalid_value - -/* Stuff for hacking variables. */ -typedef int sh_var_map_func_t PARAMS((SHELL_VAR *)); - -/* Where we keep the variables and functions */ -extern VAR_CONTEXT *global_variables; -extern VAR_CONTEXT *shell_variables; - -extern HASH_TABLE *shell_functions; -extern HASH_TABLE *temporary_env; - -extern int variable_context; -extern char *dollar_vars[]; -extern char **export_env; - -extern int tempenv_assign_error; -extern int array_needs_making; -extern int shell_level; - -/* XXX */ -extern WORD_LIST *rest_of_args; -extern int posparam_count; -extern pid_t dollar_dollar_pid; - -extern int localvar_inherit; /* declared in variables.c */ - -extern void initialize_shell_variables PARAMS((char **, int)); - -extern int validate_inherited_value PARAMS((SHELL_VAR *, int)); - -extern SHELL_VAR *set_if_not PARAMS((char *, char *)); - -extern void sh_set_lines_and_columns PARAMS((int, int)); -extern void set_pwd PARAMS((void)); -extern void set_ppid PARAMS((void)); -extern void make_funcname_visible PARAMS((int)); - -extern SHELL_VAR *var_lookup PARAMS((const char *, VAR_CONTEXT *)); - -extern SHELL_VAR *find_function PARAMS((const char *)); -extern FUNCTION_DEF *find_function_def PARAMS((const char *)); -extern SHELL_VAR *find_variable PARAMS((const char *)); -extern SHELL_VAR *find_variable_noref PARAMS((const char *)); -extern SHELL_VAR *find_variable_last_nameref PARAMS((const char *, int)); -extern SHELL_VAR *find_global_variable_last_nameref PARAMS((const char *, int)); -extern SHELL_VAR *find_variable_nameref PARAMS((SHELL_VAR *)); -extern SHELL_VAR *find_variable_nameref_for_create PARAMS((const char *, int)); -extern SHELL_VAR *find_variable_nameref_for_assignment PARAMS((const char *, int)); -/*extern SHELL_VAR *find_variable_internal PARAMS((const char *, int));*/ -extern SHELL_VAR *find_variable_tempenv PARAMS((const char *)); -extern SHELL_VAR *find_variable_notempenv PARAMS((const char *)); -extern SHELL_VAR *find_global_variable PARAMS((const char *)); -extern SHELL_VAR *find_global_variable_noref PARAMS((const char *)); -extern SHELL_VAR *find_shell_variable PARAMS((const char *)); -extern SHELL_VAR *find_tempenv_variable PARAMS((const char *)); -extern SHELL_VAR *find_variable_no_invisible PARAMS((const char *)); -extern SHELL_VAR *find_variable_for_assignment PARAMS((const char *)); -extern char *nameref_transform_name PARAMS((char *, int)); -extern SHELL_VAR *copy_variable PARAMS((SHELL_VAR *)); -extern SHELL_VAR *make_local_variable PARAMS((const char *, int)); -extern SHELL_VAR *bind_variable PARAMS((const char *, char *, int)); -extern SHELL_VAR *bind_global_variable PARAMS((const char *, char *, int)); -extern SHELL_VAR *bind_function PARAMS((const char *, COMMAND *)); - -extern void bind_function_def PARAMS((const char *, FUNCTION_DEF *, int)); - -extern SHELL_VAR **map_over PARAMS((sh_var_map_func_t *, VAR_CONTEXT *)); -SHELL_VAR **map_over_funcs PARAMS((sh_var_map_func_t *)); - -extern SHELL_VAR **all_shell_variables PARAMS((void)); -extern SHELL_VAR **all_shell_functions PARAMS((void)); -extern SHELL_VAR **all_visible_variables PARAMS((void)); -extern SHELL_VAR **all_visible_functions PARAMS((void)); -extern SHELL_VAR **all_exported_variables PARAMS((void)); -extern SHELL_VAR **local_exported_variables PARAMS((void)); -extern SHELL_VAR **all_local_variables PARAMS((int)); -#if defined (ARRAY_VARS) -extern SHELL_VAR **all_array_variables PARAMS((void)); -#endif -extern char **all_variables_matching_prefix PARAMS((const char *)); - -extern char **make_var_array PARAMS((HASH_TABLE *)); -extern char **add_or_supercede_exported_var PARAMS((char *, int)); - -extern char *get_variable_value PARAMS((SHELL_VAR *)); -extern char *get_string_value PARAMS((const char *)); -extern char *sh_get_env_value PARAMS((const char *)); -extern char *make_variable_value PARAMS((SHELL_VAR *, char *, int)); - -extern SHELL_VAR *bind_variable_value PARAMS((SHELL_VAR *, char *, int)); -extern SHELL_VAR *bind_int_variable PARAMS((char *, char *, int)); -extern SHELL_VAR *bind_var_to_int PARAMS((char *, intmax_t, int)); - -extern int assign_in_env PARAMS((WORD_DESC *, int)); - -extern int unbind_variable PARAMS((const char *)); -extern int check_unbind_variable PARAMS((const char *)); -extern int unbind_nameref PARAMS((const char *)); -extern int unbind_variable_noref PARAMS((const char *)); -extern int unbind_global_variable PARAMS((const char *)); -extern int unbind_global_variable_noref PARAMS((const char *)); -extern int unbind_func PARAMS((const char *)); -extern int unbind_function_def PARAMS((const char *)); -extern int delete_var PARAMS((const char *, VAR_CONTEXT *)); -extern int makunbound PARAMS((const char *, VAR_CONTEXT *)); -extern int kill_local_variable PARAMS((const char *)); - -extern void delete_all_variables PARAMS((HASH_TABLE *)); -extern void delete_all_contexts PARAMS((VAR_CONTEXT *)); -extern void reset_local_contexts PARAMS((void)); - -extern VAR_CONTEXT *new_var_context PARAMS((char *, int)); -extern void dispose_var_context PARAMS((VAR_CONTEXT *)); -extern VAR_CONTEXT *push_var_context PARAMS((char *, int, HASH_TABLE *)); -extern void pop_var_context PARAMS((void)); -extern VAR_CONTEXT *push_scope PARAMS((int, HASH_TABLE *)); -extern void pop_scope PARAMS((int)); - -extern void clear_dollar_vars PARAMS((void)); - -extern void push_context PARAMS((char *, int, HASH_TABLE *)); -extern void pop_context PARAMS((void)); -extern void push_dollar_vars PARAMS((void)); -extern void pop_dollar_vars PARAMS((void)); -extern void dispose_saved_dollar_vars PARAMS((void)); - -extern void init_bash_argv PARAMS((void)); -extern void save_bash_argv PARAMS((void)); -extern void push_args PARAMS((WORD_LIST *)); -extern void pop_args PARAMS((void)); - -extern void adjust_shell_level PARAMS((int)); -extern void non_unsettable PARAMS((char *)); -extern void dispose_variable PARAMS((SHELL_VAR *)); -extern void dispose_used_env_vars PARAMS((void)); -extern void dispose_function_env PARAMS((void)); -extern void dispose_builtin_env PARAMS((void)); -extern void merge_temporary_env PARAMS((void)); -extern void flush_temporary_env PARAMS((void)); -extern void merge_builtin_env PARAMS((void)); -extern void kill_all_local_variables PARAMS((void)); - -extern void set_var_read_only PARAMS((char *)); -extern void set_func_read_only PARAMS((const char *)); -extern void set_var_auto_export PARAMS((char *)); -extern void set_func_auto_export PARAMS((const char *)); - -extern void sort_variables PARAMS((SHELL_VAR **)); - -extern int chkexport PARAMS((char *)); -extern void maybe_make_export_env PARAMS((void)); -extern void update_export_env_inplace PARAMS((char *, int, char *)); -extern void put_command_name_into_env PARAMS((char *)); -extern void put_gnu_argv_flags_into_env PARAMS((intmax_t, char *)); - -extern void print_var_list PARAMS((SHELL_VAR **)); -extern void print_func_list PARAMS((SHELL_VAR **)); -extern void print_assignment PARAMS((SHELL_VAR *)); -extern void print_var_value PARAMS((SHELL_VAR *, int)); -extern void print_var_function PARAMS((SHELL_VAR *)); - -#if defined (ARRAY_VARS) -extern SHELL_VAR *make_new_array_variable PARAMS((char *)); -extern SHELL_VAR *make_local_array_variable PARAMS((char *, int)); - -extern SHELL_VAR *make_new_assoc_variable PARAMS((char *)); -extern SHELL_VAR *make_local_assoc_variable PARAMS((char *, int)); - -extern void set_pipestatus_array PARAMS((int *, int)); -extern ARRAY *save_pipestatus_array PARAMS((void)); -extern void restore_pipestatus_array PARAMS((ARRAY *)); -#endif - -extern void set_pipestatus_from_exit PARAMS((int)); - -/* The variable in NAME has just had its state changed. Check to see if it - is one of the special ones where something special happens. */ -extern void stupidly_hack_special_variables PARAMS((char *)); - -/* Reinitialize some special variables that have external effects upon unset - when the shell reinitializes itself. */ -extern void reinit_special_variables PARAMS((void)); - -extern int get_random_number PARAMS((void)); - -/* The `special variable' functions that get called when a particular - variable is set. */ -extern void sv_ifs PARAMS((char *)); -extern void sv_path PARAMS((char *)); -extern void sv_mail PARAMS((char *)); -extern void sv_funcnest PARAMS((char *)); -extern void sv_execignore PARAMS((char *)); -extern void sv_globignore PARAMS((char *)); -extern void sv_ignoreeof PARAMS((char *)); -extern void sv_strict_posix PARAMS((char *)); -extern void sv_optind PARAMS((char *)); -extern void sv_opterr PARAMS((char *)); -extern void sv_locale PARAMS((char *)); -extern void sv_xtracefd PARAMS((char *)); -extern void sv_shcompat PARAMS((char *)); - -#if defined (READLINE) -extern void sv_comp_wordbreaks PARAMS((char *)); -extern void sv_terminal PARAMS((char *)); -extern void sv_hostfile PARAMS((char *)); -extern void sv_winsize PARAMS((char *)); -#endif - -#if defined (__CYGWIN__) -extern void sv_home PARAMS((char *)); -#endif - -#if defined (HISTORY) -extern void sv_histsize PARAMS((char *)); -extern void sv_histignore PARAMS((char *)); -extern void sv_history_control PARAMS((char *)); -# if defined (BANG_HISTORY) -extern void sv_histchars PARAMS((char *)); -# endif -extern void sv_histtimefmt PARAMS((char *)); -#endif /* HISTORY */ - -#if defined (HAVE_TZSET) -extern void sv_tz PARAMS((char *)); -#endif - -#if defined (JOB_CONTROL) -extern void sv_childmax PARAMS((char *)); -#endif - -#endif /* !_VARIABLES_H_ */ diff --git a/third_party/bash/version.c b/third_party/bash/version.c deleted file mode 100644 index 38af8edca..000000000 --- a/third_party/bash/version.c +++ /dev/null @@ -1,94 +0,0 @@ -/* version.c -- distribution and version numbers. */ - -/* Copyright (C) 1989-2022 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include - -#include "stdc.h" - -#include "version.h" -#include "patchlevel.h" -#include "conftypes.h" - -#include "bashintl.h" - -extern char *shell_name; - -/* Defines from version.h */ -const char * const dist_version = DISTVERSION; -const int patch_level = PATCHLEVEL; -const int build_version = BUILDVERSION; -#ifdef RELSTATUS -const char * const release_status = RELSTATUS; -#else -const char * const release_status = (char *)0; -#endif -const char * const sccs_version = SCCSVERSION; - -const char * const bash_copyright = N_("Copyright (C) 2022 Free Software Foundation, Inc."); -const char * const bash_license = N_("License GPLv3+: GNU GPL version 3 or later \n"); - -/* If == 31, shell compatible with bash-3.1, == 32 with bash-3.2, and so on */ -int shell_compatibility_level = DEFAULT_COMPAT_LEVEL; - -/* Functions for getting, setting, and displaying the shell version. */ - -/* Forward declarations so we don't have to include externs.h */ -extern char *shell_version_string PARAMS((void)); -extern void show_shell_version PARAMS((int)); - -/* Give version information about this shell. */ -char * -shell_version_string () -{ - static char tt[32] = { '\0' }; - - if (tt[0] == '\0') - { - if (release_status) -#if HAVE_SNPRINTF - snprintf (tt, sizeof (tt), "%s.%d(%d)-%s", dist_version, patch_level, build_version, release_status); -#else - sprintf (tt, "%s.%d(%d)-%s", dist_version, patch_level, build_version, release_status); -#endif - else -#if HAVE_SNPRINTF - snprintf (tt, sizeof (tt), "%s.%d(%d)", dist_version, patch_level, build_version); -#else - sprintf (tt, "%s.%d(%d)", dist_version, patch_level, build_version); -#endif - } - return tt; -} - -void -show_shell_version (extended) - int extended; -{ - printf (_("GNU bash, version %s (%s)\n"), shell_version_string (), MACHTYPE); - if (extended) - { - printf ("%s\n", _(bash_copyright)); - printf ("%s\n", _(bash_license)); - printf ("%s\n", _("This is free software; you are free to change and redistribute it.")); - printf ("%s\n", _("There is NO WARRANTY, to the extent permitted by law.")); - } -} diff --git a/third_party/bash/version.h b/third_party/bash/version.h deleted file mode 100644 index 1a749cdbe..000000000 --- a/third_party/bash/version.h +++ /dev/null @@ -1,17 +0,0 @@ -/* Version control for the shell. This file gets changed when you say - `make version.h' to the Makefile. It is created by mkversion. */ - -/* The distribution version number of this shell. */ -#define DISTVERSION "5.2" - -/* The last built version of this shell. */ -#define BUILDVERSION 1 - -/* The release status of this shell. */ -#define RELSTATUS "release" - -/* The default shell compatibility-level (the current version) */ -#define DEFAULT_COMPAT_LEVEL 52 - -/* A version string for use by sccs and the what command. */ -#define SCCSVERSION "@(#)Bash version 5.2.0(1) release GNU" diff --git a/third_party/bash/winsize.c b/third_party/bash/winsize.c deleted file mode 100644 index e672a324d..000000000 --- a/third_party/bash/winsize.c +++ /dev/null @@ -1,104 +0,0 @@ -/* winsize.c - handle window size changes and information. */ - -/* Copyright (C) 2005-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include "stdc.h" - -#include "bashtypes.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include - -/* Try to find the definitions of `struct winsize' and TIOGCWINSZ */ - -#if 0 -#if defined (GWINSZ_IN_SYS_IOCTL) && !defined (TIOCGWINSZ) -# include -#endif /* GWINSZ_IN_SYS_IOCTL && !TIOCGWINSZ */ -#endif - -#if defined (STRUCT_WINSIZE_IN_TERMIOS) && !defined (STRUCT_WINSIZE_IN_SYS_IOCTL) -# include -#endif /* STRUCT_WINSIZE_IN_TERMIOS && !STRUCT_WINSIZE_IN_SYS_IOCTL */ - -/* Not in either of the standard places, look around. */ -#if !defined (STRUCT_WINSIZE_IN_TERMIOS) && !defined (STRUCT_WINSIZE_IN_SYS_IOCTL) -# if defined (HAVE_SYS_STREAM_H) -# include -# endif /* HAVE_SYS_STREAM_H */ -# if defined (HAVE_SYS_PTEM_H) /* SVR4.2, at least, has it here */ -# include -# define _IO_PTEM_H /* work around SVR4.2 1.1.4 bug */ -# endif /* HAVE_SYS_PTEM_H */ -# if defined (HAVE_SYS_PTE_H) /* ??? */ -# include -# endif /* HAVE_SYS_PTE_H */ -#endif /* !STRUCT_WINSIZE_IN_TERMIOS && !STRUCT_WINSIZE_IN_SYS_IOCTL */ - -#include - -/* Return the fd from which we are actually getting input. */ -#define input_tty() (shell_tty != -1) ? shell_tty : fileno (stderr) - -#if !defined (errno) -extern int errno; -#endif /* !errno */ - -extern int shell_tty; - -#if defined (READLINE) -/* Let's not call readline, forcing readline to initialize the termcap/terminfo - variables it needs, unless we have to. */ -extern int interactive_shell; -extern int no_line_editing; -extern int bash_readline_initialized; -extern void rl_set_screen_size PARAMS((int, int)); -#endif -extern void sh_set_lines_and_columns PARAMS((int, int)); - -void -get_new_window_size (from_sig, rp, cp) - int from_sig; - int *rp, *cp; -{ -#if defined (TIOCGWINSZ) - struct winsize win; - int tty; - - tty = input_tty (); - if (tty >= 0 && (ioctl (tty, TIOCGWINSZ, &win) == 0) && - win.ws_row > 0 && win.ws_col > 0) - { - sh_set_lines_and_columns (win.ws_row, win.ws_col); -#if defined (READLINE) - if ((interactive_shell && no_line_editing == 0) || bash_readline_initialized) - rl_set_screen_size (win.ws_row, win.ws_col); -#endif - if (rp) - *rp = win.ws_row; - if (cp) - *cp = win.ws_col; - } -#endif -} diff --git a/third_party/bash/xmalloc.c b/third_party/bash/xmalloc.c deleted file mode 100644 index 21b598d59..000000000 --- a/third_party/bash/xmalloc.c +++ /dev/null @@ -1,225 +0,0 @@ -/* xmalloc.c -- safe versions of malloc and realloc */ - -/* Copyright (C) 1991-2016 Free Software Foundation, Inc. - - This file is part of GNU Bash, the GNU Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if defined (HAVE_CONFIG_H) -#include "config.h" -#endif - -#include "bashtypes.h" -#include - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#if defined (HAVE_STDLIB_H) -# include -#else -# include "ansi_stdlib.h" -#endif /* HAVE_STDLIB_H */ - -#include "error.h" - -#include "bashintl.h" - -#if !defined (PTR_T) -# if defined (__STDC__) -# define PTR_T void * -# else -# define PTR_T char * -# endif /* !__STDC__ */ -#endif /* !PTR_T */ - -#if HAVE_SBRK && !HAVE_DECL_SBRK -extern char *sbrk(); -#endif - -#if HAVE_SBRK && defined (USING_BASH_MALLOC) -static PTR_T lbreak; -static int brkfound; -static size_t allocated; -#endif - -/* **************************************************************** */ -/* */ -/* Memory Allocation and Deallocation. */ -/* */ -/* **************************************************************** */ - -#if HAVE_SBRK && defined (USING_BASH_MALLOC) -#define FINDBRK() \ -do { \ - if (brkfound == 0) \ - { \ - lbreak = (PTR_T)sbrk (0); \ - brkfound++; \ - } \ -} while (0) - -static size_t -findbrk () -{ - FINDBRK(); - return (char *)sbrk (0) - (char *)lbreak; -} -#else -#define FINDBRK() -#endif - -static void -allocerr (func, bytes) - const char *func; - size_t bytes; -{ -#if HAVE_SBRK && defined (USING_BASH_MALLOC) - allocated = findbrk (); - fatal_error (_("%s: cannot allocate %lu bytes (%lu bytes allocated)"), func, (unsigned long)bytes, (unsigned long)allocated); -#else - fatal_error (_("%s: cannot allocate %lu bytes"), func, (unsigned long)bytes); -#endif /* !HAVE_SBRK */ -} - -/* Return a pointer to free()able block of memory large enough - to hold BYTES number of bytes. If the memory cannot be allocated, - print an error message and abort. */ -PTR_T -xmalloc (bytes) - size_t bytes; -{ - PTR_T temp; - -#if defined (DEBUG) - if (bytes == 0) - internal_warning("xmalloc: size argument is 0"); -#endif - - FINDBRK(); - temp = malloc (bytes); - - if (temp == 0) - allocerr ("xmalloc", bytes); - - return (temp); -} - -PTR_T -xrealloc (pointer, bytes) - PTR_T pointer; - size_t bytes; -{ - PTR_T temp; - -#if defined (DEBUG) - if (bytes == 0) - internal_warning("xrealloc: size argument is 0"); -#endif - - FINDBRK(); - temp = pointer ? realloc (pointer, bytes) : malloc (bytes); - - if (temp == 0) - allocerr ("xrealloc", bytes); - - return (temp); -} - -/* Use this as the function to call when adding unwind protects so we - don't need to know what free() returns. */ -void -xfree (string) - PTR_T string; -{ - if (string) - free (string); -} - -#ifdef USING_BASH_MALLOC -#include - -static void -sh_allocerr (func, bytes, file, line) - const char *func; - size_t bytes; - char *file; - int line; -{ -#if HAVE_SBRK - allocated = findbrk (); - fatal_error (_("%s: %s:%d: cannot allocate %lu bytes (%lu bytes allocated)"), func, file, line, (unsigned long)bytes, (unsigned long)allocated); -#else - fatal_error (_("%s: %s:%d: cannot allocate %lu bytes"), func, file, line, (unsigned long)bytes); -#endif /* !HAVE_SBRK */ -} - -PTR_T -sh_xmalloc (bytes, file, line) - size_t bytes; - char *file; - int line; -{ - PTR_T temp; - -#if defined (DEBUG) - if (bytes == 0) - internal_warning("xmalloc: %s:%d: size argument is 0", file, line); -#endif - - FINDBRK(); - temp = sh_malloc (bytes, file, line); - - if (temp == 0) - sh_allocerr ("xmalloc", bytes, file, line); - - return (temp); -} - -PTR_T -sh_xrealloc (pointer, bytes, file, line) - PTR_T pointer; - size_t bytes; - char *file; - int line; -{ - PTR_T temp; - -#if defined (DEBUG) - if (bytes == 0) - internal_warning("xrealloc: %s:%d: size argument is 0", file, line); -#endif - - FINDBRK(); - temp = pointer ? sh_realloc (pointer, bytes, file, line) : sh_malloc (bytes, file, line); - - if (temp == 0) - sh_allocerr ("xrealloc", bytes, file, line); - - return (temp); -} - -void -sh_xfree (string, file, line) - PTR_T string; - char *file; - int line; -{ - if (string) - sh_free (string, file, line); -} -#endif diff --git a/third_party/bash/xmalloc.h b/third_party/bash/xmalloc.h deleted file mode 100644 index 55d2e3d04..000000000 --- a/third_party/bash/xmalloc.h +++ /dev/null @@ -1,66 +0,0 @@ -/* xmalloc.h -- defines for the `x' memory allocation functions */ - -/* Copyright (C) 2001-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#if !defined (_XMALLOC_H_) -#define _XMALLOC_H_ - -#include "stdc.h" -#include "bashansi.h" - -/* Generic pointer type. */ -#ifndef PTR_T - -#if defined (__STDC__) -# define PTR_T void * -#else -# define PTR_T char * -#endif - -#endif /* PTR_T */ - -/* Allocation functions in xmalloc.c */ -extern PTR_T xmalloc PARAMS((size_t)); -extern PTR_T xrealloc PARAMS((void *, size_t)); -extern void xfree PARAMS((void *)); - -#if defined(USING_BASH_MALLOC) && !defined (DISABLE_MALLOC_WRAPPERS) -extern PTR_T sh_xmalloc PARAMS((size_t, const char *, int)); -extern PTR_T sh_xrealloc PARAMS((void *, size_t, const char *, int)); -extern void sh_xfree PARAMS((void *, const char *, int)); - -#define xmalloc(x) sh_xmalloc((x), __FILE__, __LINE__) -#define xrealloc(x, n) sh_xrealloc((x), (n), __FILE__, __LINE__) -#define xfree(x) sh_xfree((x), __FILE__, __LINE__) - -#ifdef free -#undef free -#endif -#define free(x) sh_xfree((x), __FILE__, __LINE__) - -extern PTR_T sh_malloc PARAMS((size_t, const char *, int)); - -#ifdef malloc -#undef malloc -#endif -#define malloc(x) sh_malloc((x), __FILE__, __LINE__) - -#endif /* USING_BASH_MALLOC */ - -#endif /* _XMALLOC_H_ */ diff --git a/third_party/bash/xmbsrtowcs.c b/third_party/bash/xmbsrtowcs.c deleted file mode 100644 index 688117885..000000000 --- a/third_party/bash/xmbsrtowcs.c +++ /dev/null @@ -1,523 +0,0 @@ -/* xmbsrtowcs.c -- replacement function for mbsrtowcs */ - -/* Copyright (C) 2002-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -/* Ask for GNU extensions to get extern declaration for mbsnrtowcs if - available via glibc. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif - -#include "config.h" - -#include "bashansi.h" - -/* , and are included in "shmbutil.h". - If , , mbsrtowcs(), exist, HANDLE_MULTIBYTE - is defined as 1. */ -#include "shmbutil.h" - -#if HANDLE_MULTIBYTE - -#include -#if !defined (errno) -extern int errno; -#endif - -#define WSBUF_INC 32 - -#ifndef FREE -# define FREE(x) do { if (x) free (x); } while (0) -#endif - -#if ! HAVE_STRCHRNUL -extern char *strchrnul PARAMS((const char *, int)); -#endif - -/* On some locales (ex. ja_JP.sjis), mbsrtowc doesn't convert 0x5c to U<0x5c>. - So, this function is made for converting 0x5c to U<0x5c>. */ - -static mbstate_t local_state; -static int local_state_use = 0; - -size_t -xmbsrtowcs (dest, src, len, pstate) - wchar_t *dest; - const char **src; - size_t len; - mbstate_t *pstate; -{ - mbstate_t *ps; - size_t mblength, wclength, n; - - ps = pstate; - if (pstate == NULL) - { - if (!local_state_use) - { - memset (&local_state, '\0', sizeof(mbstate_t)); - local_state_use = 1; - } - ps = &local_state; - } - - n = strlen (*src); - - if (dest == NULL) - { - wchar_t *wsbuf; - const char *mbs; - mbstate_t psbuf; - - /* It doesn't matter if malloc fails here, since mbsrtowcs should do - the right thing with a NULL first argument. */ - wsbuf = (wchar_t *) malloc ((n + 1) * sizeof(wchar_t)); - mbs = *src; - psbuf = *ps; - - wclength = mbsrtowcs (wsbuf, &mbs, n, &psbuf); - - if (wsbuf) - free (wsbuf); - return wclength; - } - - for (wclength = 0; wclength < len; wclength++, dest++) - { - if (mbsinit(ps)) - { - if (**src == '\0') - { - *dest = L'\0'; - *src = NULL; - return (wclength); - } - else if (**src == '\\') - { - *dest = L'\\'; - mblength = 1; - } - else - mblength = mbrtowc(dest, *src, n, ps); - } - else - mblength = mbrtowc(dest, *src, n, ps); - - /* Cannot convert multibyte character to wide character. */ - if (mblength == (size_t)-1 || mblength == (size_t)-2) - return (size_t)-1; - - *src += mblength; - n -= mblength; - - /* The multibyte string has been completely converted, - including the terminating '\0'. */ - if (*dest == L'\0') - { - *src = NULL; - break; - } - } - - return (wclength); -} - -#if HAVE_MBSNRTOWCS -/* Convert a multibyte string to a wide character string. Memory for the - new wide character string is obtained with malloc. - - Fast multiple-character version of xdupmbstowcs used when the indices are - not required and mbsnrtowcs is available. */ - -static size_t -xdupmbstowcs2 (destp, src) - wchar_t **destp; /* Store the pointer to the wide character string */ - const char *src; /* Multibyte character string */ -{ - const char *p; /* Conversion start position of src */ - wchar_t *wsbuf; /* Buffer for wide characters. */ - size_t wsbuf_size; /* Size of WSBUF */ - size_t wcnum; /* Number of wide characters in WSBUF */ - mbstate_t state; /* Conversion State */ - size_t n, wcslength; /* Number of wide characters produced by the conversion. */ - const char *end_or_backslash; - size_t nms; /* Number of multibyte characters to convert at one time. */ - mbstate_t tmp_state; - const char *tmp_p; - - memset (&state, '\0', sizeof(mbstate_t)); - - wsbuf_size = 0; - wsbuf = NULL; - - p = src; - wcnum = 0; - do - { - end_or_backslash = strchrnul(p, '\\'); - nms = end_or_backslash - p; - if (*end_or_backslash == '\0') - nms++; - - /* Compute the number of produced wide-characters. */ - tmp_p = p; - tmp_state = state; - - if (nms == 0 && *p == '\\') /* special initial case */ - nms = wcslength = 1; - else - wcslength = mbsnrtowcs (NULL, &tmp_p, nms, 0, &tmp_state); - - if (wcslength == 0) - { - tmp_p = p; /* will need below */ - tmp_state = state; - wcslength = 1; /* take a single byte */ - } - - /* Conversion failed. */ - if (wcslength == (size_t)-1) - { - free (wsbuf); - *destp = NULL; - return (size_t)-1; - } - - /* Resize the buffer if it is not large enough. */ - if (wsbuf_size < wcnum+wcslength+1) /* 1 for the L'\0' or the potential L'\\' */ - { - wchar_t *wstmp; - - while (wsbuf_size < wcnum+wcslength+1) /* 1 for the L'\0' or the potential L'\\' */ - wsbuf_size += WSBUF_INC; - - wstmp = (wchar_t *) realloc (wsbuf, wsbuf_size * sizeof (wchar_t)); - if (wstmp == NULL) - { - free (wsbuf); - *destp = NULL; - return (size_t)-1; - } - wsbuf = wstmp; - } - - /* Perform the conversion. This is assumed to return 'wcslength'. - It may set 'p' to NULL. */ - n = mbsnrtowcs(wsbuf+wcnum, &p, nms, wsbuf_size-wcnum, &state); - - if (n == 0 && p == 0) - { - wsbuf[wcnum] = L'\0'; - break; - } - - /* Compensate for taking single byte on wcs conversion failure above. */ - if (wcslength == 1 && (n == 0 || n == (size_t)-1)) - { - state = tmp_state; - p = tmp_p; - wsbuf[wcnum] = *p; - if (*p == 0) - break; - else - { - wcnum++; p++; - } - } - else - wcnum += wcslength; - - if (mbsinit (&state) && (p != NULL) && (*p == '\\')) - { - wsbuf[wcnum++] = L'\\'; - p++; - } - } - while (p != NULL); - - *destp = wsbuf; - - /* Return the length of the wide character string, not including `\0'. */ - return wcnum; -} -#endif /* HAVE_MBSNRTOWCS */ - -/* Convert a multibyte string to a wide character string. Memory for the - new wide character string is obtained with malloc. - - The return value is the length of the wide character string. Returns a - pointer to the wide character string in DESTP. If INDICESP is not NULL, - INDICESP stores the pointer to the pointer array. Each pointer is to - the first byte of each multibyte character. Memory for the pointer array - is obtained with malloc, too. - If conversion is failed, the return value is (size_t)-1 and the values - of DESTP and INDICESP are NULL. */ - -size_t -xdupmbstowcs (destp, indicesp, src) - wchar_t **destp; /* Store the pointer to the wide character string */ - char ***indicesp; /* Store the pointer to the pointer array. */ - const char *src; /* Multibyte character string */ -{ - const char *p; /* Conversion start position of src */ - wchar_t wc; /* Created wide character by conversion */ - wchar_t *wsbuf; /* Buffer for wide characters. */ - char **indices; /* Buffer for indices. */ - size_t wsbuf_size; /* Size of WSBUF */ - size_t wcnum; /* Number of wide characters in WSBUF */ - mbstate_t state; /* Conversion State */ - - /* In case SRC or DESP is NULL, conversion doesn't take place. */ - if (src == NULL || destp == NULL) - { - if (destp) - *destp = NULL; - if (indicesp) - *indicesp = NULL; - return (size_t)-1; - } - -#if HAVE_MBSNRTOWCS - if (indicesp == NULL) - return (xdupmbstowcs2 (destp, src)); -#endif - - memset (&state, '\0', sizeof(mbstate_t)); - wsbuf_size = WSBUF_INC; - - wsbuf = (wchar_t *) malloc (wsbuf_size * sizeof(wchar_t)); - if (wsbuf == NULL) - { - *destp = NULL; - if (indicesp) - *indicesp = NULL; - return (size_t)-1; - } - - indices = NULL; - if (indicesp) - { - indices = (char **) malloc (wsbuf_size * sizeof(char *)); - if (indices == NULL) - { - free (wsbuf); - *destp = NULL; - *indicesp = NULL; - return (size_t)-1; - } - } - - p = src; - wcnum = 0; - do - { - size_t mblength; /* Byte length of one multibyte character. */ - - if (mbsinit (&state)) - { - if (*p == '\0') - { - wc = L'\0'; - mblength = 1; - } - else if (*p == '\\') - { - wc = L'\\'; - mblength = 1; - } - else - mblength = mbrtowc(&wc, p, MB_LEN_MAX, &state); - } - else - mblength = mbrtowc(&wc, p, MB_LEN_MAX, &state); - - /* Conversion failed. */ - if (MB_INVALIDCH (mblength)) - { - free (wsbuf); - FREE (indices); - *destp = NULL; - if (indicesp) - *indicesp = NULL; - return (size_t)-1; - } - - ++wcnum; - - /* Resize buffers when they are not large enough. */ - if (wsbuf_size < wcnum) - { - wchar_t *wstmp; - char **idxtmp; - - wsbuf_size += WSBUF_INC; - - wstmp = (wchar_t *) realloc (wsbuf, wsbuf_size * sizeof (wchar_t)); - if (wstmp == NULL) - { - free (wsbuf); - FREE (indices); - *destp = NULL; - if (indicesp) - *indicesp = NULL; - return (size_t)-1; - } - wsbuf = wstmp; - - if (indicesp) - { - idxtmp = (char **) realloc (indices, wsbuf_size * sizeof (char *)); - if (idxtmp == NULL) - { - free (wsbuf); - free (indices); - *destp = NULL; - if (indicesp) - *indicesp = NULL; - return (size_t)-1; - } - indices = idxtmp; - } - } - - wsbuf[wcnum - 1] = wc; - if (indices) - indices[wcnum - 1] = (char *)p; - p += mblength; - } - while (MB_NULLWCH (wc) == 0); - - /* Return the length of the wide character string, not including `\0'. */ - *destp = wsbuf; - if (indicesp != NULL) - *indicesp = indices; - - return (wcnum - 1); -} - -/* Convert wide character string to multibyte character string. Treat invalid - wide characters as bytes. Used only in unusual circumstances. - - Written by Bruno Haible , 2008, adapted by Chet Ramey - for use in Bash. */ - -/* Convert wide character string *SRCP to a multibyte character string and - store the result in DEST. Store at most LEN bytes in DEST. */ -size_t -xwcsrtombs (char *dest, const wchar_t **srcp, size_t len, mbstate_t *ps) -{ - const wchar_t *src; - size_t cur_max; /* XXX - locale_cur_max */ - char buf[64], *destptr, *tmp_dest; - unsigned char uc; - mbstate_t prev_state; - - cur_max = MB_CUR_MAX; - if (cur_max > sizeof (buf)) /* Holy cow. */ - return (size_t)-1; - - src = *srcp; - - if (dest != NULL) - { - destptr = dest; - - for (; len > 0; src++) - { - wchar_t wc; - size_t ret; - - wc = *src; - /* If we have room, store directly into DEST. */ - tmp_dest = destptr; - ret = wcrtomb (len >= cur_max ? destptr : buf, wc, ps); - - if (ret == (size_t)(-1)) /* XXX */ - { - /* Since this is used for globbing and other uses of filenames, - treat invalid wide character sequences as bytes. This is - intended to be symmetric with xdupmbstowcs2. */ -handle_byte: - destptr = tmp_dest; /* in case wcrtomb modified it */ - uc = wc; - ret = 1; - if (len >= cur_max) - *destptr = uc; - else - buf[0] = uc; - if (ps) - memset (ps, 0, sizeof (mbstate_t)); - } - - if (ret > cur_max) /* Holy cow */ - goto bad_input; - - if (len < ret) - break; - - if (len < cur_max) - memcpy (destptr, buf, ret); - - if (wc == 0) - { - src = NULL; - /* Here mbsinit (ps). */ - break; - } - destptr += ret; - len -= ret; - } - *srcp = src; - return destptr - dest; - } - else - { - /* Ignore dest and len, don't store *srcp at the end, and - don't clobber *ps. */ - mbstate_t state = *ps; - size_t totalcount = 0; - - for (;; src++) - { - wchar_t wc; - size_t ret; - - wc = *src; - ret = wcrtomb (buf, wc, &state); - - if (ret == (size_t)(-1)) - goto bad_input2; - if (wc == 0) - { - /* Here mbsinit (&state). */ - break; - } - totalcount += ret; - } - return totalcount; - } - -bad_input: - *srcp = src; -bad_input2: - errno = EILSEQ; - return (size_t)(-1); -} - -#endif /* HANDLE_MULTIBYTE */ diff --git a/third_party/bash/y.tab.c b/third_party/bash/y.tab.c deleted file mode 100644 index 968b4efc3..000000000 --- a/third_party/bash/y.tab.c +++ /dev/null @@ -1,9133 +0,0 @@ -/* A Bison parser, made by GNU Bison 3.8.2. */ - -/* Bison implementation for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, - Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, - especially those whose name start with YY_ or yy_. They are - private implementation details that can be changed or removed. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output, and Bison version. */ -#define YYBISON 30802 - -/* Bison version string. */ -#define YYBISON_VERSION "3.8.2" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 0 - -/* Push parsers. */ -#define YYPUSH 0 - -/* Pull parsers. */ -#define YYPULL 1 - - - - -/* First part of user prologue. */ -#line 21 "/usr/local/src/chet/src/bash/src/parse.y" - -#include "config.h" - -#include "bashtypes.h" -#include "bashansi.h" - -#include "filecntl.h" - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#if defined (HAVE_LOCALE_H) -# include -#endif - -#include -#include "chartypes.h" -#include - -#include "memalloc.h" - -#include "bashintl.h" - -#define NEED_STRFTIME_DECL /* used in externs.h */ - -#include "shell.h" -#include "execute_cmd.h" -#include "typemax.h" /* SIZE_MAX if needed */ -#include "trap.h" -#include "flags.h" -#include "parser.h" -#include "mailcheck.h" -#include "test.h" -#include "builtins.h" -#include "common.h" -#include "builtext.h" - -#include "shmbutil.h" - -#if defined (READLINE) -# include "bashline.h" -# include "third_party/readline/readline.h" -#endif /* READLINE */ - -#if defined (HISTORY) -# include "bashhist.h" -# include "third_party/readline/history.h" -#endif /* HISTORY */ - -#if defined (JOB_CONTROL) -# include "jobs.h" -#else -extern int cleanup_dead_jobs PARAMS((void)); -#endif /* JOB_CONTROL */ - -#if defined (ALIAS) -# include "alias.h" -#else -typedef void *alias_t; -#endif /* ALIAS */ - -#if defined (PROMPT_STRING_DECODE) -# ifndef _MINIX -# include -# endif -# include -# if defined (TM_IN_SYS_TIME) -# include -# include -# endif /* TM_IN_SYS_TIME */ -# include "maxpath.h" -#endif /* PROMPT_STRING_DECODE */ - -#define RE_READ_TOKEN -99 -#define NO_EXPANSION -100 - -#define END_ALIAS -2 - -#ifdef DEBUG -# define YYDEBUG 1 -#else -# define YYDEBUG 0 -#endif - -#if defined (HANDLE_MULTIBYTE) -# define last_shell_getc_is_singlebyte \ - ((shell_input_line_index > 1) \ - ? shell_input_line_property[shell_input_line_index - 1] \ - : 1) -# define MBTEST(x) ((x) && last_shell_getc_is_singlebyte) -#else -# define last_shell_getc_is_singlebyte 1 -# define MBTEST(x) ((x)) -#endif - -#define EXTEND_SHELL_INPUT_LINE_PROPERTY() \ -do { \ - if (shell_input_line_len + 2 > shell_input_line_propsize) \ - { \ - shell_input_line_propsize = shell_input_line_len + 2; \ - shell_input_line_property = (char *)xrealloc (shell_input_line_property, \ - shell_input_line_propsize); \ - } \ -} while (0) - -#if defined (EXTENDED_GLOB) -extern int extended_glob; -#endif - -#if defined (TRANSLATABLE_STRINGS) -extern int dump_translatable_strings, dump_po_strings; -extern int singlequote_translations; -#endif /* TRANSLATABLE_STRINGS */ - -#if !defined (errno) -extern int errno; -#endif - -/* **************************************************************** */ -/* */ -/* "Forward" declarations */ -/* */ -/* **************************************************************** */ - -#ifdef DEBUG -static void debug_parser PARAMS((int)); -#endif - -static int yy_getc PARAMS((void)); -static int yy_ungetc PARAMS((int)); - -#if defined (READLINE) -static int yy_readline_get PARAMS((void)); -static int yy_readline_unget PARAMS((int)); -#endif - -static int yy_string_get PARAMS((void)); -static int yy_string_unget PARAMS((int)); -static int yy_stream_get PARAMS((void)); -static int yy_stream_unget PARAMS((int)); - -static int shell_getc PARAMS((int)); -static void shell_ungetc PARAMS((int)); -static void discard_until PARAMS((int)); - -static void push_string PARAMS((char *, int, alias_t *)); -static void pop_string PARAMS((void)); -static void free_string_list PARAMS((void)); - -static char *read_a_line PARAMS((int)); - -static int reserved_word_acceptable PARAMS((int)); -static int yylex PARAMS((void)); - -static void push_heredoc PARAMS((REDIRECT *)); -static char *mk_alexpansion PARAMS((char *)); -static int alias_expand_token PARAMS((char *)); -static int time_command_acceptable PARAMS((void)); -static int special_case_tokens PARAMS((char *)); -static int read_token PARAMS((int)); -static char *parse_matched_pair PARAMS((int, int, int, int *, int)); -static char *parse_comsub PARAMS((int, int, int, int *, int)); -#if defined (ARRAY_VARS) -static char *parse_compound_assignment PARAMS((int *)); -#endif -#if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND) -static int parse_dparen PARAMS((int)); -static int parse_arith_cmd PARAMS((char **, int)); -#endif -#if defined (COND_COMMAND) -static void cond_error PARAMS((void)); -static COND_COM *cond_expr PARAMS((void)); -static COND_COM *cond_or PARAMS((void)); -static COND_COM *cond_and PARAMS((void)); -static COND_COM *cond_term PARAMS((void)); -static int cond_skip_newlines PARAMS((void)); -static COMMAND *parse_cond_command PARAMS((void)); -#endif -#if defined (ARRAY_VARS) -static int token_is_assignment PARAMS((char *, int)); -static int token_is_ident PARAMS((char *, int)); -#endif -static int read_token_word PARAMS((int)); -static void discard_parser_constructs PARAMS((int)); - -static char *error_token_from_token PARAMS((int)); -static char *error_token_from_text PARAMS((void)); -static void print_offending_line PARAMS((void)); -static void report_syntax_error PARAMS((char *)); - -static void handle_eof_input_unit PARAMS((void)); -static void prompt_again PARAMS((int)); -#if 0 -static void reset_readline_prompt PARAMS((void)); -#endif -static void print_prompt PARAMS((void)); - -#if defined (HANDLE_MULTIBYTE) -static void set_line_mbstate PARAMS((void)); -static char *shell_input_line_property = NULL; -static size_t shell_input_line_propsize = 0; -#else -# define set_line_mbstate() -#endif - -extern int yyerror PARAMS((const char *)); - -#ifdef DEBUG -extern int yydebug; -#endif - -/* Default prompt strings */ -char *primary_prompt = PPROMPT; -char *secondary_prompt = SPROMPT; - -/* PROMPT_STRING_POINTER points to one of these, never to an actual string. */ -char *ps1_prompt, *ps2_prompt; - -/* Displayed after reading a command but before executing it in an interactive shell */ -char *ps0_prompt; - -/* Handle on the current prompt string. Indirectly points through - ps1_ or ps2_prompt. */ -char **prompt_string_pointer = (char **)NULL; -char *current_prompt_string; - -/* Non-zero means we expand aliases in commands. */ -int expand_aliases = 0; - -/* If non-zero, the decoded prompt string undergoes parameter and - variable substitution, command substitution, arithmetic substitution, - string expansion, process substitution, and quote removal in - decode_prompt_string. */ -int promptvars = 1; - -/* If non-zero, $'...' and $"..." are expanded when they appear within - a ${...} expansion, even when the expansion appears within double - quotes. */ -int extended_quote = 1; - -/* The number of lines read from input while creating the current command. */ -int current_command_line_count; - -/* The number of lines in a command saved while we run parse_and_execute */ -int saved_command_line_count; - -/* The token that currently denotes the end of parse. */ -int shell_eof_token; - -/* The token currently being read. */ -int current_token; - -/* The current parser state. */ -int parser_state; - -/* Variables to manage the task of reading here documents, because we need to - defer the reading until after a complete command has been collected. */ -static REDIRECT *redir_stack[HEREDOC_MAX]; -int need_here_doc; - -/* Where shell input comes from. History expansion is performed on each - line when the shell is interactive. */ -static char *shell_input_line = (char *)NULL; -static size_t shell_input_line_index; -static size_t shell_input_line_size; /* Amount allocated for shell_input_line. */ -static size_t shell_input_line_len; /* strlen (shell_input_line) */ - -/* Either zero or EOF. */ -static int shell_input_line_terminator; - -/* The line number in a script on which a function definition starts. */ -static int function_dstart; - -/* The line number in a script on which a function body starts. */ -static int function_bstart; - -/* The line number in a script at which an arithmetic for command starts. */ -static int arith_for_lineno; - -/* The decoded prompt string. Used if READLINE is not defined or if - editing is turned off. Analogous to current_readline_prompt. */ -static char *current_decoded_prompt; - -/* The last read token, or NULL. read_token () uses this for context - checking. */ -static int last_read_token; - -/* The token read prior to last_read_token. */ -static int token_before_that; - -/* The token read prior to token_before_that. */ -static int two_tokens_ago; - -static int global_extglob; - -/* The line number in a script where the word in a `case WORD', `select WORD' - or `for WORD' begins. This is a nested command maximum, since the array - index is decremented after a case, select, or for command is parsed. */ -#define MAX_CASE_NEST 128 -static int word_lineno[MAX_CASE_NEST+1]; -static int word_top = -1; - -/* If non-zero, it is the token that we want read_token to return - regardless of what text is (or isn't) present to be read. This - is reset by read_token. If token_to_read == WORD or - ASSIGNMENT_WORD, yylval.word should be set to word_desc_to_read. */ -static int token_to_read; -static WORD_DESC *word_desc_to_read; - -static REDIRECTEE source; -static REDIRECTEE redir; - -static FILE *yyoutstream; -static FILE *yyerrstream; - -#line 388 "y.tab.c" - -# ifndef YY_CAST -# ifdef __cplusplus -# define YY_CAST(Type, Val) static_cast (Val) -# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) -# else -# define YY_CAST(Type, Val) ((Type) (Val)) -# define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) -# endif -# endif -# ifndef YY_NULLPTR -# if defined __cplusplus -# if 201103L <= __cplusplus -# define YY_NULLPTR nullptr -# else -# define YY_NULLPTR 0 -# endif -# else -# define YY_NULLPTR ((void*)0) -# endif -# endif - -/* Use api.header.include to #include this header - instead of duplicating it here. */ -#ifndef YY_YY_Y_TAB_H_INCLUDED -# define YY_YY_Y_TAB_H_INCLUDED -/* Debug traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif -#if YYDEBUG -extern int yydebug; -#endif - -/* Token kinds. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - enum yytokentype - { - YYEMPTY = -2, - YYEOF = 0, /* "end of file" */ - YYerror = 256, /* error */ - YYUNDEF = 257, /* "invalid token" */ - IF = 258, /* IF */ - THEN = 259, /* THEN */ - ELSE = 260, /* ELSE */ - ELIF = 261, /* ELIF */ - FI = 262, /* FI */ - CASE = 263, /* CASE */ - ESAC = 264, /* ESAC */ - FOR = 265, /* FOR */ - SELECT = 266, /* SELECT */ - WHILE = 267, /* WHILE */ - UNTIL = 268, /* UNTIL */ - DO = 269, /* DO */ - DONE = 270, /* DONE */ - FUNCTION = 271, /* FUNCTION */ - COPROC = 272, /* COPROC */ - COND_START = 273, /* COND_START */ - COND_END = 274, /* COND_END */ - COND_ERROR = 275, /* COND_ERROR */ - IN = 276, /* IN */ - BANG = 277, /* BANG */ - TIME = 278, /* TIME */ - TIMEOPT = 279, /* TIMEOPT */ - TIMEIGN = 280, /* TIMEIGN */ - WORD = 281, /* WORD */ - ASSIGNMENT_WORD = 282, /* ASSIGNMENT_WORD */ - REDIR_WORD = 283, /* REDIR_WORD */ - NUMBER = 284, /* NUMBER */ - ARITH_CMD = 285, /* ARITH_CMD */ - ARITH_FOR_EXPRS = 286, /* ARITH_FOR_EXPRS */ - COND_CMD = 287, /* COND_CMD */ - AND_AND = 288, /* AND_AND */ - OR_OR = 289, /* OR_OR */ - GREATER_GREATER = 290, /* GREATER_GREATER */ - LESS_LESS = 291, /* LESS_LESS */ - LESS_AND = 292, /* LESS_AND */ - LESS_LESS_LESS = 293, /* LESS_LESS_LESS */ - GREATER_AND = 294, /* GREATER_AND */ - SEMI_SEMI = 295, /* SEMI_SEMI */ - SEMI_AND = 296, /* SEMI_AND */ - SEMI_SEMI_AND = 297, /* SEMI_SEMI_AND */ - LESS_LESS_MINUS = 298, /* LESS_LESS_MINUS */ - AND_GREATER = 299, /* AND_GREATER */ - AND_GREATER_GREATER = 300, /* AND_GREATER_GREATER */ - LESS_GREATER = 301, /* LESS_GREATER */ - GREATER_BAR = 302, /* GREATER_BAR */ - BAR_AND = 303, /* BAR_AND */ - DOLPAREN = 304, /* DOLPAREN */ - yacc_EOF = 305 /* yacc_EOF */ - }; - typedef enum yytokentype yytoken_kind_t; -#endif -/* Token kinds. */ -#define YYEMPTY -2 -#define YYEOF 0 -#define YYerror 256 -#define YYUNDEF 257 -#define IF 258 -#define THEN 259 -#define ELSE 260 -#define ELIF 261 -#define FI 262 -#define CASE 263 -#define ESAC 264 -#define FOR 265 -#define SELECT 266 -#define WHILE 267 -#define UNTIL 268 -#define DO 269 -#define DONE 270 -#define FUNCTION 271 -#define COPROC 272 -#define COND_START 273 -#define COND_END 274 -#define COND_ERROR 275 -#define IN 276 -#define BANG 277 -#define TIME 278 -#define TIMEOPT 279 -#define TIMEIGN 280 -#define WORD 281 -#define ASSIGNMENT_WORD 282 -#define REDIR_WORD 283 -#define NUMBER 284 -#define ARITH_CMD 285 -#define ARITH_FOR_EXPRS 286 -#define COND_CMD 287 -#define AND_AND 288 -#define OR_OR 289 -#define GREATER_GREATER 290 -#define LESS_LESS 291 -#define LESS_AND 292 -#define LESS_LESS_LESS 293 -#define GREATER_AND 294 -#define SEMI_SEMI 295 -#define SEMI_AND 296 -#define SEMI_SEMI_AND 297 -#define LESS_LESS_MINUS 298 -#define AND_GREATER 299 -#define AND_GREATER_GREATER 300 -#define LESS_GREATER 301 -#define GREATER_BAR 302 -#define BAR_AND 303 -#define DOLPAREN 304 -#define yacc_EOF 305 - -/* Value type. */ -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -union YYSTYPE -{ -#line 338 "/usr/local/src/chet/src/bash/src/parse.y" - - WORD_DESC *word; /* the word that we read. */ - int number; /* the number that we read. */ - WORD_LIST *word_list; - COMMAND *command; - REDIRECT *redirect; - ELEMENT element; - PATTERN_LIST *pattern; - -#line 551 "y.tab.c" - -}; -typedef union YYSTYPE YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define YYSTYPE_IS_DECLARED 1 -#endif - - -extern YYSTYPE yylval; - - -int yyparse (void); - - -#endif /* !YY_YY_Y_TAB_H_INCLUDED */ -/* Symbol kind. */ -enum yysymbol_kind_t -{ - YYSYMBOL_YYEMPTY = -2, - YYSYMBOL_YYEOF = 0, /* "end of file" */ - YYSYMBOL_YYerror = 1, /* error */ - YYSYMBOL_YYUNDEF = 2, /* "invalid token" */ - YYSYMBOL_IF = 3, /* IF */ - YYSYMBOL_THEN = 4, /* THEN */ - YYSYMBOL_ELSE = 5, /* ELSE */ - YYSYMBOL_ELIF = 6, /* ELIF */ - YYSYMBOL_FI = 7, /* FI */ - YYSYMBOL_CASE = 8, /* CASE */ - YYSYMBOL_ESAC = 9, /* ESAC */ - YYSYMBOL_FOR = 10, /* FOR */ - YYSYMBOL_SELECT = 11, /* SELECT */ - YYSYMBOL_WHILE = 12, /* WHILE */ - YYSYMBOL_UNTIL = 13, /* UNTIL */ - YYSYMBOL_DO = 14, /* DO */ - YYSYMBOL_DONE = 15, /* DONE */ - YYSYMBOL_FUNCTION = 16, /* FUNCTION */ - YYSYMBOL_COPROC = 17, /* COPROC */ - YYSYMBOL_COND_START = 18, /* COND_START */ - YYSYMBOL_COND_END = 19, /* COND_END */ - YYSYMBOL_COND_ERROR = 20, /* COND_ERROR */ - YYSYMBOL_IN = 21, /* IN */ - YYSYMBOL_BANG = 22, /* BANG */ - YYSYMBOL_TIME = 23, /* TIME */ - YYSYMBOL_TIMEOPT = 24, /* TIMEOPT */ - YYSYMBOL_TIMEIGN = 25, /* TIMEIGN */ - YYSYMBOL_WORD = 26, /* WORD */ - YYSYMBOL_ASSIGNMENT_WORD = 27, /* ASSIGNMENT_WORD */ - YYSYMBOL_REDIR_WORD = 28, /* REDIR_WORD */ - YYSYMBOL_NUMBER = 29, /* NUMBER */ - YYSYMBOL_ARITH_CMD = 30, /* ARITH_CMD */ - YYSYMBOL_ARITH_FOR_EXPRS = 31, /* ARITH_FOR_EXPRS */ - YYSYMBOL_COND_CMD = 32, /* COND_CMD */ - YYSYMBOL_AND_AND = 33, /* AND_AND */ - YYSYMBOL_OR_OR = 34, /* OR_OR */ - YYSYMBOL_GREATER_GREATER = 35, /* GREATER_GREATER */ - YYSYMBOL_LESS_LESS = 36, /* LESS_LESS */ - YYSYMBOL_LESS_AND = 37, /* LESS_AND */ - YYSYMBOL_LESS_LESS_LESS = 38, /* LESS_LESS_LESS */ - YYSYMBOL_GREATER_AND = 39, /* GREATER_AND */ - YYSYMBOL_SEMI_SEMI = 40, /* SEMI_SEMI */ - YYSYMBOL_SEMI_AND = 41, /* SEMI_AND */ - YYSYMBOL_SEMI_SEMI_AND = 42, /* SEMI_SEMI_AND */ - YYSYMBOL_LESS_LESS_MINUS = 43, /* LESS_LESS_MINUS */ - YYSYMBOL_AND_GREATER = 44, /* AND_GREATER */ - YYSYMBOL_AND_GREATER_GREATER = 45, /* AND_GREATER_GREATER */ - YYSYMBOL_LESS_GREATER = 46, /* LESS_GREATER */ - YYSYMBOL_GREATER_BAR = 47, /* GREATER_BAR */ - YYSYMBOL_BAR_AND = 48, /* BAR_AND */ - YYSYMBOL_DOLPAREN = 49, /* DOLPAREN */ - YYSYMBOL_50_ = 50, /* '&' */ - YYSYMBOL_51_ = 51, /* ';' */ - YYSYMBOL_52_n_ = 52, /* '\n' */ - YYSYMBOL_yacc_EOF = 53, /* yacc_EOF */ - YYSYMBOL_54_ = 54, /* '|' */ - YYSYMBOL_55_ = 55, /* '>' */ - YYSYMBOL_56_ = 56, /* '<' */ - YYSYMBOL_57_ = 57, /* '-' */ - YYSYMBOL_58_ = 58, /* '{' */ - YYSYMBOL_59_ = 59, /* '}' */ - YYSYMBOL_60_ = 60, /* '(' */ - YYSYMBOL_61_ = 61, /* ')' */ - YYSYMBOL_YYACCEPT = 62, /* $accept */ - YYSYMBOL_inputunit = 63, /* inputunit */ - YYSYMBOL_word_list = 64, /* word_list */ - YYSYMBOL_redirection = 65, /* redirection */ - YYSYMBOL_simple_command_element = 66, /* simple_command_element */ - YYSYMBOL_redirection_list = 67, /* redirection_list */ - YYSYMBOL_simple_command = 68, /* simple_command */ - YYSYMBOL_command = 69, /* command */ - YYSYMBOL_shell_command = 70, /* shell_command */ - YYSYMBOL_for_command = 71, /* for_command */ - YYSYMBOL_arith_for_command = 72, /* arith_for_command */ - YYSYMBOL_select_command = 73, /* select_command */ - YYSYMBOL_case_command = 74, /* case_command */ - YYSYMBOL_function_def = 75, /* function_def */ - YYSYMBOL_function_body = 76, /* function_body */ - YYSYMBOL_subshell = 77, /* subshell */ - YYSYMBOL_comsub = 78, /* comsub */ - YYSYMBOL_coproc = 79, /* coproc */ - YYSYMBOL_if_command = 80, /* if_command */ - YYSYMBOL_group_command = 81, /* group_command */ - YYSYMBOL_arith_command = 82, /* arith_command */ - YYSYMBOL_cond_command = 83, /* cond_command */ - YYSYMBOL_elif_clause = 84, /* elif_clause */ - YYSYMBOL_case_clause = 85, /* case_clause */ - YYSYMBOL_pattern_list = 86, /* pattern_list */ - YYSYMBOL_case_clause_sequence = 87, /* case_clause_sequence */ - YYSYMBOL_pattern = 88, /* pattern */ - YYSYMBOL_compound_list = 89, /* compound_list */ - YYSYMBOL_list0 = 90, /* list0 */ - YYSYMBOL_list1 = 91, /* list1 */ - YYSYMBOL_simple_list_terminator = 92, /* simple_list_terminator */ - YYSYMBOL_list_terminator = 93, /* list_terminator */ - YYSYMBOL_newline_list = 94, /* newline_list */ - YYSYMBOL_simple_list = 95, /* simple_list */ - YYSYMBOL_simple_list1 = 96, /* simple_list1 */ - YYSYMBOL_pipeline_command = 97, /* pipeline_command */ - YYSYMBOL_pipeline = 98, /* pipeline */ - YYSYMBOL_timespec = 99 /* timespec */ -}; -typedef enum yysymbol_kind_t yysymbol_kind_t; - - - - -#ifdef short -# undef short -#endif - -/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure - and (if available) are included - so that the code can choose integer types of a good width. */ - -#ifndef __PTRDIFF_MAX__ -# include /* INFRINGES ON USER NAME SPACE */ -# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_STDINT_H -# endif -#endif - -/* Narrow types that promote to a signed type and that can represent a - signed or unsigned integer of at least N bits. In tables they can - save space and decrease cache pressure. Promoting to a signed type - helps avoid bugs in integer arithmetic. */ - -#ifdef __INT_LEAST8_MAX__ -typedef __INT_LEAST8_TYPE__ yytype_int8; -#elif defined YY_STDINT_H -typedef int_least8_t yytype_int8; -#else -typedef signed char yytype_int8; -#endif - -#ifdef __INT_LEAST16_MAX__ -typedef __INT_LEAST16_TYPE__ yytype_int16; -#elif defined YY_STDINT_H -typedef int_least16_t yytype_int16; -#else -typedef short yytype_int16; -#endif - -/* Work around bug in HP-UX 11.23, which defines these macros - incorrectly for preprocessor constants. This workaround can likely - be removed in 2023, as HPE has promised support for HP-UX 11.23 - (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of - . */ -#ifdef __hpux -# undef UINT_LEAST8_MAX -# undef UINT_LEAST16_MAX -# define UINT_LEAST8_MAX 255 -# define UINT_LEAST16_MAX 65535 -#endif - -#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ -typedef __UINT_LEAST8_TYPE__ yytype_uint8; -#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ - && UINT_LEAST8_MAX <= INT_MAX) -typedef uint_least8_t yytype_uint8; -#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX -typedef unsigned char yytype_uint8; -#else -typedef short yytype_uint8; -#endif - -#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ -typedef __UINT_LEAST16_TYPE__ yytype_uint16; -#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ - && UINT_LEAST16_MAX <= INT_MAX) -typedef uint_least16_t yytype_uint16; -#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX -typedef unsigned short yytype_uint16; -#else -typedef int yytype_uint16; -#endif - -#ifndef YYPTRDIFF_T -# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ -# define YYPTRDIFF_T __PTRDIFF_TYPE__ -# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ -# elif defined PTRDIFF_MAX -# ifndef ptrdiff_t -# include /* INFRINGES ON USER NAME SPACE */ -# endif -# define YYPTRDIFF_T ptrdiff_t -# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX -# else -# define YYPTRDIFF_T long -# define YYPTRDIFF_MAXIMUM LONG_MAX -# endif -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned -# endif -#endif - -#define YYSIZE_MAXIMUM \ - YY_CAST (YYPTRDIFF_T, \ - (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ - ? YYPTRDIFF_MAXIMUM \ - : YY_CAST (YYSIZE_T, -1))) - -#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) - - -/* Stored state numbers (used for stacks). */ -typedef yytype_int16 yy_state_t; - -/* State numbers in computations. */ -typedef int yy_state_fast_t; - -#ifndef YY_ -# if defined YYENABLE_NLS && YYENABLE_NLS -# if ENABLE_NLS -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_(Msgid) dgettext ("bison-runtime", Msgid) -# endif -# endif -# ifndef YY_ -# define YY_(Msgid) Msgid -# endif -#endif - - -#ifndef YY_ATTRIBUTE_PURE -# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) -# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) -# else -# define YY_ATTRIBUTE_PURE -# endif -#endif - -#ifndef YY_ATTRIBUTE_UNUSED -# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) -# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) -# else -# define YY_ATTRIBUTE_UNUSED -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YY_USE(E) ((void) (E)) -#else -# define YY_USE(E) /* empty */ -#endif - -/* Suppress an incorrect diagnostic about yylval being uninitialized. */ -#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__ -# if __GNUC__ * 100 + __GNUC_MINOR__ < 407 -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") -# else -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ - _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") -# endif -# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ - _Pragma ("GCC diagnostic pop") -#else -# define YY_INITIAL_VALUE(Value) Value -#endif -#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_END -#endif -#ifndef YY_INITIAL_VALUE -# define YY_INITIAL_VALUE(Value) /* Nothing. */ -#endif - -#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ -# define YY_IGNORE_USELESS_CAST_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") -# define YY_IGNORE_USELESS_CAST_END \ - _Pragma ("GCC diagnostic pop") -#endif -#ifndef YY_IGNORE_USELESS_CAST_BEGIN -# define YY_IGNORE_USELESS_CAST_BEGIN -# define YY_IGNORE_USELESS_CAST_END -#endif - - -#define YY_ASSERT(E) ((void) (0 && (E))) - -#if !defined yyoverflow - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS -# include /* INFRINGES ON USER NAME SPACE */ - /* Use EXIT_SUCCESS as a witness for stdlib.h. */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's 'empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined EXIT_SUCCESS \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined EXIT_SUCCESS -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined EXIT_SUCCESS -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* !defined yyoverflow */ - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yy_state_t yyss_alloc; - YYSTYPE yyvs_alloc; -}; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \ - + YYSTACK_GAP_MAXIMUM) - -# define YYCOPY_NEEDED 1 - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYPTRDIFF_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / YYSIZEOF (*yyptr); \ - } \ - while (0) - -#endif - -#if defined YYCOPY_NEEDED && YYCOPY_NEEDED -/* Copy COUNT objects from SRC to DST. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(Dst, Src, Count) \ - __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) -# else -# define YYCOPY(Dst, Src, Count) \ - do \ - { \ - YYPTRDIFF_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (Dst)[yyi] = (Src)[yyi]; \ - } \ - while (0) -# endif -# endif -#endif /* !YYCOPY_NEEDED */ - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 121 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 740 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 62 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 38 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 174 -/* YYNSTATES -- Number of states. */ -#define YYNSTATES 349 - -/* YYMAXUTOK -- Last valid token kind. */ -#define YYMAXUTOK 305 - - -/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM - as returned by yylex, with out-of-bounds checking. */ -#define YYTRANSLATE(YYX) \ - (0 <= (YYX) && (YYX) <= YYMAXUTOK \ - ? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \ - : YYSYMBOL_YYUNDEF) - -/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM - as returned by yylex. */ -static const yytype_int8 yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 52, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 50, 2, - 60, 61, 2, 2, 2, 57, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 51, - 56, 2, 55, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 58, 54, 59, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 53 -}; - -#if YYDEBUG -/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ -static const yytype_int16 yyrline[] = -{ - 0, 395, 395, 406, 414, 423, 438, 455, 465, 467, - 471, 477, 483, 489, 495, 501, 507, 513, 519, 525, - 531, 537, 543, 549, 555, 561, 568, 575, 582, 589, - 596, 603, 609, 615, 621, 627, 633, 639, 645, 651, - 657, 663, 669, 675, 681, 687, 693, 699, 705, 711, - 717, 723, 729, 735, 743, 745, 747, 751, 755, 766, - 768, 772, 774, 776, 792, 794, 798, 800, 802, 804, - 806, 808, 810, 812, 814, 816, 818, 822, 827, 832, - 837, 842, 847, 852, 857, 864, 870, 876, 882, 890, - 895, 900, 905, 910, 915, 920, 925, 932, 937, 942, - 949, 951, 953, 955, 959, 961, 992, 999, 1003, 1009, - 1014, 1031, 1036, 1053, 1060, 1062, 1064, 1069, 1073, 1077, - 1081, 1083, 1085, 1089, 1090, 1094, 1096, 1098, 1100, 1104, - 1106, 1108, 1110, 1112, 1114, 1118, 1120, 1129, 1135, 1141, - 1142, 1149, 1153, 1155, 1157, 1164, 1166, 1173, 1177, 1178, - 1181, 1183, 1185, 1189, 1190, 1199, 1214, 1232, 1249, 1251, - 1253, 1260, 1263, 1267, 1269, 1275, 1281, 1301, 1324, 1326, - 1349, 1353, 1355, 1357, 1359 -}; -#endif - -/** Accessing symbol of state STATE. */ -#define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State]) - -#if YYDEBUG || 0 -/* The user-facing name of the symbol whose (internal) number is - YYSYMBOL. No bounds checking. */ -static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED; - -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "\"end of file\"", "error", "\"invalid token\"", "IF", "THEN", "ELSE", - "ELIF", "FI", "CASE", "ESAC", "FOR", "SELECT", "WHILE", "UNTIL", "DO", - "DONE", "FUNCTION", "COPROC", "COND_START", "COND_END", "COND_ERROR", - "IN", "BANG", "TIME", "TIMEOPT", "TIMEIGN", "WORD", "ASSIGNMENT_WORD", - "REDIR_WORD", "NUMBER", "ARITH_CMD", "ARITH_FOR_EXPRS", "COND_CMD", - "AND_AND", "OR_OR", "GREATER_GREATER", "LESS_LESS", "LESS_AND", - "LESS_LESS_LESS", "GREATER_AND", "SEMI_SEMI", "SEMI_AND", - "SEMI_SEMI_AND", "LESS_LESS_MINUS", "AND_GREATER", "AND_GREATER_GREATER", - "LESS_GREATER", "GREATER_BAR", "BAR_AND", "DOLPAREN", "'&'", "';'", - "'\\n'", "yacc_EOF", "'|'", "'>'", "'<'", "'-'", "'{'", "'}'", "'('", - "')'", "$accept", "inputunit", "word_list", "redirection", - "simple_command_element", "redirection_list", "simple_command", - "command", "shell_command", "for_command", "arith_for_command", - "select_command", "case_command", "function_def", "function_body", - "subshell", "comsub", "coproc", "if_command", "group_command", - "arith_command", "cond_command", "elif_clause", "case_clause", - "pattern_list", "case_clause_sequence", "pattern", "compound_list", - "list0", "list1", "simple_list_terminator", "list_terminator", - "newline_list", "simple_list", "simple_list1", "pipeline_command", - "pipeline", "timespec", YY_NULLPTR -}; - -static const char * -yysymbol_name (yysymbol_kind_t yysymbol) -{ - return yytname[yysymbol]; -} -#endif - -#define YYPACT_NINF (-152) - -#define yypact_value_is_default(Yyn) \ - ((Yyn) == YYPACT_NINF) - -#define YYTABLE_NINF (-1) - -#define yytable_value_is_error(Yyn) \ - 0 - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -static const yytype_int16 yypact[] = -{ - 328, 80, -152, -11, -1, 3, -152, -152, 15, 637, - -5, 433, 149, -28, -152, 187, 684, -152, 18, 28, - 130, 38, 139, 50, 52, 60, 65, 74, -152, -152, - -152, 89, 104, -152, -152, 97, -152, -152, 246, -152, - 670, -152, -152, -152, -152, -152, -152, -152, -152, -152, - -152, -152, -152, 146, 211, -152, 1, 433, -152, -152, - 135, 484, -152, 59, 61, 90, 167, 171, 10, 71, - 246, 670, 144, -152, -152, -152, -152, -152, 165, -152, - 142, 179, 192, 140, 194, 160, 227, 245, 252, 253, - 260, 261, 262, 162, 269, 178, 270, 272, 273, 274, - 277, -152, -152, -152, -152, -152, -152, -152, -152, -152, - -152, -152, -152, -152, -152, 168, 379, -152, -152, 173, - 244, -152, -152, -152, -152, 670, -152, -152, -152, -152, - -152, 535, 535, -152, -152, -152, -152, -152, -152, -152, - 205, -152, 14, -152, 36, -152, -152, -152, -152, 84, - -152, -152, -152, 249, 670, -152, 670, 670, -152, -152, - -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, - -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, - -152, -152, -152, -152, -152, -152, -152, -152, -152, -152, - -152, -152, -152, -152, 484, 484, 203, 203, 586, 586, - 145, -152, -152, -152, -152, -152, -152, 0, -152, 119, - -152, 291, 248, 66, 88, -152, 119, -152, 296, 297, - 35, -152, 670, 670, 35, -152, -152, 1, 1, -152, - -152, -152, 306, 484, 484, 484, 484, 484, 305, 169, - -152, 7, -152, -152, 302, -152, 131, -152, 265, -152, - -152, -152, -152, -152, -152, 304, 131, -152, 266, -152, - -152, -152, 35, -152, 313, 317, -152, -152, -152, 225, - 225, 225, -152, -152, -152, -152, 206, 25, -152, -152, - 307, -42, 319, 276, -152, -152, -152, 95, -152, 322, - 283, 332, 284, -152, -152, 102, -152, -152, -152, -152, - -152, -152, -152, -152, 45, 323, -152, -152, -152, 106, - -152, -152, -152, -152, -152, -152, 109, -152, -152, 264, - -152, -152, -152, 484, -152, -152, 333, 293, -152, -152, - 338, 300, -152, -152, -152, 484, 345, 303, -152, -152, - 346, 309, -152, -152, -152, -152, -152, -152, -152 -}; - -/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. - Performed when YYTABLE does not specify something else to do. Zero - means the default is an error. */ -static const yytype_uint8 yydefact[] = -{ - 0, 0, 153, 0, 0, 0, 153, 153, 0, 0, - 0, 0, 171, 54, 55, 0, 0, 118, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 153, 4, - 7, 0, 0, 153, 153, 0, 56, 59, 61, 170, - 62, 66, 76, 70, 67, 64, 72, 3, 65, 71, - 73, 74, 75, 0, 155, 162, 163, 0, 5, 6, - 0, 0, 153, 153, 0, 153, 0, 0, 0, 54, - 113, 109, 0, 151, 150, 152, 167, 164, 172, 173, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 16, 25, 40, 34, 49, 31, 43, 37, 46, - 28, 52, 53, 22, 19, 0, 0, 10, 11, 0, - 0, 1, 54, 60, 57, 63, 148, 149, 2, 153, - 153, 156, 157, 153, 153, 166, 165, 153, 154, 137, - 138, 147, 0, 153, 0, 153, 153, 153, 153, 0, - 153, 153, 153, 153, 104, 102, 111, 110, 119, 174, - 153, 18, 27, 42, 36, 51, 33, 45, 39, 48, - 30, 24, 21, 14, 15, 17, 26, 41, 35, 50, - 32, 44, 38, 47, 29, 23, 20, 12, 13, 107, - 108, 117, 106, 58, 0, 0, 160, 161, 0, 0, - 0, 153, 153, 153, 153, 153, 153, 0, 153, 0, - 153, 0, 0, 0, 0, 153, 0, 153, 0, 0, - 0, 153, 105, 112, 0, 158, 159, 169, 168, 153, - 153, 114, 0, 0, 0, 140, 141, 139, 0, 123, - 153, 0, 153, 153, 0, 8, 0, 153, 0, 87, - 88, 153, 153, 153, 153, 0, 0, 153, 0, 68, - 69, 103, 0, 100, 0, 0, 116, 142, 143, 144, - 145, 146, 99, 129, 131, 133, 124, 0, 97, 135, - 0, 0, 0, 0, 77, 9, 153, 0, 78, 0, - 0, 0, 0, 89, 153, 0, 90, 101, 115, 153, - 130, 132, 134, 98, 0, 0, 153, 79, 80, 0, - 153, 153, 85, 86, 91, 92, 0, 153, 153, 120, - 153, 136, 125, 126, 153, 153, 0, 0, 153, 153, - 0, 0, 153, 122, 127, 128, 0, 0, 83, 84, - 0, 0, 95, 96, 121, 81, 82, 93, 94 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const yytype_int16 yypgoto[] = -{ - -152, -152, 112, -29, -14, -64, 360, -152, -8, -152, - -152, -152, -152, -152, -151, -152, -152, -152, -152, -152, - -152, -152, 13, -152, 136, -152, 98, -2, -152, 30, - -152, -54, -26, -152, -123, 6, 78, -152 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int16 yydefgoto[] = -{ - 0, 35, 246, 36, 37, 125, 38, 39, 40, 41, - 42, 43, 44, 45, 155, 46, 47, 48, 49, 50, - 51, 52, 232, 238, 239, 240, 281, 120, 139, 140, - 128, 76, 61, 53, 54, 141, 56, 57 -}; - -/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule whose - number is the opposite. If YYTABLE_NINF, syntax error. */ -static const yytype_int16 yytable[] = -{ - 60, 71, 116, 135, 66, 67, 55, 157, 196, 197, - 147, 124, 305, 2, 242, 62, 278, 77, 3, 306, - 4, 5, 6, 7, 123, 63, 115, 72, 10, 65, - 64, 119, 80, 279, 303, 206, 142, 144, 2, 149, - 17, 68, 124, 3, 101, 4, 5, 6, 7, 133, - 208, 279, 138, 10, 102, 134, 123, 209, 243, 138, - 154, 156, 152, 136, 106, 17, 138, 280, 33, 261, - 153, 225, 226, 263, 2, 145, 110, 138, 111, 3, - 251, 4, 5, 6, 7, 280, 112, 138, 138, 10, - 222, 113, 223, 33, 210, 34, 193, 121, 215, 305, - 114, 17, 253, 194, 195, 216, 320, 198, 199, 310, - 143, 297, 73, 74, 75, 117, 317, 207, 138, 146, - 324, 213, 214, 328, 252, 124, 220, 124, 193, 33, - 118, 34, 58, 59, 224, 200, 138, 55, 55, 137, - 138, 148, 217, 211, 212, 245, 254, 138, 218, 219, - 229, 230, 231, 311, 138, 247, 103, 285, 138, 104, - 318, 138, 257, 158, 325, 107, 163, 329, 108, 164, - 73, 74, 75, 78, 79, 233, 234, 235, 236, 237, - 241, 150, 73, 74, 75, 151, 167, 105, 177, 168, - 159, 178, 286, 193, 193, 262, 109, 165, 126, 127, - 55, 55, 294, 160, 181, 161, 244, 182, 248, 273, - 274, 275, 154, 255, 277, 258, 154, 169, 162, 179, - 166, 287, 81, 82, 83, 84, 85, 264, 265, 189, - 86, 295, 191, 87, 88, 183, 129, 130, 201, 202, - 282, 283, 89, 90, 129, 130, 300, 301, 302, 289, - 290, 291, 292, 170, 154, 203, 204, 205, 201, 202, - 309, 131, 132, 267, 268, 269, 270, 271, 316, 332, - 230, 171, 122, 14, 15, 16, 227, 228, 172, 173, - 323, 18, 19, 20, 21, 22, 174, 175, 176, 23, - 24, 25, 26, 27, 335, 180, 184, 319, 185, 186, - 187, 31, 32, 188, 322, 192, 249, 250, 326, 327, - 221, 259, 260, 266, 272, 330, 331, 284, 334, 293, - 298, 299, 336, 337, 288, 296, 340, 341, 256, 1, - 344, 2, 333, 279, 307, 308, 3, 312, 4, 5, - 6, 7, 313, 315, 8, 9, 10, 314, 338, 321, - 11, 12, 339, 342, 13, 14, 15, 16, 17, 343, - 345, 347, 346, 18, 19, 20, 21, 22, 348, 70, - 0, 23, 24, 25, 26, 27, 276, 28, 304, 0, - 29, 30, 2, 31, 32, 0, 33, 3, 34, 4, - 5, 6, 7, 0, 0, 8, 9, 10, 0, 0, - 0, 11, 12, 0, 0, 13, 14, 15, 16, 17, - 0, 0, 0, 0, 18, 19, 20, 21, 22, 0, - 0, 0, 23, 24, 25, 26, 27, 0, 0, 0, - 0, 138, 0, 0, 31, 32, 2, 33, 0, 34, - 190, 3, 0, 4, 5, 6, 7, 0, 0, 8, - 9, 10, 0, 0, 0, 11, 12, 0, 0, 13, - 14, 15, 16, 17, 0, 0, 0, 0, 18, 19, - 20, 21, 22, 0, 0, 0, 23, 24, 25, 26, - 27, 0, 0, 0, 73, 74, 75, 2, 31, 32, - 0, 33, 3, 34, 4, 5, 6, 7, 0, 0, - 8, 9, 10, 0, 0, 0, 11, 12, 0, 0, - 13, 14, 15, 16, 17, 0, 0, 0, 0, 18, - 19, 20, 21, 22, 0, 0, 0, 23, 24, 25, - 26, 27, 0, 0, 0, 0, 138, 0, 2, 31, - 32, 0, 33, 3, 34, 4, 5, 6, 7, 0, - 0, 8, 9, 10, 0, 0, 0, 11, 12, 0, - 0, 13, 14, 15, 16, 17, 0, 0, 0, 0, - 18, 19, 20, 21, 22, 0, 0, 0, 23, 24, - 25, 26, 27, 0, 0, 0, 0, 0, 0, 2, - 31, 32, 0, 33, 3, 34, 4, 5, 6, 7, - 0, 0, 8, 9, 10, 0, 0, 0, 0, 0, - 0, 0, 13, 14, 15, 16, 17, 0, 0, 0, - 0, 18, 19, 20, 21, 22, 0, 0, 0, 23, - 24, 25, 26, 27, 0, 0, 0, 0, 138, 0, - 2, 31, 32, 0, 33, 3, 34, 4, 5, 6, - 7, 0, 0, 0, 0, 10, 0, 0, 0, 0, - 0, 0, 0, 69, 14, 15, 16, 17, 0, 0, - 0, 0, 18, 19, 20, 21, 22, 0, 0, 0, - 23, 24, 25, 26, 27, 0, 0, 0, 0, 0, - 0, 0, 31, 32, 0, 33, 0, 34, 15, 16, - 0, 0, 0, 0, 0, 18, 19, 20, 21, 22, - 0, 0, 0, 23, 24, 25, 26, 27, 0, 91, - 92, 93, 94, 95, 0, 31, 32, 96, 0, 0, - 97, 98, 0, 0, 0, 0, 0, 0, 0, 99, - 100 -}; - -static const yytype_int16 yycheck[] = -{ - 2, 9, 28, 57, 6, 7, 0, 71, 131, 132, - 64, 40, 54, 3, 14, 26, 9, 11, 8, 61, - 10, 11, 12, 13, 38, 26, 28, 32, 18, 26, - 31, 33, 60, 26, 9, 21, 62, 63, 3, 65, - 30, 26, 71, 8, 26, 10, 11, 12, 13, 48, - 14, 26, 52, 18, 26, 54, 70, 21, 58, 52, - 68, 69, 52, 57, 26, 30, 52, 60, 58, 220, - 60, 194, 195, 224, 3, 14, 26, 52, 26, 8, - 14, 10, 11, 12, 13, 60, 26, 52, 52, 18, - 154, 26, 156, 58, 58, 60, 125, 0, 14, 54, - 26, 30, 14, 129, 130, 21, 61, 133, 134, 14, - 51, 262, 51, 52, 53, 26, 14, 143, 52, 58, - 14, 147, 148, 14, 58, 154, 152, 156, 157, 58, - 26, 60, 52, 53, 160, 137, 52, 131, 132, 4, - 52, 51, 58, 145, 146, 26, 58, 52, 150, 151, - 5, 6, 7, 58, 52, 209, 26, 26, 52, 29, - 58, 52, 216, 19, 58, 26, 26, 58, 29, 29, - 51, 52, 53, 24, 25, 201, 202, 203, 204, 205, - 206, 14, 51, 52, 53, 14, 26, 57, 26, 29, - 25, 29, 246, 222, 223, 221, 57, 57, 52, 53, - 194, 195, 256, 61, 26, 26, 208, 29, 210, 40, - 41, 42, 220, 215, 240, 217, 224, 57, 26, 57, - 26, 247, 35, 36, 37, 38, 39, 229, 230, 61, - 43, 257, 59, 46, 47, 57, 33, 34, 33, 34, - 242, 243, 55, 56, 33, 34, 40, 41, 42, 251, - 252, 253, 254, 26, 262, 50, 51, 52, 33, 34, - 286, 50, 51, 233, 234, 235, 236, 237, 294, 5, - 6, 26, 26, 27, 28, 29, 198, 199, 26, 26, - 306, 35, 36, 37, 38, 39, 26, 26, 26, 43, - 44, 45, 46, 47, 320, 26, 26, 299, 26, 26, - 26, 55, 56, 26, 306, 61, 15, 59, 310, 311, - 61, 15, 15, 7, 9, 317, 318, 15, 320, 15, - 7, 4, 324, 325, 59, 59, 328, 329, 216, 1, - 332, 3, 319, 26, 15, 59, 8, 15, 10, 11, - 12, 13, 59, 59, 16, 17, 18, 15, 15, 26, - 22, 23, 59, 15, 26, 27, 28, 29, 30, 59, - 15, 15, 59, 35, 36, 37, 38, 39, 59, 9, - -1, 43, 44, 45, 46, 47, 240, 49, 280, -1, - 52, 53, 3, 55, 56, -1, 58, 8, 60, 10, - 11, 12, 13, -1, -1, 16, 17, 18, -1, -1, - -1, 22, 23, -1, -1, 26, 27, 28, 29, 30, - -1, -1, -1, -1, 35, 36, 37, 38, 39, -1, - -1, -1, 43, 44, 45, 46, 47, -1, -1, -1, - -1, 52, -1, -1, 55, 56, 3, 58, -1, 60, - 61, 8, -1, 10, 11, 12, 13, -1, -1, 16, - 17, 18, -1, -1, -1, 22, 23, -1, -1, 26, - 27, 28, 29, 30, -1, -1, -1, -1, 35, 36, - 37, 38, 39, -1, -1, -1, 43, 44, 45, 46, - 47, -1, -1, -1, 51, 52, 53, 3, 55, 56, - -1, 58, 8, 60, 10, 11, 12, 13, -1, -1, - 16, 17, 18, -1, -1, -1, 22, 23, -1, -1, - 26, 27, 28, 29, 30, -1, -1, -1, -1, 35, - 36, 37, 38, 39, -1, -1, -1, 43, 44, 45, - 46, 47, -1, -1, -1, -1, 52, -1, 3, 55, - 56, -1, 58, 8, 60, 10, 11, 12, 13, -1, - -1, 16, 17, 18, -1, -1, -1, 22, 23, -1, - -1, 26, 27, 28, 29, 30, -1, -1, -1, -1, - 35, 36, 37, 38, 39, -1, -1, -1, 43, 44, - 45, 46, 47, -1, -1, -1, -1, -1, -1, 3, - 55, 56, -1, 58, 8, 60, 10, 11, 12, 13, - -1, -1, 16, 17, 18, -1, -1, -1, -1, -1, - -1, -1, 26, 27, 28, 29, 30, -1, -1, -1, - -1, 35, 36, 37, 38, 39, -1, -1, -1, 43, - 44, 45, 46, 47, -1, -1, -1, -1, 52, -1, - 3, 55, 56, -1, 58, 8, 60, 10, 11, 12, - 13, -1, -1, -1, -1, 18, -1, -1, -1, -1, - -1, -1, -1, 26, 27, 28, 29, 30, -1, -1, - -1, -1, 35, 36, 37, 38, 39, -1, -1, -1, - 43, 44, 45, 46, 47, -1, -1, -1, -1, -1, - -1, -1, 55, 56, -1, 58, -1, 60, 28, 29, - -1, -1, -1, -1, -1, 35, 36, 37, 38, 39, - -1, -1, -1, 43, 44, 45, 46, 47, -1, 35, - 36, 37, 38, 39, -1, 55, 56, 43, -1, -1, - 46, 47, -1, -1, -1, -1, -1, -1, -1, 55, - 56 -}; - -/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of - state STATE-NUM. */ -static const yytype_int8 yystos[] = -{ - 0, 1, 3, 8, 10, 11, 12, 13, 16, 17, - 18, 22, 23, 26, 27, 28, 29, 30, 35, 36, - 37, 38, 39, 43, 44, 45, 46, 47, 49, 52, - 53, 55, 56, 58, 60, 63, 65, 66, 68, 69, - 70, 71, 72, 73, 74, 75, 77, 78, 79, 80, - 81, 82, 83, 95, 96, 97, 98, 99, 52, 53, - 89, 94, 26, 26, 31, 26, 89, 89, 26, 26, - 68, 70, 32, 51, 52, 53, 93, 97, 24, 25, - 60, 35, 36, 37, 38, 39, 43, 46, 47, 55, - 56, 35, 36, 37, 38, 39, 43, 46, 47, 55, - 56, 26, 26, 26, 29, 57, 26, 26, 29, 57, - 26, 26, 26, 26, 26, 89, 94, 26, 26, 89, - 89, 0, 26, 66, 65, 67, 52, 53, 92, 33, - 34, 50, 51, 48, 54, 93, 97, 4, 52, 90, - 91, 97, 94, 51, 94, 14, 58, 93, 51, 94, - 14, 14, 52, 60, 70, 76, 70, 67, 19, 25, - 61, 26, 26, 26, 29, 57, 26, 26, 29, 57, - 26, 26, 26, 26, 26, 26, 26, 26, 29, 57, - 26, 26, 29, 57, 26, 26, 26, 26, 26, 61, - 61, 59, 61, 65, 94, 94, 96, 96, 94, 94, - 89, 33, 34, 50, 51, 52, 21, 94, 14, 21, - 58, 89, 89, 94, 94, 14, 21, 58, 89, 89, - 94, 61, 67, 67, 94, 96, 96, 98, 98, 5, - 6, 7, 84, 94, 94, 94, 94, 94, 85, 86, - 87, 94, 14, 58, 89, 26, 64, 93, 89, 15, - 59, 14, 58, 14, 58, 89, 64, 93, 89, 15, - 15, 76, 94, 76, 89, 89, 7, 91, 91, 91, - 91, 91, 9, 40, 41, 42, 86, 94, 9, 26, - 60, 88, 89, 89, 15, 26, 93, 94, 59, 89, - 89, 89, 89, 15, 93, 94, 59, 76, 7, 4, - 40, 41, 42, 9, 88, 54, 61, 15, 59, 94, - 14, 58, 15, 59, 15, 59, 94, 14, 58, 89, - 61, 26, 89, 94, 14, 58, 89, 89, 14, 58, - 89, 89, 5, 84, 89, 94, 89, 89, 15, 59, - 89, 89, 15, 59, 89, 15, 59, 15, 59 -}; - -/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */ -static const yytype_int8 yyr1[] = -{ - 0, 62, 63, 63, 63, 63, 63, 63, 64, 64, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 65, 65, 66, 66, 66, 67, 67, 68, - 68, 69, 69, 69, 69, 69, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 71, 71, 71, - 71, 71, 71, 71, 71, 72, 72, 72, 72, 73, - 73, 73, 73, 73, 73, 73, 73, 74, 74, 74, - 75, 75, 75, 75, 76, 76, 77, 78, 78, 79, - 79, 79, 79, 79, 80, 80, 80, 81, 82, 83, - 84, 84, 84, 85, 85, 86, 86, 86, 86, 87, - 87, 87, 87, 87, 87, 88, 88, 89, 89, 90, - 90, 90, 91, 91, 91, 91, 91, 91, 92, 92, - 93, 93, 93, 94, 94, 95, 95, 95, 96, 96, - 96, 96, 96, 97, 97, 97, 97, 97, 98, 98, - 98, 99, 99, 99, 99 -}; - -/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */ -static const yytype_int8 yyr2[] = -{ - 0, 2, 2, 1, 1, 2, 2, 1, 1, 2, - 2, 2, 3, 3, 3, 3, 2, 3, 3, 2, - 3, 3, 2, 3, 3, 2, 3, 3, 2, 3, - 3, 2, 3, 3, 2, 3, 3, 2, 3, 3, - 2, 3, 3, 2, 3, 3, 2, 3, 3, 2, - 3, 3, 2, 2, 1, 1, 1, 1, 2, 1, - 2, 1, 1, 2, 1, 1, 1, 1, 5, 5, - 1, 1, 1, 1, 1, 1, 1, 6, 6, 7, - 7, 10, 10, 9, 9, 7, 7, 5, 5, 6, - 6, 7, 7, 10, 10, 9, 9, 6, 7, 6, - 5, 6, 3, 5, 1, 2, 3, 3, 3, 2, - 3, 3, 4, 2, 5, 7, 6, 3, 1, 3, - 4, 6, 5, 1, 2, 4, 4, 5, 5, 2, - 3, 2, 3, 2, 3, 1, 3, 2, 2, 3, - 3, 3, 4, 4, 4, 4, 4, 1, 1, 1, - 1, 1, 1, 0, 2, 1, 2, 2, 4, 4, - 3, 3, 1, 1, 2, 2, 2, 2, 4, 4, - 1, 1, 2, 2, 3 -}; - - -enum { YYENOMEM = -2 }; - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab -#define YYNOMEM goto yyexhaustedlab - - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ - do \ - if (yychar == YYEMPTY) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (yylen); \ - yystate = *yyssp; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ - while (0) - -/* Backward compatibility with an undocumented macro. - Use YYerror or YYUNDEF. */ -#define YYERRCODE YYUNDEF - - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (0) - - - - -# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Kind, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (0) - - -/*-----------------------------------. -| Print this symbol's value on YYO. | -`-----------------------------------*/ - -static void -yy_symbol_value_print (FILE *yyo, - yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep) -{ - FILE *yyoutput = yyo; - YY_USE (yyoutput); - if (!yyvaluep) - return; - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YY_USE (yykind); - YY_IGNORE_MAYBE_UNINITIALIZED_END -} - - -/*---------------------------. -| Print this symbol on YYO. | -`---------------------------*/ - -static void -yy_symbol_print (FILE *yyo, - yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep) -{ - YYFPRINTF (yyo, "%s %s (", - yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind)); - - yy_symbol_value_print (yyo, yykind, yyvaluep); - YYFPRINTF (yyo, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -static void -yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) -{ - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (0) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -static void -yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, - int yyrule) -{ - int yylno = yyrline[yyrule]; - int yynrhs = yyr2[yyrule]; - int yyi; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, - YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]), - &yyvsp[(yyi + 1) - (yynrhs)]); - YYFPRINTF (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyssp, yyvsp, Rule); \ -} while (0) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) ((void) 0) -# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - - - - - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -static void -yydestruct (const char *yymsg, - yysymbol_kind_t yykind, YYSTYPE *yyvaluep) -{ - YY_USE (yyvaluep); - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); - - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YY_USE (yykind); - YY_IGNORE_MAYBE_UNINITIALIZED_END -} - - -/* Lookahead token kind. */ -int yychar; - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval; -/* Number of syntax errors so far. */ -int yynerrs; - - - - -/*----------. -| yyparse. | -`----------*/ - -int -yyparse (void) -{ - yy_state_fast_t yystate = 0; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus = 0; - - /* Refer to the stacks through separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* Their size. */ - YYPTRDIFF_T yystacksize = YYINITDEPTH; - - /* The state stack: array, bottom, top. */ - yy_state_t yyssa[YYINITDEPTH]; - yy_state_t *yyss = yyssa; - yy_state_t *yyssp = yyss; - - /* The semantic value stack: array, bottom, top. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - YYSTYPE *yyvsp = yyvs; - - int yyn; - /* The return value of yyparse. */ - int yyresult; - /* Lookahead symbol kind. */ - yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - - - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yychar = YYEMPTY; /* Cause a token to be read. */ - - goto yysetstate; - - -/*------------------------------------------------------------. -| yynewstate -- push a new state, which is found in yystate. | -`------------------------------------------------------------*/ -yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - -/*--------------------------------------------------------------------. -| yysetstate -- set current state (the top of the stack) to yystate. | -`--------------------------------------------------------------------*/ -yysetstate: - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - YY_ASSERT (0 <= yystate && yystate < YYNSTATES); - YY_IGNORE_USELESS_CAST_BEGIN - *yyssp = YY_CAST (yy_state_t, yystate); - YY_IGNORE_USELESS_CAST_END - YY_STACK_PRINT (yyss, yyssp); - - if (yyss + yystacksize - 1 <= yyssp) -#if !defined yyoverflow && !defined YYSTACK_RELOCATE - YYNOMEM; -#else - { - /* Get the current used size of the three stacks, in elements. */ - YYPTRDIFF_T yysize = yyssp - yyss + 1; - -# if defined yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - yy_state_t *yyss1 = yyss; - YYSTYPE *yyvs1 = yyvs; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * YYSIZEOF (*yyssp), - &yyvs1, yysize * YYSIZEOF (*yyvsp), - &yystacksize); - yyss = yyss1; - yyvs = yyvs1; - } -# else /* defined YYSTACK_RELOCATE */ - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - YYNOMEM; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yy_state_t *yyss1 = yyss; - union yyalloc *yyptr = - YY_CAST (union yyalloc *, - YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); - if (! yyptr) - YYNOMEM; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - - YY_IGNORE_USELESS_CAST_BEGIN - YYDPRINTF ((stderr, "Stack size increased to %ld\n", - YY_CAST (long, yystacksize))); - YY_IGNORE_USELESS_CAST_END - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } -#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ - - - if (yystate == YYFINAL) - YYACCEPT; - - goto yybackup; - - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to lookahead token. */ - yyn = yypact[yystate]; - if (yypact_value_is_default (yyn)) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token\n")); - yychar = yylex (); - } - - if (yychar <= YYEOF) - { - yychar = YYEOF; - yytoken = YYSYMBOL_YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else if (yychar == YYerror) - { - /* The scanner already issued an error message, process directly - to error recovery. But do not keep the error token as - lookahead, it is too special and may lead us to an endless - loop in error recovery. */ - yychar = YYUNDEF; - yytoken = YYSYMBOL_YYerror; - goto yyerrlab1; - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yytable_value_is_error (yyn)) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the lookahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - yystate = yyn; - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - - /* Discard the shifted token. */ - yychar = YYEMPTY; - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - '$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 2: /* inputunit: simple_list simple_list_terminator */ -#line 396 "/usr/local/src/chet/src/bash/src/parse.y" - { - /* Case of regular command. Discard the error - safety net,and return the command just parsed. */ - global_command = (yyvsp[-1].command); - eof_encountered = 0; - /* discard_parser_constructs (0); */ - if (parser_state & PST_CMDSUBST) - parser_state |= PST_EOFTOKEN; - YYACCEPT; - } -#line 1954 "y.tab.c" - break; - - case 3: /* inputunit: comsub */ -#line 407 "/usr/local/src/chet/src/bash/src/parse.y" - { - /* This is special; look at the production and how - parse_comsub sets token_to_read */ - global_command = (yyvsp[0].command); - eof_encountered = 0; - YYACCEPT; - } -#line 1966 "y.tab.c" - break; - - case 4: /* inputunit: '\n' */ -#line 415 "/usr/local/src/chet/src/bash/src/parse.y" - { - /* Case of regular command, but not a very - interesting one. Return a NULL command. */ - global_command = (COMMAND *)NULL; - if (parser_state & PST_CMDSUBST) - parser_state |= PST_EOFTOKEN; - YYACCEPT; - } -#line 1979 "y.tab.c" - break; - - case 5: /* inputunit: error '\n' */ -#line 424 "/usr/local/src/chet/src/bash/src/parse.y" - { - /* Error during parsing. Return NULL command. */ - global_command = (COMMAND *)NULL; - eof_encountered = 0; - /* discard_parser_constructs (1); */ - if (interactive && parse_and_execute_level == 0) - { - YYACCEPT; - } - else - { - YYABORT; - } - } -#line 1998 "y.tab.c" - break; - - case 6: /* inputunit: error yacc_EOF */ -#line 439 "/usr/local/src/chet/src/bash/src/parse.y" - { - /* EOF after an error. Do ignoreeof or not. Really - only interesting in non-interactive shells */ - global_command = (COMMAND *)NULL; - if (last_command_exit_value == 0) - last_command_exit_value = EX_BADUSAGE; /* force error return */ - if (interactive && parse_and_execute_level == 0) - { - handle_eof_input_unit (); - YYACCEPT; - } - else - { - YYABORT; - } - } -#line 2019 "y.tab.c" - break; - - case 7: /* inputunit: yacc_EOF */ -#line 456 "/usr/local/src/chet/src/bash/src/parse.y" - { - /* Case of EOF seen by itself. Do ignoreeof or - not. */ - global_command = (COMMAND *)NULL; - handle_eof_input_unit (); - YYACCEPT; - } -#line 2031 "y.tab.c" - break; - - case 8: /* word_list: WORD */ -#line 466 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.word_list) = make_word_list ((yyvsp[0].word), (WORD_LIST *)NULL); } -#line 2037 "y.tab.c" - break; - - case 9: /* word_list: word_list WORD */ -#line 468 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.word_list) = make_word_list ((yyvsp[0].word), (yyvsp[-1].word_list)); } -#line 2043 "y.tab.c" - break; - - case 10: /* redirection: '>' WORD */ -#line 472 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.dest = 1; - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_output_direction, redir, 0); - } -#line 2053 "y.tab.c" - break; - - case 11: /* redirection: '<' WORD */ -#line 478 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.dest = 0; - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_input_direction, redir, 0); - } -#line 2063 "y.tab.c" - break; - - case 12: /* redirection: NUMBER '>' WORD */ -#line 484 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.dest = (yyvsp[-2].number); - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_output_direction, redir, 0); - } -#line 2073 "y.tab.c" - break; - - case 13: /* redirection: NUMBER '<' WORD */ -#line 490 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.dest = (yyvsp[-2].number); - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_input_direction, redir, 0); - } -#line 2083 "y.tab.c" - break; - - case 14: /* redirection: REDIR_WORD '>' WORD */ -#line 496 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.filename = (yyvsp[-2].word); - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_output_direction, redir, REDIR_VARASSIGN); - } -#line 2093 "y.tab.c" - break; - - case 15: /* redirection: REDIR_WORD '<' WORD */ -#line 502 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.filename = (yyvsp[-2].word); - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_input_direction, redir, REDIR_VARASSIGN); - } -#line 2103 "y.tab.c" - break; - - case 16: /* redirection: GREATER_GREATER WORD */ -#line 508 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.dest = 1; - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_appending_to, redir, 0); - } -#line 2113 "y.tab.c" - break; - - case 17: /* redirection: NUMBER GREATER_GREATER WORD */ -#line 514 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.dest = (yyvsp[-2].number); - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_appending_to, redir, 0); - } -#line 2123 "y.tab.c" - break; - - case 18: /* redirection: REDIR_WORD GREATER_GREATER WORD */ -#line 520 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.filename = (yyvsp[-2].word); - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_appending_to, redir, REDIR_VARASSIGN); - } -#line 2133 "y.tab.c" - break; - - case 19: /* redirection: GREATER_BAR WORD */ -#line 526 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.dest = 1; - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_output_force, redir, 0); - } -#line 2143 "y.tab.c" - break; - - case 20: /* redirection: NUMBER GREATER_BAR WORD */ -#line 532 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.dest = (yyvsp[-2].number); - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_output_force, redir, 0); - } -#line 2153 "y.tab.c" - break; - - case 21: /* redirection: REDIR_WORD GREATER_BAR WORD */ -#line 538 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.filename = (yyvsp[-2].word); - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_output_force, redir, REDIR_VARASSIGN); - } -#line 2163 "y.tab.c" - break; - - case 22: /* redirection: LESS_GREATER WORD */ -#line 544 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.dest = 0; - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_input_output, redir, 0); - } -#line 2173 "y.tab.c" - break; - - case 23: /* redirection: NUMBER LESS_GREATER WORD */ -#line 550 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.dest = (yyvsp[-2].number); - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_input_output, redir, 0); - } -#line 2183 "y.tab.c" - break; - - case 24: /* redirection: REDIR_WORD LESS_GREATER WORD */ -#line 556 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.filename = (yyvsp[-2].word); - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_input_output, redir, REDIR_VARASSIGN); - } -#line 2193 "y.tab.c" - break; - - case 25: /* redirection: LESS_LESS WORD */ -#line 562 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.dest = 0; - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_reading_until, redir, 0); - push_heredoc ((yyval.redirect)); - } -#line 2204 "y.tab.c" - break; - - case 26: /* redirection: NUMBER LESS_LESS WORD */ -#line 569 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.dest = (yyvsp[-2].number); - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_reading_until, redir, 0); - push_heredoc ((yyval.redirect)); - } -#line 2215 "y.tab.c" - break; - - case 27: /* redirection: REDIR_WORD LESS_LESS WORD */ -#line 576 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.filename = (yyvsp[-2].word); - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_reading_until, redir, REDIR_VARASSIGN); - push_heredoc ((yyval.redirect)); - } -#line 2226 "y.tab.c" - break; - - case 28: /* redirection: LESS_LESS_MINUS WORD */ -#line 583 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.dest = 0; - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_deblank_reading_until, redir, 0); - push_heredoc ((yyval.redirect)); - } -#line 2237 "y.tab.c" - break; - - case 29: /* redirection: NUMBER LESS_LESS_MINUS WORD */ -#line 590 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.dest = (yyvsp[-2].number); - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_deblank_reading_until, redir, 0); - push_heredoc ((yyval.redirect)); - } -#line 2248 "y.tab.c" - break; - - case 30: /* redirection: REDIR_WORD LESS_LESS_MINUS WORD */ -#line 597 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.filename = (yyvsp[-2].word); - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_deblank_reading_until, redir, REDIR_VARASSIGN); - push_heredoc ((yyval.redirect)); - } -#line 2259 "y.tab.c" - break; - - case 31: /* redirection: LESS_LESS_LESS WORD */ -#line 604 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.dest = 0; - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_reading_string, redir, 0); - } -#line 2269 "y.tab.c" - break; - - case 32: /* redirection: NUMBER LESS_LESS_LESS WORD */ -#line 610 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.dest = (yyvsp[-2].number); - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_reading_string, redir, 0); - } -#line 2279 "y.tab.c" - break; - - case 33: /* redirection: REDIR_WORD LESS_LESS_LESS WORD */ -#line 616 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.filename = (yyvsp[-2].word); - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_reading_string, redir, REDIR_VARASSIGN); - } -#line 2289 "y.tab.c" - break; - - case 34: /* redirection: LESS_AND NUMBER */ -#line 622 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.dest = 0; - redir.dest = (yyvsp[0].number); - (yyval.redirect) = make_redirection (source, r_duplicating_input, redir, 0); - } -#line 2299 "y.tab.c" - break; - - case 35: /* redirection: NUMBER LESS_AND NUMBER */ -#line 628 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.dest = (yyvsp[-2].number); - redir.dest = (yyvsp[0].number); - (yyval.redirect) = make_redirection (source, r_duplicating_input, redir, 0); - } -#line 2309 "y.tab.c" - break; - - case 36: /* redirection: REDIR_WORD LESS_AND NUMBER */ -#line 634 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.filename = (yyvsp[-2].word); - redir.dest = (yyvsp[0].number); - (yyval.redirect) = make_redirection (source, r_duplicating_input, redir, REDIR_VARASSIGN); - } -#line 2319 "y.tab.c" - break; - - case 37: /* redirection: GREATER_AND NUMBER */ -#line 640 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.dest = 1; - redir.dest = (yyvsp[0].number); - (yyval.redirect) = make_redirection (source, r_duplicating_output, redir, 0); - } -#line 2329 "y.tab.c" - break; - - case 38: /* redirection: NUMBER GREATER_AND NUMBER */ -#line 646 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.dest = (yyvsp[-2].number); - redir.dest = (yyvsp[0].number); - (yyval.redirect) = make_redirection (source, r_duplicating_output, redir, 0); - } -#line 2339 "y.tab.c" - break; - - case 39: /* redirection: REDIR_WORD GREATER_AND NUMBER */ -#line 652 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.filename = (yyvsp[-2].word); - redir.dest = (yyvsp[0].number); - (yyval.redirect) = make_redirection (source, r_duplicating_output, redir, REDIR_VARASSIGN); - } -#line 2349 "y.tab.c" - break; - - case 40: /* redirection: LESS_AND WORD */ -#line 658 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.dest = 0; - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_duplicating_input_word, redir, 0); - } -#line 2359 "y.tab.c" - break; - - case 41: /* redirection: NUMBER LESS_AND WORD */ -#line 664 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.dest = (yyvsp[-2].number); - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_duplicating_input_word, redir, 0); - } -#line 2369 "y.tab.c" - break; - - case 42: /* redirection: REDIR_WORD LESS_AND WORD */ -#line 670 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.filename = (yyvsp[-2].word); - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_duplicating_input_word, redir, REDIR_VARASSIGN); - } -#line 2379 "y.tab.c" - break; - - case 43: /* redirection: GREATER_AND WORD */ -#line 676 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.dest = 1; - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_duplicating_output_word, redir, 0); - } -#line 2389 "y.tab.c" - break; - - case 44: /* redirection: NUMBER GREATER_AND WORD */ -#line 682 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.dest = (yyvsp[-2].number); - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_duplicating_output_word, redir, 0); - } -#line 2399 "y.tab.c" - break; - - case 45: /* redirection: REDIR_WORD GREATER_AND WORD */ -#line 688 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.filename = (yyvsp[-2].word); - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_duplicating_output_word, redir, REDIR_VARASSIGN); - } -#line 2409 "y.tab.c" - break; - - case 46: /* redirection: GREATER_AND '-' */ -#line 694 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.dest = 1; - redir.dest = 0; - (yyval.redirect) = make_redirection (source, r_close_this, redir, 0); - } -#line 2419 "y.tab.c" - break; - - case 47: /* redirection: NUMBER GREATER_AND '-' */ -#line 700 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.dest = (yyvsp[-2].number); - redir.dest = 0; - (yyval.redirect) = make_redirection (source, r_close_this, redir, 0); - } -#line 2429 "y.tab.c" - break; - - case 48: /* redirection: REDIR_WORD GREATER_AND '-' */ -#line 706 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.filename = (yyvsp[-2].word); - redir.dest = 0; - (yyval.redirect) = make_redirection (source, r_close_this, redir, REDIR_VARASSIGN); - } -#line 2439 "y.tab.c" - break; - - case 49: /* redirection: LESS_AND '-' */ -#line 712 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.dest = 0; - redir.dest = 0; - (yyval.redirect) = make_redirection (source, r_close_this, redir, 0); - } -#line 2449 "y.tab.c" - break; - - case 50: /* redirection: NUMBER LESS_AND '-' */ -#line 718 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.dest = (yyvsp[-2].number); - redir.dest = 0; - (yyval.redirect) = make_redirection (source, r_close_this, redir, 0); - } -#line 2459 "y.tab.c" - break; - - case 51: /* redirection: REDIR_WORD LESS_AND '-' */ -#line 724 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.filename = (yyvsp[-2].word); - redir.dest = 0; - (yyval.redirect) = make_redirection (source, r_close_this, redir, REDIR_VARASSIGN); - } -#line 2469 "y.tab.c" - break; - - case 52: /* redirection: AND_GREATER WORD */ -#line 730 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.dest = 1; - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_err_and_out, redir, 0); - } -#line 2479 "y.tab.c" - break; - - case 53: /* redirection: AND_GREATER_GREATER WORD */ -#line 736 "/usr/local/src/chet/src/bash/src/parse.y" - { - source.dest = 1; - redir.filename = (yyvsp[0].word); - (yyval.redirect) = make_redirection (source, r_append_err_and_out, redir, 0); - } -#line 2489 "y.tab.c" - break; - - case 54: /* simple_command_element: WORD */ -#line 744 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.element).word = (yyvsp[0].word); (yyval.element).redirect = 0; } -#line 2495 "y.tab.c" - break; - - case 55: /* simple_command_element: ASSIGNMENT_WORD */ -#line 746 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.element).word = (yyvsp[0].word); (yyval.element).redirect = 0; } -#line 2501 "y.tab.c" - break; - - case 56: /* simple_command_element: redirection */ -#line 748 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.element).redirect = (yyvsp[0].redirect); (yyval.element).word = 0; } -#line 2507 "y.tab.c" - break; - - case 57: /* redirection_list: redirection */ -#line 752 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.redirect) = (yyvsp[0].redirect); - } -#line 2515 "y.tab.c" - break; - - case 58: /* redirection_list: redirection_list redirection */ -#line 756 "/usr/local/src/chet/src/bash/src/parse.y" - { - register REDIRECT *t; - - for (t = (yyvsp[-1].redirect); t->next; t = t->next) - ; - t->next = (yyvsp[0].redirect); - (yyval.redirect) = (yyvsp[-1].redirect); - } -#line 2528 "y.tab.c" - break; - - case 59: /* simple_command: simple_command_element */ -#line 767 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = make_simple_command ((yyvsp[0].element), (COMMAND *)NULL); } -#line 2534 "y.tab.c" - break; - - case 60: /* simple_command: simple_command simple_command_element */ -#line 769 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = make_simple_command ((yyvsp[0].element), (yyvsp[-1].command)); } -#line 2540 "y.tab.c" - break; - - case 61: /* command: simple_command */ -#line 773 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = clean_simple_command ((yyvsp[0].command)); } -#line 2546 "y.tab.c" - break; - - case 62: /* command: shell_command */ -#line 775 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = (yyvsp[0].command); } -#line 2552 "y.tab.c" - break; - - case 63: /* command: shell_command redirection_list */ -#line 777 "/usr/local/src/chet/src/bash/src/parse.y" - { - COMMAND *tc; - - tc = (yyvsp[-1].command); - if (tc && tc->redirects) - { - register REDIRECT *t; - for (t = tc->redirects; t->next; t = t->next) - ; - t->next = (yyvsp[0].redirect); - } - else if (tc) - tc->redirects = (yyvsp[0].redirect); - (yyval.command) = (yyvsp[-1].command); - } -#line 2572 "y.tab.c" - break; - - case 64: /* command: function_def */ -#line 793 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = (yyvsp[0].command); } -#line 2578 "y.tab.c" - break; - - case 65: /* command: coproc */ -#line 795 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = (yyvsp[0].command); } -#line 2584 "y.tab.c" - break; - - case 66: /* shell_command: for_command */ -#line 799 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = (yyvsp[0].command); } -#line 2590 "y.tab.c" - break; - - case 67: /* shell_command: case_command */ -#line 801 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = (yyvsp[0].command); } -#line 2596 "y.tab.c" - break; - - case 68: /* shell_command: WHILE compound_list DO compound_list DONE */ -#line 803 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = make_while_command ((yyvsp[-3].command), (yyvsp[-1].command)); } -#line 2602 "y.tab.c" - break; - - case 69: /* shell_command: UNTIL compound_list DO compound_list DONE */ -#line 805 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = make_until_command ((yyvsp[-3].command), (yyvsp[-1].command)); } -#line 2608 "y.tab.c" - break; - - case 70: /* shell_command: select_command */ -#line 807 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = (yyvsp[0].command); } -#line 2614 "y.tab.c" - break; - - case 71: /* shell_command: if_command */ -#line 809 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = (yyvsp[0].command); } -#line 2620 "y.tab.c" - break; - - case 72: /* shell_command: subshell */ -#line 811 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = (yyvsp[0].command); } -#line 2626 "y.tab.c" - break; - - case 73: /* shell_command: group_command */ -#line 813 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = (yyvsp[0].command); } -#line 2632 "y.tab.c" - break; - - case 74: /* shell_command: arith_command */ -#line 815 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = (yyvsp[0].command); } -#line 2638 "y.tab.c" - break; - - case 75: /* shell_command: cond_command */ -#line 817 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = (yyvsp[0].command); } -#line 2644 "y.tab.c" - break; - - case 76: /* shell_command: arith_for_command */ -#line 819 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = (yyvsp[0].command); } -#line 2650 "y.tab.c" - break; - - case 77: /* for_command: FOR WORD newline_list DO compound_list DONE */ -#line 823 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = make_for_command ((yyvsp[-4].word), add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), (yyvsp[-1].command), word_lineno[word_top]); - if (word_top > 0) word_top--; - } -#line 2659 "y.tab.c" - break; - - case 78: /* for_command: FOR WORD newline_list '{' compound_list '}' */ -#line 828 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = make_for_command ((yyvsp[-4].word), add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), (yyvsp[-1].command), word_lineno[word_top]); - if (word_top > 0) word_top--; - } -#line 2668 "y.tab.c" - break; - - case 79: /* for_command: FOR WORD ';' newline_list DO compound_list DONE */ -#line 833 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = make_for_command ((yyvsp[-5].word), add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), (yyvsp[-1].command), word_lineno[word_top]); - if (word_top > 0) word_top--; - } -#line 2677 "y.tab.c" - break; - - case 80: /* for_command: FOR WORD ';' newline_list '{' compound_list '}' */ -#line 838 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = make_for_command ((yyvsp[-5].word), add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), (yyvsp[-1].command), word_lineno[word_top]); - if (word_top > 0) word_top--; - } -#line 2686 "y.tab.c" - break; - - case 81: /* for_command: FOR WORD newline_list IN word_list list_terminator newline_list DO compound_list DONE */ -#line 843 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = make_for_command ((yyvsp[-8].word), REVERSE_LIST ((yyvsp[-5].word_list), WORD_LIST *), (yyvsp[-1].command), word_lineno[word_top]); - if (word_top > 0) word_top--; - } -#line 2695 "y.tab.c" - break; - - case 82: /* for_command: FOR WORD newline_list IN word_list list_terminator newline_list '{' compound_list '}' */ -#line 848 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = make_for_command ((yyvsp[-8].word), REVERSE_LIST ((yyvsp[-5].word_list), WORD_LIST *), (yyvsp[-1].command), word_lineno[word_top]); - if (word_top > 0) word_top--; - } -#line 2704 "y.tab.c" - break; - - case 83: /* for_command: FOR WORD newline_list IN list_terminator newline_list DO compound_list DONE */ -#line 853 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = make_for_command ((yyvsp[-7].word), (WORD_LIST *)NULL, (yyvsp[-1].command), word_lineno[word_top]); - if (word_top > 0) word_top--; - } -#line 2713 "y.tab.c" - break; - - case 84: /* for_command: FOR WORD newline_list IN list_terminator newline_list '{' compound_list '}' */ -#line 858 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = make_for_command ((yyvsp[-7].word), (WORD_LIST *)NULL, (yyvsp[-1].command), word_lineno[word_top]); - if (word_top > 0) word_top--; - } -#line 2722 "y.tab.c" - break; - - case 85: /* arith_for_command: FOR ARITH_FOR_EXPRS list_terminator newline_list DO compound_list DONE */ -#line 865 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = make_arith_for_command ((yyvsp[-5].word_list), (yyvsp[-1].command), arith_for_lineno); - if ((yyval.command) == 0) YYERROR; - if (word_top > 0) word_top--; - } -#line 2732 "y.tab.c" - break; - - case 86: /* arith_for_command: FOR ARITH_FOR_EXPRS list_terminator newline_list '{' compound_list '}' */ -#line 871 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = make_arith_for_command ((yyvsp[-5].word_list), (yyvsp[-1].command), arith_for_lineno); - if ((yyval.command) == 0) YYERROR; - if (word_top > 0) word_top--; - } -#line 2742 "y.tab.c" - break; - - case 87: /* arith_for_command: FOR ARITH_FOR_EXPRS DO compound_list DONE */ -#line 877 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = make_arith_for_command ((yyvsp[-3].word_list), (yyvsp[-1].command), arith_for_lineno); - if ((yyval.command) == 0) YYERROR; - if (word_top > 0) word_top--; - } -#line 2752 "y.tab.c" - break; - - case 88: /* arith_for_command: FOR ARITH_FOR_EXPRS '{' compound_list '}' */ -#line 883 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = make_arith_for_command ((yyvsp[-3].word_list), (yyvsp[-1].command), arith_for_lineno); - if ((yyval.command) == 0) YYERROR; - if (word_top > 0) word_top--; - } -#line 2762 "y.tab.c" - break; - - case 89: /* select_command: SELECT WORD newline_list DO compound_list DONE */ -#line 891 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = make_select_command ((yyvsp[-4].word), add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), (yyvsp[-1].command), word_lineno[word_top]); - if (word_top > 0) word_top--; - } -#line 2771 "y.tab.c" - break; - - case 90: /* select_command: SELECT WORD newline_list '{' compound_list '}' */ -#line 896 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = make_select_command ((yyvsp[-4].word), add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), (yyvsp[-1].command), word_lineno[word_top]); - if (word_top > 0) word_top--; - } -#line 2780 "y.tab.c" - break; - - case 91: /* select_command: SELECT WORD ';' newline_list DO compound_list DONE */ -#line 901 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = make_select_command ((yyvsp[-5].word), add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), (yyvsp[-1].command), word_lineno[word_top]); - if (word_top > 0) word_top--; - } -#line 2789 "y.tab.c" - break; - - case 92: /* select_command: SELECT WORD ';' newline_list '{' compound_list '}' */ -#line 906 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = make_select_command ((yyvsp[-5].word), add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), (yyvsp[-1].command), word_lineno[word_top]); - if (word_top > 0) word_top--; - } -#line 2798 "y.tab.c" - break; - - case 93: /* select_command: SELECT WORD newline_list IN word_list list_terminator newline_list DO compound_list DONE */ -#line 911 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = make_select_command ((yyvsp[-8].word), REVERSE_LIST ((yyvsp[-5].word_list), WORD_LIST *), (yyvsp[-1].command), word_lineno[word_top]); - if (word_top > 0) word_top--; - } -#line 2807 "y.tab.c" - break; - - case 94: /* select_command: SELECT WORD newline_list IN word_list list_terminator newline_list '{' compound_list '}' */ -#line 916 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = make_select_command ((yyvsp[-8].word), REVERSE_LIST ((yyvsp[-5].word_list), WORD_LIST *), (yyvsp[-1].command), word_lineno[word_top]); - if (word_top > 0) word_top--; - } -#line 2816 "y.tab.c" - break; - - case 95: /* select_command: SELECT WORD newline_list IN list_terminator newline_list DO compound_list DONE */ -#line 921 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = make_select_command ((yyvsp[-7].word), (WORD_LIST *)NULL, (yyvsp[-1].command), word_lineno[word_top]); - if (word_top > 0) word_top--; - } -#line 2825 "y.tab.c" - break; - - case 96: /* select_command: SELECT WORD newline_list IN list_terminator newline_list '{' compound_list '}' */ -#line 926 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = make_select_command ((yyvsp[-7].word), (WORD_LIST *)NULL, (yyvsp[-1].command), word_lineno[word_top]); - if (word_top > 0) word_top--; - } -#line 2834 "y.tab.c" - break; - - case 97: /* case_command: CASE WORD newline_list IN newline_list ESAC */ -#line 933 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = make_case_command ((yyvsp[-4].word), (PATTERN_LIST *)NULL, word_lineno[word_top]); - if (word_top > 0) word_top--; - } -#line 2843 "y.tab.c" - break; - - case 98: /* case_command: CASE WORD newline_list IN case_clause_sequence newline_list ESAC */ -#line 938 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = make_case_command ((yyvsp[-5].word), (yyvsp[-2].pattern), word_lineno[word_top]); - if (word_top > 0) word_top--; - } -#line 2852 "y.tab.c" - break; - - case 99: /* case_command: CASE WORD newline_list IN case_clause ESAC */ -#line 943 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = make_case_command ((yyvsp[-4].word), (yyvsp[-1].pattern), word_lineno[word_top]); - if (word_top > 0) word_top--; - } -#line 2861 "y.tab.c" - break; - - case 100: /* function_def: WORD '(' ')' newline_list function_body */ -#line 950 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = make_function_def ((yyvsp[-4].word), (yyvsp[0].command), function_dstart, function_bstart); } -#line 2867 "y.tab.c" - break; - - case 101: /* function_def: FUNCTION WORD '(' ')' newline_list function_body */ -#line 952 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = make_function_def ((yyvsp[-4].word), (yyvsp[0].command), function_dstart, function_bstart); } -#line 2873 "y.tab.c" - break; - - case 102: /* function_def: FUNCTION WORD function_body */ -#line 954 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = make_function_def ((yyvsp[-1].word), (yyvsp[0].command), function_dstart, function_bstart); } -#line 2879 "y.tab.c" - break; - - case 103: /* function_def: FUNCTION WORD '\n' newline_list function_body */ -#line 956 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = make_function_def ((yyvsp[-3].word), (yyvsp[0].command), function_dstart, function_bstart); } -#line 2885 "y.tab.c" - break; - - case 104: /* function_body: shell_command */ -#line 960 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = (yyvsp[0].command); } -#line 2891 "y.tab.c" - break; - - case 105: /* function_body: shell_command redirection_list */ -#line 962 "/usr/local/src/chet/src/bash/src/parse.y" - { - COMMAND *tc; - - tc = (yyvsp[-1].command); - /* According to Posix.2 3.9.5, redirections - specified after the body of a function should - be attached to the function and performed when - the function is executed, not as part of the - function definition command. */ - /* XXX - I don't think it matters, but we might - want to change this in the future to avoid - problems differentiating between a function - definition with a redirection and a function - definition containing a single command with a - redirection. The two are semantically equivalent, - though -- the only difference is in how the - command printing code displays the redirections. */ - if (tc && tc->redirects) - { - register REDIRECT *t; - for (t = tc->redirects; t->next; t = t->next) - ; - t->next = (yyvsp[0].redirect); - } - else if (tc) - tc->redirects = (yyvsp[0].redirect); - (yyval.command) = (yyvsp[-1].command); - } -#line 2924 "y.tab.c" - break; - - case 106: /* subshell: '(' compound_list ')' */ -#line 993 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = make_subshell_command ((yyvsp[-1].command)); - (yyval.command)->flags |= CMD_WANT_SUBSHELL; - } -#line 2933 "y.tab.c" - break; - - case 107: /* comsub: DOLPAREN compound_list ')' */ -#line 1000 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = (yyvsp[-1].command); - } -#line 2941 "y.tab.c" - break; - - case 108: /* comsub: DOLPAREN newline_list ')' */ -#line 1004 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = (COMMAND *)NULL; - } -#line 2949 "y.tab.c" - break; - - case 109: /* coproc: COPROC shell_command */ -#line 1010 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = make_coproc_command ("COPROC", (yyvsp[0].command)); - (yyval.command)->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL; - } -#line 2958 "y.tab.c" - break; - - case 110: /* coproc: COPROC shell_command redirection_list */ -#line 1015 "/usr/local/src/chet/src/bash/src/parse.y" - { - COMMAND *tc; - - tc = (yyvsp[-1].command); - if (tc && tc->redirects) - { - register REDIRECT *t; - for (t = tc->redirects; t->next; t = t->next) - ; - t->next = (yyvsp[0].redirect); - } - else if (tc) - tc->redirects = (yyvsp[0].redirect); - (yyval.command) = make_coproc_command ("COPROC", (yyvsp[-1].command)); - (yyval.command)->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL; - } -#line 2979 "y.tab.c" - break; - - case 111: /* coproc: COPROC WORD shell_command */ -#line 1032 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = make_coproc_command ((yyvsp[-1].word)->word, (yyvsp[0].command)); - (yyval.command)->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL; - } -#line 2988 "y.tab.c" - break; - - case 112: /* coproc: COPROC WORD shell_command redirection_list */ -#line 1037 "/usr/local/src/chet/src/bash/src/parse.y" - { - COMMAND *tc; - - tc = (yyvsp[-1].command); - if (tc && tc->redirects) - { - register REDIRECT *t; - for (t = tc->redirects; t->next; t = t->next) - ; - t->next = (yyvsp[0].redirect); - } - else if (tc) - tc->redirects = (yyvsp[0].redirect); - (yyval.command) = make_coproc_command ((yyvsp[-2].word)->word, (yyvsp[-1].command)); - (yyval.command)->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL; - } -#line 3009 "y.tab.c" - break; - - case 113: /* coproc: COPROC simple_command */ -#line 1054 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = make_coproc_command ("COPROC", clean_simple_command ((yyvsp[0].command))); - (yyval.command)->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL; - } -#line 3018 "y.tab.c" - break; - - case 114: /* if_command: IF compound_list THEN compound_list FI */ -#line 1061 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = make_if_command ((yyvsp[-3].command), (yyvsp[-1].command), (COMMAND *)NULL); } -#line 3024 "y.tab.c" - break; - - case 115: /* if_command: IF compound_list THEN compound_list ELSE compound_list FI */ -#line 1063 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = make_if_command ((yyvsp[-5].command), (yyvsp[-3].command), (yyvsp[-1].command)); } -#line 3030 "y.tab.c" - break; - - case 116: /* if_command: IF compound_list THEN compound_list elif_clause FI */ -#line 1065 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = make_if_command ((yyvsp[-4].command), (yyvsp[-2].command), (yyvsp[-1].command)); } -#line 3036 "y.tab.c" - break; - - case 117: /* group_command: '{' compound_list '}' */ -#line 1070 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = make_group_command ((yyvsp[-1].command)); } -#line 3042 "y.tab.c" - break; - - case 118: /* arith_command: ARITH_CMD */ -#line 1074 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = make_arith_command ((yyvsp[0].word_list)); } -#line 3048 "y.tab.c" - break; - - case 119: /* cond_command: COND_START COND_CMD COND_END */ -#line 1078 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = (yyvsp[-1].command); } -#line 3054 "y.tab.c" - break; - - case 120: /* elif_clause: ELIF compound_list THEN compound_list */ -#line 1082 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = make_if_command ((yyvsp[-2].command), (yyvsp[0].command), (COMMAND *)NULL); } -#line 3060 "y.tab.c" - break; - - case 121: /* elif_clause: ELIF compound_list THEN compound_list ELSE compound_list */ -#line 1084 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = make_if_command ((yyvsp[-4].command), (yyvsp[-2].command), (yyvsp[0].command)); } -#line 3066 "y.tab.c" - break; - - case 122: /* elif_clause: ELIF compound_list THEN compound_list elif_clause */ -#line 1086 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = make_if_command ((yyvsp[-3].command), (yyvsp[-1].command), (yyvsp[0].command)); } -#line 3072 "y.tab.c" - break; - - case 124: /* case_clause: case_clause_sequence pattern_list */ -#line 1091 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyvsp[0].pattern)->next = (yyvsp[-1].pattern); (yyval.pattern) = (yyvsp[0].pattern); } -#line 3078 "y.tab.c" - break; - - case 125: /* pattern_list: newline_list pattern ')' compound_list */ -#line 1095 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.pattern) = make_pattern_list ((yyvsp[-2].word_list), (yyvsp[0].command)); } -#line 3084 "y.tab.c" - break; - - case 126: /* pattern_list: newline_list pattern ')' newline_list */ -#line 1097 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.pattern) = make_pattern_list ((yyvsp[-2].word_list), (COMMAND *)NULL); } -#line 3090 "y.tab.c" - break; - - case 127: /* pattern_list: newline_list '(' pattern ')' compound_list */ -#line 1099 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.pattern) = make_pattern_list ((yyvsp[-2].word_list), (yyvsp[0].command)); } -#line 3096 "y.tab.c" - break; - - case 128: /* pattern_list: newline_list '(' pattern ')' newline_list */ -#line 1101 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.pattern) = make_pattern_list ((yyvsp[-2].word_list), (COMMAND *)NULL); } -#line 3102 "y.tab.c" - break; - - case 129: /* case_clause_sequence: pattern_list SEMI_SEMI */ -#line 1105 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.pattern) = (yyvsp[-1].pattern); } -#line 3108 "y.tab.c" - break; - - case 130: /* case_clause_sequence: case_clause_sequence pattern_list SEMI_SEMI */ -#line 1107 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyvsp[-1].pattern)->next = (yyvsp[-2].pattern); (yyval.pattern) = (yyvsp[-1].pattern); } -#line 3114 "y.tab.c" - break; - - case 131: /* case_clause_sequence: pattern_list SEMI_AND */ -#line 1109 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyvsp[-1].pattern)->flags |= CASEPAT_FALLTHROUGH; (yyval.pattern) = (yyvsp[-1].pattern); } -#line 3120 "y.tab.c" - break; - - case 132: /* case_clause_sequence: case_clause_sequence pattern_list SEMI_AND */ -#line 1111 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyvsp[-1].pattern)->flags |= CASEPAT_FALLTHROUGH; (yyvsp[-1].pattern)->next = (yyvsp[-2].pattern); (yyval.pattern) = (yyvsp[-1].pattern); } -#line 3126 "y.tab.c" - break; - - case 133: /* case_clause_sequence: pattern_list SEMI_SEMI_AND */ -#line 1113 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyvsp[-1].pattern)->flags |= CASEPAT_TESTNEXT; (yyval.pattern) = (yyvsp[-1].pattern); } -#line 3132 "y.tab.c" - break; - - case 134: /* case_clause_sequence: case_clause_sequence pattern_list SEMI_SEMI_AND */ -#line 1115 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyvsp[-1].pattern)->flags |= CASEPAT_TESTNEXT; (yyvsp[-1].pattern)->next = (yyvsp[-2].pattern); (yyval.pattern) = (yyvsp[-1].pattern); } -#line 3138 "y.tab.c" - break; - - case 135: /* pattern: WORD */ -#line 1119 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.word_list) = make_word_list ((yyvsp[0].word), (WORD_LIST *)NULL); } -#line 3144 "y.tab.c" - break; - - case 136: /* pattern: pattern '|' WORD */ -#line 1121 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.word_list) = make_word_list ((yyvsp[0].word), (yyvsp[-2].word_list)); } -#line 3150 "y.tab.c" - break; - - case 137: /* compound_list: newline_list list0 */ -#line 1130 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = (yyvsp[0].command); - if (need_here_doc && last_read_token == '\n') - gather_here_documents (); - } -#line 3160 "y.tab.c" - break; - - case 138: /* compound_list: newline_list list1 */ -#line 1136 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = (yyvsp[0].command); - } -#line 3168 "y.tab.c" - break; - - case 140: /* list0: list1 '&' newline_list */ -#line 1143 "/usr/local/src/chet/src/bash/src/parse.y" - { - if ((yyvsp[-2].command)->type == cm_connection) - (yyval.command) = connect_async_list ((yyvsp[-2].command), (COMMAND *)NULL, '&'); - else - (yyval.command) = command_connect ((yyvsp[-2].command), (COMMAND *)NULL, '&'); - } -#line 3179 "y.tab.c" - break; - - case 142: /* list1: list1 AND_AND newline_list list1 */ -#line 1154 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = command_connect ((yyvsp[-3].command), (yyvsp[0].command), AND_AND); } -#line 3185 "y.tab.c" - break; - - case 143: /* list1: list1 OR_OR newline_list list1 */ -#line 1156 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = command_connect ((yyvsp[-3].command), (yyvsp[0].command), OR_OR); } -#line 3191 "y.tab.c" - break; - - case 144: /* list1: list1 '&' newline_list list1 */ -#line 1158 "/usr/local/src/chet/src/bash/src/parse.y" - { - if ((yyvsp[-3].command)->type == cm_connection) - (yyval.command) = connect_async_list ((yyvsp[-3].command), (yyvsp[0].command), '&'); - else - (yyval.command) = command_connect ((yyvsp[-3].command), (yyvsp[0].command), '&'); - } -#line 3202 "y.tab.c" - break; - - case 145: /* list1: list1 ';' newline_list list1 */ -#line 1165 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = command_connect ((yyvsp[-3].command), (yyvsp[0].command), ';'); } -#line 3208 "y.tab.c" - break; - - case 146: /* list1: list1 '\n' newline_list list1 */ -#line 1167 "/usr/local/src/chet/src/bash/src/parse.y" - { - if (parser_state & PST_CMDSUBST) - (yyval.command) = command_connect ((yyvsp[-3].command), (yyvsp[0].command), '\n'); - else - (yyval.command) = command_connect ((yyvsp[-3].command), (yyvsp[0].command), ';'); - } -#line 3219 "y.tab.c" - break; - - case 147: /* list1: pipeline_command */ -#line 1174 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = (yyvsp[0].command); } -#line 3225 "y.tab.c" - break; - - case 150: /* list_terminator: '\n' */ -#line 1182 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.number) = '\n'; } -#line 3231 "y.tab.c" - break; - - case 151: /* list_terminator: ';' */ -#line 1184 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.number) = ';'; } -#line 3237 "y.tab.c" - break; - - case 152: /* list_terminator: yacc_EOF */ -#line 1186 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.number) = yacc_EOF; } -#line 3243 "y.tab.c" - break; - - case 155: /* simple_list: simple_list1 */ -#line 1200 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = (yyvsp[0].command); - if (need_here_doc) - gather_here_documents (); /* XXX */ - if ((parser_state & PST_CMDSUBST) && current_token == shell_eof_token) - { -INTERNAL_DEBUG (("LEGACY: parser: command substitution simple_list1 -> simple_list")); - global_command = (yyvsp[0].command); - eof_encountered = 0; - if (bash_input.type == st_string) - rewind_input_string (); - YYACCEPT; - } - } -#line 3262 "y.tab.c" - break; - - case 156: /* simple_list: simple_list1 '&' */ -#line 1215 "/usr/local/src/chet/src/bash/src/parse.y" - { - if ((yyvsp[-1].command)->type == cm_connection) - (yyval.command) = connect_async_list ((yyvsp[-1].command), (COMMAND *)NULL, '&'); - else - (yyval.command) = command_connect ((yyvsp[-1].command), (COMMAND *)NULL, '&'); - if (need_here_doc) - gather_here_documents (); /* XXX */ - if ((parser_state & PST_CMDSUBST) && current_token == shell_eof_token) - { -INTERNAL_DEBUG (("LEGACY: parser: command substitution simple_list1 '&' -> simple_list")); - global_command = (yyvsp[-1].command); - eof_encountered = 0; - if (bash_input.type == st_string) - rewind_input_string (); - YYACCEPT; - } - } -#line 3284 "y.tab.c" - break; - - case 157: /* simple_list: simple_list1 ';' */ -#line 1233 "/usr/local/src/chet/src/bash/src/parse.y" - { - (yyval.command) = (yyvsp[-1].command); - if (need_here_doc) - gather_here_documents (); /* XXX */ - if ((parser_state & PST_CMDSUBST) && current_token == shell_eof_token) - { -INTERNAL_DEBUG (("LEGACY: parser: command substitution simple_list1 ';' -> simple_list")); - global_command = (yyvsp[-1].command); - eof_encountered = 0; - if (bash_input.type == st_string) - rewind_input_string (); - YYACCEPT; - } - } -#line 3303 "y.tab.c" - break; - - case 158: /* simple_list1: simple_list1 AND_AND newline_list simple_list1 */ -#line 1250 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = command_connect ((yyvsp[-3].command), (yyvsp[0].command), AND_AND); } -#line 3309 "y.tab.c" - break; - - case 159: /* simple_list1: simple_list1 OR_OR newline_list simple_list1 */ -#line 1252 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = command_connect ((yyvsp[-3].command), (yyvsp[0].command), OR_OR); } -#line 3315 "y.tab.c" - break; - - case 160: /* simple_list1: simple_list1 '&' simple_list1 */ -#line 1254 "/usr/local/src/chet/src/bash/src/parse.y" - { - if ((yyvsp[-2].command)->type == cm_connection) - (yyval.command) = connect_async_list ((yyvsp[-2].command), (yyvsp[0].command), '&'); - else - (yyval.command) = command_connect ((yyvsp[-2].command), (yyvsp[0].command), '&'); - } -#line 3326 "y.tab.c" - break; - - case 161: /* simple_list1: simple_list1 ';' simple_list1 */ -#line 1261 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = command_connect ((yyvsp[-2].command), (yyvsp[0].command), ';'); } -#line 3332 "y.tab.c" - break; - - case 162: /* simple_list1: pipeline_command */ -#line 1264 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = (yyvsp[0].command); } -#line 3338 "y.tab.c" - break; - - case 163: /* pipeline_command: pipeline */ -#line 1268 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = (yyvsp[0].command); } -#line 3344 "y.tab.c" - break; - - case 164: /* pipeline_command: BANG pipeline_command */ -#line 1270 "/usr/local/src/chet/src/bash/src/parse.y" - { - if ((yyvsp[0].command)) - (yyvsp[0].command)->flags ^= CMD_INVERT_RETURN; /* toggle */ - (yyval.command) = (yyvsp[0].command); - } -#line 3354 "y.tab.c" - break; - - case 165: /* pipeline_command: timespec pipeline_command */ -#line 1276 "/usr/local/src/chet/src/bash/src/parse.y" - { - if ((yyvsp[0].command)) - (yyvsp[0].command)->flags |= (yyvsp[-1].number); - (yyval.command) = (yyvsp[0].command); - } -#line 3364 "y.tab.c" - break; - - case 166: /* pipeline_command: timespec list_terminator */ -#line 1282 "/usr/local/src/chet/src/bash/src/parse.y" - { - ELEMENT x; - - /* Boy, this is unclean. `time' by itself can - time a null command. We cheat and push a - newline back if the list_terminator was a newline - to avoid the double-newline problem (one to - terminate this, one to terminate the command) */ - x.word = 0; - x.redirect = 0; - (yyval.command) = make_simple_command (x, (COMMAND *)NULL); - (yyval.command)->flags |= (yyvsp[-1].number); - /* XXX - let's cheat and push a newline back */ - if ((yyvsp[0].number) == '\n') - token_to_read = '\n'; - else if ((yyvsp[0].number) == ';') - token_to_read = ';'; - parser_state &= ~PST_REDIRLIST; /* make_simple_command sets this */ - } -#line 3388 "y.tab.c" - break; - - case 167: /* pipeline_command: BANG list_terminator */ -#line 1302 "/usr/local/src/chet/src/bash/src/parse.y" - { - ELEMENT x; - - /* This is just as unclean. Posix says that `!' - by itself should be equivalent to `false'. - We cheat and push a - newline back if the list_terminator was a newline - to avoid the double-newline problem (one to - terminate this, one to terminate the command) */ - x.word = 0; - x.redirect = 0; - (yyval.command) = make_simple_command (x, (COMMAND *)NULL); - (yyval.command)->flags |= CMD_INVERT_RETURN; - /* XXX - let's cheat and push a newline back */ - if ((yyvsp[0].number) == '\n') - token_to_read = '\n'; - if ((yyvsp[0].number) == ';') - token_to_read = ';'; - parser_state &= ~PST_REDIRLIST; /* make_simple_command sets this */ - } -#line 3413 "y.tab.c" - break; - - case 168: /* pipeline: pipeline '|' newline_list pipeline */ -#line 1325 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = command_connect ((yyvsp[-3].command), (yyvsp[0].command), '|'); } -#line 3419 "y.tab.c" - break; - - case 169: /* pipeline: pipeline BAR_AND newline_list pipeline */ -#line 1327 "/usr/local/src/chet/src/bash/src/parse.y" - { - /* Make cmd1 |& cmd2 equivalent to cmd1 2>&1 | cmd2 */ - COMMAND *tc; - REDIRECTEE rd, sd; - REDIRECT *r; - - tc = (yyvsp[-3].command)->type == cm_simple ? (COMMAND *)(yyvsp[-3].command)->value.Simple : (yyvsp[-3].command); - sd.dest = 2; - rd.dest = 1; - r = make_redirection (sd, r_duplicating_output, rd, 0); - if (tc->redirects) - { - register REDIRECT *t; - for (t = tc->redirects; t->next; t = t->next) - ; - t->next = r; - } - else - tc->redirects = r; - - (yyval.command) = command_connect ((yyvsp[-3].command), (yyvsp[0].command), '|'); - } -#line 3446 "y.tab.c" - break; - - case 170: /* pipeline: command */ -#line 1350 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.command) = (yyvsp[0].command); } -#line 3452 "y.tab.c" - break; - - case 171: /* timespec: TIME */ -#line 1354 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.number) = CMD_TIME_PIPELINE; } -#line 3458 "y.tab.c" - break; - - case 172: /* timespec: TIME TIMEOPT */ -#line 1356 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.number) = CMD_TIME_PIPELINE|CMD_TIME_POSIX; } -#line 3464 "y.tab.c" - break; - - case 173: /* timespec: TIME TIMEIGN */ -#line 1358 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.number) = CMD_TIME_PIPELINE|CMD_TIME_POSIX; } -#line 3470 "y.tab.c" - break; - - case 174: /* timespec: TIME TIMEOPT TIMEIGN */ -#line 1360 "/usr/local/src/chet/src/bash/src/parse.y" - { (yyval.number) = CMD_TIME_PIPELINE|CMD_TIME_POSIX; } -#line 3476 "y.tab.c" - break; - - -#line 3480 "y.tab.c" - - default: break; - } - /* User semantic actions sometimes alter yychar, and that requires - that yytoken be updated with the new translation. We take the - approach of translating immediately before every use of yytoken. - One alternative is translating here after every semantic action, - but that translation would be missed if the semantic action invokes - YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or - if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an - incorrect destructor might then be invoked immediately. In the - case of YYERROR or YYBACKUP, subsequent parser actions might lead - to an incorrect destructor call or verbose syntax error message - before the lookahead is translated. */ - YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - - *++yyvsp = yyval; - - /* Now 'shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - { - const int yylhs = yyr1[yyn] - YYNTOKENS; - const int yyi = yypgoto[yylhs] + *yyssp; - yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp - ? yytable[yyi] - : yydefgoto[yylhs]); - } - - goto yynewstate; - - -/*--------------------------------------. -| yyerrlab -- here on detecting error. | -`--------------------------------------*/ -yyerrlab: - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar); - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; - yyerror (YY_("syntax error")); - } - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - /* Pacify compilers when the user code never invokes YYERROR and the - label yyerrorlab therefore never appears in user code. */ - if (0) - YYERROR; - ++yynerrs; - - /* Do not reclaim the symbols of the rule whose action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - /* Pop stack until we find a state that shifts the error token. */ - for (;;) - { - yyn = yypact[yystate]; - if (!yypact_value_is_default (yyn)) - { - yyn += YYSYMBOL_YYerror; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - - yydestruct ("Error: popping", - YY_ACCESSING_SYMBOL (yystate), yyvsp); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturnlab; - - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturnlab; - - -/*-----------------------------------------------------------. -| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. | -`-----------------------------------------------------------*/ -yyexhaustedlab: - yyerror (YY_("memory exhausted")); - yyresult = 2; - goto yyreturnlab; - - -/*----------------------------------------------------------. -| yyreturnlab -- parsing is finished, clean up and return. | -`----------------------------------------------------------*/ -yyreturnlab: - if (yychar != YYEMPTY) - { - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = YYTRANSLATE (yychar); - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval); - } - /* Do not reclaim the symbols of the rule whose action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - YY_ACCESSING_SYMBOL (+*yyssp), yyvsp); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif - - return yyresult; -} - -#line 1362 "/usr/local/src/chet/src/bash/src/parse.y" - - -/* Initial size to allocate for tokens, and the - amount to grow them by. */ -#define TOKEN_DEFAULT_INITIAL_SIZE 496 -#define TOKEN_DEFAULT_GROW_SIZE 512 - -/* Should we call prompt_again? */ -#define SHOULD_PROMPT() \ - (interactive && (bash_input.type == st_stdin || bash_input.type == st_stream)) - -#if defined (ALIAS) -# define expanding_alias() (pushed_string_list && pushed_string_list->expander) -#else -# define expanding_alias() 0 -#endif - -/* Global var is non-zero when end of file has been reached. */ -int EOF_Reached = 0; - -#ifdef DEBUG -static void -debug_parser (i) - int i; -{ -#if YYDEBUG != 0 - yydebug = i; - yyoutstream = stdout; - yyerrstream = stderr; -#endif -} -#endif - -/* yy_getc () returns the next available character from input or EOF. - yy_ungetc (c) makes `c' the next character to read. - init_yy_io (get, unget, type, location) makes the function GET the - installed function for getting the next character, makes UNGET the - installed function for un-getting a character, sets the type of stream - (either string or file) from TYPE, and makes LOCATION point to where - the input is coming from. */ - -/* Unconditionally returns end-of-file. */ -int -return_EOF () -{ - return (EOF); -} - -/* Variable containing the current get and unget functions. - See ./input.h for a clearer description. */ -BASH_INPUT bash_input; - -/* Set all of the fields in BASH_INPUT to NULL. Free bash_input.name if it - is non-null, avoiding a memory leak. */ -void -initialize_bash_input () -{ - bash_input.type = st_none; - FREE (bash_input.name); - bash_input.name = (char *)NULL; - bash_input.location.file = (FILE *)NULL; - bash_input.location.string = (char *)NULL; - bash_input.getter = (sh_cget_func_t *)NULL; - bash_input.ungetter = (sh_cunget_func_t *)NULL; -} - -/* Set the contents of the current bash input stream from - GET, UNGET, TYPE, NAME, and LOCATION. */ -void -init_yy_io (get, unget, type, name, location) - sh_cget_func_t *get; - sh_cunget_func_t *unget; - enum stream_type type; - const char *name; - INPUT_STREAM location; -{ - bash_input.type = type; - FREE (bash_input.name); - bash_input.name = name ? savestring (name) : (char *)NULL; - - /* XXX */ -#if defined (CRAY) - memcpy((char *)&bash_input.location.string, (char *)&location.string, sizeof(location)); -#else - bash_input.location = location; -#endif - bash_input.getter = get; - bash_input.ungetter = unget; -} - -char * -yy_input_name () -{ - return (bash_input.name ? bash_input.name : "stdin"); -} - -/* Call this to get the next character of input. */ -static int -yy_getc () -{ - return (*(bash_input.getter)) (); -} - -/* Call this to unget C. That is, to make C the next character - to be read. */ -static int -yy_ungetc (c) - int c; -{ - return (*(bash_input.ungetter)) (c); -} - -#if defined (BUFFERED_INPUT) -#ifdef INCLUDE_UNUSED -int -input_file_descriptor () -{ - switch (bash_input.type) - { - case st_stream: - return (fileno (bash_input.location.file)); - case st_bstream: - return (bash_input.location.buffered_fd); - case st_stdin: - default: - return (fileno (stdin)); - } -} -#endif -#endif /* BUFFERED_INPUT */ - -/* **************************************************************** */ -/* */ -/* Let input be read from readline (). */ -/* */ -/* **************************************************************** */ - -#if defined (READLINE) -char *current_readline_prompt = (char *)NULL; -char *current_readline_line = (char *)NULL; -int current_readline_line_index = 0; - -static int -yy_readline_get () -{ - SigHandler *old_sigint; - int line_len; - unsigned char c; - - if (current_readline_line == 0) - { - if (bash_readline_initialized == 0) - initialize_readline (); - -#if defined (JOB_CONTROL) - if (job_control) - give_terminal_to (shell_pgrp, 0); -#endif /* JOB_CONTROL */ - - old_sigint = IMPOSSIBLE_TRAP_HANDLER; - if (signal_is_ignored (SIGINT) == 0) - { - old_sigint = (SigHandler *)set_signal_handler (SIGINT, sigint_sighandler); - } - - sh_unset_nodelay_mode (fileno (rl_instream)); /* just in case */ - current_readline_line = readline (current_readline_prompt ? - current_readline_prompt : ""); - - CHECK_TERMSIG; - if (signal_is_ignored (SIGINT) == 0) - { - if (old_sigint != IMPOSSIBLE_TRAP_HANDLER) - set_signal_handler (SIGINT, old_sigint); - } - -#if 0 - /* Reset the prompt to the decoded value of prompt_string_pointer. */ - reset_readline_prompt (); -#endif - - if (current_readline_line == 0) - return (EOF); - - current_readline_line_index = 0; - line_len = strlen (current_readline_line); - - current_readline_line = (char *)xrealloc (current_readline_line, 2 + line_len); - current_readline_line[line_len++] = '\n'; - current_readline_line[line_len] = '\0'; - } - - if (current_readline_line[current_readline_line_index] == 0) - { - free (current_readline_line); - current_readline_line = (char *)NULL; - return (yy_readline_get ()); - } - else - { - c = current_readline_line[current_readline_line_index++]; - return (c); - } -} - -static int -yy_readline_unget (c) - int c; -{ - if (current_readline_line_index && current_readline_line) - current_readline_line[--current_readline_line_index] = c; - return (c); -} - -void -with_input_from_stdin () -{ - INPUT_STREAM location; - - if (bash_input.type != st_stdin && stream_on_stack (st_stdin) == 0) - { - location.string = current_readline_line; - init_yy_io (yy_readline_get, yy_readline_unget, - st_stdin, "readline stdin", location); - } -} - -/* Will we be collecting another input line and printing a prompt? This uses - different conditions than SHOULD_PROMPT(), since readline allows a user to - embed a newline in the middle of the line it collects, which the parser - will interpret as a line break and command delimiter. */ -int -parser_will_prompt () -{ - return (current_readline_line == 0 || current_readline_line[current_readline_line_index] == 0); -} - -#else /* !READLINE */ - -void -with_input_from_stdin () -{ - with_input_from_stream (stdin, "stdin"); -} -#endif /* !READLINE */ - -/* **************************************************************** */ -/* */ -/* Let input come from STRING. STRING is zero terminated. */ -/* */ -/* **************************************************************** */ - -static int -yy_string_get () -{ - register char *string; - register unsigned char c; - - string = bash_input.location.string; - - /* If the string doesn't exist, or is empty, EOF found. */ - if (string && *string) - { - c = *string++; - bash_input.location.string = string; - return (c); - } - else - return (EOF); -} - -static int -yy_string_unget (c) - int c; -{ - *(--bash_input.location.string) = c; - return (c); -} - -void -with_input_from_string (string, name) - char *string; - const char *name; -{ - INPUT_STREAM location; - - location.string = string; - init_yy_io (yy_string_get, yy_string_unget, st_string, name, location); -} - -/* Count the number of characters we've consumed from bash_input.location.string - and read into shell_input_line, but have not returned from shell_getc. - That is the true input location. Rewind bash_input.location.string by - that number of characters, so it points to the last character actually - consumed by the parser. */ -void -rewind_input_string () -{ - int xchars; - - /* number of unconsumed characters in the input -- XXX need to take newlines - into account, e.g., $(...\n) */ - xchars = shell_input_line_len - shell_input_line_index; - if (bash_input.location.string[-1] == '\n') - xchars++; - - /* XXX - how to reflect bash_input.location.string back to string passed to - parse_and_execute or xparse_dolparen? xparse_dolparen needs to know how - far into the string we parsed. parse_and_execute knows where bash_input. - location.string is, and how far from orig_string that is -- that's the - number of characters the command consumed. */ - - /* bash_input.location.string - xchars should be where we parsed to */ - /* need to do more validation on xchars value for sanity -- test cases. */ - bash_input.location.string -= xchars; -} - -/* **************************************************************** */ -/* */ -/* Let input come from STREAM. */ -/* */ -/* **************************************************************** */ - -/* These two functions used to test the value of the HAVE_RESTARTABLE_SYSCALLS - define, and just use getc/ungetc if it was defined, but since bash - installs most of its signal handlers without the SA_RESTART flag, some - signals received during a read(2) will not cause the read to be restarted. - We will need to restart it ourselves. */ - -static int -yy_stream_get () -{ - int result; - - result = EOF; - if (bash_input.location.file) - { - /* XXX - don't need terminate_immediately; getc_with_restart checks - for terminating signals itself if read returns < 0 */ - result = getc_with_restart (bash_input.location.file); - } - return (result); -} - -static int -yy_stream_unget (c) - int c; -{ - return (ungetc_with_restart (c, bash_input.location.file)); -} - -void -with_input_from_stream (stream, name) - FILE *stream; - const char *name; -{ - INPUT_STREAM location; - - location.file = stream; - init_yy_io (yy_stream_get, yy_stream_unget, st_stream, name, location); -} - -typedef struct stream_saver { - struct stream_saver *next; - BASH_INPUT bash_input; - int line; -#if defined (BUFFERED_INPUT) - BUFFERED_STREAM *bstream; -#endif /* BUFFERED_INPUT */ -} STREAM_SAVER; - -/* The globally known line number. */ -int line_number = 0; - -/* The line number offset set by assigning to LINENO. Not currently used. */ -int line_number_base = 0; - -#if defined (COND_COMMAND) -static int cond_lineno; -static int cond_token; -#endif - -STREAM_SAVER *stream_list = (STREAM_SAVER *)NULL; - -void -push_stream (reset_lineno) - int reset_lineno; -{ - STREAM_SAVER *saver = (STREAM_SAVER *)xmalloc (sizeof (STREAM_SAVER)); - - xbcopy ((char *)&bash_input, (char *)&(saver->bash_input), sizeof (BASH_INPUT)); - -#if defined (BUFFERED_INPUT) - saver->bstream = (BUFFERED_STREAM *)NULL; - /* If we have a buffered stream, clear out buffers[fd]. */ - if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0) - saver->bstream = set_buffered_stream (bash_input.location.buffered_fd, - (BUFFERED_STREAM *)NULL); -#endif /* BUFFERED_INPUT */ - - saver->line = line_number; - bash_input.name = (char *)NULL; - saver->next = stream_list; - stream_list = saver; - EOF_Reached = 0; - if (reset_lineno) - line_number = 0; -} - -void -pop_stream () -{ - if (!stream_list) - EOF_Reached = 1; - else - { - STREAM_SAVER *saver = stream_list; - - EOF_Reached = 0; - stream_list = stream_list->next; - - init_yy_io (saver->bash_input.getter, - saver->bash_input.ungetter, - saver->bash_input.type, - saver->bash_input.name, - saver->bash_input.location); - -#if defined (BUFFERED_INPUT) - /* If we have a buffered stream, restore buffers[fd]. */ - /* If the input file descriptor was changed while this was on the - save stack, update the buffered fd to the new file descriptor and - re-establish the buffer <-> bash_input fd correspondence. */ - if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0) - { - if (bash_input_fd_changed) - { - bash_input_fd_changed = 0; - if (default_buffered_input >= 0) - { - bash_input.location.buffered_fd = default_buffered_input; - saver->bstream->b_fd = default_buffered_input; - SET_CLOSE_ON_EXEC (default_buffered_input); - } - } - /* XXX could free buffered stream returned as result here. */ - set_buffered_stream (bash_input.location.buffered_fd, saver->bstream); - } -#endif /* BUFFERED_INPUT */ - - line_number = saver->line; - - FREE (saver->bash_input.name); - free (saver); - } -} - -/* Return 1 if a stream of type TYPE is saved on the stack. */ -int -stream_on_stack (type) - enum stream_type type; -{ - register STREAM_SAVER *s; - - for (s = stream_list; s; s = s->next) - if (s->bash_input.type == type) - return 1; - return 0; -} - -/* Save the current token state and return it in a malloced array. */ -int * -save_token_state () -{ - int *ret; - - ret = (int *)xmalloc (4 * sizeof (int)); - ret[0] = last_read_token; - ret[1] = token_before_that; - ret[2] = two_tokens_ago; - ret[3] = current_token; - return ret; -} - -void -restore_token_state (ts) - int *ts; -{ - if (ts == 0) - return; - last_read_token = ts[0]; - token_before_that = ts[1]; - two_tokens_ago = ts[2]; - current_token = ts[3]; -} - -/* - * This is used to inhibit alias expansion and reserved word recognition - * inside case statement pattern lists. A `case statement pattern list' is: - * - * everything between the `in' in a `case word in' and the next ')' - * or `esac' - * everything between a `;;' and the next `)' or `esac' - */ - -#define END_OF_ALIAS 0 - -/* - * Pseudo-global variables used in implementing token-wise alias expansion. - */ - -/* - * Pushing and popping strings. This works together with shell_getc to - * implement alias expansion on a per-token basis. - */ - -#define PSH_ALIAS 0x01 -#define PSH_DPAREN 0x02 -#define PSH_SOURCE 0x04 -#define PSH_ARRAY 0x08 - -typedef struct string_saver { - struct string_saver *next; - int expand_alias; /* Value to set expand_alias to when string is popped. */ - char *saved_line; -#if defined (ALIAS) - alias_t *expander; /* alias that caused this line to be pushed. */ -#endif - size_t saved_line_size, saved_line_index, saved_line_len; - int saved_line_terminator; - int flags; -} STRING_SAVER; - -STRING_SAVER *pushed_string_list = (STRING_SAVER *)NULL; - -/* - * Push the current shell_input_line onto a stack of such lines and make S - * the current input. Used when expanding aliases. EXPAND is used to set - * the value of expand_next_token when the string is popped, so that the - * word after the alias in the original line is handled correctly when the - * alias expands to multiple words. TOKEN is the token that was expanded - * into S; it is saved and used to prevent infinite recursive expansion. - */ -static void -push_string (s, expand, ap) - char *s; - int expand; - alias_t *ap; -{ - STRING_SAVER *temp = (STRING_SAVER *)xmalloc (sizeof (STRING_SAVER)); - - temp->expand_alias = expand; - temp->saved_line = shell_input_line; - temp->saved_line_size = shell_input_line_size; - temp->saved_line_len = shell_input_line_len; - temp->saved_line_index = shell_input_line_index; - temp->saved_line_terminator = shell_input_line_terminator; - temp->flags = 0; -#if defined (ALIAS) - temp->expander = ap; - if (ap) - temp->flags = PSH_ALIAS; -#endif - temp->next = pushed_string_list; - pushed_string_list = temp; - -#if defined (ALIAS) - if (ap) - ap->flags |= AL_BEINGEXPANDED; -#endif - - shell_input_line = s; - shell_input_line_size = shell_input_line_len = STRLEN (s); - shell_input_line_index = 0; - shell_input_line_terminator = '\0'; -#if 0 - parser_state &= ~PST_ALEXPNEXT; /* XXX */ -#endif - - set_line_mbstate (); -} - -/* - * Make the top of the pushed_string stack be the current shell input. - * Only called when there is something on the stack. Called from shell_getc - * when it thinks it has consumed the string generated by an alias expansion - * and needs to return to the original input line. - */ -static void -pop_string () -{ - STRING_SAVER *t; - - FREE (shell_input_line); - shell_input_line = pushed_string_list->saved_line; - shell_input_line_index = pushed_string_list->saved_line_index; - shell_input_line_size = pushed_string_list->saved_line_size; - shell_input_line_len = pushed_string_list->saved_line_len; - shell_input_line_terminator = pushed_string_list->saved_line_terminator; - -#if defined (ALIAS) - if (pushed_string_list->expand_alias) - parser_state |= PST_ALEXPNEXT; - else - parser_state &= ~PST_ALEXPNEXT; -#endif - - t = pushed_string_list; - pushed_string_list = pushed_string_list->next; - -#if defined (ALIAS) - if (t->expander) - t->expander->flags &= ~AL_BEINGEXPANDED; -#endif - - free ((char *)t); - - set_line_mbstate (); -} - -static void -free_string_list () -{ - register STRING_SAVER *t, *t1; - - for (t = pushed_string_list; t; ) - { - t1 = t->next; - FREE (t->saved_line); -#if defined (ALIAS) - if (t->expander) - t->expander->flags &= ~AL_BEINGEXPANDED; -#endif - free ((char *)t); - t = t1; - } - pushed_string_list = (STRING_SAVER *)NULL; -} - -void -free_pushed_string_input () -{ -#if defined (ALIAS) || defined (DPAREN_ARITHMETIC) - free_string_list (); -#endif -} - -int -parser_expanding_alias () -{ - return (expanding_alias ()); -} - -void -parser_save_alias () -{ -#if defined (ALIAS) || defined (DPAREN_ARITHMETIC) - push_string ((char *)NULL, 0, (alias_t *)NULL); - pushed_string_list->flags = PSH_SOURCE; /* XXX - for now */ -#else - ; -#endif -} - -void -parser_restore_alias () -{ -#if defined (ALIAS) || defined (DPAREN_ARITHMETIC) - if (pushed_string_list) - pop_string (); -#else - ; -#endif -} - -#if defined (ALIAS) -/* Before freeing AP, make sure that there aren't any cases of pointer - aliasing that could cause us to reference freed memory later on. */ -void -clear_string_list_expander (ap) - alias_t *ap; -{ - register STRING_SAVER *t; - - for (t = pushed_string_list; t; t = t->next) - { - if (t->expander && t->expander == ap) - t->expander = 0; - } -} -#endif - -void -clear_shell_input_line () -{ - if (shell_input_line) - shell_input_line[shell_input_line_index = 0] = '\0'; -} - -/* Return a line of text, taken from wherever yylex () reads input. - If there is no more input, then we return NULL. If REMOVE_QUOTED_NEWLINE - is non-zero, we remove unquoted \ pairs. This is used by - read_secondary_line to read here documents. */ -static char * -read_a_line (remove_quoted_newline) - int remove_quoted_newline; -{ - static char *line_buffer = (char *)NULL; - static int buffer_size = 0; - int indx, c, peekc, pass_next; - -#if defined (READLINE) - if (no_line_editing && SHOULD_PROMPT ()) -#else - if (SHOULD_PROMPT ()) -#endif - print_prompt (); - - pass_next = indx = 0; - while (1) - { - /* Allow immediate exit if interrupted during input. */ - QUIT; - - c = yy_getc (); - - /* Ignore null bytes in input. */ - if (c == 0) - continue; - - /* If there is no more input, then we return NULL. */ - if (c == EOF) - { - if (interactive && bash_input.type == st_stream) - clearerr (stdin); - if (indx == 0) - return ((char *)NULL); - c = '\n'; - } - - /* `+2' in case the final character in the buffer is a newline or we - have to handle CTLESC or CTLNUL. */ - RESIZE_MALLOCED_BUFFER (line_buffer, indx, 2, buffer_size, 128); - - /* IF REMOVE_QUOTED_NEWLINES is non-zero, we are reading a - here document with an unquoted delimiter. In this case, - the line will be expanded as if it were in double quotes. - We allow a backslash to escape the next character, but we - need to treat the backslash specially only if a backslash - quoting a backslash-newline pair appears in the line. */ - if (pass_next) - { - line_buffer[indx++] = c; - pass_next = 0; - } - else if (c == '\\' && remove_quoted_newline) - { - QUIT; - peekc = yy_getc (); - if (peekc == '\n') - { - line_number++; - continue; /* Make the unquoted \ pair disappear. */ - } - else - { - yy_ungetc (peekc); - pass_next = 1; - line_buffer[indx++] = c; /* Preserve the backslash. */ - } - } - else - { - /* remove_quoted_newline is non-zero if the here-document delimiter - is unquoted. In this case, we will be expanding the lines and - need to make sure CTLESC and CTLNUL in the input are quoted. */ - if (remove_quoted_newline && (c == CTLESC || c == CTLNUL)) - line_buffer[indx++] = CTLESC; - line_buffer[indx++] = c; - } - - if (c == '\n') - { - line_buffer[indx] = '\0'; - return (line_buffer); - } - } -} - -/* Return a line as in read_a_line (), but insure that the prompt is - the secondary prompt. This is used to read the lines of a here - document. REMOVE_QUOTED_NEWLINE is non-zero if we should remove - newlines quoted with backslashes while reading the line. It is - non-zero unless the delimiter of the here document was quoted. */ -char * -read_secondary_line (remove_quoted_newline) - int remove_quoted_newline; -{ - char *ret; - int n, c; - - prompt_string_pointer = &ps2_prompt; - if (SHOULD_PROMPT ()) - prompt_again (0); - ret = read_a_line (remove_quoted_newline); -#if defined (HISTORY) - if (ret && remember_on_history && (parser_state & PST_HEREDOC)) - { - /* To make adding the here-document body right, we need to rely on - history_delimiting_chars() returning \n for the first line of the - here-document body and the null string for the second and subsequent - lines, so we avoid double newlines. - current_command_line_count == 2 for the first line of the body. */ - - current_command_line_count++; - maybe_add_history (ret); - } -#endif /* HISTORY */ - return ret; -} - -/* **************************************************************** */ -/* */ -/* YYLEX () */ -/* */ -/* **************************************************************** */ - -/* Reserved words. These are only recognized as the first word of a - command. */ -STRING_INT_ALIST word_token_alist[] = { - { "if", IF }, - { "then", THEN }, - { "else", ELSE }, - { "elif", ELIF }, - { "fi", FI }, - { "case", CASE }, - { "esac", ESAC }, - { "for", FOR }, -#if defined (SELECT_COMMAND) - { "select", SELECT }, -#endif - { "while", WHILE }, - { "until", UNTIL }, - { "do", DO }, - { "done", DONE }, - { "in", IN }, - { "function", FUNCTION }, -#if defined (COMMAND_TIMING) - { "time", TIME }, -#endif - { "{", '{' }, - { "}", '}' }, - { "!", BANG }, -#if defined (COND_COMMAND) - { "[[", COND_START }, - { "]]", COND_END }, -#endif -#if defined (COPROCESS_SUPPORT) - { "coproc", COPROC }, -#endif - { (char *)NULL, 0} -}; - -/* other tokens that can be returned by read_token() */ -STRING_INT_ALIST other_token_alist[] = { - /* Multiple-character tokens with special values */ - { "--", TIMEIGN }, - { "-p", TIMEOPT }, - { "&&", AND_AND }, - { "||", OR_OR }, - { ">>", GREATER_GREATER }, - { "<<", LESS_LESS }, - { "<&", LESS_AND }, - { ">&", GREATER_AND }, - { ";;", SEMI_SEMI }, - { ";&", SEMI_AND }, - { ";;&", SEMI_SEMI_AND }, - { "<<-", LESS_LESS_MINUS }, - { "<<<", LESS_LESS_LESS }, - { "&>", AND_GREATER }, - { "&>>", AND_GREATER_GREATER }, - { "<>", LESS_GREATER }, - { ">|", GREATER_BAR }, - { "|&", BAR_AND }, - { "EOF", yacc_EOF }, - /* Tokens whose value is the character itself */ - { ">", '>' }, - { "<", '<' }, - { "-", '-' }, - { "{", '{' }, - { "}", '}' }, - { ";", ';' }, - { "(", '(' }, - { ")", ')' }, - { "|", '|' }, - { "&", '&' }, - { "newline", '\n' }, - { (char *)NULL, 0} -}; - -/* others not listed here: - WORD look at yylval.word - ASSIGNMENT_WORD look at yylval.word - NUMBER look at yylval.number - ARITH_CMD look at yylval.word_list - ARITH_FOR_EXPRS look at yylval.word_list - COND_CMD look at yylval.command -*/ - -/* These are used by read_token_word, but appear up here so that shell_getc - can use them to decide when to add otherwise blank lines to the history. */ - -/* The primary delimiter stack. */ -struct dstack dstack = { (char *)NULL, 0, 0 }; - -/* A temporary delimiter stack to be used when decoding prompt strings. - This is needed because command substitutions in prompt strings (e.g., PS2) - can screw up the parser's quoting state. */ -static struct dstack temp_dstack = { (char *)NULL, 0, 0 }; - -/* Macro for accessing the top delimiter on the stack. Returns the - delimiter or zero if none. */ -#define current_delimiter(ds) \ - (ds.delimiter_depth ? ds.delimiters[ds.delimiter_depth - 1] : 0) - -#define push_delimiter(ds, character) \ - do \ - { \ - if (ds.delimiter_depth + 2 > ds.delimiter_space) \ - ds.delimiters = (char *)xrealloc \ - (ds.delimiters, (ds.delimiter_space += 10) * sizeof (char)); \ - ds.delimiters[ds.delimiter_depth] = character; \ - ds.delimiter_depth++; \ - } \ - while (0) - -#define pop_delimiter(ds) ds.delimiter_depth-- - -/* Return the next shell input character. This always reads characters - from shell_input_line; when that line is exhausted, it is time to - read the next line. This is called by read_token when the shell is - processing normal command input. */ - -/* This implements one-character lookahead/lookbehind across physical input - lines, to avoid something being lost because it's pushed back with - shell_ungetc when we're at the start of a line. */ -static int eol_ungetc_lookahead = 0; - -static int unquoted_backslash = 0; - -static int -shell_getc (remove_quoted_newline) - int remove_quoted_newline; -{ - register int i; - int c, truncating, last_was_backslash; - unsigned char uc; - - QUIT; - - last_was_backslash = 0; - if (sigwinch_received) - { - sigwinch_received = 0; - get_new_window_size (0, (int *)0, (int *)0); - } - - if (eol_ungetc_lookahead) - { - c = eol_ungetc_lookahead; - eol_ungetc_lookahead = 0; - return (c); - } - -#if defined (ALIAS) || defined (DPAREN_ARITHMETIC) - /* If shell_input_line[shell_input_line_index] == 0, but there is - something on the pushed list of strings, then we don't want to go - off and get another line. We let the code down below handle it. */ - - if (!shell_input_line || ((!shell_input_line[shell_input_line_index]) && - (pushed_string_list == (STRING_SAVER *)NULL))) -#else /* !ALIAS && !DPAREN_ARITHMETIC */ - if (!shell_input_line || !shell_input_line[shell_input_line_index]) -#endif /* !ALIAS && !DPAREN_ARITHMETIC */ - { - line_number++; - - /* Let's not let one really really long line blow up memory allocation */ - if (shell_input_line && shell_input_line_size >= 32768) - { - free (shell_input_line); - shell_input_line = 0; - shell_input_line_size = 0; - } - - restart_read: - - /* Allow immediate exit if interrupted during input. */ - QUIT; - - i = truncating = 0; - shell_input_line_terminator = 0; - - /* If the shell is interactive, but not currently printing a prompt - (interactive_shell && interactive == 0), we don't want to print - notifies or cleanup the jobs -- we want to defer it until we do - print the next prompt. */ - if (interactive_shell == 0 || SHOULD_PROMPT()) - { -#if defined (JOB_CONTROL) - /* This can cause a problem when reading a command as the result - of a trap, when the trap is called from flush_child. This call - had better not cause jobs to disappear from the job table in - that case, or we will have big trouble. */ - notify_and_cleanup (); -#else /* !JOB_CONTROL */ - cleanup_dead_jobs (); -#endif /* !JOB_CONTROL */ - } - -#if defined (READLINE) - if (no_line_editing && SHOULD_PROMPT()) -#else - if (SHOULD_PROMPT()) -#endif - print_prompt (); - - if (bash_input.type == st_stream) - clearerr (stdin); - - while (1) - { - c = yy_getc (); - - /* Allow immediate exit if interrupted during input. */ - QUIT; - - if (c == '\0') - { - /* If we get EOS while parsing a string, treat it as EOF so we - don't just keep looping. Happens very rarely */ - if (bash_input.type == st_string) - { - if (i == 0) - shell_input_line_terminator = EOF; - shell_input_line[i] = '\0'; - c = EOF; - break; - } - continue; - } - - /* Theoretical overflow */ - /* If we can't put 256 bytes more into the buffer, allocate - everything we can and fill it as full as we can. */ - /* XXX - we ignore rest of line using `truncating' flag */ - if (shell_input_line_size > (SIZE_MAX - 256)) - { - size_t n; - - n = SIZE_MAX - i; /* how much more can we put into the buffer? */ - if (n <= 2) /* we have to save 1 for the newline added below */ - { - if (truncating == 0) - internal_warning(_("shell_getc: shell_input_line_size (%zu) exceeds SIZE_MAX (%lu): line truncated"), shell_input_line_size, (unsigned long)SIZE_MAX); - shell_input_line[i] = '\0'; - truncating = 1; - } - if (shell_input_line_size < SIZE_MAX) - { - shell_input_line_size = SIZE_MAX; - shell_input_line = xrealloc (shell_input_line, shell_input_line_size); - } - } - else - RESIZE_MALLOCED_BUFFER (shell_input_line, i, 2, shell_input_line_size, 256); - - if (c == EOF) - { - if (bash_input.type == st_stream) - clearerr (stdin); - - if (i == 0) - shell_input_line_terminator = EOF; - - shell_input_line[i] = '\0'; - break; - } - - if (truncating == 0 || c == '\n') - shell_input_line[i++] = c; - - if (c == '\n') - { - shell_input_line[--i] = '\0'; - current_command_line_count++; - break; - } - - last_was_backslash = last_was_backslash == 0 && c == '\\'; - } - - shell_input_line_index = 0; - shell_input_line_len = i; /* == strlen (shell_input_line) */ - - set_line_mbstate (); - -#if defined (HISTORY) - if (remember_on_history && shell_input_line && shell_input_line[0]) - { - char *expansions; -# if defined (BANG_HISTORY) - /* If the current delimiter is a single quote, we should not be - performing history expansion, even if we're on a different - line from the original single quote. */ - if (current_delimiter (dstack) == '\'') - history_quoting_state = '\''; - else if (current_delimiter (dstack) == '"') - history_quoting_state = '"'; - else - history_quoting_state = 0; -# endif - /* Calling with a third argument of 1 allows remember_on_history to - determine whether or not the line is saved to the history list */ - expansions = pre_process_line (shell_input_line, 1, 1); -# if defined (BANG_HISTORY) - history_quoting_state = 0; -# endif - if (expansions != shell_input_line) - { - free (shell_input_line); - shell_input_line = expansions; - shell_input_line_len = shell_input_line ? - strlen (shell_input_line) : 0; - if (shell_input_line_len == 0) - current_command_line_count--; - - /* We have to force the xrealloc below because we don't know - the true allocated size of shell_input_line anymore. */ - shell_input_line_size = shell_input_line_len; - - set_line_mbstate (); - } - } - /* Try to do something intelligent with blank lines encountered while - entering multi-line commands. XXX - this is grotesque */ - else if (remember_on_history && shell_input_line && - shell_input_line[0] == '\0' && - current_command_line_count > 1) - { - if (current_delimiter (dstack)) - /* We know shell_input_line[0] == 0 and we're reading some sort of - quoted string. This means we've got a line consisting of only - a newline in a quoted string. We want to make sure this line - gets added to the history. */ - maybe_add_history (shell_input_line); - else - { - char *hdcs; - hdcs = history_delimiting_chars (shell_input_line); - if (hdcs && hdcs[0] == ';') - maybe_add_history (shell_input_line); - } - } - -#endif /* HISTORY */ - - if (shell_input_line) - { - /* Lines that signify the end of the shell's input should not be - echoed. We should not echo lines while parsing command - substitutions with recursive calls into the parsing engine; those - should only be echoed once when we read the word. That is the - reason for the test against shell_eof_token, which is set to a - right paren when parsing the contents of command substitutions. */ - if (echo_input_at_read && (shell_input_line[0] || - shell_input_line_terminator != EOF) && - shell_eof_token == 0) - fprintf (stderr, "%s\n", shell_input_line); - } - else - { - shell_input_line_size = 0; - prompt_string_pointer = ¤t_prompt_string; - if (SHOULD_PROMPT ()) - prompt_again (0); - goto restart_read; - } - - /* Add the newline to the end of this string, iff the string does - not already end in an EOF character. */ - if (shell_input_line_terminator != EOF) - { - if (shell_input_line_size < SIZE_MAX-3 && (shell_input_line_len+3 > shell_input_line_size)) - shell_input_line = (char *)xrealloc (shell_input_line, - 1 + (shell_input_line_size += 2)); - - /* Don't add a newline to a string that ends with a backslash if we're - going to be removing quoted newlines, since that will eat the - backslash. Add another backslash instead (will be removed by - word expansion). */ - if (bash_input.type == st_string && expanding_alias() == 0 && last_was_backslash && c == EOF && remove_quoted_newline) - shell_input_line[shell_input_line_len] = '\\'; - else - shell_input_line[shell_input_line_len] = '\n'; - shell_input_line[shell_input_line_len + 1] = '\0'; - -#if defined (HANDLE_MULTIBYTE) - /* This is kind of an abstraction violation, but there's no need to - go through the entire shell_input_line again with a call to - set_line_mbstate(). */ - EXTEND_SHELL_INPUT_LINE_PROPERTY(); - shell_input_line_property[shell_input_line_len] = 1; -#endif - } - } - -next_alias_char: - if (shell_input_line_index == 0) - unquoted_backslash = 0; - - uc = shell_input_line[shell_input_line_index]; - - if (uc) - { - unquoted_backslash = unquoted_backslash == 0 && uc == '\\'; - shell_input_line_index++; - } - -#if defined (ALIAS) || defined (DPAREN_ARITHMETIC) - /* If UC is NULL, we have reached the end of the current input string. If - pushed_string_list is non-empty, it's time to pop to the previous string - because we have fully consumed the result of the last alias expansion. - Do it transparently; just return the next character of the string popped - to. */ - /* If pushed_string_list != 0 but pushed_string_list->expander == 0 (not - currently tested) and the flags value is not PSH_SOURCE, we are not - parsing an alias, we have just saved one (push_string, when called by - the parse_dparen code) In this case, just go on as well. The PSH_SOURCE - case is handled below. */ - - /* If we're at the end of an alias expansion add a space to make sure that - the alias remains marked as being in use while we expand its last word. - This makes sure that pop_string doesn't mark the alias as not in use - before the string resulting from the alias expansion is tokenized and - checked for alias expansion, preventing recursion. At this point, the - last character in shell_input_line is the last character of the alias - expansion. We test that last character to determine whether or not to - return the space that will delimit the token and postpone the pop_string. - This set of conditions duplicates what used to be in mk_alexpansion () - below, with the addition that we don't add a space if we're currently - reading a quoted string or in a shell comment. */ -#ifndef OLD_ALIAS_HACK - if (uc == 0 && pushed_string_list && pushed_string_list->flags != PSH_SOURCE && - pushed_string_list->flags != PSH_DPAREN && - (parser_state & PST_COMMENT) == 0 && - (parser_state & PST_ENDALIAS) == 0 && /* only once */ - shell_input_line_index > 0 && - shellblank (shell_input_line[shell_input_line_index-1]) == 0 && - shell_input_line[shell_input_line_index-1] != '\n' && - unquoted_backslash == 0 && - shellmeta (shell_input_line[shell_input_line_index-1]) == 0 && - (current_delimiter (dstack) != '\'' && current_delimiter (dstack) != '"')) - { - parser_state |= PST_ENDALIAS; - /* We need to do this to make sure last_shell_getc_is_singlebyte returns - true, since we are returning a single-byte space. */ - if (shell_input_line_index == shell_input_line_len && last_shell_getc_is_singlebyte == 0) - { -#if 0 - EXTEND_SHELL_INPUT_LINE_PROPERTY(); - shell_input_line_property[shell_input_line_len++] = 1; - /* extend shell_input_line to accommodate the shell_ungetc that - read_token_word() will perform, since we're extending the index */ - RESIZE_MALLOCED_BUFFER (shell_input_line, shell_input_line_index, 2, shell_input_line_size, 16); - shell_input_line[++shell_input_line_index] = '\0'; /* XXX */ -#else - shell_input_line_property[shell_input_line_index - 1] = 1; -#endif - } - return ' '; /* END_ALIAS */ - } -#endif - -pop_alias: -#endif /* ALIAS || DPAREN_ARITHMETIC */ - /* This case works for PSH_DPAREN as well as the shell_ungets() case that uses - push_string */ - if (uc == 0 && pushed_string_list && pushed_string_list->flags != PSH_SOURCE) - { - parser_state &= ~PST_ENDALIAS; - pop_string (); - uc = shell_input_line[shell_input_line_index]; - if (uc) - shell_input_line_index++; - } - - if MBTEST(uc == '\\' && remove_quoted_newline && shell_input_line[shell_input_line_index] == '\n') - { - if (SHOULD_PROMPT ()) - prompt_again (0); - line_number++; - - /* What do we do here if we're expanding an alias whose definition - includes an escaped newline? If that's the last character in the - alias expansion, we just pop the pushed string list (recall that - we inhibit the appending of a space if newline is the last - character). If it's not the last character, we need to consume the - quoted newline and move to the next character in the expansion. */ -#if defined (ALIAS) - if (expanding_alias () && shell_input_line[shell_input_line_index+1] == '\0') - { - uc = 0; - goto pop_alias; - } - else if (expanding_alias () && shell_input_line[shell_input_line_index+1] != '\0') - { - shell_input_line_index++; /* skip newline */ - goto next_alias_char; /* and get next character */ - } - else -#endif - goto restart_read; - } - - if (uc == 0 && shell_input_line_terminator == EOF) - return ((shell_input_line_index != 0) ? '\n' : EOF); - -#if defined (ALIAS) || defined (DPAREN_ARITHMETIC) - /* We already know that we are not parsing an alias expansion because of the - check for expanding_alias() above. This knows how parse_and_execute - handles switching to st_string input while an alias is being expanded, - hence the check for pushed_string_list without pushed_string_list->expander - and the check for PSH_SOURCE as pushed_string_list->flags. - parse_and_execute and parse_string both change the input type to st_string - and place the string to be parsed and executed into location.string, so - we should not stop reading that until the pointer is '\0'. - The check for shell_input_line_terminator may be superfluous. - - This solves the problem of `.' inside a multi-line alias with embedded - newlines executing things out of order. */ - if (uc == 0 && bash_input.type == st_string && *bash_input.location.string && - pushed_string_list && pushed_string_list->flags == PSH_SOURCE && - shell_input_line_terminator == 0) - { - shell_input_line_index = 0; - goto restart_read; - } -#endif - - return (uc); -} - -/* Put C back into the input for the shell. This might need changes for - HANDLE_MULTIBYTE around EOLs. Since we (currently) never push back a - character different than we read, shell_input_line_property doesn't need - to change when manipulating shell_input_line. The define for - last_shell_getc_is_singlebyte should take care of it, though. */ -static void -shell_ungetc (c) - int c; -{ - if (shell_input_line && shell_input_line_index) - shell_input_line[--shell_input_line_index] = c; - else - eol_ungetc_lookahead = c; -} - -/* Push S back into shell_input_line; updating shell_input_line_index */ -void -shell_ungets (s) - char *s; -{ - size_t slen, chars_left; - - slen = strlen (s); - - if (shell_input_line[shell_input_line_index] == '\0') - { - /* Easy, just overwrite shell_input_line. This is preferred because it - saves on set_line_mbstate () and other overhead like push_string */ - if (shell_input_line_size <= slen) - RESIZE_MALLOCED_BUFFER (shell_input_line, shell_input_line_index, slen + 1, shell_input_line_size, 64); - strcpy (shell_input_line, s); - shell_input_line_index = 0; - shell_input_line_len = slen; - shell_input_line_terminator = 0; - } - else if (shell_input_line_index >= slen) - { - /* Just as easy, just back up shell_input_line_index, but it means we - will re-process some characters in set_line_mbstate(). Need to - watch pushing back newlines here. */ - while (slen > 0) - shell_input_line[--shell_input_line_index] = s[--slen]; - } - else if (s[slen - 1] == '\n') - { - push_string (savestring (s), 0, (alias_t *)NULL); - /* push_string does set_line_mbstate () */ - return; - } - else - { - /* Harder case: pushing back input string that's longer than what we've - consumed from shell_input_line so far. */ - INTERNAL_DEBUG (("shell_ungets: not at end of shell_input_line")); - - chars_left = shell_input_line_len - shell_input_line_index; - if (shell_input_line_size <= (slen + chars_left)) - RESIZE_MALLOCED_BUFFER (shell_input_line, shell_input_line_index, chars_left + slen + 1, shell_input_line_size, 64); - memmove (shell_input_line + slen, shell_input_line + shell_input_line_index, shell_input_line_len - shell_input_line_index); - strcpy (shell_input_line, s); - shell_input_line_index = 0; - shell_input_line_len = strlen (shell_input_line); /* chars_left + slen? */ - } - -#if defined (HANDLE_MULTIBYTE) - set_line_mbstate (); /* XXX */ -#endif -} - -char * -parser_remaining_input () -{ - if (shell_input_line == 0) - return 0; - if ((int)shell_input_line_index < 0 || shell_input_line_index >= shell_input_line_len) - return ""; /* XXX */ - return (shell_input_line + shell_input_line_index); -} - -#ifdef INCLUDE_UNUSED -/* Back the input pointer up by one, effectively `ungetting' a character. */ -static void -shell_ungetchar () -{ - if (shell_input_line && shell_input_line_index) - shell_input_line_index--; -} -#endif - -/* Discard input until CHARACTER is seen, then push that character back - onto the input stream. */ -static void -discard_until (character) - int character; -{ - int c; - - while ((c = shell_getc (0)) != EOF && c != character) - ; - - if (c != EOF) - shell_ungetc (c); -} - -void -execute_variable_command (command, vname) - char *command, *vname; -{ - char *last_lastarg; - sh_parser_state_t ps; - - save_parser_state (&ps); - last_lastarg = get_string_value ("_"); - if (last_lastarg) - last_lastarg = savestring (last_lastarg); - - parse_and_execute (savestring (command), vname, SEVAL_NONINT|SEVAL_NOHIST); - - restore_parser_state (&ps); - bind_variable ("_", last_lastarg, 0); - FREE (last_lastarg); - - if (token_to_read == '\n') /* reset_parser was called */ - token_to_read = 0; -} - -void -push_token (x) - int x; -{ - two_tokens_ago = token_before_that; - token_before_that = last_read_token; - last_read_token = current_token; - - current_token = x; -} - -/* Place to remember the token. We try to keep the buffer - at a reasonable size, but it can grow. */ -static char *token = (char *)NULL; - -/* Current size of the token buffer. */ -static size_t token_buffer_size; - -/* Command to read_token () explaining what we want it to do. */ -#define READ 0 -#define RESET 1 -#define prompt_is_ps1 \ - (!prompt_string_pointer || prompt_string_pointer == &ps1_prompt) - -/* Function for yyparse to call. yylex keeps track of - the last two tokens read, and calls read_token. */ -static int -yylex () -{ - if (interactive && (current_token == 0 || current_token == '\n')) - { - /* Before we print a prompt, we might have to check mailboxes. - We do this only if it is time to do so. Notice that only here - is the mail alarm reset; nothing takes place in check_mail () - except the checking of mail. Please don't change this. */ - if (prompt_is_ps1 && parse_and_execute_level == 0 && time_to_check_mail ()) - { - check_mail (); - reset_mail_timer (); - } - - /* Avoid printing a prompt if we're not going to read anything, e.g. - after resetting the parser with read_token (RESET). */ - if (token_to_read == 0 && SHOULD_PROMPT ()) - prompt_again (0); - } - - two_tokens_ago = token_before_that; - token_before_that = last_read_token; - last_read_token = current_token; - current_token = read_token (READ); - - if ((parser_state & PST_EOFTOKEN) && current_token == shell_eof_token) - { - /* placeholder for any special handling. */ - return (current_token); - } - - if (current_token < 0) -#if defined (YYERRCODE) && !defined (YYUNDEF) - current_token = YYERRCODE; -#else - current_token = YYerror; -#endif - - return (current_token); -} - -/* When non-zero, we have read the required tokens - which allow ESAC to be the next one read. */ -static int esacs_needed_count; - -/* When non-zero, we can read IN as an acceptable token, regardless of how - many newlines we read. */ -static int expecting_in_token; - -static void -push_heredoc (r) - REDIRECT *r; -{ - if (need_here_doc >= HEREDOC_MAX) - { - last_command_exit_value = EX_BADUSAGE; - need_here_doc = 0; - report_syntax_error (_("maximum here-document count exceeded")); - reset_parser (); - exit_shell (last_command_exit_value); - } - redir_stack[need_here_doc++] = r; -} - -void -gather_here_documents () -{ - int r; - - r = 0; - here_doc_first_line = 1; - while (need_here_doc > 0) - { - parser_state |= PST_HEREDOC; - make_here_document (redir_stack[r++], line_number); - parser_state &= ~PST_HEREDOC; - need_here_doc--; - redir_stack[r - 1] = 0; /* XXX */ - } - here_doc_first_line = 0; /* just in case */ -} - -/* When non-zero, an open-brace used to create a group is awaiting a close - brace partner. */ -static int open_brace_count; - -/* In the following three macros, `token' is always last_read_token */ - -/* Are we in the middle of parsing a redirection where we are about to read - a word? This is used to make sure alias expansion doesn't happen in the - middle of a redirection, even though we're parsing a simple command. */ -#define parsing_redirection(token) \ - (token == '<' || token == '>' || \ - token == GREATER_GREATER || token == GREATER_BAR || \ - token == LESS_GREATER || token == LESS_LESS_MINUS || \ - token == LESS_LESS || token == LESS_LESS_LESS || \ - token == LESS_AND || token == GREATER_AND || token == AND_GREATER) - -/* Is `token' one that will allow a WORD to be read in a command position? - We can read a simple command name on which we should attempt alias expansion - or we can read an assignment statement. */ -#define command_token_position(token) \ - (((token) == ASSIGNMENT_WORD) || \ - ((parser_state&PST_REDIRLIST) && parsing_redirection(token) == 0) || \ - ((token) != SEMI_SEMI && (token) != SEMI_AND && (token) != SEMI_SEMI_AND && reserved_word_acceptable(token))) - -/* Are we in a position where we can read an assignment statement? */ -#define assignment_acceptable(token) \ - (command_token_position(token) && ((parser_state & PST_CASEPAT) == 0)) - -/* Check to see if TOKEN is a reserved word and return the token - value if it is. */ -#define CHECK_FOR_RESERVED_WORD(tok) \ - do { \ - if (!dollar_present && !quoted && \ - reserved_word_acceptable (last_read_token)) \ - { \ - int i; \ - for (i = 0; word_token_alist[i].word != (char *)NULL; i++) \ - if (STREQ (tok, word_token_alist[i].word)) \ - { \ - if ((parser_state & PST_CASEPAT) && (word_token_alist[i].token != ESAC)) \ - break; \ - if (word_token_alist[i].token == TIME && time_command_acceptable () == 0) \ - break; \ - if ((parser_state & PST_CASEPAT) && last_read_token == '|' && word_token_alist[i].token == ESAC) \ - break; /* Posix grammar rule 4 */ \ - if ((parser_state & PST_CASEPAT) && last_read_token == '(' && word_token_alist[i].token == ESAC) /*)*/ \ - break; /* phantom Posix grammar rule 4 */ \ - if (word_token_alist[i].token == ESAC) { \ - parser_state &= ~(PST_CASEPAT|PST_CASESTMT); \ - esacs_needed_count--; \ - } else if (word_token_alist[i].token == CASE) \ - parser_state |= PST_CASESTMT; \ - else if (word_token_alist[i].token == COND_END) \ - parser_state &= ~(PST_CONDCMD|PST_CONDEXPR); \ - else if (word_token_alist[i].token == COND_START) \ - parser_state |= PST_CONDCMD; \ - else if (word_token_alist[i].token == '{') \ - open_brace_count++; \ - else if (word_token_alist[i].token == '}' && open_brace_count) \ - open_brace_count--; \ - return (word_token_alist[i].token); \ - } \ - } \ - } while (0) - -#if defined (ALIAS) - - /* OK, we have a token. Let's try to alias expand it, if (and only if) - it's eligible. - - It is eligible for expansion if EXPAND_ALIASES is set, and - the token is unquoted and the last token read was a command - separator (or expand_next_token is set), and we are currently - processing an alias (pushed_string_list is non-empty) and this - token is not the same as the current or any previously - processed alias. - - Special cases that disqualify: - In a pattern list in a case statement (parser_state & PST_CASEPAT). */ - -static char * -mk_alexpansion (s) - char *s; -{ - int l; - char *r; - - l = strlen (s); - r = xmalloc (l + 2); - strcpy (r, s); -#ifdef OLD_ALIAS_HACK - /* If the last character in the alias is a newline, don't add a trailing - space to the expansion. Works with shell_getc above. */ - /* Need to do something about the case where the alias expansion contains - an unmatched quoted string, since appending this space affects the - subsequent output. */ - if (l > 0 && r[l - 1] != ' ' && r[l - 1] != '\n' && shellmeta(r[l - 1]) == 0) - r[l++] = ' '; -#endif - r[l] = '\0'; - return r; -} - -static int -alias_expand_token (tokstr) - char *tokstr; -{ - char *expanded; - alias_t *ap; - -#if 0 - if (((parser_state & PST_ALEXPNEXT) || command_token_position (last_read_token)) && - (parser_state & PST_CASEPAT) == 0) -#else - if ((parser_state & PST_ALEXPNEXT) || assignment_acceptable (last_read_token)) -#endif - { - ap = find_alias (tokstr); - - /* Currently expanding this token. */ - if (ap && (ap->flags & AL_BEINGEXPANDED)) - return (NO_EXPANSION); - -#ifdef OLD_ALIAS_HACK - /* mk_alexpansion puts an extra space on the end of the alias expansion, - so the lookahead by the parser works right (the alias needs to remain - `in use' while parsing its last word to avoid alias recursion for - something like "alias echo=echo"). If this gets changed, make sure - the code in shell_getc that deals with reaching the end of an - expanded alias is changed with it. */ -#endif - expanded = ap ? mk_alexpansion (ap->value) : (char *)NULL; - - if (expanded) - { - push_string (expanded, ap->flags & AL_EXPANDNEXT, ap); - return (RE_READ_TOKEN); - } - else - /* This is an eligible token that does not have an expansion. */ - return (NO_EXPANSION); - } - return (NO_EXPANSION); -} -#endif /* ALIAS */ - -static int -time_command_acceptable () -{ -#if defined (COMMAND_TIMING) - int i; - - if (posixly_correct && shell_compatibility_level > 41) - { - /* Quick check of the rest of the line to find the next token. If it - begins with a `-', Posix says to not return `time' as the token. - This was interp 267. */ - i = shell_input_line_index; - while (i < shell_input_line_len && (shell_input_line[i] == ' ' || shell_input_line[i] == '\t')) - i++; - if (shell_input_line[i] == '-') - return 0; - } - - switch (last_read_token) - { - case 0: - case ';': - case '\n': - if (token_before_that == '|') - return (0); - /* FALLTHROUGH */ - case AND_AND: - case OR_OR: - case '&': - case WHILE: - case DO: - case UNTIL: - case IF: - case THEN: - case ELIF: - case ELSE: - case '{': /* } */ - case '(': /* )( */ - case ')': /* only valid in case statement */ - case BANG: /* ! time pipeline */ - case TIME: /* time time pipeline */ - case TIMEOPT: /* time -p time pipeline */ - case TIMEIGN: /* time -p -- ... */ - return 1; - default: - return 0; - } -#else - return 0; -#endif /* COMMAND_TIMING */ -} - -/* Handle special cases of token recognition: - IN is recognized if the last token was WORD and the token - before that was FOR or CASE or SELECT. - - DO is recognized if the last token was WORD and the token - before that was FOR or SELECT. - - ESAC is recognized if the last token caused `esacs_needed_count' - to be set - - `{' is recognized if the last token as WORD and the token - before that was FUNCTION, or if we just parsed an arithmetic - `for' command. - - `}' is recognized if there is an unclosed `{' present. - - `-p' is returned as TIMEOPT if the last read token was TIME. - `--' is returned as TIMEIGN if the last read token was TIME or TIMEOPT. - - ']]' is returned as COND_END if the parser is currently parsing - a conditional expression ((parser_state & PST_CONDEXPR) != 0) - - `time' is returned as TIME if and only if it is immediately - preceded by one of `;', `\n', `||', `&&', or `&'. -*/ - -static int -special_case_tokens (tokstr) - char *tokstr; -{ - /* Posix grammar rule 6 */ - if ((last_read_token == WORD) && -#if defined (SELECT_COMMAND) - ((token_before_that == FOR) || (token_before_that == CASE) || (token_before_that == SELECT)) && -#else - ((token_before_that == FOR) || (token_before_that == CASE)) && -#endif - (tokstr[0] == 'i' && tokstr[1] == 'n' && tokstr[2] == 0)) - { - if (token_before_that == CASE) - { - parser_state |= PST_CASEPAT; - esacs_needed_count++; - } - if (expecting_in_token) - expecting_in_token--; - return (IN); - } - - /* XXX - leaving above code intact for now, but it should eventually be - removed in favor of this clause. */ - /* Posix grammar rule 6 */ - if (expecting_in_token && (last_read_token == WORD || last_read_token == '\n') && - (tokstr[0] == 'i' && tokstr[1] == 'n' && tokstr[2] == 0)) - { - if (parser_state & PST_CASESTMT) - { - parser_state |= PST_CASEPAT; - esacs_needed_count++; - } - expecting_in_token--; - return (IN); - } - /* Posix grammar rule 6, third word in FOR: for i; do command-list; done */ - else if (expecting_in_token && (last_read_token == '\n' || last_read_token == ';') && - (tokstr[0] == 'd' && tokstr[1] == 'o' && tokstr[2] == '\0')) - { - expecting_in_token--; - return (DO); - } - - /* for i do; command-list; done */ - if (last_read_token == WORD && -#if defined (SELECT_COMMAND) - (token_before_that == FOR || token_before_that == SELECT) && -#else - (token_before_that == FOR) && -#endif - (tokstr[0] == 'd' && tokstr[1] == 'o' && tokstr[2] == '\0')) - { - if (expecting_in_token) - expecting_in_token--; - return (DO); - } - - /* Ditto for ESAC in the CASE case. - Specifically, this handles "case word in esac", which is a legal - construct, certainly because someone will pass an empty arg to the - case construct, and we don't want it to barf. Of course, we should - insist that the case construct has at least one pattern in it, but - the designers disagree. */ - if (esacs_needed_count) - { - if (last_read_token == IN && STREQ (tokstr, "esac")) - { - esacs_needed_count--; - parser_state &= ~PST_CASEPAT; - return (ESAC); - } - } - - /* The start of a shell function definition. */ - if (parser_state & PST_ALLOWOPNBRC) - { - parser_state &= ~PST_ALLOWOPNBRC; - if (tokstr[0] == '{' && tokstr[1] == '\0') /* } */ - { - open_brace_count++; - function_bstart = line_number; - return ('{'); /* } */ - } - } - - /* We allow a `do' after a for ((...)) without an intervening - list_terminator */ - if (last_read_token == ARITH_FOR_EXPRS && tokstr[0] == 'd' && tokstr[1] == 'o' && !tokstr[2]) - return (DO); - if (last_read_token == ARITH_FOR_EXPRS && tokstr[0] == '{' && tokstr[1] == '\0') /* } */ - { - open_brace_count++; - return ('{'); /* } */ - } - - if (open_brace_count && reserved_word_acceptable (last_read_token) && tokstr[0] == '}' && !tokstr[1]) - { - open_brace_count--; /* { */ - return ('}'); - } - -#if defined (COMMAND_TIMING) - /* Handle -p after `time'. */ - if (last_read_token == TIME && tokstr[0] == '-' && tokstr[1] == 'p' && !tokstr[2]) - return (TIMEOPT); - /* Handle -- after `time'. */ - if (last_read_token == TIME && tokstr[0] == '-' && tokstr[1] == '-' && !tokstr[2]) - return (TIMEIGN); - /* Handle -- after `time -p'. */ - if (last_read_token == TIMEOPT && tokstr[0] == '-' && tokstr[1] == '-' && !tokstr[2]) - return (TIMEIGN); -#endif - -#if defined (COND_COMMAND) /* [[ */ - if ((parser_state & PST_CONDEXPR) && tokstr[0] == ']' && tokstr[1] == ']' && tokstr[2] == '\0') - return (COND_END); -#endif - - return (-1); -} - -/* Called from shell.c when Control-C is typed at top level. Or - by the error rule at top level. */ -void -reset_parser () -{ - dstack.delimiter_depth = 0; /* No delimiters found so far. */ - open_brace_count = 0; - -#if defined (EXTENDED_GLOB) - /* Reset to global value of extended glob */ - if (parser_state & (PST_EXTPAT|PST_CMDSUBST)) - extended_glob = global_extglob; -#endif - - parser_state = 0; - here_doc_first_line = 0; - -#if defined (ALIAS) || defined (DPAREN_ARITHMETIC) - if (pushed_string_list) - free_string_list (); -#endif /* ALIAS || DPAREN_ARITHMETIC */ - - /* This is where we resynchronize to the next newline on error/reset */ - if (shell_input_line) - { - free (shell_input_line); - shell_input_line = (char *)NULL; - shell_input_line_size = shell_input_line_index = 0; - } - - FREE (word_desc_to_read); - word_desc_to_read = (WORD_DESC *)NULL; - - eol_ungetc_lookahead = 0; - - /* added post-bash-5.1 */ - need_here_doc = 0; - redir_stack[0] = 0; - esacs_needed_count = expecting_in_token = 0; - - current_token = '\n'; /* XXX */ - last_read_token = '\n'; - token_to_read = '\n'; -} - -void -reset_readahead_token () -{ - if (token_to_read == '\n') - token_to_read = 0; -} - -/* Read the next token. Command can be READ (normal operation) or - RESET (to normalize state). */ -static int -read_token (command) - int command; -{ - int character; /* Current character. */ - int peek_char; /* Temporary look-ahead character. */ - int result; /* The thing to return. */ - - if (command == RESET) - { - reset_parser (); - return ('\n'); - } - - if (token_to_read) - { - result = token_to_read; - if (token_to_read == WORD || token_to_read == ASSIGNMENT_WORD) - { - yylval.word = word_desc_to_read; - word_desc_to_read = (WORD_DESC *)NULL; - } - token_to_read = 0; - return (result); - } - -#if defined (COND_COMMAND) - if ((parser_state & (PST_CONDCMD|PST_CONDEXPR)) == PST_CONDCMD) - { - cond_lineno = line_number; - parser_state |= PST_CONDEXPR; - yylval.command = parse_cond_command (); - if (cond_token != COND_END) - { - cond_error (); - return (-1); - } - token_to_read = COND_END; - parser_state &= ~(PST_CONDEXPR|PST_CONDCMD); - return (COND_CMD); - } -#endif - -#if defined (ALIAS) - /* This is a place to jump back to once we have successfully expanded a - token with an alias and pushed the string with push_string () */ - re_read_token: -#endif /* ALIAS */ - - /* Read a single word from input. Start by skipping blanks. */ - while ((character = shell_getc (1)) != EOF && shellblank (character)) - ; - - if (character == EOF) - { - EOF_Reached = 1; - return (yacc_EOF); - } - - /* If we hit the end of the string and we're not expanding an alias (e.g., - we are eval'ing a string that is an incomplete command), return EOF */ - if (character == '\0' && bash_input.type == st_string && expanding_alias() == 0) - { - INTERNAL_DEBUG (("shell_getc: bash_input.location.string = `%s'", bash_input.location.string)); - EOF_Reached = 1; - return (yacc_EOF); - } - - if MBTEST(character == '#' && (!interactive || interactive_comments)) - { - /* A comment. Discard until EOL or EOF, and then return a newline. */ - parser_state |= PST_COMMENT; - discard_until ('\n'); - shell_getc (0); - parser_state &= ~PST_COMMENT; - character = '\n'; /* this will take the next if statement and return. */ - } - - if MBTEST(character == '\n') - { - /* If we're about to return an unquoted newline, we can go and collect - the text of any pending here document. */ - if (need_here_doc) - gather_here_documents (); - -#if defined (ALIAS) - parser_state &= ~PST_ALEXPNEXT; -#endif /* ALIAS */ - - parser_state &= ~PST_ASSIGNOK; - - return (character); - } - - if (parser_state & PST_REGEXP) - goto tokword; - - /* Shell meta-characters. */ - if MBTEST(shellmeta (character)) - { -#if defined (ALIAS) - /* Turn off alias tokenization iff this character sequence would - not leave us ready to read a command. */ - if (character == '<' || character == '>') - parser_state &= ~PST_ALEXPNEXT; -#endif /* ALIAS */ - - parser_state &= ~PST_ASSIGNOK; - - /* If we are parsing a command substitution and we have read a character - that marks the end of it, don't bother to skip over quoted newlines - when we read the next token. We're just interested in a character - that will turn this into a two-character token, so we let the higher - layers deal with quoted newlines following the command substitution. */ - if ((parser_state & PST_CMDSUBST) && character == shell_eof_token) - peek_char = shell_getc (0); - else - peek_char = shell_getc (1); - - if MBTEST(character == peek_char) - { - switch (character) - { - case '<': - /* If '<' then we could be at "<<" or at "<<-". We have to - look ahead one more character. */ - peek_char = shell_getc (1); - if MBTEST(peek_char == '-') - return (LESS_LESS_MINUS); - else if MBTEST(peek_char == '<') - return (LESS_LESS_LESS); - else - { - shell_ungetc (peek_char); - return (LESS_LESS); - } - - case '>': - return (GREATER_GREATER); - - case ';': - parser_state |= PST_CASEPAT; -#if defined (ALIAS) - parser_state &= ~PST_ALEXPNEXT; -#endif /* ALIAS */ - - peek_char = shell_getc (1); - if MBTEST(peek_char == '&') - return (SEMI_SEMI_AND); - else - { - shell_ungetc (peek_char); - return (SEMI_SEMI); - } - - case '&': - return (AND_AND); - - case '|': - return (OR_OR); - -#if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND) - case '(': /* ) */ - result = parse_dparen (character); - if (result == -2) - break; - else - return result; -#endif - } - } - else if MBTEST(character == '<' && peek_char == '&') - return (LESS_AND); - else if MBTEST(character == '>' && peek_char == '&') - return (GREATER_AND); - else if MBTEST(character == '<' && peek_char == '>') - return (LESS_GREATER); - else if MBTEST(character == '>' && peek_char == '|') - return (GREATER_BAR); - else if MBTEST(character == '&' && peek_char == '>') - { - peek_char = shell_getc (1); - if MBTEST(peek_char == '>') - return (AND_GREATER_GREATER); - else - { - shell_ungetc (peek_char); - return (AND_GREATER); - } - } - else if MBTEST(character == '|' && peek_char == '&') - return (BAR_AND); - else if MBTEST(character == ';' && peek_char == '&') - { - parser_state |= PST_CASEPAT; -#if defined (ALIAS) - parser_state &= ~PST_ALEXPNEXT; -#endif /* ALIAS */ - return (SEMI_AND); - } - - shell_ungetc (peek_char); - - /* If we look like we are reading the start of a function - definition, then let the reader know about it so that - we will do the right thing with `{'. */ - if MBTEST(character == ')' && last_read_token == '(' && token_before_that == WORD) - { - parser_state |= PST_ALLOWOPNBRC; -#if defined (ALIAS) - parser_state &= ~PST_ALEXPNEXT; -#endif /* ALIAS */ - function_dstart = line_number; - } - - /* case pattern lists may be preceded by an optional left paren. If - we're not trying to parse a case pattern list, the left paren - indicates a subshell. */ - if MBTEST(character == '(' && (parser_state & PST_CASEPAT) == 0) /* ) */ - parser_state |= PST_SUBSHELL; - /*(*/ - else if MBTEST((parser_state & PST_CASEPAT) && character == ')') - parser_state &= ~PST_CASEPAT; - /*(*/ - else if MBTEST((parser_state & PST_SUBSHELL) && character == ')') - parser_state &= ~PST_SUBSHELL; - -#if defined (PROCESS_SUBSTITUTION) - /* Check for the constructs which introduce process substitution. - Shells running in `posix mode' don't do process substitution. */ - if MBTEST((character != '>' && character != '<') || peek_char != '(') /*)*/ -#endif /* PROCESS_SUBSTITUTION */ - return (character); - } - - /* Hack <&- (close stdin) case. Also <&N- (dup and close). */ - if MBTEST(character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND)) - return (character); - -tokword: - /* Okay, if we got this far, we have to read a word. Read one, - and then check it against the known ones. */ - result = read_token_word (character); -#if defined (ALIAS) - if (result == RE_READ_TOKEN) - goto re_read_token; -#endif - return result; -} - -/* - * Match a $(...) or other grouping construct. This has to handle embedded - * quoted strings ('', ``, "") and nested constructs. It also must handle - * reprompting the user, if necessary, after reading a newline, and returning - * correct error values if it reads EOF. - */ -#define P_FIRSTCLOSE 0x0001 -#define P_ALLOWESC 0x0002 -#define P_DQUOTE 0x0004 -#define P_COMMAND 0x0008 /* parsing a command, so look for comments */ -#define P_BACKQUOTE 0x0010 /* parsing a backquoted command substitution */ -#define P_ARRAYSUB 0x0020 /* parsing a [...] array subscript for assignment */ -#define P_DOLBRACE 0x0040 /* parsing a ${...} construct */ - -/* Lexical state while parsing a grouping construct or $(...). */ -#define LEX_WASDOL 0x0001 -#define LEX_CKCOMMENT 0x0002 -#define LEX_INCOMMENT 0x0004 -#define LEX_PASSNEXT 0x0008 -#define LEX_RESWDOK 0x0010 -#define LEX_CKCASE 0x0020 -#define LEX_INCASE 0x0040 -#define LEX_INHEREDOC 0x0080 -#define LEX_HEREDELIM 0x0100 /* reading here-doc delimiter */ -#define LEX_STRIPDOC 0x0200 /* <<- strip tabs from here doc delim */ -#define LEX_QUOTEDDOC 0x0400 /* here doc with quoted delim */ -#define LEX_INWORD 0x0800 -#define LEX_GTLT 0x1000 -#define LEX_CKESAC 0x2000 /* check esac after in -- for later */ -#define LEX_CASEWD 0x4000 /* word after case */ -#define LEX_PATLIST 0x8000 /* case statement pattern list */ - -#define COMSUB_META(ch) ((ch) == ';' || (ch) == '&' || (ch) == '|') - -#define CHECK_NESTRET_ERROR() \ - do { \ - if (nestret == &matched_pair_error) \ - { \ - free (ret); \ - return &matched_pair_error; \ - } \ - } while (0) - -#define APPEND_NESTRET() \ - do { \ - if (nestlen) \ - { \ - RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64); \ - strcpy (ret + retind, nestret); \ - retind += nestlen; \ - } \ - } while (0) - -static char matched_pair_error; - -static char * -parse_matched_pair (qc, open, close, lenp, flags) - int qc; /* `"' if this construct is within double quotes */ - int open, close; - int *lenp, flags; -{ - int count, ch, prevch, tflags; - int nestlen, ttranslen, start_lineno; - char *ret, *nestret, *ttrans; - int retind, retsize, rflags; - int dolbrace_state; - - dolbrace_state = (flags & P_DOLBRACE) ? DOLBRACE_PARAM : 0; - -/*itrace("parse_matched_pair[%d]: open = %c close = %c flags = %d", line_number, open, close, flags);*/ - count = 1; - tflags = 0; - - if ((flags & P_COMMAND) && qc != '`' && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0) - tflags |= LEX_CKCOMMENT; - - /* RFLAGS is the set of flags we want to pass to recursive calls. */ - rflags = (qc == '"') ? P_DQUOTE : (flags & P_DQUOTE); - - ret = (char *)xmalloc (retsize = 64); - retind = 0; - - start_lineno = line_number; - ch = EOF; /* just in case */ - while (count) - { - prevch = ch; - ch = shell_getc (qc != '\'' && (tflags & (LEX_PASSNEXT)) == 0); - - if (ch == EOF) - { - free (ret); - parser_error (start_lineno, _("unexpected EOF while looking for matching `%c'"), close); - EOF_Reached = 1; /* XXX */ - return (&matched_pair_error); - } - - /* Possible reprompting. */ - if MBTEST(ch == '\n' && SHOULD_PROMPT ()) - prompt_again (0); - - /* Don't bother counting parens or doing anything else if in a comment - or part of a case statement */ - if (tflags & LEX_INCOMMENT) - { - /* Add this character. */ - RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64); - ret[retind++] = ch; - - if MBTEST(ch == '\n') - tflags &= ~LEX_INCOMMENT; - - continue; - } - - /* Not exactly right yet, should handle shell metacharacters, too. If - any changes are made to this test, make analogous changes to subst.c: - extract_delimited_string(). */ - else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (retind == 0 || ret[retind-1] == '\n' || shellblank (ret[retind - 1]))) - tflags |= LEX_INCOMMENT; - - if (tflags & LEX_PASSNEXT) /* last char was backslash */ - { - tflags &= ~LEX_PASSNEXT; - /* XXX - PST_NOEXPAND? */ - if MBTEST(qc != '\'' && ch == '\n') /* double-quoted \ disappears. */ - { - if (retind > 0) - retind--; /* swallow previously-added backslash */ - continue; - } - - RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64); - if MBTEST(ch == CTLESC) - ret[retind++] = CTLESC; - ret[retind++] = ch; - continue; - } - /* If we're reparsing the input (e.g., from parse_string_to_word_list), - we've already prepended CTLESC to single-quoted results of $'...'. - We may want to do this for other CTLESC-quoted characters in - reparse, too. */ - else if MBTEST((parser_state & PST_REPARSE) && open == '\'' && (ch == CTLESC || ch == CTLNUL)) - { - RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64); - ret[retind++] = ch; - continue; - } - else if MBTEST(ch == CTLESC || ch == CTLNUL) /* special shell escapes */ - { - RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64); - ret[retind++] = CTLESC; - ret[retind++] = ch; - continue; - } - else if MBTEST(ch == close) /* ending delimiter */ - count--; - /* handle nested ${...} specially. */ - else if MBTEST(open != close && (tflags & LEX_WASDOL) && open == '{' && ch == open) /* } */ - count++; - else if MBTEST(((flags & P_FIRSTCLOSE) == 0) && ch == open) /* nested begin */ - count++; - - /* Add this character. */ - RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64); - ret[retind++] = ch; - - /* If we just read the ending character, don't bother continuing. */ - if (count == 0) - break; - - if (open == '\'') /* '' inside grouping construct */ - { - if MBTEST((flags & P_ALLOWESC) && ch == '\\') - tflags |= LEX_PASSNEXT; - continue; - } - - if MBTEST(ch == '\\') /* backslashes */ - tflags |= LEX_PASSNEXT; - - /* Based on which dolstate is currently in (param, op, or word), - decide what the op is. We're really only concerned if it's % or - #, so we can turn on a flag that says whether or not we should - treat single quotes as special when inside a double-quoted - ${...}. This logic must agree with subst.c:extract_dollar_brace_string - since they share the same defines. */ - /* FLAG POSIX INTERP 221 */ - if (flags & P_DOLBRACE) - { - /* ${param%[%]word} */ - if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '%' && retind > 1) - dolbrace_state = DOLBRACE_QUOTE; - /* ${param#[#]word} */ - else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '#' && retind > 1) - dolbrace_state = DOLBRACE_QUOTE; - /* ${param/[/]pat/rep} */ - else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '/' && retind > 1) - dolbrace_state = DOLBRACE_QUOTE2; /* XXX */ - /* ${param^[^]pat} */ - else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '^' && retind > 1) - dolbrace_state = DOLBRACE_QUOTE; - /* ${param,[,]pat} */ - else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == ',' && retind > 1) - dolbrace_state = DOLBRACE_QUOTE; - else if MBTEST(dolbrace_state == DOLBRACE_PARAM && strchr ("#%^,~:-=?+/", ch) != 0) - dolbrace_state = DOLBRACE_OP; - else if MBTEST(dolbrace_state == DOLBRACE_OP && strchr ("#%^,~:-=?+/", ch) == 0) - dolbrace_state = DOLBRACE_WORD; - } - - /* The big hammer. Single quotes aren't special in double quotes. The - problem is that Posix used to say the single quotes are semi-special: - within a double-quoted ${...} construct "an even number of - unescaped double-quotes or single-quotes, if any, shall occur." */ - /* This was changed in Austin Group Interp 221 */ - if MBTEST(posixly_correct && shell_compatibility_level > 41 && dolbrace_state != DOLBRACE_QUOTE && dolbrace_state != DOLBRACE_QUOTE2 && (flags & P_DQUOTE) && (flags & P_DOLBRACE) && ch == '\'') - continue; - - /* Could also check open == '`' if we want to parse grouping constructs - inside old-style command substitution. */ - if (open != close) /* a grouping construct */ - { - if MBTEST(shellquote (ch)) - { - /* '', ``, or "" inside $(...) or other grouping construct. */ - push_delimiter (dstack, ch); - if MBTEST((tflags & LEX_WASDOL) && ch == '\'') /* $'...' inside group */ - nestret = parse_matched_pair (ch, ch, ch, &nestlen, P_ALLOWESC|rflags); - else - nestret = parse_matched_pair (ch, ch, ch, &nestlen, rflags); - pop_delimiter (dstack); - CHECK_NESTRET_ERROR (); - - if MBTEST((tflags & LEX_WASDOL) && ch == '\'' && (extended_quote || (rflags & P_DQUOTE) == 0 || dolbrace_state == DOLBRACE_QUOTE || dolbrace_state == DOLBRACE_QUOTE2)) - { - /* Translate $'...' here. */ - /* PST_NOEXPAND */ - ttrans = ansiexpand (nestret, 0, nestlen - 1, &ttranslen); - free (nestret); - - /* If we're parsing a double-quoted brace expansion and we are - not in a place where single quotes are treated specially, - make sure we single-quote the results of the ansi - expansion because quote removal should remove them later */ - /* FLAG POSIX INTERP 221 */ - if ((shell_compatibility_level > 42) && (rflags & P_DQUOTE) && (dolbrace_state == DOLBRACE_QUOTE2 || dolbrace_state == DOLBRACE_QUOTE) && (flags & P_DOLBRACE)) - { - nestret = sh_single_quote (ttrans); - free (ttrans); - nestlen = strlen (nestret); - } -#if 0 /* TAG:bash-5.3 */ - /* This single-quotes PARAM in ${PARAM OP WORD} when PARAM - contains a $'...' even when extended_quote is set. */ - else if ((rflags & P_DQUOTE) && (dolbrace_state == DOLBRACE_PARAM) && (flags & P_DOLBRACE)) - { - nestret = sh_single_quote (ttrans); - free (ttrans); - nestlen = strlen (nestret); - } -#endif - else if ((rflags & P_DQUOTE) == 0) - { - nestret = sh_single_quote (ttrans); - free (ttrans); - nestlen = strlen (nestret); - } - else - { - /* Should we quote CTLESC here? */ - nestret = ttrans; - nestlen = ttranslen; - } - retind -= 2; /* back up before the $' */ - } -#if defined (TRANSLATABLE_STRINGS) - else if MBTEST((tflags & LEX_WASDOL) && ch == '"' && (extended_quote || (rflags & P_DQUOTE) == 0)) - { - /* Locale expand $"..." here. */ - /* PST_NOEXPAND */ - ttrans = locale_expand (nestret, 0, nestlen - 1, start_lineno, &ttranslen); - free (nestret); - - /* If we're supposed to single-quote translated strings, - check whether the translated result is different from - the original and single-quote the string if it is. */ - if (singlequote_translations && - ((nestlen - 1) != ttranslen || STREQN (nestret, ttrans, ttranslen) == 0)) - { - if ((rflags & P_DQUOTE) == 0) - nestret = sh_single_quote (ttrans); - else if ((rflags & P_DQUOTE) && (dolbrace_state == DOLBRACE_QUOTE2) && (flags & P_DOLBRACE)) - nestret = sh_single_quote (ttrans); - else - /* single quotes aren't special, use backslash instead */ - nestret = sh_backslash_quote_for_double_quotes (ttrans, 0); - } - else - nestret = sh_mkdoublequoted (ttrans, ttranslen, 0); - free (ttrans); - nestlen = strlen (nestret); - retind -= 2; /* back up before the $" */ - } -#endif /* TRANSLATABLE_STRINGS */ - - APPEND_NESTRET (); - FREE (nestret); - } - else if ((flags & (P_ARRAYSUB|P_DOLBRACE)) && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */ - goto parse_dollar_word; -#if defined (PROCESS_SUBSTITUTION) - /* XXX - technically this should only be recognized at the start of - a word */ - else if ((flags & (P_ARRAYSUB|P_DOLBRACE)) && (tflags & LEX_GTLT) && (ch == '(')) /* ) */ - goto parse_dollar_word; -#endif - } - /* Parse an old-style command substitution within double quotes as a - single word. */ - /* XXX - sh and ksh93 don't do this - XXX */ - else if MBTEST(open == '"' && ch == '`') - { - nestret = parse_matched_pair (0, '`', '`', &nestlen, rflags); - - CHECK_NESTRET_ERROR (); - APPEND_NESTRET (); - - FREE (nestret); - } - else if MBTEST(open != '`' && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */ - /* check for $(), $[], or ${} inside quoted string. */ - { -parse_dollar_word: - if (open == ch) /* undo previous increment */ - count--; - if (ch == '(') /* ) */ - nestret = parse_comsub (0, '(', ')', &nestlen, (rflags|P_COMMAND) & ~P_DQUOTE); - else if (ch == '{') /* } */ - nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|P_DOLBRACE|rflags); - else if (ch == '[') /* ] */ - nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags); - - CHECK_NESTRET_ERROR (); - APPEND_NESTRET (); - - FREE (nestret); - } -#if defined (PROCESS_SUBSTITUTION) - if MBTEST((ch == '<' || ch == '>') && (tflags & LEX_GTLT) == 0) - tflags |= LEX_GTLT; - else - tflags &= ~LEX_GTLT; -#endif - if MBTEST(ch == '$' && (tflags & LEX_WASDOL) == 0) - tflags |= LEX_WASDOL; - else - tflags &= ~LEX_WASDOL; - } - - ret[retind] = '\0'; - if (lenp) - *lenp = retind; -/*itrace("parse_matched_pair[%d]: returning %s", line_number, ret);*/ - return ret; -} - -#if defined (DEBUG) -static void -dump_tflags (flags) - int flags; -{ - int f; - - f = flags; - fprintf (stderr, "%d -> ", f); - if (f & LEX_WASDOL) - { - f &= ~LEX_WASDOL; - fprintf (stderr, "LEX_WASDOL%s", f ? "|" : ""); - } - if (f & LEX_CKCOMMENT) - { - f &= ~LEX_CKCOMMENT; - fprintf (stderr, "LEX_CKCOMMENT%s", f ? "|" : ""); - } - if (f & LEX_INCOMMENT) - { - f &= ~LEX_INCOMMENT; - fprintf (stderr, "LEX_INCOMMENT%s", f ? "|" : ""); - } - if (f & LEX_PASSNEXT) - { - f &= ~LEX_PASSNEXT; - fprintf (stderr, "LEX_PASSNEXT%s", f ? "|" : ""); - } - if (f & LEX_RESWDOK) - { - f &= ~LEX_RESWDOK; - fprintf (stderr, "LEX_RESWDOK%s", f ? "|" : ""); - } - if (f & LEX_CKCASE) - { - f &= ~LEX_CKCASE; - fprintf (stderr, "LEX_CKCASE%s", f ? "|" : ""); - } - if (f & LEX_CKESAC) - { - f &= ~LEX_CKESAC; - fprintf (stderr, "LEX_CKESAC%s", f ? "|" : ""); - } - if (f & LEX_INCASE) - { - f &= ~LEX_INCASE; - fprintf (stderr, "LEX_INCASE%s", f ? "|" : ""); - } - if (f & LEX_CASEWD) - { - f &= ~LEX_CASEWD; - fprintf (stderr, "LEX_CASEWD%s", f ? "|" : ""); - } - if (f & LEX_PATLIST) - { - f &= ~LEX_PATLIST; - fprintf (stderr, "LEX_PATLIST%s", f ? "|" : ""); - } - if (f & LEX_INHEREDOC) - { - f &= ~LEX_INHEREDOC; - fprintf (stderr, "LEX_INHEREDOC%s", f ? "|" : ""); - } - if (f & LEX_HEREDELIM) - { - f &= ~LEX_HEREDELIM; - fprintf (stderr, "LEX_HEREDELIM%s", f ? "|" : ""); - } - if (f & LEX_STRIPDOC) - { - f &= ~LEX_STRIPDOC; - fprintf (stderr, "LEX_WASDOL%s", f ? "|" : ""); - } - if (f & LEX_QUOTEDDOC) - { - f &= ~LEX_QUOTEDDOC; - fprintf (stderr, "LEX_QUOTEDDOC%s", f ? "|" : ""); - } - if (f & LEX_INWORD) - { - f &= ~LEX_INWORD; - fprintf (stderr, "LEX_INWORD%s", f ? "|" : ""); - } - - fprintf (stderr, "\n"); - fflush (stderr); -} -#endif - -/* Parse a $(...) command substitution. This reads input from the current - input stream. */ -static char * -parse_comsub (qc, open, close, lenp, flags) - int qc; /* `"' if this construct is within double quotes */ - int open, close; - int *lenp, flags; -{ - int peekc, r; - int start_lineno, local_extglob, was_extpat; - char *ret, *tcmd; - int retlen; - sh_parser_state_t ps; - STRING_SAVER *saved_strings; - COMMAND *saved_global, *parsed_command; - - /* Posix interp 217 says arithmetic expressions have precedence, so - assume $(( introduces arithmetic expansion and parse accordingly. */ - if (open == '(') /*)*/ - { - peekc = shell_getc (1); - shell_ungetc (peekc); - if (peekc == '(') /*)*/ - return (parse_matched_pair (qc, open, close, lenp, 0)); - } - -/*itrace("parse_comsub: qc = `%c' open = %c close = %c", qc, open, close);*/ - - /*debug_parser(1);*/ - start_lineno = line_number; - - save_parser_state (&ps); - - was_extpat = (parser_state & PST_EXTPAT); - - /* State flags we don't want to persist into command substitutions. */ - parser_state &= ~(PST_REGEXP|PST_EXTPAT|PST_CONDCMD|PST_CONDEXPR|PST_COMPASSIGN); - /* Could do PST_CASESTMT too, but that also affects history. Setting - expecting_in_token below should take care of the parsing requirements. - Unsetting PST_REDIRLIST isn't strictly necessary because of how we set - token_to_read below, but we do it anyway. */ - parser_state &= ~(PST_CASEPAT|PST_ALEXPNEXT|PST_SUBSHELL|PST_REDIRLIST); - /* State flags we want to set for this run through the parser. */ - parser_state |= PST_CMDSUBST|PST_EOFTOKEN|PST_NOEXPAND; - - /* leave pushed_string_list alone, since we might need to consume characters - from it to satisfy this command substitution (in some perverse case). */ - shell_eof_token = close; - - saved_global = global_command; /* might not be necessary */ - global_command = (COMMAND *)NULL; - - /* These are reset by reset_parser() */ - need_here_doc = 0; - esacs_needed_count = expecting_in_token = 0; - - /* We want to expand aliases on this pass if we're in posix mode, since the - standard says you have to take aliases into account when looking for the - terminating right paren. Otherwise, we defer until execution time for - backwards compatibility. */ - if (expand_aliases) - expand_aliases = posixly_correct != 0; -#if defined (EXTENDED_GLOB) - /* If (parser_state & PST_EXTPAT), we're parsing an extended pattern for a - conditional command and have already set global_extglob appropriately. */ - if (shell_compatibility_level <= 51 && was_extpat == 0) - { - local_extglob = global_extglob = extended_glob; - extended_glob = 1; - } -#endif - - current_token = '\n'; /* XXX */ - token_to_read = DOLPAREN; /* let's trick the parser */ - - r = yyparse (); - - if (need_here_doc > 0) - { - internal_warning ("command substitution: %d unterminated here-document%s", need_here_doc, (need_here_doc == 1) ? "" : "s"); - gather_here_documents (); /* XXX check compatibility level? */ - } - -#if defined (EXTENDED_GLOB) - if (shell_compatibility_level <= 51 && was_extpat == 0) - extended_glob = local_extglob; -#endif - - parsed_command = global_command; - - if (EOF_Reached) - { - shell_eof_token = ps.eof_token; - expand_aliases = ps.expand_aliases; - - /* yyparse() has already called yyerror() and reset_parser() */ - return (&matched_pair_error); - } - else if (r != 0) - { - /* parser_error (start_lineno, _("could not parse command substitution")); */ - /* Non-interactive shells exit on parse error in a command substitution. */ - if (last_command_exit_value == 0) - last_command_exit_value = EXECUTION_FAILURE; - set_exit_status (last_command_exit_value); - if (interactive_shell == 0) - jump_to_top_level (FORCE_EOF); /* This is like reader_loop() */ - else - { - shell_eof_token = ps.eof_token; - expand_aliases = ps.expand_aliases; - - jump_to_top_level (DISCARD); /* XXX - return (&matched_pair_error)? */ - } - } - - if (current_token != shell_eof_token) - { -INTERNAL_DEBUG(("current_token (%d) != shell_eof_token (%c)", current_token, shell_eof_token)); - token_to_read = current_token; - - /* If we get here we can check eof_encountered and if it's 1 but the - previous EOF_Reached test didn't succeed, we can assume that the shell - is interactive and ignoreeof is set. We might want to restore the - parser state in this case. */ - shell_eof_token = ps.eof_token; - expand_aliases = ps.expand_aliases; - - return (&matched_pair_error); - } - - /* We don't want to restore the old pushed string list, since we might have - used it to consume additional input from an alias while parsing this - command substitution. */ - saved_strings = pushed_string_list; - restore_parser_state (&ps); - pushed_string_list = saved_strings; - - tcmd = print_comsub (parsed_command); /* returns static memory */ - retlen = strlen (tcmd); - if (tcmd[0] == '(') /* ) need a space to prevent arithmetic expansion */ - retlen++; - ret = xmalloc (retlen + 2); - if (tcmd[0] == '(') /* ) */ - { - ret[0] = ' '; - strcpy (ret + 1, tcmd); - } - else - strcpy (ret, tcmd); - ret[retlen++] = ')'; - ret[retlen] = '\0'; - - dispose_command (parsed_command); - global_command = saved_global; - - if (lenp) - *lenp = retlen; - -/*itrace("parse_comsub:%d: returning `%s'", line_number, ret);*/ - return ret; -} - -/* Recursively call the parser to parse a $(...) command substitution. This is - called by the word expansion code and so does not have to reset as much - parser state before calling yyparse(). */ -char * -xparse_dolparen (base, string, indp, flags) - char *base; - char *string; - int *indp; - int flags; -{ - sh_parser_state_t ps; - sh_input_line_state_t ls; - int orig_ind, nc, sflags, start_lineno; - char *ret, *ep, *ostring; - -/*debug_parser(1);*/ - orig_ind = *indp; - ostring = string; - start_lineno = line_number; - - if (*string == 0) - { - if (flags & SX_NOALLOC) - return (char *)NULL; - - ret = xmalloc (1); - ret[0] = '\0'; - return ret; - } - -/*itrace("xparse_dolparen: size = %d shell_input_line = `%s' string=`%s'", shell_input_line_size, shell_input_line, string);*/ - - sflags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOFREE; - if (flags & SX_NOLONGJMP) - sflags |= SEVAL_NOLONGJMP; - - save_parser_state (&ps); - save_input_line_state (&ls); - -#if defined (ALIAS) || defined (DPAREN_ARITHMETIC) - pushed_string_list = (STRING_SAVER *)NULL; -#endif - /*(*/ - parser_state |= PST_CMDSUBST|PST_EOFTOKEN; /* allow instant ')' */ /*(*/ - shell_eof_token = ')'; - if (flags & SX_COMPLETE) - parser_state |= PST_NOERROR; - - /* Don't expand aliases on this pass at all. Either parse_comsub() does it - at parse time, in which case this string already has aliases expanded, - or command_substitute() does it in the child process executing the - command substitution and we want to defer it completely until then. The - old value will be restored by restore_parser_state(). */ - expand_aliases = 0; -#if defined (EXTENDED_GLOB) - global_extglob = extended_glob; /* for reset_parser() */ -#endif - - token_to_read = DOLPAREN; /* let's trick the parser */ - - nc = parse_string (string, "command substitution", sflags, (COMMAND **)NULL, &ep); - - /* Should we save and restore the bison/yacc lookahead token (yychar) here? - Or only if it's not YYEMPTY? */ - if (current_token == shell_eof_token) - yyclearin; /* might want to clear lookahead token unconditionally */ - - reset_parser (); /* resets extended_glob too */ - /* reset_parser() clears shell_input_line and associated variables, including - parser_state, so we want to reset things, then restore what we need. */ - restore_input_line_state (&ls); - restore_parser_state (&ps); - - token_to_read = 0; - - /* If parse_string returns < 0, we need to jump to top level with the - negative of the return value. We abandon the rest of this input line - first */ - if (nc < 0) - { - clear_shell_input_line (); /* XXX */ - if (bash_input.type != st_string) /* paranoia */ - parser_state &= ~(PST_CMDSUBST|PST_EOFTOKEN); - if ((flags & SX_NOLONGJMP) == 0) - jump_to_top_level (-nc); /* XXX */ - } - - /* Need to find how many characters parse_string() consumed, update - *indp, if flags != 0, copy the portion of the string parsed into RET - and return it. If flags & 1 (SX_NOALLOC) we can return NULL. */ - - /*(*/ - if (ep[-1] != ')') - { -#if 0 - if (ep[-1] != '\n') - itrace("xparse_dolparen:%d: ep[-1] != RPAREN (%d), ep = `%s'", line_number, ep[-1], ep); -#endif - - while (ep > ostring && ep[-1] == '\n') ep--; - } - - nc = ep - ostring; - *indp = ep - base - 1; - - /*((*/ -#if 0 - if (base[*indp] != ')') - itrace("xparse_dolparen:%d: base[%d] != RPAREN (%d), base = `%s'", line_number, *indp, base[*indp], base); - if (*indp < orig_ind) - itrace("xparse_dolparen:%d: *indp (%d) < orig_ind (%d), orig_string = `%s'", line_number, *indp, orig_ind, ostring); -#endif - - if (base[*indp] != ')' && (flags & SX_NOLONGJMP) == 0) - { - /*(*/ - if ((flags & SX_NOERROR) == 0) - parser_error (start_lineno, _("unexpected EOF while looking for matching `%c'"), ')'); - jump_to_top_level (DISCARD); - } - - if (flags & SX_NOALLOC) - return (char *)NULL; - - if (nc == 0) - { - ret = xmalloc (1); - ret[0] = '\0'; - } - else - ret = substring (ostring, 0, nc - 1); - - return ret; -} - -/* Recursively call the parser to parse the string from a $(...) command - substitution to a COMMAND *. This is called from command_substitute() and - has the same parser state constraints as xparse_dolparen(). */ -COMMAND * -parse_string_to_command (string, flags) - char *string; - int flags; -{ - sh_parser_state_t ps; - sh_input_line_state_t ls; - int nc, sflags; - size_t slen; - char *ret, *ep; - COMMAND *cmd; - - if (*string == 0) - return (COMMAND *)NULL; - - ep = string; - slen = STRLEN (string); - -/*itrace("parse_string_to_command: size = %d shell_input_line = `%s' string=`%s'", shell_input_line_size, shell_input_line, string);*/ - - sflags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOFREE; - if (flags & SX_NOLONGJMP) - sflags |= SEVAL_NOLONGJMP; - - save_parser_state (&ps); - save_input_line_state (&ls); - -#if defined (ALIAS) || defined (DPAREN_ARITHMETIC) - pushed_string_list = (STRING_SAVER *)NULL; -#endif - if (flags & SX_COMPLETE) - parser_state |= PST_NOERROR; - - expand_aliases = 0; - - cmd = 0; - nc = parse_string (string, "command substitution", sflags, &cmd, &ep); - - reset_parser (); - /* reset_parser() clears shell_input_line and associated variables, including - parser_state, so we want to reset things, then restore what we need. */ - restore_input_line_state (&ls); - restore_parser_state (&ps); - - /* If parse_string returns < 0, we need to jump to top level with the - negative of the return value. We abandon the rest of this input line - first */ - if (nc < 0) - { - clear_shell_input_line (); /* XXX */ - if ((flags & SX_NOLONGJMP) == 0) - jump_to_top_level (-nc); /* XXX */ - } - - /* Need to check how many characters parse_string() consumed, make sure it's - the entire string. */ - if (nc < slen) - { - dispose_command (cmd); - return (COMMAND *)NULL; - } - - return cmd; -} - -#if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND) -/* Parse a double-paren construct. It can be either an arithmetic - command, an arithmetic `for' command, or a nested subshell. Returns - the parsed token, -1 on error, or -2 if we didn't do anything and - should just go on. */ -static int -parse_dparen (c) - int c; -{ - int cmdtyp, sline; - char *wval; - WORD_DESC *wd; - -#if defined (ARITH_FOR_COMMAND) - if (last_read_token == FOR) - { - if (word_top < MAX_CASE_NEST) - word_top++; - arith_for_lineno = word_lineno[word_top] = line_number; - cmdtyp = parse_arith_cmd (&wval, 0); - if (cmdtyp == 1) - { - wd = alloc_word_desc (); - wd->word = wval; - yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL); - return (ARITH_FOR_EXPRS); - } - else - return -1; /* ERROR */ - } -#endif - -#if defined (DPAREN_ARITHMETIC) - if (reserved_word_acceptable (last_read_token)) - { - sline = line_number; - - cmdtyp = parse_arith_cmd (&wval, 0); - if (cmdtyp == 1) /* arithmetic command */ - { - wd = alloc_word_desc (); - wd->word = wval; - wd->flags = W_QUOTED|W_NOSPLIT|W_NOGLOB|W_NOTILDE|W_NOPROCSUB; - yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL); - return (ARITH_CMD); - } - else if (cmdtyp == 0) /* nested subshell */ - { - push_string (wval, 0, (alias_t *)NULL); - pushed_string_list->flags = PSH_DPAREN; - if ((parser_state & PST_CASEPAT) == 0) - parser_state |= PST_SUBSHELL; - return (c); - } - else /* ERROR */ - return -1; - } -#endif - - return -2; /* XXX */ -} - -/* We've seen a `(('. Look for the matching `))'. If we get it, return 1. - If not, assume it's a nested subshell for backwards compatibility and - return 0. In any case, put the characters we've consumed into a locally- - allocated buffer and make *ep point to that buffer. Return -1 on an - error, for example EOF. */ -static int -parse_arith_cmd (ep, adddq) - char **ep; - int adddq; -{ - int exp_lineno, rval, c; - char *ttok, *tokstr; - int ttoklen; - - exp_lineno = line_number; - ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0); - rval = 1; - if (ttok == &matched_pair_error) - return -1; - /* Check that the next character is the closing right paren. If - not, this is a syntax error. ( */ - c = shell_getc (0); - if MBTEST(c != ')') - rval = 0; - - tokstr = (char *)xmalloc (ttoklen + 4); - - /* if ADDDQ != 0 then (( ... )) -> "..." */ - if (rval == 1 && adddq) /* arith cmd, add double quotes */ - { - tokstr[0] = '"'; - strncpy (tokstr + 1, ttok, ttoklen - 1); - tokstr[ttoklen] = '"'; - tokstr[ttoklen+1] = '\0'; - } - else if (rval == 1) /* arith cmd, don't add double quotes */ - { - strncpy (tokstr, ttok, ttoklen - 1); - tokstr[ttoklen-1] = '\0'; - } - else /* nested subshell */ - { - tokstr[0] = '('; - strncpy (tokstr + 1, ttok, ttoklen - 1); - tokstr[ttoklen] = ')'; - tokstr[ttoklen+1] = c; - tokstr[ttoklen+2] = '\0'; - } - - *ep = tokstr; - FREE (ttok); - return rval; -} -#endif /* DPAREN_ARITHMETIC || ARITH_FOR_COMMAND */ - -#if defined (COND_COMMAND) -static void -cond_error () -{ - char *etext; - - if (EOF_Reached && cond_token != COND_ERROR) /* [[ */ - parser_error (cond_lineno, _("unexpected EOF while looking for `]]'")); - else if (cond_token != COND_ERROR) - { - if (etext = error_token_from_token (cond_token)) - { - parser_error (cond_lineno, _("syntax error in conditional expression: unexpected token `%s'"), etext); - free (etext); - } - else - parser_error (cond_lineno, _("syntax error in conditional expression")); - } -} - -static COND_COM * -cond_expr () -{ - return (cond_or ()); -} - -static COND_COM * -cond_or () -{ - COND_COM *l, *r; - - l = cond_and (); - if (cond_token == OR_OR) - { - r = cond_or (); - l = make_cond_node (COND_OR, (WORD_DESC *)NULL, l, r); - } - return l; -} - -static COND_COM * -cond_and () -{ - COND_COM *l, *r; - - l = cond_term (); - if (cond_token == AND_AND) - { - r = cond_and (); - l = make_cond_node (COND_AND, (WORD_DESC *)NULL, l, r); - } - return l; -} - -static int -cond_skip_newlines () -{ - while ((cond_token = read_token (READ)) == '\n') - { - if (SHOULD_PROMPT ()) - prompt_again (0); - } - return (cond_token); -} - -#define COND_RETURN_ERROR() \ - do { cond_token = COND_ERROR; return ((COND_COM *)NULL); } while (0) - -static COND_COM * -cond_term () -{ - WORD_DESC *op; - COND_COM *term, *tleft, *tright; - int tok, lineno, local_extglob; - char *etext; - - /* Read a token. It can be a left paren, a `!', a unary operator, or a - word that should be the first argument of a binary operator. Start by - skipping newlines, since this is a compound command. */ - tok = cond_skip_newlines (); - lineno = line_number; - if (tok == COND_END) - { - COND_RETURN_ERROR (); - } - else if (tok == '(') - { - term = cond_expr (); - if (cond_token != ')') - { - if (term) - dispose_cond_node (term); /* ( */ - if (etext = error_token_from_token (cond_token)) - { - parser_error (lineno, _("unexpected token `%s', expected `)'"), etext); - free (etext); - } - else - parser_error (lineno, _("expected `)'")); - COND_RETURN_ERROR (); - } - term = make_cond_node (COND_EXPR, (WORD_DESC *)NULL, term, (COND_COM *)NULL); - (void)cond_skip_newlines (); - } - else if (tok == BANG || (tok == WORD && (yylval.word->word[0] == '!' && yylval.word->word[1] == '\0'))) - { - if (tok == WORD) - dispose_word (yylval.word); /* not needed */ - term = cond_term (); - if (term) - term->flags ^= CMD_INVERT_RETURN; - } - else if (tok == WORD && yylval.word->word[0] == '-' && yylval.word->word[1] && yylval.word->word[2] == 0 && test_unop (yylval.word->word)) - { - op = yylval.word; - tok = read_token (READ); - if (tok == WORD) - { - tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL); - term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL); - } - else - { - dispose_word (op); - if (etext = error_token_from_token (tok)) - { - parser_error (line_number, _("unexpected argument `%s' to conditional unary operator"), etext); - free (etext); - } - else - parser_error (line_number, _("unexpected argument to conditional unary operator")); - COND_RETURN_ERROR (); - } - - (void)cond_skip_newlines (); - } - else if (tok == WORD) /* left argument to binary operator */ - { - /* lhs */ - tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL); - - /* binop */ - /* tok = cond_skip_newlines (); ? */ - tok = read_token (READ); - if (tok == WORD && test_binop (yylval.word->word)) - { - op = yylval.word; - if (op->word[0] == '=' && (op->word[1] == '\0' || (op->word[1] == '=' && op->word[2] == '\0'))) - parser_state |= PST_EXTPAT; - else if (op->word[0] == '!' && op->word[1] == '=' && op->word[2] == '\0') - parser_state |= PST_EXTPAT; - } -#if defined (COND_REGEXP) - else if (tok == WORD && STREQ (yylval.word->word, "=~")) - { - op = yylval.word; - parser_state |= PST_REGEXP; - } -#endif - else if (tok == '<' || tok == '>') - op = make_word_from_token (tok); /* ( */ - /* There should be a check before blindly accepting the `)' that we have - seen the opening `('. */ - else if (tok == COND_END || tok == AND_AND || tok == OR_OR || tok == ')') - { - /* Special case. [[ x ]] is equivalent to [[ -n x ]], just like - the test command. Similarly for [[ x && expr ]] or - [[ x || expr ]] or [[ (x) ]]. */ - op = make_word ("-n"); - term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL); - cond_token = tok; - return (term); - } - else - { - if (etext = error_token_from_token (tok)) - { - parser_error (line_number, _("unexpected token `%s', conditional binary operator expected"), etext); - free (etext); - } - else - parser_error (line_number, _("conditional binary operator expected")); - dispose_cond_node (tleft); - COND_RETURN_ERROR (); - } - - /* rhs */ - local_extglob = extended_glob; - if (parser_state & PST_EXTPAT) - extended_glob = 1; - tok = read_token (READ); - if (parser_state & PST_EXTPAT) - extended_glob = local_extglob; - parser_state &= ~(PST_REGEXP|PST_EXTPAT); - - if (tok == WORD) - { - tright = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL); - term = make_cond_node (COND_BINARY, op, tleft, tright); - } - else - { - if (etext = error_token_from_token (tok)) - { - parser_error (line_number, _("unexpected argument `%s' to conditional binary operator"), etext); - free (etext); - } - else - parser_error (line_number, _("unexpected argument to conditional binary operator")); - dispose_cond_node (tleft); - dispose_word (op); - COND_RETURN_ERROR (); - } - - (void)cond_skip_newlines (); - } - else - { - if (tok < 256) - parser_error (line_number, _("unexpected token `%c' in conditional command"), tok); - else if (etext = error_token_from_token (tok)) - { - parser_error (line_number, _("unexpected token `%s' in conditional command"), etext); - free (etext); - } - else - parser_error (line_number, _("unexpected token %d in conditional command"), tok); - COND_RETURN_ERROR (); - } - return (term); -} - -/* This is kind of bogus -- we slip a mini recursive-descent parser in - here to handle the conditional statement syntax. */ -static COMMAND * -parse_cond_command () -{ - COND_COM *cexp; - - global_extglob = extended_glob; - cexp = cond_expr (); - return (make_cond_command (cexp)); -} -#endif - -#if defined (ARRAY_VARS) -/* When this is called, it's guaranteed that we don't care about anything - in t beyond i. We use a buffer with room for the characters we add just - in case assignment() ends up doing something like parsing a command - substitution that will reallocate atoken. We don't want to write beyond - the end of an allocated buffer. */ -static int -token_is_assignment (t, i) - char *t; - int i; -{ - int r; - char *atoken; - - atoken = xmalloc (i + 3); - memcpy (atoken, t, i); - atoken[i] = '='; - atoken[i+1] = '\0'; - - r = assignment (atoken, (parser_state & PST_COMPASSIGN) != 0); - - free (atoken); - - /* XXX - check that r == i to avoid returning false positive for - t containing `=' before t[i]. */ - return (r > 0 && r == i); -} - -/* XXX - possible changes here for `+=' */ -static int -token_is_ident (t, i) - char *t; - int i; -{ - unsigned char c; - int r; - - c = t[i]; - t[i] = '\0'; - r = legal_identifier (t); - t[i] = c; - return r; -} -#endif - -static int -read_token_word (character) - int character; -{ - /* The value for YYLVAL when a WORD is read. */ - WORD_DESC *the_word; - - /* Index into the token that we are building. */ - int token_index; - - /* ALL_DIGITS becomes zero when we see a non-digit. */ - int all_digit_token; - - /* DOLLAR_PRESENT becomes non-zero if we see a `$'. */ - int dollar_present; - - /* COMPOUND_ASSIGNMENT becomes non-zero if we are parsing a compound - assignment. */ - int compound_assignment; - - /* QUOTED becomes non-zero if we see one of ("), ('), (`), or (\). */ - int quoted; - - /* Non-zero means to ignore the value of the next character, and just - to add it no matter what. */ - int pass_next_character; - - /* The current delimiting character. */ - int cd; - int result, peek_char; - char *ttok, *ttrans; - int ttoklen, ttranslen; - intmax_t lvalue; - - if (token_buffer_size < TOKEN_DEFAULT_INITIAL_SIZE) - token = (char *)xrealloc (token, token_buffer_size = TOKEN_DEFAULT_INITIAL_SIZE); - - token_index = 0; - all_digit_token = DIGIT (character); - dollar_present = quoted = pass_next_character = compound_assignment = 0; - - for (;;) - { - if (character == EOF) - goto got_token; - - if (pass_next_character) - { - pass_next_character = 0; - goto got_escaped_character; - } - - cd = current_delimiter (dstack); - - /* Handle backslashes. Quote lots of things when not inside of - double-quotes, quote some things inside of double-quotes. */ - if MBTEST(character == '\\') - { - if (parser_state & PST_NOEXPAND) - { - pass_next_character++; - quoted = 1; - goto got_character; - } - - peek_char = shell_getc (0); - - /* Backslash-newline is ignored in all cases except - when quoted with single quotes. */ - if MBTEST(peek_char == '\n') - { - character = '\n'; - goto next_character; - } - else - { - shell_ungetc (peek_char); - - /* If the next character is to be quoted, note it now. */ - if MBTEST(cd == 0 || cd == '`' || - (cd == '"' && peek_char >= 0 && (sh_syntaxtab[peek_char] & CBSDQUOTE))) - pass_next_character++; - - quoted = 1; - goto got_character; - } - } - - /* Parse a matched pair of quote characters. */ - if MBTEST(shellquote (character)) - { - push_delimiter (dstack, character); - ttok = parse_matched_pair (character, character, character, &ttoklen, (character == '`') ? P_COMMAND : 0); - pop_delimiter (dstack); - if (ttok == &matched_pair_error) - return -1; /* Bail immediately. */ - RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2, - token_buffer_size, TOKEN_DEFAULT_GROW_SIZE); - token[token_index++] = character; - strcpy (token + token_index, ttok); - token_index += ttoklen; - all_digit_token = 0; - if (character != '`') - quoted = 1; - dollar_present |= (character == '"' && strchr (ttok, '$') != 0); - FREE (ttok); - goto next_character; - } - -#ifdef COND_REGEXP - /* When parsing a regexp as a single word inside a conditional command, - we need to special-case characters special to both the shell and - regular expressions. Right now, that is only '(' and '|'. */ /*)*/ - if MBTEST((parser_state & PST_REGEXP) && (character == '(' || character == '|')) /*)*/ - { - if (character == '|') - goto got_character; - - push_delimiter (dstack, character); - ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0); - pop_delimiter (dstack); - if (ttok == &matched_pair_error) - return -1; /* Bail immediately. */ - RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2, - token_buffer_size, TOKEN_DEFAULT_GROW_SIZE); - token[token_index++] = character; - strcpy (token + token_index, ttok); - token_index += ttoklen; - FREE (ttok); - dollar_present = all_digit_token = 0; - goto next_character; - } -#endif /* COND_REGEXP */ - -#ifdef EXTENDED_GLOB - /* Parse a ksh-style extended pattern matching specification. */ - if MBTEST(extended_glob && PATTERN_CHAR (character)) - { - peek_char = shell_getc (1); - if MBTEST(peek_char == '(') /* ) */ - { - push_delimiter (dstack, peek_char); - ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0); - pop_delimiter (dstack); - if (ttok == &matched_pair_error) - return -1; /* Bail immediately. */ - RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 3, - token_buffer_size, - TOKEN_DEFAULT_GROW_SIZE); - token[token_index++] = character; - token[token_index++] = peek_char; - strcpy (token + token_index, ttok); - token_index += ttoklen; - FREE (ttok); - dollar_present = all_digit_token = 0; - goto next_character; - } - else - shell_ungetc (peek_char); - } -#endif /* EXTENDED_GLOB */ - - /* If the delimiter character is not single quote, parse some of - the shell expansions that must be read as a single word. */ - if MBTEST(shellexp (character)) - { - peek_char = shell_getc (1); - /* $(...), <(...), >(...), $((...)), ${...}, and $[...] constructs */ - if MBTEST(peek_char == '(' || - ((peek_char == '{' || peek_char == '[') && character == '$')) /* ) ] } */ - { - if (peek_char == '{') /* } */ - ttok = parse_matched_pair (cd, '{', '}', &ttoklen, P_FIRSTCLOSE|P_DOLBRACE); - else if (peek_char == '(') /* ) */ - { - /* XXX - push and pop the `(' as a delimiter for use by - the command-oriented-history code. This way newlines - appearing in the $(...) string get added to the - history literally rather than causing a possibly- - incorrect `;' to be added. ) */ - push_delimiter (dstack, peek_char); - ttok = parse_comsub (cd, '(', ')', &ttoklen, P_COMMAND); - pop_delimiter (dstack); - } - else - ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0); - if (ttok == &matched_pair_error) - return -1; /* Bail immediately. */ - RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 3, - token_buffer_size, - TOKEN_DEFAULT_GROW_SIZE); - token[token_index++] = character; - token[token_index++] = peek_char; - strcpy (token + token_index, ttok); - token_index += ttoklen; - FREE (ttok); - dollar_present = 1; - all_digit_token = 0; - goto next_character; - } - /* This handles $'...' and $"..." new-style quoted strings. */ -#if defined (TRANSLATABLE_STRINGS) - else if MBTEST(character == '$' && (peek_char == '\'' || peek_char == '"')) -#else - else if MBTEST(character == '$' && peek_char == '\'') -#endif - { - int first_line; - - first_line = line_number; - push_delimiter (dstack, peek_char); - ttok = parse_matched_pair (peek_char, peek_char, peek_char, - &ttoklen, - (peek_char == '\'') ? P_ALLOWESC : 0); - pop_delimiter (dstack); - if (ttok == &matched_pair_error) - return -1; - if (peek_char == '\'') - { - /* PST_NOEXPAND */ - ttrans = ansiexpand (ttok, 0, ttoklen - 1, &ttranslen); - free (ttok); - - /* Insert the single quotes and correctly quote any - embedded single quotes (allowed because P_ALLOWESC was - passed to parse_matched_pair). */ - ttok = sh_single_quote (ttrans); - free (ttrans); - ttranslen = strlen (ttok); - ttrans = ttok; - } -#if defined (TRANSLATABLE_STRINGS) - else - { - /* PST_NOEXPAND */ - /* Try to locale-expand the converted string. */ - ttrans = locale_expand (ttok, 0, ttoklen - 1, first_line, &ttranslen); - free (ttok); - - /* Add the double quotes back (or single quotes if the user - has set that option). */ - if (singlequote_translations && - ((ttoklen - 1) != ttranslen || STREQN (ttok, ttrans, ttranslen) == 0)) - ttok = sh_single_quote (ttrans); - else - ttok = sh_mkdoublequoted (ttrans, ttranslen, 0); - - free (ttrans); - ttrans = ttok; - ttranslen = strlen (ttrans); - } -#endif /* TRANSLATABLE_STRINGS */ - - RESIZE_MALLOCED_BUFFER (token, token_index, ttranslen + 1, - token_buffer_size, - TOKEN_DEFAULT_GROW_SIZE); - strcpy (token + token_index, ttrans); - token_index += ttranslen; - FREE (ttrans); - quoted = 1; - all_digit_token = 0; - goto next_character; - } - /* This could eventually be extended to recognize all of the - shell's single-character parameter expansions, and set flags.*/ - else if MBTEST(character == '$' && peek_char == '$') - { - RESIZE_MALLOCED_BUFFER (token, token_index, 3, - token_buffer_size, - TOKEN_DEFAULT_GROW_SIZE); - token[token_index++] = '$'; - token[token_index++] = peek_char; - dollar_present = 1; - all_digit_token = 0; - goto next_character; - } - else - shell_ungetc (peek_char); - } - -#if defined (ARRAY_VARS) - /* Identify possible array subscript assignment; match [...]. If - parser_state&PST_COMPASSIGN, we need to parse [sub]=words treating - `sub' as if it were enclosed in double quotes. */ - else if MBTEST(character == '[' && /* ] */ - ((token_index > 0 && assignment_acceptable (last_read_token) && token_is_ident (token, token_index)) || - (token_index == 0 && (parser_state&PST_COMPASSIGN)))) - { - ttok = parse_matched_pair (cd, '[', ']', &ttoklen, P_ARRAYSUB); - if (ttok == &matched_pair_error) - return -1; /* Bail immediately. */ - RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2, - token_buffer_size, - TOKEN_DEFAULT_GROW_SIZE); - token[token_index++] = character; - strcpy (token + token_index, ttok); - token_index += ttoklen; - FREE (ttok); - all_digit_token = 0; - goto next_character; - } - /* Identify possible compound array variable assignment. */ - else if MBTEST(character == '=' && token_index > 0 && (assignment_acceptable (last_read_token) || (parser_state & PST_ASSIGNOK)) && token_is_assignment (token, token_index)) - { - peek_char = shell_getc (1); - if MBTEST(peek_char == '(') /* ) */ - { - ttok = parse_compound_assignment (&ttoklen); - - RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 4, - token_buffer_size, - TOKEN_DEFAULT_GROW_SIZE); - - token[token_index++] = '='; - token[token_index++] = '('; - if (ttok) - { - strcpy (token + token_index, ttok); - token_index += ttoklen; - } - token[token_index++] = ')'; - FREE (ttok); - all_digit_token = 0; - compound_assignment = 1; -#if 1 - goto next_character; -#else - goto got_token; /* ksh93 seems to do this */ -#endif - } - else - shell_ungetc (peek_char); - } -#endif - - /* When not parsing a multi-character word construct, shell meta- - characters break words. */ - if MBTEST(shellbreak (character)) - { - shell_ungetc (character); - goto got_token; - } - -got_character: - if MBTEST(character == CTLESC || character == CTLNUL) - { - RESIZE_MALLOCED_BUFFER (token, token_index, 2, token_buffer_size, - TOKEN_DEFAULT_GROW_SIZE); - token[token_index++] = CTLESC; - } - else -got_escaped_character: - RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size, - TOKEN_DEFAULT_GROW_SIZE); - - token[token_index++] = character; - - all_digit_token &= DIGIT (character); - dollar_present |= character == '$'; - - next_character: - if (character == '\n' && SHOULD_PROMPT ()) - prompt_again (0); - - /* We want to remove quoted newlines (that is, a \ pair) - unless we are within single quotes or pass_next_character is - set (the shell equivalent of literal-next). */ - cd = current_delimiter (dstack); - character = shell_getc (cd != '\'' && pass_next_character == 0); - } /* end for (;;) */ - -got_token: - - /* Calls to RESIZE_MALLOCED_BUFFER ensure there is sufficient room. */ - token[token_index] = '\0'; - - /* Check to see what thing we should return. If the last_read_token - is a `<', or a `&', or the character which ended this token is - a '>' or '<', then, and ONLY then, is this input token a NUMBER. - Otherwise, it is just a word, and should be returned as such. */ - if MBTEST(all_digit_token && (character == '<' || character == '>' || - last_read_token == LESS_AND || - last_read_token == GREATER_AND)) - { - if (legal_number (token, &lvalue) && (int)lvalue == lvalue) - { - yylval.number = lvalue; - return (NUMBER); - } - } - - /* Check for special case tokens. */ - result = (last_shell_getc_is_singlebyte) ? special_case_tokens (token) : -1; - if (result >= 0) - return result; - -#if defined (ALIAS) - /* Posix.2 does not allow reserved words to be aliased, so check for all - of them, including special cases, before expanding the current token - as an alias. */ - if MBTEST(posixly_correct) - CHECK_FOR_RESERVED_WORD (token); - - /* Aliases are expanded iff EXPAND_ALIASES is non-zero, and quoting - inhibits alias expansion. */ - if (expand_aliases && quoted == 0) - { - result = alias_expand_token (token); - if (result == RE_READ_TOKEN) - return (RE_READ_TOKEN); - else if (result == NO_EXPANSION) - parser_state &= ~PST_ALEXPNEXT; - } - - /* If not in Posix.2 mode, check for reserved words after alias - expansion. */ - if MBTEST(posixly_correct == 0) -#endif - CHECK_FOR_RESERVED_WORD (token); - - the_word = alloc_word_desc (); - the_word->word = (char *)xmalloc (1 + token_index); - the_word->flags = 0; - strcpy (the_word->word, token); - if (dollar_present) - the_word->flags |= W_HASDOLLAR; - if (quoted) - the_word->flags |= W_QUOTED; /*(*/ - if (compound_assignment && token[token_index-1] == ')') - the_word->flags |= W_COMPASSIGN; - /* A word is an assignment if it appears at the beginning of a - simple command, or after another assignment word. This is - context-dependent, so it cannot be handled in the grammar. */ - if (assignment (token, (parser_state & PST_COMPASSIGN) != 0)) - { - the_word->flags |= W_ASSIGNMENT; - /* Don't perform word splitting on assignment statements. */ - if (assignment_acceptable (last_read_token) || (parser_state & PST_COMPASSIGN) != 0) - { - the_word->flags |= W_NOSPLIT; - if (parser_state & PST_COMPASSIGN) - the_word->flags |= W_NOGLOB; /* XXX - W_NOBRACE? */ - } - } - - if (command_token_position (last_read_token)) - { - struct builtin *b; - b = builtin_address_internal (token, 0); - if (b && (b->flags & ASSIGNMENT_BUILTIN)) - parser_state |= PST_ASSIGNOK; - else if (STREQ (token, "eval") || STREQ (token, "let")) - parser_state |= PST_ASSIGNOK; - } - - yylval.word = the_word; - - /* should we check that quoted == 0 as well? */ - if MBTEST(token[0] == '{' && token[token_index-1] == '}' && - (character == '<' || character == '>')) - { - /* can use token; already copied to the_word */ - token[token_index-1] = '\0'; -#if defined (ARRAY_VARS) - if (legal_identifier (token+1) || valid_array_reference (token+1, 0)) -#else - if (legal_identifier (token+1)) -#endif - { - strcpy (the_word->word, token+1); -/* itrace("read_token_word: returning REDIR_WORD for %s", the_word->word); */ - yylval.word = the_word; /* accommodate recursive call */ - return (REDIR_WORD); - } - else - /* valid_array_reference can call the parser recursively; need to - make sure that yylval.word doesn't change if we are going to - return WORD or ASSIGNMENT_WORD */ - yylval.word = the_word; - } - - result = ((the_word->flags & (W_ASSIGNMENT|W_NOSPLIT)) == (W_ASSIGNMENT|W_NOSPLIT)) - ? ASSIGNMENT_WORD : WORD; - - switch (last_read_token) - { - case FUNCTION: - parser_state |= PST_ALLOWOPNBRC; - function_dstart = line_number; - break; - case CASE: - case SELECT: - case FOR: - if (word_top < MAX_CASE_NEST) - word_top++; - word_lineno[word_top] = line_number; - expecting_in_token++; - break; - } - - return (result); -} - -/* Return 1 if TOKSYM is a token that after being read would allow - a reserved word to be seen, else 0. */ -static int -reserved_word_acceptable (toksym) - int toksym; -{ - switch (toksym) - { - case '\n': - case ';': - case '(': - case ')': - case '|': - case '&': - case '{': - case '}': /* XXX */ - case AND_AND: - case ARITH_CMD: - case BANG: - case BAR_AND: - case COND_END: - case DO: - case DONE: - case ELIF: - case ELSE: - case ESAC: - case FI: - case IF: - case OR_OR: - case SEMI_SEMI: - case SEMI_AND: - case SEMI_SEMI_AND: - case THEN: - case TIME: - case TIMEOPT: - case TIMEIGN: - case COPROC: - case UNTIL: - case WHILE: - case 0: - case DOLPAREN: - return 1; - default: -#if defined (COPROCESS_SUPPORT) - if (last_read_token == WORD && token_before_that == COPROC) - return 1; -#endif - if (last_read_token == WORD && token_before_that == FUNCTION) - return 1; - return 0; - } -} - -/* Return the index of TOKEN in the alist of reserved words, or -1 if - TOKEN is not a shell reserved word. */ -int -find_reserved_word (tokstr) - char *tokstr; -{ - int i; - for (i = 0; word_token_alist[i].word; i++) - if (STREQ (tokstr, word_token_alist[i].word)) - return i; - return -1; -} - -/* An interface to let the rest of the shell (primarily the completion - system) know what the parser is expecting. */ -int -parser_in_command_position () -{ - return (command_token_position (last_read_token)); -} - -#if 0 -#if defined (READLINE) -/* Called after each time readline is called. This insures that whatever - the new prompt string is gets propagated to readline's local prompt - variable. */ -static void -reset_readline_prompt () -{ - char *temp_prompt; - - if (prompt_string_pointer) - { - temp_prompt = (*prompt_string_pointer) - ? decode_prompt_string (*prompt_string_pointer) - : (char *)NULL; - - if (temp_prompt == 0) - { - temp_prompt = (char *)xmalloc (1); - temp_prompt[0] = '\0'; - } - - FREE (current_readline_prompt); - current_readline_prompt = temp_prompt; - } -} -#endif /* READLINE */ -#endif /* 0 */ - -#if defined (HISTORY) -/* A list of tokens which can be followed by newlines, but not by - semi-colons. When concatenating multiple lines of history, the - newline separator for such tokens is replaced with a space. */ -static const int no_semi_successors[] = { - '\n', '{', '(', ')', ';', '&', '|', - CASE, DO, ELSE, IF, SEMI_SEMI, SEMI_AND, SEMI_SEMI_AND, THEN, UNTIL, - WHILE, AND_AND, OR_OR, IN, - 0 -}; - -/* If we are not within a delimited expression, try to be smart - about which separators can be semi-colons and which must be - newlines. Returns the string that should be added into the - history entry. LINE is the line we're about to add; it helps - make some more intelligent decisions in certain cases. */ -char * -history_delimiting_chars (line) - const char *line; -{ - static int last_was_heredoc = 0; /* was the last entry the start of a here document? */ - register int i; - - if ((parser_state & PST_HEREDOC) == 0) - last_was_heredoc = 0; - - if (dstack.delimiter_depth != 0) - return ("\n"); - - /* We look for current_command_line_count == 2 because we are looking to - add the first line of the body of the here document (the second line - of the command). We also keep LAST_WAS_HEREDOC as a private sentinel - variable to note when we think we added the first line of a here doc - (the one with a "<<" somewhere in it) */ - if (parser_state & PST_HEREDOC) - { - if (last_was_heredoc) - { - last_was_heredoc = 0; - return "\n"; - } - return (here_doc_first_line ? "\n" : ""); - } - - if (parser_state & PST_COMPASSIGN) - return (" "); - - /* First, handle some special cases. */ - /*(*/ - /* If we just read `()', assume it's a function definition, and don't - add a semicolon. If the token before the `)' was not `(', and we're - not in the midst of parsing a case statement, assume it's a - parenthesized command and add the semicolon. */ - /*)(*/ - if (token_before_that == ')') - { - if (two_tokens_ago == '(') /*)*/ /* function def */ - return " "; - /* This does not work for subshells inside case statement - command lists. It's a suboptimal solution. */ - else if (parser_state & PST_CASESTMT) /* case statement pattern */ - return " "; - else - return "; "; /* (...) subshell */ - } - else if (token_before_that == WORD && two_tokens_ago == FUNCTION) - return " "; /* function def using `function name' without `()' */ - - /* If we're not in a here document, but we think we're about to parse one, - and we would otherwise return a `;', return a newline to delimit the - line with the here-doc delimiter */ - else if ((parser_state & PST_HEREDOC) == 0 && current_command_line_count > 1 && last_read_token == '\n' && strstr (line, "<<")) - { - last_was_heredoc = 1; - return "\n"; - } - else if ((parser_state & PST_HEREDOC) == 0 && current_command_line_count > 1 && need_here_doc > 0) - return "\n"; - else if (token_before_that == WORD && two_tokens_ago == FOR) - { - /* Tricky. `for i\nin ...' should not have a semicolon, but - `for i\ndo ...' should. We do what we can. */ - for (i = shell_input_line_index; whitespace (shell_input_line[i]); i++) - ; - if (shell_input_line[i] && shell_input_line[i] == 'i' && shell_input_line[i+1] == 'n') - return " "; - return ";"; - } - else if (two_tokens_ago == CASE && token_before_that == WORD && (parser_state & PST_CASESTMT)) - return " "; - - for (i = 0; no_semi_successors[i]; i++) - { - if (token_before_that == no_semi_successors[i]) - return (" "); - } - - /* Assume that by this point we are reading lines in a multi-line command. - If we have multiple consecutive blank lines we want to return only one - semicolon. */ - if (line_isblank (line)) - return (current_command_line_count > 1 && last_read_token == '\n' && token_before_that != '\n') ? "; " : ""; - - return ("; "); -} -#endif /* HISTORY */ - -/* Issue a prompt, or prepare to issue a prompt when the next character - is read. */ -static void -prompt_again (force) - int force; -{ - char *temp_prompt; - - if (interactive == 0 || expanding_alias ()) /* XXX */ - return; - - ps1_prompt = get_string_value ("PS1"); - ps2_prompt = get_string_value ("PS2"); - - ps0_prompt = get_string_value ("PS0"); - - if (!prompt_string_pointer) - prompt_string_pointer = &ps1_prompt; - - temp_prompt = *prompt_string_pointer - ? decode_prompt_string (*prompt_string_pointer) - : (char *)NULL; - - if (temp_prompt == 0) - { - temp_prompt = (char *)xmalloc (1); - temp_prompt[0] = '\0'; - } - - current_prompt_string = *prompt_string_pointer; - prompt_string_pointer = &ps2_prompt; - -#if defined (READLINE) - if (!no_line_editing) - { - FREE (current_readline_prompt); - current_readline_prompt = temp_prompt; - } - else -#endif /* READLINE */ - { - FREE (current_decoded_prompt); - current_decoded_prompt = temp_prompt; - } -} - -int -get_current_prompt_level () -{ - return ((current_prompt_string && current_prompt_string == ps2_prompt) ? 2 : 1); -} - -void -set_current_prompt_level (x) - int x; -{ - prompt_string_pointer = (x == 2) ? &ps2_prompt : &ps1_prompt; - current_prompt_string = *prompt_string_pointer; -} - -static void -print_prompt () -{ - fprintf (stderr, "%s", current_decoded_prompt); - fflush (stderr); -} - -#if defined (HISTORY) - /* The history library increments the history offset as soon as it stores - the first line of a potentially multi-line command, so we compensate - here by returning one fewer when appropriate. */ -static int -prompt_history_number (pmt) - char *pmt; -{ - int ret; - - ret = history_number (); - if (ret == 1) - return ret; - - if (pmt == ps1_prompt) /* are we expanding $PS1? */ - return ret; - else if (pmt == ps2_prompt && command_oriented_history == 0) - return ret; /* not command oriented history */ - else if (pmt == ps2_prompt && command_oriented_history && current_command_first_line_saved) - return ret - 1; - else - return ret - 1; /* PS0, PS4, ${var@P}, PS2 other cases */ -} -#endif - -/* Return a string which will be printed as a prompt. The string - may contain special characters which are decoded as follows: - - \a bell (ascii 07) - \d the date in Day Mon Date format - \e escape (ascii 033) - \h the hostname up to the first `.' - \H the hostname - \j the number of active jobs - \l the basename of the shell's tty device name - \n CRLF - \r CR - \s the name of the shell - \t the time in 24-hour hh:mm:ss format - \T the time in 12-hour hh:mm:ss format - \@ the time in 12-hour hh:mm am/pm format - \A the time in 24-hour hh:mm format - \D{fmt} the result of passing FMT to strftime(3) - \u your username - \v the version of bash (e.g., 2.00) - \V the release of bash, version + patchlevel (e.g., 2.00.0) - \w the current working directory - \W the last element of $PWD - \! the history number of this command - \# the command number of this command - \$ a $ or a # if you are root - \nnn character code nnn in octal - \\ a backslash - \[ begin a sequence of non-printing chars - \] end a sequence of non-printing chars -*/ -#define PROMPT_GROWTH 48 -char * -decode_prompt_string (string) - char *string; -{ - WORD_LIST *list; - char *result, *t, *orig_string; - struct dstack save_dstack; - int last_exit_value, last_comsub_pid; -#if defined (PROMPT_STRING_DECODE) - size_t result_size; - size_t result_index; - int c, n, i; - char *temp, *t_host, octal_string[4]; - struct tm *tm; - time_t the_time; - char timebuf[128]; - char *timefmt; - - result = (char *)xmalloc (result_size = PROMPT_GROWTH); - result[result_index = 0] = 0; - temp = (char *)NULL; - orig_string = string; - - while (c = *string++) - { - if (posixly_correct && c == '!') - { - if (*string == '!') - { - temp = savestring ("!"); - goto add_string; - } - else - { -#if !defined (HISTORY) - temp = savestring ("1"); -#else /* HISTORY */ - temp = itos (prompt_history_number (orig_string)); -#endif /* HISTORY */ - string--; /* add_string increments string again. */ - goto add_string; - } - } - if (c == '\\') - { - c = *string; - - switch (c) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - strncpy (octal_string, string, 3); - octal_string[3] = '\0'; - - n = read_octal (octal_string); - temp = (char *)xmalloc (3); - - if (n == CTLESC || n == CTLNUL) - { - temp[0] = CTLESC; - temp[1] = n; - temp[2] = '\0'; - } - else if (n == -1) - { - temp[0] = '\\'; - temp[1] = '\0'; - } - else - { - temp[0] = n; - temp[1] = '\0'; - } - - for (c = 0; n != -1 && c < 3 && ISOCTAL (*string); c++) - string++; - - c = 0; /* tested at add_string: */ - goto add_string; - - case 'd': - case 't': - case 'T': - case '@': - case 'A': - /* Make the current time/date into a string. */ - (void) time (&the_time); -#if defined (HAVE_TZSET) - sv_tz ("TZ"); /* XXX -- just make sure */ -#endif - tm = localtime (&the_time); - - if (c == 'd') - n = strftime (timebuf, sizeof (timebuf), "%a %b %d", tm); - else if (c == 't') - n = strftime (timebuf, sizeof (timebuf), "%H:%M:%S", tm); - else if (c == 'T') - n = strftime (timebuf, sizeof (timebuf), "%I:%M:%S", tm); - else if (c == '@') - n = strftime (timebuf, sizeof (timebuf), "%I:%M %p", tm); - else if (c == 'A') - n = strftime (timebuf, sizeof (timebuf), "%H:%M", tm); - - if (n == 0) - timebuf[0] = '\0'; - else - timebuf[sizeof(timebuf) - 1] = '\0'; - - temp = savestring (timebuf); - goto add_string; - - case 'D': /* strftime format */ - if (string[1] != '{') /* } */ - goto not_escape; - - (void) time (&the_time); - tm = localtime (&the_time); - string += 2; /* skip { */ - timefmt = xmalloc (strlen (string) + 3); - for (t = timefmt; *string && *string != '}'; ) - *t++ = *string++; - *t = '\0'; - c = *string; /* tested at add_string */ - if (timefmt[0] == '\0') - { - timefmt[0] = '%'; - timefmt[1] = 'X'; /* locale-specific current time */ - timefmt[2] = '\0'; - } - n = strftime (timebuf, sizeof (timebuf), timefmt, tm); - free (timefmt); - - if (n == 0) - timebuf[0] = '\0'; - else - timebuf[sizeof(timebuf) - 1] = '\0'; - - if (promptvars || posixly_correct) - /* Make sure that expand_prompt_string is called with a - second argument of Q_DOUBLE_QUOTES if we use this - function here. */ - temp = sh_backslash_quote_for_double_quotes (timebuf, 0); - else - temp = savestring (timebuf); - goto add_string; - - case 'n': - temp = (char *)xmalloc (3); - temp[0] = no_line_editing ? '\n' : '\r'; - temp[1] = no_line_editing ? '\0' : '\n'; - temp[2] = '\0'; - goto add_string; - - case 's': - temp = base_pathname (shell_name); - /* Try to quote anything the user can set in the file system */ - if (promptvars || posixly_correct) - { - char *t; - t = sh_strvis (temp); - temp = sh_backslash_quote_for_double_quotes (t, 0); - free (t); - } - else - temp = sh_strvis (temp); - goto add_string; - - case 'v': - case 'V': - temp = (char *)xmalloc (16); - if (c == 'v') - strcpy (temp, dist_version); - else - sprintf (temp, "%s.%d", dist_version, patch_level); - goto add_string; - - case 'w': - case 'W': - { - /* Use the value of PWD because it is much more efficient. */ - char t_string[PATH_MAX]; - int tlen; - - temp = get_string_value ("PWD"); - - if (temp == 0) - { - if (getcwd (t_string, sizeof(t_string)) == 0) - { - t_string[0] = '.'; - tlen = 1; - } - else - tlen = strlen (t_string); - } - else - { - tlen = sizeof (t_string) - 1; - strncpy (t_string, temp, tlen); - } - t_string[tlen] = '\0'; - -#if defined (MACOSX) - /* Convert from "fs" format to "input" format */ - temp = fnx_fromfs (t_string, strlen (t_string)); - if (temp != t_string) - strcpy (t_string, temp); -#endif - -#define ROOT_PATH(x) ((x)[0] == '/' && (x)[1] == 0) -#define DOUBLE_SLASH_ROOT(x) ((x)[0] == '/' && (x)[1] == '/' && (x)[2] == 0) - /* Abbreviate \W as ~ if $PWD == $HOME */ - if (c == 'W' && (((t = get_string_value ("HOME")) == 0) || STREQ (t, t_string) == 0)) - { - if (ROOT_PATH (t_string) == 0 && DOUBLE_SLASH_ROOT (t_string) == 0) - { - t = strrchr (t_string, '/'); - if (t) - memmove (t_string, t + 1, strlen (t)); /* strlen(t) to copy NULL */ - } - } -#undef ROOT_PATH -#undef DOUBLE_SLASH_ROOT - else - { - /* polite_directory_format is guaranteed to return a string - no longer than PATH_MAX - 1 characters. */ - temp = polite_directory_format (t_string); - if (temp != t_string) - strcpy (t_string, temp); - } - - temp = trim_pathname (t_string, PATH_MAX - 1); - /* If we're going to be expanding the prompt string later, - quote the directory name. */ - if (promptvars || posixly_correct) - /* Make sure that expand_prompt_string is called with a - second argument of Q_DOUBLE_QUOTES if we use this - function here. */ - { - char *t; - t = sh_strvis (t_string); - temp = sh_backslash_quote_for_double_quotes (t, 0); - free (t); - } - else - temp = sh_strvis (t_string); - - goto add_string; - } - - case 'u': - if (current_user.user_name == 0) - get_current_user_info (); - temp = savestring (current_user.user_name); - goto add_string; - - case 'h': - case 'H': - t_host = savestring (current_host_name); - if (c == 'h' && (t = (char *)strchr (t_host, '.'))) - *t = '\0'; - if (promptvars || posixly_correct) - /* Make sure that expand_prompt_string is called with a - second argument of Q_DOUBLE_QUOTES if we use this - function here. */ - temp = sh_backslash_quote_for_double_quotes (t_host, 0); - else - temp = savestring (t_host); - free (t_host); - goto add_string; - - case '#': - n = current_command_number; - /* If we have already incremented current_command_number (PS4, - ${var@P}), compensate */ - if (orig_string != ps0_prompt && orig_string != ps1_prompt && orig_string != ps2_prompt) - n--; - temp = itos (n); - goto add_string; - - case '!': -#if !defined (HISTORY) - temp = savestring ("1"); -#else /* HISTORY */ - temp = itos (prompt_history_number (orig_string)); -#endif /* HISTORY */ - goto add_string; - - case '$': - t = temp = (char *)xmalloc (3); - if ((promptvars || posixly_correct) && (current_user.euid != 0)) - *t++ = '\\'; - *t++ = current_user.euid == 0 ? '#' : '$'; - *t = '\0'; - goto add_string; - - case 'j': - temp = itos (count_all_jobs ()); - goto add_string; - - case 'l': -#if defined (HAVE_TTYNAME) - temp = (char *)ttyname (fileno (stdin)); - t = temp ? base_pathname (temp) : "tty"; - temp = savestring (t); -#else - temp = savestring ("tty"); -#endif /* !HAVE_TTYNAME */ - goto add_string; - -#if defined (READLINE) - case '[': - case ']': - if (no_line_editing) - { - string++; - break; - } - temp = (char *)xmalloc (3); - n = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE; - i = 0; - if (n == CTLESC || n == CTLNUL) - temp[i++] = CTLESC; - temp[i++] = n; - temp[i] = '\0'; - goto add_string; -#endif /* READLINE */ - - case '\\': - case 'a': - case 'e': - case 'r': - temp = (char *)xmalloc (2); - if (c == 'a') - temp[0] = '\07'; - else if (c == 'e') - temp[0] = '\033'; - else if (c == 'r') - temp[0] = '\r'; - else /* (c == '\\') */ - temp[0] = c; - temp[1] = '\0'; - goto add_string; - - default: -not_escape: - temp = (char *)xmalloc (3); - temp[0] = '\\'; - temp[1] = c; - temp[2] = '\0'; - - add_string: - if (c) - string++; - result = - sub_append_string (temp, result, &result_index, &result_size); - temp = (char *)NULL; /* Freed in sub_append_string (). */ - result[result_index] = '\0'; - break; - } - } - else - { - RESIZE_MALLOCED_BUFFER (result, result_index, 3, result_size, PROMPT_GROWTH); - /* dequote_string should take care of removing this if we are not - performing the rest of the word expansions. */ - if (c == CTLESC || c == CTLNUL) - result[result_index++] = CTLESC; - result[result_index++] = c; - result[result_index] = '\0'; - } - } -#else /* !PROMPT_STRING_DECODE */ - result = savestring (string); -#endif /* !PROMPT_STRING_DECODE */ - - /* Save the delimiter stack and point `dstack' to temp space so any - command substitutions in the prompt string won't result in screwing - up the parser's quoting state. */ - save_dstack = dstack; - dstack = temp_dstack; - dstack.delimiter_depth = 0; - - /* Perform variable and parameter expansion and command substitution on - the prompt string. */ - if (promptvars || posixly_correct) - { - last_exit_value = last_command_exit_value; - last_comsub_pid = last_command_subst_pid; - list = expand_prompt_string (result, Q_DOUBLE_QUOTES, 0); - free (result); - result = string_list (list); - dispose_words (list); - last_command_exit_value = last_exit_value; - last_command_subst_pid = last_comsub_pid; - } - else - { - t = dequote_string (result); - free (result); - result = t; - } - - dstack = save_dstack; - - return (result); -} - -/************************************************ - * * - * ERROR HANDLING * - * * - ************************************************/ - -/* Report a syntax error, and restart the parser. Call here for fatal - errors. */ -int -yyerror (msg) - const char *msg; -{ - if ((parser_state & PST_NOERROR) == 0) - report_syntax_error ((char *)NULL); - reset_parser (); - return (0); -} - -static char * -error_token_from_token (tok) - int tok; -{ - char *t; - - if (t = find_token_in_alist (tok, word_token_alist, 0)) - return t; - - if (t = find_token_in_alist (tok, other_token_alist, 0)) - return t; - - t = (char *)NULL; - /* This stuff is dicy and needs closer inspection */ - switch (current_token) - { - case WORD: - case ASSIGNMENT_WORD: - if (yylval.word) - t = savestring (yylval.word->word); - break; - case NUMBER: - t = itos (yylval.number); - break; - case ARITH_CMD: - if (yylval.word_list) - t = string_list (yylval.word_list); - break; - case ARITH_FOR_EXPRS: - if (yylval.word_list) - t = string_list_internal (yylval.word_list, " ; "); - break; - case COND_CMD: - t = (char *)NULL; /* punt */ - break; - } - - return t; -} - -static char * -error_token_from_text () -{ - char *msg, *t; - int token_end, i; - - t = shell_input_line; - i = shell_input_line_index; - token_end = 0; - msg = (char *)NULL; - - if (i && t[i] == '\0') - i--; - - while (i && (whitespace (t[i]) || t[i] == '\n')) - i--; - - if (i) - token_end = i + 1; - - while (i && (member (t[i], " \n\t;|&") == 0)) - i--; - - while (i != token_end && (whitespace (t[i]) || t[i] == '\n')) - i++; - - /* Return our idea of the offending token. */ - if (token_end || (i == 0 && token_end == 0)) - { - if (token_end) - msg = substring (t, i, token_end); - else /* one-character token */ - { - msg = (char *)xmalloc (2); - msg[0] = t[i]; - msg[1] = '\0'; - } - } - - return (msg); -} - -static void -print_offending_line () -{ - char *msg; - int token_end; - - msg = savestring (shell_input_line); - token_end = strlen (msg); - while (token_end && msg[token_end - 1] == '\n') - msg[--token_end] = '\0'; - - parser_error (line_number, "`%s'", msg); - free (msg); -} - -/* Report a syntax error with line numbers, etc. - Call here for recoverable errors. If you have a message to print, - then place it in MESSAGE, otherwise pass NULL and this will figure - out an appropriate message for you. */ -static void -report_syntax_error (message) - char *message; -{ - char *msg, *p; - - if (message) - { - parser_error (line_number, "%s", message); - if (interactive && EOF_Reached) - EOF_Reached = 0; - last_command_exit_value = (executing_builtin && parse_and_execute_level) ? EX_BADSYNTAX : EX_BADUSAGE; - set_pipestatus_from_exit (last_command_exit_value); - return; - } - - /* If the line of input we're reading is not null, try to find the - objectionable token. First, try to figure out what token the - parser's complaining about by looking at current_token. */ - if (current_token != 0 && EOF_Reached == 0 && (msg = error_token_from_token (current_token))) - { - if (ansic_shouldquote (msg)) - { - p = ansic_quote (msg, 0, NULL); - free (msg); - msg = p; - } - parser_error (line_number, _("syntax error near unexpected token `%s'"), msg); - free (msg); - - if (interactive == 0) - print_offending_line (); - - last_command_exit_value = (executing_builtin && parse_and_execute_level) ? EX_BADSYNTAX : EX_BADUSAGE; - set_pipestatus_from_exit (last_command_exit_value); - return; - } - - /* If looking at the current token doesn't prove fruitful, try to find the - offending token by analyzing the text of the input line near the current - input line index and report what we find. */ - if (shell_input_line && *shell_input_line) - { - msg = error_token_from_text (); - if (msg) - { - parser_error (line_number, _("syntax error near `%s'"), msg); - free (msg); - } - - /* If not interactive, print the line containing the error. */ - if (interactive == 0) - print_offending_line (); - } - else - { - if (EOF_Reached && shell_eof_token && current_token != shell_eof_token) - parser_error (line_number, _("unexpected EOF while looking for matching `%c'"), shell_eof_token); - else - { - msg = EOF_Reached ? _("syntax error: unexpected end of file") : _("syntax error"); - parser_error (line_number, "%s", msg); - } - - /* When the shell is interactive, this file uses EOF_Reached - only for error reporting. Other mechanisms are used to - decide whether or not to exit. */ - if (interactive && EOF_Reached) - EOF_Reached = 0; - } - - last_command_exit_value = (executing_builtin && parse_and_execute_level) ? EX_BADSYNTAX : EX_BADUSAGE; - set_pipestatus_from_exit (last_command_exit_value); -} - -/* ??? Needed function. ??? We have to be able to discard the constructs - created during parsing. In the case of error, we want to return - allocated objects to the memory pool. In the case of no error, we want - to throw away the information about where the allocated objects live. - (dispose_command () will actually free the command.) */ -static void -discard_parser_constructs (error_p) - int error_p; -{ -} - -/************************************************ - * * - * EOF HANDLING * - * * - ************************************************/ - -/* Do that silly `type "bye" to exit' stuff. You know, "ignoreeof". */ - -/* A flag denoting whether or not ignoreeof is set. */ -int ignoreeof = 0; - -/* The number of times that we have encountered an EOF character without - another character intervening. When this gets above the limit, the - shell terminates. */ -int eof_encountered = 0; - -/* The limit for eof_encountered. */ -int eof_encountered_limit = 10; - -/* If we have EOF as the only input unit, this user wants to leave - the shell. If the shell is not interactive, then just leave. - Otherwise, if ignoreeof is set, and we haven't done this the - required number of times in a row, print a message. */ -static void -handle_eof_input_unit () -{ - if (interactive) - { - /* shell.c may use this to decide whether or not to write out the - history, among other things. We use it only for error reporting - in this file. */ - if (EOF_Reached) - EOF_Reached = 0; - - /* If the user wants to "ignore" eof, then let her do so, kind of. */ - if (ignoreeof) - { - if (eof_encountered < eof_encountered_limit) - { - fprintf (stderr, _("Use \"%s\" to leave the shell.\n"), - login_shell ? "logout" : "exit"); - eof_encountered++; - /* Reset the parsing state. */ - last_read_token = current_token = '\n'; - /* Reset the prompt string to be $PS1. */ - prompt_string_pointer = (char **)NULL; - prompt_again (0); - return; - } - } - - /* In this case EOF should exit the shell. Do it now. */ - reset_parser (); - - last_shell_builtin = this_shell_builtin; - this_shell_builtin = exit_builtin; - exit_builtin ((WORD_LIST *)NULL); - } - else - { - /* We don't write history files, etc., for non-interactive shells. */ - EOF_Reached = 1; - } -} - -/************************************************ - * * - * STRING PARSING FUNCTIONS * - * * - ************************************************/ - -/* It's very important that these two functions treat the characters - between ( and ) identically. */ - -static WORD_LIST parse_string_error; - -/* Take a string and run it through the shell parser, returning the - resultant word list. Used by compound array assignment. */ -WORD_LIST * -parse_string_to_word_list (s, flags, whom) - char *s; - int flags; - const char *whom; -{ - WORD_LIST *wl; - int tok, orig_current_token, orig_line_number; - int orig_parser_state; - sh_parser_state_t ps; - int ea; - - orig_line_number = line_number; - save_parser_state (&ps); - -#if defined (HISTORY) - bash_history_disable (); -#endif - - push_stream (1); - if (ea = expanding_alias ()) - parser_save_alias (); - - /* WORD to avoid parsing reserved words as themselves and just parse them as - WORDs. */ - last_read_token = WORD; - - current_command_line_count = 0; - echo_input_at_read = expand_aliases = 0; - - with_input_from_string (s, whom); - wl = (WORD_LIST *)NULL; - - if (flags & 1) - { - orig_parser_state = parser_state; /* XXX - not needed? */ - /* State flags we don't want to persist into compound assignments. */ - parser_state &= ~PST_NOEXPAND; /* parse_comsub sentinel */ - /* State flags we want to set for this run through the tokenizer. */ - parser_state |= PST_COMPASSIGN|PST_REPARSE; - } - - while ((tok = read_token (READ)) != yacc_EOF) - { - if (tok == '\n' && *bash_input.location.string == '\0') - break; - if (tok == '\n') /* Allow newlines in compound assignments */ - continue; - if (tok != WORD && tok != ASSIGNMENT_WORD) - { - line_number = orig_line_number + line_number - 1; - orig_current_token = current_token; - current_token = tok; - yyerror (NULL); /* does the right thing */ - current_token = orig_current_token; - if (wl) - dispose_words (wl); - wl = &parse_string_error; - break; - } - wl = make_word_list (yylval.word, wl); - } - - last_read_token = '\n'; - pop_stream (); - - if (ea) - parser_restore_alias (); - - restore_parser_state (&ps); - - if (flags & 1) - parser_state = orig_parser_state; /* XXX - not needed? */ - - if (wl == &parse_string_error) - { - set_exit_status (EXECUTION_FAILURE); - if (interactive_shell == 0 && posixly_correct) - jump_to_top_level (FORCE_EOF); - else - jump_to_top_level (DISCARD); - } - - return (REVERSE_LIST (wl, WORD_LIST *)); -} - -static char * -parse_compound_assignment (retlenp) - int *retlenp; -{ - WORD_LIST *wl, *rl; - int tok, orig_line_number, assignok; - sh_parser_state_t ps; - char *ret; - - orig_line_number = line_number; - save_parser_state (&ps); - - /* WORD to avoid parsing reserved words as themselves and just parse them as - WORDs. Plus it means we won't be in a command position and so alias - expansion won't happen. */ - last_read_token = WORD; - - token = (char *)NULL; - token_buffer_size = 0; - wl = (WORD_LIST *)NULL; /* ( */ - - assignok = parser_state&PST_ASSIGNOK; /* XXX */ - - /* State flags we don't want to persist into compound assignments. */ - parser_state &= ~(PST_NOEXPAND|PST_CONDCMD|PST_CONDEXPR|PST_REGEXP|PST_EXTPAT); - /* State flags we want to set for this run through the tokenizer. */ - parser_state |= PST_COMPASSIGN; - - esacs_needed_count = expecting_in_token = 0; - - while ((tok = read_token (READ)) != ')') - { - if (tok == '\n') /* Allow newlines in compound assignments */ - { - if (SHOULD_PROMPT ()) - prompt_again (0); - continue; - } - if (tok != WORD && tok != ASSIGNMENT_WORD) - { - current_token = tok; /* for error reporting */ - if (tok == yacc_EOF) /* ( */ - parser_error (orig_line_number, _("unexpected EOF while looking for matching `)'")); - else - yyerror(NULL); /* does the right thing */ - if (wl) - dispose_words (wl); - wl = &parse_string_error; - break; - } - wl = make_word_list (yylval.word, wl); - } - - restore_parser_state (&ps); - - if (wl == &parse_string_error) - { - set_exit_status (EXECUTION_FAILURE); - last_read_token = '\n'; /* XXX */ - if (interactive_shell == 0 && posixly_correct) - jump_to_top_level (FORCE_EOF); - else - jump_to_top_level (DISCARD); - } - - if (wl) - { - rl = REVERSE_LIST (wl, WORD_LIST *); - ret = string_list (rl); - dispose_words (rl); - } - else - ret = (char *)NULL; - - if (retlenp) - *retlenp = (ret && *ret) ? strlen (ret) : 0; - - if (assignok) - parser_state |= PST_ASSIGNOK; - - return ret; -} - -/************************************************ - * * - * SAVING AND RESTORING PARTIAL PARSE STATE * - * * - ************************************************/ - -sh_parser_state_t * -save_parser_state (ps) - sh_parser_state_t *ps; -{ - if (ps == 0) - ps = (sh_parser_state_t *)xmalloc (sizeof (sh_parser_state_t)); - if (ps == 0) - return ((sh_parser_state_t *)NULL); - - ps->parser_state = parser_state; - ps->token_state = save_token_state (); - - ps->input_line_terminator = shell_input_line_terminator; - ps->eof_encountered = eof_encountered; - ps->eol_lookahead = eol_ungetc_lookahead; - - ps->prompt_string_pointer = prompt_string_pointer; - - ps->current_command_line_count = current_command_line_count; - -#if defined (HISTORY) - ps->remember_on_history = remember_on_history; -# if defined (BANG_HISTORY) - ps->history_expansion_inhibited = history_expansion_inhibited; -# endif -#endif - - ps->last_command_exit_value = last_command_exit_value; -#if defined (ARRAY_VARS) - ps->pipestatus = save_pipestatus_array (); -#endif - - ps->last_shell_builtin = last_shell_builtin; - ps->this_shell_builtin = this_shell_builtin; - - ps->expand_aliases = expand_aliases; - ps->echo_input_at_read = echo_input_at_read; - ps->need_here_doc = need_here_doc; - ps->here_doc_first_line = here_doc_first_line; - - ps->esacs_needed = esacs_needed_count; - ps->expecting_in = expecting_in_token; - - if (need_here_doc == 0) - ps->redir_stack[0] = 0; - else - memcpy (ps->redir_stack, redir_stack, sizeof (redir_stack[0]) * HEREDOC_MAX); - -#if defined (ALIAS) || defined (DPAREN_ARITHMETIC) - ps->pushed_strings = pushed_string_list; -#endif - - ps->eof_token = shell_eof_token; - ps->token = token; - ps->token_buffer_size = token_buffer_size; - /* Force reallocation on next call to read_token_word */ - token = 0; - token_buffer_size = 0; - - return (ps); -} - -void -restore_parser_state (ps) - sh_parser_state_t *ps; -{ - int i; - - if (ps == 0) - return; - - parser_state = ps->parser_state; - if (ps->token_state) - { - restore_token_state (ps->token_state); - free (ps->token_state); - } - - shell_input_line_terminator = ps->input_line_terminator; - eof_encountered = ps->eof_encountered; - eol_ungetc_lookahead = ps->eol_lookahead; - - prompt_string_pointer = ps->prompt_string_pointer; - - current_command_line_count = ps->current_command_line_count; - -#if defined (HISTORY) - remember_on_history = ps->remember_on_history; -# if defined (BANG_HISTORY) - history_expansion_inhibited = ps->history_expansion_inhibited; -# endif -#endif - - last_command_exit_value = ps->last_command_exit_value; -#if defined (ARRAY_VARS) - restore_pipestatus_array (ps->pipestatus); -#endif - - last_shell_builtin = ps->last_shell_builtin; - this_shell_builtin = ps->this_shell_builtin; - - expand_aliases = ps->expand_aliases; - echo_input_at_read = ps->echo_input_at_read; - need_here_doc = ps->need_here_doc; - here_doc_first_line = ps->here_doc_first_line; - - esacs_needed_count = ps->esacs_needed; - expecting_in_token = ps->expecting_in; - -#if 0 - for (i = 0; i < HEREDOC_MAX; i++) - redir_stack[i] = ps->redir_stack[i]; -#else - if (need_here_doc == 0) - redir_stack[0] = 0; - else - memcpy (redir_stack, ps->redir_stack, sizeof (redir_stack[0]) * HEREDOC_MAX); -#endif - -#if defined (ALIAS) || defined (DPAREN_ARITHMETIC) - pushed_string_list = (STRING_SAVER *)ps->pushed_strings; -#endif - - FREE (token); - token = ps->token; - token_buffer_size = ps->token_buffer_size; - shell_eof_token = ps->eof_token; -} - -sh_input_line_state_t * -save_input_line_state (ls) - sh_input_line_state_t *ls; -{ - if (ls == 0) - ls = (sh_input_line_state_t *)xmalloc (sizeof (sh_input_line_state_t)); - if (ls == 0) - return ((sh_input_line_state_t *)NULL); - - ls->input_line = shell_input_line; - ls->input_line_size = shell_input_line_size; - ls->input_line_len = shell_input_line_len; - ls->input_line_index = shell_input_line_index; - -#if defined (HANDLE_MULTIBYTE) - ls->input_property = shell_input_line_property; - ls->input_propsize = shell_input_line_propsize; -#endif - - /* force reallocation */ - shell_input_line = 0; - shell_input_line_size = shell_input_line_len = shell_input_line_index = 0; - -#if defined (HANDLE_MULTIBYTE) - shell_input_line_property = 0; - shell_input_line_propsize = 0; -#endif - - return ls; -} - -void -restore_input_line_state (ls) - sh_input_line_state_t *ls; -{ - FREE (shell_input_line); - shell_input_line = ls->input_line; - shell_input_line_size = ls->input_line_size; - shell_input_line_len = ls->input_line_len; - shell_input_line_index = ls->input_line_index; - -#if defined (HANDLE_MULTIBYTE) - FREE (shell_input_line_property); - shell_input_line_property = ls->input_property; - shell_input_line_propsize = ls->input_propsize; -#endif - -#if 0 - set_line_mbstate (); -#endif -} - -/************************************************ - * * - * MULTIBYTE CHARACTER HANDLING * - * * - ************************************************/ - -#if defined (HANDLE_MULTIBYTE) - -/* We don't let the property buffer get larger than this unless the line is */ -#define MAX_PROPSIZE 32768 - -static void -set_line_mbstate () -{ - int c; - size_t i, previ, len; - mbstate_t mbs, prevs; - size_t mbclen; - int ilen; - - if (shell_input_line == NULL) - return; - len = STRLEN (shell_input_line); /* XXX - shell_input_line_len ? */ - if (len == 0) - return; - if (shell_input_line_propsize >= MAX_PROPSIZE && len < MAX_PROPSIZE>>1) - { - free (shell_input_line_property); - shell_input_line_property = 0; - shell_input_line_propsize = 0; - } - if (len+1 > shell_input_line_propsize) - { - shell_input_line_propsize = len + 1; - shell_input_line_property = (char *)xrealloc (shell_input_line_property, shell_input_line_propsize); - } - - if (locale_mb_cur_max == 1) - { - memset (shell_input_line_property, 1, len); - return; - } - - /* XXX - use whether or not we are in a UTF-8 locale to avoid calls to - mbrlen */ - if (locale_utf8locale == 0) - memset (&prevs, '\0', sizeof (mbstate_t)); - - for (i = previ = 0; i < len; i++) - { - if (locale_utf8locale == 0) - mbs = prevs; - - c = shell_input_line[i]; - if (c == EOF) - { - size_t j; - for (j = i; j < len; j++) - shell_input_line_property[j] = 1; - break; - } - - if (locale_utf8locale) - { - if ((unsigned char)shell_input_line[previ] < 128) /* i != previ */ - mbclen = 1; - else - { - ilen = utf8_mblen (shell_input_line + previ, i - previ + 1); - mbclen = (ilen == -1) ? (size_t)-1 - : ((ilen == -2) ? (size_t)-2 : (size_t)ilen); - } - } - else - mbclen = mbrlen (shell_input_line + previ, i - previ + 1, &mbs); - - if (mbclen == 1 || mbclen == (size_t)-1) - { - mbclen = 1; - previ = i + 1; - } - else if (mbclen == (size_t)-2) - mbclen = 0; - else if (mbclen > 1) - { - mbclen = 0; - previ = i + 1; - if (locale_utf8locale == 0) - prevs = mbs; - } - else - { - size_t j; - for (j = i; j < len; j++) - shell_input_line_property[j] = 1; - break; - } - - shell_input_line_property[i] = mbclen; - } -} -#endif /* HANDLE_MULTIBYTE */ diff --git a/third_party/bash/y.tab.h b/third_party/bash/y.tab.h deleted file mode 100644 index 3f3010777..000000000 --- a/third_party/bash/y.tab.h +++ /dev/null @@ -1,191 +0,0 @@ -/* A Bison parser, made by GNU Bison 3.8.2. */ - -/* Bison interface for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, - Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, - especially those whose name start with YY_ or yy_. They are - private implementation details that can be changed or removed. */ - -#ifndef YY_YY_Y_TAB_H_INCLUDED -# define YY_YY_Y_TAB_H_INCLUDED -/* Debug traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif -#if YYDEBUG -extern int yydebug; -#endif - -/* Token kinds. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - enum yytokentype - { - YYEMPTY = -2, - YYEOF = 0, /* "end of file" */ - YYerror = 256, /* error */ - YYUNDEF = 257, /* "invalid token" */ - IF = 258, /* IF */ - THEN = 259, /* THEN */ - ELSE = 260, /* ELSE */ - ELIF = 261, /* ELIF */ - FI = 262, /* FI */ - CASE = 263, /* CASE */ - ESAC = 264, /* ESAC */ - FOR = 265, /* FOR */ - SELECT = 266, /* SELECT */ - WHILE = 267, /* WHILE */ - UNTIL = 268, /* UNTIL */ - DO = 269, /* DO */ - DONE = 270, /* DONE */ - FUNCTION = 271, /* FUNCTION */ - COPROC = 272, /* COPROC */ - COND_START = 273, /* COND_START */ - COND_END = 274, /* COND_END */ - COND_ERROR = 275, /* COND_ERROR */ - IN = 276, /* IN */ - BANG = 277, /* BANG */ - TIME = 278, /* TIME */ - TIMEOPT = 279, /* TIMEOPT */ - TIMEIGN = 280, /* TIMEIGN */ - WORD = 281, /* WORD */ - ASSIGNMENT_WORD = 282, /* ASSIGNMENT_WORD */ - REDIR_WORD = 283, /* REDIR_WORD */ - NUMBER = 284, /* NUMBER */ - ARITH_CMD = 285, /* ARITH_CMD */ - ARITH_FOR_EXPRS = 286, /* ARITH_FOR_EXPRS */ - COND_CMD = 287, /* COND_CMD */ - AND_AND = 288, /* AND_AND */ - OR_OR = 289, /* OR_OR */ - GREATER_GREATER = 290, /* GREATER_GREATER */ - LESS_LESS = 291, /* LESS_LESS */ - LESS_AND = 292, /* LESS_AND */ - LESS_LESS_LESS = 293, /* LESS_LESS_LESS */ - GREATER_AND = 294, /* GREATER_AND */ - SEMI_SEMI = 295, /* SEMI_SEMI */ - SEMI_AND = 296, /* SEMI_AND */ - SEMI_SEMI_AND = 297, /* SEMI_SEMI_AND */ - LESS_LESS_MINUS = 298, /* LESS_LESS_MINUS */ - AND_GREATER = 299, /* AND_GREATER */ - AND_GREATER_GREATER = 300, /* AND_GREATER_GREATER */ - LESS_GREATER = 301, /* LESS_GREATER */ - GREATER_BAR = 302, /* GREATER_BAR */ - BAR_AND = 303, /* BAR_AND */ - DOLPAREN = 304, /* DOLPAREN */ - yacc_EOF = 305 /* yacc_EOF */ - }; - typedef enum yytokentype yytoken_kind_t; -#endif -/* Token kinds. */ -#define YYEMPTY -2 -#define YYEOF 0 -#define YYerror 256 -#define YYUNDEF 257 -#define IF 258 -#define THEN 259 -#define ELSE 260 -#define ELIF 261 -#define FI 262 -#define CASE 263 -#define ESAC 264 -#define FOR 265 -#define SELECT 266 -#define WHILE 267 -#define UNTIL 268 -#define DO 269 -#define DONE 270 -#define FUNCTION 271 -#define COPROC 272 -#define COND_START 273 -#define COND_END 274 -#define COND_ERROR 275 -#define IN 276 -#define BANG 277 -#define TIME 278 -#define TIMEOPT 279 -#define TIMEIGN 280 -#define WORD 281 -#define ASSIGNMENT_WORD 282 -#define REDIR_WORD 283 -#define NUMBER 284 -#define ARITH_CMD 285 -#define ARITH_FOR_EXPRS 286 -#define COND_CMD 287 -#define AND_AND 288 -#define OR_OR 289 -#define GREATER_GREATER 290 -#define LESS_LESS 291 -#define LESS_AND 292 -#define LESS_LESS_LESS 293 -#define GREATER_AND 294 -#define SEMI_SEMI 295 -#define SEMI_AND 296 -#define SEMI_SEMI_AND 297 -#define LESS_LESS_MINUS 298 -#define AND_GREATER 299 -#define AND_GREATER_GREATER 300 -#define LESS_GREATER 301 -#define GREATER_BAR 302 -#define BAR_AND 303 -#define DOLPAREN 304 -#define yacc_EOF 305 - -/* Value type. */ -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -union YYSTYPE -{ -#line 338 "/usr/local/src/chet/src/bash/src/parse.y" - - WORD_DESC *word; /* the word that we read. */ - int number; /* the number that we read. */ - WORD_LIST *word_list; - COMMAND *command; - REDIRECT *redirect; - ELEMENT element; - PATTERN_LIST *pattern; - -#line 177 "y.tab.h" - -}; -typedef union YYSTYPE YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define YYSTYPE_IS_DECLARED 1 -#endif - - -extern YYSTYPE yylval; - - -int yyparse (void); - - -#endif /* !YY_YY_Y_TAB_H_INCLUDED */ diff --git a/third_party/bash/zcatfd.c b/third_party/bash/zcatfd.c deleted file mode 100644 index b172c1aa5..000000000 --- a/third_party/bash/zcatfd.c +++ /dev/null @@ -1,74 +0,0 @@ -/* zcatfd - copy contents of file descriptor to another */ - -/* Copyright (C) 2002-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include - -#include "stdc.h" - -#if !defined (errno) -extern int errno; -#endif - -#ifndef ZBUFSIZ -# define ZBUFSIZ 4096 -#endif - -extern ssize_t zread PARAMS((int, char *, size_t)); -extern int zwrite PARAMS((int, char *, ssize_t)); - -/* Dump contents of file descriptor FD to OFD. FN is the filename for - error messages (not used right now). */ -int -zcatfd (fd, ofd, fn) - int fd, ofd; - char *fn; -{ - ssize_t nr; - int rval; - char lbuf[ZBUFSIZ]; - - rval = 0; - while (1) - { - nr = zread (fd, lbuf, sizeof (lbuf)); - if (nr == 0) - break; - else if (nr < 0) - { - rval = -1; - break; - } - else if (zwrite (ofd, lbuf, nr) < 0) - { - rval = -1; - break; - } - } - - return rval; -} diff --git a/third_party/bash/zgetline.c b/third_party/bash/zgetline.c deleted file mode 100644 index 2b4801fc6..000000000 --- a/third_party/bash/zgetline.c +++ /dev/null @@ -1,126 +0,0 @@ -/* zgetline - read a line of input from a specified file descriptor and return - a pointer to a newly-allocated buffer containing the data. */ - -/* Copyright (C) 2008-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include -#include "xmalloc.h" - -#if !defined (errno) -extern int errno; -#endif - -extern ssize_t zread PARAMS((int, char *, size_t)); -extern ssize_t zreadc PARAMS((int, char *)); -extern ssize_t zreadintr PARAMS((int, char *, size_t)); -extern ssize_t zreadcintr PARAMS((int, char *)); - -typedef ssize_t breadfunc_t PARAMS((int, char *, size_t)); -typedef ssize_t creadfunc_t PARAMS((int, char *)); - -/* Initial memory allocation for automatic growing buffer in zreadlinec */ -#define GET_LINE_INITIAL_ALLOCATION 16 - -/* Derived from GNU libc's getline. - The behavior is almost the same as getline. See man getline. - The differences are - (1) using file descriptor instead of FILE *; - (2) the order of arguments: the file descriptor comes first; - (3) the addition of a fourth argument, DELIM; sets the delimiter to - be something other than newline if desired. If setting DELIM, - the next argument should be 1; and - (4) the addition of a fifth argument, UNBUFFERED_READ; this argument - controls whether get_line uses buffering or not to get a byte data - from FD. get_line uses zreadc if UNBUFFERED_READ is zero; and - uses zread if UNBUFFERED_READ is non-zero. - - Returns number of bytes read or -1 on error. */ - -ssize_t -zgetline (fd, lineptr, n, delim, unbuffered_read) - int fd; - char **lineptr; - size_t *n; - int delim; - int unbuffered_read; -{ - int retval; - size_t nr; - char *line, c; - - if (lineptr == 0 || n == 0 || (*lineptr == 0 && *n != 0)) - return -1; - - nr = 0; - line = *lineptr; - - while (1) - { - retval = unbuffered_read ? zread (fd, &c, 1) : zreadc(fd, &c); - - if (retval <= 0) - { - if (line && nr > 0) - line[nr] = '\0'; - break; - } - - if (nr + 2 >= *n) - { - size_t new_size; - - new_size = (*n == 0) ? GET_LINE_INITIAL_ALLOCATION : *n * 2; - line = (*n >= new_size) ? NULL : xrealloc (*lineptr, new_size); - - if (line) - { - *lineptr = line; - *n = new_size; - } - else - { - if (*n > 0) - { - (*lineptr)[*n - 1] = '\0'; - nr = *n - 2; - } - break; - } - } - - line[nr] = c; - nr++; - - if (c == delim) - { - line[nr] = '\0'; - break; - } - } - - return nr - 1; -} diff --git a/third_party/bash/zmapfd.c b/third_party/bash/zmapfd.c deleted file mode 100644 index 19a861a62..000000000 --- a/third_party/bash/zmapfd.c +++ /dev/null @@ -1,93 +0,0 @@ -/* zmapfd - read contents of file descriptor into a newly-allocated buffer */ - -/* Copyright (C) 2006-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include - -#include "bashansi.h" -#include "command.h" -#include "general.h" - -#if !defined (errno) -extern int errno; -#endif - -#ifndef ZBUFSIZ -# define ZBUFSIZ 4096 -#endif - -extern ssize_t zread PARAMS((int, char *, size_t)); - -/* Dump contents of file descriptor FD to *OSTR. FN is the filename for - error messages (not used right now). */ -int -zmapfd (fd, ostr, fn) - int fd; - char **ostr; - char *fn; -{ - ssize_t nr; - int rval; - char lbuf[ZBUFSIZ]; - char *result; - size_t rsize, rind; - - rval = 0; - result = (char *)xmalloc (rsize = ZBUFSIZ); - rind = 0; - - while (1) - { - nr = zread (fd, lbuf, sizeof (lbuf)); - if (nr == 0) - { - rval = rind; - break; - } - else if (nr < 0) - { - free (result); - if (ostr) - *ostr = (char *)NULL; - return -1; - } - - RESIZE_MALLOCED_BUFFER (result, rind, nr, rsize, ZBUFSIZ); - memcpy (result+rind, lbuf, nr); - rind += nr; - } - - RESIZE_MALLOCED_BUFFER (result, rind, 1, rsize, 128); - result[rind] = '\0'; - - if (ostr) - *ostr = result; - else - free (result); - - return rval; -} diff --git a/third_party/bash/zread.c b/third_party/bash/zread.c deleted file mode 100644 index ea38f6690..000000000 --- a/third_party/bash/zread.c +++ /dev/null @@ -1,228 +0,0 @@ -/* zread - read data from file descriptor into buffer with retries */ - -/* Copyright (C) 1999-2020 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include -#include - -#if !defined (errno) -extern int errno; -#endif - -#ifndef SEEK_CUR -# define SEEK_CUR 1 -#endif - -#ifndef ZBUFSIZ -# define ZBUFSIZ 4096 -#endif - -extern int executing_builtin; - -extern void check_signals_and_traps (void); -extern void check_signals (void); -extern int signal_is_trapped (int); -extern int read_builtin_timeout (int); - -/* Read LEN bytes from FD into BUF. Retry the read on EINTR. Any other - error causes the loop to break. */ -ssize_t -zread (fd, buf, len) - int fd; - char *buf; - size_t len; -{ - ssize_t r; - - check_signals (); /* check for signals before a blocking read */ - /* should generalize into a mechanism where different parts of the shell can - `register' timeouts and have them checked here. */ - while (((r = read_builtin_timeout (fd)) < 0 || (r = read (fd, buf, len)) < 0) && - errno == EINTR) - { - int t; - t = errno; - /* XXX - bash-5.0 */ - /* We check executing_builtin and run traps here for backwards compatibility */ - if (executing_builtin) - check_signals_and_traps (); /* XXX - should it be check_signals()? */ - else - check_signals (); - errno = t; - } - - return r; -} - -/* Read LEN bytes from FD into BUF. Retry the read on EINTR, up to three - interrupts. Any other error causes the loop to break. */ - -#ifdef NUM_INTR -# undef NUM_INTR -#endif -#define NUM_INTR 3 - -ssize_t -zreadretry (fd, buf, len) - int fd; - char *buf; - size_t len; -{ - ssize_t r; - int nintr; - - for (nintr = 0; ; ) - { - r = read (fd, buf, len); - if (r >= 0) - return r; - if (r == -1 && errno == EINTR) - { - if (++nintr >= NUM_INTR) - return -1; - continue; - } - return r; - } -} - -/* Call read(2) and allow it to be interrupted. Just a stub for now. */ -ssize_t -zreadintr (fd, buf, len) - int fd; - char *buf; - size_t len; -{ - check_signals (); - return (read (fd, buf, len)); -} - -/* Read one character from FD and return it in CP. Return values are as - in read(2). This does some local buffering to avoid many one-character - calls to read(2), like those the `read' builtin performs. */ - -static char lbuf[ZBUFSIZ]; -static size_t lind, lused; - -ssize_t -zreadc (fd, cp) - int fd; - char *cp; -{ - ssize_t nr; - - if (lind == lused || lused == 0) - { - nr = zread (fd, lbuf, sizeof (lbuf)); - lind = 0; - if (nr <= 0) - { - lused = 0; - return nr; - } - lused = nr; - } - if (cp) - *cp = lbuf[lind++]; - return 1; -} - -/* Don't mix calls to zreadc and zreadcintr in the same function, since they - use the same local buffer. */ -ssize_t -zreadcintr (fd, cp) - int fd; - char *cp; -{ - ssize_t nr; - - if (lind == lused || lused == 0) - { - nr = zreadintr (fd, lbuf, sizeof (lbuf)); - lind = 0; - if (nr <= 0) - { - lused = 0; - return nr; - } - lused = nr; - } - if (cp) - *cp = lbuf[lind++]; - return 1; -} - -/* Like zreadc, but read a specified number of characters at a time. Used - for `read -N'. */ -ssize_t -zreadn (fd, cp, len) - int fd; - char *cp; - size_t len; -{ - ssize_t nr; - - if (lind == lused || lused == 0) - { - if (len > sizeof (lbuf)) - len = sizeof (lbuf); - nr = zread (fd, lbuf, len); - lind = 0; - if (nr <= 0) - { - lused = 0; - return nr; - } - lused = nr; - } - if (cp) - *cp = lbuf[lind++]; - return 1; -} - -void -zreset () -{ - lind = lused = 0; -} - -/* Sync the seek pointer for FD so that the kernel's idea of the last char - read is the last char returned by zreadc. */ -void -zsyncfd (fd) - int fd; -{ - off_t off, r; - - off = lused - lind; - r = 0; - if (off > 0) - r = lseek (fd, -off, SEEK_CUR); - - if (r != -1) - lused = lind = 0; -} diff --git a/third_party/bash/zwrite.c b/third_party/bash/zwrite.c deleted file mode 100644 index db04750d7..000000000 --- a/third_party/bash/zwrite.c +++ /dev/null @@ -1,64 +0,0 @@ -/* zwrite - write contents of buffer to file descriptor, retrying on error */ - -/* Copyright (C) 1999-2002 Free Software Foundation, Inc. - - This file is part of GNU Bash, the Bourne Again SHell. - - Bash is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Bash is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Bash. If not, see . -*/ - -#include "config.h" - -#include - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#include - -#if !defined (errno) -extern int errno; -#endif - -/* Write NB bytes from BUF to file descriptor FD, retrying the write if - it is interrupted. We retry three times if we get a zero-length - write. Any other signal causes this function to return prematurely. */ -int -zwrite (fd, buf, nb) - int fd; - char *buf; - size_t nb; -{ - int n, i, nt; - - for (n = nb, nt = 0;;) - { - i = write (fd, buf, n); - if (i > 0) - { - n -= i; - if (n <= 0) - return nb; - buf += i; - } - else if (i == 0) - { - if (++nt > 3) - return (nb - n); - } - else if (errno != EINTR) - return -1; - } -} diff --git a/third_party/bzip2/bzip2.c b/third_party/bzip2/bzip2.c index d91483807..43d570ea1 100644 --- a/third_party/bzip2/bzip2.c +++ b/third_party/bzip2/bzip2.c @@ -14,6 +14,7 @@ #include "libc/sysv/consts/sig.h" #include "libc/utime.h" #include "libc/time.h" +#include "libc/ctype.h" #include "third_party/bzip2/bzlib.h" /*-----------------------------------------------------------*/ diff --git a/third_party/intel/amxcomplexintrin.internal.h b/third_party/intel/amxcomplexintrin.internal.h new file mode 100644 index 000000000..72f8bd383 --- /dev/null +++ b/third_party/intel/amxcomplexintrin.internal.h @@ -0,0 +1,23 @@ +#if defined(__x86_64__) && !(__ASSEMBLER__ + __LINKER__ + 0) +#if !defined _IMMINTRIN_H_INCLUDED +#error "Never use directly; include instead." +#endif +#ifndef _AMXCOMPLEXINTRIN_H_INCLUDED +#define _AMXCOMPLEXINTRIN_H_INCLUDED +#if !defined(__AMX_COMPLEX__) +#pragma GCC push_options +#pragma GCC target("amx-complex") +#define __DISABLE_AMX_COMPLEX__ +#endif +#if defined(__x86_64__) +#define _tile_cmmimfp16ps_internal(src1_dst,src2,src3) __asm__ volatile ("{tcmmimfp16ps\t%%tmm"#src3", %%tmm"#src2", %%tmm"#src1_dst"|tcmmimfp16ps\t%%tmm"#src1_dst", %%tmm"#src2", %%tmm"#src3"}" ::) +#define _tile_cmmrlfp16ps_internal(src1_dst,src2,src3) __asm__ volatile ("{tcmmrlfp16ps\t%%tmm"#src3", %%tmm"#src2", %%tmm"#src1_dst"|tcmmrlfp16ps\t%%tmm"#src1_dst", %%tmm"#src2", %%tmm"#src3"}" ::) +#define _tile_cmmimfp16ps(src1_dst,src2,src3) _tile_cmmimfp16ps_internal (src1_dst, src2, src3) +#define _tile_cmmrlfp16ps(src1_dst,src2,src3) _tile_cmmrlfp16ps_internal (src1_dst, src2, src3) +#endif +#ifdef __DISABLE_AMX_COMPLEX__ +#undef __DISABLE_AMX_COMPLEX__ +#pragma GCC pop_options +#endif +#endif +#endif diff --git a/third_party/intel/amxfp16intrin.internal.h b/third_party/intel/amxfp16intrin.internal.h new file mode 100644 index 000000000..b9c3dfb51 --- /dev/null +++ b/third_party/intel/amxfp16intrin.internal.h @@ -0,0 +1,16 @@ +#if defined(__x86_64__) && !(__ASSEMBLER__ + __LINKER__ + 0) +#if !defined _IMMINTRIN_H_INCLUDED +#error "Never use directly; include instead." +#endif +#ifndef _AMXFP16INTRIN_H_INCLUDED +#define _AMXFP16INTRIN_H_INCLUDED +#if defined(__x86_64__) +#define _tile_dpfp16ps_internal(dst,src1,src2) __asm__ volatile ("{tdpfp16ps\t%%tmm"#src2", %%tmm"#src1", %%tmm"#dst"|tdpfp16ps\t%%tmm"#dst", %%tmm"#src1", %%tmm"#src2"}" ::) +#define _tile_dpfp16ps(dst,src1,src2) _tile_dpfp16ps_internal (dst,src1,src2) +#endif +#ifdef __DISABLE_AMX_FP16__ +#undef __DISABLE_AMX_FP16__ +#pragma GCC pop_options +#endif +#endif +#endif diff --git a/third_party/intel/amxtileintrin.internal.h b/third_party/intel/amxtileintrin.internal.h index 00e403118..37b49d3a2 100644 --- a/third_party/intel/amxtileintrin.internal.h +++ b/third_party/intel/amxtileintrin.internal.h @@ -14,13 +14,13 @@ extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _tile_loadconfig (const void *__config) { - __asm__ volatile ("ldtilecfg\t%X0" :: "m" (*((const void **)__config))); + __builtin_ia32_ldtilecfg (__config); } extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _tile_storeconfig (void *__config) { - __asm__ volatile ("sttilecfg\t%X0" : "=m" (*((void **)__config))); + __builtin_ia32_sttilecfg (__config); } extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -29,11 +29,11 @@ _tile_release (void) __asm__ volatile ("tilerelease" ::); } #define _tile_loadd(dst,base,stride) _tile_loadd_internal (dst, base, stride) -#define _tile_loadd_internal(dst,base,stride) __asm__ volatile ("{tileloadd\t(%0,%1,1), %%tmm"#dst"|tileloadd\t%%tmm"#dst", [%0+%1*1]}" :: "r" ((const void*) (base)), "r" ((long) (stride))) +#define _tile_loadd_internal(dst,base,stride) __asm__ volatile ("{tileloadd\t(%0,%1,1), %%tmm"#dst"|tileloadd\t%%tmm"#dst", [%0+%1*1]}" :: "r" ((const void*) (base)), "r" ((__PTRDIFF_TYPE__) (stride))) #define _tile_stream_loadd(dst,base,stride) _tile_stream_loadd_internal (dst, base, stride) -#define _tile_stream_loadd_internal(dst,base,stride) __asm__ volatile ("{tileloaddt1\t(%0,%1,1), %%tmm"#dst"|tileloaddt1\t%%tmm"#dst", [%0+%1*1]}" :: "r" ((const void*) (base)), "r" ((long) (stride))) +#define _tile_stream_loadd_internal(dst,base,stride) __asm__ volatile ("{tileloaddt1\t(%0,%1,1), %%tmm"#dst"|tileloaddt1\t%%tmm"#dst", [%0+%1*1]}" :: "r" ((const void*) (base)), "r" ((__PTRDIFF_TYPE__) (stride))) #define _tile_stored(dst,base,stride) _tile_stored_internal (dst, base, stride) -#define _tile_stored_internal(src,base,stride) __asm__ volatile ("{tilestored\t%%tmm"#src", (%0,%1,1)|tilestored\t[%0+%1*1], %%tmm"#src"}" :: "r" ((void*) (base)), "r" ((long) (stride)) : "memory") +#define _tile_stored_internal(src,base,stride) __asm__ volatile ("{tilestored\t%%tmm"#src", (%0,%1,1)|tilestored\t[%0+%1*1], %%tmm"#src"}" :: "r" ((void*) (base)), "r" ((__PTRDIFF_TYPE__) (stride)) : "memory") #define _tile_zero(dst) _tile_zero_internal (dst) #define _tile_zero_internal(dst) __asm__ volatile ("tilezero\t%%tmm"#dst ::) #endif diff --git a/third_party/intel/avx2intrin.internal.h b/third_party/intel/avx2intrin.internal.h index e323cf2fd..e84ddfcda 100644 --- a/third_party/intel/avx2intrin.internal.h +++ b/third_party/intel/avx2intrin.internal.h @@ -1443,6 +1443,206 @@ _mm256_mask_i64gather_epi32 (__m128i __src, int const *__base, #define _mm256_i64gather_epi32(BASE, INDEX, SCALE) (__m128i) __builtin_ia32_gatherdiv4si256 ((__v4si) _mm_setzero_si128 (), (int const *) (BASE), (__v4di)(__m256i) (INDEX), (__v4si)_mm_set1_epi32(-1), (int) (SCALE)) #define _mm256_mask_i64gather_epi32(SRC, BASE, INDEX, MASK, SCALE) (__m128i) __builtin_ia32_gatherdiv4si256 ((__v4si)(__m128i) (SRC), (int const *) (BASE), (__v4di)(__m256i) (INDEX), (__v4si)(__m128i) (MASK), (int) (SCALE)) #endif +#define _MM_REDUCE_OPERATOR_BASIC_EPI16(op) __v8hi __T1 = (__v8hi)__W; __v8hi __T2 = __builtin_shufflevector (__T1, __T1, 4, 5, 6, 7, 4, 5, 6, 7); __v8hi __T3 = __T1 op __T2; __v8hi __T4 = __builtin_shufflevector (__T3, __T3, 2, 3, 2, 3, 4, 5, 6, 7); __v8hi __T5 = __T3 op __T4; __v8hi __T6 = __builtin_shufflevector (__T5, __T5, 1, 1, 2, 3, 4, 5, 6, 7); __v8hi __T7 = __T5 op __T6; return __T7[0] +extern __inline short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_reduce_add_epi16 (__m128i __W) +{ + _MM_REDUCE_OPERATOR_BASIC_EPI16 (+); +} +extern __inline short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_reduce_mul_epi16 (__m128i __W) +{ + _MM_REDUCE_OPERATOR_BASIC_EPI16 (*); +} +extern __inline short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_reduce_and_epi16 (__m128i __W) +{ + _MM_REDUCE_OPERATOR_BASIC_EPI16 (&); +} +extern __inline short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_reduce_or_epi16 (__m128i __W) +{ + _MM_REDUCE_OPERATOR_BASIC_EPI16 (|); +} +#define _MM_REDUCE_OPERATOR_MAX_MIN_EP16(op) __m128i __T1 = (__m128i)__builtin_shufflevector ((__v8hi)__V, (__v8hi)__V, 4, 5, 6, 7, 4, 5, 6, 7); __m128i __T2 = _mm_##op (__V, __T1); __m128i __T3 = (__m128i)__builtin_shufflevector ((__v8hi)__T2, (__v8hi)__T2, 2, 3, 2, 3, 4, 5, 6, 7); __m128i __T4 = _mm_##op (__T2, __T3); __m128i __T5 = (__m128i)__builtin_shufflevector ((__v8hi)__T4, (__v8hi)__T4, 1, 1, 2, 3, 4, 5, 6, 7); __v8hi __T6 = (__v8hi)_mm_##op (__T4, __T5); return __T6[0] +extern __inline short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_reduce_max_epi16 (__m128i __V) +{ + _MM_REDUCE_OPERATOR_MAX_MIN_EP16 (max_epi16); +} +extern __inline unsigned short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_reduce_max_epu16 (__m128i __V) +{ + _MM_REDUCE_OPERATOR_MAX_MIN_EP16 (max_epu16); +} +extern __inline short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_reduce_min_epi16 (__m128i __V) +{ + _MM_REDUCE_OPERATOR_MAX_MIN_EP16 (min_epi16); +} +extern __inline unsigned short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_reduce_min_epu16 (__m128i __V) +{ + _MM_REDUCE_OPERATOR_MAX_MIN_EP16 (min_epu16); +} +#define _MM256_REDUCE_OPERATOR_BASIC_EPI16(op) __v8hi __T1 = (__v8hi)_mm256_extracti128_si256 (__W, 0); __v8hi __T2 = (__v8hi)_mm256_extracti128_si256 (__W, 1); __v8hi __T3 = __T1 op __T2; __v8hi __T4 = __builtin_shufflevector (__T3, __T3, 4, 5, 6, 7, 4, 5, 6, 7); __v8hi __T5 = __T3 op __T4; __v8hi __T6 = __builtin_shufflevector (__T5, __T5, 2, 3, 2, 3, 4, 5, 6, 7); __v8hi __T7 = __T5 op __T6; __v8hi __T8 = __builtin_shufflevector (__T7, __T7, 1, 1, 2, 3, 4, 5, 6, 7); __v8hi __T9 = __T7 op __T8; return __T9[0] +extern __inline short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_reduce_add_epi16 (__m256i __W) +{ + _MM256_REDUCE_OPERATOR_BASIC_EPI16 (+); +} +extern __inline short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_reduce_mul_epi16 (__m256i __W) +{ + _MM256_REDUCE_OPERATOR_BASIC_EPI16 (*); +} +extern __inline short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_reduce_and_epi16 (__m256i __W) +{ + _MM256_REDUCE_OPERATOR_BASIC_EPI16 (&); +} +extern __inline short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_reduce_or_epi16 (__m256i __W) +{ + _MM256_REDUCE_OPERATOR_BASIC_EPI16 (|); +} +#define _MM256_REDUCE_OPERATOR_MAX_MIN_EP16(op) __m128i __T1 = _mm256_extracti128_si256 (__V, 0); __m128i __T2 = _mm256_extracti128_si256 (__V, 1); __m128i __T3 = _mm_##op (__T1, __T2); __m128i __T4 = (__m128i)__builtin_shufflevector ((__v8hi)__T3, (__v8hi)__T3, 4, 5, 6, 7, 4, 5, 6, 7); __m128i __T5 = _mm_##op (__T3, __T4); __m128i __T6 = (__m128i)__builtin_shufflevector ((__v8hi)__T5, (__v8hi)__T5, 2, 3, 2, 3, 4, 5, 6, 7); __m128i __T7 = _mm_##op (__T5, __T6); __m128i __T8 = (__m128i)__builtin_shufflevector ((__v8hi)__T7, (__v8hi)__T7, 1, 1, 2, 3, 4, 5, 6, 7); __v8hi __T9 = (__v8hi)_mm_##op (__T7, __T8); return __T9[0] +extern __inline short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_reduce_max_epi16 (__m256i __V) +{ + _MM256_REDUCE_OPERATOR_MAX_MIN_EP16 (max_epi16); +} +extern __inline unsigned short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_reduce_max_epu16 (__m256i __V) +{ + _MM256_REDUCE_OPERATOR_MAX_MIN_EP16 (max_epu16); +} +extern __inline short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_reduce_min_epi16 (__m256i __V) +{ + _MM256_REDUCE_OPERATOR_MAX_MIN_EP16 (min_epi16); +} +extern __inline unsigned short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_reduce_min_epu16 (__m256i __V) +{ + _MM256_REDUCE_OPERATOR_MAX_MIN_EP16 (min_epu16); +} +#define _MM_REDUCE_OPERATOR_BASIC_EPI8(op) __v16qi __T1 = (__v16qi)__W; __v16qi __T2 = __builtin_shufflevector (__T1, __T1, 8, 9, 10, 11, 12, 13, 14, 15, 8, 9, 10, 11, 12, 13, 14, 15); __v16qi __T3 = __T1 op __T2; __v16qi __T4 = __builtin_shufflevector (__T3, __T3, 4, 5, 6, 7, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); __v16qi __T5 = __T3 op __T4; __v16qi __T6 = __builtin_shufflevector (__T5, __T5, 2, 3, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); __v16qi __T7 = __T5 op __T6; __v16qi __T8 = __builtin_shufflevector (__T7, __T7, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); __v16qi __T9 = __T7 op __T8; return __T9[0] +extern __inline char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_reduce_add_epi8 (__m128i __W) +{ + _MM_REDUCE_OPERATOR_BASIC_EPI8 (+); +} +extern __inline char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_reduce_mul_epi8 (__m128i __W) +{ + _MM_REDUCE_OPERATOR_BASIC_EPI8 (*); +} +extern __inline char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_reduce_and_epi8 (__m128i __W) +{ + _MM_REDUCE_OPERATOR_BASIC_EPI8 (&); +} +extern __inline char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_reduce_or_epi8 (__m128i __W) +{ + _MM_REDUCE_OPERATOR_BASIC_EPI8 (|); +} +#define _MM_REDUCE_OPERATOR_MAX_MIN_EP8(op) __m128i __T1 = (__m128i)__builtin_shufflevector ((__v16qi)__V, (__v16qi)__V, 8, 9, 10, 11, 12, 13, 14, 15, 8, 9, 10, 11, 12, 13, 14, 15); __m128i __T2 = _mm_##op (__V, __T1); __m128i __T3 = (__m128i)__builtin_shufflevector ((__v16qi)__T2, (__v16qi)__T2, 4, 5, 6, 7, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); __m128i __T4 = _mm_##op (__T2, __T3); __m128i __T5 = (__m128i)__builtin_shufflevector ((__v16qi)__T4, (__v16qi)__T4, 2, 3, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); __m128i __T6 = _mm_##op (__T4, __T5); __m128i __T7 = (__m128i)__builtin_shufflevector ((__v16qi)__T6, (__v16qi)__T6, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); __v16qi __T8 = (__v16qi)_mm_##op (__T6, __T7); return __T8[0] +extern __inline signed char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_reduce_max_epi8 (__m128i __V) +{ + _MM_REDUCE_OPERATOR_MAX_MIN_EP8 (max_epi8); +} +extern __inline unsigned char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_reduce_max_epu8 (__m128i __V) +{ + _MM_REDUCE_OPERATOR_MAX_MIN_EP8 (max_epu8); +} +extern __inline signed char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_reduce_min_epi8 (__m128i __V) +{ + _MM_REDUCE_OPERATOR_MAX_MIN_EP8 (min_epi8); +} +extern __inline unsigned char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_reduce_min_epu8 (__m128i __V) +{ + _MM_REDUCE_OPERATOR_MAX_MIN_EP8 (min_epu8); +} +#define _MM256_REDUCE_OPERATOR_BASIC_EPI8(op) __v16qi __T1 = (__v16qi)_mm256_extracti128_si256 (__W, 0); __v16qi __T2 = (__v16qi)_mm256_extracti128_si256 (__W, 1); __v16qi __T3 = __T1 op __T2; __v16qi __T4 = __builtin_shufflevector (__T3, __T3, 8, 9, 10, 11, 12, 13, 14, 15, 8, 9, 10, 11, 12, 13, 14, 15); __v16qi __T5 = __T3 op __T4; __v16qi __T6 = __builtin_shufflevector (__T5, __T5, 4, 5, 6, 7, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); __v16qi __T7 = __T5 op __T6; __v16qi __T8 = __builtin_shufflevector (__T7, __T7, 2, 3, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); __v16qi __T9 = __T7 op __T8; __v16qi __T10 = __builtin_shufflevector (__T9, __T9, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); __v16qi __T11 = __T9 op __T10; return __T11[0] +extern __inline char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_reduce_add_epi8 (__m256i __W) +{ + _MM256_REDUCE_OPERATOR_BASIC_EPI8 (+); +} +extern __inline char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_reduce_mul_epi8 (__m256i __W) +{ + _MM256_REDUCE_OPERATOR_BASIC_EPI8 (*); +} +extern __inline char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_reduce_and_epi8 (__m256i __W) +{ + _MM256_REDUCE_OPERATOR_BASIC_EPI8 (&); +} +extern __inline char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_reduce_or_epi8 (__m256i __W) +{ + _MM256_REDUCE_OPERATOR_BASIC_EPI8 (|); +} +#define _MM256_REDUCE_OPERATOR_MAX_MIN_EP8(op) __m128i __T1 = _mm256_extracti128_si256 (__V, 0); __m128i __T2 = _mm256_extracti128_si256 (__V, 1); __m128i __T3 = _mm_##op (__T1, __T2); __m128i __T4 = (__m128i)__builtin_shufflevector ((__v16qi)__T3, (__v16qi)__T3, 8, 9, 10, 11, 12, 13, 14, 15, 8, 9, 10, 11, 12, 13, 14, 15); __m128i __T5 = _mm_##op (__T3, __T4); __m128i __T6 = (__m128i)__builtin_shufflevector ((__v16qi)__T5, (__v16qi)__T5, 4, 5, 6, 7, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); __m128i __T7 = _mm_##op (__T5, __T6); __m128i __T8 = (__m128i)__builtin_shufflevector ((__v16qi)__T7, (__v16qi)__T5, 2, 3, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); __m128i __T9 = _mm_##op (__T7, __T8); __m128i __T10 = (__m128i)__builtin_shufflevector ((__v16qi)__T9, (__v16qi)__T9, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); __v16qi __T11 = (__v16qi)_mm_##op (__T9, __T10); return __T11[0] +extern __inline signed char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_reduce_max_epi8 (__m256i __V) +{ + _MM256_REDUCE_OPERATOR_MAX_MIN_EP8 (max_epi8); +} +extern __inline unsigned char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_reduce_max_epu8 (__m256i __V) +{ + _MM256_REDUCE_OPERATOR_MAX_MIN_EP8 (max_epu8); +} +extern __inline signed char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_reduce_min_epi8 (__m256i __V) +{ + _MM256_REDUCE_OPERATOR_MAX_MIN_EP8 (min_epi8); +} +extern __inline unsigned char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_reduce_min_epu8 (__m256i __V) +{ + _MM256_REDUCE_OPERATOR_MAX_MIN_EP8 (min_epu8); +} #ifdef __DISABLE_AVX2__ #undef __DISABLE_AVX2__ #pragma GCC pop_options diff --git a/third_party/intel/avx5124fmapsintrin.internal.h b/third_party/intel/avx5124fmapsintrin.internal.h index 7134f1227..acd03b5e6 100644 --- a/third_party/intel/avx5124fmapsintrin.internal.h +++ b/third_party/intel/avx5124fmapsintrin.internal.h @@ -6,7 +6,7 @@ #define _AVX5124FMAPSINTRIN_H_INCLUDED #ifndef __AVX5124FMAPS__ #pragma GCC push_options -#pragma GCC target("avx5124fmaps") +#pragma GCC target("avx5124fmaps,evex512") #define __DISABLE_AVX5124FMAPS__ #endif extern __inline __m512 diff --git a/third_party/intel/avx5124vnniwintrin.internal.h b/third_party/intel/avx5124vnniwintrin.internal.h index b94ca1d2f..247c0f633 100644 --- a/third_party/intel/avx5124vnniwintrin.internal.h +++ b/third_party/intel/avx5124vnniwintrin.internal.h @@ -6,7 +6,7 @@ #define _AVX5124VNNIWINTRIN_H_INCLUDED #ifndef __AVX5124VNNIW__ #pragma GCC push_options -#pragma GCC target("avx5124vnniw") +#pragma GCC target("avx5124vnniw,evex512") #define __DISABLE_AVX5124VNNIW__ #endif extern __inline __m512i diff --git a/third_party/intel/avx512bf16intrin.internal.h b/third_party/intel/avx512bf16intrin.internal.h index 5bc3f8358..d4c79624d 100644 --- a/third_party/intel/avx512bf16intrin.internal.h +++ b/third_party/intel/avx512bf16intrin.internal.h @@ -4,38 +4,45 @@ #endif #ifndef _AVX512BF16INTRIN_H_INCLUDED #define _AVX512BF16INTRIN_H_INCLUDED -#ifndef __AVX512BF16__ +#if !defined (__AVX512BF16__) || defined (__EVEX512__) #pragma GCC push_options -#pragma GCC target("avx512bf16") +#pragma GCC target("avx512bf16,no-evex512") #define __DISABLE_AVX512BF16__ #endif -typedef short __v32bh __attribute__ ((__vector_size__ (64))); -typedef short __m512bh __attribute__ ((__vector_size__ (64), __may_alias__)); extern __inline float __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtsbh_ss (__bfloat16 __A) +_mm_cvtsbh_ss (__bf16 __A) { - union{ float a; unsigned int b;} __tmp; - __tmp.b = ((unsigned int)(__A)) << 16; - return __tmp.a; + return __builtin_ia32_cvtbf2sf (__A); } +#ifdef __DISABLE_AVX512BF16__ +#undef __DISABLE_AVX512BF16__ +#pragma GCC pop_options +#endif +#if !defined (__AVX512BF16__) || !defined (__EVEX512__) +#pragma GCC push_options +#pragma GCC target("avx512bf16,evex512") +#define __DISABLE_AVX512BF16_512__ +#endif +typedef __bf16 __v32bf __attribute__ ((__vector_size__ (64))); +typedef __bf16 __m512bh __attribute__ ((__vector_size__ (64), __may_alias__)); extern __inline __m512bh __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm512_cvtne2ps_pbh (__m512 __A, __m512 __B) { - return (__m512bh)__builtin_ia32_cvtne2ps2bf16_v32hi(__A, __B); + return (__m512bh)__builtin_ia32_cvtne2ps2bf16_v32bf(__A, __B); } extern __inline __m512bh __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm512_mask_cvtne2ps_pbh (__m512bh __A, __mmask32 __B, __m512 __C, __m512 __D) { - return (__m512bh)__builtin_ia32_cvtne2ps2bf16_v32hi_mask(__C, __D, __A, __B); + return (__m512bh)__builtin_ia32_cvtne2ps2bf16_v32bf_mask(__C, __D, __A, __B); } extern __inline __m512bh __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm512_maskz_cvtne2ps_pbh (__mmask32 __A, __m512 __B, __m512 __C) { - return (__m512bh)__builtin_ia32_cvtne2ps2bf16_v32hi_maskz(__B, __C, __A); + return (__m512bh)__builtin_ia32_cvtne2ps2bf16_v32bf_maskz(__B, __C, __A); } extern __inline __m256bh __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -96,8 +103,8 @@ _mm512_mask_cvtpbh_ps (__m512 __S, __mmask16 __U, __m256bh __A) (__m512i)__S, (__mmask16)__U, (__m512i)_mm512_cvtepi16_epi32 ((__m256i)__A), 16))); } -#ifdef __DISABLE_AVX512BF16__ -#undef __DISABLE_AVX512BF16__ +#ifdef __DISABLE_AVX512BF16_512__ +#undef __DISABLE_AVX512BF16_512__ #pragma GCC pop_options #endif #endif diff --git a/third_party/intel/avx512bf16vlintrin.internal.h b/third_party/intel/avx512bf16vlintrin.internal.h index 216196fcf..5d441b6dd 100644 --- a/third_party/intel/avx512bf16vlintrin.internal.h +++ b/third_party/intel/avx512bf16vlintrin.internal.h @@ -4,57 +4,85 @@ #endif #ifndef _AVX512BF16VLINTRIN_H_INCLUDED #define _AVX512BF16VLINTRIN_H_INCLUDED -#if !defined(__AVX512VL__) || !defined(__AVX512BF16__) +#if !defined(__AVX512VL__) || !defined(__AVX512BF16__) || defined (__EVEX512__) #pragma GCC push_options -#pragma GCC target("avx512bf16,avx512vl") +#pragma GCC target("avx512bf16,avx512vl,no-evex512") #define __DISABLE_AVX512BF16VL__ #endif -typedef short __v16bh __attribute__ ((__vector_size__ (32))); -typedef short __v8bh __attribute__ ((__vector_size__ (16))); -typedef short __m256bh __attribute__ ((__vector_size__ (32), __may_alias__)); -typedef short __m128bh __attribute__ ((__vector_size__ (16), __may_alias__)); -typedef unsigned short __bfloat16; +typedef __bf16 __v16bf __attribute__ ((__vector_size__ (32))); +typedef __bf16 __v8bf __attribute__ ((__vector_size__ (16))); +typedef __bf16 __m256bh __attribute__ ((__vector_size__ (32), __may_alias__)); +typedef __bf16 __m128bh __attribute__ ((__vector_size__ (16), __may_alias__)); +typedef __bf16 __bfloat16; +extern __inline __m128 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_avx512_castsi128_ps(__m128i __A) +{ + return (__m128) __A; +} +extern __inline __m256 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_avx512_castsi256_ps (__m256i __A) +{ + return (__m256) __A; +} +extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_avx512_slli_epi32 (__m128i __A, int __B) +{ + return (__m128i)__builtin_ia32_pslldi128 ((__v4si)__A, __B); +} +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_avx512_slli_epi32 (__m256i __A, int __B) +{ + return (__m256i)__builtin_ia32_pslldi256 ((__v8si)__A, __B); +} +extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_avx512_cvtepi16_epi32 (__m128i __X) +{ + return (__m128i) __builtin_ia32_pmovsxwd128 ((__v8hi)__X); +} +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_avx512_cvtepi16_epi32 (__m128i __X) +{ + return (__m256i) __builtin_ia32_pmovsxwd256 ((__v8hi)__X); +} +#define _mm256_cvtneps_pbh(A) (__m128bh) __builtin_ia32_cvtneps2bf16_v8sf (A) +#define _mm_cvtneps_pbh(A) (__m128bh) __builtin_ia32_cvtneps2bf16_v4sf (A) extern __inline __m256bh __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm256_cvtne2ps_pbh (__m256 __A, __m256 __B) { - return (__m256bh)__builtin_ia32_cvtne2ps2bf16_v16hi(__A, __B); + return (__m256bh)__builtin_ia32_cvtne2ps2bf16_v16bf(__A, __B); } extern __inline __m256bh __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm256_mask_cvtne2ps_pbh (__m256bh __A, __mmask16 __B, __m256 __C, __m256 __D) { - return (__m256bh)__builtin_ia32_cvtne2ps2bf16_v16hi_mask(__C, __D, __A, __B); + return (__m256bh)__builtin_ia32_cvtne2ps2bf16_v16bf_mask(__C, __D, __A, __B); } extern __inline __m256bh __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm256_maskz_cvtne2ps_pbh (__mmask16 __A, __m256 __B, __m256 __C) { - return (__m256bh)__builtin_ia32_cvtne2ps2bf16_v16hi_maskz(__B, __C, __A); + return (__m256bh)__builtin_ia32_cvtne2ps2bf16_v16bf_maskz(__B, __C, __A); } extern __inline __m128bh __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_cvtne2ps_pbh (__m128 __A, __m128 __B) { - return (__m128bh)__builtin_ia32_cvtne2ps2bf16_v8hi(__A, __B); + return (__m128bh)__builtin_ia32_cvtne2ps2bf16_v8bf(__A, __B); } extern __inline __m128bh __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_mask_cvtne2ps_pbh (__m128bh __A, __mmask8 __B, __m128 __C, __m128 __D) { - return (__m128bh)__builtin_ia32_cvtne2ps2bf16_v8hi_mask(__C, __D, __A, __B); + return (__m128bh)__builtin_ia32_cvtne2ps2bf16_v8bf_mask(__C, __D, __A, __B); } extern __inline __m128bh __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_maskz_cvtne2ps_pbh (__mmask8 __A, __m128 __B, __m128 __C) { - return (__m128bh)__builtin_ia32_cvtne2ps2bf16_v8hi_maskz(__B, __C, __A); -} -extern __inline __m128bh -__attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_cvtneps_pbh (__m256 __A) -{ - return (__m128bh)__builtin_ia32_cvtneps2bf16_v8sf(__A); + return (__m128bh)__builtin_ia32_cvtne2ps2bf16_v8bf_maskz(__B, __C, __A); } extern __inline __m128bh __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -70,12 +98,6 @@ _mm256_maskz_cvtneps_pbh (__mmask8 __A, __m256 __B) } extern __inline __m128bh __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtneps_pbh (__m128 __A) -{ - return (__m128bh)__builtin_ia32_cvtneps2bf16_v4sf(__A); -} -extern __inline __m128bh -__attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_mask_cvtneps_pbh (__m128bh __A, __mmask8 __B, __m128 __C) { return (__m128bh)__builtin_ia32_cvtneps2bf16_v4sf_mask(__C, __A, __B); @@ -122,34 +144,34 @@ _mm_maskz_dpbf16_ps (__mmask8 __A, __m128 __B, __m128bh __C, __m128bh __D) { return (__m128)__builtin_ia32_dpbf16ps_v4sf_maskz(__B, __C, __D, __A); } -extern __inline __bfloat16 +extern __inline __bf16 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm_cvtness_sbh (float __A) { __v4sf __V = {__A, 0, 0, 0}; - __v8hi __R = __builtin_ia32_cvtneps2bf16_v4sf_mask ((__v4sf)__V, - (__v8hi)_mm_undefined_si128 (), (__mmask8)-1); + __v8bf __R = __builtin_ia32_cvtneps2bf16_v4sf_mask ((__v4sf)__V, + (__v8bf)_mm_avx512_undefined_si128 (), (__mmask8)-1); return __R[0]; } extern __inline __m128 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm_cvtpbh_ps (__m128bh __A) { - return (__m128)_mm_castsi128_ps ((__m128i)_mm_slli_epi32 ( - (__m128i)_mm_cvtepi16_epi32 ((__m128i)__A), 16)); + return (__m128)_mm_avx512_castsi128_ps ((__m128i)_mm_avx512_slli_epi32 ( + (__m128i)_mm_avx512_cvtepi16_epi32 ((__m128i)__A), 16)); } extern __inline __m256 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_cvtpbh_ps (__m128bh __A) { - return (__m256)_mm256_castsi256_ps ((__m256i)_mm256_slli_epi32 ( - (__m256i)_mm256_cvtepi16_epi32 ((__m128i)__A), 16)); + return (__m256)_mm256_avx512_castsi256_ps ((__m256i)_mm256_avx512_slli_epi32 ( + (__m256i)_mm256_avx512_cvtepi16_epi32 ((__m128i)__A), 16)); } extern __inline __m128 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm_maskz_cvtpbh_ps (__mmask8 __U, __m128bh __A) { - return (__m128)_mm_castsi128_ps ((__m128i)_mm_slli_epi32 ( + return (__m128)_mm_avx512_castsi128_ps ((__m128i)_mm_avx512_slli_epi32 ( (__m128i)_mm_maskz_cvtepi16_epi32 ( (__mmask8)__U, (__m128i)__A), 16)); } @@ -157,7 +179,7 @@ extern __inline __m256 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_maskz_cvtpbh_ps (__mmask8 __U, __m128bh __A) { - return (__m256)_mm256_castsi256_ps ((__m256i)_mm256_slli_epi32 ( + return (__m256)_mm256_avx512_castsi256_ps ((__m256i)_mm256_avx512_slli_epi32 ( (__m256i)_mm256_maskz_cvtepi16_epi32 ( (__mmask8)__U, (__m128i)__A), 16)); } @@ -165,16 +187,16 @@ extern __inline __m128 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm_mask_cvtpbh_ps (__m128 __S, __mmask8 __U, __m128bh __A) { - return (__m128)_mm_castsi128_ps ((__m128i)_mm_mask_slli_epi32 ( - (__m128i)__S, (__mmask8)__U, (__m128i)_mm_cvtepi16_epi32 ( + return (__m128)_mm_avx512_castsi128_ps ((__m128i)_mm_mask_slli_epi32 ( + (__m128i)__S, (__mmask8)__U, (__m128i)_mm_avx512_cvtepi16_epi32 ( (__m128i)__A), 16)); } extern __inline __m256 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_mask_cvtpbh_ps (__m256 __S, __mmask8 __U, __m128bh __A) { - return (__m256)_mm256_castsi256_ps ((__m256i)_mm256_mask_slli_epi32 ( - (__m256i)__S, (__mmask8)__U, (__m256i)_mm256_cvtepi16_epi32 ( + return (__m256)_mm256_avx512_castsi256_ps ((__m256i)_mm256_mask_slli_epi32 ( + (__m256i)__S, (__mmask8)__U, (__m256i)_mm256_avx512_cvtepi16_epi32 ( (__m128i)__A), 16)); } #ifdef __DISABLE_AVX512BF16VL__ diff --git a/third_party/intel/avx512bitalgintrin.internal.h b/third_party/intel/avx512bitalgintrin.internal.h index aa7750fec..32b668185 100644 --- a/third_party/intel/avx512bitalgintrin.internal.h +++ b/third_party/intel/avx512bitalgintrin.internal.h @@ -1,12 +1,12 @@ #if defined(__x86_64__) && !(__ASSEMBLER__ + __LINKER__ + 0) #if !defined _IMMINTRIN_H_INCLUDED -# error "Never use directly; include instead." +# error "Never use directly; include instead." #endif #ifndef _AVX512BITALGINTRIN_H_INCLUDED #define _AVX512BITALGINTRIN_H_INCLUDED -#ifndef __AVX512BITALG__ +#if !defined (__AVX512BITALG__) || !defined (__EVEX512__) #pragma GCC push_options -#pragma GCC target("avx512bitalg") +#pragma GCC target("avx512bitalg,evex512") #define __DISABLE_AVX512BITALG__ #endif extern __inline __m512i @@ -21,15 +21,6 @@ _mm512_popcnt_epi16 (__m512i __A) { return (__m512i) __builtin_ia32_vpopcountw_v32hi ((__v32hi) __A); } -#ifdef __DISABLE_AVX512BITALG__ -#undef __DISABLE_AVX512BITALG__ -#pragma GCC pop_options -#endif -#if !defined(__AVX512BITALG__) || !defined(__AVX512BW__) -#pragma GCC push_options -#pragma GCC target("avx512bitalg,avx512bw") -#define __DISABLE_AVX512BITALGBW__ -#endif extern __inline __m512i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm512_mask_popcnt_epi8 (__m512i __W, __mmask64 __U, __m512i __A) @@ -80,150 +71,8 @@ _mm512_mask_bitshuffle_epi64_mask (__mmask64 __M, __m512i __A, __m512i __B) (__v64qi) __B, (__mmask64) __M); } -#ifdef __DISABLE_AVX512BITALGBW__ -#undef __DISABLE_AVX512BITALGBW__ -#pragma GCC pop_options -#endif -#if !defined(__AVX512BITALG__) || !defined(__AVX512VL__) || !defined(__AVX512BW__) -#pragma GCC push_options -#pragma GCC target("avx512bitalg,avx512vl,avx512bw") -#define __DISABLE_AVX512BITALGVLBW__ -#endif -extern __inline __m256i -__attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_popcnt_epi8 (__m256i __W, __mmask32 __U, __m256i __A) -{ - return (__m256i) __builtin_ia32_vpopcountb_v32qi_mask ((__v32qi) __A, - (__v32qi) __W, - (__mmask32) __U); -} -extern __inline __m256i -__attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_maskz_popcnt_epi8 (__mmask32 __U, __m256i __A) -{ - return (__m256i) __builtin_ia32_vpopcountb_v32qi_mask ((__v32qi) __A, - (__v32qi) - _mm256_setzero_si256 (), - (__mmask32) __U); -} -extern __inline __mmask32 -__attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_bitshuffle_epi64_mask (__m256i __A, __m256i __B) -{ - return (__mmask32) __builtin_ia32_vpshufbitqmb256_mask ((__v32qi) __A, - (__v32qi) __B, - (__mmask32) -1); -} -extern __inline __mmask32 -__attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_bitshuffle_epi64_mask (__mmask32 __M, __m256i __A, __m256i __B) -{ - return (__mmask32) __builtin_ia32_vpshufbitqmb256_mask ((__v32qi) __A, - (__v32qi) __B, - (__mmask32) __M); -} -#ifdef __DISABLE_AVX512BITALGVLBW__ -#undef __DISABLE_AVX512BITALGVLBW__ -#pragma GCC pop_options -#endif -#if !defined(__AVX512BITALG__) || !defined(__AVX512VL__) -#pragma GCC push_options -#pragma GCC target("avx512bitalg,avx512vl") -#define __DISABLE_AVX512BITALGVL__ -#endif -extern __inline __mmask16 -__attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_bitshuffle_epi64_mask (__m128i __A, __m128i __B) -{ - return (__mmask16) __builtin_ia32_vpshufbitqmb128_mask ((__v16qi) __A, - (__v16qi) __B, - (__mmask16) -1); -} -extern __inline __mmask16 -__attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_bitshuffle_epi64_mask (__mmask16 __M, __m128i __A, __m128i __B) -{ - return (__mmask16) __builtin_ia32_vpshufbitqmb128_mask ((__v16qi) __A, - (__v16qi) __B, - (__mmask16) __M); -} -extern __inline __m256i -__attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_popcnt_epi8 (__m256i __A) -{ - return (__m256i) __builtin_ia32_vpopcountb_v32qi ((__v32qi) __A); -} -extern __inline __m256i -__attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_popcnt_epi16 (__m256i __A) -{ - return (__m256i) __builtin_ia32_vpopcountw_v16hi ((__v16hi) __A); -} -extern __inline __m128i -__attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_popcnt_epi8 (__m128i __A) -{ - return (__m128i) __builtin_ia32_vpopcountb_v16qi ((__v16qi) __A); -} -extern __inline __m128i -__attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_popcnt_epi16 (__m128i __A) -{ - return (__m128i) __builtin_ia32_vpopcountw_v8hi ((__v8hi) __A); -} -extern __inline __m256i -__attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_popcnt_epi16 (__m256i __W, __mmask16 __U, __m256i __A) -{ - return (__m256i) __builtin_ia32_vpopcountw_v16hi_mask ((__v16hi) __A, - (__v16hi) __W, - (__mmask16) __U); -} -extern __inline __m256i -__attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_maskz_popcnt_epi16 (__mmask16 __U, __m256i __A) -{ - return (__m256i) __builtin_ia32_vpopcountw_v16hi_mask ((__v16hi) __A, - (__v16hi) - _mm256_setzero_si256 (), - (__mmask16) __U); -} -extern __inline __m128i -__attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_popcnt_epi8 (__m128i __W, __mmask16 __U, __m128i __A) -{ - return (__m128i) __builtin_ia32_vpopcountb_v16qi_mask ((__v16qi) __A, - (__v16qi) __W, - (__mmask16) __U); -} -extern __inline __m128i -__attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_popcnt_epi8 (__mmask16 __U, __m128i __A) -{ - return (__m128i) __builtin_ia32_vpopcountb_v16qi_mask ((__v16qi) __A, - (__v16qi) - _mm_setzero_si128 (), - (__mmask16) __U); -} -extern __inline __m128i -__attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_popcnt_epi16 (__m128i __W, __mmask8 __U, __m128i __A) -{ - return (__m128i) __builtin_ia32_vpopcountw_v8hi_mask ((__v8hi) __A, - (__v8hi) __W, - (__mmask8) __U); -} -extern __inline __m128i -__attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_popcnt_epi16 (__mmask8 __U, __m128i __A) -{ - return (__m128i) __builtin_ia32_vpopcountw_v8hi_mask ((__v8hi) __A, - (__v8hi) - _mm_setzero_si128 (), - (__mmask8) __U); -} -#ifdef __DISABLE_AVX512BITALGVL__ -#undef __DISABLE_AVX512BITALGVL__ +#ifdef __DISABLE_AVX512BITALG__ +#undef __DISABLE_AVX512BITALG__ #pragma GCC pop_options #endif #endif diff --git a/third_party/intel/avx512bitalgvlintrin.internal.h b/third_party/intel/avx512bitalgvlintrin.internal.h new file mode 100644 index 000000000..5a5d85e2f --- /dev/null +++ b/third_party/intel/avx512bitalgvlintrin.internal.h @@ -0,0 +1,141 @@ +#if defined(__x86_64__) && !(__ASSEMBLER__ + __LINKER__ + 0) +#if !defined _IMMINTRIN_H_INCLUDED +# error "Never use directly; include instead." +#endif +#ifndef _AVX512BITALGVLINTRIN_H_INCLUDED +#define _AVX512BITALGVLINTRIN_H_INCLUDED +#if !defined(__AVX512BITALG__) || !defined(__AVX512VL__) || defined (__EVEX512__) +#pragma GCC push_options +#pragma GCC target("avx512bitalg,avx512vl,no-evex512") +#define __DISABLE_AVX512BITALGVL__ +#endif +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_mask_popcnt_epi8 (__m256i __W, __mmask32 __U, __m256i __A) +{ + return (__m256i) __builtin_ia32_vpopcountb_v32qi_mask ((__v32qi) __A, + (__v32qi) __W, + (__mmask32) __U); +} +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_maskz_popcnt_epi8 (__mmask32 __U, __m256i __A) +{ + return (__m256i) __builtin_ia32_vpopcountb_v32qi_mask ((__v32qi) __A, + (__v32qi) + _mm256_avx512_setzero_si256 (), + (__mmask32) __U); +} +extern __inline __mmask32 +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_bitshuffle_epi64_mask (__m256i __A, __m256i __B) +{ + return (__mmask32) __builtin_ia32_vpshufbitqmb256_mask ((__v32qi) __A, + (__v32qi) __B, + (__mmask32) -1); +} +extern __inline __mmask32 +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_mask_bitshuffle_epi64_mask (__mmask32 __M, __m256i __A, __m256i __B) +{ + return (__mmask32) __builtin_ia32_vpshufbitqmb256_mask ((__v32qi) __A, + (__v32qi) __B, + (__mmask32) __M); +} +extern __inline __mmask16 +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_bitshuffle_epi64_mask (__m128i __A, __m128i __B) +{ + return (__mmask16) __builtin_ia32_vpshufbitqmb128_mask ((__v16qi) __A, + (__v16qi) __B, + (__mmask16) -1); +} +extern __inline __mmask16 +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_bitshuffle_epi64_mask (__mmask16 __M, __m128i __A, __m128i __B) +{ + return (__mmask16) __builtin_ia32_vpshufbitqmb128_mask ((__v16qi) __A, + (__v16qi) __B, + (__mmask16) __M); +} +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_popcnt_epi8 (__m256i __A) +{ + return (__m256i) __builtin_ia32_vpopcountb_v32qi ((__v32qi) __A); +} +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_popcnt_epi16 (__m256i __A) +{ + return (__m256i) __builtin_ia32_vpopcountw_v16hi ((__v16hi) __A); +} +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_popcnt_epi8 (__m128i __A) +{ + return (__m128i) __builtin_ia32_vpopcountb_v16qi ((__v16qi) __A); +} +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_popcnt_epi16 (__m128i __A) +{ + return (__m128i) __builtin_ia32_vpopcountw_v8hi ((__v8hi) __A); +} +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_mask_popcnt_epi16 (__m256i __W, __mmask16 __U, __m256i __A) +{ + return (__m256i) __builtin_ia32_vpopcountw_v16hi_mask ((__v16hi) __A, + (__v16hi) __W, + (__mmask16) __U); +} +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_maskz_popcnt_epi16 (__mmask16 __U, __m256i __A) +{ + return (__m256i) __builtin_ia32_vpopcountw_v16hi_mask ((__v16hi) __A, + (__v16hi) + _mm256_avx512_setzero_si256 (), + (__mmask16) __U); +} +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_popcnt_epi8 (__m128i __W, __mmask16 __U, __m128i __A) +{ + return (__m128i) __builtin_ia32_vpopcountb_v16qi_mask ((__v16qi) __A, + (__v16qi) __W, + (__mmask16) __U); +} +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_popcnt_epi8 (__mmask16 __U, __m128i __A) +{ + return (__m128i) __builtin_ia32_vpopcountb_v16qi_mask ((__v16qi) __A, + (__v16qi) + _mm_avx512_setzero_si128 (), + (__mmask16) __U); +} +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_popcnt_epi16 (__m128i __W, __mmask8 __U, __m128i __A) +{ + return (__m128i) __builtin_ia32_vpopcountw_v8hi_mask ((__v8hi) __A, + (__v8hi) __W, + (__mmask8) __U); +} +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_popcnt_epi16 (__mmask8 __U, __m128i __A) +{ + return (__m128i) __builtin_ia32_vpopcountw_v8hi_mask ((__v8hi) __A, + (__v8hi) + _mm_avx512_setzero_si128 (), + (__mmask8) __U); +} +#ifdef __DISABLE_AVX512BITALGVL__ +#undef __DISABLE_AVX512BITALGVL__ +#pragma GCC pop_options +#endif +#endif +#endif diff --git a/third_party/intel/avx512bwintrin.internal.h b/third_party/intel/avx512bwintrin.internal.h index 27f94a612..a213e7c7d 100644 --- a/third_party/intel/avx512bwintrin.internal.h +++ b/third_party/intel/avx512bwintrin.internal.h @@ -4,16 +4,35 @@ #endif #ifndef _AVX512BWINTRIN_H_INCLUDED #define _AVX512BWINTRIN_H_INCLUDED -#ifndef __AVX512BW__ +#if !defined (__AVX512BW__) || defined (__EVEX512__) #pragma GCC push_options -#pragma GCC target("avx512bw") +#pragma GCC target("avx512bw,no-evex512") #define __DISABLE_AVX512BW__ #endif -typedef short __v32hi __attribute__ ((__vector_size__ (64))); -typedef short __v32hi_u __attribute__ ((__vector_size__ (64), __may_alias__, __aligned__ (1))); -typedef char __v64qi __attribute__ ((__vector_size__ (64))); -typedef char __v64qi_u __attribute__ ((__vector_size__ (64), __may_alias__, __aligned__ (1))); typedef unsigned long long __mmask64; +extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_avx512_set_epi32 (int __q3, int __q2, int __q1, int __q0) +{ + return __extension__ (__m128i)(__v4si){ __q0, __q1, __q2, __q3 }; +} +extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_avx512_set_epi16 (short __q7, short __q6, short __q5, short __q4, + short __q3, short __q2, short __q1, short __q0) +{ + return __extension__ (__m128i)(__v8hi){ + __q0, __q1, __q2, __q3, __q4, __q5, __q6, __q7 }; +} +extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_avx512_set_epi8 (char __q15, char __q14, char __q13, char __q12, + char __q11, char __q10, char __q09, char __q08, + char __q07, char __q06, char __q05, char __q04, + char __q03, char __q02, char __q01, char __q00) +{ + return __extension__ (__m128i)(__v16qi){ + __q00, __q01, __q02, __q03, __q04, __q05, __q06, __q07, + __q08, __q09, __q10, __q11, __q12, __q13, __q14, __q15 + }; +} extern __inline unsigned char __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _ktest_mask32_u8 (__mmask32 __A, __mmask32 __B, unsigned char *__CF) @@ -23,37 +42,18 @@ _ktest_mask32_u8 (__mmask32 __A, __mmask32 __B, unsigned char *__CF) } extern __inline unsigned char __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_ktest_mask64_u8 (__mmask64 __A, __mmask64 __B, unsigned char *__CF) -{ - *__CF = (unsigned char) __builtin_ia32_ktestcdi (__A, __B); - return (unsigned char) __builtin_ia32_ktestzdi (__A, __B); -} -extern __inline unsigned char -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _ktestz_mask32_u8 (__mmask32 __A, __mmask32 __B) { return (unsigned char) __builtin_ia32_ktestzsi (__A, __B); } extern __inline unsigned char __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_ktestz_mask64_u8 (__mmask64 __A, __mmask64 __B) -{ - return (unsigned char) __builtin_ia32_ktestzdi (__A, __B); -} -extern __inline unsigned char -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _ktestc_mask32_u8 (__mmask32 __A, __mmask32 __B) { return (unsigned char) __builtin_ia32_ktestcsi (__A, __B); } extern __inline unsigned char __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_ktestc_mask64_u8 (__mmask64 __A, __mmask64 __B) -{ - return (unsigned char) __builtin_ia32_ktestcdi (__A, __B); -} -extern __inline unsigned char -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _kortest_mask32_u8 (__mmask32 __A, __mmask32 __B, unsigned char *__CF) { *__CF = (unsigned char) __builtin_ia32_kortestcsi (__A, __B); @@ -61,6 +61,136 @@ _kortest_mask32_u8 (__mmask32 __A, __mmask32 __B, unsigned char *__CF) } extern __inline unsigned char __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_kortestz_mask32_u8 (__mmask32 __A, __mmask32 __B) +{ + return (unsigned char) __builtin_ia32_kortestzsi (__A, __B); +} +extern __inline unsigned char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_kortestc_mask32_u8 (__mmask32 __A, __mmask32 __B) +{ + return (unsigned char) __builtin_ia32_kortestcsi (__A, __B); +} +extern __inline __mmask32 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_kadd_mask32 (__mmask32 __A, __mmask32 __B) +{ + return (__mmask32) __builtin_ia32_kaddsi ((__mmask32) __A, (__mmask32) __B); +} +extern __inline unsigned int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_cvtmask32_u32 (__mmask32 __A) +{ + return (unsigned int) __builtin_ia32_kmovd ((__mmask32) __A); +} +extern __inline __mmask32 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_cvtu32_mask32 (unsigned int __A) +{ + return (__mmask32) __builtin_ia32_kmovd ((__mmask32) __A); +} +extern __inline __mmask32 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_load_mask32 (__mmask32 *__A) +{ + return (__mmask32) __builtin_ia32_kmovd (*__A); +} +extern __inline void +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_store_mask32 (__mmask32 *__A, __mmask32 __B) +{ + *(__mmask32 *) __A = __builtin_ia32_kmovd (__B); +} +extern __inline __mmask32 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_knot_mask32 (__mmask32 __A) +{ + return (__mmask32) __builtin_ia32_knotsi ((__mmask32) __A); +} +extern __inline __mmask32 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_kor_mask32 (__mmask32 __A, __mmask32 __B) +{ + return (__mmask32) __builtin_ia32_korsi ((__mmask32) __A, (__mmask32) __B); +} +extern __inline __mmask32 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_kxnor_mask32 (__mmask32 __A, __mmask32 __B) +{ + return (__mmask32) __builtin_ia32_kxnorsi ((__mmask32) __A, (__mmask32) __B); +} +extern __inline __mmask32 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_kxor_mask32 (__mmask32 __A, __mmask32 __B) +{ + return (__mmask32) __builtin_ia32_kxorsi ((__mmask32) __A, (__mmask32) __B); +} +extern __inline __mmask32 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_kand_mask32 (__mmask32 __A, __mmask32 __B) +{ + return (__mmask32) __builtin_ia32_kandsi ((__mmask32) __A, (__mmask32) __B); +} +extern __inline __mmask32 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_kandn_mask32 (__mmask32 __A, __mmask32 __B) +{ + return (__mmask32) __builtin_ia32_kandnsi ((__mmask32) __A, (__mmask32) __B); +} +extern __inline __mmask32 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm512_kunpackw (__mmask32 __A, __mmask32 __B) +{ + return (__mmask32) __builtin_ia32_kunpcksi ((__mmask32) __A, + (__mmask32) __B); +} +extern __inline __mmask32 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_kunpackw_mask32 (__mmask16 __A, __mmask16 __B) +{ + return (__mmask32) __builtin_ia32_kunpcksi ((__mmask32) __A, + (__mmask32) __B); +} +#if __OPTIMIZE__ +extern __inline __mmask32 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_kshiftli_mask32 (__mmask32 __A, unsigned int __B) +{ + return (__mmask32) __builtin_ia32_kshiftlisi ((__mmask32) __A, + (__mmask8) __B); +} +extern __inline __mmask32 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_kshiftri_mask32 (__mmask32 __A, unsigned int __B) +{ + return (__mmask32) __builtin_ia32_kshiftrisi ((__mmask32) __A, + (__mmask8) __B); +} +#else +#define _kshiftli_mask32(X, Y) ((__mmask32) __builtin_ia32_kshiftlisi ((__mmask32)(X), (__mmask8)(Y))) +#define _kshiftri_mask32(X, Y) ((__mmask32) __builtin_ia32_kshiftrisi ((__mmask32)(X), (__mmask8)(Y))) +#endif +extern __inline unsigned char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_ktest_mask64_u8 (__mmask64 __A, __mmask64 __B, unsigned char *__CF) +{ + *__CF = (unsigned char) __builtin_ia32_ktestcdi (__A, __B); + return (unsigned char) __builtin_ia32_ktestzdi (__A, __B); +} +extern __inline unsigned char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_ktestz_mask64_u8 (__mmask64 __A, __mmask64 __B) +{ + return (unsigned char) __builtin_ia32_ktestzdi (__A, __B); +} +extern __inline unsigned char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_ktestc_mask64_u8 (__mmask64 __A, __mmask64 __B) +{ + return (unsigned char) __builtin_ia32_ktestcdi (__A, __B); +} +extern __inline unsigned char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _kortest_mask64_u8 (__mmask64 __A, __mmask64 __B, unsigned char *__CF) { *__CF = (unsigned char) __builtin_ia32_kortestcdi (__A, __B); @@ -68,70 +198,34 @@ _kortest_mask64_u8 (__mmask64 __A, __mmask64 __B, unsigned char *__CF) } extern __inline unsigned char __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_kortestz_mask32_u8 (__mmask32 __A, __mmask32 __B) -{ - return (unsigned char) __builtin_ia32_kortestzsi (__A, __B); -} -extern __inline unsigned char -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _kortestz_mask64_u8 (__mmask64 __A, __mmask64 __B) { return (unsigned char) __builtin_ia32_kortestzdi (__A, __B); } extern __inline unsigned char __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_kortestc_mask32_u8 (__mmask32 __A, __mmask32 __B) -{ - return (unsigned char) __builtin_ia32_kortestcsi (__A, __B); -} -extern __inline unsigned char -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _kortestc_mask64_u8 (__mmask64 __A, __mmask64 __B) { return (unsigned char) __builtin_ia32_kortestcdi (__A, __B); } -extern __inline __mmask32 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_kadd_mask32 (__mmask32 __A, __mmask32 __B) -{ - return (__mmask32) __builtin_ia32_kaddsi ((__mmask32) __A, (__mmask32) __B); -} extern __inline __mmask64 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _kadd_mask64 (__mmask64 __A, __mmask64 __B) { return (__mmask64) __builtin_ia32_kadddi ((__mmask64) __A, (__mmask64) __B); } -extern __inline unsigned int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_cvtmask32_u32 (__mmask32 __A) -{ - return (unsigned int) __builtin_ia32_kmovd ((__mmask32) __A); -} extern __inline unsigned long long __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _cvtmask64_u64 (__mmask64 __A) { return (unsigned long long) __builtin_ia32_kmovq ((__mmask64) __A); } -extern __inline __mmask32 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_cvtu32_mask32 (unsigned int __A) -{ - return (__mmask32) __builtin_ia32_kmovd ((__mmask32) __A); -} extern __inline __mmask64 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _cvtu64_mask64 (unsigned long long __A) { return (__mmask64) __builtin_ia32_kmovq ((__mmask64) __A); } -extern __inline __mmask32 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_load_mask32 (__mmask32 *__A) -{ - return (__mmask32) __builtin_ia32_kmovd (*__A); -} extern __inline __mmask64 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _load_mask64 (__mmask64 *__A) @@ -140,88 +234,59 @@ _load_mask64 (__mmask64 *__A) } extern __inline void __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_store_mask32 (__mmask32 *__A, __mmask32 __B) -{ - *(__mmask32 *) __A = __builtin_ia32_kmovd (__B); -} -extern __inline void -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _store_mask64 (__mmask64 *__A, __mmask64 __B) { *(__mmask64 *) __A = __builtin_ia32_kmovq (__B); } -extern __inline __mmask32 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_knot_mask32 (__mmask32 __A) -{ - return (__mmask32) __builtin_ia32_knotsi ((__mmask32) __A); -} extern __inline __mmask64 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _knot_mask64 (__mmask64 __A) { return (__mmask64) __builtin_ia32_knotdi ((__mmask64) __A); } -extern __inline __mmask32 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_kor_mask32 (__mmask32 __A, __mmask32 __B) -{ - return (__mmask32) __builtin_ia32_korsi ((__mmask32) __A, (__mmask32) __B); -} extern __inline __mmask64 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _kor_mask64 (__mmask64 __A, __mmask64 __B) { return (__mmask64) __builtin_ia32_kordi ((__mmask64) __A, (__mmask64) __B); } -extern __inline __mmask32 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_kxnor_mask32 (__mmask32 __A, __mmask32 __B) -{ - return (__mmask32) __builtin_ia32_kxnorsi ((__mmask32) __A, (__mmask32) __B); -} extern __inline __mmask64 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _kxnor_mask64 (__mmask64 __A, __mmask64 __B) { return (__mmask64) __builtin_ia32_kxnordi ((__mmask64) __A, (__mmask64) __B); } -extern __inline __mmask32 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_kxor_mask32 (__mmask32 __A, __mmask32 __B) -{ - return (__mmask32) __builtin_ia32_kxorsi ((__mmask32) __A, (__mmask32) __B); -} extern __inline __mmask64 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _kxor_mask64 (__mmask64 __A, __mmask64 __B) { return (__mmask64) __builtin_ia32_kxordi ((__mmask64) __A, (__mmask64) __B); } -extern __inline __mmask32 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_kand_mask32 (__mmask32 __A, __mmask32 __B) -{ - return (__mmask32) __builtin_ia32_kandsi ((__mmask32) __A, (__mmask32) __B); -} extern __inline __mmask64 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _kand_mask64 (__mmask64 __A, __mmask64 __B) { return (__mmask64) __builtin_ia32_kanddi ((__mmask64) __A, (__mmask64) __B); } -extern __inline __mmask32 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_kandn_mask32 (__mmask32 __A, __mmask32 __B) -{ - return (__mmask32) __builtin_ia32_kandnsi ((__mmask32) __A, (__mmask32) __B); -} extern __inline __mmask64 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _kandn_mask64 (__mmask64 __A, __mmask64 __B) { return (__mmask64) __builtin_ia32_kandndi ((__mmask64) __A, (__mmask64) __B); } +#ifdef __DISABLE_AVX512BW__ +#undef __DISABLE_AVX512BW__ +#pragma GCC pop_options +#endif +#if !defined (__AVX512BW__) || !defined (__EVEX512__) +#pragma GCC push_options +#pragma GCC target("avx512bw,evex512") +#define __DISABLE_AVX512BW_512__ +#endif +typedef short __v32hi __attribute__ ((__vector_size__ (64))); +typedef short __v32hi_u __attribute__ ((__vector_size__ (64), __may_alias__, __aligned__ (1))); +typedef char __v64qi __attribute__ ((__vector_size__ (64))); +typedef char __v64qi_u __attribute__ ((__vector_size__ (64), __may_alias__, __aligned__ (1))); extern __inline __m512i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_mask_mov_epi16 (__m512i __W, __mmask32 __U, __m512i __A) @@ -293,20 +358,6 @@ _mm512_maskz_mov_epi8 (__mmask64 __U, __m512i __A) _mm512_setzero_si512 (), (__mmask64) __U); } -extern __inline __mmask32 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm512_kunpackw (__mmask32 __A, __mmask32 __B) -{ - return (__mmask32) __builtin_ia32_kunpcksi ((__mmask32) __A, - (__mmask32) __B); -} -extern __inline __mmask32 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_kunpackw_mask32 (__mmask16 __A, __mmask16 __B) -{ - return (__mmask32) __builtin_ia32_kunpcksi ((__mmask32) __A, - (__mmask32) __B); -} extern __inline __mmask64 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_kunpackd (__mmask64 __A, __mmask64 __B) @@ -2463,13 +2514,6 @@ _mm512_mask_packus_epi32 (__m512i __W, __mmask32 __M, __m512i __A, __M); } #ifdef __OPTIMIZE__ -extern __inline __mmask32 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_kshiftli_mask32 (__mmask32 __A, unsigned int __B) -{ - return (__mmask32) __builtin_ia32_kshiftlisi ((__mmask32) __A, - (__mmask8) __B); -} extern __inline __mmask64 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _kshiftli_mask64 (__mmask64 __A, unsigned int __B) @@ -2477,13 +2521,6 @@ _kshiftli_mask64 (__mmask64 __A, unsigned int __B) return (__mmask64) __builtin_ia32_kshiftlidi ((__mmask64) __A, (__mmask8) __B); } -extern __inline __mmask32 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_kshiftri_mask32 (__mmask32 __A, unsigned int __B) -{ - return (__mmask32) __builtin_ia32_kshiftrisi ((__mmask32) __A, - (__mmask8) __B); -} extern __inline __mmask64 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _kshiftri_mask64 (__mmask64 __A, unsigned int __B) @@ -2557,7 +2594,7 @@ _mm512_maskz_dbsad_epu8 (__mmask32 __U, __m512i __A, __m512i __B, } extern __inline __m512i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm512_srli_epi16 (__m512i __A, const int __imm) +_mm512_srli_epi16 (__m512i __A, const unsigned int __imm) { return (__m512i) __builtin_ia32_psrlwi512_mask ((__v32hi) __A, __imm, (__v32hi) @@ -2567,7 +2604,7 @@ _mm512_srli_epi16 (__m512i __A, const int __imm) extern __inline __m512i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_mask_srli_epi16 (__m512i __W, __mmask32 __U, __m512i __A, - const int __imm) + const unsigned int __imm) { return (__m512i) __builtin_ia32_psrlwi512_mask ((__v32hi) __A, __imm, (__v32hi) __W, @@ -2584,7 +2621,7 @@ _mm512_maskz_srli_epi16 (__mmask32 __U, __m512i __A, const int __imm) } extern __inline __m512i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm512_slli_epi16 (__m512i __A, const int __B) +_mm512_slli_epi16 (__m512i __A, const unsigned int __B) { return (__m512i) __builtin_ia32_psllwi512_mask ((__v32hi) __A, __B, (__v32hi) @@ -2594,7 +2631,7 @@ _mm512_slli_epi16 (__m512i __A, const int __B) extern __inline __m512i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_mask_slli_epi16 (__m512i __W, __mmask32 __U, __m512i __A, - const int __B) + const unsigned int __B) { return (__m512i) __builtin_ia32_psllwi512_mask ((__v32hi) __A, __B, (__v32hi) __W, @@ -2602,7 +2639,7 @@ _mm512_mask_slli_epi16 (__m512i __W, __mmask32 __U, __m512i __A, } extern __inline __m512i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm512_maskz_slli_epi16 (__mmask32 __U, __m512i __A, const int __B) +_mm512_maskz_slli_epi16 (__mmask32 __U, __m512i __A, const unsigned int __B) { return (__m512i) __builtin_ia32_psllwi512_mask ((__v32hi) __A, __B, (__v32hi) @@ -2673,7 +2710,7 @@ _mm512_maskz_shufflelo_epi16 (__mmask32 __U, __m512i __A, } extern __inline __m512i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm512_srai_epi16 (__m512i __A, const int __imm) +_mm512_srai_epi16 (__m512i __A, const unsigned int __imm) { return (__m512i) __builtin_ia32_psrawi512_mask ((__v32hi) __A, __imm, (__v32hi) @@ -2683,7 +2720,7 @@ _mm512_srai_epi16 (__m512i __A, const int __imm) extern __inline __m512i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_mask_srai_epi16 (__m512i __W, __mmask32 __U, __m512i __A, - const int __imm) + const unsigned int __imm) { return (__m512i) __builtin_ia32_psrawi512_mask ((__v32hi) __A, __imm, (__v32hi) __W, @@ -2691,7 +2728,7 @@ _mm512_mask_srai_epi16 (__m512i __W, __mmask32 __U, __m512i __A, } extern __inline __m512i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm512_maskz_srai_epi16 (__mmask32 __U, __m512i __A, const int __imm) +_mm512_maskz_srai_epi16 (__mmask32 __U, __m512i __A, const unsigned int __imm) { return (__m512i) __builtin_ia32_psrawi512_mask ((__v32hi) __A, __imm, (__v32hi) @@ -2795,9 +2832,7 @@ _mm512_bsrli_epi128 (__m512i __A, const int __N) return (__m512i) __builtin_ia32_psrldq512 (__A, __N * 8); } #else -#define _kshiftli_mask32(X, Y) ((__mmask32) __builtin_ia32_kshiftlisi ((__mmask32)(X), (__mmask8)(Y))) #define _kshiftli_mask64(X, Y) ((__mmask64) __builtin_ia32_kshiftlidi ((__mmask64)(X), (__mmask8)(Y))) -#define _kshiftri_mask32(X, Y) ((__mmask32) __builtin_ia32_kshiftrisi ((__mmask32)(X), (__mmask8)(Y))) #define _kshiftri_mask64(X, Y) ((__mmask64) __builtin_ia32_kshiftridi ((__mmask64)(X), (__mmask8)(Y))) #define _mm512_alignr_epi8(X, Y, N) ((__m512i) __builtin_ia32_palignr512 ((__v8di)(__m512i)(X), (__v8di)(__m512i)(Y), (int)((N) * 8))) #define _mm512_mask_alignr_epi8(W, U, X, Y, N) ((__m512i) __builtin_ia32_palignr512_mask ((__v8di)(__m512i)(X), (__v8di)(__m512i)(Y), (int)((N) * 8), (__v8di)(__m512i)(W), (__mmask64)(U))) @@ -2805,21 +2840,21 @@ _mm512_bsrli_epi128 (__m512i __A, const int __N) #define _mm512_dbsad_epu8(X, Y, C) ((__m512i) __builtin_ia32_dbpsadbw512_mask ((__v64qi)(__m512i) (X), (__v64qi)(__m512i) (Y), (int) (C), (__v32hi)(__m512i) _mm512_setzero_si512 (), (__mmask32)-1)) #define _mm512_mask_dbsad_epu8(W, U, X, Y, C) ((__m512i) __builtin_ia32_dbpsadbw512_mask ((__v64qi)(__m512i) (X), (__v64qi)(__m512i) (Y), (int) (C), (__v32hi)(__m512i)(W), (__mmask32)(U))) #define _mm512_maskz_dbsad_epu8(U, X, Y, C) ((__m512i) __builtin_ia32_dbpsadbw512_mask ((__v64qi)(__m512i) (X), (__v64qi)(__m512i) (Y), (int) (C), (__v32hi)(__m512i) _mm512_setzero_si512 (), (__mmask32)(U))) -#define _mm512_srli_epi16(A, B) ((__m512i) __builtin_ia32_psrlwi512_mask ((__v32hi)(__m512i)(A), (int)(B), (__v32hi)_mm512_setzero_si512 (), (__mmask32)-1)) -#define _mm512_mask_srli_epi16(W, U, A, B) ((__m512i) __builtin_ia32_psrlwi512_mask ((__v32hi)(__m512i)(A), (int)(B), (__v32hi)(__m512i)(W), (__mmask32)(U))) +#define _mm512_srli_epi16(A, B) ((__m512i) __builtin_ia32_psrlwi512_mask ((__v32hi)(__m512i)(A), (unsigned int)(B), (__v32hi)_mm512_setzero_si512 (), (__mmask32)-1)) +#define _mm512_mask_srli_epi16(W, U, A, B) ((__m512i) __builtin_ia32_psrlwi512_mask ((__v32hi)(__m512i)(A), (unsigned int)(B), (__v32hi)(__m512i)(W), (__mmask32)(U))) #define _mm512_maskz_srli_epi16(U, A, B) ((__m512i) __builtin_ia32_psrlwi512_mask ((__v32hi)(__m512i)(A), (int)(B), (__v32hi)_mm512_setzero_si512 (), (__mmask32)(U))) -#define _mm512_slli_epi16(X, C) ((__m512i)__builtin_ia32_psllwi512_mask ((__v32hi)(__m512i)(X), (int)(C), (__v32hi)(__m512i)_mm512_setzero_si512 (), (__mmask32)-1)) -#define _mm512_mask_slli_epi16(W, U, X, C) ((__m512i)__builtin_ia32_psllwi512_mask ((__v32hi)(__m512i)(X), (int)(C), (__v32hi)(__m512i)(W), (__mmask32)(U))) -#define _mm512_maskz_slli_epi16(U, X, C) ((__m512i)__builtin_ia32_psllwi512_mask ((__v32hi)(__m512i)(X), (int)(C), (__v32hi)(__m512i)_mm512_setzero_si512 (), (__mmask32)(U))) +#define _mm512_slli_epi16(X, C) ((__m512i)__builtin_ia32_psllwi512_mask ((__v32hi)(__m512i)(X), (unsigned int)(C), (__v32hi)(__m512i)_mm512_setzero_si512 (), (__mmask32)-1)) +#define _mm512_mask_slli_epi16(W, U, X, C) ((__m512i)__builtin_ia32_psllwi512_mask ((__v32hi)(__m512i)(X), (unsigned int)(C), (__v32hi)(__m512i)(W), (__mmask32)(U))) +#define _mm512_maskz_slli_epi16(U, X, C) ((__m512i)__builtin_ia32_psllwi512_mask ((__v32hi)(__m512i)(X), (unsigned int)(C), (__v32hi)(__m512i)_mm512_setzero_si512 (), (__mmask32)(U))) #define _mm512_shufflehi_epi16(A, B) ((__m512i) __builtin_ia32_pshufhw512_mask ((__v32hi)(__m512i)(A), (int)(B), (__v32hi)(__m512i) _mm512_setzero_si512 (), (__mmask32)-1)) #define _mm512_mask_shufflehi_epi16(W, U, A, B) ((__m512i) __builtin_ia32_pshufhw512_mask ((__v32hi)(__m512i)(A), (int)(B), (__v32hi)(__m512i)(W), (__mmask32)(U))) #define _mm512_maskz_shufflehi_epi16(U, A, B) ((__m512i) __builtin_ia32_pshufhw512_mask ((__v32hi)(__m512i)(A), (int)(B), (__v32hi)(__m512i) _mm512_setzero_si512 (), (__mmask32)(U))) #define _mm512_shufflelo_epi16(A, B) ((__m512i) __builtin_ia32_pshuflw512_mask ((__v32hi)(__m512i)(A), (int)(B), (__v32hi)(__m512i) _mm512_setzero_si512 (), (__mmask32)-1)) #define _mm512_mask_shufflelo_epi16(W, U, A, B) ((__m512i) __builtin_ia32_pshuflw512_mask ((__v32hi)(__m512i)(A), (int)(B), (__v32hi)(__m512i)(W), (__mmask32)(U))) #define _mm512_maskz_shufflelo_epi16(U, A, B) ((__m512i) __builtin_ia32_pshuflw512_mask ((__v32hi)(__m512i)(A), (int)(B), (__v32hi)(__m512i) _mm512_setzero_si512 (), (__mmask32)(U))) -#define _mm512_srai_epi16(A, B) ((__m512i) __builtin_ia32_psrawi512_mask ((__v32hi)(__m512i)(A), (int)(B), (__v32hi)_mm512_setzero_si512 (), (__mmask32)-1)) -#define _mm512_mask_srai_epi16(W, U, A, B) ((__m512i) __builtin_ia32_psrawi512_mask ((__v32hi)(__m512i)(A), (int)(B), (__v32hi)(__m512i)(W), (__mmask32)(U))) -#define _mm512_maskz_srai_epi16(U, A, B) ((__m512i) __builtin_ia32_psrawi512_mask ((__v32hi)(__m512i)(A), (int)(B), (__v32hi)_mm512_setzero_si512 (), (__mmask32)(U))) +#define _mm512_srai_epi16(A, B) ((__m512i) __builtin_ia32_psrawi512_mask ((__v32hi)(__m512i)(A), (unsigned int)(B), (__v32hi)_mm512_setzero_si512 (), (__mmask32)-1)) +#define _mm512_mask_srai_epi16(W, U, A, B) ((__m512i) __builtin_ia32_psrawi512_mask ((__v32hi)(__m512i)(A), (unsigned int)(B), (__v32hi)(__m512i)(W), (__mmask32)(U))) +#define _mm512_maskz_srai_epi16(U, A, B) ((__m512i) __builtin_ia32_psrawi512_mask ((__v32hi)(__m512i)(A), (unsigned int)(B), (__v32hi)_mm512_setzero_si512 (), (__mmask32)(U))) #define _mm512_mask_blend_epi16(__U, __A, __W) ((__m512i) __builtin_ia32_blendmw_512_mask ((__v32hi) (__A), (__v32hi) (__W), (__mmask32) (__U))) #define _mm512_mask_blend_epi8(__U, __A, __W) ((__m512i) __builtin_ia32_blendmb_512_mask ((__v64qi) (__A), (__v64qi) (__W), (__mmask64) (__U))) #define _mm512_cmp_epi16_mask(X, Y, P) ((__mmask32) __builtin_ia32_cmpw512_mask ((__v32hi)(__m512i)(X), (__v32hi)(__m512i)(Y), (int)(P), (__mmask32)(-1))) @@ -2833,8 +2868,8 @@ _mm512_bsrli_epi128 (__m512i __A, const int __N) #define _mm512_bslli_epi128(A, N) ((__m512i)__builtin_ia32_pslldq512 ((__m512i)(A), (int)(N) * 8)) #define _mm512_bsrli_epi128(A, N) ((__m512i)__builtin_ia32_psrldq512 ((__m512i)(A), (int)(N) * 8)) #endif -#ifdef __DISABLE_AVX512BW__ -#undef __DISABLE_AVX512BW__ +#ifdef __DISABLE_AVX512BW_512__ +#undef __DISABLE_AVX512BW_512__ #pragma GCC pop_options #endif #endif diff --git a/third_party/intel/avx512cdintrin.internal.h b/third_party/intel/avx512cdintrin.internal.h index 83b643edb..a5218487a 100644 --- a/third_party/intel/avx512cdintrin.internal.h +++ b/third_party/intel/avx512cdintrin.internal.h @@ -6,7 +6,7 @@ #define _AVX512CDINTRIN_H_INCLUDED #ifndef __AVX512CD__ #pragma GCC push_options -#pragma GCC target("avx512cd") +#pragma GCC target("avx512cd,evex512") #define __DISABLE_AVX512CD__ #endif typedef long long __v8di __attribute__ ((__vector_size__ (64))); diff --git a/third_party/intel/avx512dqintrin.internal.h b/third_party/intel/avx512dqintrin.internal.h index 0cf6a7080..c32d7d877 100644 --- a/third_party/intel/avx512dqintrin.internal.h +++ b/third_party/intel/avx512dqintrin.internal.h @@ -4,9 +4,9 @@ #endif #ifndef _AVX512DQINTRIN_H_INCLUDED #define _AVX512DQINTRIN_H_INCLUDED -#ifndef __AVX512DQ__ +#if !defined (__AVX512DQ__) || defined (__EVEX512__) #pragma GCC push_options -#pragma GCC target("avx512dq") +#pragma GCC target("avx512dq,no-evex512") #define __DISABLE_AVX512DQ__ #endif extern __inline unsigned char @@ -138,6 +138,330 @@ _kandn_mask8 (__mmask8 __A, __mmask8 __B) { return (__mmask8) __builtin_ia32_kandnqi ((__mmask8) __A, (__mmask8) __B); } +#ifdef __OPTIMIZE__ +extern __inline __mmask8 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_kshiftli_mask8 (__mmask8 __A, unsigned int __B) +{ + return (__mmask8) __builtin_ia32_kshiftliqi ((__mmask8) __A, (__mmask8) __B); +} +extern __inline __mmask8 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_kshiftri_mask8 (__mmask8 __A, unsigned int __B) +{ + return (__mmask8) __builtin_ia32_kshiftriqi ((__mmask8) __A, (__mmask8) __B); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_reduce_sd (__m128d __A, __m128d __B, int __C) +{ + return (__m128d) __builtin_ia32_reducesd_mask ((__v2df) __A, + (__v2df) __B, __C, + (__v2df) _mm_avx512_setzero_pd (), + (__mmask8) -1); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_reduce_round_sd (__m128d __A, __m128d __B, int __C, const int __R) +{ + return (__m128d) __builtin_ia32_reducesd_mask_round ((__v2df) __A, + (__v2df) __B, __C, + (__v2df) + _mm_avx512_setzero_pd (), + (__mmask8) -1, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_reduce_sd (__m128d __W, __mmask8 __U, __m128d __A, + __m128d __B, int __C) +{ + return (__m128d) __builtin_ia32_reducesd_mask ((__v2df) __A, + (__v2df) __B, __C, + (__v2df) __W, + (__mmask8) __U); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_reduce_round_sd (__m128d __W, __mmask8 __U, __m128d __A, + __m128d __B, int __C, const int __R) +{ + return (__m128d) __builtin_ia32_reducesd_mask_round ((__v2df) __A, + (__v2df) __B, __C, + (__v2df) __W, + __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_reduce_sd (__mmask8 __U, __m128d __A, __m128d __B, int __C) +{ + return (__m128d) __builtin_ia32_reducesd_mask ((__v2df) __A, + (__v2df) __B, __C, + (__v2df) _mm_avx512_setzero_pd (), + (__mmask8) __U); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_reduce_round_sd (__mmask8 __U, __m128d __A, __m128d __B, + int __C, const int __R) +{ + return (__m128d) __builtin_ia32_reducesd_mask_round ((__v2df) __A, + (__v2df) __B, __C, + (__v2df) + _mm_avx512_setzero_pd (), + __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_reduce_ss (__m128 __A, __m128 __B, int __C) +{ + return (__m128) __builtin_ia32_reducess_mask ((__v4sf) __A, + (__v4sf) __B, __C, + (__v4sf) _mm_avx512_setzero_ps (), + (__mmask8) -1); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_reduce_round_ss (__m128 __A, __m128 __B, int __C, const int __R) +{ + return (__m128) __builtin_ia32_reducess_mask_round ((__v4sf) __A, + (__v4sf) __B, __C, + (__v4sf) + _mm_avx512_setzero_ps (), + (__mmask8) -1, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_reduce_ss (__m128 __W, __mmask8 __U, __m128 __A, + __m128 __B, int __C) +{ + return (__m128) __builtin_ia32_reducess_mask ((__v4sf) __A, + (__v4sf) __B, __C, + (__v4sf) __W, + (__mmask8) __U); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_reduce_round_ss (__m128 __W, __mmask8 __U, __m128 __A, + __m128 __B, int __C, const int __R) +{ + return (__m128) __builtin_ia32_reducess_mask_round ((__v4sf) __A, + (__v4sf) __B, __C, + (__v4sf) __W, + __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_reduce_ss (__mmask8 __U, __m128 __A, __m128 __B, int __C) +{ + return (__m128) __builtin_ia32_reducess_mask ((__v4sf) __A, + (__v4sf) __B, __C, + (__v4sf) _mm_avx512_setzero_ps (), + (__mmask8) __U); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_reduce_round_ss (__mmask8 __U, __m128 __A, __m128 __B, + int __C, const int __R) +{ + return (__m128) __builtin_ia32_reducess_mask_round ((__v4sf) __A, + (__v4sf) __B, __C, + (__v4sf) + _mm_avx512_setzero_ps (), + __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_range_sd (__m128d __A, __m128d __B, int __C) +{ + return (__m128d) __builtin_ia32_rangesd128_mask_round ((__v2df) __A, + (__v2df) __B, __C, + (__v2df) + _mm_avx512_setzero_pd (), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_range_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B, int __C) +{ + return (__m128d) __builtin_ia32_rangesd128_mask_round ((__v2df) __A, + (__v2df) __B, __C, + (__v2df) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_range_sd (__mmask8 __U, __m128d __A, __m128d __B, int __C) +{ + return (__m128d) __builtin_ia32_rangesd128_mask_round ((__v2df) __A, + (__v2df) __B, __C, + (__v2df) + _mm_avx512_setzero_pd (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_range_ss (__m128 __A, __m128 __B, int __C) +{ + return (__m128) __builtin_ia32_rangess128_mask_round ((__v4sf) __A, + (__v4sf) __B, __C, + (__v4sf) + _mm_avx512_setzero_ps (), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_range_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B, int __C) +{ + return (__m128) __builtin_ia32_rangess128_mask_round ((__v4sf) __A, + (__v4sf) __B, __C, + (__v4sf) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_range_ss (__mmask8 __U, __m128 __A, __m128 __B, int __C) +{ + return (__m128) __builtin_ia32_rangess128_mask_round ((__v4sf) __A, + (__v4sf) __B, __C, + (__v4sf) + _mm_avx512_setzero_ps (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_range_round_sd (__m128d __A, __m128d __B, int __C, const int __R) +{ + return (__m128d) __builtin_ia32_rangesd128_mask_round ((__v2df) __A, + (__v2df) __B, __C, + (__v2df) + _mm_avx512_setzero_pd (), + (__mmask8) -1, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_range_round_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B, + int __C, const int __R) +{ + return (__m128d) __builtin_ia32_rangesd128_mask_round ((__v2df) __A, + (__v2df) __B, __C, + (__v2df) __W, + (__mmask8) __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_range_round_sd (__mmask8 __U, __m128d __A, __m128d __B, int __C, + const int __R) +{ + return (__m128d) __builtin_ia32_rangesd128_mask_round ((__v2df) __A, + (__v2df) __B, __C, + (__v2df) + _mm_avx512_setzero_pd (), + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_range_round_ss (__m128 __A, __m128 __B, int __C, const int __R) +{ + return (__m128) __builtin_ia32_rangess128_mask_round ((__v4sf) __A, + (__v4sf) __B, __C, + (__v4sf) + _mm_avx512_setzero_ps (), + (__mmask8) -1, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_range_round_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B, + int __C, const int __R) +{ + return (__m128) __builtin_ia32_rangess128_mask_round ((__v4sf) __A, + (__v4sf) __B, __C, + (__v4sf) __W, + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_range_round_ss (__mmask8 __U, __m128 __A, __m128 __B, int __C, + const int __R) +{ + return (__m128) __builtin_ia32_rangess128_mask_round ((__v4sf) __A, + (__v4sf) __B, __C, + (__v4sf) + _mm_avx512_setzero_ps (), + (__mmask8) __U, __R); +} +extern __inline __mmask8 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_fpclass_ss_mask (__m128 __A, const int __imm) +{ + return (__mmask8) __builtin_ia32_fpclassss_mask ((__v4sf) __A, __imm, + (__mmask8) -1); +} +extern __inline __mmask8 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_fpclass_sd_mask (__m128d __A, const int __imm) +{ + return (__mmask8) __builtin_ia32_fpclasssd_mask ((__v2df) __A, __imm, + (__mmask8) -1); +} +extern __inline __mmask8 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fpclass_ss_mask (__mmask8 __U, __m128 __A, const int __imm) +{ + return (__mmask8) __builtin_ia32_fpclassss_mask ((__v4sf) __A, __imm, __U); +} +extern __inline __mmask8 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fpclass_sd_mask (__mmask8 __U, __m128d __A, const int __imm) +{ + return (__mmask8) __builtin_ia32_fpclasssd_mask ((__v2df) __A, __imm, __U); +} +#else +#define _kshiftli_mask8(X, Y) ((__mmask8) __builtin_ia32_kshiftliqi ((__mmask8)(X), (__mmask8)(Y))) +#define _kshiftri_mask8(X, Y) ((__mmask8) __builtin_ia32_kshiftriqi ((__mmask8)(X), (__mmask8)(Y))) +#define _mm_range_sd(A, B, C) ((__m128d) __builtin_ia32_rangesd128_mask_round ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__v2df) _mm_avx512_setzero_pd (), (__mmask8) -1, _MM_FROUND_CUR_DIRECTION)) +#define _mm_mask_range_sd(W, U, A, B, C) ((__m128d) __builtin_ia32_rangesd128_mask_round ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__v2df)(__m128d)(W), (__mmask8)(U), _MM_FROUND_CUR_DIRECTION)) +#define _mm_maskz_range_sd(U, A, B, C) ((__m128d) __builtin_ia32_rangesd128_mask_round ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__v2df) _mm_avx512_setzero_pd (), (__mmask8)(U), _MM_FROUND_CUR_DIRECTION)) +#define _mm_range_ss(A, B, C) ((__m128) __builtin_ia32_rangess128_mask_round ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__v4sf) _mm_avx512_setzero_ps (), (__mmask8) -1, _MM_FROUND_CUR_DIRECTION)) +#define _mm_mask_range_ss(W, U, A, B, C) ((__m128) __builtin_ia32_rangess128_mask_round ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__v4sf)(__m128)(W), (__mmask8)(U), _MM_FROUND_CUR_DIRECTION)) +#define _mm_maskz_range_ss(U, A, B, C) ((__m128) __builtin_ia32_rangess128_mask_round ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__v4sf) _mm_avx512_setzero_ps (), (__mmask8)(U), _MM_FROUND_CUR_DIRECTION)) +#define _mm_range_round_sd(A, B, C, R) ((__m128d) __builtin_ia32_rangesd128_mask_round ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__v2df) _mm_avx512_setzero_pd (), (__mmask8) -1, (R))) +#define _mm_mask_range_round_sd(W, U, A, B, C, R) ((__m128d) __builtin_ia32_rangesd128_mask_round ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__v2df)(__m128d)(W), (__mmask8)(U), (R))) +#define _mm_maskz_range_round_sd(U, A, B, C, R) ((__m128d) __builtin_ia32_rangesd128_mask_round ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__v2df) _mm_avx512_setzero_pd (), (__mmask8)(U), (R))) +#define _mm_range_round_ss(A, B, C, R) ((__m128) __builtin_ia32_rangess128_mask_round ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__v4sf) _mm_avx512_setzero_ps (), (__mmask8) -1, (R))) +#define _mm_mask_range_round_ss(W, U, A, B, C, R) ((__m128) __builtin_ia32_rangess128_mask_round ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__v4sf)(__m128)(W), (__mmask8)(U), (R))) +#define _mm_maskz_range_round_ss(U, A, B, C, R) ((__m128) __builtin_ia32_rangess128_mask_round ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__v4sf) _mm_avx512_setzero_ps (), (__mmask8)(U), (R))) +#define _mm_fpclass_ss_mask(X, C) ((__mmask8) __builtin_ia32_fpclassss_mask ((__v4sf) (__m128) (X), (int) (C), (__mmask8) (-1))) +#define _mm_fpclass_sd_mask(X, C) ((__mmask8) __builtin_ia32_fpclasssd_mask ((__v2df) (__m128d) (X), (int) (C), (__mmask8) (-1))) +#define _mm_mask_fpclass_ss_mask(X, C, U) ((__mmask8) __builtin_ia32_fpclassss_mask ((__v4sf) (__m128) (X), (int) (C), (__mmask8) (U))) +#define _mm_mask_fpclass_sd_mask(X, C, U) ((__mmask8) __builtin_ia32_fpclasssd_mask ((__v2df) (__m128d) (X), (int) (C), (__mmask8) (U))) +#define _mm_reduce_sd(A, B, C) ((__m128d) __builtin_ia32_reducesd_mask ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__v2df) _mm_avx512_setzero_pd (), (__mmask8)-1)) +#define _mm_mask_reduce_sd(W, U, A, B, C) ((__m128d) __builtin_ia32_reducesd_mask ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__v2df)(__m128d)(W), (__mmask8)(U))) +#define _mm_maskz_reduce_sd(U, A, B, C) ((__m128d) __builtin_ia32_reducesd_mask ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__v2df) _mm_avx512_setzero_pd (), (__mmask8)(U))) +#define _mm_reduce_round_sd(A, B, C, R) ((__m128d) __builtin_ia32_reducesd_round ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__mmask8)(U), (int)(R))) +#define _mm_mask_reduce_round_sd(W, U, A, B, C, R) ((__m128d) __builtin_ia32_reducesd_mask_round ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__v2df)(__m128d)(W), (__mmask8)(U), (int)(R))) +#define _mm_maskz_reduce_round_sd(U, A, B, C, R) ((__m128d) __builtin_ia32_reducesd_mask_round ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__v2df) _mm_avx512_setzero_pd (), (__mmask8)(U), (int)(R))) +#define _mm_reduce_ss(A, B, C) ((__m128) __builtin_ia32_reducess_mask ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__v4sf) _mm_avx512_setzero_ps (), (__mmask8)-1)) +#define _mm_mask_reduce_ss(W, U, A, B, C) ((__m128) __builtin_ia32_reducess_mask ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__v4sf)(__m128)(W), (__mmask8)(U))) +#define _mm_maskz_reduce_ss(U, A, B, C) ((__m128) __builtin_ia32_reducess_mask ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__v4sf) _mm_avx512_setzero_ps (), (__mmask8)(U))) +#define _mm_reduce_round_ss(A, B, C, R) ((__m128) __builtin_ia32_reducess_round ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__mmask8)(U), (int)(R))) +#define _mm_mask_reduce_round_ss(W, U, A, B, C, R) ((__m128) __builtin_ia32_reducess_mask_round ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__v4sf)(__m128)(W), (__mmask8)(U), (int)(R))) +#define _mm_maskz_reduce_round_ss(U, A, B, C, R) ((__m128) __builtin_ia32_reducesd_mask_round ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__v4sf) _mm_avx512_setzero_ps (), (__mmask8)(U), (int)(R))) +#endif +#ifdef __DISABLE_AVX512DQ__ +#undef __DISABLE_AVX512DQ__ +#pragma GCC pop_options +#endif +#if !defined (__AVX512DQ__) || !defined (__EVEX512__) +#pragma GCC push_options +#pragma GCC target("avx512dq,evex512") +#define __DISABLE_AVX512DQ_512__ +#endif extern __inline __m512d __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_broadcast_f64x2 (__m128d __A) @@ -939,18 +1263,6 @@ _mm512_maskz_cvtepu64_pd (__mmask8 __U, __m512i __A) _MM_FROUND_CUR_DIRECTION); } #ifdef __OPTIMIZE__ -extern __inline __mmask8 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_kshiftli_mask8 (__mmask8 __A, unsigned int __B) -{ - return (__mmask8) __builtin_ia32_kshiftliqi ((__mmask8) __A, (__mmask8) __B); -} -extern __inline __mmask8 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_kshiftri_mask8 (__mmask8 __A, unsigned int __B) -{ - return (__mmask8) __builtin_ia32_kshiftriqi ((__mmask8) __A, (__mmask8) __B); -} extern __inline __m512d __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_range_pd (__m512d __A, __m512d __B, int __C) @@ -1017,276 +1329,6 @@ _mm512_maskz_range_ps (__mmask16 __U, __m512 __A, __m512 __B, int __C) (__mmask16) __U, _MM_FROUND_CUR_DIRECTION); } -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_reduce_sd (__m128d __A, __m128d __B, int __C) -{ - return (__m128d) __builtin_ia32_reducesd_mask ((__v2df) __A, - (__v2df) __B, __C, - (__v2df) _mm_setzero_pd (), - (__mmask8) -1); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_reduce_round_sd (__m128d __A, __m128d __B, int __C, const int __R) -{ - return (__m128d) __builtin_ia32_reducesd_mask_round ((__v2df) __A, - (__v2df) __B, __C, - (__v2df) - _mm_setzero_pd (), - (__mmask8) -1, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_reduce_sd (__m128d __W, __mmask8 __U, __m128d __A, - __m128d __B, int __C) -{ - return (__m128d) __builtin_ia32_reducesd_mask ((__v2df) __A, - (__v2df) __B, __C, - (__v2df) __W, - (__mmask8) __U); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_reduce_round_sd (__m128d __W, __mmask8 __U, __m128d __A, - __m128d __B, int __C, const int __R) -{ - return (__m128d) __builtin_ia32_reducesd_mask_round ((__v2df) __A, - (__v2df) __B, __C, - (__v2df) __W, - __U, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_reduce_sd (__mmask8 __U, __m128d __A, __m128d __B, int __C) -{ - return (__m128d) __builtin_ia32_reducesd_mask ((__v2df) __A, - (__v2df) __B, __C, - (__v2df) _mm_setzero_pd (), - (__mmask8) __U); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_reduce_round_sd (__mmask8 __U, __m128d __A, __m128d __B, - int __C, const int __R) -{ - return (__m128d) __builtin_ia32_reducesd_mask_round ((__v2df) __A, - (__v2df) __B, __C, - (__v2df) - _mm_setzero_pd (), - __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_reduce_ss (__m128 __A, __m128 __B, int __C) -{ - return (__m128) __builtin_ia32_reducess_mask ((__v4sf) __A, - (__v4sf) __B, __C, - (__v4sf) _mm_setzero_ps (), - (__mmask8) -1); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_reduce_round_ss (__m128 __A, __m128 __B, int __C, const int __R) -{ - return (__m128) __builtin_ia32_reducess_mask_round ((__v4sf) __A, - (__v4sf) __B, __C, - (__v4sf) - _mm_setzero_ps (), - (__mmask8) -1, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_reduce_ss (__m128 __W, __mmask8 __U, __m128 __A, - __m128 __B, int __C) -{ - return (__m128) __builtin_ia32_reducess_mask ((__v4sf) __A, - (__v4sf) __B, __C, - (__v4sf) __W, - (__mmask8) __U); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_reduce_round_ss (__m128 __W, __mmask8 __U, __m128 __A, - __m128 __B, int __C, const int __R) -{ - return (__m128) __builtin_ia32_reducess_mask_round ((__v4sf) __A, - (__v4sf) __B, __C, - (__v4sf) __W, - __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_reduce_ss (__mmask8 __U, __m128 __A, __m128 __B, int __C) -{ - return (__m128) __builtin_ia32_reducess_mask ((__v4sf) __A, - (__v4sf) __B, __C, - (__v4sf) _mm_setzero_ps (), - (__mmask8) __U); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_reduce_round_ss (__mmask8 __U, __m128 __A, __m128 __B, - int __C, const int __R) -{ - return (__m128) __builtin_ia32_reducess_mask_round ((__v4sf) __A, - (__v4sf) __B, __C, - (__v4sf) - _mm_setzero_ps (), - __U, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_range_sd (__m128d __A, __m128d __B, int __C) -{ - return (__m128d) __builtin_ia32_rangesd128_mask_round ((__v2df) __A, - (__v2df) __B, __C, - (__v2df) - _mm_setzero_pd (), - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_range_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B, int __C) -{ - return (__m128d) __builtin_ia32_rangesd128_mask_round ((__v2df) __A, - (__v2df) __B, __C, - (__v2df) __W, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_range_sd (__mmask8 __U, __m128d __A, __m128d __B, int __C) -{ - return (__m128d) __builtin_ia32_rangesd128_mask_round ((__v2df) __A, - (__v2df) __B, __C, - (__v2df) - _mm_setzero_pd (), - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_range_ss (__m128 __A, __m128 __B, int __C) -{ - return (__m128) __builtin_ia32_rangess128_mask_round ((__v4sf) __A, - (__v4sf) __B, __C, - (__v4sf) - _mm_setzero_ps (), - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_range_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B, int __C) -{ - return (__m128) __builtin_ia32_rangess128_mask_round ((__v4sf) __A, - (__v4sf) __B, __C, - (__v4sf) __W, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_range_ss (__mmask8 __U, __m128 __A, __m128 __B, int __C) -{ - return (__m128) __builtin_ia32_rangess128_mask_round ((__v4sf) __A, - (__v4sf) __B, __C, - (__v4sf) - _mm_setzero_ps (), - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_range_round_sd (__m128d __A, __m128d __B, int __C, const int __R) -{ - return (__m128d) __builtin_ia32_rangesd128_mask_round ((__v2df) __A, - (__v2df) __B, __C, - (__v2df) - _mm_setzero_pd (), - (__mmask8) -1, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_range_round_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B, - int __C, const int __R) -{ - return (__m128d) __builtin_ia32_rangesd128_mask_round ((__v2df) __A, - (__v2df) __B, __C, - (__v2df) __W, - (__mmask8) __U, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_range_round_sd (__mmask8 __U, __m128d __A, __m128d __B, int __C, - const int __R) -{ - return (__m128d) __builtin_ia32_rangesd128_mask_round ((__v2df) __A, - (__v2df) __B, __C, - (__v2df) - _mm_setzero_pd (), - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_range_round_ss (__m128 __A, __m128 __B, int __C, const int __R) -{ - return (__m128) __builtin_ia32_rangess128_mask_round ((__v4sf) __A, - (__v4sf) __B, __C, - (__v4sf) - _mm_setzero_ps (), - (__mmask8) -1, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_range_round_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B, - int __C, const int __R) -{ - return (__m128) __builtin_ia32_rangess128_mask_round ((__v4sf) __A, - (__v4sf) __B, __C, - (__v4sf) __W, - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_range_round_ss (__mmask8 __U, __m128 __A, __m128 __B, int __C, - const int __R) -{ - return (__m128) __builtin_ia32_rangess128_mask_round ((__v4sf) __A, - (__v4sf) __B, __C, - (__v4sf) - _mm_setzero_ps (), - (__mmask8) __U, __R); -} -extern __inline __mmask8 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_fpclass_ss_mask (__m128 __A, const int __imm) -{ - return (__mmask8) __builtin_ia32_fpclassss_mask ((__v4sf) __A, __imm, - (__mmask8) -1); -} -extern __inline __mmask8 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_fpclass_sd_mask (__m128d __A, const int __imm) -{ - return (__mmask8) __builtin_ia32_fpclasssd_mask ((__v2df) __A, __imm, - (__mmask8) -1); -} -extern __inline __mmask8 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fpclass_ss_mask (__mmask8 __U, __m128 __A, const int __imm) -{ - return (__mmask8) __builtin_ia32_fpclassss_mask ((__v4sf) __A, __imm, __U); -} -extern __inline __mmask8 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fpclass_sd_mask (__mmask8 __U, __m128d __A, const int __imm) -{ - return (__mmask8) __builtin_ia32_fpclasssd_mask ((__v2df) __A, __imm, __U); -} extern __inline __m512i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_cvtt_roundpd_epi64 (__m512d __A, const int __R) @@ -2145,20 +2187,6 @@ _mm512_fpclass_ps_mask (__m512 __A, const int __imm) (__mmask16) -1); } #else -#define _kshiftli_mask8(X, Y) ((__mmask8) __builtin_ia32_kshiftliqi ((__mmask8)(X), (__mmask8)(Y))) -#define _kshiftri_mask8(X, Y) ((__mmask8) __builtin_ia32_kshiftriqi ((__mmask8)(X), (__mmask8)(Y))) -#define _mm_range_sd(A, B, C) ((__m128d) __builtin_ia32_rangesd128_mask_round ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__v2df) _mm_setzero_pd (), (__mmask8) -1, _MM_FROUND_CUR_DIRECTION)) -#define _mm_mask_range_sd(W, U, A, B, C) ((__m128d) __builtin_ia32_rangesd128_mask_round ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__v2df)(__m128d)(W), (__mmask8)(U), _MM_FROUND_CUR_DIRECTION)) -#define _mm_maskz_range_sd(U, A, B, C) ((__m128d) __builtin_ia32_rangesd128_mask_round ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__v2df) _mm_setzero_pd (), (__mmask8)(U), _MM_FROUND_CUR_DIRECTION)) -#define _mm_range_ss(A, B, C) ((__m128) __builtin_ia32_rangess128_mask_round ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__v4sf) _mm_setzero_ps (), (__mmask8) -1, _MM_FROUND_CUR_DIRECTION)) -#define _mm_mask_range_ss(W, U, A, B, C) ((__m128) __builtin_ia32_rangess128_mask_round ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__v4sf)(__m128)(W), (__mmask8)(U), _MM_FROUND_CUR_DIRECTION)) -#define _mm_maskz_range_ss(U, A, B, C) ((__m128) __builtin_ia32_rangess128_mask_round ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__v4sf) _mm_setzero_ps (), (__mmask8)(U), _MM_FROUND_CUR_DIRECTION)) -#define _mm_range_round_sd(A, B, C, R) ((__m128d) __builtin_ia32_rangesd128_mask_round ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__v2df) _mm_setzero_pd (), (__mmask8) -1, (R))) -#define _mm_mask_range_round_sd(W, U, A, B, C, R) ((__m128d) __builtin_ia32_rangesd128_mask_round ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__v2df)(__m128d)(W), (__mmask8)(U), (R))) -#define _mm_maskz_range_round_sd(U, A, B, C, R) ((__m128d) __builtin_ia32_rangesd128_mask_round ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__v2df) _mm_setzero_pd (), (__mmask8)(U), (R))) -#define _mm_range_round_ss(A, B, C, R) ((__m128) __builtin_ia32_rangess128_mask_round ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__v4sf) _mm_setzero_ps (), (__mmask8) -1, (R))) -#define _mm_mask_range_round_ss(W, U, A, B, C, R) ((__m128) __builtin_ia32_rangess128_mask_round ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__v4sf)(__m128)(W), (__mmask8)(U), (R))) -#define _mm_maskz_range_round_ss(U, A, B, C, R) ((__m128) __builtin_ia32_rangess128_mask_round ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__v4sf) _mm_setzero_ps (), (__mmask8)(U), (R))) #define _mm512_cvtt_roundpd_epi64(A, B) ((__m512i)__builtin_ia32_cvttpd2qq512_mask ((A), (__v8di) _mm512_setzero_si512 (), -1, (B))) #define _mm512_mask_cvtt_roundpd_epi64(W, U, A, B) ((__m512i)__builtin_ia32_cvttpd2qq512_mask ((A), (__v8di)(W), (U), (B))) #define _mm512_maskz_cvtt_roundpd_epi64(U, A, B) ((__m512i)__builtin_ia32_cvttpd2qq512_mask ((A), (__v8di)_mm512_setzero_si512 (), (U), (B))) @@ -2243,29 +2271,13 @@ _mm512_fpclass_ps_mask (__m512 __A, const int __imm) #define _mm512_inserti32x8(X, Y, C) ((__m512i) __builtin_ia32_inserti32x8_mask ((__v16si)(__m512i) (X), (__v8si)(__m256i) (Y), (int) (C), (__v16si)(__m512i)_mm512_setzero_si512 (), (__mmask16)-1)) #define _mm512_mask_inserti32x8(W, U, X, Y, C) ((__m512i) __builtin_ia32_inserti32x8_mask ((__v16si)(__m512i) (X), (__v8si)(__m256i) (Y), (int) (C), (__v16si)(__m512i)(W), (__mmask16)(U))) #define _mm512_maskz_inserti32x8(U, X, Y, C) ((__m512i) __builtin_ia32_inserti32x8_mask ((__v16si)(__m512i) (X), (__v8si)(__m256i) (Y), (int) (C), (__v16si)(__m512i)_mm512_setzero_si512 (), (__mmask16)(U))) -#define _mm_fpclass_ss_mask(X, C) ((__mmask8) __builtin_ia32_fpclassss_mask ((__v4sf) (__m128) (X), (int) (C), (__mmask8) (-1))) -#define _mm_fpclass_sd_mask(X, C) ((__mmask8) __builtin_ia32_fpclasssd_mask ((__v2df) (__m128d) (X), (int) (C), (__mmask8) (-1))) -#define _mm_mask_fpclass_ss_mask(X, C, U) ((__mmask8) __builtin_ia32_fpclassss_mask ((__v4sf) (__m128) (X), (int) (C), (__mmask8) (U))) -#define _mm_mask_fpclass_sd_mask(X, C, U) ((__mmask8) __builtin_ia32_fpclasssd_mask ((__v2df) (__m128d) (X), (int) (C), (__mmask8) (U))) #define _mm512_mask_fpclass_pd_mask(u, X, C) ((__mmask8) __builtin_ia32_fpclasspd512_mask ((__v8df) (__m512d) (X), (int) (C), (__mmask8)(u))) #define _mm512_mask_fpclass_ps_mask(u, x, c) ((__mmask16) __builtin_ia32_fpclassps512_mask ((__v16sf) (__m512) (x), (int) (c),(__mmask16)(u))) #define _mm512_fpclass_pd_mask(X, C) ((__mmask8) __builtin_ia32_fpclasspd512_mask ((__v8df) (__m512d) (X), (int) (C), (__mmask8)-1)) #define _mm512_fpclass_ps_mask(x, c) ((__mmask16) __builtin_ia32_fpclassps512_mask ((__v16sf) (__m512) (x), (int) (c),(__mmask16)-1)) -#define _mm_reduce_sd(A, B, C) ((__m128d) __builtin_ia32_reducesd_mask ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__v2df) _mm_setzero_pd (), (__mmask8)-1)) -#define _mm_mask_reduce_sd(W, U, A, B, C) ((__m128d) __builtin_ia32_reducesd_mask ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__v2df)(__m128d)(W), (__mmask8)(U))) -#define _mm_maskz_reduce_sd(U, A, B, C) ((__m128d) __builtin_ia32_reducesd_mask ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__v2df) _mm_setzero_pd (), (__mmask8)(U))) -#define _mm_reduce_round_sd(A, B, C, R) ((__m128d) __builtin_ia32_reducesd_round ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__mmask8)(U), (int)(R))) -#define _mm_mask_reduce_round_sd(W, U, A, B, C, R) ((__m128d) __builtin_ia32_reducesd_mask_round ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__v2df)(__m128d)(W), (__mmask8)(U), (int)(R))) -#define _mm_maskz_reduce_round_sd(U, A, B, C, R) ((__m128d) __builtin_ia32_reducesd_mask_round ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__v2df) _mm_setzero_pd (), (__mmask8)(U), (int)(R))) -#define _mm_reduce_ss(A, B, C) ((__m128) __builtin_ia32_reducess_mask ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__v4sf) _mm_setzero_ps (), (__mmask8)-1)) -#define _mm_mask_reduce_ss(W, U, A, B, C) ((__m128) __builtin_ia32_reducess_mask ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__v4sf)(__m128)(W), (__mmask8)(U))) -#define _mm_maskz_reduce_ss(U, A, B, C) ((__m128) __builtin_ia32_reducess_mask ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__v4sf) _mm_setzero_ps (), (__mmask8)(U))) -#define _mm_reduce_round_ss(A, B, C, R) ((__m128) __builtin_ia32_reducess_round ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__mmask8)(U), (int)(R))) -#define _mm_mask_reduce_round_ss(W, U, A, B, C, R) ((__m128) __builtin_ia32_reducess_mask_round ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__v4sf)(__m128)(W), (__mmask8)(U), (int)(R))) -#define _mm_maskz_reduce_round_ss(U, A, B, C, R) ((__m128) __builtin_ia32_reducesd_mask_round ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__v4sf) _mm_setzero_ps (), (__mmask8)(U), (int)(R))) #endif -#ifdef __DISABLE_AVX512DQ__ -#undef __DISABLE_AVX512DQ__ +#ifdef __DISABLE_AVX512DQ_512__ +#undef __DISABLE_AVX512DQ_512__ #pragma GCC pop_options #endif #endif diff --git a/third_party/intel/avx512erintrin.internal.h b/third_party/intel/avx512erintrin.internal.h index d50aba432..0422ce7c5 100644 --- a/third_party/intel/avx512erintrin.internal.h +++ b/third_party/intel/avx512erintrin.internal.h @@ -6,7 +6,7 @@ #define _AVX512ERINTRIN_H_INCLUDED #ifndef __AVX512ER__ #pragma GCC push_options -#pragma GCC target("avx512er") +#pragma GCC target("avx512er,evex512") #define __DISABLE_AVX512ER__ #endif typedef double __v8df __attribute__ ((__vector_size__ (64))); @@ -20,9 +20,8 @@ extern __inline __m512d __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_exp2a23_round_pd (__m512d __A, int __R) { - __m512d __W; return (__m512d) __builtin_ia32_exp2pd_mask ((__v8df) __A, - (__v8df) __W, + (__v8df) _mm512_undefined_pd (), (__mmask8) -1, __R); } extern __inline __m512d @@ -45,9 +44,8 @@ extern __inline __m512 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_exp2a23_round_ps (__m512 __A, int __R) { - __m512 __W; return (__m512) __builtin_ia32_exp2ps_mask ((__v16sf) __A, - (__v16sf) __W, + (__v16sf) _mm512_undefined_ps (), (__mmask16) -1, __R); } extern __inline __m512 @@ -70,9 +68,8 @@ extern __inline __m512d __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_rcp28_round_pd (__m512d __A, int __R) { - __m512d __W; return (__m512d) __builtin_ia32_rcp28pd_mask ((__v8df) __A, - (__v8df) __W, + (__v8df) _mm512_undefined_pd (), (__mmask8) -1, __R); } extern __inline __m512d @@ -95,9 +92,8 @@ extern __inline __m512 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_rcp28_round_ps (__m512 __A, int __R) { - __m512 __W; return (__m512) __builtin_ia32_rcp28ps_mask ((__v16sf) __A, - (__v16sf) __W, + (__v16sf) _mm512_undefined_ps (), (__mmask16) -1, __R); } extern __inline __m512 @@ -180,9 +176,8 @@ extern __inline __m512d __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_rsqrt28_round_pd (__m512d __A, int __R) { - __m512d __W; return (__m512d) __builtin_ia32_rsqrt28pd_mask ((__v8df) __A, - (__v8df) __W, + (__v8df) _mm512_undefined_pd (), (__mmask8) -1, __R); } extern __inline __m512d @@ -205,9 +200,8 @@ extern __inline __m512 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_rsqrt28_round_ps (__m512 __A, int __R) { - __m512 __W; return (__m512) __builtin_ia32_rsqrt28ps_mask ((__v16sf) __A, - (__v16sf) __W, + (__v16sf) _mm512_undefined_ps (), (__mmask16) -1, __R); } extern __inline __m512 diff --git a/third_party/intel/avx512fintrin.internal.h b/third_party/intel/avx512fintrin.internal.h index a2c2c788c..b940a86ff 100644 --- a/third_party/intel/avx512fintrin.internal.h +++ b/third_party/intel/avx512fintrin.internal.h @@ -4,11 +4,2925 @@ #endif #ifndef _AVX512FINTRIN_H_INCLUDED #define _AVX512FINTRIN_H_INCLUDED -#ifndef __AVX512F__ +#if !defined (__AVX512F__) || defined (__EVEX512__) #pragma GCC push_options -#pragma GCC target("avx512f") +#pragma GCC target("avx512f,no-evex512") #define __DISABLE_AVX512F__ #endif +typedef unsigned char __mmask8; +typedef unsigned short __mmask16; +typedef unsigned int __mmask32; +typedef enum +{ + _MM_MANT_NORM_1_2, + _MM_MANT_NORM_p5_2, + _MM_MANT_NORM_p5_1, + _MM_MANT_NORM_p75_1p5 +} _MM_MANTISSA_NORM_ENUM; +typedef enum +{ + _MM_MANT_SIGN_src, + _MM_MANT_SIGN_zero, + _MM_MANT_SIGN_nan +} _MM_MANTISSA_SIGN_ENUM; +extern __inline __m128 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_avx512_undefined_ps (void) +{ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Winit-self" + __m128 __Y = __Y; +#pragma GCC diagnostic pop + return __Y; +} +extern __inline __m128d __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_avx512_undefined_pd (void) +{ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Winit-self" + __m128d __Y = __Y; +#pragma GCC diagnostic pop + return __Y; +} +extern __inline __m128 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_avx512_setzero_ps (void) +{ + return __extension__ (__m128){ 0.0f, 0.0f, 0.0f, 0.0f }; +} +extern __inline __m128d __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_avx512_setzero_pd (void) +{ + return __extension__ (__m128d){ 0.0, 0.0 }; +} +#ifdef __OPTIMIZE__ +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_add_round_sd (__m128d __A, __m128d __B, const int __R) +{ + return (__m128d) __builtin_ia32_addsd_round ((__v2df) __A, + (__v2df) __B, + __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_add_round_sd (__m128d __W, __mmask8 __U, __m128d __A, + __m128d __B, const int __R) +{ + return (__m128d) __builtin_ia32_addsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_add_round_sd (__mmask8 __U, __m128d __A, __m128d __B, + const int __R) +{ + return (__m128d) __builtin_ia32_addsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) + _mm_avx512_setzero_pd (), + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_add_round_ss (__m128 __A, __m128 __B, const int __R) +{ + return (__m128) __builtin_ia32_addss_round ((__v4sf) __A, + (__v4sf) __B, + __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_add_round_ss (__m128 __W, __mmask8 __U, __m128 __A, + __m128 __B, const int __R) +{ + return (__m128) __builtin_ia32_addss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_add_round_ss (__mmask8 __U, __m128 __A, __m128 __B, + const int __R) +{ + return (__m128) __builtin_ia32_addss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) + _mm_avx512_setzero_ps (), + (__mmask8) __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_sub_round_sd (__m128d __A, __m128d __B, const int __R) +{ + return (__m128d) __builtin_ia32_subsd_round ((__v2df) __A, + (__v2df) __B, + __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_sub_round_sd (__m128d __W, __mmask8 __U, __m128d __A, + __m128d __B, const int __R) +{ + return (__m128d) __builtin_ia32_subsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_sub_round_sd (__mmask8 __U, __m128d __A, __m128d __B, + const int __R) +{ + return (__m128d) __builtin_ia32_subsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) + _mm_avx512_setzero_pd (), + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_sub_round_ss (__m128 __A, __m128 __B, const int __R) +{ + return (__m128) __builtin_ia32_subss_round ((__v4sf) __A, + (__v4sf) __B, + __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_sub_round_ss (__m128 __W, __mmask8 __U, __m128 __A, + __m128 __B, const int __R) +{ + return (__m128) __builtin_ia32_subss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_sub_round_ss (__mmask8 __U, __m128 __A, __m128 __B, + const int __R) +{ + return (__m128) __builtin_ia32_subss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) + _mm_avx512_setzero_ps (), + (__mmask8) __U, __R); +} +#else +#define _mm_add_round_sd(A, B, C) (__m128d)__builtin_ia32_addsd_round(A, B, C) +#define _mm_mask_add_round_sd(W, U, A, B, C) (__m128d)__builtin_ia32_addsd_mask_round(A, B, W, U, C) +#define _mm_maskz_add_round_sd(U, A, B, C) (__m128d)__builtin_ia32_addsd_mask_round(A, B, (__v2df)_mm_avx512_setzero_pd(), U, C) +#define _mm_add_round_ss(A, B, C) (__m128)__builtin_ia32_addss_round(A, B, C) +#define _mm_mask_add_round_ss(W, U, A, B, C) (__m128)__builtin_ia32_addss_mask_round(A, B, W, U, C) +#define _mm_maskz_add_round_ss(U, A, B, C) (__m128)__builtin_ia32_addss_mask_round(A, B, (__v4sf)_mm_avx512_setzero_ps(), U, C) +#define _mm_sub_round_sd(A, B, C) (__m128d)__builtin_ia32_subsd_round(A, B, C) +#define _mm_mask_sub_round_sd(W, U, A, B, C) (__m128d)__builtin_ia32_subsd_mask_round(A, B, W, U, C) +#define _mm_maskz_sub_round_sd(U, A, B, C) (__m128d)__builtin_ia32_subsd_mask_round(A, B, (__v2df)_mm_avx512_setzero_pd(), U, C) +#define _mm_sub_round_ss(A, B, C) (__m128)__builtin_ia32_subss_round(A, B, C) +#define _mm_mask_sub_round_ss(W, U, A, B, C) (__m128)__builtin_ia32_subss_mask_round(A, B, W, U, C) +#define _mm_maskz_sub_round_ss(U, A, B, C) (__m128)__builtin_ia32_subss_mask_round(A, B, (__v4sf)_mm_avx512_setzero_ps(), U, C) +#endif +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_rcp14_sd (__m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_rcp14sd ((__v2df) __B, + (__v2df) __A); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_rcp14_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_rcp14sd_mask ((__v2df) __B, + (__v2df) __A, + (__v2df) __W, + (__mmask8) __U); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_rcp14_sd (__mmask8 __U, __m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_rcp14sd_mask ((__v2df) __B, + (__v2df) __A, + (__v2df) _mm_avx512_setzero_ps (), + (__mmask8) __U); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_rcp14_ss (__m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_rcp14ss ((__v4sf) __B, + (__v4sf) __A); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_rcp14_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_rcp14ss_mask ((__v4sf) __B, + (__v4sf) __A, + (__v4sf) __W, + (__mmask8) __U); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_rcp14_ss (__mmask8 __U, __m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_rcp14ss_mask ((__v4sf) __B, + (__v4sf) __A, + (__v4sf) _mm_avx512_setzero_ps (), + (__mmask8) __U); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_rsqrt14_sd (__m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_rsqrt14sd ((__v2df) __B, + (__v2df) __A); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_rsqrt14_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_rsqrt14sd_mask ((__v2df) __B, + (__v2df) __A, + (__v2df) __W, + (__mmask8) __U); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_rsqrt14_sd (__mmask8 __U, __m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_rsqrt14sd_mask ((__v2df) __B, + (__v2df) __A, + (__v2df) _mm_avx512_setzero_pd (), + (__mmask8) __U); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_rsqrt14_ss (__m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_rsqrt14ss ((__v4sf) __B, + (__v4sf) __A); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_rsqrt14_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_rsqrt14ss_mask ((__v4sf) __B, + (__v4sf) __A, + (__v4sf) __W, + (__mmask8) __U); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_rsqrt14_ss (__mmask8 __U, __m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_rsqrt14ss_mask ((__v4sf) __B, + (__v4sf) __A, + (__v4sf) _mm_avx512_setzero_ps (), + (__mmask8) __U); +} +#ifdef __OPTIMIZE__ +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_sqrt_round_sd (__m128d __A, __m128d __B, const int __R) +{ + return (__m128d) __builtin_ia32_sqrtsd_mask_round ((__v2df) __B, + (__v2df) __A, + (__v2df) + _mm_avx512_setzero_pd (), + (__mmask8) -1, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_sqrt_round_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B, + const int __R) +{ + return (__m128d) __builtin_ia32_sqrtsd_mask_round ((__v2df) __B, + (__v2df) __A, + (__v2df) __W, + (__mmask8) __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_sqrt_round_sd (__mmask8 __U, __m128d __A, __m128d __B, const int __R) +{ + return (__m128d) __builtin_ia32_sqrtsd_mask_round ((__v2df) __B, + (__v2df) __A, + (__v2df) + _mm_avx512_setzero_pd (), + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_sqrt_round_ss (__m128 __A, __m128 __B, const int __R) +{ + return (__m128) __builtin_ia32_sqrtss_mask_round ((__v4sf) __B, + (__v4sf) __A, + (__v4sf) + _mm_avx512_setzero_ps (), + (__mmask8) -1, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_sqrt_round_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B, + const int __R) +{ + return (__m128) __builtin_ia32_sqrtss_mask_round ((__v4sf) __B, + (__v4sf) __A, + (__v4sf) __W, + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_sqrt_round_ss (__mmask8 __U, __m128 __A, __m128 __B, const int __R) +{ + return (__m128) __builtin_ia32_sqrtss_mask_round ((__v4sf) __B, + (__v4sf) __A, + (__v4sf) + _mm_avx512_setzero_ps (), + (__mmask8) __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mul_round_sd (__m128d __A, __m128d __B, const int __R) +{ + return (__m128d) __builtin_ia32_mulsd_round ((__v2df) __A, + (__v2df) __B, + __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_mul_round_sd (__m128d __W, __mmask8 __U, __m128d __A, + __m128d __B, const int __R) +{ + return (__m128d) __builtin_ia32_mulsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_mul_round_sd (__mmask8 __U, __m128d __A, __m128d __B, + const int __R) +{ + return (__m128d) __builtin_ia32_mulsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) + _mm_avx512_setzero_pd (), + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mul_round_ss (__m128 __A, __m128 __B, const int __R) +{ + return (__m128) __builtin_ia32_mulss_round ((__v4sf) __A, + (__v4sf) __B, + __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_mul_round_ss (__m128 __W, __mmask8 __U, __m128 __A, + __m128 __B, const int __R) +{ + return (__m128) __builtin_ia32_mulss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_mul_round_ss (__mmask8 __U, __m128 __A, __m128 __B, + const int __R) +{ + return (__m128) __builtin_ia32_mulss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) + _mm_avx512_setzero_ps (), + (__mmask8) __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_div_round_sd (__m128d __A, __m128d __B, const int __R) +{ + return (__m128d) __builtin_ia32_divsd_round ((__v2df) __A, + (__v2df) __B, + __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_div_round_sd (__m128d __W, __mmask8 __U, __m128d __A, + __m128d __B, const int __R) +{ + return (__m128d) __builtin_ia32_divsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_div_round_sd (__mmask8 __U, __m128d __A, __m128d __B, + const int __R) +{ + return (__m128d) __builtin_ia32_divsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) + _mm_avx512_setzero_pd (), + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_div_round_ss (__m128 __A, __m128 __B, const int __R) +{ + return (__m128) __builtin_ia32_divss_round ((__v4sf) __A, + (__v4sf) __B, + __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_div_round_ss (__m128 __W, __mmask8 __U, __m128 __A, + __m128 __B, const int __R) +{ + return (__m128) __builtin_ia32_divss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_div_round_ss (__mmask8 __U, __m128 __A, __m128 __B, + const int __R) +{ + return (__m128) __builtin_ia32_divss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) + _mm_avx512_setzero_ps (), + (__mmask8) __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_scalef_round_sd (__m128d __A, __m128d __B, const int __R) +{ + return (__m128d) __builtin_ia32_scalefsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) + _mm_avx512_setzero_pd (), + (__mmask8) -1, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_scalef_round_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B, + const int __R) +{ + return (__m128d) __builtin_ia32_scalefsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_scalef_round_sd (__mmask8 __U, __m128d __A, __m128d __B, + const int __R) +{ + return (__m128d) __builtin_ia32_scalefsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) + _mm_avx512_setzero_pd (), + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_scalef_round_ss (__m128 __A, __m128 __B, const int __R) +{ + return (__m128) __builtin_ia32_scalefss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) + _mm_avx512_setzero_ps (), + (__mmask8) -1, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_scalef_round_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B, + const int __R) +{ + return (__m128) __builtin_ia32_scalefss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_scalef_round_ss (__mmask8 __U, __m128 __A, __m128 __B, const int __R) +{ + return (__m128) __builtin_ia32_scalefss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) + _mm_avx512_setzero_ps (), + (__mmask8) __U, __R); +} +#else +#define _mm_sqrt_round_sd(A, B, C) (__m128d)__builtin_ia32_sqrtsd_mask_round (B, A, (__v2df) _mm_avx512_setzero_pd (), -1, C) +#define _mm_mask_sqrt_round_sd(W, U, A, B, C) (__m128d)__builtin_ia32_sqrtsd_mask_round (B, A, W, U, C) +#define _mm_maskz_sqrt_round_sd(U, A, B, C) (__m128d)__builtin_ia32_sqrtsd_mask_round (B, A, (__v2df) _mm_avx512_setzero_pd (), U, C) +#define _mm_sqrt_round_ss(A, B, C) (__m128)__builtin_ia32_sqrtss_mask_round (B, A, (__v4sf) _mm_avx512_setzero_ps (), -1, C) +#define _mm_mask_sqrt_round_ss(W, U, A, B, C) (__m128)__builtin_ia32_sqrtss_mask_round (B, A, W, U, C) +#define _mm_maskz_sqrt_round_ss(U, A, B, C) (__m128)__builtin_ia32_sqrtss_mask_round (B, A, (__v4sf) _mm_avx512_setzero_ps (), U, C) +#define _mm_mul_round_sd(A, B, C) (__m128d)__builtin_ia32_mulsd_round(A, B, C) +#define _mm_mask_mul_round_sd(W, U, A, B, C) (__m128d)__builtin_ia32_mulsd_mask_round(A, B, W, U, C) +#define _mm_maskz_mul_round_sd(U, A, B, C) (__m128d)__builtin_ia32_mulsd_mask_round(A, B, (__v2df)_mm_avx512_setzero_pd(), U, C) +#define _mm_mul_round_ss(A, B, C) (__m128)__builtin_ia32_mulss_round(A, B, C) +#define _mm_mask_mul_round_ss(W, U, A, B, C) (__m128)__builtin_ia32_mulss_mask_round(A, B, W, U, C) +#define _mm_maskz_mul_round_ss(U, A, B, C) (__m128)__builtin_ia32_mulss_mask_round(A, B, (__v4sf)_mm_avx512_setzero_ps(), U, C) +#define _mm_div_round_sd(A, B, C) (__m128d)__builtin_ia32_divsd_round(A, B, C) +#define _mm_mask_div_round_sd(W, U, A, B, C) (__m128d)__builtin_ia32_divsd_mask_round(A, B, W, U, C) +#define _mm_maskz_div_round_sd(U, A, B, C) (__m128d)__builtin_ia32_divsd_mask_round(A, B, (__v2df)_mm_avx512_setzero_pd(), U, C) +#define _mm_div_round_ss(A, B, C) (__m128)__builtin_ia32_divss_round(A, B, C) +#define _mm_mask_div_round_ss(W, U, A, B, C) (__m128)__builtin_ia32_divss_mask_round(A, B, W, U, C) +#define _mm_maskz_div_round_ss(U, A, B, C) (__m128)__builtin_ia32_divss_mask_round(A, B, (__v4sf)_mm_avx512_setzero_ps(), U, C) +#define _mm_scalef_round_sd(A, B, C) ((__m128d) __builtin_ia32_scalefsd_mask_round ((A), (B), (__v2df) _mm_avx512_undefined_pd (), -1, (C))) +#define _mm_scalef_round_ss(A, B, C) ((__m128) __builtin_ia32_scalefss_mask_round ((A), (B), (__v4sf) _mm_avx512_undefined_ps (), -1, (C))) +#define _mm_mask_scalef_round_sd(W, U, A, B, C) ((__m128d) __builtin_ia32_scalefsd_mask_round ((A), (B), (W), (U), (C))) +#define _mm_mask_scalef_round_ss(W, U, A, B, C) ((__m128) __builtin_ia32_scalefss_mask_round ((A), (B), (W), (U), (C))) +#define _mm_maskz_scalef_round_sd(U, A, B, C) ((__m128d) __builtin_ia32_scalefsd_mask_round ((A), (B), (__v2df) _mm_avx512_setzero_pd (), (U), (C))) +#define _mm_maskz_scalef_round_ss(U, A, B, C) ((__m128) __builtin_ia32_scalefss_mask_round ((A), (B), (__v4sf) _mm_avx512_setzero_ps (), (U), (C))) +#endif +#define _mm_mask_sqrt_sd(W, U, A, B) _mm_mask_sqrt_round_sd ((W), (U), (A), (B), _MM_FROUND_CUR_DIRECTION) +#define _mm_maskz_sqrt_sd(U, A, B) _mm_maskz_sqrt_round_sd ((U), (A), (B), _MM_FROUND_CUR_DIRECTION) +#define _mm_mask_sqrt_ss(W, U, A, B) _mm_mask_sqrt_round_ss ((W), (U), (A), (B), _MM_FROUND_CUR_DIRECTION) +#define _mm_maskz_sqrt_ss(U, A, B) _mm_maskz_sqrt_round_ss ((U), (A), (B), _MM_FROUND_CUR_DIRECTION) +#define _mm_mask_scalef_sd(W, U, A, B) _mm_mask_scalef_round_sd ((W), (U), (A), (B), _MM_FROUND_CUR_DIRECTION) +#define _mm_maskz_scalef_sd(U, A, B) _mm_maskz_scalef_round_sd ((U), (A), (B), _MM_FROUND_CUR_DIRECTION) +#define _mm_mask_scalef_ss(W, U, A, B) _mm_mask_scalef_round_ss ((W), (U), (A), (B), _MM_FROUND_CUR_DIRECTION) +#define _mm_maskz_scalef_ss(U, A, B) _mm_maskz_scalef_round_ss ((U), (A), (B), _MM_FROUND_CUR_DIRECTION) +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtu32_sd (__m128d __A, unsigned __B) +{ + return (__m128d) __builtin_ia32_cvtusi2sd32 ((__v2df) __A, __B); +} +#ifdef __x86_64__ +#ifdef __OPTIMIZE__ +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundu64_sd (__m128d __A, unsigned long long __B, const int __R) +{ + return (__m128d) __builtin_ia32_cvtusi2sd64 ((__v2df) __A, __B, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundi64_sd (__m128d __A, long long __B, const int __R) +{ + return (__m128d) __builtin_ia32_cvtsi2sd64 ((__v2df) __A, __B, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundsi64_sd (__m128d __A, long long __B, const int __R) +{ + return (__m128d) __builtin_ia32_cvtsi2sd64 ((__v2df) __A, __B, __R); +} +#else +#define _mm_cvt_roundu64_sd(A, B, C) (__m128d)__builtin_ia32_cvtusi2sd64(A, B, C) +#define _mm_cvt_roundi64_sd(A, B, C) (__m128d)__builtin_ia32_cvtsi2sd64(A, B, C) +#define _mm_cvt_roundsi64_sd(A, B, C) (__m128d)__builtin_ia32_cvtsi2sd64(A, B, C) +#endif +#endif +#ifdef __OPTIMIZE__ +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundu32_ss (__m128 __A, unsigned __B, const int __R) +{ + return (__m128) __builtin_ia32_cvtusi2ss32 ((__v4sf) __A, __B, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundsi32_ss (__m128 __A, int __B, const int __R) +{ + return (__m128) __builtin_ia32_cvtsi2ss32 ((__v4sf) __A, __B, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundi32_ss (__m128 __A, int __B, const int __R) +{ + return (__m128) __builtin_ia32_cvtsi2ss32 ((__v4sf) __A, __B, __R); +} +#else +#define _mm_cvt_roundu32_ss(A, B, C) (__m128)__builtin_ia32_cvtusi2ss32(A, B, C) +#define _mm_cvt_roundi32_ss(A, B, C) (__m128)__builtin_ia32_cvtsi2ss32(A, B, C) +#define _mm_cvt_roundsi32_ss(A, B, C) (__m128)__builtin_ia32_cvtsi2ss32(A, B, C) +#endif +#ifdef __x86_64__ +#ifdef __OPTIMIZE__ +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundu64_ss (__m128 __A, unsigned long long __B, const int __R) +{ + return (__m128) __builtin_ia32_cvtusi2ss64 ((__v4sf) __A, __B, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundsi64_ss (__m128 __A, long long __B, const int __R) +{ + return (__m128) __builtin_ia32_cvtsi2ss64 ((__v4sf) __A, __B, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundi64_ss (__m128 __A, long long __B, const int __R) +{ + return (__m128) __builtin_ia32_cvtsi2ss64 ((__v4sf) __A, __B, __R); +} +#else +#define _mm_cvt_roundu64_ss(A, B, C) (__m128)__builtin_ia32_cvtusi2ss64(A, B, C) +#define _mm_cvt_roundi64_ss(A, B, C) (__m128)__builtin_ia32_cvtsi2ss64(A, B, C) +#define _mm_cvt_roundsi64_ss(A, B, C) (__m128)__builtin_ia32_cvtsi2ss64(A, B, C) +#endif +#endif +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_load_ss (__m128 __W, __mmask8 __U, const float *__P) +{ + return (__m128) __builtin_ia32_loadss_mask (__P, (__v4sf) __W, __U); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_load_ss (__mmask8 __U, const float *__P) +{ + return (__m128) __builtin_ia32_loadss_mask (__P, (__v4sf) _mm_avx512_setzero_ps (), + __U); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_load_sd (__m128d __W, __mmask8 __U, const double *__P) +{ + return (__m128d) __builtin_ia32_loadsd_mask (__P, (__v2df) __W, __U); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_load_sd (__mmask8 __U, const double *__P) +{ + return (__m128d) __builtin_ia32_loadsd_mask (__P, (__v2df) _mm_avx512_setzero_pd (), + __U); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_move_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_movess_mask ((__v4sf) __A, (__v4sf) __B, + (__v4sf) __W, __U); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_move_ss (__mmask8 __U, __m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_movess_mask ((__v4sf) __A, (__v4sf) __B, + (__v4sf) _mm_avx512_setzero_ps (), __U); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_move_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_movesd_mask ((__v2df) __A, (__v2df) __B, + (__v2df) __W, __U); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_move_sd (__mmask8 __U, __m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_movesd_mask ((__v2df) __A, (__v2df) __B, + (__v2df) _mm_avx512_setzero_pd (), + __U); +} +extern __inline void +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_store_ss (float *__P, __mmask8 __U, __m128 __A) +{ + __builtin_ia32_storess_mask (__P, (__v4sf) __A, (__mmask8) __U); +} +extern __inline void +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_store_sd (double *__P, __mmask8 __U, __m128d __A) +{ + __builtin_ia32_storesd_mask (__P, (__v2df) __A, (__mmask8) __U); +} +#ifdef __OPTIMIZE__ +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_fixupimm_round_sd (__m128d __A, __m128d __B, __m128i __C, + const int __imm, const int __R) +{ + return (__m128d) __builtin_ia32_fixupimmsd_mask ((__v2df) __A, + (__v2df) __B, + (__v2di) __C, __imm, + (__mmask8) -1, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fixupimm_round_sd (__m128d __A, __mmask8 __U, __m128d __B, + __m128i __C, const int __imm, const int __R) +{ + return (__m128d) __builtin_ia32_fixupimmsd_mask ((__v2df) __A, + (__v2df) __B, + (__v2di) __C, __imm, + (__mmask8) __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fixupimm_round_sd (__mmask8 __U, __m128d __A, __m128d __B, + __m128i __C, const int __imm, const int __R) +{ + return (__m128d) __builtin_ia32_fixupimmsd_maskz ((__v2df) __A, + (__v2df) __B, + (__v2di) __C, + __imm, + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_fixupimm_round_ss (__m128 __A, __m128 __B, __m128i __C, + const int __imm, const int __R) +{ + return (__m128) __builtin_ia32_fixupimmss_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4si) __C, __imm, + (__mmask8) -1, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fixupimm_round_ss (__m128 __A, __mmask8 __U, __m128 __B, + __m128i __C, const int __imm, const int __R) +{ + return (__m128) __builtin_ia32_fixupimmss_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4si) __C, __imm, + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fixupimm_round_ss (__mmask8 __U, __m128 __A, __m128 __B, + __m128i __C, const int __imm, const int __R) +{ + return (__m128) __builtin_ia32_fixupimmss_maskz ((__v4sf) __A, + (__v4sf) __B, + (__v4si) __C, __imm, + (__mmask8) __U, __R); +} +#else +#define _mm_fixupimm_round_sd(X, Y, Z, C, R) ((__m128d)__builtin_ia32_fixupimmsd_mask ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (__v2di)(__m128i)(Z), (int)(C), (__mmask8)(-1), (R))) +#define _mm_mask_fixupimm_round_sd(X, U, Y, Z, C, R) ((__m128d)__builtin_ia32_fixupimmsd_mask ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (__v2di)(__m128i)(Z), (int)(C), (__mmask8)(U), (R))) +#define _mm_maskz_fixupimm_round_sd(U, X, Y, Z, C, R) ((__m128d)__builtin_ia32_fixupimmsd_maskz ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (__v2di)(__m128i)(Z), (int)(C), (__mmask8)(U), (R))) +#define _mm_fixupimm_round_ss(X, Y, Z, C, R) ((__m128)__builtin_ia32_fixupimmss_mask ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (__v4si)(__m128i)(Z), (int)(C), (__mmask8)(-1), (R))) +#define _mm_mask_fixupimm_round_ss(X, U, Y, Z, C, R) ((__m128)__builtin_ia32_fixupimmss_mask ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (__v4si)(__m128i)(Z), (int)(C), (__mmask8)(U), (R))) +#define _mm_maskz_fixupimm_round_ss(U, X, Y, Z, C, R) ((__m128)__builtin_ia32_fixupimmss_maskz ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (__v4si)(__m128i)(Z), (int)(C), (__mmask8)(U), (R))) +#endif +#ifdef __x86_64__ +#ifdef __OPTIMIZE__ +extern __inline unsigned long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundss_u64 (__m128 __A, const int __R) +{ + return (unsigned long long) __builtin_ia32_vcvtss2usi64 ((__v4sf) __A, __R); +} +extern __inline long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundss_si64 (__m128 __A, const int __R) +{ + return (long long) __builtin_ia32_vcvtss2si64 ((__v4sf) __A, __R); +} +extern __inline long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundss_i64 (__m128 __A, const int __R) +{ + return (long long) __builtin_ia32_vcvtss2si64 ((__v4sf) __A, __R); +} +extern __inline unsigned long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtt_roundss_u64 (__m128 __A, const int __R) +{ + return (unsigned long long) __builtin_ia32_vcvttss2usi64 ((__v4sf) __A, __R); +} +extern __inline long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtt_roundss_i64 (__m128 __A, const int __R) +{ + return (long long) __builtin_ia32_vcvttss2si64 ((__v4sf) __A, __R); +} +extern __inline long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtt_roundss_si64 (__m128 __A, const int __R) +{ + return (long long) __builtin_ia32_vcvttss2si64 ((__v4sf) __A, __R); +} +#else +#define _mm_cvt_roundss_u64(A, B) ((unsigned long long)__builtin_ia32_vcvtss2usi64(A, B)) +#define _mm_cvt_roundss_si64(A, B) ((long long)__builtin_ia32_vcvtss2si64(A, B)) +#define _mm_cvt_roundss_i64(A, B) ((long long)__builtin_ia32_vcvtss2si64(A, B)) +#define _mm_cvtt_roundss_u64(A, B) ((unsigned long long)__builtin_ia32_vcvttss2usi64(A, B)) +#define _mm_cvtt_roundss_i64(A, B) ((long long)__builtin_ia32_vcvttss2si64(A, B)) +#define _mm_cvtt_roundss_si64(A, B) ((long long)__builtin_ia32_vcvttss2si64(A, B)) +#endif +#endif +#ifdef __OPTIMIZE__ +extern __inline unsigned +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundss_u32 (__m128 __A, const int __R) +{ + return (unsigned) __builtin_ia32_vcvtss2usi32 ((__v4sf) __A, __R); +} +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundss_si32 (__m128 __A, const int __R) +{ + return (int) __builtin_ia32_vcvtss2si32 ((__v4sf) __A, __R); +} +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundss_i32 (__m128 __A, const int __R) +{ + return (int) __builtin_ia32_vcvtss2si32 ((__v4sf) __A, __R); +} +extern __inline unsigned +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtt_roundss_u32 (__m128 __A, const int __R) +{ + return (unsigned) __builtin_ia32_vcvttss2usi32 ((__v4sf) __A, __R); +} +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtt_roundss_i32 (__m128 __A, const int __R) +{ + return (int) __builtin_ia32_vcvttss2si32 ((__v4sf) __A, __R); +} +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtt_roundss_si32 (__m128 __A, const int __R) +{ + return (int) __builtin_ia32_vcvttss2si32 ((__v4sf) __A, __R); +} +#else +#define _mm_cvt_roundss_u32(A, B) ((unsigned)__builtin_ia32_vcvtss2usi32(A, B)) +#define _mm_cvt_roundss_si32(A, B) ((int)__builtin_ia32_vcvtss2si32(A, B)) +#define _mm_cvt_roundss_i32(A, B) ((int)__builtin_ia32_vcvtss2si32(A, B)) +#define _mm_cvtt_roundss_u32(A, B) ((unsigned)__builtin_ia32_vcvttss2usi32(A, B)) +#define _mm_cvtt_roundss_si32(A, B) ((int)__builtin_ia32_vcvttss2si32(A, B)) +#define _mm_cvtt_roundss_i32(A, B) ((int)__builtin_ia32_vcvttss2si32(A, B)) +#endif +#ifdef __x86_64__ +#ifdef __OPTIMIZE__ +extern __inline unsigned long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundsd_u64 (__m128d __A, const int __R) +{ + return (unsigned long long) __builtin_ia32_vcvtsd2usi64 ((__v2df) __A, __R); +} +extern __inline long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundsd_si64 (__m128d __A, const int __R) +{ + return (long long) __builtin_ia32_vcvtsd2si64 ((__v2df) __A, __R); +} +extern __inline long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundsd_i64 (__m128d __A, const int __R) +{ + return (long long) __builtin_ia32_vcvtsd2si64 ((__v2df) __A, __R); +} +extern __inline unsigned long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtt_roundsd_u64 (__m128d __A, const int __R) +{ + return (unsigned long long) __builtin_ia32_vcvttsd2usi64 ((__v2df) __A, __R); +} +extern __inline long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtt_roundsd_si64 (__m128d __A, const int __R) +{ + return (long long) __builtin_ia32_vcvttsd2si64 ((__v2df) __A, __R); +} +extern __inline long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtt_roundsd_i64 (__m128d __A, const int __R) +{ + return (long long) __builtin_ia32_vcvttsd2si64 ((__v2df) __A, __R); +} +#else +#define _mm_cvt_roundsd_u64(A, B) ((unsigned long long)__builtin_ia32_vcvtsd2usi64(A, B)) +#define _mm_cvt_roundsd_si64(A, B) ((long long)__builtin_ia32_vcvtsd2si64(A, B)) +#define _mm_cvt_roundsd_i64(A, B) ((long long)__builtin_ia32_vcvtsd2si64(A, B)) +#define _mm_cvtt_roundsd_u64(A, B) ((unsigned long long)__builtin_ia32_vcvttsd2usi64(A, B)) +#define _mm_cvtt_roundsd_si64(A, B) ((long long)__builtin_ia32_vcvttsd2si64(A, B)) +#define _mm_cvtt_roundsd_i64(A, B) ((long long)__builtin_ia32_vcvttsd2si64(A, B)) +#endif +#endif +#ifdef __OPTIMIZE__ +extern __inline unsigned +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundsd_u32 (__m128d __A, const int __R) +{ + return (unsigned) __builtin_ia32_vcvtsd2usi32 ((__v2df) __A, __R); +} +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundsd_si32 (__m128d __A, const int __R) +{ + return (int) __builtin_ia32_vcvtsd2si32 ((__v2df) __A, __R); +} +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundsd_i32 (__m128d __A, const int __R) +{ + return (int) __builtin_ia32_vcvtsd2si32 ((__v2df) __A, __R); +} +extern __inline unsigned +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtt_roundsd_u32 (__m128d __A, const int __R) +{ + return (unsigned) __builtin_ia32_vcvttsd2usi32 ((__v2df) __A, __R); +} +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtt_roundsd_i32 (__m128d __A, const int __R) +{ + return (int) __builtin_ia32_vcvttsd2si32 ((__v2df) __A, __R); +} +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtt_roundsd_si32 (__m128d __A, const int __R) +{ + return (int) __builtin_ia32_vcvttsd2si32 ((__v2df) __A, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundsd_ss (__m128 __A, __m128d __B, const int __R) +{ + return (__m128) __builtin_ia32_cvtsd2ss_round ((__v4sf) __A, + (__v2df) __B, + __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_cvt_roundsd_ss (__m128 __W, __mmask8 __U, __m128 __A, + __m128d __B, const int __R) +{ + return (__m128) __builtin_ia32_cvtsd2ss_mask_round ((__v4sf) __A, + (__v2df) __B, + (__v4sf) __W, + __U, + __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_cvt_roundsd_ss (__mmask8 __U, __m128 __A, + __m128d __B, const int __R) +{ + return (__m128) __builtin_ia32_cvtsd2ss_mask_round ((__v4sf) __A, + (__v2df) __B, + _mm_avx512_setzero_ps (), + __U, + __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundss_sd (__m128d __A, __m128 __B, const int __R) +{ + return (__m128d) __builtin_ia32_cvtss2sd_round ((__v2df) __A, + (__v4sf) __B, + __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_cvt_roundss_sd (__m128d __W, __mmask8 __U, __m128d __A, + __m128 __B, const int __R) +{ + return (__m128d) __builtin_ia32_cvtss2sd_mask_round ((__v2df) __A, + (__v4sf) __B, + (__v2df) __W, + __U, + __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_cvt_roundss_sd (__mmask8 __U, __m128d __A, + __m128 __B, const int __R) +{ + return (__m128d) __builtin_ia32_cvtss2sd_mask_round ((__v2df) __A, + (__v4sf) __B, + _mm_avx512_setzero_pd (), + __U, + __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_getexp_round_ss (__m128 __A, __m128 __B, const int __R) +{ + return (__m128) __builtin_ia32_getexpss128_round ((__v4sf) __A, + (__v4sf) __B, + __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_getexp_round_ss (__m128 __W, __mmask8 __U, __m128 __A, + __m128 __B, const int __R) +{ + return (__m128) __builtin_ia32_getexpss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_getexp_round_ss (__mmask8 __U, __m128 __A, __m128 __B, + const int __R) +{ + return (__m128) __builtin_ia32_getexpss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) + _mm_avx512_setzero_ps (), + (__mmask8) __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_getexp_round_sd (__m128d __A, __m128d __B, const int __R) +{ + return (__m128d) __builtin_ia32_getexpsd128_round ((__v2df) __A, + (__v2df) __B, + __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_getexp_round_sd (__m128d __W, __mmask8 __U, __m128d __A, + __m128d __B, const int __R) +{ + return (__m128d) __builtin_ia32_getexpsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_getexp_round_sd (__mmask8 __U, __m128d __A, __m128d __B, + const int __R) +{ + return (__m128d) __builtin_ia32_getexpsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) + _mm_avx512_setzero_pd (), + (__mmask8) __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_getmant_round_sd (__m128d __A, __m128d __B, + _MM_MANTISSA_NORM_ENUM __C, + _MM_MANTISSA_SIGN_ENUM __D, const int __R) +{ + return (__m128d) __builtin_ia32_getmantsd_round ((__v2df) __A, + (__v2df) __B, + (__D << 2) | __C, + __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_getmant_round_sd (__m128d __W, __mmask8 __U, __m128d __A, + __m128d __B, _MM_MANTISSA_NORM_ENUM __C, + _MM_MANTISSA_SIGN_ENUM __D, const int __R) +{ + return (__m128d) __builtin_ia32_getmantsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__D << 2) | __C, + (__v2df) __W, + __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_getmant_round_sd (__mmask8 __U, __m128d __A, __m128d __B, + _MM_MANTISSA_NORM_ENUM __C, + _MM_MANTISSA_SIGN_ENUM __D, const int __R) +{ + return (__m128d) __builtin_ia32_getmantsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__D << 2) | __C, + (__v2df) + _mm_avx512_setzero_pd(), + __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_getmant_round_ss (__m128 __A, __m128 __B, + _MM_MANTISSA_NORM_ENUM __C, + _MM_MANTISSA_SIGN_ENUM __D, const int __R) +{ + return (__m128) __builtin_ia32_getmantss_round ((__v4sf) __A, + (__v4sf) __B, + (__D << 2) | __C, + __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_getmant_round_ss (__m128 __W, __mmask8 __U, __m128 __A, + __m128 __B, _MM_MANTISSA_NORM_ENUM __C, + _MM_MANTISSA_SIGN_ENUM __D, const int __R) +{ + return (__m128) __builtin_ia32_getmantss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__D << 2) | __C, + (__v4sf) __W, + __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_getmant_round_ss (__mmask8 __U, __m128 __A, __m128 __B, + _MM_MANTISSA_NORM_ENUM __C, + _MM_MANTISSA_SIGN_ENUM __D, const int __R) +{ + return (__m128) __builtin_ia32_getmantss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__D << 2) | __C, + (__v4sf) + _mm_avx512_setzero_ps(), + __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_roundscale_round_ss (__m128 __A, __m128 __B, const int __imm, + const int __R) +{ + return (__m128) + __builtin_ia32_rndscaless_mask_round ((__v4sf) __A, + (__v4sf) __B, __imm, + (__v4sf) + _mm_avx512_setzero_ps (), + (__mmask8) -1, + __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_roundscale_round_ss (__m128 __A, __mmask8 __B, __m128 __C, + __m128 __D, const int __imm, const int __R) +{ + return (__m128) + __builtin_ia32_rndscaless_mask_round ((__v4sf) __C, + (__v4sf) __D, __imm, + (__v4sf) __A, + (__mmask8) __B, + __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_roundscale_round_ss (__mmask8 __A, __m128 __B, __m128 __C, + const int __imm, const int __R) +{ + return (__m128) + __builtin_ia32_rndscaless_mask_round ((__v4sf) __B, + (__v4sf) __C, __imm, + (__v4sf) + _mm_avx512_setzero_ps (), + (__mmask8) __A, + __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_roundscale_round_sd (__m128d __A, __m128d __B, const int __imm, + const int __R) +{ + return (__m128d) + __builtin_ia32_rndscalesd_mask_round ((__v2df) __A, + (__v2df) __B, __imm, + (__v2df) + _mm_avx512_setzero_pd (), + (__mmask8) -1, + __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_roundscale_round_sd (__m128d __A, __mmask8 __B, __m128d __C, + __m128d __D, const int __imm, const int __R) +{ + return (__m128d) + __builtin_ia32_rndscalesd_mask_round ((__v2df) __C, + (__v2df) __D, __imm, + (__v2df) __A, + (__mmask8) __B, + __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_roundscale_round_sd (__mmask8 __A, __m128d __B, __m128d __C, + const int __imm, const int __R) +{ + return (__m128d) + __builtin_ia32_rndscalesd_mask_round ((__v2df) __B, + (__v2df) __C, __imm, + (__v2df) + _mm_avx512_setzero_pd (), + (__mmask8) __A, + __R); +} +#else +#define _mm_cvt_roundsd_u32(A, B) ((unsigned)__builtin_ia32_vcvtsd2usi32(A, B)) +#define _mm_cvt_roundsd_si32(A, B) ((int)__builtin_ia32_vcvtsd2si32(A, B)) +#define _mm_cvt_roundsd_i32(A, B) ((int)__builtin_ia32_vcvtsd2si32(A, B)) +#define _mm_cvtt_roundsd_u32(A, B) ((unsigned)__builtin_ia32_vcvttsd2usi32(A, B)) +#define _mm_cvtt_roundsd_si32(A, B) ((int)__builtin_ia32_vcvttsd2si32(A, B)) +#define _mm_cvtt_roundsd_i32(A, B) ((int)__builtin_ia32_vcvttsd2si32(A, B)) +#define _mm_cvt_roundsd_ss(A, B, C) (__m128)__builtin_ia32_cvtsd2ss_round(A, B, C) +#define _mm_mask_cvt_roundsd_ss(W, U, A, B, C) (__m128)__builtin_ia32_cvtsd2ss_mask_round ((A), (B), (W), (U), (C)) +#define _mm_maskz_cvt_roundsd_ss(U, A, B, C) (__m128)__builtin_ia32_cvtsd2ss_mask_round ((A), (B), _mm_avx512_setzero_ps (), (U), (C)) +#define _mm_cvt_roundss_sd(A, B, C) (__m128d)__builtin_ia32_cvtss2sd_round(A, B, C) +#define _mm_mask_cvt_roundss_sd(W, U, A, B, C) (__m128d)__builtin_ia32_cvtss2sd_mask_round ((A), (B), (W), (U), (C)) +#define _mm_maskz_cvt_roundss_sd(U, A, B, C) (__m128d)__builtin_ia32_cvtss2sd_mask_round ((A), (B), _mm_avx512_setzero_pd (), (U), (C)) +#define _mm_getmant_round_sd(X, Y, C, D, R) ((__m128d)__builtin_ia32_getmantsd_round ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (int)(((D)<<2) | (C)), (R))) +#define _mm_mask_getmant_round_sd(W, U, X, Y, C, D, R) ((__m128d)__builtin_ia32_getmantsd_mask_round ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (int)(((D)<<2) | (C)), (__v2df)(__m128d)(W), (__mmask8)(U), (R))) +#define _mm_maskz_getmant_round_sd(U, X, Y, C, D, R) ((__m128d)__builtin_ia32_getmantsd_mask_round ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (int)(((D)<<2) | (C)), (__v2df)(__m128d)_mm_avx512_setzero_pd(), (__mmask8)(U), (R))) +#define _mm_getmant_round_ss(X, Y, C, D, R) ((__m128)__builtin_ia32_getmantss_round ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (int)(((D)<<2) | (C)), (R))) +#define _mm_mask_getmant_round_ss(W, U, X, Y, C, D, R) ((__m128)__builtin_ia32_getmantss_mask_round ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (int)(((D)<<2) | (C)), (__v4sf)(__m128)(W), (__mmask8)(U), (R))) +#define _mm_maskz_getmant_round_ss(U, X, Y, C, D, R) ((__m128)__builtin_ia32_getmantss_mask_round ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (int)(((D)<<2) | (C)), (__v4sf)(__m128)_mm_avx512_setzero_ps(), (__mmask8)(U), (R))) +#define _mm_getexp_round_ss(A, B, R) ((__m128)__builtin_ia32_getexpss128_round((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), R)) +#define _mm_mask_getexp_round_ss(W, U, A, B, C) (__m128)__builtin_ia32_getexpss_mask_round(A, B, W, U, C) +#define _mm_maskz_getexp_round_ss(U, A, B, C) (__m128)__builtin_ia32_getexpss_mask_round(A, B, (__v4sf)_mm_avx512_setzero_ps(), U, C) +#define _mm_getexp_round_sd(A, B, R) ((__m128d)__builtin_ia32_getexpsd128_round((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), R)) +#define _mm_mask_getexp_round_sd(W, U, A, B, C) (__m128d)__builtin_ia32_getexpsd_mask_round(A, B, W, U, C) +#define _mm_maskz_getexp_round_sd(U, A, B, C) (__m128d)__builtin_ia32_getexpsd_mask_round(A, B, (__v2df)_mm_avx512_setzero_pd(), U, C) +#define _mm_roundscale_round_ss(A, B, I, R) ((__m128) __builtin_ia32_rndscaless_mask_round ((__v4sf) (__m128) (A), (__v4sf) (__m128) (B), (int) (I), (__v4sf) _mm_avx512_setzero_ps (), (__mmask8) (-1), (int) (R))) +#define _mm_mask_roundscale_round_ss(A, U, B, C, I, R) ((__m128) __builtin_ia32_rndscaless_mask_round ((__v4sf) (__m128) (B), (__v4sf) (__m128) (C), (int) (I), (__v4sf) (__m128) (A), (__mmask8) (U), (int) (R))) +#define _mm_maskz_roundscale_round_ss(U, A, B, I, R) ((__m128) __builtin_ia32_rndscaless_mask_round ((__v4sf) (__m128) (A), (__v4sf) (__m128) (B), (int) (I), (__v4sf) _mm_avx512_setzero_ps (), (__mmask8) (U), (int) (R))) +#define _mm_roundscale_round_sd(A, B, I, R) ((__m128d) __builtin_ia32_rndscalesd_mask_round ((__v2df) (__m128d) (A), (__v2df) (__m128d) (B), (int) (I), (__v2df) _mm_avx512_setzero_pd (), (__mmask8) (-1), (int) (R))) +#define _mm_mask_roundscale_round_sd(A, U, B, C, I, R) ((__m128d) __builtin_ia32_rndscalesd_mask_round ((__v2df) (__m128d) (B), (__v2df) (__m128d) (C), (int) (I), (__v2df) (__m128d) (A), (__mmask8) (U), (int) (R))) +#define _mm_maskz_roundscale_round_sd(U, A, B, I, R) ((__m128d) __builtin_ia32_rndscalesd_mask_round ((__v2df) (__m128d) (A), (__v2df) (__m128d) (B), (int) (I), (__v2df) _mm_avx512_setzero_pd (), (__mmask8) (U), (int) (R))) +#endif +#define _mm_mask_cvtss_sd(W, U, A, B) _mm_mask_cvt_roundss_sd ((W), (U), (A), (B), _MM_FROUND_CUR_DIRECTION) +#define _mm_maskz_cvtss_sd(U, A, B) _mm_maskz_cvt_roundss_sd ((U), (A), (B), _MM_FROUND_CUR_DIRECTION) +#define _mm_mask_cvtsd_ss(W, U, A, B) _mm_mask_cvt_roundsd_ss ((W), (U), (A), (B), _MM_FROUND_CUR_DIRECTION) +#define _mm_maskz_cvtsd_ss(U, A, B) _mm_maskz_cvt_roundsd_ss ((U), (A), (B), _MM_FROUND_CUR_DIRECTION) +#ifdef __OPTIMIZE__ +extern __inline __mmask16 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_kshiftli_mask16 (__mmask16 __A, unsigned int __B) +{ + return (__mmask16) __builtin_ia32_kshiftlihi ((__mmask16) __A, + (__mmask8) __B); +} +extern __inline __mmask16 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_kshiftri_mask16 (__mmask16 __A, unsigned int __B) +{ + return (__mmask16) __builtin_ia32_kshiftrihi ((__mmask16) __A, + (__mmask8) __B); +} +extern __inline __mmask8 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cmp_round_sd_mask (__m128d __X, __m128d __Y, const int __P, const int __R) +{ + return (__mmask8) __builtin_ia32_cmpsd_mask ((__v2df) __X, + (__v2df) __Y, __P, + (__mmask8) -1, __R); +} +extern __inline __mmask8 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_cmp_round_sd_mask (__mmask8 __M, __m128d __X, __m128d __Y, + const int __P, const int __R) +{ + return (__mmask8) __builtin_ia32_cmpsd_mask ((__v2df) __X, + (__v2df) __Y, __P, + (__mmask8) __M, __R); +} +extern __inline __mmask8 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cmp_round_ss_mask (__m128 __X, __m128 __Y, const int __P, const int __R) +{ + return (__mmask8) __builtin_ia32_cmpss_mask ((__v4sf) __X, + (__v4sf) __Y, __P, + (__mmask8) -1, __R); +} +extern __inline __mmask8 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_cmp_round_ss_mask (__mmask8 __M, __m128 __X, __m128 __Y, + const int __P, const int __R) +{ + return (__mmask8) __builtin_ia32_cmpss_mask ((__v4sf) __X, + (__v4sf) __Y, __P, + (__mmask8) __M, __R); +} +#else +#define _kshiftli_mask16(X, Y) ((__mmask16) __builtin_ia32_kshiftlihi ((__mmask16)(X), (__mmask8)(Y))) +#define _kshiftri_mask16(X, Y) ((__mmask16) __builtin_ia32_kshiftrihi ((__mmask16)(X), (__mmask8)(Y))) +#define _mm_cmp_round_sd_mask(X, Y, P, R) ((__mmask8) __builtin_ia32_cmpsd_mask ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (int)(P), (__mmask8)-1, R)) +#define _mm_mask_cmp_round_sd_mask(M, X, Y, P, R) ((__mmask8) __builtin_ia32_cmpsd_mask ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (int)(P), (M), R)) +#define _mm_cmp_round_ss_mask(X, Y, P, R) ((__mmask8) __builtin_ia32_cmpss_mask ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (int)(P), (__mmask8)-1, R)) +#define _mm_mask_cmp_round_ss_mask(M, X, Y, P, R) ((__mmask8) __builtin_ia32_cmpss_mask ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (int)(P), (M), R)) +#endif +extern __inline unsigned char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_kortest_mask16_u8 (__mmask16 __A, __mmask16 __B, unsigned char *__CF) +{ + *__CF = (unsigned char) __builtin_ia32_kortestchi (__A, __B); + return (unsigned char) __builtin_ia32_kortestzhi (__A, __B); +} +extern __inline unsigned char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_kortestz_mask16_u8 (__mmask16 __A, __mmask16 __B) +{ + return (unsigned char) __builtin_ia32_kortestzhi ((__mmask16) __A, + (__mmask16) __B); +} +extern __inline unsigned char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_kortestc_mask16_u8 (__mmask16 __A, __mmask16 __B) +{ + return (unsigned char) __builtin_ia32_kortestchi ((__mmask16) __A, + (__mmask16) __B); +} +extern __inline unsigned int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_cvtmask16_u32 (__mmask16 __A) +{ + return (unsigned int) __builtin_ia32_kmovw ((__mmask16 ) __A); +} +extern __inline __mmask16 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_cvtu32_mask16 (unsigned int __A) +{ + return (__mmask16) __builtin_ia32_kmovw ((__mmask16 ) __A); +} +extern __inline __mmask16 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_load_mask16 (__mmask16 *__A) +{ + return (__mmask16) __builtin_ia32_kmovw (*(__mmask16 *) __A); +} +extern __inline void +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_store_mask16 (__mmask16 *__A, __mmask16 __B) +{ + *(__mmask16 *) __A = __builtin_ia32_kmovw (__B); +} +extern __inline __mmask16 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_kand_mask16 (__mmask16 __A, __mmask16 __B) +{ + return (__mmask16) __builtin_ia32_kandhi ((__mmask16) __A, (__mmask16) __B); +} +extern __inline __mmask16 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_kandn_mask16 (__mmask16 __A, __mmask16 __B) +{ + return (__mmask16) __builtin_ia32_kandnhi ((__mmask16) __A, + (__mmask16) __B); +} +extern __inline __mmask16 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_kor_mask16 (__mmask16 __A, __mmask16 __B) +{ + return (__mmask16) __builtin_ia32_korhi ((__mmask16) __A, (__mmask16) __B); +} +extern __inline __mmask16 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_kxnor_mask16 (__mmask16 __A, __mmask16 __B) +{ + return (__mmask16) __builtin_ia32_kxnorhi ((__mmask16) __A, (__mmask16) __B); +} +extern __inline __mmask16 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_kxor_mask16 (__mmask16 __A, __mmask16 __B) +{ + return (__mmask16) __builtin_ia32_kxorhi ((__mmask16) __A, (__mmask16) __B); +} +extern __inline __mmask16 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_knot_mask16 (__mmask16 __A) +{ + return (__mmask16) __builtin_ia32_knothi ((__mmask16) __A); +} +extern __inline __mmask16 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_kunpackb_mask16 (__mmask8 __A, __mmask8 __B) +{ + return (__mmask16) __builtin_ia32_kunpckhi ((__mmask16) __A, (__mmask16) __B); +} +#ifdef __OPTIMIZE__ +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_max_round_sd (__m128d __A, __m128d __B, const int __R) +{ + return (__m128d) __builtin_ia32_maxsd_round ((__v2df) __A, + (__v2df) __B, + __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_max_round_sd (__m128d __W, __mmask8 __U, __m128d __A, + __m128d __B, const int __R) +{ + return (__m128d) __builtin_ia32_maxsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_max_round_sd (__mmask8 __U, __m128d __A, __m128d __B, + const int __R) +{ + return (__m128d) __builtin_ia32_maxsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) + _mm_avx512_setzero_pd (), + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_max_round_ss (__m128 __A, __m128 __B, const int __R) +{ + return (__m128) __builtin_ia32_maxss_round ((__v4sf) __A, + (__v4sf) __B, + __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_max_round_ss (__m128 __W, __mmask8 __U, __m128 __A, + __m128 __B, const int __R) +{ + return (__m128) __builtin_ia32_maxss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_max_round_ss (__mmask8 __U, __m128 __A, __m128 __B, + const int __R) +{ + return (__m128) __builtin_ia32_maxss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) + _mm_avx512_setzero_ps (), + (__mmask8) __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_min_round_sd (__m128d __A, __m128d __B, const int __R) +{ + return (__m128d) __builtin_ia32_minsd_round ((__v2df) __A, + (__v2df) __B, + __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_min_round_sd (__m128d __W, __mmask8 __U, __m128d __A, + __m128d __B, const int __R) +{ + return (__m128d) __builtin_ia32_minsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_min_round_sd (__mmask8 __U, __m128d __A, __m128d __B, + const int __R) +{ + return (__m128d) __builtin_ia32_minsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) + _mm_avx512_setzero_pd (), + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_min_round_ss (__m128 __A, __m128 __B, const int __R) +{ + return (__m128) __builtin_ia32_minss_round ((__v4sf) __A, + (__v4sf) __B, + __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_min_round_ss (__m128 __W, __mmask8 __U, __m128 __A, + __m128 __B, const int __R) +{ + return (__m128) __builtin_ia32_minss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_min_round_ss (__mmask8 __U, __m128 __A, __m128 __B, + const int __R) +{ + return (__m128) __builtin_ia32_minss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) + _mm_avx512_setzero_ps (), + (__mmask8) __U, __R); +} +#else +#define _mm_max_round_sd(A, B, C) (__m128d)__builtin_ia32_maxsd_round(A, B, C) +#define _mm_mask_max_round_sd(W, U, A, B, C) (__m128d)__builtin_ia32_maxsd_mask_round(A, B, W, U, C) +#define _mm_maskz_max_round_sd(U, A, B, C) (__m128d)__builtin_ia32_maxsd_mask_round(A, B, (__v2df)_mm_avx512_setzero_pd(), U, C) +#define _mm_max_round_ss(A, B, C) (__m128)__builtin_ia32_maxss_round(A, B, C) +#define _mm_mask_max_round_ss(W, U, A, B, C) (__m128)__builtin_ia32_maxss_mask_round(A, B, W, U, C) +#define _mm_maskz_max_round_ss(U, A, B, C) (__m128)__builtin_ia32_maxss_mask_round(A, B, (__v4sf)_mm_avx512_setzero_ps(), U, C) +#define _mm_min_round_sd(A, B, C) (__m128d)__builtin_ia32_minsd_round(A, B, C) +#define _mm_mask_min_round_sd(W, U, A, B, C) (__m128d)__builtin_ia32_minsd_mask_round(A, B, W, U, C) +#define _mm_maskz_min_round_sd(U, A, B, C) (__m128d)__builtin_ia32_minsd_mask_round(A, B, (__v2df)_mm_avx512_setzero_pd(), U, C) +#define _mm_min_round_ss(A, B, C) (__m128)__builtin_ia32_minss_round(A, B, C) +#define _mm_mask_min_round_ss(W, U, A, B, C) (__m128)__builtin_ia32_minss_mask_round(A, B, W, U, C) +#define _mm_maskz_min_round_ss(U, A, B, C) (__m128)__builtin_ia32_minss_mask_round(A, B, (__v4sf)_mm_avx512_setzero_ps(), U, C) +#endif +#ifdef __OPTIMIZE__ +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_fmadd_round_sd (__m128d __W, __m128d __A, __m128d __B, const int __R) +{ + return (__m128d) __builtin_ia32_vfmaddsd3_round ((__v2df) __W, + (__v2df) __A, + (__v2df) __B, + __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_fmadd_round_ss (__m128 __W, __m128 __A, __m128 __B, const int __R) +{ + return (__m128) __builtin_ia32_vfmaddss3_round ((__v4sf) __W, + (__v4sf) __A, + (__v4sf) __B, + __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_fmsub_round_sd (__m128d __W, __m128d __A, __m128d __B, const int __R) +{ + return (__m128d) __builtin_ia32_vfmaddsd3_round ((__v2df) __W, + (__v2df) __A, + -(__v2df) __B, + __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_fmsub_round_ss (__m128 __W, __m128 __A, __m128 __B, const int __R) +{ + return (__m128) __builtin_ia32_vfmaddss3_round ((__v4sf) __W, + (__v4sf) __A, + -(__v4sf) __B, + __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_fnmadd_round_sd (__m128d __W, __m128d __A, __m128d __B, const int __R) +{ + return (__m128d) __builtin_ia32_vfmaddsd3_round ((__v2df) __W, + -(__v2df) __A, + (__v2df) __B, + __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_fnmadd_round_ss (__m128 __W, __m128 __A, __m128 __B, const int __R) +{ + return (__m128) __builtin_ia32_vfmaddss3_round ((__v4sf) __W, + -(__v4sf) __A, + (__v4sf) __B, + __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_fnmsub_round_sd (__m128d __W, __m128d __A, __m128d __B, const int __R) +{ + return (__m128d) __builtin_ia32_vfmaddsd3_round ((__v2df) __W, + -(__v2df) __A, + -(__v2df) __B, + __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_fnmsub_round_ss (__m128 __W, __m128 __A, __m128 __B, const int __R) +{ + return (__m128) __builtin_ia32_vfmaddss3_round ((__v4sf) __W, + -(__v4sf) __A, + -(__v4sf) __B, + __R); +} +#else +#define _mm_fmadd_round_sd(A, B, C, R) (__m128d)__builtin_ia32_vfmaddsd3_round(A, B, C, R) +#define _mm_fmadd_round_ss(A, B, C, R) (__m128)__builtin_ia32_vfmaddss3_round(A, B, C, R) +#define _mm_fmsub_round_sd(A, B, C, R) (__m128d)__builtin_ia32_vfmaddsd3_round(A, B, -(C), R) +#define _mm_fmsub_round_ss(A, B, C, R) (__m128)__builtin_ia32_vfmaddss3_round(A, B, -(C), R) +#define _mm_fnmadd_round_sd(A, B, C, R) (__m128d)__builtin_ia32_vfmaddsd3_round(A, -(B), C, R) +#define _mm_fnmadd_round_ss(A, B, C, R) (__m128)__builtin_ia32_vfmaddss3_round(A, -(B), C, R) +#define _mm_fnmsub_round_sd(A, B, C, R) (__m128d)__builtin_ia32_vfmaddsd3_round(A, -(B), -(C), R) +#define _mm_fnmsub_round_ss(A, B, C, R) (__m128)__builtin_ia32_vfmaddss3_round(A, -(B), -(C), R) +#endif +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fmadd_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_vfmaddsd3_mask ((__v2df) __W, + (__v2df) __A, + (__v2df) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fmadd_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_vfmaddss3_mask ((__v4sf) __W, + (__v4sf) __A, + (__v4sf) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask3_fmadd_sd (__m128d __W, __m128d __A, __m128d __B, __mmask8 __U) +{ + return (__m128d) __builtin_ia32_vfmaddsd3_mask3 ((__v2df) __W, + (__v2df) __A, + (__v2df) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask3_fmadd_ss (__m128 __W, __m128 __A, __m128 __B, __mmask8 __U) +{ + return (__m128) __builtin_ia32_vfmaddss3_mask3 ((__v4sf) __W, + (__v4sf) __A, + (__v4sf) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fmadd_sd (__mmask8 __U, __m128d __W, __m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_vfmaddsd3_maskz ((__v2df) __W, + (__v2df) __A, + (__v2df) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fmadd_ss (__mmask8 __U, __m128 __W, __m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_vfmaddss3_maskz ((__v4sf) __W, + (__v4sf) __A, + (__v4sf) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fmsub_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_vfmaddsd3_mask ((__v2df) __W, + (__v2df) __A, + -(__v2df) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fmsub_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_vfmaddss3_mask ((__v4sf) __W, + (__v4sf) __A, + -(__v4sf) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask3_fmsub_sd (__m128d __W, __m128d __A, __m128d __B, __mmask8 __U) +{ + return (__m128d) __builtin_ia32_vfmsubsd3_mask3 ((__v2df) __W, + (__v2df) __A, + (__v2df) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask3_fmsub_ss (__m128 __W, __m128 __A, __m128 __B, __mmask8 __U) +{ + return (__m128) __builtin_ia32_vfmsubss3_mask3 ((__v4sf) __W, + (__v4sf) __A, + (__v4sf) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fmsub_sd (__mmask8 __U, __m128d __W, __m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_vfmaddsd3_maskz ((__v2df) __W, + (__v2df) __A, + -(__v2df) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fmsub_ss (__mmask8 __U, __m128 __W, __m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_vfmaddss3_maskz ((__v4sf) __W, + (__v4sf) __A, + -(__v4sf) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fnmadd_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_vfmaddsd3_mask ((__v2df) __W, + -(__v2df) __A, + (__v2df) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fnmadd_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_vfmaddss3_mask ((__v4sf) __W, + -(__v4sf) __A, + (__v4sf) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask3_fnmadd_sd (__m128d __W, __m128d __A, __m128d __B, __mmask8 __U) +{ + return (__m128d) __builtin_ia32_vfmaddsd3_mask3 ((__v2df) __W, + -(__v2df) __A, + (__v2df) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask3_fnmadd_ss (__m128 __W, __m128 __A, __m128 __B, __mmask8 __U) +{ + return (__m128) __builtin_ia32_vfmaddss3_mask3 ((__v4sf) __W, + -(__v4sf) __A, + (__v4sf) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fnmadd_sd (__mmask8 __U, __m128d __W, __m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_vfmaddsd3_maskz ((__v2df) __W, + -(__v2df) __A, + (__v2df) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fnmadd_ss (__mmask8 __U, __m128 __W, __m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_vfmaddss3_maskz ((__v4sf) __W, + -(__v4sf) __A, + (__v4sf) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fnmsub_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_vfmaddsd3_mask ((__v2df) __W, + -(__v2df) __A, + -(__v2df) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fnmsub_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_vfmaddss3_mask ((__v4sf) __W, + -(__v4sf) __A, + -(__v4sf) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask3_fnmsub_sd (__m128d __W, __m128d __A, __m128d __B, __mmask8 __U) +{ + return (__m128d) __builtin_ia32_vfmsubsd3_mask3 ((__v2df) __W, + -(__v2df) __A, + (__v2df) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask3_fnmsub_ss (__m128 __W, __m128 __A, __m128 __B, __mmask8 __U) +{ + return (__m128) __builtin_ia32_vfmsubss3_mask3 ((__v4sf) __W, + -(__v4sf) __A, + (__v4sf) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fnmsub_sd (__mmask8 __U, __m128d __W, __m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_vfmaddsd3_maskz ((__v2df) __W, + -(__v2df) __A, + -(__v2df) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fnmsub_ss (__mmask8 __U, __m128 __W, __m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_vfmaddss3_maskz ((__v4sf) __W, + -(__v4sf) __A, + -(__v4sf) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +#ifdef __OPTIMIZE__ +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fmadd_round_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B, + const int __R) +{ + return (__m128d) __builtin_ia32_vfmaddsd3_mask ((__v2df) __W, + (__v2df) __A, + (__v2df) __B, + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fmadd_round_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B, + const int __R) +{ + return (__m128) __builtin_ia32_vfmaddss3_mask ((__v4sf) __W, + (__v4sf) __A, + (__v4sf) __B, + (__mmask8) __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask3_fmadd_round_sd (__m128d __W, __m128d __A, __m128d __B, __mmask8 __U, + const int __R) +{ + return (__m128d) __builtin_ia32_vfmaddsd3_mask3 ((__v2df) __W, + (__v2df) __A, + (__v2df) __B, + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask3_fmadd_round_ss (__m128 __W, __m128 __A, __m128 __B, __mmask8 __U, + const int __R) +{ + return (__m128) __builtin_ia32_vfmaddss3_mask3 ((__v4sf) __W, + (__v4sf) __A, + (__v4sf) __B, + (__mmask8) __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fmadd_round_sd (__mmask8 __U, __m128d __W, __m128d __A, __m128d __B, + const int __R) +{ + return (__m128d) __builtin_ia32_vfmaddsd3_maskz ((__v2df) __W, + (__v2df) __A, + (__v2df) __B, + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fmadd_round_ss (__mmask8 __U, __m128 __W, __m128 __A, __m128 __B, + const int __R) +{ + return (__m128) __builtin_ia32_vfmaddss3_maskz ((__v4sf) __W, + (__v4sf) __A, + (__v4sf) __B, + (__mmask8) __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fmsub_round_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B, + const int __R) +{ + return (__m128d) __builtin_ia32_vfmaddsd3_mask ((__v2df) __W, + (__v2df) __A, + -(__v2df) __B, + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fmsub_round_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B, + const int __R) +{ + return (__m128) __builtin_ia32_vfmaddss3_mask ((__v4sf) __W, + (__v4sf) __A, + -(__v4sf) __B, + (__mmask8) __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask3_fmsub_round_sd (__m128d __W, __m128d __A, __m128d __B, __mmask8 __U, + const int __R) +{ + return (__m128d) __builtin_ia32_vfmsubsd3_mask3 ((__v2df) __W, + (__v2df) __A, + (__v2df) __B, + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask3_fmsub_round_ss (__m128 __W, __m128 __A, __m128 __B, __mmask8 __U, + const int __R) +{ + return (__m128) __builtin_ia32_vfmsubss3_mask3 ((__v4sf) __W, + (__v4sf) __A, + (__v4sf) __B, + (__mmask8) __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fmsub_round_sd (__mmask8 __U, __m128d __W, __m128d __A, __m128d __B, + const int __R) +{ + return (__m128d) __builtin_ia32_vfmaddsd3_maskz ((__v2df) __W, + (__v2df) __A, + -(__v2df) __B, + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fmsub_round_ss (__mmask8 __U, __m128 __W, __m128 __A, __m128 __B, + const int __R) +{ + return (__m128) __builtin_ia32_vfmaddss3_maskz ((__v4sf) __W, + (__v4sf) __A, + -(__v4sf) __B, + (__mmask8) __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fnmadd_round_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B, + const int __R) +{ + return (__m128d) __builtin_ia32_vfmaddsd3_mask ((__v2df) __W, + -(__v2df) __A, + (__v2df) __B, + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fnmadd_round_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B, + const int __R) +{ + return (__m128) __builtin_ia32_vfmaddss3_mask ((__v4sf) __W, + -(__v4sf) __A, + (__v4sf) __B, + (__mmask8) __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask3_fnmadd_round_sd (__m128d __W, __m128d __A, __m128d __B, __mmask8 __U, + const int __R) +{ + return (__m128d) __builtin_ia32_vfmaddsd3_mask3 ((__v2df) __W, + -(__v2df) __A, + (__v2df) __B, + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask3_fnmadd_round_ss (__m128 __W, __m128 __A, __m128 __B, __mmask8 __U, + const int __R) +{ + return (__m128) __builtin_ia32_vfmaddss3_mask3 ((__v4sf) __W, + -(__v4sf) __A, + (__v4sf) __B, + (__mmask8) __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fnmadd_round_sd (__mmask8 __U, __m128d __W, __m128d __A, __m128d __B, + const int __R) +{ + return (__m128d) __builtin_ia32_vfmaddsd3_maskz ((__v2df) __W, + -(__v2df) __A, + (__v2df) __B, + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fnmadd_round_ss (__mmask8 __U, __m128 __W, __m128 __A, __m128 __B, + const int __R) +{ + return (__m128) __builtin_ia32_vfmaddss3_maskz ((__v4sf) __W, + -(__v4sf) __A, + (__v4sf) __B, + (__mmask8) __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fnmsub_round_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B, + const int __R) +{ + return (__m128d) __builtin_ia32_vfmaddsd3_mask ((__v2df) __W, + -(__v2df) __A, + -(__v2df) __B, + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fnmsub_round_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B, + const int __R) +{ + return (__m128) __builtin_ia32_vfmaddss3_mask ((__v4sf) __W, + -(__v4sf) __A, + -(__v4sf) __B, + (__mmask8) __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask3_fnmsub_round_sd (__m128d __W, __m128d __A, __m128d __B, __mmask8 __U, + const int __R) +{ + return (__m128d) __builtin_ia32_vfmsubsd3_mask3 ((__v2df) __W, + -(__v2df) __A, + (__v2df) __B, + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask3_fnmsub_round_ss (__m128 __W, __m128 __A, __m128 __B, __mmask8 __U, + const int __R) +{ + return (__m128) __builtin_ia32_vfmsubss3_mask3 ((__v4sf) __W, + -(__v4sf) __A, + (__v4sf) __B, + (__mmask8) __U, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fnmsub_round_sd (__mmask8 __U, __m128d __W, __m128d __A, __m128d __B, + const int __R) +{ + return (__m128d) __builtin_ia32_vfmaddsd3_maskz ((__v2df) __W, + -(__v2df) __A, + -(__v2df) __B, + (__mmask8) __U, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fnmsub_round_ss (__mmask8 __U, __m128 __W, __m128 __A, __m128 __B, + const int __R) +{ + return (__m128) __builtin_ia32_vfmaddss3_maskz ((__v4sf) __W, + -(__v4sf) __A, + -(__v4sf) __B, + (__mmask8) __U, __R); +} +#else +#define _mm_mask_fmadd_round_sd(A, U, B, C, R) (__m128d) __builtin_ia32_vfmaddsd3_mask (A, B, C, U, R) +#define _mm_mask_fmadd_round_ss(A, U, B, C, R) (__m128) __builtin_ia32_vfmaddss3_mask (A, B, C, U, R) +#define _mm_mask3_fmadd_round_sd(A, B, C, U, R) (__m128d) __builtin_ia32_vfmaddsd3_mask3 (A, B, C, U, R) +#define _mm_mask3_fmadd_round_ss(A, B, C, U, R) (__m128) __builtin_ia32_vfmaddss3_mask3 (A, B, C, U, R) +#define _mm_maskz_fmadd_round_sd(U, A, B, C, R) (__m128d) __builtin_ia32_vfmaddsd3_maskz (A, B, C, U, R) +#define _mm_maskz_fmadd_round_ss(U, A, B, C, R) (__m128) __builtin_ia32_vfmaddss3_maskz (A, B, C, U, R) +#define _mm_mask_fmsub_round_sd(A, U, B, C, R) (__m128d) __builtin_ia32_vfmaddsd3_mask (A, B, -(C), U, R) +#define _mm_mask_fmsub_round_ss(A, U, B, C, R) (__m128) __builtin_ia32_vfmaddss3_mask (A, B, -(C), U, R) +#define _mm_mask3_fmsub_round_sd(A, B, C, U, R) (__m128d) __builtin_ia32_vfmsubsd3_mask3 (A, B, C, U, R) +#define _mm_mask3_fmsub_round_ss(A, B, C, U, R) (__m128) __builtin_ia32_vfmsubss3_mask3 (A, B, C, U, R) +#define _mm_maskz_fmsub_round_sd(U, A, B, C, R) (__m128d) __builtin_ia32_vfmaddsd3_maskz (A, B, -(C), U, R) +#define _mm_maskz_fmsub_round_ss(U, A, B, C, R) (__m128) __builtin_ia32_vfmaddss3_maskz (A, B, -(C), U, R) +#define _mm_mask_fnmadd_round_sd(A, U, B, C, R) (__m128d) __builtin_ia32_vfmaddsd3_mask (A, -(B), C, U, R) +#define _mm_mask_fnmadd_round_ss(A, U, B, C, R) (__m128) __builtin_ia32_vfmaddss3_mask (A, -(B), C, U, R) +#define _mm_mask3_fnmadd_round_sd(A, B, C, U, R) (__m128d) __builtin_ia32_vfmaddsd3_mask3 (A, -(B), C, U, R) +#define _mm_mask3_fnmadd_round_ss(A, B, C, U, R) (__m128) __builtin_ia32_vfmaddss3_mask3 (A, -(B), C, U, R) +#define _mm_maskz_fnmadd_round_sd(U, A, B, C, R) (__m128d) __builtin_ia32_vfmaddsd3_maskz (A, -(B), C, U, R) +#define _mm_maskz_fnmadd_round_ss(U, A, B, C, R) (__m128) __builtin_ia32_vfmaddss3_maskz (A, -(B), C, U, R) +#define _mm_mask_fnmsub_round_sd(A, U, B, C, R) (__m128d) __builtin_ia32_vfmaddsd3_mask (A, -(B), -(C), U, R) +#define _mm_mask_fnmsub_round_ss(A, U, B, C, R) (__m128) __builtin_ia32_vfmaddss3_mask (A, -(B), -(C), U, R) +#define _mm_mask3_fnmsub_round_sd(A, B, C, U, R) (__m128d) __builtin_ia32_vfmsubsd3_mask3 (A, -(B), C, U, R) +#define _mm_mask3_fnmsub_round_ss(A, B, C, U, R) (__m128) __builtin_ia32_vfmsubss3_mask3 (A, -(B), C, U, R) +#define _mm_maskz_fnmsub_round_sd(U, A, B, C, R) (__m128d) __builtin_ia32_vfmaddsd3_maskz (A, -(B), -(C), U, R) +#define _mm_maskz_fnmsub_round_ss(U, A, B, C, R) (__m128) __builtin_ia32_vfmaddss3_maskz (A, -(B), -(C), U, R) +#endif +#ifdef __OPTIMIZE__ +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_comi_round_ss (__m128 __A, __m128 __B, const int __P, const int __R) +{ + return __builtin_ia32_vcomiss ((__v4sf) __A, (__v4sf) __B, __P, __R); +} +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_comi_round_sd (__m128d __A, __m128d __B, const int __P, const int __R) +{ + return __builtin_ia32_vcomisd ((__v2df) __A, (__v2df) __B, __P, __R); +} +#else +#define _mm_comi_round_ss(A, B, C, D)__builtin_ia32_vcomiss(A, B, C, D) +#define _mm_comi_round_sd(A, B, C, D)__builtin_ia32_vcomisd(A, B, C, D) +#endif +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_add_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_addsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_add_sd (__mmask8 __U, __m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_addsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) + _mm_avx512_setzero_pd (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_add_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_addss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_add_ss (__mmask8 __U, __m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_addss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) + _mm_avx512_setzero_ps (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_sub_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_subsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_sub_sd (__mmask8 __U, __m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_subsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) + _mm_avx512_setzero_pd (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_sub_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_subss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_sub_ss (__mmask8 __U, __m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_subss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) + _mm_avx512_setzero_ps (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_mul_sd (__m128d __W, __mmask8 __U, __m128d __A, + __m128d __B) +{ + return (__m128d) __builtin_ia32_mulsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_mul_sd (__mmask8 __U, __m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_mulsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) + _mm_avx512_setzero_pd (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_mul_ss (__m128 __W, __mmask8 __U, __m128 __A, + __m128 __B) +{ + return (__m128) __builtin_ia32_mulss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_mul_ss (__mmask8 __U, __m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_mulss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) + _mm_avx512_setzero_ps (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_div_sd (__m128d __W, __mmask8 __U, __m128d __A, + __m128d __B) +{ + return (__m128d) __builtin_ia32_divsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_div_sd (__mmask8 __U, __m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_divsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) + _mm_avx512_setzero_pd (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_div_ss (__m128 __W, __mmask8 __U, __m128 __A, + __m128 __B) +{ + return (__m128) __builtin_ia32_divss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_div_ss (__mmask8 __U, __m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_divss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) + _mm_avx512_setzero_ps (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_max_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_maxsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_max_sd (__mmask8 __U, __m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_maxsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) + _mm_avx512_setzero_pd (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_max_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_maxss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_max_ss (__mmask8 __U, __m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_maxss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) + _mm_avx512_setzero_ps (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_min_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_minsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_min_sd (__mmask8 __U, __m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_minsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) + _mm_avx512_setzero_pd (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_min_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_minss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_min_ss (__mmask8 __U, __m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_minss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) + _mm_avx512_setzero_ps (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_scalef_sd (__m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_scalefsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) + _mm_avx512_setzero_pd (), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_scalef_ss (__m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_scalefss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) + _mm_avx512_setzero_ps (), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +#ifdef __x86_64__ +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtu64_ss (__m128 __A, unsigned long long __B) +{ + return (__m128) __builtin_ia32_cvtusi2ss64 ((__v4sf) __A, __B, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtu64_sd (__m128d __A, unsigned long long __B) +{ + return (__m128d) __builtin_ia32_cvtusi2sd64 ((__v2df) __A, __B, + _MM_FROUND_CUR_DIRECTION); +} +#endif +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtu32_ss (__m128 __A, unsigned __B) +{ + return (__m128) __builtin_ia32_cvtusi2ss32 ((__v4sf) __A, __B, + _MM_FROUND_CUR_DIRECTION); +} +#ifdef __OPTIMIZE__ +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_fixupimm_sd (__m128d __A, __m128d __B, __m128i __C, const int __imm) +{ + return (__m128d) __builtin_ia32_fixupimmsd_mask ((__v2df) __A, + (__v2df) __B, + (__v2di) __C, __imm, + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fixupimm_sd (__m128d __A, __mmask8 __U, __m128d __B, + __m128i __C, const int __imm) +{ + return (__m128d) __builtin_ia32_fixupimmsd_mask ((__v2df) __A, + (__v2df) __B, + (__v2di) __C, __imm, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fixupimm_sd (__mmask8 __U, __m128d __A, __m128d __B, + __m128i __C, const int __imm) +{ + return (__m128d) __builtin_ia32_fixupimmsd_maskz ((__v2df) __A, + (__v2df) __B, + (__v2di) __C, + __imm, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_fixupimm_ss (__m128 __A, __m128 __B, __m128i __C, const int __imm) +{ + return (__m128) __builtin_ia32_fixupimmss_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4si) __C, __imm, + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fixupimm_ss (__m128 __A, __mmask8 __U, __m128 __B, + __m128i __C, const int __imm) +{ + return (__m128) __builtin_ia32_fixupimmss_mask ((__v4sf) __A, + (__v4sf) __B, + (__v4si) __C, __imm, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fixupimm_ss (__mmask8 __U, __m128 __A, __m128 __B, + __m128i __C, const int __imm) +{ + return (__m128) __builtin_ia32_fixupimmss_maskz ((__v4sf) __A, + (__v4sf) __B, + (__v4si) __C, __imm, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +#else +#define _mm_fixupimm_sd(X, Y, Z, C) ((__m128d)__builtin_ia32_fixupimmsd_mask ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (__v2di)(__m128i)(Z), (int)(C), (__mmask8)(-1), _MM_FROUND_CUR_DIRECTION)) +#define _mm_mask_fixupimm_sd(X, U, Y, Z, C) ((__m128d)__builtin_ia32_fixupimmsd_mask ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (__v2di)(__m128i)(Z), (int)(C), (__mmask8)(U), _MM_FROUND_CUR_DIRECTION)) +#define _mm_maskz_fixupimm_sd(U, X, Y, Z, C) ((__m128d)__builtin_ia32_fixupimmsd_maskz ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (__v2di)(__m128i)(Z), (int)(C), (__mmask8)(U), _MM_FROUND_CUR_DIRECTION)) +#define _mm_fixupimm_ss(X, Y, Z, C) ((__m128)__builtin_ia32_fixupimmss_mask ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (__v4si)(__m128i)(Z), (int)(C), (__mmask8)(-1), _MM_FROUND_CUR_DIRECTION)) +#define _mm_mask_fixupimm_ss(X, U, Y, Z, C) ((__m128)__builtin_ia32_fixupimmss_mask ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (__v4si)(__m128i)(Z), (int)(C), (__mmask8)(U), _MM_FROUND_CUR_DIRECTION)) +#define _mm_maskz_fixupimm_ss(U, X, Y, Z, C) ((__m128)__builtin_ia32_fixupimmss_maskz ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (__v4si)(__m128i)(Z), (int)(C), (__mmask8)(U), _MM_FROUND_CUR_DIRECTION)) +#endif +#ifdef __x86_64__ +extern __inline unsigned long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtss_u64 (__m128 __A) +{ + return (unsigned long long) __builtin_ia32_vcvtss2usi64 ((__v4sf) + __A, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline unsigned long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvttss_u64 (__m128 __A) +{ + return (unsigned long long) __builtin_ia32_vcvttss2usi64 ((__v4sf) + __A, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvttss_i64 (__m128 __A) +{ + return (long long) __builtin_ia32_vcvttss2si64 ((__v4sf) __A, + _MM_FROUND_CUR_DIRECTION); +} +#endif +extern __inline unsigned +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtss_u32 (__m128 __A) +{ + return (unsigned) __builtin_ia32_vcvtss2usi32 ((__v4sf) __A, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline unsigned +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvttss_u32 (__m128 __A) +{ + return (unsigned) __builtin_ia32_vcvttss2usi32 ((__v4sf) __A, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvttss_i32 (__m128 __A) +{ + return (int) __builtin_ia32_vcvttss2si32 ((__v4sf) __A, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtsd_i32 (__m128d __A) +{ + return (int) __builtin_ia32_cvtsd2si ((__v2df) __A); +} +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtss_i32 (__m128 __A) +{ + return (int) __builtin_ia32_cvtss2si ((__v4sf) __A); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvti32_sd (__m128d __A, int __B) +{ + return (__m128d) __builtin_ia32_cvtsi2sd ((__v2df) __A, __B); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvti32_ss (__m128 __A, int __B) +{ + return (__m128) __builtin_ia32_cvtsi2ss ((__v4sf) __A, __B); +} +#ifdef __x86_64__ +extern __inline unsigned long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtsd_u64 (__m128d __A) +{ + return (unsigned long long) __builtin_ia32_vcvtsd2usi64 ((__v2df) + __A, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline unsigned long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvttsd_u64 (__m128d __A) +{ + return (unsigned long long) __builtin_ia32_vcvttsd2usi64 ((__v2df) + __A, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvttsd_i64 (__m128d __A) +{ + return (long long) __builtin_ia32_vcvttsd2si64 ((__v2df) __A, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtsd_i64 (__m128d __A) +{ + return (long long) __builtin_ia32_cvtsd2si64 ((__v2df) __A); +} +extern __inline long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtss_i64 (__m128 __A) +{ + return (long long) __builtin_ia32_cvtss2si64 ((__v4sf) __A); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvti64_sd (__m128d __A, long long __B) +{ + return (__m128d) __builtin_ia32_cvtsi642sd ((__v2df) __A, __B); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvti64_ss (__m128 __A, long long __B) +{ + return (__m128) __builtin_ia32_cvtsi642ss ((__v4sf) __A, __B); +} +#endif +extern __inline unsigned +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtsd_u32 (__m128d __A) +{ + return (unsigned) __builtin_ia32_vcvtsd2usi32 ((__v2df) __A, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline unsigned +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvttsd_u32 (__m128d __A) +{ + return (unsigned) __builtin_ia32_vcvttsd2usi32 ((__v2df) __A, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvttsd_i32 (__m128d __A) +{ + return (int) __builtin_ia32_vcvttsd2si32 ((__v2df) __A, + _MM_FROUND_CUR_DIRECTION); +} +#ifdef __OPTIMIZE__ +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_getexp_ss (__m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_getexpss128_round ((__v4sf) __A, + (__v4sf) __B, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_getexp_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_getexpss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_getexp_ss (__mmask8 __U, __m128 __A, __m128 __B) +{ + return (__m128) __builtin_ia32_getexpss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__v4sf) + _mm_avx512_setzero_ps (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_getexp_sd (__m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_getexpsd128_round ((__v2df) __A, + (__v2df) __B, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_getexp_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_getexpsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) __W, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_getexp_sd (__mmask8 __U, __m128d __A, __m128d __B) +{ + return (__m128d) __builtin_ia32_getexpsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__v2df) + _mm_avx512_setzero_pd (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_getmant_sd (__m128d __A, __m128d __B, _MM_MANTISSA_NORM_ENUM __C, + _MM_MANTISSA_SIGN_ENUM __D) +{ + return (__m128d) __builtin_ia32_getmantsd_round ((__v2df) __A, + (__v2df) __B, + (__D << 2) | __C, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_getmant_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B, + _MM_MANTISSA_NORM_ENUM __C, _MM_MANTISSA_SIGN_ENUM __D) +{ + return (__m128d) __builtin_ia32_getmantsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__D << 2) | __C, + (__v2df) __W, + __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_getmant_sd (__mmask8 __U, __m128d __A, __m128d __B, + _MM_MANTISSA_NORM_ENUM __C, _MM_MANTISSA_SIGN_ENUM __D) +{ + return (__m128d) __builtin_ia32_getmantsd_mask_round ((__v2df) __A, + (__v2df) __B, + (__D << 2) | __C, + (__v2df) + _mm_avx512_setzero_pd(), + __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_getmant_ss (__m128 __A, __m128 __B, _MM_MANTISSA_NORM_ENUM __C, + _MM_MANTISSA_SIGN_ENUM __D) +{ + return (__m128) __builtin_ia32_getmantss_round ((__v4sf) __A, + (__v4sf) __B, + (__D << 2) | __C, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_getmant_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B, + _MM_MANTISSA_NORM_ENUM __C, _MM_MANTISSA_SIGN_ENUM __D) +{ + return (__m128) __builtin_ia32_getmantss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__D << 2) | __C, + (__v4sf) __W, + __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_getmant_ss (__mmask8 __U, __m128 __A, __m128 __B, + _MM_MANTISSA_NORM_ENUM __C, _MM_MANTISSA_SIGN_ENUM __D) +{ + return (__m128) __builtin_ia32_getmantss_mask_round ((__v4sf) __A, + (__v4sf) __B, + (__D << 2) | __C, + (__v4sf) + _mm_avx512_setzero_ps(), + __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_roundscale_ss (__m128 __A, __m128 __B, const int __imm) +{ + return (__m128) + __builtin_ia32_rndscaless_mask_round ((__v4sf) __A, + (__v4sf) __B, __imm, + (__v4sf) + _mm_avx512_setzero_ps (), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_roundscale_ss (__m128 __A, __mmask8 __B, __m128 __C, __m128 __D, + const int __imm) +{ + return (__m128) + __builtin_ia32_rndscaless_mask_round ((__v4sf) __C, + (__v4sf) __D, __imm, + (__v4sf) __A, + (__mmask8) __B, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_roundscale_ss (__mmask8 __A, __m128 __B, __m128 __C, + const int __imm) +{ + return (__m128) + __builtin_ia32_rndscaless_mask_round ((__v4sf) __B, + (__v4sf) __C, __imm, + (__v4sf) + _mm_avx512_setzero_ps (), + (__mmask8) __A, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_roundscale_sd (__m128d __A, __m128d __B, const int __imm) +{ + return (__m128d) + __builtin_ia32_rndscalesd_mask_round ((__v2df) __A, + (__v2df) __B, __imm, + (__v2df) + _mm_avx512_setzero_pd (), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_roundscale_sd (__m128d __A, __mmask8 __B, __m128d __C, __m128d __D, + const int __imm) +{ + return (__m128d) + __builtin_ia32_rndscalesd_mask_round ((__v2df) __C, + (__v2df) __D, __imm, + (__v2df) __A, + (__mmask8) __B, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_roundscale_sd (__mmask8 __A, __m128d __B, __m128d __C, + const int __imm) +{ + return (__m128d) + __builtin_ia32_rndscalesd_mask_round ((__v2df) __B, + (__v2df) __C, __imm, + (__v2df) + _mm_avx512_setzero_pd (), + (__mmask8) __A, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __mmask8 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cmp_sd_mask (__m128d __X, __m128d __Y, const int __P) +{ + return (__mmask8) __builtin_ia32_cmpsd_mask ((__v2df) __X, + (__v2df) __Y, __P, + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __mmask8 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_cmp_sd_mask (__mmask8 __M, __m128d __X, __m128d __Y, const int __P) +{ + return (__mmask8) __builtin_ia32_cmpsd_mask ((__v2df) __X, + (__v2df) __Y, __P, + (__mmask8) __M, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __mmask8 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cmp_ss_mask (__m128 __X, __m128 __Y, const int __P) +{ + return (__mmask8) __builtin_ia32_cmpss_mask ((__v4sf) __X, + (__v4sf) __Y, __P, + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __mmask8 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_cmp_ss_mask (__mmask8 __M, __m128 __X, __m128 __Y, const int __P) +{ + return (__mmask8) __builtin_ia32_cmpss_mask ((__v4sf) __X, + (__v4sf) __Y, __P, + (__mmask8) __M, + _MM_FROUND_CUR_DIRECTION); +} +#else +#define _mm_getmant_sd(X, Y, C, D) ((__m128d)__builtin_ia32_getmantsd_round ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (int)(((D)<<2) | (C)), _MM_FROUND_CUR_DIRECTION)) +#define _mm_mask_getmant_sd(W, U, X, Y, C, D) ((__m128d)__builtin_ia32_getmantsd_mask_round ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (int)(((D)<<2) | (C)), (__v2df)(__m128d)(W), (__mmask8)(U), _MM_FROUND_CUR_DIRECTION)) +#define _mm_maskz_getmant_sd(U, X, Y, C, D) ((__m128d)__builtin_ia32_getmantsd_mask_round ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (int)(((D)<<2) | (C)), (__v2df)_mm_avx512_setzero_pd(), (__mmask8)(U), _MM_FROUND_CUR_DIRECTION)) +#define _mm_getmant_ss(X, Y, C, D) ((__m128)__builtin_ia32_getmantss_round ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (int)(((D)<<2) | (C)), _MM_FROUND_CUR_DIRECTION)) +#define _mm_mask_getmant_ss(W, U, X, Y, C, D) ((__m128)__builtin_ia32_getmantss_mask_round ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (int)(((D)<<2) | (C)), (__v4sf)(__m128)(W), (__mmask8)(U), _MM_FROUND_CUR_DIRECTION)) +#define _mm_maskz_getmant_ss(U, X, Y, C, D) ((__m128)__builtin_ia32_getmantss_mask_round ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (int)(((D)<<2) | (C)), (__v4sf)_mm_avx512_setzero_ps(), (__mmask8)(U), _MM_FROUND_CUR_DIRECTION)) +#define _mm_getexp_ss(A, B) ((__m128)__builtin_ia32_getexpss128_round((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), _MM_FROUND_CUR_DIRECTION)) +#define _mm_mask_getexp_ss(W, U, A, B) (__m128)__builtin_ia32_getexpss_mask_round(A, B, W, U, _MM_FROUND_CUR_DIRECTION) +#define _mm_maskz_getexp_ss(U, A, B) (__m128)__builtin_ia32_getexpss_mask_round(A, B, (__v4sf)_mm_avx512_setzero_ps(), U, _MM_FROUND_CUR_DIRECTION) +#define _mm_getexp_sd(A, B) ((__m128d)__builtin_ia32_getexpsd128_round((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), _MM_FROUND_CUR_DIRECTION)) +#define _mm_mask_getexp_sd(W, U, A, B) (__m128d)__builtin_ia32_getexpsd_mask_round(A, B, W, U, _MM_FROUND_CUR_DIRECTION) +#define _mm_maskz_getexp_sd(U, A, B) (__m128d)__builtin_ia32_getexpsd_mask_round(A, B, (__v2df)_mm_avx512_setzero_pd(), U, _MM_FROUND_CUR_DIRECTION) +#define _mm_roundscale_ss(A, B, I) ((__m128) __builtin_ia32_rndscaless_mask_round ((__v4sf) (__m128) (A), (__v4sf) (__m128) (B), (int) (I), (__v4sf) _mm_avx512_setzero_ps (), (__mmask8) (-1), _MM_FROUND_CUR_DIRECTION)) +#define _mm_mask_roundscale_ss(A, U, B, C, I) ((__m128) __builtin_ia32_rndscaless_mask_round ((__v4sf) (__m128) (B), (__v4sf) (__m128) (C), (int) (I), (__v4sf) (__m128) (A), (__mmask8) (U), _MM_FROUND_CUR_DIRECTION)) +#define _mm_maskz_roundscale_ss(U, A, B, I) ((__m128) __builtin_ia32_rndscaless_mask_round ((__v4sf) (__m128) (A), (__v4sf) (__m128) (B), (int) (I), (__v4sf) _mm_avx512_setzero_ps (), (__mmask8) (U), _MM_FROUND_CUR_DIRECTION)) +#define _mm_roundscale_sd(A, B, I) ((__m128d) __builtin_ia32_rndscalesd_mask_round ((__v2df) (__m128d) (A), (__v2df) (__m128d) (B), (int) (I), (__v2df) _mm_avx512_setzero_pd (), (__mmask8) (-1), _MM_FROUND_CUR_DIRECTION)) +#define _mm_mask_roundscale_sd(A, U, B, C, I) ((__m128d) __builtin_ia32_rndscalesd_mask_round ((__v2df) (__m128d) (B), (__v2df) (__m128d) (C), (int) (I), (__v2df) (__m128d) (A), (__mmask8) (U), _MM_FROUND_CUR_DIRECTION)) +#define _mm_maskz_roundscale_sd(U, A, B, I) ((__m128d) __builtin_ia32_rndscalesd_mask_round ((__v2df) (__m128d) (A), (__v2df) (__m128d) (B), (int) (I), (__v2df) _mm_avx512_setzero_pd (), (__mmask8) (U), _MM_FROUND_CUR_DIRECTION)) +#define _mm_cmp_sd_mask(X, Y, P) ((__mmask8) __builtin_ia32_cmpsd_mask ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (int)(P), (__mmask8)-1,_MM_FROUND_CUR_DIRECTION)) +#define _mm_mask_cmp_sd_mask(M, X, Y, P) ((__mmask8) __builtin_ia32_cmpsd_mask ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (int)(P), M,_MM_FROUND_CUR_DIRECTION)) +#define _mm_cmp_ss_mask(X, Y, P) ((__mmask8) __builtin_ia32_cmpss_mask ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (int)(P), (__mmask8)-1,_MM_FROUND_CUR_DIRECTION)) +#define _mm_mask_cmp_ss_mask(M, X, Y, P) ((__mmask8) __builtin_ia32_cmpss_mask ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (int)(P), M,_MM_FROUND_CUR_DIRECTION)) +#endif +#ifdef __DISABLE_AVX512F__ +#undef __DISABLE_AVX512F__ +#pragma GCC pop_options +#endif +#if !defined (__AVX512F__) || !defined (__EVEX512__) +#pragma GCC push_options +#pragma GCC target("avx512f,evex512") +#define __DISABLE_AVX512F_512__ +#endif typedef double __v8df __attribute__ ((__vector_size__ (64))); typedef float __v16sf __attribute__ ((__vector_size__ (64))); typedef long long __v8di __attribute__ ((__vector_size__ (64))); @@ -25,8 +2939,6 @@ typedef double __m512d __attribute__ ((__vector_size__ (64), __may_alias__)); typedef float __m512_u __attribute__ ((__vector_size__ (64), __may_alias__, __aligned__ (1))); typedef long long __m512i_u __attribute__ ((__vector_size__ (64), __may_alias__, __aligned__ (1))); typedef double __m512d_u __attribute__ ((__vector_size__ (64), __may_alias__, __aligned__ (1))); -typedef unsigned char __mmask8; -typedef unsigned short __mmask16; extern __inline __mmask16 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_int2mask (int __M) @@ -134,7 +3046,10 @@ extern __inline __m512 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_undefined_ps (void) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Winit-self" __m512 __Y = __Y; +#pragma GCC diagnostic pop return __Y; } #define _mm512_undefined _mm512_undefined_ps @@ -142,14 +3057,20 @@ extern __inline __m512d __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_undefined_pd (void) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Winit-self" __m512d __Y = __Y; +#pragma GCC diagnostic pop return __Y; } extern __inline __m512i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_undefined_epi32 (void) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Winit-self" __m512i __Y = __Y; +#pragma GCC diagnostic pop return __Y; } #define _mm512_undefined_si512 _mm512_undefined_epi32 @@ -877,9 +3798,9 @@ _mm512_maskz_slli_epi64 (__mmask8 __U, __m512i __A, unsigned int __B) (__mmask8) __U); } #else -#define _mm512_slli_epi64(X, C) ((__m512i) __builtin_ia32_psllqi512_mask ((__v8di)(__m512i)(X), (int)(C), (__v8di)(__m512i)_mm512_undefined_epi32 (), (__mmask8)-1)) -#define _mm512_mask_slli_epi64(W, U, X, C) ((__m512i) __builtin_ia32_psllqi512_mask ((__v8di)(__m512i)(X), (int)(C), (__v8di)(__m512i)(W), (__mmask8)(U))) -#define _mm512_maskz_slli_epi64(U, X, C) ((__m512i) __builtin_ia32_psllqi512_mask ((__v8di)(__m512i)(X), (int)(C), (__v8di)(__m512i)_mm512_setzero_si512 (), (__mmask8)(U))) +#define _mm512_slli_epi64(X, C) ((__m512i) __builtin_ia32_psllqi512_mask ((__v8di)(__m512i)(X), (unsigned int)(C), (__v8di)(__m512i)_mm512_undefined_epi32 (), (__mmask8)-1)) +#define _mm512_mask_slli_epi64(W, U, X, C) ((__m512i) __builtin_ia32_psllqi512_mask ((__v8di)(__m512i)(X), (unsigned int)(C), (__v8di)(__m512i)(W), (__mmask8)(U))) +#define _mm512_maskz_slli_epi64(U, X, C) ((__m512i) __builtin_ia32_psllqi512_mask ((__v8di)(__m512i)(X), (unsigned int)(C), (__v8di)(__m512i)_mm512_setzero_si512 (), (__mmask8)(U))) #endif extern __inline __m512i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) @@ -939,9 +3860,9 @@ _mm512_maskz_srli_epi64 (__mmask8 __U, __m512i __A, unsigned int __B) (__mmask8) __U); } #else -#define _mm512_srli_epi64(X, C) ((__m512i) __builtin_ia32_psrlqi512_mask ((__v8di)(__m512i)(X), (int)(C), (__v8di)(__m512i)_mm512_undefined_epi32 (), (__mmask8)-1)) -#define _mm512_mask_srli_epi64(W, U, X, C) ((__m512i) __builtin_ia32_psrlqi512_mask ((__v8di)(__m512i)(X), (int)(C), (__v8di)(__m512i)(W), (__mmask8)(U))) -#define _mm512_maskz_srli_epi64(U, X, C) ((__m512i) __builtin_ia32_psrlqi512_mask ((__v8di)(__m512i)(X), (int)(C), (__v8di)(__m512i)_mm512_setzero_si512 (), (__mmask8)(U))) +#define _mm512_srli_epi64(X, C) ((__m512i) __builtin_ia32_psrlqi512_mask ((__v8di)(__m512i)(X), (unsigned int)(C), (__v8di)(__m512i)_mm512_undefined_epi32 (), (__mmask8)-1)) +#define _mm512_mask_srli_epi64(W, U, X, C) ((__m512i) __builtin_ia32_psrlqi512_mask ((__v8di)(__m512i)(X), (unsigned int)(C), (__v8di)(__m512i)(W), (__mmask8)(U))) +#define _mm512_maskz_srli_epi64(U, X, C) ((__m512i) __builtin_ia32_psrlqi512_mask ((__v8di)(__m512i)(X), (unsigned int)(C), (__v8di)(__m512i)_mm512_setzero_si512 (), (__mmask8)(U))) #endif extern __inline __m512i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) @@ -1001,9 +3922,9 @@ _mm512_maskz_srai_epi64 (__mmask8 __U, __m512i __A, unsigned int __B) (__mmask8) __U); } #else -#define _mm512_srai_epi64(X, C) ((__m512i) __builtin_ia32_psraqi512_mask ((__v8di)(__m512i)(X), (int)(C), (__v8di)(__m512i)_mm512_undefined_epi32 (), (__mmask8)-1)) -#define _mm512_mask_srai_epi64(W, U, X, C) ((__m512i) __builtin_ia32_psraqi512_mask ((__v8di)(__m512i)(X), (int)(C), (__v8di)(__m512i)(W), (__mmask8)(U))) -#define _mm512_maskz_srai_epi64(U, X, C) ((__m512i) __builtin_ia32_psraqi512_mask ((__v8di)(__m512i)(X), (int)(C), (__v8di)(__m512i)_mm512_setzero_si512 (), (__mmask8)(U))) +#define _mm512_srai_epi64(X, C) ((__m512i) __builtin_ia32_psraqi512_mask ((__v8di)(__m512i)(X), (unsigned int)(C), (__v8di)(__m512i)_mm512_undefined_epi32 (), (__mmask8)-1)) +#define _mm512_mask_srai_epi64(W, U, X, C) ((__m512i) __builtin_ia32_psraqi512_mask ((__v8di)(__m512i)(X), (unsigned int)(C), (__v8di)(__m512i)(W), (__mmask8)(U))) +#define _mm512_maskz_srai_epi64(U, X, C) ((__m512i) __builtin_ia32_psraqi512_mask ((__v8di)(__m512i)(X), (unsigned int)(C), (__v8di)(__m512i)_mm512_setzero_si512 (), (__mmask8)(U))) #endif extern __inline __m512i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) @@ -1063,9 +3984,9 @@ _mm512_maskz_slli_epi32 (__mmask16 __U, __m512i __A, unsigned int __B) (__mmask16) __U); } #else -#define _mm512_slli_epi32(X, C) ((__m512i) __builtin_ia32_pslldi512_mask ((__v16si)(__m512i)(X), (int)(C), (__v16si)(__m512i)_mm512_undefined_epi32 (), (__mmask16)-1)) -#define _mm512_mask_slli_epi32(W, U, X, C) ((__m512i) __builtin_ia32_pslldi512_mask ((__v16si)(__m512i)(X), (int)(C), (__v16si)(__m512i)(W), (__mmask16)(U))) -#define _mm512_maskz_slli_epi32(U, X, C) ((__m512i) __builtin_ia32_pslldi512_mask ((__v16si)(__m512i)(X), (int)(C), (__v16si)(__m512i)_mm512_setzero_si512 (), (__mmask16)(U))) +#define _mm512_slli_epi32(X, C) ((__m512i) __builtin_ia32_pslldi512_mask ((__v16si)(__m512i)(X), (unsigned int)(C), (__v16si)(__m512i)_mm512_undefined_epi32 (), (__mmask16)-1)) +#define _mm512_mask_slli_epi32(W, U, X, C) ((__m512i) __builtin_ia32_pslldi512_mask ((__v16si)(__m512i)(X), (unsigned int)(C), (__v16si)(__m512i)(W), (__mmask16)(U))) +#define _mm512_maskz_slli_epi32(U, X, C) ((__m512i) __builtin_ia32_pslldi512_mask ((__v16si)(__m512i)(X), (unsigned int)(C), (__v16si)(__m512i)_mm512_setzero_si512 (), (__mmask16)(U))) #endif extern __inline __m512i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) @@ -1125,9 +4046,9 @@ _mm512_maskz_srli_epi32 (__mmask16 __U, __m512i __A, unsigned int __B) (__mmask16) __U); } #else -#define _mm512_srli_epi32(X, C) ((__m512i) __builtin_ia32_psrldi512_mask ((__v16si)(__m512i)(X), (int)(C), (__v16si)(__m512i)_mm512_undefined_epi32 (), (__mmask16)-1)) -#define _mm512_mask_srli_epi32(W, U, X, C) ((__m512i) __builtin_ia32_psrldi512_mask ((__v16si)(__m512i)(X), (int)(C), (__v16si)(__m512i)(W), (__mmask16)(U))) -#define _mm512_maskz_srli_epi32(U, X, C) ((__m512i) __builtin_ia32_psrldi512_mask ((__v16si)(__m512i)(X), (int)(C), (__v16si)(__m512i)_mm512_setzero_si512 (), (__mmask16)(U))) +#define _mm512_srli_epi32(X, C) ((__m512i) __builtin_ia32_psrldi512_mask ((__v16si)(__m512i)(X), (unsigned int)(C), (__v16si)(__m512i)_mm512_undefined_epi32 (), (__mmask16)-1)) +#define _mm512_mask_srli_epi32(W, U, X, C) ((__m512i) __builtin_ia32_psrldi512_mask ((__v16si)(__m512i)(X), (unsigned int)(C), (__v16si)(__m512i)(W), (__mmask16)(U))) +#define _mm512_maskz_srli_epi32(U, X, C) ((__m512i) __builtin_ia32_psrldi512_mask ((__v16si)(__m512i)(X), (unsigned int)(C), (__v16si)(__m512i)_mm512_setzero_si512 (), (__mmask16)(U))) #endif extern __inline __m512i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) @@ -1187,9 +4108,9 @@ _mm512_maskz_srai_epi32 (__mmask16 __U, __m512i __A, unsigned int __B) (__mmask16) __U); } #else -#define _mm512_srai_epi32(X, C) ((__m512i) __builtin_ia32_psradi512_mask ((__v16si)(__m512i)(X), (int)(C), (__v16si)(__m512i)_mm512_undefined_epi32 (), (__mmask16)-1)) -#define _mm512_mask_srai_epi32(W, U, X, C) ((__m512i) __builtin_ia32_psradi512_mask ((__v16si)(__m512i)(X), (int)(C), (__v16si)(__m512i)(W), (__mmask16)(U))) -#define _mm512_maskz_srai_epi32(U, X, C) ((__m512i) __builtin_ia32_psradi512_mask ((__v16si)(__m512i)(X), (int)(C), (__v16si)(__m512i)_mm512_setzero_si512 (), (__mmask16)(U))) +#define _mm512_srai_epi32(X, C) ((__m512i) __builtin_ia32_psradi512_mask ((__v16si)(__m512i)(X), (unsigned int)(C), (__v16si)(__m512i)_mm512_undefined_epi32 (), (__mmask16)-1)) +#define _mm512_mask_srai_epi32(W, U, X, C) ((__m512i) __builtin_ia32_psradi512_mask ((__v16si)(__m512i)(X), (unsigned int)(C), (__v16si)(__m512i)(W), (__mmask16)(U))) +#define _mm512_maskz_srai_epi32(U, X, C) ((__m512i) __builtin_ia32_psradi512_mask ((__v16si)(__m512i)(X), (unsigned int)(C), (__v16si)(__m512i)_mm512_setzero_si512 (), (__mmask16)(U))) #endif extern __inline __m512i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) @@ -1220,137 +4141,6 @@ _mm512_maskz_sra_epi32 (__mmask16 __U, __m512i __A, __m128i __B) _mm512_setzero_si512 (), (__mmask16) __U); } -#ifdef __OPTIMIZE__ -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_add_round_sd (__m128d __A, __m128d __B, const int __R) -{ - return (__m128d) __builtin_ia32_addsd_round ((__v2df) __A, - (__v2df) __B, - __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_add_round_sd (__m128d __W, __mmask8 __U, __m128d __A, - __m128d __B, const int __R) -{ - return (__m128d) __builtin_ia32_addsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) __W, - (__mmask8) __U, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_add_round_sd (__mmask8 __U, __m128d __A, __m128d __B, - const int __R) -{ - return (__m128d) __builtin_ia32_addsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) - _mm_setzero_pd (), - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_add_round_ss (__m128 __A, __m128 __B, const int __R) -{ - return (__m128) __builtin_ia32_addss_round ((__v4sf) __A, - (__v4sf) __B, - __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_add_round_ss (__m128 __W, __mmask8 __U, __m128 __A, - __m128 __B, const int __R) -{ - return (__m128) __builtin_ia32_addss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) __W, - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_add_round_ss (__mmask8 __U, __m128 __A, __m128 __B, - const int __R) -{ - return (__m128) __builtin_ia32_addss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) - _mm_setzero_ps (), - (__mmask8) __U, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_sub_round_sd (__m128d __A, __m128d __B, const int __R) -{ - return (__m128d) __builtin_ia32_subsd_round ((__v2df) __A, - (__v2df) __B, - __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_sub_round_sd (__m128d __W, __mmask8 __U, __m128d __A, - __m128d __B, const int __R) -{ - return (__m128d) __builtin_ia32_subsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) __W, - (__mmask8) __U, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_sub_round_sd (__mmask8 __U, __m128d __A, __m128d __B, - const int __R) -{ - return (__m128d) __builtin_ia32_subsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) - _mm_setzero_pd (), - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_sub_round_ss (__m128 __A, __m128 __B, const int __R) -{ - return (__m128) __builtin_ia32_subss_round ((__v4sf) __A, - (__v4sf) __B, - __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_sub_round_ss (__m128 __W, __mmask8 __U, __m128 __A, - __m128 __B, const int __R) -{ - return (__m128) __builtin_ia32_subss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) __W, - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_sub_round_ss (__mmask8 __U, __m128 __A, __m128 __B, - const int __R) -{ - return (__m128) __builtin_ia32_subss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) - _mm_setzero_ps (), - (__mmask8) __U, __R); -} -#else -#define _mm_add_round_sd(A, B, C) (__m128d)__builtin_ia32_addsd_round(A, B, C) -#define _mm_mask_add_round_sd(W, U, A, B, C) (__m128d)__builtin_ia32_addsd_mask_round(A, B, W, U, C) -#define _mm_maskz_add_round_sd(U, A, B, C) (__m128d)__builtin_ia32_addsd_mask_round(A, B, (__v2df)_mm_setzero_pd(), U, C) -#define _mm_add_round_ss(A, B, C) (__m128)__builtin_ia32_addss_round(A, B, C) -#define _mm_mask_add_round_ss(W, U, A, B, C) (__m128)__builtin_ia32_addss_mask_round(A, B, W, U, C) -#define _mm_maskz_add_round_ss(U, A, B, C) (__m128)__builtin_ia32_addss_mask_round(A, B, (__v4sf)_mm_setzero_ps(), U, C) -#define _mm_sub_round_sd(A, B, C) (__m128d)__builtin_ia32_subsd_round(A, B, C) -#define _mm_mask_sub_round_sd(W, U, A, B, C) (__m128d)__builtin_ia32_subsd_mask_round(A, B, W, U, C) -#define _mm_maskz_sub_round_sd(U, A, B, C) (__m128d)__builtin_ia32_subsd_mask_round(A, B, (__v2df)_mm_setzero_pd(), U, C) -#define _mm_sub_round_ss(A, B, C) (__m128)__builtin_ia32_subss_round(A, B, C) -#define _mm_mask_sub_round_ss(W, U, A, B, C) (__m128)__builtin_ia32_subss_mask_round(A, B, W, U, C) -#define _mm_maskz_sub_round_ss(U, A, B, C) (__m128)__builtin_ia32_subss_mask_round(A, B, (__v4sf)_mm_setzero_ps(), U, C) -#endif typedef enum { _MM_TERNLOG_A = 0xF0, @@ -1490,56 +4280,6 @@ _mm512_maskz_rcp14_ps (__mmask16 __U, __m512 __A) _mm512_setzero_ps (), (__mmask16) __U); } -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_rcp14_sd (__m128d __A, __m128d __B) -{ - return (__m128d) __builtin_ia32_rcp14sd ((__v2df) __B, - (__v2df) __A); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_rcp14_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) -{ - return (__m128d) __builtin_ia32_rcp14sd_mask ((__v2df) __B, - (__v2df) __A, - (__v2df) __W, - (__mmask8) __U); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_rcp14_sd (__mmask8 __U, __m128d __A, __m128d __B) -{ - return (__m128d) __builtin_ia32_rcp14sd_mask ((__v2df) __B, - (__v2df) __A, - (__v2df) _mm_setzero_ps (), - (__mmask8) __U); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_rcp14_ss (__m128 __A, __m128 __B) -{ - return (__m128) __builtin_ia32_rcp14ss ((__v4sf) __B, - (__v4sf) __A); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_rcp14_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) -{ - return (__m128) __builtin_ia32_rcp14ss_mask ((__v4sf) __B, - (__v4sf) __A, - (__v4sf) __W, - (__mmask8) __U); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_rcp14_ss (__mmask8 __U, __m128 __A, __m128 __B) -{ - return (__m128) __builtin_ia32_rcp14ss_mask ((__v4sf) __B, - (__v4sf) __A, - (__v4sf) _mm_setzero_ps (), - (__mmask8) __U); -} extern __inline __m512d __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_rsqrt14_pd (__m512d __A) @@ -1592,56 +4332,6 @@ _mm512_maskz_rsqrt14_ps (__mmask16 __U, __m512 __A) _mm512_setzero_ps (), (__mmask16) __U); } -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_rsqrt14_sd (__m128d __A, __m128d __B) -{ - return (__m128d) __builtin_ia32_rsqrt14sd ((__v2df) __B, - (__v2df) __A); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_rsqrt14_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) -{ - return (__m128d) __builtin_ia32_rsqrt14sd_mask ((__v2df) __B, - (__v2df) __A, - (__v2df) __W, - (__mmask8) __U); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_rsqrt14_sd (__mmask8 __U, __m128d __A, __m128d __B) -{ - return (__m128d) __builtin_ia32_rsqrt14sd_mask ((__v2df) __B, - (__v2df) __A, - (__v2df) _mm_setzero_pd (), - (__mmask8) __U); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_rsqrt14_ss (__m128 __A, __m128 __B) -{ - return (__m128) __builtin_ia32_rsqrt14ss ((__v4sf) __B, - (__v4sf) __A); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_rsqrt14_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) -{ - return (__m128) __builtin_ia32_rsqrt14ss_mask ((__v4sf) __B, - (__v4sf) __A, - (__v4sf) __W, - (__mmask8) __U); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_rsqrt14_ss (__mmask8 __U, __m128 __A, __m128 __B) -{ - return (__m128) __builtin_ia32_rsqrt14ss_mask ((__v4sf) __B, - (__v4sf) __A, - (__v4sf) _mm_setzero_ps (), - (__mmask8) __U); -} #ifdef __OPTIMIZE__ extern __inline __m512d __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) @@ -1696,66 +4386,6 @@ _mm512_maskz_sqrt_round_ps (__mmask16 __U, __m512 __A, const int __R) _mm512_setzero_ps (), (__mmask16) __U, __R); } -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_sqrt_round_sd (__m128d __A, __m128d __B, const int __R) -{ - return (__m128d) __builtin_ia32_sqrtsd_mask_round ((__v2df) __B, - (__v2df) __A, - (__v2df) - _mm_setzero_pd (), - (__mmask8) -1, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_sqrt_round_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B, - const int __R) -{ - return (__m128d) __builtin_ia32_sqrtsd_mask_round ((__v2df) __B, - (__v2df) __A, - (__v2df) __W, - (__mmask8) __U, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_sqrt_round_sd (__mmask8 __U, __m128d __A, __m128d __B, const int __R) -{ - return (__m128d) __builtin_ia32_sqrtsd_mask_round ((__v2df) __B, - (__v2df) __A, - (__v2df) - _mm_setzero_pd (), - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_sqrt_round_ss (__m128 __A, __m128 __B, const int __R) -{ - return (__m128) __builtin_ia32_sqrtss_mask_round ((__v4sf) __B, - (__v4sf) __A, - (__v4sf) - _mm_setzero_ps (), - (__mmask8) -1, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_sqrt_round_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B, - const int __R) -{ - return (__m128) __builtin_ia32_sqrtss_mask_round ((__v4sf) __B, - (__v4sf) __A, - (__v4sf) __W, - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_sqrt_round_ss (__mmask8 __U, __m128 __A, __m128 __B, const int __R) -{ - return (__m128) __builtin_ia32_sqrtss_mask_round ((__v4sf) __B, - (__v4sf) __A, - (__v4sf) - _mm_setzero_ps (), - (__mmask8) __U, __R); -} #else #define _mm512_sqrt_round_pd(A, C) (__m512d)__builtin_ia32_sqrtpd512_mask(A, (__v8df)_mm512_undefined_pd(), -1, C) #define _mm512_mask_sqrt_round_pd(W, U, A, C) (__m512d)__builtin_ia32_sqrtpd512_mask(A, W, U, C) @@ -1763,17 +4393,7 @@ _mm_maskz_sqrt_round_ss (__mmask8 __U, __m128 __A, __m128 __B, const int __R) #define _mm512_sqrt_round_ps(A, C) (__m512)__builtin_ia32_sqrtps512_mask(A, (__v16sf)_mm512_undefined_ps(), -1, C) #define _mm512_mask_sqrt_round_ps(W, U, A, C) (__m512)__builtin_ia32_sqrtps512_mask(A, W, U, C) #define _mm512_maskz_sqrt_round_ps(U, A, C) (__m512)__builtin_ia32_sqrtps512_mask(A, (__v16sf)_mm512_setzero_ps(), U, C) -#define _mm_sqrt_round_sd(A, B, C) (__m128d)__builtin_ia32_sqrtsd_mask_round (B, A, (__v2df) _mm_setzero_pd (), -1, C) -#define _mm_mask_sqrt_round_sd(W, U, A, B, C) (__m128d)__builtin_ia32_sqrtsd_mask_round (B, A, W, U, C) -#define _mm_maskz_sqrt_round_sd(U, A, B, C) (__m128d)__builtin_ia32_sqrtsd_mask_round (B, A, (__v2df) _mm_setzero_pd (), U, C) -#define _mm_sqrt_round_ss(A, B, C) (__m128)__builtin_ia32_sqrtss_mask_round (B, A, (__v4sf) _mm_setzero_ps (), -1, C) -#define _mm_mask_sqrt_round_ss(W, U, A, B, C) (__m128)__builtin_ia32_sqrtss_mask_round (B, A, W, U, C) -#define _mm_maskz_sqrt_round_ss(U, A, B, C) (__m128)__builtin_ia32_sqrtss_mask_round (B, A, (__v4sf) _mm_setzero_ps (), U, C) #endif -#define _mm_mask_sqrt_sd(W, U, A, B) _mm_mask_sqrt_round_sd ((W), (U), (A), (B), _MM_FROUND_CUR_DIRECTION) -#define _mm_maskz_sqrt_sd(U, A, B) _mm_maskz_sqrt_round_sd ((U), (A), (B), _MM_FROUND_CUR_DIRECTION) -#define _mm_mask_sqrt_ss(W, U, A, B) _mm_mask_sqrt_round_ss ((W), (U), (A), (B), _MM_FROUND_CUR_DIRECTION) -#define _mm_maskz_sqrt_ss(U, A, B) _mm_maskz_sqrt_round_ss ((U), (A), (B), _MM_FROUND_CUR_DIRECTION) extern __inline __m512i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_cvtepi8_epi32 (__m128i __A) @@ -2294,122 +4914,6 @@ _mm512_maskz_div_round_ps (__mmask16 __U, __m512 __A, __m512 __B, const int __R) _mm512_setzero_ps (), (__mmask16) __U, __R); } -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mul_round_sd (__m128d __A, __m128d __B, const int __R) -{ - return (__m128d) __builtin_ia32_mulsd_round ((__v2df) __A, - (__v2df) __B, - __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_mul_round_sd (__m128d __W, __mmask8 __U, __m128d __A, - __m128d __B, const int __R) -{ - return (__m128d) __builtin_ia32_mulsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) __W, - (__mmask8) __U, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_mul_round_sd (__mmask8 __U, __m128d __A, __m128d __B, - const int __R) -{ - return (__m128d) __builtin_ia32_mulsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) - _mm_setzero_pd (), - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mul_round_ss (__m128 __A, __m128 __B, const int __R) -{ - return (__m128) __builtin_ia32_mulss_round ((__v4sf) __A, - (__v4sf) __B, - __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_mul_round_ss (__m128 __W, __mmask8 __U, __m128 __A, - __m128 __B, const int __R) -{ - return (__m128) __builtin_ia32_mulss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) __W, - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_mul_round_ss (__mmask8 __U, __m128 __A, __m128 __B, - const int __R) -{ - return (__m128) __builtin_ia32_mulss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) - _mm_setzero_ps (), - (__mmask8) __U, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_div_round_sd (__m128d __A, __m128d __B, const int __R) -{ - return (__m128d) __builtin_ia32_divsd_round ((__v2df) __A, - (__v2df) __B, - __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_div_round_sd (__m128d __W, __mmask8 __U, __m128d __A, - __m128d __B, const int __R) -{ - return (__m128d) __builtin_ia32_divsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) __W, - (__mmask8) __U, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_div_round_sd (__mmask8 __U, __m128d __A, __m128d __B, - const int __R) -{ - return (__m128d) __builtin_ia32_divsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) - _mm_setzero_pd (), - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_div_round_ss (__m128 __A, __m128 __B, const int __R) -{ - return (__m128) __builtin_ia32_divss_round ((__v4sf) __A, - (__v4sf) __B, - __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_div_round_ss (__m128 __W, __mmask8 __U, __m128 __A, - __m128 __B, const int __R) -{ - return (__m128) __builtin_ia32_divss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) __W, - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_div_round_ss (__mmask8 __U, __m128 __A, __m128 __B, - const int __R) -{ - return (__m128) __builtin_ia32_divss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) - _mm_setzero_ps (), - (__mmask8) __U, __R); -} #else #define _mm512_mul_round_pd(A, B, C) (__m512d)__builtin_ia32_mulpd512_mask(A, B, (__v8df)_mm512_undefined_pd(), -1, C) #define _mm512_mask_mul_round_pd(W, U, A, B, C) (__m512d)__builtin_ia32_mulpd512_mask(A, B, W, U, C) @@ -2423,18 +4927,6 @@ _mm_maskz_div_round_ss (__mmask8 __U, __m128 __A, __m128 __B, #define _mm512_div_round_ps(A, B, C) (__m512)__builtin_ia32_divps512_mask(A, B, (__v16sf)_mm512_undefined_ps(), -1, C) #define _mm512_mask_div_round_ps(W, U, A, B, C) (__m512)__builtin_ia32_divps512_mask(A, B, W, U, C) #define _mm512_maskz_div_round_ps(U, A, B, C) (__m512)__builtin_ia32_divps512_mask(A, B, (__v16sf)_mm512_setzero_ps(), U, C) -#define _mm_mul_round_sd(A, B, C) (__m128d)__builtin_ia32_mulsd_round(A, B, C) -#define _mm_mask_mul_round_sd(W, U, A, B, C) (__m128d)__builtin_ia32_mulsd_mask_round(A, B, W, U, C) -#define _mm_maskz_mul_round_sd(U, A, B, C) (__m128d)__builtin_ia32_mulsd_mask_round(A, B, (__v2df)_mm_setzero_pd(), U, C) -#define _mm_mul_round_ss(A, B, C) (__m128)__builtin_ia32_mulss_round(A, B, C) -#define _mm_mask_mul_round_ss(W, U, A, B, C) (__m128)__builtin_ia32_mulss_mask_round(A, B, W, U, C) -#define _mm_maskz_mul_round_ss(U, A, B, C) (__m128)__builtin_ia32_mulss_mask_round(A, B, (__v4sf)_mm_setzero_ps(), U, C) -#define _mm_div_round_sd(A, B, C) (__m128d)__builtin_ia32_divsd_round(A, B, C) -#define _mm_mask_div_round_sd(W, U, A, B, C) (__m128d)__builtin_ia32_divsd_mask_round(A, B, W, U, C) -#define _mm_maskz_div_round_sd(U, A, B, C) (__m128d)__builtin_ia32_divsd_mask_round(A, B, (__v2df)_mm_setzero_pd(), U, C) -#define _mm_div_round_ss(A, B, C) (__m128)__builtin_ia32_divss_round(A, B, C) -#define _mm_mask_div_round_ss(W, U, A, B, C) (__m128)__builtin_ia32_divss_mask_round(A, B, W, U, C) -#define _mm_maskz_div_round_ss(U, A, B, C) (__m128)__builtin_ia32_divss_mask_round(A, B, (__v4sf)_mm_setzero_ps(), U, C) #endif #ifdef __OPTIMIZE__ extern __inline __m512d @@ -2636,67 +5128,6 @@ _mm512_maskz_scalef_round_ps (__mmask16 __U, __m512 __A, __m512 __B, _mm512_setzero_ps (), (__mmask16) __U, __R); } -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_scalef_round_sd (__m128d __A, __m128d __B, const int __R) -{ - return (__m128d) __builtin_ia32_scalefsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) - _mm_setzero_pd (), - (__mmask8) -1, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_scalef_round_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B, - const int __R) -{ - return (__m128d) __builtin_ia32_scalefsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) __W, - (__mmask8) __U, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_scalef_round_sd (__mmask8 __U, __m128d __A, __m128d __B, - const int __R) -{ - return (__m128d) __builtin_ia32_scalefsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) - _mm_setzero_pd (), - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_scalef_round_ss (__m128 __A, __m128 __B, const int __R) -{ - return (__m128) __builtin_ia32_scalefss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) - _mm_setzero_ps (), - (__mmask8) -1, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_scalef_round_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B, - const int __R) -{ - return (__m128) __builtin_ia32_scalefss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) __W, - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_scalef_round_ss (__mmask8 __U, __m128 __A, __m128 __B, const int __R) -{ - return (__m128) __builtin_ia32_scalefss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) - _mm_setzero_ps (), - (__mmask8) __U, __R); -} #else #define _mm512_scalef_round_pd(A, B, C) ((__m512d) __builtin_ia32_scalefpd512_mask((A), (B), (__v8df) _mm512_undefined_pd(), -1, (C))) #define _mm512_mask_scalef_round_pd(W, U, A, B, C) ((__m512d) __builtin_ia32_scalefpd512_mask((A), (B), (W), (U), (C))) @@ -2704,17 +5135,7 @@ _mm_maskz_scalef_round_ss (__mmask8 __U, __m128 __A, __m128 __B, const int __R) #define _mm512_scalef_round_ps(A, B, C) ((__m512) __builtin_ia32_scalefps512_mask((A), (B), (__v16sf) _mm512_undefined_ps(), -1, (C))) #define _mm512_mask_scalef_round_ps(W, U, A, B, C) ((__m512) __builtin_ia32_scalefps512_mask((A), (B), (W), (U), (C))) #define _mm512_maskz_scalef_round_ps(U, A, B, C) ((__m512) __builtin_ia32_scalefps512_mask((A), (B), (__v16sf) _mm512_setzero_ps(), (U), (C))) -#define _mm_scalef_round_sd(A, B, C) ((__m128d) __builtin_ia32_scalefsd_mask_round ((A), (B), (__v2df) _mm_undefined_pd (), -1, (C))) -#define _mm_scalef_round_ss(A, B, C) ((__m128) __builtin_ia32_scalefss_mask_round ((A), (B), (__v4sf) _mm_undefined_ps (), -1, (C))) -#define _mm_mask_scalef_round_sd(W, U, A, B, C) ((__m128d) __builtin_ia32_scalefsd_mask_round ((A), (B), (W), (U), (C))) -#define _mm_mask_scalef_round_ss(W, U, A, B, C) ((__m128) __builtin_ia32_scalefss_mask_round ((A), (B), (W), (U), (C))) -#define _mm_maskz_scalef_round_sd(U, A, B, C) ((__m128d) __builtin_ia32_scalefsd_mask_round ((A), (B), (__v2df) _mm_setzero_pd (), (U), (C))) -#define _mm_maskz_scalef_round_ss(U, A, B, C) ((__m128) __builtin_ia32_scalefss_mask_round ((A), (B), (__v4sf) _mm_setzero_ps (), (U), (C))) #endif -#define _mm_mask_scalef_sd(W, U, A, B) _mm_mask_scalef_round_sd ((W), (U), (A), (B), _MM_FROUND_CUR_DIRECTION) -#define _mm_maskz_scalef_sd(U, A, B) _mm_maskz_scalef_round_sd ((U), (A), (B), _MM_FROUND_CUR_DIRECTION) -#define _mm_mask_scalef_ss(W, U, A, B) _mm_mask_scalef_round_ss ((W), (U), (A), (B), _MM_FROUND_CUR_DIRECTION) -#define _mm_maskz_scalef_ss(U, A, B) _mm_maskz_scalef_round_ss ((U), (A), (B), _MM_FROUND_CUR_DIRECTION) #ifdef __OPTIMIZE__ extern __inline __m512d __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) @@ -4168,88 +6589,6 @@ _mm512_maskz_cvt_roundps_epu32 (__mmask16 __U, __m512 __A, const int __R) #define _mm512_mask_cvt_roundps_epu32(W, U, A, B) ((__m512i)__builtin_ia32_cvtps2udq512_mask(A, (__v16si)(W), U, B)) #define _mm512_maskz_cvt_roundps_epu32(U, A, B) ((__m512i)__builtin_ia32_cvtps2udq512_mask(A, (__v16si)_mm512_setzero_si512 (), U, B)) #endif -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtu32_sd (__m128d __A, unsigned __B) -{ - return (__m128d) __builtin_ia32_cvtusi2sd32 ((__v2df) __A, __B); -} -#ifdef __x86_64__ -#ifdef __OPTIMIZE__ -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundu64_sd (__m128d __A, unsigned long long __B, const int __R) -{ - return (__m128d) __builtin_ia32_cvtusi2sd64 ((__v2df) __A, __B, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundi64_sd (__m128d __A, long long __B, const int __R) -{ - return (__m128d) __builtin_ia32_cvtsi2sd64 ((__v2df) __A, __B, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundsi64_sd (__m128d __A, long long __B, const int __R) -{ - return (__m128d) __builtin_ia32_cvtsi2sd64 ((__v2df) __A, __B, __R); -} -#else -#define _mm_cvt_roundu64_sd(A, B, C) (__m128d)__builtin_ia32_cvtusi2sd64(A, B, C) -#define _mm_cvt_roundi64_sd(A, B, C) (__m128d)__builtin_ia32_cvtsi2sd64(A, B, C) -#define _mm_cvt_roundsi64_sd(A, B, C) (__m128d)__builtin_ia32_cvtsi2sd64(A, B, C) -#endif -#endif -#ifdef __OPTIMIZE__ -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundu32_ss (__m128 __A, unsigned __B, const int __R) -{ - return (__m128) __builtin_ia32_cvtusi2ss32 ((__v4sf) __A, __B, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundsi32_ss (__m128 __A, int __B, const int __R) -{ - return (__m128) __builtin_ia32_cvtsi2ss32 ((__v4sf) __A, __B, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundi32_ss (__m128 __A, int __B, const int __R) -{ - return (__m128) __builtin_ia32_cvtsi2ss32 ((__v4sf) __A, __B, __R); -} -#else -#define _mm_cvt_roundu32_ss(A, B, C) (__m128)__builtin_ia32_cvtusi2ss32(A, B, C) -#define _mm_cvt_roundi32_ss(A, B, C) (__m128)__builtin_ia32_cvtsi2ss32(A, B, C) -#define _mm_cvt_roundsi32_ss(A, B, C) (__m128)__builtin_ia32_cvtsi2ss32(A, B, C) -#endif -#ifdef __x86_64__ -#ifdef __OPTIMIZE__ -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundu64_ss (__m128 __A, unsigned long long __B, const int __R) -{ - return (__m128) __builtin_ia32_cvtusi2ss64 ((__v4sf) __A, __B, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundsi64_ss (__m128 __A, long long __B, const int __R) -{ - return (__m128) __builtin_ia32_cvtsi2ss64 ((__v4sf) __A, __B, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundi64_ss (__m128 __A, long long __B, const int __R) -{ - return (__m128) __builtin_ia32_cvtsi2ss64 ((__v4sf) __A, __B, __R); -} -#else -#define _mm_cvt_roundu64_ss(A, B, C) (__m128)__builtin_ia32_cvtusi2ss64(A, B, C) -#define _mm_cvt_roundi64_ss(A, B, C) (__m128)__builtin_ia32_cvtsi2ss64(A, B, C) -#define _mm_cvt_roundsi64_ss(A, B, C) (__m128)__builtin_ia32_cvtsi2ss64(A, B, C) -#endif -#endif extern __inline __m128i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_cvtepi32_epi8 (__m512i __A) @@ -5138,73 +7477,6 @@ _mm512_mask_storeu_ps (void *__P, __mmask16 __U, __m512 __A) __builtin_ia32_storeups512_mask ((float *) __P, (__v16sf) __A, (__mmask16) __U); } -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_load_ss (__m128 __W, __mmask8 __U, const float *__P) -{ - return (__m128) __builtin_ia32_loadss_mask (__P, (__v4sf) __W, __U); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_load_ss (__mmask8 __U, const float *__P) -{ - return (__m128) __builtin_ia32_loadss_mask (__P, (__v4sf) _mm_setzero_ps (), - __U); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_load_sd (__m128d __W, __mmask8 __U, const double *__P) -{ - return (__m128d) __builtin_ia32_loadsd_mask (__P, (__v2df) __W, __U); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_load_sd (__mmask8 __U, const double *__P) -{ - return (__m128d) __builtin_ia32_loadsd_mask (__P, (__v2df) _mm_setzero_pd (), - __U); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_move_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) -{ - return (__m128) __builtin_ia32_movess_mask ((__v4sf) __A, (__v4sf) __B, - (__v4sf) __W, __U); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_move_ss (__mmask8 __U, __m128 __A, __m128 __B) -{ - return (__m128) __builtin_ia32_movess_mask ((__v4sf) __A, (__v4sf) __B, - (__v4sf) _mm_setzero_ps (), __U); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_move_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) -{ - return (__m128d) __builtin_ia32_movesd_mask ((__v2df) __A, (__v2df) __B, - (__v2df) __W, __U); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_move_sd (__mmask8 __U, __m128d __A, __m128d __B) -{ - return (__m128d) __builtin_ia32_movesd_mask ((__v2df) __A, (__v2df) __B, - (__v2df) _mm_setzero_pd (), - __U); -} -extern __inline void -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_store_ss (float *__P, __mmask8 __U, __m128 __A) -{ - __builtin_ia32_storess_mask (__P, (__v4sf) __A, (__mmask8) __U); -} -extern __inline void -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_store_sd (double *__P, __mmask8 __U, __m128d __A) -{ - __builtin_ia32_storesd_mask (__P, (__v2df) __A, (__mmask8) __U); -} extern __inline __m512i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_loadu_epi64 (void const *__P) @@ -5887,67 +8159,6 @@ _mm512_maskz_fixupimm_round_ps (__mmask16 __U, __m512 __A, __m512 __B, __imm, (__mmask16) __U, __R); } -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_fixupimm_round_sd (__m128d __A, __m128d __B, __m128i __C, - const int __imm, const int __R) -{ - return (__m128d) __builtin_ia32_fixupimmsd_mask ((__v2df) __A, - (__v2df) __B, - (__v2di) __C, __imm, - (__mmask8) -1, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fixupimm_round_sd (__m128d __A, __mmask8 __U, __m128d __B, - __m128i __C, const int __imm, const int __R) -{ - return (__m128d) __builtin_ia32_fixupimmsd_mask ((__v2df) __A, - (__v2df) __B, - (__v2di) __C, __imm, - (__mmask8) __U, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fixupimm_round_sd (__mmask8 __U, __m128d __A, __m128d __B, - __m128i __C, const int __imm, const int __R) -{ - return (__m128d) __builtin_ia32_fixupimmsd_maskz ((__v2df) __A, - (__v2df) __B, - (__v2di) __C, - __imm, - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_fixupimm_round_ss (__m128 __A, __m128 __B, __m128i __C, - const int __imm, const int __R) -{ - return (__m128) __builtin_ia32_fixupimmss_mask ((__v4sf) __A, - (__v4sf) __B, - (__v4si) __C, __imm, - (__mmask8) -1, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fixupimm_round_ss (__m128 __A, __mmask8 __U, __m128 __B, - __m128i __C, const int __imm, const int __R) -{ - return (__m128) __builtin_ia32_fixupimmss_mask ((__v4sf) __A, - (__v4sf) __B, - (__v4si) __C, __imm, - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fixupimm_round_ss (__mmask8 __U, __m128 __A, __m128 __B, - __m128i __C, const int __imm, const int __R) -{ - return (__m128) __builtin_ia32_fixupimmss_maskz ((__v4sf) __A, - (__v4sf) __B, - (__v4si) __C, __imm, - (__mmask8) __U, __R); -} #else #define _mm512_shuffle_pd(X, Y, C) ((__m512d)__builtin_ia32_shufpd512_mask ((__v8df)(__m512d)(X), (__v8df)(__m512d)(Y), (int)(C), (__v8df)(__m512d)_mm512_undefined_pd(), (__mmask8)-1)) #define _mm512_mask_shuffle_pd(W, U, X, Y, C) ((__m512d)__builtin_ia32_shufpd512_mask ((__v8df)(__m512d)(X), (__v8df)(__m512d)(Y), (int)(C), (__v8df)(__m512d)(W), (__mmask8)(U))) @@ -5961,12 +8172,6 @@ _mm_maskz_fixupimm_round_ss (__mmask8 __U, __m128 __A, __m128 __B, #define _mm512_fixupimm_round_ps(X, Y, Z, C, R) ((__m512)__builtin_ia32_fixupimmps512_mask ((__v16sf)(__m512)(X), (__v16sf)(__m512)(Y), (__v16si)(__m512i)(Z), (int)(C), (__mmask16)(-1), (R))) #define _mm512_mask_fixupimm_round_ps(X, U, Y, Z, C, R) ((__m512)__builtin_ia32_fixupimmps512_mask ((__v16sf)(__m512)(X), (__v16sf)(__m512)(Y), (__v16si)(__m512i)(Z), (int)(C), (__mmask16)(U), (R))) #define _mm512_maskz_fixupimm_round_ps(U, X, Y, Z, C, R) ((__m512)__builtin_ia32_fixupimmps512_maskz ((__v16sf)(__m512)(X), (__v16sf)(__m512)(Y), (__v16si)(__m512i)(Z), (int)(C), (__mmask16)(U), (R))) -#define _mm_fixupimm_round_sd(X, Y, Z, C, R) ((__m128d)__builtin_ia32_fixupimmsd_mask ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (__v2di)(__m128i)(Z), (int)(C), (__mmask8)(-1), (R))) -#define _mm_mask_fixupimm_round_sd(X, U, Y, Z, C, R) ((__m128d)__builtin_ia32_fixupimmsd_mask ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (__v2di)(__m128i)(Z), (int)(C), (__mmask8)(U), (R))) -#define _mm_maskz_fixupimm_round_sd(U, X, Y, Z, C, R) ((__m128d)__builtin_ia32_fixupimmsd_maskz ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (__v2di)(__m128i)(Z), (int)(C), (__mmask8)(U), (R))) -#define _mm_fixupimm_round_ss(X, Y, Z, C, R) ((__m128)__builtin_ia32_fixupimmss_mask ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (__v4si)(__m128i)(Z), (int)(C), (__mmask8)(-1), (R))) -#define _mm_mask_fixupimm_round_ss(X, U, Y, Z, C, R) ((__m128)__builtin_ia32_fixupimmss_mask ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (__v4si)(__m128i)(Z), (int)(C), (__mmask8)(U), (R))) -#define _mm_maskz_fixupimm_round_ss(U, X, Y, Z, C, R) ((__m128)__builtin_ia32_fixupimmss_maskz ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (__v4si)(__m128i)(Z), (int)(C), (__mmask8)(U), (R))) #endif extern __inline __m512 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) @@ -6579,190 +8784,6 @@ _mm512_maskz_unpacklo_epi64 (__mmask8 __U, __m512i __A, __m512i __B) _mm512_setzero_si512 (), (__mmask8) __U); } -#ifdef __x86_64__ -#ifdef __OPTIMIZE__ -extern __inline unsigned long long -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundss_u64 (__m128 __A, const int __R) -{ - return (unsigned long long) __builtin_ia32_vcvtss2usi64 ((__v4sf) __A, __R); -} -extern __inline long long -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundss_si64 (__m128 __A, const int __R) -{ - return (long long) __builtin_ia32_vcvtss2si64 ((__v4sf) __A, __R); -} -extern __inline long long -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundss_i64 (__m128 __A, const int __R) -{ - return (long long) __builtin_ia32_vcvtss2si64 ((__v4sf) __A, __R); -} -extern __inline unsigned long long -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtt_roundss_u64 (__m128 __A, const int __R) -{ - return (unsigned long long) __builtin_ia32_vcvttss2usi64 ((__v4sf) __A, __R); -} -extern __inline long long -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtt_roundss_i64 (__m128 __A, const int __R) -{ - return (long long) __builtin_ia32_vcvttss2si64 ((__v4sf) __A, __R); -} -extern __inline long long -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtt_roundss_si64 (__m128 __A, const int __R) -{ - return (long long) __builtin_ia32_vcvttss2si64 ((__v4sf) __A, __R); -} -#else -#define _mm_cvt_roundss_u64(A, B) ((unsigned long long)__builtin_ia32_vcvtss2usi64(A, B)) -#define _mm_cvt_roundss_si64(A, B) ((long long)__builtin_ia32_vcvtss2si64(A, B)) -#define _mm_cvt_roundss_i64(A, B) ((long long)__builtin_ia32_vcvtss2si64(A, B)) -#define _mm_cvtt_roundss_u64(A, B) ((unsigned long long)__builtin_ia32_vcvttss2usi64(A, B)) -#define _mm_cvtt_roundss_i64(A, B) ((long long)__builtin_ia32_vcvttss2si64(A, B)) -#define _mm_cvtt_roundss_si64(A, B) ((long long)__builtin_ia32_vcvttss2si64(A, B)) -#endif -#endif -#ifdef __OPTIMIZE__ -extern __inline unsigned -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundss_u32 (__m128 __A, const int __R) -{ - return (unsigned) __builtin_ia32_vcvtss2usi32 ((__v4sf) __A, __R); -} -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundss_si32 (__m128 __A, const int __R) -{ - return (int) __builtin_ia32_vcvtss2si32 ((__v4sf) __A, __R); -} -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundss_i32 (__m128 __A, const int __R) -{ - return (int) __builtin_ia32_vcvtss2si32 ((__v4sf) __A, __R); -} -extern __inline unsigned -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtt_roundss_u32 (__m128 __A, const int __R) -{ - return (unsigned) __builtin_ia32_vcvttss2usi32 ((__v4sf) __A, __R); -} -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtt_roundss_i32 (__m128 __A, const int __R) -{ - return (int) __builtin_ia32_vcvttss2si32 ((__v4sf) __A, __R); -} -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtt_roundss_si32 (__m128 __A, const int __R) -{ - return (int) __builtin_ia32_vcvttss2si32 ((__v4sf) __A, __R); -} -#else -#define _mm_cvt_roundss_u32(A, B) ((unsigned)__builtin_ia32_vcvtss2usi32(A, B)) -#define _mm_cvt_roundss_si32(A, B) ((int)__builtin_ia32_vcvtss2si32(A, B)) -#define _mm_cvt_roundss_i32(A, B) ((int)__builtin_ia32_vcvtss2si32(A, B)) -#define _mm_cvtt_roundss_u32(A, B) ((unsigned)__builtin_ia32_vcvttss2usi32(A, B)) -#define _mm_cvtt_roundss_si32(A, B) ((int)__builtin_ia32_vcvttss2si32(A, B)) -#define _mm_cvtt_roundss_i32(A, B) ((int)__builtin_ia32_vcvttss2si32(A, B)) -#endif -#ifdef __x86_64__ -#ifdef __OPTIMIZE__ -extern __inline unsigned long long -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundsd_u64 (__m128d __A, const int __R) -{ - return (unsigned long long) __builtin_ia32_vcvtsd2usi64 ((__v2df) __A, __R); -} -extern __inline long long -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundsd_si64 (__m128d __A, const int __R) -{ - return (long long) __builtin_ia32_vcvtsd2si64 ((__v2df) __A, __R); -} -extern __inline long long -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundsd_i64 (__m128d __A, const int __R) -{ - return (long long) __builtin_ia32_vcvtsd2si64 ((__v2df) __A, __R); -} -extern __inline unsigned long long -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtt_roundsd_u64 (__m128d __A, const int __R) -{ - return (unsigned long long) __builtin_ia32_vcvttsd2usi64 ((__v2df) __A, __R); -} -extern __inline long long -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtt_roundsd_si64 (__m128d __A, const int __R) -{ - return (long long) __builtin_ia32_vcvttsd2si64 ((__v2df) __A, __R); -} -extern __inline long long -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtt_roundsd_i64 (__m128d __A, const int __R) -{ - return (long long) __builtin_ia32_vcvttsd2si64 ((__v2df) __A, __R); -} -#else -#define _mm_cvt_roundsd_u64(A, B) ((unsigned long long)__builtin_ia32_vcvtsd2usi64(A, B)) -#define _mm_cvt_roundsd_si64(A, B) ((long long)__builtin_ia32_vcvtsd2si64(A, B)) -#define _mm_cvt_roundsd_i64(A, B) ((long long)__builtin_ia32_vcvtsd2si64(A, B)) -#define _mm_cvtt_roundsd_u64(A, B) ((unsigned long long)__builtin_ia32_vcvttsd2usi64(A, B)) -#define _mm_cvtt_roundsd_si64(A, B) ((long long)__builtin_ia32_vcvttsd2si64(A, B)) -#define _mm_cvtt_roundsd_i64(A, B) ((long long)__builtin_ia32_vcvttsd2si64(A, B)) -#endif -#endif -#ifdef __OPTIMIZE__ -extern __inline unsigned -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundsd_u32 (__m128d __A, const int __R) -{ - return (unsigned) __builtin_ia32_vcvtsd2usi32 ((__v2df) __A, __R); -} -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundsd_si32 (__m128d __A, const int __R) -{ - return (int) __builtin_ia32_vcvtsd2si32 ((__v2df) __A, __R); -} -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundsd_i32 (__m128d __A, const int __R) -{ - return (int) __builtin_ia32_vcvtsd2si32 ((__v2df) __A, __R); -} -extern __inline unsigned -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtt_roundsd_u32 (__m128d __A, const int __R) -{ - return (unsigned) __builtin_ia32_vcvttsd2usi32 ((__v2df) __A, __R); -} -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtt_roundsd_i32 (__m128d __A, const int __R) -{ - return (int) __builtin_ia32_vcvttsd2si32 ((__v2df) __A, __R); -} -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtt_roundsd_si32 (__m128d __A, const int __R) -{ - return (int) __builtin_ia32_vcvttsd2si32 ((__v2df) __A, __R); -} -#else -#define _mm_cvt_roundsd_u32(A, B) ((unsigned)__builtin_ia32_vcvtsd2usi32(A, B)) -#define _mm_cvt_roundsd_si32(A, B) ((int)__builtin_ia32_vcvtsd2si32(A, B)) -#define _mm_cvt_roundsd_i32(A, B) ((int)__builtin_ia32_vcvtsd2si32(A, B)) -#define _mm_cvtt_roundsd_u32(A, B) ((unsigned)__builtin_ia32_vcvttsd2usi32(A, B)) -#define _mm_cvtt_roundsd_si32(A, B) ((int)__builtin_ia32_vcvttsd2si32(A, B)) -#define _mm_cvtt_roundsd_i32(A, B) ((int)__builtin_ia32_vcvttsd2si32(A, B)) -#endif extern __inline __m512d __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_movedup_pd (__m512d __A) @@ -7032,81 +9053,11 @@ _mm512_maskz_cvt_roundpd_ps (__mmask8 __U, __m512d __A, const int __R) _mm256_setzero_ps (), (__mmask8) __U, __R); } -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundsd_ss (__m128 __A, __m128d __B, const int __R) -{ - return (__m128) __builtin_ia32_cvtsd2ss_round ((__v4sf) __A, - (__v2df) __B, - __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_cvt_roundsd_ss (__m128 __W, __mmask8 __U, __m128 __A, - __m128d __B, const int __R) -{ - return (__m128) __builtin_ia32_cvtsd2ss_mask_round ((__v4sf) __A, - (__v2df) __B, - (__v4sf) __W, - __U, - __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_cvt_roundsd_ss (__mmask8 __U, __m128 __A, - __m128d __B, const int __R) -{ - return (__m128) __builtin_ia32_cvtsd2ss_mask_round ((__v4sf) __A, - (__v2df) __B, - _mm_setzero_ps (), - __U, - __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundss_sd (__m128d __A, __m128 __B, const int __R) -{ - return (__m128d) __builtin_ia32_cvtss2sd_round ((__v2df) __A, - (__v4sf) __B, - __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_cvt_roundss_sd (__m128d __W, __mmask8 __U, __m128d __A, - __m128 __B, const int __R) -{ - return (__m128d) __builtin_ia32_cvtss2sd_mask_round ((__v2df) __A, - (__v4sf) __B, - (__v2df) __W, - __U, - __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_cvt_roundss_sd (__mmask8 __U, __m128d __A, - __m128 __B, const int __R) -{ - return (__m128d) __builtin_ia32_cvtss2sd_mask_round ((__v2df) __A, - (__v4sf) __B, - _mm_setzero_pd (), - __U, - __R); -} #else #define _mm512_cvt_roundpd_ps(A, B) (__m256)__builtin_ia32_cvtpd2ps512_mask(A, (__v8sf)_mm256_undefined_ps(), -1, B) #define _mm512_mask_cvt_roundpd_ps(W, U, A, B) (__m256)__builtin_ia32_cvtpd2ps512_mask(A, (__v8sf)(W), U, B) #define _mm512_maskz_cvt_roundpd_ps(U, A, B) (__m256)__builtin_ia32_cvtpd2ps512_mask(A, (__v8sf)_mm256_setzero_ps(), U, B) -#define _mm_cvt_roundsd_ss(A, B, C) (__m128)__builtin_ia32_cvtsd2ss_round(A, B, C) -#define _mm_mask_cvt_roundsd_ss(W, U, A, B, C) (__m128)__builtin_ia32_cvtsd2ss_mask_round ((A), (B), (W), (U), (C)) -#define _mm_maskz_cvt_roundsd_ss(U, A, B, C) (__m128)__builtin_ia32_cvtsd2ss_mask_round ((A), (B), _mm_setzero_ps (), (U), (C)) -#define _mm_cvt_roundss_sd(A, B, C) (__m128d)__builtin_ia32_cvtss2sd_round(A, B, C) -#define _mm_mask_cvt_roundss_sd(W, U, A, B, C) (__m128d)__builtin_ia32_cvtss2sd_mask_round ((A), (B), (W), (U), (C)) -#define _mm_maskz_cvt_roundss_sd(U, A, B, C) (__m128d)__builtin_ia32_cvtss2sd_mask_round ((A), (B), _mm_setzero_pd (), (U), (C)) #endif -#define _mm_mask_cvtss_sd(W, U, A, B) _mm_mask_cvt_roundss_sd ((W), (U), (A), (B), _MM_FROUND_CUR_DIRECTION) -#define _mm_maskz_cvtss_sd(U, A, B) _mm_maskz_cvt_roundss_sd ((U), (A), (B), _MM_FROUND_CUR_DIRECTION) -#define _mm_mask_cvtsd_ss(W, U, A, B) _mm_mask_cvt_roundsd_ss ((W), (U), (A), (B), _MM_FROUND_CUR_DIRECTION) -#define _mm_maskz_cvtsd_ss(U, A, B) _mm_maskz_cvt_roundsd_ss ((U), (A), (B), _MM_FROUND_CUR_DIRECTION) extern __inline void __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_stream_si512 (__m512i * __P, __m512i __A) @@ -7131,78 +9082,7 @@ _mm512_stream_load_si512 (void *__P) { return __builtin_ia32_movntdqa512 ((__v8di *)__P); } -typedef enum -{ - _MM_MANT_NORM_1_2, - _MM_MANT_NORM_p5_2, - _MM_MANT_NORM_p5_1, - _MM_MANT_NORM_p75_1p5 -} _MM_MANTISSA_NORM_ENUM; -typedef enum -{ - _MM_MANT_SIGN_src, - _MM_MANT_SIGN_zero, - _MM_MANT_SIGN_nan -} _MM_MANTISSA_SIGN_ENUM; #ifdef __OPTIMIZE__ -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_getexp_round_ss (__m128 __A, __m128 __B, const int __R) -{ - return (__m128) __builtin_ia32_getexpss128_round ((__v4sf) __A, - (__v4sf) __B, - __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_getexp_round_ss (__m128 __W, __mmask8 __U, __m128 __A, - __m128 __B, const int __R) -{ - return (__m128) __builtin_ia32_getexpss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) __W, - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_getexp_round_ss (__mmask8 __U, __m128 __A, __m128 __B, - const int __R) -{ - return (__m128) __builtin_ia32_getexpss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) - _mm_setzero_ps (), - (__mmask8) __U, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_getexp_round_sd (__m128d __A, __m128d __B, const int __R) -{ - return (__m128d) __builtin_ia32_getexpsd128_round ((__v2df) __A, - (__v2df) __B, - __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_getexp_round_sd (__m128d __W, __mmask8 __U, __m128d __A, - __m128d __B, const int __R) -{ - return (__m128d) __builtin_ia32_getexpsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) __W, - (__mmask8) __U, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_getexp_round_sd (__mmask8 __U, __m128d __A, __m128d __B, - const int __R) -{ - return (__m128d) __builtin_ia32_getexpsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) - _mm_setzero_pd (), - (__mmask8) __U, __R); -} extern __inline __m512 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_getexp_round_ps (__m512 __A, const int __R) @@ -7323,78 +9203,6 @@ _mm512_maskz_getmant_round_ps (__mmask16 __U, __m512 __A, _mm512_setzero_ps (), __U, __R); } -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_getmant_round_sd (__m128d __A, __m128d __B, - _MM_MANTISSA_NORM_ENUM __C, - _MM_MANTISSA_SIGN_ENUM __D, const int __R) -{ - return (__m128d) __builtin_ia32_getmantsd_round ((__v2df) __A, - (__v2df) __B, - (__D << 2) | __C, - __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_getmant_round_sd (__m128d __W, __mmask8 __U, __m128d __A, - __m128d __B, _MM_MANTISSA_NORM_ENUM __C, - _MM_MANTISSA_SIGN_ENUM __D, const int __R) -{ - return (__m128d) __builtin_ia32_getmantsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__D << 2) | __C, - (__v2df) __W, - __U, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_getmant_round_sd (__mmask8 __U, __m128d __A, __m128d __B, - _MM_MANTISSA_NORM_ENUM __C, - _MM_MANTISSA_SIGN_ENUM __D, const int __R) -{ - return (__m128d) __builtin_ia32_getmantsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__D << 2) | __C, - (__v2df) - _mm_setzero_pd(), - __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_getmant_round_ss (__m128 __A, __m128 __B, - _MM_MANTISSA_NORM_ENUM __C, - _MM_MANTISSA_SIGN_ENUM __D, const int __R) -{ - return (__m128) __builtin_ia32_getmantss_round ((__v4sf) __A, - (__v4sf) __B, - (__D << 2) | __C, - __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_getmant_round_ss (__m128 __W, __mmask8 __U, __m128 __A, - __m128 __B, _MM_MANTISSA_NORM_ENUM __C, - _MM_MANTISSA_SIGN_ENUM __D, const int __R) -{ - return (__m128) __builtin_ia32_getmantss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__D << 2) | __C, - (__v4sf) __W, - __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_getmant_round_ss (__mmask8 __U, __m128 __A, __m128 __B, - _MM_MANTISSA_NORM_ENUM __C, - _MM_MANTISSA_SIGN_ENUM __D, const int __R) -{ - return (__m128) __builtin_ia32_getmantss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__D << 2) | __C, - (__v4sf) - _mm_setzero_ps(), - __U, __R); -} #else #define _mm512_getmant_round_pd(X, B, C, R) ((__m512d)__builtin_ia32_getmantpd512_mask ((__v8df)(__m512d)(X), (int)(((C)<<2) | (B)), (__v8df)(__m512d)_mm512_undefined_pd(), (__mmask8)-1, (R))) #define _mm512_mask_getmant_round_pd(W, U, X, B, C, R) ((__m512d)__builtin_ia32_getmantpd512_mask ((__v8df)(__m512d)(X), (int)(((C)<<2) | (B)), (__v8df)(__m512d)(W), (__mmask8)(U), (R))) @@ -7402,18 +9210,6 @@ _mm_maskz_getmant_round_ss (__mmask8 __U, __m128 __A, __m128 __B, #define _mm512_getmant_round_ps(X, B, C, R) ((__m512)__builtin_ia32_getmantps512_mask ((__v16sf)(__m512)(X), (int)(((C)<<2) | (B)), (__v16sf)(__m512)_mm512_undefined_ps(), (__mmask16)-1, (R))) #define _mm512_mask_getmant_round_ps(W, U, X, B, C, R) ((__m512)__builtin_ia32_getmantps512_mask ((__v16sf)(__m512)(X), (int)(((C)<<2) | (B)), (__v16sf)(__m512)(W), (__mmask16)(U), (R))) #define _mm512_maskz_getmant_round_ps(U, X, B, C, R) ((__m512)__builtin_ia32_getmantps512_mask ((__v16sf)(__m512)(X), (int)(((C)<<2) | (B)), (__v16sf)(__m512)_mm512_setzero_ps(), (__mmask16)(U), (R))) -#define _mm_getmant_round_sd(X, Y, C, D, R) ((__m128d)__builtin_ia32_getmantsd_round ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (int)(((D)<<2) | (C)), (R))) -#define _mm_mask_getmant_round_sd(W, U, X, Y, C, D, R) ((__m128d)__builtin_ia32_getmantsd_mask_round ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (int)(((D)<<2) | (C)), (__v2df)(__m128d)(W), (__mmask8)(U), (R))) -#define _mm_maskz_getmant_round_sd(U, X, Y, C, D, R) ((__m128d)__builtin_ia32_getmantsd_mask_round ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (int)(((D)<<2) | (C)), (__v2df)(__m128d)_mm_setzero_pd(), (__mmask8)(U), (R))) -#define _mm_getmant_round_ss(X, Y, C, D, R) ((__m128)__builtin_ia32_getmantss_round ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (int)(((D)<<2) | (C)), (R))) -#define _mm_mask_getmant_round_ss(W, U, X, Y, C, D, R) ((__m128)__builtin_ia32_getmantss_mask_round ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (int)(((D)<<2) | (C)), (__v4sf)(__m128)(W), (__mmask8)(U), (R))) -#define _mm_maskz_getmant_round_ss(U, X, Y, C, D, R) ((__m128)__builtin_ia32_getmantss_mask_round ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (int)(((D)<<2) | (C)), (__v4sf)(__m128)_mm_setzero_ps(), (__mmask8)(U), (R))) -#define _mm_getexp_round_ss(A, B, R) ((__m128)__builtin_ia32_getexpss128_round((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), R)) -#define _mm_mask_getexp_round_ss(W, U, A, B, C) (__m128)__builtin_ia32_getexpss_mask_round(A, B, W, U, C) -#define _mm_maskz_getexp_round_ss(U, A, B, C) (__m128)__builtin_ia32_getexpss_mask_round(A, B, (__v4sf)_mm_setzero_ps(), U, C) -#define _mm_getexp_round_sd(A, B, R) ((__m128d)__builtin_ia32_getexpsd128_round((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), R)) -#define _mm_mask_getexp_round_sd(W, U, A, B, C) (__m128d)__builtin_ia32_getexpsd_mask_round(A, B, W, U, C) -#define _mm_maskz_getexp_round_sd(U, A, B, C) (__m128d)__builtin_ia32_getexpsd_mask_round(A, B, (__v2df)_mm_setzero_pd(), U, C) #define _mm512_getexp_round_ps(A, R) ((__m512)__builtin_ia32_getexpps512_mask((__v16sf)(__m512)(A), (__v16sf)_mm512_undefined_ps(), (__mmask16)-1, R)) #define _mm512_mask_getexp_round_ps(W, U, A, R) ((__m512)__builtin_ia32_getexpps512_mask((__v16sf)(__m512)(A), (__v16sf)(__m512)(W), (__mmask16)(U), R)) #define _mm512_maskz_getexp_round_ps(U, A, R) ((__m512)__builtin_ia32_getexpps512_mask((__v16sf)(__m512)(A), (__v16sf)_mm512_setzero_ps(), (__mmask16)(U), R)) @@ -7480,82 +9276,6 @@ _mm512_maskz_roundscale_round_pd (__mmask8 __A, __m512d __B, _mm512_setzero_pd (), (__mmask8) __A, __R); } -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_roundscale_round_ss (__m128 __A, __m128 __B, const int __imm, - const int __R) -{ - return (__m128) - __builtin_ia32_rndscaless_mask_round ((__v4sf) __A, - (__v4sf) __B, __imm, - (__v4sf) - _mm_setzero_ps (), - (__mmask8) -1, - __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_roundscale_round_ss (__m128 __A, __mmask8 __B, __m128 __C, - __m128 __D, const int __imm, const int __R) -{ - return (__m128) - __builtin_ia32_rndscaless_mask_round ((__v4sf) __C, - (__v4sf) __D, __imm, - (__v4sf) __A, - (__mmask8) __B, - __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_roundscale_round_ss (__mmask8 __A, __m128 __B, __m128 __C, - const int __imm, const int __R) -{ - return (__m128) - __builtin_ia32_rndscaless_mask_round ((__v4sf) __B, - (__v4sf) __C, __imm, - (__v4sf) - _mm_setzero_ps (), - (__mmask8) __A, - __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_roundscale_round_sd (__m128d __A, __m128d __B, const int __imm, - const int __R) -{ - return (__m128d) - __builtin_ia32_rndscalesd_mask_round ((__v2df) __A, - (__v2df) __B, __imm, - (__v2df) - _mm_setzero_pd (), - (__mmask8) -1, - __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_roundscale_round_sd (__m128d __A, __mmask8 __B, __m128d __C, - __m128d __D, const int __imm, const int __R) -{ - return (__m128d) - __builtin_ia32_rndscalesd_mask_round ((__v2df) __C, - (__v2df) __D, __imm, - (__v2df) __A, - (__mmask8) __B, - __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_roundscale_round_sd (__mmask8 __A, __m128d __B, __m128d __C, - const int __imm, const int __R) -{ - return (__m128d) - __builtin_ia32_rndscalesd_mask_round ((__v2df) __B, - (__v2df) __C, __imm, - (__v2df) - _mm_setzero_pd (), - (__mmask8) __A, - __R); -} #else #define _mm512_roundscale_round_ps(A, B, R) ((__m512) __builtin_ia32_rndscaleps_mask ((__v16sf)(__m512)(A), (int)(B), (__v16sf)_mm512_undefined_ps(), (__mmask16)(-1), R)) #define _mm512_mask_roundscale_round_ps(A, B, C, D, R) ((__m512) __builtin_ia32_rndscaleps_mask ((__v16sf)(__m512)(C), (int)(D), (__v16sf)(__m512)(A), (__mmask16)(B), R)) @@ -7563,12 +9283,6 @@ _mm_maskz_roundscale_round_sd (__mmask8 __A, __m128d __B, __m128d __C, #define _mm512_roundscale_round_pd(A, B, R) ((__m512d) __builtin_ia32_rndscalepd_mask ((__v8df)(__m512d)(A), (int)(B), (__v8df)_mm512_undefined_pd(), (__mmask8)(-1), R)) #define _mm512_mask_roundscale_round_pd(A, B, C, D, R) ((__m512d) __builtin_ia32_rndscalepd_mask ((__v8df)(__m512d)(C), (int)(D), (__v8df)(__m512d)(A), (__mmask8)(B), R)) #define _mm512_maskz_roundscale_round_pd(A, B, C, R) ((__m512d) __builtin_ia32_rndscalepd_mask ((__v8df)(__m512d)(B), (int)(C), (__v8df)_mm512_setzero_pd(), (__mmask8)(A), R)) -#define _mm_roundscale_round_ss(A, B, I, R) ((__m128) __builtin_ia32_rndscaless_mask_round ((__v4sf) (__m128) (A), (__v4sf) (__m128) (B), (int) (I), (__v4sf) _mm_setzero_ps (), (__mmask8) (-1), (int) (R))) -#define _mm_mask_roundscale_round_ss(A, U, B, C, I, R) ((__m128) __builtin_ia32_rndscaless_mask_round ((__v4sf) (__m128) (B), (__v4sf) (__m128) (C), (int) (I), (__v4sf) (__m128) (A), (__mmask8) (U), (int) (R))) -#define _mm_maskz_roundscale_round_ss(U, A, B, I, R) ((__m128) __builtin_ia32_rndscaless_mask_round ((__v4sf) (__m128) (A), (__v4sf) (__m128) (B), (int) (I), (__v4sf) _mm_setzero_ps (), (__mmask8) (U), (int) (R))) -#define _mm_roundscale_round_sd(A, B, I, R) ((__m128d) __builtin_ia32_rndscalesd_mask_round ((__v2df) (__m128d) (A), (__v2df) (__m128d) (B), (int) (I), (__v2df) _mm_setzero_pd (), (__mmask8) (-1), (int) (R))) -#define _mm_mask_roundscale_round_sd(A, U, B, C, I, R) ((__m128d) __builtin_ia32_rndscalesd_mask_round ((__v2df) (__m128d) (B), (__v2df) (__m128d) (C), (int) (I), (__v2df) (__m128d) (A), (__mmask8) (U), (int) (R))) -#define _mm_maskz_roundscale_round_sd(U, A, B, I, R) ((__m128d) __builtin_ia32_rndscalesd_mask_round ((__v2df) (__m128d) (A), (__v2df) (__m128d) (B), (int) (I), (__v2df) _mm_setzero_pd (), (__mmask8) (U), (int) (R))) #endif extern __inline __m512 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) @@ -8039,20 +9753,6 @@ _mm512_cmpneq_epu64_mask (__m512i __X, __m512i __Y) #define _MM_CMPINT_NLE 0x6 #define _MM_CMPINT_GT 0x6 #ifdef __OPTIMIZE__ -extern __inline __mmask16 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_kshiftli_mask16 (__mmask16 __A, unsigned int __B) -{ - return (__mmask16) __builtin_ia32_kshiftlihi ((__mmask16) __A, - (__mmask8) __B); -} -extern __inline __mmask16 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_kshiftri_mask16 (__mmask16 __A, unsigned int __B) -{ - return (__mmask16) __builtin_ia32_kshiftrihi ((__mmask16) __A, - (__mmask8) __B); -} extern __inline __mmask8 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_cmp_epi64_mask (__m512i __X, __m512i __Y, const int __P) @@ -8156,43 +9856,7 @@ _mm512_mask_cmp_round_ps_mask (__mmask16 __U, __m512 __X, __m512 __Y, (__v16sf) __Y, __P, (__mmask16) __U, __R); } -extern __inline __mmask8 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cmp_round_sd_mask (__m128d __X, __m128d __Y, const int __P, const int __R) -{ - return (__mmask8) __builtin_ia32_cmpsd_mask ((__v2df) __X, - (__v2df) __Y, __P, - (__mmask8) -1, __R); -} -extern __inline __mmask8 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_cmp_round_sd_mask (__mmask8 __M, __m128d __X, __m128d __Y, - const int __P, const int __R) -{ - return (__mmask8) __builtin_ia32_cmpsd_mask ((__v2df) __X, - (__v2df) __Y, __P, - (__mmask8) __M, __R); -} -extern __inline __mmask8 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cmp_round_ss_mask (__m128 __X, __m128 __Y, const int __P, const int __R) -{ - return (__mmask8) __builtin_ia32_cmpss_mask ((__v4sf) __X, - (__v4sf) __Y, __P, - (__mmask8) -1, __R); -} -extern __inline __mmask8 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_cmp_round_ss_mask (__mmask8 __M, __m128 __X, __m128 __Y, - const int __P, const int __R) -{ - return (__mmask8) __builtin_ia32_cmpss_mask ((__v4sf) __X, - (__v4sf) __Y, __P, - (__mmask8) __M, __R); -} #else -#define _kshiftli_mask16(X, Y) ((__mmask16) __builtin_ia32_kshiftlihi ((__mmask16)(X), (__mmask8)(Y))) -#define _kshiftri_mask16(X, Y) ((__mmask16) __builtin_ia32_kshiftrihi ((__mmask16)(X), (__mmask8)(Y))) #define _mm512_cmp_epi64_mask(X, Y, P) ((__mmask8) __builtin_ia32_cmpq512_mask ((__v8di)(__m512i)(X), (__v8di)(__m512i)(Y), (int)(P), (__mmask8)-1)) #define _mm512_cmp_epi32_mask(X, Y, P) ((__mmask16) __builtin_ia32_cmpd512_mask ((__v16si)(__m512i)(X), (__v16si)(__m512i)(Y), (int)(P), (__mmask16)-1)) #define _mm512_cmp_epu64_mask(X, Y, P) ((__mmask8) __builtin_ia32_ucmpq512_mask ((__v8di)(__m512i)(X), (__v8di)(__m512i)(Y), (int)(P), (__mmask8)-1)) @@ -8205,10 +9869,6 @@ _mm_mask_cmp_round_ss_mask (__mmask8 __M, __m128 __X, __m128 __Y, #define _mm512_mask_cmp_epu32_mask(M, X, Y, P) ((__mmask16) __builtin_ia32_ucmpd512_mask ((__v16si)(__m512i)(X), (__v16si)(__m512i)(Y), (int)(P), (__mmask16)(M))) #define _mm512_mask_cmp_round_pd_mask(M, X, Y, P, R) ((__mmask8) __builtin_ia32_cmppd512_mask ((__v8df)(__m512d)(X), (__v8df)(__m512d)(Y), (int)(P), (__mmask8)(M), R)) #define _mm512_mask_cmp_round_ps_mask(M, X, Y, P, R) ((__mmask16) __builtin_ia32_cmpps512_mask ((__v16sf)(__m512)(X), (__v16sf)(__m512)(Y), (int)(P), (__mmask16)(M), R)) -#define _mm_cmp_round_sd_mask(X, Y, P, R) ((__mmask8) __builtin_ia32_cmpsd_mask ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (int)(P), (__mmask8)-1, R)) -#define _mm_mask_cmp_round_sd_mask(M, X, Y, P, R) ((__mmask8) __builtin_ia32_cmpsd_mask ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (int)(P), (M), R)) -#define _mm_cmp_round_ss_mask(X, Y, P, R) ((__mmask8) __builtin_ia32_cmpss_mask ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (int)(P), (__mmask8)-1, R)) -#define _mm_mask_cmp_round_ss_mask(M, X, Y, P, R) ((__mmask8) __builtin_ia32_cmpss_mask ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (int)(P), (M), R)) #endif #ifdef __OPTIMIZE__ extern __inline __m512 @@ -8774,57 +10434,6 @@ _mm512_maskz_expandloadu_epi32 (__mmask16 __U, void const *__P) _mm512_setzero_si512 (), (__mmask16) __U); } -#define _kand_mask16 _mm512_kand -#define _kandn_mask16 _mm512_kandn -#define _knot_mask16 _mm512_knot -#define _kor_mask16 _mm512_kor -#define _kxnor_mask16 _mm512_kxnor -#define _kxor_mask16 _mm512_kxor -extern __inline unsigned char -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_kortest_mask16_u8 (__mmask16 __A, __mmask16 __B, unsigned char *__CF) -{ - *__CF = (unsigned char) __builtin_ia32_kortestchi (__A, __B); - return (unsigned char) __builtin_ia32_kortestzhi (__A, __B); -} -extern __inline unsigned char -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_kortestz_mask16_u8 (__mmask16 __A, __mmask16 __B) -{ - return (unsigned char) __builtin_ia32_kortestzhi ((__mmask16) __A, - (__mmask16) __B); -} -extern __inline unsigned char -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_kortestc_mask16_u8 (__mmask16 __A, __mmask16 __B) -{ - return (unsigned char) __builtin_ia32_kortestchi ((__mmask16) __A, - (__mmask16) __B); -} -extern __inline unsigned int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_cvtmask16_u32 (__mmask16 __A) -{ - return (unsigned int) __builtin_ia32_kmovw ((__mmask16 ) __A); -} -extern __inline __mmask16 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_cvtu32_mask16 (unsigned int __A) -{ - return (__mmask16) __builtin_ia32_kmovw ((__mmask16 ) __A); -} -extern __inline __mmask16 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_load_mask16 (__mmask16 *__A) -{ - return (__mmask16) __builtin_ia32_kmovw (*(__mmask16 *) __A); -} -extern __inline void -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_store_mask16 (__mmask16 *__A, __mmask16 __B) -{ - *(__mmask16 *) __A = __builtin_ia32_kmovw (__B); -} extern __inline __mmask16 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_kand (__mmask16 __A, __mmask16 __B) @@ -8882,12 +10491,6 @@ _mm512_kunpackb (__mmask16 __A, __mmask16 __B) { return (__mmask16) __builtin_ia32_kunpckhi ((__mmask16) __A, (__mmask16) __B); } -extern __inline __mmask16 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_kunpackb_mask16 (__mmask8 __A, __mmask8 __B) -{ - return (__mmask16) __builtin_ia32_kunpckhi ((__mmask16) __A, (__mmask16) __B); -} #ifdef __OPTIMIZE__ extern __inline __m512i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) @@ -9192,137 +10795,6 @@ _mm512_maskz_unpacklo_ps (__mmask16 __U, __m512 __A, __m512 __B) _mm512_setzero_ps (), (__mmask16) __U); } -#ifdef __OPTIMIZE__ -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_max_round_sd (__m128d __A, __m128d __B, const int __R) -{ - return (__m128d) __builtin_ia32_maxsd_round ((__v2df) __A, - (__v2df) __B, - __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_max_round_sd (__m128d __W, __mmask8 __U, __m128d __A, - __m128d __B, const int __R) -{ - return (__m128d) __builtin_ia32_maxsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) __W, - (__mmask8) __U, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_max_round_sd (__mmask8 __U, __m128d __A, __m128d __B, - const int __R) -{ - return (__m128d) __builtin_ia32_maxsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) - _mm_setzero_pd (), - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_max_round_ss (__m128 __A, __m128 __B, const int __R) -{ - return (__m128) __builtin_ia32_maxss_round ((__v4sf) __A, - (__v4sf) __B, - __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_max_round_ss (__m128 __W, __mmask8 __U, __m128 __A, - __m128 __B, const int __R) -{ - return (__m128) __builtin_ia32_maxss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) __W, - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_max_round_ss (__mmask8 __U, __m128 __A, __m128 __B, - const int __R) -{ - return (__m128) __builtin_ia32_maxss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) - _mm_setzero_ps (), - (__mmask8) __U, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_min_round_sd (__m128d __A, __m128d __B, const int __R) -{ - return (__m128d) __builtin_ia32_minsd_round ((__v2df) __A, - (__v2df) __B, - __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_min_round_sd (__m128d __W, __mmask8 __U, __m128d __A, - __m128d __B, const int __R) -{ - return (__m128d) __builtin_ia32_minsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) __W, - (__mmask8) __U, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_min_round_sd (__mmask8 __U, __m128d __A, __m128d __B, - const int __R) -{ - return (__m128d) __builtin_ia32_minsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) - _mm_setzero_pd (), - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_min_round_ss (__m128 __A, __m128 __B, const int __R) -{ - return (__m128) __builtin_ia32_minss_round ((__v4sf) __A, - (__v4sf) __B, - __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_min_round_ss (__m128 __W, __mmask8 __U, __m128 __A, - __m128 __B, const int __R) -{ - return (__m128) __builtin_ia32_minss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) __W, - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_min_round_ss (__mmask8 __U, __m128 __A, __m128 __B, - const int __R) -{ - return (__m128) __builtin_ia32_minss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) - _mm_setzero_ps (), - (__mmask8) __U, __R); -} -#else -#define _mm_max_round_sd(A, B, C) (__m128d)__builtin_ia32_maxsd_round(A, B, C) -#define _mm_mask_max_round_sd(W, U, A, B, C) (__m128d)__builtin_ia32_maxsd_mask_round(A, B, W, U, C) -#define _mm_maskz_max_round_sd(U, A, B, C) (__m128d)__builtin_ia32_maxsd_mask_round(A, B, (__v2df)_mm_setzero_pd(), U, C) -#define _mm_max_round_ss(A, B, C) (__m128)__builtin_ia32_maxss_round(A, B, C) -#define _mm_mask_max_round_ss(W, U, A, B, C) (__m128)__builtin_ia32_maxss_mask_round(A, B, W, U, C) -#define _mm_maskz_max_round_ss(U, A, B, C) (__m128)__builtin_ia32_maxss_mask_round(A, B, (__v4sf)_mm_setzero_ps(), U, C) -#define _mm_min_round_sd(A, B, C) (__m128d)__builtin_ia32_minsd_round(A, B, C) -#define _mm_mask_min_round_sd(W, U, A, B, C) (__m128d)__builtin_ia32_minsd_mask_round(A, B, W, U, C) -#define _mm_maskz_min_round_sd(U, A, B, C) (__m128d)__builtin_ia32_minsd_mask_round(A, B, (__v2df)_mm_setzero_pd(), U, C) -#define _mm_min_round_ss(A, B, C) (__m128)__builtin_ia32_minss_round(A, B, C) -#define _mm_mask_min_round_ss(W, U, A, B, C) (__m128)__builtin_ia32_minss_mask_round(A, B, W, U, C) -#define _mm_maskz_min_round_ss(U, A, B, C) (__m128)__builtin_ia32_minss_mask_round(A, B, (__v4sf)_mm_setzero_ps(), U, C) -#endif extern __inline __m512d __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_mask_blend_pd (__mmask8 __U, __m512d __A, __m512d __W) @@ -9355,613 +10827,6 @@ _mm512_mask_blend_epi32 (__mmask16 __U, __m512i __A, __m512i __W) (__v16si) __W, (__mmask16) __U); } -#ifdef __OPTIMIZE__ -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_fmadd_round_sd (__m128d __W, __m128d __A, __m128d __B, const int __R) -{ - return (__m128d) __builtin_ia32_vfmaddsd3_round ((__v2df) __W, - (__v2df) __A, - (__v2df) __B, - __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_fmadd_round_ss (__m128 __W, __m128 __A, __m128 __B, const int __R) -{ - return (__m128) __builtin_ia32_vfmaddss3_round ((__v4sf) __W, - (__v4sf) __A, - (__v4sf) __B, - __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_fmsub_round_sd (__m128d __W, __m128d __A, __m128d __B, const int __R) -{ - return (__m128d) __builtin_ia32_vfmaddsd3_round ((__v2df) __W, - (__v2df) __A, - -(__v2df) __B, - __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_fmsub_round_ss (__m128 __W, __m128 __A, __m128 __B, const int __R) -{ - return (__m128) __builtin_ia32_vfmaddss3_round ((__v4sf) __W, - (__v4sf) __A, - -(__v4sf) __B, - __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_fnmadd_round_sd (__m128d __W, __m128d __A, __m128d __B, const int __R) -{ - return (__m128d) __builtin_ia32_vfmaddsd3_round ((__v2df) __W, - -(__v2df) __A, - (__v2df) __B, - __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_fnmadd_round_ss (__m128 __W, __m128 __A, __m128 __B, const int __R) -{ - return (__m128) __builtin_ia32_vfmaddss3_round ((__v4sf) __W, - -(__v4sf) __A, - (__v4sf) __B, - __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_fnmsub_round_sd (__m128d __W, __m128d __A, __m128d __B, const int __R) -{ - return (__m128d) __builtin_ia32_vfmaddsd3_round ((__v2df) __W, - -(__v2df) __A, - -(__v2df) __B, - __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_fnmsub_round_ss (__m128 __W, __m128 __A, __m128 __B, const int __R) -{ - return (__m128) __builtin_ia32_vfmaddss3_round ((__v4sf) __W, - -(__v4sf) __A, - -(__v4sf) __B, - __R); -} -#else -#define _mm_fmadd_round_sd(A, B, C, R) (__m128d)__builtin_ia32_vfmaddsd3_round(A, B, C, R) -#define _mm_fmadd_round_ss(A, B, C, R) (__m128)__builtin_ia32_vfmaddss3_round(A, B, C, R) -#define _mm_fmsub_round_sd(A, B, C, R) (__m128d)__builtin_ia32_vfmaddsd3_round(A, B, -(C), R) -#define _mm_fmsub_round_ss(A, B, C, R) (__m128)__builtin_ia32_vfmaddss3_round(A, B, -(C), R) -#define _mm_fnmadd_round_sd(A, B, C, R) (__m128d)__builtin_ia32_vfmaddsd3_round(A, -(B), C, R) -#define _mm_fnmadd_round_ss(A, B, C, R) (__m128)__builtin_ia32_vfmaddss3_round(A, -(B), C, R) -#define _mm_fnmsub_round_sd(A, B, C, R) (__m128d)__builtin_ia32_vfmaddsd3_round(A, -(B), -(C), R) -#define _mm_fnmsub_round_ss(A, B, C, R) (__m128)__builtin_ia32_vfmaddss3_round(A, -(B), -(C), R) -#endif -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fmadd_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) -{ - return (__m128d) __builtin_ia32_vfmaddsd3_mask ((__v2df) __W, - (__v2df) __A, - (__v2df) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fmadd_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) -{ - return (__m128) __builtin_ia32_vfmaddss3_mask ((__v4sf) __W, - (__v4sf) __A, - (__v4sf) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask3_fmadd_sd (__m128d __W, __m128d __A, __m128d __B, __mmask8 __U) -{ - return (__m128d) __builtin_ia32_vfmaddsd3_mask3 ((__v2df) __W, - (__v2df) __A, - (__v2df) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask3_fmadd_ss (__m128 __W, __m128 __A, __m128 __B, __mmask8 __U) -{ - return (__m128) __builtin_ia32_vfmaddss3_mask3 ((__v4sf) __W, - (__v4sf) __A, - (__v4sf) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fmadd_sd (__mmask8 __U, __m128d __W, __m128d __A, __m128d __B) -{ - return (__m128d) __builtin_ia32_vfmaddsd3_maskz ((__v2df) __W, - (__v2df) __A, - (__v2df) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fmadd_ss (__mmask8 __U, __m128 __W, __m128 __A, __m128 __B) -{ - return (__m128) __builtin_ia32_vfmaddss3_maskz ((__v4sf) __W, - (__v4sf) __A, - (__v4sf) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fmsub_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) -{ - return (__m128d) __builtin_ia32_vfmaddsd3_mask ((__v2df) __W, - (__v2df) __A, - -(__v2df) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fmsub_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) -{ - return (__m128) __builtin_ia32_vfmaddss3_mask ((__v4sf) __W, - (__v4sf) __A, - -(__v4sf) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask3_fmsub_sd (__m128d __W, __m128d __A, __m128d __B, __mmask8 __U) -{ - return (__m128d) __builtin_ia32_vfmsubsd3_mask3 ((__v2df) __W, - (__v2df) __A, - (__v2df) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask3_fmsub_ss (__m128 __W, __m128 __A, __m128 __B, __mmask8 __U) -{ - return (__m128) __builtin_ia32_vfmsubss3_mask3 ((__v4sf) __W, - (__v4sf) __A, - (__v4sf) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fmsub_sd (__mmask8 __U, __m128d __W, __m128d __A, __m128d __B) -{ - return (__m128d) __builtin_ia32_vfmaddsd3_maskz ((__v2df) __W, - (__v2df) __A, - -(__v2df) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fmsub_ss (__mmask8 __U, __m128 __W, __m128 __A, __m128 __B) -{ - return (__m128) __builtin_ia32_vfmaddss3_maskz ((__v4sf) __W, - (__v4sf) __A, - -(__v4sf) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fnmadd_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) -{ - return (__m128d) __builtin_ia32_vfmaddsd3_mask ((__v2df) __W, - -(__v2df) __A, - (__v2df) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fnmadd_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) -{ - return (__m128) __builtin_ia32_vfmaddss3_mask ((__v4sf) __W, - -(__v4sf) __A, - (__v4sf) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask3_fnmadd_sd (__m128d __W, __m128d __A, __m128d __B, __mmask8 __U) -{ - return (__m128d) __builtin_ia32_vfmaddsd3_mask3 ((__v2df) __W, - -(__v2df) __A, - (__v2df) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask3_fnmadd_ss (__m128 __W, __m128 __A, __m128 __B, __mmask8 __U) -{ - return (__m128) __builtin_ia32_vfmaddss3_mask3 ((__v4sf) __W, - -(__v4sf) __A, - (__v4sf) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fnmadd_sd (__mmask8 __U, __m128d __W, __m128d __A, __m128d __B) -{ - return (__m128d) __builtin_ia32_vfmaddsd3_maskz ((__v2df) __W, - -(__v2df) __A, - (__v2df) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fnmadd_ss (__mmask8 __U, __m128 __W, __m128 __A, __m128 __B) -{ - return (__m128) __builtin_ia32_vfmaddss3_maskz ((__v4sf) __W, - -(__v4sf) __A, - (__v4sf) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fnmsub_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) -{ - return (__m128d) __builtin_ia32_vfmaddsd3_mask ((__v2df) __W, - -(__v2df) __A, - -(__v2df) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fnmsub_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) -{ - return (__m128) __builtin_ia32_vfmaddss3_mask ((__v4sf) __W, - -(__v4sf) __A, - -(__v4sf) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask3_fnmsub_sd (__m128d __W, __m128d __A, __m128d __B, __mmask8 __U) -{ - return (__m128d) __builtin_ia32_vfmsubsd3_mask3 ((__v2df) __W, - -(__v2df) __A, - (__v2df) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask3_fnmsub_ss (__m128 __W, __m128 __A, __m128 __B, __mmask8 __U) -{ - return (__m128) __builtin_ia32_vfmsubss3_mask3 ((__v4sf) __W, - -(__v4sf) __A, - (__v4sf) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fnmsub_sd (__mmask8 __U, __m128d __W, __m128d __A, __m128d __B) -{ - return (__m128d) __builtin_ia32_vfmaddsd3_maskz ((__v2df) __W, - -(__v2df) __A, - -(__v2df) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fnmsub_ss (__mmask8 __U, __m128 __W, __m128 __A, __m128 __B) -{ - return (__m128) __builtin_ia32_vfmaddss3_maskz ((__v4sf) __W, - -(__v4sf) __A, - -(__v4sf) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -#ifdef __OPTIMIZE__ -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fmadd_round_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B, - const int __R) -{ - return (__m128d) __builtin_ia32_vfmaddsd3_mask ((__v2df) __W, - (__v2df) __A, - (__v2df) __B, - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fmadd_round_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B, - const int __R) -{ - return (__m128) __builtin_ia32_vfmaddss3_mask ((__v4sf) __W, - (__v4sf) __A, - (__v4sf) __B, - (__mmask8) __U, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask3_fmadd_round_sd (__m128d __W, __m128d __A, __m128d __B, __mmask8 __U, - const int __R) -{ - return (__m128d) __builtin_ia32_vfmaddsd3_mask3 ((__v2df) __W, - (__v2df) __A, - (__v2df) __B, - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask3_fmadd_round_ss (__m128 __W, __m128 __A, __m128 __B, __mmask8 __U, - const int __R) -{ - return (__m128) __builtin_ia32_vfmaddss3_mask3 ((__v4sf) __W, - (__v4sf) __A, - (__v4sf) __B, - (__mmask8) __U, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fmadd_round_sd (__mmask8 __U, __m128d __W, __m128d __A, __m128d __B, - const int __R) -{ - return (__m128d) __builtin_ia32_vfmaddsd3_maskz ((__v2df) __W, - (__v2df) __A, - (__v2df) __B, - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fmadd_round_ss (__mmask8 __U, __m128 __W, __m128 __A, __m128 __B, - const int __R) -{ - return (__m128) __builtin_ia32_vfmaddss3_maskz ((__v4sf) __W, - (__v4sf) __A, - (__v4sf) __B, - (__mmask8) __U, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fmsub_round_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B, - const int __R) -{ - return (__m128d) __builtin_ia32_vfmaddsd3_mask ((__v2df) __W, - (__v2df) __A, - -(__v2df) __B, - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fmsub_round_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B, - const int __R) -{ - return (__m128) __builtin_ia32_vfmaddss3_mask ((__v4sf) __W, - (__v4sf) __A, - -(__v4sf) __B, - (__mmask8) __U, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask3_fmsub_round_sd (__m128d __W, __m128d __A, __m128d __B, __mmask8 __U, - const int __R) -{ - return (__m128d) __builtin_ia32_vfmsubsd3_mask3 ((__v2df) __W, - (__v2df) __A, - (__v2df) __B, - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask3_fmsub_round_ss (__m128 __W, __m128 __A, __m128 __B, __mmask8 __U, - const int __R) -{ - return (__m128) __builtin_ia32_vfmsubss3_mask3 ((__v4sf) __W, - (__v4sf) __A, - (__v4sf) __B, - (__mmask8) __U, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fmsub_round_sd (__mmask8 __U, __m128d __W, __m128d __A, __m128d __B, - const int __R) -{ - return (__m128d) __builtin_ia32_vfmaddsd3_maskz ((__v2df) __W, - (__v2df) __A, - -(__v2df) __B, - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fmsub_round_ss (__mmask8 __U, __m128 __W, __m128 __A, __m128 __B, - const int __R) -{ - return (__m128) __builtin_ia32_vfmaddss3_maskz ((__v4sf) __W, - (__v4sf) __A, - -(__v4sf) __B, - (__mmask8) __U, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fnmadd_round_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B, - const int __R) -{ - return (__m128d) __builtin_ia32_vfmaddsd3_mask ((__v2df) __W, - -(__v2df) __A, - (__v2df) __B, - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fnmadd_round_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B, - const int __R) -{ - return (__m128) __builtin_ia32_vfmaddss3_mask ((__v4sf) __W, - -(__v4sf) __A, - (__v4sf) __B, - (__mmask8) __U, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask3_fnmadd_round_sd (__m128d __W, __m128d __A, __m128d __B, __mmask8 __U, - const int __R) -{ - return (__m128d) __builtin_ia32_vfmaddsd3_mask3 ((__v2df) __W, - -(__v2df) __A, - (__v2df) __B, - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask3_fnmadd_round_ss (__m128 __W, __m128 __A, __m128 __B, __mmask8 __U, - const int __R) -{ - return (__m128) __builtin_ia32_vfmaddss3_mask3 ((__v4sf) __W, - -(__v4sf) __A, - (__v4sf) __B, - (__mmask8) __U, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fnmadd_round_sd (__mmask8 __U, __m128d __W, __m128d __A, __m128d __B, - const int __R) -{ - return (__m128d) __builtin_ia32_vfmaddsd3_maskz ((__v2df) __W, - -(__v2df) __A, - (__v2df) __B, - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fnmadd_round_ss (__mmask8 __U, __m128 __W, __m128 __A, __m128 __B, - const int __R) -{ - return (__m128) __builtin_ia32_vfmaddss3_maskz ((__v4sf) __W, - -(__v4sf) __A, - (__v4sf) __B, - (__mmask8) __U, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fnmsub_round_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B, - const int __R) -{ - return (__m128d) __builtin_ia32_vfmaddsd3_mask ((__v2df) __W, - -(__v2df) __A, - -(__v2df) __B, - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fnmsub_round_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B, - const int __R) -{ - return (__m128) __builtin_ia32_vfmaddss3_mask ((__v4sf) __W, - -(__v4sf) __A, - -(__v4sf) __B, - (__mmask8) __U, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask3_fnmsub_round_sd (__m128d __W, __m128d __A, __m128d __B, __mmask8 __U, - const int __R) -{ - return (__m128d) __builtin_ia32_vfmsubsd3_mask3 ((__v2df) __W, - -(__v2df) __A, - (__v2df) __B, - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask3_fnmsub_round_ss (__m128 __W, __m128 __A, __m128 __B, __mmask8 __U, - const int __R) -{ - return (__m128) __builtin_ia32_vfmsubss3_mask3 ((__v4sf) __W, - -(__v4sf) __A, - (__v4sf) __B, - (__mmask8) __U, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fnmsub_round_sd (__mmask8 __U, __m128d __W, __m128d __A, __m128d __B, - const int __R) -{ - return (__m128d) __builtin_ia32_vfmaddsd3_maskz ((__v2df) __W, - -(__v2df) __A, - -(__v2df) __B, - (__mmask8) __U, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fnmsub_round_ss (__mmask8 __U, __m128 __W, __m128 __A, __m128 __B, - const int __R) -{ - return (__m128) __builtin_ia32_vfmaddss3_maskz ((__v4sf) __W, - -(__v4sf) __A, - -(__v4sf) __B, - (__mmask8) __U, __R); -} -#else -#define _mm_mask_fmadd_round_sd(A, U, B, C, R) (__m128d) __builtin_ia32_vfmaddsd3_mask (A, B, C, U, R) -#define _mm_mask_fmadd_round_ss(A, U, B, C, R) (__m128) __builtin_ia32_vfmaddss3_mask (A, B, C, U, R) -#define _mm_mask3_fmadd_round_sd(A, B, C, U, R) (__m128d) __builtin_ia32_vfmaddsd3_mask3 (A, B, C, U, R) -#define _mm_mask3_fmadd_round_ss(A, B, C, U, R) (__m128) __builtin_ia32_vfmaddss3_mask3 (A, B, C, U, R) -#define _mm_maskz_fmadd_round_sd(U, A, B, C, R) (__m128d) __builtin_ia32_vfmaddsd3_maskz (A, B, C, U, R) -#define _mm_maskz_fmadd_round_ss(U, A, B, C, R) (__m128) __builtin_ia32_vfmaddss3_maskz (A, B, C, U, R) -#define _mm_mask_fmsub_round_sd(A, U, B, C, R) (__m128d) __builtin_ia32_vfmaddsd3_mask (A, B, -(C), U, R) -#define _mm_mask_fmsub_round_ss(A, U, B, C, R) (__m128) __builtin_ia32_vfmaddss3_mask (A, B, -(C), U, R) -#define _mm_mask3_fmsub_round_sd(A, B, C, U, R) (__m128d) __builtin_ia32_vfmsubsd3_mask3 (A, B, C, U, R) -#define _mm_mask3_fmsub_round_ss(A, B, C, U, R) (__m128) __builtin_ia32_vfmsubss3_mask3 (A, B, C, U, R) -#define _mm_maskz_fmsub_round_sd(U, A, B, C, R) (__m128d) __builtin_ia32_vfmaddsd3_maskz (A, B, -(C), U, R) -#define _mm_maskz_fmsub_round_ss(U, A, B, C, R) (__m128) __builtin_ia32_vfmaddss3_maskz (A, B, -(C), U, R) -#define _mm_mask_fnmadd_round_sd(A, U, B, C, R) (__m128d) __builtin_ia32_vfmaddsd3_mask (A, -(B), C, U, R) -#define _mm_mask_fnmadd_round_ss(A, U, B, C, R) (__m128) __builtin_ia32_vfmaddss3_mask (A, -(B), C, U, R) -#define _mm_mask3_fnmadd_round_sd(A, B, C, U, R) (__m128d) __builtin_ia32_vfmaddsd3_mask3 (A, -(B), C, U, R) -#define _mm_mask3_fnmadd_round_ss(A, B, C, U, R) (__m128) __builtin_ia32_vfmaddss3_mask3 (A, -(B), C, U, R) -#define _mm_maskz_fnmadd_round_sd(U, A, B, C, R) (__m128d) __builtin_ia32_vfmaddsd3_maskz (A, -(B), C, U, R) -#define _mm_maskz_fnmadd_round_ss(U, A, B, C, R) (__m128) __builtin_ia32_vfmaddss3_maskz (A, -(B), C, U, R) -#define _mm_mask_fnmsub_round_sd(A, U, B, C, R) (__m128d) __builtin_ia32_vfmaddsd3_mask (A, -(B), -(C), U, R) -#define _mm_mask_fnmsub_round_ss(A, U, B, C, R) (__m128) __builtin_ia32_vfmaddss3_mask (A, -(B), -(C), U, R) -#define _mm_mask3_fnmsub_round_sd(A, B, C, U, R) (__m128d) __builtin_ia32_vfmsubsd3_mask3 (A, -(B), C, U, R) -#define _mm_mask3_fnmsub_round_ss(A, B, C, U, R) (__m128) __builtin_ia32_vfmsubss3_mask3 (A, -(B), C, U, R) -#define _mm_maskz_fnmsub_round_sd(U, A, B, C, R) (__m128d) __builtin_ia32_vfmaddsd3_maskz (A, -(B), -(C), U, R) -#define _mm_maskz_fnmsub_round_ss(U, A, B, C, R) (__m128) __builtin_ia32_vfmaddss3_maskz (A, -(B), -(C), U, R) -#endif -#ifdef __OPTIMIZE__ -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_comi_round_ss (__m128 __A, __m128 __B, const int __P, const int __R) -{ - return __builtin_ia32_vcomiss ((__v4sf) __A, (__v4sf) __B, __P, __R); -} -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_comi_round_sd (__m128d __A, __m128d __B, const int __P, const int __R) -{ - return __builtin_ia32_vcomisd ((__v2df) __A, (__v2df) __B, __P, __R); -} -#else -#define _mm_comi_round_ss(A, B, C, D)__builtin_ia32_vcomiss(A, B, C, D) -#define _mm_comi_round_sd(A, B, C, D)__builtin_ia32_vcomisd(A, B, C, D) -#endif extern __inline __m512d __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_sqrt_pd (__m512d __A) @@ -10074,48 +10939,6 @@ _mm512_maskz_add_ps (__mmask16 __U, __m512 __A, __m512 __B) (__mmask16) __U, _MM_FROUND_CUR_DIRECTION); } -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_add_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) -{ - return (__m128d) __builtin_ia32_addsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) __W, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_add_sd (__mmask8 __U, __m128d __A, __m128d __B) -{ - return (__m128d) __builtin_ia32_addsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) - _mm_setzero_pd (), - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_add_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) -{ - return (__m128) __builtin_ia32_addss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) __W, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_add_ss (__mmask8 __U, __m128 __A, __m128 __B) -{ - return (__m128) __builtin_ia32_addss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) - _mm_setzero_ps (), - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} extern __inline __m512d __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_sub_pd (__m512d __A, __m512d __B) @@ -10170,48 +10993,6 @@ _mm512_maskz_sub_ps (__mmask16 __U, __m512 __A, __m512 __B) (__mmask16) __U, _MM_FROUND_CUR_DIRECTION); } -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_sub_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) -{ - return (__m128d) __builtin_ia32_subsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) __W, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_sub_sd (__mmask8 __U, __m128d __A, __m128d __B) -{ - return (__m128d) __builtin_ia32_subsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) - _mm_setzero_pd (), - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_sub_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) -{ - return (__m128) __builtin_ia32_subss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) __W, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_sub_ss (__mmask8 __U, __m128 __A, __m128 __B) -{ - return (__m128) __builtin_ia32_subss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) - _mm_setzero_ps (), - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} extern __inline __m512d __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_mul_pd (__m512d __A, __m512d __B) @@ -10266,50 +11047,6 @@ _mm512_maskz_mul_ps (__mmask16 __U, __m512 __A, __m512 __B) (__mmask16) __U, _MM_FROUND_CUR_DIRECTION); } -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_mul_sd (__m128d __W, __mmask8 __U, __m128d __A, - __m128d __B) -{ - return (__m128d) __builtin_ia32_mulsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) __W, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_mul_sd (__mmask8 __U, __m128d __A, __m128d __B) -{ - return (__m128d) __builtin_ia32_mulsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) - _mm_setzero_pd (), - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_mul_ss (__m128 __W, __mmask8 __U, __m128 __A, - __m128 __B) -{ - return (__m128) __builtin_ia32_mulss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) __W, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_mul_ss (__mmask8 __U, __m128 __A, __m128 __B) -{ - return (__m128) __builtin_ia32_mulss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) - _mm_setzero_ps (), - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} extern __inline __m512d __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_div_pd (__m512d __M, __m512d __V) @@ -10364,50 +11101,6 @@ _mm512_maskz_div_ps (__mmask16 __U, __m512 __A, __m512 __B) (__mmask16) __U, _MM_FROUND_CUR_DIRECTION); } -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_div_sd (__m128d __W, __mmask8 __U, __m128d __A, - __m128d __B) -{ - return (__m128d) __builtin_ia32_divsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) __W, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_div_sd (__mmask8 __U, __m128d __A, __m128d __B) -{ - return (__m128d) __builtin_ia32_divsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) - _mm_setzero_pd (), - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_div_ss (__m128 __W, __mmask8 __U, __m128 __A, - __m128 __B) -{ - return (__m128) __builtin_ia32_divss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) __W, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_div_ss (__mmask8 __U, __m128 __A, __m128 __B) -{ - return (__m128) __builtin_ia32_divss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) - _mm_setzero_ps (), - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} extern __inline __m512d __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_max_pd (__m512d __A, __m512d __B) @@ -10472,48 +11165,6 @@ _mm512_maskz_max_ps (__mmask16 __U, __m512 __A, __m512 __B) (__mmask16) __U, _MM_FROUND_CUR_DIRECTION); } -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_max_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) -{ - return (__m128d) __builtin_ia32_maxsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) __W, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_max_sd (__mmask8 __U, __m128d __A, __m128d __B) -{ - return (__m128d) __builtin_ia32_maxsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) - _mm_setzero_pd (), - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_max_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) -{ - return (__m128) __builtin_ia32_maxss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) __W, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_max_ss (__mmask8 __U, __m128 __A, __m128 __B) -{ - return (__m128) __builtin_ia32_maxss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) - _mm_setzero_ps (), - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} extern __inline __m512d __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_min_pd (__m512d __A, __m512d __B) @@ -10578,48 +11229,6 @@ _mm512_maskz_min_ps (__mmask16 __U, __m512 __A, __m512 __B) (__mmask16) __U, _MM_FROUND_CUR_DIRECTION); } -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_min_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) -{ - return (__m128d) __builtin_ia32_minsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) __W, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_min_sd (__mmask8 __U, __m128d __A, __m128d __B) -{ - return (__m128d) __builtin_ia32_minsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) - _mm_setzero_pd (), - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_min_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) -{ - return (__m128) __builtin_ia32_minss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) __W, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_min_ss (__mmask8 __U, __m128 __A, __m128 __B) -{ - return (__m128) __builtin_ia32_minss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) - _mm_setzero_ps (), - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} extern __inline __m512d __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_scalef_pd (__m512d __A, __m512d __B) @@ -10684,28 +11293,6 @@ _mm512_maskz_scalef_ps (__mmask16 __U, __m512 __A, __m512 __B) (__mmask16) __U, _MM_FROUND_CUR_DIRECTION); } -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_scalef_sd (__m128d __A, __m128d __B) -{ - return (__m128d) __builtin_ia32_scalefsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) - _mm_setzero_pd (), - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_scalef_ss (__m128 __A, __m128 __B) -{ - return (__m128) __builtin_ia32_scalefss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) - _mm_setzero_ps (), - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} extern __inline __m512d __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_fmadd_pd (__m512d __A, __m512d __B, __m512d __C) @@ -11430,29 +12017,6 @@ _mm512_cvtss_f32 (__m512 __A) { return __A[0]; } -#ifdef __x86_64__ -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtu64_ss (__m128 __A, unsigned long long __B) -{ - return (__m128) __builtin_ia32_cvtusi2ss64 ((__v4sf) __A, __B, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtu64_sd (__m128d __A, unsigned long long __B) -{ - return (__m128d) __builtin_ia32_cvtusi2sd64 ((__v2df) __A, __B, - _MM_FROUND_CUR_DIRECTION); -} -#endif -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtu32_ss (__m128 __A, unsigned __B) -{ - return (__m128) __builtin_ia32_cvtusi2ss32 ((__v4sf) __A, __B, - _MM_FROUND_CUR_DIRECTION); -} extern __inline __m512 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_cvtepi32_ps (__m512i __A) @@ -11582,71 +12146,6 @@ _mm512_maskz_fixupimm_ps (__mmask16 __U, __m512 __A, __m512 __B, (__mmask16) __U, _MM_FROUND_CUR_DIRECTION); } -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_fixupimm_sd (__m128d __A, __m128d __B, __m128i __C, const int __imm) -{ - return (__m128d) __builtin_ia32_fixupimmsd_mask ((__v2df) __A, - (__v2df) __B, - (__v2di) __C, __imm, - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fixupimm_sd (__m128d __A, __mmask8 __U, __m128d __B, - __m128i __C, const int __imm) -{ - return (__m128d) __builtin_ia32_fixupimmsd_mask ((__v2df) __A, - (__v2df) __B, - (__v2di) __C, __imm, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fixupimm_sd (__mmask8 __U, __m128d __A, __m128d __B, - __m128i __C, const int __imm) -{ - return (__m128d) __builtin_ia32_fixupimmsd_maskz ((__v2df) __A, - (__v2df) __B, - (__v2di) __C, - __imm, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_fixupimm_ss (__m128 __A, __m128 __B, __m128i __C, const int __imm) -{ - return (__m128) __builtin_ia32_fixupimmss_mask ((__v4sf) __A, - (__v4sf) __B, - (__v4si) __C, __imm, - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fixupimm_ss (__m128 __A, __mmask8 __U, __m128 __B, - __m128i __C, const int __imm) -{ - return (__m128) __builtin_ia32_fixupimmss_mask ((__v4sf) __A, - (__v4sf) __B, - (__v4si) __C, __imm, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fixupimm_ss (__mmask8 __U, __m128 __A, __m128 __B, - __m128i __C, const int __imm) -{ - return (__m128) __builtin_ia32_fixupimmss_maskz ((__v4sf) __A, - (__v4sf) __B, - (__v4si) __C, __imm, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} #else #define _mm512_fixupimm_pd(X, Y, Z, C) ((__m512d)__builtin_ia32_fixupimmpd512_mask ((__v8df)(__m512d)(X), (__v8df)(__m512d)(Y), (__v8di)(__m512i)(Z), (int)(C), (__mmask8)(-1), _MM_FROUND_CUR_DIRECTION)) #define _mm512_mask_fixupimm_pd(X, U, Y, Z, C) ((__m512d)__builtin_ia32_fixupimmpd512_mask ((__v8df)(__m512d)(X), (__v8df)(__m512d)(Y), (__v8di)(__m512i)(Z), (int)(C), (__mmask8)(U), _MM_FROUND_CUR_DIRECTION)) @@ -11654,37 +12153,6 @@ _mm_maskz_fixupimm_ss (__mmask8 __U, __m128 __A, __m128 __B, #define _mm512_fixupimm_ps(X, Y, Z, C) ((__m512)__builtin_ia32_fixupimmps512_mask ((__v16sf)(__m512)(X), (__v16sf)(__m512)(Y), (__v16si)(__m512i)(Z), (int)(C), (__mmask16)(-1), _MM_FROUND_CUR_DIRECTION)) #define _mm512_mask_fixupimm_ps(X, U, Y, Z, C) ((__m512)__builtin_ia32_fixupimmps512_mask ((__v16sf)(__m512)(X), (__v16sf)(__m512)(Y), (__v16si)(__m512i)(Z), (int)(C), (__mmask16)(U), _MM_FROUND_CUR_DIRECTION)) #define _mm512_maskz_fixupimm_ps(U, X, Y, Z, C) ((__m512)__builtin_ia32_fixupimmps512_maskz ((__v16sf)(__m512)(X), (__v16sf)(__m512)(Y), (__v16si)(__m512i)(Z), (int)(C), (__mmask16)(U), _MM_FROUND_CUR_DIRECTION)) -#define _mm_fixupimm_sd(X, Y, Z, C) ((__m128d)__builtin_ia32_fixupimmsd_mask ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (__v2di)(__m128i)(Z), (int)(C), (__mmask8)(-1), _MM_FROUND_CUR_DIRECTION)) -#define _mm_mask_fixupimm_sd(X, U, Y, Z, C) ((__m128d)__builtin_ia32_fixupimmsd_mask ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (__v2di)(__m128i)(Z), (int)(C), (__mmask8)(U), _MM_FROUND_CUR_DIRECTION)) -#define _mm_maskz_fixupimm_sd(U, X, Y, Z, C) ((__m128d)__builtin_ia32_fixupimmsd_maskz ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (__v2di)(__m128i)(Z), (int)(C), (__mmask8)(U), _MM_FROUND_CUR_DIRECTION)) -#define _mm_fixupimm_ss(X, Y, Z, C) ((__m128)__builtin_ia32_fixupimmss_mask ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (__v4si)(__m128i)(Z), (int)(C), (__mmask8)(-1), _MM_FROUND_CUR_DIRECTION)) -#define _mm_mask_fixupimm_ss(X, U, Y, Z, C) ((__m128)__builtin_ia32_fixupimmss_mask ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (__v4si)(__m128i)(Z), (int)(C), (__mmask8)(U), _MM_FROUND_CUR_DIRECTION)) -#define _mm_maskz_fixupimm_ss(U, X, Y, Z, C) ((__m128)__builtin_ia32_fixupimmss_maskz ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (__v4si)(__m128i)(Z), (int)(C), (__mmask8)(U), _MM_FROUND_CUR_DIRECTION)) -#endif -#ifdef __x86_64__ -extern __inline unsigned long long -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtss_u64 (__m128 __A) -{ - return (unsigned long long) __builtin_ia32_vcvtss2usi64 ((__v4sf) - __A, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline unsigned long long -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvttss_u64 (__m128 __A) -{ - return (unsigned long long) __builtin_ia32_vcvttss2usi64 ((__v4sf) - __A, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline long long -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvttss_i64 (__m128 __A) -{ - return (long long) __builtin_ia32_vcvttss2si64 ((__v4sf) __A, - _MM_FROUND_CUR_DIRECTION); -} #endif extern __inline int __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) @@ -11693,121 +12161,6 @@ _mm512_cvtsi512_si32 (__m512i __A) __v16si __B = (__v16si) __A; return __B[0]; } -extern __inline unsigned -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtss_u32 (__m128 __A) -{ - return (unsigned) __builtin_ia32_vcvtss2usi32 ((__v4sf) __A, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline unsigned -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvttss_u32 (__m128 __A) -{ - return (unsigned) __builtin_ia32_vcvttss2usi32 ((__v4sf) __A, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvttss_i32 (__m128 __A) -{ - return (int) __builtin_ia32_vcvttss2si32 ((__v4sf) __A, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtsd_i32 (__m128d __A) -{ - return (int) __builtin_ia32_cvtsd2si ((__v2df) __A); -} -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtss_i32 (__m128 __A) -{ - return (int) __builtin_ia32_cvtss2si ((__v4sf) __A); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvti32_sd (__m128d __A, int __B) -{ - return (__m128d) __builtin_ia32_cvtsi2sd ((__v2df) __A, __B); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvti32_ss (__m128 __A, int __B) -{ - return (__m128) __builtin_ia32_cvtsi2ss ((__v4sf) __A, __B); -} -#ifdef __x86_64__ -extern __inline unsigned long long -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtsd_u64 (__m128d __A) -{ - return (unsigned long long) __builtin_ia32_vcvtsd2usi64 ((__v2df) - __A, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline unsigned long long -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvttsd_u64 (__m128d __A) -{ - return (unsigned long long) __builtin_ia32_vcvttsd2usi64 ((__v2df) - __A, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline long long -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvttsd_i64 (__m128d __A) -{ - return (long long) __builtin_ia32_vcvttsd2si64 ((__v2df) __A, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline long long -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtsd_i64 (__m128d __A) -{ - return (long long) __builtin_ia32_cvtsd2si64 ((__v2df) __A); -} -extern __inline long long -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtss_i64 (__m128 __A) -{ - return (long long) __builtin_ia32_cvtss2si64 ((__v4sf) __A); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvti64_sd (__m128d __A, long long __B) -{ - return (__m128d) __builtin_ia32_cvtsi642sd ((__v2df) __A, __B); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvti64_ss (__m128 __A, long long __B) -{ - return (__m128) __builtin_ia32_cvtsi642ss ((__v4sf) __A, __B); -} -#endif -extern __inline unsigned -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtsd_u32 (__m128d __A) -{ - return (unsigned) __builtin_ia32_vcvtsd2usi32 ((__v2df) __A, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline unsigned -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvttsd_u32 (__m128d __A) -{ - return (unsigned) __builtin_ia32_vcvttsd2usi32 ((__v2df) __A, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvttsd_i32 (__m128d __A) -{ - return (int) __builtin_ia32_vcvttsd2si32 ((__v2df) __A, - _MM_FROUND_CUR_DIRECTION); -} extern __inline __m512d __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_cvtps_pd (__m256 __A) @@ -11954,64 +12307,6 @@ _mm512_maskz_getexp_pd (__mmask8 __U, __m512d __A) (__mmask8) __U, _MM_FROUND_CUR_DIRECTION); } -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_getexp_ss (__m128 __A, __m128 __B) -{ - return (__m128) __builtin_ia32_getexpss128_round ((__v4sf) __A, - (__v4sf) __B, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_getexp_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B) -{ - return (__m128) __builtin_ia32_getexpss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) __W, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_getexp_ss (__mmask8 __U, __m128 __A, __m128 __B) -{ - return (__m128) __builtin_ia32_getexpss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__v4sf) - _mm_setzero_ps (), - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_getexp_sd (__m128d __A, __m128d __B) -{ - return (__m128d) __builtin_ia32_getexpsd128_round ((__v2df) __A, - (__v2df) __B, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_getexp_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B) -{ - return (__m128d) __builtin_ia32_getexpsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) __W, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_getexp_sd (__mmask8 __U, __m128d __A, __m128d __B) -{ - return (__m128d) __builtin_ia32_getexpsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__v2df) - _mm_setzero_pd (), - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} extern __inline __m512d __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_getmant_pd (__m512d __A, _MM_MANTISSA_NORM_ENUM __B, @@ -12078,76 +12373,6 @@ _mm512_maskz_getmant_ps (__mmask16 __U, __m512 __A, __U, _MM_FROUND_CUR_DIRECTION); } -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_getmant_sd (__m128d __A, __m128d __B, _MM_MANTISSA_NORM_ENUM __C, - _MM_MANTISSA_SIGN_ENUM __D) -{ - return (__m128d) __builtin_ia32_getmantsd_round ((__v2df) __A, - (__v2df) __B, - (__D << 2) | __C, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_getmant_sd (__m128d __W, __mmask8 __U, __m128d __A, __m128d __B, - _MM_MANTISSA_NORM_ENUM __C, _MM_MANTISSA_SIGN_ENUM __D) -{ - return (__m128d) __builtin_ia32_getmantsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__D << 2) | __C, - (__v2df) __W, - __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_getmant_sd (__mmask8 __U, __m128d __A, __m128d __B, - _MM_MANTISSA_NORM_ENUM __C, _MM_MANTISSA_SIGN_ENUM __D) -{ - return (__m128d) __builtin_ia32_getmantsd_mask_round ((__v2df) __A, - (__v2df) __B, - (__D << 2) | __C, - (__v2df) - _mm_setzero_pd(), - __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_getmant_ss (__m128 __A, __m128 __B, _MM_MANTISSA_NORM_ENUM __C, - _MM_MANTISSA_SIGN_ENUM __D) -{ - return (__m128) __builtin_ia32_getmantss_round ((__v4sf) __A, - (__v4sf) __B, - (__D << 2) | __C, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_getmant_ss (__m128 __W, __mmask8 __U, __m128 __A, __m128 __B, - _MM_MANTISSA_NORM_ENUM __C, _MM_MANTISSA_SIGN_ENUM __D) -{ - return (__m128) __builtin_ia32_getmantss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__D << 2) | __C, - (__v4sf) __W, - __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_getmant_ss (__mmask8 __U, __m128 __A, __m128 __B, - _MM_MANTISSA_NORM_ENUM __C, _MM_MANTISSA_SIGN_ENUM __D) -{ - return (__m128) __builtin_ia32_getmantss_mask_round ((__v4sf) __A, - (__v4sf) __B, - (__D << 2) | __C, - (__v4sf) - _mm_setzero_ps(), - __U, - _MM_FROUND_CUR_DIRECTION); -} #else #define _mm512_getmant_pd(X, B, C) ((__m512d)__builtin_ia32_getmantpd512_mask ((__v8df)(__m512d)(X), (int)(((C)<<2) | (B)), (__v8df)_mm512_undefined_pd(), (__mmask8)-1, _MM_FROUND_CUR_DIRECTION)) #define _mm512_mask_getmant_pd(W, U, X, B, C) ((__m512d)__builtin_ia32_getmantpd512_mask ((__v8df)(__m512d)(X), (int)(((C)<<2) | (B)), (__v8df)(__m512d)(W), (__mmask8)(U), _MM_FROUND_CUR_DIRECTION)) @@ -12155,18 +12380,6 @@ _mm_maskz_getmant_ss (__mmask8 __U, __m128 __A, __m128 __B, #define _mm512_getmant_ps(X, B, C) ((__m512)__builtin_ia32_getmantps512_mask ((__v16sf)(__m512)(X), (int)(((C)<<2) | (B)), (__v16sf)_mm512_undefined_ps(), (__mmask16)-1, _MM_FROUND_CUR_DIRECTION)) #define _mm512_mask_getmant_ps(W, U, X, B, C) ((__m512)__builtin_ia32_getmantps512_mask ((__v16sf)(__m512)(X), (int)(((C)<<2) | (B)), (__v16sf)(__m512)(W), (__mmask16)(U), _MM_FROUND_CUR_DIRECTION)) #define _mm512_maskz_getmant_ps(U, X, B, C) ((__m512)__builtin_ia32_getmantps512_mask ((__v16sf)(__m512)(X), (int)(((C)<<2) | (B)), (__v16sf)_mm512_setzero_ps(), (__mmask16)(U), _MM_FROUND_CUR_DIRECTION)) -#define _mm_getmant_sd(X, Y, C, D) ((__m128d)__builtin_ia32_getmantsd_round ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (int)(((D)<<2) | (C)), _MM_FROUND_CUR_DIRECTION)) -#define _mm_mask_getmant_sd(W, U, X, Y, C, D) ((__m128d)__builtin_ia32_getmantsd_mask_round ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (int)(((D)<<2) | (C)), (__v2df)(__m128d)(W), (__mmask8)(U), _MM_FROUND_CUR_DIRECTION)) -#define _mm_maskz_getmant_sd(U, X, Y, C, D) ((__m128d)__builtin_ia32_getmantsd_mask_round ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (int)(((D)<<2) | (C)), (__v2df)_mm_setzero_pd(), (__mmask8)(U), _MM_FROUND_CUR_DIRECTION)) -#define _mm_getmant_ss(X, Y, C, D) ((__m128)__builtin_ia32_getmantss_round ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (int)(((D)<<2) | (C)), _MM_FROUND_CUR_DIRECTION)) -#define _mm_mask_getmant_ss(W, U, X, Y, C, D) ((__m128)__builtin_ia32_getmantss_mask_round ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (int)(((D)<<2) | (C)), (__v4sf)(__m128)(W), (__mmask8)(U), _MM_FROUND_CUR_DIRECTION)) -#define _mm_maskz_getmant_ss(U, X, Y, C, D) ((__m128)__builtin_ia32_getmantss_mask_round ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (int)(((D)<<2) | (C)), (__v4sf)_mm_setzero_ps(), (__mmask8)(U), _MM_FROUND_CUR_DIRECTION)) -#define _mm_getexp_ss(A, B) ((__m128)__builtin_ia32_getexpss128_round((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), _MM_FROUND_CUR_DIRECTION)) -#define _mm_mask_getexp_ss(W, U, A, B) (__m128)__builtin_ia32_getexpss_mask_round(A, B, W, U, _MM_FROUND_CUR_DIRECTION) -#define _mm_maskz_getexp_ss(U, A, B) (__m128)__builtin_ia32_getexpss_mask_round(A, B, (__v4sf)_mm_setzero_ps(), U, _MM_FROUND_CUR_DIRECTION) -#define _mm_getexp_sd(A, B) ((__m128d)__builtin_ia32_getexpsd128_round((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), _MM_FROUND_CUR_DIRECTION)) -#define _mm_mask_getexp_sd(W, U, A, B) (__m128d)__builtin_ia32_getexpsd_mask_round(A, B, W, U, _MM_FROUND_CUR_DIRECTION) -#define _mm_maskz_getexp_sd(U, A, B) (__m128d)__builtin_ia32_getexpsd_mask_round(A, B, (__v2df)_mm_setzero_pd(), U, _MM_FROUND_CUR_DIRECTION) #define _mm512_getexp_ps(A) ((__m512)__builtin_ia32_getexpps512_mask((__v16sf)(__m512)(A), (__v16sf)_mm512_undefined_ps(), (__mmask16)-1, _MM_FROUND_CUR_DIRECTION)) #define _mm512_mask_getexp_ps(W, U, A) ((__m512)__builtin_ia32_getexpps512_mask((__v16sf)(__m512)(A), (__v16sf)(__m512)(W), (__mmask16)(U), _MM_FROUND_CUR_DIRECTION)) #define _mm512_maskz_getexp_ps(U, A) ((__m512)__builtin_ia32_getexpps512_mask((__v16sf)(__m512)(A), (__v16sf)_mm512_setzero_ps(), (__mmask16)(U), _MM_FROUND_CUR_DIRECTION)) @@ -12237,80 +12450,6 @@ _mm512_maskz_roundscale_pd (__mmask8 __A, __m512d __B, const int __imm) (__mmask8) __A, _MM_FROUND_CUR_DIRECTION); } -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_roundscale_ss (__m128 __A, __m128 __B, const int __imm) -{ - return (__m128) - __builtin_ia32_rndscaless_mask_round ((__v4sf) __A, - (__v4sf) __B, __imm, - (__v4sf) - _mm_setzero_ps (), - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_roundscale_ss (__m128 __A, __mmask8 __B, __m128 __C, __m128 __D, - const int __imm) -{ - return (__m128) - __builtin_ia32_rndscaless_mask_round ((__v4sf) __C, - (__v4sf) __D, __imm, - (__v4sf) __A, - (__mmask8) __B, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_roundscale_ss (__mmask8 __A, __m128 __B, __m128 __C, - const int __imm) -{ - return (__m128) - __builtin_ia32_rndscaless_mask_round ((__v4sf) __B, - (__v4sf) __C, __imm, - (__v4sf) - _mm_setzero_ps (), - (__mmask8) __A, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_roundscale_sd (__m128d __A, __m128d __B, const int __imm) -{ - return (__m128d) - __builtin_ia32_rndscalesd_mask_round ((__v2df) __A, - (__v2df) __B, __imm, - (__v2df) - _mm_setzero_pd (), - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_roundscale_sd (__m128d __A, __mmask8 __B, __m128d __C, __m128d __D, - const int __imm) -{ - return (__m128d) - __builtin_ia32_rndscalesd_mask_round ((__v2df) __C, - (__v2df) __D, __imm, - (__v2df) __A, - (__mmask8) __B, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_roundscale_sd (__mmask8 __A, __m128d __B, __m128d __C, - const int __imm) -{ - return (__m128d) - __builtin_ia32_rndscalesd_mask_round ((__v2df) __B, - (__v2df) __C, __imm, - (__v2df) - _mm_setzero_pd (), - (__mmask8) __A, - _MM_FROUND_CUR_DIRECTION); -} #else #define _mm512_roundscale_ps(A, B) ((__m512) __builtin_ia32_rndscaleps_mask ((__v16sf)(__m512)(A), (int)(B), (__v16sf)_mm512_undefined_ps(), (__mmask16)(-1), _MM_FROUND_CUR_DIRECTION)) #define _mm512_mask_roundscale_ps(A, B, C, D) ((__m512) __builtin_ia32_rndscaleps_mask ((__v16sf)(__m512)(C), (int)(D), (__v16sf)(__m512)(A), (__mmask16)(B), _MM_FROUND_CUR_DIRECTION)) @@ -12318,12 +12457,6 @@ _mm_maskz_roundscale_sd (__mmask8 __A, __m128d __B, __m128d __C, #define _mm512_roundscale_pd(A, B) ((__m512d) __builtin_ia32_rndscalepd_mask ((__v8df)(__m512d)(A), (int)(B), (__v8df)_mm512_undefined_pd(), (__mmask8)(-1), _MM_FROUND_CUR_DIRECTION)) #define _mm512_mask_roundscale_pd(A, B, C, D) ((__m512d) __builtin_ia32_rndscalepd_mask ((__v8df)(__m512d)(C), (int)(D), (__v8df)(__m512d)(A), (__mmask8)(B), _MM_FROUND_CUR_DIRECTION)) #define _mm512_maskz_roundscale_pd(A, B, C) ((__m512d) __builtin_ia32_rndscalepd_mask ((__v8df)(__m512d)(B), (int)(C), (__v8df)_mm512_setzero_pd(), (__mmask8)(A), _MM_FROUND_CUR_DIRECTION)) -#define _mm_roundscale_ss(A, B, I) ((__m128) __builtin_ia32_rndscaless_mask_round ((__v4sf) (__m128) (A), (__v4sf) (__m128) (B), (int) (I), (__v4sf) _mm_setzero_ps (), (__mmask8) (-1), _MM_FROUND_CUR_DIRECTION)) -#define _mm_mask_roundscale_ss(A, U, B, C, I) ((__m128) __builtin_ia32_rndscaless_mask_round ((__v4sf) (__m128) (B), (__v4sf) (__m128) (C), (int) (I), (__v4sf) (__m128) (A), (__mmask8) (U), _MM_FROUND_CUR_DIRECTION)) -#define _mm_maskz_roundscale_ss(U, A, B, I) ((__m128) __builtin_ia32_rndscaless_mask_round ((__v4sf) (__m128) (A), (__v4sf) (__m128) (B), (int) (I), (__v4sf) _mm_setzero_ps (), (__mmask8) (U), _MM_FROUND_CUR_DIRECTION)) -#define _mm_roundscale_sd(A, B, I) ((__m128d) __builtin_ia32_rndscalesd_mask_round ((__v2df) (__m128d) (A), (__v2df) (__m128d) (B), (int) (I), (__v2df) _mm_setzero_pd (), (__mmask8) (-1), _MM_FROUND_CUR_DIRECTION)) -#define _mm_mask_roundscale_sd(A, U, B, C, I) ((__m128d) __builtin_ia32_rndscalesd_mask_round ((__v2df) (__m128d) (B), (__v2df) (__m128d) (C), (int) (I), (__v2df) (__m128d) (A), (__mmask8) (U), _MM_FROUND_CUR_DIRECTION)) -#define _mm_maskz_roundscale_sd(U, A, B, I) ((__m128d) __builtin_ia32_rndscalesd_mask_round ((__v2df) (__m128d) (A), (__v2df) (__m128d) (B), (int) (I), (__v2df) _mm_setzero_pd (), (__mmask8) (U), _MM_FROUND_CUR_DIRECTION)) #endif #ifdef __OPTIMIZE__ extern __inline __mmask8 @@ -12362,51 +12495,11 @@ _mm512_mask_cmp_pd_mask (__mmask8 __U, __m512d __X, __m512d __Y, const int __P) (__mmask8) __U, _MM_FROUND_CUR_DIRECTION); } -extern __inline __mmask8 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cmp_sd_mask (__m128d __X, __m128d __Y, const int __P) -{ - return (__mmask8) __builtin_ia32_cmpsd_mask ((__v2df) __X, - (__v2df) __Y, __P, - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __mmask8 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_cmp_sd_mask (__mmask8 __M, __m128d __X, __m128d __Y, const int __P) -{ - return (__mmask8) __builtin_ia32_cmpsd_mask ((__v2df) __X, - (__v2df) __Y, __P, - (__mmask8) __M, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __mmask8 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cmp_ss_mask (__m128 __X, __m128 __Y, const int __P) -{ - return (__mmask8) __builtin_ia32_cmpss_mask ((__v4sf) __X, - (__v4sf) __Y, __P, - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __mmask8 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_cmp_ss_mask (__mmask8 __M, __m128 __X, __m128 __Y, const int __P) -{ - return (__mmask8) __builtin_ia32_cmpss_mask ((__v4sf) __X, - (__v4sf) __Y, __P, - (__mmask8) __M, - _MM_FROUND_CUR_DIRECTION); -} #else #define _mm512_cmp_pd_mask(X, Y, P) ((__mmask8) __builtin_ia32_cmppd512_mask ((__v8df)(__m512d)(X), (__v8df)(__m512d)(Y), (int)(P), (__mmask8)-1,_MM_FROUND_CUR_DIRECTION)) #define _mm512_cmp_ps_mask(X, Y, P) ((__mmask16) __builtin_ia32_cmpps512_mask ((__v16sf)(__m512)(X), (__v16sf)(__m512)(Y), (int)(P), (__mmask16)-1,_MM_FROUND_CUR_DIRECTION)) #define _mm512_mask_cmp_pd_mask(M, X, Y, P) ((__mmask8) __builtin_ia32_cmppd512_mask ((__v8df)(__m512d)(X), (__v8df)(__m512d)(Y), (int)(P), (__mmask8)(M), _MM_FROUND_CUR_DIRECTION)) #define _mm512_mask_cmp_ps_mask(M, X, Y, P) ((__mmask16) __builtin_ia32_cmpps512_mask ((__v16sf)(__m512)(X), (__v16sf)(__m512)(Y), (int)(P), (__mmask16)(M),_MM_FROUND_CUR_DIRECTION)) -#define _mm_cmp_sd_mask(X, Y, P) ((__mmask8) __builtin_ia32_cmpsd_mask ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (int)(P), (__mmask8)-1,_MM_FROUND_CUR_DIRECTION)) -#define _mm_mask_cmp_sd_mask(M, X, Y, P) ((__mmask8) __builtin_ia32_cmpsd_mask ((__v2df)(__m128d)(X), (__v2df)(__m128d)(Y), (int)(P), M,_MM_FROUND_CUR_DIRECTION)) -#define _mm_cmp_ss_mask(X, Y, P) ((__mmask8) __builtin_ia32_cmpss_mask ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (int)(P), (__mmask8)-1,_MM_FROUND_CUR_DIRECTION)) -#define _mm_mask_cmp_ss_mask(M, X, Y, P) ((__mmask8) __builtin_ia32_cmpss_mask ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (int)(P), M,_MM_FROUND_CUR_DIRECTION)) #endif extern __inline __mmask8 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) @@ -13237,8 +13330,8 @@ _mm512_mask_reduce_max_pd (__mmask8 __U, __m512d __A) __MM512_REDUCE_OP (max_pd); } #undef __MM512_REDUCE_OP -#ifdef __DISABLE_AVX512F__ -#undef __DISABLE_AVX512F__ +#ifdef __DISABLE_AVX512F_512__ +#undef __DISABLE_AVX512F_512__ #pragma GCC pop_options #endif #endif diff --git a/third_party/intel/avx512fp16intrin.internal.h b/third_party/intel/avx512fp16intrin.internal.h index 4f249cc30..04868b7bc 100644 --- a/third_party/intel/avx512fp16intrin.internal.h +++ b/third_party/intel/avx512fp16intrin.internal.h @@ -2,22 +2,19 @@ #ifndef _IMMINTRIN_H_INCLUDED #error "Never use directly; include instead." #endif -#ifndef __AVX512FP16INTRIN_H_INCLUDED -#define __AVX512FP16INTRIN_H_INCLUDED -#ifndef __AVX512FP16__ +#ifndef _AVX512FP16INTRIN_H_INCLUDED +#define _AVX512FP16INTRIN_H_INCLUDED +#if !defined (__AVX512FP16__) || defined (__EVEX512__) #pragma GCC push_options -#pragma GCC target("avx512fp16") +#pragma GCC target("avx512fp16,no-evex512") #define __DISABLE_AVX512FP16__ #endif typedef _Float16 __v8hf __attribute__ ((__vector_size__ (16))); typedef _Float16 __v16hf __attribute__ ((__vector_size__ (32))); -typedef _Float16 __v32hf __attribute__ ((__vector_size__ (64))); typedef _Float16 __m128h __attribute__ ((__vector_size__ (16), __may_alias__)); typedef _Float16 __m256h __attribute__ ((__vector_size__ (32), __may_alias__)); -typedef _Float16 __m512h __attribute__ ((__vector_size__ (64), __may_alias__)); typedef _Float16 __m128h_u __attribute__ ((__vector_size__ (16), __may_alias__, __aligned__ (1))); typedef _Float16 __m256h_u __attribute__ ((__vector_size__ (32), __may_alias__, __aligned__ (1))); -typedef _Float16 __m512h_u __attribute__ ((__vector_size__ (64), __may_alias__, __aligned__ (1))); extern __inline __m128h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm_set_ph (_Float16 __A7, _Float16 __A6, _Float16 __A5, @@ -41,6 +38,2159 @@ _mm256_set_ph (_Float16 __A15, _Float16 __A14, _Float16 __A13, __A8, __A9, __A10, __A11, __A12, __A13, __A14, __A15 }; } +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_setr_ph (_Float16 __A0, _Float16 __A1, _Float16 __A2, + _Float16 __A3, _Float16 __A4, _Float16 __A5, + _Float16 __A6, _Float16 __A7) +{ + return _mm_set_ph (__A7, __A6, __A5, __A4, __A3, __A2, __A1, __A0); +} +extern __inline __m256h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_setr_ph (_Float16 __A0, _Float16 __A1, _Float16 __A2, + _Float16 __A3, _Float16 __A4, _Float16 __A5, + _Float16 __A6, _Float16 __A7, _Float16 __A8, + _Float16 __A9, _Float16 __A10, _Float16 __A11, + _Float16 __A12, _Float16 __A13, _Float16 __A14, + _Float16 __A15) +{ + return _mm256_set_ph (__A15, __A14, __A13, __A12, __A11, __A10, __A9, + __A8, __A7, __A6, __A5, __A4, __A3, __A2, __A1, + __A0); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_set1_ph (_Float16 __A) +{ + return _mm_set_ph (__A, __A, __A, __A, __A, __A, __A, __A); +} +extern __inline __m256h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_set1_ph (_Float16 __A) +{ + return _mm256_set_ph (__A, __A, __A, __A, __A, __A, __A, __A, + __A, __A, __A, __A, __A, __A, __A, __A); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_setzero_ph (void) +{ + return _mm_set1_ph (0.0f16); +} +extern __inline __m256h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_setzero_ph (void) +{ + return _mm256_set1_ph (0.0f16); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_undefined_ph (void) +{ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Winit-self" + __m128h __Y = __Y; +#pragma GCC diagnostic pop + return __Y; +} +extern __inline __m256h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_undefined_ph (void) +{ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Winit-self" + __m256h __Y = __Y; +#pragma GCC diagnostic pop + return __Y; +} +extern __inline _Float16 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_cvtsh_h (__m256h __A) +{ + return __A[0]; +} +extern __inline __m256h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_load_ph (void const *__P) +{ + return *(const __m256h *) __P; +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_load_ph (void const *__P) +{ + return *(const __m128h *) __P; +} +extern __inline __m256h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_loadu_ph (void const *__P) +{ + return *(const __m256h_u *) __P; +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_loadu_ph (void const *__P) +{ + return *(const __m128h_u *) __P; +} +extern __inline void +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_store_ph (void *__P, __m256h __A) +{ + *(__m256h *) __P = __A; +} +extern __inline void +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_store_ph (void *__P, __m128h __A) +{ + *(__m128h *) __P = __A; +} +extern __inline void +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_storeu_ph (void *__P, __m256h __A) +{ + *(__m256h_u *) __P = __A; +} +extern __inline void +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_storeu_ph (void *__P, __m128h __A) +{ + *(__m128h_u *) __P = __A; +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_set_sh (_Float16 __F) +{ + return _mm_set_ph (0.0f16, 0.0f16, 0.0f16, 0.0f16, 0.0f16, 0.0f16, 0.0f16, + __F); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_load_sh (void const *__P) +{ + return _mm_set_ph (0.0f16, 0.0f16, 0.0f16, 0.0f16, 0.0f16, 0.0f16, 0.0f16, + *(_Float16 const *) __P); +} +extern __inline void +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_store_sh (void *__P, __m128h __A) +{ + *(_Float16 *) __P = ((__v8hf)__A)[0]; +} +extern __inline __m128h + __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_add_sh (__m128h __A, __m128h __B) +{ + __A[0] += __B[0]; + return __A; +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_add_sh (__m128h __A, __mmask8 __B, __m128h __C, __m128h __D) +{ + return __builtin_ia32_addsh_mask (__C, __D, __A, __B); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_add_sh (__mmask8 __A, __m128h __B, __m128h __C) +{ + return __builtin_ia32_addsh_mask (__B, __C, _mm_setzero_ph (), + __A); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_sub_sh (__m128h __A, __m128h __B) +{ + __A[0] -= __B[0]; + return __A; +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_sub_sh (__m128h __A, __mmask8 __B, __m128h __C, __m128h __D) +{ + return __builtin_ia32_subsh_mask (__C, __D, __A, __B); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_sub_sh (__mmask8 __A, __m128h __B, __m128h __C) +{ + return __builtin_ia32_subsh_mask (__B, __C, _mm_setzero_ph (), + __A); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mul_sh (__m128h __A, __m128h __B) +{ + __A[0] *= __B[0]; + return __A; +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_mul_sh (__m128h __A, __mmask8 __B, __m128h __C, __m128h __D) +{ + return __builtin_ia32_mulsh_mask (__C, __D, __A, __B); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_mul_sh (__mmask8 __A, __m128h __B, __m128h __C) +{ + return __builtin_ia32_mulsh_mask (__B, __C, _mm_setzero_ph (), __A); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_div_sh (__m128h __A, __m128h __B) +{ + __A[0] /= __B[0]; + return __A; +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_div_sh (__m128h __A, __mmask8 __B, __m128h __C, __m128h __D) +{ + return __builtin_ia32_divsh_mask (__C, __D, __A, __B); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_div_sh (__mmask8 __A, __m128h __B, __m128h __C) +{ + return __builtin_ia32_divsh_mask (__B, __C, _mm_setzero_ph (), + __A); +} +#ifdef __OPTIMIZE__ +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_add_round_sh (__m128h __A, __m128h __B, const int __C) +{ + return __builtin_ia32_addsh_mask_round (__A, __B, + _mm_setzero_ph (), + (__mmask8) -1, __C); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_add_round_sh (__m128h __A, __mmask8 __B, __m128h __C, + __m128h __D, const int __E) +{ + return __builtin_ia32_addsh_mask_round (__C, __D, __A, __B, __E); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_add_round_sh (__mmask8 __A, __m128h __B, __m128h __C, + const int __D) +{ + return __builtin_ia32_addsh_mask_round (__B, __C, + _mm_setzero_ph (), + __A, __D); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_sub_round_sh (__m128h __A, __m128h __B, const int __C) +{ + return __builtin_ia32_subsh_mask_round (__A, __B, + _mm_setzero_ph (), + (__mmask8) -1, __C); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_sub_round_sh (__m128h __A, __mmask8 __B, __m128h __C, + __m128h __D, const int __E) +{ + return __builtin_ia32_subsh_mask_round (__C, __D, __A, __B, __E); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_sub_round_sh (__mmask8 __A, __m128h __B, __m128h __C, + const int __D) +{ + return __builtin_ia32_subsh_mask_round (__B, __C, + _mm_setzero_ph (), + __A, __D); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mul_round_sh (__m128h __A, __m128h __B, const int __C) +{ + return __builtin_ia32_mulsh_mask_round (__A, __B, + _mm_setzero_ph (), + (__mmask8) -1, __C); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_mul_round_sh (__m128h __A, __mmask8 __B, __m128h __C, + __m128h __D, const int __E) +{ + return __builtin_ia32_mulsh_mask_round (__C, __D, __A, __B, __E); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_mul_round_sh (__mmask8 __A, __m128h __B, __m128h __C, + const int __D) +{ + return __builtin_ia32_mulsh_mask_round (__B, __C, + _mm_setzero_ph (), + __A, __D); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_div_round_sh (__m128h __A, __m128h __B, const int __C) +{ + return __builtin_ia32_divsh_mask_round (__A, __B, + _mm_setzero_ph (), + (__mmask8) -1, __C); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_div_round_sh (__m128h __A, __mmask8 __B, __m128h __C, + __m128h __D, const int __E) +{ + return __builtin_ia32_divsh_mask_round (__C, __D, __A, __B, __E); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_div_round_sh (__mmask8 __A, __m128h __B, __m128h __C, + const int __D) +{ + return __builtin_ia32_divsh_mask_round (__B, __C, + _mm_setzero_ph (), + __A, __D); +} +#else +#define _mm_add_round_sh(A, B, C) ((__m128h)__builtin_ia32_addsh_mask_round ((A), (B), _mm_setzero_ph (), (__mmask8)-1, (C))) +#define _mm_mask_add_round_sh(A, B, C, D, E) ((__m128h)__builtin_ia32_addsh_mask_round ((C), (D), (A), (B), (E))) +#define _mm_maskz_add_round_sh(A, B, C, D) ((__m128h)__builtin_ia32_addsh_mask_round ((B), (C), _mm_setzero_ph (), (A), (D))) +#define _mm_sub_round_sh(A, B, C) ((__m128h)__builtin_ia32_subsh_mask_round ((A), (B), _mm_setzero_ph (), (__mmask8)-1, (C))) +#define _mm_mask_sub_round_sh(A, B, C, D, E) ((__m128h)__builtin_ia32_subsh_mask_round ((C), (D), (A), (B), (E))) +#define _mm_maskz_sub_round_sh(A, B, C, D) ((__m128h)__builtin_ia32_subsh_mask_round ((B), (C), _mm_setzero_ph (), (A), (D))) +#define _mm_mul_round_sh(A, B, C) ((__m128h)__builtin_ia32_mulsh_mask_round ((A), (B), _mm_setzero_ph (), (__mmask8)-1, (C))) +#define _mm_mask_mul_round_sh(A, B, C, D, E) ((__m128h)__builtin_ia32_mulsh_mask_round ((C), (D), (A), (B), (E))) +#define _mm_maskz_mul_round_sh(A, B, C, D) ((__m128h)__builtin_ia32_mulsh_mask_round ((B), (C), _mm_setzero_ph (), (A), (D))) +#define _mm_div_round_sh(A, B, C) ((__m128h)__builtin_ia32_divsh_mask_round ((A), (B), _mm_setzero_ph (), (__mmask8)-1, (C))) +#define _mm_mask_div_round_sh(A, B, C, D, E) ((__m128h)__builtin_ia32_divsh_mask_round ((C), (D), (A), (B), (E))) +#define _mm_maskz_div_round_sh(A, B, C, D) ((__m128h)__builtin_ia32_divsh_mask_round ((B), (C), _mm_setzero_ph (), (A), (D))) +#endif +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_max_sh (__m128h __A, __m128h __B) +{ + __A[0] = __A[0] > __B[0] ? __A[0] : __B[0]; + return __A; +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_max_sh (__m128h __A, __mmask8 __B, __m128h __C, __m128h __D) +{ + return __builtin_ia32_maxsh_mask (__C, __D, __A, __B); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_max_sh (__mmask8 __A, __m128h __B, __m128h __C) +{ + return __builtin_ia32_maxsh_mask (__B, __C, _mm_setzero_ph (), + __A); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_min_sh (__m128h __A, __m128h __B) +{ + __A[0] = __A[0] < __B[0] ? __A[0] : __B[0]; + return __A; +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_min_sh (__m128h __A, __mmask8 __B, __m128h __C, __m128h __D) +{ + return __builtin_ia32_minsh_mask (__C, __D, __A, __B); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_min_sh (__mmask8 __A, __m128h __B, __m128h __C) +{ + return __builtin_ia32_minsh_mask (__B, __C, _mm_setzero_ph (), + __A); +} +#ifdef __OPTIMIZE__ +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_max_round_sh (__m128h __A, __m128h __B, const int __C) +{ + return __builtin_ia32_maxsh_mask_round (__A, __B, + _mm_setzero_ph (), + (__mmask8) -1, __C); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_max_round_sh (__m128h __A, __mmask8 __B, __m128h __C, + __m128h __D, const int __E) +{ + return __builtin_ia32_maxsh_mask_round (__C, __D, __A, __B, __E); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_max_round_sh (__mmask8 __A, __m128h __B, __m128h __C, + const int __D) +{ + return __builtin_ia32_maxsh_mask_round (__B, __C, + _mm_setzero_ph (), + __A, __D); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_min_round_sh (__m128h __A, __m128h __B, const int __C) +{ + return __builtin_ia32_minsh_mask_round (__A, __B, + _mm_setzero_ph (), + (__mmask8) -1, __C); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_min_round_sh (__m128h __A, __mmask8 __B, __m128h __C, + __m128h __D, const int __E) +{ + return __builtin_ia32_minsh_mask_round (__C, __D, __A, __B, __E); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_min_round_sh (__mmask8 __A, __m128h __B, __m128h __C, + const int __D) +{ + return __builtin_ia32_minsh_mask_round (__B, __C, + _mm_setzero_ph (), + __A, __D); +} +#else +#define _mm_max_round_sh(A, B, C) (__builtin_ia32_maxsh_mask_round ((A), (B), _mm_setzero_ph (), (__mmask8)-1, (C))) +#define _mm_mask_max_round_sh(A, B, C, D, E) (__builtin_ia32_maxsh_mask_round ((C), (D), (A), (B), (E))) +#define _mm_maskz_max_round_sh(A, B, C, D) (__builtin_ia32_maxsh_mask_round ((B), (C), _mm_setzero_ph (), (A), (D))) +#define _mm_min_round_sh(A, B, C) (__builtin_ia32_minsh_mask_round ((A), (B), _mm_setzero_ph (), (__mmask8)-1, (C))) +#define _mm_mask_min_round_sh(A, B, C, D, E) (__builtin_ia32_minsh_mask_round ((C), (D), (A), (B), (E))) +#define _mm_maskz_min_round_sh(A, B, C, D) (__builtin_ia32_minsh_mask_round ((B), (C), _mm_setzero_ph (), (A), (D))) +#endif +#ifdef __OPTIMIZE__ +extern __inline __mmask8 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cmp_sh_mask (__m128h __A, __m128h __B, const int __C) +{ + return (__mmask8) + __builtin_ia32_cmpsh_mask_round (__A, __B, + __C, (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __mmask8 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_cmp_sh_mask (__mmask8 __A, __m128h __B, __m128h __C, + const int __D) +{ + return (__mmask8) + __builtin_ia32_cmpsh_mask_round (__B, __C, + __D, __A, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __mmask8 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cmp_round_sh_mask (__m128h __A, __m128h __B, const int __C, + const int __D) +{ + return (__mmask8) __builtin_ia32_cmpsh_mask_round (__A, __B, + __C, (__mmask8) -1, + __D); +} +extern __inline __mmask8 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_cmp_round_sh_mask (__mmask8 __A, __m128h __B, __m128h __C, + const int __D, const int __E) +{ + return (__mmask8) __builtin_ia32_cmpsh_mask_round (__B, __C, + __D, __A, + __E); +} +#else +#define _mm_cmp_sh_mask(A, B, C) (__builtin_ia32_cmpsh_mask_round ((A), (B), (C), (-1), (_MM_FROUND_CUR_DIRECTION))) +#define _mm_mask_cmp_sh_mask(A, B, C, D) (__builtin_ia32_cmpsh_mask_round ((B), (C), (D), (A), (_MM_FROUND_CUR_DIRECTION))) +#define _mm_cmp_round_sh_mask(A, B, C, D) (__builtin_ia32_cmpsh_mask_round ((A), (B), (C), (-1), (D))) +#define _mm_mask_cmp_round_sh_mask(A, B, C, D, E) (__builtin_ia32_cmpsh_mask_round ((B), (C), (D), (A), (E))) +#endif +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_comieq_sh (__m128h __A, __m128h __B) +{ + return __builtin_ia32_cmpsh_mask_round (__A, __B, _CMP_EQ_OS, + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_comilt_sh (__m128h __A, __m128h __B) +{ + return __builtin_ia32_cmpsh_mask_round (__A, __B, _CMP_LT_OS, + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_comile_sh (__m128h __A, __m128h __B) +{ + return __builtin_ia32_cmpsh_mask_round (__A, __B, _CMP_LE_OS, + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_comigt_sh (__m128h __A, __m128h __B) +{ + return __builtin_ia32_cmpsh_mask_round (__A, __B, _CMP_GT_OS, + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_comige_sh (__m128h __A, __m128h __B) +{ + return __builtin_ia32_cmpsh_mask_round (__A, __B, _CMP_GE_OS, + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_comineq_sh (__m128h __A, __m128h __B) +{ + return __builtin_ia32_cmpsh_mask_round (__A, __B, _CMP_NEQ_US, + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_ucomieq_sh (__m128h __A, __m128h __B) +{ + return __builtin_ia32_cmpsh_mask_round (__A, __B, _CMP_EQ_OQ, + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_ucomilt_sh (__m128h __A, __m128h __B) +{ + return __builtin_ia32_cmpsh_mask_round (__A, __B, _CMP_LT_OQ, + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_ucomile_sh (__m128h __A, __m128h __B) +{ + return __builtin_ia32_cmpsh_mask_round (__A, __B, _CMP_LE_OQ, + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_ucomigt_sh (__m128h __A, __m128h __B) +{ + return __builtin_ia32_cmpsh_mask_round (__A, __B, _CMP_GT_OQ, + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_ucomige_sh (__m128h __A, __m128h __B) +{ + return __builtin_ia32_cmpsh_mask_round (__A, __B, _CMP_GE_OQ, + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_ucomineq_sh (__m128h __A, __m128h __B) +{ + return __builtin_ia32_cmpsh_mask_round (__A, __B, _CMP_NEQ_UQ, + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +#ifdef __OPTIMIZE__ +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_comi_sh (__m128h __A, __m128h __B, const int __P) +{ + return __builtin_ia32_cmpsh_mask_round (__A, __B, __P, + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_comi_round_sh (__m128h __A, __m128h __B, const int __P, const int __R) +{ + return __builtin_ia32_cmpsh_mask_round (__A, __B, __P, + (__mmask8) -1,__R); +} +#else +#define _mm_comi_round_sh(A, B, P, R) (__builtin_ia32_cmpsh_mask_round ((A), (B), (P), (__mmask8) (-1), (R))) +#define _mm_comi_sh(A, B, P) (__builtin_ia32_cmpsh_mask_round ((A), (B), (P), (__mmask8) (-1), _MM_FROUND_CUR_DIRECTION)) +#endif +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_sqrt_sh (__m128h __A, __m128h __B) +{ + return __builtin_ia32_sqrtsh_mask_round (__B, __A, + _mm_setzero_ph (), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_sqrt_sh (__m128h __A, __mmask8 __B, __m128h __C, __m128h __D) +{ + return __builtin_ia32_sqrtsh_mask_round (__D, __C, __A, __B, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_sqrt_sh (__mmask8 __A, __m128h __B, __m128h __C) +{ + return __builtin_ia32_sqrtsh_mask_round (__C, __B, + _mm_setzero_ph (), + __A, _MM_FROUND_CUR_DIRECTION); +} +#ifdef __OPTIMIZE__ +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_sqrt_round_sh (__m128h __A, __m128h __B, const int __C) +{ + return __builtin_ia32_sqrtsh_mask_round (__B, __A, + _mm_setzero_ph (), + (__mmask8) -1, __C); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_sqrt_round_sh (__m128h __A, __mmask8 __B, __m128h __C, + __m128h __D, const int __E) +{ + return __builtin_ia32_sqrtsh_mask_round (__D, __C, __A, __B, + __E); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_sqrt_round_sh (__mmask8 __A, __m128h __B, __m128h __C, + const int __D) +{ + return __builtin_ia32_sqrtsh_mask_round (__C, __B, + _mm_setzero_ph (), + __A, __D); +} +#else +#define _mm_sqrt_round_sh(A, B, C) (__builtin_ia32_sqrtsh_mask_round ((B), (A), _mm_setzero_ph (), (__mmask8)-1, (C))) +#define _mm_mask_sqrt_round_sh(A, B, C, D, E) (__builtin_ia32_sqrtsh_mask_round ((D), (C), (A), (B), (E))) +#define _mm_maskz_sqrt_round_sh(A, B, C, D) (__builtin_ia32_sqrtsh_mask_round ((C), (B), _mm_setzero_ph (), (A), (D))) +#endif +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_rsqrt_sh (__m128h __A, __m128h __B) +{ + return __builtin_ia32_rsqrtsh_mask (__B, __A, _mm_setzero_ph (), + (__mmask8) -1); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_rsqrt_sh (__m128h __A, __mmask8 __B, __m128h __C, __m128h __D) +{ + return __builtin_ia32_rsqrtsh_mask (__D, __C, __A, __B); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_rsqrt_sh (__mmask8 __A, __m128h __B, __m128h __C) +{ + return __builtin_ia32_rsqrtsh_mask (__C, __B, _mm_setzero_ph (), + __A); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_rcp_sh (__m128h __A, __m128h __B) +{ + return __builtin_ia32_rcpsh_mask (__B, __A, _mm_setzero_ph (), + (__mmask8) -1); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_rcp_sh (__m128h __A, __mmask32 __B, __m128h __C, __m128h __D) +{ + return __builtin_ia32_rcpsh_mask (__D, __C, __A, __B); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_rcp_sh (__mmask32 __A, __m128h __B, __m128h __C) +{ + return __builtin_ia32_rcpsh_mask (__C, __B, _mm_setzero_ph (), + __A); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_scalef_sh (__m128h __A, __m128h __B) +{ + return __builtin_ia32_scalefsh_mask_round (__A, __B, + _mm_setzero_ph (), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_scalef_sh (__m128h __A, __mmask8 __B, __m128h __C, __m128h __D) +{ + return __builtin_ia32_scalefsh_mask_round (__C, __D, __A, __B, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_scalef_sh (__mmask8 __A, __m128h __B, __m128h __C) +{ + return __builtin_ia32_scalefsh_mask_round (__B, __C, + _mm_setzero_ph (), + __A, + _MM_FROUND_CUR_DIRECTION); +} +#ifdef __OPTIMIZE__ +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_scalef_round_sh (__m128h __A, __m128h __B, const int __C) +{ + return __builtin_ia32_scalefsh_mask_round (__A, __B, + _mm_setzero_ph (), + (__mmask8) -1, __C); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_scalef_round_sh (__m128h __A, __mmask8 __B, __m128h __C, + __m128h __D, const int __E) +{ + return __builtin_ia32_scalefsh_mask_round (__C, __D, __A, __B, + __E); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_scalef_round_sh (__mmask8 __A, __m128h __B, __m128h __C, + const int __D) +{ + return __builtin_ia32_scalefsh_mask_round (__B, __C, + _mm_setzero_ph (), + __A, __D); +} +#else +#define _mm_scalef_round_sh(A, B, C) (__builtin_ia32_scalefsh_mask_round ((A), (B), _mm_setzero_ph (), (__mmask8)-1, (C))) +#define _mm_mask_scalef_round_sh(A, B, C, D, E) (__builtin_ia32_scalefsh_mask_round ((C), (D), (A), (B), (E))) +#define _mm_maskz_scalef_round_sh(A, B, C, D) (__builtin_ia32_scalefsh_mask_round ((B), (C), _mm_setzero_ph (), (A), (D))) +#endif +#ifdef __OPTIMIZE__ +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_reduce_sh (__m128h __A, __m128h __B, int __C) +{ + return __builtin_ia32_reducesh_mask_round (__A, __B, __C, + _mm_setzero_ph (), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_reduce_sh (__m128h __A, __mmask8 __B, __m128h __C, + __m128h __D, int __E) +{ + return __builtin_ia32_reducesh_mask_round (__C, __D, __E, __A, __B, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_reduce_sh (__mmask8 __A, __m128h __B, __m128h __C, int __D) +{ + return __builtin_ia32_reducesh_mask_round (__B, __C, __D, + _mm_setzero_ph (), __A, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_reduce_round_sh (__m128h __A, __m128h __B, int __C, const int __D) +{ + return __builtin_ia32_reducesh_mask_round (__A, __B, __C, + _mm_setzero_ph (), + (__mmask8) -1, __D); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_reduce_round_sh (__m128h __A, __mmask8 __B, __m128h __C, + __m128h __D, int __E, const int __F) +{ + return __builtin_ia32_reducesh_mask_round (__C, __D, __E, __A, + __B, __F); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_reduce_round_sh (__mmask8 __A, __m128h __B, __m128h __C, + int __D, const int __E) +{ + return __builtin_ia32_reducesh_mask_round (__B, __C, __D, + _mm_setzero_ph (), + __A, __E); +} +#else +#define _mm_reduce_sh(A, B, C) (__builtin_ia32_reducesh_mask_round ((A), (B), (C), _mm_setzero_ph (), (__mmask8)-1, _MM_FROUND_CUR_DIRECTION)) +#define _mm_mask_reduce_sh(A, B, C, D, E) (__builtin_ia32_reducesh_mask_round ((C), (D), (E), (A), (B), _MM_FROUND_CUR_DIRECTION)) +#define _mm_maskz_reduce_sh(A, B, C, D) (__builtin_ia32_reducesh_mask_round ((B), (C), (D), _mm_setzero_ph (), (A), _MM_FROUND_CUR_DIRECTION)) +#define _mm_reduce_round_sh(A, B, C, D) (__builtin_ia32_reducesh_mask_round ((A), (B), (C), _mm_setzero_ph (), (__mmask8)-1, (D))) +#define _mm_mask_reduce_round_sh(A, B, C, D, E, F) (__builtin_ia32_reducesh_mask_round ((C), (D), (E), (A), (B), (F))) +#define _mm_maskz_reduce_round_sh(A, B, C, D, E) (__builtin_ia32_reducesh_mask_round ((B), (C), (D), _mm_setzero_ph (), (A), (E))) +#endif +#ifdef __OPTIMIZE__ +extern __inline __m128h + __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_roundscale_sh (__m128h __A, __m128h __B, int __C) +{ + return __builtin_ia32_rndscalesh_mask_round (__A, __B, __C, + _mm_setzero_ph (), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_roundscale_sh (__m128h __A, __mmask8 __B, __m128h __C, + __m128h __D, int __E) +{ + return __builtin_ia32_rndscalesh_mask_round (__C, __D, __E, __A, __B, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_roundscale_sh (__mmask8 __A, __m128h __B, __m128h __C, int __D) +{ + return __builtin_ia32_rndscalesh_mask_round (__B, __C, __D, + _mm_setzero_ph (), __A, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_roundscale_round_sh (__m128h __A, __m128h __B, int __C, const int __D) +{ + return __builtin_ia32_rndscalesh_mask_round (__A, __B, __C, + _mm_setzero_ph (), + (__mmask8) -1, + __D); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_roundscale_round_sh (__m128h __A, __mmask8 __B, __m128h __C, + __m128h __D, int __E, const int __F) +{ + return __builtin_ia32_rndscalesh_mask_round (__C, __D, __E, + __A, __B, __F); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_roundscale_round_sh (__mmask8 __A, __m128h __B, __m128h __C, + int __D, const int __E) +{ + return __builtin_ia32_rndscalesh_mask_round (__B, __C, __D, + _mm_setzero_ph (), + __A, __E); +} +#else +#define _mm_roundscale_sh(A, B, C) (__builtin_ia32_rndscalesh_mask_round ((A), (B), (C), _mm_setzero_ph (), (__mmask8)-1, _MM_FROUND_CUR_DIRECTION)) +#define _mm_mask_roundscale_sh(A, B, C, D, E) (__builtin_ia32_rndscalesh_mask_round ((C), (D), (E), (A), (B), _MM_FROUND_CUR_DIRECTION)) +#define _mm_maskz_roundscale_sh(A, B, C, D) (__builtin_ia32_rndscalesh_mask_round ((B), (C), (D), _mm_setzero_ph (), (A), _MM_FROUND_CUR_DIRECTION)) +#define _mm_roundscale_round_sh(A, B, C, D) (__builtin_ia32_rndscalesh_mask_round ((A), (B), (C), _mm_setzero_ph (), (__mmask8)-1, (D))) +#define _mm_mask_roundscale_round_sh(A, B, C, D, E, F) (__builtin_ia32_rndscalesh_mask_round ((C), (D), (E), (A), (B), (F))) +#define _mm_maskz_roundscale_round_sh(A, B, C, D, E) (__builtin_ia32_rndscalesh_mask_round ((B), (C), (D), _mm_setzero_ph (), (A), (E))) +#endif +#ifdef __OPTIMIZE__ +extern __inline __mmask8 + __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_fpclass_sh_mask (__m128h __A, const int __imm) +{ + return (__mmask8) __builtin_ia32_fpclasssh_mask ((__v8hf) __A, __imm, + (__mmask8) -1); +} +extern __inline __mmask8 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fpclass_sh_mask (__mmask8 __U, __m128h __A, const int __imm) +{ + return (__mmask8) __builtin_ia32_fpclasssh_mask ((__v8hf) __A, __imm, __U); +} +#else +#define _mm_fpclass_sh_mask(X, C) ((__mmask8) __builtin_ia32_fpclasssh_mask ((__v8hf) (__m128h) (X), (int) (C), (__mmask8) (-1))) +#define _mm_mask_fpclass_sh_mask(U, X, C) ((__mmask8) __builtin_ia32_fpclasssh_mask ((__v8hf) (__m128h) (X), (int) (C), (__mmask8) (U))) +#endif +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_getexp_sh (__m128h __A, __m128h __B) +{ + return (__m128h) + __builtin_ia32_getexpsh_mask_round ((__v8hf) __A, (__v8hf) __B, + (__v8hf) _mm_setzero_ph (), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_getexp_sh (__m128h __W, __mmask8 __U, __m128h __A, __m128h __B) +{ + return (__m128h) + __builtin_ia32_getexpsh_mask_round ((__v8hf) __A, (__v8hf) __B, + (__v8hf) __W, (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_getexp_sh (__mmask8 __U, __m128h __A, __m128h __B) +{ + return (__m128h) + __builtin_ia32_getexpsh_mask_round ((__v8hf) __A, (__v8hf) __B, + (__v8hf) _mm_setzero_ph (), + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +#ifdef __OPTIMIZE__ +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_getexp_round_sh (__m128h __A, __m128h __B, const int __R) +{ + return (__m128h) __builtin_ia32_getexpsh_mask_round ((__v8hf) __A, + (__v8hf) __B, + _mm_setzero_ph (), + (__mmask8) -1, + __R); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_getexp_round_sh (__m128h __W, __mmask8 __U, __m128h __A, + __m128h __B, const int __R) +{ + return (__m128h) __builtin_ia32_getexpsh_mask_round ((__v8hf) __A, + (__v8hf) __B, + (__v8hf) __W, + (__mmask8) __U, __R); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_getexp_round_sh (__mmask8 __U, __m128h __A, __m128h __B, + const int __R) +{ + return (__m128h) __builtin_ia32_getexpsh_mask_round ((__v8hf) __A, + (__v8hf) __B, + (__v8hf) + _mm_setzero_ph (), + (__mmask8) __U, __R); +} +#else +#define _mm_getexp_round_sh(A, B, R) ((__m128h)__builtin_ia32_getexpsh_mask_round((__v8hf)(__m128h)(A), (__v8hf)(__m128h)(B), (__v8hf)_mm_setzero_ph(), (__mmask8)-1, R)) +#define _mm_mask_getexp_round_sh(W, U, A, B, C) (__m128h)__builtin_ia32_getexpsh_mask_round(A, B, W, U, C) +#define _mm_maskz_getexp_round_sh(U, A, B, C) (__m128h)__builtin_ia32_getexpsh_mask_round(A, B, (__v8hf)_mm_setzero_ph(), U, C) +#endif +#ifdef __OPTIMIZE__ +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_getmant_sh (__m128h __A, __m128h __B, + _MM_MANTISSA_NORM_ENUM __C, + _MM_MANTISSA_SIGN_ENUM __D) +{ + return (__m128h) + __builtin_ia32_getmantsh_mask_round ((__v8hf) __A, (__v8hf) __B, + (__D << 2) | __C, _mm_setzero_ph (), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_getmant_sh (__m128h __W, __mmask8 __U, __m128h __A, + __m128h __B, _MM_MANTISSA_NORM_ENUM __C, + _MM_MANTISSA_SIGN_ENUM __D) +{ + return (__m128h) + __builtin_ia32_getmantsh_mask_round ((__v8hf) __A, (__v8hf) __B, + (__D << 2) | __C, (__v8hf) __W, + __U, _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_getmant_sh (__mmask8 __U, __m128h __A, __m128h __B, + _MM_MANTISSA_NORM_ENUM __C, + _MM_MANTISSA_SIGN_ENUM __D) +{ + return (__m128h) + __builtin_ia32_getmantsh_mask_round ((__v8hf) __A, (__v8hf) __B, + (__D << 2) | __C, + (__v8hf) _mm_setzero_ph(), + __U, _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_getmant_round_sh (__m128h __A, __m128h __B, + _MM_MANTISSA_NORM_ENUM __C, + _MM_MANTISSA_SIGN_ENUM __D, const int __R) +{ + return (__m128h) __builtin_ia32_getmantsh_mask_round ((__v8hf) __A, + (__v8hf) __B, + (__D << 2) | __C, + _mm_setzero_ph (), + (__mmask8) -1, + __R); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_getmant_round_sh (__m128h __W, __mmask8 __U, __m128h __A, + __m128h __B, _MM_MANTISSA_NORM_ENUM __C, + _MM_MANTISSA_SIGN_ENUM __D, const int __R) +{ + return (__m128h) __builtin_ia32_getmantsh_mask_round ((__v8hf) __A, + (__v8hf) __B, + (__D << 2) | __C, + (__v8hf) __W, + __U, __R); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_getmant_round_sh (__mmask8 __U, __m128h __A, __m128h __B, + _MM_MANTISSA_NORM_ENUM __C, + _MM_MANTISSA_SIGN_ENUM __D, const int __R) +{ + return (__m128h) __builtin_ia32_getmantsh_mask_round ((__v8hf) __A, + (__v8hf) __B, + (__D << 2) | __C, + (__v8hf) + _mm_setzero_ph(), + __U, __R); +} +#else +#define _mm_getmant_sh(X, Y, C, D) ((__m128h)__builtin_ia32_getmantsh_mask_round ((__v8hf)(__m128h)(X), (__v8hf)(__m128h)(Y), (int)(((D)<<2) | (C)), (__v8hf)(__m128h) _mm_setzero_ph (), (__mmask8)-1, _MM_FROUND_CUR_DIRECTION)) +#define _mm_mask_getmant_sh(W, U, X, Y, C, D) ((__m128h)__builtin_ia32_getmantsh_mask_round ((__v8hf)(__m128h)(X), (__v8hf)(__m128h)(Y), (int)(((D)<<2) | (C)), (__v8hf)(__m128h)(W), (__mmask8)(U), _MM_FROUND_CUR_DIRECTION)) +#define _mm_maskz_getmant_sh(U, X, Y, C, D) ((__m128h)__builtin_ia32_getmantsh_mask_round ((__v8hf)(__m128h)(X), (__v8hf)(__m128h)(Y), (int)(((D)<<2) | (C)), (__v8hf)(__m128h) _mm_setzero_ph(), (__mmask8)(U), _MM_FROUND_CUR_DIRECTION)) +#define _mm_getmant_round_sh(X, Y, C, D, R) ((__m128h)__builtin_ia32_getmantsh_mask_round ((__v8hf)(__m128h)(X), (__v8hf)(__m128h)(Y), (int)(((D)<<2) | (C)), (__v8hf)(__m128h) _mm_setzero_ph (), (__mmask8)-1, (R))) +#define _mm_mask_getmant_round_sh(W, U, X, Y, C, D, R) ((__m128h)__builtin_ia32_getmantsh_mask_round ((__v8hf)(__m128h)(X), (__v8hf)(__m128h)(Y), (int)(((D)<<2) | (C)), (__v8hf)(__m128h)(W), (__mmask8)(U), (R))) +#define _mm_maskz_getmant_round_sh(U, X, Y, C, D, R) ((__m128h)__builtin_ia32_getmantsh_mask_round ((__v8hf)(__m128h)(X), (__v8hf)(__m128h)(Y), (int)(((D)<<2) | (C)), (__v8hf)(__m128h) _mm_setzero_ph(), (__mmask8)(U), (R))) +#endif +extern __inline __m128i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtsi16_si128 (short __A) +{ + return _mm_avx512_set_epi16 (0, 0, 0, 0, 0, 0, 0, __A); +} +extern __inline short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtsi128_si16 (__m128i __A) +{ + return __builtin_ia32_vec_ext_v8hi ((__v8hi)__A, 0); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_load_sh (__m128h __A, __mmask8 __B, _Float16 const* __C) +{ + return __builtin_ia32_loadsh_mask (__C, __A, __B); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_load_sh (__mmask8 __A, _Float16 const* __B) +{ + return __builtin_ia32_loadsh_mask (__B, _mm_setzero_ph (), __A); +} +extern __inline void +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_store_sh (_Float16 const* __A, __mmask8 __B, __m128h __C) +{ + __builtin_ia32_storesh_mask (__A, __C, __B); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_move_sh (__m128h __A, __m128h __B) +{ + __A[0] = __B[0]; + return __A; +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_move_sh (__m128h __A, __mmask8 __B, __m128h __C, __m128h __D) +{ + return __builtin_ia32_vmovsh_mask (__C, __D, __A, __B); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_move_sh (__mmask8 __A, __m128h __B, __m128h __C) +{ + return __builtin_ia32_vmovsh_mask (__B, __C, _mm_setzero_ph (), __A); +} +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtsh_i32 (__m128h __A) +{ + return (int) __builtin_ia32_vcvtsh2si32_round (__A, _MM_FROUND_CUR_DIRECTION); +} +extern __inline unsigned +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtsh_u32 (__m128h __A) +{ + return (int) __builtin_ia32_vcvtsh2usi32_round (__A, + _MM_FROUND_CUR_DIRECTION); +} +#ifdef __OPTIMIZE__ +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundsh_i32 (__m128h __A, const int __R) +{ + return (int) __builtin_ia32_vcvtsh2si32_round (__A, __R); +} +extern __inline unsigned +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundsh_u32 (__m128h __A, const int __R) +{ + return (int) __builtin_ia32_vcvtsh2usi32_round (__A, __R); +} +#else +#define _mm_cvt_roundsh_i32(A, B) ((int)__builtin_ia32_vcvtsh2si32_round ((A), (B))) +#define _mm_cvt_roundsh_u32(A, B) ((int)__builtin_ia32_vcvtsh2usi32_round ((A), (B))) +#endif +#ifdef __x86_64__ +extern __inline long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtsh_i64 (__m128h __A) +{ + return (long long) + __builtin_ia32_vcvtsh2si64_round (__A, _MM_FROUND_CUR_DIRECTION); +} +extern __inline unsigned long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtsh_u64 (__m128h __A) +{ + return (long long) + __builtin_ia32_vcvtsh2usi64_round (__A, _MM_FROUND_CUR_DIRECTION); +} +#ifdef __OPTIMIZE__ +extern __inline long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundsh_i64 (__m128h __A, const int __R) +{ + return (long long) __builtin_ia32_vcvtsh2si64_round (__A, __R); +} +extern __inline unsigned long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundsh_u64 (__m128h __A, const int __R) +{ + return (long long) __builtin_ia32_vcvtsh2usi64_round (__A, __R); +} +#else +#define _mm_cvt_roundsh_i64(A, B) ((long long)__builtin_ia32_vcvtsh2si64_round ((A), (B))) +#define _mm_cvt_roundsh_u64(A, B) ((long long)__builtin_ia32_vcvtsh2usi64_round ((A), (B))) +#endif +#endif +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvti32_sh (__m128h __A, int __B) +{ + return __builtin_ia32_vcvtsi2sh32_round (__A, __B, _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtu32_sh (__m128h __A, unsigned int __B) +{ + return __builtin_ia32_vcvtusi2sh32_round (__A, __B, _MM_FROUND_CUR_DIRECTION); +} +#ifdef __OPTIMIZE__ +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundi32_sh (__m128h __A, int __B, const int __R) +{ + return __builtin_ia32_vcvtsi2sh32_round (__A, __B, __R); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundu32_sh (__m128h __A, unsigned int __B, const int __R) +{ + return __builtin_ia32_vcvtusi2sh32_round (__A, __B, __R); +} +#else +#define _mm_cvt_roundi32_sh(A, B, C) (__builtin_ia32_vcvtsi2sh32_round ((A), (B), (C))) +#define _mm_cvt_roundu32_sh(A, B, C) (__builtin_ia32_vcvtusi2sh32_round ((A), (B), (C))) +#endif +#ifdef __x86_64__ +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvti64_sh (__m128h __A, long long __B) +{ + return __builtin_ia32_vcvtsi2sh64_round (__A, __B, _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtu64_sh (__m128h __A, unsigned long long __B) +{ + return __builtin_ia32_vcvtusi2sh64_round (__A, __B, _MM_FROUND_CUR_DIRECTION); +} +#ifdef __OPTIMIZE__ +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundi64_sh (__m128h __A, long long __B, const int __R) +{ + return __builtin_ia32_vcvtsi2sh64_round (__A, __B, __R); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundu64_sh (__m128h __A, unsigned long long __B, const int __R) +{ + return __builtin_ia32_vcvtusi2sh64_round (__A, __B, __R); +} +#else +#define _mm_cvt_roundi64_sh(A, B, C) (__builtin_ia32_vcvtsi2sh64_round ((A), (B), (C))) +#define _mm_cvt_roundu64_sh(A, B, C) (__builtin_ia32_vcvtusi2sh64_round ((A), (B), (C))) +#endif +#endif +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvttsh_i32 (__m128h __A) +{ + return (int) + __builtin_ia32_vcvttsh2si32_round (__A, _MM_FROUND_CUR_DIRECTION); +} +extern __inline unsigned +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvttsh_u32 (__m128h __A) +{ + return (int) + __builtin_ia32_vcvttsh2usi32_round (__A, _MM_FROUND_CUR_DIRECTION); +} +#ifdef __OPTIMIZE__ +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtt_roundsh_i32 (__m128h __A, const int __R) +{ + return (int) __builtin_ia32_vcvttsh2si32_round (__A, __R); +} +extern __inline unsigned +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtt_roundsh_u32 (__m128h __A, const int __R) +{ + return (int) __builtin_ia32_vcvttsh2usi32_round (__A, __R); +} +#else +#define _mm_cvtt_roundsh_i32(A, B) ((int)__builtin_ia32_vcvttsh2si32_round ((A), (B))) +#define _mm_cvtt_roundsh_u32(A, B) ((int)__builtin_ia32_vcvttsh2usi32_round ((A), (B))) +#endif +#ifdef __x86_64__ +extern __inline long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvttsh_i64 (__m128h __A) +{ + return (long long) + __builtin_ia32_vcvttsh2si64_round (__A, _MM_FROUND_CUR_DIRECTION); +} +extern __inline unsigned long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvttsh_u64 (__m128h __A) +{ + return (long long) + __builtin_ia32_vcvttsh2usi64_round (__A, _MM_FROUND_CUR_DIRECTION); +} +#ifdef __OPTIMIZE__ +extern __inline long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtt_roundsh_i64 (__m128h __A, const int __R) +{ + return (long long) __builtin_ia32_vcvttsh2si64_round (__A, __R); +} +extern __inline unsigned long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtt_roundsh_u64 (__m128h __A, const int __R) +{ + return (long long) __builtin_ia32_vcvttsh2usi64_round (__A, __R); +} +#else +#define _mm_cvtt_roundsh_i64(A, B) ((long long)__builtin_ia32_vcvttsh2si64_round ((A), (B))) +#define _mm_cvtt_roundsh_u64(A, B) ((long long)__builtin_ia32_vcvttsh2usi64_round ((A), (B))) +#endif +#endif +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtsh_ss (__m128 __A, __m128h __B) +{ + return __builtin_ia32_vcvtsh2ss_mask_round (__B, __A, + _mm_avx512_setzero_ps (), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_cvtsh_ss (__m128 __A, __mmask8 __B, __m128 __C, + __m128h __D) +{ + return __builtin_ia32_vcvtsh2ss_mask_round (__D, __C, __A, __B, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_cvtsh_ss (__mmask8 __A, __m128 __B, + __m128h __C) +{ + return __builtin_ia32_vcvtsh2ss_mask_round (__C, __B, + _mm_avx512_setzero_ps (), + __A, _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtsh_sd (__m128d __A, __m128h __B) +{ + return __builtin_ia32_vcvtsh2sd_mask_round (__B, __A, + _mm_avx512_setzero_pd (), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_cvtsh_sd (__m128d __A, __mmask8 __B, __m128d __C, + __m128h __D) +{ + return __builtin_ia32_vcvtsh2sd_mask_round (__D, __C, __A, __B, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_cvtsh_sd (__mmask8 __A, __m128d __B, __m128h __C) +{ + return __builtin_ia32_vcvtsh2sd_mask_round (__C, __B, + _mm_avx512_setzero_pd (), + __A, _MM_FROUND_CUR_DIRECTION); +} +#ifdef __OPTIMIZE__ +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundsh_ss (__m128 __A, __m128h __B, const int __R) +{ + return __builtin_ia32_vcvtsh2ss_mask_round (__B, __A, + _mm_avx512_setzero_ps (), + (__mmask8) -1, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_cvt_roundsh_ss (__m128 __A, __mmask8 __B, __m128 __C, + __m128h __D, const int __R) +{ + return __builtin_ia32_vcvtsh2ss_mask_round (__D, __C, __A, __B, __R); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_cvt_roundsh_ss (__mmask8 __A, __m128 __B, + __m128h __C, const int __R) +{ + return __builtin_ia32_vcvtsh2ss_mask_round (__C, __B, + _mm_avx512_setzero_ps (), + __A, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundsh_sd (__m128d __A, __m128h __B, const int __R) +{ + return __builtin_ia32_vcvtsh2sd_mask_round (__B, __A, + _mm_avx512_setzero_pd (), + (__mmask8) -1, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_cvt_roundsh_sd (__m128d __A, __mmask8 __B, __m128d __C, + __m128h __D, const int __R) +{ + return __builtin_ia32_vcvtsh2sd_mask_round (__D, __C, __A, __B, __R); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_cvt_roundsh_sd (__mmask8 __A, __m128d __B, __m128h __C, const int __R) +{ + return __builtin_ia32_vcvtsh2sd_mask_round (__C, __B, + _mm_avx512_setzero_pd (), + __A, __R); +} +#else +#define _mm_cvt_roundsh_ss(A, B, R) (__builtin_ia32_vcvtsh2ss_mask_round ((B), (A), _mm_avx512_setzero_ps (), (__mmask8) -1, (R))) +#define _mm_mask_cvt_roundsh_ss(A, B, C, D, R) (__builtin_ia32_vcvtsh2ss_mask_round ((D), (C), (A), (B), (R))) +#define _mm_maskz_cvt_roundsh_ss(A, B, C, R) (__builtin_ia32_vcvtsh2ss_mask_round ((C), (B), _mm_avx512_setzero_ps (), (A), (R))) +#define _mm_cvt_roundsh_sd(A, B, R) (__builtin_ia32_vcvtsh2sd_mask_round ((B), (A), _mm_avx512_setzero_pd (), (__mmask8) -1, (R))) +#define _mm_mask_cvt_roundsh_sd(A, B, C, D, R) (__builtin_ia32_vcvtsh2sd_mask_round ((D), (C), (A), (B), (R))) +#define _mm_maskz_cvt_roundsh_sd(A, B, C, R) (__builtin_ia32_vcvtsh2sd_mask_round ((C), (B), _mm_avx512_setzero_pd (), (A), (R))) +#endif +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtss_sh (__m128h __A, __m128 __B) +{ + return __builtin_ia32_vcvtss2sh_mask_round (__B, __A, + _mm_setzero_ph (), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_cvtss_sh (__m128h __A, __mmask8 __B, __m128h __C, __m128 __D) +{ + return __builtin_ia32_vcvtss2sh_mask_round (__D, __C, __A, __B, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_cvtss_sh (__mmask8 __A, __m128h __B, __m128 __C) +{ + return __builtin_ia32_vcvtss2sh_mask_round (__C, __B, + _mm_setzero_ph (), + __A, _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtsd_sh (__m128h __A, __m128d __B) +{ + return __builtin_ia32_vcvtsd2sh_mask_round (__B, __A, + _mm_setzero_ph (), + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_cvtsd_sh (__m128h __A, __mmask8 __B, __m128h __C, __m128d __D) +{ + return __builtin_ia32_vcvtsd2sh_mask_round (__D, __C, __A, __B, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_cvtsd_sh (__mmask8 __A, __m128h __B, __m128d __C) +{ + return __builtin_ia32_vcvtsd2sh_mask_round (__C, __B, + _mm_setzero_ph (), + __A, _MM_FROUND_CUR_DIRECTION); +} +#ifdef __OPTIMIZE__ +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundss_sh (__m128h __A, __m128 __B, const int __R) +{ + return __builtin_ia32_vcvtss2sh_mask_round (__B, __A, + _mm_setzero_ph (), + (__mmask8) -1, __R); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_cvt_roundss_sh (__m128h __A, __mmask8 __B, __m128h __C, __m128 __D, + const int __R) +{ + return __builtin_ia32_vcvtss2sh_mask_round (__D, __C, __A, __B, __R); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_cvt_roundss_sh (__mmask8 __A, __m128h __B, __m128 __C, + const int __R) +{ + return __builtin_ia32_vcvtss2sh_mask_round (__C, __B, + _mm_setzero_ph (), + __A, __R); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvt_roundsd_sh (__m128h __A, __m128d __B, const int __R) +{ + return __builtin_ia32_vcvtsd2sh_mask_round (__B, __A, + _mm_setzero_ph (), + (__mmask8) -1, __R); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_cvt_roundsd_sh (__m128h __A, __mmask8 __B, __m128h __C, __m128d __D, + const int __R) +{ + return __builtin_ia32_vcvtsd2sh_mask_round (__D, __C, __A, __B, __R); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_cvt_roundsd_sh (__mmask8 __A, __m128h __B, __m128d __C, + const int __R) +{ + return __builtin_ia32_vcvtsd2sh_mask_round (__C, __B, + _mm_setzero_ph (), + __A, __R); +} +#else +#define _mm_cvt_roundss_sh(A, B, R) (__builtin_ia32_vcvtss2sh_mask_round ((B), (A), _mm_setzero_ph (), (__mmask8) -1, R)) +#define _mm_mask_cvt_roundss_sh(A, B, C, D, R) (__builtin_ia32_vcvtss2sh_mask_round ((D), (C), (A), (B), (R))) +#define _mm_maskz_cvt_roundss_sh(A, B, C, R) (__builtin_ia32_vcvtss2sh_mask_round ((C), (B), _mm_setzero_ph (), A, R)) +#define _mm_cvt_roundsd_sh(A, B, R) (__builtin_ia32_vcvtsd2sh_mask_round ((B), (A), _mm_setzero_ph (), (__mmask8) -1, R)) +#define _mm_mask_cvt_roundsd_sh(A, B, C, D, R) (__builtin_ia32_vcvtsd2sh_mask_round ((D), (C), (A), (B), (R))) +#define _mm_maskz_cvt_roundsd_sh(A, B, C, R) (__builtin_ia32_vcvtsd2sh_mask_round ((C), (B), _mm_setzero_ph (), (A), (R))) +#endif +extern __inline _Float16 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtsh_h (__m128h __A) +{ + return __A[0]; +} +extern __inline __m128h + __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_fmadd_sh (__m128h __W, __m128h __A, __m128h __B) +{ + return (__m128h) __builtin_ia32_vfmaddsh3_mask ((__v8hf) __W, + (__v8hf) __A, + (__v8hf) __B, + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fmadd_sh (__m128h __W, __mmask8 __U, __m128h __A, __m128h __B) +{ + return (__m128h) __builtin_ia32_vfmaddsh3_mask ((__v8hf) __W, + (__v8hf) __A, + (__v8hf) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask3_fmadd_sh (__m128h __W, __m128h __A, __m128h __B, __mmask8 __U) +{ + return (__m128h) __builtin_ia32_vfmaddsh3_mask3 ((__v8hf) __W, + (__v8hf) __A, + (__v8hf) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fmadd_sh (__mmask8 __U, __m128h __W, __m128h __A, __m128h __B) +{ + return (__m128h) __builtin_ia32_vfmaddsh3_maskz ((__v8hf) __W, + (__v8hf) __A, + (__v8hf) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +#ifdef __OPTIMIZE__ +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_fmadd_round_sh (__m128h __W, __m128h __A, __m128h __B, const int __R) +{ + return (__m128h) __builtin_ia32_vfmaddsh3_mask ((__v8hf) __W, + (__v8hf) __A, + (__v8hf) __B, + (__mmask8) -1, + __R); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fmadd_round_sh (__m128h __W, __mmask8 __U, __m128h __A, __m128h __B, + const int __R) +{ + return (__m128h) __builtin_ia32_vfmaddsh3_mask ((__v8hf) __W, + (__v8hf) __A, + (__v8hf) __B, + (__mmask8) __U, __R); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask3_fmadd_round_sh (__m128h __W, __m128h __A, __m128h __B, __mmask8 __U, + const int __R) +{ + return (__m128h) __builtin_ia32_vfmaddsh3_mask3 ((__v8hf) __W, + (__v8hf) __A, + (__v8hf) __B, + (__mmask8) __U, __R); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fmadd_round_sh (__mmask8 __U, __m128h __W, __m128h __A, + __m128h __B, const int __R) +{ + return (__m128h) __builtin_ia32_vfmaddsh3_maskz ((__v8hf) __W, + (__v8hf) __A, + (__v8hf) __B, + (__mmask8) __U, __R); +} +#else +#define _mm_fmadd_round_sh(A, B, C, R) ((__m128h) __builtin_ia32_vfmaddsh3_mask ((A), (B), (C), (-1), (R))) +#define _mm_mask_fmadd_round_sh(A, U, B, C, R) ((__m128h) __builtin_ia32_vfmaddsh3_mask ((A), (B), (C), (U), (R))) +#define _mm_mask3_fmadd_round_sh(A, B, C, U, R) ((__m128h) __builtin_ia32_vfmaddsh3_mask3 ((A), (B), (C), (U), (R))) +#define _mm_maskz_fmadd_round_sh(U, A, B, C, R) ((__m128h) __builtin_ia32_vfmaddsh3_maskz ((A), (B), (C), (U), (R))) +#endif +extern __inline __m128h + __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_fnmadd_sh (__m128h __W, __m128h __A, __m128h __B) +{ + return (__m128h) __builtin_ia32_vfnmaddsh3_mask ((__v8hf) __W, + (__v8hf) __A, + (__v8hf) __B, + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fnmadd_sh (__m128h __W, __mmask8 __U, __m128h __A, __m128h __B) +{ + return (__m128h) __builtin_ia32_vfnmaddsh3_mask ((__v8hf) __W, + (__v8hf) __A, + (__v8hf) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask3_fnmadd_sh (__m128h __W, __m128h __A, __m128h __B, __mmask8 __U) +{ + return (__m128h) __builtin_ia32_vfnmaddsh3_mask3 ((__v8hf) __W, + (__v8hf) __A, + (__v8hf) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fnmadd_sh (__mmask8 __U, __m128h __W, __m128h __A, __m128h __B) +{ + return (__m128h) __builtin_ia32_vfnmaddsh3_maskz ((__v8hf) __W, + (__v8hf) __A, + (__v8hf) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +#ifdef __OPTIMIZE__ +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_fnmadd_round_sh (__m128h __W, __m128h __A, __m128h __B, const int __R) +{ + return (__m128h) __builtin_ia32_vfnmaddsh3_mask ((__v8hf) __W, + (__v8hf) __A, + (__v8hf) __B, + (__mmask8) -1, + __R); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fnmadd_round_sh (__m128h __W, __mmask8 __U, __m128h __A, __m128h __B, + const int __R) +{ + return (__m128h) __builtin_ia32_vfnmaddsh3_mask ((__v8hf) __W, + (__v8hf) __A, + (__v8hf) __B, + (__mmask8) __U, __R); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask3_fnmadd_round_sh (__m128h __W, __m128h __A, __m128h __B, __mmask8 __U, + const int __R) +{ + return (__m128h) __builtin_ia32_vfnmaddsh3_mask3 ((__v8hf) __W, + (__v8hf) __A, + (__v8hf) __B, + (__mmask8) __U, __R); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fnmadd_round_sh (__mmask8 __U, __m128h __W, __m128h __A, + __m128h __B, const int __R) +{ + return (__m128h) __builtin_ia32_vfnmaddsh3_maskz ((__v8hf) __W, + (__v8hf) __A, + (__v8hf) __B, + (__mmask8) __U, __R); +} +#else +#define _mm_fnmadd_round_sh(A, B, C, R) ((__m128h) __builtin_ia32_vfnmaddsh3_mask ((A), (B), (C), (-1), (R))) +#define _mm_mask_fnmadd_round_sh(A, U, B, C, R) ((__m128h) __builtin_ia32_vfnmaddsh3_mask ((A), (B), (C), (U), (R))) +#define _mm_mask3_fnmadd_round_sh(A, B, C, U, R) ((__m128h) __builtin_ia32_vfnmaddsh3_mask3 ((A), (B), (C), (U), (R))) +#define _mm_maskz_fnmadd_round_sh(U, A, B, C, R) ((__m128h) __builtin_ia32_vfnmaddsh3_maskz ((A), (B), (C), (U), (R))) +#endif +extern __inline __m128h + __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_fmsub_sh (__m128h __W, __m128h __A, __m128h __B) +{ + return (__m128h) __builtin_ia32_vfmaddsh3_mask ((__v8hf) __W, + (__v8hf) __A, + -(__v8hf) __B, + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fmsub_sh (__m128h __W, __mmask8 __U, __m128h __A, __m128h __B) +{ + return (__m128h) __builtin_ia32_vfmaddsh3_mask ((__v8hf) __W, + (__v8hf) __A, + -(__v8hf) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask3_fmsub_sh (__m128h __W, __m128h __A, __m128h __B, __mmask8 __U) +{ + return (__m128h) __builtin_ia32_vfmsubsh3_mask3 ((__v8hf) __W, + (__v8hf) __A, + (__v8hf) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fmsub_sh (__mmask8 __U, __m128h __W, __m128h __A, __m128h __B) +{ + return (__m128h) __builtin_ia32_vfmaddsh3_maskz ((__v8hf) __W, + (__v8hf) __A, + -(__v8hf) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +#ifdef __OPTIMIZE__ +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_fmsub_round_sh (__m128h __W, __m128h __A, __m128h __B, const int __R) +{ + return (__m128h) __builtin_ia32_vfmaddsh3_mask ((__v8hf) __W, + (__v8hf) __A, + -(__v8hf) __B, + (__mmask8) -1, + __R); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fmsub_round_sh (__m128h __W, __mmask8 __U, __m128h __A, __m128h __B, + const int __R) +{ + return (__m128h) __builtin_ia32_vfmaddsh3_mask ((__v8hf) __W, + (__v8hf) __A, + -(__v8hf) __B, + (__mmask8) __U, __R); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask3_fmsub_round_sh (__m128h __W, __m128h __A, __m128h __B, __mmask8 __U, + const int __R) +{ + return (__m128h) __builtin_ia32_vfmsubsh3_mask3 ((__v8hf) __W, + (__v8hf) __A, + (__v8hf) __B, + (__mmask8) __U, __R); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fmsub_round_sh (__mmask8 __U, __m128h __W, __m128h __A, + __m128h __B, const int __R) +{ + return (__m128h) __builtin_ia32_vfmaddsh3_maskz ((__v8hf) __W, + (__v8hf) __A, + -(__v8hf) __B, + (__mmask8) __U, __R); +} +#else +#define _mm_fmsub_round_sh(A, B, C, R) ((__m128h) __builtin_ia32_vfmaddsh3_mask ((A), (B), -(C), (-1), (R))) +#define _mm_mask_fmsub_round_sh(A, U, B, C, R) ((__m128h) __builtin_ia32_vfmaddsh3_mask ((A), (B), -(C), (U), (R))) +#define _mm_mask3_fmsub_round_sh(A, B, C, U, R) ((__m128h) __builtin_ia32_vfmsubsh3_mask3 ((A), (B), (C), (U), (R))) +#define _mm_maskz_fmsub_round_sh(U, A, B, C, R) ((__m128h) __builtin_ia32_vfmaddsh3_maskz ((A), (B), -(C), (U), (R))) +#endif +extern __inline __m128h + __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_fnmsub_sh (__m128h __W, __m128h __A, __m128h __B) +{ + return (__m128h) __builtin_ia32_vfmaddsh3_mask ((__v8hf) __W, + -(__v8hf) __A, + -(__v8hf) __B, + (__mmask8) -1, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fnmsub_sh (__m128h __W, __mmask8 __U, __m128h __A, __m128h __B) +{ + return (__m128h) __builtin_ia32_vfmaddsh3_mask ((__v8hf) __W, + -(__v8hf) __A, + -(__v8hf) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask3_fnmsub_sh (__m128h __W, __m128h __A, __m128h __B, __mmask8 __U) +{ + return (__m128h) __builtin_ia32_vfmsubsh3_mask3 ((__v8hf) __W, + -(__v8hf) __A, + (__v8hf) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fnmsub_sh (__mmask8 __U, __m128h __W, __m128h __A, __m128h __B) +{ + return (__m128h) __builtin_ia32_vfmaddsh3_maskz ((__v8hf) __W, + -(__v8hf) __A, + -(__v8hf) __B, + (__mmask8) __U, + _MM_FROUND_CUR_DIRECTION); +} +#ifdef __OPTIMIZE__ +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_fnmsub_round_sh (__m128h __W, __m128h __A, __m128h __B, const int __R) +{ + return (__m128h) __builtin_ia32_vfmaddsh3_mask ((__v8hf) __W, + -(__v8hf) __A, + -(__v8hf) __B, + (__mmask8) -1, + __R); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fnmsub_round_sh (__m128h __W, __mmask8 __U, __m128h __A, __m128h __B, + const int __R) +{ + return (__m128h) __builtin_ia32_vfmaddsh3_mask ((__v8hf) __W, + -(__v8hf) __A, + -(__v8hf) __B, + (__mmask8) __U, __R); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask3_fnmsub_round_sh (__m128h __W, __m128h __A, __m128h __B, __mmask8 __U, + const int __R) +{ + return (__m128h) __builtin_ia32_vfmsubsh3_mask3 ((__v8hf) __W, + -(__v8hf) __A, + (__v8hf) __B, + (__mmask8) __U, __R); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fnmsub_round_sh (__mmask8 __U, __m128h __W, __m128h __A, + __m128h __B, const int __R) +{ + return (__m128h) __builtin_ia32_vfmaddsh3_maskz ((__v8hf) __W, + -(__v8hf) __A, + -(__v8hf) __B, + (__mmask8) __U, __R); +} +#else +#define _mm_fnmsub_round_sh(A, B, C, R) ((__m128h) __builtin_ia32_vfmaddsh3_mask ((A), -(B), -(C), (-1), (R))) +#define _mm_mask_fnmsub_round_sh(A, U, B, C, R) ((__m128h) __builtin_ia32_vfmaddsh3_mask ((A), -(B), -(C), (U), (R))) +#define _mm_mask3_fnmsub_round_sh(A, B, C, U, R) ((__m128h) __builtin_ia32_vfmsubsh3_mask3 ((A), -(B), (C), (U), (R))) +#define _mm_maskz_fnmsub_round_sh(U, A, B, C, R) ((__m128h) __builtin_ia32_vfmaddsh3_maskz ((A), -(B), -(C), (U), (R))) +#endif +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fcmadd_sch (__m128h __A, __mmask8 __B, __m128h __C, __m128h __D) +{ + return (__m128h) + __builtin_ia32_vfcmaddcsh_mask_round ((__v8hf) __A, + (__v8hf) __C, + (__v8hf) __D, __B, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask3_fcmadd_sch (__m128h __A, __m128h __B, __m128h __C, __mmask8 __D) +{ + return (__m128h) + __builtin_ia32_vfcmaddcsh_mask3_round ((__v8hf) __A, + (__v8hf) __B, + (__v8hf) __C, __D, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fcmadd_sch (__mmask8 __A, __m128h __B, __m128h __C, __m128h __D) +{ + return (__m128h) + __builtin_ia32_vfcmaddcsh_maskz_round ((__v8hf) __B, + (__v8hf) __C, + (__v8hf) __D, + __A, _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_fcmadd_sch (__m128h __A, __m128h __B, __m128h __C) +{ + return (__m128h) + __builtin_ia32_vfcmaddcsh_round ((__v8hf) __A, + (__v8hf) __B, + (__v8hf) __C, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fmadd_sch (__m128h __A, __mmask8 __B, __m128h __C, __m128h __D) +{ + return (__m128h) + __builtin_ia32_vfmaddcsh_mask_round ((__v8hf) __A, + (__v8hf) __C, + (__v8hf) __D, __B, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask3_fmadd_sch (__m128h __A, __m128h __B, __m128h __C, __mmask8 __D) +{ + return (__m128h) + __builtin_ia32_vfmaddcsh_mask3_round ((__v8hf) __A, + (__v8hf) __B, + (__v8hf) __C, __D, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fmadd_sch (__mmask8 __A, __m128h __B, __m128h __C, __m128h __D) +{ + return (__m128h) + __builtin_ia32_vfmaddcsh_maskz_round ((__v8hf) __B, + (__v8hf) __C, + (__v8hf) __D, + __A, _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_fmadd_sch (__m128h __A, __m128h __B, __m128h __C) +{ + return (__m128h) + __builtin_ia32_vfmaddcsh_round ((__v8hf) __A, + (__v8hf) __B, + (__v8hf) __C, + _MM_FROUND_CUR_DIRECTION); +} +#ifdef __OPTIMIZE__ +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fcmadd_round_sch (__m128h __A, __mmask8 __B, __m128h __C, + __m128h __D, const int __E) +{ + return (__m128h) + __builtin_ia32_vfcmaddcsh_mask_round ((__v8hf) __A, + (__v8hf) __C, + (__v8hf) __D, + __B, __E); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask3_fcmadd_round_sch (__m128h __A, __m128h __B, __m128h __C, + __mmask8 __D, const int __E) +{ + return (__m128h) + __builtin_ia32_vfcmaddcsh_mask3_round ((__v8hf) __A, + (__v8hf) __B, + (__v8hf) __C, + __D, __E); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fcmadd_round_sch (__mmask8 __A, __m128h __B, __m128h __C, + __m128h __D, const int __E) +{ + return (__m128h) + __builtin_ia32_vfcmaddcsh_maskz_round ((__v8hf) __B, + (__v8hf) __C, + (__v8hf) __D, + __A, __E); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_fcmadd_round_sch (__m128h __A, __m128h __B, __m128h __C, const int __D) +{ + return (__m128h) + __builtin_ia32_vfcmaddcsh_round ((__v8hf) __A, + (__v8hf) __B, + (__v8hf) __C, + __D); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fmadd_round_sch (__m128h __A, __mmask8 __B, __m128h __C, + __m128h __D, const int __E) +{ + return (__m128h) + __builtin_ia32_vfmaddcsh_mask_round ((__v8hf) __A, + (__v8hf) __C, + (__v8hf) __D, + __B, __E); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask3_fmadd_round_sch (__m128h __A, __m128h __B, __m128h __C, + __mmask8 __D, const int __E) +{ + return (__m128h) + __builtin_ia32_vfmaddcsh_mask3_round ((__v8hf) __A, + (__v8hf) __B, + (__v8hf) __C, + __D, __E); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fmadd_round_sch (__mmask8 __A, __m128h __B, __m128h __C, + __m128h __D, const int __E) +{ + return (__m128h) + __builtin_ia32_vfmaddcsh_maskz_round ((__v8hf) __B, + (__v8hf) __C, + (__v8hf) __D, + __A, __E); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_fmadd_round_sch (__m128h __A, __m128h __B, __m128h __C, const int __D) +{ + return (__m128h) + __builtin_ia32_vfmaddcsh_round ((__v8hf) __A, + (__v8hf) __B, + (__v8hf) __C, + __D); +} +#else +#define _mm_mask_fcmadd_round_sch(A, B, C, D, E) ((__m128h) __builtin_ia32_vfcmaddcsh_mask_round ((__v8hf) (A), (__v8hf) (C), (__v8hf) (D), (B), (E))) +#define _mm_mask3_fcmadd_round_sch(A, B, C, D, E) ((__m128h) __builtin_ia32_vfcmaddcsh_mask3_round ((__v8hf) (A), (__v8hf) (B), (__v8hf) (C), (D), (E))) +#define _mm_maskz_fcmadd_round_sch(A, B, C, D, E) __builtin_ia32_vfcmaddcsh_maskz_round ((B), (C), (D), (A), (E)) +#define _mm_fcmadd_round_sch(A, B, C, D) __builtin_ia32_vfcmaddcsh_round ((A), (B), (C), (D)) +#define _mm_mask_fmadd_round_sch(A, B, C, D, E) ((__m128h) __builtin_ia32_vfmaddcsh_mask_round ((__v8hf) (A), (__v8hf) (C), (__v8hf) (D), (B), (E))) +#define _mm_mask3_fmadd_round_sch(A, B, C, D, E) ((__m128h) __builtin_ia32_vfmaddcsh_mask3_round ((__v8hf) (A), (__v8hf) (B), (__v8hf) (C), (D), (E))) +#define _mm_maskz_fmadd_round_sch(A, B, C, D, E) __builtin_ia32_vfmaddcsh_maskz_round ((B), (C), (D), (A), (E)) +#define _mm_fmadd_round_sch(A, B, C, D) __builtin_ia32_vfmaddcsh_round ((A), (B), (C), (D)) +#endif +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_fcmul_sch (__m128h __A, __m128h __B) +{ + return (__m128h) + __builtin_ia32_vfcmulcsh_round ((__v8hf) __A, + (__v8hf) __B, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fcmul_sch (__m128h __A, __mmask8 __B, __m128h __C, __m128h __D) +{ + return (__m128h) + __builtin_ia32_vfcmulcsh_mask_round ((__v8hf) __C, + (__v8hf) __D, + (__v8hf) __A, + __B, _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fcmul_sch (__mmask8 __A, __m128h __B, __m128h __C) +{ + return (__m128h) + __builtin_ia32_vfcmulcsh_mask_round ((__v8hf) __B, + (__v8hf) __C, + _mm_setzero_ph (), + __A, _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_fmul_sch (__m128h __A, __m128h __B) +{ + return (__m128h) + __builtin_ia32_vfmulcsh_round ((__v8hf) __A, + (__v8hf) __B, + _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fmul_sch (__m128h __A, __mmask8 __B, __m128h __C, __m128h __D) +{ + return (__m128h) + __builtin_ia32_vfmulcsh_mask_round ((__v8hf) __C, + (__v8hf) __D, + (__v8hf) __A, + __B, _MM_FROUND_CUR_DIRECTION); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fmul_sch (__mmask8 __A, __m128h __B, __m128h __C) +{ + return (__m128h) + __builtin_ia32_vfmulcsh_mask_round ((__v8hf) __B, + (__v8hf) __C, + _mm_setzero_ph (), + __A, _MM_FROUND_CUR_DIRECTION); +} +#ifdef __OPTIMIZE__ +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_fcmul_round_sch (__m128h __A, __m128h __B, const int __D) +{ + return (__m128h) + __builtin_ia32_vfcmulcsh_round ((__v8hf) __A, + (__v8hf) __B, + __D); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fcmul_round_sch (__m128h __A, __mmask8 __B, __m128h __C, + __m128h __D, const int __E) +{ + return (__m128h) + __builtin_ia32_vfcmulcsh_mask_round ((__v8hf) __C, + (__v8hf) __D, + (__v8hf) __A, + __B, __E); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fcmul_round_sch (__mmask8 __A, __m128h __B, __m128h __C, + const int __E) +{ + return (__m128h) + __builtin_ia32_vfcmulcsh_mask_round ((__v8hf) __B, + (__v8hf) __C, + _mm_setzero_ph (), + __A, __E); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_fmul_round_sch (__m128h __A, __m128h __B, const int __D) +{ + return (__m128h) + __builtin_ia32_vfmulcsh_round ((__v8hf) __A, + (__v8hf) __B, __D); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_fmul_round_sch (__m128h __A, __mmask8 __B, __m128h __C, + __m128h __D, const int __E) +{ + return (__m128h) + __builtin_ia32_vfmulcsh_mask_round ((__v8hf) __C, + (__v8hf) __D, + (__v8hf) __A, + __B, __E); +} +extern __inline __m128h +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_fmul_round_sch (__mmask8 __A, __m128h __B, __m128h __C, const int __E) +{ + return (__m128h) + __builtin_ia32_vfmulcsh_mask_round ((__v8hf) __B, + (__v8hf) __C, + _mm_setzero_ph (), + __A, __E); +} +#else +#define _mm_fcmul_round_sch(__A, __B, __D) (__m128h) __builtin_ia32_vfcmulcsh_round ((__v8hf) __A, (__v8hf) __B, __D) +#define _mm_mask_fcmul_round_sch(__A, __B, __C, __D, __E) (__m128h) __builtin_ia32_vfcmulcsh_mask_round ((__v8hf) __C, (__v8hf) __D, (__v8hf) __A, __B, __E) +#define _mm_maskz_fcmul_round_sch(__A, __B, __C, __E) (__m128h) __builtin_ia32_vfcmulcsh_mask_round ((__v8hf) __B, (__v8hf) __C, _mm_setzero_ph (), __A, __E) +#define _mm_fmul_round_sch(__A, __B, __D) (__m128h) __builtin_ia32_vfmulcsh_round ((__v8hf) __A, (__v8hf) __B, __D) +#define _mm_mask_fmul_round_sch(__A, __B, __C, __D, __E) (__m128h) __builtin_ia32_vfmulcsh_mask_round ((__v8hf) __C, (__v8hf) __D, (__v8hf) __A, __B, __E) +#define _mm_maskz_fmul_round_sch(__A, __B, __C, __E) (__m128h) __builtin_ia32_vfmulcsh_mask_round ((__v8hf) __B, (__v8hf) __C, _mm_setzero_ph (), __A, __E) +#endif +#define _mm_mul_sch(A, B) _mm_fmul_sch ((A), (B)) +#define _mm_mask_mul_sch(W, U, A, B) _mm_mask_fmul_sch ((W), (U), (A), (B)) +#define _mm_maskz_mul_sch(U, A, B) _mm_maskz_fmul_sch ((U), (A), (B)) +#define _mm_mul_round_sch(A, B, R) _mm_fmul_round_sch ((A), (B), (R)) +#define _mm_mask_mul_round_sch(W, U, A, B, R) _mm_mask_fmul_round_sch ((W), (U), (A), (B), (R)) +#define _mm_maskz_mul_round_sch(U, A, B, R) _mm_maskz_fmul_round_sch ((U), (A), (B), (R)) +#define _mm_cmul_sch(A, B) _mm_fcmul_sch ((A), (B)) +#define _mm_mask_cmul_sch(W, U, A, B) _mm_mask_fcmul_sch ((W), (U), (A), (B)) +#define _mm_maskz_cmul_sch(U, A, B) _mm_maskz_fcmul_sch ((U), (A), (B)) +#define _mm_cmul_round_sch(A, B, R) _mm_fcmul_round_sch ((A), (B), (R)) +#define _mm_mask_cmul_round_sch(W, U, A, B, R) _mm_mask_fcmul_round_sch ((W), (U), (A), (B), (R)) +#define _mm_maskz_cmul_round_sch(U, A, B, R) _mm_maskz_fcmul_round_sch ((U), (A), (B), (R)) +#ifdef __DISABLE_AVX512FP16__ +#undef __DISABLE_AVX512FP16__ +#pragma GCC pop_options +#endif +#if !defined (__AVX512FP16__) || !defined (__EVEX512__) +#pragma GCC push_options +#pragma GCC target("avx512fp16,evex512") +#define __DISABLE_AVX512FP16_512__ +#endif +typedef _Float16 __v32hf __attribute__ ((__vector_size__ (64))); +typedef _Float16 __m512h __attribute__ ((__vector_size__ (64), __may_alias__)); +typedef _Float16 __m512h_u __attribute__ ((__vector_size__ (64), __may_alias__, __aligned__ (1))); extern __inline __m512h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_set_ph (_Float16 __A31, _Float16 __A30, _Float16 __A29, @@ -64,27 +2214,6 @@ _mm512_set_ph (_Float16 __A31, _Float16 __A30, _Float16 __A29, __A24, __A25, __A26, __A27, __A28, __A29, __A30, __A31 }; } -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_setr_ph (_Float16 __A0, _Float16 __A1, _Float16 __A2, - _Float16 __A3, _Float16 __A4, _Float16 __A5, - _Float16 __A6, _Float16 __A7) -{ - return _mm_set_ph (__A7, __A6, __A5, __A4, __A3, __A2, __A1, __A0); -} -extern __inline __m256h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_setr_ph (_Float16 __A0, _Float16 __A1, _Float16 __A2, - _Float16 __A3, _Float16 __A4, _Float16 __A5, - _Float16 __A6, _Float16 __A7, _Float16 __A8, - _Float16 __A9, _Float16 __A10, _Float16 __A11, - _Float16 __A12, _Float16 __A13, _Float16 __A14, - _Float16 __A15) -{ - return _mm256_set_ph (__A15, __A14, __A13, __A12, __A11, __A10, __A9, - __A8, __A7, __A6, __A5, __A4, __A3, __A2, __A1, - __A0); -} extern __inline __m512h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_setr_ph (_Float16 __A0, _Float16 __A1, _Float16 __A2, @@ -105,19 +2234,6 @@ _mm512_setr_ph (_Float16 __A0, _Float16 __A1, _Float16 __A2, __A10, __A9, __A8, __A7, __A6, __A5, __A4, __A3, __A2, __A1, __A0); } -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_set1_ph (_Float16 __A) -{ - return _mm_set_ph (__A, __A, __A, __A, __A, __A, __A, __A); -} -extern __inline __m256h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_set1_ph (_Float16 __A) -{ - return _mm256_set_ph (__A, __A, __A, __A, __A, __A, __A, __A, - __A, __A, __A, __A, __A, __A, __A, __A); -} extern __inline __m512h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_set1_ph (_Float16 __A) @@ -127,59 +2243,24 @@ _mm512_set1_ph (_Float16 __A) __A, __A, __A, __A, __A, __A, __A, __A, __A, __A, __A, __A, __A, __A, __A, __A); } -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_setzero_ph (void) -{ - return _mm_set1_ph (0.0f); -} -extern __inline __m256h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_setzero_ph (void) -{ - return _mm256_set1_ph (0.0f); -} extern __inline __m512h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_setzero_ph (void) { - return _mm512_set1_ph (0.0f); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_undefined_ph (void) -{ - __m128h __Y = __Y; - return __Y; -} -extern __inline __m256h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_undefined_ph (void) -{ - __m256h __Y = __Y; - return __Y; + return _mm512_set1_ph (0.0f16); } extern __inline __m512h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_undefined_ph (void) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Winit-self" __m512h __Y = __Y; +#pragma GCC diagnostic pop return __Y; } extern __inline _Float16 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtsh_h (__m128h __A) -{ - return __A[0]; -} -extern __inline _Float16 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_cvtsh_h (__m256h __A) -{ - return __A[0]; -} -extern __inline _Float16 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_cvtsh_h (__m512h __A) { return __A[0]; @@ -208,10 +2289,10 @@ _mm512_castph512_ph128 (__m512h __A) { union { - __m128h a[4]; - __m512h v; - } u = { .v = __A }; - return u.a[0]; + __m128h __a[4]; + __m512h __v; + } __u = { .__v = __A }; + return __u.__a[0]; } extern __inline __m256h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) @@ -219,10 +2300,10 @@ _mm512_castph512_ph256 (__m512h __A) { union { - __m256h a[2]; - __m512h v; - } u = { .v = __A }; - return u.a[0]; + __m256h __a[2]; + __m512h __v; + } __u = { .__v = __A }; + return __u.__a[0]; } extern __inline __m512h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) @@ -230,11 +2311,11 @@ _mm512_castph128_ph512 (__m128h __A) { union { - __m128h a[4]; - __m512h v; - } u; - u.a[0] = __A; - return u.v; + __m128h __a[4]; + __m512h __v; + } __u; + __u.__a[0] = __A; + return __u.__v; } extern __inline __m512h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) @@ -242,11 +2323,11 @@ _mm512_castph256_ph512 (__m256h __A) { union { - __m256h a[2]; - __m512h v; - } u; - u.a[0] = __A; - return u.v; + __m256h __a[2]; + __m512h __v; + } __u; + __u.__a[0] = __A; + return __u.__v; } extern __inline __m512h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) @@ -280,61 +2361,18 @@ _mm512_castsi512_ph (__m512i __a) { return (__m512h) __a; } -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_set_sh (_Float16 __F) -{ - return _mm_set_ph (0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, __F); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_load_sh (void const *__P) -{ - return _mm_set_ph (0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, - *(_Float16 const *) __P); -} extern __inline __m512h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_load_ph (void const *__P) { return *(const __m512h *) __P; } -extern __inline __m256h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_load_ph (void const *__P) -{ - return *(const __m256h *) __P; -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_load_ph (void const *__P) -{ - return *(const __m128h *) __P; -} extern __inline __m512h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_loadu_ph (void const *__P) { return *(const __m512h_u *) __P; } -extern __inline __m256h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_loadu_ph (void const *__P) -{ - return *(const __m256h_u *) __P; -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_loadu_ph (void const *__P) -{ - return *(const __m128h_u *) __P; -} -extern __inline void -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_store_sh (void *__P, __m128h __A) -{ - *(_Float16 *) __P = ((__v8hf)__A)[0]; -} extern __inline void __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_store_ph (void *__P, __m512h __A) @@ -343,34 +2381,10 @@ _mm512_store_ph (void *__P, __m512h __A) } extern __inline void __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_store_ph (void *__P, __m256h __A) -{ - *(__m256h *) __P = __A; -} -extern __inline void -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_store_ph (void *__P, __m128h __A) -{ - *(__m128h *) __P = __A; -} -extern __inline void -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_storeu_ph (void *__P, __m512h __A) { *(__m512h_u *) __P = __A; } -extern __inline void -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_storeu_ph (void *__P, __m256h __A) -{ - *(__m256h_u *) __P = __A; -} -extern __inline void -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_storeu_ph (void *__P, __m128h __A) -{ - *(__m128h_u *) __P = __A; -} extern __inline __m512h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_abs_ph (__m512h __A) @@ -589,196 +2603,6 @@ _mm512_maskz_conj_pch (__mmask16 __U, __m512h __A) (__v16sf) _mm512_setzero_ps (), (__mmask16) __U); } -extern __inline __m128h - __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_add_sh (__m128h __A, __m128h __B) -{ - __A[0] += __B[0]; - return __A; -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_add_sh (__m128h __A, __mmask8 __B, __m128h __C, __m128h __D) -{ - return __builtin_ia32_addsh_mask (__C, __D, __A, __B); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_add_sh (__mmask8 __A, __m128h __B, __m128h __C) -{ - return __builtin_ia32_addsh_mask (__B, __C, _mm_setzero_ph (), - __A); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_sub_sh (__m128h __A, __m128h __B) -{ - __A[0] -= __B[0]; - return __A; -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_sub_sh (__m128h __A, __mmask8 __B, __m128h __C, __m128h __D) -{ - return __builtin_ia32_subsh_mask (__C, __D, __A, __B); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_sub_sh (__mmask8 __A, __m128h __B, __m128h __C) -{ - return __builtin_ia32_subsh_mask (__B, __C, _mm_setzero_ph (), - __A); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mul_sh (__m128h __A, __m128h __B) -{ - __A[0] *= __B[0]; - return __A; -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_mul_sh (__m128h __A, __mmask8 __B, __m128h __C, __m128h __D) -{ - return __builtin_ia32_mulsh_mask (__C, __D, __A, __B); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_mul_sh (__mmask8 __A, __m128h __B, __m128h __C) -{ - return __builtin_ia32_mulsh_mask (__B, __C, _mm_setzero_ph (), __A); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_div_sh (__m128h __A, __m128h __B) -{ - __A[0] /= __B[0]; - return __A; -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_div_sh (__m128h __A, __mmask8 __B, __m128h __C, __m128h __D) -{ - return __builtin_ia32_divsh_mask (__C, __D, __A, __B); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_div_sh (__mmask8 __A, __m128h __B, __m128h __C) -{ - return __builtin_ia32_divsh_mask (__B, __C, _mm_setzero_ph (), - __A); -} -#ifdef __OPTIMIZE__ -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_add_round_sh (__m128h __A, __m128h __B, const int __C) -{ - return __builtin_ia32_addsh_mask_round (__A, __B, - _mm_setzero_ph (), - (__mmask8) -1, __C); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_add_round_sh (__m128h __A, __mmask8 __B, __m128h __C, - __m128h __D, const int __E) -{ - return __builtin_ia32_addsh_mask_round (__C, __D, __A, __B, __E); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_add_round_sh (__mmask8 __A, __m128h __B, __m128h __C, - const int __D) -{ - return __builtin_ia32_addsh_mask_round (__B, __C, - _mm_setzero_ph (), - __A, __D); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_sub_round_sh (__m128h __A, __m128h __B, const int __C) -{ - return __builtin_ia32_subsh_mask_round (__A, __B, - _mm_setzero_ph (), - (__mmask8) -1, __C); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_sub_round_sh (__m128h __A, __mmask8 __B, __m128h __C, - __m128h __D, const int __E) -{ - return __builtin_ia32_subsh_mask_round (__C, __D, __A, __B, __E); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_sub_round_sh (__mmask8 __A, __m128h __B, __m128h __C, - const int __D) -{ - return __builtin_ia32_subsh_mask_round (__B, __C, - _mm_setzero_ph (), - __A, __D); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mul_round_sh (__m128h __A, __m128h __B, const int __C) -{ - return __builtin_ia32_mulsh_mask_round (__A, __B, - _mm_setzero_ph (), - (__mmask8) -1, __C); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_mul_round_sh (__m128h __A, __mmask8 __B, __m128h __C, - __m128h __D, const int __E) -{ - return __builtin_ia32_mulsh_mask_round (__C, __D, __A, __B, __E); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_mul_round_sh (__mmask8 __A, __m128h __B, __m128h __C, - const int __D) -{ - return __builtin_ia32_mulsh_mask_round (__B, __C, - _mm_setzero_ph (), - __A, __D); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_div_round_sh (__m128h __A, __m128h __B, const int __C) -{ - return __builtin_ia32_divsh_mask_round (__A, __B, - _mm_setzero_ph (), - (__mmask8) -1, __C); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_div_round_sh (__m128h __A, __mmask8 __B, __m128h __C, - __m128h __D, const int __E) -{ - return __builtin_ia32_divsh_mask_round (__C, __D, __A, __B, __E); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_div_round_sh (__mmask8 __A, __m128h __B, __m128h __C, - const int __D) -{ - return __builtin_ia32_divsh_mask_round (__B, __C, - _mm_setzero_ph (), - __A, __D); -} -#else -#define _mm_add_round_sh(A, B, C) ((__m128h)__builtin_ia32_addsh_mask_round ((A), (B), _mm_setzero_ph (), (__mmask8)-1, (C))) -#define _mm_mask_add_round_sh(A, B, C, D, E) ((__m128h)__builtin_ia32_addsh_mask_round ((C), (D), (A), (B), (E))) -#define _mm_maskz_add_round_sh(A, B, C, D) ((__m128h)__builtin_ia32_addsh_mask_round ((B), (C), _mm_setzero_ph (), (A), (D))) -#define _mm_sub_round_sh(A, B, C) ((__m128h)__builtin_ia32_subsh_mask_round ((A), (B), _mm_setzero_ph (), (__mmask8)-1, (C))) -#define _mm_mask_sub_round_sh(A, B, C, D, E) ((__m128h)__builtin_ia32_subsh_mask_round ((C), (D), (A), (B), (E))) -#define _mm_maskz_sub_round_sh(A, B, C, D) ((__m128h)__builtin_ia32_subsh_mask_round ((B), (C), _mm_setzero_ph (), (A), (D))) -#define _mm_mul_round_sh(A, B, C) ((__m128h)__builtin_ia32_mulsh_mask_round ((A), (B), _mm_setzero_ph (), (__mmask8)-1, (C))) -#define _mm_mask_mul_round_sh(A, B, C, D, E) ((__m128h)__builtin_ia32_mulsh_mask_round ((C), (D), (A), (B), (E))) -#define _mm_maskz_mul_round_sh(A, B, C, D) ((__m128h)__builtin_ia32_mulsh_mask_round ((B), (C), _mm_setzero_ph (), (A), (D))) -#define _mm_div_round_sh(A, B, C) ((__m128h)__builtin_ia32_divsh_mask_round ((A), (B), _mm_setzero_ph (), (__mmask8)-1, (C))) -#define _mm_mask_div_round_sh(A, B, C, D, E) ((__m128h)__builtin_ia32_divsh_mask_round ((C), (D), (A), (B), (E))) -#define _mm_maskz_div_round_sh(A, B, C, D) ((__m128h)__builtin_ia32_divsh_mask_round ((B), (C), _mm_setzero_ph (), (A), (D))) -#endif extern __inline __m512h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_max_ph (__m512h __A, __m512h __B) @@ -878,103 +2702,6 @@ _mm512_maskz_min_round_ph (__mmask32 __A, __m512h __B, __m512h __C, #define _mm512_mask_min_round_ph(A, B, C, D, E) (__builtin_ia32_minph512_mask_round ((C), (D), (A), (B), (E))) #define _mm512_maskz_min_round_ph(A, B, C, D) (__builtin_ia32_minph512_mask_round ((B), (C), _mm512_setzero_ph (), (A), (D))) #endif -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_max_sh (__m128h __A, __m128h __B) -{ - __A[0] = __A[0] > __B[0] ? __A[0] : __B[0]; - return __A; -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_max_sh (__m128h __A, __mmask8 __B, __m128h __C, __m128h __D) -{ - return __builtin_ia32_maxsh_mask (__C, __D, __A, __B); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_max_sh (__mmask8 __A, __m128h __B, __m128h __C) -{ - return __builtin_ia32_maxsh_mask (__B, __C, _mm_setzero_ph (), - __A); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_min_sh (__m128h __A, __m128h __B) -{ - __A[0] = __A[0] < __B[0] ? __A[0] : __B[0]; - return __A; -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_min_sh (__m128h __A, __mmask8 __B, __m128h __C, __m128h __D) -{ - return __builtin_ia32_minsh_mask (__C, __D, __A, __B); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_min_sh (__mmask8 __A, __m128h __B, __m128h __C) -{ - return __builtin_ia32_minsh_mask (__B, __C, _mm_setzero_ph (), - __A); -} -#ifdef __OPTIMIZE__ -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_max_round_sh (__m128h __A, __m128h __B, const int __C) -{ - return __builtin_ia32_maxsh_mask_round (__A, __B, - _mm_setzero_ph (), - (__mmask8) -1, __C); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_max_round_sh (__m128h __A, __mmask8 __B, __m128h __C, - __m128h __D, const int __E) -{ - return __builtin_ia32_maxsh_mask_round (__C, __D, __A, __B, __E); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_max_round_sh (__mmask8 __A, __m128h __B, __m128h __C, - const int __D) -{ - return __builtin_ia32_maxsh_mask_round (__B, __C, - _mm_setzero_ph (), - __A, __D); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_min_round_sh (__m128h __A, __m128h __B, const int __C) -{ - return __builtin_ia32_minsh_mask_round (__A, __B, - _mm_setzero_ph (), - (__mmask8) -1, __C); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_min_round_sh (__m128h __A, __mmask8 __B, __m128h __C, - __m128h __D, const int __E) -{ - return __builtin_ia32_minsh_mask_round (__C, __D, __A, __B, __E); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_min_round_sh (__mmask8 __A, __m128h __B, __m128h __C, - const int __D) -{ - return __builtin_ia32_minsh_mask_round (__B, __C, - _mm_setzero_ph (), - __A, __D); -} -#else -#define _mm_max_round_sh(A, B, C) (__builtin_ia32_maxsh_mask_round ((A), (B), _mm_setzero_ph (), (__mmask8)-1, (C))) -#define _mm_mask_max_round_sh(A, B, C, D, E) (__builtin_ia32_maxsh_mask_round ((C), (D), (A), (B), (E))) -#define _mm_maskz_max_round_sh(A, B, C, D) (__builtin_ia32_maxsh_mask_round ((B), (C), _mm_setzero_ph (), (A), (D))) -#define _mm_min_round_sh(A, B, C) (__builtin_ia32_minsh_mask_round ((A), (B), _mm_setzero_ph (), (__mmask8)-1, (C))) -#define _mm_mask_min_round_sh(A, B, C, D, E) (__builtin_ia32_minsh_mask_round ((C), (D), (A), (B), (E))) -#define _mm_maskz_min_round_sh(A, B, C, D) (__builtin_ia32_minsh_mask_round ((B), (C), _mm_setzero_ph (), (A), (D))) -#endif #ifdef __OPTIMIZE extern __inline __mmask32 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) @@ -1015,166 +2742,6 @@ _mm512_mask_cmp_round_ph_mask (__mmask32 __A, __m512h __B, __m512h __C, #define _mm512_cmp_round_ph_mask(A, B, C, D) (__builtin_ia32_cmpph512_mask_round ((A), (B), (C), (-1), (D))) #define _mm512_mask_cmp_round_ph_mask(A, B, C, D, E) (__builtin_ia32_cmpph512_mask_round ((B), (C), (D), (A), (E))) #endif -#ifdef __OPTIMIZE__ -extern __inline __mmask8 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cmp_sh_mask (__m128h __A, __m128h __B, const int __C) -{ - return (__mmask8) - __builtin_ia32_cmpsh_mask_round (__A, __B, - __C, (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __mmask8 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_cmp_sh_mask (__mmask8 __A, __m128h __B, __m128h __C, - const int __D) -{ - return (__mmask8) - __builtin_ia32_cmpsh_mask_round (__B, __C, - __D, __A, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __mmask8 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cmp_round_sh_mask (__m128h __A, __m128h __B, const int __C, - const int __D) -{ - return (__mmask8) __builtin_ia32_cmpsh_mask_round (__A, __B, - __C, (__mmask8) -1, - __D); -} -extern __inline __mmask8 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_cmp_round_sh_mask (__mmask8 __A, __m128h __B, __m128h __C, - const int __D, const int __E) -{ - return (__mmask8) __builtin_ia32_cmpsh_mask_round (__B, __C, - __D, __A, - __E); -} -#else -#define _mm_cmp_sh_mask(A, B, C) (__builtin_ia32_cmpsh_mask_round ((A), (B), (C), (-1), (_MM_FROUND_CUR_DIRECTION))) -#define _mm_mask_cmp_sh_mask(A, B, C, D) (__builtin_ia32_cmpsh_mask_round ((B), (C), (D), (A), (_MM_FROUND_CUR_DIRECTION))) -#define _mm_cmp_round_sh_mask(A, B, C, D) (__builtin_ia32_cmpsh_mask_round ((A), (B), (C), (-1), (D))) -#define _mm_mask_cmp_round_sh_mask(A, B, C, D, E) (__builtin_ia32_cmpsh_mask_round ((B), (C), (D), (A), (E))) -#endif -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_comieq_sh (__m128h __A, __m128h __B) -{ - return __builtin_ia32_cmpsh_mask_round (__A, __B, _CMP_EQ_OS, - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_comilt_sh (__m128h __A, __m128h __B) -{ - return __builtin_ia32_cmpsh_mask_round (__A, __B, _CMP_LT_OS, - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_comile_sh (__m128h __A, __m128h __B) -{ - return __builtin_ia32_cmpsh_mask_round (__A, __B, _CMP_LE_OS, - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_comigt_sh (__m128h __A, __m128h __B) -{ - return __builtin_ia32_cmpsh_mask_round (__A, __B, _CMP_GT_OS, - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_comige_sh (__m128h __A, __m128h __B) -{ - return __builtin_ia32_cmpsh_mask_round (__A, __B, _CMP_GE_OS, - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_comineq_sh (__m128h __A, __m128h __B) -{ - return __builtin_ia32_cmpsh_mask_round (__A, __B, _CMP_NEQ_US, - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_ucomieq_sh (__m128h __A, __m128h __B) -{ - return __builtin_ia32_cmpsh_mask_round (__A, __B, _CMP_EQ_OQ, - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_ucomilt_sh (__m128h __A, __m128h __B) -{ - return __builtin_ia32_cmpsh_mask_round (__A, __B, _CMP_LT_OQ, - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_ucomile_sh (__m128h __A, __m128h __B) -{ - return __builtin_ia32_cmpsh_mask_round (__A, __B, _CMP_LE_OQ, - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_ucomigt_sh (__m128h __A, __m128h __B) -{ - return __builtin_ia32_cmpsh_mask_round (__A, __B, _CMP_GT_OQ, - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_ucomige_sh (__m128h __A, __m128h __B) -{ - return __builtin_ia32_cmpsh_mask_round (__A, __B, _CMP_GE_OQ, - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_ucomineq_sh (__m128h __A, __m128h __B) -{ - return __builtin_ia32_cmpsh_mask_round (__A, __B, _CMP_NEQ_UQ, - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -#ifdef __OPTIMIZE__ -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_comi_sh (__m128h __A, __m128h __B, const int __P) -{ - return __builtin_ia32_cmpsh_mask_round (__A, __B, __P, - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_comi_round_sh (__m128h __A, __m128h __B, const int __P, const int __R) -{ - return __builtin_ia32_cmpsh_mask_round (__A, __B, __P, - (__mmask8) -1,__R); -} -#else -#define _mm_comi_round_sh(A, B, P, R) (__builtin_ia32_cmpsh_mask_round ((A), (B), (P), (__mmask8) (-1), (R))) -#define _mm_comi_sh(A, B, P) (__builtin_ia32_cmpsh_mask_round ((A), (B), (P), (__mmask8) (-1), _MM_FROUND_CUR_DIRECTION)) -#endif extern __inline __m512h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_sqrt_ph (__m512h __A) @@ -1249,81 +2816,6 @@ _mm512_maskz_rsqrt_ph (__mmask32 __A, __m512h __B) return __builtin_ia32_rsqrtph512_mask (__B, _mm512_setzero_ph (), __A); } -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_rsqrt_sh (__m128h __A, __m128h __B) -{ - return __builtin_ia32_rsqrtsh_mask (__B, __A, _mm_setzero_ph (), - (__mmask8) -1); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_rsqrt_sh (__m128h __A, __mmask8 __B, __m128h __C, __m128h __D) -{ - return __builtin_ia32_rsqrtsh_mask (__D, __C, __A, __B); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_rsqrt_sh (__mmask8 __A, __m128h __B, __m128h __C) -{ - return __builtin_ia32_rsqrtsh_mask (__C, __B, _mm_setzero_ph (), - __A); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_sqrt_sh (__m128h __A, __m128h __B) -{ - return __builtin_ia32_sqrtsh_mask_round (__B, __A, - _mm_setzero_ph (), - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_sqrt_sh (__m128h __A, __mmask8 __B, __m128h __C, __m128h __D) -{ - return __builtin_ia32_sqrtsh_mask_round (__D, __C, __A, __B, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_sqrt_sh (__mmask8 __A, __m128h __B, __m128h __C) -{ - return __builtin_ia32_sqrtsh_mask_round (__C, __B, - _mm_setzero_ph (), - __A, _MM_FROUND_CUR_DIRECTION); -} -#ifdef __OPTIMIZE__ -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_sqrt_round_sh (__m128h __A, __m128h __B, const int __C) -{ - return __builtin_ia32_sqrtsh_mask_round (__B, __A, - _mm_setzero_ph (), - (__mmask8) -1, __C); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_sqrt_round_sh (__m128h __A, __mmask8 __B, __m128h __C, - __m128h __D, const int __E) -{ - return __builtin_ia32_sqrtsh_mask_round (__D, __C, __A, __B, - __E); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_sqrt_round_sh (__mmask8 __A, __m128h __B, __m128h __C, - const int __D) -{ - return __builtin_ia32_sqrtsh_mask_round (__C, __B, - _mm_setzero_ph (), - __A, __D); -} -#else -#define _mm_sqrt_round_sh(A, B, C) (__builtin_ia32_sqrtsh_mask_round ((B), (A), _mm_setzero_ph (), (__mmask8)-1, (C))) -#define _mm_mask_sqrt_round_sh(A, B, C, D, E) (__builtin_ia32_sqrtsh_mask_round ((D), (C), (A), (B), (E))) -#define _mm_maskz_sqrt_round_sh(A, B, C, D) (__builtin_ia32_sqrtsh_mask_round ((C), (B), _mm_setzero_ph (), (A), (D))) -#endif extern __inline __m512h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_rcp_ph (__m512h __A) @@ -1344,26 +2836,6 @@ _mm512_maskz_rcp_ph (__mmask32 __A, __m512h __B) return __builtin_ia32_rcpph512_mask (__B, _mm512_setzero_ph (), __A); } -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_rcp_sh (__m128h __A, __m128h __B) -{ - return __builtin_ia32_rcpsh_mask (__B, __A, _mm_setzero_ph (), - (__mmask8) -1); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_rcp_sh (__m128h __A, __mmask32 __B, __m128h __C, __m128h __D) -{ - return __builtin_ia32_rcpsh_mask (__D, __C, __A, __B); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_rcp_sh (__mmask32 __A, __m128h __B, __m128h __C) -{ - return __builtin_ia32_rcpsh_mask (__C, __B, _mm_setzero_ph (), - __A); -} extern __inline __m512h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_scalef_ph (__m512h __A, __m512h __B) @@ -1420,62 +2892,6 @@ _mm512_maskz_scalef_round_ph (__mmask32 __A, __m512h __B, __m512h __C, #define _mm512_mask_scalef_round_ph(A, B, C, D, E) (__builtin_ia32_scalefph512_mask_round ((C), (D), (A), (B), (E))) #define _mm512_maskz_scalef_round_ph(A, B, C, D) (__builtin_ia32_scalefph512_mask_round ((B), (C), _mm512_setzero_ph (), (A), (D))) #endif -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_scalef_sh (__m128h __A, __m128h __B) -{ - return __builtin_ia32_scalefsh_mask_round (__A, __B, - _mm_setzero_ph (), - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_scalef_sh (__m128h __A, __mmask8 __B, __m128h __C, __m128h __D) -{ - return __builtin_ia32_scalefsh_mask_round (__C, __D, __A, __B, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_scalef_sh (__mmask8 __A, __m128h __B, __m128h __C) -{ - return __builtin_ia32_scalefsh_mask_round (__B, __C, - _mm_setzero_ph (), - __A, - _MM_FROUND_CUR_DIRECTION); -} -#ifdef __OPTIMIZE__ -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_scalef_round_sh (__m128h __A, __m128h __B, const int __C) -{ - return __builtin_ia32_scalefsh_mask_round (__A, __B, - _mm_setzero_ph (), - (__mmask8) -1, __C); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_scalef_round_sh (__m128h __A, __mmask8 __B, __m128h __C, - __m128h __D, const int __E) -{ - return __builtin_ia32_scalefsh_mask_round (__C, __D, __A, __B, - __E); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_scalef_round_sh (__mmask8 __A, __m128h __B, __m128h __C, - const int __D) -{ - return __builtin_ia32_scalefsh_mask_round (__B, __C, - _mm_setzero_ph (), - __A, __D); -} -#else -#define _mm_scalef_round_sh(A, B, C) (__builtin_ia32_scalefsh_mask_round ((A), (B), _mm_setzero_ph (), (__mmask8)-1, (C))) -#define _mm_mask_scalef_round_sh(A, B, C, D, E) (__builtin_ia32_scalefsh_mask_round ((C), (D), (A), (B), (E))) -#define _mm_maskz_scalef_round_sh(A, B, C, D) (__builtin_ia32_scalefsh_mask_round ((B), (C), _mm_setzero_ph (), (A), (D))) -#endif #ifdef __OPTIMIZE__ extern __inline __m512h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) @@ -1536,65 +2952,6 @@ _mm512_maskz_reduce_round_ph (__mmask32 __A, __m512h __B, int __C, #define _mm512_maskz_reduce_round_ph(A, B, C, D) (__builtin_ia32_reduceph512_mask_round ((B), (C), _mm512_setzero_ph (), (A), (D))) #endif #ifdef __OPTIMIZE__ -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_reduce_sh (__m128h __A, __m128h __B, int __C) -{ - return __builtin_ia32_reducesh_mask_round (__A, __B, __C, - _mm_setzero_ph (), - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_reduce_sh (__m128h __A, __mmask8 __B, __m128h __C, - __m128h __D, int __E) -{ - return __builtin_ia32_reducesh_mask_round (__C, __D, __E, __A, __B, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_reduce_sh (__mmask8 __A, __m128h __B, __m128h __C, int __D) -{ - return __builtin_ia32_reducesh_mask_round (__B, __C, __D, - _mm_setzero_ph (), __A, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_reduce_round_sh (__m128h __A, __m128h __B, int __C, const int __D) -{ - return __builtin_ia32_reducesh_mask_round (__A, __B, __C, - _mm_setzero_ph (), - (__mmask8) -1, __D); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_reduce_round_sh (__m128h __A, __mmask8 __B, __m128h __C, - __m128h __D, int __E, const int __F) -{ - return __builtin_ia32_reducesh_mask_round (__C, __D, __E, __A, - __B, __F); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_reduce_round_sh (__mmask8 __A, __m128h __B, __m128h __C, - int __D, const int __E) -{ - return __builtin_ia32_reducesh_mask_round (__B, __C, __D, - _mm_setzero_ph (), - __A, __E); -} -#else -#define _mm_reduce_sh(A, B, C) (__builtin_ia32_reducesh_mask_round ((A), (B), (C), _mm_setzero_ph (), (__mmask8)-1, _MM_FROUND_CUR_DIRECTION)) -#define _mm_mask_reduce_sh(A, B, C, D, E) (__builtin_ia32_reducesh_mask_round ((C), (D), (E), (A), (B), _MM_FROUND_CUR_DIRECTION)) -#define _mm_maskz_reduce_sh(A, B, C, D) (__builtin_ia32_reducesh_mask_round ((B), (C), (D), _mm_setzero_ph (), (A), _MM_FROUND_CUR_DIRECTION)) -#define _mm_reduce_round_sh(A, B, C, D) (__builtin_ia32_reducesh_mask_round ((A), (B), (C), _mm_setzero_ph (), (__mmask8)-1, (D))) -#define _mm_mask_reduce_round_sh(A, B, C, D, E, F) (__builtin_ia32_reducesh_mask_round ((C), (D), (E), (A), (B), (F))) -#define _mm_maskz_reduce_round_sh(A, B, C, D, E) (__builtin_ia32_reducesh_mask_round ((B), (C), (D), _mm_setzero_ph (), (A), (E))) -#endif -#ifdef __OPTIMIZE__ extern __inline __m512h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_roundscale_ph (__m512h __A, int __B) @@ -1656,84 +3013,6 @@ _mm512_maskz_roundscale_round_ph (__mmask32 __A, __m512h __B, int __C, #define _mm512_maskz_roundscale_round_ph(A, B, C, D) (__builtin_ia32_rndscaleph512_mask_round ((B), (C), _mm512_setzero_ph (), (A), (D))) #endif #ifdef __OPTIMIZE__ -extern __inline __m128h - __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_roundscale_sh (__m128h __A, __m128h __B, int __C) -{ - return __builtin_ia32_rndscalesh_mask_round (__A, __B, __C, - _mm_setzero_ph (), - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_roundscale_sh (__m128h __A, __mmask8 __B, __m128h __C, - __m128h __D, int __E) -{ - return __builtin_ia32_rndscalesh_mask_round (__C, __D, __E, __A, __B, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_roundscale_sh (__mmask8 __A, __m128h __B, __m128h __C, int __D) -{ - return __builtin_ia32_rndscalesh_mask_round (__B, __C, __D, - _mm_setzero_ph (), __A, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_roundscale_round_sh (__m128h __A, __m128h __B, int __C, const int __D) -{ - return __builtin_ia32_rndscalesh_mask_round (__A, __B, __C, - _mm_setzero_ph (), - (__mmask8) -1, - __D); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_roundscale_round_sh (__m128h __A, __mmask8 __B, __m128h __C, - __m128h __D, int __E, const int __F) -{ - return __builtin_ia32_rndscalesh_mask_round (__C, __D, __E, - __A, __B, __F); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_roundscale_round_sh (__mmask8 __A, __m128h __B, __m128h __C, - int __D, const int __E) -{ - return __builtin_ia32_rndscalesh_mask_round (__B, __C, __D, - _mm_setzero_ph (), - __A, __E); -} -#else -#define _mm_roundscale_sh(A, B, C) (__builtin_ia32_rndscalesh_mask_round ((A), (B), (C), _mm_setzero_ph (), (__mmask8)-1, _MM_FROUND_CUR_DIRECTION)) -#define _mm_mask_roundscale_sh(A, B, C, D, E) (__builtin_ia32_rndscalesh_mask_round ((C), (D), (E), (A), (B), _MM_FROUND_CUR_DIRECTION)) -#define _mm_maskz_roundscale_sh(A, B, C, D) (__builtin_ia32_rndscalesh_mask_round ((B), (C), (D), _mm_setzero_ph (), (A), _MM_FROUND_CUR_DIRECTION)) -#define _mm_roundscale_round_sh(A, B, C, D) (__builtin_ia32_rndscalesh_mask_round ((A), (B), (C), _mm_setzero_ph (), (__mmask8)-1, (D))) -#define _mm_mask_roundscale_round_sh(A, B, C, D, E, F) (__builtin_ia32_rndscalesh_mask_round ((C), (D), (E), (A), (B), (F))) -#define _mm_maskz_roundscale_round_sh(A, B, C, D, E) (__builtin_ia32_rndscalesh_mask_round ((B), (C), (D), _mm_setzero_ph (), (A), (E))) -#endif -#ifdef __OPTIMIZE__ -extern __inline __mmask8 - __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_fpclass_sh_mask (__m128h __A, const int __imm) -{ - return (__mmask8) __builtin_ia32_fpclasssh_mask ((__v8hf) __A, __imm, - (__mmask8) -1); -} -extern __inline __mmask8 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fpclass_sh_mask (__mmask8 __U, __m128h __A, const int __imm) -{ - return (__mmask8) __builtin_ia32_fpclasssh_mask ((__v8hf) __A, __imm, __U); -} -#else -#define _mm_fpclass_sh_mask(X, C) ((__mmask8) __builtin_ia32_fpclasssh_mask ((__v8hf) (__m128h) (X), (int) (C), (__mmask8) (-1))) -#define _mm_mask_fpclass_sh_mask(U, X, C) ((__mmask8) __builtin_ia32_fpclasssh_mask ((__v8hf) (__m128h) (X), (int) (C), (__mmask8) (U))) -#endif -#ifdef __OPTIMIZE__ extern __inline __mmask32 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_mask_fpclass_ph_mask (__mmask32 __U, __m512h __A, @@ -1754,35 +3033,6 @@ _mm512_fpclass_ph_mask (__m512h __A, const int __imm) #define _mm512_mask_fpclass_ph_mask(u, x, c) ((__mmask32) __builtin_ia32_fpclassph512_mask ((__v32hf) (__m512h) (x), (int) (c),(__mmask8)(u))) #define _mm512_fpclass_ph_mask(x, c) ((__mmask32) __builtin_ia32_fpclassph512_mask ((__v32hf) (__m512h) (x), (int) (c),(__mmask8)-1)) #endif -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_getexp_sh (__m128h __A, __m128h __B) -{ - return (__m128h) - __builtin_ia32_getexpsh_mask_round ((__v8hf) __A, (__v8hf) __B, - (__v8hf) _mm_setzero_ph (), - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_getexp_sh (__m128h __W, __mmask8 __U, __m128h __A, __m128h __B) -{ - return (__m128h) - __builtin_ia32_getexpsh_mask_round ((__v8hf) __A, (__v8hf) __B, - (__v8hf) __W, (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_getexp_sh (__mmask8 __U, __m128h __A, __m128h __B) -{ - return (__m128h) - __builtin_ia32_getexpsh_mask_round ((__v8hf) __A, (__v8hf) __B, - (__v8hf) _mm_setzero_ph (), - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} extern __inline __m512h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_getexp_ph (__m512h __A) @@ -1810,37 +3060,6 @@ _mm512_maskz_getexp_ph (__mmask32 __U, __m512h __A) (__mmask32) __U, _MM_FROUND_CUR_DIRECTION); } #ifdef __OPTIMIZE__ -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_getexp_round_sh (__m128h __A, __m128h __B, const int __R) -{ - return (__m128h) __builtin_ia32_getexpsh_mask_round ((__v8hf) __A, - (__v8hf) __B, - _mm_setzero_ph (), - (__mmask8) -1, - __R); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_getexp_round_sh (__m128h __W, __mmask8 __U, __m128h __A, - __m128h __B, const int __R) -{ - return (__m128h) __builtin_ia32_getexpsh_mask_round ((__v8hf) __A, - (__v8hf) __B, - (__v8hf) __W, - (__mmask8) __U, __R); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_getexp_round_sh (__mmask8 __U, __m128h __A, __m128h __B, - const int __R) -{ - return (__m128h) __builtin_ia32_getexpsh_mask_round ((__v8hf) __A, - (__v8hf) __B, - (__v8hf) - _mm_setzero_ph (), - (__mmask8) __U, __R); -} extern __inline __m512h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_getexp_round_ph (__m512h __A, const int __R) @@ -1869,49 +3088,11 @@ _mm512_maskz_getexp_round_ph (__mmask32 __U, __m512h __A, const int __R) (__mmask32) __U, __R); } #else -#define _mm_getexp_round_sh(A, B, R) ((__m128h)__builtin_ia32_getexpsh_mask_round((__v8hf)(__m128h)(A), (__v8hf)(__m128h)(B), (__v8hf)_mm_setzero_ph(), (__mmask8)-1, R)) -#define _mm_mask_getexp_round_sh(W, U, A, B, C) (__m128h)__builtin_ia32_getexpsh_mask_round(A, B, W, U, C) -#define _mm_maskz_getexp_round_sh(U, A, B, C) (__m128h)__builtin_ia32_getexpsh_mask_round(A, B, (__v8hf)_mm_setzero_ph(), U, C) #define _mm512_getexp_round_ph(A, R) ((__m512h)__builtin_ia32_getexpph512_mask((__v32hf)(__m512h)(A), (__v32hf)_mm512_setzero_ph(), (__mmask32)-1, R)) #define _mm512_mask_getexp_round_ph(W, U, A, R) ((__m512h)__builtin_ia32_getexpph512_mask((__v32hf)(__m512h)(A), (__v32hf)(__m512h)(W), (__mmask32)(U), R)) #define _mm512_maskz_getexp_round_ph(U, A, R) ((__m512h)__builtin_ia32_getexpph512_mask((__v32hf)(__m512h)(A), (__v32hf)_mm512_setzero_ph(), (__mmask32)(U), R)) #endif #ifdef __OPTIMIZE__ -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_getmant_sh (__m128h __A, __m128h __B, - _MM_MANTISSA_NORM_ENUM __C, - _MM_MANTISSA_SIGN_ENUM __D) -{ - return (__m128h) - __builtin_ia32_getmantsh_mask_round ((__v8hf) __A, (__v8hf) __B, - (__D << 2) | __C, _mm_setzero_ph (), - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_getmant_sh (__m128h __W, __mmask8 __U, __m128h __A, - __m128h __B, _MM_MANTISSA_NORM_ENUM __C, - _MM_MANTISSA_SIGN_ENUM __D) -{ - return (__m128h) - __builtin_ia32_getmantsh_mask_round ((__v8hf) __A, (__v8hf) __B, - (__D << 2) | __C, (__v8hf) __W, - __U, _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_getmant_sh (__mmask8 __U, __m128h __A, __m128h __B, - _MM_MANTISSA_NORM_ENUM __C, - _MM_MANTISSA_SIGN_ENUM __D) -{ - return (__m128h) - __builtin_ia32_getmantsh_mask_round ((__v8hf) __A, (__v8hf) __B, - (__D << 2) | __C, - (__v8hf) _mm_setzero_ph(), - __U, _MM_FROUND_CUR_DIRECTION); -} extern __inline __m512h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_getmant_ph (__m512h __A, _MM_MANTISSA_NORM_ENUM __B, @@ -1947,44 +3128,6 @@ _mm512_maskz_getmant_ph (__mmask32 __U, __m512h __A, __U, _MM_FROUND_CUR_DIRECTION); } -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_getmant_round_sh (__m128h __A, __m128h __B, - _MM_MANTISSA_NORM_ENUM __C, - _MM_MANTISSA_SIGN_ENUM __D, const int __R) -{ - return (__m128h) __builtin_ia32_getmantsh_mask_round ((__v8hf) __A, - (__v8hf) __B, - (__D << 2) | __C, - _mm_setzero_ph (), - (__mmask8) -1, - __R); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_getmant_round_sh (__m128h __W, __mmask8 __U, __m128h __A, - __m128h __B, _MM_MANTISSA_NORM_ENUM __C, - _MM_MANTISSA_SIGN_ENUM __D, const int __R) -{ - return (__m128h) __builtin_ia32_getmantsh_mask_round ((__v8hf) __A, - (__v8hf) __B, - (__D << 2) | __C, - (__v8hf) __W, - __U, __R); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_getmant_round_sh (__mmask8 __U, __m128h __A, __m128h __B, - _MM_MANTISSA_NORM_ENUM __C, - _MM_MANTISSA_SIGN_ENUM __D, const int __R) -{ - return (__m128h) __builtin_ia32_getmantsh_mask_round ((__v8hf) __A, - (__v8hf) __B, - (__D << 2) | __C, - (__v8hf) - _mm_setzero_ph(), - __U, __R); -} extern __inline __m512h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_getmant_round_ph (__m512h __A, _MM_MANTISSA_NORM_ENUM __B, @@ -2022,65 +3165,10 @@ _mm512_maskz_getmant_round_ph (__mmask32 __U, __m512h __A, #define _mm512_getmant_ph(X, B, C) ((__m512h)__builtin_ia32_getmantph512_mask ((__v32hf)(__m512h)(X), (int)(((C)<<2) | (B)), (__v32hf)(__m512h) _mm512_setzero_ph(), (__mmask32)-1, _MM_FROUND_CUR_DIRECTION)) #define _mm512_mask_getmant_ph(W, U, X, B, C) ((__m512h)__builtin_ia32_getmantph512_mask ((__v32hf)(__m512h)(X), (int)(((C)<<2) | (B)), (__v32hf)(__m512h)(W), (__mmask32)(U), _MM_FROUND_CUR_DIRECTION)) #define _mm512_maskz_getmant_ph(U, X, B, C) ((__m512h)__builtin_ia32_getmantph512_mask ((__v32hf)(__m512h)(X), (int)(((C)<<2) | (B)), (__v32hf)(__m512h) _mm512_setzero_ph(), (__mmask32)(U), _MM_FROUND_CUR_DIRECTION)) -#define _mm_getmant_sh(X, Y, C, D) ((__m128h)__builtin_ia32_getmantsh_mask_round ((__v8hf)(__m128h)(X), (__v8hf)(__m128h)(Y), (int)(((D)<<2) | (C)), (__v8hf)(__m128h) _mm_setzero_ph (), (__mmask8)-1, _MM_FROUND_CUR_DIRECTION)) -#define _mm_mask_getmant_sh(W, U, X, Y, C, D) ((__m128h)__builtin_ia32_getmantsh_mask_round ((__v8hf)(__m128h)(X), (__v8hf)(__m128h)(Y), (int)(((D)<<2) | (C)), (__v8hf)(__m128h)(W), (__mmask8)(U), _MM_FROUND_CUR_DIRECTION)) -#define _mm_maskz_getmant_sh(U, X, Y, C, D) ((__m128h)__builtin_ia32_getmantsh_mask_round ((__v8hf)(__m128h)(X), (__v8hf)(__m128h)(Y), (int)(((D)<<2) | (C)), (__v8hf)(__m128h) _mm_setzero_ph(), (__mmask8)(U), _MM_FROUND_CUR_DIRECTION)) #define _mm512_getmant_round_ph(X, B, C, R) ((__m512h)__builtin_ia32_getmantph512_mask ((__v32hf)(__m512h)(X), (int)(((C)<<2) | (B)), (__v32hf)(__m512h) _mm512_setzero_ph(), (__mmask32)-1, (R))) #define _mm512_mask_getmant_round_ph(W, U, X, B, C, R) ((__m512h)__builtin_ia32_getmantph512_mask ((__v32hf)(__m512h)(X), (int)(((C)<<2) | (B)), (__v32hf)(__m512h)(W), (__mmask32)(U), (R))) #define _mm512_maskz_getmant_round_ph(U, X, B, C, R) ((__m512h)__builtin_ia32_getmantph512_mask ((__v32hf)(__m512h)(X), (int)(((C)<<2) | (B)), (__v32hf)(__m512h) _mm512_setzero_ph(), (__mmask32)(U), (R))) -#define _mm_getmant_round_sh(X, Y, C, D, R) ((__m128h)__builtin_ia32_getmantsh_mask_round ((__v8hf)(__m128h)(X), (__v8hf)(__m128h)(Y), (int)(((D)<<2) | (C)), (__v8hf)(__m128h) _mm_setzero_ph (), (__mmask8)-1, (R))) -#define _mm_mask_getmant_round_sh(W, U, X, Y, C, D, R) ((__m128h)__builtin_ia32_getmantsh_mask_round ((__v8hf)(__m128h)(X), (__v8hf)(__m128h)(Y), (int)(((D)<<2) | (C)), (__v8hf)(__m128h)(W), (__mmask8)(U), (R))) -#define _mm_maskz_getmant_round_sh(U, X, Y, C, D, R) ((__m128h)__builtin_ia32_getmantsh_mask_round ((__v8hf)(__m128h)(X), (__v8hf)(__m128h)(Y), (int)(((D)<<2) | (C)), (__v8hf)(__m128h) _mm_setzero_ph(), (__mmask8)(U), (R))) #endif -extern __inline __m128i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtsi16_si128 (short __A) -{ - return _mm_set_epi16 (0, 0, 0, 0, 0, 0, 0, __A); -} -extern __inline short -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtsi128_si16 (__m128i __A) -{ - return __builtin_ia32_vec_ext_v8hi ((__v8hi)__A, 0); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_load_sh (__m128h __A, __mmask8 __B, _Float16 const* __C) -{ - return __builtin_ia32_loadsh_mask (__C, __A, __B); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_load_sh (__mmask8 __A, _Float16 const* __B) -{ - return __builtin_ia32_loadsh_mask (__B, _mm_setzero_ph (), __A); -} -extern __inline void -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_store_sh (_Float16 const* __A, __mmask8 __B, __m128h __C) -{ - __builtin_ia32_storesh_mask (__A, __C, __B); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_move_sh (__m128h __A, __m128h __B) -{ - __A[0] = __B[0]; - return __A; -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_move_sh (__m128h __A, __mmask8 __B, __m128h __C, __m128h __D) -{ - return __builtin_ia32_vmovsh_mask (__C, __D, __A, __B); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_move_sh (__mmask8 __A, __m128h __B, __m128h __C) -{ - return __builtin_ia32_vmovsh_mask (__B, __C, _mm_setzero_ph (), __A); -} extern __inline __m512i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_cvtph_epi32 (__m256h __A) @@ -3220,193 +4308,6 @@ _mm512_maskz_cvt_roundepu16_ph (__mmask32 __A, __m512i __B, int __C) #define _mm512_mask_cvt_roundepu16_ph(A, B, C, D) (__builtin_ia32_vcvtuw2ph512_mask_round ((__v32hi)(C), (A), (B), (D))) #define _mm512_maskz_cvt_roundepu16_ph(A, B, C) (__builtin_ia32_vcvtuw2ph512_mask_round ((__v32hi)(B), _mm512_setzero_ph (), (A), (C))) #endif -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtsh_i32 (__m128h __A) -{ - return (int) __builtin_ia32_vcvtsh2si32_round (__A, _MM_FROUND_CUR_DIRECTION); -} -extern __inline unsigned -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtsh_u32 (__m128h __A) -{ - return (int) __builtin_ia32_vcvtsh2usi32_round (__A, - _MM_FROUND_CUR_DIRECTION); -} -#ifdef __OPTIMIZE__ -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundsh_i32 (__m128h __A, const int __R) -{ - return (int) __builtin_ia32_vcvtsh2si32_round (__A, __R); -} -extern __inline unsigned -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundsh_u32 (__m128h __A, const int __R) -{ - return (int) __builtin_ia32_vcvtsh2usi32_round (__A, __R); -} -#else -#define _mm_cvt_roundsh_i32(A, B) ((int)__builtin_ia32_vcvtsh2si32_round ((A), (B))) -#define _mm_cvt_roundsh_u32(A, B) ((int)__builtin_ia32_vcvtsh2usi32_round ((A), (B))) -#endif -#ifdef __x86_64__ -extern __inline long long -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtsh_i64 (__m128h __A) -{ - return (long long) - __builtin_ia32_vcvtsh2si64_round (__A, _MM_FROUND_CUR_DIRECTION); -} -extern __inline unsigned long long -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtsh_u64 (__m128h __A) -{ - return (long long) - __builtin_ia32_vcvtsh2usi64_round (__A, _MM_FROUND_CUR_DIRECTION); -} -#ifdef __OPTIMIZE__ -extern __inline long long -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundsh_i64 (__m128h __A, const int __R) -{ - return (long long) __builtin_ia32_vcvtsh2si64_round (__A, __R); -} -extern __inline unsigned long long -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundsh_u64 (__m128h __A, const int __R) -{ - return (long long) __builtin_ia32_vcvtsh2usi64_round (__A, __R); -} -#else -#define _mm_cvt_roundsh_i64(A, B) ((long long)__builtin_ia32_vcvtsh2si64_round ((A), (B))) -#define _mm_cvt_roundsh_u64(A, B) ((long long)__builtin_ia32_vcvtsh2usi64_round ((A), (B))) -#endif -#endif -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvttsh_i32 (__m128h __A) -{ - return (int) - __builtin_ia32_vcvttsh2si32_round (__A, _MM_FROUND_CUR_DIRECTION); -} -extern __inline unsigned -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvttsh_u32 (__m128h __A) -{ - return (int) - __builtin_ia32_vcvttsh2usi32_round (__A, _MM_FROUND_CUR_DIRECTION); -} -#ifdef __OPTIMIZE__ -extern __inline int -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtt_roundsh_i32 (__m128h __A, const int __R) -{ - return (int) __builtin_ia32_vcvttsh2si32_round (__A, __R); -} -extern __inline unsigned -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtt_roundsh_u32 (__m128h __A, const int __R) -{ - return (int) __builtin_ia32_vcvttsh2usi32_round (__A, __R); -} -#else -#define _mm_cvtt_roundsh_i32(A, B) ((int)__builtin_ia32_vcvttsh2si32_round ((A), (B))) -#define _mm_cvtt_roundsh_u32(A, B) ((int)__builtin_ia32_vcvttsh2usi32_round ((A), (B))) -#endif -#ifdef __x86_64__ -extern __inline long long -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvttsh_i64 (__m128h __A) -{ - return (long long) - __builtin_ia32_vcvttsh2si64_round (__A, _MM_FROUND_CUR_DIRECTION); -} -extern __inline unsigned long long -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvttsh_u64 (__m128h __A) -{ - return (long long) - __builtin_ia32_vcvttsh2usi64_round (__A, _MM_FROUND_CUR_DIRECTION); -} -#ifdef __OPTIMIZE__ -extern __inline long long -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtt_roundsh_i64 (__m128h __A, const int __R) -{ - return (long long) __builtin_ia32_vcvttsh2si64_round (__A, __R); -} -extern __inline unsigned long long -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtt_roundsh_u64 (__m128h __A, const int __R) -{ - return (long long) __builtin_ia32_vcvttsh2usi64_round (__A, __R); -} -#else -#define _mm_cvtt_roundsh_i64(A, B) ((long long)__builtin_ia32_vcvttsh2si64_round ((A), (B))) -#define _mm_cvtt_roundsh_u64(A, B) ((long long)__builtin_ia32_vcvttsh2usi64_round ((A), (B))) -#endif -#endif -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvti32_sh (__m128h __A, int __B) -{ - return __builtin_ia32_vcvtsi2sh32_round (__A, __B, _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtu32_sh (__m128h __A, unsigned int __B) -{ - return __builtin_ia32_vcvtusi2sh32_round (__A, __B, _MM_FROUND_CUR_DIRECTION); -} -#ifdef __OPTIMIZE__ -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundi32_sh (__m128h __A, int __B, const int __R) -{ - return __builtin_ia32_vcvtsi2sh32_round (__A, __B, __R); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundu32_sh (__m128h __A, unsigned int __B, const int __R) -{ - return __builtin_ia32_vcvtusi2sh32_round (__A, __B, __R); -} -#else -#define _mm_cvt_roundi32_sh(A, B, C) (__builtin_ia32_vcvtsi2sh32_round ((A), (B), (C))) -#define _mm_cvt_roundu32_sh(A, B, C) (__builtin_ia32_vcvtusi2sh32_round ((A), (B), (C))) -#endif -#ifdef __x86_64__ -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvti64_sh (__m128h __A, long long __B) -{ - return __builtin_ia32_vcvtsi2sh64_round (__A, __B, _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtu64_sh (__m128h __A, unsigned long long __B) -{ - return __builtin_ia32_vcvtusi2sh64_round (__A, __B, _MM_FROUND_CUR_DIRECTION); -} -#ifdef __OPTIMIZE__ -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundi64_sh (__m128h __A, long long __B, const int __R) -{ - return __builtin_ia32_vcvtsi2sh64_round (__A, __B, __R); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundu64_sh (__m128h __A, unsigned long long __B, const int __R) -{ - return __builtin_ia32_vcvtusi2sh64_round (__A, __B, __R); -} -#else -#define _mm_cvt_roundi64_sh(A, B, C) (__builtin_ia32_vcvtsi2sh64_round ((A), (B), (C))) -#define _mm_cvt_roundu64_sh(A, B, C) (__builtin_ia32_vcvtusi2sh64_round ((A), (B), (C))) -#endif -#endif extern __inline __m512d __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_cvtph_pd (__m128h __A) @@ -3629,218 +4530,6 @@ _mm512_maskz_cvt_roundpd_ph (__mmask8 __A, __m512d __B, int __C) #define _mm512_mask_cvt_roundpd_ph(A, B, C, D) (__builtin_ia32_vcvtpd2ph512_mask_round ((__v8df)(C), (A), (B), (D))) #define _mm512_maskz_cvt_roundpd_ph(A, B, C) (__builtin_ia32_vcvtpd2ph512_mask_round ((__v8df)(B), _mm_setzero_ph (), (A), (C))) #endif -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtsh_ss (__m128 __A, __m128h __B) -{ - return __builtin_ia32_vcvtsh2ss_mask_round (__B, __A, - _mm_setzero_ps (), - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_cvtsh_ss (__m128 __A, __mmask8 __B, __m128 __C, - __m128h __D) -{ - return __builtin_ia32_vcvtsh2ss_mask_round (__D, __C, __A, __B, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_cvtsh_ss (__mmask8 __A, __m128 __B, - __m128h __C) -{ - return __builtin_ia32_vcvtsh2ss_mask_round (__C, __B, - _mm_setzero_ps (), - __A, _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtsh_sd (__m128d __A, __m128h __B) -{ - return __builtin_ia32_vcvtsh2sd_mask_round (__B, __A, - _mm_setzero_pd (), - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_cvtsh_sd (__m128d __A, __mmask8 __B, __m128d __C, - __m128h __D) -{ - return __builtin_ia32_vcvtsh2sd_mask_round (__D, __C, __A, __B, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_cvtsh_sd (__mmask8 __A, __m128d __B, __m128h __C) -{ - return __builtin_ia32_vcvtsh2sd_mask_round (__C, __B, - _mm_setzero_pd (), - __A, _MM_FROUND_CUR_DIRECTION); -} -#ifdef __OPTIMIZE__ -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundsh_ss (__m128 __A, __m128h __B, const int __R) -{ - return __builtin_ia32_vcvtsh2ss_mask_round (__B, __A, - _mm_setzero_ps (), - (__mmask8) -1, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_cvt_roundsh_ss (__m128 __A, __mmask8 __B, __m128 __C, - __m128h __D, const int __R) -{ - return __builtin_ia32_vcvtsh2ss_mask_round (__D, __C, __A, __B, __R); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_cvt_roundsh_ss (__mmask8 __A, __m128 __B, - __m128h __C, const int __R) -{ - return __builtin_ia32_vcvtsh2ss_mask_round (__C, __B, - _mm_setzero_ps (), - __A, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundsh_sd (__m128d __A, __m128h __B, const int __R) -{ - return __builtin_ia32_vcvtsh2sd_mask_round (__B, __A, - _mm_setzero_pd (), - (__mmask8) -1, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_cvt_roundsh_sd (__m128d __A, __mmask8 __B, __m128d __C, - __m128h __D, const int __R) -{ - return __builtin_ia32_vcvtsh2sd_mask_round (__D, __C, __A, __B, __R); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_cvt_roundsh_sd (__mmask8 __A, __m128d __B, __m128h __C, const int __R) -{ - return __builtin_ia32_vcvtsh2sd_mask_round (__C, __B, - _mm_setzero_pd (), - __A, __R); -} -#else -#define _mm_cvt_roundsh_ss(A, B, R) (__builtin_ia32_vcvtsh2ss_mask_round ((B), (A), _mm_setzero_ps (), (__mmask8) -1, (R))) -#define _mm_mask_cvt_roundsh_ss(A, B, C, D, R) (__builtin_ia32_vcvtsh2ss_mask_round ((D), (C), (A), (B), (R))) -#define _mm_maskz_cvt_roundsh_ss(A, B, C, R) (__builtin_ia32_vcvtsh2ss_mask_round ((C), (B), _mm_setzero_ps (), (A), (R))) -#define _mm_cvt_roundsh_sd(A, B, R) (__builtin_ia32_vcvtsh2sd_mask_round ((B), (A), _mm_setzero_pd (), (__mmask8) -1, (R))) -#define _mm_mask_cvt_roundsh_sd(A, B, C, D, R) (__builtin_ia32_vcvtsh2sd_mask_round ((D), (C), (A), (B), (R))) -#define _mm_maskz_cvt_roundsh_sd(A, B, C, R) (__builtin_ia32_vcvtsh2sd_mask_round ((C), (B), _mm_setzero_pd (), (A), (R))) -#endif -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtss_sh (__m128h __A, __m128 __B) -{ - return __builtin_ia32_vcvtss2sh_mask_round (__B, __A, - _mm_setzero_ph (), - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_cvtss_sh (__m128h __A, __mmask8 __B, __m128h __C, __m128 __D) -{ - return __builtin_ia32_vcvtss2sh_mask_round (__D, __C, __A, __B, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_cvtss_sh (__mmask8 __A, __m128h __B, __m128 __C) -{ - return __builtin_ia32_vcvtss2sh_mask_round (__C, __B, - _mm_setzero_ph (), - __A, _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvtsd_sh (__m128h __A, __m128d __B) -{ - return __builtin_ia32_vcvtsd2sh_mask_round (__B, __A, - _mm_setzero_ph (), - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_cvtsd_sh (__m128h __A, __mmask8 __B, __m128h __C, __m128d __D) -{ - return __builtin_ia32_vcvtsd2sh_mask_round (__D, __C, __A, __B, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_cvtsd_sh (__mmask8 __A, __m128h __B, __m128d __C) -{ - return __builtin_ia32_vcvtsd2sh_mask_round (__C, __B, - _mm_setzero_ph (), - __A, _MM_FROUND_CUR_DIRECTION); -} -#ifdef __OPTIMIZE__ -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundss_sh (__m128h __A, __m128 __B, const int __R) -{ - return __builtin_ia32_vcvtss2sh_mask_round (__B, __A, - _mm_setzero_ph (), - (__mmask8) -1, __R); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_cvt_roundss_sh (__m128h __A, __mmask8 __B, __m128h __C, __m128 __D, - const int __R) -{ - return __builtin_ia32_vcvtss2sh_mask_round (__D, __C, __A, __B, __R); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_cvt_roundss_sh (__mmask8 __A, __m128h __B, __m128 __C, - const int __R) -{ - return __builtin_ia32_vcvtss2sh_mask_round (__C, __B, - _mm_setzero_ph (), - __A, __R); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cvt_roundsd_sh (__m128h __A, __m128d __B, const int __R) -{ - return __builtin_ia32_vcvtsd2sh_mask_round (__B, __A, - _mm_setzero_ph (), - (__mmask8) -1, __R); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_cvt_roundsd_sh (__m128h __A, __mmask8 __B, __m128h __C, __m128d __D, - const int __R) -{ - return __builtin_ia32_vcvtsd2sh_mask_round (__D, __C, __A, __B, __R); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_cvt_roundsd_sh (__mmask8 __A, __m128h __B, __m128d __C, - const int __R) -{ - return __builtin_ia32_vcvtsd2sh_mask_round (__C, __B, - _mm_setzero_ph (), - __A, __R); -} -#else -#define _mm_cvt_roundss_sh(A, B, R) (__builtin_ia32_vcvtss2sh_mask_round ((B), (A), _mm_setzero_ph (), (__mmask8) -1, R)) -#define _mm_mask_cvt_roundss_sh(A, B, C, D, R) (__builtin_ia32_vcvtss2sh_mask_round ((D), (C), (A), (B), (R))) -#define _mm_maskz_cvt_roundss_sh(A, B, C, R) (__builtin_ia32_vcvtss2sh_mask_round ((C), (B), _mm_setzero_ph (), A, R)) -#define _mm_cvt_roundsd_sh(A, B, R) (__builtin_ia32_vcvtsd2sh_mask_round ((B), (A), _mm_setzero_ph (), (__mmask8) -1, R)) -#define _mm_mask_cvt_roundsd_sh(A, B, C, D, R) (__builtin_ia32_vcvtsd2sh_mask_round ((D), (C), (A), (B), (R))) -#define _mm_maskz_cvt_roundsd_sh(A, B, C, R) (__builtin_ia32_vcvtsd2sh_mask_round ((C), (B), _mm_setzero_ph (), (A), (R))) -#endif extern __inline __m512h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_fmaddsub_ph (__m512h __A, __m512h __B, __m512h __C) @@ -4393,354 +5082,6 @@ _mm512_maskz_fnmsub_round_ph (__mmask32 __U, __m512h __A, __m512h __B, #define _mm512_mask3_fnmsub_round_ph(A, B, C, U, R) ((__m512h)__builtin_ia32_vfnmsubph512_mask3 ((A), (B), (C), (U), (R))) #define _mm512_maskz_fnmsub_round_ph(U, A, B, C, R) ((__m512h)__builtin_ia32_vfnmsubph512_maskz ((A), (B), (C), (U), (R))) #endif -extern __inline __m128h - __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_fmadd_sh (__m128h __W, __m128h __A, __m128h __B) -{ - return (__m128h) __builtin_ia32_vfmaddsh3_mask ((__v8hf) __W, - (__v8hf) __A, - (__v8hf) __B, - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fmadd_sh (__m128h __W, __mmask8 __U, __m128h __A, __m128h __B) -{ - return (__m128h) __builtin_ia32_vfmaddsh3_mask ((__v8hf) __W, - (__v8hf) __A, - (__v8hf) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask3_fmadd_sh (__m128h __W, __m128h __A, __m128h __B, __mmask8 __U) -{ - return (__m128h) __builtin_ia32_vfmaddsh3_mask3 ((__v8hf) __W, - (__v8hf) __A, - (__v8hf) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fmadd_sh (__mmask8 __U, __m128h __W, __m128h __A, __m128h __B) -{ - return (__m128h) __builtin_ia32_vfmaddsh3_maskz ((__v8hf) __W, - (__v8hf) __A, - (__v8hf) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -#ifdef __OPTIMIZE__ -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_fmadd_round_sh (__m128h __W, __m128h __A, __m128h __B, const int __R) -{ - return (__m128h) __builtin_ia32_vfmaddsh3_mask ((__v8hf) __W, - (__v8hf) __A, - (__v8hf) __B, - (__mmask8) -1, - __R); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fmadd_round_sh (__m128h __W, __mmask8 __U, __m128h __A, __m128h __B, - const int __R) -{ - return (__m128h) __builtin_ia32_vfmaddsh3_mask ((__v8hf) __W, - (__v8hf) __A, - (__v8hf) __B, - (__mmask8) __U, __R); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask3_fmadd_round_sh (__m128h __W, __m128h __A, __m128h __B, __mmask8 __U, - const int __R) -{ - return (__m128h) __builtin_ia32_vfmaddsh3_mask3 ((__v8hf) __W, - (__v8hf) __A, - (__v8hf) __B, - (__mmask8) __U, __R); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fmadd_round_sh (__mmask8 __U, __m128h __W, __m128h __A, - __m128h __B, const int __R) -{ - return (__m128h) __builtin_ia32_vfmaddsh3_maskz ((__v8hf) __W, - (__v8hf) __A, - (__v8hf) __B, - (__mmask8) __U, __R); -} -#else -#define _mm_fmadd_round_sh(A, B, C, R) ((__m128h) __builtin_ia32_vfmaddsh3_mask ((A), (B), (C), (-1), (R))) -#define _mm_mask_fmadd_round_sh(A, U, B, C, R) ((__m128h) __builtin_ia32_vfmaddsh3_mask ((A), (B), (C), (U), (R))) -#define _mm_mask3_fmadd_round_sh(A, B, C, U, R) ((__m128h) __builtin_ia32_vfmaddsh3_mask3 ((A), (B), (C), (U), (R))) -#define _mm_maskz_fmadd_round_sh(U, A, B, C, R) ((__m128h) __builtin_ia32_vfmaddsh3_maskz ((A), (B), (C), (U), (R))) -#endif -extern __inline __m128h - __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_fnmadd_sh (__m128h __W, __m128h __A, __m128h __B) -{ - return (__m128h) __builtin_ia32_vfnmaddsh3_mask ((__v8hf) __W, - (__v8hf) __A, - (__v8hf) __B, - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fnmadd_sh (__m128h __W, __mmask8 __U, __m128h __A, __m128h __B) -{ - return (__m128h) __builtin_ia32_vfnmaddsh3_mask ((__v8hf) __W, - (__v8hf) __A, - (__v8hf) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask3_fnmadd_sh (__m128h __W, __m128h __A, __m128h __B, __mmask8 __U) -{ - return (__m128h) __builtin_ia32_vfnmaddsh3_mask3 ((__v8hf) __W, - (__v8hf) __A, - (__v8hf) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fnmadd_sh (__mmask8 __U, __m128h __W, __m128h __A, __m128h __B) -{ - return (__m128h) __builtin_ia32_vfnmaddsh3_maskz ((__v8hf) __W, - (__v8hf) __A, - (__v8hf) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -#ifdef __OPTIMIZE__ -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_fnmadd_round_sh (__m128h __W, __m128h __A, __m128h __B, const int __R) -{ - return (__m128h) __builtin_ia32_vfnmaddsh3_mask ((__v8hf) __W, - (__v8hf) __A, - (__v8hf) __B, - (__mmask8) -1, - __R); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fnmadd_round_sh (__m128h __W, __mmask8 __U, __m128h __A, __m128h __B, - const int __R) -{ - return (__m128h) __builtin_ia32_vfnmaddsh3_mask ((__v8hf) __W, - (__v8hf) __A, - (__v8hf) __B, - (__mmask8) __U, __R); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask3_fnmadd_round_sh (__m128h __W, __m128h __A, __m128h __B, __mmask8 __U, - const int __R) -{ - return (__m128h) __builtin_ia32_vfnmaddsh3_mask3 ((__v8hf) __W, - (__v8hf) __A, - (__v8hf) __B, - (__mmask8) __U, __R); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fnmadd_round_sh (__mmask8 __U, __m128h __W, __m128h __A, - __m128h __B, const int __R) -{ - return (__m128h) __builtin_ia32_vfnmaddsh3_maskz ((__v8hf) __W, - (__v8hf) __A, - (__v8hf) __B, - (__mmask8) __U, __R); -} -#else -#define _mm_fnmadd_round_sh(A, B, C, R) ((__m128h) __builtin_ia32_vfnmaddsh3_mask ((A), (B), (C), (-1), (R))) -#define _mm_mask_fnmadd_round_sh(A, U, B, C, R) ((__m128h) __builtin_ia32_vfnmaddsh3_mask ((A), (B), (C), (U), (R))) -#define _mm_mask3_fnmadd_round_sh(A, B, C, U, R) ((__m128h) __builtin_ia32_vfnmaddsh3_mask3 ((A), (B), (C), (U), (R))) -#define _mm_maskz_fnmadd_round_sh(U, A, B, C, R) ((__m128h) __builtin_ia32_vfnmaddsh3_maskz ((A), (B), (C), (U), (R))) -#endif -extern __inline __m128h - __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_fmsub_sh (__m128h __W, __m128h __A, __m128h __B) -{ - return (__m128h) __builtin_ia32_vfmaddsh3_mask ((__v8hf) __W, - (__v8hf) __A, - -(__v8hf) __B, - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fmsub_sh (__m128h __W, __mmask8 __U, __m128h __A, __m128h __B) -{ - return (__m128h) __builtin_ia32_vfmaddsh3_mask ((__v8hf) __W, - (__v8hf) __A, - -(__v8hf) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask3_fmsub_sh (__m128h __W, __m128h __A, __m128h __B, __mmask8 __U) -{ - return (__m128h) __builtin_ia32_vfmsubsh3_mask3 ((__v8hf) __W, - (__v8hf) __A, - (__v8hf) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fmsub_sh (__mmask8 __U, __m128h __W, __m128h __A, __m128h __B) -{ - return (__m128h) __builtin_ia32_vfmaddsh3_maskz ((__v8hf) __W, - (__v8hf) __A, - -(__v8hf) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -#ifdef __OPTIMIZE__ -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_fmsub_round_sh (__m128h __W, __m128h __A, __m128h __B, const int __R) -{ - return (__m128h) __builtin_ia32_vfmaddsh3_mask ((__v8hf) __W, - (__v8hf) __A, - -(__v8hf) __B, - (__mmask8) -1, - __R); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fmsub_round_sh (__m128h __W, __mmask8 __U, __m128h __A, __m128h __B, - const int __R) -{ - return (__m128h) __builtin_ia32_vfmaddsh3_mask ((__v8hf) __W, - (__v8hf) __A, - -(__v8hf) __B, - (__mmask8) __U, __R); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask3_fmsub_round_sh (__m128h __W, __m128h __A, __m128h __B, __mmask8 __U, - const int __R) -{ - return (__m128h) __builtin_ia32_vfmsubsh3_mask3 ((__v8hf) __W, - (__v8hf) __A, - (__v8hf) __B, - (__mmask8) __U, __R); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fmsub_round_sh (__mmask8 __U, __m128h __W, __m128h __A, - __m128h __B, const int __R) -{ - return (__m128h) __builtin_ia32_vfmaddsh3_maskz ((__v8hf) __W, - (__v8hf) __A, - -(__v8hf) __B, - (__mmask8) __U, __R); -} -#else -#define _mm_fmsub_round_sh(A, B, C, R) ((__m128h) __builtin_ia32_vfmaddsh3_mask ((A), (B), -(C), (-1), (R))) -#define _mm_mask_fmsub_round_sh(A, U, B, C, R) ((__m128h) __builtin_ia32_vfmaddsh3_mask ((A), (B), -(C), (U), (R))) -#define _mm_mask3_fmsub_round_sh(A, B, C, U, R) ((__m128h) __builtin_ia32_vfmsubsh3_mask3 ((A), (B), (C), (U), (R))) -#define _mm_maskz_fmsub_round_sh(U, A, B, C, R) ((__m128h) __builtin_ia32_vfmaddsh3_maskz ((A), (B), -(C), (U), (R))) -#endif -extern __inline __m128h - __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_fnmsub_sh (__m128h __W, __m128h __A, __m128h __B) -{ - return (__m128h) __builtin_ia32_vfmaddsh3_mask ((__v8hf) __W, - -(__v8hf) __A, - -(__v8hf) __B, - (__mmask8) -1, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fnmsub_sh (__m128h __W, __mmask8 __U, __m128h __A, __m128h __B) -{ - return (__m128h) __builtin_ia32_vfmaddsh3_mask ((__v8hf) __W, - -(__v8hf) __A, - -(__v8hf) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask3_fnmsub_sh (__m128h __W, __m128h __A, __m128h __B, __mmask8 __U) -{ - return (__m128h) __builtin_ia32_vfmsubsh3_mask3 ((__v8hf) __W, - -(__v8hf) __A, - (__v8hf) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fnmsub_sh (__mmask8 __U, __m128h __W, __m128h __A, __m128h __B) -{ - return (__m128h) __builtin_ia32_vfmaddsh3_maskz ((__v8hf) __W, - -(__v8hf) __A, - -(__v8hf) __B, - (__mmask8) __U, - _MM_FROUND_CUR_DIRECTION); -} -#ifdef __OPTIMIZE__ -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_fnmsub_round_sh (__m128h __W, __m128h __A, __m128h __B, const int __R) -{ - return (__m128h) __builtin_ia32_vfmaddsh3_mask ((__v8hf) __W, - -(__v8hf) __A, - -(__v8hf) __B, - (__mmask8) -1, - __R); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fnmsub_round_sh (__m128h __W, __mmask8 __U, __m128h __A, __m128h __B, - const int __R) -{ - return (__m128h) __builtin_ia32_vfmaddsh3_mask ((__v8hf) __W, - -(__v8hf) __A, - -(__v8hf) __B, - (__mmask8) __U, __R); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask3_fnmsub_round_sh (__m128h __W, __m128h __A, __m128h __B, __mmask8 __U, - const int __R) -{ - return (__m128h) __builtin_ia32_vfmsubsh3_mask3 ((__v8hf) __W, - -(__v8hf) __A, - (__v8hf) __B, - (__mmask8) __U, __R); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fnmsub_round_sh (__mmask8 __U, __m128h __W, __m128h __A, - __m128h __B, const int __R) -{ - return (__m128h) __builtin_ia32_vfmaddsh3_maskz ((__v8hf) __W, - -(__v8hf) __A, - -(__v8hf) __B, - (__mmask8) __U, __R); -} -#else -#define _mm_fnmsub_round_sh(A, B, C, R) ((__m128h) __builtin_ia32_vfmaddsh3_mask ((A), -(B), -(C), (-1), (R))) -#define _mm_mask_fnmsub_round_sh(A, U, B, C, R) ((__m128h) __builtin_ia32_vfmaddsh3_mask ((A), -(B), -(C), (U), (R))) -#define _mm_mask3_fnmsub_round_sh(A, B, C, U, R) ((__m128h) __builtin_ia32_vfmsubsh3_mask3 ((A), -(B), (C), (U), (R))) -#define _mm_maskz_fnmsub_round_sh(U, A, B, C, R) ((__m128h) __builtin_ia32_vfmaddsh3_maskz ((A), -(B), -(C), (U), (R))) -#endif extern __inline __m512h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm512_fcmadd_pch (__m512h __A, __m512h __B, __m512h __C) @@ -5046,310 +5387,6 @@ _mm512_maskz_fmul_round_pch (__mmask16 __A, __m512h __B, #define _mm512_mask_fmul_round_pch(A, B, C, D, E) (__m512h) __builtin_ia32_vfmulcph512_mask_round ((C), (D), (A), (B), (E)) #define _mm512_maskz_fmul_round_pch(A, B, C, E) (__m512h) __builtin_ia32_vfmulcph512_mask_round ((B), (C), (__v32hf) _mm512_setzero_ph (), (A), (E)) #endif -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fcmadd_sch (__m128h __A, __mmask8 __B, __m128h __C, __m128h __D) -{ - return (__m128h) - __builtin_ia32_vfcmaddcsh_mask_round ((__v8hf) __A, - (__v8hf) __C, - (__v8hf) __D, __B, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask3_fcmadd_sch (__m128h __A, __m128h __B, __m128h __C, __mmask8 __D) -{ - return (__m128h) - __builtin_ia32_vfcmaddcsh_mask3_round ((__v8hf) __A, - (__v8hf) __B, - (__v8hf) __C, __D, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fcmadd_sch (__mmask8 __A, __m128h __B, __m128h __C, __m128h __D) -{ - return (__m128h) - __builtin_ia32_vfcmaddcsh_maskz_round ((__v8hf) __B, - (__v8hf) __C, - (__v8hf) __D, - __A, _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_fcmadd_sch (__m128h __A, __m128h __B, __m128h __C) -{ - return (__m128h) - __builtin_ia32_vfcmaddcsh_round ((__v8hf) __A, - (__v8hf) __B, - (__v8hf) __C, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fmadd_sch (__m128h __A, __mmask8 __B, __m128h __C, __m128h __D) -{ - return (__m128h) - __builtin_ia32_vfmaddcsh_mask_round ((__v8hf) __A, - (__v8hf) __C, - (__v8hf) __D, __B, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask3_fmadd_sch (__m128h __A, __m128h __B, __m128h __C, __mmask8 __D) -{ - return (__m128h) - __builtin_ia32_vfmaddcsh_mask3_round ((__v8hf) __A, - (__v8hf) __B, - (__v8hf) __C, __D, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fmadd_sch (__mmask8 __A, __m128h __B, __m128h __C, __m128h __D) -{ - return (__m128h) - __builtin_ia32_vfmaddcsh_maskz_round ((__v8hf) __B, - (__v8hf) __C, - (__v8hf) __D, - __A, _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_fmadd_sch (__m128h __A, __m128h __B, __m128h __C) -{ - return (__m128h) - __builtin_ia32_vfmaddcsh_round ((__v8hf) __A, - (__v8hf) __B, - (__v8hf) __C, - _MM_FROUND_CUR_DIRECTION); -} -#ifdef __OPTIMIZE__ -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fcmadd_round_sch (__m128h __A, __mmask8 __B, __m128h __C, - __m128h __D, const int __E) -{ - return (__m128h) - __builtin_ia32_vfcmaddcsh_mask_round ((__v8hf) __A, - (__v8hf) __C, - (__v8hf) __D, - __B, __E); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask3_fcmadd_round_sch (__m128h __A, __m128h __B, __m128h __C, - __mmask8 __D, const int __E) -{ - return (__m128h) - __builtin_ia32_vfcmaddcsh_mask3_round ((__v8hf) __A, - (__v8hf) __B, - (__v8hf) __C, - __D, __E); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fcmadd_round_sch (__mmask8 __A, __m128h __B, __m128h __C, - __m128h __D, const int __E) -{ - return (__m128h) - __builtin_ia32_vfcmaddcsh_maskz_round ((__v8hf) __B, - (__v8hf) __C, - (__v8hf) __D, - __A, __E); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_fcmadd_round_sch (__m128h __A, __m128h __B, __m128h __C, const int __D) -{ - return (__m128h) - __builtin_ia32_vfcmaddcsh_round ((__v8hf) __A, - (__v8hf) __B, - (__v8hf) __C, - __D); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fmadd_round_sch (__m128h __A, __mmask8 __B, __m128h __C, - __m128h __D, const int __E) -{ - return (__m128h) - __builtin_ia32_vfmaddcsh_mask_round ((__v8hf) __A, - (__v8hf) __C, - (__v8hf) __D, - __B, __E); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask3_fmadd_round_sch (__m128h __A, __m128h __B, __m128h __C, - __mmask8 __D, const int __E) -{ - return (__m128h) - __builtin_ia32_vfmaddcsh_mask3_round ((__v8hf) __A, - (__v8hf) __B, - (__v8hf) __C, - __D, __E); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fmadd_round_sch (__mmask8 __A, __m128h __B, __m128h __C, - __m128h __D, const int __E) -{ - return (__m128h) - __builtin_ia32_vfmaddcsh_maskz_round ((__v8hf) __B, - (__v8hf) __C, - (__v8hf) __D, - __A, __E); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_fmadd_round_sch (__m128h __A, __m128h __B, __m128h __C, const int __D) -{ - return (__m128h) - __builtin_ia32_vfmaddcsh_round ((__v8hf) __A, - (__v8hf) __B, - (__v8hf) __C, - __D); -} -#else -#define _mm_mask_fcmadd_round_sch(A, B, C, D, E) ((__m128h) __builtin_ia32_vfcmaddcsh_mask_round ((__v8hf) (A), (__v8hf) (C), (__v8hf) (D), (B), (E))) -#define _mm_mask3_fcmadd_round_sch(A, B, C, D, E) ((__m128h) __builtin_ia32_vfcmaddcsh_mask3_round ((__v8hf) (A), (__v8hf) (B), (__v8hf) (C), (D), (E))) -#define _mm_maskz_fcmadd_round_sch(A, B, C, D, E) __builtin_ia32_vfcmaddcsh_maskz_round ((B), (C), (D), (A), (E)) -#define _mm_fcmadd_round_sch(A, B, C, D) __builtin_ia32_vfcmaddcsh_round ((A), (B), (C), (D)) -#define _mm_mask_fmadd_round_sch(A, B, C, D, E) ((__m128h) __builtin_ia32_vfmaddcsh_mask_round ((__v8hf) (A), (__v8hf) (C), (__v8hf) (D), (B), (E))) -#define _mm_mask3_fmadd_round_sch(A, B, C, D, E) ((__m128h) __builtin_ia32_vfmaddcsh_mask3_round ((__v8hf) (A), (__v8hf) (B), (__v8hf) (C), (D), (E))) -#define _mm_maskz_fmadd_round_sch(A, B, C, D, E) __builtin_ia32_vfmaddcsh_maskz_round ((B), (C), (D), (A), (E)) -#define _mm_fmadd_round_sch(A, B, C, D) __builtin_ia32_vfmaddcsh_round ((A), (B), (C), (D)) -#endif -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_fcmul_sch (__m128h __A, __m128h __B) -{ - return (__m128h) - __builtin_ia32_vfcmulcsh_round ((__v8hf) __A, - (__v8hf) __B, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fcmul_sch (__m128h __A, __mmask8 __B, __m128h __C, __m128h __D) -{ - return (__m128h) - __builtin_ia32_vfcmulcsh_mask_round ((__v8hf) __C, - (__v8hf) __D, - (__v8hf) __A, - __B, _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fcmul_sch (__mmask8 __A, __m128h __B, __m128h __C) -{ - return (__m128h) - __builtin_ia32_vfcmulcsh_mask_round ((__v8hf) __B, - (__v8hf) __C, - _mm_setzero_ph (), - __A, _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_fmul_sch (__m128h __A, __m128h __B) -{ - return (__m128h) - __builtin_ia32_vfmulcsh_round ((__v8hf) __A, - (__v8hf) __B, - _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fmul_sch (__m128h __A, __mmask8 __B, __m128h __C, __m128h __D) -{ - return (__m128h) - __builtin_ia32_vfmulcsh_mask_round ((__v8hf) __C, - (__v8hf) __D, - (__v8hf) __A, - __B, _MM_FROUND_CUR_DIRECTION); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fmul_sch (__mmask8 __A, __m128h __B, __m128h __C) -{ - return (__m128h) - __builtin_ia32_vfmulcsh_mask_round ((__v8hf) __B, - (__v8hf) __C, - _mm_setzero_ph (), - __A, _MM_FROUND_CUR_DIRECTION); -} -#ifdef __OPTIMIZE__ -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_fcmul_round_sch (__m128h __A, __m128h __B, const int __D) -{ - return (__m128h) - __builtin_ia32_vfcmulcsh_round ((__v8hf) __A, - (__v8hf) __B, - __D); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fcmul_round_sch (__m128h __A, __mmask8 __B, __m128h __C, - __m128h __D, const int __E) -{ - return (__m128h) - __builtin_ia32_vfcmulcsh_mask_round ((__v8hf) __C, - (__v8hf) __D, - (__v8hf) __A, - __B, __E); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fcmul_round_sch (__mmask8 __A, __m128h __B, __m128h __C, - const int __E) -{ - return (__m128h) - __builtin_ia32_vfcmulcsh_mask_round ((__v8hf) __B, - (__v8hf) __C, - _mm_setzero_ph (), - __A, __E); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_fmul_round_sch (__m128h __A, __m128h __B, const int __D) -{ - return (__m128h) - __builtin_ia32_vfmulcsh_round ((__v8hf) __A, - (__v8hf) __B, __D); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_fmul_round_sch (__m128h __A, __mmask8 __B, __m128h __C, - __m128h __D, const int __E) -{ - return (__m128h) - __builtin_ia32_vfmulcsh_mask_round ((__v8hf) __C, - (__v8hf) __D, - (__v8hf) __A, - __B, __E); -} -extern __inline __m128h -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_fmul_round_sch (__mmask8 __A, __m128h __B, __m128h __C, const int __E) -{ - return (__m128h) - __builtin_ia32_vfmulcsh_mask_round ((__v8hf) __B, - (__v8hf) __C, - _mm_setzero_ph (), - __A, __E); -} -#else -#define _mm_fcmul_round_sch(__A, __B, __D) (__m128h) __builtin_ia32_vfcmulcsh_round ((__v8hf) __A, (__v8hf) __B, __D) -#define _mm_mask_fcmul_round_sch(__A, __B, __C, __D, __E) (__m128h) __builtin_ia32_vfcmulcsh_mask_round ((__v8hf) __C, (__v8hf) __D, (__v8hf) __A, __B, __E) -#define _mm_maskz_fcmul_round_sch(__A, __B, __C, __E) (__m128h) __builtin_ia32_vfcmulcsh_mask_round ((__v8hf) __B, (__v8hf) __C, _mm_setzero_ph (), __A, __E) -#define _mm_fmul_round_sch(__A, __B, __D) (__m128h) __builtin_ia32_vfmulcsh_round ((__v8hf) __A, (__v8hf) __B, __D) -#define _mm_mask_fmul_round_sch(__A, __B, __C, __D, __E) (__m128h) __builtin_ia32_vfmulcsh_mask_round ((__v8hf) __C, (__v8hf) __D, (__v8hf) __A, __B, __E) -#define _mm_maskz_fmul_round_sch(__A, __B, __C, __E) (__m128h) __builtin_ia32_vfmulcsh_mask_round ((__v8hf) __B, (__v8hf) __C, _mm_setzero_ph (), __A, __E) -#endif #define _MM512_REDUCE_OP(op) __m256h __T1 = (__m256h) _mm512_extractf64x4_pd ((__m512d) __A, 0); __m256h __T2 = (__m256h) _mm512_extractf64x4_pd ((__m512d) __A, 1); __m256h __T3 = (__T1 op __T2); __m128h __T4 = (__m128h) _mm256_extractf128_pd ((__m256d) __T3, 0); __m128h __T5 = (__m128h) _mm256_extractf128_pd ((__m256d) __T3, 1); __m128h __T6 = (__T4 op __T5); __m128h __T7 = (__m128h) __builtin_shuffle ((__m128h)__T6, (__v8hi) { 4, 5, 6, 7, 0, 1, 2, 3 }); __m128h __T8 = (__T6 op __T7); __m128h __T9 = (__m128h) __builtin_shuffle ((__m128h)__T8, (__v8hi) { 2, 3, 0, 1, 4, 5, 6, 7 }); __m128h __T10 = __T8 op __T9; return __T10[0] op __T10[1] extern __inline _Float16 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) @@ -5415,10 +5452,10 @@ _mm512_set1_pch (_Float16 _Complex __A) { union { - _Float16 _Complex a; - float b; - } u = { .a = __A}; - return (__m512h) _mm512_set1_ps (u.b); + _Float16 _Complex __a; + float __b; + } __u = { .__a = __A}; + return (__m512h) _mm512_set1_ps (__u.__b); } #define _mm512_mul_pch(A, B) _mm512_fmul_pch ((A), (B)) #define _mm512_mask_mul_pch(W, U, A, B) _mm512_mask_fmul_pch ((W), (U), (A), (B)) @@ -5432,20 +5469,8 @@ _mm512_set1_pch (_Float16 _Complex __A) #define _mm512_cmul_round_pch(A, B, R) _mm512_fcmul_round_pch ((A), (B), (R)) #define _mm512_mask_cmul_round_pch(W, U, A, B, R) _mm512_mask_fcmul_round_pch ((W), (U), (A), (B), (R)) #define _mm512_maskz_cmul_round_pch(U, A, B, R) _mm512_maskz_fcmul_round_pch ((U), (A), (B), (R)) -#define _mm_mul_sch(A, B) _mm_fmul_sch ((A), (B)) -#define _mm_mask_mul_sch(W, U, A, B) _mm_mask_fmul_sch ((W), (U), (A), (B)) -#define _mm_maskz_mul_sch(U, A, B) _mm_maskz_fmul_sch ((U), (A), (B)) -#define _mm_mul_round_sch(A, B, R) _mm_fmul_round_sch ((A), (B), (R)) -#define _mm_mask_mul_round_sch(W, U, A, B, R) _mm_mask_fmul_round_sch ((W), (U), (A), (B), (R)) -#define _mm_maskz_mul_round_sch(U, A, B, R) _mm_maskz_fmul_round_sch ((U), (A), (B), (R)) -#define _mm_cmul_sch(A, B) _mm_fcmul_sch ((A), (B)) -#define _mm_mask_cmul_sch(W, U, A, B) _mm_mask_fcmul_sch ((W), (U), (A), (B)) -#define _mm_maskz_cmul_sch(U, A, B) _mm_maskz_fcmul_sch ((U), (A), (B)) -#define _mm_cmul_round_sch(A, B, R) _mm_fcmul_round_sch ((A), (B), (R)) -#define _mm_mask_cmul_round_sch(W, U, A, B, R) _mm_mask_fcmul_round_sch ((W), (U), (A), (B), (R)) -#define _mm_maskz_cmul_round_sch(U, A, B, R) _mm_maskz_fcmul_round_sch ((U), (A), (B), (R)) -#ifdef __DISABLE_AVX512FP16__ -#undef __DISABLE_AVX512FP16__ +#ifdef __DISABLE_AVX512FP16_512__ +#undef __DISABLE_AVX512FP16_512__ #pragma GCC pop_options #endif #endif diff --git a/third_party/intel/avx512fp16vlintrin.internal.h b/third_party/intel/avx512fp16vlintrin.internal.h index d42a041a9..f994366a6 100644 --- a/third_party/intel/avx512fp16vlintrin.internal.h +++ b/third_party/intel/avx512fp16vlintrin.internal.h @@ -4,11 +4,33 @@ #endif #ifndef __AVX512FP16VLINTRIN_H_INCLUDED #define __AVX512FP16VLINTRIN_H_INCLUDED -#if !defined(__AVX512VL__) || !defined(__AVX512FP16__) +#if !defined(__AVX512VL__) || !defined(__AVX512FP16__) || defined (__EVEX512__) #pragma GCC push_options -#pragma GCC target("avx512fp16,avx512vl") +#pragma GCC target("avx512fp16,avx512vl,no-evex512") #define __DISABLE_AVX512FP16VL__ #endif +extern __inline __m128 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_avx512_set1_ps (float __F) +{ + return __extension__ (__m128)(__v4sf){ __F, __F, __F, __F }; +} +extern __inline __m256 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_avx512_set1_ps (float __A) +{ + return __extension__ (__m256){ __A, __A, __A, __A, + __A, __A, __A, __A }; +} +extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_avx512_and_si128 (__m128i __A, __m128i __B) +{ + return (__m128i) ((__v2du)__A & (__v2du)__B); +} +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_avx512_and_si256 (__m256i __A, __m256i __B) +{ + return (__m256i) ((__v4du)__A & (__v4du)__B); +} extern __inline __m128 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm_castph_ps (__m128h __a) @@ -87,10 +109,10 @@ _mm256_castph256_ph128 (__m256h __A) { union { - __m128h a[2]; - __m256h v; - } u = { .v = __A }; - return u.a[0]; + __m128h __a[2]; + __m256h __v; + } __u = { .__v = __A }; + return __u.__a[0]; } extern __inline __m256h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) @@ -98,24 +120,24 @@ _mm256_castph128_ph256 (__m128h __A) { union { - __m128h a[2]; - __m256h v; - } u; - u.a[0] = __A; - return u.v; + __m128h __a[2]; + __m256h __v; + } __u; + __u.__a[0] = __A; + return __u.__v; } extern __inline __m256h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_zextph128_ph256 (__m128h __A) { - return (__m256h) _mm256_insertf128_ps (_mm256_setzero_ps (), + return (__m256h) _mm256_avx512_insertf128_ps (_mm256_avx512_setzero_ps (), (__m128) __A, 0); } extern __inline __m256h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_conj_pch (__m256h __A) { - return (__m256h) _mm256_xor_epi32 ((__m256i) __A, _mm256_set1_epi32 (1<<31)); + return (__m256h) _mm256_xor_epi32 ((__m256i) __A, _mm256_avx512_set1_epi32 (1<<31)); } extern __inline __m256h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) @@ -133,14 +155,14 @@ _mm256_maskz_conj_pch (__mmask8 __U, __m256h __A) return (__m256h) __builtin_ia32_movaps256_mask ((__v8sf) _mm256_conj_pch (__A), (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm_conj_pch (__m128h __A) { - return (__m128h) _mm_xor_epi32 ((__m128i) __A, _mm_set1_epi32 (1<<31)); + return (__m128h) _mm_xor_epi32 ((__m128i) __A, _mm_avx512_set1_epi32 (1<<31)); } extern __inline __m128h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) @@ -155,7 +177,7 @@ __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm_maskz_conj_pch (__mmask8 __U, __m128h __A) { return (__m128h) __builtin_ia32_movaps128_mask ((__v4sf) _mm_conj_pch (__A), - (__v4sf) _mm_setzero_ps (), + (__v4sf) _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128h @@ -398,15 +420,15 @@ extern __inline __m128h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm_abs_ph (__m128h __A) { - return (__m128h) _mm_and_si128 ( _mm_set1_epi32 (0x7FFF7FFF), - (__m128i) __A); + return (__m128h) _mm_avx512_and_si128 (_mm_avx512_set1_epi32 (0x7FFF7FFF), + (__m128i) __A); } extern __inline __m256h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_abs_ph (__m256h __A) { - return (__m256h) _mm256_and_si256 ( _mm256_set1_epi32 (0x7FFF7FFF), - (__m256i) __A); + return (__m256h) _mm256_avx512_and_si256 (_mm256_avx512_set1_epi32 (0x7FFF7FFF), + (__m256i) __A); } #ifdef __OPTIMIZE extern __inline __mmask8 @@ -884,7 +906,7 @@ _mm_cvtph_epi32 (__m128h __A) return (__m128i) __builtin_ia32_vcvtph2dq128_mask (__A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -900,7 +922,7 @@ _mm_maskz_cvtph_epi32 (__mmask8 __A, __m128h __B) { return (__m128i) __builtin_ia32_vcvtph2dq128_mask (__B, - (__v4si) _mm_setzero_si128 (), + (__v4si) _mm_avx512_setzero_si128 (), __A); } extern __inline __m256i @@ -910,7 +932,7 @@ _mm256_cvtph_epi32 (__m128h __A) return (__m256i) __builtin_ia32_vcvtph2dq256_mask (__A, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -927,7 +949,7 @@ _mm256_maskz_cvtph_epi32 (__mmask8 __A, __m128h __B) return (__m256i) __builtin_ia32_vcvtph2dq256_mask (__B, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __A); } extern __inline __m128i @@ -937,7 +959,7 @@ _mm_cvtph_epu32 (__m128h __A) return (__m128i) __builtin_ia32_vcvtph2udq128_mask (__A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -954,7 +976,7 @@ _mm_maskz_cvtph_epu32 (__mmask8 __A, __m128h __B) return (__m128i) __builtin_ia32_vcvtph2udq128_mask (__B, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __A); } extern __inline __m256i @@ -964,7 +986,7 @@ _mm256_cvtph_epu32 (__m128h __A) return (__m256i) __builtin_ia32_vcvtph2udq256_mask (__A, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -980,7 +1002,7 @@ _mm256_maskz_cvtph_epu32 (__mmask8 __A, __m128h __B) { return (__m256i) __builtin_ia32_vcvtph2udq256_mask (__B, - (__v8si) _mm256_setzero_si256 (), + (__v8si) _mm256_avx512_setzero_si256 (), __A); } extern __inline __m128i @@ -989,7 +1011,7 @@ _mm_cvttph_epi32 (__m128h __A) { return (__m128i) __builtin_ia32_vcvttph2dq128_mask (__A, - (__v4si) _mm_setzero_si128 (), + (__v4si) _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -1006,7 +1028,7 @@ _mm_maskz_cvttph_epi32 (__mmask8 __A, __m128h __B) { return (__m128i) __builtin_ia32_vcvttph2dq128_mask (__B, - (__v4si) _mm_setzero_si128 (), + (__v4si) _mm_avx512_setzero_si128 (), __A); } extern __inline __m256i @@ -1016,7 +1038,7 @@ _mm256_cvttph_epi32 (__m128h __A) return (__m256i) __builtin_ia32_vcvttph2dq256_mask (__A, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -1035,7 +1057,7 @@ _mm256_maskz_cvttph_epi32 (__mmask8 __A, __m128h __B) return (__m256i) __builtin_ia32_vcvttph2dq256_mask (__B, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __A); } extern __inline __m128i @@ -1045,7 +1067,7 @@ _mm_cvttph_epu32 (__m128h __A) return (__m128i) __builtin_ia32_vcvttph2udq128_mask (__A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -1064,7 +1086,7 @@ _mm_maskz_cvttph_epu32 (__mmask8 __A, __m128h __B) return (__m128i) __builtin_ia32_vcvttph2udq128_mask (__B, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __A); } extern __inline __m256i @@ -1074,7 +1096,7 @@ _mm256_cvttph_epu32 (__m128h __A) return (__m256i) __builtin_ia32_vcvttph2udq256_mask (__A, (__v8si) - _mm256_setzero_si256 (), (__mmask8) -1); + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) @@ -1092,7 +1114,7 @@ _mm256_maskz_cvttph_epu32 (__mmask8 __A, __m128h __B) return (__m256i) __builtin_ia32_vcvttph2udq256_mask (__B, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __A); } extern __inline __m128h @@ -1191,7 +1213,7 @@ _mm_cvtph_epi64 (__m128h __A) { return __builtin_ia32_vcvtph2qq128_mask (__A, - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -1205,7 +1227,7 @@ __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm_maskz_cvtph_epi64 (__mmask8 __A, __m128h __B) { return __builtin_ia32_vcvtph2qq128_mask (__B, - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __A); } extern __inline __m256i @@ -1213,7 +1235,7 @@ __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_cvtph_epi64 (__m128h __A) { return __builtin_ia32_vcvtph2qq256_mask (__A, - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -1227,7 +1249,7 @@ __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_maskz_cvtph_epi64 (__mmask8 __A, __m128h __B) { return __builtin_ia32_vcvtph2qq256_mask (__B, - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __A); } extern __inline __m128i @@ -1235,7 +1257,7 @@ __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm_cvtph_epu64 (__m128h __A) { return __builtin_ia32_vcvtph2uqq128_mask (__A, - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -1249,7 +1271,7 @@ __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm_maskz_cvtph_epu64 (__mmask8 __A, __m128h __B) { return __builtin_ia32_vcvtph2uqq128_mask (__B, - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __A); } extern __inline __m256i @@ -1257,7 +1279,7 @@ __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_cvtph_epu64 (__m128h __A) { return __builtin_ia32_vcvtph2uqq256_mask (__A, - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -1271,7 +1293,7 @@ __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_maskz_cvtph_epu64 (__mmask8 __A, __m128h __B) { return __builtin_ia32_vcvtph2uqq256_mask (__B, - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __A); } extern __inline __m128i @@ -1279,7 +1301,7 @@ __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm_cvttph_epi64 (__m128h __A) { return __builtin_ia32_vcvttph2qq128_mask (__A, - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -1295,7 +1317,7 @@ __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm_maskz_cvttph_epi64 (__mmask8 __A, __m128h __B) { return __builtin_ia32_vcvttph2qq128_mask (__B, - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __A); } extern __inline __m256i @@ -1303,7 +1325,7 @@ __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_cvttph_epi64 (__m128h __A) { return __builtin_ia32_vcvttph2qq256_mask (__A, - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -1319,7 +1341,7 @@ __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_maskz_cvttph_epi64 (__mmask8 __A, __m128h __B) { return __builtin_ia32_vcvttph2qq256_mask (__B, - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __A); } extern __inline __m128i @@ -1327,7 +1349,7 @@ __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm_cvttph_epu64 (__m128h __A) { return __builtin_ia32_vcvttph2uqq128_mask (__A, - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -1343,7 +1365,7 @@ __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm_maskz_cvttph_epu64 (__mmask8 __A, __m128h __B) { return __builtin_ia32_vcvttph2uqq128_mask (__B, - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __A); } extern __inline __m256i @@ -1351,7 +1373,7 @@ __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_cvttph_epu64 (__m128h __A) { return __builtin_ia32_vcvttph2uqq256_mask (__A, - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -1367,7 +1389,7 @@ __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_maskz_cvttph_epu64 (__mmask8 __A, __m128h __B) { return __builtin_ia32_vcvttph2uqq256_mask (__B, - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __A); } extern __inline __m128h @@ -1465,7 +1487,7 @@ _mm_cvtph_epi16 (__m128h __A) return (__m128i) __builtin_ia32_vcvtph2w128_mask (__A, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -1482,7 +1504,7 @@ _mm_maskz_cvtph_epi16 (__mmask8 __A, __m128h __B) return (__m128i) __builtin_ia32_vcvtph2w128_mask (__B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __A); } extern __inline __m256i @@ -1492,7 +1514,7 @@ _mm256_cvtph_epi16 (__m256h __A) return (__m256i) __builtin_ia32_vcvtph2w256_mask (__A, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) -1); } extern __inline __m256i @@ -1509,7 +1531,7 @@ _mm256_maskz_cvtph_epi16 (__mmask16 __A, __m256h __B) return (__m256i) __builtin_ia32_vcvtph2w256_mask (__B, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __A); } extern __inline __m128i @@ -1519,7 +1541,7 @@ _mm_cvtph_epu16 (__m128h __A) return (__m128i) __builtin_ia32_vcvtph2uw128_mask (__A, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -1536,7 +1558,7 @@ _mm_maskz_cvtph_epu16 (__mmask8 __A, __m128h __B) return (__m128i) __builtin_ia32_vcvtph2uw128_mask (__B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __A); } extern __inline __m256i @@ -1546,7 +1568,7 @@ _mm256_cvtph_epu16 (__m256h __A) return (__m256i) __builtin_ia32_vcvtph2uw256_mask (__A, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) -1); } extern __inline __m256i @@ -1563,7 +1585,7 @@ _mm256_maskz_cvtph_epu16 (__mmask16 __A, __m256h __B) return (__m256i) __builtin_ia32_vcvtph2uw256_mask (__B, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __A); } extern __inline __m128i @@ -1573,7 +1595,7 @@ _mm_cvttph_epi16 (__m128h __A) return (__m128i) __builtin_ia32_vcvttph2w128_mask (__A, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -1592,7 +1614,7 @@ _mm_maskz_cvttph_epi16 (__mmask8 __A, __m128h __B) return (__m128i) __builtin_ia32_vcvttph2w128_mask (__B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __A); } extern __inline __m256i @@ -1602,7 +1624,7 @@ _mm256_cvttph_epi16 (__m256h __A) return (__m256i) __builtin_ia32_vcvttph2w256_mask (__A, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) -1); } extern __inline __m256i @@ -1621,7 +1643,7 @@ _mm256_maskz_cvttph_epi16 (__mmask16 __A, __m256h __B) return (__m256i) __builtin_ia32_vcvttph2w256_mask (__B, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __A); } extern __inline __m128i @@ -1631,7 +1653,7 @@ _mm_cvttph_epu16 (__m128h __A) return (__m128i) __builtin_ia32_vcvttph2uw128_mask (__A, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -1650,7 +1672,7 @@ _mm_maskz_cvttph_epu16 (__mmask8 __A, __m128h __B) return (__m128i) __builtin_ia32_vcvttph2uw128_mask (__B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __A); } extern __inline __m256i @@ -1660,7 +1682,7 @@ _mm256_cvttph_epu16 (__m256h __A) return (__m256i) __builtin_ia32_vcvttph2uw256_mask (__A, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) -1); } extern __inline __m256i @@ -1678,7 +1700,7 @@ _mm256_maskz_cvttph_epu16 (__mmask16 __A, __m256h __B) { return (__m256i) __builtin_ia32_vcvttph2uw256_mask (__B, - (__v16hi) _mm256_setzero_si256 (), + (__v16hi) _mm256_avx512_setzero_si256 (), __A); } extern __inline __m128h @@ -1778,7 +1800,7 @@ __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm_cvtph_pd (__m128h __A) { return __builtin_ia32_vcvtph2pd128_mask (__A, - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) -1); } extern __inline __m128d @@ -1791,14 +1813,14 @@ extern __inline __m128d __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm_maskz_cvtph_pd (__mmask8 __A, __m128h __B) { - return __builtin_ia32_vcvtph2pd128_mask (__B, _mm_setzero_pd (), __A); + return __builtin_ia32_vcvtph2pd128_mask (__B, _mm_avx512_setzero_pd (), __A); } extern __inline __m256d __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_cvtph_pd (__m128h __A) { return __builtin_ia32_vcvtph2pd256_mask (__A, - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) -1); } extern __inline __m256d @@ -1812,7 +1834,7 @@ __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_maskz_cvtph_pd (__mmask8 __A, __m128h __B) { return __builtin_ia32_vcvtph2pd256_mask (__B, - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), __A); } extern __inline __m128 @@ -1820,7 +1842,7 @@ __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm_cvtxph_ps (__m128h __A) { return __builtin_ia32_vcvtph2psx128_mask (__A, - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) -1); } extern __inline __m128 @@ -1833,14 +1855,14 @@ extern __inline __m128 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm_maskz_cvtxph_ps (__mmask8 __A, __m128h __B) { - return __builtin_ia32_vcvtph2psx128_mask (__B, _mm_setzero_ps (), __A); + return __builtin_ia32_vcvtph2psx128_mask (__B, _mm_avx512_setzero_ps (), __A); } extern __inline __m256 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_cvtxph_ps (__m128h __A) { return __builtin_ia32_vcvtph2psx256_mask (__A, - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) -1); } extern __inline __m256 @@ -1854,7 +1876,7 @@ __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_maskz_cvtxph_ps (__mmask8 __A, __m128h __B) { return __builtin_ia32_vcvtph2psx256_mask (__B, - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), __A); } extern __inline __m128h @@ -2667,7 +2689,7 @@ _mm256_maskz_fcmul_pch (__mmask8 __A, __m256h __B, __m256h __C) _mm256_setzero_ph (), __A); } -#define _MM256_REDUCE_OP(op) __m128h __T1 = (__m128h) _mm256_extractf128_pd ((__m256d) __A, 0); __m128h __T2 = (__m128h) _mm256_extractf128_pd ((__m256d) __A, 1); __m128h __T3 = (__T1 op __T2); __m128h __T4 = (__m128h) __builtin_shuffle (__T3, (__v8hi) { 4, 5, 6, 7, 0, 1, 2, 3 }); __m128h __T5 = (__T3) op (__T4); __m128h __T6 = (__m128h) __builtin_shuffle (__T5, (__v8hi) { 2, 3, 0, 1, 4, 5, 6, 7 }); __m128h __T7 = __T5 op __T6; return __T7[0] op __T7[1] +#define _MM256_REDUCE_OP(op) __m128h __T1 = (__m128h) _mm256_avx512_extractf128_pd ((__m256d) __A, 0); __m128h __T2 = (__m128h) _mm256_avx512_extractf128_pd ((__m256d) __A, 1); __m128h __T3 = (__T1 op __T2); __m128h __T4 = (__m128h) __builtin_shuffle (__T3, (__v8hi) { 4, 5, 6, 7, 0, 1, 2, 3 }); __m128h __T5 = (__T3) op (__T4); __m128h __T6 = (__m128h) __builtin_shuffle (__T5, (__v8hi) { 2, 3, 0, 1, 4, 5, 6, 7 }); __m128h __T7 = __T5 op __T6; return __T7[0] op __T7[1] extern __inline _Float16 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_reduce_add_ph (__m256h __A) @@ -2681,7 +2703,7 @@ _mm256_reduce_mul_ph (__m256h __A) _MM256_REDUCE_OP (*); } #undef _MM256_REDUCE_OP -#define _MM256_REDUCE_OP(op) __m128h __T1 = (__m128h) _mm256_extractf128_pd ((__m256d) __A, 0); __m128h __T2 = (__m128h) _mm256_extractf128_pd ((__m256d) __A, 1); __m128h __T3 = _mm_##op (__T1, __T2); __m128h __T4 = (__m128h) __builtin_shuffle (__T3, (__v8hi) { 2, 3, 0, 1, 6, 7, 4, 5 }); __m128h __T5 = _mm_##op (__T3, __T4); __m128h __T6 = (__m128h) __builtin_shuffle (__T5, (__v8hi) { 4, 5 }); __m128h __T7 = _mm_##op (__T5, __T6); __m128h __T8 = (__m128h) __builtin_shuffle (__T7, (__v8hi) { 1, 0 }); __m128h __T9 = _mm_##op (__T7, __T8); return __T9[0] +#define _MM256_REDUCE_OP(op) __m128h __T1 = (__m128h) _mm256_avx512_extractf128_pd ((__m256d) __A, 0); __m128h __T2 = (__m128h) _mm256_avx512_extractf128_pd ((__m256d) __A, 1); __m128h __T3 = _mm_##op (__T1, __T2); __m128h __T4 = (__m128h) __builtin_shuffle (__T3, (__v8hi) { 2, 3, 0, 1, 6, 7, 4, 5 }); __m128h __T5 = _mm_##op (__T3, __T4); __m128h __T6 = (__m128h) __builtin_shuffle (__T5, (__v8hi) { 4, 5 }); __m128h __T7 = _mm_##op (__T5, __T6); __m128h __T8 = (__m128h) __builtin_shuffle (__T7, (__v8hi) { 1, 0 }); __m128h __T9 = _mm_##op (__T7, __T8); return __T9[0] extern __inline _Float16 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_reduce_min_ph (__m256h __A) @@ -2783,10 +2805,10 @@ _mm256_set1_pch (_Float16 _Complex __A) { union { - _Float16 _Complex a; - float b; - } u = { .a = __A }; - return (__m256h) _mm256_set1_ps (u.b); + _Float16 _Complex __a; + float __b; + } __u = { .__a = __A }; + return (__m256h) _mm256_avx512_set1_ps (__u.__b); } extern __inline __m128h __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) @@ -2794,10 +2816,10 @@ _mm_set1_pch (_Float16 _Complex __A) { union { - _Float16 _Complex a; - float b; - } u = { .a = __A }; - return (__m128h) _mm_set1_ps (u.b); + _Float16 _Complex __a; + float __b; + } __u = { .__a = __A }; + return (__m128h) _mm_avx512_set1_ps (__u.__b); } #define _mm_mul_pch(A, B) _mm_fmul_pch ((A), (B)) #define _mm_mask_mul_pch(W, U, A, B) _mm_mask_fmul_pch ((W), (U), (A), (B)) diff --git a/third_party/intel/avx512ifmaintrin.internal.h b/third_party/intel/avx512ifmaintrin.internal.h index c26b71b24..64f167125 100644 --- a/third_party/intel/avx512ifmaintrin.internal.h +++ b/third_party/intel/avx512ifmaintrin.internal.h @@ -4,9 +4,9 @@ #endif #ifndef _AVX512IFMAINTRIN_H_INCLUDED #define _AVX512IFMAINTRIN_H_INCLUDED -#ifndef __AVX512IFMA__ +#if !defined (__AVX512IFMA__) || !defined (__EVEX512__) #pragma GCC push_options -#pragma GCC target("avx512ifma") +#pragma GCC target("avx512ifma,evex512") #define __DISABLE_AVX512IFMA__ #endif extern __inline __m512i diff --git a/third_party/intel/avx512ifmavlintrin.internal.h b/third_party/intel/avx512ifmavlintrin.internal.h index 38dedfee7..56c548d9d 100644 --- a/third_party/intel/avx512ifmavlintrin.internal.h +++ b/third_party/intel/avx512ifmavlintrin.internal.h @@ -4,47 +4,15 @@ #endif #ifndef _AVX512IFMAVLINTRIN_H_INCLUDED #define _AVX512IFMAVLINTRIN_H_INCLUDED -#if !defined(__AVX512VL__) || !defined(__AVX512IFMA__) +#if !defined(__AVX512VL__) || !defined(__AVX512IFMA__) || defined (__EVEX512__) #pragma GCC push_options -#pragma GCC target("avx512ifma,avx512vl") +#pragma GCC target("avx512ifma,avx512vl,no-evex512") #define __DISABLE_AVX512IFMAVL__ #endif -extern __inline __m128i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_madd52lo_epu64 (__m128i __X, __m128i __Y, __m128i __Z) -{ - return (__m128i) __builtin_ia32_vpmadd52luq128_mask ((__v2di) __X, - (__v2di) __Y, - (__v2di) __Z, - (__mmask8) -1); -} -extern __inline __m128i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_madd52hi_epu64 (__m128i __X, __m128i __Y, __m128i __Z) -{ - return (__m128i) __builtin_ia32_vpmadd52huq128_mask ((__v2di) __X, - (__v2di) __Y, - (__v2di) __Z, - (__mmask8) -1); -} -extern __inline __m256i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_madd52lo_epu64 (__m256i __X, __m256i __Y, __m256i __Z) -{ - return (__m256i) __builtin_ia32_vpmadd52luq256_mask ((__v4di) __X, - (__v4di) __Y, - (__v4di) __Z, - (__mmask8) -1); -} -extern __inline __m256i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_madd52hi_epu64 (__m256i __X, __m256i __Y, __m256i __Z) -{ - return (__m256i) __builtin_ia32_vpmadd52huq256_mask ((__v4di) __X, - (__v4di) __Y, - (__v4di) __Z, - (__mmask8) -1); -} +#define _mm_madd52lo_epu64(A, B, C) ((__m128i) __builtin_ia32_vpmadd52luq128 ((__v2di) (A), (__v2di) (B), (__v2di) (C))) +#define _mm_madd52hi_epu64(A, B, C) ((__m128i) __builtin_ia32_vpmadd52huq128 ((__v2di) (A), (__v2di) (B), (__v2di) (C))) +#define _mm256_madd52lo_epu64(A, B, C) ((__m256i) __builtin_ia32_vpmadd52luq256 ((__v4di) (A), (__v4di) (B), (__v4di) (C))) +#define _mm256_madd52hi_epu64(A, B, C) ((__m256i) __builtin_ia32_vpmadd52huq256 ((__v4di) (A), (__v4di) (B), (__v4di) (C))) extern __inline __m128i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm_mask_madd52lo_epu64 (__m128i __W, __mmask8 __M, __m128i __X, __m128i __Y) diff --git a/third_party/intel/avx512pfintrin.internal.h b/third_party/intel/avx512pfintrin.internal.h index 4a9d538f4..bbb339c0a 100644 --- a/third_party/intel/avx512pfintrin.internal.h +++ b/third_party/intel/avx512pfintrin.internal.h @@ -6,7 +6,7 @@ #define _AVX512PFINTRIN_H_INCLUDED #ifndef __AVX512PF__ #pragma GCC push_options -#pragma GCC target("avx512pf") +#pragma GCC target("avx512pf,evex512") #define __DISABLE_AVX512PF__ #endif typedef long long __v8di __attribute__ ((__vector_size__ (64))); diff --git a/third_party/intel/avx512vbmi2intrin.internal.h b/third_party/intel/avx512vbmi2intrin.internal.h index 71cee34b0..e8afb814c 100644 --- a/third_party/intel/avx512vbmi2intrin.internal.h +++ b/third_party/intel/avx512vbmi2intrin.internal.h @@ -4,9 +4,9 @@ #endif #ifndef __AVX512VBMI2INTRIN_H_INCLUDED #define __AVX512VBMI2INTRIN_H_INCLUDED -#if !defined(__AVX512VBMI2__) +#if !defined(__AVX512VBMI2__) || !defined (__EVEX512__) #pragma GCC push_options -#pragma GCC target("avx512vbmi2") +#pragma GCC target("avx512vbmi2,evex512") #define __DISABLE_AVX512VBMI2__ #endif #ifdef __OPTIMIZE__ @@ -224,15 +224,6 @@ _mm512_maskz_shldv_epi64 (__mmask8 __A, __m512i __B, __m512i __C, __m512i __D) return (__m512i)__builtin_ia32_vpshldv_v8di_maskz ((__v8di)__B, (__v8di) __C, (__v8di) __D, (__mmask8)__A); } -#ifdef __DISABLE_AVX512VBMI2__ -#undef __DISABLE_AVX512VBMI2__ -#pragma GCC pop_options -#endif -#if !defined(__AVX512VBMI2__) || !defined(__AVX512BW__) -#pragma GCC push_options -#pragma GCC target("avx512vbmi2,avx512bw") -#define __DISABLE_AVX512VBMI2BW__ -#endif extern __inline __m512i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm512_mask_compress_epi8 (__m512i __A, __mmask64 __B, __m512i __C) @@ -398,8 +389,8 @@ _mm512_maskz_shldv_epi16 (__mmask32 __A, __m512i __B, __m512i __C, __m512i __D) return (__m512i)__builtin_ia32_vpshldv_v32hi_maskz ((__v32hi)__B, (__v32hi) __C, (__v32hi) __D, (__mmask32)__A); } -#ifdef __DISABLE_AVX512VBMI2BW__ -#undef __DISABLE_AVX512VBMI2BW__ +#ifdef __DISABLE_AVX512VBMI2__ +#undef __DISABLE_AVX512VBMI2__ #pragma GCC pop_options #endif #endif diff --git a/third_party/intel/avx512vbmi2vlintrin.internal.h b/third_party/intel/avx512vbmi2vlintrin.internal.h index 07f97fb52..515a28507 100644 --- a/third_party/intel/avx512vbmi2vlintrin.internal.h +++ b/third_party/intel/avx512vbmi2vlintrin.internal.h @@ -4,9 +4,9 @@ #endif #ifndef _AVX512VBMI2VLINTRIN_H_INCLUDED #define _AVX512VBMI2VLINTRIN_H_INCLUDED -#if !defined(__AVX512VL__) || !defined(__AVX512VBMI2__) +#if !defined(__AVX512VL__) || !defined(__AVX512VBMI2__) || defined (__EVEX512__) #pragma GCC push_options -#pragma GCC target("avx512vbmi2,avx512vl") +#pragma GCC target("avx512vbmi2,avx512vl,no-evex512") #define __DISABLE_AVX512VBMI2VL__ #endif extern __inline __m128i @@ -21,7 +21,7 @@ __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_maskz_compress_epi8 (__mmask16 __A, __m128i __B) { return (__m128i) __builtin_ia32_compressqi128_mask ((__v16qi) __B, - (__v16qi) _mm_setzero_si128 (), (__mmask16) __A); + (__v16qi) _mm_avx512_setzero_si128 (), (__mmask16) __A); } extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -42,7 +42,7 @@ __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_maskz_compress_epi16 (__mmask8 __A, __m128i __B) { return (__m128i) __builtin_ia32_compresshi128_mask ((__v8hi) __B, - (__v8hi) _mm_setzero_si128 (), (__mmask8) __A); + (__v8hi) _mm_avx512_setzero_si128 (), (__mmask8) __A); } extern __inline __m256i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -56,7 +56,7 @@ __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm256_maskz_compress_epi16 (__mmask16 __A, __m256i __B) { return (__m256i) __builtin_ia32_compresshi256_mask ((__v16hi) __B, - (__v16hi) _mm256_setzero_si256 (), (__mmask16) __A); + (__v16hi) _mm256_avx512_setzero_si256 (), (__mmask16) __A); } extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -85,7 +85,7 @@ __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_maskz_expand_epi8 (__mmask16 __A, __m128i __B) { return (__m128i) __builtin_ia32_expandqi128_maskz ((__v16qi) __B, - (__v16qi) _mm_setzero_si128 (), (__mmask16) __A); + (__v16qi) _mm_avx512_setzero_si128 (), (__mmask16) __A); } extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -99,7 +99,7 @@ __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_maskz_expandloadu_epi8 (__mmask16 __A, const void * __B) { return (__m128i) __builtin_ia32_expandloadqi128_maskz ((const __v16qi *) __B, - (__v16qi) _mm_setzero_si128 (), (__mmask16) __A); + (__v16qi) _mm_avx512_setzero_si128 (), (__mmask16) __A); } extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -114,7 +114,7 @@ __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_maskz_expand_epi16 (__mmask8 __A, __m128i __B) { return (__m128i) __builtin_ia32_expandhi128_maskz ((__v8hi) __B, - (__v8hi) _mm_setzero_si128 (), (__mmask8) __A); + (__v8hi) _mm_avx512_setzero_si128 (), (__mmask8) __A); } extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -128,7 +128,7 @@ __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_maskz_expandloadu_epi16 (__mmask8 __A, const void * __B) { return (__m128i) __builtin_ia32_expandloadhi128_maskz ((const __v8hi *) __B, - (__v8hi) _mm_setzero_si128 (), (__mmask8) __A); + (__v8hi) _mm_avx512_setzero_si128 (), (__mmask8) __A); } extern __inline __m256i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -143,7 +143,7 @@ __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm256_maskz_expand_epi16 (__mmask16 __A, __m256i __B) { return (__m256i) __builtin_ia32_expandhi256_maskz ((__v16hi) __B, - (__v16hi) _mm256_setzero_si256 (), (__mmask16) __A); + (__v16hi) _mm256_avx512_setzero_si256 (), (__mmask16) __A); } extern __inline __m256i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -157,7 +157,7 @@ __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm256_maskz_expandloadu_epi16 (__mmask16 __A, const void * __B) { return (__m256i) __builtin_ia32_expandloadhi256_maskz ((const __v16hi *) __B, - (__v16hi) _mm256_setzero_si256 (), (__mmask16) __A); + (__v16hi) _mm256_avx512_setzero_si256 (), (__mmask16) __A); } #ifdef __OPTIMIZE__ extern __inline __m256i @@ -180,7 +180,7 @@ __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm256_maskz_shrdi_epi16 (__mmask16 __A, __m256i __B, __m256i __C, int __D) { return (__m256i)__builtin_ia32_vpshrd_v16hi_mask ((__v16hi)__B, - (__v16hi) __C, __D, (__v16hi) _mm256_setzero_si256 (), (__mmask16)__A); + (__v16hi) __C, __D, (__v16hi) _mm256_avx512_setzero_si256 (), (__mmask16)__A); } extern __inline __m256i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -195,7 +195,7 @@ __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm256_maskz_shrdi_epi32 (__mmask8 __A, __m256i __B, __m256i __C, int __D) { return (__m256i)__builtin_ia32_vpshrd_v8si_mask ((__v8si)__B, (__v8si) __C, - __D, (__v8si) _mm256_setzero_si256 (), (__mmask8)__A); + __D, (__v8si) _mm256_avx512_setzero_si256 (), (__mmask8)__A); } extern __inline __m256i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -216,7 +216,7 @@ __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm256_maskz_shrdi_epi64 (__mmask8 __A, __m256i __B, __m256i __C, int __D) { return (__m256i)__builtin_ia32_vpshrd_v4di_mask ((__v4di)__B, (__v4di) __C, - __D, (__v4di) _mm256_setzero_si256 (), (__mmask8)__A); + __D, (__v4di) _mm256_avx512_setzero_si256 (), (__mmask8)__A); } extern __inline __m256i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -237,7 +237,7 @@ __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_maskz_shrdi_epi16 (__mmask8 __A, __m128i __B, __m128i __C, int __D) { return (__m128i)__builtin_ia32_vpshrd_v8hi_mask ((__v8hi)__B, (__v8hi) __C, - __D, (__v8hi) _mm_setzero_si128 (), (__mmask8)__A); + __D, (__v8hi) _mm_avx512_setzero_si128 (), (__mmask8)__A); } extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -258,7 +258,7 @@ __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_maskz_shrdi_epi32 (__mmask8 __A, __m128i __B, __m128i __C, int __D) { return (__m128i)__builtin_ia32_vpshrd_v4si_mask ((__v4si)__B, (__v4si) __C, - __D, (__v4si) _mm_setzero_si128 (), (__mmask8)__A); + __D, (__v4si) _mm_avx512_setzero_si128 (), (__mmask8)__A); } extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -279,7 +279,7 @@ __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_maskz_shrdi_epi64 (__mmask8 __A, __m128i __B, __m128i __C, int __D) { return (__m128i)__builtin_ia32_vpshrd_v2di_mask ((__v2di)__B, (__v2di) __C, - __D, (__v2di) _mm_setzero_si128 (), (__mmask8)__A); + __D, (__v2di) _mm_avx512_setzero_si128 (), (__mmask8)__A); } extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -307,7 +307,7 @@ __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm256_maskz_shldi_epi16 (__mmask16 __A, __m256i __B, __m256i __C, int __D) { return (__m256i)__builtin_ia32_vpshld_v16hi_mask ((__v16hi)__B, - (__v16hi) __C, __D, (__v16hi) _mm256_setzero_si256 (), (__mmask16)__A); + (__v16hi) __C, __D, (__v16hi) _mm256_avx512_setzero_si256 (), (__mmask16)__A); } extern __inline __m256i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -322,7 +322,7 @@ __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm256_maskz_shldi_epi32 (__mmask8 __A, __m256i __B, __m256i __C, int __D) { return (__m256i)__builtin_ia32_vpshld_v8si_mask ((__v8si)__B, (__v8si) __C, - __D, (__v8si) _mm256_setzero_si256 (), (__mmask8)__A); + __D, (__v8si) _mm256_avx512_setzero_si256 (), (__mmask8)__A); } extern __inline __m256i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -343,7 +343,7 @@ __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm256_maskz_shldi_epi64 (__mmask8 __A, __m256i __B, __m256i __C, int __D) { return (__m256i)__builtin_ia32_vpshld_v4di_mask ((__v4di)__B, (__v4di) __C, - __D, (__v4di) _mm256_setzero_si256 (), (__mmask8)__A); + __D, (__v4di) _mm256_avx512_setzero_si256 (), (__mmask8)__A); } extern __inline __m256i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -364,7 +364,7 @@ __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_maskz_shldi_epi16 (__mmask8 __A, __m128i __B, __m128i __C, int __D) { return (__m128i)__builtin_ia32_vpshld_v8hi_mask ((__v8hi)__B, (__v8hi) __C, - __D, (__v8hi) _mm_setzero_si128 (), (__mmask8)__A); + __D, (__v8hi) _mm_avx512_setzero_si128 (), (__mmask8)__A); } extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -385,7 +385,7 @@ __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_maskz_shldi_epi32 (__mmask8 __A, __m128i __B, __m128i __C, int __D) { return (__m128i)__builtin_ia32_vpshld_v4si_mask ((__v4si)__B, (__v4si) __C, - __D, (__v4si) _mm_setzero_si128 (), (__mmask8)__A); + __D, (__v4si) _mm_avx512_setzero_si128 (), (__mmask8)__A); } extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -406,7 +406,7 @@ __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_maskz_shldi_epi64 (__mmask8 __A, __m128i __B, __m128i __C, int __D) { return (__m128i)__builtin_ia32_vpshld_v2di_mask ((__v2di)__B, (__v2di) __C, - __D, (__v2di) _mm_setzero_si128 (), (__mmask8)__A); + __D, (__v2di) _mm_avx512_setzero_si128 (), (__mmask8)__A); } extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -417,40 +417,40 @@ _mm_shldi_epi64 (__m128i __A, __m128i __B, int __C) #else #define _mm256_shrdi_epi16(A, B, C) ((__m256i) __builtin_ia32_vpshrd_v16hi ((__v16hi)(__m256i)(A), (__v16hi)(__m256i)(B),(int)(C))) #define _mm256_mask_shrdi_epi16(A, B, C, D, E) ((__m256i) __builtin_ia32_vpshrd_v16hi_mask ((__v16hi)(__m256i)(C), (__v16hi)(__m256i)(D), (int)(E), (__v16hi)(__m256i)(A), (__mmask16)(B))) -#define _mm256_maskz_shrdi_epi16(A, B, C, D) ((__m256i) __builtin_ia32_vpshrd_v16hi_mask ((__v16hi)(__m256i)(B), (__v16hi)(__m256i)(C),(int)(D), (__v16hi)(__m256i)_mm256_setzero_si256 (), (__mmask16)(A))) +#define _mm256_maskz_shrdi_epi16(A, B, C, D) ((__m256i) __builtin_ia32_vpshrd_v16hi_mask ((__v16hi)(__m256i)(B), (__v16hi)(__m256i)(C),(int)(D), (__v16hi)(__m256i)_mm256_avx512_setzero_si256 (), (__mmask16)(A))) #define _mm256_shrdi_epi32(A, B, C) ((__m256i) __builtin_ia32_vpshrd_v8si ((__v8si)(__m256i)(A), (__v8si)(__m256i)(B),(int)(C))) #define _mm256_mask_shrdi_epi32(A, B, C, D, E) ((__m256i) __builtin_ia32_vpshrd_v8si_mask ((__v8si)(__m256i)(C), (__v8si)(__m256i)(D), (int)(E), (__v8si)(__m256i)(A), (__mmask8)(B))) -#define _mm256_maskz_shrdi_epi32(A, B, C, D) ((__m256i) __builtin_ia32_vpshrd_v8si_mask ((__v8si)(__m256i)(B), (__v8si)(__m256i)(C),(int)(D), (__v8si)(__m256i)_mm256_setzero_si256 (), (__mmask8)(A))) +#define _mm256_maskz_shrdi_epi32(A, B, C, D) ((__m256i) __builtin_ia32_vpshrd_v8si_mask ((__v8si)(__m256i)(B), (__v8si)(__m256i)(C),(int)(D), (__v8si)(__m256i)_mm256_avx512_setzero_si256 (), (__mmask8)(A))) #define _mm256_shrdi_epi64(A, B, C) ((__m256i) __builtin_ia32_vpshrd_v4di ((__v4di)(__m256i)(A), (__v4di)(__m256i)(B),(int)(C))) #define _mm256_mask_shrdi_epi64(A, B, C, D, E) ((__m256i) __builtin_ia32_vpshrd_v4di_mask ((__v4di)(__m256i)(C), (__v4di)(__m256i)(D), (int)(E), (__v4di)(__m256i)(A), (__mmask8)(B))) -#define _mm256_maskz_shrdi_epi64(A, B, C, D) ((__m256i) __builtin_ia32_vpshrd_v4di_mask ((__v4di)(__m256i)(B), (__v4di)(__m256i)(C),(int)(D), (__v4di)(__m256i)_mm256_setzero_si256 (), (__mmask8)(A))) +#define _mm256_maskz_shrdi_epi64(A, B, C, D) ((__m256i) __builtin_ia32_vpshrd_v4di_mask ((__v4di)(__m256i)(B), (__v4di)(__m256i)(C),(int)(D), (__v4di)(__m256i)_mm256_avx512_setzero_si256 (), (__mmask8)(A))) #define _mm_shrdi_epi16(A, B, C) ((__m128i) __builtin_ia32_vpshrd_v8hi ((__v8hi)(__m128i)(A), (__v8hi)(__m128i)(B),(int)(C))) #define _mm_mask_shrdi_epi16(A, B, C, D, E) ((__m128i) __builtin_ia32_vpshrd_v8hi_mask ((__v8hi)(__m128i)(C), (__v8hi)(__m128i)(D), (int)(E), (__v8hi)(__m128i)(A), (__mmask8)(B))) -#define _mm_maskz_shrdi_epi16(A, B, C, D) ((__m128i) __builtin_ia32_vpshrd_v8hi_mask ((__v8hi)(__m128i)(B), (__v8hi)(__m128i)(C),(int)(D), (__v8hi)(__m128i)_mm_setzero_si128 (), (__mmask8)(A))) +#define _mm_maskz_shrdi_epi16(A, B, C, D) ((__m128i) __builtin_ia32_vpshrd_v8hi_mask ((__v8hi)(__m128i)(B), (__v8hi)(__m128i)(C),(int)(D), (__v8hi)(__m128i)_mm_avx512_setzero_si128 (), (__mmask8)(A))) #define _mm_shrdi_epi32(A, B, C) ((__m128i) __builtin_ia32_vpshrd_v4si ((__v4si)(__m128i)(A), (__v4si)(__m128i)(B),(int)(C))) #define _mm_mask_shrdi_epi32(A, B, C, D, E) ((__m128i) __builtin_ia32_vpshrd_v4si_mask ((__v4si)(__m128i)(C), (__v4si)(__m128i)(D), (int)(E), (__v4si)(__m128i)(A), (__mmask8)(B))) -#define _mm_maskz_shrdi_epi32(A, B, C, D) ((__m128i) __builtin_ia32_vpshrd_v4si_mask ((__v4si)(__m128i)(B), (__v4si)(__m128i)(C),(int)(D), (__v4si)(__m128i)_mm_setzero_si128 (), (__mmask8)(A))) +#define _mm_maskz_shrdi_epi32(A, B, C, D) ((__m128i) __builtin_ia32_vpshrd_v4si_mask ((__v4si)(__m128i)(B), (__v4si)(__m128i)(C),(int)(D), (__v4si)(__m128i)_mm_avx512_setzero_si128 (), (__mmask8)(A))) #define _mm_shrdi_epi64(A, B, C) ((__m128i) __builtin_ia32_vpshrd_v2di ((__v2di)(__m128i)(A), (__v2di)(__m128i)(B),(int)(C))) #define _mm_mask_shrdi_epi64(A, B, C, D, E) ((__m128i) __builtin_ia32_vpshrd_v2di_mask ((__v2di)(__m128i)(C), (__v2di)(__m128i)(D), (int)(E), (__v2di)(__m128i)(A), (__mmask8)(B))) -#define _mm_maskz_shrdi_epi64(A, B, C, D) ((__m128i) __builtin_ia32_vpshrd_v2di_mask ((__v2di)(__m128i)(B), (__v2di)(__m128i)(C),(int)(D), (__v2di)(__m128i)_mm_setzero_si128 (), (__mmask8)(A))) +#define _mm_maskz_shrdi_epi64(A, B, C, D) ((__m128i) __builtin_ia32_vpshrd_v2di_mask ((__v2di)(__m128i)(B), (__v2di)(__m128i)(C),(int)(D), (__v2di)(__m128i)_mm_avx512_setzero_si128 (), (__mmask8)(A))) #define _mm256_shldi_epi16(A, B, C) ((__m256i) __builtin_ia32_vpshld_v16hi ((__v16hi)(__m256i)(A), (__v16hi)(__m256i)(B),(int)(C))) #define _mm256_mask_shldi_epi16(A, B, C, D, E) ((__m256i) __builtin_ia32_vpshld_v16hi_mask ((__v16hi)(__m256i)(C), (__v16hi)(__m256i)(D), (int)(E), (__v16hi)(__m256i)(A), (__mmask16)(B))) -#define _mm256_maskz_shldi_epi16(A, B, C, D) ((__m256i) __builtin_ia32_vpshld_v16hi_mask ((__v16hi)(__m256i)(B), (__v16hi)(__m256i)(C),(int)(D), (__v16hi)(__m256i)_mm256_setzero_si256 (), (__mmask16)(A))) +#define _mm256_maskz_shldi_epi16(A, B, C, D) ((__m256i) __builtin_ia32_vpshld_v16hi_mask ((__v16hi)(__m256i)(B), (__v16hi)(__m256i)(C),(int)(D), (__v16hi)(__m256i)_mm256_avx512_setzero_si256 (), (__mmask16)(A))) #define _mm256_shldi_epi32(A, B, C) ((__m256i) __builtin_ia32_vpshld_v8si ((__v8si)(__m256i)(A), (__v8si)(__m256i)(B),(int)(C))) #define _mm256_mask_shldi_epi32(A, B, C, D, E) ((__m256i) __builtin_ia32_vpshld_v8si_mask ((__v8si)(__m256i)(C), (__v8si)(__m256i)(D), (int)(E), (__v8si)(__m256i)(A), (__mmask8)(B))) -#define _mm256_maskz_shldi_epi32(A, B, C, D) ((__m256i) __builtin_ia32_vpshld_v8si_mask ((__v8si)(__m256i)(B), (__v8si)(__m256i)(C),(int)(D), (__v8si)(__m256i)_mm256_setzero_si256 (), (__mmask8)(A))) +#define _mm256_maskz_shldi_epi32(A, B, C, D) ((__m256i) __builtin_ia32_vpshld_v8si_mask ((__v8si)(__m256i)(B), (__v8si)(__m256i)(C),(int)(D), (__v8si)(__m256i)_mm256_avx512_setzero_si256 (), (__mmask8)(A))) #define _mm256_shldi_epi64(A, B, C) ((__m256i) __builtin_ia32_vpshld_v4di ((__v4di)(__m256i)(A), (__v4di)(__m256i)(B),(int)(C))) #define _mm256_mask_shldi_epi64(A, B, C, D, E) ((__m256i) __builtin_ia32_vpshld_v4di_mask ((__v4di)(__m256i)(C), (__v4di)(__m256i)(D), (int)(E), (__v4di)(__m256i)(A), (__mmask8)(B))) -#define _mm256_maskz_shldi_epi64(A, B, C, D) ((__m256i) __builtin_ia32_vpshld_v4di_mask ((__v4di)(__m256i)(B), (__v4di)(__m256i)(C),(int)(D), (__v4di)(__m256i)_mm256_setzero_si256 (), (__mmask8)(A))) +#define _mm256_maskz_shldi_epi64(A, B, C, D) ((__m256i) __builtin_ia32_vpshld_v4di_mask ((__v4di)(__m256i)(B), (__v4di)(__m256i)(C),(int)(D), (__v4di)(__m256i)_mm256_avx512_setzero_si256 (), (__mmask8)(A))) #define _mm_shldi_epi16(A, B, C) ((__m128i) __builtin_ia32_vpshld_v8hi ((__v8hi)(__m128i)(A), (__v8hi)(__m128i)(B),(int)(C))) #define _mm_mask_shldi_epi16(A, B, C, D, E) ((__m128i) __builtin_ia32_vpshld_v8hi_mask ((__v8hi)(__m128i)(C), (__v8hi)(__m128i)(D), (int)(E), (__v8hi)(__m128i)(A), (__mmask8)(B))) -#define _mm_maskz_shldi_epi16(A, B, C, D) ((__m128i) __builtin_ia32_vpshld_v8hi_mask ((__v8hi)(__m128i)(B), (__v8hi)(__m128i)(C),(int)(D), (__v8hi)(__m128i)_mm_setzero_si128 (), (__mmask8)(A))) +#define _mm_maskz_shldi_epi16(A, B, C, D) ((__m128i) __builtin_ia32_vpshld_v8hi_mask ((__v8hi)(__m128i)(B), (__v8hi)(__m128i)(C),(int)(D), (__v8hi)(__m128i)_mm_avx512_setzero_si128 (), (__mmask8)(A))) #define _mm_shldi_epi32(A, B, C) ((__m128i) __builtin_ia32_vpshld_v4si ((__v4si)(__m128i)(A), (__v4si)(__m128i)(B),(int)(C))) #define _mm_mask_shldi_epi32(A, B, C, D, E) ((__m128i) __builtin_ia32_vpshld_v4si_mask ((__v4si)(__m128i)(C), (__v4si)(__m128i)(D), (int)(E), (__v4si)(__m128i)(A), (__mmask8)(B))) -#define _mm_maskz_shldi_epi32(A, B, C, D) ((__m128i) __builtin_ia32_vpshld_v4si_mask ((__v4si)(__m128i)(B), (__v4si)(__m128i)(C),(int)(D), (__v4si)(__m128i)_mm_setzero_si128 (), (__mmask8)(A))) +#define _mm_maskz_shldi_epi32(A, B, C, D) ((__m128i) __builtin_ia32_vpshld_v4si_mask ((__v4si)(__m128i)(B), (__v4si)(__m128i)(C),(int)(D), (__v4si)(__m128i)_mm_avx512_setzero_si128 (), (__mmask8)(A))) #define _mm_shldi_epi64(A, B, C) ((__m128i) __builtin_ia32_vpshld_v2di ((__v2di)(__m128i)(A), (__v2di)(__m128i)(B),(int)(C))) #define _mm_mask_shldi_epi64(A, B, C, D, E) ((__m128i) __builtin_ia32_vpshld_v2di_mask ((__v2di)(__m128i)(C), (__v2di)(__m128i)(D), (int)(E), (__v2di)(__m128i)(A), (__mmask8)(B))) -#define _mm_maskz_shldi_epi64(A, B, C, D) ((__m128i) __builtin_ia32_vpshld_v2di_mask ((__v2di)(__m128i)(B), (__v2di)(__m128i)(C),(int)(D), (__v2di)(__m128i)_mm_setzero_si128 (), (__mmask8)(A))) +#define _mm_maskz_shldi_epi64(A, B, C, D) ((__m128i) __builtin_ia32_vpshld_v2di_mask ((__v2di)(__m128i)(B), (__v2di)(__m128i)(C),(int)(D), (__v2di)(__m128i)_mm_avx512_setzero_si128 (), (__mmask8)(A))) #endif extern __inline __m256i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -704,15 +704,6 @@ _mm_maskz_shldv_epi64 (__mmask8 __A, __m128i __B, __m128i __C, __m128i __D) return (__m128i)__builtin_ia32_vpshldv_v2di_maskz ((__v2di)__B, (__v2di) __C, (__v2di) __D, (__mmask8)__A); } -#ifdef __DISABLE_AVX512VBMI2VL__ -#undef __DISABLE_AVX512VBMI2VL__ -#pragma GCC pop_options -#endif -#if !defined(__AVX512VL__) || !defined(__AVX512VBMI2__) || !defined(__AVX512BW__) -#pragma GCC push_options -#pragma GCC target("avx512vbmi2,avx512vl,avx512bw") -#define __DISABLE_AVX512VBMI2VLBW__ -#endif extern __inline __m256i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm256_mask_compress_epi8 (__m256i __A, __mmask32 __B, __m256i __C) @@ -725,7 +716,7 @@ __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm256_maskz_compress_epi8 (__mmask32 __A, __m256i __B) { return (__m256i) __builtin_ia32_compressqi256_mask ((__v32qi) __B, - (__v32qi) _mm256_setzero_si256 (), (__mmask32) __A); + (__v32qi) _mm256_avx512_setzero_si256 (), (__mmask32) __A); } extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -747,7 +738,7 @@ __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm256_maskz_expand_epi8 (__mmask32 __A, __m256i __B) { return (__m256i) __builtin_ia32_expandqi256_maskz ((__v32qi) __B, - (__v32qi) _mm256_setzero_si256 (), (__mmask32) __A); + (__v32qi) _mm256_avx512_setzero_si256 (), (__mmask32) __A); } extern __inline __m256i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -761,10 +752,10 @@ __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm256_maskz_expandloadu_epi8 (__mmask32 __A, const void * __B) { return (__m256i) __builtin_ia32_expandloadqi256_maskz ((const __v32qi *) __B, - (__v32qi) _mm256_setzero_si256 (), (__mmask32) __A); + (__v32qi) _mm256_avx512_setzero_si256 (), (__mmask32) __A); } -#ifdef __DISABLE_AVX512VBMI2VLBW__ -#undef __DISABLE_AVX512VBMI2VLBW__ +#ifdef __DISABLE_AVX512VBMI2VL__ +#undef __DISABLE_AVX512VBMI2VL__ #pragma GCC pop_options #endif #endif diff --git a/third_party/intel/avx512vbmiintrin.internal.h b/third_party/intel/avx512vbmiintrin.internal.h index 54ebf1fce..a8bec07f7 100644 --- a/third_party/intel/avx512vbmiintrin.internal.h +++ b/third_party/intel/avx512vbmiintrin.internal.h @@ -4,9 +4,9 @@ #endif #ifndef _AVX512VBMIINTRIN_H_INCLUDED #define _AVX512VBMIINTRIN_H_INCLUDED -#ifndef __AVX512VBMI__ +#if !defined (__AVX512VBMI__) || !defined (__EVEX512__) #pragma GCC push_options -#pragma GCC target("avx512vbmi") +#pragma GCC target("avx512vbmi,evex512") #define __DISABLE_AVX512VBMI__ #endif extern __inline __m512i diff --git a/third_party/intel/avx512vbmivlintrin.internal.h b/third_party/intel/avx512vbmivlintrin.internal.h index a61ec41d4..a77038635 100644 --- a/third_party/intel/avx512vbmivlintrin.internal.h +++ b/third_party/intel/avx512vbmivlintrin.internal.h @@ -4,9 +4,9 @@ #endif #ifndef _AVX512VBMIVLINTRIN_H_INCLUDED #define _AVX512VBMIVLINTRIN_H_INCLUDED -#if !defined(__AVX512VL__) || !defined(__AVX512VBMI__) +#if !defined(__AVX512VL__) || !defined(__AVX512VBMI__) || defined (__EVEX512__) #pragma GCC push_options -#pragma GCC target("avx512vbmi,avx512vl") +#pragma GCC target("avx512vbmi,avx512vl,no-evex512") #define __DISABLE_AVX512VBMIVL__ #endif extern __inline __m256i @@ -25,7 +25,7 @@ _mm256_maskz_multishift_epi64_epi8 (__mmask32 __M, __m256i __X, __m256i __Y) return (__m256i) __builtin_ia32_vpmultishiftqb256_mask ((__v32qi) __X, (__v32qi) __Y, (__v32qi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask32) __M); } extern __inline __m256i @@ -35,7 +35,7 @@ _mm256_multishift_epi64_epi8 (__m256i __X, __m256i __Y) return (__m256i) __builtin_ia32_vpmultishiftqb256_mask ((__v32qi) __X, (__v32qi) __Y, (__v32qi) - _mm256_undefined_si256 (), + _mm256_avx512_undefined_si256 (), (__mmask32) -1); } extern __inline __m128i @@ -54,7 +54,7 @@ _mm_maskz_multishift_epi64_epi8 (__mmask16 __M, __m128i __X, __m128i __Y) return (__m128i) __builtin_ia32_vpmultishiftqb128_mask ((__v16qi) __X, (__v16qi) __Y, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask16) __M); } extern __inline __m128i @@ -64,7 +64,7 @@ _mm_multishift_epi64_epi8 (__m128i __X, __m128i __Y) return (__m128i) __builtin_ia32_vpmultishiftqb128_mask ((__v16qi) __X, (__v16qi) __Y, (__v16qi) - _mm_undefined_si128 (), + _mm_avx512_undefined_si128 (), (__mmask16) -1); } extern __inline __m256i @@ -74,7 +74,7 @@ _mm256_permutexvar_epi8 (__m256i __A, __m256i __B) return (__m256i) __builtin_ia32_permvarqi256_mask ((__v32qi) __B, (__v32qi) __A, (__v32qi) - _mm256_undefined_si256 (), + _mm256_avx512_undefined_si256 (), (__mmask32) -1); } extern __inline __m256i @@ -85,7 +85,7 @@ _mm256_maskz_permutexvar_epi8 (__mmask32 __M, __m256i __A, return (__m256i) __builtin_ia32_permvarqi256_mask ((__v32qi) __B, (__v32qi) __A, (__v32qi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask32) __M); } extern __inline __m256i @@ -105,7 +105,7 @@ _mm_permutexvar_epi8 (__m128i __A, __m128i __B) return (__m128i) __builtin_ia32_permvarqi128_mask ((__v16qi) __B, (__v16qi) __A, (__v16qi) - _mm_undefined_si128 (), + _mm_avx512_undefined_si128 (), (__mmask16) -1); } extern __inline __m128i @@ -115,7 +115,7 @@ _mm_maskz_permutexvar_epi8 (__mmask16 __M, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_permvarqi128_mask ((__v16qi) __B, (__v16qi) __A, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask16) __M); } extern __inline __m128i diff --git a/third_party/intel/avx512vlbwintrin.internal.h b/third_party/intel/avx512vlbwintrin.internal.h index 03b3f5d04..f01024b9b 100644 --- a/third_party/intel/avx512vlbwintrin.internal.h +++ b/third_party/intel/avx512vlbwintrin.internal.h @@ -4,15 +4,119 @@ #endif #ifndef _AVX512VLBWINTRIN_H_INCLUDED #define _AVX512VLBWINTRIN_H_INCLUDED -#if !defined(__AVX512VL__) || !defined(__AVX512BW__) +#if !defined(__AVX512VL__) || !defined(__AVX512BW__) || defined (__EVEX512__) #pragma GCC push_options -#pragma GCC target("avx512vl,avx512bw") +#pragma GCC target("avx512vl,avx512bw,no-evex512") #define __DISABLE_AVX512VLBW__ #endif typedef short __v16hi_u __attribute__ ((__vector_size__ (32), __may_alias__, __aligned__ (1))); typedef short __v8hi_u __attribute__ ((__vector_size__ (16), __may_alias__, __aligned__ (1))); typedef char __v32qi_u __attribute__ ((__vector_size__ (32), __may_alias__, __aligned__ (1))); typedef char __v16qi_u __attribute__ ((__vector_size__ (16), __may_alias__, __aligned__ (1))); +extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_avx512_set1_epi32 (int __A) +{ + return _mm_avx512_set_epi32 (__A, __A, __A, __A); +} +extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_avx512_set1_epi16 (short __A) +{ + return _mm_avx512_set_epi16 (__A, __A, __A, __A, __A, __A, __A, __A); +} +extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_avx512_set1_epi8 (char __A) +{ + return _mm_avx512_set_epi8 (__A, __A, __A, __A, __A, __A, __A, __A, + __A, __A, __A, __A, __A, __A, __A, __A); +} +extern __inline __m256i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_avx512_set_epi16 (short __q15, short __q14, short __q13, short __q12, + short __q11, short __q10, short __q09, short __q08, + short __q07, short __q06, short __q05, short __q04, + short __q03, short __q02, short __q01, short __q00) +{ + return __extension__ (__m256i)(__v16hi){ + __q00, __q01, __q02, __q03, __q04, __q05, __q06, __q07, + __q08, __q09, __q10, __q11, __q12, __q13, __q14, __q15 + }; +} +extern __inline __m256i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_avx512_set_epi8 (char __q31, char __q30, char __q29, char __q28, + char __q27, char __q26, char __q25, char __q24, + char __q23, char __q22, char __q21, char __q20, + char __q19, char __q18, char __q17, char __q16, + char __q15, char __q14, char __q13, char __q12, + char __q11, char __q10, char __q09, char __q08, + char __q07, char __q06, char __q05, char __q04, + char __q03, char __q02, char __q01, char __q00) +{ + return __extension__ (__m256i)(__v32qi){ + __q00, __q01, __q02, __q03, __q04, __q05, __q06, __q07, + __q08, __q09, __q10, __q11, __q12, __q13, __q14, __q15, + __q16, __q17, __q18, __q19, __q20, __q21, __q22, __q23, + __q24, __q25, __q26, __q27, __q28, __q29, __q30, __q31 + }; +} +extern __inline __m256i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_avx512_set1_epi16 (short __A) +{ + return _mm256_avx512_set_epi16 (__A, __A, __A, __A, __A, __A, __A, __A, + __A, __A, __A, __A, __A, __A, __A, __A); +} +extern __inline __m256i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_avx512_set1_epi32 (int __A) +{ + return __extension__ (__m256i)(__v8si){ __A, __A, __A, __A, + __A, __A, __A, __A }; +} +extern __inline __m256i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_avx512_set1_epi8 (char __A) +{ + return _mm256_avx512_set_epi8 (__A, __A, __A, __A, __A, __A, __A, __A, + __A, __A, __A, __A, __A, __A, __A, __A, + __A, __A, __A, __A, __A, __A, __A, __A, + __A, __A, __A, __A, __A, __A, __A, __A); +} +extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_avx512_max_epi16 (__m128i __A, __m128i __B) +{ + return (__m128i)__builtin_ia32_pmaxsw128 ((__v8hi)__A, (__v8hi)__B); +} +extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_avx512_min_epi16 (__m128i __A, __m128i __B) +{ + return (__m128i)__builtin_ia32_pminsw128 ((__v8hi)__A, (__v8hi)__B); +} +extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_avx512_max_epu16 (__m128i __X, __m128i __Y) +{ + return (__m128i) __builtin_ia32_pmaxuw128 ((__v8hi)__X, (__v8hi)__Y); +} +extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_avx512_min_epu16 (__m128i __X, __m128i __Y) +{ + return (__m128i) __builtin_ia32_pminuw128 ((__v8hi)__X, (__v8hi)__Y); +} +extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_avx512_max_epi8 (__m128i __X, __m128i __Y) +{ + return (__m128i) __builtin_ia32_pmaxsb128 ((__v16qi)__X, (__v16qi)__Y); +} +extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_avx512_min_epi8 (__m128i __X, __m128i __Y) +{ + return (__m128i) __builtin_ia32_pminsb128 ((__v16qi)__X, (__v16qi)__Y); +} +extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_avx512_max_epu8 (__m128i __A, __m128i __B) +{ + return (__m128i)__builtin_ia32_pmaxub128 ((__v16qi)__A, (__v16qi)__B); +} +extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_avx512_min_epu8 (__m128i __A, __m128i __B) +{ + return (__m128i)__builtin_ia32_pminub128 ((__v16qi)__A, (__v16qi)__B); +} extern __inline __m256i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_mask_mov_epi8 (__m256i __W, __mmask32 __U, __m256i __A) @@ -23,11 +127,63 @@ _mm256_mask_mov_epi8 (__m256i __W, __mmask32 __U, __m256i __A) } extern __inline __m256i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_avx512_max_epi16 (__m256i __A, __m256i __B) +{ + return (__m256i)__builtin_ia32_pmaxsw256 ((__v16hi)__A, (__v16hi)__B); +} +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_avx512_min_epi16 (__m256i __A, __m256i __B) +{ + return (__m256i)__builtin_ia32_pminsw256 ((__v16hi)__A, (__v16hi)__B); +} +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_avx512_max_epu16 (__m256i __A, __m256i __B) +{ + return (__m256i)__builtin_ia32_pmaxuw256 ((__v16hi)__A, (__v16hi)__B); +} +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_avx512_min_epu16 (__m256i __A, __m256i __B) +{ + return (__m256i)__builtin_ia32_pminuw256 ((__v16hi)__A, (__v16hi)__B); +} +#ifdef __OPTIMIZE__ +extern __inline __m256 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_avx512_insertf128_ps (__m256 __X, __m128 __Y, const int __O) +{ + return (__m256) __builtin_ia32_vinsertf128_ps256 ((__v8sf)__X, + (__v4sf)__Y, + __O); +} +extern __inline __m128d __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_avx512_extractf128_pd (__m256d __X, const int __N) +{ + return (__m128d) __builtin_ia32_vextractf128_pd256 ((__v4df)__X, __N); +} +extern __inline __m128i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_avx512_extracti128_si256 (__m256i __X, const int __M) +{ + return (__m128i) __builtin_ia32_extract128i256 ((__v4di)__X, __M); +} +#else +#define _mm256_avx512_insertf128_ps(X, Y, O) ((__m256) __builtin_ia32_vinsertf128_ps256 ((__v8sf)(__m256)(X), (__v4sf)(__m128)(Y), (int)(O))) +#define _mm256_avx512_extractf128_pd(X, N) ((__m128d) __builtin_ia32_vextractf128_pd256 ((__v4df)(__m256d)(X), (int)(N))) +#define _mm256_avx512_extracti128_si256(X, M) ((__m128i) __builtin_ia32_extract128i256 ((__v4di)(__m256i)(X), (int)(M))) +#endif +#define _MM256_AVX512_REDUCE_OPERATOR_BASIC_EPI16(op) __v8hi __T1 = (__v8hi)_mm256_avx512_extracti128_si256 (__W, 0); __v8hi __T2 = (__v8hi)_mm256_avx512_extracti128_si256 (__W, 1); __v8hi __T3 = __T1 op __T2; __v8hi __T4 = __builtin_shufflevector (__T3, __T3, 4, 5, 6, 7, 4, 5, 6, 7); __v8hi __T5 = __T3 op __T4; __v8hi __T6 = __builtin_shufflevector (__T5, __T5, 2, 3, 2, 3, 4, 5, 6, 7); __v8hi __T7 = __T5 op __T6; __v8hi __T8 = __builtin_shufflevector (__T7, __T7, 1, 1, 2, 3, 4, 5, 6, 7); __v8hi __T9 = __T7 op __T8; return __T9[0] +#define _MM256_AVX512_REDUCE_OPERATOR_MAX_MIN_EP16(op) __m128i __T1 = _mm256_avx512_extracti128_si256 (__V, 0); __m128i __T2 = _mm256_avx512_extracti128_si256 (__V, 1); __m128i __T3 = _mm_avx512_##op (__T1, __T2); __m128i __T4 = (__m128i)__builtin_shufflevector ((__v8hi)__T3, (__v8hi)__T3, 4, 5, 6, 7, 4, 5, 6, 7); __m128i __T5 = _mm_avx512_##op (__T3, __T4); __m128i __T6 = (__m128i)__builtin_shufflevector ((__v8hi)__T5, (__v8hi)__T5, 2, 3, 2, 3, 4, 5, 6, 7); __m128i __T7 = _mm_avx512_##op (__T5, __T6); __m128i __T8 = (__m128i)__builtin_shufflevector ((__v8hi)__T7, (__v8hi)__T7, 1, 1, 2, 3, 4, 5, 6, 7); __v8hi __T9 = (__v8hi)_mm_avx512_##op (__T7, __T8); return __T9[0] +#define _MM256_AVX512_REDUCE_OPERATOR_BASIC_EPI8(op) __v16qi __T1 = (__v16qi)_mm256_avx512_extracti128_si256 (__W, 0); __v16qi __T2 = (__v16qi)_mm256_avx512_extracti128_si256 (__W, 1); __v16qi __T3 = __T1 op __T2; __v16qi __T4 = __builtin_shufflevector (__T3, __T3, 8, 9, 10, 11, 12, 13, 14, 15, 8, 9, 10, 11, 12, 13, 14, 15); __v16qi __T5 = __T3 op __T4; __v16qi __T6 = __builtin_shufflevector (__T5, __T5, 4, 5, 6, 7, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); __v16qi __T7 = __T5 op __T6; __v16qi __T8 = __builtin_shufflevector (__T7, __T7, 2, 3, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); __v16qi __T9 = __T7 op __T8; __v16qi __T10 = __builtin_shufflevector (__T9, __T9, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); __v16qi __T11 = __T9 op __T10; return __T11[0] +#define _MM256_AVX512_REDUCE_OPERATOR_MAX_MIN_EP8(op) __m128i __T1 = _mm256_avx512_extracti128_si256 (__V, 0); __m128i __T2 = _mm256_avx512_extracti128_si256 (__V, 1); __m128i __T3 = _mm_avx512_##op (__T1, __T2); __m128i __T4 = (__m128i)__builtin_shufflevector ((__v16qi)__T3, (__v16qi)__T3, 8, 9, 10, 11, 12, 13, 14, 15, 8, 9, 10, 11, 12, 13, 14, 15); __m128i __T5 = _mm_avx512_##op (__T3, __T4); __m128i __T6 = (__m128i)__builtin_shufflevector ((__v16qi)__T5, (__v16qi)__T5, 4, 5, 6, 7, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); __m128i __T7 = _mm_avx512_##op (__T5, __T6); __m128i __T8 = (__m128i)__builtin_shufflevector ((__v16qi)__T7, (__v16qi)__T5, 2, 3, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); __m128i __T9 = _mm_avx512_##op (__T7, __T8); __m128i __T10 = (__m128i)__builtin_shufflevector ((__v16qi)__T9, (__v16qi)__T9, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); __v16qi __T11 = (__v16qi)_mm_avx512_##op (__T9, __T10); return __T11[0] +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_maskz_mov_epi8 (__mmask32 __U, __m256i __A) { return (__m256i) __builtin_ia32_movdquqi256_mask ((__v32qi) __A, (__v32qi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask32) __U); } extern __inline __m128i @@ -44,7 +200,7 @@ _mm_maskz_mov_epi8 (__mmask16 __U, __m128i __A) { return (__m128i) __builtin_ia32_movdquqi128_mask ((__v16qi) __A, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask16) __U); } extern __inline void @@ -95,7 +251,7 @@ _mm256_maskz_loadu_epi16 (__mmask16 __U, void const *__P) { return (__m256i) __builtin_ia32_loaddquhi256_mask ((const short *) __P, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m128i @@ -118,7 +274,7 @@ _mm_maskz_loadu_epi16 (__mmask8 __U, void const *__P) { return (__m128i) __builtin_ia32_loaddquhi128_mask ((const short *) __P, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -135,7 +291,7 @@ _mm256_maskz_mov_epi16 (__mmask16 __U, __m256i __A) { return (__m256i) __builtin_ia32_movdquhi256_mask ((__v16hi) __A, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m128i @@ -152,7 +308,7 @@ _mm_maskz_mov_epi16 (__mmask8 __U, __m128i __A) { return (__m128i) __builtin_ia32_movdquhi128_mask ((__v8hi) __A, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -175,7 +331,7 @@ _mm256_maskz_loadu_epi8 (__mmask32 __U, void const *__P) { return (__m256i) __builtin_ia32_loaddquqi256_mask ((const char *) __P, (__v32qi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask32) __U); } extern __inline __m128i @@ -198,15 +354,47 @@ _mm_maskz_loadu_epi8 (__mmask16 __U, void const *__P) { return (__m128i) __builtin_ia32_loaddquqi128_mask ((const char *) __P, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask16) __U); } extern __inline __m128i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_blend_epi16 (__mmask8 __U, __m128i __A, __m128i __W) +{ + return (__m128i) __builtin_ia32_blendmw_128_mask ((__v8hi) __A, + (__v8hi) __W, + (__mmask8) __U); +} +extern __inline __m128i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_blend_epi8 (__mmask16 __U, __m128i __A, __m128i __W) +{ + return (__m128i) __builtin_ia32_blendmb_128_mask ((__v16qi) __A, + (__v16qi) __W, + (__mmask16) __U); +} +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_mask_blend_epi16 (__mmask16 __U, __m256i __A, __m256i __W) +{ + return (__m256i) __builtin_ia32_blendmw_256_mask ((__v16hi) __A, + (__v16hi) __W, + (__mmask16) __U); +} +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_mask_blend_epi8 (__mmask32 __U, __m256i __A, __m256i __W) +{ + return (__m256i) __builtin_ia32_blendmb_256_mask ((__v32qi) __A, + (__v32qi) __W, + (__mmask32) __U); +} +extern __inline __m128i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_cvtepi16_epi8 (__m256i __A) { return (__m128i) __builtin_ia32_pmovwb256_mask ((__v16hi) __A, - (__v16qi)_mm_undefined_si128(), + (__v16qi)_mm_avx512_undefined_si128(), (__mmask16) -1); } extern __inline void @@ -228,7 +416,7 @@ _mm256_maskz_cvtepi16_epi8 (__mmask16 __M, __m256i __A) { return (__m128i) __builtin_ia32_pmovwb256_mask ((__v16hi) __A, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -236,7 +424,7 @@ __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm_cvtsepi16_epi8 (__m128i __A) { return (__m128i) __builtin_ia32_pmovswb128_mask ((__v8hi) __A, - (__v16qi)_mm_undefined_si128(), + (__v16qi)_mm_avx512_undefined_si128(), (__mmask8) -1); } extern __inline void @@ -258,7 +446,7 @@ _mm_maskz_cvtsepi16_epi8 (__mmask8 __M, __m128i __A) { return (__m128i) __builtin_ia32_pmovswb128_mask ((__v8hi) __A, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -266,7 +454,7 @@ __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_cvtsepi16_epi8 (__m256i __A) { return (__m128i) __builtin_ia32_pmovswb256_mask ((__v16hi) __A, - (__v16qi)_mm_undefined_si128(), + (__v16qi)_mm_avx512_undefined_si128(), (__mmask16) -1); } extern __inline void @@ -288,7 +476,7 @@ _mm256_maskz_cvtsepi16_epi8 (__mmask16 __M, __m256i __A) { return (__m128i) __builtin_ia32_pmovswb256_mask ((__v16hi) __A, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -296,7 +484,7 @@ __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm_cvtusepi16_epi8 (__m128i __A) { return (__m128i) __builtin_ia32_pmovuswb128_mask ((__v8hi) __A, - (__v16qi)_mm_undefined_si128(), + (__v16qi)_mm_avx512_undefined_si128(), (__mmask8) -1); } extern __inline void @@ -319,7 +507,7 @@ _mm_maskz_cvtusepi16_epi8 (__mmask8 __M, __m128i __A) { return (__m128i) __builtin_ia32_pmovuswb128_mask ((__v8hi) __A, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -327,7 +515,7 @@ __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_cvtusepi16_epi8 (__m256i __A) { return (__m128i) __builtin_ia32_pmovuswb256_mask ((__v16hi) __A, - (__v16qi)_mm_undefined_si128(), + (__v16qi)_mm_avx512_undefined_si128(), (__mmask16) -1); } extern __inline void @@ -350,7 +538,7 @@ _mm256_maskz_cvtusepi16_epi8 (__mmask16 __M, __m256i __A) { return (__m128i) __builtin_ia32_pmovuswb256_mask ((__v16hi) __A, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m256i @@ -367,7 +555,7 @@ _mm256_maskz_broadcastb_epi8 (__mmask32 __M, __m128i __A) { return (__m256i) __builtin_ia32_pbroadcastb256_mask ((__v16qi) __A, (__v32qi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __M); } extern __inline __m256i @@ -384,7 +572,7 @@ _mm256_maskz_set1_epi8 (__mmask32 __M, char __A) { return (__m256i) __builtin_ia32_pbroadcastb256_gpr_mask (__A, (__v32qi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __M); } extern __inline __m128i @@ -401,7 +589,7 @@ _mm_maskz_broadcastb_epi8 (__mmask16 __M, __m128i __A) { return (__m128i) __builtin_ia32_pbroadcastb128_mask ((__v16qi) __A, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -418,7 +606,7 @@ _mm_maskz_set1_epi8 (__mmask16 __M, char __A) { return (__m128i) __builtin_ia32_pbroadcastb128_gpr_mask (__A, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m256i @@ -435,7 +623,7 @@ _mm256_maskz_broadcastw_epi16 (__mmask16 __M, __m128i __A) { return (__m256i) __builtin_ia32_pbroadcastw256_mask ((__v8hi) __A, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __M); } extern __inline __m256i @@ -452,7 +640,7 @@ _mm256_maskz_set1_epi16 (__mmask16 __M, short __A) { return (__m256i) __builtin_ia32_pbroadcastw256_gpr_mask (__A, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __M); } extern __inline __m128i @@ -469,7 +657,7 @@ _mm_maskz_broadcastw_epi16 (__mmask8 __M, __m128i __A) { return (__m128i) __builtin_ia32_pbroadcastw128_mask ((__v8hi) __A, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -486,7 +674,7 @@ _mm_maskz_set1_epi16 (__mmask8 __M, short __A) { return (__m128i) __builtin_ia32_pbroadcastw128_gpr_mask (__A, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m256i @@ -496,7 +684,7 @@ _mm256_permutexvar_epi16 (__m256i __A, __m256i __B) return (__m256i) __builtin_ia32_permvarhi256_mask ((__v16hi) __B, (__v16hi) __A, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) -1); } extern __inline __m256i @@ -507,7 +695,7 @@ _mm256_maskz_permutexvar_epi16 (__mmask16 __M, __m256i __A, return (__m256i) __builtin_ia32_permvarhi256_mask ((__v16hi) __B, (__v16hi) __A, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __M); } extern __inline __m256i @@ -527,7 +715,7 @@ _mm_permutexvar_epi16 (__m128i __A, __m128i __B) return (__m128i) __builtin_ia32_permvarhi128_mask ((__v8hi) __B, (__v8hi) __A, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -537,7 +725,7 @@ _mm_maskz_permutexvar_epi16 (__mmask8 __M, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_permvarhi128_mask ((__v8hi) __B, (__v8hi) __A, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __M); } extern __inline __m128i @@ -659,7 +847,7 @@ _mm256_maskz_maddubs_epi16 (__mmask16 __U, __m256i __X, __m256i __Y) return (__m256i) __builtin_ia32_pmaddubsw256_mask ((__v32qi) __X, (__v32qi) __Y, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m128i @@ -679,7 +867,7 @@ _mm_maskz_maddubs_epi16 (__mmask8 __U, __m128i __X, __m128i __Y) return (__m128i) __builtin_ia32_pmaddubsw128_mask ((__v16qi) __X, (__v16qi) __Y, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -699,7 +887,7 @@ _mm256_maskz_madd_epi16 (__mmask8 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pmaddwd256_mask ((__v16hi) __A, (__v16hi) __B, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -719,7 +907,7 @@ _mm_maskz_madd_epi16 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pmaddwd128_mask ((__v8hi) __A, (__v8hi) __B, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __mmask16 @@ -837,7 +1025,7 @@ _mm256_maskz_min_epu16 (__mmask16 __M, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pminuw256_mask ((__v16hi) __A, (__v16hi) __B, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __M); } extern __inline __m256i @@ -857,7 +1045,7 @@ _mm_maskz_min_epu16 (__mmask8 __M, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pminuw128_mask ((__v8hi) __A, (__v8hi) __B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __M); } extern __inline __m128i @@ -877,7 +1065,7 @@ _mm256_maskz_min_epi16 (__mmask16 __M, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pminsw256_mask ((__v16hi) __A, (__v16hi) __B, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __M); } extern __inline __m256i @@ -897,7 +1085,7 @@ _mm256_maskz_max_epu8 (__mmask32 __M, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pmaxub256_mask ((__v32qi) __A, (__v32qi) __B, (__v32qi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask32) __M); } extern __inline __m256i @@ -917,7 +1105,7 @@ _mm_maskz_max_epu8 (__mmask16 __M, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pmaxub128_mask ((__v16qi) __A, (__v16qi) __B, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask16) __M); } extern __inline __m128i @@ -937,7 +1125,7 @@ _mm256_maskz_max_epi8 (__mmask32 __M, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pmaxsb256_mask ((__v32qi) __A, (__v32qi) __B, (__v32qi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask32) __M); } extern __inline __m256i @@ -957,7 +1145,7 @@ _mm_maskz_max_epi8 (__mmask16 __M, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pmaxsb128_mask ((__v16qi) __A, (__v16qi) __B, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask16) __M); } extern __inline __m128i @@ -977,7 +1165,7 @@ _mm256_maskz_min_epu8 (__mmask32 __M, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pminub256_mask ((__v32qi) __A, (__v32qi) __B, (__v32qi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask32) __M); } extern __inline __m256i @@ -997,7 +1185,7 @@ _mm_maskz_min_epu8 (__mmask16 __M, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pminub128_mask ((__v16qi) __A, (__v16qi) __B, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask16) __M); } extern __inline __m128i @@ -1017,7 +1205,7 @@ _mm256_maskz_min_epi8 (__mmask32 __M, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pminsb256_mask ((__v32qi) __A, (__v32qi) __B, (__v32qi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask32) __M); } extern __inline __m256i @@ -1037,7 +1225,7 @@ _mm_maskz_min_epi8 (__mmask16 __M, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pminsb128_mask ((__v16qi) __A, (__v16qi) __B, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask16) __M); } extern __inline __m128i @@ -1057,7 +1245,7 @@ _mm256_maskz_max_epi16 (__mmask16 __M, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pmaxsw256_mask ((__v16hi) __A, (__v16hi) __B, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __M); } extern __inline __m256i @@ -1077,7 +1265,7 @@ _mm_maskz_max_epi16 (__mmask8 __M, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pmaxsw128_mask ((__v8hi) __A, (__v8hi) __B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __M); } extern __inline __m128i @@ -1097,7 +1285,7 @@ _mm256_maskz_max_epu16 (__mmask16 __M, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pmaxuw256_mask ((__v16hi) __A, (__v16hi) __B, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __M); } extern __inline __m256i @@ -1117,7 +1305,7 @@ _mm_maskz_max_epu16 (__mmask8 __M, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pmaxuw128_mask ((__v8hi) __A, (__v8hi) __B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __M); } extern __inline __m128i @@ -1137,7 +1325,7 @@ _mm_maskz_min_epi16 (__mmask8 __M, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pminsw128_mask ((__v8hi) __A, (__v8hi) __B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __M); } extern __inline __m128i @@ -1171,7 +1359,7 @@ _mm256_maskz_alignr_epi8 (__mmask32 __U, __m256i __A, __m256i __B, (__v4di) __B, __N * 8, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask32) __U); } extern __inline __m128i @@ -1194,7 +1382,7 @@ _mm_maskz_alignr_epi8 (__mmask16 __U, __m128i __A, __m128i __B, (__v2di) __B, __N * 8, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask16) __U); } extern __inline __m256i @@ -1205,7 +1393,7 @@ _mm256_dbsad_epu8 (__m256i __A, __m256i __B, const int __imm) (__v32qi) __B, __imm, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) -1); } extern __inline __m256i @@ -1228,7 +1416,7 @@ _mm256_maskz_dbsad_epu8 (__mmask16 __U, __m256i __A, __m256i __B, (__v32qi) __B, __imm, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m128i @@ -1239,7 +1427,7 @@ _mm_dbsad_epu8 (__m128i __A, __m128i __B, const int __imm) (__v16qi) __B, __imm, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -1262,41 +1450,9 @@ _mm_maskz_dbsad_epu8 (__mmask8 __U, __m128i __A, __m128i __B, (__v16qi) __B, __imm, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } -extern __inline __m128i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_blend_epi16 (__mmask8 __U, __m128i __A, __m128i __W) -{ - return (__m128i) __builtin_ia32_blendmw_128_mask ((__v8hi) __A, - (__v8hi) __W, - (__mmask8) __U); -} -extern __inline __m128i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_blend_epi8 (__mmask16 __U, __m128i __A, __m128i __W) -{ - return (__m128i) __builtin_ia32_blendmb_128_mask ((__v16qi) __A, - (__v16qi) __W, - (__mmask16) __U); -} -extern __inline __m256i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_blend_epi16 (__mmask16 __U, __m256i __A, __m256i __W) -{ - return (__m256i) __builtin_ia32_blendmw_256_mask ((__v16hi) __A, - (__v16hi) __W, - (__mmask16) __U); -} -extern __inline __m256i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_blend_epi8 (__mmask32 __U, __m256i __A, __m256i __W) -{ - return (__m256i) __builtin_ia32_blendmb_256_mask ((__v32qi) __A, - (__v32qi) __W, - (__mmask32) __U); -} extern __inline __mmask8 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm_mask_cmp_epi16_mask (__mmask8 __U, __m128i __X, __m128i __Y, @@ -1448,7 +1604,7 @@ _mm256_maskz_srli_epi16 (__mmask16 __U, __m256i __A, const int __imm) { return (__m256i) __builtin_ia32_psrlwi256_mask ((__v16hi) __A, __imm, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m128i @@ -1466,7 +1622,7 @@ _mm_maskz_srli_epi16 (__mmask8 __U, __m128i __A, const int __imm) { return (__m128i) __builtin_ia32_psrlwi128_mask ((__v8hi) __A, __imm, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -1487,7 +1643,7 @@ _mm256_maskz_shufflehi_epi16 (__mmask16 __U, __m256i __A, return (__m256i) __builtin_ia32_pshufhw256_mask ((__v16hi) __A, __imm, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m128i @@ -1505,7 +1661,7 @@ _mm_maskz_shufflehi_epi16 (__mmask8 __U, __m128i __A, const int __imm) { return (__m128i) __builtin_ia32_pshufhw128_mask ((__v8hi) __A, __imm, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -1526,7 +1682,7 @@ _mm256_maskz_shufflelo_epi16 (__mmask16 __U, __m256i __A, return (__m256i) __builtin_ia32_pshuflw256_mask ((__v16hi) __A, __imm, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m128i @@ -1544,13 +1700,13 @@ _mm_maskz_shufflelo_epi16 (__mmask8 __U, __m128i __A, const int __imm) { return (__m128i) __builtin_ia32_pshuflw128_mask ((__v8hi) __A, __imm, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_mask_srai_epi16 (__m256i __W, __mmask16 __U, __m256i __A, - const int __imm) + const unsigned int __imm) { return (__m256i) __builtin_ia32_psrawi256_mask ((__v16hi) __A, __imm, (__v16hi) __W, @@ -1558,17 +1714,17 @@ _mm256_mask_srai_epi16 (__m256i __W, __mmask16 __U, __m256i __A, } extern __inline __m256i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_maskz_srai_epi16 (__mmask16 __U, __m256i __A, const int __imm) +_mm256_maskz_srai_epi16 (__mmask16 __U, __m256i __A, const unsigned int __imm) { return (__m256i) __builtin_ia32_psrawi256_mask ((__v16hi) __A, __imm, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m128i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm_mask_srai_epi16 (__m128i __W, __mmask8 __U, __m128i __A, - const int __imm) + const unsigned int __imm) { return (__m128i) __builtin_ia32_psrawi128_mask ((__v8hi) __A, __imm, (__v8hi) __W, @@ -1576,17 +1732,17 @@ _mm_mask_srai_epi16 (__m128i __W, __mmask8 __U, __m128i __A, } extern __inline __m128i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_srai_epi16 (__mmask8 __U, __m128i __A, const int __imm) +_mm_maskz_srai_epi16 (__mmask8 __U, __m128i __A, const unsigned int __imm) { return (__m128i) __builtin_ia32_psrawi128_mask ((__v8hi) __A, __imm, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_mask_slli_epi16 (__m256i __W, __mmask16 __U, __m256i __A, - int __B) + unsigned int __B) { return (__m256i) __builtin_ia32_psllwi256_mask ((__v16hi) __A, __B, (__v16hi) __W, @@ -1594,16 +1750,16 @@ _mm256_mask_slli_epi16 (__m256i __W, __mmask16 __U, __m256i __A, } extern __inline __m256i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_maskz_slli_epi16 (__mmask16 __U, __m256i __A, int __B) +_mm256_maskz_slli_epi16 (__mmask16 __U, __m256i __A, unsigned int __B) { return (__m256i) __builtin_ia32_psllwi256_mask ((__v16hi) __A, __B, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m128i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_slli_epi16 (__m128i __W, __mmask8 __U, __m128i __A, int __B) +_mm_mask_slli_epi16 (__m128i __W, __mmask8 __U, __m128i __A, unsigned int __B) { return (__m128i) __builtin_ia32_psllwi128_mask ((__v8hi) __A, __B, (__v8hi) __W, @@ -1611,48 +1767,44 @@ _mm_mask_slli_epi16 (__m128i __W, __mmask8 __U, __m128i __A, int __B) } extern __inline __m128i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_slli_epi16 (__mmask8 __U, __m128i __A, int __B) +_mm_maskz_slli_epi16 (__mmask8 __U, __m128i __A, unsigned int __B) { return (__m128i) __builtin_ia32_psllwi128_mask ((__v8hi) __A, __B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } #else #define _mm256_mask_alignr_epi8(W, U, X, Y, N) ((__m256i) __builtin_ia32_palignr256_mask ((__v4di)(__m256i)(X), (__v4di)(__m256i)(Y), (int)((N) * 8), (__v4di)(__m256i)(X), (__mmask32)(U))) #define _mm256_mask_srli_epi16(W, U, A, B) ((__m256i) __builtin_ia32_psrlwi256_mask ((__v16hi)(__m256i)(A), (int)(B), (__v16hi)(__m256i)(W), (__mmask16)(U))) -#define _mm256_maskz_srli_epi16(U, A, B) ((__m256i) __builtin_ia32_psrlwi256_mask ((__v16hi)(__m256i)(A), (int)(B), (__v16hi)_mm256_setzero_si256 (), (__mmask16)(U))) +#define _mm256_maskz_srli_epi16(U, A, B) ((__m256i) __builtin_ia32_psrlwi256_mask ((__v16hi)(__m256i)(A), (int)(B), (__v16hi)_mm256_avx512_setzero_si256 (), (__mmask16)(U))) #define _mm_mask_srli_epi16(W, U, A, B) ((__m128i) __builtin_ia32_psrlwi128_mask ((__v8hi)(__m128i)(A), (int)(B), (__v8hi)(__m128i)(W), (__mmask8)(U))) -#define _mm_maskz_srli_epi16(U, A, B) ((__m128i) __builtin_ia32_psrlwi128_mask ((__v8hi)(__m128i)(A), (int)(B), (__v8hi)_mm_setzero_si128(), (__mmask8)(U))) -#define _mm256_mask_srai_epi16(W, U, A, B) ((__m256i) __builtin_ia32_psrawi256_mask ((__v16hi)(__m256i)(A), (int)(B), (__v16hi)(__m256i)(W), (__mmask16)(U))) -#define _mm256_maskz_srai_epi16(U, A, B) ((__m256i) __builtin_ia32_psrawi256_mask ((__v16hi)(__m256i)(A), (int)(B), (__v16hi)_mm256_setzero_si256 (), (__mmask16)(U))) -#define _mm_mask_srai_epi16(W, U, A, B) ((__m128i) __builtin_ia32_psrawi128_mask ((__v8hi)(__m128i)(A), (int)(B), (__v8hi)(__m128i)(W), (__mmask8)(U))) -#define _mm_maskz_srai_epi16(U, A, B) ((__m128i) __builtin_ia32_psrawi128_mask ((__v8hi)(__m128i)(A), (int)(B), (__v8hi)_mm_setzero_si128(), (__mmask8)(U))) +#define _mm_maskz_srli_epi16(U, A, B) ((__m128i) __builtin_ia32_psrlwi128_mask ((__v8hi)(__m128i)(A), (int)(B), (__v8hi)_mm_avx512_setzero_si128 (), (__mmask8)(U))) +#define _mm256_mask_srai_epi16(W, U, A, B) ((__m256i) __builtin_ia32_psrawi256_mask ((__v16hi)(__m256i)(A), (unsigned int)(B), (__v16hi)(__m256i)(W), (__mmask16)(U))) +#define _mm256_maskz_srai_epi16(U, A, B) ((__m256i) __builtin_ia32_psrawi256_mask ((__v16hi)(__m256i)(A), (unsigned int)(B), (__v16hi)_mm256_avx512_setzero_si256 (), (__mmask16)(U))) +#define _mm_mask_srai_epi16(W, U, A, B) ((__m128i) __builtin_ia32_psrawi128_mask ((__v8hi)(__m128i)(A), (unsigned int)(B), (__v8hi)(__m128i)(W), (__mmask8)(U))) +#define _mm_maskz_srai_epi16(U, A, B) ((__m128i) __builtin_ia32_psrawi128_mask ((__v8hi)(__m128i)(A), (unsigned int)(B), (__v8hi)_mm_avx512_setzero_si128(), (__mmask8)(U))) #define _mm256_mask_shufflehi_epi16(W, U, A, B) ((__m256i) __builtin_ia32_pshufhw256_mask ((__v16hi)(__m256i)(A), (int)(B), (__v16hi)(__m256i)(W), (__mmask16)(U))) -#define _mm256_maskz_shufflehi_epi16(U, A, B) ((__m256i) __builtin_ia32_pshufhw256_mask ((__v16hi)(__m256i)(A), (int)(B), (__v16hi)(__m256i)_mm256_setzero_si256 (), (__mmask16)(U))) +#define _mm256_maskz_shufflehi_epi16(U, A, B) ((__m256i) __builtin_ia32_pshufhw256_mask ((__v16hi)(__m256i)(A), (int)(B), (__v16hi)(__m256i)_mm256_avx512_setzero_si256 (), (__mmask16)(U))) #define _mm_mask_shufflehi_epi16(W, U, A, B) ((__m128i) __builtin_ia32_pshufhw128_mask ((__v8hi)(__m128i)(A), (int)(B), (__v8hi)(__m128i)(W), (__mmask8)(U))) -#define _mm_maskz_shufflehi_epi16(U, A, B) ((__m128i) __builtin_ia32_pshufhw128_mask ((__v8hi)(__m128i)(A), (int)(B), (__v8hi)(__m128i)_mm_setzero_si128 (), (__mmask8)(U))) +#define _mm_maskz_shufflehi_epi16(U, A, B) ((__m128i) __builtin_ia32_pshufhw128_mask ((__v8hi)(__m128i)(A), (int)(B), (__v8hi)(__m128i)_mm_avx512_setzero_si128 (), (__mmask8)(U))) #define _mm256_mask_shufflelo_epi16(W, U, A, B) ((__m256i) __builtin_ia32_pshuflw256_mask ((__v16hi)(__m256i)(A), (int)(B), (__v16hi)(__m256i)(W), (__mmask16)(U))) -#define _mm256_maskz_shufflelo_epi16(U, A, B) ((__m256i) __builtin_ia32_pshuflw256_mask ((__v16hi)(__m256i)(A), (int)(B), (__v16hi)(__m256i)_mm256_setzero_si256 (), (__mmask16)(U))) +#define _mm256_maskz_shufflelo_epi16(U, A, B) ((__m256i) __builtin_ia32_pshuflw256_mask ((__v16hi)(__m256i)(A), (int)(B), (__v16hi)(__m256i)_mm256_avx512_setzero_si256 (), (__mmask16)(U))) #define _mm_mask_shufflelo_epi16(W, U, A, B) ((__m128i) __builtin_ia32_pshuflw128_mask ((__v8hi)(__m128i)(A), (int)(B), (__v8hi)(__m128i)(W), (__mmask8)(U))) -#define _mm_maskz_shufflelo_epi16(U, A, B) ((__m128i) __builtin_ia32_pshuflw128_mask ((__v8hi)(__m128i)(A), (int)(B), (__v8hi)(__m128i)_mm_setzero_si128 (), (__mmask8)(U))) -#define _mm256_maskz_alignr_epi8(U, X, Y, N) ((__m256i) __builtin_ia32_palignr256_mask ((__v4di)(__m256i)(X), (__v4di)(__m256i)(Y), (int)((N) * 8), (__v4di)(__m256i)_mm256_setzero_si256 (), (__mmask32)(U))) +#define _mm_maskz_shufflelo_epi16(U, A, B) ((__m128i) __builtin_ia32_pshuflw128_mask ((__v8hi)(__m128i)(A), (int)(B), (__v8hi)(__m128i)_mm_avx512_setzero_si128 (), (__mmask8)(U))) +#define _mm256_maskz_alignr_epi8(U, X, Y, N) ((__m256i) __builtin_ia32_palignr256_mask ((__v4di)(__m256i)(X), (__v4di)(__m256i)(Y), (int)((N) * 8), (__v4di)(__m256i)_mm256_avx512_setzero_si256 (), (__mmask32)(U))) #define _mm_mask_alignr_epi8(W, U, X, Y, N) ((__m128i) __builtin_ia32_palignr128_mask ((__v2di)(__m128i)(X), (__v2di)(__m128i)(Y), (int)((N) * 8), (__v2di)(__m128i)(X), (__mmask16)(U))) -#define _mm_maskz_alignr_epi8(U, X, Y, N) ((__m128i) __builtin_ia32_palignr128_mask ((__v2di)(__m128i)(X), (__v2di)(__m128i)(Y), (int)((N) * 8), (__v2di)(__m128i)_mm_setzero_si128 (), (__mmask16)(U))) -#define _mm_mask_slli_epi16(W, U, X, C) ((__m128i)__builtin_ia32_psllwi128_mask ((__v8hi)(__m128i)(X), (int)(C), (__v8hi)(__m128i)(W), (__mmask8)(U))) -#define _mm_maskz_slli_epi16(U, X, C) ((__m128i)__builtin_ia32_psllwi128_mask ((__v8hi)(__m128i)(X), (int)(C), (__v8hi)(__m128i)_mm_setzero_si128 (), (__mmask8)(U))) -#define _mm256_dbsad_epu8(X, Y, C) ((__m256i) __builtin_ia32_dbpsadbw256_mask ((__v32qi)(__m256i) (X), (__v32qi)(__m256i) (Y), (int) (C), (__v16hi)(__m256i)_mm256_setzero_si256(), (__mmask16)-1)) -#define _mm256_mask_slli_epi16(W, U, X, C) ((__m256i)__builtin_ia32_psllwi256_mask ((__v16hi)(__m256i)(X), (int)(C), (__v16hi)(__m256i)(W), (__mmask16)(U))) -#define _mm256_maskz_slli_epi16(U, X, C) ((__m256i)__builtin_ia32_psllwi256_mask ((__v16hi)(__m256i)(X), (int)(C), (__v16hi)(__m256i)_mm256_setzero_si256 (), (__mmask16)(U))) +#define _mm_maskz_alignr_epi8(U, X, Y, N) ((__m128i) __builtin_ia32_palignr128_mask ((__v2di)(__m128i)(X), (__v2di)(__m128i)(Y), (int)((N) * 8), (__v2di)(__m128i)_mm_avx512_setzero_si128 (), (__mmask16)(U))) +#define _mm_mask_slli_epi16(W, U, X, C) ((__m128i)__builtin_ia32_psllwi128_mask ((__v8hi)(__m128i)(X), (unsigned int)(C), (__v8hi)(__m128i)(W), (__mmask8)(U))) +#define _mm_maskz_slli_epi16(U, X, C) ((__m128i)__builtin_ia32_psllwi128_mask ((__v8hi)(__m128i)(X), (unsigned int)(C), (__v8hi)(__m128i)_mm_avx512_setzero_si128 (), (__mmask8)(U))) +#define _mm256_dbsad_epu8(X, Y, C) ((__m256i) __builtin_ia32_dbpsadbw256_mask ((__v32qi)(__m256i) (X), (__v32qi)(__m256i) (Y), (int) (C), (__v16hi)(__m256i)_mm256_avx512_setzero_si256(), (__mmask16)-1)) +#define _mm256_mask_slli_epi16(W, U, X, C) ((__m256i)__builtin_ia32_psllwi256_mask ((__v16hi)(__m256i)(X), (unsigned int)(C), (__v16hi)(__m256i)(W), (__mmask16)(U))) +#define _mm256_maskz_slli_epi16(U, X, C) ((__m256i)__builtin_ia32_psllwi256_mask ((__v16hi)(__m256i)(X), (unsigned int)(C), (__v16hi)(__m256i)_mm256_avx512_setzero_si256 (), (__mmask16)(U))) #define _mm256_mask_dbsad_epu8(W, U, X, Y, C) ((__m256i) __builtin_ia32_dbpsadbw256_mask ((__v32qi)(__m256i) (X), (__v32qi)(__m256i) (Y), (int) (C), (__v16hi)(__m256i)(W), (__mmask16)(U))) -#define _mm256_maskz_dbsad_epu8(U, X, Y, C) ((__m256i) __builtin_ia32_dbpsadbw256_mask ((__v32qi)(__m256i) (X), (__v32qi)(__m256i) (Y), (int) (C), (__v16hi)(__m256i)_mm256_setzero_si256(), (__mmask16)(U))) -#define _mm_dbsad_epu8(X, Y, C) ((__m128i) __builtin_ia32_dbpsadbw128_mask ((__v16qi)(__m128i) (X), (__v16qi)(__m128i) (Y), (int) (C), (__v8hi)(__m128i)_mm_setzero_si128(), (__mmask8)-1)) +#define _mm256_maskz_dbsad_epu8(U, X, Y, C) ((__m256i) __builtin_ia32_dbpsadbw256_mask ((__v32qi)(__m256i) (X), (__v32qi)(__m256i) (Y), (int) (C), (__v16hi)(__m256i)_mm256_avx512_setzero_si256(), (__mmask16)(U))) +#define _mm_dbsad_epu8(X, Y, C) ((__m128i) __builtin_ia32_dbpsadbw128_mask ((__v16qi)(__m128i) (X), (__v16qi)(__m128i) (Y), (int) (C), (__v8hi)(__m128i)_mm_avx512_setzero_si128(), (__mmask8)-1)) #define _mm_mask_dbsad_epu8(W, U, X, Y, C) ((__m128i) __builtin_ia32_dbpsadbw128_mask ((__v16qi)(__m128i) (X), (__v16qi)(__m128i) (Y), (int) (C), (__v8hi)(__m128i)(W), (__mmask8)(U))) -#define _mm_maskz_dbsad_epu8(U, X, Y, C) ((__m128i) __builtin_ia32_dbpsadbw128_mask ((__v16qi)(__m128i) (X), (__v16qi)(__m128i) (Y), (int) (C), (__v8hi)(__m128i)_mm_setzero_si128(), (__mmask8)(U))) -#define _mm_mask_blend_epi16(__U, __A, __W) ((__m128i) __builtin_ia32_blendmw_128_mask ((__v8hi) (__A), (__v8hi) (__W), (__mmask8) (__U))) -#define _mm_mask_blend_epi8(__U, __A, __W) ((__m128i) __builtin_ia32_blendmb_128_mask ((__v16qi) (__A), (__v16qi) (__W), (__mmask16) (__U))) -#define _mm256_mask_blend_epi16(__U, __A, __W) ((__m256i) __builtin_ia32_blendmw_256_mask ((__v16hi) (__A), (__v16hi) (__W), (__mmask16) (__U))) -#define _mm256_mask_blend_epi8(__U, __A, __W) ((__m256i) __builtin_ia32_blendmb_256_mask ((__v32qi) (__A), (__v32qi) (__W), (__mmask32) (__U))) +#define _mm_maskz_dbsad_epu8(U, X, Y, C) ((__m128i) __builtin_ia32_dbpsadbw128_mask ((__v16qi)(__m128i) (X), (__v16qi)(__m128i) (Y), (int) (C), (__v8hi)(__m128i)_mm_avx512_setzero_si128(), (__mmask8)(U))) #define _mm_cmp_epi16_mask(X, Y, P) ((__mmask8) __builtin_ia32_cmpw128_mask ((__v8hi)(__m128i)(X), (__v8hi)(__m128i)(Y), (int)(P), (__mmask8)(-1))) #define _mm_cmp_epi8_mask(X, Y, P) ((__mmask16) __builtin_ia32_cmpb128_mask ((__v16qi)(__m128i)(X), (__v16qi)(__m128i)(Y), (int)(P), (__mmask16)(-1))) #define _mm256_cmp_epi16_mask(X, Y, P) ((__mmask16) __builtin_ia32_cmpw256_mask ((__v16hi)(__m256i)(X), (__v16hi)(__m256i)(Y), (int)(P), (__mmask16)(-1))) @@ -1879,7 +2031,7 @@ _mm256_maskz_mulhrs_epi16 (__mmask16 __U, __m256i __X, __m256i __Y) return (__m256i) __builtin_ia32_pmulhrsw256_mask ((__v16hi) __X, (__v16hi) __Y, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m256i @@ -1899,7 +2051,7 @@ _mm256_maskz_mulhi_epu16 (__mmask16 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pmulhuw256_mask ((__v16hi) __A, (__v16hi) __B, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m256i @@ -1919,7 +2071,7 @@ _mm256_maskz_mulhi_epi16 (__mmask16 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pmulhw256_mask ((__v16hi) __A, (__v16hi) __B, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m128i @@ -1939,7 +2091,7 @@ _mm_maskz_mulhi_epi16 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pmulhw128_mask ((__v8hi) __A, (__v8hi) __B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i @@ -1959,7 +2111,7 @@ _mm_maskz_mulhi_epu16 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pmulhuw128_mask ((__v8hi) __A, (__v8hi) __B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i @@ -1979,7 +2131,7 @@ _mm_maskz_mulhrs_epi16 (__mmask8 __U, __m128i __X, __m128i __Y) return (__m128i) __builtin_ia32_pmulhrsw128_mask ((__v8hi) __X, (__v8hi) __Y, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -1999,7 +2151,7 @@ _mm256_maskz_mullo_epi16 (__mmask16 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pmullw256_mask ((__v16hi) __A, (__v16hi) __B, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m128i @@ -2019,7 +2171,7 @@ _mm_maskz_mullo_epi16 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pmullw128_mask ((__v8hi) __A, (__v8hi) __B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -2036,7 +2188,7 @@ _mm256_maskz_cvtepi8_epi16 (__mmask16 __U, __m128i __A) { return (__m256i) __builtin_ia32_pmovsxbw256_mask ((__v16qi) __A, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m128i @@ -2053,7 +2205,7 @@ _mm_maskz_cvtepi8_epi16 (__mmask8 __U, __m128i __A) { return (__m128i) __builtin_ia32_pmovsxbw128_mask ((__v16qi) __A, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -2070,7 +2222,7 @@ _mm256_maskz_cvtepu8_epi16 (__mmask16 __U, __m128i __A) { return (__m256i) __builtin_ia32_pmovzxbw256_mask ((__v16qi) __A, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m128i @@ -2087,7 +2239,7 @@ _mm_maskz_cvtepu8_epi16 (__mmask8 __U, __m128i __A) { return (__m128i) __builtin_ia32_pmovzxbw128_mask ((__v16qi) __A, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -2107,7 +2259,7 @@ _mm256_maskz_avg_epu8 (__mmask32 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pavgb256_mask ((__v32qi) __A, (__v32qi) __B, (__v32qi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask32) __U); } extern __inline __m128i @@ -2127,7 +2279,7 @@ _mm_maskz_avg_epu8 (__mmask16 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pavgb128_mask ((__v16qi) __A, (__v16qi) __B, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask16) __U); } extern __inline __m256i @@ -2147,7 +2299,7 @@ _mm256_maskz_avg_epu16 (__mmask16 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pavgw256_mask ((__v16hi) __A, (__v16hi) __B, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m128i @@ -2167,7 +2319,7 @@ _mm_maskz_avg_epu16 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pavgw128_mask ((__v8hi) __A, (__v8hi) __B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -2187,7 +2339,7 @@ _mm256_maskz_add_epi8 (__mmask32 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_paddb256_mask ((__v32qi) __A, (__v32qi) __B, (__v32qi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask32) __U); } extern __inline __m256i @@ -2207,7 +2359,7 @@ _mm256_maskz_add_epi16 (__mmask16 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_paddw256_mask ((__v16hi) __A, (__v16hi) __B, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m256i @@ -2227,7 +2379,7 @@ _mm256_maskz_adds_epi8 (__mmask32 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_paddsb256_mask ((__v32qi) __A, (__v32qi) __B, (__v32qi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask32) __U); } extern __inline __m256i @@ -2247,7 +2399,7 @@ _mm256_maskz_adds_epi16 (__mmask16 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_paddsw256_mask ((__v16hi) __A, (__v16hi) __B, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m256i @@ -2267,7 +2419,7 @@ _mm256_maskz_adds_epu8 (__mmask32 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_paddusb256_mask ((__v32qi) __A, (__v32qi) __B, (__v32qi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask32) __U); } extern __inline __m256i @@ -2287,7 +2439,7 @@ _mm256_maskz_adds_epu16 (__mmask16 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_paddusw256_mask ((__v16hi) __A, (__v16hi) __B, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m256i @@ -2307,7 +2459,7 @@ _mm256_maskz_sub_epi8 (__mmask32 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_psubb256_mask ((__v32qi) __A, (__v32qi) __B, (__v32qi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask32) __U); } extern __inline __m256i @@ -2327,7 +2479,7 @@ _mm256_maskz_sub_epi16 (__mmask16 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_psubw256_mask ((__v16hi) __A, (__v16hi) __B, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m256i @@ -2347,7 +2499,7 @@ _mm256_maskz_subs_epi8 (__mmask32 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_psubsb256_mask ((__v32qi) __A, (__v32qi) __B, (__v32qi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask32) __U); } extern __inline __m256i @@ -2367,7 +2519,7 @@ _mm256_maskz_subs_epi16 (__mmask16 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_psubsw256_mask ((__v16hi) __A, (__v16hi) __B, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m256i @@ -2387,7 +2539,7 @@ _mm256_maskz_subs_epu8 (__mmask32 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_psubusb256_mask ((__v32qi) __A, (__v32qi) __B, (__v32qi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask32) __U); } extern __inline __m256i @@ -2407,7 +2559,7 @@ _mm256_maskz_subs_epu16 (__mmask16 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_psubusw256_mask ((__v16hi) __A, (__v16hi) __B, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m128i @@ -2427,7 +2579,7 @@ _mm_maskz_add_epi8 (__mmask16 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_paddb128_mask ((__v16qi) __A, (__v16qi) __B, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask16) __U); } extern __inline __m128i @@ -2447,7 +2599,7 @@ _mm_maskz_add_epi16 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_paddw128_mask ((__v8hi) __A, (__v8hi) __B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -2467,7 +2619,7 @@ _mm256_maskz_unpackhi_epi8 (__mmask32 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_punpckhbw256_mask ((__v32qi) __A, (__v32qi) __B, (__v32qi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask32) __U); } extern __inline __m128i @@ -2487,7 +2639,7 @@ _mm_maskz_unpackhi_epi8 (__mmask16 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_punpckhbw128_mask ((__v16qi) __A, (__v16qi) __B, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask16) __U); } extern __inline __m256i @@ -2507,7 +2659,7 @@ _mm256_maskz_unpackhi_epi16 (__mmask16 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_punpckhwd256_mask ((__v16hi) __A, (__v16hi) __B, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m128i @@ -2527,7 +2679,7 @@ _mm_maskz_unpackhi_epi16 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_punpckhwd128_mask ((__v8hi) __A, (__v8hi) __B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -2547,7 +2699,7 @@ _mm256_maskz_unpacklo_epi8 (__mmask32 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_punpcklbw256_mask ((__v32qi) __A, (__v32qi) __B, (__v32qi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask32) __U); } extern __inline __m128i @@ -2567,7 +2719,7 @@ _mm_maskz_unpacklo_epi8 (__mmask16 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_punpcklbw128_mask ((__v16qi) __A, (__v16qi) __B, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask16) __U); } extern __inline __m256i @@ -2587,7 +2739,7 @@ _mm256_maskz_unpacklo_epi16 (__mmask16 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_punpcklwd256_mask ((__v16hi) __A, (__v16hi) __B, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m128i @@ -2607,7 +2759,7 @@ _mm_maskz_unpacklo_epi16 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_punpcklwd128_mask ((__v8hi) __A, (__v8hi) __B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __mmask16 @@ -2939,7 +3091,7 @@ _mm256_maskz_shuffle_epi8 (__mmask32 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pshufb256_mask ((__v32qi) __A, (__v32qi) __B, (__v32qi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask32) __U); } extern __inline __m128i @@ -2959,7 +3111,7 @@ _mm_maskz_shuffle_epi8 (__mmask16 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pshufb128_mask ((__v16qi) __A, (__v16qi) __B, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask16) __U); } extern __inline __m256i @@ -2969,7 +3121,7 @@ _mm256_maskz_packs_epi16 (__mmask32 __M, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_packsswb256_mask ((__v16hi) __A, (__v16hi) __B, (__v32qi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __M); } extern __inline __m256i @@ -2989,7 +3141,7 @@ _mm_maskz_packs_epi16 (__mmask16 __M, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_packsswb128_mask ((__v8hi) __A, (__v8hi) __B, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -3009,7 +3161,7 @@ _mm256_maskz_packus_epi16 (__mmask32 __M, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_packuswb256_mask ((__v16hi) __A, (__v16hi) __B, (__v32qi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __M); } extern __inline __m256i @@ -3029,7 +3181,7 @@ _mm_maskz_packus_epi16 (__mmask16 __M, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_packuswb128_mask ((__v8hi) __A, (__v8hi) __B, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -3056,7 +3208,7 @@ _mm256_maskz_abs_epi8 (__mmask32 __U, __m256i __A) { return (__m256i) __builtin_ia32_pabsb256_mask ((__v32qi) __A, (__v32qi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask32) __U); } extern __inline __m128i @@ -3073,7 +3225,7 @@ _mm_maskz_abs_epi8 (__mmask16 __U, __m128i __A) { return (__m128i) __builtin_ia32_pabsb128_mask ((__v16qi) __A, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask16) __U); } extern __inline __m256i @@ -3090,7 +3242,7 @@ _mm256_maskz_abs_epi16 (__mmask16 __U, __m256i __A) { return (__m256i) __builtin_ia32_pabsw256_mask ((__v16hi) __A, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m128i @@ -3107,7 +3259,7 @@ _mm_maskz_abs_epi16 (__mmask8 __U, __m128i __A) { return (__m128i) __builtin_ia32_pabsw128_mask ((__v8hi) __A, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __mmask32 @@ -3229,7 +3381,7 @@ _mm_maskz_subs_epi8 (__mmask16 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_psubsb128_mask ((__v16qi) __A, (__v16qi) __B, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask16) __U); } extern __inline __m128i @@ -3249,7 +3401,7 @@ _mm_maskz_subs_epi16 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_psubsw128_mask ((__v8hi) __A, (__v8hi) __B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i @@ -3269,7 +3421,7 @@ _mm_maskz_subs_epu8 (__mmask16 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_psubusb128_mask ((__v16qi) __A, (__v16qi) __B, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask16) __U); } extern __inline __m128i @@ -3289,7 +3441,7 @@ _mm_maskz_subs_epu16 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_psubusw128_mask ((__v8hi) __A, (__v8hi) __B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -3309,7 +3461,7 @@ _mm256_maskz_srl_epi16 (__mmask16 __U, __m256i __A, __m128i __B) return (__m256i) __builtin_ia32_psrlw256_mask ((__v16hi) __A, (__v8hi) __B, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m128i @@ -3329,7 +3481,7 @@ _mm_maskz_srl_epi16 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_psrlw128_mask ((__v8hi) __A, (__v8hi) __B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -3349,7 +3501,7 @@ _mm256_maskz_sra_epi16 (__mmask16 __U, __m256i __A, __m128i __B) return (__m256i) __builtin_ia32_psraw256_mask ((__v16hi) __A, (__v8hi) __B, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m128i @@ -3369,7 +3521,7 @@ _mm_maskz_sra_epi16 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_psraw128_mask ((__v8hi) __A, (__v8hi) __B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i @@ -3379,7 +3531,7 @@ _mm_maskz_adds_epi16 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_paddsw128_mask ((__v8hi) __A, (__v8hi) __B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i @@ -3399,7 +3551,7 @@ _mm_maskz_adds_epu8 (__mmask16 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_paddusb128_mask ((__v16qi) __A, (__v16qi) __B, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask16) __U); } extern __inline __m128i @@ -3419,7 +3571,7 @@ _mm_maskz_adds_epu16 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_paddusw128_mask ((__v8hi) __A, (__v8hi) __B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i @@ -3439,7 +3591,7 @@ _mm_maskz_sub_epi8 (__mmask16 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_psubb128_mask ((__v16qi) __A, (__v16qi) __B, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask16) __U); } extern __inline __m128i @@ -3459,7 +3611,7 @@ _mm_maskz_sub_epi16 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_psubw128_mask ((__v8hi) __A, (__v8hi) __B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i @@ -3479,7 +3631,7 @@ _mm_maskz_adds_epi8 (__mmask16 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_paddsb128_mask ((__v16qi) __A, (__v16qi) __B, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask16) __U); } extern __inline __m128i @@ -3487,7 +3639,7 @@ __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm_cvtepi16_epi8 (__m128i __A) { return (__m128i) __builtin_ia32_pmovwb128_mask ((__v8hi) __A, - (__v16qi)_mm_undefined_si128(), + (__v16qi)_mm_avx512_undefined_si128(), (__mmask8) -1); } extern __inline void @@ -3509,7 +3661,7 @@ _mm_maskz_cvtepi16_epi8 (__mmask8 __M, __m128i __A) { return (__m128i) __builtin_ia32_pmovwb128_mask ((__v8hi) __A, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m256i @@ -3519,7 +3671,7 @@ _mm256_srav_epi16 (__m256i __A, __m256i __B) return (__m256i) __builtin_ia32_psrav16hi_mask ((__v16hi) __A, (__v16hi) __B, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) -1); } extern __inline __m256i @@ -3539,7 +3691,7 @@ _mm256_maskz_srav_epi16 (__mmask16 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_psrav16hi_mask ((__v16hi) __A, (__v16hi) __B, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m128i @@ -3549,7 +3701,7 @@ _mm_srav_epi16 (__m128i __A, __m128i __B) return (__m128i) __builtin_ia32_psrav8hi_mask ((__v8hi) __A, (__v8hi) __B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -3569,7 +3721,7 @@ _mm_maskz_srav_epi16 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_psrav8hi_mask ((__v8hi) __A, (__v8hi) __B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -3579,7 +3731,7 @@ _mm256_srlv_epi16 (__m256i __A, __m256i __B) return (__m256i) __builtin_ia32_psrlv16hi_mask ((__v16hi) __A, (__v16hi) __B, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) -1); } extern __inline __m256i @@ -3599,7 +3751,7 @@ _mm256_maskz_srlv_epi16 (__mmask16 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_psrlv16hi_mask ((__v16hi) __A, (__v16hi) __B, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m128i @@ -3609,7 +3761,7 @@ _mm_srlv_epi16 (__m128i __A, __m128i __B) return (__m128i) __builtin_ia32_psrlv8hi_mask ((__v8hi) __A, (__v8hi) __B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -3629,7 +3781,7 @@ _mm_maskz_srlv_epi16 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_psrlv8hi_mask ((__v8hi) __A, (__v8hi) __B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -3639,7 +3791,7 @@ _mm256_sllv_epi16 (__m256i __A, __m256i __B) return (__m256i) __builtin_ia32_psllv16hi_mask ((__v16hi) __A, (__v16hi) __B, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) -1); } extern __inline __m256i @@ -3659,7 +3811,7 @@ _mm256_maskz_sllv_epi16 (__mmask16 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_psllv16hi_mask ((__v16hi) __A, (__v16hi) __B, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m128i @@ -3669,7 +3821,7 @@ _mm_sllv_epi16 (__m128i __A, __m128i __B) return (__m128i) __builtin_ia32_psllv8hi_mask ((__v8hi) __A, (__v8hi) __B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -3689,7 +3841,7 @@ _mm_maskz_sllv_epi16 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_psllv8hi_mask ((__v8hi) __A, (__v8hi) __B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i @@ -3709,7 +3861,7 @@ _mm_maskz_sll_epi16 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_psllw128_mask ((__v8hi) __A, (__v8hi) __B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -3729,7 +3881,7 @@ _mm256_maskz_sll_epi16 (__mmask16 __U, __m256i __A, __m128i __B) return (__m256i) __builtin_ia32_psllw256_mask ((__v16hi) __A, (__v8hi) __B, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m256i @@ -3739,7 +3891,7 @@ _mm256_maskz_packus_epi32 (__mmask16 __M, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_packusdw256_mask ((__v8si) __A, (__v8si) __B, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __M); } extern __inline __m256i @@ -3759,7 +3911,7 @@ _mm_maskz_packus_epi32 (__mmask8 __M, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_packusdw128_mask ((__v4si) __A, (__v4si) __B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -3778,7 +3930,7 @@ _mm256_maskz_packs_epi32 (__mmask16 __M, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_packssdw256_mask ((__v8si) __A, (__v8si) __B, (__v16hi) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __M); } extern __inline __m256i @@ -3798,7 +3950,7 @@ _mm_maskz_packs_epi32 (__mmask8 __M, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_packssdw128_mask ((__v4si) __A, (__v4si) __B, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -4066,6 +4218,230 @@ _mm256_mask_cmple_epi16_mask (__mmask16 __M, __m256i __X, __m256i __Y) (__v16hi) __Y, 2, (__mmask16) __M); } +extern __inline short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_reduce_add_epi16 (__mmask8 __M, __m128i __W) +{ + __W = _mm_maskz_mov_epi16 (__M, __W); + _MM_REDUCE_OPERATOR_BASIC_EPI16 (+); +} +extern __inline short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_reduce_mul_epi16 (__mmask8 __M, __m128i __W) +{ + __W = _mm_mask_mov_epi16 (_mm_avx512_set1_epi16 (1), __M, __W); + _MM_REDUCE_OPERATOR_BASIC_EPI16 (*); +} +extern __inline short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_reduce_and_epi16 (__mmask8 __M, __m128i __W) +{ + __W = _mm_mask_mov_epi16 (_mm_avx512_set1_epi16 (-1), __M, __W); + _MM_REDUCE_OPERATOR_BASIC_EPI16 (&); +} +extern __inline short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_reduce_or_epi16 (__mmask8 __M, __m128i __W) +{ + __W = _mm_maskz_mov_epi16 (__M, __W); + _MM_REDUCE_OPERATOR_BASIC_EPI16 (|); +} +extern __inline short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_reduce_max_epi16 (__mmask16 __M, __m128i __V) +{ + __V = _mm_mask_mov_epi16 (_mm_avx512_set1_epi16 (-32767-1), __M, __V); + _MM_REDUCE_OPERATOR_MAX_MIN_EP16 (avx512_max_epi16); +} +extern __inline unsigned short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_reduce_max_epu16 (__mmask16 __M, __m128i __V) +{ + __V = _mm_maskz_mov_epi16 (__M, __V); + _MM_REDUCE_OPERATOR_MAX_MIN_EP16 (avx512_max_epu16); +} +extern __inline short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_reduce_min_epi16 (__mmask16 __M, __m128i __V) +{ + __V = _mm_mask_mov_epi16 (_mm_avx512_set1_epi16 (32767), __M, __V); + _MM_REDUCE_OPERATOR_MAX_MIN_EP16 (avx512_min_epi16); +} +extern __inline unsigned short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_reduce_min_epu16 (__mmask16 __M, __m128i __V) +{ + __V = _mm_mask_mov_epi16 (_mm_avx512_set1_epi16 (-1), __M, __V); + _MM_REDUCE_OPERATOR_MAX_MIN_EP16 (avx512_min_epu16); +} +extern __inline short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_mask_reduce_add_epi16 (__mmask16 __M, __m256i __W) +{ + __W = _mm256_maskz_mov_epi16 (__M, __W); + _MM256_AVX512_REDUCE_OPERATOR_BASIC_EPI16 (+); +} +extern __inline short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_mask_reduce_mul_epi16 (__mmask16 __M, __m256i __W) +{ + __W = _mm256_mask_mov_epi16 (_mm256_avx512_set1_epi16 (1), __M, __W); + _MM256_AVX512_REDUCE_OPERATOR_BASIC_EPI16 (*); +} +extern __inline short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_mask_reduce_and_epi16 (__mmask16 __M, __m256i __W) +{ + __W = _mm256_mask_mov_epi16 (_mm256_avx512_set1_epi16 (-1), __M, __W); + _MM256_AVX512_REDUCE_OPERATOR_BASIC_EPI16 (&); +} +extern __inline short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_mask_reduce_or_epi16 (__mmask16 __M, __m256i __W) +{ + __W = _mm256_maskz_mov_epi16 (__M, __W); + _MM256_AVX512_REDUCE_OPERATOR_BASIC_EPI16 (|); +} +extern __inline short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_mask_reduce_max_epi16 (__mmask16 __M, __m256i __V) +{ + __V = _mm256_mask_mov_epi16 (_mm256_avx512_set1_epi16 (-32767-1), __M, __V); + _MM256_AVX512_REDUCE_OPERATOR_MAX_MIN_EP16 (max_epi16); +} +extern __inline unsigned short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_mask_reduce_max_epu16 (__mmask16 __M, __m256i __V) +{ + __V = _mm256_maskz_mov_epi16 (__M, __V); + _MM256_AVX512_REDUCE_OPERATOR_MAX_MIN_EP16 (max_epu16); +} +extern __inline short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_mask_reduce_min_epi16 (__mmask16 __M, __m256i __V) +{ + __V = _mm256_mask_mov_epi16 (_mm256_avx512_set1_epi16 (32767), __M, __V); + _MM256_AVX512_REDUCE_OPERATOR_MAX_MIN_EP16 (min_epi16); +} +extern __inline unsigned short +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_mask_reduce_min_epu16 (__mmask16 __M, __m256i __V) +{ + __V = _mm256_mask_mov_epi16 (_mm256_avx512_set1_epi16 (-1), __M, __V); + _MM256_AVX512_REDUCE_OPERATOR_MAX_MIN_EP16 (min_epu16); +} +extern __inline char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_reduce_add_epi8 (__mmask16 __M, __m128i __W) +{ + __W = _mm_maskz_mov_epi8 (__M, __W); + _MM_REDUCE_OPERATOR_BASIC_EPI8 (+); +} +extern __inline char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_reduce_mul_epi8 (__mmask16 __M, __m128i __W) +{ + __W = _mm_mask_mov_epi8 (_mm_avx512_set1_epi8 (1), __M, __W); + _MM_REDUCE_OPERATOR_BASIC_EPI8 (*); +} +extern __inline char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_reduce_and_epi8 (__mmask16 __M, __m128i __W) +{ + __W = _mm_mask_mov_epi8 (_mm_avx512_set1_epi8 (-1), __M, __W); + _MM_REDUCE_OPERATOR_BASIC_EPI8 (&); +} +extern __inline char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_reduce_or_epi8 (__mmask16 __M, __m128i __W) +{ + __W = _mm_maskz_mov_epi8 (__M, __W); + _MM_REDUCE_OPERATOR_BASIC_EPI8 (|); +} +extern __inline signed char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_reduce_max_epi8 (__mmask16 __M, __m128i __V) +{ + __V = _mm_mask_mov_epi8 (_mm_avx512_set1_epi8 (-127-1), __M, __V); + _MM_REDUCE_OPERATOR_MAX_MIN_EP8 (avx512_max_epi8); +} +extern __inline unsigned char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_reduce_max_epu8 (__mmask16 __M, __m128i __V) +{ + __V = _mm_maskz_mov_epi8 (__M, __V); + _MM_REDUCE_OPERATOR_MAX_MIN_EP8 (avx512_max_epu8); +} +extern __inline signed char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_reduce_min_epi8 (__mmask16 __M, __m128i __V) +{ + __V = _mm_mask_mov_epi8 (_mm_avx512_set1_epi8 (127), __M, __V); + _MM_REDUCE_OPERATOR_MAX_MIN_EP8 (avx512_min_epi8); +} +extern __inline unsigned char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_reduce_min_epu8 (__mmask16 __M, __m128i __V) +{ + __V = _mm_mask_mov_epi8 (_mm_avx512_set1_epi8 (-1), __M, __V); + _MM_REDUCE_OPERATOR_MAX_MIN_EP8 (avx512_min_epu8); +} +extern __inline char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_mask_reduce_add_epi8 (__mmask32 __M, __m256i __W) +{ + __W = _mm256_maskz_mov_epi8 (__M, __W); + _MM256_AVX512_REDUCE_OPERATOR_BASIC_EPI8 (+); +} +extern __inline char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_mask_reduce_mul_epi8 (__mmask32 __M, __m256i __W) +{ + __W = _mm256_mask_mov_epi8 (_mm256_avx512_set1_epi8 (1), __M, __W); + _MM256_AVX512_REDUCE_OPERATOR_BASIC_EPI8 (*); +} +extern __inline char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_mask_reduce_and_epi8 (__mmask32 __M, __m256i __W) +{ + __W = _mm256_mask_mov_epi8 (_mm256_avx512_set1_epi8 (-1), __M, __W); + _MM256_AVX512_REDUCE_OPERATOR_BASIC_EPI8 (&); +} +extern __inline char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_mask_reduce_or_epi8 (__mmask32 __M, __m256i __W) +{ + __W = _mm256_maskz_mov_epi8 (__M, __W); + _MM256_AVX512_REDUCE_OPERATOR_BASIC_EPI8 (|); +} +extern __inline signed char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_mask_reduce_max_epi8 (__mmask32 __M, __m256i __V) +{ + __V = _mm256_mask_mov_epi8 (_mm256_avx512_set1_epi8 (-127-1), __M, __V); + _MM256_AVX512_REDUCE_OPERATOR_MAX_MIN_EP8 (max_epi8); +} +extern __inline unsigned char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_mask_reduce_max_epu8 (__mmask32 __M, __m256i __V) +{ + __V = _mm256_maskz_mov_epi8 (__M, __V); + _MM256_AVX512_REDUCE_OPERATOR_MAX_MIN_EP8 (max_epu8); +} +extern __inline signed char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_mask_reduce_min_epi8 (__mmask32 __M, __m256i __V) +{ + __V = _mm256_mask_mov_epi8 (_mm256_avx512_set1_epi8 (127), __M, __V); + _MM256_AVX512_REDUCE_OPERATOR_MAX_MIN_EP8 (min_epi8); +} +extern __inline unsigned char +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_mask_reduce_min_epu8 (__mmask32 __M, __m256i __V) +{ + __V = _mm256_mask_mov_epi8 (_mm256_avx512_set1_epi8 (-1), __M, __V); + _MM256_AVX512_REDUCE_OPERATOR_MAX_MIN_EP8 (min_epu8); +} #ifdef __DISABLE_AVX512VLBW__ #undef __DISABLE_AVX512VLBW__ #pragma GCC pop_options diff --git a/third_party/intel/avx512vldqintrin.internal.h b/third_party/intel/avx512vldqintrin.internal.h index a3e0ba447..7d9c282a2 100644 --- a/third_party/intel/avx512vldqintrin.internal.h +++ b/third_party/intel/avx512vldqintrin.internal.h @@ -4,9 +4,9 @@ #endif #ifndef _AVX512VLDQINTRIN_H_INCLUDED #define _AVX512VLDQINTRIN_H_INCLUDED -#if !defined(__AVX512VL__) || !defined(__AVX512DQ__) +#if !defined(__AVX512VL__) || !defined(__AVX512DQ__) || defined (__EVEX512__) #pragma GCC push_options -#pragma GCC target("avx512vl,avx512dq") +#pragma GCC target("avx512vl,avx512dq,no-evex512") #define __DISABLE_AVX512VLDQ__ #endif extern __inline __m256i @@ -15,7 +15,7 @@ _mm256_cvttpd_epi64 (__m256d __A) { return (__m256i) __builtin_ia32_cvttpd2qq256_mask ((__v4df) __A, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -32,7 +32,7 @@ _mm256_maskz_cvttpd_epi64 (__mmask8 __U, __m256d __A) { return (__m256i) __builtin_ia32_cvttpd2qq256_mask ((__v4df) __A, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -41,7 +41,7 @@ _mm_cvttpd_epi64 (__m128d __A) { return (__m128i) __builtin_ia32_cvttpd2qq128_mask ((__v2df) __A, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -58,7 +58,7 @@ _mm_maskz_cvttpd_epi64 (__mmask8 __U, __m128d __A) { return (__m128i) __builtin_ia32_cvttpd2qq128_mask ((__v2df) __A, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -67,7 +67,7 @@ _mm256_cvttpd_epu64 (__m256d __A) { return (__m256i) __builtin_ia32_cvttpd2uqq256_mask ((__v4df) __A, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -84,7 +84,7 @@ _mm256_maskz_cvttpd_epu64 (__mmask8 __U, __m256d __A) { return (__m256i) __builtin_ia32_cvttpd2uqq256_mask ((__v4df) __A, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -93,7 +93,7 @@ _mm_cvttpd_epu64 (__m128d __A) { return (__m128i) __builtin_ia32_cvttpd2uqq128_mask ((__v2df) __A, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -110,7 +110,7 @@ _mm_maskz_cvttpd_epu64 (__mmask8 __U, __m128d __A) { return (__m128i) __builtin_ia32_cvttpd2uqq128_mask ((__v2df) __A, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -119,7 +119,7 @@ _mm256_cvtpd_epi64 (__m256d __A) { return (__m256i) __builtin_ia32_cvtpd2qq256_mask ((__v4df) __A, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -136,7 +136,7 @@ _mm256_maskz_cvtpd_epi64 (__mmask8 __U, __m256d __A) { return (__m256i) __builtin_ia32_cvtpd2qq256_mask ((__v4df) __A, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -145,7 +145,7 @@ _mm_cvtpd_epi64 (__m128d __A) { return (__m128i) __builtin_ia32_cvtpd2qq128_mask ((__v2df) __A, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -162,7 +162,7 @@ _mm_maskz_cvtpd_epi64 (__mmask8 __U, __m128d __A) { return (__m128i) __builtin_ia32_cvtpd2qq128_mask ((__v2df) __A, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -171,7 +171,7 @@ _mm256_cvtpd_epu64 (__m256d __A) { return (__m256i) __builtin_ia32_cvtpd2uqq256_mask ((__v4df) __A, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -188,7 +188,7 @@ _mm256_maskz_cvtpd_epu64 (__mmask8 __U, __m256d __A) { return (__m256i) __builtin_ia32_cvtpd2uqq256_mask ((__v4df) __A, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -197,7 +197,7 @@ _mm_cvtpd_epu64 (__m128d __A) { return (__m128i) __builtin_ia32_cvtpd2uqq128_mask ((__v2df) __A, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -214,7 +214,7 @@ _mm_maskz_cvtpd_epu64 (__mmask8 __U, __m128d __A) { return (__m128i) __builtin_ia32_cvtpd2uqq128_mask ((__v2df) __A, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -223,7 +223,7 @@ _mm256_cvttps_epi64 (__m128 __A) { return (__m256i) __builtin_ia32_cvttps2qq256_mask ((__v4sf) __A, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -240,7 +240,7 @@ _mm256_maskz_cvttps_epi64 (__mmask8 __U, __m128 __A) { return (__m256i) __builtin_ia32_cvttps2qq256_mask ((__v4sf) __A, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -249,7 +249,7 @@ _mm_cvttps_epi64 (__m128 __A) { return (__m128i) __builtin_ia32_cvttps2qq128_mask ((__v4sf) __A, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -266,7 +266,7 @@ _mm_maskz_cvttps_epi64 (__mmask8 __U, __m128 __A) { return (__m128i) __builtin_ia32_cvttps2qq128_mask ((__v4sf) __A, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -275,7 +275,7 @@ _mm256_cvttps_epu64 (__m128 __A) { return (__m256i) __builtin_ia32_cvttps2uqq256_mask ((__v4sf) __A, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -292,7 +292,7 @@ _mm256_maskz_cvttps_epu64 (__mmask8 __U, __m128 __A) { return (__m256i) __builtin_ia32_cvttps2uqq256_mask ((__v4sf) __A, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -301,7 +301,7 @@ _mm_cvttps_epu64 (__m128 __A) { return (__m128i) __builtin_ia32_cvttps2uqq128_mask ((__v4sf) __A, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -318,7 +318,7 @@ _mm_maskz_cvttps_epu64 (__mmask8 __U, __m128 __A) { return (__m128i) __builtin_ia32_cvttps2uqq128_mask ((__v4sf) __A, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256d @@ -327,7 +327,7 @@ _mm256_broadcast_f64x2 (__m128d __A) { return (__m256d) __builtin_ia32_broadcastf64x2_256_mask ((__v2df) __A, - (__v4df)_mm256_undefined_pd(), + (__v4df)_mm256_avx512_undefined_pd(), (__mmask8) -1); } extern __inline __m256d @@ -346,7 +346,7 @@ _mm256_maskz_broadcast_f64x2 (__mmask8 __M, __m128d __A) return (__m256d) __builtin_ia32_broadcastf64x2_256_mask ((__v2df) __A, (__v4df) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), __M); } extern __inline __m256i @@ -355,7 +355,7 @@ _mm256_broadcast_i64x2 (__m128i __A) { return (__m256i) __builtin_ia32_broadcasti64x2_256_mask ((__v2di) __A, - (__v4di)_mm256_undefined_si256(), + (__v4di)_mm256_avx512_undefined_si256(), (__mmask8) -1); } extern __inline __m256i @@ -374,7 +374,7 @@ _mm256_maskz_broadcast_i64x2 (__mmask8 __M, __m128i __A) return (__m256i) __builtin_ia32_broadcasti64x2_256_mask ((__v2di) __A, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __M); } extern __inline __m256 @@ -382,7 +382,7 @@ __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_broadcast_f32x2 (__m128 __A) { return (__m256) __builtin_ia32_broadcastf32x2_256_mask ((__v4sf) __A, - (__v8sf)_mm256_undefined_ps(), + (__v8sf)_mm256_avx512_undefined_ps(), (__mmask8) -1); } extern __inline __m256 @@ -399,7 +399,7 @@ _mm256_maskz_broadcast_f32x2 (__mmask8 __M, __m128 __A) { return (__m256) __builtin_ia32_broadcastf32x2_256_mask ((__v4sf) __A, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), __M); } extern __inline __m256i @@ -408,7 +408,7 @@ _mm256_broadcast_i32x2 (__m128i __A) { return (__m256i) __builtin_ia32_broadcasti32x2_256_mask ((__v4si) __A, - (__v8si)_mm256_undefined_si256(), + (__v8si)_mm256_avx512_undefined_si256(), (__mmask8) -1); } extern __inline __m256i @@ -427,7 +427,7 @@ _mm256_maskz_broadcast_i32x2 (__mmask8 __M, __m128i __A) return (__m256i) __builtin_ia32_broadcasti32x2_256_mask ((__v4si) __A, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __M); } extern __inline __m128i @@ -436,7 +436,7 @@ _mm_broadcast_i32x2 (__m128i __A) { return (__m128i) __builtin_ia32_broadcasti32x2_128_mask ((__v4si) __A, - (__v4si)_mm_undefined_si128(), + (__v4si)_mm_avx512_undefined_si128(), (__mmask8) -1); } extern __inline __m128i @@ -455,7 +455,7 @@ _mm_maskz_broadcast_i32x2 (__mmask8 __M, __m128i __A) return (__m128i) __builtin_ia32_broadcasti32x2_128_mask ((__v4si) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m256i @@ -481,7 +481,7 @@ _mm256_maskz_mullo_epi64 (__mmask8 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pmullq256_mask ((__v4di) __A, (__v4di) __B, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -507,7 +507,7 @@ _mm_maskz_mullo_epi64 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pmullq128_mask ((__v2di) __A, (__v2di) __B, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256d @@ -527,7 +527,7 @@ _mm256_maskz_andnot_pd (__mmask8 __U, __m256d __A, __m256d __B) return (__m256d) __builtin_ia32_andnpd256_mask ((__v4df) __A, (__v4df) __B, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128d @@ -547,7 +547,7 @@ _mm_maskz_andnot_pd (__mmask8 __U, __m128d __A, __m128d __B) return (__m128d) __builtin_ia32_andnpd128_mask ((__v2df) __A, (__v2df) __B, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256 @@ -567,7 +567,7 @@ _mm256_maskz_andnot_ps (__mmask8 __U, __m256 __A, __m256 __B) return (__m256) __builtin_ia32_andnps256_mask ((__v8sf) __A, (__v8sf) __B, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128 @@ -586,7 +586,7 @@ _mm_maskz_andnot_ps (__mmask8 __U, __m128 __A, __m128 __B) return (__m128) __builtin_ia32_andnps128_mask ((__v4sf) __A, (__v4sf) __B, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m256i @@ -595,7 +595,7 @@ _mm256_cvtps_epi64 (__m128 __A) { return (__m256i) __builtin_ia32_cvtps2qq256_mask ((__v4sf) __A, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -612,7 +612,7 @@ _mm256_maskz_cvtps_epi64 (__mmask8 __U, __m128 __A) { return (__m256i) __builtin_ia32_cvtps2qq256_mask ((__v4sf) __A, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -621,7 +621,7 @@ _mm_cvtps_epi64 (__m128 __A) { return (__m128i) __builtin_ia32_cvtps2qq128_mask ((__v4sf) __A, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -638,7 +638,7 @@ _mm_maskz_cvtps_epi64 (__mmask8 __U, __m128 __A) { return (__m128i) __builtin_ia32_cvtps2qq128_mask ((__v4sf) __A, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -647,7 +647,7 @@ _mm256_cvtps_epu64 (__m128 __A) { return (__m256i) __builtin_ia32_cvtps2uqq256_mask ((__v4sf) __A, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -664,7 +664,7 @@ _mm256_maskz_cvtps_epu64 (__mmask8 __U, __m128 __A) { return (__m256i) __builtin_ia32_cvtps2uqq256_mask ((__v4sf) __A, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -673,7 +673,7 @@ _mm_cvtps_epu64 (__m128 __A) { return (__m128i) __builtin_ia32_cvtps2uqq128_mask ((__v4sf) __A, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -690,7 +690,7 @@ _mm_maskz_cvtps_epu64 (__mmask8 __U, __m128 __A) { return (__m128i) __builtin_ia32_cvtps2uqq128_mask ((__v4sf) __A, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128 @@ -699,7 +699,7 @@ _mm256_cvtepi64_ps (__m256i __A) { return (__m128) __builtin_ia32_cvtqq2ps256_mask ((__v4di) __A, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) -1); } extern __inline __m128 @@ -716,7 +716,7 @@ _mm256_maskz_cvtepi64_ps (__mmask8 __U, __m256i __A) { return (__m128) __builtin_ia32_cvtqq2ps256_mask ((__v4di) __A, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128 @@ -725,7 +725,7 @@ _mm_cvtepi64_ps (__m128i __A) { return (__m128) __builtin_ia32_cvtqq2ps128_mask ((__v2di) __A, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) -1); } extern __inline __m128 @@ -742,7 +742,7 @@ _mm_maskz_cvtepi64_ps (__mmask8 __U, __m128i __A) { return (__m128) __builtin_ia32_cvtqq2ps128_mask ((__v2di) __A, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128 @@ -751,7 +751,7 @@ _mm256_cvtepu64_ps (__m256i __A) { return (__m128) __builtin_ia32_cvtuqq2ps256_mask ((__v4di) __A, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) -1); } extern __inline __m128 @@ -768,7 +768,7 @@ _mm256_maskz_cvtepu64_ps (__mmask8 __U, __m256i __A) { return (__m128) __builtin_ia32_cvtuqq2ps256_mask ((__v4di) __A, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128 @@ -777,7 +777,7 @@ _mm_cvtepu64_ps (__m128i __A) { return (__m128) __builtin_ia32_cvtuqq2ps128_mask ((__v2di) __A, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) -1); } extern __inline __m128 @@ -794,7 +794,7 @@ _mm_maskz_cvtepu64_ps (__mmask8 __U, __m128i __A) { return (__m128) __builtin_ia32_cvtuqq2ps128_mask ((__v2di) __A, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m256d @@ -803,7 +803,7 @@ _mm256_cvtepi64_pd (__m256i __A) { return (__m256d) __builtin_ia32_cvtqq2pd256_mask ((__v4di) __A, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) -1); } extern __inline __m256d @@ -820,7 +820,7 @@ _mm256_maskz_cvtepi64_pd (__mmask8 __U, __m256i __A) { return (__m256d) __builtin_ia32_cvtqq2pd256_mask ((__v4di) __A, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128d @@ -829,7 +829,7 @@ _mm_cvtepi64_pd (__m128i __A) { return (__m128d) __builtin_ia32_cvtqq2pd128_mask ((__v2di) __A, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) -1); } extern __inline __m128d @@ -846,7 +846,7 @@ _mm_maskz_cvtepi64_pd (__mmask8 __U, __m128i __A) { return (__m128d) __builtin_ia32_cvtqq2pd128_mask ((__v2di) __A, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256d @@ -855,7 +855,7 @@ _mm256_cvtepu64_pd (__m256i __A) { return (__m256d) __builtin_ia32_cvtuqq2pd256_mask ((__v4di) __A, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) -1); } extern __inline __m256d @@ -872,7 +872,7 @@ _mm256_maskz_cvtepu64_pd (__mmask8 __U, __m256i __A) { return (__m256d) __builtin_ia32_cvtuqq2pd256_mask ((__v4di) __A, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256d @@ -892,7 +892,7 @@ _mm256_maskz_and_pd (__mmask8 __U, __m256d __A, __m256d __B) return (__m256d) __builtin_ia32_andpd256_mask ((__v4df) __A, (__v4df) __B, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128d @@ -911,7 +911,7 @@ _mm_maskz_and_pd (__mmask8 __U, __m128d __A, __m128d __B) return (__m128d) __builtin_ia32_andpd128_mask ((__v2df) __A, (__v2df) __B, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256 @@ -930,7 +930,7 @@ _mm256_maskz_and_ps (__mmask8 __U, __m256 __A, __m256 __B) return (__m256) __builtin_ia32_andps256_mask ((__v8sf) __A, (__v8sf) __B, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128 @@ -949,7 +949,7 @@ _mm_maskz_and_ps (__mmask8 __U, __m128 __A, __m128 __B) return (__m128) __builtin_ia32_andps128_mask ((__v4sf) __A, (__v4sf) __B, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128d @@ -958,7 +958,7 @@ _mm_cvtepu64_pd (__m128i __A) { return (__m128d) __builtin_ia32_cvtuqq2pd128_mask ((__v2di) __A, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) -1); } extern __inline __m128d @@ -975,7 +975,7 @@ _mm_maskz_cvtepu64_pd (__mmask8 __U, __m128i __A) { return (__m128d) __builtin_ia32_cvtuqq2pd128_mask ((__v2di) __A, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256d @@ -995,7 +995,7 @@ _mm256_maskz_xor_pd (__mmask8 __U, __m256d __A, __m256d __B) return (__m256d) __builtin_ia32_xorpd256_mask ((__v4df) __A, (__v4df) __B, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128d @@ -1014,7 +1014,7 @@ _mm_maskz_xor_pd (__mmask8 __U, __m128d __A, __m128d __B) return (__m128d) __builtin_ia32_xorpd128_mask ((__v2df) __A, (__v2df) __B, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256 @@ -1033,7 +1033,7 @@ _mm256_maskz_xor_ps (__mmask8 __U, __m256 __A, __m256 __B) return (__m256) __builtin_ia32_xorps256_mask ((__v8sf) __A, (__v8sf) __B, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128 @@ -1052,7 +1052,7 @@ _mm_maskz_xor_ps (__mmask8 __U, __m128 __A, __m128 __B) return (__m128) __builtin_ia32_xorps128_mask ((__v4sf) __A, (__v4sf) __B, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m256d @@ -1071,7 +1071,7 @@ _mm256_maskz_or_pd (__mmask8 __U, __m256d __A, __m256d __B) return (__m256d) __builtin_ia32_orpd256_mask ((__v4df) __A, (__v4df) __B, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128d @@ -1090,7 +1090,7 @@ _mm_maskz_or_pd (__mmask8 __U, __m128d __A, __m128d __B) return (__m128d) __builtin_ia32_orpd128_mask ((__v2df) __A, (__v2df) __B, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256 @@ -1109,7 +1109,7 @@ _mm256_maskz_or_ps (__mmask8 __U, __m256 __A, __m256 __B) return (__m256) __builtin_ia32_orps256_mask ((__v8sf) __A, (__v8sf) __B, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128 @@ -1128,7 +1128,7 @@ _mm_maskz_or_ps (__mmask8 __U, __m128 __A, __m128 __B) return (__m128) __builtin_ia32_orps128_mask ((__v4sf) __A, (__v4sf) __B, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128i @@ -1187,7 +1187,7 @@ _mm256_extractf64x2_pd (__m256d __A, const int __imm) return (__m128d) __builtin_ia32_extractf64x2_256_mask ((__v4df) __A, __imm, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) -1); } extern __inline __m128d @@ -1209,7 +1209,7 @@ _mm256_maskz_extractf64x2_pd (__mmask8 __U, __m256d __A, return (__m128d) __builtin_ia32_extractf64x2_256_mask ((__v4df) __A, __imm, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } @@ -1220,7 +1220,7 @@ _mm256_extracti64x2_epi64 (__m256i __A, const int __imm) return (__m128i) __builtin_ia32_extracti64x2_256_mask ((__v4di) __A, __imm, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -1242,7 +1242,7 @@ _mm256_maskz_extracti64x2_epi64 (__mmask8 __U, __m256i __A, return (__m128i) __builtin_ia32_extracti64x2_256_mask ((__v4di) __A, __imm, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } @@ -1252,7 +1252,7 @@ _mm256_reduce_pd (__m256d __A, int __B) { return (__m256d) __builtin_ia32_reducepd256_mask ((__v4df) __A, __B, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) -1); } extern __inline __m256d @@ -1269,7 +1269,7 @@ _mm256_maskz_reduce_pd (__mmask8 __U, __m256d __A, int __B) { return (__m256d) __builtin_ia32_reducepd256_mask ((__v4df) __A, __B, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128d @@ -1278,7 +1278,7 @@ _mm_reduce_pd (__m128d __A, int __B) { return (__m128d) __builtin_ia32_reducepd128_mask ((__v2df) __A, __B, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) -1); } extern __inline __m128d @@ -1295,7 +1295,7 @@ _mm_maskz_reduce_pd (__mmask8 __U, __m128d __A, int __B) { return (__m128d) __builtin_ia32_reducepd128_mask ((__v2df) __A, __B, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256 @@ -1304,7 +1304,7 @@ _mm256_reduce_ps (__m256 __A, int __B) { return (__m256) __builtin_ia32_reduceps256_mask ((__v8sf) __A, __B, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) -1); } extern __inline __m256 @@ -1321,7 +1321,7 @@ _mm256_maskz_reduce_ps (__mmask8 __U, __m256 __A, int __B) { return (__m256) __builtin_ia32_reduceps256_mask ((__v8sf) __A, __B, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128 @@ -1330,7 +1330,7 @@ _mm_reduce_ps (__m128 __A, int __B) { return (__m128) __builtin_ia32_reduceps128_mask ((__v4sf) __A, __B, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) -1); } extern __inline __m128 @@ -1347,7 +1347,7 @@ _mm_maskz_reduce_ps (__mmask8 __U, __m128 __A, int __B) { return (__m128) __builtin_ia32_reduceps128_mask ((__v4sf) __A, __B, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m256d @@ -1357,7 +1357,7 @@ _mm256_range_pd (__m256d __A, __m256d __B, int __C) return (__m256d) __builtin_ia32_rangepd256_mask ((__v4df) __A, (__v4df) __B, __C, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) -1); } extern __inline __m256d @@ -1377,7 +1377,7 @@ _mm256_maskz_range_pd (__mmask8 __U, __m256d __A, __m256d __B, int __C) return (__m256d) __builtin_ia32_rangepd256_mask ((__v4df) __A, (__v4df) __B, __C, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128d @@ -1387,7 +1387,7 @@ _mm_range_pd (__m128d __A, __m128d __B, int __C) return (__m128d) __builtin_ia32_rangepd128_mask ((__v2df) __A, (__v2df) __B, __C, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) -1); } extern __inline __m128d @@ -1407,7 +1407,7 @@ _mm_maskz_range_pd (__mmask8 __U, __m128d __A, __m128d __B, int __C) return (__m128d) __builtin_ia32_rangepd128_mask ((__v2df) __A, (__v2df) __B, __C, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256 @@ -1417,7 +1417,7 @@ _mm256_range_ps (__m256 __A, __m256 __B, int __C) return (__m256) __builtin_ia32_rangeps256_mask ((__v8sf) __A, (__v8sf) __B, __C, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) -1); } extern __inline __m256 @@ -1437,7 +1437,7 @@ _mm256_maskz_range_ps (__mmask8 __U, __m256 __A, __m256 __B, int __C) return (__m256) __builtin_ia32_rangeps256_mask ((__v8sf) __A, (__v8sf) __B, __C, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128 @@ -1447,7 +1447,7 @@ _mm_range_ps (__m128 __A, __m128 __B, int __C) return (__m128) __builtin_ia32_rangeps128_mask ((__v4sf) __A, (__v4sf) __B, __C, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) -1); } extern __inline __m128 @@ -1467,7 +1467,7 @@ _mm_maskz_range_ps (__mmask8 __U, __m128 __A, __m128 __B, int __C) return (__m128) __builtin_ia32_rangeps128_mask ((__v4sf) __A, (__v4sf) __B, __C, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __mmask8 @@ -1539,7 +1539,7 @@ _mm256_inserti64x2 (__m256i __A, __m128i __B, const int __imm) (__v2di) __B, __imm, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -1563,7 +1563,7 @@ _mm256_maskz_inserti64x2 (__mmask8 __U, __m256i __A, __m128i __B, (__v2di) __B, __imm, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } @@ -1575,7 +1575,7 @@ _mm256_insertf64x2 (__m256d __A, __m128d __B, const int __imm) (__v2df) __B, __imm, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) -1); } extern __inline __m256d @@ -1599,47 +1599,47 @@ _mm256_maskz_insertf64x2 (__mmask8 __U, __m256d __A, __m128d __B, (__v2df) __B, __imm, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } #else -#define _mm256_insertf64x2(X, Y, C) ((__m256d) __builtin_ia32_insertf64x2_256_mask ((__v4df)(__m256d) (X), (__v2df)(__m128d) (Y), (int) (C), (__v4df)(__m256d)_mm256_setzero_pd(), (__mmask8)-1)) +#define _mm256_insertf64x2(X, Y, C) ((__m256d) __builtin_ia32_insertf64x2_256_mask ((__v4df)(__m256d) (X), (__v2df)(__m128d) (Y), (int) (C), (__v4df)(__m256d)_mm256_avx512_setzero_pd(), (__mmask8)-1)) #define _mm256_mask_insertf64x2(W, U, X, Y, C) ((__m256d) __builtin_ia32_insertf64x2_256_mask ((__v4df)(__m256d) (X), (__v2df)(__m128d) (Y), (int) (C), (__v4df)(__m256d)(W), (__mmask8)(U))) -#define _mm256_maskz_insertf64x2(U, X, Y, C) ((__m256d) __builtin_ia32_insertf64x2_256_mask ((__v4df)(__m256d) (X), (__v2df)(__m128d) (Y), (int) (C), (__v4df)(__m256d)_mm256_setzero_pd(), (__mmask8)(U))) -#define _mm256_inserti64x2(X, Y, C) ((__m256i) __builtin_ia32_inserti64x2_256_mask ((__v4di)(__m256i) (X), (__v2di)(__m128i) (Y), (int) (C), (__v4di)(__m256i)_mm256_setzero_si256 (), (__mmask8)-1)) +#define _mm256_maskz_insertf64x2(U, X, Y, C) ((__m256d) __builtin_ia32_insertf64x2_256_mask ((__v4df)(__m256d) (X), (__v2df)(__m128d) (Y), (int) (C), (__v4df)(__m256d)_mm256_avx512_setzero_pd(), (__mmask8)(U))) +#define _mm256_inserti64x2(X, Y, C) ((__m256i) __builtin_ia32_inserti64x2_256_mask ((__v4di)(__m256i) (X), (__v2di)(__m128i) (Y), (int) (C), (__v4di)(__m256i)_mm256_avx512_setzero_si256 (), (__mmask8)-1)) #define _mm256_mask_inserti64x2(W, U, X, Y, C) ((__m256i) __builtin_ia32_inserti64x2_256_mask ((__v4di)(__m256i) (X), (__v2di)(__m128i) (Y), (int) (C), (__v4di)(__m256i)(W), (__mmask8)(U))) -#define _mm256_maskz_inserti64x2(U, X, Y, C) ((__m256i) __builtin_ia32_inserti64x2_256_mask ((__v4di)(__m256i) (X), (__v2di)(__m128i) (Y), (int) (C), (__v4di)(__m256i)_mm256_setzero_si256 (), (__mmask8)(U))) -#define _mm256_extractf64x2_pd(X, C) ((__m128d) __builtin_ia32_extractf64x2_256_mask ((__v4df)(__m256d) (X), (int) (C), (__v2df)(__m128d) _mm_setzero_pd(), (__mmask8)-1)) +#define _mm256_maskz_inserti64x2(U, X, Y, C) ((__m256i) __builtin_ia32_inserti64x2_256_mask ((__v4di)(__m256i) (X), (__v2di)(__m128i) (Y), (int) (C), (__v4di)(__m256i)_mm256_avx512_setzero_si256 (), (__mmask8)(U))) +#define _mm256_extractf64x2_pd(X, C) ((__m128d) __builtin_ia32_extractf64x2_256_mask ((__v4df)(__m256d) (X), (int) (C), (__v2df)(__m128d) _mm_avx512_setzero_pd(), (__mmask8)-1)) #define _mm256_mask_extractf64x2_pd(W, U, X, C) ((__m128d) __builtin_ia32_extractf64x2_256_mask ((__v4df)(__m256d) (X), (int) (C), (__v2df)(__m128d) (W), (__mmask8) (U))) -#define _mm256_maskz_extractf64x2_pd(U, X, C) ((__m128d) __builtin_ia32_extractf64x2_256_mask ((__v4df)(__m256d) (X), (int) (C), (__v2df)(__m128d) _mm_setzero_pd(), (__mmask8) (U))) -#define _mm256_extracti64x2_epi64(X, C) ((__m128i) __builtin_ia32_extracti64x2_256_mask ((__v4di)(__m256i) (X), (int) (C), (__v2di)(__m128i) _mm_setzero_si128 (), (__mmask8)-1)) +#define _mm256_maskz_extractf64x2_pd(U, X, C) ((__m128d) __builtin_ia32_extractf64x2_256_mask ((__v4df)(__m256d) (X), (int) (C), (__v2df)(__m128d) _mm_avx512_setzero_pd(), (__mmask8) (U))) +#define _mm256_extracti64x2_epi64(X, C) ((__m128i) __builtin_ia32_extracti64x2_256_mask ((__v4di)(__m256i) (X), (int) (C), (__v2di)(__m128i) _mm_avx512_setzero_si128 (), (__mmask8)-1)) #define _mm256_mask_extracti64x2_epi64(W, U, X, C) ((__m128i) __builtin_ia32_extracti64x2_256_mask ((__v4di)(__m256i) (X), (int) (C), (__v2di)(__m128i) (W), (__mmask8) (U))) -#define _mm256_maskz_extracti64x2_epi64(U, X, C) ((__m128i) __builtin_ia32_extracti64x2_256_mask ((__v4di)(__m256i) (X), (int) (C), (__v2di)(__m128i) _mm_setzero_si128 (), (__mmask8) (U))) -#define _mm256_reduce_pd(A, B) ((__m256d) __builtin_ia32_reducepd256_mask ((__v4df)(__m256d)(A), (int)(B), (__v4df)_mm256_setzero_pd(), (__mmask8)-1)) +#define _mm256_maskz_extracti64x2_epi64(U, X, C) ((__m128i) __builtin_ia32_extracti64x2_256_mask ((__v4di)(__m256i) (X), (int) (C), (__v2di)(__m128i) _mm_avx512_setzero_si128 (), (__mmask8) (U))) +#define _mm256_reduce_pd(A, B) ((__m256d) __builtin_ia32_reducepd256_mask ((__v4df)(__m256d)(A), (int)(B), (__v4df)_mm256_avx512_setzero_pd(), (__mmask8)-1)) #define _mm256_mask_reduce_pd(W, U, A, B) ((__m256d) __builtin_ia32_reducepd256_mask ((__v4df)(__m256d)(A), (int)(B), (__v4df)(__m256d)(W), (__mmask8)(U))) -#define _mm256_maskz_reduce_pd(U, A, B) ((__m256d) __builtin_ia32_reducepd256_mask ((__v4df)(__m256d)(A), (int)(B), (__v4df)_mm256_setzero_pd(), (__mmask8)(U))) -#define _mm_reduce_pd(A, B) ((__m128d) __builtin_ia32_reducepd128_mask ((__v2df)(__m128d)(A), (int)(B), (__v2df)_mm_setzero_pd(), (__mmask8)-1)) +#define _mm256_maskz_reduce_pd(U, A, B) ((__m256d) __builtin_ia32_reducepd256_mask ((__v4df)(__m256d)(A), (int)(B), (__v4df)_mm256_avx512_setzero_pd(), (__mmask8)(U))) +#define _mm_reduce_pd(A, B) ((__m128d) __builtin_ia32_reducepd128_mask ((__v2df)(__m128d)(A), (int)(B), (__v2df)_mm_avx512_setzero_pd(), (__mmask8)-1)) #define _mm_mask_reduce_pd(W, U, A, B) ((__m128d) __builtin_ia32_reducepd128_mask ((__v2df)(__m128d)(A), (int)(B), (__v2df)(__m128d)(W), (__mmask8)(U))) -#define _mm_maskz_reduce_pd(U, A, B) ((__m128d) __builtin_ia32_reducepd128_mask ((__v2df)(__m128d)(A), (int)(B), (__v2df)_mm_setzero_pd(), (__mmask8)(U))) -#define _mm256_reduce_ps(A, B) ((__m256) __builtin_ia32_reduceps256_mask ((__v8sf)(__m256)(A), (int)(B), (__v8sf)_mm256_setzero_ps(), (__mmask8)-1)) +#define _mm_maskz_reduce_pd(U, A, B) ((__m128d) __builtin_ia32_reducepd128_mask ((__v2df)(__m128d)(A), (int)(B), (__v2df)_mm_avx512_setzero_pd(), (__mmask8)(U))) +#define _mm256_reduce_ps(A, B) ((__m256) __builtin_ia32_reduceps256_mask ((__v8sf)(__m256)(A), (int)(B), (__v8sf)_mm256_avx512_setzero_ps(), (__mmask8)-1)) #define _mm256_mask_reduce_ps(W, U, A, B) ((__m256) __builtin_ia32_reduceps256_mask ((__v8sf)(__m256)(A), (int)(B), (__v8sf)(__m256)(W), (__mmask8)(U))) -#define _mm256_maskz_reduce_ps(U, A, B) ((__m256) __builtin_ia32_reduceps256_mask ((__v8sf)(__m256)(A), (int)(B), (__v8sf)_mm256_setzero_ps(), (__mmask8)(U))) -#define _mm_reduce_ps(A, B) ((__m128) __builtin_ia32_reduceps128_mask ((__v4sf)(__m128)(A), (int)(B), (__v4sf)_mm_setzero_ps(), (__mmask8)-1)) +#define _mm256_maskz_reduce_ps(U, A, B) ((__m256) __builtin_ia32_reduceps256_mask ((__v8sf)(__m256)(A), (int)(B), (__v8sf)_mm256_avx512_setzero_ps(), (__mmask8)(U))) +#define _mm_reduce_ps(A, B) ((__m128) __builtin_ia32_reduceps128_mask ((__v4sf)(__m128)(A), (int)(B), (__v4sf)_mm_avx512_setzero_ps(), (__mmask8)-1)) #define _mm_mask_reduce_ps(W, U, A, B) ((__m128) __builtin_ia32_reduceps128_mask ((__v4sf)(__m128)(A), (int)(B), (__v4sf)(__m128)(W), (__mmask8)(U))) -#define _mm_maskz_reduce_ps(U, A, B) ((__m128) __builtin_ia32_reduceps128_mask ((__v4sf)(__m128)(A), (int)(B), (__v4sf)_mm_setzero_ps(), (__mmask8)(U))) -#define _mm256_range_pd(A, B, C) ((__m256d) __builtin_ia32_rangepd256_mask ((__v4df)(__m256d)(A), (__v4df)(__m256d)(B), (int)(C), (__v4df)_mm256_setzero_pd(), (__mmask8)-1)) -#define _mm256_maskz_range_pd(U, A, B, C) ((__m256d) __builtin_ia32_rangepd256_mask ((__v4df)(__m256d)(A), (__v4df)(__m256d)(B), (int)(C), (__v4df)_mm256_setzero_pd(), (__mmask8)(U))) -#define _mm_range_pd(A, B, C) ((__m128d) __builtin_ia32_rangepd128_mask ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__v2df)_mm_setzero_pd(), (__mmask8)-1)) -#define _mm256_range_ps(A, B, C) ((__m256) __builtin_ia32_rangeps256_mask ((__v8sf)(__m256)(A), (__v8sf)(__m256)(B), (int)(C), (__v8sf)_mm256_setzero_ps(), (__mmask8)-1)) +#define _mm_maskz_reduce_ps(U, A, B) ((__m128) __builtin_ia32_reduceps128_mask ((__v4sf)(__m128)(A), (int)(B), (__v4sf)_mm_avx512_setzero_ps(), (__mmask8)(U))) +#define _mm256_range_pd(A, B, C) ((__m256d) __builtin_ia32_rangepd256_mask ((__v4df)(__m256d)(A), (__v4df)(__m256d)(B), (int)(C), (__v4df)_mm256_avx512_setzero_pd(), (__mmask8)-1)) +#define _mm256_maskz_range_pd(U, A, B, C) ((__m256d) __builtin_ia32_rangepd256_mask ((__v4df)(__m256d)(A), (__v4df)(__m256d)(B), (int)(C), (__v4df)_mm256_avx512_setzero_pd(), (__mmask8)(U))) +#define _mm_range_pd(A, B, C) ((__m128d) __builtin_ia32_rangepd128_mask ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__v2df)_mm_avx512_setzero_pd(), (__mmask8)-1)) +#define _mm256_range_ps(A, B, C) ((__m256) __builtin_ia32_rangeps256_mask ((__v8sf)(__m256)(A), (__v8sf)(__m256)(B), (int)(C), (__v8sf)_mm256_avx512_setzero_ps(), (__mmask8)-1)) #define _mm256_mask_range_ps(W, U, A, B, C) ((__m256) __builtin_ia32_rangeps256_mask ((__v8sf)(__m256)(A), (__v8sf)(__m256)(B), (int)(C), (__v8sf)(__m256)(W), (__mmask8)(U))) -#define _mm256_maskz_range_ps(U, A, B, C) ((__m256) __builtin_ia32_rangeps256_mask ((__v8sf)(__m256)(A), (__v8sf)(__m256)(B), (int)(C), (__v8sf)_mm256_setzero_ps(), (__mmask8)(U))) -#define _mm_range_ps(A, B, C) ((__m128) __builtin_ia32_rangeps128_mask ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__v4sf)_mm_setzero_ps(), (__mmask8)-1)) +#define _mm256_maskz_range_ps(U, A, B, C) ((__m256) __builtin_ia32_rangeps256_mask ((__v8sf)(__m256)(A), (__v8sf)(__m256)(B), (int)(C), (__v8sf)_mm256_avx512_setzero_ps(), (__mmask8)(U))) +#define _mm_range_ps(A, B, C) ((__m128) __builtin_ia32_rangeps128_mask ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__v4sf)_mm_avx512_setzero_ps(), (__mmask8)-1)) #define _mm_mask_range_ps(W, U, A, B, C) ((__m128) __builtin_ia32_rangeps128_mask ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__v4sf)(__m128)(W), (__mmask8)(U))) -#define _mm_maskz_range_ps(U, A, B, C) ((__m128) __builtin_ia32_rangeps128_mask ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__v4sf)_mm_setzero_ps(), (__mmask8)(U))) +#define _mm_maskz_range_ps(U, A, B, C) ((__m128) __builtin_ia32_rangeps128_mask ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__v4sf)_mm_avx512_setzero_ps(), (__mmask8)(U))) #define _mm256_mask_range_pd(W, U, A, B, C) ((__m256d) __builtin_ia32_rangepd256_mask ((__v4df)(__m256d)(A), (__v4df)(__m256d)(B), (int)(C), (__v4df)(__m256d)(W), (__mmask8)(U))) #define _mm_mask_range_pd(W, U, A, B, C) ((__m128d) __builtin_ia32_rangepd128_mask ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__v2df)(__m128d)(W), (__mmask8)(U))) -#define _mm_maskz_range_pd(U, A, B, C) ((__m128d) __builtin_ia32_rangepd128_mask ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__v2df)_mm_setzero_pd(), (__mmask8)(U))) +#define _mm_maskz_range_pd(U, A, B, C) ((__m128d) __builtin_ia32_rangepd128_mask ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__v2df)_mm_avx512_setzero_pd(), (__mmask8)(U))) #define _mm256_mask_fpclass_pd_mask(u, X, C) ((__mmask8) __builtin_ia32_fpclasspd256_mask ((__v4df) (__m256d) (X), (int) (C),(__mmask8)(u))) #define _mm256_mask_fpclass_ps_mask(u, X, C) ((__mmask8) __builtin_ia32_fpclassps256_mask ((__v8sf) (__m256) (X), (int) (C),(__mmask8)(u))) #define _mm_mask_fpclass_pd_mask(u, X, C) ((__mmask8) __builtin_ia32_fpclasspd128_mask ((__v2df) (__m128d) (X), (int) (C),(__mmask8)(u))) diff --git a/third_party/intel/avx512vlintrin.internal.h b/third_party/intel/avx512vlintrin.internal.h index 493f80abb..5610d7143 100644 --- a/third_party/intel/avx512vlintrin.internal.h +++ b/third_party/intel/avx512vlintrin.internal.h @@ -4,9 +4,9 @@ #endif #ifndef _AVX512VLINTRIN_H_INCLUDED #define _AVX512VLINTRIN_H_INCLUDED -#ifndef __AVX512VL__ +#if !defined (__AVX512VL__) || defined (__EVEX512__) #pragma GCC push_options -#pragma GCC target("avx512vl") +#pragma GCC target("avx512vl,no-evex512") #define __DISABLE_AVX512VL__ #endif typedef unsigned int __mmask32; @@ -14,6 +14,63 @@ typedef int __v4si_u __attribute__ ((__vector_size__ (16), __may_alias__, __alig typedef int __v8si_u __attribute__ ((__vector_size__ (32), __may_alias__, __aligned__ (1))); typedef long long __v2di_u __attribute__ ((__vector_size__ (16), __may_alias__, __aligned__ (1))); typedef long long __v4di_u __attribute__ ((__vector_size__ (32), __may_alias__, __aligned__ (1))); +extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_avx512_undefined_si128 (void) +{ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Winit-self" + __m128i __Y = __Y; +#pragma GCC diagnostic pop + return __Y; +} +extern __inline __m256 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_avx512_undefined_ps (void) +{ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Winit-self" + __m256 __Y = __Y; +#pragma GCC diagnostic pop + return __Y; +} +extern __inline __m256d __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_avx512_undefined_pd (void) +{ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Winit-self" + __m256d __Y = __Y; +#pragma GCC diagnostic pop + return __Y; +} +extern __inline __m256i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_avx512_undefined_si256 (void) +{ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Winit-self" + __m256i __Y = __Y; +#pragma GCC diagnostic pop + return __Y; +} +extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_avx512_setzero_si128 (void) +{ + return __extension__ (__m128i)(__v4si){ 0, 0, 0, 0 }; +} +extern __inline __m256 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_avx512_setzero_ps (void) +{ + return __extension__ (__m256){ 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0 }; +} +extern __inline __m256d __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_avx512_setzero_pd (void) +{ + return __extension__ (__m256d){ 0.0, 0.0, 0.0, 0.0 }; +} +extern __inline __m256i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_avx512_setzero_si256 (void) +{ + return __extension__ (__m256i)(__v4di){ 0, 0, 0, 0 }; +} extern __inline __m256d __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_mask_mov_pd (__m256d __W, __mmask8 __U, __m256d __A) @@ -28,7 +85,7 @@ _mm256_maskz_mov_pd (__mmask8 __U, __m256d __A) { return (__m256d) __builtin_ia32_movapd256_mask ((__v4df) __A, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128d @@ -45,7 +102,7 @@ _mm_maskz_mov_pd (__mmask8 __U, __m128d __A) { return (__m128d) __builtin_ia32_movapd128_mask ((__v2df) __A, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256d @@ -62,7 +119,7 @@ _mm256_maskz_load_pd (__mmask8 __U, void const *__P) { return (__m256d) __builtin_ia32_loadapd256_mask ((__v4df *) __P, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128d @@ -79,7 +136,7 @@ _mm_maskz_load_pd (__mmask8 __U, void const *__P) { return (__m128d) __builtin_ia32_loadapd128_mask ((__v2df *) __P, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline void @@ -112,7 +169,7 @@ _mm256_maskz_mov_ps (__mmask8 __U, __m256 __A) { return (__m256) __builtin_ia32_movaps256_mask ((__v8sf) __A, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128 @@ -129,7 +186,7 @@ _mm_maskz_mov_ps (__mmask8 __U, __m128 __A) { return (__m128) __builtin_ia32_movaps128_mask ((__v4sf) __A, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m256 @@ -146,7 +203,7 @@ _mm256_maskz_load_ps (__mmask8 __U, void const *__P) { return (__m256) __builtin_ia32_loadaps256_mask ((__v8sf *) __P, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128 @@ -163,7 +220,7 @@ _mm_maskz_load_ps (__mmask8 __U, void const *__P) { return (__m128) __builtin_ia32_loadaps128_mask ((__v4sf *) __P, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline void @@ -196,7 +253,7 @@ _mm256_maskz_mov_epi64 (__mmask8 __U, __m256i __A) { return (__m256i) __builtin_ia32_movdqa64_256_mask ((__v4di) __A, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -213,7 +270,7 @@ _mm_maskz_mov_epi64 (__mmask8 __U, __m128i __A) { return (__m128i) __builtin_ia32_movdqa64_128_mask ((__v2di) __A, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -237,7 +294,7 @@ _mm256_maskz_load_epi64 (__mmask8 __U, void const *__P) { return (__m256i) __builtin_ia32_movdqa64load256_mask ((__v4di *) __P, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } @@ -262,7 +319,7 @@ _mm_maskz_load_epi64 (__mmask8 __U, void const *__P) { return (__m128i) __builtin_ia32_movdqa64load128_mask ((__v2di *) __P, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } @@ -296,7 +353,7 @@ _mm256_maskz_mov_epi32 (__mmask8 __U, __m256i __A) { return (__m256i) __builtin_ia32_movdqa32_256_mask ((__v8si) __A, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -313,7 +370,7 @@ _mm_maskz_mov_epi32 (__mmask8 __U, __m128i __A) { return (__m128i) __builtin_ia32_movdqa32_128_mask ((__v4si) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -337,7 +394,7 @@ _mm256_maskz_load_epi32 (__mmask8 __U, void const *__P) { return (__m256i) __builtin_ia32_movdqa32load256_mask ((__v8si *) __P, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } @@ -362,7 +419,7 @@ _mm_maskz_load_epi32 (__mmask8 __U, void const *__P) { return (__m128i) __builtin_ia32_movdqa32load128_mask ((__v4si *) __P, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } @@ -410,7 +467,7 @@ _mm_maskz_add_pd (__mmask8 __U, __m128d __A, __m128d __B) return (__m128d) __builtin_ia32_addpd128_mask ((__v2df) __A, (__v2df) __B, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256d @@ -430,7 +487,7 @@ _mm256_maskz_add_pd (__mmask8 __U, __m256d __A, __m256d __B) return (__m256d) __builtin_ia32_addpd256_mask ((__v4df) __A, (__v4df) __B, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128 @@ -449,7 +506,7 @@ _mm_maskz_add_ps (__mmask8 __U, __m128 __A, __m128 __B) return (__m128) __builtin_ia32_addps128_mask ((__v4sf) __A, (__v4sf) __B, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m256 @@ -468,7 +525,7 @@ _mm256_maskz_add_ps (__mmask8 __U, __m256 __A, __m256 __B) return (__m256) __builtin_ia32_addps256_mask ((__v8sf) __A, (__v8sf) __B, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128d @@ -487,7 +544,7 @@ _mm_maskz_sub_pd (__mmask8 __U, __m128d __A, __m128d __B) return (__m128d) __builtin_ia32_subpd128_mask ((__v2df) __A, (__v2df) __B, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256d @@ -507,7 +564,7 @@ _mm256_maskz_sub_pd (__mmask8 __U, __m256d __A, __m256d __B) return (__m256d) __builtin_ia32_subpd256_mask ((__v4df) __A, (__v4df) __B, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128 @@ -526,7 +583,7 @@ _mm_maskz_sub_ps (__mmask8 __U, __m128 __A, __m128 __B) return (__m128) __builtin_ia32_subps128_mask ((__v4sf) __A, (__v4sf) __B, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m256 @@ -545,7 +602,7 @@ _mm256_maskz_sub_ps (__mmask8 __U, __m256 __A, __m256 __B) return (__m256) __builtin_ia32_subps256_mask ((__v8sf) __A, (__v8sf) __B, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline void @@ -574,7 +631,7 @@ _mm256_maskz_loadu_pd (__mmask8 __U, void const *__P) { return (__m256d) __builtin_ia32_loadupd256_mask ((const double *) __P, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128d @@ -591,7 +648,7 @@ _mm_maskz_loadu_pd (__mmask8 __U, void const *__P) { return (__m128d) __builtin_ia32_loadupd128_mask ((const double *) __P, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline void @@ -624,7 +681,7 @@ _mm256_maskz_loadu_ps (__mmask8 __U, void const *__P) { return (__m256) __builtin_ia32_loadups256_mask ((const float *) __P, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128 @@ -641,7 +698,7 @@ _mm_maskz_loadu_ps (__mmask8 __U, void const *__P) { return (__m128) __builtin_ia32_loadups128_mask ((const float *) __P, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline void @@ -680,7 +737,7 @@ _mm256_maskz_loadu_epi64 (__mmask8 __U, void const *__P) { return (__m256i) __builtin_ia32_loaddqudi256_mask ((const long long *) __P, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -703,7 +760,7 @@ _mm_maskz_loadu_epi64 (__mmask8 __U, void const *__P) { return (__m128i) __builtin_ia32_loaddqudi128_mask ((const long long *) __P, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline void @@ -754,7 +811,7 @@ _mm256_maskz_loadu_epi32 (__mmask8 __U, void const *__P) { return (__m256i) __builtin_ia32_loaddqusi256_mask ((const int *) __P, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -777,7 +834,7 @@ _mm_maskz_loadu_epi32 (__mmask8 __U, void const *__P) { return (__m128i) __builtin_ia32_loaddqusi128_mask ((const int *) __P, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline void @@ -808,6 +865,70 @@ _mm_mask_storeu_epi32 (void *__P, __mmask8 __U, __m128i __A) (__v4si) __A, (__mmask8) __U); } +extern __inline __m256d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_mask_blend_pd (__mmask8 __U, __m256d __A, __m256d __W) +{ + return (__m256d) __builtin_ia32_blendmpd_256_mask ((__v4df) __A, + (__v4df) __W, + (__mmask8) __U); +} +extern __inline __m256 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_mask_blend_ps (__mmask8 __U, __m256 __A, __m256 __W) +{ + return (__m256) __builtin_ia32_blendmps_256_mask ((__v8sf) __A, + (__v8sf) __W, + (__mmask8) __U); +} +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_mask_blend_epi64 (__mmask8 __U, __m256i __A, __m256i __W) +{ + return (__m256i) __builtin_ia32_blendmq_256_mask ((__v4di) __A, + (__v4di) __W, + (__mmask8) __U); +} +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_mask_blend_epi32 (__mmask8 __U, __m256i __A, __m256i __W) +{ + return (__m256i) __builtin_ia32_blendmd_256_mask ((__v8si) __A, + (__v8si) __W, + (__mmask8) __U); +} +extern __inline __m128d +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_blend_pd (__mmask8 __U, __m128d __A, __m128d __W) +{ + return (__m128d) __builtin_ia32_blendmpd_128_mask ((__v2df) __A, + (__v2df) __W, + (__mmask8) __U); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_blend_ps (__mmask8 __U, __m128 __A, __m128 __W) +{ + return (__m128) __builtin_ia32_blendmps_128_mask ((__v4sf) __A, + (__v4sf) __W, + (__mmask8) __U); +} +extern __inline __m128i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_blend_epi64 (__mmask8 __U, __m128i __A, __m128i __W) +{ + return (__m128i) __builtin_ia32_blendmq_128_mask ((__v2di) __A, + (__v2di) __W, + (__mmask8) __U); +} +extern __inline __m128i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_blend_epi32 (__mmask8 __U, __m128i __A, __m128i __W) +{ + return (__m128i) __builtin_ia32_blendmd_128_mask ((__v4si) __A, + (__v4si) __W, + (__mmask8) __U); +} extern __inline __m256i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_mask_abs_epi32 (__m256i __W, __mmask8 __U, __m256i __A) @@ -822,7 +943,7 @@ _mm256_maskz_abs_epi32 (__mmask8 __U, __m256i __A) { return (__m256i) __builtin_ia32_pabsd256_mask ((__v8si) __A, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -839,7 +960,7 @@ _mm_maskz_abs_epi32 (__mmask8 __U, __m128i __A) { return (__m128i) __builtin_ia32_pabsd128_mask ((__v4si) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -848,7 +969,7 @@ _mm256_abs_epi64 (__m256i __A) { return (__m256i) __builtin_ia32_pabsq256_mask ((__v4di) __A, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -865,7 +986,7 @@ _mm256_maskz_abs_epi64 (__mmask8 __U, __m256i __A) { return (__m256i) __builtin_ia32_pabsq256_mask ((__v4di) __A, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -874,7 +995,7 @@ _mm_abs_epi64 (__m128i __A) { return (__m128i) __builtin_ia32_pabsq128_mask ((__v2di) __A, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -891,7 +1012,7 @@ _mm_maskz_abs_epi64 (__mmask8 __U, __m128i __A) { return (__m128i) __builtin_ia32_pabsq128_mask ((__v2di) __A, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i @@ -900,7 +1021,7 @@ _mm256_cvtpd_epu32 (__m256d __A) { return (__m128i) __builtin_ia32_cvtpd2udq256_mask ((__v4df) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -917,7 +1038,7 @@ _mm256_maskz_cvtpd_epu32 (__mmask8 __U, __m256d __A) { return (__m128i) __builtin_ia32_cvtpd2udq256_mask ((__v4df) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i @@ -926,7 +1047,7 @@ _mm_cvtpd_epu32 (__m128d __A) { return (__m128i) __builtin_ia32_cvtpd2udq128_mask ((__v2df) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -943,7 +1064,7 @@ _mm_maskz_cvtpd_epu32 (__mmask8 __U, __m128d __A) { return (__m128i) __builtin_ia32_cvtpd2udq128_mask ((__v2df) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -960,7 +1081,7 @@ _mm256_maskz_cvttps_epi32 (__mmask8 __U, __m256 __A) { return (__m256i) __builtin_ia32_cvttps2dq256_mask ((__v8sf) __A, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -977,7 +1098,7 @@ _mm_maskz_cvttps_epi32 (__mmask8 __U, __m128 __A) { return (__m128i) __builtin_ia32_cvttps2dq128_mask ((__v4sf) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -986,7 +1107,7 @@ _mm256_cvttps_epu32 (__m256 __A) { return (__m256i) __builtin_ia32_cvttps2udq256_mask ((__v8sf) __A, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -1003,7 +1124,7 @@ _mm256_maskz_cvttps_epu32 (__mmask8 __U, __m256 __A) { return (__m256i) __builtin_ia32_cvttps2udq256_mask ((__v8sf) __A, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -1012,7 +1133,7 @@ _mm_cvttps_epu32 (__m128 __A) { return (__m128i) __builtin_ia32_cvttps2udq128_mask ((__v4sf) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -1029,7 +1150,7 @@ _mm_maskz_cvttps_epu32 (__mmask8 __U, __m128 __A) { return (__m128i) __builtin_ia32_cvttps2udq128_mask ((__v4sf) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i @@ -1046,7 +1167,7 @@ _mm256_maskz_cvttpd_epi32 (__mmask8 __U, __m256d __A) { return (__m128i) __builtin_ia32_cvttpd2dq256_mask ((__v4df) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i @@ -1063,7 +1184,7 @@ _mm_maskz_cvttpd_epi32 (__mmask8 __U, __m128d __A) { return (__m128i) __builtin_ia32_cvttpd2dq128_mask ((__v2df) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i @@ -1072,7 +1193,7 @@ _mm256_cvttpd_epu32 (__m256d __A) { return (__m128i) __builtin_ia32_cvttpd2udq256_mask ((__v4df) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -1089,7 +1210,7 @@ _mm256_maskz_cvttpd_epu32 (__mmask8 __U, __m256d __A) { return (__m128i) __builtin_ia32_cvttpd2udq256_mask ((__v4df) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i @@ -1098,7 +1219,7 @@ _mm_cvttpd_epu32 (__m128d __A) { return (__m128i) __builtin_ia32_cvttpd2udq128_mask ((__v2df) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -1115,7 +1236,7 @@ _mm_maskz_cvttpd_epu32 (__mmask8 __U, __m128d __A) { return (__m128i) __builtin_ia32_cvttpd2udq128_mask ((__v2df) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i @@ -1132,7 +1253,7 @@ _mm256_maskz_cvtpd_epi32 (__mmask8 __U, __m256d __A) { return (__m128i) __builtin_ia32_cvtpd2dq256_mask ((__v4df) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i @@ -1149,7 +1270,7 @@ _mm_maskz_cvtpd_epi32 (__mmask8 __U, __m128d __A) { return (__m128i) __builtin_ia32_cvtpd2dq128_mask ((__v2df) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256d @@ -1166,7 +1287,7 @@ _mm256_maskz_cvtepi32_pd (__mmask8 __U, __m128i __A) { return (__m256d) __builtin_ia32_cvtdq2pd256_mask ((__v4si) __A, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128d @@ -1183,7 +1304,7 @@ _mm_maskz_cvtepi32_pd (__mmask8 __U, __m128i __A) { return (__m128d) __builtin_ia32_cvtdq2pd128_mask ((__v4si) __A, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256d @@ -1192,7 +1313,7 @@ _mm256_cvtepu32_pd (__m128i __A) { return (__m256d) __builtin_ia32_cvtudq2pd256_mask ((__v4si) __A, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) -1); } extern __inline __m256d @@ -1209,7 +1330,7 @@ _mm256_maskz_cvtepu32_pd (__mmask8 __U, __m128i __A) { return (__m256d) __builtin_ia32_cvtudq2pd256_mask ((__v4si) __A, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128d @@ -1218,7 +1339,7 @@ _mm_cvtepu32_pd (__m128i __A) { return (__m128d) __builtin_ia32_cvtudq2pd128_mask ((__v4si) __A, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) -1); } extern __inline __m128d @@ -1235,7 +1356,7 @@ _mm_maskz_cvtepu32_pd (__mmask8 __U, __m128i __A) { return (__m128d) __builtin_ia32_cvtudq2pd128_mask ((__v4si) __A, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256 @@ -1252,7 +1373,7 @@ _mm256_maskz_cvtepi32_ps (__mmask8 __U, __m256i __A) { return (__m256) __builtin_ia32_cvtdq2ps256_mask ((__v8si) __A, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128 @@ -1269,7 +1390,7 @@ _mm_maskz_cvtepi32_ps (__mmask8 __U, __m128i __A) { return (__m128) __builtin_ia32_cvtdq2ps128_mask ((__v4si) __A, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m256 @@ -1278,7 +1399,7 @@ _mm256_cvtepu32_ps (__m256i __A) { return (__m256) __builtin_ia32_cvtudq2ps256_mask ((__v8si) __A, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) -1); } extern __inline __m256 @@ -1295,7 +1416,7 @@ _mm256_maskz_cvtepu32_ps (__mmask8 __U, __m256i __A) { return (__m256) __builtin_ia32_cvtudq2ps256_mask ((__v8si) __A, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128 @@ -1304,7 +1425,7 @@ _mm_cvtepu32_ps (__m128i __A) { return (__m128) __builtin_ia32_cvtudq2ps128_mask ((__v4si) __A, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) -1); } extern __inline __m128 @@ -1321,7 +1442,7 @@ _mm_maskz_cvtepu32_ps (__mmask8 __U, __m128i __A) { return (__m128) __builtin_ia32_cvtudq2ps128_mask ((__v4si) __A, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m256d @@ -1338,7 +1459,7 @@ _mm256_maskz_cvtps_pd (__mmask8 __U, __m128 __A) { return (__m256d) __builtin_ia32_cvtps2pd256_mask ((__v4sf) __A, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128d @@ -1355,7 +1476,7 @@ _mm_maskz_cvtps_pd (__mmask8 __U, __m128 __A) { return (__m128d) __builtin_ia32_cvtps2pd128_mask ((__v4sf) __A, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128i @@ -1364,7 +1485,7 @@ _mm_cvtepi32_epi8 (__m128i __A) { return (__m128i) __builtin_ia32_pmovdb128_mask ((__v4si) __A, (__v16qi) - _mm_undefined_si128 (), + _mm_avx512_undefined_si128 (), (__mmask8) -1); } extern __inline void @@ -1386,7 +1507,7 @@ _mm_maskz_cvtepi32_epi8 (__mmask8 __M, __m128i __A) { return (__m128i) __builtin_ia32_pmovdb128_mask ((__v4si) __A, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -1395,7 +1516,7 @@ _mm256_cvtepi32_epi8 (__m256i __A) { return (__m128i) __builtin_ia32_pmovdb256_mask ((__v8si) __A, (__v16qi) - _mm_undefined_si128 (), + _mm_avx512_undefined_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -1417,7 +1538,7 @@ _mm256_maskz_cvtepi32_epi8 (__mmask8 __M, __m256i __A) { return (__m128i) __builtin_ia32_pmovdb256_mask ((__v8si) __A, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -1426,7 +1547,7 @@ _mm_cvtsepi32_epi8 (__m128i __A) { return (__m128i) __builtin_ia32_pmovsdb128_mask ((__v4si) __A, (__v16qi) - _mm_undefined_si128 (), + _mm_avx512_undefined_si128 (), (__mmask8) -1); } extern __inline void @@ -1448,7 +1569,7 @@ _mm_maskz_cvtsepi32_epi8 (__mmask8 __M, __m128i __A) { return (__m128i) __builtin_ia32_pmovsdb128_mask ((__v4si) __A, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -1457,7 +1578,7 @@ _mm256_cvtsepi32_epi8 (__m256i __A) { return (__m128i) __builtin_ia32_pmovsdb256_mask ((__v8si) __A, (__v16qi) - _mm_undefined_si128 (), + _mm_avx512_undefined_si128 (), (__mmask8) -1); } extern __inline void @@ -1479,7 +1600,7 @@ _mm256_maskz_cvtsepi32_epi8 (__mmask8 __M, __m256i __A) { return (__m128i) __builtin_ia32_pmovsdb256_mask ((__v8si) __A, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -1488,7 +1609,7 @@ _mm_cvtusepi32_epi8 (__m128i __A) { return (__m128i) __builtin_ia32_pmovusdb128_mask ((__v4si) __A, (__v16qi) - _mm_undefined_si128 (), + _mm_avx512_undefined_si128 (), (__mmask8) -1); } extern __inline void @@ -1511,7 +1632,7 @@ _mm_maskz_cvtusepi32_epi8 (__mmask8 __M, __m128i __A) { return (__m128i) __builtin_ia32_pmovusdb128_mask ((__v4si) __A, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -1520,7 +1641,7 @@ _mm256_cvtusepi32_epi8 (__m256i __A) { return (__m128i) __builtin_ia32_pmovusdb256_mask ((__v8si) __A, (__v16qi) - _mm_undefined_si128 (), + _mm_avx512_undefined_si128 (), (__mmask8) -1); } extern __inline void @@ -1543,7 +1664,7 @@ _mm256_maskz_cvtusepi32_epi8 (__mmask8 __M, __m256i __A) { return (__m128i) __builtin_ia32_pmovusdb256_mask ((__v8si) __A, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -1552,7 +1673,7 @@ _mm_cvtepi32_epi16 (__m128i __A) { return (__m128i) __builtin_ia32_pmovdw128_mask ((__v4si) __A, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline void @@ -1574,7 +1695,7 @@ _mm_maskz_cvtepi32_epi16 (__mmask8 __M, __m128i __A) { return (__m128i) __builtin_ia32_pmovdw128_mask ((__v4si) __A, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -1583,7 +1704,7 @@ _mm256_cvtepi32_epi16 (__m256i __A) { return (__m128i) __builtin_ia32_pmovdw256_mask ((__v8si) __A, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline void @@ -1605,7 +1726,7 @@ _mm256_maskz_cvtepi32_epi16 (__mmask8 __M, __m256i __A) { return (__m128i) __builtin_ia32_pmovdw256_mask ((__v8si) __A, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -1614,7 +1735,7 @@ _mm_cvtsepi32_epi16 (__m128i __A) { return (__m128i) __builtin_ia32_pmovsdw128_mask ((__v4si) __A, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline void @@ -1637,7 +1758,7 @@ _mm_maskz_cvtsepi32_epi16 (__mmask8 __M, __m128i __A) { return (__m128i) __builtin_ia32_pmovsdw128_mask ((__v4si) __A, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -1646,7 +1767,7 @@ _mm256_cvtsepi32_epi16 (__m256i __A) { return (__m128i) __builtin_ia32_pmovsdw256_mask ((__v8si) __A, (__v8hi) - _mm_undefined_si128 (), + _mm_avx512_undefined_si128 (), (__mmask8) -1); } extern __inline void @@ -1668,7 +1789,7 @@ _mm256_maskz_cvtsepi32_epi16 (__mmask8 __M, __m256i __A) { return (__m128i) __builtin_ia32_pmovsdw256_mask ((__v8si) __A, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -1677,7 +1798,7 @@ _mm_cvtusepi32_epi16 (__m128i __A) { return (__m128i) __builtin_ia32_pmovusdw128_mask ((__v4si) __A, (__v8hi) - _mm_undefined_si128 (), + _mm_avx512_undefined_si128 (), (__mmask8) -1); } extern __inline void @@ -1699,7 +1820,7 @@ _mm_maskz_cvtusepi32_epi16 (__mmask8 __M, __m128i __A) { return (__m128i) __builtin_ia32_pmovusdw128_mask ((__v4si) __A, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -1708,7 +1829,7 @@ _mm256_cvtusepi32_epi16 (__m256i __A) { return (__m128i) __builtin_ia32_pmovusdw256_mask ((__v8si) __A, (__v8hi) - _mm_undefined_si128 (), + _mm_avx512_undefined_si128 (), (__mmask8) -1); } extern __inline void @@ -1730,7 +1851,7 @@ _mm256_maskz_cvtusepi32_epi16 (__mmask8 __M, __m256i __A) { return (__m128i) __builtin_ia32_pmovusdw256_mask ((__v8si) __A, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -1739,7 +1860,7 @@ _mm_cvtepi64_epi8 (__m128i __A) { return (__m128i) __builtin_ia32_pmovqb128_mask ((__v2di) __A, (__v16qi) - _mm_undefined_si128 (), + _mm_avx512_undefined_si128 (), (__mmask8) -1); } extern __inline void @@ -1761,7 +1882,7 @@ _mm_maskz_cvtepi64_epi8 (__mmask8 __M, __m128i __A) { return (__m128i) __builtin_ia32_pmovqb128_mask ((__v2di) __A, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -1770,7 +1891,7 @@ _mm256_cvtepi64_epi8 (__m256i __A) { return (__m128i) __builtin_ia32_pmovqb256_mask ((__v4di) __A, (__v16qi) - _mm_undefined_si128 (), + _mm_avx512_undefined_si128 (), (__mmask8) -1); } extern __inline void @@ -1792,7 +1913,7 @@ _mm256_maskz_cvtepi64_epi8 (__mmask8 __M, __m256i __A) { return (__m128i) __builtin_ia32_pmovqb256_mask ((__v4di) __A, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -1801,7 +1922,7 @@ _mm_cvtsepi64_epi8 (__m128i __A) { return (__m128i) __builtin_ia32_pmovsqb128_mask ((__v2di) __A, (__v16qi) - _mm_undefined_si128 (), + _mm_avx512_undefined_si128 (), (__mmask8) -1); } extern __inline void @@ -1823,7 +1944,7 @@ _mm_maskz_cvtsepi64_epi8 (__mmask8 __M, __m128i __A) { return (__m128i) __builtin_ia32_pmovsqb128_mask ((__v2di) __A, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -1832,7 +1953,7 @@ _mm256_cvtsepi64_epi8 (__m256i __A) { return (__m128i) __builtin_ia32_pmovsqb256_mask ((__v4di) __A, (__v16qi) - _mm_undefined_si128 (), + _mm_avx512_undefined_si128 (), (__mmask8) -1); } extern __inline void @@ -1854,7 +1975,7 @@ _mm256_maskz_cvtsepi64_epi8 (__mmask8 __M, __m256i __A) { return (__m128i) __builtin_ia32_pmovsqb256_mask ((__v4di) __A, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -1863,7 +1984,7 @@ _mm_cvtusepi64_epi8 (__m128i __A) { return (__m128i) __builtin_ia32_pmovusqb128_mask ((__v2di) __A, (__v16qi) - _mm_undefined_si128 (), + _mm_avx512_undefined_si128 (), (__mmask8) -1); } extern __inline void @@ -1886,7 +2007,7 @@ _mm_maskz_cvtusepi64_epi8 (__mmask8 __M, __m128i __A) { return (__m128i) __builtin_ia32_pmovusqb128_mask ((__v2di) __A, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -1895,7 +2016,7 @@ _mm256_cvtusepi64_epi8 (__m256i __A) { return (__m128i) __builtin_ia32_pmovusqb256_mask ((__v4di) __A, (__v16qi) - _mm_undefined_si128 (), + _mm_avx512_undefined_si128 (), (__mmask8) -1); } extern __inline void @@ -1918,7 +2039,7 @@ _mm256_maskz_cvtusepi64_epi8 (__mmask8 __M, __m256i __A) { return (__m128i) __builtin_ia32_pmovusqb256_mask ((__v4di) __A, (__v16qi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -1927,7 +2048,7 @@ _mm_cvtepi64_epi16 (__m128i __A) { return (__m128i) __builtin_ia32_pmovqw128_mask ((__v2di) __A, (__v8hi) - _mm_undefined_si128 (), + _mm_avx512_undefined_si128 (), (__mmask8) -1); } extern __inline void @@ -1950,7 +2071,7 @@ _mm_maskz_cvtepi64_epi16 (__mmask8 __M, __m128i __A) { return (__m128i) __builtin_ia32_pmovqw128_mask ((__v2di) __A, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -1959,7 +2080,7 @@ _mm256_cvtepi64_epi16 (__m256i __A) { return (__m128i) __builtin_ia32_pmovqw256_mask ((__v4di) __A, (__v8hi) - _mm_undefined_si128 (), + _mm_avx512_undefined_si128 (), (__mmask8) -1); } extern __inline void @@ -1981,7 +2102,7 @@ _mm256_maskz_cvtepi64_epi16 (__mmask8 __M, __m256i __A) { return (__m128i) __builtin_ia32_pmovqw256_mask ((__v4di) __A, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -1990,7 +2111,7 @@ _mm_cvtsepi64_epi16 (__m128i __A) { return (__m128i) __builtin_ia32_pmovsqw128_mask ((__v2di) __A, (__v8hi) - _mm_undefined_si128 (), + _mm_avx512_undefined_si128 (), (__mmask8) -1); } extern __inline void @@ -2012,7 +2133,7 @@ _mm_maskz_cvtsepi64_epi16 (__mmask8 __M, __m128i __A) { return (__m128i) __builtin_ia32_pmovsqw128_mask ((__v2di) __A, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -2021,7 +2142,7 @@ _mm256_cvtsepi64_epi16 (__m256i __A) { return (__m128i) __builtin_ia32_pmovsqw256_mask ((__v4di) __A, (__v8hi) - _mm_undefined_si128 (), + _mm_avx512_undefined_si128 (), (__mmask8) -1); } extern __inline void @@ -2043,7 +2164,7 @@ _mm256_maskz_cvtsepi64_epi16 (__mmask8 __M, __m256i __A) { return (__m128i) __builtin_ia32_pmovsqw256_mask ((__v4di) __A, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -2052,7 +2173,7 @@ _mm_cvtusepi64_epi16 (__m128i __A) { return (__m128i) __builtin_ia32_pmovusqw128_mask ((__v2di) __A, (__v8hi) - _mm_undefined_si128 (), + _mm_avx512_undefined_si128 (), (__mmask8) -1); } extern __inline void @@ -2074,7 +2195,7 @@ _mm_maskz_cvtusepi64_epi16 (__mmask8 __M, __m128i __A) { return (__m128i) __builtin_ia32_pmovusqw128_mask ((__v2di) __A, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -2083,7 +2204,7 @@ _mm256_cvtusepi64_epi16 (__m256i __A) { return (__m128i) __builtin_ia32_pmovusqw256_mask ((__v4di) __A, (__v8hi) - _mm_undefined_si128 (), + _mm_avx512_undefined_si128 (), (__mmask8) -1); } extern __inline void @@ -2105,7 +2226,7 @@ _mm256_maskz_cvtusepi64_epi16 (__mmask8 __M, __m256i __A) { return (__m128i) __builtin_ia32_pmovusqw256_mask ((__v4di) __A, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -2114,7 +2235,7 @@ _mm_cvtepi64_epi32 (__m128i __A) { return (__m128i) __builtin_ia32_pmovqd128_mask ((__v2di) __A, (__v4si) - _mm_undefined_si128 (), + _mm_avx512_undefined_si128 (), (__mmask8) -1); } extern __inline void @@ -2137,7 +2258,7 @@ _mm_maskz_cvtepi64_epi32 (__mmask8 __M, __m128i __A) { return (__m128i) __builtin_ia32_pmovqd128_mask ((__v2di) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -2146,7 +2267,7 @@ _mm256_cvtepi64_epi32 (__m256i __A) { return (__m128i) __builtin_ia32_pmovqd256_mask ((__v4di) __A, (__v4si) - _mm_undefined_si128 (), + _mm_avx512_undefined_si128 (), (__mmask8) -1); } extern __inline void @@ -2168,7 +2289,7 @@ _mm256_maskz_cvtepi64_epi32 (__mmask8 __M, __m256i __A) { return (__m128i) __builtin_ia32_pmovqd256_mask ((__v4di) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -2177,7 +2298,7 @@ _mm_cvtsepi64_epi32 (__m128i __A) { return (__m128i) __builtin_ia32_pmovsqd128_mask ((__v2di) __A, (__v4si) - _mm_undefined_si128 (), + _mm_avx512_undefined_si128 (), (__mmask8) -1); } extern __inline void @@ -2199,7 +2320,7 @@ _mm_maskz_cvtsepi64_epi32 (__mmask8 __M, __m128i __A) { return (__m128i) __builtin_ia32_pmovsqd128_mask ((__v2di) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -2208,7 +2329,7 @@ _mm256_cvtsepi64_epi32 (__m256i __A) { return (__m128i) __builtin_ia32_pmovsqd256_mask ((__v4di) __A, (__v4si) - _mm_undefined_si128 (), + _mm_avx512_undefined_si128 (), (__mmask8) -1); } extern __inline void @@ -2231,7 +2352,7 @@ _mm256_maskz_cvtsepi64_epi32 (__mmask8 __M, __m256i __A) { return (__m128i) __builtin_ia32_pmovsqd256_mask ((__v4di) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -2240,7 +2361,7 @@ _mm_cvtusepi64_epi32 (__m128i __A) { return (__m128i) __builtin_ia32_pmovusqd128_mask ((__v2di) __A, (__v4si) - _mm_undefined_si128 (), + _mm_avx512_undefined_si128 (), (__mmask8) -1); } extern __inline void @@ -2262,7 +2383,7 @@ _mm_maskz_cvtusepi64_epi32 (__mmask8 __M, __m128i __A) { return (__m128i) __builtin_ia32_pmovusqd128_mask ((__v2di) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -2271,7 +2392,7 @@ _mm256_cvtusepi64_epi32 (__m256i __A) { return (__m128i) __builtin_ia32_pmovusqd256_mask ((__v4di) __A, (__v4si) - _mm_undefined_si128 (), + _mm_avx512_undefined_si128 (), (__mmask8) -1); } extern __inline void @@ -2293,7 +2414,7 @@ _mm256_maskz_cvtusepi64_epi32 (__mmask8 __M, __m256i __A) { return (__m128i) __builtin_ia32_pmovusqd256_mask ((__v4di) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m256 @@ -2310,7 +2431,7 @@ _mm256_maskz_broadcastss_ps (__mmask8 __M, __m128 __A) { return (__m256) __builtin_ia32_broadcastss256_mask ((__v4sf) __A, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), __M); } extern __inline __m128 @@ -2327,7 +2448,7 @@ _mm_maskz_broadcastss_ps (__mmask8 __M, __m128 __A) { return (__m128) __builtin_ia32_broadcastss128_mask ((__v4sf) __A, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), __M); } extern __inline __m256d @@ -2344,7 +2465,7 @@ _mm256_maskz_broadcastsd_pd (__mmask8 __M, __m128d __A) { return (__m256d) __builtin_ia32_broadcastsd256_mask ((__v2df) __A, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), __M); } extern __inline __m256i @@ -2361,7 +2482,7 @@ _mm256_maskz_broadcastd_epi32 (__mmask8 __M, __m128i __A) { return (__m256i) __builtin_ia32_pbroadcastd256_mask ((__v4si) __A, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __M); } extern __inline __m256i @@ -2377,7 +2498,7 @@ _mm256_maskz_set1_epi32 (__mmask8 __M, int __A) { return (__m256i) __builtin_ia32_pbroadcastd256_gpr_mask (__A, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __M); } extern __inline __m128i @@ -2394,7 +2515,7 @@ _mm_maskz_broadcastd_epi32 (__mmask8 __M, __m128i __A) { return (__m128i) __builtin_ia32_pbroadcastd128_mask ((__v4si) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -2410,7 +2531,7 @@ _mm_maskz_set1_epi32 (__mmask8 __M, int __A) { return (__m128i) __builtin_ia32_pbroadcastd128_gpr_mask (__A, - (__v4si) _mm_setzero_si128 (), + (__v4si) _mm_avx512_setzero_si128 (), __M); } extern __inline __m256i @@ -2427,7 +2548,7 @@ _mm256_maskz_broadcastq_epi64 (__mmask8 __M, __m128i __A) { return (__m256i) __builtin_ia32_pbroadcastq256_mask ((__v2di) __A, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __M); } extern __inline __m256i @@ -2443,7 +2564,7 @@ _mm256_maskz_set1_epi64 (__mmask8 __M, long long __A) { return (__m256i) __builtin_ia32_pbroadcastq256_gpr_mask (__A, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __M); } extern __inline __m128i @@ -2460,7 +2581,7 @@ _mm_maskz_broadcastq_epi64 (__mmask8 __M, __m128i __A) { return (__m128i) __builtin_ia32_pbroadcastq128_mask ((__v2di) __A, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -2476,7 +2597,7 @@ _mm_maskz_set1_epi64 (__mmask8 __M, long long __A) { return (__m128i) __builtin_ia32_pbroadcastq128_gpr_mask (__A, - (__v2di) _mm_setzero_si128 (), + (__v2di) _mm_avx512_setzero_si128 (), __M); } extern __inline __m256 @@ -2484,7 +2605,7 @@ __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_broadcast_f32x4 (__m128 __A) { return (__m256) __builtin_ia32_broadcastf32x4_256_mask ((__v4sf) __A, - (__v8sf)_mm256_undefined_pd (), + (__v8sf)_mm256_avx512_undefined_pd (), (__mmask8) -1); } extern __inline __m256 @@ -2501,7 +2622,7 @@ _mm256_maskz_broadcast_f32x4 (__mmask8 __M, __m128 __A) { return (__m256) __builtin_ia32_broadcastf32x4_256_mask ((__v4sf) __A, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), __M); } extern __inline __m256i @@ -2510,7 +2631,7 @@ _mm256_broadcast_i32x4 (__m128i __A) { return (__m256i) __builtin_ia32_broadcasti32x4_256_mask ((__v4si) __A, - (__v8si)_mm256_undefined_si256 (), + (__v8si)_mm256_avx512_undefined_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -2529,7 +2650,7 @@ _mm256_maskz_broadcast_i32x4 (__mmask8 __M, __m128i __A) return (__m256i) __builtin_ia32_broadcasti32x4_256_mask ((__v4si) __A, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __M); } extern __inline __m256i @@ -2546,7 +2667,7 @@ _mm256_maskz_cvtepi8_epi32 (__mmask8 __U, __m128i __A) { return (__m256i) __builtin_ia32_pmovsxbd256_mask ((__v16qi) __A, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -2563,7 +2684,7 @@ _mm_maskz_cvtepi8_epi32 (__mmask8 __U, __m128i __A) { return (__m128i) __builtin_ia32_pmovsxbd128_mask ((__v16qi) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -2580,7 +2701,7 @@ _mm256_maskz_cvtepi8_epi64 (__mmask8 __U, __m128i __A) { return (__m256i) __builtin_ia32_pmovsxbq256_mask ((__v16qi) __A, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -2597,7 +2718,7 @@ _mm_maskz_cvtepi8_epi64 (__mmask8 __U, __m128i __A) { return (__m128i) __builtin_ia32_pmovsxbq128_mask ((__v16qi) __A, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -2614,7 +2735,7 @@ _mm256_maskz_cvtepi16_epi32 (__mmask8 __U, __m128i __A) { return (__m256i) __builtin_ia32_pmovsxwd256_mask ((__v8hi) __A, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -2631,7 +2752,7 @@ _mm_maskz_cvtepi16_epi32 (__mmask8 __U, __m128i __A) { return (__m128i) __builtin_ia32_pmovsxwd128_mask ((__v8hi) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -2648,7 +2769,7 @@ _mm256_maskz_cvtepi16_epi64 (__mmask8 __U, __m128i __A) { return (__m256i) __builtin_ia32_pmovsxwq256_mask ((__v8hi) __A, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -2665,7 +2786,7 @@ _mm_maskz_cvtepi16_epi64 (__mmask8 __U, __m128i __A) { return (__m128i) __builtin_ia32_pmovsxwq128_mask ((__v8hi) __A, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -2682,7 +2803,7 @@ _mm256_maskz_cvtepi32_epi64 (__mmask8 __U, __m128i __X) { return (__m256i) __builtin_ia32_pmovsxdq256_mask ((__v4si) __X, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -2699,7 +2820,7 @@ _mm_maskz_cvtepi32_epi64 (__mmask8 __U, __m128i __X) { return (__m128i) __builtin_ia32_pmovsxdq128_mask ((__v4si) __X, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -2716,7 +2837,7 @@ _mm256_maskz_cvtepu8_epi32 (__mmask8 __U, __m128i __A) { return (__m256i) __builtin_ia32_pmovzxbd256_mask ((__v16qi) __A, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -2733,7 +2854,7 @@ _mm_maskz_cvtepu8_epi32 (__mmask8 __U, __m128i __A) { return (__m128i) __builtin_ia32_pmovzxbd128_mask ((__v16qi) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -2750,7 +2871,7 @@ _mm256_maskz_cvtepu8_epi64 (__mmask8 __U, __m128i __A) { return (__m256i) __builtin_ia32_pmovzxbq256_mask ((__v16qi) __A, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -2767,7 +2888,7 @@ _mm_maskz_cvtepu8_epi64 (__mmask8 __U, __m128i __A) { return (__m128i) __builtin_ia32_pmovzxbq128_mask ((__v16qi) __A, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -2784,7 +2905,7 @@ _mm256_maskz_cvtepu16_epi32 (__mmask8 __U, __m128i __A) { return (__m256i) __builtin_ia32_pmovzxwd256_mask ((__v8hi) __A, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -2801,7 +2922,7 @@ _mm_maskz_cvtepu16_epi32 (__mmask8 __U, __m128i __A) { return (__m128i) __builtin_ia32_pmovzxwd128_mask ((__v8hi) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -2818,7 +2939,7 @@ _mm256_maskz_cvtepu16_epi64 (__mmask8 __U, __m128i __A) { return (__m256i) __builtin_ia32_pmovzxwq256_mask ((__v8hi) __A, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -2835,7 +2956,7 @@ _mm_maskz_cvtepu16_epi64 (__mmask8 __U, __m128i __A) { return (__m128i) __builtin_ia32_pmovzxwq128_mask ((__v8hi) __A, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -2852,7 +2973,7 @@ _mm256_maskz_cvtepu32_epi64 (__mmask8 __U, __m128i __X) { return (__m256i) __builtin_ia32_pmovzxdq256_mask ((__v4si) __X, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -2869,7 +2990,7 @@ _mm_maskz_cvtepu32_epi64 (__mmask8 __U, __m128i __X) { return (__m128i) __builtin_ia32_pmovzxdq128_mask ((__v4si) __X, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256d @@ -2878,7 +2999,7 @@ _mm256_rcp14_pd (__m256d __A) { return (__m256d) __builtin_ia32_rcp14pd256_mask ((__v4df) __A, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) -1); } extern __inline __m256d @@ -2895,7 +3016,7 @@ _mm256_maskz_rcp14_pd (__mmask8 __U, __m256d __A) { return (__m256d) __builtin_ia32_rcp14pd256_mask ((__v4df) __A, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128d @@ -2904,7 +3025,7 @@ _mm_rcp14_pd (__m128d __A) { return (__m128d) __builtin_ia32_rcp14pd128_mask ((__v2df) __A, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) -1); } extern __inline __m128d @@ -2921,7 +3042,7 @@ _mm_maskz_rcp14_pd (__mmask8 __U, __m128d __A) { return (__m128d) __builtin_ia32_rcp14pd128_mask ((__v2df) __A, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256 @@ -2930,7 +3051,7 @@ _mm256_rcp14_ps (__m256 __A) { return (__m256) __builtin_ia32_rcp14ps256_mask ((__v8sf) __A, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) -1); } extern __inline __m256 @@ -2947,7 +3068,7 @@ _mm256_maskz_rcp14_ps (__mmask8 __U, __m256 __A) { return (__m256) __builtin_ia32_rcp14ps256_mask ((__v8sf) __A, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128 @@ -2956,7 +3077,7 @@ _mm_rcp14_ps (__m128 __A) { return (__m128) __builtin_ia32_rcp14ps128_mask ((__v4sf) __A, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) -1); } extern __inline __m128 @@ -2973,7 +3094,7 @@ _mm_maskz_rcp14_ps (__mmask8 __U, __m128 __A) { return (__m128) __builtin_ia32_rcp14ps128_mask ((__v4sf) __A, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m256d @@ -2982,7 +3103,7 @@ _mm256_rsqrt14_pd (__m256d __A) { return (__m256d) __builtin_ia32_rsqrt14pd256_mask ((__v4df) __A, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) -1); } extern __inline __m256d @@ -2999,7 +3120,7 @@ _mm256_maskz_rsqrt14_pd (__mmask8 __U, __m256d __A) { return (__m256d) __builtin_ia32_rsqrt14pd256_mask ((__v4df) __A, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128d @@ -3008,7 +3129,7 @@ _mm_rsqrt14_pd (__m128d __A) { return (__m128d) __builtin_ia32_rsqrt14pd128_mask ((__v2df) __A, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) -1); } extern __inline __m128d @@ -3025,7 +3146,7 @@ _mm_maskz_rsqrt14_pd (__mmask8 __U, __m128d __A) { return (__m128d) __builtin_ia32_rsqrt14pd128_mask ((__v2df) __A, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256 @@ -3034,7 +3155,7 @@ _mm256_rsqrt14_ps (__m256 __A) { return (__m256) __builtin_ia32_rsqrt14ps256_mask ((__v8sf) __A, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) -1); } extern __inline __m256 @@ -3051,7 +3172,7 @@ _mm256_maskz_rsqrt14_ps (__mmask8 __U, __m256 __A) { return (__m256) __builtin_ia32_rsqrt14ps256_mask ((__v8sf) __A, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128 @@ -3060,7 +3181,7 @@ _mm_rsqrt14_ps (__m128 __A) { return (__m128) __builtin_ia32_rsqrt14ps128_mask ((__v4sf) __A, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) -1); } extern __inline __m128 @@ -3077,7 +3198,7 @@ _mm_maskz_rsqrt14_ps (__mmask8 __U, __m128 __A) { return (__m128) __builtin_ia32_rsqrt14ps128_mask ((__v4sf) __A, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m256d @@ -3094,7 +3215,7 @@ _mm256_maskz_sqrt_pd (__mmask8 __U, __m256d __A) { return (__m256d) __builtin_ia32_sqrtpd256_mask ((__v4df) __A, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128d @@ -3111,7 +3232,7 @@ _mm_maskz_sqrt_pd (__mmask8 __U, __m128d __A) { return (__m128d) __builtin_ia32_sqrtpd128_mask ((__v2df) __A, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256 @@ -3128,7 +3249,7 @@ _mm256_maskz_sqrt_ps (__mmask8 __U, __m256 __A) { return (__m256) __builtin_ia32_sqrtps256_mask ((__v8sf) __A, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128 @@ -3145,7 +3266,7 @@ _mm_maskz_sqrt_ps (__mmask8 __U, __m128 __A) { return (__m128) __builtin_ia32_sqrtps128_mask ((__v4sf) __A, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m256i @@ -3165,7 +3286,7 @@ _mm256_maskz_add_epi32 (__mmask8 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_paddd256_mask ((__v8si) __A, (__v8si) __B, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m256i @@ -3185,7 +3306,7 @@ _mm256_maskz_add_epi64 (__mmask8 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_paddq256_mask ((__v4di) __A, (__v4di) __B, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m256i @@ -3205,7 +3326,7 @@ _mm256_maskz_sub_epi32 (__mmask8 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_psubd256_mask ((__v8si) __A, (__v8si) __B, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m256i @@ -3225,7 +3346,7 @@ _mm256_maskz_sub_epi64 (__mmask8 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_psubq256_mask ((__v4di) __A, (__v4di) __B, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -3245,7 +3366,7 @@ _mm_maskz_add_epi32 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_paddd128_mask ((__v4si) __A, (__v4si) __B, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i @@ -3265,7 +3386,7 @@ _mm_maskz_add_epi64 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_paddq128_mask ((__v2di) __A, (__v2di) __B, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i @@ -3285,7 +3406,7 @@ _mm_maskz_sub_epi32 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_psubd128_mask ((__v4si) __A, (__v4si) __B, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i @@ -3305,7 +3426,7 @@ _mm_maskz_sub_epi64 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_psubq128_mask ((__v2di) __A, (__v2di) __B, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256 @@ -3314,7 +3435,7 @@ _mm256_getexp_ps (__m256 __A) { return (__m256) __builtin_ia32_getexpps256_mask ((__v8sf) __A, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) -1); } extern __inline __m256 @@ -3331,7 +3452,7 @@ _mm256_maskz_getexp_ps (__mmask8 __U, __m256 __A) { return (__m256) __builtin_ia32_getexpps256_mask ((__v8sf) __A, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m256d @@ -3340,7 +3461,7 @@ _mm256_getexp_pd (__m256d __A) { return (__m256d) __builtin_ia32_getexppd256_mask ((__v4df) __A, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) -1); } extern __inline __m256d @@ -3357,7 +3478,7 @@ _mm256_maskz_getexp_pd (__mmask8 __U, __m256d __A) { return (__m256d) __builtin_ia32_getexppd256_mask ((__v4df) __A, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128 @@ -3366,7 +3487,7 @@ _mm_getexp_ps (__m128 __A) { return (__m128) __builtin_ia32_getexpps128_mask ((__v4sf) __A, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) -1); } extern __inline __m128 @@ -3383,7 +3504,7 @@ _mm_maskz_getexp_ps (__mmask8 __U, __m128 __A) { return (__m128) __builtin_ia32_getexpps128_mask ((__v4sf) __A, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128d @@ -3392,7 +3513,7 @@ _mm_getexp_pd (__m128d __A) { return (__m128d) __builtin_ia32_getexppd128_mask ((__v2df) __A, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) -1); } extern __inline __m128d @@ -3409,7 +3530,7 @@ _mm_maskz_getexp_pd (__mmask8 __U, __m128d __A) { return (__m128d) __builtin_ia32_getexppd128_mask ((__v2df) __A, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256i @@ -3429,7 +3550,7 @@ _mm256_maskz_srl_epi32 (__mmask8 __U, __m256i __A, __m128i __B) return (__m256i) __builtin_ia32_psrld256_mask ((__v8si) __A, (__v4si) __B, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -3449,7 +3570,7 @@ _mm_maskz_srl_epi32 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_psrld128_mask ((__v4si) __A, (__v4si) __B, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -3469,7 +3590,7 @@ _mm256_maskz_srl_epi64 (__mmask8 __U, __m256i __A, __m128i __B) return (__m256i) __builtin_ia32_psrlq256_mask ((__v4di) __A, (__v2di) __B, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -3489,7 +3610,7 @@ _mm_maskz_srl_epi64 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_psrlq128_mask ((__v2di) __A, (__v2di) __B, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -3509,7 +3630,7 @@ _mm256_maskz_and_epi32 (__mmask8 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pandd256_mask ((__v8si) __A, (__v8si) __B, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m256d @@ -3519,7 +3640,7 @@ _mm256_scalef_pd (__m256d __A, __m256d __B) return (__m256d) __builtin_ia32_scalefpd256_mask ((__v4df) __A, (__v4df) __B, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) -1); } extern __inline __m256d @@ -3539,7 +3660,7 @@ _mm256_maskz_scalef_pd (__mmask8 __U, __m256d __A, __m256d __B) return (__m256d) __builtin_ia32_scalefpd256_mask ((__v4df) __A, (__v4df) __B, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256 @@ -3549,7 +3670,7 @@ _mm256_scalef_ps (__m256 __A, __m256 __B) return (__m256) __builtin_ia32_scalefps256_mask ((__v8sf) __A, (__v8sf) __B, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) -1); } extern __inline __m256 @@ -3569,7 +3690,7 @@ _mm256_maskz_scalef_ps (__mmask8 __U, __m256 __A, __m256 __B) return (__m256) __builtin_ia32_scalefps256_mask ((__v8sf) __A, (__v8sf) __B, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128d @@ -3579,7 +3700,7 @@ _mm_scalef_pd (__m128d __A, __m128d __B) return (__m128d) __builtin_ia32_scalefpd128_mask ((__v2df) __A, (__v2df) __B, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) -1); } extern __inline __m128d @@ -3599,7 +3720,7 @@ _mm_maskz_scalef_pd (__mmask8 __U, __m128d __A, __m128d __B) return (__m128d) __builtin_ia32_scalefpd128_mask ((__v2df) __A, (__v2df) __B, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128 @@ -3609,7 +3730,7 @@ _mm_scalef_ps (__m128 __A, __m128 __B) return (__m128) __builtin_ia32_scalefps128_mask ((__v4sf) __A, (__v4sf) __B, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) -1); } extern __inline __m128 @@ -3628,7 +3749,7 @@ _mm_maskz_scalef_ps (__mmask8 __U, __m128 __A, __m128 __B) return (__m128) __builtin_ia32_scalefps128_mask ((__v4sf) __A, (__v4sf) __B, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m256d @@ -4358,7 +4479,7 @@ _mm_maskz_and_epi32 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pandd128_mask ((__v4si) __A, (__v4si) __B, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -4378,7 +4499,7 @@ _mm256_maskz_andnot_epi32 (__mmask8 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pandnd256_mask ((__v8si) __A, (__v8si) __B, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -4398,7 +4519,7 @@ _mm_maskz_andnot_epi32 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pandnd128_mask ((__v4si) __A, (__v4si) __B, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -4418,7 +4539,7 @@ _mm256_maskz_or_epi32 (__mmask8 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pord256_mask ((__v8si) __A, (__v8si) __B, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m256i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -4442,7 +4563,7 @@ _mm_maskz_or_epi32 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pord128_mask ((__v4si) __A, (__v4si) __B, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -4467,7 +4588,7 @@ _mm256_maskz_xor_epi32 (__mmask8 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pxord256_mask ((__v8si) __A, (__v8si) __B, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m256i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -4492,7 +4613,7 @@ _mm_maskz_xor_epi32 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pxord128_mask ((__v4si) __A, (__v4si) __B, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -4514,7 +4635,7 @@ _mm_maskz_cvtpd_ps (__mmask8 __U, __m128d __A) { return (__m128) __builtin_ia32_cvtpd2ps_mask ((__v2df) __A, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128 @@ -4531,7 +4652,7 @@ _mm256_maskz_cvtpd_ps (__mmask8 __U, __m256d __A) { return (__m128) __builtin_ia32_cvtpd2ps256_mask ((__v4df) __A, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m256i @@ -4548,7 +4669,7 @@ _mm256_maskz_cvtps_epi32 (__mmask8 __U, __m256 __A) { return (__m256i) __builtin_ia32_cvtps2dq256_mask ((__v8sf) __A, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -4565,7 +4686,7 @@ _mm_maskz_cvtps_epi32 (__mmask8 __U, __m128 __A) { return (__m128i) __builtin_ia32_cvtps2dq128_mask ((__v4sf) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -4574,7 +4695,7 @@ _mm256_cvtps_epu32 (__m256 __A) { return (__m256i) __builtin_ia32_cvtps2udq256_mask ((__v8sf) __A, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -4591,7 +4712,7 @@ _mm256_maskz_cvtps_epu32 (__mmask8 __U, __m256 __A) { return (__m256i) __builtin_ia32_cvtps2udq256_mask ((__v8sf) __A, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -4600,7 +4721,7 @@ _mm_cvtps_epu32 (__m128 __A) { return (__m128i) __builtin_ia32_cvtps2udq128_mask ((__v4sf) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -4617,7 +4738,7 @@ _mm_maskz_cvtps_epu32 (__mmask8 __U, __m128 __A) { return (__m128i) __builtin_ia32_cvtps2udq128_mask ((__v4sf) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256d @@ -4634,7 +4755,7 @@ _mm256_maskz_movedup_pd (__mmask8 __U, __m256d __A) { return (__m256d) __builtin_ia32_movddup256_mask ((__v4df) __A, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128d @@ -4651,7 +4772,7 @@ _mm_maskz_movedup_pd (__mmask8 __U, __m128d __A) { return (__m128d) __builtin_ia32_movddup128_mask ((__v2df) __A, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256 @@ -4668,7 +4789,7 @@ _mm256_maskz_movehdup_ps (__mmask8 __U, __m256 __A) { return (__m256) __builtin_ia32_movshdup256_mask ((__v8sf) __A, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128 @@ -4685,7 +4806,7 @@ _mm_maskz_movehdup_ps (__mmask8 __U, __m128 __A) { return (__m128) __builtin_ia32_movshdup128_mask ((__v4sf) __A, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m256 @@ -4702,7 +4823,7 @@ _mm256_maskz_moveldup_ps (__mmask8 __U, __m256 __A) { return (__m256) __builtin_ia32_movsldup256_mask ((__v8sf) __A, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128 @@ -4719,7 +4840,7 @@ _mm_maskz_moveldup_ps (__mmask8 __U, __m128 __A) { return (__m128) __builtin_ia32_movsldup128_mask ((__v4sf) __A, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128i @@ -4739,7 +4860,7 @@ _mm_maskz_unpackhi_epi32 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_punpckhdq128_mask ((__v4si) __A, (__v4si) __B, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -4759,7 +4880,7 @@ _mm256_maskz_unpackhi_epi32 (__mmask8 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_punpckhdq256_mask ((__v8si) __A, (__v8si) __B, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -4779,7 +4900,7 @@ _mm_maskz_unpackhi_epi64 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_punpckhqdq128_mask ((__v2di) __A, (__v2di) __B, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -4799,7 +4920,7 @@ _mm256_maskz_unpackhi_epi64 (__mmask8 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_punpckhqdq256_mask ((__v4di) __A, (__v4di) __B, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -4819,7 +4940,7 @@ _mm_maskz_unpacklo_epi32 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_punpckldq128_mask ((__v4si) __A, (__v4si) __B, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -4839,7 +4960,7 @@ _mm256_maskz_unpacklo_epi32 (__mmask8 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_punpckldq256_mask ((__v8si) __A, (__v8si) __B, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -4859,7 +4980,7 @@ _mm_maskz_unpacklo_epi64 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_punpcklqdq128_mask ((__v2di) __A, (__v2di) __B, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -4879,7 +5000,7 @@ _mm256_maskz_unpacklo_epi64 (__mmask8 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_punpcklqdq256_mask ((__v4di) __A, (__v4di) __B, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __mmask8 @@ -5256,7 +5377,7 @@ _mm256_maskz_compress_pd (__mmask8 __U, __m256d __A) { return (__m256d) __builtin_ia32_compressdf256_mask ((__v4df) __A, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline void @@ -5281,7 +5402,7 @@ _mm_maskz_compress_pd (__mmask8 __U, __m128d __A) { return (__m128d) __builtin_ia32_compressdf128_mask ((__v2df) __A, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline void @@ -5306,7 +5427,7 @@ _mm256_maskz_compress_ps (__mmask8 __U, __m256 __A) { return (__m256) __builtin_ia32_compresssf256_mask ((__v8sf) __A, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline void @@ -5331,7 +5452,7 @@ _mm_maskz_compress_ps (__mmask8 __U, __m128 __A) { return (__m128) __builtin_ia32_compresssf128_mask ((__v4sf) __A, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline void @@ -5356,7 +5477,7 @@ _mm256_maskz_compress_epi64 (__mmask8 __U, __m256i __A) { return (__m256i) __builtin_ia32_compressdi256_mask ((__v4di) __A, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline void @@ -5381,7 +5502,7 @@ _mm_maskz_compress_epi64 (__mmask8 __U, __m128i __A) { return (__m128i) __builtin_ia32_compressdi128_mask ((__v2di) __A, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline void @@ -5406,7 +5527,7 @@ _mm256_maskz_compress_epi32 (__mmask8 __U, __m256i __A) { return (__m256i) __builtin_ia32_compresssi256_mask ((__v8si) __A, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline void @@ -5431,7 +5552,7 @@ _mm_maskz_compress_epi32 (__mmask8 __U, __m128i __A) { return (__m128i) __builtin_ia32_compresssi128_mask ((__v4si) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline void @@ -5456,7 +5577,7 @@ _mm256_maskz_expand_pd (__mmask8 __U, __m256d __A) { return (__m256d) __builtin_ia32_expanddf256_maskz ((__v4df) __A, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256d @@ -5474,7 +5595,7 @@ _mm256_maskz_expandloadu_pd (__mmask8 __U, void const *__P) { return (__m256d) __builtin_ia32_expandloaddf256_maskz ((__v4df *) __P, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } @@ -5492,7 +5613,7 @@ _mm_maskz_expand_pd (__mmask8 __U, __m128d __A) { return (__m128d) __builtin_ia32_expanddf128_maskz ((__v2df) __A, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128d @@ -5510,7 +5631,7 @@ _mm_maskz_expandloadu_pd (__mmask8 __U, void const *__P) { return (__m128d) __builtin_ia32_expandloaddf128_maskz ((__v2df *) __P, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } @@ -5528,7 +5649,7 @@ _mm256_maskz_expand_ps (__mmask8 __U, __m256 __A) { return (__m256) __builtin_ia32_expandsf256_maskz ((__v8sf) __A, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m256 @@ -5545,7 +5666,7 @@ _mm256_maskz_expandloadu_ps (__mmask8 __U, void const *__P) { return (__m256) __builtin_ia32_expandloadsf256_maskz ((__v8sf *) __P, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } @@ -5563,7 +5684,7 @@ _mm_maskz_expand_ps (__mmask8 __U, __m128 __A) { return (__m128) __builtin_ia32_expandsf128_maskz ((__v4sf) __A, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128 @@ -5580,7 +5701,7 @@ _mm_maskz_expandloadu_ps (__mmask8 __U, void const *__P) { return (__m128) __builtin_ia32_expandloadsf128_maskz ((__v4sf *) __P, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } @@ -5598,7 +5719,7 @@ _mm256_maskz_expand_epi64 (__mmask8 __U, __m256i __A) { return (__m256i) __builtin_ia32_expanddi256_maskz ((__v4di) __A, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m256i @@ -5617,7 +5738,7 @@ _mm256_maskz_expandloadu_epi64 (__mmask8 __U, void const *__P) { return (__m256i) __builtin_ia32_expandloaddi256_maskz ((__v4di *) __P, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } @@ -5635,7 +5756,7 @@ _mm_maskz_expand_epi64 (__mmask8 __U, __m128i __A) { return (__m128i) __builtin_ia32_expanddi128_maskz ((__v2di) __A, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i @@ -5653,7 +5774,7 @@ _mm_maskz_expandloadu_epi64 (__mmask8 __U, void const *__P) { return (__m128i) __builtin_ia32_expandloaddi128_maskz ((__v2di *) __P, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } @@ -5671,7 +5792,7 @@ _mm256_maskz_expand_epi32 (__mmask8 __U, __m256i __A) { return (__m256i) __builtin_ia32_expandsi256_maskz ((__v8si) __A, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m256i @@ -5690,7 +5811,7 @@ _mm256_maskz_expandloadu_epi32 (__mmask8 __U, void const *__P) { return (__m256i) __builtin_ia32_expandloadsi256_maskz ((__v8si *) __P, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } @@ -5708,7 +5829,7 @@ _mm_maskz_expand_epi32 (__mmask8 __U, __m128i __A) { return (__m128i) __builtin_ia32_expandsi128_maskz ((__v4si) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i @@ -5726,7 +5847,7 @@ _mm_maskz_expandloadu_epi32 (__mmask8 __U, void const *__P) { return (__m128i) __builtin_ia32_expandloadsi128_maskz ((__v4si *) __P, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } @@ -6093,7 +6214,7 @@ _mm_srav_epi64 (__m128i __X, __m128i __Y) return (__m128i) __builtin_ia32_psravq128_mask ((__v2di) __X, (__v2di) __Y, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -6113,7 +6234,7 @@ _mm_maskz_srav_epi64 (__mmask8 __U, __m128i __X, __m128i __Y) return (__m128i) __builtin_ia32_psravq128_mask ((__v2di) __X, (__v2di) __Y, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -6133,7 +6254,7 @@ _mm256_maskz_sllv_epi32 (__mmask8 __U, __m256i __X, __m256i __Y) return (__m256i) __builtin_ia32_psllv8si_mask ((__v8si) __X, (__v8si) __Y, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -6153,7 +6274,7 @@ _mm_maskz_sllv_epi32 (__mmask8 __U, __m128i __X, __m128i __Y) return (__m128i) __builtin_ia32_psllv4si_mask ((__v4si) __X, (__v4si) __Y, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -6173,7 +6294,7 @@ _mm256_maskz_sllv_epi64 (__mmask8 __U, __m256i __X, __m256i __Y) return (__m256i) __builtin_ia32_psllv4di_mask ((__v4di) __X, (__v4di) __Y, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -6193,7 +6314,7 @@ _mm_maskz_sllv_epi64 (__mmask8 __U, __m128i __X, __m128i __Y) return (__m128i) __builtin_ia32_psllv2di_mask ((__v2di) __X, (__v2di) __Y, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -6213,7 +6334,7 @@ _mm256_maskz_srav_epi32 (__mmask8 __U, __m256i __X, __m256i __Y) return (__m256i) __builtin_ia32_psrav8si_mask ((__v8si) __X, (__v8si) __Y, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -6233,7 +6354,7 @@ _mm_maskz_srav_epi32 (__mmask8 __U, __m128i __X, __m128i __Y) return (__m128i) __builtin_ia32_psrav4si_mask ((__v4si) __X, (__v4si) __Y, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -6253,7 +6374,7 @@ _mm256_maskz_srlv_epi32 (__mmask8 __U, __m256i __X, __m256i __Y) return (__m256i) __builtin_ia32_psrlv8si_mask ((__v8si) __X, (__v8si) __Y, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -6273,7 +6394,7 @@ _mm_maskz_srlv_epi32 (__mmask8 __U, __m128i __X, __m128i __Y) return (__m128i) __builtin_ia32_psrlv4si_mask ((__v4si) __X, (__v4si) __Y, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -6293,7 +6414,7 @@ _mm256_maskz_srlv_epi64 (__mmask8 __U, __m256i __X, __m256i __Y) return (__m256i) __builtin_ia32_psrlv4di_mask ((__v4di) __X, (__v4di) __Y, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -6313,7 +6434,7 @@ _mm_maskz_srlv_epi64 (__mmask8 __U, __m128i __X, __m128i __Y) return (__m128i) __builtin_ia32_psrlv2di_mask ((__v2di) __X, (__v2di) __Y, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -6323,7 +6444,7 @@ _mm256_rolv_epi32 (__m256i __A, __m256i __B) return (__m256i) __builtin_ia32_prolvd256_mask ((__v8si) __A, (__v8si) __B, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -6343,7 +6464,7 @@ _mm256_maskz_rolv_epi32 (__mmask8 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_prolvd256_mask ((__v8si) __A, (__v8si) __B, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -6353,7 +6474,7 @@ _mm_rolv_epi32 (__m128i __A, __m128i __B) return (__m128i) __builtin_ia32_prolvd128_mask ((__v4si) __A, (__v4si) __B, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -6373,7 +6494,7 @@ _mm_maskz_rolv_epi32 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_prolvd128_mask ((__v4si) __A, (__v4si) __B, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -6383,7 +6504,7 @@ _mm256_rorv_epi32 (__m256i __A, __m256i __B) return (__m256i) __builtin_ia32_prorvd256_mask ((__v8si) __A, (__v8si) __B, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -6403,7 +6524,7 @@ _mm256_maskz_rorv_epi32 (__mmask8 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_prorvd256_mask ((__v8si) __A, (__v8si) __B, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -6413,7 +6534,7 @@ _mm_rorv_epi32 (__m128i __A, __m128i __B) return (__m128i) __builtin_ia32_prorvd128_mask ((__v4si) __A, (__v4si) __B, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -6433,7 +6554,7 @@ _mm_maskz_rorv_epi32 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_prorvd128_mask ((__v4si) __A, (__v4si) __B, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -6443,7 +6564,7 @@ _mm256_rolv_epi64 (__m256i __A, __m256i __B) return (__m256i) __builtin_ia32_prolvq256_mask ((__v4di) __A, (__v4di) __B, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -6463,7 +6584,7 @@ _mm256_maskz_rolv_epi64 (__mmask8 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_prolvq256_mask ((__v4di) __A, (__v4di) __B, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -6473,7 +6594,7 @@ _mm_rolv_epi64 (__m128i __A, __m128i __B) return (__m128i) __builtin_ia32_prolvq128_mask ((__v2di) __A, (__v2di) __B, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -6493,7 +6614,7 @@ _mm_maskz_rolv_epi64 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_prolvq128_mask ((__v2di) __A, (__v2di) __B, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -6503,7 +6624,7 @@ _mm256_rorv_epi64 (__m256i __A, __m256i __B) return (__m256i) __builtin_ia32_prorvq256_mask ((__v4di) __A, (__v4di) __B, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -6523,7 +6644,7 @@ _mm256_maskz_rorv_epi64 (__mmask8 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_prorvq256_mask ((__v4di) __A, (__v4di) __B, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -6533,7 +6654,7 @@ _mm_rorv_epi64 (__m128i __A, __m128i __B) return (__m128i) __builtin_ia32_prorvq128_mask ((__v2di) __A, (__v2di) __B, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -6553,7 +6674,7 @@ _mm_maskz_rorv_epi64 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_prorvq128_mask ((__v2di) __A, (__v2di) __B, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -6563,7 +6684,7 @@ _mm256_srav_epi64 (__m256i __X, __m256i __Y) return (__m256i) __builtin_ia32_psravq256_mask ((__v4di) __X, (__v4di) __Y, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -6583,7 +6704,7 @@ _mm256_maskz_srav_epi64 (__mmask8 __U, __m256i __X, __m256i __Y) return (__m256i) __builtin_ia32_psravq256_mask ((__v4di) __X, (__v4di) __Y, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m256i @@ -6602,7 +6723,7 @@ _mm256_maskz_and_epi64 (__mmask8 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pandq256_mask ((__v4di) __A, (__v4di) __B, (__v4di) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), __U); } extern __inline __m128i @@ -6621,7 +6742,7 @@ _mm_maskz_and_epi64 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pandq128_mask ((__v2di) __A, (__v2di) __B, (__v2di) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), __U); } extern __inline __m256i @@ -6640,7 +6761,7 @@ _mm256_maskz_andnot_epi64 (__mmask8 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pandnq256_mask ((__v4di) __A, (__v4di) __B, (__v4di) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), __U); } extern __inline __m128i @@ -6659,7 +6780,7 @@ _mm_maskz_andnot_epi64 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pandnq128_mask ((__v2di) __A, (__v2di) __B, (__v2di) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), __U); } extern __inline __m256i @@ -6679,7 +6800,7 @@ _mm256_maskz_or_epi64 (__mmask8 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_porq256_mask ((__v4di) __A, (__v4di) __B, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m256i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -6703,7 +6824,7 @@ _mm_maskz_or_epi64 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_porq128_mask ((__v2di) __A, (__v2di) __B, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -6728,7 +6849,7 @@ _mm256_maskz_xor_epi64 (__mmask8 __U, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pxorq256_mask ((__v4di) __A, (__v4di) __B, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m256i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -6753,7 +6874,7 @@ _mm_maskz_xor_epi64 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pxorq128_mask ((__v2di) __A, (__v2di) __B, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -6778,7 +6899,7 @@ _mm256_maskz_max_pd (__mmask8 __U, __m256d __A, __m256d __B) return (__m256d) __builtin_ia32_maxpd256_mask ((__v4df) __A, (__v4df) __B, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256 @@ -6797,7 +6918,7 @@ _mm256_maskz_max_ps (__mmask8 __U, __m256 __A, __m256 __B) return (__m256) __builtin_ia32_maxps256_mask ((__v8sf) __A, (__v8sf) __B, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128 @@ -6816,7 +6937,7 @@ _mm_maskz_div_ps (__mmask8 __U, __m128 __A, __m128 __B) return (__m128) __builtin_ia32_divps_mask ((__v4sf) __A, (__v4sf) __B, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128d @@ -6835,7 +6956,7 @@ _mm_maskz_div_pd (__mmask8 __U, __m128d __A, __m128d __B) return (__m128d) __builtin_ia32_divpd_mask ((__v2df) __A, (__v2df) __B, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256d @@ -6865,7 +6986,7 @@ _mm256_maskz_min_pd (__mmask8 __U, __m256d __A, __m256d __B) return (__m256d) __builtin_ia32_minpd256_mask ((__v4df) __A, (__v4df) __B, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256 @@ -6884,7 +7005,7 @@ _mm256_maskz_div_pd (__mmask8 __U, __m256d __A, __m256d __B) return (__m256d) __builtin_ia32_divpd256_mask ((__v4df) __A, (__v4df) __B, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256 @@ -6903,7 +7024,7 @@ _mm256_maskz_min_ps (__mmask8 __U, __m256 __A, __m256 __B) return (__m256) __builtin_ia32_minps256_mask ((__v8sf) __A, (__v8sf) __B, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m256 @@ -6913,7 +7034,7 @@ _mm256_maskz_div_ps (__mmask8 __U, __m256 __A, __m256 __B) return (__m256) __builtin_ia32_divps256_mask ((__v8sf) __A, (__v8sf) __B, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128 @@ -6941,7 +7062,7 @@ _mm_maskz_min_ps (__mmask8 __U, __m128 __A, __m128 __B) return (__m128) __builtin_ia32_minps_mask ((__v4sf) __A, (__v4sf) __B, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128 @@ -6951,7 +7072,7 @@ _mm_maskz_mul_ps (__mmask8 __U, __m128 __A, __m128 __B) return (__m128) __builtin_ia32_mulps_mask ((__v4sf) __A, (__v4sf) __B, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128 @@ -6970,7 +7091,7 @@ _mm_maskz_max_ps (__mmask8 __U, __m128 __A, __m128 __B) return (__m128) __builtin_ia32_maxps_mask ((__v4sf) __A, (__v4sf) __B, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128d @@ -6989,7 +7110,7 @@ _mm_maskz_min_pd (__mmask8 __U, __m128d __A, __m128d __B) return (__m128d) __builtin_ia32_minpd_mask ((__v2df) __A, (__v2df) __B, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128d @@ -7008,7 +7129,7 @@ _mm_maskz_max_pd (__mmask8 __U, __m128d __A, __m128d __B) return (__m128d) __builtin_ia32_maxpd_mask ((__v2df) __A, (__v2df) __B, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128d @@ -7027,7 +7148,7 @@ _mm_maskz_mul_pd (__mmask8 __U, __m128d __A, __m128d __B) return (__m128d) __builtin_ia32_mulpd_mask ((__v2df) __A, (__v2df) __B, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256 @@ -7046,7 +7167,7 @@ _mm256_maskz_mul_ps (__mmask8 __U, __m256 __A, __m256 __B) return (__m256) __builtin_ia32_mulps256_mask ((__v8sf) __A, (__v8sf) __B, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m256d @@ -7066,7 +7187,7 @@ _mm256_maskz_mul_pd (__mmask8 __U, __m256d __A, __m256d __B) return (__m256d) __builtin_ia32_mulpd256_mask ((__v4df) __A, (__v4df) __B, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256i @@ -7076,7 +7197,7 @@ _mm256_maskz_max_epi64 (__mmask8 __M, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pmaxsq256_mask ((__v4di) __A, (__v4di) __B, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __M); } extern __inline __m256i @@ -7095,7 +7216,7 @@ _mm256_min_epi64 (__m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pminsq256_mask ((__v4di) __A, (__v4di) __B, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -7114,7 +7235,7 @@ _mm256_maskz_min_epi64 (__mmask8 __M, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pminsq256_mask ((__v4di) __A, (__v4di) __B, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __M); } extern __inline __m256i @@ -7124,7 +7245,7 @@ _mm256_maskz_max_epu64 (__mmask8 __M, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pmaxuq256_mask ((__v4di) __A, (__v4di) __B, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __M); } extern __inline __m256i @@ -7134,7 +7255,7 @@ _mm256_max_epi64 (__m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pmaxsq256_mask ((__v4di) __A, (__v4di) __B, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -7144,7 +7265,7 @@ _mm256_max_epu64 (__m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pmaxuq256_mask ((__v4di) __A, (__v4di) __B, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -7163,7 +7284,7 @@ _mm256_min_epu64 (__m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pminuq256_mask ((__v4di) __A, (__v4di) __B, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -7182,7 +7303,7 @@ _mm256_maskz_min_epu64 (__mmask8 __M, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pminuq256_mask ((__v4di) __A, (__v4di) __B, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __M); } extern __inline __m256i @@ -7192,7 +7313,7 @@ _mm256_maskz_max_epi32 (__mmask8 __M, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pmaxsd256_mask ((__v8si) __A, (__v8si) __B, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __M); } extern __inline __m256i @@ -7211,7 +7332,7 @@ _mm256_maskz_min_epi32 (__mmask8 __M, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pminsd256_mask ((__v8si) __A, (__v8si) __B, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __M); } extern __inline __m256i @@ -7230,7 +7351,7 @@ _mm256_maskz_max_epu32 (__mmask8 __M, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pmaxud256_mask ((__v8si) __A, (__v8si) __B, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __M); } extern __inline __m256i @@ -7249,7 +7370,7 @@ _mm256_maskz_min_epu32 (__mmask8 __M, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pminud256_mask ((__v8si) __A, (__v8si) __B, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __M); } extern __inline __m256i @@ -7268,7 +7389,7 @@ _mm_maskz_max_epi64 (__mmask8 __M, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pmaxsq128_mask ((__v2di) __A, (__v2di) __B, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -7287,7 +7408,7 @@ _mm_min_epi64 (__m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pminsq128_mask ((__v2di) __A, (__v2di) __B, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -7306,7 +7427,7 @@ _mm_maskz_min_epi64 (__mmask8 __M, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pminsq128_mask ((__v2di) __A, (__v2di) __B, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -7316,7 +7437,7 @@ _mm_maskz_max_epu64 (__mmask8 __M, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pmaxuq128_mask ((__v2di) __A, (__v2di) __B, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -7326,7 +7447,7 @@ _mm_max_epi64 (__m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pmaxsq128_mask ((__v2di) __A, (__v2di) __B, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -7336,7 +7457,7 @@ _mm_max_epu64 (__m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pmaxuq128_mask ((__v2di) __A, (__v2di) __B, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -7355,7 +7476,7 @@ _mm_min_epu64 (__m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pminuq128_mask ((__v2di) __A, (__v2di) __B, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -7374,7 +7495,7 @@ _mm_maskz_min_epu64 (__mmask8 __M, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pminuq128_mask ((__v2di) __A, (__v2di) __B, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -7384,7 +7505,7 @@ _mm_maskz_max_epi32 (__mmask8 __M, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pmaxsd128_mask ((__v4si) __A, (__v4si) __B, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -7403,7 +7524,7 @@ _mm_maskz_min_epi32 (__mmask8 __M, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pminsd128_mask ((__v4si) __A, (__v4si) __B, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -7422,7 +7543,7 @@ _mm_maskz_max_epu32 (__mmask8 __M, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pmaxud128_mask ((__v4si) __A, (__v4si) __B, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -7441,7 +7562,7 @@ _mm_maskz_min_epu32 (__mmask8 __M, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pminud128_mask ((__v4si) __A, (__v4si) __B, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -7453,254 +7574,6 @@ _mm_mask_min_epu32 (__m128i __W, __mmask8 __M, __m128i __A, (__v4si) __B, (__v4si) __W, __M); } -#ifndef __AVX512CD__ -#pragma GCC push_options -#pragma GCC target("avx512vl,avx512cd") -#define __DISABLE_AVX512VLCD__ -#endif -extern __inline __m128i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_broadcastmb_epi64 (__mmask8 __A) -{ - return (__m128i) __builtin_ia32_broadcastmb128 (__A); -} -extern __inline __m256i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_broadcastmb_epi64 (__mmask8 __A) -{ - return (__m256i) __builtin_ia32_broadcastmb256 (__A); -} -extern __inline __m128i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_broadcastmw_epi32 (__mmask16 __A) -{ - return (__m128i) __builtin_ia32_broadcastmw128 (__A); -} -extern __inline __m256i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_broadcastmw_epi32 (__mmask16 __A) -{ - return (__m256i) __builtin_ia32_broadcastmw256 (__A); -} -extern __inline __m256i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_lzcnt_epi32 (__m256i __A) -{ - return (__m256i) __builtin_ia32_vplzcntd_256_mask ((__v8si) __A, - (__v8si) - _mm256_setzero_si256 (), - (__mmask8) -1); -} -extern __inline __m256i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_lzcnt_epi32 (__m256i __W, __mmask8 __U, __m256i __A) -{ - return (__m256i) __builtin_ia32_vplzcntd_256_mask ((__v8si) __A, - (__v8si) __W, - (__mmask8) __U); -} -extern __inline __m256i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_maskz_lzcnt_epi32 (__mmask8 __U, __m256i __A) -{ - return (__m256i) __builtin_ia32_vplzcntd_256_mask ((__v8si) __A, - (__v8si) - _mm256_setzero_si256 (), - (__mmask8) __U); -} -extern __inline __m256i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_lzcnt_epi64 (__m256i __A) -{ - return (__m256i) __builtin_ia32_vplzcntq_256_mask ((__v4di) __A, - (__v4di) - _mm256_setzero_si256 (), - (__mmask8) -1); -} -extern __inline __m256i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_lzcnt_epi64 (__m256i __W, __mmask8 __U, __m256i __A) -{ - return (__m256i) __builtin_ia32_vplzcntq_256_mask ((__v4di) __A, - (__v4di) __W, - (__mmask8) __U); -} -extern __inline __m256i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_maskz_lzcnt_epi64 (__mmask8 __U, __m256i __A) -{ - return (__m256i) __builtin_ia32_vplzcntq_256_mask ((__v4di) __A, - (__v4di) - _mm256_setzero_si256 (), - (__mmask8) __U); -} -extern __inline __m256i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_conflict_epi64 (__m256i __A) -{ - return (__m256i) __builtin_ia32_vpconflictdi_256_mask ((__v4di) __A, - (__v4di) - _mm256_setzero_si256 (), - (__mmask8) -1); -} -extern __inline __m256i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_conflict_epi64 (__m256i __W, __mmask8 __U, __m256i __A) -{ - return (__m256i) __builtin_ia32_vpconflictdi_256_mask ((__v4di) __A, - (__v4di) __W, - (__mmask8) - __U); -} -extern __inline __m256i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_maskz_conflict_epi64 (__mmask8 __U, __m256i __A) -{ - return (__m256i) __builtin_ia32_vpconflictdi_256_mask ((__v4di) __A, - (__v4di) - _mm256_setzero_si256 (), - (__mmask8) - __U); -} -extern __inline __m256i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_conflict_epi32 (__m256i __A) -{ - return (__m256i) __builtin_ia32_vpconflictsi_256_mask ((__v8si) __A, - (__v8si) - _mm256_setzero_si256 (), - (__mmask8) -1); -} -extern __inline __m256i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_conflict_epi32 (__m256i __W, __mmask8 __U, __m256i __A) -{ - return (__m256i) __builtin_ia32_vpconflictsi_256_mask ((__v8si) __A, - (__v8si) __W, - (__mmask8) - __U); -} -extern __inline __m256i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_maskz_conflict_epi32 (__mmask8 __U, __m256i __A) -{ - return (__m256i) __builtin_ia32_vpconflictsi_256_mask ((__v8si) __A, - (__v8si) - _mm256_setzero_si256 (), - (__mmask8) - __U); -} -extern __inline __m128i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_lzcnt_epi32 (__m128i __A) -{ - return (__m128i) __builtin_ia32_vplzcntd_128_mask ((__v4si) __A, - (__v4si) - _mm_setzero_si128 (), - (__mmask8) -1); -} -extern __inline __m128i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_lzcnt_epi32 (__m128i __W, __mmask8 __U, __m128i __A) -{ - return (__m128i) __builtin_ia32_vplzcntd_128_mask ((__v4si) __A, - (__v4si) __W, - (__mmask8) __U); -} -extern __inline __m128i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_lzcnt_epi32 (__mmask8 __U, __m128i __A) -{ - return (__m128i) __builtin_ia32_vplzcntd_128_mask ((__v4si) __A, - (__v4si) - _mm_setzero_si128 (), - (__mmask8) __U); -} -extern __inline __m128i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_lzcnt_epi64 (__m128i __A) -{ - return (__m128i) __builtin_ia32_vplzcntq_128_mask ((__v2di) __A, - (__v2di) - _mm_setzero_si128 (), - (__mmask8) -1); -} -extern __inline __m128i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_lzcnt_epi64 (__m128i __W, __mmask8 __U, __m128i __A) -{ - return (__m128i) __builtin_ia32_vplzcntq_128_mask ((__v2di) __A, - (__v2di) __W, - (__mmask8) __U); -} -extern __inline __m128i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_lzcnt_epi64 (__mmask8 __U, __m128i __A) -{ - return (__m128i) __builtin_ia32_vplzcntq_128_mask ((__v2di) __A, - (__v2di) - _mm_setzero_si128 (), - (__mmask8) __U); -} -extern __inline __m128i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_conflict_epi64 (__m128i __A) -{ - return (__m128i) __builtin_ia32_vpconflictdi_128_mask ((__v2di) __A, - (__v2di) - _mm_setzero_si128 (), - (__mmask8) -1); -} -extern __inline __m128i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_conflict_epi64 (__m128i __W, __mmask8 __U, __m128i __A) -{ - return (__m128i) __builtin_ia32_vpconflictdi_128_mask ((__v2di) __A, - (__v2di) __W, - (__mmask8) - __U); -} -extern __inline __m128i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_conflict_epi64 (__mmask8 __U, __m128i __A) -{ - return (__m128i) __builtin_ia32_vpconflictdi_128_mask ((__v2di) __A, - (__v2di) - _mm_setzero_si128 (), - (__mmask8) - __U); -} -extern __inline __m128i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_conflict_epi32 (__m128i __A) -{ - return (__m128i) __builtin_ia32_vpconflictsi_128_mask ((__v4si) __A, - (__v4si) - _mm_setzero_si128 (), - (__mmask8) -1); -} -extern __inline __m128i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_conflict_epi32 (__m128i __W, __mmask8 __U, __m128i __A) -{ - return (__m128i) __builtin_ia32_vpconflictsi_128_mask ((__v4si) __A, - (__v4si) __W, - (__mmask8) - __U); -} -extern __inline __m128i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_conflict_epi32 (__mmask8 __U, __m128i __A) -{ - return (__m128i) __builtin_ia32_vpconflictsi_128_mask ((__v4si) __A, - (__v4si) - _mm_setzero_si128 (), - (__mmask8) - __U); -} -#ifdef __DISABLE_AVX512VLCD__ -#pragma GCC pop_options -#endif extern __inline __m256d __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_mask_unpacklo_pd (__m256d __W, __mmask8 __U, __m256d __A, @@ -7718,7 +7591,7 @@ _mm256_maskz_unpacklo_pd (__mmask8 __U, __m256d __A, __m256d __B) return (__m256d) __builtin_ia32_unpcklpd256_mask ((__v4df) __A, (__v4df) __B, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128d @@ -7738,7 +7611,7 @@ _mm_maskz_unpacklo_pd (__mmask8 __U, __m128d __A, __m128d __B) return (__m128d) __builtin_ia32_unpcklpd128_mask ((__v2df) __A, (__v2df) __B, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256 @@ -7768,7 +7641,7 @@ _mm256_maskz_unpackhi_pd (__mmask8 __U, __m256d __A, __m256d __B) return (__m256d) __builtin_ia32_unpckhpd256_mask ((__v4df) __A, (__v4df) __B, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128d @@ -7788,7 +7661,7 @@ _mm_maskz_unpackhi_pd (__mmask8 __U, __m128d __A, __m128d __B) return (__m128d) __builtin_ia32_unpckhpd128_mask ((__v2df) __A, (__v2df) __B, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256 @@ -7808,7 +7681,7 @@ _mm256_maskz_unpackhi_ps (__mmask8 __U, __m256 __A, __m256 __B) return (__m256) __builtin_ia32_unpckhps256_mask ((__v8sf) __A, (__v8sf) __B, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128 @@ -7827,7 +7700,7 @@ _mm_maskz_unpackhi_ps (__mmask8 __U, __m128 __A, __m128 __B) return (__m128) __builtin_ia32_unpckhps128_mask ((__v4sf) __A, (__v4sf) __B, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128 @@ -7844,7 +7717,7 @@ _mm_maskz_cvtph_ps (__mmask8 __U, __m128i __A) { return (__m128) __builtin_ia32_vcvtph2ps_mask ((__v8hi) __A, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m256 @@ -7854,7 +7727,7 @@ _mm256_maskz_unpacklo_ps (__mmask8 __U, __m256 __A, __m256 __B) return (__m256) __builtin_ia32_unpcklps256_mask ((__v8sf) __A, (__v8sf) __B, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m256 @@ -7871,7 +7744,7 @@ _mm256_maskz_cvtph_ps (__mmask8 __U, __m128i __A) { return (__m256) __builtin_ia32_vcvtph2ps256_mask ((__v8hi) __A, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128 @@ -7890,7 +7763,7 @@ _mm_maskz_unpacklo_ps (__mmask8 __U, __m128 __A, __m128 __B) return (__m128) __builtin_ia32_unpcklps128_mask ((__v4sf) __A, (__v4sf) __B, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m256i @@ -7910,7 +7783,7 @@ _mm256_maskz_sra_epi32 (__mmask8 __U, __m256i __A, __m128i __B) return (__m256i) __builtin_ia32_psrad256_mask ((__v8si) __A, (__v4si) __B, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -7930,7 +7803,7 @@ _mm_maskz_sra_epi32 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_psrad128_mask ((__v4si) __A, (__v4si) __B, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -7940,7 +7813,7 @@ _mm256_sra_epi64 (__m256i __A, __m128i __B) return (__m256i) __builtin_ia32_psraq256_mask ((__v4di) __A, (__v2di) __B, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -7960,7 +7833,7 @@ _mm256_maskz_sra_epi64 (__mmask8 __U, __m256i __A, __m128i __B) return (__m256i) __builtin_ia32_psraq256_mask ((__v4di) __A, (__v2di) __B, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -7970,7 +7843,7 @@ _mm_sra_epi64 (__m128i __A, __m128i __B) return (__m128i) __builtin_ia32_psraq128_mask ((__v2di) __A, (__v2di) __B, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -7990,7 +7863,7 @@ _mm_maskz_sra_epi64 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_psraq128_mask ((__v2di) __A, (__v2di) __B, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i @@ -8010,7 +7883,7 @@ _mm_maskz_sll_epi32 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pslld128_mask ((__v4si) __A, (__v4si) __B, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i @@ -8030,7 +7903,7 @@ _mm_maskz_sll_epi64 (__mmask8 __U, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_psllq128_mask ((__v2di) __A, (__v2di) __B, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -8050,7 +7923,7 @@ _mm256_maskz_sll_epi32 (__mmask8 __U, __m256i __A, __m128i __B) return (__m256i) __builtin_ia32_pslld256_mask ((__v8si) __A, (__v4si) __B, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m256i @@ -8070,7 +7943,7 @@ _mm256_maskz_sll_epi64 (__mmask8 __U, __m256i __A, __m128i __B) return (__m256i) __builtin_ia32_psllq256_mask ((__v4di) __A, (__v2di) __B, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m256 @@ -8090,7 +7963,7 @@ _mm256_maskz_permutexvar_ps (__mmask8 __U, __m256i __X, __m256 __Y) return (__m256) __builtin_ia32_permvarsf256_mask ((__v8sf) __Y, (__v8si) __X, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m256d @@ -8100,7 +7973,7 @@ _mm256_permutexvar_pd (__m256i __X, __m256d __Y) return (__m256d) __builtin_ia32_permvardf256_mask ((__v4df) __Y, (__v4di) __X, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) -1); } extern __inline __m256d @@ -8120,7 +7993,7 @@ _mm256_maskz_permutexvar_pd (__mmask8 __U, __m256i __X, __m256d __Y) return (__m256d) __builtin_ia32_permvardf256_mask ((__v4df) __Y, (__v4di) __X, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256d @@ -8141,7 +8014,7 @@ _mm256_maskz_permutevar_pd (__mmask8 __U, __m256d __A, __m256i __C) return (__m256d) __builtin_ia32_vpermilvarpd256_mask ((__v4df) __A, (__v4di) __C, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } @@ -8162,7 +8035,7 @@ _mm256_maskz_permutevar_ps (__mmask8 __U, __m256 __A, __m256i __C) return (__m256) __builtin_ia32_vpermilvarps256_mask ((__v8sf) __A, (__v8si) __C, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128d @@ -8182,7 +8055,7 @@ _mm_maskz_permutevar_pd (__mmask8 __U, __m128d __A, __m128i __C) return (__m128d) __builtin_ia32_vpermilvarpd_mask ((__v2df) __A, (__v2di) __C, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128 @@ -8202,7 +8075,7 @@ _mm_maskz_permutevar_ps (__mmask8 __U, __m128 __A, __m128i __C) return (__m128) __builtin_ia32_vpermilvarps_mask ((__v4sf) __A, (__v4si) __C, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m256i @@ -8212,7 +8085,7 @@ _mm256_maskz_mullo_epi32 (__mmask8 __M, __m256i __A, __m256i __B) return (__m256i) __builtin_ia32_pmulld256_mask ((__v8si) __A, (__v8si) __B, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __M); } extern __inline __m256i @@ -8222,7 +8095,7 @@ _mm256_maskz_permutexvar_epi64 (__mmask8 __M, __m256i __X, __m256i __Y) return (__m256i) __builtin_ia32_permvardi256_mask ((__v4di) __Y, (__v4di) __X, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __M); } extern __inline __m256i @@ -8241,7 +8114,7 @@ _mm_maskz_mullo_epi32 (__mmask8 __M, __m128i __A, __m128i __B) return (__m128i) __builtin_ia32_pmulld128_mask ((__v4si) __A, (__v4si) __B, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m128i @@ -8269,7 +8142,7 @@ _mm256_maskz_mul_epi32 (__mmask8 __M, __m256i __X, __m256i __Y) return (__m256i) __builtin_ia32_pmuldq256_mask ((__v8si) __X, (__v8si) __Y, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __M); } extern __inline __m128i @@ -8288,7 +8161,7 @@ _mm_maskz_mul_epi32 (__mmask8 __M, __m128i __X, __m128i __Y) return (__m128i) __builtin_ia32_pmuldq128_mask ((__v4si) __X, (__v4si) __Y, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m256i @@ -8298,7 +8171,7 @@ _mm256_permutexvar_epi64 (__m256i __X, __m256i __Y) return (__m256i) __builtin_ia32_permvardi256_mask ((__v4di) __Y, (__v4di) __X, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -8327,7 +8200,7 @@ _mm256_maskz_permutexvar_epi32 (__mmask8 __M, __m256i __X, __m256i __Y) return (__m256i) __builtin_ia32_permvarsi256_mask ((__v8si) __Y, (__v8si) __X, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __M); } extern __inline __m256i @@ -8337,7 +8210,7 @@ _mm256_maskz_mul_epu32 (__mmask8 __M, __m256i __X, __m256i __Y) return (__m256i) __builtin_ia32_pmuludq256_mask ((__v8si) __X, (__v8si) __Y, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), __M); } extern __inline __m128i @@ -8356,7 +8229,7 @@ _mm_maskz_mul_epu32 (__mmask8 __M, __m128i __X, __m128i __Y) return (__m128i) __builtin_ia32_pmuludq128_mask ((__v4si) __X, (__v4si) __Y, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), __M); } extern __inline __m256i @@ -8366,7 +8239,7 @@ _mm256_permutexvar_epi32 (__m256i __X, __m256i __Y) return (__m256i) __builtin_ia32_permvarsi256_mask ((__v8si) __Y, (__v8si) __X, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -8899,7 +8772,7 @@ _mm256_permutex_epi64 (__m256i __X, const int __I) return (__m256i) __builtin_ia32_permdi256_mask ((__v4di) __X, __I, (__v4di) - _mm256_setzero_si256(), + _mm256_avx512_setzero_si256(), (__mmask8) -1); } extern __inline __m256i @@ -8919,7 +8792,7 @@ _mm256_maskz_permutex_epi64 (__mmask8 __M, __m256i __X, const int __I) return (__m256i) __builtin_ia32_permdi256_mask ((__v4di) __X, __I, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __M); } extern __inline __m256d @@ -8940,7 +8813,7 @@ _mm256_maskz_shuffle_pd (__mmask8 __U, __m256d __A, __m256d __B, return (__m256d) __builtin_ia32_shufpd256_mask ((__v4df) __A, (__v4df) __B, __imm, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128d @@ -8961,7 +8834,7 @@ _mm_maskz_shuffle_pd (__mmask8 __U, __m128d __A, __m128d __B, return (__m128d) __builtin_ia32_shufpd128_mask ((__v2df) __A, (__v2df) __B, __imm, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256 @@ -8982,7 +8855,7 @@ _mm256_maskz_shuffle_ps (__mmask8 __U, __m256 __A, __m256 __B, return (__m256) __builtin_ia32_shufps256_mask ((__v8sf) __A, (__v8sf) __B, __imm, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128 @@ -9003,7 +8876,7 @@ _mm_maskz_shuffle_ps (__mmask8 __U, __m128 __A, __m128 __B, return (__m128) __builtin_ia32_shufps128_mask ((__v4sf) __A, (__v4sf) __B, __imm, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m256i @@ -9014,7 +8887,7 @@ _mm256_inserti32x4 (__m256i __A, __m128i __B, const int __imm) (__v4si) __B, __imm, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -9038,7 +8911,7 @@ _mm256_maskz_inserti32x4 (__mmask8 __U, __m256i __A, __m128i __B, (__v4si) __B, __imm, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } @@ -9050,7 +8923,7 @@ _mm256_insertf32x4 (__m256 __A, __m128 __B, const int __imm) (__v4sf) __B, __imm, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) -1); } extern __inline __m256 @@ -9073,7 +8946,7 @@ _mm256_maskz_insertf32x4 (__mmask8 __U, __m256 __A, __m128 __B, (__v4sf) __B, __imm, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128i @@ -9083,7 +8956,7 @@ _mm256_extracti32x4_epi32 (__m256i __A, const int __imm) return (__m128i) __builtin_ia32_extracti32x4_256_mask ((__v8si) __A, __imm, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -9105,7 +8978,7 @@ _mm256_maskz_extracti32x4_epi32 (__mmask8 __U, __m256i __A, return (__m128i) __builtin_ia32_extracti32x4_256_mask ((__v8si) __A, __imm, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } @@ -9116,7 +8989,7 @@ _mm256_extractf32x4_ps (__m256 __A, const int __imm) return (__m128) __builtin_ia32_extractf32x4_256_mask ((__v8sf) __A, __imm, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) -1); } extern __inline __m128 @@ -9138,7 +9011,7 @@ _mm256_maskz_extractf32x4_ps (__mmask8 __U, __m256 __A, return (__m128) __builtin_ia32_extractf32x4_256_mask ((__v8sf) __A, __imm, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } @@ -9150,7 +9023,7 @@ _mm256_shuffle_i64x2 (__m256i __A, __m256i __B, const int __imm) (__v4di) __B, __imm, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -9173,7 +9046,7 @@ _mm256_maskz_shuffle_i64x2 (__mmask8 __U, __m256i __A, __m256i __B, (__v4di) __B, __imm, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m256i @@ -9184,7 +9057,7 @@ _mm256_shuffle_i32x4 (__m256i __A, __m256i __B, const int __imm) (__v8si) __B, __imm, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -9207,7 +9080,7 @@ _mm256_maskz_shuffle_i32x4 (__mmask8 __U, __m256i __A, __m256i __B, (__v8si) __B, __imm, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m256d @@ -9218,7 +9091,7 @@ _mm256_shuffle_f64x2 (__m256d __A, __m256d __B, const int __imm) (__v4df) __B, __imm, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) -1); } extern __inline __m256d @@ -9241,7 +9114,7 @@ _mm256_maskz_shuffle_f64x2 (__mmask8 __U, __m256d __A, __m256d __B, (__v4df) __B, __imm, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256 @@ -9252,7 +9125,7 @@ _mm256_shuffle_f32x4 (__m256 __A, __m256 __B, const int __imm) (__v8sf) __B, __imm, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) -1); } extern __inline __m256 @@ -9275,7 +9148,7 @@ _mm256_maskz_shuffle_f32x4 (__mmask8 __U, __m256 __A, __m256 __B, (__v8sf) __B, __imm, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m256d @@ -9412,7 +9285,7 @@ _mm_maskz_fixupimm_ps (__mmask8 __U, __m128 __A, __m128 __B, extern __inline __m256i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_mask_srli_epi32 (__m256i __W, __mmask8 __U, __m256i __A, - const int __imm) + const unsigned int __imm) { return (__m256i) __builtin_ia32_psrldi256_mask ((__v8si) __A, __imm, (__v8si) __W, @@ -9420,17 +9293,17 @@ _mm256_mask_srli_epi32 (__m256i __W, __mmask8 __U, __m256i __A, } extern __inline __m256i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_maskz_srli_epi32 (__mmask8 __U, __m256i __A, const int __imm) +_mm256_maskz_srli_epi32 (__mmask8 __U, __m256i __A, const unsigned int __imm) { return (__m256i) __builtin_ia32_psrldi256_mask ((__v8si) __A, __imm, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm_mask_srli_epi32 (__m128i __W, __mmask8 __U, __m128i __A, - const int __imm) + const unsigned int __imm) { return (__m128i) __builtin_ia32_psrldi128_mask ((__v4si) __A, __imm, (__v4si) __W, @@ -9438,17 +9311,17 @@ _mm_mask_srli_epi32 (__m128i __W, __mmask8 __U, __m128i __A, } extern __inline __m128i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_srli_epi32 (__mmask8 __U, __m128i __A, const int __imm) +_mm_maskz_srli_epi32 (__mmask8 __U, __m128i __A, const unsigned int __imm) { return (__m128i) __builtin_ia32_psrldi128_mask ((__v4si) __A, __imm, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_mask_srli_epi64 (__m256i __W, __mmask8 __U, __m256i __A, - const int __imm) + const unsigned int __imm) { return (__m256i) __builtin_ia32_psrlqi256_mask ((__v4di) __A, __imm, (__v4di) __W, @@ -9456,17 +9329,17 @@ _mm256_mask_srli_epi64 (__m256i __W, __mmask8 __U, __m256i __A, } extern __inline __m256i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_maskz_srli_epi64 (__mmask8 __U, __m256i __A, const int __imm) +_mm256_maskz_srli_epi64 (__mmask8 __U, __m256i __A, const unsigned int __imm) { return (__m256i) __builtin_ia32_psrlqi256_mask ((__v4di) __A, __imm, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm_mask_srli_epi64 (__m128i __W, __mmask8 __U, __m128i __A, - const int __imm) + const unsigned int __imm) { return (__m128i) __builtin_ia32_psrlqi128_mask ((__v2di) __A, __imm, (__v2di) __W, @@ -9474,11 +9347,11 @@ _mm_mask_srli_epi64 (__m128i __W, __mmask8 __U, __m128i __A, } extern __inline __m128i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_srli_epi64 (__mmask8 __U, __m128i __A, const int __imm) +_mm_maskz_srli_epi64 (__mmask8 __U, __m128i __A, const unsigned int __imm) { return (__m128i) __builtin_ia32_psrlqi128_mask ((__v2di) __A, __imm, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -9640,7 +9513,7 @@ _mm256_roundscale_ps (__m256 __A, const int __imm) return (__m256) __builtin_ia32_rndscaleps_256_mask ((__v8sf) __A, __imm, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) -1); } extern __inline __m256 @@ -9660,7 +9533,7 @@ _mm256_maskz_roundscale_ps (__mmask8 __U, __m256 __A, const int __imm) return (__m256) __builtin_ia32_rndscaleps_256_mask ((__v8sf) __A, __imm, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m256d @@ -9670,7 +9543,7 @@ _mm256_roundscale_pd (__m256d __A, const int __imm) return (__m256d) __builtin_ia32_rndscalepd_256_mask ((__v4df) __A, __imm, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) -1); } extern __inline __m256d @@ -9690,7 +9563,7 @@ _mm256_maskz_roundscale_pd (__mmask8 __U, __m256d __A, const int __imm) return (__m256d) __builtin_ia32_rndscalepd_256_mask ((__v4df) __A, __imm, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128 @@ -9700,7 +9573,7 @@ _mm_roundscale_ps (__m128 __A, const int __imm) return (__m128) __builtin_ia32_rndscaleps_128_mask ((__v4sf) __A, __imm, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) -1); } extern __inline __m128 @@ -9720,7 +9593,7 @@ _mm_maskz_roundscale_ps (__mmask8 __U, __m128 __A, const int __imm) return (__m128) __builtin_ia32_rndscaleps_128_mask ((__v4sf) __A, __imm, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128d @@ -9730,7 +9603,7 @@ _mm_roundscale_pd (__m128d __A, const int __imm) return (__m128d) __builtin_ia32_rndscalepd_128_mask ((__v2df) __A, __imm, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) -1); } extern __inline __m128d @@ -9750,7 +9623,7 @@ _mm_maskz_roundscale_pd (__mmask8 __U, __m128d __A, const int __imm) return (__m128d) __builtin_ia32_rndscalepd_128_mask ((__v2df) __A, __imm, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256 @@ -9761,7 +9634,7 @@ _mm256_getmant_ps (__m256 __A, _MM_MANTISSA_NORM_ENUM __B, return (__m256) __builtin_ia32_getmantps256_mask ((__v8sf) __A, (__C << 2) | __B, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) -1); } extern __inline __m256 @@ -9784,7 +9657,7 @@ _mm256_maskz_getmant_ps (__mmask8 __U, __m256 __A, return (__m256) __builtin_ia32_getmantps256_mask ((__v8sf) __A, (__C << 2) | __B, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128 @@ -9795,7 +9668,7 @@ _mm_getmant_ps (__m128 __A, _MM_MANTISSA_NORM_ENUM __B, return (__m128) __builtin_ia32_getmantps128_mask ((__v4sf) __A, (__C << 2) | __B, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) -1); } extern __inline __m128 @@ -9818,7 +9691,7 @@ _mm_maskz_getmant_ps (__mmask8 __U, __m128 __A, return (__m128) __builtin_ia32_getmantps128_mask ((__v4sf) __A, (__C << 2) | __B, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m256d @@ -9829,7 +9702,7 @@ _mm256_getmant_pd (__m256d __A, _MM_MANTISSA_NORM_ENUM __B, return (__m256d) __builtin_ia32_getmantpd256_mask ((__v4df) __A, (__C << 2) | __B, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) -1); } extern __inline __m256d @@ -9852,7 +9725,7 @@ _mm256_maskz_getmant_pd (__mmask8 __U, __m256d __A, return (__m256d) __builtin_ia32_getmantpd256_mask ((__v4df) __A, (__C << 2) | __B, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128d @@ -9863,7 +9736,7 @@ _mm_getmant_pd (__m128d __A, _MM_MANTISSA_NORM_ENUM __B, return (__m128d) __builtin_ia32_getmantpd128_mask ((__v2df) __A, (__C << 2) | __B, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) -1); } extern __inline __m128d @@ -9886,7 +9759,7 @@ _mm_maskz_getmant_pd (__mmask8 __U, __m128d __A, return (__m128d) __builtin_ia32_getmantpd128_mask ((__v2df) __A, (__C << 2) | __B, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256 @@ -10369,7 +10242,7 @@ _mm256_maskz_shuffle_epi32 (__mmask8 __U, __m256i __A, { return (__m256i) __builtin_ia32_pshufd256_mask ((__v8si) __A, __mask, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -10388,7 +10261,7 @@ _mm_maskz_shuffle_epi32 (__mmask8 __U, __m128i __A, { return (__m128i) __builtin_ia32_pshufd128_mask ((__v4si) __A, __mask, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -10397,7 +10270,7 @@ _mm256_rol_epi32 (__m256i __A, const int __B) { return (__m256i) __builtin_ia32_prold256_mask ((__v8si) __A, __B, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -10415,7 +10288,7 @@ _mm256_maskz_rol_epi32 (__mmask8 __U, __m256i __A, const int __B) { return (__m256i) __builtin_ia32_prold256_mask ((__v8si) __A, __B, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -10424,7 +10297,7 @@ _mm_rol_epi32 (__m128i __A, const int __B) { return (__m128i) __builtin_ia32_prold128_mask ((__v4si) __A, __B, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -10442,7 +10315,7 @@ _mm_maskz_rol_epi32 (__mmask8 __U, __m128i __A, const int __B) { return (__m128i) __builtin_ia32_prold128_mask ((__v4si) __A, __B, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -10451,7 +10324,7 @@ _mm256_ror_epi32 (__m256i __A, const int __B) { return (__m256i) __builtin_ia32_prord256_mask ((__v8si) __A, __B, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -10469,7 +10342,7 @@ _mm256_maskz_ror_epi32 (__mmask8 __U, __m256i __A, const int __B) { return (__m256i) __builtin_ia32_prord256_mask ((__v8si) __A, __B, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -10478,7 +10351,7 @@ _mm_ror_epi32 (__m128i __A, const int __B) { return (__m128i) __builtin_ia32_prord128_mask ((__v4si) __A, __B, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -10496,7 +10369,7 @@ _mm_maskz_ror_epi32 (__mmask8 __U, __m128i __A, const int __B) { return (__m128i) __builtin_ia32_prord128_mask ((__v4si) __A, __B, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -10505,7 +10378,7 @@ _mm256_rol_epi64 (__m256i __A, const int __B) { return (__m256i) __builtin_ia32_prolq256_mask ((__v4di) __A, __B, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -10523,7 +10396,7 @@ _mm256_maskz_rol_epi64 (__mmask8 __U, __m256i __A, const int __B) { return (__m256i) __builtin_ia32_prolq256_mask ((__v4di) __A, __B, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -10532,7 +10405,7 @@ _mm_rol_epi64 (__m128i __A, const int __B) { return (__m128i) __builtin_ia32_prolq128_mask ((__v2di) __A, __B, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -10550,7 +10423,7 @@ _mm_maskz_rol_epi64 (__mmask8 __U, __m128i __A, const int __B) { return (__m128i) __builtin_ia32_prolq128_mask ((__v2di) __A, __B, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -10559,7 +10432,7 @@ _mm256_ror_epi64 (__m256i __A, const int __B) { return (__m256i) __builtin_ia32_prorq256_mask ((__v4di) __A, __B, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -10577,7 +10450,7 @@ _mm256_maskz_ror_epi64 (__mmask8 __U, __m256i __A, const int __B) { return (__m256i) __builtin_ia32_prorq256_mask ((__v4di) __A, __B, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -10586,7 +10459,7 @@ _mm_ror_epi64 (__m128i __A, const int __B) { return (__m128i) __builtin_ia32_prorq128_mask ((__v2di) __A, __B, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -10604,7 +10477,7 @@ _mm_maskz_ror_epi64 (__mmask8 __U, __m128i __A, const int __B) { return (__m128i) __builtin_ia32_prorq128_mask ((__v2di) __A, __B, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i @@ -10614,7 +10487,7 @@ _mm_alignr_epi32 (__m128i __A, __m128i __B, const int __imm) return (__m128i) __builtin_ia32_alignd128_mask ((__v4si) __A, (__v4si) __B, __imm, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -10635,7 +10508,7 @@ _mm_maskz_alignr_epi32 (__mmask8 __U, __m128i __A, __m128i __B, return (__m128i) __builtin_ia32_alignd128_mask ((__v4si) __A, (__v4si) __B, __imm, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i @@ -10645,7 +10518,7 @@ _mm_alignr_epi64 (__m128i __A, __m128i __B, const int __imm) return (__m128i) __builtin_ia32_alignq128_mask ((__v2di) __A, (__v2di) __B, __imm, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i @@ -10666,7 +10539,7 @@ _mm_maskz_alignr_epi64 (__mmask8 __U, __m128i __A, __m128i __B, return (__m128i) __builtin_ia32_alignq128_mask ((__v2di) __A, (__v2di) __B, __imm, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -10676,7 +10549,7 @@ _mm256_alignr_epi32 (__m256i __A, __m256i __B, const int __imm) return (__m256i) __builtin_ia32_alignd256_mask ((__v8si) __A, (__v8si) __B, __imm, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -10697,7 +10570,7 @@ _mm256_maskz_alignr_epi32 (__mmask8 __U, __m256i __A, __m256i __B, return (__m256i) __builtin_ia32_alignd256_mask ((__v8si) __A, (__v8si) __B, __imm, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m256i @@ -10707,7 +10580,7 @@ _mm256_alignr_epi64 (__m256i __A, __m256i __B, const int __imm) return (__m256i) __builtin_ia32_alignq256_mask ((__v4di) __A, (__v4di) __B, __imm, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i @@ -10728,7 +10601,7 @@ _mm256_maskz_alignr_epi64 (__mmask8 __U, __m256i __A, __m256i __B, return (__m256i) __builtin_ia32_alignq256_mask ((__v4di) __A, (__v4di) __B, __imm, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i @@ -10746,7 +10619,7 @@ _mm_maskz_cvtps_ph (__mmask8 __U, __m128 __A, const int __I) { return (__m128i) __builtin_ia32_vcvtps2ph_mask ((__v4sf) __A, __I, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i @@ -10764,13 +10637,13 @@ _mm256_maskz_cvtps_ph (__mmask8 __U, __m256 __A, const int __I) { return (__m128i) __builtin_ia32_vcvtps2ph256_mask ((__v8sf) __A, __I, (__v8hi) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_mask_srai_epi32 (__m256i __W, __mmask8 __U, __m256i __A, - const int __imm) + const unsigned int __imm) { return (__m256i) __builtin_ia32_psradi256_mask ((__v8si) __A, __imm, (__v8si) __W, @@ -10778,17 +10651,17 @@ _mm256_mask_srai_epi32 (__m256i __W, __mmask8 __U, __m256i __A, } extern __inline __m256i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_maskz_srai_epi32 (__mmask8 __U, __m256i __A, const int __imm) +_mm256_maskz_srai_epi32 (__mmask8 __U, __m256i __A, const unsigned int __imm) { return (__m256i) __builtin_ia32_psradi256_mask ((__v8si) __A, __imm, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm_mask_srai_epi32 (__m128i __W, __mmask8 __U, __m128i __A, - const int __imm) + const unsigned int __imm) { return (__m128i) __builtin_ia32_psradi128_mask ((__v4si) __A, __imm, (__v4si) __W, @@ -10796,26 +10669,26 @@ _mm_mask_srai_epi32 (__m128i __W, __mmask8 __U, __m128i __A, } extern __inline __m128i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_srai_epi32 (__mmask8 __U, __m128i __A, const int __imm) +_mm_maskz_srai_epi32 (__mmask8 __U, __m128i __A, const unsigned int __imm) { return (__m128i) __builtin_ia32_psradi128_mask ((__v4si) __A, __imm, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_srai_epi64 (__m256i __A, const int __imm) +_mm256_srai_epi64 (__m256i __A, const unsigned int __imm) { return (__m256i) __builtin_ia32_psraqi256_mask ((__v4di) __A, __imm, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) -1); } extern __inline __m256i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_mask_srai_epi64 (__m256i __W, __mmask8 __U, __m256i __A, - const int __imm) + const unsigned int __imm) { return (__m256i) __builtin_ia32_psraqi256_mask ((__v4di) __A, __imm, (__v4di) __W, @@ -10823,26 +10696,26 @@ _mm256_mask_srai_epi64 (__m256i __W, __mmask8 __U, __m256i __A, } extern __inline __m256i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_maskz_srai_epi64 (__mmask8 __U, __m256i __A, const int __imm) +_mm256_maskz_srai_epi64 (__mmask8 __U, __m256i __A, const unsigned int __imm) { return (__m256i) __builtin_ia32_psraqi256_mask ((__v4di) __A, __imm, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m128i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_srai_epi64 (__m128i __A, const int __imm) +_mm_srai_epi64 (__m128i __A, const unsigned int __imm) { return (__m128i) __builtin_ia32_psraqi128_mask ((__v2di) __A, __imm, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) -1); } extern __inline __m128i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm_mask_srai_epi64 (__m128i __W, __mmask8 __U, __m128i __A, - const int __imm) + const unsigned int __imm) { return (__m128i) __builtin_ia32_psraqi128_mask ((__v2di) __A, __imm, (__v2di) __W, @@ -10850,16 +10723,16 @@ _mm_mask_srai_epi64 (__m128i __W, __mmask8 __U, __m128i __A, } extern __inline __m128i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_srai_epi64 (__mmask8 __U, __m128i __A, const int __imm) +_mm_maskz_srai_epi64 (__mmask8 __U, __m128i __A, const unsigned int __imm) { return (__m128i) __builtin_ia32_psraqi128_mask ((__v2di) __A, __imm, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_slli_epi32 (__m128i __W, __mmask8 __U, __m128i __A, int __B) +_mm_mask_slli_epi32 (__m128i __W, __mmask8 __U, __m128i __A, unsigned int __B) { return (__m128i) __builtin_ia32_pslldi128_mask ((__v4si) __A, __B, (__v4si) __W, @@ -10867,16 +10740,16 @@ _mm_mask_slli_epi32 (__m128i __W, __mmask8 __U, __m128i __A, int __B) } extern __inline __m128i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_slli_epi32 (__mmask8 __U, __m128i __A, int __B) +_mm_maskz_slli_epi32 (__mmask8 __U, __m128i __A, unsigned int __B) { return (__m128i) __builtin_ia32_pslldi128_mask ((__v4si) __A, __B, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m128i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_slli_epi64 (__m128i __W, __mmask8 __U, __m128i __A, int __B) +_mm_mask_slli_epi64 (__m128i __W, __mmask8 __U, __m128i __A, unsigned int __B) { return (__m128i) __builtin_ia32_psllqi128_mask ((__v2di) __A, __B, (__v2di) __W, @@ -10884,17 +10757,17 @@ _mm_mask_slli_epi64 (__m128i __W, __mmask8 __U, __m128i __A, int __B) } extern __inline __m128i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_maskz_slli_epi64 (__mmask8 __U, __m128i __A, int __B) +_mm_maskz_slli_epi64 (__mmask8 __U, __m128i __A, unsigned int __B) { return (__m128i) __builtin_ia32_psllqi128_mask ((__v2di) __A, __B, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_mask_slli_epi32 (__m256i __W, __mmask8 __U, __m256i __A, - int __B) + unsigned int __B) { return (__m256i) __builtin_ia32_pslldi256_mask ((__v8si) __A, __B, (__v8si) __W, @@ -10902,17 +10775,17 @@ _mm256_mask_slli_epi32 (__m256i __W, __mmask8 __U, __m256i __A, } extern __inline __m256i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_maskz_slli_epi32 (__mmask8 __U, __m256i __A, int __B) +_mm256_maskz_slli_epi32 (__mmask8 __U, __m256i __A, unsigned int __B) { return (__m256i) __builtin_ia32_pslldi256_mask ((__v8si) __A, __B, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m256i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_mask_slli_epi64 (__m256i __W, __mmask8 __U, __m256i __A, - int __B) + unsigned int __B) { return (__m256i) __builtin_ia32_psllqi256_mask ((__v4di) __A, __B, (__v4di) __W, @@ -10920,11 +10793,11 @@ _mm256_mask_slli_epi64 (__m256i __W, __mmask8 __U, __m256i __A, } extern __inline __m256i __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_maskz_slli_epi64 (__mmask8 __U, __m256i __A, int __B) +_mm256_maskz_slli_epi64 (__mmask8 __U, __m256i __A, unsigned int __B) { return (__m256i) __builtin_ia32_psllqi256_mask ((__v4di) __A, __B, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } extern __inline __m256d @@ -10942,7 +10815,7 @@ _mm256_maskz_permutex_pd (__mmask8 __U, __m256d __X, const int __imm) { return (__m256d) __builtin_ia32_permdf256_mask ((__v4df) __X, __imm, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256d @@ -10960,7 +10833,7 @@ _mm256_maskz_permute_pd (__mmask8 __U, __m256d __X, const int __C) { return (__m256d) __builtin_ia32_vpermilpd256_mask ((__v4df) __X, __C, (__v4df) - _mm256_setzero_pd (), + _mm256_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m128d @@ -10978,7 +10851,7 @@ _mm_maskz_permute_pd (__mmask8 __U, __m128d __X, const int __C) { return (__m128d) __builtin_ia32_vpermilpd_mask ((__v2df) __X, __C, (__v2df) - _mm_setzero_pd (), + _mm_avx512_setzero_pd (), (__mmask8) __U); } extern __inline __m256 @@ -10996,7 +10869,7 @@ _mm256_maskz_permute_ps (__mmask8 __U, __m256 __X, const int __C) { return (__m256) __builtin_ia32_vpermilps256_mask ((__v8sf) __X, __C, (__v8sf) - _mm256_setzero_ps (), + _mm256_avx512_setzero_ps (), (__mmask8) __U); } extern __inline __m128 @@ -11014,73 +10887,9 @@ _mm_maskz_permute_ps (__mmask8 __U, __m128 __X, const int __C) { return (__m128) __builtin_ia32_vpermilps_mask ((__v4sf) __X, __C, (__v4sf) - _mm_setzero_ps (), + _mm_avx512_setzero_ps (), (__mmask8) __U); } -extern __inline __m256d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_blend_pd (__mmask8 __U, __m256d __A, __m256d __W) -{ - return (__m256d) __builtin_ia32_blendmpd_256_mask ((__v4df) __A, - (__v4df) __W, - (__mmask8) __U); -} -extern __inline __m256 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_blend_ps (__mmask8 __U, __m256 __A, __m256 __W) -{ - return (__m256) __builtin_ia32_blendmps_256_mask ((__v8sf) __A, - (__v8sf) __W, - (__mmask8) __U); -} -extern __inline __m256i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_blend_epi64 (__mmask8 __U, __m256i __A, __m256i __W) -{ - return (__m256i) __builtin_ia32_blendmq_256_mask ((__v4di) __A, - (__v4di) __W, - (__mmask8) __U); -} -extern __inline __m256i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm256_mask_blend_epi32 (__mmask8 __U, __m256i __A, __m256i __W) -{ - return (__m256i) __builtin_ia32_blendmd_256_mask ((__v8si) __A, - (__v8si) __W, - (__mmask8) __U); -} -extern __inline __m128d -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_blend_pd (__mmask8 __U, __m128d __A, __m128d __W) -{ - return (__m128d) __builtin_ia32_blendmpd_128_mask ((__v2df) __A, - (__v2df) __W, - (__mmask8) __U); -} -extern __inline __m128 -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_blend_ps (__mmask8 __U, __m128 __A, __m128 __W) -{ - return (__m128) __builtin_ia32_blendmps_128_mask ((__v4sf) __A, - (__v4sf) __W, - (__mmask8) __U); -} -extern __inline __m128i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_blend_epi64 (__mmask8 __U, __m128i __A, __m128i __W) -{ - return (__m128i) __builtin_ia32_blendmq_128_mask ((__v2di) __A, - (__v2di) __W, - (__mmask8) __U); -} -extern __inline __m128i -__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mask_blend_epi32 (__mmask8 __U, __m128i __A, __m128i __W) -{ - return (__m128i) __builtin_ia32_blendmd_128_mask ((__v4si) __A, - (__v4si) __W, - (__mmask8) __U); -} extern __inline __mmask8 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) _mm256_cmp_epi64_mask (__m256i __X, __m256i __Y, const int __P) @@ -11291,46 +11100,46 @@ _mm256_permutex_pd (__m256d __X, const int __M) { return (__m256d) __builtin_ia32_permdf256_mask ((__v4df) __X, __M, (__v4df) - _mm256_undefined_pd (), + _mm256_avx512_undefined_pd (), (__mmask8) -1); } #else -#define _mm256_permutex_pd(X, M) ((__m256d) __builtin_ia32_permdf256_mask ((__v4df)(__m256d)(X), (int)(M), (__v4df)(__m256d) _mm256_undefined_pd (), (__mmask8)-1)) -#define _mm256_permutex_epi64(X, I) ((__m256i) __builtin_ia32_permdi256_mask ((__v4di)(__m256i)(X), (int)(I), (__v4di)(__m256i) (_mm256_setzero_si256 ()), (__mmask8) -1)) -#define _mm256_maskz_permutex_epi64(M, X, I) ((__m256i) __builtin_ia32_permdi256_mask ((__v4di)(__m256i)(X), (int)(I), (__v4di)(__m256i) (_mm256_setzero_si256 ()), (__mmask8)(M))) +#define _mm256_permutex_pd(X, M) ((__m256d) __builtin_ia32_permdf256_mask ((__v4df)(__m256d)(X), (int)(M), (__v4df)(__m256d) _mm256_avx512_undefined_pd (), (__mmask8)-1)) +#define _mm256_permutex_epi64(X, I) ((__m256i) __builtin_ia32_permdi256_mask ((__v4di)(__m256i)(X), (int)(I), (__v4di)(__m256i) (_mm256_avx512_setzero_si256 ()), (__mmask8) -1)) +#define _mm256_maskz_permutex_epi64(M, X, I) ((__m256i) __builtin_ia32_permdi256_mask ((__v4di)(__m256i)(X), (int)(I), (__v4di)(__m256i) (_mm256_avx512_setzero_si256 ()), (__mmask8)(M))) #define _mm256_mask_permutex_epi64(W, M, X, I) ((__m256i) __builtin_ia32_permdi256_mask ((__v4di)(__m256i)(X), (int)(I), (__v4di)(__m256i)(W), (__mmask8)(M))) -#define _mm256_insertf32x4(X, Y, C) ((__m256) __builtin_ia32_insertf32x4_256_mask ((__v8sf)(__m256) (X), (__v4sf)(__m128) (Y), (int) (C), (__v8sf)(__m256)_mm256_setzero_ps (), (__mmask8)-1)) +#define _mm256_insertf32x4(X, Y, C) ((__m256) __builtin_ia32_insertf32x4_256_mask ((__v8sf)(__m256) (X), (__v4sf)(__m128) (Y), (int) (C), (__v8sf)(__m256)_mm256_avx512_setzero_ps (), (__mmask8)-1)) #define _mm256_mask_insertf32x4(W, U, X, Y, C) ((__m256) __builtin_ia32_insertf32x4_256_mask ((__v8sf)(__m256) (X), (__v4sf)(__m128) (Y), (int) (C), (__v8sf)(__m256)(W), (__mmask8)(U))) -#define _mm256_maskz_insertf32x4(U, X, Y, C) ((__m256) __builtin_ia32_insertf32x4_256_mask ((__v8sf)(__m256) (X), (__v4sf)(__m128) (Y), (int) (C), (__v8sf)(__m256)_mm256_setzero_ps (), (__mmask8)(U))) -#define _mm256_inserti32x4(X, Y, C) ((__m256i) __builtin_ia32_inserti32x4_256_mask ((__v8si)(__m256i) (X), (__v4si)(__m128i) (Y), (int) (C), (__v8si)(__m256i)_mm256_setzero_si256 (), (__mmask8)-1)) +#define _mm256_maskz_insertf32x4(U, X, Y, C) ((__m256) __builtin_ia32_insertf32x4_256_mask ((__v8sf)(__m256) (X), (__v4sf)(__m128) (Y), (int) (C), (__v8sf)(__m256)_mm256_avx512_setzero_ps (), (__mmask8)(U))) +#define _mm256_inserti32x4(X, Y, C) ((__m256i) __builtin_ia32_inserti32x4_256_mask ((__v8si)(__m256i) (X), (__v4si)(__m128i) (Y), (int) (C), (__v8si)(__m256i)_mm256_avx512_setzero_si256 (), (__mmask8)-1)) #define _mm256_mask_inserti32x4(W, U, X, Y, C) ((__m256i) __builtin_ia32_inserti32x4_256_mask ((__v8si)(__m256i) (X), (__v4si)(__m128i) (Y), (int) (C), (__v8si)(__m256i)(W), (__mmask8)(U))) -#define _mm256_maskz_inserti32x4(U, X, Y, C) ((__m256i) __builtin_ia32_inserti32x4_256_mask ((__v8si)(__m256i) (X), (__v4si)(__m128i) (Y), (int) (C), (__v8si)(__m256i)_mm256_setzero_si256 (), (__mmask8)(U))) -#define _mm256_extractf32x4_ps(X, C) ((__m128) __builtin_ia32_extractf32x4_256_mask ((__v8sf)(__m256) (X), (int) (C), (__v4sf)(__m128)_mm_setzero_ps (), (__mmask8)-1)) +#define _mm256_maskz_inserti32x4(U, X, Y, C) ((__m256i) __builtin_ia32_inserti32x4_256_mask ((__v8si)(__m256i) (X), (__v4si)(__m128i) (Y), (int) (C), (__v8si)(__m256i)_mm256_avx512_setzero_si256 (), (__mmask8)(U))) +#define _mm256_extractf32x4_ps(X, C) ((__m128) __builtin_ia32_extractf32x4_256_mask ((__v8sf)(__m256) (X), (int) (C), (__v4sf)(__m128)_mm_avx512_setzero_ps (), (__mmask8)-1)) #define _mm256_mask_extractf32x4_ps(W, U, X, C) ((__m128) __builtin_ia32_extractf32x4_256_mask ((__v8sf)(__m256) (X), (int) (C), (__v4sf)(__m128)(W), (__mmask8)(U))) -#define _mm256_maskz_extractf32x4_ps(U, X, C) ((__m128) __builtin_ia32_extractf32x4_256_mask ((__v8sf)(__m256) (X), (int) (C), (__v4sf)(__m128)_mm_setzero_ps (), (__mmask8)(U))) -#define _mm256_extracti32x4_epi32(X, C) ((__m128i) __builtin_ia32_extracti32x4_256_mask ((__v8si)(__m256i) (X), (int) (C), (__v4si)(__m128i)_mm_setzero_si128 (), (__mmask8)-1)) +#define _mm256_maskz_extractf32x4_ps(U, X, C) ((__m128) __builtin_ia32_extractf32x4_256_mask ((__v8sf)(__m256) (X), (int) (C), (__v4sf)(__m128)_mm_avx512_setzero_ps (), (__mmask8)(U))) +#define _mm256_extracti32x4_epi32(X, C) ((__m128i) __builtin_ia32_extracti32x4_256_mask ((__v8si)(__m256i) (X), (int) (C), (__v4si)(__m128i)_mm_avx512_setzero_si128 (), (__mmask8)-1)) #define _mm256_mask_extracti32x4_epi32(W, U, X, C) ((__m128i) __builtin_ia32_extracti32x4_256_mask ((__v8si)(__m256i) (X), (int) (C), (__v4si)(__m128i)(W), (__mmask8)(U))) -#define _mm256_maskz_extracti32x4_epi32(U, X, C) ((__m128i) __builtin_ia32_extracti32x4_256_mask ((__v8si)(__m256i) (X), (int) (C), (__v4si)(__m128i)_mm_setzero_si128 (), (__mmask8)(U))) -#define _mm256_shuffle_i64x2(X, Y, C) ((__m256i) __builtin_ia32_shuf_i64x2_256_mask ((__v4di)(__m256i)(X), (__v4di)(__m256i)(Y), (int)(C), (__v4di)(__m256i)_mm256_setzero_si256 (), (__mmask8)-1)) +#define _mm256_maskz_extracti32x4_epi32(U, X, C) ((__m128i) __builtin_ia32_extracti32x4_256_mask ((__v8si)(__m256i) (X), (int) (C), (__v4si)(__m128i)_mm_avx512_setzero_si128 (), (__mmask8)(U))) +#define _mm256_shuffle_i64x2(X, Y, C) ((__m256i) __builtin_ia32_shuf_i64x2_256_mask ((__v4di)(__m256i)(X), (__v4di)(__m256i)(Y), (int)(C), (__v4di)(__m256i)_mm256_avx512_setzero_si256 (), (__mmask8)-1)) #define _mm256_mask_shuffle_i64x2(W, U, X, Y, C) ((__m256i) __builtin_ia32_shuf_i64x2_256_mask ((__v4di)(__m256i)(X), (__v4di)(__m256i)(Y), (int)(C), (__v4di)(__m256i)(W), (__mmask8)(U))) -#define _mm256_maskz_shuffle_i64x2(U, X, Y, C) ((__m256i) __builtin_ia32_shuf_i64x2_256_mask ((__v4di)(__m256i)(X), (__v4di)(__m256i)(Y), (int)(C), (__v4di)(__m256i)_mm256_setzero_si256 (), (__mmask8)(U))) -#define _mm256_shuffle_i32x4(X, Y, C) ((__m256i) __builtin_ia32_shuf_i32x4_256_mask ((__v8si)(__m256i)(X), (__v8si)(__m256i)(Y), (int)(C), (__v8si)(__m256i) _mm256_setzero_si256 (), (__mmask8)-1)) +#define _mm256_maskz_shuffle_i64x2(U, X, Y, C) ((__m256i) __builtin_ia32_shuf_i64x2_256_mask ((__v4di)(__m256i)(X), (__v4di)(__m256i)(Y), (int)(C), (__v4di)(__m256i)_mm256_avx512_setzero_si256 (), (__mmask8)(U))) +#define _mm256_shuffle_i32x4(X, Y, C) ((__m256i) __builtin_ia32_shuf_i32x4_256_mask ((__v8si)(__m256i)(X), (__v8si)(__m256i)(Y), (int)(C), (__v8si)(__m256i) _mm256_avx512_setzero_si256 (), (__mmask8)-1)) #define _mm256_mask_shuffle_i32x4(W, U, X, Y, C) ((__m256i) __builtin_ia32_shuf_i32x4_256_mask ((__v8si)(__m256i)(X), (__v8si)(__m256i)(Y), (int)(C), (__v8si)(__m256i)(W), (__mmask8)(U))) -#define _mm256_maskz_shuffle_i32x4(U, X, Y, C) ((__m256i) __builtin_ia32_shuf_i32x4_256_mask ((__v8si)(__m256i)(X), (__v8si)(__m256i)(Y), (int)(C), (__v8si)(__m256i) _mm256_setzero_si256 (), (__mmask8)(U))) -#define _mm256_shuffle_f64x2(X, Y, C) ((__m256d) __builtin_ia32_shuf_f64x2_256_mask ((__v4df)(__m256d)(X), (__v4df)(__m256d)(Y), (int)(C), (__v4df)(__m256d)_mm256_setzero_pd (), (__mmask8)-1)) +#define _mm256_maskz_shuffle_i32x4(U, X, Y, C) ((__m256i) __builtin_ia32_shuf_i32x4_256_mask ((__v8si)(__m256i)(X), (__v8si)(__m256i)(Y), (int)(C), (__v8si)(__m256i) _mm256_avx512_setzero_si256 (), (__mmask8)(U))) +#define _mm256_shuffle_f64x2(X, Y, C) ((__m256d) __builtin_ia32_shuf_f64x2_256_mask ((__v4df)(__m256d)(X), (__v4df)(__m256d)(Y), (int)(C), (__v4df)(__m256d)_mm256_avx512_setzero_pd (), (__mmask8)-1)) #define _mm256_mask_shuffle_f64x2(W, U, X, Y, C) ((__m256d) __builtin_ia32_shuf_f64x2_256_mask ((__v4df)(__m256d)(X), (__v4df)(__m256d)(Y), (int)(C), (__v4df)(__m256d)(W), (__mmask8)(U))) -#define _mm256_maskz_shuffle_f64x2(U, X, Y, C) ((__m256d) __builtin_ia32_shuf_f64x2_256_mask ((__v4df)(__m256d)(X), (__v4df)(__m256d)(Y), (int)(C), (__v4df)(__m256d)_mm256_setzero_pd( ), (__mmask8)(U))) -#define _mm256_shuffle_f32x4(X, Y, C) ((__m256) __builtin_ia32_shuf_f32x4_256_mask ((__v8sf)(__m256)(X), (__v8sf)(__m256)(Y), (int)(C), (__v8sf)(__m256)_mm256_setzero_ps (), (__mmask8)-1)) +#define _mm256_maskz_shuffle_f64x2(U, X, Y, C) ((__m256d) __builtin_ia32_shuf_f64x2_256_mask ((__v4df)(__m256d)(X), (__v4df)(__m256d)(Y), (int)(C), (__v4df)(__m256d)_mm256_avx512_setzero_pd( ), (__mmask8)(U))) +#define _mm256_shuffle_f32x4(X, Y, C) ((__m256) __builtin_ia32_shuf_f32x4_256_mask ((__v8sf)(__m256)(X), (__v8sf)(__m256)(Y), (int)(C), (__v8sf)(__m256)_mm256_avx512_setzero_ps (), (__mmask8)-1)) #define _mm256_mask_shuffle_f32x4(W, U, X, Y, C) ((__m256) __builtin_ia32_shuf_f32x4_256_mask ((__v8sf)(__m256)(X), (__v8sf)(__m256)(Y), (int)(C), (__v8sf)(__m256)(W), (__mmask8)(U))) -#define _mm256_maskz_shuffle_f32x4(U, X, Y, C) ((__m256) __builtin_ia32_shuf_f32x4_256_mask ((__v8sf)(__m256)(X), (__v8sf)(__m256)(Y), (int)(C), (__v8sf)(__m256)_mm256_setzero_ps (), (__mmask8)(U))) +#define _mm256_maskz_shuffle_f32x4(U, X, Y, C) ((__m256) __builtin_ia32_shuf_f32x4_256_mask ((__v8sf)(__m256)(X), (__v8sf)(__m256)(Y), (int)(C), (__v8sf)(__m256)_mm256_avx512_setzero_ps (), (__mmask8)(U))) #define _mm256_mask_shuffle_pd(W, U, A, B, C) ((__m256d)__builtin_ia32_shufpd256_mask ((__v4df)(__m256d)(A), (__v4df)(__m256d)(B), (int)(C), (__v4df)(__m256d)(W), (__mmask8)(U))) -#define _mm256_maskz_shuffle_pd(U, A, B, C) ((__m256d)__builtin_ia32_shufpd256_mask ((__v4df)(__m256d)(A), (__v4df)(__m256d)(B), (int)(C), (__v4df)(__m256d) _mm256_setzero_pd (), (__mmask8)(U))) +#define _mm256_maskz_shuffle_pd(U, A, B, C) ((__m256d)__builtin_ia32_shufpd256_mask ((__v4df)(__m256d)(A), (__v4df)(__m256d)(B), (int)(C), (__v4df)(__m256d) _mm256_avx512_setzero_pd (), (__mmask8)(U))) #define _mm_mask_shuffle_pd(W, U, A, B, C) ((__m128d)__builtin_ia32_shufpd128_mask ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__v2df)(__m128d)(W), (__mmask8)(U))) -#define _mm_maskz_shuffle_pd(U, A, B, C) ((__m128d)__builtin_ia32_shufpd128_mask ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__v2df)(__m128d)_mm_setzero_pd (), (__mmask8)(U))) +#define _mm_maskz_shuffle_pd(U, A, B, C) ((__m128d)__builtin_ia32_shufpd128_mask ((__v2df)(__m128d)(A), (__v2df)(__m128d)(B), (int)(C), (__v2df)(__m128d)_mm_avx512_setzero_pd (), (__mmask8)(U))) #define _mm256_mask_shuffle_ps(W, U, A, B, C) ((__m256) __builtin_ia32_shufps256_mask ((__v8sf)(__m256)(A), (__v8sf)(__m256)(B), (int)(C), (__v8sf)(__m256)(W), (__mmask8)(U))) -#define _mm256_maskz_shuffle_ps(U, A, B, C) ((__m256) __builtin_ia32_shufps256_mask ((__v8sf)(__m256)(A), (__v8sf)(__m256)(B), (int)(C), (__v8sf)(__m256)_mm256_setzero_ps (), (__mmask8)(U))) +#define _mm256_maskz_shuffle_ps(U, A, B, C) ((__m256) __builtin_ia32_shufps256_mask ((__v8sf)(__m256)(A), (__v8sf)(__m256)(B), (int)(C), (__v8sf)(__m256)_mm256_avx512_setzero_ps (), (__mmask8)(U))) #define _mm_mask_shuffle_ps(W, U, A, B, C) ((__m128) __builtin_ia32_shufps128_mask ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__v4sf)(__m128)(W), (__mmask8)(U))) -#define _mm_maskz_shuffle_ps(U, A, B, C) ((__m128) __builtin_ia32_shufps128_mask ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__v4sf)(__m128)_mm_setzero_ps (), (__mmask8)(U))) +#define _mm_maskz_shuffle_ps(U, A, B, C) ((__m128) __builtin_ia32_shufps128_mask ((__v4sf)(__m128)(A), (__v4sf)(__m128)(B), (int)(C), (__v4sf)(__m128)_mm_avx512_setzero_ps (), (__mmask8)(U))) #define _mm256_fixupimm_pd(X, Y, Z, C) ((__m256d)__builtin_ia32_fixupimmpd256_mask ((__v4df)(__m256d)(X), (__v4df)(__m256d)(Y), (__v4di)(__m256i)(Z), (int)(C), (__mmask8)(-1))) #define _mm256_mask_fixupimm_pd(X, U, Y, Z, C) ((__m256d)__builtin_ia32_fixupimmpd256_mask ((__v4df)(__m256d)(X), (__v4df)(__m256d)(Y), (__v4di)(__m256i)(Z), (int)(C), (__mmask8)(U))) #define _mm256_maskz_fixupimm_pd(U, X, Y, Z, C) ((__m256d)__builtin_ia32_fixupimmpd256_maskz ((__v4df)(__m256d)(X), (__v4df)(__m256d)(Y), (__v4di)(__m256i)(Z), (int)(C), (__mmask8)(U))) @@ -11343,22 +11152,22 @@ _mm256_permutex_pd (__m256d __X, const int __M) #define _mm_fixupimm_ps(X, Y, Z, C) ((__m128)__builtin_ia32_fixupimmps128_mask ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (__v4si)(__m128i)(Z), (int)(C), (__mmask8)(-1))) #define _mm_mask_fixupimm_ps(X, U, Y, Z, C) ((__m128)__builtin_ia32_fixupimmps128_mask ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (__v4si)(__m128i)(Z), (int)(C), (__mmask8)(U))) #define _mm_maskz_fixupimm_ps(U, X, Y, Z, C) ((__m128)__builtin_ia32_fixupimmps128_maskz ((__v4sf)(__m128)(X), (__v4sf)(__m128)(Y), (__v4si)(__m128i)(Z), (int)(C), (__mmask8)(U))) -#define _mm256_mask_srli_epi32(W, U, A, B) ((__m256i) __builtin_ia32_psrldi256_mask ((__v8si)(__m256i)(A), (int)(B), (__v8si)(__m256i)(W), (__mmask8)(U))) -#define _mm256_maskz_srli_epi32(U, A, B) ((__m256i) __builtin_ia32_psrldi256_mask ((__v8si)(__m256i)(A), (int)(B), (__v8si)_mm256_setzero_si256 (), (__mmask8)(U))) -#define _mm_mask_srli_epi32(W, U, A, B) ((__m128i) __builtin_ia32_psrldi128_mask ((__v4si)(__m128i)(A), (int)(B), (__v4si)(__m128i)(W), (__mmask8)(U))) -#define _mm_maskz_srli_epi32(U, A, B) ((__m128i) __builtin_ia32_psrldi128_mask ((__v4si)(__m128i)(A), (int)(B), (__v4si)_mm_setzero_si128 (), (__mmask8)(U))) -#define _mm256_mask_srli_epi64(W, U, A, B) ((__m256i) __builtin_ia32_psrlqi256_mask ((__v4di)(__m256i)(A), (int)(B), (__v4di)(__m256i)(W), (__mmask8)(U))) -#define _mm256_maskz_srli_epi64(U, A, B) ((__m256i) __builtin_ia32_psrlqi256_mask ((__v4di)(__m256i)(A), (int)(B), (__v4di)_mm256_setzero_si256 (), (__mmask8)(U))) -#define _mm_mask_srli_epi64(W, U, A, B) ((__m128i) __builtin_ia32_psrlqi128_mask ((__v2di)(__m128i)(A), (int)(B), (__v2di)(__m128i)(W), (__mmask8)(U))) -#define _mm_maskz_srli_epi64(U, A, B) ((__m128i) __builtin_ia32_psrlqi128_mask ((__v2di)(__m128i)(A), (int)(B), (__v2di)_mm_setzero_si128 (), (__mmask8)(U))) -#define _mm256_mask_slli_epi32(W, U, X, C) ((__m256i)__builtin_ia32_pslldi256_mask ((__v8si)(__m256i)(X), (int)(C), (__v8si)(__m256i)(W), (__mmask8)(U))) -#define _mm256_maskz_slli_epi32(U, X, C) ((__m256i)__builtin_ia32_pslldi256_mask ((__v8si)(__m256i)(X), (int)(C), (__v8si)(__m256i)_mm256_setzero_si256 (), (__mmask8)(U))) -#define _mm256_mask_slli_epi64(W, U, X, C) ((__m256i)__builtin_ia32_psllqi256_mask ((__v4di)(__m256i)(X), (int)(C), (__v4di)(__m256i)(W), (__mmask8)(U))) -#define _mm256_maskz_slli_epi64(U, X, C) ((__m256i)__builtin_ia32_psllqi256_mask ((__v4di)(__m256i)(X), (int)(C), (__v4di)(__m256i)_mm256_setzero_si256 (), (__mmask8)(U))) -#define _mm_mask_slli_epi32(W, U, X, C) ((__m128i)__builtin_ia32_pslldi128_mask ((__v4si)(__m128i)(X), (int)(C), (__v4si)(__m128i)(W), (__mmask8)(U))) -#define _mm_maskz_slli_epi32(U, X, C) ((__m128i)__builtin_ia32_pslldi128_mask ((__v4si)(__m128i)(X), (int)(C), (__v4si)(__m128i)_mm_setzero_si128 (), (__mmask8)(U))) -#define _mm_mask_slli_epi64(W, U, X, C) ((__m128i)__builtin_ia32_psllqi128_mask ((__v2di)(__m128i)(X), (int)(C), (__v2di)(__m128i)(W), (__mmask8)(U))) -#define _mm_maskz_slli_epi64(U, X, C) ((__m128i)__builtin_ia32_psllqi128_mask ((__v2di)(__m128i)(X), (int)(C), (__v2di)(__m128i)_mm_setzero_si128 (), (__mmask8)(U))) +#define _mm256_mask_srli_epi32(W, U, A, B) ((__m256i) __builtin_ia32_psrldi256_mask ((__v8si)(__m256i)(A), (unsigned int)(B), (__v8si)(__m256i)(W), (__mmask8)(U))) +#define _mm256_maskz_srli_epi32(U, A, B) ((__m256i) __builtin_ia32_psrldi256_mask ((__v8si)(__m256i)(A), (unsigned int)(B), (__v8si)_mm256_avx512_setzero_si256 (), (__mmask8)(U))) +#define _mm_mask_srli_epi32(W, U, A, B) ((__m128i) __builtin_ia32_psrldi128_mask ((__v4si)(__m128i)(A), (unsigned int)(B), (__v4si)(__m128i)(W), (__mmask8)(U))) +#define _mm_maskz_srli_epi32(U, A, B) ((__m128i) __builtin_ia32_psrldi128_mask ((__v4si)(__m128i)(A), (unsigned int)(B), (__v4si)_mm_avx512_setzero_si128 (), (__mmask8)(U))) +#define _mm256_mask_srli_epi64(W, U, A, B) ((__m256i) __builtin_ia32_psrlqi256_mask ((__v4di)(__m256i)(A), (unsigned int)(B), (__v4di)(__m256i)(W), (__mmask8)(U))) +#define _mm256_maskz_srli_epi64(U, A, B) ((__m256i) __builtin_ia32_psrlqi256_mask ((__v4di)(__m256i)(A), (unsigned int)(B), (__v4di)_mm256_avx512_setzero_si256 (), (__mmask8)(U))) +#define _mm_mask_srli_epi64(W, U, A, B) ((__m128i) __builtin_ia32_psrlqi128_mask ((__v2di)(__m128i)(A), (unsigned int)(B), (__v2di)(__m128i)(W), (__mmask8)(U))) +#define _mm_maskz_srli_epi64(U, A, B) ((__m128i) __builtin_ia32_psrlqi128_mask ((__v2di)(__m128i)(A), (unsigned int)(B), (__v2di)_mm_avx512_setzero_si128 (), (__mmask8)(U))) +#define _mm256_mask_slli_epi32(W, U, X, C) ((__m256i)__builtin_ia32_pslldi256_mask ((__v8si)(__m256i)(X), (unsigned int)(C), (__v8si)(__m256i)(W), (__mmask8)(U))) +#define _mm256_maskz_slli_epi32(U, X, C) ((__m256i)__builtin_ia32_pslldi256_mask ((__v8si)(__m256i)(X), (unsigned int)(C), (__v8si)(__m256i)_mm256_avx512_setzero_si256 (), (__mmask8)(U))) +#define _mm256_mask_slli_epi64(W, U, X, C) ((__m256i)__builtin_ia32_psllqi256_mask ((__v4di)(__m256i)(X), (unsigned int)(C), (__v4di)(__m256i)(W), (__mmask8)(U))) +#define _mm256_maskz_slli_epi64(U, X, C) ((__m256i)__builtin_ia32_psllqi256_mask ((__v4di)(__m256i)(X), (unsigned int)(C), (__v4di)(__m256i)_mm256_avx512_setzero_si256 (), (__mmask8)(U))) +#define _mm_mask_slli_epi32(W, U, X, C) ((__m128i)__builtin_ia32_pslldi128_mask ((__v4si)(__m128i)(X), (unsigned int)(C), (__v4si)(__m128i)(W), (__mmask8)(U))) +#define _mm_maskz_slli_epi32(U, X, C) ((__m128i)__builtin_ia32_pslldi128_mask ((__v4si)(__m128i)(X), (unsigned int)(C), (__v4si)(__m128i)_mm_avx512_setzero_si128 (), (__mmask8)(U))) +#define _mm_mask_slli_epi64(W, U, X, C) ((__m128i)__builtin_ia32_psllqi128_mask ((__v2di)(__m128i)(X), (unsigned int)(C), (__v2di)(__m128i)(W), (__mmask8)(U))) +#define _mm_maskz_slli_epi64(U, X, C) ((__m128i)__builtin_ia32_psllqi128_mask ((__v2di)(__m128i)(X), (unsigned int)(C), (__v2di)(__m128i)_mm_avx512_setzero_si128 (), (__mmask8)(U))) #define _mm256_ternarylogic_epi64(A, B, C, I) ((__m256i) __builtin_ia32_pternlogq256_mask ((__v4di) (__m256i) (A), (__v4di) (__m256i) (B), (__v4di) (__m256i) (C), (unsigned char) (I), (__mmask8) -1)) #define _mm256_mask_ternarylogic_epi64(A, U, B, C, I) ((__m256i) __builtin_ia32_pternlogq256_mask ((__v4di) (__m256i) (A), (__v4di) (__m256i) (B), (__v4di) (__m256i) (C), (unsigned char) (I), (__mmask8) (U))) #define _mm256_maskz_ternarylogic_epi64(U, A, B, C, I) ((__m256i) __builtin_ia32_pternlogq256_maskz ((__v4di) (__m256i) (A), (__v4di) (__m256i) (B), (__v4di) (__m256i) (C), (unsigned char) (I), (__mmask8) (U))) @@ -11371,30 +11180,30 @@ _mm256_permutex_pd (__m256d __X, const int __M) #define _mm_ternarylogic_epi32(A, B, C, I) ((__m128i) __builtin_ia32_pternlogd128_mask ((__v4si) (__m128i) (A), (__v4si) (__m128i) (B), (__v4si) (__m128i) (C), (unsigned char) (I), (__mmask8) -1)) #define _mm_mask_ternarylogic_epi32(A, U, B, C, I) ((__m128i) __builtin_ia32_pternlogd128_mask ((__v4si) (__m128i) (A), (__v4si) (__m128i) (B), (__v4si) (__m128i) (C), (unsigned char) (I), (__mmask8) (U))) #define _mm_maskz_ternarylogic_epi32(U, A, B, C, I) ((__m128i) __builtin_ia32_pternlogd128_maskz ((__v4si) (__m128i) (A), (__v4si) (__m128i) (B), (__v4si) (__m128i) (C), (unsigned char) (I), (__mmask8) (U))) -#define _mm256_roundscale_ps(A, B) ((__m256) __builtin_ia32_rndscaleps_256_mask ((__v8sf)(__m256)(A), (int)(B), (__v8sf)(__m256)_mm256_setzero_ps (), (__mmask8)-1)) +#define _mm256_roundscale_ps(A, B) ((__m256) __builtin_ia32_rndscaleps_256_mask ((__v8sf)(__m256)(A), (int)(B), (__v8sf)(__m256)_mm256_avx512_setzero_ps (), (__mmask8)-1)) #define _mm256_mask_roundscale_ps(W, U, A, B) ((__m256) __builtin_ia32_rndscaleps_256_mask ((__v8sf)(__m256)(A), (int)(B), (__v8sf)(__m256)(W), (__mmask8)(U))) -#define _mm256_maskz_roundscale_ps(U, A, B) ((__m256) __builtin_ia32_rndscaleps_256_mask ((__v8sf)(__m256)(A), (int)(B), (__v8sf)(__m256)_mm256_setzero_ps (), (__mmask8)(U))) -#define _mm256_roundscale_pd(A, B) ((__m256d) __builtin_ia32_rndscalepd_256_mask ((__v4df)(__m256d)(A), (int)(B), (__v4df)(__m256d)_mm256_setzero_pd (), (__mmask8)-1)) +#define _mm256_maskz_roundscale_ps(U, A, B) ((__m256) __builtin_ia32_rndscaleps_256_mask ((__v8sf)(__m256)(A), (int)(B), (__v8sf)(__m256)_mm256_avx512_setzero_ps (), (__mmask8)(U))) +#define _mm256_roundscale_pd(A, B) ((__m256d) __builtin_ia32_rndscalepd_256_mask ((__v4df)(__m256d)(A), (int)(B), (__v4df)(__m256d)_mm256_avx512_setzero_pd (), (__mmask8)-1)) #define _mm256_mask_roundscale_pd(W, U, A, B) ((__m256d) __builtin_ia32_rndscalepd_256_mask ((__v4df)(__m256d)(A), (int)(B), (__v4df)(__m256d)(W), (__mmask8)(U))) -#define _mm256_maskz_roundscale_pd(U, A, B) ((__m256d) __builtin_ia32_rndscalepd_256_mask ((__v4df)(__m256d)(A), (int)(B), (__v4df)(__m256d)_mm256_setzero_pd (), (__mmask8)(U))) -#define _mm_roundscale_ps(A, B) ((__m128) __builtin_ia32_rndscaleps_128_mask ((__v4sf)(__m128)(A), (int)(B), (__v4sf)(__m128)_mm_setzero_ps (), (__mmask8)-1)) +#define _mm256_maskz_roundscale_pd(U, A, B) ((__m256d) __builtin_ia32_rndscalepd_256_mask ((__v4df)(__m256d)(A), (int)(B), (__v4df)(__m256d)_mm256_avx512_setzero_pd (), (__mmask8)(U))) +#define _mm_roundscale_ps(A, B) ((__m128) __builtin_ia32_rndscaleps_128_mask ((__v4sf)(__m128)(A), (int)(B), (__v4sf)(__m128)_mm_avx512_setzero_ps (), (__mmask8)-1)) #define _mm_mask_roundscale_ps(W, U, A, B) ((__m128) __builtin_ia32_rndscaleps_128_mask ((__v4sf)(__m128)(A), (int)(B), (__v4sf)(__m128)(W), (__mmask8)(U))) -#define _mm_maskz_roundscale_ps(U, A, B) ((__m128) __builtin_ia32_rndscaleps_128_mask ((__v4sf)(__m128)(A), (int)(B), (__v4sf)(__m128)_mm_setzero_ps (), (__mmask8)(U))) -#define _mm_roundscale_pd(A, B) ((__m128d) __builtin_ia32_rndscalepd_128_mask ((__v2df)(__m128d)(A), (int)(B), (__v2df)(__m128d)_mm_setzero_pd (), (__mmask8)-1)) +#define _mm_maskz_roundscale_ps(U, A, B) ((__m128) __builtin_ia32_rndscaleps_128_mask ((__v4sf)(__m128)(A), (int)(B), (__v4sf)(__m128)_mm_avx512_setzero_ps (), (__mmask8)(U))) +#define _mm_roundscale_pd(A, B) ((__m128d) __builtin_ia32_rndscalepd_128_mask ((__v2df)(__m128d)(A), (int)(B), (__v2df)(__m128d)_mm_avx512_setzero_pd (), (__mmask8)-1)) #define _mm_mask_roundscale_pd(W, U, A, B) ((__m128d) __builtin_ia32_rndscalepd_128_mask ((__v2df)(__m128d)(A), (int)(B), (__v2df)(__m128d)(W), (__mmask8)(U))) -#define _mm_maskz_roundscale_pd(U, A, B) ((__m128d) __builtin_ia32_rndscalepd_128_mask ((__v2df)(__m128d)(A), (int)(B), (__v2df)(__m128d)_mm_setzero_pd (), (__mmask8)(U))) -#define _mm256_getmant_ps(X, B, C) ((__m256) __builtin_ia32_getmantps256_mask ((__v8sf)(__m256) (X), (int)(((C)<<2) | (B)), (__v8sf)(__m256)_mm256_setzero_ps (), (__mmask8)-1)) +#define _mm_maskz_roundscale_pd(U, A, B) ((__m128d) __builtin_ia32_rndscalepd_128_mask ((__v2df)(__m128d)(A), (int)(B), (__v2df)(__m128d)_mm_avx512_setzero_pd (), (__mmask8)(U))) +#define _mm256_getmant_ps(X, B, C) ((__m256) __builtin_ia32_getmantps256_mask ((__v8sf)(__m256) (X), (int)(((C)<<2) | (B)), (__v8sf)(__m256)_mm256_avx512_setzero_ps (), (__mmask8)-1)) #define _mm256_mask_getmant_ps(W, U, X, B, C) ((__m256) __builtin_ia32_getmantps256_mask ((__v8sf)(__m256) (X), (int)(((C)<<2) | (B)), (__v8sf)(__m256)(W), (__mmask8)(U))) -#define _mm256_maskz_getmant_ps(U, X, B, C) ((__m256) __builtin_ia32_getmantps256_mask ((__v8sf)(__m256) (X), (int)(((C)<<2) | (B)), (__v8sf)(__m256)_mm256_setzero_ps (), (__mmask8)(U))) -#define _mm_getmant_ps(X, B, C) ((__m128) __builtin_ia32_getmantps128_mask ((__v4sf)(__m128) (X), (int)(((C)<<2) | (B)), (__v4sf)(__m128)_mm_setzero_ps (), (__mmask8)-1)) +#define _mm256_maskz_getmant_ps(U, X, B, C) ((__m256) __builtin_ia32_getmantps256_mask ((__v8sf)(__m256) (X), (int)(((C)<<2) | (B)), (__v8sf)(__m256)_mm256_avx512_setzero_ps (), (__mmask8)(U))) +#define _mm_getmant_ps(X, B, C) ((__m128) __builtin_ia32_getmantps128_mask ((__v4sf)(__m128) (X), (int)(((C)<<2) | (B)), (__v4sf)(__m128)_mm_avx512_setzero_ps (), (__mmask8)-1)) #define _mm_mask_getmant_ps(W, U, X, B, C) ((__m128) __builtin_ia32_getmantps128_mask ((__v4sf)(__m128) (X), (int)(((C)<<2) | (B)), (__v4sf)(__m128)(W), (__mmask8)(U))) -#define _mm_maskz_getmant_ps(U, X, B, C) ((__m128) __builtin_ia32_getmantps128_mask ((__v4sf)(__m128) (X), (int)(((C)<<2) | (B)), (__v4sf)(__m128)_mm_setzero_ps (), (__mmask8)(U))) -#define _mm256_getmant_pd(X, B, C) ((__m256d) __builtin_ia32_getmantpd256_mask ((__v4df)(__m256d) (X), (int)(((C)<<2) | (B)), (__v4df)(__m256d)_mm256_setzero_pd (), (__mmask8)-1)) +#define _mm_maskz_getmant_ps(U, X, B, C) ((__m128) __builtin_ia32_getmantps128_mask ((__v4sf)(__m128) (X), (int)(((C)<<2) | (B)), (__v4sf)(__m128)_mm_avx512_setzero_ps (), (__mmask8)(U))) +#define _mm256_getmant_pd(X, B, C) ((__m256d) __builtin_ia32_getmantpd256_mask ((__v4df)(__m256d) (X), (int)(((C)<<2) | (B)), (__v4df)(__m256d)_mm256_avx512_setzero_pd (), (__mmask8)-1)) #define _mm256_mask_getmant_pd(W, U, X, B, C) ((__m256d) __builtin_ia32_getmantpd256_mask ((__v4df)(__m256d) (X), (int)(((C)<<2) | (B)), (__v4df)(__m256d)(W), (__mmask8)(U))) -#define _mm256_maskz_getmant_pd(U, X, B, C) ((__m256d) __builtin_ia32_getmantpd256_mask ((__v4df)(__m256d) (X), (int)(((C)<<2) | (B)), (__v4df)(__m256d)_mm256_setzero_pd (), (__mmask8)(U))) -#define _mm_getmant_pd(X, B, C) ((__m128d) __builtin_ia32_getmantpd128_mask ((__v2df)(__m128d) (X), (int)(((C)<<2) | (B)), (__v2df)(__m128d)_mm_setzero_pd (), (__mmask8)-1)) +#define _mm256_maskz_getmant_pd(U, X, B, C) ((__m256d) __builtin_ia32_getmantpd256_mask ((__v4df)(__m256d) (X), (int)(((C)<<2) | (B)), (__v4df)(__m256d)_mm256_avx512_setzero_pd (), (__mmask8)(U))) +#define _mm_getmant_pd(X, B, C) ((__m128d) __builtin_ia32_getmantpd128_mask ((__v2df)(__m128d) (X), (int)(((C)<<2) | (B)), (__v2df)(__m128d)_mm_avx512_setzero_pd (), (__mmask8)-1)) #define _mm_mask_getmant_pd(W, U, X, B, C) ((__m128d) __builtin_ia32_getmantpd128_mask ((__v2df)(__m128d) (X), (int)(((C)<<2) | (B)), (__v2df)(__m128d)(W), (__mmask8)(U))) -#define _mm_maskz_getmant_pd(U, X, B, C) ((__m128d) __builtin_ia32_getmantpd128_mask ((__v2df)(__m128d) (X), (int)(((C)<<2) | (B)), (__v2df)(__m128d)_mm_setzero_pd (), (__mmask8)(U))) +#define _mm_maskz_getmant_pd(U, X, B, C) ((__m128d) __builtin_ia32_getmantpd128_mask ((__v2df)(__m128d) (X), (int)(((C)<<2) | (B)), (__v2df)(__m128d)_mm_avx512_setzero_pd (), (__mmask8)(U))) #define _mm256_mmask_i32gather_ps(V1OLD, MASK, INDEX, ADDR, SCALE) (__m256) __builtin_ia32_gather3siv8sf ((__v8sf)(__m256) (V1OLD), (void const *) (ADDR), (__v8si)(__m256i) (INDEX), (__mmask8) (MASK), (int) (SCALE)) #define _mm_mmask_i32gather_ps(V1OLD, MASK, INDEX, ADDR, SCALE) (__m128) __builtin_ia32_gather3siv4sf ((__v4sf)(__m128) (V1OLD), (void const *) (ADDR), (__v4si)(__m128i) (INDEX), (__mmask8) (MASK), (int) (SCALE)) #define _mm256_mmask_i32gather_pd(V1OLD, MASK, INDEX, ADDR, SCALE) (__m256d) __builtin_ia32_gather3siv4df ((__v4df)(__m256d) (V1OLD), (void const *) (ADDR), (__v4si)(__m128i) (INDEX), (__mmask8) (MASK), (int) (SCALE)) @@ -11444,77 +11253,69 @@ _mm256_permutex_pd (__m256d __X, const int __M) #define _mm_i64scatter_epi64(ADDR, INDEX, V1, SCALE) __builtin_ia32_scatterdiv2di ((void *) (ADDR), (__mmask8)0xFF, (__v2di)(__m128i) (INDEX), (__v2di)(__m128i) (V1), (int) (SCALE)) #define _mm_mask_i64scatter_epi64(ADDR, MASK, INDEX, V1, SCALE) __builtin_ia32_scatterdiv2di ((void *) (ADDR), (__mmask8) (MASK), (__v2di)(__m128i) (INDEX), (__v2di)(__m128i) (V1), (int) (SCALE)) #define _mm256_mask_shuffle_epi32(W, U, X, C) ((__m256i) __builtin_ia32_pshufd256_mask ((__v8si)(__m256i)(X), (int)(C), (__v8si)(__m256i)(W), (__mmask8)(U))) -#define _mm256_maskz_shuffle_epi32(U, X, C) ((__m256i) __builtin_ia32_pshufd256_mask ((__v8si)(__m256i)(X), (int)(C), (__v8si)(__m256i) _mm256_setzero_si256 (), (__mmask8)(U))) +#define _mm256_maskz_shuffle_epi32(U, X, C) ((__m256i) __builtin_ia32_pshufd256_mask ((__v8si)(__m256i)(X), (int)(C), (__v8si)(__m256i) _mm256_avx512_setzero_si256 (), (__mmask8)(U))) #define _mm_mask_shuffle_epi32(W, U, X, C) ((__m128i) __builtin_ia32_pshufd128_mask ((__v4si)(__m128i)(X), (int)(C), (__v4si)(__m128i)(W), (__mmask8)(U))) -#define _mm_maskz_shuffle_epi32(U, X, C) ((__m128i) __builtin_ia32_pshufd128_mask ((__v4si)(__m128i)(X), (int)(C), (__v4si)(__m128i)_mm_setzero_si128 (), (__mmask8)(U))) -#define _mm256_rol_epi64(A, B) ((__m256i)__builtin_ia32_prolq256_mask ((__v4di)(__m256i)(A), (int)(B), (__v4di)(__m256i)_mm256_setzero_si256 (), (__mmask8)-1)) +#define _mm_maskz_shuffle_epi32(U, X, C) ((__m128i) __builtin_ia32_pshufd128_mask ((__v4si)(__m128i)(X), (int)(C), (__v4si)(__m128i)_mm_avx512_setzero_si128 (), (__mmask8)(U))) +#define _mm256_rol_epi64(A, B) ((__m256i)__builtin_ia32_prolq256_mask ((__v4di)(__m256i)(A), (int)(B), (__v4di)(__m256i)_mm256_avx512_setzero_si256 (), (__mmask8)-1)) #define _mm256_mask_rol_epi64(W, U, A, B) ((__m256i)__builtin_ia32_prolq256_mask ((__v4di)(__m256i)(A), (int)(B), (__v4di)(__m256i)(W), (__mmask8)(U))) -#define _mm256_maskz_rol_epi64(U, A, B) ((__m256i)__builtin_ia32_prolq256_mask ((__v4di)(__m256i)(A), (int)(B), (__v4di)(__m256i)_mm256_setzero_si256 (), (__mmask8)(U))) -#define _mm_rol_epi64(A, B) ((__m128i)__builtin_ia32_prolq128_mask ((__v2di)(__m128i)(A), (int)(B), (__v2di)(__m128i)_mm_setzero_si128 (), (__mmask8)-1)) +#define _mm256_maskz_rol_epi64(U, A, B) ((__m256i)__builtin_ia32_prolq256_mask ((__v4di)(__m256i)(A), (int)(B), (__v4di)(__m256i)_mm256_avx512_setzero_si256 (), (__mmask8)(U))) +#define _mm_rol_epi64(A, B) ((__m128i)__builtin_ia32_prolq128_mask ((__v2di)(__m128i)(A), (int)(B), (__v2di)(__m128i)_mm_avx512_setzero_si128 (), (__mmask8)-1)) #define _mm_mask_rol_epi64(W, U, A, B) ((__m128i)__builtin_ia32_prolq128_mask ((__v2di)(__m128i)(A), (int)(B), (__v2di)(__m128i)(W), (__mmask8)(U))) -#define _mm_maskz_rol_epi64(U, A, B) ((__m128i)__builtin_ia32_prolq128_mask ((__v2di)(__m128i)(A), (int)(B), (__v2di)(__m128i)_mm_setzero_si128 (), (__mmask8)(U))) -#define _mm256_ror_epi64(A, B) ((__m256i)__builtin_ia32_prorq256_mask ((__v4di)(__m256i)(A), (int)(B), (__v4di)(__m256i)_mm256_setzero_si256 (), (__mmask8)-1)) +#define _mm_maskz_rol_epi64(U, A, B) ((__m128i)__builtin_ia32_prolq128_mask ((__v2di)(__m128i)(A), (int)(B), (__v2di)(__m128i)_mm_avx512_setzero_si128 (), (__mmask8)(U))) +#define _mm256_ror_epi64(A, B) ((__m256i)__builtin_ia32_prorq256_mask ((__v4di)(__m256i)(A), (int)(B), (__v4di)(__m256i)_mm256_avx512_setzero_si256 (), (__mmask8)-1)) #define _mm256_mask_ror_epi64(W, U, A, B) ((__m256i)__builtin_ia32_prorq256_mask ((__v4di)(__m256i)(A), (int)(B), (__v4di)(__m256i)(W), (__mmask8)(U))) -#define _mm256_maskz_ror_epi64(U, A, B) ((__m256i)__builtin_ia32_prorq256_mask ((__v4di)(__m256i)(A), (int)(B), (__v4di)(__m256i)_mm256_setzero_si256 (), (__mmask8)(U))) -#define _mm_ror_epi64(A, B) ((__m128i)__builtin_ia32_prorq128_mask ((__v2di)(__m128i)(A), (int)(B), (__v2di)(__m128i)_mm_setzero_si128 (), (__mmask8)-1)) +#define _mm256_maskz_ror_epi64(U, A, B) ((__m256i)__builtin_ia32_prorq256_mask ((__v4di)(__m256i)(A), (int)(B), (__v4di)(__m256i)_mm256_avx512_setzero_si256 (), (__mmask8)(U))) +#define _mm_ror_epi64(A, B) ((__m128i)__builtin_ia32_prorq128_mask ((__v2di)(__m128i)(A), (int)(B), (__v2di)(__m128i)_mm_avx512_setzero_si128 (), (__mmask8)-1)) #define _mm_mask_ror_epi64(W, U, A, B) ((__m128i)__builtin_ia32_prorq128_mask ((__v2di)(__m128i)(A), (int)(B), (__v2di)(__m128i)(W), (__mmask8)(U))) -#define _mm_maskz_ror_epi64(U, A, B) ((__m128i)__builtin_ia32_prorq128_mask ((__v2di)(__m128i)(A), (int)(B), (__v2di)(__m128i)_mm_setzero_si128 (), (__mmask8)(U))) -#define _mm256_rol_epi32(A, B) ((__m256i)__builtin_ia32_prold256_mask ((__v8si)(__m256i)(A), (int)(B), (__v8si)(__m256i)_mm256_setzero_si256 (), (__mmask8)-1)) +#define _mm_maskz_ror_epi64(U, A, B) ((__m128i)__builtin_ia32_prorq128_mask ((__v2di)(__m128i)(A), (int)(B), (__v2di)(__m128i)_mm_avx512_setzero_si128 (), (__mmask8)(U))) +#define _mm256_rol_epi32(A, B) ((__m256i)__builtin_ia32_prold256_mask ((__v8si)(__m256i)(A), (int)(B), (__v8si)(__m256i)_mm256_avx512_setzero_si256 (), (__mmask8)-1)) #define _mm256_mask_rol_epi32(W, U, A, B) ((__m256i)__builtin_ia32_prold256_mask ((__v8si)(__m256i)(A), (int)(B), (__v8si)(__m256i)(W), (__mmask8)(U))) -#define _mm256_maskz_rol_epi32(U, A, B) ((__m256i)__builtin_ia32_prold256_mask ((__v8si)(__m256i)(A), (int)(B), (__v8si)(__m256i)_mm256_setzero_si256 (), (__mmask8)(U))) -#define _mm_rol_epi32(A, B) ((__m128i)__builtin_ia32_prold128_mask ((__v4si)(__m128i)(A), (int)(B), (__v4si)(__m128i)_mm_setzero_si128 (), (__mmask8)-1)) +#define _mm256_maskz_rol_epi32(U, A, B) ((__m256i)__builtin_ia32_prold256_mask ((__v8si)(__m256i)(A), (int)(B), (__v8si)(__m256i)_mm256_avx512_setzero_si256 (), (__mmask8)(U))) +#define _mm_rol_epi32(A, B) ((__m128i)__builtin_ia32_prold128_mask ((__v4si)(__m128i)(A), (int)(B), (__v4si)(__m128i)_mm_avx512_setzero_si128 (), (__mmask8)-1)) #define _mm_mask_rol_epi32(W, U, A, B) ((__m128i)__builtin_ia32_prold128_mask ((__v4si)(__m128i)(A), (int)(B), (__v4si)(__m128i)(W), (__mmask8)(U))) -#define _mm_maskz_rol_epi32(U, A, B) ((__m128i)__builtin_ia32_prold128_mask ((__v4si)(__m128i)(A), (int)(B), (__v4si)(__m128i)_mm_setzero_si128 (), (__mmask8)(U))) -#define _mm256_ror_epi32(A, B) ((__m256i)__builtin_ia32_prord256_mask ((__v8si)(__m256i)(A), (int)(B), (__v8si)(__m256i)_mm256_setzero_si256 (), (__mmask8)-1)) +#define _mm_maskz_rol_epi32(U, A, B) ((__m128i)__builtin_ia32_prold128_mask ((__v4si)(__m128i)(A), (int)(B), (__v4si)(__m128i)_mm_avx512_setzero_si128 (), (__mmask8)(U))) +#define _mm256_ror_epi32(A, B) ((__m256i)__builtin_ia32_prord256_mask ((__v8si)(__m256i)(A), (int)(B), (__v8si)(__m256i)_mm256_avx512_setzero_si256 (), (__mmask8)-1)) #define _mm256_mask_ror_epi32(W, U, A, B) ((__m256i)__builtin_ia32_prord256_mask ((__v8si)(__m256i)(A), (int)(B), (__v8si)(__m256i)(W), (__mmask8)(U))) -#define _mm256_maskz_ror_epi32(U, A, B) ((__m256i)__builtin_ia32_prord256_mask ((__v8si)(__m256i)(A), (int)(B), (__v8si)(__m256i) _mm256_setzero_si256 (), (__mmask8)(U))) -#define _mm_ror_epi32(A, B) ((__m128i)__builtin_ia32_prord128_mask ((__v4si)(__m128i)(A), (int)(B), (__v4si)(__m128i)_mm_setzero_si128 (), (__mmask8)-1)) +#define _mm256_maskz_ror_epi32(U, A, B) ((__m256i)__builtin_ia32_prord256_mask ((__v8si)(__m256i)(A), (int)(B), (__v8si)(__m256i) _mm256_avx512_setzero_si256 (), (__mmask8)(U))) +#define _mm_ror_epi32(A, B) ((__m128i)__builtin_ia32_prord128_mask ((__v4si)(__m128i)(A), (int)(B), (__v4si)(__m128i)_mm_avx512_setzero_si128 (), (__mmask8)-1)) #define _mm_mask_ror_epi32(W, U, A, B) ((__m128i)__builtin_ia32_prord128_mask ((__v4si)(__m128i)(A), (int)(B), (__v4si)(__m128i)(W), (__mmask8)(U))) -#define _mm_maskz_ror_epi32(U, A, B) ((__m128i)__builtin_ia32_prord128_mask ((__v4si)(__m128i)(A), (int)(B), (__v4si)(__m128i)_mm_setzero_si128 (), (__mmask8)(U))) +#define _mm_maskz_ror_epi32(U, A, B) ((__m128i)__builtin_ia32_prord128_mask ((__v4si)(__m128i)(A), (int)(B), (__v4si)(__m128i)_mm_avx512_setzero_si128 (), (__mmask8)(U))) #define _mm256_alignr_epi32(X, Y, C) ((__m256i)__builtin_ia32_alignd256_mask ((__v8si)(__m256i)(X), (__v8si)(__m256i)(Y), (int)(C), (__v8si)(__m256i)(X), (__mmask8)-1)) #define _mm256_mask_alignr_epi32(W, U, X, Y, C) ((__m256i)__builtin_ia32_alignd256_mask ((__v8si)(__m256i)(X), (__v8si)(__m256i)(Y), (int)(C), (__v8si)(__m256i)(W), (__mmask8)(U))) -#define _mm256_maskz_alignr_epi32(U, X, Y, C) ((__m256i)__builtin_ia32_alignd256_mask ((__v8si)(__m256i)(X), (__v8si)(__m256i)(Y), (int)(C), (__v8si)(__m256i)_mm256_setzero_si256 (), (__mmask8)(U))) +#define _mm256_maskz_alignr_epi32(U, X, Y, C) ((__m256i)__builtin_ia32_alignd256_mask ((__v8si)(__m256i)(X), (__v8si)(__m256i)(Y), (int)(C), (__v8si)(__m256i)_mm256_avx512_setzero_si256 (), (__mmask8)(U))) #define _mm256_alignr_epi64(X, Y, C) ((__m256i)__builtin_ia32_alignq256_mask ((__v4di)(__m256i)(X), (__v4di)(__m256i)(Y), (int)(C), (__v4di)(__m256i)(X), (__mmask8)-1)) #define _mm256_mask_alignr_epi64(W, U, X, Y, C) ((__m256i)__builtin_ia32_alignq256_mask ((__v4di)(__m256i)(X), (__v4di)(__m256i)(Y), (int)(C), (__v4di)(__m256i)(W), (__mmask8)(U))) -#define _mm256_maskz_alignr_epi64(U, X, Y, C) ((__m256i)__builtin_ia32_alignq256_mask ((__v4di)(__m256i)(X), (__v4di)(__m256i)(Y), (int)(C), (__v4di)(__m256i)_mm256_setzero_si256 (), (__mmask8)(U))) +#define _mm256_maskz_alignr_epi64(U, X, Y, C) ((__m256i)__builtin_ia32_alignq256_mask ((__v4di)(__m256i)(X), (__v4di)(__m256i)(Y), (int)(C), (__v4di)(__m256i)_mm256_avx512_setzero_si256 (), (__mmask8)(U))) #define _mm_alignr_epi32(X, Y, C) ((__m128i)__builtin_ia32_alignd128_mask ((__v4si)(__m128i)(X), (__v4si)(__m128i)(Y), (int)(C), (__v4si)(__m128i)(X), (__mmask8)-1)) #define _mm_mask_alignr_epi32(W, U, X, Y, C) ((__m128i)__builtin_ia32_alignd128_mask ((__v4si)(__m128i)(X), (__v4si)(__m128i)(Y), (int)(C), (__v4si)(__m128i)(W), (__mmask8)(U))) -#define _mm_maskz_alignr_epi32(U, X, Y, C) ((__m128i)__builtin_ia32_alignd128_mask ((__v4si)(__m128i)(X), (__v4si)(__m128i)(Y), (int)(C), (__v4si)(__m128i)_mm_setzero_si128 (), (__mmask8)(U))) +#define _mm_maskz_alignr_epi32(U, X, Y, C) ((__m128i)__builtin_ia32_alignd128_mask ((__v4si)(__m128i)(X), (__v4si)(__m128i)(Y), (int)(C), (__v4si)(__m128i)_mm_avx512_setzero_si128 (), (__mmask8)(U))) #define _mm_alignr_epi64(X, Y, C) ((__m128i)__builtin_ia32_alignq128_mask ((__v2di)(__m128i)(X), (__v2di)(__m128i)(Y), (int)(C), (__v2di)(__m128i)(X), (__mmask8)-1)) #define _mm_mask_alignr_epi64(W, U, X, Y, C) ((__m128i)__builtin_ia32_alignq128_mask ((__v2di)(__m128i)(X), (__v2di)(__m128i)(Y), (int)(C), (__v2di)(__m128i)(X), (__mmask8)-1)) -#define _mm_maskz_alignr_epi64(U, X, Y, C) ((__m128i)__builtin_ia32_alignq128_mask ((__v2di)(__m128i)(X), (__v2di)(__m128i)(Y), (int)(C), (__v2di)(__m128i)_mm_setzero_si128 (), (__mmask8)(U))) +#define _mm_maskz_alignr_epi64(U, X, Y, C) ((__m128i)__builtin_ia32_alignq128_mask ((__v2di)(__m128i)(X), (__v2di)(__m128i)(Y), (int)(C), (__v2di)(__m128i)_mm_avx512_setzero_si128 (), (__mmask8)(U))) #define _mm_mask_cvtps_ph(W, U, A, I) ((__m128i) __builtin_ia32_vcvtps2ph_mask ((__v4sf)(__m128) (A), (int) (I), (__v8hi)(__m128i) (W), (__mmask8) (U))) -#define _mm_maskz_cvtps_ph(U, A, I) ((__m128i) __builtin_ia32_vcvtps2ph_mask ((__v4sf)(__m128) (A), (int) (I), (__v8hi)(__m128i) _mm_setzero_si128 (), (__mmask8) (U))) +#define _mm_maskz_cvtps_ph(U, A, I) ((__m128i) __builtin_ia32_vcvtps2ph_mask ((__v4sf)(__m128) (A), (int) (I), (__v8hi)(__m128i) _mm_avx512_setzero_si128 (), (__mmask8) (U))) #define _mm256_mask_cvtps_ph(W, U, A, I) ((__m128i) __builtin_ia32_vcvtps2ph256_mask ((__v8sf)(__m256) (A), (int) (I), (__v8hi)(__m128i) (W), (__mmask8) (U))) -#define _mm256_maskz_cvtps_ph(U, A, I) ((__m128i) __builtin_ia32_vcvtps2ph256_mask ((__v8sf)(__m256) (A), (int) (I), (__v8hi)(__m128i) _mm_setzero_si128 (), (__mmask8) (U))) -#define _mm256_mask_srai_epi32(W, U, A, B) ((__m256i) __builtin_ia32_psradi256_mask ((__v8si)(__m256i)(A), (int)(B), (__v8si)(__m256i)(W), (__mmask8)(U))) -#define _mm256_maskz_srai_epi32(U, A, B) ((__m256i) __builtin_ia32_psradi256_mask ((__v8si)(__m256i)(A), (int)(B), (__v8si)_mm256_setzero_si256 (), (__mmask8)(U))) -#define _mm_mask_srai_epi32(W, U, A, B) ((__m128i) __builtin_ia32_psradi128_mask ((__v4si)(__m128i)(A), (int)(B), (__v4si)(__m128i)(W), (__mmask8)(U))) -#define _mm_maskz_srai_epi32(U, A, B) ((__m128i) __builtin_ia32_psradi128_mask ((__v4si)(__m128i)(A), (int)(B), (__v4si)_mm_setzero_si128 (), (__mmask8)(U))) -#define _mm256_srai_epi64(A, B) ((__m256i) __builtin_ia32_psraqi256_mask ((__v4di)(__m256i)(A), (int)(B), (__v4di)_mm256_setzero_si256 (), (__mmask8)-1)) -#define _mm256_mask_srai_epi64(W, U, A, B) ((__m256i) __builtin_ia32_psraqi256_mask ((__v4di)(__m256i)(A), (int)(B), (__v4di)(__m256i)(W), (__mmask8)(U))) -#define _mm256_maskz_srai_epi64(U, A, B) ((__m256i) __builtin_ia32_psraqi256_mask ((__v4di)(__m256i)(A), (int)(B), (__v4di)_mm256_setzero_si256 (), (__mmask8)(U))) -#define _mm_srai_epi64(A, B) ((__m128i) __builtin_ia32_psraqi128_mask ((__v2di)(__m128i)(A), (int)(B), (__v2di)_mm_setzero_si128 (), (__mmask8)-1)) -#define _mm_mask_srai_epi64(W, U, A, B) ((__m128i) __builtin_ia32_psraqi128_mask ((__v2di)(__m128i)(A), (int)(B), (__v2di)(__m128i)(W), (__mmask8)(U))) -#define _mm_maskz_srai_epi64(U, A, B) ((__m128i) __builtin_ia32_psraqi128_mask ((__v2di)(__m128i)(A), (int)(B), (__v2di)_mm_setzero_si128 (), (__mmask8)(U))) +#define _mm256_maskz_cvtps_ph(U, A, I) ((__m128i) __builtin_ia32_vcvtps2ph256_mask ((__v8sf)(__m256) (A), (int) (I), (__v8hi)(__m128i) _mm_avx512_setzero_si128 (), (__mmask8) (U))) +#define _mm256_mask_srai_epi32(W, U, A, B) ((__m256i) __builtin_ia32_psradi256_mask ((__v8si)(__m256i)(A), (unsigned int)(B), (__v8si)(__m256i)(W), (__mmask8)(U))) +#define _mm256_maskz_srai_epi32(U, A, B) ((__m256i) __builtin_ia32_psradi256_mask ((__v8si)(__m256i)(A), (unsigned int)(B), (__v8si)_mm256_avx512_setzero_si256 (), (__mmask8)(U))) +#define _mm_mask_srai_epi32(W, U, A, B) ((__m128i) __builtin_ia32_psradi128_mask ((__v4si)(__m128i)(A), (unsigned int)(B), (__v4si)(__m128i)(W), (__mmask8)(U))) +#define _mm_maskz_srai_epi32(U, A, B) ((__m128i) __builtin_ia32_psradi128_mask ((__v4si)(__m128i)(A), (unsigned int)(B), (__v4si)_mm_avx512_setzero_si128 (), (__mmask8)(U))) +#define _mm256_srai_epi64(A, B) ((__m256i) __builtin_ia32_psraqi256_mask ((__v4di)(__m256i)(A), (unsigned int)(B), (__v4di)_mm256_avx512_setzero_si256 (), (__mmask8)-1)) +#define _mm256_mask_srai_epi64(W, U, A, B) ((__m256i) __builtin_ia32_psraqi256_mask ((__v4di)(__m256i)(A), (unsigned int)(B), (__v4di)(__m256i)(W), (__mmask8)(U))) +#define _mm256_maskz_srai_epi64(U, A, B) ((__m256i) __builtin_ia32_psraqi256_mask ((__v4di)(__m256i)(A), (unsigned int)(B), (__v4di)_mm256_avx512_setzero_si256 (), (__mmask8)(U))) +#define _mm_srai_epi64(A, B) ((__m128i) __builtin_ia32_psraqi128_mask ((__v2di)(__m128i)(A), (unsigned int)(B), (__v2di)_mm_avx512_setzero_si128 (), (__mmask8)-1)) +#define _mm_mask_srai_epi64(W, U, A, B) ((__m128i) __builtin_ia32_psraqi128_mask ((__v2di)(__m128i)(A), (unsigned int)(B), (__v2di)(__m128i)(W), (__mmask8)(U))) +#define _mm_maskz_srai_epi64(U, A, B) ((__m128i) __builtin_ia32_psraqi128_mask ((__v2di)(__m128i)(A), (unsigned int)(B), (__v2di)_mm_avx512_setzero_si128 (), (__mmask8)(U))) #define _mm256_mask_permutex_pd(W, U, A, B) ((__m256d) __builtin_ia32_permdf256_mask ((__v4df)(__m256d)(A), (int)(B), (__v4df)(__m256d)(W), (__mmask8)(U))) -#define _mm256_maskz_permutex_pd(U, A, B) ((__m256d) __builtin_ia32_permdf256_mask ((__v4df)(__m256d)(A), (int)(B), (__v4df)(__m256d)_mm256_setzero_pd (), (__mmask8)(U))) +#define _mm256_maskz_permutex_pd(U, A, B) ((__m256d) __builtin_ia32_permdf256_mask ((__v4df)(__m256d)(A), (int)(B), (__v4df)(__m256d)_mm256_avx512_setzero_pd (), (__mmask8)(U))) #define _mm256_mask_permute_pd(W, U, X, C) ((__m256d) __builtin_ia32_vpermilpd256_mask ((__v4df)(__m256d)(X), (int)(C), (__v4df)(__m256d)(W), (__mmask8)(U))) -#define _mm256_maskz_permute_pd(U, X, C) ((__m256d) __builtin_ia32_vpermilpd256_mask ((__v4df)(__m256d)(X), (int)(C), (__v4df)(__m256d)_mm256_setzero_pd (), (__mmask8)(U))) +#define _mm256_maskz_permute_pd(U, X, C) ((__m256d) __builtin_ia32_vpermilpd256_mask ((__v4df)(__m256d)(X), (int)(C), (__v4df)(__m256d)_mm256_avx512_setzero_pd (), (__mmask8)(U))) #define _mm256_mask_permute_ps(W, U, X, C) ((__m256) __builtin_ia32_vpermilps256_mask ((__v8sf)(__m256)(X), (int)(C), (__v8sf)(__m256)(W), (__mmask8)(U))) -#define _mm256_maskz_permute_ps(U, X, C) ((__m256) __builtin_ia32_vpermilps256_mask ((__v8sf)(__m256)(X), (int)(C), (__v8sf)(__m256)_mm256_setzero_ps (), (__mmask8)(U))) +#define _mm256_maskz_permute_ps(U, X, C) ((__m256) __builtin_ia32_vpermilps256_mask ((__v8sf)(__m256)(X), (int)(C), (__v8sf)(__m256)_mm256_avx512_setzero_ps (), (__mmask8)(U))) #define _mm_mask_permute_pd(W, U, X, C) ((__m128d) __builtin_ia32_vpermilpd_mask ((__v2df)(__m128d)(X), (int)(C), (__v2df)(__m128d)(W), (__mmask8)(U))) -#define _mm_maskz_permute_pd(U, X, C) ((__m128d) __builtin_ia32_vpermilpd_mask ((__v2df)(__m128d)(X), (int)(C), (__v2df)(__m128d)_mm_setzero_pd (), (__mmask8)(U))) +#define _mm_maskz_permute_pd(U, X, C) ((__m128d) __builtin_ia32_vpermilpd_mask ((__v2df)(__m128d)(X), (int)(C), (__v2df)(__m128d)_mm_avx512_setzero_pd (), (__mmask8)(U))) #define _mm_mask_permute_ps(W, U, X, C) ((__m128) __builtin_ia32_vpermilps_mask ((__v4sf)(__m128)(X), (int)(C), (__v4sf)(__m128)(W), (__mmask8)(U))) -#define _mm_maskz_permute_ps(U, X, C) ((__m128) __builtin_ia32_vpermilps_mask ((__v4sf)(__m128)(X), (int)(C), (__v4sf)(__m128)_mm_setzero_ps (), (__mmask8)(U))) -#define _mm256_mask_blend_pd(__U, __A, __W) ((__m256d) __builtin_ia32_blendmpd_256_mask ((__v4df) (__A), (__v4df) (__W), (__mmask8) (__U))) -#define _mm256_mask_blend_ps(__U, __A, __W) ((__m256) __builtin_ia32_blendmps_256_mask ((__v8sf) (__A), (__v8sf) (__W), (__mmask8) (__U))) -#define _mm256_mask_blend_epi64(__U, __A, __W) ((__m256i) __builtin_ia32_blendmq_256_mask ((__v4di) (__A), (__v4di) (__W), (__mmask8) (__U))) -#define _mm256_mask_blend_epi32(__U, __A, __W) ((__m256i) __builtin_ia32_blendmd_256_mask ((__v8si) (__A), (__v8si) (__W), (__mmask8) (__U))) -#define _mm_mask_blend_pd(__U, __A, __W) ((__m128d) __builtin_ia32_blendmpd_128_mask ((__v2df) (__A), (__v2df) (__W), (__mmask8) (__U))) -#define _mm_mask_blend_ps(__U, __A, __W) ((__m128) __builtin_ia32_blendmps_128_mask ((__v4sf) (__A), (__v4sf) (__W), (__mmask8) (__U))) -#define _mm_mask_blend_epi64(__U, __A, __W) ((__m128i) __builtin_ia32_blendmq_128_mask ((__v2di) (__A), (__v2di) (__W), (__mmask8) (__U))) -#define _mm_mask_blend_epi32(__U, __A, __W) ((__m128i) __builtin_ia32_blendmd_128_mask ((__v4si) (__A), (__v4si) (__W), (__mmask8) (__U))) +#define _mm_maskz_permute_ps(U, X, C) ((__m128) __builtin_ia32_vpermilps_mask ((__v4sf)(__m128)(X), (int)(C), (__v4sf)(__m128)_mm_avx512_setzero_ps (), (__mmask8)(U))) #define _mm256_cmp_epu32_mask(X, Y, P) ((__mmask8) __builtin_ia32_ucmpd256_mask ((__v8si)(__m256i)(X), (__v8si)(__m256i)(Y), (int)(P), (__mmask8)-1)) #define _mm256_cmp_epi64_mask(X, Y, P) ((__mmask8) __builtin_ia32_cmpq256_mask ((__v4di)(__m256i)(X), (__v4di)(__m256i)(Y), (int)(P), (__mmask8)-1)) #define _mm256_cmp_epi32_mask(X, Y, P) ((__mmask8) __builtin_ia32_cmpd256_mask ((__v8si)(__m256i)(X), (__v8si)(__m256i)(Y), (int)(P), (__mmask8)-1)) @@ -11549,5 +11350,253 @@ _mm256_permutex_pd (__m256d __X, const int __M) #undef __DISABLE_AVX512VL__ #pragma GCC pop_options #endif +#if !defined (__AVX512CD__) || !defined (__AVX512VL__) +#pragma GCC push_options +#pragma GCC target("avx512vl,avx512cd,no-evex512") +#define __DISABLE_AVX512VLCD__ +#endif +extern __inline __m128i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_broadcastmb_epi64 (__mmask8 __A) +{ + return (__m128i) __builtin_ia32_broadcastmb128 (__A); +} +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_broadcastmb_epi64 (__mmask8 __A) +{ + return (__m256i) __builtin_ia32_broadcastmb256 (__A); +} +extern __inline __m128i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_broadcastmw_epi32 (__mmask16 __A) +{ + return (__m128i) __builtin_ia32_broadcastmw128 (__A); +} +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_broadcastmw_epi32 (__mmask16 __A) +{ + return (__m256i) __builtin_ia32_broadcastmw256 (__A); +} +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_lzcnt_epi32 (__m256i __A) +{ + return (__m256i) __builtin_ia32_vplzcntd_256_mask ((__v8si) __A, + (__v8si) + _mm256_avx512_setzero_si256 (), + (__mmask8) -1); +} +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_mask_lzcnt_epi32 (__m256i __W, __mmask8 __U, __m256i __A) +{ + return (__m256i) __builtin_ia32_vplzcntd_256_mask ((__v8si) __A, + (__v8si) __W, + (__mmask8) __U); +} +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_maskz_lzcnt_epi32 (__mmask8 __U, __m256i __A) +{ + return (__m256i) __builtin_ia32_vplzcntd_256_mask ((__v8si) __A, + (__v8si) + _mm256_avx512_setzero_si256 (), + (__mmask8) __U); +} +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_lzcnt_epi64 (__m256i __A) +{ + return (__m256i) __builtin_ia32_vplzcntq_256_mask ((__v4di) __A, + (__v4di) + _mm256_avx512_setzero_si256 (), + (__mmask8) -1); +} +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_mask_lzcnt_epi64 (__m256i __W, __mmask8 __U, __m256i __A) +{ + return (__m256i) __builtin_ia32_vplzcntq_256_mask ((__v4di) __A, + (__v4di) __W, + (__mmask8) __U); +} +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_maskz_lzcnt_epi64 (__mmask8 __U, __m256i __A) +{ + return (__m256i) __builtin_ia32_vplzcntq_256_mask ((__v4di) __A, + (__v4di) + _mm256_avx512_setzero_si256 (), + (__mmask8) __U); +} +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_conflict_epi64 (__m256i __A) +{ + return (__m256i) __builtin_ia32_vpconflictdi_256_mask ((__v4di) __A, + (__v4di) + _mm256_avx512_setzero_si256 (), + (__mmask8) -1); +} +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_mask_conflict_epi64 (__m256i __W, __mmask8 __U, __m256i __A) +{ + return (__m256i) __builtin_ia32_vpconflictdi_256_mask ((__v4di) __A, + (__v4di) __W, + (__mmask8) + __U); +} +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_maskz_conflict_epi64 (__mmask8 __U, __m256i __A) +{ + return (__m256i) __builtin_ia32_vpconflictdi_256_mask ((__v4di) __A, + (__v4di) + _mm256_avx512_setzero_si256 (), + (__mmask8) + __U); +} +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_conflict_epi32 (__m256i __A) +{ + return (__m256i) __builtin_ia32_vpconflictsi_256_mask ((__v8si) __A, + (__v8si) + _mm256_avx512_setzero_si256 (), + (__mmask8) -1); +} +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_mask_conflict_epi32 (__m256i __W, __mmask8 __U, __m256i __A) +{ + return (__m256i) __builtin_ia32_vpconflictsi_256_mask ((__v8si) __A, + (__v8si) __W, + (__mmask8) + __U); +} +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_maskz_conflict_epi32 (__mmask8 __U, __m256i __A) +{ + return (__m256i) __builtin_ia32_vpconflictsi_256_mask ((__v8si) __A, + (__v8si) + _mm256_avx512_setzero_si256 (), + (__mmask8) + __U); +} +extern __inline __m128i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_lzcnt_epi32 (__m128i __A) +{ + return (__m128i) __builtin_ia32_vplzcntd_128_mask ((__v4si) __A, + (__v4si) + _mm_avx512_setzero_si128 (), + (__mmask8) -1); +} +extern __inline __m128i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_lzcnt_epi32 (__m128i __W, __mmask8 __U, __m128i __A) +{ + return (__m128i) __builtin_ia32_vplzcntd_128_mask ((__v4si) __A, + (__v4si) __W, + (__mmask8) __U); +} +extern __inline __m128i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_lzcnt_epi32 (__mmask8 __U, __m128i __A) +{ + return (__m128i) __builtin_ia32_vplzcntd_128_mask ((__v4si) __A, + (__v4si) + _mm_avx512_setzero_si128 (), + (__mmask8) __U); +} +extern __inline __m128i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_lzcnt_epi64 (__m128i __A) +{ + return (__m128i) __builtin_ia32_vplzcntq_128_mask ((__v2di) __A, + (__v2di) + _mm_avx512_setzero_si128 (), + (__mmask8) -1); +} +extern __inline __m128i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_lzcnt_epi64 (__m128i __W, __mmask8 __U, __m128i __A) +{ + return (__m128i) __builtin_ia32_vplzcntq_128_mask ((__v2di) __A, + (__v2di) __W, + (__mmask8) __U); +} +extern __inline __m128i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_lzcnt_epi64 (__mmask8 __U, __m128i __A) +{ + return (__m128i) __builtin_ia32_vplzcntq_128_mask ((__v2di) __A, + (__v2di) + _mm_avx512_setzero_si128 (), + (__mmask8) __U); +} +extern __inline __m128i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_conflict_epi64 (__m128i __A) +{ + return (__m128i) __builtin_ia32_vpconflictdi_128_mask ((__v2di) __A, + (__v2di) + _mm_avx512_setzero_si128 (), + (__mmask8) -1); +} +extern __inline __m128i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_conflict_epi64 (__m128i __W, __mmask8 __U, __m128i __A) +{ + return (__m128i) __builtin_ia32_vpconflictdi_128_mask ((__v2di) __A, + (__v2di) __W, + (__mmask8) + __U); +} +extern __inline __m128i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_conflict_epi64 (__mmask8 __U, __m128i __A) +{ + return (__m128i) __builtin_ia32_vpconflictdi_128_mask ((__v2di) __A, + (__v2di) + _mm_avx512_setzero_si128 (), + (__mmask8) + __U); +} +extern __inline __m128i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_conflict_epi32 (__m128i __A) +{ + return (__m128i) __builtin_ia32_vpconflictsi_128_mask ((__v4si) __A, + (__v4si) + _mm_avx512_setzero_si128 (), + (__mmask8) -1); +} +extern __inline __m128i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mask_conflict_epi32 (__m128i __W, __mmask8 __U, __m128i __A) +{ + return (__m128i) __builtin_ia32_vpconflictsi_128_mask ((__v4si) __A, + (__v4si) __W, + (__mmask8) + __U); +} +extern __inline __m128i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_maskz_conflict_epi32 (__mmask8 __U, __m128i __A) +{ + return (__m128i) __builtin_ia32_vpconflictsi_128_mask ((__v4si) __A, + (__v4si) + _mm_avx512_setzero_si128 (), + (__mmask8) + __U); +} +#ifdef __DISABLE_AVX512VLCD__ +#pragma GCC pop_options +#endif #endif #endif diff --git a/third_party/intel/avx512vnniintrin.internal.h b/third_party/intel/avx512vnniintrin.internal.h index a9c41879b..cbc7da1cc 100644 --- a/third_party/intel/avx512vnniintrin.internal.h +++ b/third_party/intel/avx512vnniintrin.internal.h @@ -4,9 +4,9 @@ #endif #ifndef __AVX512VNNIINTRIN_H_INCLUDED #define __AVX512VNNIINTRIN_H_INCLUDED -#if !defined(__AVX512VNNI__) +#if !defined(__AVX512VNNI__) || !defined (__EVEX512__) #pragma GCC push_options -#pragma GCC target("avx512vnni") +#pragma GCC target("avx512vnni,evex512") #define __DISABLE_AVX512VNNI__ #endif extern __inline __m512i diff --git a/third_party/intel/avx512vnnivlintrin.internal.h b/third_party/intel/avx512vnnivlintrin.internal.h index f403563b8..411ebcc57 100644 --- a/third_party/intel/avx512vnnivlintrin.internal.h +++ b/third_party/intel/avx512vnnivlintrin.internal.h @@ -4,9 +4,9 @@ #endif #ifndef _AVX512VNNIVLINTRIN_H_INCLUDED #define _AVX512VNNIVLINTRIN_H_INCLUDED -#if !defined(__AVX512VL__) || !defined(__AVX512VNNI__) +#if !defined(__AVX512VL__) || !defined(__AVX512VNNI__) || defined (__EVEX512__) #pragma GCC push_options -#pragma GCC target("avx512vnni,avx512vl") +#pragma GCC target("avx512vnni,avx512vl,no-evex512") #define __DISABLE_AVX512VNNIVL__ #endif #define _mm256_dpbusd_epi32(A, B, C) ((__m256i) __builtin_ia32_vpdpbusd_v8si ((__v8si) (A), (__v8si) (B), (__v8si) (C))) diff --git a/third_party/intel/avx512vp2intersectintrin.internal.h b/third_party/intel/avx512vp2intersectintrin.internal.h index 189aa37b2..09ada18c5 100644 --- a/third_party/intel/avx512vp2intersectintrin.internal.h +++ b/third_party/intel/avx512vp2intersectintrin.internal.h @@ -4,9 +4,9 @@ #endif #ifndef _AVX512VP2INTERSECTINTRIN_H_INCLUDED #define _AVX512VP2INTERSECTINTRIN_H_INCLUDED -#if !defined(__AVX512VP2INTERSECT__) +#if !defined(__AVX512VP2INTERSECT__) || !defined (__EVEX512__) #pragma GCC push_options -#pragma GCC target("avx512vp2intersect") +#pragma GCC target("avx512vp2intersect,evex512") #define __DISABLE_AVX512VP2INTERSECT__ #endif extern __inline void diff --git a/third_party/intel/avx512vp2intersectvlintrin.internal.h b/third_party/intel/avx512vp2intersectvlintrin.internal.h index e38624ebf..dad5b821b 100644 --- a/third_party/intel/avx512vp2intersectvlintrin.internal.h +++ b/third_party/intel/avx512vp2intersectvlintrin.internal.h @@ -4,9 +4,9 @@ #endif #ifndef _AVX512VP2INTERSECTVLINTRIN_H_INCLUDED #define _AVX512VP2INTERSECTVLINTRIN_H_INCLUDED -#if !defined(__AVX512VP2INTERSECT__) || !defined(__AVX512VL__) +#if !defined(__AVX512VP2INTERSECT__) || !defined(__AVX512VL__) || defined (__EVEX512__) #pragma GCC push_options -#pragma GCC target("avx512vp2intersect,avx512vl") +#pragma GCC target("avx512vp2intersect,avx512vl,no-evex512") #define __DISABLE_AVX512VP2INTERSECTVL__ #endif extern __inline void diff --git a/third_party/intel/avx512vpopcntdqintrin.internal.h b/third_party/intel/avx512vpopcntdqintrin.internal.h index fe4d5c834..93ff9cce8 100644 --- a/third_party/intel/avx512vpopcntdqintrin.internal.h +++ b/third_party/intel/avx512vpopcntdqintrin.internal.h @@ -4,9 +4,9 @@ #endif #ifndef _AVX512VPOPCNTDQINTRIN_H_INCLUDED #define _AVX512VPOPCNTDQINTRIN_H_INCLUDED -#ifndef __AVX512VPOPCNTDQ__ +#if !defined (__AVX512VPOPCNTDQ__) || !defined (__EVEX512__) #pragma GCC push_options -#pragma GCC target("avx512vpopcntdq") +#pragma GCC target("avx512vpopcntdq,evex512") #define __DISABLE_AVX512VPOPCNTDQ__ #endif extern __inline __m512i diff --git a/third_party/intel/avx512vpopcntdqvlintrin.internal.h b/third_party/intel/avx512vpopcntdqvlintrin.internal.h index a86d84ce3..c2ff8e24a 100644 --- a/third_party/intel/avx512vpopcntdqvlintrin.internal.h +++ b/third_party/intel/avx512vpopcntdqvlintrin.internal.h @@ -4,9 +4,9 @@ #endif #ifndef _AVX512VPOPCNTDQVLINTRIN_H_INCLUDED #define _AVX512VPOPCNTDQVLINTRIN_H_INCLUDED -#if !defined(__AVX512VPOPCNTDQ__) || !defined(__AVX512VL__) +#if !defined(__AVX512VPOPCNTDQ__) || !defined(__AVX512VL__) || defined (__EVEX512__) #pragma GCC push_options -#pragma GCC target("avx512vpopcntdq,avx512vl") +#pragma GCC target("avx512vpopcntdq,avx512vl,no-evex512") #define __DISABLE_AVX512VPOPCNTDQVL__ #endif extern __inline __m128i @@ -29,7 +29,7 @@ _mm_maskz_popcnt_epi32 (__mmask16 __U, __m128i __A) { return (__m128i) __builtin_ia32_vpopcountd_v4si_mask ((__v4si) __A, (__v4si) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask16) __U); } extern __inline __m256i @@ -52,7 +52,7 @@ _mm256_maskz_popcnt_epi32 (__mmask16 __U, __m256i __A) { return (__m256i) __builtin_ia32_vpopcountd_v8si_mask ((__v8si) __A, (__v8si) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask16) __U); } extern __inline __m128i @@ -75,7 +75,7 @@ _mm_maskz_popcnt_epi64 (__mmask8 __U, __m128i __A) { return (__m128i) __builtin_ia32_vpopcountq_v2di_mask ((__v2di) __A, (__v2di) - _mm_setzero_si128 (), + _mm_avx512_setzero_si128 (), (__mmask8) __U); } extern __inline __m256i @@ -98,7 +98,7 @@ _mm256_maskz_popcnt_epi64 (__mmask8 __U, __m256i __A) { return (__m256i) __builtin_ia32_vpopcountq_v4di_mask ((__v4di) __A, (__v4di) - _mm256_setzero_si256 (), + _mm256_avx512_setzero_si256 (), (__mmask8) __U); } #ifdef __DISABLE_AVX512VPOPCNTDQVL__ diff --git a/third_party/intel/avxifmaintrin.internal.h b/third_party/intel/avxifmaintrin.internal.h new file mode 100644 index 000000000..283bd9800 --- /dev/null +++ b/third_party/intel/avxifmaintrin.internal.h @@ -0,0 +1,49 @@ +#if defined(__x86_64__) && !(__ASSEMBLER__ + __LINKER__ + 0) +#ifndef _IMMINTRIN_H_INCLUDED +#error "Never use directly; include instead." +#endif +#ifndef _AVXIFMAINTRIN_H_INCLUDED +#define _AVXIFMAINTRIN_H_INCLUDED +#ifndef __AVXIFMA__ +#pragma GCC push_options +#pragma GCC target("avxifma") +#define __DISABLE_AVXIFMA__ +#endif +extern __inline __m128i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_madd52lo_avx_epu64 (__m128i __X, __m128i __Y, __m128i __Z) +{ + return (__m128i) __builtin_ia32_vpmadd52luq128 ((__v2di) __X, + (__v2di) __Y, + (__v2di) __Z); +} +extern __inline __m128i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_madd52hi_avx_epu64 (__m128i __X, __m128i __Y, __m128i __Z) +{ + return (__m128i) __builtin_ia32_vpmadd52huq128 ((__v2di) __X, + (__v2di) __Y, + (__v2di) __Z); +} +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_madd52lo_avx_epu64 (__m256i __X, __m256i __Y, __m256i __Z) +{ + return (__m256i) __builtin_ia32_vpmadd52luq256 ((__v4di) __X, + (__v4di) __Y, + (__v4di) __Z); +} +extern __inline __m256i +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_madd52hi_avx_epu64 (__m256i __X, __m256i __Y, __m256i __Z) +{ + return (__m256i) __builtin_ia32_vpmadd52huq256 ((__v4di) __X, + (__v4di) __Y, + (__v4di) __Z); +} +#ifdef __DISABLE_AVXIFMA__ +#undef __DISABLE_AVXIFMA__ +#pragma GCC pop_options +#endif +#endif +#endif diff --git a/third_party/intel/avxintrin.internal.h b/third_party/intel/avxintrin.internal.h index f2c84ef94..79b38ff59 100644 --- a/third_party/intel/avxintrin.internal.h +++ b/third_party/intel/avxintrin.internal.h @@ -872,19 +872,28 @@ _mm256_movemask_ps (__m256 __A) extern __inline __m256d __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm256_undefined_pd (void) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Winit-self" __m256d __Y = __Y; +#pragma GCC diagnostic pop return __Y; } extern __inline __m256 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm256_undefined_ps (void) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Winit-self" __m256 __Y = __Y; +#pragma GCC diagnostic pop return __Y; } extern __inline __m256i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm256_undefined_si256 (void) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Winit-self" __m256i __Y = __Y; +#pragma GCC diagnostic pop return __Y; } extern __inline __m256d __attribute__((__gnu_inline__, __always_inline__, __artificial__)) diff --git a/third_party/intel/avxneconvertintrin.internal.h b/third_party/intel/avxneconvertintrin.internal.h new file mode 100644 index 000000000..30e99da75 --- /dev/null +++ b/third_party/intel/avxneconvertintrin.internal.h @@ -0,0 +1,101 @@ +#if defined(__x86_64__) && !(__ASSEMBLER__ + __LINKER__ + 0) +#ifndef _IMMINTRIN_H_INCLUDED +#error "Never use directly; include instead." +#endif +#ifndef _AVXNECONVERTINTRIN_H_INCLUDED +#define _AVXNECONVERTINTRIN_H_INCLUDED +#ifndef __AVXNECONVERT__ +#pragma GCC push_options +#pragma GCC target ("avxneconvert") +#define __DISABLE_AVXNECONVERT__ +#endif +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_bcstnebf16_ps (const void *__P) +{ + return (__m128) __builtin_ia32_vbcstnebf162ps128 ((const __bf16 *) __P); +} +extern __inline __m256 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_bcstnebf16_ps (const void *__P) +{ + return (__m256) __builtin_ia32_vbcstnebf162ps256 ((const __bf16 *) __P); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_bcstnesh_ps (const void *__P) +{ + return (__m128) __builtin_ia32_vbcstnesh2ps128 ((const _Float16 *) __P); +} +extern __inline __m256 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_bcstnesh_ps (const void *__P) +{ + return (__m256) __builtin_ia32_vbcstnesh2ps256 ((const _Float16 *) __P); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtneebf16_ps (const __m128bh *__A) +{ + return (__m128) __builtin_ia32_vcvtneebf162ps128 ((const __v8bf *) __A); +} +extern __inline __m256 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_cvtneebf16_ps (const __m256bh *__A) +{ + return (__m256) __builtin_ia32_vcvtneebf162ps256 ((const __v16bf *) __A); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtneeph_ps (const __m128h *__A) +{ + return (__m128) __builtin_ia32_vcvtneeph2ps128 ((const __v8hf *) __A); +} +extern __inline __m256 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_cvtneeph_ps (const __m256h *__A) +{ + return (__m256) __builtin_ia32_vcvtneeph2ps256 ((const __v16hf *) __A); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtneobf16_ps (const __m128bh *__A) +{ + return (__m128) __builtin_ia32_vcvtneobf162ps128 ((const __v8bf *) __A); +} +extern __inline __m256 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_cvtneobf16_ps (const __m256bh *__A) +{ + return (__m256) __builtin_ia32_vcvtneobf162ps256 ((const __v16bf *) __A); +} +extern __inline __m128 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtneoph_ps (const __m128h *__A) +{ + return (__m128) __builtin_ia32_vcvtneoph2ps128 ((const __v8hf *) __A); +} +extern __inline __m256 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_cvtneoph_ps (const __m256h *__A) +{ + return (__m256) __builtin_ia32_vcvtneoph2ps256 ((const __v16hf *) __A); +} +extern __inline __m128bh +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm_cvtneps_avx_pbh (__m128 __A) +{ + return (__m128bh) __builtin_ia32_cvtneps2bf16_v4sf (__A); +} +extern __inline __m128bh +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_cvtneps_avx_pbh (__m256 __A) +{ + return (__m128bh) __builtin_ia32_cvtneps2bf16_v8sf (__A); +} +#ifdef __DISABLE_AVXNECONVERT__ +#undef __DISABLE_AVXNECONVERT__ +#pragma GCC pop_options +#endif +#endif +#endif diff --git a/third_party/intel/avxvnniint16intrin.internal.h b/third_party/intel/avxvnniint16intrin.internal.h new file mode 100644 index 000000000..feec58128 --- /dev/null +++ b/third_party/intel/avxvnniint16intrin.internal.h @@ -0,0 +1,101 @@ +#if defined(__x86_64__) && !(__ASSEMBLER__ + __LINKER__ + 0) +#if !defined _IMMINTRIN_H_INCLUDED +#error "Never use directly; include instead." +#endif +#ifndef _AVXVNNIINT16INTRIN_H_INCLUDED +#define _AVXVNNIINT16INTRIN_H_INCLUDED +#if !defined(__AVXVNNIINT16__) +#pragma GCC push_options +#pragma GCC target("avxvnniint16") +#define __DISABLE_AVXVNNIINT16__ +#endif +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_dpwsud_avx_epi32 (__m128i __W, __m128i __A, __m128i __B) +{ + return (__m128i) + __builtin_ia32_vpdpwsud128 ((__v4si) __W, (__v4si) __A, (__v4si) __B); +} +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_dpwsuds_avx_epi32 (__m128i __W, __m128i __A, __m128i __B) +{ + return (__m128i) + __builtin_ia32_vpdpwsuds128 ((__v4si) __W, (__v4si) __A, (__v4si) __B); +} +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_dpwusd_avx_epi32 (__m128i __W, __m128i __A, __m128i __B) +{ + return (__m128i) + __builtin_ia32_vpdpwusd128 ((__v4si) __W, (__v4si) __A, (__v4si) __B); +} +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_dpwusds_avx_epi32 (__m128i __W, __m128i __A, __m128i __B) +{ + return (__m128i) + __builtin_ia32_vpdpwusds128 ((__v4si) __W, (__v4si) __A, (__v4si) __B); +} +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_dpwuud_avx_epi32 (__m128i __W, __m128i __A, __m128i __B) +{ + return (__m128i) + __builtin_ia32_vpdpwuud128 ((__v4si) __W, (__v4si) __A, (__v4si) __B); +} +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_dpwuuds_avx_epi32 (__m128i __W, __m128i __A, __m128i __B) +{ + return (__m128i) + __builtin_ia32_vpdpwuuds128 ((__v4si) __W, (__v4si) __A, (__v4si) __B); +} +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_dpwsud_avx_epi32 (__m256i __W, __m256i __A, __m256i __B) +{ + return (__m256i) + __builtin_ia32_vpdpwsud256 ((__v8si) __W, (__v8si) __A, (__v8si) __B); +} +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_dpwsuds_avx_epi32 (__m256i __W, __m256i __A, __m256i __B) +{ + return (__m256i) + __builtin_ia32_vpdpwsuds256 ((__v8si) __W, (__v8si) __A, (__v8si) __B); +} +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_dpwusd_avx_epi32 (__m256i __W, __m256i __A, __m256i __B) +{ + return (__m256i) + __builtin_ia32_vpdpwusd256 ((__v8si) __W, (__v8si) __A, (__v8si) __B); +} +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_dpwusds_avx_epi32 (__m256i __W, __m256i __A, __m256i __B) +{ + return (__m256i) + __builtin_ia32_vpdpwusds256 ((__v8si) __W, (__v8si) __A, (__v8si) __B); +} +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_dpwuud_avx_epi32 (__m256i __W, __m256i __A, __m256i __B) +{ + return (__m256i) + __builtin_ia32_vpdpwuud256 ((__v8si) __W, (__v8si) __A, (__v8si) __B); +} +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_dpwuuds_avx_epi32 (__m256i __W, __m256i __A, __m256i __B) +{ + return (__m256i) + __builtin_ia32_vpdpwuuds256 ((__v8si) __W, (__v8si) __A, (__v8si) __B); +} +#ifdef __DISABLE_AVXVNNIINT16__ +#undef __DISABLE_AVXVNNIINT16__ +#pragma GCC pop_options +#endif +#endif +#endif diff --git a/third_party/intel/avxvnniint8intrin.internal.h b/third_party/intel/avxvnniint8intrin.internal.h new file mode 100644 index 000000000..7e933ed06 --- /dev/null +++ b/third_party/intel/avxvnniint8intrin.internal.h @@ -0,0 +1,101 @@ +#if defined(__x86_64__) && !(__ASSEMBLER__ + __LINKER__ + 0) +#if !defined _IMMINTRIN_H_INCLUDED +#error "Never use directly; include instead." +#endif +#ifndef _AVXVNNIINT8INTRIN_H_INCLUDED +#define _AVXVNNIINT8INTRIN_H_INCLUDED +#if !defined(__AVXVNNIINT8__) +#pragma GCC push_options +#pragma GCC target("avxvnniint8") +#define __DISABLE_AVXVNNIINT8__ +#endif +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_dpbssd_epi32 (__m128i __W, __m128i __A, __m128i __B) +{ + return (__m128i) + __builtin_ia32_vpdpbssd128 ((__v4si) __W, (__v4si) __A, (__v4si) __B); +} +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_dpbssds_epi32 (__m128i __W, __m128i __A, __m128i __B) +{ + return (__m128i) + __builtin_ia32_vpdpbssds128 ((__v4si) __W, (__v4si) __A, (__v4si) __B); +} +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_dpbsud_epi32 (__m128i __W, __m128i __A, __m128i __B) +{ + return (__m128i) + __builtin_ia32_vpdpbsud128 ((__v4si) __W, (__v4si) __A, (__v4si) __B); +} +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_dpbsuds_epi32 (__m128i __W, __m128i __A, __m128i __B) +{ + return (__m128i) + __builtin_ia32_vpdpbsuds128 ((__v4si) __W, (__v4si) __A, (__v4si) __B); +} +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_dpbuud_epi32 (__m128i __W, __m128i __A, __m128i __B) +{ + return (__m128i) + __builtin_ia32_vpdpbuud128 ((__v4si) __W, (__v4si) __A, (__v4si) __B); +} +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_dpbuuds_epi32 (__m128i __W, __m128i __A, __m128i __B) +{ + return (__m128i) + __builtin_ia32_vpdpbuuds128 ((__v4si) __W, (__v4si) __A, (__v4si) __B); +} +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_dpbssd_epi32 (__m256i __W, __m256i __A, __m256i __B) +{ + return (__m256i) + __builtin_ia32_vpdpbssd256 ((__v8si) __W, (__v8si) __A, (__v8si) __B); +} +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_dpbssds_epi32 (__m256i __W, __m256i __A, __m256i __B) +{ + return (__m256i) + __builtin_ia32_vpdpbssds256 ((__v8si) __W, (__v8si) __A, (__v8si) __B); +} +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_dpbsud_epi32 (__m256i __W, __m256i __A, __m256i __B) +{ + return (__m256i) + __builtin_ia32_vpdpbsud256 ((__v8si) __W, (__v8si) __A, (__v8si) __B); +} +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_dpbsuds_epi32 (__m256i __W, __m256i __A, __m256i __B) +{ + return (__m256i) + __builtin_ia32_vpdpbsuds256 ((__v8si) __W, (__v8si) __A, (__v8si) __B); +} +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_dpbuud_epi32 (__m256i __W, __m256i __A, __m256i __B) +{ + return (__m256i) + __builtin_ia32_vpdpbuud256 ((__v8si) __W, (__v8si) __A, (__v8si) __B); +} +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_dpbuuds_epi32 (__m256i __W, __m256i __A, __m256i __B) +{ + return (__m256i) + __builtin_ia32_vpdpbuuds256 ((__v8si) __W, (__v8si) __A, (__v8si) __B); +} +#ifdef __DISABLE_AVXVNNIINT8__ +#undef __DISABLE_AVXVNNIINT8__ +#pragma GCC pop_options +#endif +#endif +#endif diff --git a/third_party/intel/bmmintrin.internal.h b/third_party/intel/bmmintrin.internal.h new file mode 100644 index 000000000..5394598c7 --- /dev/null +++ b/third_party/intel/bmmintrin.internal.h @@ -0,0 +1,6 @@ +#if defined(__x86_64__) && !(__ASSEMBLER__ + __LINKER__ + 0) +#ifndef _BMMINTRIN_H_INCLUDED +#define _BMMINTRIN_H_INCLUDED +# error "SSE5 instruction set removed from compiler" +#endif +#endif diff --git a/third_party/intel/cmpccxaddintrin.internal.h b/third_party/intel/cmpccxaddintrin.internal.h new file mode 100644 index 000000000..6b3924a2c --- /dev/null +++ b/third_party/intel/cmpccxaddintrin.internal.h @@ -0,0 +1,55 @@ +#if defined(__x86_64__) && !(__ASSEMBLER__ + __LINKER__ + 0) +#ifndef _X86GPRINTRIN_H_INCLUDED +#error "Never use directly; include instead." +#endif +#ifndef _CMPCCXADDINTRIN_H_INCLUDED +#define _CMPCCXADDINTRIN_H_INCLUDED +#ifdef __x86_64__ +#ifndef __CMPCCXADD__ +#pragma GCC push_options +#pragma GCC target("cmpccxadd") +#define __DISABLE_CMPCCXADD__ +#endif +typedef enum { + _CMPCCX_O, + _CMPCCX_NO, + _CMPCCX_B, + _CMPCCX_NB, + _CMPCCX_Z, + _CMPCCX_NZ, + _CMPCCX_BE, + _CMPCCX_NBE, + _CMPCCX_S, + _CMPCCX_NS, + _CMPCCX_P, + _CMPCCX_NP, + _CMPCCX_L, + _CMPCCX_NL, + _CMPCCX_LE, + _CMPCCX_NLE, +} _CMPCCX_ENUM; +#ifdef __OPTIMIZE__ +extern __inline int +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_cmpccxadd_epi32 (int *__A, int __B, int __C, const _CMPCCX_ENUM __D) +{ + return __builtin_ia32_cmpccxadd (__A, __B, __C, __D); +} +extern __inline long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_cmpccxadd_epi64 (long long *__A, long long __B, long long __C, + const _CMPCCX_ENUM __D) +{ + return __builtin_ia32_cmpccxadd64 (__A, __B, __C, __D); +} +#else +#define _cmpccxadd_epi32(A,B,C,D) __builtin_ia32_cmpccxadd ((int *) (A), (int) (B), (int) (C), (_CMPCCX_ENUM) (D)) +#define _cmpccxadd_epi64(A,B,C,D) __builtin_ia32_cmpccxadd64 ((long long *) (A), (long long) (B), (long long) (C), (_CMPCCX_ENUM) (D)) +#endif +#ifdef __DISABLE_CMPCCXADD__ +#undef __DISABLE_CMPCCXADD__ +#pragma GCC pop_options +#endif +#endif +#endif +#endif diff --git a/third_party/intel/cpuid.internal.h b/third_party/intel/cpuid.internal.h index 3f082193c..dd9b2cc3d 100644 --- a/third_party/intel/cpuid.internal.h +++ b/third_party/intel/cpuid.internal.h @@ -1,9 +1,6 @@ #if defined(__x86_64__) && !(__ASSEMBLER__ + __LINKER__ + 0) #ifndef _CPUID_H_INCLUDED #define _CPUID_H_INCLUDED -#define bit_AVXVNNI (1 << 4) -#define bit_AVX512BF16 (1 << 5) -#define bit_HRESET (1 << 22) #define bit_SSE3 (1 << 0) #define bit_PCLMUL (1 << 1) #define bit_LZCNT (1 << 5) @@ -70,34 +67,54 @@ #define bit_SHSTK (1 << 7) #define bit_GFNI (1 << 8) #define bit_VAES (1 << 9) -#define bit_AVX512VNNI (1 << 11) #define bit_VPCLMULQDQ (1 << 10) +#define bit_AVX512VNNI (1 << 11) #define bit_AVX512BITALG (1 << 12) #define bit_AVX512VPOPCNTDQ (1 << 14) #define bit_RDPID (1 << 22) +#define bit_KL (1 << 23) +#define bit_CLDEMOTE (1 << 25) #define bit_MOVDIRI (1 << 27) #define bit_MOVDIR64B (1 << 28) #define bit_ENQCMD (1 << 29) -#define bit_CLDEMOTE (1 << 25) -#define bit_KL (1 << 23) #define bit_AVX5124VNNIW (1 << 2) #define bit_AVX5124FMAPS (1 << 3) -#define bit_AVX512VP2INTERSECT (1 << 8) -#define bit_AVX512FP16 (1 << 23) -#define bit_IBT (1 << 20) #define bit_UINTR (1 << 5) -#define bit_PCONFIG (1 << 18) +#define bit_AVX512VP2INTERSECT (1 << 8) #define bit_SERIALIZE (1 << 14) #define bit_TSXLDTRK (1 << 16) +#define bit_PCONFIG (1 << 18) +#define bit_IBT (1 << 20) #define bit_AMX_BF16 (1 << 22) +#define bit_AVX512FP16 (1 << 23) #define bit_AMX_TILE (1 << 24) #define bit_AMX_INT8 (1 << 25) +#define bit_SHA512 (1 << 0) +#define bit_SM3 (1 << 1) +#define bit_SM4 (1 << 2) +#define bit_RAOINT (1 << 3) +#define bit_AVXVNNI (1 << 4) +#define bit_AVX512BF16 (1 << 5) +#define bit_CMPCCXADD (1 << 7) +#define bit_AMX_COMPLEX (1 << 8) +#define bit_AMX_FP16 (1 << 21) +#define bit_HRESET (1 << 22) +#define bit_AVXIFMA (1 << 23) +#define bit_AVXVNNIINT8 (1 << 4) +#define bit_AVXNECONVERT (1 << 5) +#define bit_AVXVNNIINT16 (1 << 10) +#define bit_PREFETCHI (1 << 14) +#define bit_USER_MSR (1 << 15) +#define bit_AVX10 (1 << 19) +#define bit_APX_F (1 << 21) #define bit_XSAVEOPT (1 << 0) #define bit_XSAVEC (1 << 1) #define bit_XSAVES (1 << 3) #define bit_PTWRITE (1 << 4) #define bit_AESKLE ( 1<<0 ) #define bit_WIDEKL ( 1<<2 ) +#define bit_AVX10_256 (1 << 17) +#define bit_AVX10_512 (1 << 18) #define signature_AMD_ebx 0x68747541 #define signature_AMD_ecx 0x444d4163 #define signature_AMD_edx 0x69746e65 @@ -137,6 +154,9 @@ #define signature_VORTEX_ebx 0x74726f56 #define signature_VORTEX_ecx 0x436f5320 #define signature_VORTEX_edx 0x36387865 +#define signature_SHANGHAI_ebx 0x68532020 +#define signature_SHANGHAI_ecx 0x20206961 +#define signature_SHANGHAI_edx 0x68676e61 #ifndef __x86_64__ #define __cpuid(level, a, b, c, d) do { if (__builtin_constant_p (level) && (level) != 1) __asm__ __volatile__ ("cpuid\n\t" : "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "0" (level)); else __asm__ __volatile__ ("cpuid\n\t" : "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "0" (level), "1" (0), "2" (0)); } while (0) #else @@ -175,7 +195,7 @@ __get_cpuid_max (unsigned int __ext, unsigned int *__sig) : "=&r" (__eax), "=&r" (__ebx) : "i" (0x00200000)); #endif - if (!((__eax ^ __ebx) & 0x00200000)) + if (__builtin_expect (!((__eax ^ __ebx) & 0x00200000), 0)) return 0; #endif __cpuid (__ext, __eax, __ebx, __ecx, __edx); @@ -202,7 +222,7 @@ __get_cpuid_count (unsigned int __leaf, unsigned int __subleaf, { unsigned int __ext = __leaf & 0x80000000; unsigned int __maxlevel = __get_cpuid_max (__ext, 0); - if (__maxlevel == 0 || __maxlevel < __leaf) + if (__builtin_expect (__maxlevel == 0, 0) || __maxlevel < __leaf) return 0; __cpuid_count (__leaf, __subleaf, *__eax, *__ebx, *__ecx, *__edx); return 1; diff --git a/third_party/intel/emmintrin.internal.h b/third_party/intel/emmintrin.internal.h index c0c3bf59d..6f781d3be 100644 --- a/third_party/intel/emmintrin.internal.h +++ b/third_party/intel/emmintrin.internal.h @@ -50,7 +50,10 @@ _mm_setr_pd (double __W, double __X) extern __inline __m128d __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_undefined_pd (void) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Winit-self" __m128d __Y = __Y; +#pragma GCC diagnostic pop return __Y; } extern __inline __m128d __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -605,7 +608,10 @@ _mm_move_epi64 (__m128i __A) extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_undefined_si128 (void) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Winit-self" __m128i __Y = __Y; +#pragma GCC diagnostic pop return __Y; } extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) diff --git a/third_party/intel/gfniintrin.internal.h b/third_party/intel/gfniintrin.internal.h index 6dfe26778..b56cfeda9 100644 --- a/third_party/intel/gfniintrin.internal.h +++ b/third_party/intel/gfniintrin.internal.h @@ -94,7 +94,7 @@ __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_maskz_gf2p8mul_epi8 (__mmask16 __A, __m128i __B, __m128i __C) { return (__m128i) __builtin_ia32_vgf2p8mulb_v16qi_mask ((__v16qi) __B, - (__v16qi) __C, (__v16qi) _mm_setzero_si128 (), __A); + (__v16qi) __C, (__v16qi) _mm_avx512_setzero_si128 (), __A); } #ifdef __OPTIMIZE__ extern __inline __m128i @@ -115,7 +115,7 @@ _mm_maskz_gf2p8affineinv_epi64_epi8 (__mmask16 __A, __m128i __B, __m128i __C, { return (__m128i) __builtin_ia32_vgf2p8affineinvqb_v16qi_mask ((__v16qi) __B, (__v16qi) __C, __D, - (__v16qi) _mm_setzero_si128 (), + (__v16qi) _mm_avx512_setzero_si128 (), __A); } extern __inline __m128i @@ -132,13 +132,13 @@ _mm_maskz_gf2p8affine_epi64_epi8 (__mmask16 __A, __m128i __B, __m128i __C, const int __D) { return (__m128i) __builtin_ia32_vgf2p8affineqb_v16qi_mask ((__v16qi) __B, - (__v16qi) __C, __D, (__v16qi) _mm_setzero_si128 (), __A); + (__v16qi) __C, __D, (__v16qi) _mm_avx512_setzero_si128 (), __A); } #else #define _mm_mask_gf2p8affineinv_epi64_epi8(A, B, C, D, E) ((__m128i) __builtin_ia32_vgf2p8affineinvqb_v16qi_mask( (__v16qi)(__m128i)(C), (__v16qi)(__m128i)(D), (int)(E), (__v16qi)(__m128i)(A), (__mmask16)(B))) -#define _mm_maskz_gf2p8affineinv_epi64_epi8(A, B, C, D) ((__m128i) __builtin_ia32_vgf2p8affineinvqb_v16qi_mask( (__v16qi)(__m128i)(B), (__v16qi)(__m128i)(C), (int)(D), (__v16qi)(__m128i) _mm_setzero_si128 (), (__mmask16)(A))) +#define _mm_maskz_gf2p8affineinv_epi64_epi8(A, B, C, D) ((__m128i) __builtin_ia32_vgf2p8affineinvqb_v16qi_mask( (__v16qi)(__m128i)(B), (__v16qi)(__m128i)(C), (int)(D), (__v16qi)(__m128i) _mm_avx512_setzero_si128 (), (__mmask16)(A))) #define _mm_mask_gf2p8affine_epi64_epi8(A, B, C, D, E) ((__m128i) __builtin_ia32_vgf2p8affineqb_v16qi_mask((__v16qi)(__m128i)(C), (__v16qi)(__m128i)(D), (int)(E), (__v16qi)(__m128i)(A), (__mmask16)(B))) -#define _mm_maskz_gf2p8affine_epi64_epi8(A, B, C, D) ((__m128i) __builtin_ia32_vgf2p8affineqb_v16qi_mask((__v16qi)(__m128i)(B), (__v16qi)(__m128i)(C), (int)(D), (__v16qi)(__m128i) _mm_setzero_si128 (), (__mmask16)(A))) +#define _mm_maskz_gf2p8affine_epi64_epi8(A, B, C, D) ((__m128i) __builtin_ia32_vgf2p8affineqb_v16qi_mask((__v16qi)(__m128i)(B), (__v16qi)(__m128i)(C), (int)(D), (__v16qi)(__m128i) _mm_avx512_setzero_si128 (), (__mmask16)(A))) #endif #ifdef __DISABLE_GFNIAVX512VL__ #undef __DISABLE_GFNIAVX512VL__ @@ -163,7 +163,7 @@ __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm256_maskz_gf2p8mul_epi8 (__mmask32 __A, __m256i __B, __m256i __C) { return (__m256i) __builtin_ia32_vgf2p8mulb_v32qi_mask ((__v32qi) __B, - (__v32qi) __C, (__v32qi) _mm256_setzero_si256 (), __A); + (__v32qi) __C, (__v32qi) _mm256_avx512_setzero_si256 (), __A); } #ifdef __OPTIMIZE__ extern __inline __m256i @@ -184,7 +184,7 @@ _mm256_maskz_gf2p8affineinv_epi64_epi8 (__mmask32 __A, __m256i __B, { return (__m256i) __builtin_ia32_vgf2p8affineinvqb_v32qi_mask ((__v32qi) __B, (__v32qi) __C, __D, - (__v32qi) _mm256_setzero_si256 (), __A); + (__v32qi) _mm256_avx512_setzero_si256 (), __A); } extern __inline __m256i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -203,21 +203,56 @@ _mm256_maskz_gf2p8affine_epi64_epi8 (__mmask32 __A, __m256i __B, __m256i __C, const int __D) { return (__m256i) __builtin_ia32_vgf2p8affineqb_v32qi_mask ((__v32qi) __B, - (__v32qi) __C, __D, (__v32qi)_mm256_setzero_si256 (), __A); + (__v32qi) __C, __D, (__v32qi)_mm256_avx512_setzero_si256 (), __A); } #else #define _mm256_mask_gf2p8affineinv_epi64_epi8(A, B, C, D, E) ((__m256i) __builtin_ia32_vgf2p8affineinvqb_v32qi_mask( (__v32qi)(__m256i)(C), (__v32qi)(__m256i)(D), (int)(E), (__v32qi)(__m256i)(A), (__mmask32)(B))) -#define _mm256_maskz_gf2p8affineinv_epi64_epi8(A, B, C, D) ((__m256i) __builtin_ia32_vgf2p8affineinvqb_v32qi_mask( (__v32qi)(__m256i)(B), (__v32qi)(__m256i)(C), (int)(D), (__v32qi)(__m256i) _mm256_setzero_si256 (), (__mmask32)(A))) +#define _mm256_maskz_gf2p8affineinv_epi64_epi8(A, B, C, D) ((__m256i) __builtin_ia32_vgf2p8affineinvqb_v32qi_mask( (__v32qi)(__m256i)(B), (__v32qi)(__m256i)(C), (int)(D), (__v32qi)(__m256i) _mm256_avx512_setzero_si256 (), (__mmask32)(A))) #define _mm256_mask_gf2p8affine_epi64_epi8(A, B, C, D, E) ((__m256i) __builtin_ia32_vgf2p8affineqb_v32qi_mask((__v32qi)(__m256i)(C), (__v32qi)(__m256i)(D), (int)(E), (__v32qi)(__m256i)(A), (__mmask32)(B))) -#define _mm256_maskz_gf2p8affine_epi64_epi8(A, B, C, D) ((__m256i) __builtin_ia32_vgf2p8affineqb_v32qi_mask((__v32qi)(__m256i)(B), (__v32qi)(__m256i)(C), (int)(D), (__v32qi)(__m256i) _mm256_setzero_si256 (), (__mmask32)(A))) +#define _mm256_maskz_gf2p8affine_epi64_epi8(A, B, C, D) ((__m256i) __builtin_ia32_vgf2p8affineqb_v32qi_mask((__v32qi)(__m256i)(B), (__v32qi)(__m256i)(C), (int)(D), (__v32qi)(__m256i) _mm256_avx512_setzero_si256 (), (__mmask32)(A))) #endif #ifdef __DISABLE_GFNIAVX512VLBW__ #undef __DISABLE_GFNIAVX512VLBW__ #pragma GCC pop_options #endif -#if !defined(__GFNI__) || !defined(__AVX512F__) || !defined(__AVX512BW__) +#if !defined(__GFNI__) || !defined(__EVEX512__) || !defined(__AVX512F__) #pragma GCC push_options -#pragma GCC target("gfni,avx512f,avx512bw") +#pragma GCC target("gfni,avx512f,evex512") +#define __DISABLE_GFNIAVX512F__ +#endif +extern __inline __m512i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm512_gf2p8mul_epi8 (__m512i __A, __m512i __B) +{ + return (__m512i) __builtin_ia32_vgf2p8mulb_v64qi ((__v64qi) __A, + (__v64qi) __B); +} +#ifdef __OPTIMIZE__ +extern __inline __m512i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm512_gf2p8affineinv_epi64_epi8 (__m512i __A, __m512i __B, const int __C) +{ + return (__m512i) __builtin_ia32_vgf2p8affineinvqb_v64qi ((__v64qi) __A, + (__v64qi) __B, __C); +} +extern __inline __m512i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm512_gf2p8affine_epi64_epi8 (__m512i __A, __m512i __B, const int __C) +{ + return (__m512i) __builtin_ia32_vgf2p8affineqb_v64qi ((__v64qi) __A, + (__v64qi) __B, __C); +} +#else +#define _mm512_gf2p8affineinv_epi64_epi8(A, B, C) ((__m512i) __builtin_ia32_vgf2p8affineinvqb_v64qi ( (__v64qi)(__m512i)(A), (__v64qi)(__m512i)(B), (int)(C))) +#define _mm512_gf2p8affine_epi64_epi8(A, B, C) ((__m512i) __builtin_ia32_vgf2p8affineqb_v64qi ((__v64qi)(__m512i)(A), (__v64qi)(__m512i)(B), (int)(C))) +#endif +#ifdef __DISABLE_GFNIAVX512F__ +#undef __DISABLE_GFNIAVX512F__ +#pragma GCC pop_options +#endif +#if !defined(__GFNI__) || !defined(__EVEX512__) || !defined(__AVX512BW__) +#pragma GCC push_options +#pragma GCC target("gfni,avx512bw,evex512") #define __DISABLE_GFNIAVX512FBW__ #endif extern __inline __m512i @@ -235,13 +270,6 @@ _mm512_maskz_gf2p8mul_epi8 (__mmask64 __A, __m512i __B, __m512i __C) return (__m512i) __builtin_ia32_vgf2p8mulb_v64qi_mask ((__v64qi) __B, (__v64qi) __C, (__v64qi) _mm512_setzero_si512 (), __A); } -extern __inline __m512i -__attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm512_gf2p8mul_epi8 (__m512i __A, __m512i __B) -{ - return (__m512i) __builtin_ia32_vgf2p8mulb_v64qi ((__v64qi) __A, - (__v64qi) __B); -} #ifdef __OPTIMIZE__ extern __inline __m512i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) @@ -265,13 +293,6 @@ _mm512_maskz_gf2p8affineinv_epi64_epi8 (__mmask64 __A, __m512i __B, } extern __inline __m512i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm512_gf2p8affineinv_epi64_epi8 (__m512i __A, __m512i __B, const int __C) -{ - return (__m512i) __builtin_ia32_vgf2p8affineinvqb_v64qi ((__v64qi) __A, - (__v64qi) __B, __C); -} -extern __inline __m512i -__attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm512_mask_gf2p8affine_epi64_epi8 (__m512i __A, __mmask64 __B, __m512i __C, __m512i __D, const int __E) { @@ -286,20 +307,11 @@ _mm512_maskz_gf2p8affine_epi64_epi8 (__mmask64 __A, __m512i __B, __m512i __C, return (__m512i) __builtin_ia32_vgf2p8affineqb_v64qi_mask ((__v64qi) __B, (__v64qi) __C, __D, (__v64qi) _mm512_setzero_si512 (), __A); } -extern __inline __m512i -__attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm512_gf2p8affine_epi64_epi8 (__m512i __A, __m512i __B, const int __C) -{ - return (__m512i) __builtin_ia32_vgf2p8affineqb_v64qi ((__v64qi) __A, - (__v64qi) __B, __C); -} #else #define _mm512_mask_gf2p8affineinv_epi64_epi8(A, B, C, D, E) ((__m512i) __builtin_ia32_vgf2p8affineinvqb_v64qi_mask( (__v64qi)(__m512i)(C), (__v64qi)(__m512i)(D), (int)(E), (__v64qi)(__m512i)(A), (__mmask64)(B))) #define _mm512_maskz_gf2p8affineinv_epi64_epi8(A, B, C, D) ((__m512i) __builtin_ia32_vgf2p8affineinvqb_v64qi_mask( (__v64qi)(__m512i)(B), (__v64qi)(__m512i)(C), (int)(D), (__v64qi)(__m512i) _mm512_setzero_si512 (), (__mmask64)(A))) -#define _mm512_gf2p8affineinv_epi64_epi8(A, B, C) ((__m512i) __builtin_ia32_vgf2p8affineinvqb_v64qi ( (__v64qi)(__m512i)(A), (__v64qi)(__m512i)(B), (int)(C))) #define _mm512_mask_gf2p8affine_epi64_epi8(A, B, C, D, E) ((__m512i) __builtin_ia32_vgf2p8affineqb_v64qi_mask((__v64qi)(__m512i)(C), (__v64qi)(__m512i)(D), (int)(E), (__v64qi)(__m512i)(A), (__mmask64)(B))) #define _mm512_maskz_gf2p8affine_epi64_epi8(A, B, C, D) ((__m512i) __builtin_ia32_vgf2p8affineqb_v64qi_mask((__v64qi)(__m512i)(B), (__v64qi)(__m512i)(C), (int)(D), (__v64qi)(__m512i) _mm512_setzero_si512 (), (__mmask64)(A))) -#define _mm512_gf2p8affine_epi64_epi8(A, B, C) ((__m512i) __builtin_ia32_vgf2p8affineqb_v64qi ((__v64qi)(__m512i)(A), (__v64qi)(__m512i)(B), (int)(C))) #endif #ifdef __DISABLE_GFNIAVX512FBW__ #undef __DISABLE_GFNIAVX512FBW__ diff --git a/third_party/intel/immintrin.internal.h b/third_party/intel/immintrin.internal.h index a932d9755..1d02c5183 100644 --- a/third_party/intel/immintrin.internal.h +++ b/third_party/intel/immintrin.internal.h @@ -11,6 +11,9 @@ #include "third_party/intel/wmmintrin.internal.h" #include "third_party/intel/avxintrin.internal.h" #include "third_party/intel/avxvnniintrin.internal.h" +#include "third_party/intel/avxifmaintrin.internal.h" +#include "third_party/intel/avxvnniint8intrin.internal.h" +#include "third_party/intel/avxvnniint16intrin.internal.h" #include "third_party/intel/avx2intrin.internal.h" #include "third_party/intel/avx512fintrin.internal.h" #include "third_party/intel/avx512erintrin.internal.h" @@ -34,13 +37,15 @@ #include "third_party/intel/avx512vnnivlintrin.internal.h" #include "third_party/intel/avx512vpopcntdqvlintrin.internal.h" #include "third_party/intel/avx512bitalgintrin.internal.h" +#include "third_party/intel/avx512bitalgvlintrin.internal.h" #include "third_party/intel/avx512vp2intersectintrin.internal.h" #include "third_party/intel/avx512vp2intersectvlintrin.internal.h" -#ifdef __SSE2__ #include "third_party/intel/avx512fp16intrin.internal.h" #include "third_party/intel/avx512fp16vlintrin.internal.h" -#endif #include "third_party/intel/shaintrin.internal.h" +#include "third_party/intel/sm3intrin.internal.h" +#include "third_party/intel/sha512intrin.internal.h" +#include "third_party/intel/sm4intrin.internal.h" #include "third_party/intel/fmaintrin.internal.h" #include "third_party/intel/f16cintrin.internal.h" #include "third_party/intel/rtmintrin.internal.h" @@ -49,10 +54,13 @@ #include "third_party/intel/vpclmulqdqintrin.internal.h" #include "third_party/intel/avx512bf16vlintrin.internal.h" #include "third_party/intel/avx512bf16intrin.internal.h" +#include "third_party/intel/avxneconvertintrin.internal.h" #include "third_party/intel/amxtileintrin.internal.h" #include "third_party/intel/amxint8intrin.internal.h" #include "third_party/intel/amxbf16intrin.internal.h" +#include "third_party/intel/amxcomplexintrin.internal.h" #include "third_party/intel/prfchwintrin.internal.h" #include "third_party/intel/keylockerintrin.internal.h" +#include "third_party/intel/amxfp16intrin.internal.h" #endif #endif diff --git a/third_party/intel/mm_malloc.internal.h b/third_party/intel/mm_malloc.internal.h index e3b5a0423..4a41f80c8 100644 --- a/third_party/intel/mm_malloc.internal.h +++ b/third_party/intel/mm_malloc.internal.h @@ -3,23 +3,27 @@ #define _MM_MALLOC_H_INCLUDED #include "libc/mem/mem.h" #ifndef __cplusplus -extern int _mm_posix_memalign(void **, size_t, size_t) +extern int posix_memalign (void **, size_t, size_t); #else -extern "C" int _mm_posix_memalign(void **, size_t, size_t) throw() +extern "C" int posix_memalign (void **, size_t, size_t) throw (); #endif - __asm__("posix_memalign"); -static __inline void *_mm_malloc(size_t __size, size_t __alignment) { +static __inline void * +_mm_malloc (size_t __size, size_t __alignment) +{ void *__ptr; - if (__alignment == 1) return malloc(__size); - if (__alignment == 2 || (sizeof(void *) == 8 && __alignment == 4)) - __alignment = sizeof(void *); - if (_mm_posix_memalign(&__ptr, __alignment, __size) == 0) + if (__alignment == 1) + return malloc (__size); + if (__alignment == 2 || (sizeof (void *) == 8 && __alignment == 4)) + __alignment = sizeof (void *); + if (posix_memalign (&__ptr, __alignment, __size) == 0) return __ptr; else return NULL; } -static __inline void _mm_free(void *__ptr) { - free(__ptr); +static __inline void +_mm_free (void *__ptr) +{ + free (__ptr); } #endif #endif diff --git a/third_party/intel/prfchiintrin.internal.h b/third_party/intel/prfchiintrin.internal.h new file mode 100644 index 000000000..9ae2660fc --- /dev/null +++ b/third_party/intel/prfchiintrin.internal.h @@ -0,0 +1,31 @@ +#if defined(__x86_64__) && !(__ASSEMBLER__ + __LINKER__ + 0) +#if !defined _X86GPRINTRIN_H_INCLUDED +# error "Never use directly; include instead." +#endif +#ifndef _PRFCHIINTRIN_H_INCLUDED +#define _PRFCHIINTRIN_H_INCLUDED +#ifdef __x86_64__ +#ifndef __PREFETCHI__ +#pragma GCC push_options +#pragma GCC target("prefetchi") +#define __DISABLE_PREFETCHI__ +#endif +extern __inline void +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_m_prefetchit0 (void* __P) +{ + __builtin_ia32_prefetchi (__P, 3); +} +extern __inline void +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_m_prefetchit1 (void* __P) +{ + __builtin_ia32_prefetchi (__P, 2); +} +#ifdef __DISABLE_PREFETCHI__ +#undef __DISABLE_PREFETCHI__ +#pragma GCC pop_options +#endif +#endif +#endif +#endif diff --git a/third_party/intel/raointintrin.internal.h b/third_party/intel/raointintrin.internal.h new file mode 100644 index 000000000..9e841b16c --- /dev/null +++ b/third_party/intel/raointintrin.internal.h @@ -0,0 +1,67 @@ +#if defined(__x86_64__) && !(__ASSEMBLER__ + __LINKER__ + 0) +#ifndef _X86GPRINTRIN_H_INCLUDED +#error "Never use directly; include instead." +#endif +#ifndef __RAOINTINTRIN_H_INCLUDED +#define __RAOINTINTRIN_H_INCLUDED +#ifndef __RAOINT__ +#pragma GCC push_options +#pragma GCC target("raoint") +#define __DISABLE_RAOINT__ +#endif +extern __inline void +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_aadd_i32 (int *__A, int __B) +{ + __builtin_ia32_aadd32 ((int *)__A, __B); +} +extern __inline void +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_aand_i32 (int *__A, int __B) +{ + __builtin_ia32_aand32 ((int *)__A, __B); +} +extern __inline void +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_aor_i32 (int *__A, int __B) +{ + __builtin_ia32_aor32 ((int *)__A, __B); +} +extern __inline void +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_axor_i32 (int *__A, int __B) +{ + __builtin_ia32_axor32 ((int *)__A, __B); +} +#ifdef __x86_64__ +extern __inline void +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_aadd_i64 (long long *__A, long long __B) +{ + __builtin_ia32_aadd64 ((long long *)__A, __B); +} +extern __inline void +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_aand_i64 (long long *__A, long long __B) +{ + __builtin_ia32_aand64 ((long long *)__A, __B); +} +extern __inline void +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_aor_i64 (long long *__A, long long __B) +{ + __builtin_ia32_aor64 ((long long *)__A, __B); +} +extern __inline void +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_axor_i64 (long long *__A, long long __B) +{ + __builtin_ia32_axor64 ((long long *)__A, __B); +} +#endif +#ifdef __DISABLE_RAOINT__ +#undef __DISABLE_RAOINT__ +#pragma GCC pop_options +#endif +#endif +#endif diff --git a/third_party/intel/sha512intrin.internal.h b/third_party/intel/sha512intrin.internal.h new file mode 100644 index 000000000..b233f24c4 --- /dev/null +++ b/third_party/intel/sha512intrin.internal.h @@ -0,0 +1,36 @@ +#if defined(__x86_64__) && !(__ASSEMBLER__ + __LINKER__ + 0) +#ifndef _IMMINTRIN_H_INCLUDED +#error "Never use directly; include instead." +#endif +#ifndef _SHA512INTRIN_H_INCLUDED +#define _SHA512INTRIN_H_INCLUDED +#ifndef __SHA512__ +#pragma GCC push_options +#pragma GCC target("sha512") +#define __DISABLE_SHA512__ +#endif +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_sha512msg1_epi64 (__m256i __A, __m128i __B) +{ + return (__m256i) __builtin_ia32_vsha512msg1 ((__v4di) __A, (__v2di) __B); +} +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_sha512msg2_epi64 (__m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_vsha512msg2 ((__v4di) __A, (__v4di) __B); +} +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_sha512rnds2_epi64 (__m256i __A, __m256i __B, __m128i __C) +{ + return (__m256i) __builtin_ia32_vsha512rnds2 ((__v4di) __A, (__v4di) __B, + (__v2di) __C); +} +#ifdef __DISABLE_SHA512__ +#undef __DISABLE_SHA512__ +#pragma GCC pop_options +#endif +#endif +#endif diff --git a/third_party/intel/sm3intrin.internal.h b/third_party/intel/sm3intrin.internal.h new file mode 100644 index 000000000..98df61745 --- /dev/null +++ b/third_party/intel/sm3intrin.internal.h @@ -0,0 +1,42 @@ +#if defined(__x86_64__) && !(__ASSEMBLER__ + __LINKER__ + 0) +#ifndef _IMMINTRIN_H_INCLUDED +#error "Never use directly; include instead." +#endif +#ifndef _SM3INTRIN_H_INCLUDED +#define _SM3INTRIN_H_INCLUDED +#ifndef __SM3__ +#pragma GCC push_options +#pragma GCC target("sm3") +#define __DISABLE_SM3__ +#endif +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_sm3msg1_epi32 (__m128i __A, __m128i __B, __m128i __C) +{ + return (__m128i) __builtin_ia32_vsm3msg1 ((__v4si) __A, (__v4si) __B, + (__v4si) __C); +} +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_sm3msg2_epi32 (__m128i __A, __m128i __B, __m128i __C) +{ + return (__m128i) __builtin_ia32_vsm3msg2 ((__v4si) __A, (__v4si) __B, + (__v4si) __C); +} +#ifdef __OPTIMIZE__ +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_sm3rnds2_epi32 (__m128i __A, __m128i __B, __m128i __C, const int __D) +{ + return (__m128i) __builtin_ia32_vsm3rnds2 ((__v4si) __A, (__v4si) __B, + (__v4si) __C, __D); +} +#else +#define _mm_sm3rnds2_epi32(A, B, C, D) ((__m128i) __builtin_ia32_vsm3rnds2 ((__v4si) (A), (__v4si) (B), (__v4si) (C), (int) (D))) +#endif +#ifdef __DISABLE_SM3__ +#undef __DISABLE_SM3__ +#pragma GCC pop_options +#endif +#endif +#endif diff --git a/third_party/intel/sm4intrin.internal.h b/third_party/intel/sm4intrin.internal.h new file mode 100644 index 000000000..17658edd4 --- /dev/null +++ b/third_party/intel/sm4intrin.internal.h @@ -0,0 +1,41 @@ +#if defined(__x86_64__) && !(__ASSEMBLER__ + __LINKER__ + 0) +#ifndef _IMMINTRIN_H_INCLUDED +#error "Never use directly; include instead." +#endif +#ifndef _SM4INTRIN_H_INCLUDED +#define _SM4INTRIN_H_INCLUDED +#ifndef __SM4__ +#pragma GCC push_options +#pragma GCC target("sm4") +#define __DISABLE_SM4__ +#endif +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_sm4key4_epi32 (__m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_vsm4key4128 ((__v4si) __A, (__v4si) __B); +} +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_sm4key4_epi32 (__m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_vsm4key4256 ((__v8si) __A, (__v8si) __B); +} +extern __inline __m128i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_sm4rnds4_epi32 (__m128i __A, __m128i __B) +{ + return (__m128i) __builtin_ia32_vsm4rnds4128 ((__v4si) __A, (__v4si) __B); +} +extern __inline __m256i +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm256_sm4rnds4_epi32 (__m256i __A, __m256i __B) +{ + return (__m256i) __builtin_ia32_vsm4rnds4256 ((__v8si) __A, (__v8si) __B); +} +#ifdef __DISABLE_SM4__ +#undef __DISABLE_SM4__ +#pragma GCC pop_options +#endif +#endif +#endif diff --git a/third_party/intel/smmintrin.internal.h b/third_party/intel/smmintrin.internal.h index 5179c6e2e..a2e28ecaf 100644 --- a/third_party/intel/smmintrin.internal.h +++ b/third_party/intel/smmintrin.internal.h @@ -224,12 +224,12 @@ _mm_insert_ps (__m128 __D, __m128 __S, const int __N) extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_extract_ps (__m128 __X, const int __N) { - union { int i; float f; } __tmp; - __tmp.f = __builtin_ia32_vec_ext_v4sf ((__v4sf)__X, __N); - return __tmp.i; + union { int __i; float __f; } __tmp; + __tmp.__f = __builtin_ia32_vec_ext_v4sf ((__v4sf)__X, __N); + return __tmp.__i; } #else -#define _mm_extract_ps(X, N) (__extension__ ({ union { int i; float f; } __tmp; __tmp.f = __builtin_ia32_vec_ext_v4sf ((__v4sf)(__m128)(X), (int)(N)); __tmp.i; })) +#define _mm_extract_ps(X, N) (__extension__ ({ union { int __i; float __f; } __tmp; __tmp.__f = __builtin_ia32_vec_ext_v4sf ((__v4sf)(__m128)(X), (int)(N)); __tmp.__i; })) #endif #define _MM_EXTRACT_FLOAT(D, S, N) { (D) = __builtin_ia32_vec_ext_v4sf ((__v4sf)(S), (N)); } #define _MM_PICK_OUT_PS(X, N) _mm_insert_ps (_mm_setzero_ps (), (X), _MM_MK_INSERTPS_NDX ((N), 0, 0x0e)) diff --git a/third_party/intel/upgrade.sh b/third_party/intel/upgrade.sh index f5f32ddae..9fcd0a74f 100755 --- a/third_party/intel/upgrade.sh +++ b/third_party/intel/upgrade.sh @@ -7,6 +7,8 @@ FILES=' adxintrin ammintrin amxbf16intrin +amxcomplexintrin +amxfp16intrin amxint8intrin amxtileintrin avx2intrin @@ -15,6 +17,7 @@ avx5124vnniwintrin avx512bf16intrin avx512bf16vlintrin avx512bitalgintrin +avx512bitalgvlintrin avx512bwintrin avx512cdintrin avx512dqintrin @@ -38,15 +41,21 @@ avx512vp2intersectintrin avx512vp2intersectvlintrin avx512vpopcntdqintrin avx512vpopcntdqvlintrin +avxifmaintrin +avxvnniint8intrin +avxvnniint16intrin avxintrin +avxneconvertintrin avxvnniintrin bmi2intrin +bmmintrin bmiintrin cetintrin cldemoteintrin clflushoptintrin clwbintrin clzerointrin +cmpccxaddintrin cpuid emmintrin enqcmdintrin @@ -72,17 +81,23 @@ pconfigintrin pkuintrin pmmintrin popcntintrin +prfchiintrin prfchwintrin +raointintrin rdseedintrin rtmintrin serializeintrin sgxintrin +sha512intrin shaintrin +sm3intrin +sm4intrin smmintrin tbmintrin tmmintrin tsxldtrkintrin uintrintrin +usermsrintrin vaesintrin vpclmulqdqintrin waitpkgintrin diff --git a/third_party/intel/usermsrintrin.internal.h b/third_party/intel/usermsrintrin.internal.h new file mode 100644 index 000000000..481e3ffe6 --- /dev/null +++ b/third_party/intel/usermsrintrin.internal.h @@ -0,0 +1,31 @@ +#if defined(__x86_64__) && !(__ASSEMBLER__ + __LINKER__ + 0) +#if !defined _X86GPRINTRIN_H_INCLUDED +#error "Never use directly; include instead." +#endif +#ifndef _USER_MSRINTRIN_H_INCLUDED +#define _USER_MSRINTRIN_H_INCLUDED +#ifdef __x86_64__ +#ifndef __USER_MSR__ +#pragma GCC push_options +#pragma GCC target("usermsr") +#define __DISABLE_USER_MSR__ +#endif +extern __inline unsigned long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_urdmsr (unsigned long long __A) +{ + return (unsigned long long) __builtin_ia32_urdmsr (__A); +} +extern __inline void +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +_uwrmsr (unsigned long long __A, unsigned long long __B) +{ + __builtin_ia32_uwrmsr (__A, __B); +} +#ifdef __DISABLE_USER_MSR__ +#undef __DISABLE_USER_MSR__ +#pragma GCC pop_options +#endif +#endif +#endif +#endif diff --git a/third_party/intel/vaesintrin.internal.h b/third_party/intel/vaesintrin.internal.h index 6a55221af..574b40880 100644 --- a/third_party/intel/vaesintrin.internal.h +++ b/third_party/intel/vaesintrin.internal.h @@ -1,9 +1,9 @@ #if defined(__x86_64__) && !(__ASSEMBLER__ + __LINKER__ + 0) #ifndef __VAESINTRIN_H_INCLUDED #define __VAESINTRIN_H_INCLUDED -#if !defined(__VAES__) || !defined(__AVX__) +#if !defined(__VAES__) #pragma GCC push_options -#pragma GCC target("vaes,avx") +#pragma GCC target("vaes") #define __DISABLE_VAES__ #endif extern __inline __m256i @@ -36,9 +36,9 @@ _mm256_aesenclast_epi128 (__m256i __A, __m256i __B) #undef __DISABLE_VAES__ #pragma GCC pop_options #endif -#if !defined(__VAES__) || !defined(__AVX512F__) +#if !defined(__VAES__) || !defined(__AVX512F__) || !defined(__EVEX512__) #pragma GCC push_options -#pragma GCC target("vaes,avx512f") +#pragma GCC target("vaes,avx512f,evex512") #define __DISABLE_VAESF__ #endif extern __inline __m512i diff --git a/third_party/intel/vpclmulqdqintrin.internal.h b/third_party/intel/vpclmulqdqintrin.internal.h index f2726d0e3..e1e8785d7 100644 --- a/third_party/intel/vpclmulqdqintrin.internal.h +++ b/third_party/intel/vpclmulqdqintrin.internal.h @@ -4,9 +4,9 @@ #endif #ifndef _VPCLMULQDQINTRIN_H_INCLUDED #define _VPCLMULQDQINTRIN_H_INCLUDED -#if !defined(__VPCLMULQDQ__) || !defined(__AVX512F__) +#if !defined(__VPCLMULQDQ__) || !defined(__AVX512F__) || !defined(__EVEX512__) #pragma GCC push_options -#pragma GCC target("vpclmulqdq,avx512f") +#pragma GCC target("vpclmulqdq,avx512f,evex512") #define __DISABLE_VPCLMULQDQF__ #endif #ifdef __OPTIMIZE__ @@ -24,9 +24,9 @@ _mm512_clmulepi64_epi128 (__m512i __A, __m512i __B, const int __C) #undef __DISABLE_VPCLMULQDQF__ #pragma GCC pop_options #endif -#if !defined(__VPCLMULQDQ__) || !defined(__AVX__) +#if !defined(__VPCLMULQDQ__) #pragma GCC push_options -#pragma GCC target("vpclmulqdq,avx") +#pragma GCC target("vpclmulqdq") #define __DISABLE_VPCLMULQDQ__ #endif #ifdef __OPTIMIZE__ diff --git a/third_party/intel/wmmintrin.internal.h b/third_party/intel/wmmintrin.internal.h index ff5dee236..c1c3f274e 100644 --- a/third_party/intel/wmmintrin.internal.h +++ b/third_party/intel/wmmintrin.internal.h @@ -7,27 +7,10 @@ #pragma GCC target("aes,sse2") #define __DISABLE_AES__ #endif -extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_aesdec_si128 (__m128i __X, __m128i __Y) -{ - return (__m128i) __builtin_ia32_aesdec128 ((__v2di)__X, (__v2di)__Y); -} -extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_aesdeclast_si128 (__m128i __X, __m128i __Y) -{ - return (__m128i) __builtin_ia32_aesdeclast128 ((__v2di)__X, - (__v2di)__Y); -} -extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_aesenc_si128 (__m128i __X, __m128i __Y) -{ - return (__m128i) __builtin_ia32_aesenc128 ((__v2di)__X, (__v2di)__Y); -} -extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_aesenclast_si128 (__m128i __X, __m128i __Y) -{ - return (__m128i) __builtin_ia32_aesenclast128 ((__v2di)__X, (__v2di)__Y); -} +#define _mm_aesdec_si128(X, Y) (__m128i) __builtin_ia32_aesdec128 ((__v2di) (X), (__v2di) (Y)) +#define _mm_aesdeclast_si128(X, Y) (__m128i) __builtin_ia32_aesdeclast128 ((__v2di) (X), (__v2di) (Y)) +#define _mm_aesenc_si128(X, Y) (__m128i) __builtin_ia32_aesenc128 ((__v2di) (X), (__v2di) (Y)) +#define _mm_aesenclast_si128(X, Y) (__m128i) __builtin_ia32_aesenclast128 ((__v2di) (X), (__v2di) (Y)) extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_aesimc_si128 (__m128i __X) { diff --git a/third_party/intel/x86gprintrin.internal.h b/third_party/intel/x86gprintrin.internal.h index 875718588..f9b3e8554 100644 --- a/third_party/intel/x86gprintrin.internal.h +++ b/third_party/intel/x86gprintrin.internal.h @@ -16,6 +16,7 @@ #include "third_party/intel/clflushoptintrin.internal.h" #include "third_party/intel/clwbintrin.internal.h" #include "third_party/intel/clzerointrin.internal.h" +#include "third_party/intel/cmpccxaddintrin.internal.h" #include "third_party/intel/enqcmdintrin.internal.h" #include "third_party/intel/fxsrintrin.internal.h" #include "third_party/intel/lzcntintrin.internal.h" @@ -26,6 +27,8 @@ #include "third_party/intel/pconfigintrin.internal.h" #include "third_party/intel/popcntintrin.internal.h" #include "third_party/intel/pkuintrin.internal.h" +#include "third_party/intel/prfchiintrin.internal.h" +#include "third_party/intel/raointintrin.internal.h" #include "third_party/intel/rdseedintrin.internal.h" #include "third_party/intel/rtmintrin.internal.h" #include "third_party/intel/serializeintrin.internal.h" @@ -41,6 +44,7 @@ #include "third_party/intel/xsavesintrin.internal.h" #include "third_party/intel/xtestintrin.internal.h" #include "third_party/intel/hresetintrin.internal.h" +#include "third_party/intel/usermsrintrin.internal.h" extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _wbinvd (void) diff --git a/third_party/intel/xmmintrin.internal.h b/third_party/intel/xmmintrin.internal.h index 3a97b9fa1..65e42bc5e 100644 --- a/third_party/intel/xmmintrin.internal.h +++ b/third_party/intel/xmmintrin.internal.h @@ -5,6 +5,8 @@ #include "third_party/intel/mm_malloc.internal.h" enum _mm_hint { + _MM_HINT_IT0 = 19, + _MM_HINT_IT1 = 18, _MM_HINT_ET0 = 7, _MM_HINT_ET1 = 6, _MM_HINT_T0 = 3, @@ -16,10 +18,11 @@ enum _mm_hint extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_prefetch (const void *__P, enum _mm_hint __I) { - __builtin_prefetch (__P, (__I & 0x4) >> 2, __I & 0x3); + __builtin_ia32_prefetch (__P, (__I & 0x4) >> 2, + __I & 0x3, (__I & 0x10) >> 4); } #else -#define _mm_prefetch(P, I) __builtin_prefetch ((P), ((I & 0x4) >> 2), (I & 0x3)) +#define _mm_prefetch(P, I) __builtin_ia32_prefetch ((P), ((I) & 0x4) >> 2, ((I) & 0x3), ((I) & 0x10) >> 4) #endif #ifndef __SSE__ #pragma GCC push_options @@ -55,7 +58,10 @@ typedef float __v4sf __attribute__ ((__vector_size__ (16))); extern __inline __m128 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_undefined_ps (void) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Winit-self" __m128 __Y = __Y; +#pragma GCC diagnostic pop return __Y; } extern __inline __m128 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) diff --git a/third_party/libcxx/BUILD.mk b/third_party/libcxx/BUILD.mk index e45f701f1..a7d25568c 100644 --- a/third_party/libcxx/BUILD.mk +++ b/third_party/libcxx/BUILD.mk @@ -8,6 +8,7 @@ THIRD_PARTY_LIBCXX = $(THIRD_PARTY_LIBCXX_A_DEPS) $(THIRD_PARTY_LIBCXX_A) THIRD_PARTY_LIBCXX_A = o/$(MODE)/third_party/libcxx/libcxx.a THIRD_PARTY_LIBCXX_A_HDRS = \ +third_party/libcxx/__assertion_handler \ third_party/libcxx/__algorithm/adjacent_find.h \ third_party/libcxx/__algorithm/all_of.h \ third_party/libcxx/__algorithm/any_of.h \ @@ -31,6 +32,8 @@ third_party/libcxx/__algorithm/find_end.h \ third_party/libcxx/__algorithm/find_first_of.h \ third_party/libcxx/__algorithm/find_if.h \ third_party/libcxx/__algorithm/find_if_not.h \ +third_party/libcxx/__algorithm/find_segment_if.h \ +third_party/libcxx/__algorithm/fold.h \ third_party/libcxx/__algorithm/for_each.h \ third_party/libcxx/__algorithm/for_each_n.h \ third_party/libcxx/__algorithm/for_each_segment.h \ @@ -79,18 +82,22 @@ third_party/libcxx/__algorithm/partition_copy.h \ third_party/libcxx/__algorithm/partition_point.h \ third_party/libcxx/__algorithm/pop_heap.h \ third_party/libcxx/__algorithm/prev_permutation.h \ +third_party/libcxx/__algorithm/pstl.h \ third_party/libcxx/__algorithm/push_heap.h \ third_party/libcxx/__algorithm/ranges_adjacent_find.h \ third_party/libcxx/__algorithm/ranges_all_of.h \ third_party/libcxx/__algorithm/ranges_any_of.h \ third_party/libcxx/__algorithm/ranges_binary_search.h \ third_party/libcxx/__algorithm/ranges_clamp.h \ +third_party/libcxx/__algorithm/ranges_contains.h \ +third_party/libcxx/__algorithm/ranges_contains_subrange.h \ third_party/libcxx/__algorithm/ranges_copy.h \ third_party/libcxx/__algorithm/ranges_copy_backward.h \ third_party/libcxx/__algorithm/ranges_copy_if.h \ third_party/libcxx/__algorithm/ranges_copy_n.h \ third_party/libcxx/__algorithm/ranges_count.h \ third_party/libcxx/__algorithm/ranges_count_if.h \ +third_party/libcxx/__algorithm/ranges_ends_with.h \ third_party/libcxx/__algorithm/ranges_equal.h \ third_party/libcxx/__algorithm/ranges_equal_range.h \ third_party/libcxx/__algorithm/ranges_fill.h \ @@ -100,6 +107,7 @@ third_party/libcxx/__algorithm/ranges_find_end.h \ third_party/libcxx/__algorithm/ranges_find_first_of.h \ third_party/libcxx/__algorithm/ranges_find_if.h \ third_party/libcxx/__algorithm/ranges_find_if_not.h \ +third_party/libcxx/__algorithm/ranges_find_last.h \ third_party/libcxx/__algorithm/ranges_for_each.h \ third_party/libcxx/__algorithm/ranges_for_each_n.h \ third_party/libcxx/__algorithm/ranges_generate.h \ @@ -190,6 +198,7 @@ third_party/libcxx/__algorithm/shift_left.h \ third_party/libcxx/__algorithm/shift_right.h \ third_party/libcxx/__algorithm/shuffle.h \ third_party/libcxx/__algorithm/sift_down.h \ +third_party/libcxx/__algorithm/simd_utils.h \ third_party/libcxx/__algorithm/sort.h \ third_party/libcxx/__algorithm/sort_heap.h \ third_party/libcxx/__algorithm/stable_partition.h \ @@ -210,6 +219,7 @@ third_party/libcxx/__atomic/atomic_base.h \ third_party/libcxx/__atomic/atomic_flag.h \ third_party/libcxx/__atomic/atomic_init.h \ third_party/libcxx/__atomic/atomic_lock_free.h \ +third_party/libcxx/__atomic/atomic_ref.h \ third_party/libcxx/__atomic/atomic_sync.h \ third_party/libcxx/__atomic/check_memory_order.h \ third_party/libcxx/__atomic/contention_t.h \ @@ -218,7 +228,7 @@ third_party/libcxx/__atomic/fence.h \ third_party/libcxx/__atomic/is_always_lock_free.h \ third_party/libcxx/__atomic/kill_dependency.h \ third_party/libcxx/__atomic/memory_order.h \ -third_party/libcxx/__availability \ +third_party/libcxx/__atomic/to_gcc_order.h \ third_party/libcxx/__bit/bit_cast.h \ third_party/libcxx/__bit/bit_ceil.h \ third_party/libcxx/__bit/bit_floor.h \ @@ -230,6 +240,7 @@ third_party/libcxx/__bit/countl.h \ third_party/libcxx/__bit/countr.h \ third_party/libcxx/__bit/endian.h \ third_party/libcxx/__bit/has_single_bit.h \ +third_party/libcxx/__bit/invert_if.h \ third_party/libcxx/__bit/popcount.h \ third_party/libcxx/__bit/rotate.h \ third_party/libcxx/__bit_reference \ @@ -249,11 +260,14 @@ third_party/libcxx/__chrono/convert_to_timespec.h \ third_party/libcxx/__chrono/convert_to_tm.h \ third_party/libcxx/__chrono/day.h \ third_party/libcxx/__chrono/duration.h \ +third_party/libcxx/__chrono/exception.h \ third_party/libcxx/__chrono/file_clock.h \ third_party/libcxx/__chrono/formatter.h \ third_party/libcxx/__chrono/hh_mm_ss.h \ third_party/libcxx/__chrono/high_resolution_clock.h \ +third_party/libcxx/__chrono/leap_second.h \ third_party/libcxx/__chrono/literals.h \ +third_party/libcxx/__chrono/local_info.h \ third_party/libcxx/__chrono/month.h \ third_party/libcxx/__chrono/month_weekday.h \ third_party/libcxx/__chrono/monthday.h \ @@ -261,13 +275,19 @@ third_party/libcxx/__chrono/ostream.h \ third_party/libcxx/__chrono/parser_std_format_spec.h \ third_party/libcxx/__chrono/statically_widen.h \ third_party/libcxx/__chrono/steady_clock.h \ +third_party/libcxx/__chrono/sys_info.h \ third_party/libcxx/__chrono/system_clock.h \ third_party/libcxx/__chrono/time_point.h \ +third_party/libcxx/__chrono/time_zone.h \ +third_party/libcxx/__chrono/time_zone_link.h \ +third_party/libcxx/__chrono/tzdb.h \ +third_party/libcxx/__chrono/tzdb_list.h \ third_party/libcxx/__chrono/weekday.h \ third_party/libcxx/__chrono/year.h \ third_party/libcxx/__chrono/year_month.h \ third_party/libcxx/__chrono/year_month_day.h \ third_party/libcxx/__chrono/year_month_weekday.h \ +third_party/libcxx/__chrono/zoned_time.h \ third_party/libcxx/__compare/common_comparison_category.h \ third_party/libcxx/__compare/compare_partial_order_fallback.h \ third_party/libcxx/__compare/compare_strong_order_fallback.h \ @@ -306,12 +326,18 @@ third_party/libcxx/__concepts/totally_ordered.h \ third_party/libcxx/__condition_variable/condition_variable.h \ third_party/libcxx/__config \ third_party/libcxx/__config_site \ +third_party/libcxx/__configuration/abi.h \ +third_party/libcxx/__configuration/availability.h \ +third_party/libcxx/__configuration/compiler.h \ +third_party/libcxx/__configuration/language.h \ +third_party/libcxx/__configuration/platform.h \ third_party/libcxx/__coroutine/coroutine_handle.h \ third_party/libcxx/__coroutine/coroutine_traits.h \ third_party/libcxx/__coroutine/noop_coroutine_handle.h \ third_party/libcxx/__coroutine/trivial_awaitables.h \ -third_party/libcxx/__debug \ third_party/libcxx/__debug_utils/randomize_range.h \ +third_party/libcxx/__debug_utils/sanitizers.h \ +third_party/libcxx/__debug_utils/strict_weak_ordering_check.h \ third_party/libcxx/__exception/exception.h \ third_party/libcxx/__exception/exception_ptr.h \ third_party/libcxx/__exception/nested_exception.h \ @@ -349,7 +375,6 @@ third_party/libcxx/__format/format_args.h \ third_party/libcxx/__format/format_context.h \ third_party/libcxx/__format/format_error.h \ third_party/libcxx/__format/format_functions.h \ -third_party/libcxx/__format/format_fwd.h \ third_party/libcxx/__format/format_parse_context.h \ third_party/libcxx/__format/format_string.h \ third_party/libcxx/__format/format_to_n_result.h \ @@ -363,11 +388,13 @@ third_party/libcxx/__format/formatter_output.h \ third_party/libcxx/__format/formatter_pointer.h \ third_party/libcxx/__format/formatter_string.h \ third_party/libcxx/__format/formatter_tuple.h \ +third_party/libcxx/__format/indic_conjunct_break_table.h \ third_party/libcxx/__format/parser_std_format_spec.h \ third_party/libcxx/__format/range_default_formatter.h \ third_party/libcxx/__format/range_formatter.h \ third_party/libcxx/__format/unicode.h \ third_party/libcxx/__format/width_estimation_table.h \ +third_party/libcxx/__format/write_escaped.h \ third_party/libcxx/__functional/binary_function.h \ third_party/libcxx/__functional/binary_negate.h \ third_party/libcxx/__functional/bind.h \ @@ -396,30 +423,40 @@ third_party/libcxx/__functional/unary_function.h \ third_party/libcxx/__functional/unary_negate.h \ third_party/libcxx/__functional/weak_result_type.h \ third_party/libcxx/__fwd/array.h \ +third_party/libcxx/__fwd/bit_reference.h \ +third_party/libcxx/__fwd/complex.h \ +third_party/libcxx/__fwd/deque.h \ +third_party/libcxx/__fwd/format.h \ third_party/libcxx/__fwd/fstream.h \ -third_party/libcxx/__fwd/get.h \ -third_party/libcxx/__fwd/hash.h \ +third_party/libcxx/__fwd/functional.h \ third_party/libcxx/__fwd/ios.h \ third_party/libcxx/__fwd/istream.h \ +third_party/libcxx/__fwd/mdspan.h \ +third_party/libcxx/__fwd/memory.h \ third_party/libcxx/__fwd/memory_resource.h \ third_party/libcxx/__fwd/ostream.h \ third_party/libcxx/__fwd/pair.h \ +third_party/libcxx/__fwd/queue.h \ third_party/libcxx/__fwd/span.h \ third_party/libcxx/__fwd/sstream.h \ +third_party/libcxx/__fwd/stack.h \ third_party/libcxx/__fwd/streambuf.h \ third_party/libcxx/__fwd/string.h \ third_party/libcxx/__fwd/string_view.h \ third_party/libcxx/__fwd/subrange.h \ third_party/libcxx/__fwd/tuple.h \ +third_party/libcxx/__fwd/vector.h \ third_party/libcxx/__hash_table \ third_party/libcxx/__ios/fpos.h \ third_party/libcxx/__iterator/access.h \ third_party/libcxx/__iterator/advance.h \ +third_party/libcxx/__iterator/aliasing_iterator.h \ third_party/libcxx/__iterator/back_insert_iterator.h \ third_party/libcxx/__iterator/bounded_iter.h \ third_party/libcxx/__iterator/common_iterator.h \ third_party/libcxx/__iterator/concepts.h \ third_party/libcxx/__iterator/counted_iterator.h \ +third_party/libcxx/__iterator/cpp17_iterator_concepts.h \ third_party/libcxx/__iterator/data.h \ third_party/libcxx/__iterator/default_sentinel.h \ third_party/libcxx/__iterator/distance.h \ @@ -445,6 +482,7 @@ third_party/libcxx/__iterator/ostreambuf_iterator.h \ third_party/libcxx/__iterator/permutable.h \ third_party/libcxx/__iterator/prev.h \ third_party/libcxx/__iterator/projected.h \ +third_party/libcxx/__iterator/ranges_iterator_traits.h \ third_party/libcxx/__iterator/readable_traits.h \ third_party/libcxx/__iterator/reverse_access.h \ third_party/libcxx/__iterator/reverse_iterator.h \ @@ -454,7 +492,37 @@ third_party/libcxx/__iterator/sortable.h \ third_party/libcxx/__iterator/unreachable_sentinel.h \ third_party/libcxx/__iterator/wrap_iter.h \ third_party/libcxx/__locale \ +third_party/libcxx/__locale_dir/locale_base_api.h \ +third_party/libcxx/__locale_dir/locale_base_api/bsd_locale_defaults.h \ +third_party/libcxx/__locale_dir/locale_base_api/bsd_locale_fallbacks.h \ +third_party/libcxx/__locale_dir/locale_base_api/locale_guard.h \ +third_party/libcxx/__math/abs.h \ +third_party/libcxx/__math/copysign.h \ +third_party/libcxx/__math/error_functions.h \ +third_party/libcxx/__math/exponential_functions.h \ +third_party/libcxx/__math/fdim.h \ +third_party/libcxx/__math/fma.h \ +third_party/libcxx/__math/gamma.h \ +third_party/libcxx/__math/hyperbolic_functions.h \ +third_party/libcxx/__math/hypot.h \ +third_party/libcxx/__math/inverse_hyperbolic_functions.h \ +third_party/libcxx/__math/inverse_trigonometric_functions.h \ +third_party/libcxx/__math/logarithms.h \ +third_party/libcxx/__math/min_max.h \ +third_party/libcxx/__math/modulo.h \ +third_party/libcxx/__math/remainder.h \ +third_party/libcxx/__math/roots.h \ +third_party/libcxx/__math/rounding_functions.h \ +third_party/libcxx/__math/special_functions.h \ +third_party/libcxx/__math/traits.h \ +third_party/libcxx/__math/trigonometric_functions.h \ +third_party/libcxx/__mbstate_t.h \ +third_party/libcxx/__mdspan/default_accessor.h \ third_party/libcxx/__mdspan/extents.h \ +third_party/libcxx/__mdspan/layout_left.h \ +third_party/libcxx/__mdspan/layout_right.h \ +third_party/libcxx/__mdspan/layout_stride.h \ +third_party/libcxx/__mdspan/mdspan.h \ third_party/libcxx/__memory/addressof.h \ third_party/libcxx/__memory/align.h \ third_party/libcxx/__memory/aligned_alloc.h \ @@ -471,6 +539,8 @@ third_party/libcxx/__memory/compressed_pair.h \ third_party/libcxx/__memory/concepts.h \ third_party/libcxx/__memory/construct_at.h \ third_party/libcxx/__memory/destruct_n.h \ +third_party/libcxx/__memory/inout_ptr.h \ +third_party/libcxx/__memory/out_ptr.h \ third_party/libcxx/__memory/pointer_traits.h \ third_party/libcxx/__memory/ranges_construct_at.h \ third_party/libcxx/__memory/ranges_uninitialized_algorithms.h \ @@ -492,6 +562,7 @@ third_party/libcxx/__memory_resource/synchronized_pool_resource.h \ third_party/libcxx/__memory_resource/unsynchronized_pool_resource.h \ third_party/libcxx/__mutex/lock_guard.h \ third_party/libcxx/__mutex/mutex.h \ +third_party/libcxx/__mutex/once_flag.h \ third_party/libcxx/__mutex/tag_types.h \ third_party/libcxx/__mutex/unique_lock.h \ third_party/libcxx/__node_handle \ @@ -504,10 +575,31 @@ third_party/libcxx/__numeric/inner_product.h \ third_party/libcxx/__numeric/iota.h \ third_party/libcxx/__numeric/midpoint.h \ third_party/libcxx/__numeric/partial_sum.h \ +third_party/libcxx/__numeric/pstl.h \ third_party/libcxx/__numeric/reduce.h \ +third_party/libcxx/__numeric/saturation_arithmetic.h \ third_party/libcxx/__numeric/transform_exclusive_scan.h \ third_party/libcxx/__numeric/transform_inclusive_scan.h \ third_party/libcxx/__numeric/transform_reduce.h \ +third_party/libcxx/__ostream/basic_ostream.h \ +third_party/libcxx/__ostream/print.h \ +third_party/libcxx/__pstl/backend.h \ +third_party/libcxx/__pstl/backend_fwd.h \ +third_party/libcxx/__pstl/backends/default.h \ +third_party/libcxx/__pstl/backends/libdispatch.h \ +third_party/libcxx/__pstl/backends/serial.h \ +third_party/libcxx/__pstl/backends/std_thread.h \ +third_party/libcxx/__pstl/cpu_algos/any_of.h \ +third_party/libcxx/__pstl/cpu_algos/cpu_traits.h \ +third_party/libcxx/__pstl/cpu_algos/fill.h \ +third_party/libcxx/__pstl/cpu_algos/find_if.h \ +third_party/libcxx/__pstl/cpu_algos/for_each.h \ +third_party/libcxx/__pstl/cpu_algos/merge.h \ +third_party/libcxx/__pstl/cpu_algos/stable_sort.h \ +third_party/libcxx/__pstl/cpu_algos/transform.h \ +third_party/libcxx/__pstl/cpu_algos/transform_reduce.h \ +third_party/libcxx/__pstl/dispatch.h \ +third_party/libcxx/__pstl/handle_exception.h \ third_party/libcxx/__random/bernoulli_distribution.h \ third_party/libcxx/__random/binomial_distribution.h \ third_party/libcxx/__random/cauchy_distribution.h \ @@ -548,10 +640,10 @@ third_party/libcxx/__random/weibull_distribution.h \ third_party/libcxx/__ranges/access.h \ third_party/libcxx/__ranges/all.h \ third_party/libcxx/__ranges/as_rvalue_view.h \ +third_party/libcxx/__ranges/chunk_by_view.h \ third_party/libcxx/__ranges/common_view.h \ third_party/libcxx/__ranges/concepts.h \ third_party/libcxx/__ranges/container_compatible_range.h \ -third_party/libcxx/__ranges/copyable_box.h \ third_party/libcxx/__ranges/counted.h \ third_party/libcxx/__ranges/dangling.h \ third_party/libcxx/__ranges/data.h \ @@ -568,12 +660,14 @@ third_party/libcxx/__ranges/iota_view.h \ third_party/libcxx/__ranges/istream_view.h \ third_party/libcxx/__ranges/join_view.h \ third_party/libcxx/__ranges/lazy_split_view.h \ +third_party/libcxx/__ranges/movable_box.h \ third_party/libcxx/__ranges/non_propagating_cache.h \ third_party/libcxx/__ranges/owning_view.h \ third_party/libcxx/__ranges/range_adaptor.h \ third_party/libcxx/__ranges/rbegin.h \ third_party/libcxx/__ranges/ref_view.h \ third_party/libcxx/__ranges/rend.h \ +third_party/libcxx/__ranges/repeat_view.h \ third_party/libcxx/__ranges/reverse_view.h \ third_party/libcxx/__ranges/single_view.h \ third_party/libcxx/__ranges/size.h \ @@ -581,6 +675,7 @@ third_party/libcxx/__ranges/split_view.h \ third_party/libcxx/__ranges/subrange.h \ third_party/libcxx/__ranges/take_view.h \ third_party/libcxx/__ranges/take_while_view.h \ +third_party/libcxx/__ranges/to.h \ third_party/libcxx/__ranges/transform_view.h \ third_party/libcxx/__ranges/view_interface.h \ third_party/libcxx/__ranges/views.h \ @@ -590,25 +685,40 @@ third_party/libcxx/__std_mbstate_t.h \ third_party/libcxx/__stop_token/atomic_unique_lock.h \ third_party/libcxx/__stop_token/intrusive_list_view.h \ third_party/libcxx/__stop_token/intrusive_shared_ptr.h \ +third_party/libcxx/__stop_token/stop_callback.h \ +third_party/libcxx/__stop_token/stop_source.h \ +third_party/libcxx/__stop_token/stop_state.h \ +third_party/libcxx/__stop_token/stop_token.h \ third_party/libcxx/__string/char_traits.h \ third_party/libcxx/__string/constexpr_c_functions.h \ third_party/libcxx/__string/extern_template_lists.h \ +third_party/libcxx/__support/xlocale/__nop_locale_mgmt.h \ +third_party/libcxx/__support/xlocale/__posix_l_fallback.h \ +third_party/libcxx/__support/xlocale/__strtonum_fallback.h \ third_party/libcxx/__system_error/errc.h \ third_party/libcxx/__system_error/error_category.h \ third_party/libcxx/__system_error/error_code.h \ third_party/libcxx/__system_error/error_condition.h \ third_party/libcxx/__system_error/system_error.h \ +third_party/libcxx/__thread/formatter.h \ +third_party/libcxx/__thread/id.h \ +third_party/libcxx/__thread/jthread.h \ third_party/libcxx/__thread/poll_with_backoff.h \ +third_party/libcxx/__thread/support.h \ +third_party/libcxx/__thread/support/pthread.h \ +third_party/libcxx/__thread/this_thread.h \ +third_party/libcxx/__thread/thread.h \ third_party/libcxx/__thread/timed_backoff_policy.h \ -third_party/libcxx/__threading_support \ third_party/libcxx/__tree \ +third_party/libcxx/__tuple/find_index.h \ +third_party/libcxx/__tuple/ignore.h \ third_party/libcxx/__tuple/make_tuple_types.h \ -third_party/libcxx/__tuple/pair_like.h \ third_party/libcxx/__tuple/sfinae_helpers.h \ third_party/libcxx/__tuple/tuple_element.h \ third_party/libcxx/__tuple/tuple_indices.h \ third_party/libcxx/__tuple/tuple_like.h \ third_party/libcxx/__tuple/tuple_like_ext.h \ +third_party/libcxx/__tuple/tuple_like_no_subrange.h \ third_party/libcxx/__tuple/tuple_size.h \ third_party/libcxx/__tuple/tuple_types.h \ third_party/libcxx/__type_traits/add_const.h \ @@ -620,7 +730,6 @@ third_party/libcxx/__type_traits/add_volatile.h \ third_party/libcxx/__type_traits/aligned_storage.h \ third_party/libcxx/__type_traits/aligned_union.h \ third_party/libcxx/__type_traits/alignment_of.h \ -third_party/libcxx/__type_traits/apply_cv.h \ third_party/libcxx/__type_traits/can_extract_key.h \ third_party/libcxx/__type_traits/common_reference.h \ third_party/libcxx/__type_traits/common_type.h \ @@ -628,8 +737,10 @@ third_party/libcxx/__type_traits/conditional.h \ third_party/libcxx/__type_traits/conjunction.h \ third_party/libcxx/__type_traits/copy_cv.h \ third_party/libcxx/__type_traits/copy_cvref.h \ +third_party/libcxx/__type_traits/datasizeof.h \ third_party/libcxx/__type_traits/decay.h \ third_party/libcxx/__type_traits/dependent_type.h \ +third_party/libcxx/__type_traits/desugars_to.h \ third_party/libcxx/__type_traits/disjunction.h \ third_party/libcxx/__type_traits/enable_if.h \ third_party/libcxx/__type_traits/extent.h \ @@ -654,10 +765,7 @@ third_party/libcxx/__type_traits/is_const.h \ third_party/libcxx/__type_traits/is_constant_evaluated.h \ third_party/libcxx/__type_traits/is_constructible.h \ third_party/libcxx/__type_traits/is_convertible.h \ -third_party/libcxx/__type_traits/is_copy_assignable.h \ -third_party/libcxx/__type_traits/is_copy_constructible.h \ third_party/libcxx/__type_traits/is_core_convertible.h \ -third_party/libcxx/__type_traits/is_default_constructible.h \ third_party/libcxx/__type_traits/is_destructible.h \ third_party/libcxx/__type_traits/is_empty.h \ third_party/libcxx/__type_traits/is_enum.h \ @@ -670,20 +778,11 @@ third_party/libcxx/__type_traits/is_fundamental.h \ third_party/libcxx/__type_traits/is_implicitly_default_constructible.h \ third_party/libcxx/__type_traits/is_integral.h \ third_party/libcxx/__type_traits/is_literal_type.h \ -third_party/libcxx/__type_traits/is_member_function_pointer.h \ -third_party/libcxx/__type_traits/is_member_object_pointer.h \ third_party/libcxx/__type_traits/is_member_pointer.h \ -third_party/libcxx/__type_traits/is_move_assignable.h \ -third_party/libcxx/__type_traits/is_move_constructible.h \ third_party/libcxx/__type_traits/is_nothrow_assignable.h \ third_party/libcxx/__type_traits/is_nothrow_constructible.h \ third_party/libcxx/__type_traits/is_nothrow_convertible.h \ -third_party/libcxx/__type_traits/is_nothrow_copy_assignable.h \ -third_party/libcxx/__type_traits/is_nothrow_copy_constructible.h \ -third_party/libcxx/__type_traits/is_nothrow_default_constructible.h \ third_party/libcxx/__type_traits/is_nothrow_destructible.h \ -third_party/libcxx/__type_traits/is_nothrow_move_assignable.h \ -third_party/libcxx/__type_traits/is_nothrow_move_constructible.h \ third_party/libcxx/__type_traits/is_null_pointer.h \ third_party/libcxx/__type_traits/is_object.h \ third_party/libcxx/__type_traits/is_pod.h \ @@ -695,7 +794,6 @@ third_party/libcxx/__type_traits/is_reference_wrapper.h \ third_party/libcxx/__type_traits/is_referenceable.h \ third_party/libcxx/__type_traits/is_same.h \ third_party/libcxx/__type_traits/is_scalar.h \ -third_party/libcxx/__type_traits/is_scoped_enum.h \ third_party/libcxx/__type_traits/is_signed.h \ third_party/libcxx/__type_traits/is_signed_integer.h \ third_party/libcxx/__type_traits/is_specialization.h \ @@ -704,14 +802,10 @@ third_party/libcxx/__type_traits/is_swappable.h \ third_party/libcxx/__type_traits/is_trivial.h \ third_party/libcxx/__type_traits/is_trivially_assignable.h \ third_party/libcxx/__type_traits/is_trivially_constructible.h \ -third_party/libcxx/__type_traits/is_trivially_copy_assignable.h \ -third_party/libcxx/__type_traits/is_trivially_copy_constructible.h \ third_party/libcxx/__type_traits/is_trivially_copyable.h \ -third_party/libcxx/__type_traits/is_trivially_default_constructible.h \ third_party/libcxx/__type_traits/is_trivially_destructible.h \ third_party/libcxx/__type_traits/is_trivially_lexicographically_comparable.h \ -third_party/libcxx/__type_traits/is_trivially_move_assignable.h \ -third_party/libcxx/__type_traits/is_trivially_move_constructible.h \ +third_party/libcxx/__type_traits/is_trivially_relocatable.h \ third_party/libcxx/__type_traits/is_unbounded_array.h \ third_party/libcxx/__type_traits/is_union.h \ third_party/libcxx/__type_traits/is_unsigned.h \ @@ -728,7 +822,6 @@ third_party/libcxx/__type_traits/maybe_const.h \ third_party/libcxx/__type_traits/nat.h \ third_party/libcxx/__type_traits/negation.h \ third_party/libcxx/__type_traits/noexcept_move_assign_container.h \ -third_party/libcxx/__type_traits/predicate_traits.h \ third_party/libcxx/__type_traits/promote.h \ third_party/libcxx/__type_traits/rank.h \ third_party/libcxx/__type_traits/remove_all_extents.h \ @@ -749,23 +842,29 @@ third_party/libcxx/__type_traits/unwrap_ref.h \ third_party/libcxx/__type_traits/void_t.h \ third_party/libcxx/__undef_macros \ third_party/libcxx/__utility/as_const.h \ +third_party/libcxx/__utility/as_lvalue.h \ third_party/libcxx/__utility/auto_cast.h \ third_party/libcxx/__utility/cmp.h \ third_party/libcxx/__utility/convert_to_integral.h \ third_party/libcxx/__utility/declval.h \ +third_party/libcxx/__utility/empty.h \ third_party/libcxx/__utility/exception_guard.h \ third_party/libcxx/__utility/exchange.h \ third_party/libcxx/__utility/forward.h \ third_party/libcxx/__utility/forward_like.h \ third_party/libcxx/__utility/in_place.h \ third_party/libcxx/__utility/integer_sequence.h \ +third_party/libcxx/__utility/is_pointer_in_range.h \ +third_party/libcxx/__utility/is_valid_range.h \ third_party/libcxx/__utility/move.h \ +third_party/libcxx/__utility/no_destroy.h \ third_party/libcxx/__utility/pair.h \ third_party/libcxx/__utility/piecewise_construct.h \ third_party/libcxx/__utility/priority_tag.h \ +third_party/libcxx/__utility/private_constructor_tag.h \ third_party/libcxx/__utility/rel_ops.h \ +third_party/libcxx/__utility/small_buffer.h \ third_party/libcxx/__utility/swap.h \ -third_party/libcxx/__utility/terminate_on_exception.h \ third_party/libcxx/__utility/to_underlying.h \ third_party/libcxx/__utility/unreachable.h \ third_party/libcxx/__variant/monostate.h \ @@ -793,6 +892,1094 @@ third_party/libcxx/cmath \ third_party/libcxx/codecvt \ third_party/libcxx/compare \ third_party/libcxx/complex \ +third_party/libcxx/complex.h \ +third_party/libcxx/concepts \ +third_party/libcxx/condition_variable \ +third_party/libcxx/coroutine \ +third_party/libcxx/csetjmp \ +third_party/libcxx/csignal \ +third_party/libcxx/cstdarg \ +third_party/libcxx/cstdbool \ +third_party/libcxx/cstddef \ +third_party/libcxx/cstdint \ +third_party/libcxx/cstdio \ +third_party/libcxx/cstdlib \ +third_party/libcxx/cstring \ +third_party/libcxx/ctgmath \ +third_party/libcxx/ctime \ +third_party/libcxx/ctype.h \ +third_party/libcxx/cuchar \ +third_party/libcxx/cwchar \ +third_party/libcxx/cwctype \ +third_party/libcxx/deque \ +third_party/libcxx/errno.h \ +third_party/libcxx/exception \ +third_party/libcxx/execution \ +third_party/libcxx/expected \ +third_party/libcxx/experimental/__config \ +third_party/libcxx/experimental/__simd/aligned_tag.h \ +third_party/libcxx/experimental/__simd/declaration.h \ +third_party/libcxx/experimental/__simd/reference.h \ +third_party/libcxx/experimental/__simd/scalar.h \ +third_party/libcxx/experimental/__simd/simd.h \ +third_party/libcxx/experimental/__simd/simd_mask.h \ +third_party/libcxx/experimental/__simd/traits.h \ +third_party/libcxx/experimental/__simd/utility.h \ +third_party/libcxx/experimental/__simd/vec_ext.h \ +third_party/libcxx/experimental/iterator \ +third_party/libcxx/experimental/memory \ +third_party/libcxx/experimental/propagate_const \ +third_party/libcxx/experimental/simd \ +third_party/libcxx/experimental/type_traits \ +third_party/libcxx/experimental/utility \ +third_party/libcxx/ext/__hash \ +third_party/libcxx/ext/hash_map \ +third_party/libcxx/ext/hash_set \ +third_party/libcxx/fenv.h \ +third_party/libcxx/filesystem \ +third_party/libcxx/float.h \ +third_party/libcxx/format \ +third_party/libcxx/forward_list \ +third_party/libcxx/fstream \ +third_party/libcxx/functional \ +third_party/libcxx/future \ +third_party/libcxx/initializer_list \ +third_party/libcxx/inttypes.h \ +third_party/libcxx/iomanip \ +third_party/libcxx/ios \ +third_party/libcxx/iosfwd \ +third_party/libcxx/iostream \ +third_party/libcxx/istream \ +third_party/libcxx/iterator \ +third_party/libcxx/latch \ +third_party/libcxx/limits \ +third_party/libcxx/list \ +third_party/libcxx/locale \ +third_party/libcxx/locale.h \ +third_party/libcxx/map \ +third_party/libcxx/math.h \ +third_party/libcxx/mdspan \ +third_party/libcxx/memory \ +third_party/libcxx/memory_resource \ +third_party/libcxx/mutex \ +third_party/libcxx/new \ +third_party/libcxx/numbers \ +third_party/libcxx/numeric \ +third_party/libcxx/optional \ +third_party/libcxx/ostream \ +third_party/libcxx/print \ +third_party/libcxx/queue \ +third_party/libcxx/random \ +third_party/libcxx/ranges \ +third_party/libcxx/ratio \ +third_party/libcxx/regex \ +third_party/libcxx/scoped_allocator \ +third_party/libcxx/semaphore \ +third_party/libcxx/set \ +third_party/libcxx/shared_mutex \ +third_party/libcxx/source_location \ +third_party/libcxx/span \ +third_party/libcxx/sstream \ +third_party/libcxx/stack \ +third_party/libcxx/stdatomic.h \ +third_party/libcxx/stdbool.h \ +third_party/libcxx/stddef.h \ +third_party/libcxx/stdexcept \ +third_party/libcxx/stdint.h \ +third_party/libcxx/stdio.h \ +third_party/libcxx/stdlib.h \ +third_party/libcxx/stop_token \ +third_party/libcxx/streambuf \ +third_party/libcxx/string \ +third_party/libcxx/string.h \ +third_party/libcxx/string_view \ +third_party/libcxx/strstream \ +third_party/libcxx/syncstream \ +third_party/libcxx/system_error \ +third_party/libcxx/tgmath.h \ +third_party/libcxx/thread \ +third_party/libcxx/tuple \ +third_party/libcxx/type_traits \ +third_party/libcxx/typeindex \ +third_party/libcxx/typeinfo \ +third_party/libcxx/uchar.h \ +third_party/libcxx/unordered_map \ +third_party/libcxx/unordered_set \ +third_party/libcxx/utility \ +third_party/libcxx/valarray \ +third_party/libcxx/variant \ +third_party/libcxx/vector \ +third_party/libcxx/version \ +third_party/libcxx/wchar.h \ +third_party/libcxx/wctype.h \ +third_party/libcxx/fs/error.h \ +third_party/libcxx/fs/file_descriptor.h \ +third_party/libcxx/fs/format_string.h \ +third_party/libcxx/fs/path_parser.h \ +third_party/libcxx/fs/posix_compat.h \ +third_party/libcxx/fs/time_utils.h \ +third_party/libcxx/chrono_system_time_init.h \ +third_party/libcxx/iostream_init.h \ +third_party/libcxx/memory_resource_init_helper.h \ +third_party/libcxx/std_stream.h \ +third_party/libcxx/overridable_function.h \ +third_party/libcxx/atomic_support.h \ +third_party/libcxx/exception_libcxxabi.h \ +third_party/libcxx/exception_pointer_cxxabi.h \ +third_party/libcxx/to_chars_floating_point.h \ +third_party/libcxx/refstring.h \ +third_party/libcxx/config_elast.h \ +third_party/libcxx/sso_allocator.h \ +third_party/libcxx/stdexcept_default.h \ +third_party/libcxx/ryu/common.h \ +third_party/libcxx/ryu/d2fixed_full_table.h \ +third_party/libcxx/ryu/d2fixed.h \ +third_party/libcxx/ryu/d2s_full_table.h \ +third_party/libcxx/ryu/d2s.h \ +third_party/libcxx/ryu/d2s_intrinsics.h \ +third_party/libcxx/ryu/digit_table.h \ +third_party/libcxx/ryu/f2s.h \ +third_party/libcxx/ryu/ryu.h \ + +THIRD_PARTY_LIBCXX_A_SRCS = \ +third_party/libcxx/algorithm.cpp \ +third_party/libcxx/any.cpp \ +third_party/libcxx/atomic.cpp \ +third_party/libcxx/barrier.cpp \ +third_party/libcxx/bind.cpp \ +third_party/libcxx/call_once.cpp \ +third_party/libcxx/charconv.cpp \ +third_party/libcxx/chrono.cpp \ +third_party/libcxx/condition_variable.cpp \ +third_party/libcxx/condition_variable_destructor.cpp \ +third_party/libcxx/error_category.cpp \ +third_party/libcxx/exception.cpp \ +third_party/libcxx/expected.cpp \ +third_party/libcxx/fstream.cpp \ +third_party/libcxx/functional.cpp \ +third_party/libcxx/future.cpp \ +third_party/libcxx/hash.cpp \ +third_party/libcxx/ios.cpp \ +third_party/libcxx/ios.instantiations.cpp \ +third_party/libcxx/iostream.cpp \ +third_party/libcxx/legacy_pointer_safety.cpp \ +third_party/libcxx/locale.cpp \ +third_party/libcxx/memory.cpp \ +third_party/libcxx/memory_resource.cpp \ +third_party/libcxx/mutex.cpp \ +third_party/libcxx/mutex_destructor.cpp \ +third_party/libcxx/new.cpp \ +third_party/libcxx/new_handler.cpp \ +third_party/libcxx/new_helpers.cpp \ +third_party/libcxx/optional.cpp \ +third_party/libcxx/ostream.cpp \ +third_party/libcxx/print.cpp \ +third_party/libcxx/random.cpp \ +third_party/libcxx/random_shuffle.cpp \ +third_party/libcxx/regex.cpp \ +third_party/libcxx/shared_mutex.cpp \ +third_party/libcxx/stdexcept.cpp \ +third_party/libcxx/string.cpp \ +third_party/libcxx/strstream.cpp \ +third_party/libcxx/system_error.cpp \ +third_party/libcxx/thread.cpp \ +third_party/libcxx/typeinfo.cpp \ +third_party/libcxx/valarray.cpp \ +third_party/libcxx/variant.cpp \ +third_party/libcxx/vector.cpp \ +third_party/libcxx/verbose_abort.cpp \ +third_party/libcxx/fs/directory_entry.cpp \ +third_party/libcxx/fs/directory_iterator.cpp \ +third_party/libcxx/fs/filesystem_clock.cpp \ +third_party/libcxx/fs/filesystem_error.cpp \ +third_party/libcxx/fs/int128_builtins.cpp \ +third_party/libcxx/fs/operations.cpp \ +third_party/libcxx/fs/path.cpp \ +third_party/libcxx/ryu/d2fixed.cpp \ +third_party/libcxx/ryu/d2s.cpp \ +third_party/libcxx/ryu/f2s.cpp \ + +THIRD_PARTY_LIBCXX_A_HDRS_CHECKEM = \ +third_party/libcxx/__assertion_handler \ +third_party/libcxx/__algorithm/adjacent_find.h \ +third_party/libcxx/__algorithm/all_of.h \ +third_party/libcxx/__algorithm/any_of.h \ +third_party/libcxx/__algorithm/binary_search.h \ +third_party/libcxx/__algorithm/clamp.h \ +third_party/libcxx/__algorithm/comp.h \ +third_party/libcxx/__algorithm/comp_ref_type.h \ +third_party/libcxx/__algorithm/copy.h \ +third_party/libcxx/__algorithm/copy_backward.h \ +third_party/libcxx/__algorithm/copy_if.h \ +third_party/libcxx/__algorithm/copy_move_common.h \ +third_party/libcxx/__algorithm/copy_n.h \ +third_party/libcxx/__algorithm/count.h \ +third_party/libcxx/__algorithm/count_if.h \ +third_party/libcxx/__algorithm/equal.h \ +third_party/libcxx/__algorithm/equal_range.h \ +third_party/libcxx/__algorithm/fill.h \ +third_party/libcxx/__algorithm/fill_n.h \ +third_party/libcxx/__algorithm/find.h \ +third_party/libcxx/__algorithm/find_end.h \ +third_party/libcxx/__algorithm/find_first_of.h \ +third_party/libcxx/__algorithm/find_if.h \ +third_party/libcxx/__algorithm/find_if_not.h \ +third_party/libcxx/__algorithm/find_segment_if.h \ +third_party/libcxx/__algorithm/fold.h \ +third_party/libcxx/__algorithm/for_each.h \ +third_party/libcxx/__algorithm/for_each_n.h \ +third_party/libcxx/__algorithm/for_each_segment.h \ +third_party/libcxx/__algorithm/generate.h \ +third_party/libcxx/__algorithm/generate_n.h \ +third_party/libcxx/__algorithm/half_positive.h \ +third_party/libcxx/__algorithm/in_found_result.h \ +third_party/libcxx/__algorithm/in_fun_result.h \ +third_party/libcxx/__algorithm/in_in_out_result.h \ +third_party/libcxx/__algorithm/in_in_result.h \ +third_party/libcxx/__algorithm/in_out_out_result.h \ +third_party/libcxx/__algorithm/in_out_result.h \ +third_party/libcxx/__algorithm/includes.h \ +third_party/libcxx/__algorithm/inplace_merge.h \ +third_party/libcxx/__algorithm/is_heap.h \ +third_party/libcxx/__algorithm/is_heap_until.h \ +third_party/libcxx/__algorithm/is_partitioned.h \ +third_party/libcxx/__algorithm/is_permutation.h \ +third_party/libcxx/__algorithm/is_sorted.h \ +third_party/libcxx/__algorithm/is_sorted_until.h \ +third_party/libcxx/__algorithm/iter_swap.h \ +third_party/libcxx/__algorithm/iterator_operations.h \ +third_party/libcxx/__algorithm/lexicographical_compare.h \ +third_party/libcxx/__algorithm/lexicographical_compare_three_way.h \ +third_party/libcxx/__algorithm/lower_bound.h \ +third_party/libcxx/__algorithm/make_heap.h \ +third_party/libcxx/__algorithm/make_projected.h \ +third_party/libcxx/__algorithm/max.h \ +third_party/libcxx/__algorithm/max_element.h \ +third_party/libcxx/__algorithm/merge.h \ +third_party/libcxx/__algorithm/min.h \ +third_party/libcxx/__algorithm/min_element.h \ +third_party/libcxx/__algorithm/min_max_result.h \ +third_party/libcxx/__algorithm/minmax.h \ +third_party/libcxx/__algorithm/minmax_element.h \ +third_party/libcxx/__algorithm/mismatch.h \ +third_party/libcxx/__algorithm/move.h \ +third_party/libcxx/__algorithm/move_backward.h \ +third_party/libcxx/__algorithm/next_permutation.h \ +third_party/libcxx/__algorithm/none_of.h \ +third_party/libcxx/__algorithm/nth_element.h \ +third_party/libcxx/__algorithm/partial_sort.h \ +third_party/libcxx/__algorithm/partial_sort_copy.h \ +third_party/libcxx/__algorithm/partition.h \ +third_party/libcxx/__algorithm/partition_copy.h \ +third_party/libcxx/__algorithm/partition_point.h \ +third_party/libcxx/__algorithm/pop_heap.h \ +third_party/libcxx/__algorithm/prev_permutation.h \ +third_party/libcxx/__algorithm/pstl.h \ +third_party/libcxx/__algorithm/push_heap.h \ +third_party/libcxx/__algorithm/ranges_adjacent_find.h \ +third_party/libcxx/__algorithm/ranges_all_of.h \ +third_party/libcxx/__algorithm/ranges_any_of.h \ +third_party/libcxx/__algorithm/ranges_binary_search.h \ +third_party/libcxx/__algorithm/ranges_clamp.h \ +third_party/libcxx/__algorithm/ranges_contains.h \ +third_party/libcxx/__algorithm/ranges_contains_subrange.h \ +third_party/libcxx/__algorithm/ranges_copy.h \ +third_party/libcxx/__algorithm/ranges_copy_backward.h \ +third_party/libcxx/__algorithm/ranges_copy_if.h \ +third_party/libcxx/__algorithm/ranges_copy_n.h \ +third_party/libcxx/__algorithm/ranges_count.h \ +third_party/libcxx/__algorithm/ranges_count_if.h \ +third_party/libcxx/__algorithm/ranges_ends_with.h \ +third_party/libcxx/__algorithm/ranges_equal.h \ +third_party/libcxx/__algorithm/ranges_equal_range.h \ +third_party/libcxx/__algorithm/ranges_fill.h \ +third_party/libcxx/__algorithm/ranges_fill_n.h \ +third_party/libcxx/__algorithm/ranges_find.h \ +third_party/libcxx/__algorithm/ranges_find_end.h \ +third_party/libcxx/__algorithm/ranges_find_first_of.h \ +third_party/libcxx/__algorithm/ranges_find_if.h \ +third_party/libcxx/__algorithm/ranges_find_if_not.h \ +third_party/libcxx/__algorithm/ranges_find_last.h \ +third_party/libcxx/__algorithm/ranges_for_each.h \ +third_party/libcxx/__algorithm/ranges_for_each_n.h \ +third_party/libcxx/__algorithm/ranges_generate.h \ +third_party/libcxx/__algorithm/ranges_generate_n.h \ +third_party/libcxx/__algorithm/ranges_includes.h \ +third_party/libcxx/__algorithm/ranges_inplace_merge.h \ +third_party/libcxx/__algorithm/ranges_is_heap.h \ +third_party/libcxx/__algorithm/ranges_is_heap_until.h \ +third_party/libcxx/__algorithm/ranges_is_partitioned.h \ +third_party/libcxx/__algorithm/ranges_is_permutation.h \ +third_party/libcxx/__algorithm/ranges_is_sorted.h \ +third_party/libcxx/__algorithm/ranges_is_sorted_until.h \ +third_party/libcxx/__algorithm/ranges_iterator_concept.h \ +third_party/libcxx/__algorithm/ranges_lexicographical_compare.h \ +third_party/libcxx/__algorithm/ranges_lower_bound.h \ +third_party/libcxx/__algorithm/ranges_make_heap.h \ +third_party/libcxx/__algorithm/ranges_max.h \ +third_party/libcxx/__algorithm/ranges_max_element.h \ +third_party/libcxx/__algorithm/ranges_merge.h \ +third_party/libcxx/__algorithm/ranges_min.h \ +third_party/libcxx/__algorithm/ranges_min_element.h \ +third_party/libcxx/__algorithm/ranges_minmax.h \ +third_party/libcxx/__algorithm/ranges_minmax_element.h \ +third_party/libcxx/__algorithm/ranges_mismatch.h \ +third_party/libcxx/__algorithm/ranges_move.h \ +third_party/libcxx/__algorithm/ranges_move_backward.h \ +third_party/libcxx/__algorithm/ranges_next_permutation.h \ +third_party/libcxx/__algorithm/ranges_none_of.h \ +third_party/libcxx/__algorithm/ranges_nth_element.h \ +third_party/libcxx/__algorithm/ranges_partial_sort.h \ +third_party/libcxx/__algorithm/ranges_partial_sort_copy.h \ +third_party/libcxx/__algorithm/ranges_partition.h \ +third_party/libcxx/__algorithm/ranges_partition_copy.h \ +third_party/libcxx/__algorithm/ranges_partition_point.h \ +third_party/libcxx/__algorithm/ranges_pop_heap.h \ +third_party/libcxx/__algorithm/ranges_prev_permutation.h \ +third_party/libcxx/__algorithm/ranges_push_heap.h \ +third_party/libcxx/__algorithm/ranges_remove.h \ +third_party/libcxx/__algorithm/ranges_remove_copy.h \ +third_party/libcxx/__algorithm/ranges_remove_copy_if.h \ +third_party/libcxx/__algorithm/ranges_remove_if.h \ +third_party/libcxx/__algorithm/ranges_replace.h \ +third_party/libcxx/__algorithm/ranges_replace_copy.h \ +third_party/libcxx/__algorithm/ranges_replace_copy_if.h \ +third_party/libcxx/__algorithm/ranges_replace_if.h \ +third_party/libcxx/__algorithm/ranges_reverse.h \ +third_party/libcxx/__algorithm/ranges_reverse_copy.h \ +third_party/libcxx/__algorithm/ranges_rotate.h \ +third_party/libcxx/__algorithm/ranges_rotate_copy.h \ +third_party/libcxx/__algorithm/ranges_sample.h \ +third_party/libcxx/__algorithm/ranges_search.h \ +third_party/libcxx/__algorithm/ranges_search_n.h \ +third_party/libcxx/__algorithm/ranges_set_difference.h \ +third_party/libcxx/__algorithm/ranges_set_intersection.h \ +third_party/libcxx/__algorithm/ranges_set_symmetric_difference.h \ +third_party/libcxx/__algorithm/ranges_set_union.h \ +third_party/libcxx/__algorithm/ranges_shuffle.h \ +third_party/libcxx/__algorithm/ranges_sort.h \ +third_party/libcxx/__algorithm/ranges_sort_heap.h \ +third_party/libcxx/__algorithm/ranges_stable_partition.h \ +third_party/libcxx/__algorithm/ranges_stable_sort.h \ +third_party/libcxx/__algorithm/ranges_starts_with.h \ +third_party/libcxx/__algorithm/ranges_swap_ranges.h \ +third_party/libcxx/__algorithm/ranges_transform.h \ +third_party/libcxx/__algorithm/ranges_unique.h \ +third_party/libcxx/__algorithm/ranges_unique_copy.h \ +third_party/libcxx/__algorithm/ranges_upper_bound.h \ +third_party/libcxx/__algorithm/remove.h \ +third_party/libcxx/__algorithm/remove_copy.h \ +third_party/libcxx/__algorithm/remove_copy_if.h \ +third_party/libcxx/__algorithm/remove_if.h \ +third_party/libcxx/__algorithm/replace.h \ +third_party/libcxx/__algorithm/replace_copy.h \ +third_party/libcxx/__algorithm/replace_copy_if.h \ +third_party/libcxx/__algorithm/replace_if.h \ +third_party/libcxx/__algorithm/reverse.h \ +third_party/libcxx/__algorithm/reverse_copy.h \ +third_party/libcxx/__algorithm/rotate.h \ +third_party/libcxx/__algorithm/rotate_copy.h \ +third_party/libcxx/__algorithm/sample.h \ +third_party/libcxx/__algorithm/search.h \ +third_party/libcxx/__algorithm/search_n.h \ +third_party/libcxx/__algorithm/set_difference.h \ +third_party/libcxx/__algorithm/set_intersection.h \ +third_party/libcxx/__algorithm/set_symmetric_difference.h \ +third_party/libcxx/__algorithm/set_union.h \ +third_party/libcxx/__algorithm/shift_left.h \ +third_party/libcxx/__algorithm/shift_right.h \ +third_party/libcxx/__algorithm/shuffle.h \ +third_party/libcxx/__algorithm/sift_down.h \ +third_party/libcxx/__algorithm/simd_utils.h \ +third_party/libcxx/__algorithm/sort.h \ +third_party/libcxx/__algorithm/sort_heap.h \ +third_party/libcxx/__algorithm/stable_partition.h \ +third_party/libcxx/__algorithm/stable_sort.h \ +third_party/libcxx/__algorithm/swap_ranges.h \ +third_party/libcxx/__algorithm/three_way_comp_ref_type.h \ +third_party/libcxx/__algorithm/transform.h \ +third_party/libcxx/__algorithm/uniform_random_bit_generator_adaptor.h \ +third_party/libcxx/__algorithm/unique.h \ +third_party/libcxx/__algorithm/unique_copy.h \ +third_party/libcxx/__algorithm/unwrap_iter.h \ +third_party/libcxx/__algorithm/unwrap_range.h \ +third_party/libcxx/__algorithm/upper_bound.h \ +third_party/libcxx/__assert \ +third_party/libcxx/__atomic/aliases.h \ +third_party/libcxx/__atomic/atomic.h \ +third_party/libcxx/__atomic/atomic_base.h \ +third_party/libcxx/__atomic/atomic_flag.h \ +third_party/libcxx/__atomic/atomic_init.h \ +third_party/libcxx/__atomic/atomic_lock_free.h \ +third_party/libcxx/__atomic/atomic_ref.h \ +third_party/libcxx/__atomic/atomic_sync.h \ +third_party/libcxx/__atomic/check_memory_order.h \ +third_party/libcxx/__atomic/contention_t.h \ +third_party/libcxx/__atomic/cxx_atomic_impl.h \ +third_party/libcxx/__atomic/fence.h \ +third_party/libcxx/__atomic/is_always_lock_free.h \ +third_party/libcxx/__atomic/kill_dependency.h \ +third_party/libcxx/__atomic/memory_order.h \ +third_party/libcxx/__atomic/to_gcc_order.h \ +third_party/libcxx/__bit/bit_cast.h \ +third_party/libcxx/__bit/bit_ceil.h \ +third_party/libcxx/__bit/bit_floor.h \ +third_party/libcxx/__bit/bit_log2.h \ +third_party/libcxx/__bit/bit_width.h \ +third_party/libcxx/__bit/blsr.h \ +third_party/libcxx/__bit/byteswap.h \ +third_party/libcxx/__bit/countl.h \ +third_party/libcxx/__bit/countr.h \ +third_party/libcxx/__bit/endian.h \ +third_party/libcxx/__bit/has_single_bit.h \ +third_party/libcxx/__bit/invert_if.h \ +third_party/libcxx/__bit/popcount.h \ +third_party/libcxx/__bit/rotate.h \ +third_party/libcxx/__bit_reference \ +third_party/libcxx/__charconv/chars_format.h \ +third_party/libcxx/__charconv/from_chars_integral.h \ +third_party/libcxx/__charconv/from_chars_result.h \ +third_party/libcxx/__charconv/tables.h \ +third_party/libcxx/__charconv/to_chars.h \ +third_party/libcxx/__charconv/to_chars_base_10.h \ +third_party/libcxx/__charconv/to_chars_floating_point.h \ +third_party/libcxx/__charconv/to_chars_integral.h \ +third_party/libcxx/__charconv/to_chars_result.h \ +third_party/libcxx/__charconv/traits.h \ +third_party/libcxx/__chrono/calendar.h \ +third_party/libcxx/__chrono/concepts.h \ +third_party/libcxx/__chrono/convert_to_timespec.h \ +third_party/libcxx/__chrono/convert_to_tm.h \ +third_party/libcxx/__chrono/day.h \ +third_party/libcxx/__chrono/duration.h \ +third_party/libcxx/__chrono/exception.h \ +third_party/libcxx/__chrono/file_clock.h \ +third_party/libcxx/__chrono/formatter.h \ +third_party/libcxx/__chrono/hh_mm_ss.h \ +third_party/libcxx/__chrono/high_resolution_clock.h \ +third_party/libcxx/__chrono/leap_second.h \ +third_party/libcxx/__chrono/literals.h \ +third_party/libcxx/__chrono/local_info.h \ +third_party/libcxx/__chrono/month.h \ +third_party/libcxx/__chrono/month_weekday.h \ +third_party/libcxx/__chrono/monthday.h \ +third_party/libcxx/__chrono/ostream.h \ +third_party/libcxx/__chrono/parser_std_format_spec.h \ +third_party/libcxx/__chrono/statically_widen.h \ +third_party/libcxx/__chrono/steady_clock.h \ +third_party/libcxx/__chrono/sys_info.h \ +third_party/libcxx/__chrono/system_clock.h \ +third_party/libcxx/__chrono/time_point.h \ +third_party/libcxx/__chrono/time_zone.h \ +third_party/libcxx/__chrono/time_zone_link.h \ +third_party/libcxx/__chrono/tzdb.h \ +third_party/libcxx/__chrono/tzdb_list.h \ +third_party/libcxx/__chrono/weekday.h \ +third_party/libcxx/__chrono/year.h \ +third_party/libcxx/__chrono/year_month.h \ +third_party/libcxx/__chrono/year_month_day.h \ +third_party/libcxx/__chrono/year_month_weekday.h \ +third_party/libcxx/__chrono/zoned_time.h \ +third_party/libcxx/__compare/common_comparison_category.h \ +third_party/libcxx/__compare/compare_partial_order_fallback.h \ +third_party/libcxx/__compare/compare_strong_order_fallback.h \ +third_party/libcxx/__compare/compare_three_way.h \ +third_party/libcxx/__compare/compare_three_way_result.h \ +third_party/libcxx/__compare/compare_weak_order_fallback.h \ +third_party/libcxx/__compare/is_eq.h \ +third_party/libcxx/__compare/ordering.h \ +third_party/libcxx/__compare/partial_order.h \ +third_party/libcxx/__compare/strong_order.h \ +third_party/libcxx/__compare/synth_three_way.h \ +third_party/libcxx/__compare/three_way_comparable.h \ +third_party/libcxx/__compare/weak_order.h \ +third_party/libcxx/__concepts/arithmetic.h \ +third_party/libcxx/__concepts/assignable.h \ +third_party/libcxx/__concepts/boolean_testable.h \ +third_party/libcxx/__concepts/class_or_enum.h \ +third_party/libcxx/__concepts/common_reference_with.h \ +third_party/libcxx/__concepts/common_with.h \ +third_party/libcxx/__concepts/constructible.h \ +third_party/libcxx/__concepts/convertible_to.h \ +third_party/libcxx/__concepts/copyable.h \ +third_party/libcxx/__concepts/derived_from.h \ +third_party/libcxx/__concepts/destructible.h \ +third_party/libcxx/__concepts/different_from.h \ +third_party/libcxx/__concepts/equality_comparable.h \ +third_party/libcxx/__concepts/invocable.h \ +third_party/libcxx/__concepts/movable.h \ +third_party/libcxx/__concepts/predicate.h \ +third_party/libcxx/__concepts/regular.h \ +third_party/libcxx/__concepts/relation.h \ +third_party/libcxx/__concepts/same_as.h \ +third_party/libcxx/__concepts/semiregular.h \ +third_party/libcxx/__concepts/swappable.h \ +third_party/libcxx/__concepts/totally_ordered.h \ +third_party/libcxx/__condition_variable/condition_variable.h \ +third_party/libcxx/__config \ +third_party/libcxx/__config_site \ +third_party/libcxx/__configuration/abi.h \ +third_party/libcxx/__configuration/availability.h \ +third_party/libcxx/__configuration/compiler.h \ +third_party/libcxx/__configuration/language.h \ +third_party/libcxx/__configuration/platform.h \ +third_party/libcxx/__coroutine/coroutine_handle.h \ +third_party/libcxx/__coroutine/coroutine_traits.h \ +third_party/libcxx/__coroutine/noop_coroutine_handle.h \ +third_party/libcxx/__coroutine/trivial_awaitables.h \ +third_party/libcxx/__debug_utils/randomize_range.h \ +third_party/libcxx/__debug_utils/sanitizers.h \ +third_party/libcxx/__debug_utils/strict_weak_ordering_check.h \ +third_party/libcxx/__exception/exception.h \ +third_party/libcxx/__exception/exception_ptr.h \ +third_party/libcxx/__exception/nested_exception.h \ +third_party/libcxx/__exception/operations.h \ +third_party/libcxx/__exception/terminate.h \ +third_party/libcxx/__expected/bad_expected_access.h \ +third_party/libcxx/__expected/expected.h \ +third_party/libcxx/__expected/unexpect.h \ +third_party/libcxx/__expected/unexpected.h \ +third_party/libcxx/__filesystem/copy_options.h \ +third_party/libcxx/__filesystem/directory_entry.h \ +third_party/libcxx/__filesystem/directory_iterator.h \ +third_party/libcxx/__filesystem/directory_options.h \ +third_party/libcxx/__filesystem/file_status.h \ +third_party/libcxx/__filesystem/file_time_type.h \ +third_party/libcxx/__filesystem/file_type.h \ +third_party/libcxx/__filesystem/filesystem_error.h \ +third_party/libcxx/__filesystem/operations.h \ +third_party/libcxx/__filesystem/path.h \ +third_party/libcxx/__filesystem/path_iterator.h \ +third_party/libcxx/__filesystem/perm_options.h \ +third_party/libcxx/__filesystem/perms.h \ +third_party/libcxx/__filesystem/recursive_directory_iterator.h \ +third_party/libcxx/__filesystem/space_info.h \ +third_party/libcxx/__filesystem/u8path.h \ +third_party/libcxx/__format/buffer.h \ +third_party/libcxx/__format/concepts.h \ +third_party/libcxx/__format/enable_insertable.h \ +third_party/libcxx/__format/escaped_output_table.h \ +third_party/libcxx/__format/extended_grapheme_cluster_table.h \ +third_party/libcxx/__format/format_arg.h \ +third_party/libcxx/__format/format_args.h \ +third_party/libcxx/__format/format_context.h \ +third_party/libcxx/__format/format_error.h \ +third_party/libcxx/__format/format_functions.h \ +third_party/libcxx/__format/format_parse_context.h \ +third_party/libcxx/__format/format_string.h \ +third_party/libcxx/__format/format_to_n_result.h \ +third_party/libcxx/__format/formatter.h \ +third_party/libcxx/__format/formatter_bool.h \ +third_party/libcxx/__format/formatter_char.h \ +third_party/libcxx/__format/formatter_floating_point.h \ +third_party/libcxx/__format/formatter_integer.h \ +third_party/libcxx/__format/formatter_integral.h \ +third_party/libcxx/__format/formatter_output.h \ +third_party/libcxx/__format/formatter_pointer.h \ +third_party/libcxx/__format/formatter_string.h \ +third_party/libcxx/__format/formatter_tuple.h \ +third_party/libcxx/__format/indic_conjunct_break_table.h \ +third_party/libcxx/__format/parser_std_format_spec.h \ +third_party/libcxx/__format/unicode.h \ +third_party/libcxx/__format/width_estimation_table.h \ +third_party/libcxx/__format/write_escaped.h \ +third_party/libcxx/__functional/binary_function.h \ +third_party/libcxx/__functional/binary_negate.h \ +third_party/libcxx/__functional/bind.h \ +third_party/libcxx/__functional/bind_back.h \ +third_party/libcxx/__functional/bind_front.h \ +third_party/libcxx/__functional/binder1st.h \ +third_party/libcxx/__functional/binder2nd.h \ +third_party/libcxx/__functional/compose.h \ +third_party/libcxx/__functional/default_searcher.h \ +third_party/libcxx/__functional/function.h \ +third_party/libcxx/__functional/hash.h \ +third_party/libcxx/__functional/identity.h \ +third_party/libcxx/__functional/invoke.h \ +third_party/libcxx/__functional/is_transparent.h \ +third_party/libcxx/__functional/mem_fn.h \ +third_party/libcxx/__functional/mem_fun_ref.h \ +third_party/libcxx/__functional/not_fn.h \ +third_party/libcxx/__functional/operations.h \ +third_party/libcxx/__functional/perfect_forward.h \ +third_party/libcxx/__functional/pointer_to_binary_function.h \ +third_party/libcxx/__functional/pointer_to_unary_function.h \ +third_party/libcxx/__functional/ranges_operations.h \ +third_party/libcxx/__functional/reference_wrapper.h \ +third_party/libcxx/__functional/unary_function.h \ +third_party/libcxx/__functional/unary_negate.h \ +third_party/libcxx/__functional/weak_result_type.h \ +third_party/libcxx/__fwd/array.h \ +third_party/libcxx/__fwd/bit_reference.h \ +third_party/libcxx/__fwd/complex.h \ +third_party/libcxx/__fwd/deque.h \ +third_party/libcxx/__fwd/format.h \ +third_party/libcxx/__fwd/fstream.h \ +third_party/libcxx/__fwd/functional.h \ +third_party/libcxx/__fwd/ios.h \ +third_party/libcxx/__fwd/istream.h \ +third_party/libcxx/__fwd/mdspan.h \ +third_party/libcxx/__fwd/memory.h \ +third_party/libcxx/__fwd/memory_resource.h \ +third_party/libcxx/__fwd/ostream.h \ +third_party/libcxx/__fwd/pair.h \ +third_party/libcxx/__fwd/queue.h \ +third_party/libcxx/__fwd/span.h \ +third_party/libcxx/__fwd/sstream.h \ +third_party/libcxx/__fwd/stack.h \ +third_party/libcxx/__fwd/streambuf.h \ +third_party/libcxx/__fwd/string.h \ +third_party/libcxx/__fwd/string_view.h \ +third_party/libcxx/__fwd/subrange.h \ +third_party/libcxx/__fwd/tuple.h \ +third_party/libcxx/__fwd/vector.h \ +third_party/libcxx/__hash_table \ +third_party/libcxx/__ios/fpos.h \ +third_party/libcxx/__iterator/access.h \ +third_party/libcxx/__iterator/advance.h \ +third_party/libcxx/__iterator/aliasing_iterator.h \ +third_party/libcxx/__iterator/back_insert_iterator.h \ +third_party/libcxx/__iterator/bounded_iter.h \ +third_party/libcxx/__iterator/common_iterator.h \ +third_party/libcxx/__iterator/concepts.h \ +third_party/libcxx/__iterator/counted_iterator.h \ +third_party/libcxx/__iterator/cpp17_iterator_concepts.h \ +third_party/libcxx/__iterator/data.h \ +third_party/libcxx/__iterator/default_sentinel.h \ +third_party/libcxx/__iterator/distance.h \ +third_party/libcxx/__iterator/empty.h \ +third_party/libcxx/__iterator/erase_if_container.h \ +third_party/libcxx/__iterator/front_insert_iterator.h \ +third_party/libcxx/__iterator/incrementable_traits.h \ +third_party/libcxx/__iterator/indirectly_comparable.h \ +third_party/libcxx/__iterator/insert_iterator.h \ +third_party/libcxx/__iterator/istream_iterator.h \ +third_party/libcxx/__iterator/istreambuf_iterator.h \ +third_party/libcxx/__iterator/iter_move.h \ +third_party/libcxx/__iterator/iter_swap.h \ +third_party/libcxx/__iterator/iterator.h \ +third_party/libcxx/__iterator/iterator_traits.h \ +third_party/libcxx/__iterator/iterator_with_data.h \ +third_party/libcxx/__iterator/mergeable.h \ +third_party/libcxx/__iterator/move_iterator.h \ +third_party/libcxx/__iterator/move_sentinel.h \ +third_party/libcxx/__iterator/next.h \ +third_party/libcxx/__iterator/ostream_iterator.h \ +third_party/libcxx/__iterator/ostreambuf_iterator.h \ +third_party/libcxx/__iterator/permutable.h \ +third_party/libcxx/__iterator/prev.h \ +third_party/libcxx/__iterator/projected.h \ +third_party/libcxx/__iterator/ranges_iterator_traits.h \ +third_party/libcxx/__iterator/readable_traits.h \ +third_party/libcxx/__iterator/reverse_access.h \ +third_party/libcxx/__iterator/reverse_iterator.h \ +third_party/libcxx/__iterator/segmented_iterator.h \ +third_party/libcxx/__iterator/size.h \ +third_party/libcxx/__iterator/sortable.h \ +third_party/libcxx/__iterator/unreachable_sentinel.h \ +third_party/libcxx/__iterator/wrap_iter.h \ +third_party/libcxx/__locale \ +third_party/libcxx/__locale_dir/locale_base_api.h \ +third_party/libcxx/__locale_dir/locale_base_api/bsd_locale_defaults.h \ +third_party/libcxx/__locale_dir/locale_base_api/bsd_locale_fallbacks.h \ +third_party/libcxx/__locale_dir/locale_base_api/locale_guard.h \ +third_party/libcxx/__math/abs.h \ +third_party/libcxx/__math/copysign.h \ +third_party/libcxx/__math/error_functions.h \ +third_party/libcxx/__math/exponential_functions.h \ +third_party/libcxx/__math/fdim.h \ +third_party/libcxx/__math/fma.h \ +third_party/libcxx/__math/gamma.h \ +third_party/libcxx/__math/hyperbolic_functions.h \ +third_party/libcxx/__math/hypot.h \ +third_party/libcxx/__math/inverse_hyperbolic_functions.h \ +third_party/libcxx/__math/inverse_trigonometric_functions.h \ +third_party/libcxx/__math/logarithms.h \ +third_party/libcxx/__math/min_max.h \ +third_party/libcxx/__math/modulo.h \ +third_party/libcxx/__math/remainder.h \ +third_party/libcxx/__math/roots.h \ +third_party/libcxx/__math/rounding_functions.h \ +third_party/libcxx/__math/special_functions.h \ +third_party/libcxx/__math/traits.h \ +third_party/libcxx/__math/trigonometric_functions.h \ +third_party/libcxx/__mbstate_t.h \ +third_party/libcxx/__mdspan/default_accessor.h \ +third_party/libcxx/__mdspan/extents.h \ +third_party/libcxx/__mdspan/layout_left.h \ +third_party/libcxx/__mdspan/layout_right.h \ +third_party/libcxx/__mdspan/layout_stride.h \ +third_party/libcxx/__mdspan/mdspan.h \ +third_party/libcxx/__memory/addressof.h \ +third_party/libcxx/__memory/align.h \ +third_party/libcxx/__memory/aligned_alloc.h \ +third_party/libcxx/__memory/allocate_at_least.h \ +third_party/libcxx/__memory/allocation_guard.h \ +third_party/libcxx/__memory/allocator.h \ +third_party/libcxx/__memory/allocator_arg_t.h \ +third_party/libcxx/__memory/allocator_destructor.h \ +third_party/libcxx/__memory/allocator_traits.h \ +third_party/libcxx/__memory/assume_aligned.h \ +third_party/libcxx/__memory/auto_ptr.h \ +third_party/libcxx/__memory/builtin_new_allocator.h \ +third_party/libcxx/__memory/compressed_pair.h \ +third_party/libcxx/__memory/concepts.h \ +third_party/libcxx/__memory/construct_at.h \ +third_party/libcxx/__memory/destruct_n.h \ +third_party/libcxx/__memory/inout_ptr.h \ +third_party/libcxx/__memory/out_ptr.h \ +third_party/libcxx/__memory/pointer_traits.h \ +third_party/libcxx/__memory/ranges_construct_at.h \ +third_party/libcxx/__memory/ranges_uninitialized_algorithms.h \ +third_party/libcxx/__memory/raw_storage_iterator.h \ +third_party/libcxx/__memory/shared_ptr.h \ +third_party/libcxx/__memory/swap_allocator.h \ +third_party/libcxx/__memory/temp_value.h \ +third_party/libcxx/__memory/temporary_buffer.h \ +third_party/libcxx/__memory/uninitialized_algorithms.h \ +third_party/libcxx/__memory/unique_ptr.h \ +third_party/libcxx/__memory/uses_allocator.h \ +third_party/libcxx/__memory/uses_allocator_construction.h \ +third_party/libcxx/__memory/voidify.h \ +third_party/libcxx/__memory_resource/memory_resource.h \ +third_party/libcxx/__memory_resource/monotonic_buffer_resource.h \ +third_party/libcxx/__memory_resource/polymorphic_allocator.h \ +third_party/libcxx/__memory_resource/pool_options.h \ +third_party/libcxx/__memory_resource/synchronized_pool_resource.h \ +third_party/libcxx/__memory_resource/unsynchronized_pool_resource.h \ +third_party/libcxx/__mutex/lock_guard.h \ +third_party/libcxx/__mutex/mutex.h \ +third_party/libcxx/__mutex/once_flag.h \ +third_party/libcxx/__mutex/tag_types.h \ +third_party/libcxx/__mutex/unique_lock.h \ +third_party/libcxx/__node_handle \ +third_party/libcxx/__numeric/accumulate.h \ +third_party/libcxx/__numeric/adjacent_difference.h \ +third_party/libcxx/__numeric/exclusive_scan.h \ +third_party/libcxx/__numeric/gcd_lcm.h \ +third_party/libcxx/__numeric/inclusive_scan.h \ +third_party/libcxx/__numeric/inner_product.h \ +third_party/libcxx/__numeric/iota.h \ +third_party/libcxx/__numeric/midpoint.h \ +third_party/libcxx/__numeric/partial_sum.h \ +third_party/libcxx/__numeric/pstl.h \ +third_party/libcxx/__numeric/reduce.h \ +third_party/libcxx/__numeric/saturation_arithmetic.h \ +third_party/libcxx/__numeric/transform_exclusive_scan.h \ +third_party/libcxx/__numeric/transform_inclusive_scan.h \ +third_party/libcxx/__numeric/transform_reduce.h \ +third_party/libcxx/__ostream/basic_ostream.h \ +third_party/libcxx/__ostream/print.h \ +third_party/libcxx/__pstl/backend.h \ +third_party/libcxx/__pstl/backend_fwd.h \ +third_party/libcxx/__pstl/backends/default.h \ +third_party/libcxx/__pstl/backends/libdispatch.h \ +third_party/libcxx/__pstl/backends/serial.h \ +third_party/libcxx/__pstl/backends/std_thread.h \ +third_party/libcxx/__pstl/cpu_algos/any_of.h \ +third_party/libcxx/__pstl/cpu_algos/cpu_traits.h \ +third_party/libcxx/__pstl/cpu_algos/fill.h \ +third_party/libcxx/__pstl/cpu_algos/find_if.h \ +third_party/libcxx/__pstl/cpu_algos/for_each.h \ +third_party/libcxx/__pstl/cpu_algos/merge.h \ +third_party/libcxx/__pstl/cpu_algos/stable_sort.h \ +third_party/libcxx/__pstl/cpu_algos/transform.h \ +third_party/libcxx/__pstl/cpu_algos/transform_reduce.h \ +third_party/libcxx/__pstl/dispatch.h \ +third_party/libcxx/__pstl/handle_exception.h \ +third_party/libcxx/__random/bernoulli_distribution.h \ +third_party/libcxx/__random/binomial_distribution.h \ +third_party/libcxx/__random/cauchy_distribution.h \ +third_party/libcxx/__random/chi_squared_distribution.h \ +third_party/libcxx/__random/clamp_to_integral.h \ +third_party/libcxx/__random/default_random_engine.h \ +third_party/libcxx/__random/discard_block_engine.h \ +third_party/libcxx/__random/discrete_distribution.h \ +third_party/libcxx/__random/exponential_distribution.h \ +third_party/libcxx/__random/extreme_value_distribution.h \ +third_party/libcxx/__random/fisher_f_distribution.h \ +third_party/libcxx/__random/gamma_distribution.h \ +third_party/libcxx/__random/generate_canonical.h \ +third_party/libcxx/__random/geometric_distribution.h \ +third_party/libcxx/__random/independent_bits_engine.h \ +third_party/libcxx/__random/is_seed_sequence.h \ +third_party/libcxx/__random/is_valid.h \ +third_party/libcxx/__random/knuth_b.h \ +third_party/libcxx/__random/linear_congruential_engine.h \ +third_party/libcxx/__random/log2.h \ +third_party/libcxx/__random/lognormal_distribution.h \ +third_party/libcxx/__random/mersenne_twister_engine.h \ +third_party/libcxx/__random/negative_binomial_distribution.h \ +third_party/libcxx/__random/normal_distribution.h \ +third_party/libcxx/__random/piecewise_constant_distribution.h \ +third_party/libcxx/__random/piecewise_linear_distribution.h \ +third_party/libcxx/__random/poisson_distribution.h \ +third_party/libcxx/__random/random_device.h \ +third_party/libcxx/__random/ranlux.h \ +third_party/libcxx/__random/seed_seq.h \ +third_party/libcxx/__random/shuffle_order_engine.h \ +third_party/libcxx/__random/student_t_distribution.h \ +third_party/libcxx/__random/subtract_with_carry_engine.h \ +third_party/libcxx/__random/uniform_int_distribution.h \ +third_party/libcxx/__random/uniform_random_bit_generator.h \ +third_party/libcxx/__random/uniform_real_distribution.h \ +third_party/libcxx/__random/weibull_distribution.h \ +third_party/libcxx/__ranges/access.h \ +third_party/libcxx/__ranges/all.h \ +third_party/libcxx/__ranges/as_rvalue_view.h \ +third_party/libcxx/__ranges/chunk_by_view.h \ +third_party/libcxx/__ranges/common_view.h \ +third_party/libcxx/__ranges/concepts.h \ +third_party/libcxx/__ranges/container_compatible_range.h \ +third_party/libcxx/__ranges/counted.h \ +third_party/libcxx/__ranges/dangling.h \ +third_party/libcxx/__ranges/data.h \ +third_party/libcxx/__ranges/drop_view.h \ +third_party/libcxx/__ranges/drop_while_view.h \ +third_party/libcxx/__ranges/elements_view.h \ +third_party/libcxx/__ranges/empty.h \ +third_party/libcxx/__ranges/empty_view.h \ +third_party/libcxx/__ranges/enable_borrowed_range.h \ +third_party/libcxx/__ranges/enable_view.h \ +third_party/libcxx/__ranges/filter_view.h \ +third_party/libcxx/__ranges/from_range.h \ +third_party/libcxx/__ranges/iota_view.h \ +third_party/libcxx/__ranges/istream_view.h \ +third_party/libcxx/__ranges/join_view.h \ +third_party/libcxx/__ranges/lazy_split_view.h \ +third_party/libcxx/__ranges/movable_box.h \ +third_party/libcxx/__ranges/non_propagating_cache.h \ +third_party/libcxx/__ranges/owning_view.h \ +third_party/libcxx/__ranges/range_adaptor.h \ +third_party/libcxx/__ranges/rbegin.h \ +third_party/libcxx/__ranges/ref_view.h \ +third_party/libcxx/__ranges/rend.h \ +third_party/libcxx/__ranges/repeat_view.h \ +third_party/libcxx/__ranges/reverse_view.h \ +third_party/libcxx/__ranges/single_view.h \ +third_party/libcxx/__ranges/size.h \ +third_party/libcxx/__ranges/split_view.h \ +third_party/libcxx/__ranges/subrange.h \ +third_party/libcxx/__ranges/take_view.h \ +third_party/libcxx/__ranges/take_while_view.h \ +third_party/libcxx/__ranges/to.h \ +third_party/libcxx/__ranges/transform_view.h \ +third_party/libcxx/__ranges/view_interface.h \ +third_party/libcxx/__ranges/views.h \ +third_party/libcxx/__ranges/zip_view.h \ +third_party/libcxx/__split_buffer \ +third_party/libcxx/__std_mbstate_t.h \ +third_party/libcxx/__stop_token/atomic_unique_lock.h \ +third_party/libcxx/__stop_token/intrusive_list_view.h \ +third_party/libcxx/__stop_token/intrusive_shared_ptr.h \ +third_party/libcxx/__stop_token/stop_callback.h \ +third_party/libcxx/__stop_token/stop_source.h \ +third_party/libcxx/__stop_token/stop_state.h \ +third_party/libcxx/__stop_token/stop_token.h \ +third_party/libcxx/__string/char_traits.h \ +third_party/libcxx/__string/constexpr_c_functions.h \ +third_party/libcxx/__string/extern_template_lists.h \ +third_party/libcxx/__support/xlocale/__nop_locale_mgmt.h \ +third_party/libcxx/__support/xlocale/__posix_l_fallback.h \ +third_party/libcxx/__support/xlocale/__strtonum_fallback.h \ +third_party/libcxx/__system_error/errc.h \ +third_party/libcxx/__system_error/error_category.h \ +third_party/libcxx/__system_error/error_code.h \ +third_party/libcxx/__system_error/error_condition.h \ +third_party/libcxx/__system_error/system_error.h \ +third_party/libcxx/__thread/formatter.h \ +third_party/libcxx/__thread/id.h \ +third_party/libcxx/__thread/jthread.h \ +third_party/libcxx/__thread/poll_with_backoff.h \ +third_party/libcxx/__thread/support.h \ +third_party/libcxx/__thread/support/pthread.h \ +third_party/libcxx/__thread/this_thread.h \ +third_party/libcxx/__thread/thread.h \ +third_party/libcxx/__thread/timed_backoff_policy.h \ +third_party/libcxx/__tree \ +third_party/libcxx/__tuple/find_index.h \ +third_party/libcxx/__tuple/ignore.h \ +third_party/libcxx/__tuple/make_tuple_types.h \ +third_party/libcxx/__tuple/sfinae_helpers.h \ +third_party/libcxx/__tuple/tuple_element.h \ +third_party/libcxx/__tuple/tuple_indices.h \ +third_party/libcxx/__tuple/tuple_like.h \ +third_party/libcxx/__tuple/tuple_like_ext.h \ +third_party/libcxx/__tuple/tuple_like_no_subrange.h \ +third_party/libcxx/__tuple/tuple_size.h \ +third_party/libcxx/__tuple/tuple_types.h \ +third_party/libcxx/__type_traits/add_const.h \ +third_party/libcxx/__type_traits/add_cv.h \ +third_party/libcxx/__type_traits/add_lvalue_reference.h \ +third_party/libcxx/__type_traits/add_pointer.h \ +third_party/libcxx/__type_traits/add_rvalue_reference.h \ +third_party/libcxx/__type_traits/add_volatile.h \ +third_party/libcxx/__type_traits/aligned_storage.h \ +third_party/libcxx/__type_traits/aligned_union.h \ +third_party/libcxx/__type_traits/alignment_of.h \ +third_party/libcxx/__type_traits/can_extract_key.h \ +third_party/libcxx/__type_traits/common_reference.h \ +third_party/libcxx/__type_traits/common_type.h \ +third_party/libcxx/__type_traits/conditional.h \ +third_party/libcxx/__type_traits/conjunction.h \ +third_party/libcxx/__type_traits/copy_cv.h \ +third_party/libcxx/__type_traits/copy_cvref.h \ +third_party/libcxx/__type_traits/datasizeof.h \ +third_party/libcxx/__type_traits/decay.h \ +third_party/libcxx/__type_traits/dependent_type.h \ +third_party/libcxx/__type_traits/desugars_to.h \ +third_party/libcxx/__type_traits/disjunction.h \ +third_party/libcxx/__type_traits/enable_if.h \ +third_party/libcxx/__type_traits/extent.h \ +third_party/libcxx/__type_traits/has_unique_object_representation.h \ +third_party/libcxx/__type_traits/has_virtual_destructor.h \ +third_party/libcxx/__type_traits/integral_constant.h \ +third_party/libcxx/__type_traits/invoke.h \ +third_party/libcxx/__type_traits/is_abstract.h \ +third_party/libcxx/__type_traits/is_aggregate.h \ +third_party/libcxx/__type_traits/is_allocator.h \ +third_party/libcxx/__type_traits/is_always_bitcastable.h \ +third_party/libcxx/__type_traits/is_arithmetic.h \ +third_party/libcxx/__type_traits/is_array.h \ +third_party/libcxx/__type_traits/is_assignable.h \ +third_party/libcxx/__type_traits/is_base_of.h \ +third_party/libcxx/__type_traits/is_bounded_array.h \ +third_party/libcxx/__type_traits/is_callable.h \ +third_party/libcxx/__type_traits/is_char_like_type.h \ +third_party/libcxx/__type_traits/is_class.h \ +third_party/libcxx/__type_traits/is_compound.h \ +third_party/libcxx/__type_traits/is_const.h \ +third_party/libcxx/__type_traits/is_constant_evaluated.h \ +third_party/libcxx/__type_traits/is_constructible.h \ +third_party/libcxx/__type_traits/is_convertible.h \ +third_party/libcxx/__type_traits/is_core_convertible.h \ +third_party/libcxx/__type_traits/is_destructible.h \ +third_party/libcxx/__type_traits/is_empty.h \ +third_party/libcxx/__type_traits/is_enum.h \ +third_party/libcxx/__type_traits/is_equality_comparable.h \ +third_party/libcxx/__type_traits/is_execution_policy.h \ +third_party/libcxx/__type_traits/is_final.h \ +third_party/libcxx/__type_traits/is_floating_point.h \ +third_party/libcxx/__type_traits/is_function.h \ +third_party/libcxx/__type_traits/is_fundamental.h \ +third_party/libcxx/__type_traits/is_implicitly_default_constructible.h \ +third_party/libcxx/__type_traits/is_integral.h \ +third_party/libcxx/__type_traits/is_literal_type.h \ +third_party/libcxx/__type_traits/is_member_pointer.h \ +third_party/libcxx/__type_traits/is_nothrow_assignable.h \ +third_party/libcxx/__type_traits/is_nothrow_constructible.h \ +third_party/libcxx/__type_traits/is_nothrow_convertible.h \ +third_party/libcxx/__type_traits/is_nothrow_destructible.h \ +third_party/libcxx/__type_traits/is_null_pointer.h \ +third_party/libcxx/__type_traits/is_object.h \ +third_party/libcxx/__type_traits/is_pod.h \ +third_party/libcxx/__type_traits/is_pointer.h \ +third_party/libcxx/__type_traits/is_polymorphic.h \ +third_party/libcxx/__type_traits/is_primary_template.h \ +third_party/libcxx/__type_traits/is_reference.h \ +third_party/libcxx/__type_traits/is_reference_wrapper.h \ +third_party/libcxx/__type_traits/is_referenceable.h \ +third_party/libcxx/__type_traits/is_same.h \ +third_party/libcxx/__type_traits/is_scalar.h \ +third_party/libcxx/__type_traits/is_signed.h \ +third_party/libcxx/__type_traits/is_signed_integer.h \ +third_party/libcxx/__type_traits/is_specialization.h \ +third_party/libcxx/__type_traits/is_standard_layout.h \ +third_party/libcxx/__type_traits/is_swappable.h \ +third_party/libcxx/__type_traits/is_trivial.h \ +third_party/libcxx/__type_traits/is_trivially_assignable.h \ +third_party/libcxx/__type_traits/is_trivially_constructible.h \ +third_party/libcxx/__type_traits/is_trivially_copyable.h \ +third_party/libcxx/__type_traits/is_trivially_destructible.h \ +third_party/libcxx/__type_traits/is_trivially_lexicographically_comparable.h \ +third_party/libcxx/__type_traits/is_trivially_relocatable.h \ +third_party/libcxx/__type_traits/is_unbounded_array.h \ +third_party/libcxx/__type_traits/is_union.h \ +third_party/libcxx/__type_traits/is_unsigned.h \ +third_party/libcxx/__type_traits/is_unsigned_integer.h \ +third_party/libcxx/__type_traits/is_valid_expansion.h \ +third_party/libcxx/__type_traits/is_void.h \ +third_party/libcxx/__type_traits/is_volatile.h \ +third_party/libcxx/__type_traits/lazy.h \ +third_party/libcxx/__type_traits/make_32_64_or_128_bit.h \ +third_party/libcxx/__type_traits/make_const_lvalue_ref.h \ +third_party/libcxx/__type_traits/make_signed.h \ +third_party/libcxx/__type_traits/make_unsigned.h \ +third_party/libcxx/__type_traits/maybe_const.h \ +third_party/libcxx/__type_traits/nat.h \ +third_party/libcxx/__type_traits/negation.h \ +third_party/libcxx/__type_traits/noexcept_move_assign_container.h \ +third_party/libcxx/__type_traits/promote.h \ +third_party/libcxx/__type_traits/rank.h \ +third_party/libcxx/__type_traits/remove_all_extents.h \ +third_party/libcxx/__type_traits/remove_const.h \ +third_party/libcxx/__type_traits/remove_const_ref.h \ +third_party/libcxx/__type_traits/remove_cv.h \ +third_party/libcxx/__type_traits/remove_cvref.h \ +third_party/libcxx/__type_traits/remove_extent.h \ +third_party/libcxx/__type_traits/remove_pointer.h \ +third_party/libcxx/__type_traits/remove_reference.h \ +third_party/libcxx/__type_traits/remove_volatile.h \ +third_party/libcxx/__type_traits/result_of.h \ +third_party/libcxx/__type_traits/strip_signature.h \ +third_party/libcxx/__type_traits/type_identity.h \ +third_party/libcxx/__type_traits/type_list.h \ +third_party/libcxx/__type_traits/underlying_type.h \ +third_party/libcxx/__type_traits/unwrap_ref.h \ +third_party/libcxx/__type_traits/void_t.h \ +third_party/libcxx/__undef_macros \ +third_party/libcxx/__utility/as_const.h \ +third_party/libcxx/__utility/as_lvalue.h \ +third_party/libcxx/__utility/auto_cast.h \ +third_party/libcxx/__utility/cmp.h \ +third_party/libcxx/__utility/convert_to_integral.h \ +third_party/libcxx/__utility/declval.h \ +third_party/libcxx/__utility/empty.h \ +third_party/libcxx/__utility/exception_guard.h \ +third_party/libcxx/__utility/exchange.h \ +third_party/libcxx/__utility/forward.h \ +third_party/libcxx/__utility/forward_like.h \ +third_party/libcxx/__utility/in_place.h \ +third_party/libcxx/__utility/integer_sequence.h \ +third_party/libcxx/__utility/is_pointer_in_range.h \ +third_party/libcxx/__utility/is_valid_range.h \ +third_party/libcxx/__utility/move.h \ +third_party/libcxx/__utility/no_destroy.h \ +third_party/libcxx/__utility/pair.h \ +third_party/libcxx/__utility/piecewise_construct.h \ +third_party/libcxx/__utility/priority_tag.h \ +third_party/libcxx/__utility/private_constructor_tag.h \ +third_party/libcxx/__utility/rel_ops.h \ +third_party/libcxx/__utility/small_buffer.h \ +third_party/libcxx/__utility/swap.h \ +third_party/libcxx/__utility/to_underlying.h \ +third_party/libcxx/__utility/unreachable.h \ +third_party/libcxx/__variant/monostate.h \ +third_party/libcxx/__verbose_abort \ +third_party/libcxx/algorithm \ +third_party/libcxx/any \ +third_party/libcxx/array \ +third_party/libcxx/atomic \ +third_party/libcxx/barrier \ +third_party/libcxx/bit \ +third_party/libcxx/bitset \ +third_party/libcxx/cassert \ +third_party/libcxx/ccomplex \ +third_party/libcxx/cctype \ +third_party/libcxx/cerrno \ +third_party/libcxx/cfenv \ +third_party/libcxx/cfloat \ +third_party/libcxx/charconv \ +third_party/libcxx/chrono \ +third_party/libcxx/cinttypes \ +third_party/libcxx/ciso646 \ +third_party/libcxx/climits \ +third_party/libcxx/clocale \ +third_party/libcxx/cmath \ +third_party/libcxx/codecvt \ +third_party/libcxx/compare \ +third_party/libcxx/complex \ +third_party/libcxx/complex.h \ third_party/libcxx/concepts \ third_party/libcxx/condition_variable \ third_party/libcxx/coroutine \ @@ -815,24 +2002,20 @@ third_party/libcxx/exception \ third_party/libcxx/execution \ third_party/libcxx/expected \ third_party/libcxx/experimental/__config \ -third_party/libcxx/experimental/__memory \ -third_party/libcxx/experimental/deque \ -third_party/libcxx/experimental/forward_list \ +third_party/libcxx/experimental/__simd/aligned_tag.h \ +third_party/libcxx/experimental/__simd/declaration.h \ +third_party/libcxx/experimental/__simd/reference.h \ +third_party/libcxx/experimental/__simd/scalar.h \ +third_party/libcxx/experimental/__simd/simd.h \ +third_party/libcxx/experimental/__simd/simd_mask.h \ +third_party/libcxx/experimental/__simd/traits.h \ +third_party/libcxx/experimental/__simd/utility.h \ +third_party/libcxx/experimental/__simd/vec_ext.h \ third_party/libcxx/experimental/iterator \ -third_party/libcxx/experimental/list \ -third_party/libcxx/experimental/map \ -third_party/libcxx/experimental/memory_resource \ +third_party/libcxx/experimental/memory \ third_party/libcxx/experimental/propagate_const \ -third_party/libcxx/experimental/regex \ -third_party/libcxx/experimental/set \ -third_party/libcxx/experimental/simd \ -third_party/libcxx/experimental/string \ third_party/libcxx/experimental/type_traits \ -third_party/libcxx/experimental/unordered_map \ -third_party/libcxx/experimental/unordered_set \ third_party/libcxx/experimental/utility \ -third_party/libcxx/experimental/vector \ -third_party/libcxx/ext/__hash \ third_party/libcxx/filesystem \ third_party/libcxx/format \ third_party/libcxx/forward_list \ @@ -860,6 +2043,7 @@ third_party/libcxx/numbers \ third_party/libcxx/numeric \ third_party/libcxx/optional \ third_party/libcxx/ostream \ +third_party/libcxx/print \ third_party/libcxx/queue \ third_party/libcxx/random \ third_party/libcxx/ranges \ @@ -873,11 +2057,14 @@ third_party/libcxx/source_location \ third_party/libcxx/span \ third_party/libcxx/sstream \ third_party/libcxx/stack \ +third_party/libcxx/stdatomic.h \ third_party/libcxx/stdexcept \ +third_party/libcxx/stop_token \ third_party/libcxx/streambuf \ third_party/libcxx/string \ third_party/libcxx/string_view \ third_party/libcxx/strstream \ +third_party/libcxx/syncstream \ third_party/libcxx/system_error \ third_party/libcxx/thread \ third_party/libcxx/tuple \ @@ -891,180 +2078,32 @@ third_party/libcxx/valarray \ third_party/libcxx/variant \ third_party/libcxx/vector \ third_party/libcxx/version \ - -THIRD_PARTY_LIBCXX_A_INCS = \ -third_party/libcxx/__algorithm/pstl_any_all_none_of.h \ -third_party/libcxx/__algorithm/pstl_backend.h \ -third_party/libcxx/__algorithm/pstl_backends/cpu_backend.h \ -third_party/libcxx/__algorithm/pstl_backends/cpu_backends/any_of.h \ -third_party/libcxx/__algorithm/pstl_backends/cpu_backends/backend.h \ -third_party/libcxx/__algorithm/pstl_backends/cpu_backends/fill.h \ -third_party/libcxx/__algorithm/pstl_backends/cpu_backends/find_if.h \ -third_party/libcxx/__algorithm/pstl_backends/cpu_backends/for_each.h \ -third_party/libcxx/__algorithm/pstl_backends/cpu_backends/merge.h \ -third_party/libcxx/__algorithm/pstl_backends/cpu_backends/serial.h \ -third_party/libcxx/__algorithm/pstl_backends/cpu_backends/thread.h \ -third_party/libcxx/__algorithm/pstl_backends/cpu_backends/transform.h \ -third_party/libcxx/__algorithm/pstl_copy.h \ -third_party/libcxx/__algorithm/pstl_fill.h \ -third_party/libcxx/__algorithm/pstl_find.h \ -third_party/libcxx/__algorithm/pstl_for_each.h \ -third_party/libcxx/__algorithm/pstl_frontend_dispatch.h \ -third_party/libcxx/__algorithm/pstl_merge.h \ -third_party/libcxx/__algorithm/pstl_transform.h \ -third_party/libcxx/__locale_dir/locale_base_api/bsd_locale_defaults.h \ -third_party/libcxx/__locale_dir/locale_base_api/bsd_locale_fallbacks.h \ -third_party/libcxx/__locale_dir/locale_base_api/locale_guard.h \ -third_party/libcxx/__mbstate_t.h \ -third_party/libcxx/__pstl/internal/algorithm_fwd.h \ -third_party/libcxx/__pstl/internal/algorithm_impl.h \ -third_party/libcxx/__pstl/internal/execution_defs.h \ -third_party/libcxx/__pstl/internal/execution_impl.h \ -third_party/libcxx/__pstl/internal/glue_algorithm_defs.h \ -third_party/libcxx/__pstl/internal/glue_algorithm_impl.h \ -third_party/libcxx/__pstl/internal/glue_memory_defs.h \ -third_party/libcxx/__pstl/internal/glue_memory_impl.h \ -third_party/libcxx/__pstl/internal/glue_numeric_defs.h \ -third_party/libcxx/__pstl/internal/glue_numeric_impl.h \ -third_party/libcxx/__pstl/internal/memory_impl.h \ -third_party/libcxx/__pstl/internal/numeric_fwd.h \ -third_party/libcxx/__pstl/internal/numeric_impl.h \ -third_party/libcxx/__pstl/internal/omp/parallel_for.h \ -third_party/libcxx/__pstl/internal/omp/parallel_for_each.h \ -third_party/libcxx/__pstl/internal/omp/parallel_invoke.h \ -third_party/libcxx/__pstl/internal/omp/parallel_merge.h \ -third_party/libcxx/__pstl/internal/omp/parallel_reduce.h \ -third_party/libcxx/__pstl/internal/omp/parallel_scan.h \ -third_party/libcxx/__pstl/internal/omp/parallel_stable_partial_sort.h \ -third_party/libcxx/__pstl/internal/omp/parallel_stable_sort.h \ -third_party/libcxx/__pstl/internal/omp/parallel_transform_reduce.h \ -third_party/libcxx/__pstl/internal/omp/parallel_transform_scan.h \ -third_party/libcxx/__pstl/internal/omp/util.h \ -third_party/libcxx/__pstl/internal/parallel_backend.h \ -third_party/libcxx/__pstl/internal/parallel_backend_omp.h \ -third_party/libcxx/__pstl/internal/parallel_backend_serial.h \ -third_party/libcxx/__pstl/internal/parallel_backend_tbb.h \ -third_party/libcxx/__pstl/internal/parallel_backend_utils.h \ -third_party/libcxx/__pstl/internal/unseq_backend_simd.h \ -third_party/libcxx/__pstl/internal/utils.h \ -third_party/libcxx/__pstl_algorithm \ -third_party/libcxx/__pstl_config_site \ -third_party/libcxx/__pstl_memory \ -third_party/libcxx/__pstl_numeric \ -third_party/libcxx/__support/android/locale_bionic.h \ -third_party/libcxx/__support/musl/xlocale.h \ -third_party/libcxx/complex.h \ -third_party/libcxx/ctype.h \ -third_party/libcxx/errno.h \ -third_party/libcxx/fenv.h \ -third_party/libcxx/float.h \ -third_party/libcxx/inttypes.h \ -third_party/libcxx/limits.h \ -third_party/libcxx/locale.h \ -third_party/libcxx/math.h \ -third_party/libcxx/setjmp.h \ -third_party/libcxx/src/chrono_system_time_init.h \ -third_party/libcxx/src/experimental/memory_resource_init_helper.h \ -third_party/libcxx/src/filesystem/filesystem_common.h \ -third_party/libcxx/src/filesystem/posix_compat.h \ -third_party/libcxx/src/include/apple_availability.h \ -third_party/libcxx/src/include/atomic_support.h \ -third_party/libcxx/src/include/config_elast.h \ -third_party/libcxx/src/include/refstring.h \ -third_party/libcxx/src/include/ryu/common.h \ -third_party/libcxx/src/include/ryu/d2fixed.h \ -third_party/libcxx/src/include/ryu/d2fixed_full_table.h \ -third_party/libcxx/src/include/ryu/d2s.h \ -third_party/libcxx/src/include/ryu/d2s_full_table.h \ -third_party/libcxx/src/include/ryu/d2s_intrinsics.h \ -third_party/libcxx/src/include/ryu/digit_table.h \ -third_party/libcxx/src/include/ryu/f2s.h \ -third_party/libcxx/src/include/ryu/ryu.h \ -third_party/libcxx/src/include/sso_allocator.h \ -third_party/libcxx/src/include/to_chars_floating_point.h \ -third_party/libcxx/src/iostream_init.h \ -third_party/libcxx/src/memory_resource_init_helper.h \ -third_party/libcxx/src/std_stream.h \ -third_party/libcxx/src/support/runtime/exception_fallback.ipp \ -third_party/libcxx/src/support/runtime/exception_glibcxx.ipp \ -third_party/libcxx/src/support/runtime/exception_libcxxabi.ipp \ -third_party/libcxx/src/support/runtime/exception_libcxxrt.ipp \ -third_party/libcxx/src/support/runtime/exception_msvc.ipp \ -third_party/libcxx/src/support/runtime/exception_pointer_cxxabi.ipp \ -third_party/libcxx/src/support/runtime/exception_pointer_glibcxx.ipp \ -third_party/libcxx/src/support/runtime/exception_pointer_msvc.ipp \ -third_party/libcxx/src/support/runtime/exception_pointer_unimplemented.ipp \ -third_party/libcxx/src/support/runtime/new_handler_fallback.ipp \ -third_party/libcxx/src/support/runtime/stdexcept_default.ipp \ -third_party/libcxx/src/support/runtime/stdexcept_vcruntime.ipp \ -third_party/libcxx/stdatomic.h \ -third_party/libcxx/stdbool.h \ -third_party/libcxx/stddef.h \ -third_party/libcxx/stdint.h \ -third_party/libcxx/stdio.h \ -third_party/libcxx/stdlib.h \ -third_party/libcxx/string.h \ -third_party/libcxx/tgmath.h \ -third_party/libcxx/uchar.h \ -third_party/libcxx/wchar.h \ -third_party/libcxx/wctype.h \ -third_party/libcxx/libcxx.imp \ -third_party/libcxx/module.modulemap \ - -THIRD_PARTY_LIBCXX_A_SRCS = \ -third_party/libcxx/src/algorithm.cpp \ -third_party/libcxx/src/any.cpp \ -third_party/libcxx/src/atomic.cpp \ -third_party/libcxx/src/barrier.cpp \ -third_party/libcxx/src/bind.cpp \ -third_party/libcxx/src/charconv.cpp \ -third_party/libcxx/src/chrono.cpp \ -third_party/libcxx/src/condition_variable.cpp \ -third_party/libcxx/src/condition_variable_destructor.cpp \ -third_party/libcxx/src/debug.cpp \ -third_party/libcxx/src/exception.cpp \ -third_party/libcxx/src/experimental/memory_resource.cpp \ -third_party/libcxx/src/filesystem/directory_iterator.cpp \ -third_party/libcxx/src/filesystem/int128_builtins.cpp \ -third_party/libcxx/src/filesystem/operations.cpp \ -third_party/libcxx/src/functional.cpp \ -third_party/libcxx/src/future.cpp \ -third_party/libcxx/src/hash.cpp \ -third_party/libcxx/src/ios.cpp \ -third_party/libcxx/src/ios.instantiations.cpp \ -third_party/libcxx/src/iostream.cpp \ -third_party/libcxx/src/legacy_debug_handler.cpp \ -third_party/libcxx/src/legacy_pointer_safety.cpp \ -third_party/libcxx/src/locale.cpp \ -third_party/libcxx/src/memory.cpp \ -third_party/libcxx/src/memory_resource.cpp \ -third_party/libcxx/src/mutex.cpp \ -third_party/libcxx/src/mutex_destructor.cpp \ -third_party/libcxx/src/new.cpp \ -third_party/libcxx/src/optional.cpp \ -third_party/libcxx/src/random.cpp \ -third_party/libcxx/src/regex.cpp \ -third_party/libcxx/src/ryu/d2fixed.cpp \ -third_party/libcxx/src/ryu/d2s.cpp \ -third_party/libcxx/src/ryu/f2s.cpp \ -third_party/libcxx/src/shared_mutex.cpp \ -third_party/libcxx/src/stdexcept.cpp \ -third_party/libcxx/src/string.cpp \ -third_party/libcxx/src/strstream.cpp \ -third_party/libcxx/src/system_error.cpp \ -third_party/libcxx/src/thread.cpp \ -third_party/libcxx/src/typeinfo.cpp \ -third_party/libcxx/src/valarray.cpp \ -third_party/libcxx/src/variant.cpp \ -third_party/libcxx/src/vector.cpp \ -third_party/libcxx/src/verbose_abort.cpp +third_party/libcxx/fs/error.h \ +third_party/libcxx/fs/file_descriptor.h \ +third_party/libcxx/fs/format_string.h \ +third_party/libcxx/fs/path_parser.h \ +third_party/libcxx/fs/posix_compat.h \ +third_party/libcxx/fs/time_utils.h \ +third_party/libcxx/std_stream.h \ +third_party/libcxx/overridable_function.h \ +third_party/libcxx/atomic_support.h \ +third_party/libcxx/refstring.h \ +third_party/libcxx/config_elast.h \ +third_party/libcxx/sso_allocator.h \ +third_party/libcxx/stdexcept_default.h \ +third_party/libcxx/ryu/common.h \ +third_party/libcxx/ryu/d2fixed_full_table.h \ +third_party/libcxx/ryu/d2s_full_table.h \ +third_party/libcxx/ryu/d2s_intrinsics.h \ +third_party/libcxx/ryu/digit_table.h \ +third_party/libcxx/ryu/ryu.h \ THIRD_PARTY_LIBCXX_A_OBJS = \ $(THIRD_PARTY_LIBCXX_A_SRCS:%.cpp=o/$(MODE)/%.o) THIRD_PARTY_LIBCXX_A_CHECKS = \ $(THIRD_PARTY_LIBCXX_A).pkg \ - $(THIRD_PARTY_LIBCXX_A_HDRS:%=o/$(MODE)/%.okk) + $(THIRD_PARTY_LIBCXX_A_HDRS_CHECKEM:%=o/$(MODE)/%.okk) THIRD_PARTY_LIBCXX_A_DIRECTDEPS = \ LIBC_CALLS \ diff --git a/third_party/libcxx/CREDITS.TXT b/third_party/libcxx/CREDITS.TXT deleted file mode 100644 index 46a06c6ea..000000000 --- a/third_party/libcxx/CREDITS.TXT +++ /dev/null @@ -1,150 +0,0 @@ -This file is a partial list of people who have contributed to the LLVM/libc++ -project. If you have contributed a patch or made some other contribution to -LLVM/libc++, please submit a patch to this file to add yourself, and it will be -done! - -The list is sorted by surname and formatted to allow easy grepping and -beautification by scripts. The fields are: name (N), email (E), web-address -(W), PGP key ID and fingerprint (P), description (D), and snail-mail address -(S). - -N: Saleem Abdulrasool -E: compnerd@compnerd.org -D: Minor patches and Linux fixes. - -N: Dan Albert -E: danalbert@google.com -D: Android support and test runner improvements. - -N: Dimitry Andric -E: dimitry@andric.com -D: Visibility fixes, minor FreeBSD portability patches. - -N: Holger Arnold -E: holgerar@gmail.com -D: Minor fix. - -N: Ruben Van Boxem -E: vanboxem dot ruben at gmail dot com -D: Initial Windows patches. - -N: David Chisnall -E: theraven at theravensnest dot org -D: FreeBSD and Solaris ports, libcxxrt support, some atomics work. - -N: Marshall Clow -E: mclow.lists@gmail.com -E: marshall@idio.com -D: C++14 support, patches and bug fixes. - -N: Jonathan B Coe -E: jbcoe@me.com -D: Implementation of propagate_const. - -N: Glen Joseph Fernandes -E: glenjofe@gmail.com -D: Implementation of to_address. - -N: Eric Fiselier -E: eric@efcs.ca -D: LFTS support, patches and bug fixes. - -N: Bill Fisher -E: william.w.fisher@gmail.com -D: Regex bug fixes. - -N: Matthew Dempsky -E: matthew@dempsky.org -D: Minor patches and bug fixes. - -N: Google Inc. -D: Copyright owner and contributor of the CityHash algorithm - -N: Howard Hinnant -E: hhinnant@apple.com -D: Architect and primary author of libc++ - -N: Hyeon-bin Jeong -E: tuhertz@gmail.com -D: Minor patches and bug fixes. - -N: Argyrios Kyrtzidis -E: kyrtzidis@apple.com -D: Bug fixes. - -N: Bruce Mitchener, Jr. -E: bruce.mitchener@gmail.com -D: Emscripten-related changes. - -N: Michel Morin -E: mimomorin@gmail.com -D: Minor patches to is_convertible. - -N: Andrew Morrow -E: andrew.c.morrow@gmail.com -D: Minor patches and Linux fixes. - -N: Michael Park -E: mcypark@gmail.com -D: Implementation of . - -N: Arvid Picciani -E: aep at exys dot org -D: Minor patches and musl port. - -N: Bjorn Reese -E: breese@users.sourceforge.net -D: Initial regex prototype - -N: Nico Rieck -E: nico.rieck@gmail.com -D: Windows fixes - -N: Jon Roelofs -E: jroelofS@jroelofs.com -D: Remote testing, Newlib port, baremetal/single-threaded support. - -N: Jonathan Sauer -D: Minor patches, mostly related to constexpr - -N: Craig Silverstein -E: csilvers@google.com -D: Implemented Cityhash as the string hash function on 64-bit machines - -N: Richard Smith -D: Minor patches. - -N: Joerg Sonnenberger -E: joerg@NetBSD.org -D: NetBSD port. - -N: Stephan Tolksdorf -E: st@quanttec.com -D: Minor fix - -N: Michael van der Westhuizen -E: r1mikey at gmail dot com - -N: Larisse Voufo -D: Minor patches. - -N: Klaas de Vries -E: klaas at klaasgaaf dot nl -D: Minor bug fix. - -N: Zhang Xiongpang -E: zhangxiongpang@gmail.com -D: Minor patches and bug fixes. - -N: Xing Xue -E: xingxue@ca.ibm.com -D: AIX port - -N: Zhihao Yuan -E: lichray@gmail.com -D: Standard compatibility fixes. - -N: Jeffrey Yasskin -E: jyasskin@gmail.com -E: jyasskin@google.com -D: Linux fixes. diff --git a/third_party/libcxx/LICENSE.TXT b/third_party/libcxx/LICENSE.TXT deleted file mode 100644 index e159d2834..000000000 --- a/third_party/libcxx/LICENSE.TXT +++ /dev/null @@ -1,311 +0,0 @@ -============================================================================== -The LLVM Project is under the Apache License v2.0 with LLVM Exceptions: -============================================================================== - - 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. - - ----- LLVM Exceptions to the Apache 2.0 License ---- - -As an exception, if, as a result of your compiling your source code, portions -of this Software are embedded into an Object form of such source code, you -may redistribute such embedded portions in such Object form without complying -with the conditions of Sections 4(a), 4(b) and 4(d) of the License. - -In addition, if you combine or link compiled forms of this Software with -software that is licensed under the GPLv2 ("Combined Software") and if a -court of competent jurisdiction determines that the patent provision (Section -3), the indemnity provision (Section 9) or other Section of the License -conflicts with the conditions of the GPLv2, you may retroactively and -prospectively choose to deem waived or otherwise exclude such Section(s) of -the License, but only in their entirety and only with respect to the Combined -Software. - -============================================================================== -Software from third parties included in the LLVM Project: -============================================================================== -The LLVM Project contains third party software which is under different license -terms. All such code will be identified clearly using at least one of two -mechanisms: -1) It will be in a separate directory tree with its own `LICENSE.txt` or - `LICENSE` file at the top containing the specific license and restrictions - which apply to that software, or -2) It will contain specific license and restriction terms at the top of every - file. - -============================================================================== -Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy): -============================================================================== - -The libc++ library is dual licensed under both the University of Illinois -"BSD-Like" license and the MIT license. As a user of this code you may choose -to use it under either license. As a contributor, you agree to allow your code -to be used under both. - -Full text of the relevant licenses is included below. - -============================================================================== - -University of Illinois/NCSA -Open Source License - -Copyright (c) 2009-2019 by the contributors listed in CREDITS.TXT - -All rights reserved. - -Developed by: - - LLVM Team - - University of Illinois at Urbana-Champaign - - http://llvm.org - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal with -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: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimers. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimers in the - documentation and/or other materials provided with the distribution. - - * Neither the names of the LLVM Team, University of Illinois at - Urbana-Champaign, nor the names of its contributors may be used to - endorse or promote products derived from this Software without specific - prior written permission. - -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 -CONTRIBUTORS 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 WITH THE -SOFTWARE. - -============================================================================== - -Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT - -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. diff --git a/third_party/libcxx/README.cosmo b/third_party/libcxx/README.cosmo index 506113754..7a86bd505 100644 --- a/third_party/libcxx/README.cosmo +++ b/third_party/libcxx/README.cosmo @@ -5,14 +5,11 @@ DESCRIPTION ORIGIN git@github.com:llvm/llvm-project.git - commit ad0543f4ea82ec41c5e854af65758fa8d92d5553 - Author: Haojian Wu - Date: Thu Jun 1 15:31:43 2023 +0200 + commit 83c2bfdacb0593b3a72e93098a55afdcd93d865f + Date: Mon Jul 22 10:22:23 2024 -0400 LOCAL CHANGES - Wrote __config_site - - Add __COSMOPOLITAN__ when appropriate + - Shaped and molded directory structure - Kludged (and probably broke) awful `cerr` feature - - Break apart locale.cpp due to its outrageous build times - - Suppress -Wattribute sometimes due to __always_inline__ hack diff --git a/third_party/libcxx/__algorithm/adjacent_find.h b/third_party/libcxx/__algorithm/adjacent_find.h index 30df4a976..6f15456e3 100644 --- a/third_party/libcxx/__algorithm/adjacent_find.h +++ b/third_party/libcxx/__algorithm/adjacent_find.h @@ -20,10 +20,13 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter __adjacent_find(_Iter __first, _Sent __last, _BinaryPredicate&& __pred) { if (__first == __last) return __first; @@ -37,17 +40,19 @@ __adjacent_find(_Iter __first, _Sent __last, _BinaryPredicate&& __pred) { } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) { return std::__adjacent_find(std::move(__first), std::move(__last), __pred); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator adjacent_find(_ForwardIterator __first, _ForwardIterator __last) { return std::adjacent_find(std::move(__first), std::move(__last), __equal_to()); } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_ADJACENT_FIND_H diff --git a/third_party/libcxx/__algorithm/all_of.h b/third_party/libcxx/__algorithm/all_of.h index 237f8495c..ec84eea75 100644 --- a/third_party/libcxx/__algorithm/all_of.h +++ b/third_party/libcxx/__algorithm/all_of.h @@ -19,7 +19,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { for (; __first != __last; ++__first) if (!__pred(*__first)) diff --git a/third_party/libcxx/__algorithm/any_of.h b/third_party/libcxx/__algorithm/any_of.h index fe0882816..b5ff778c4 100644 --- a/third_party/libcxx/__algorithm/any_of.h +++ b/third_party/libcxx/__algorithm/any_of.h @@ -19,7 +19,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool any_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { for (; __first != __last; ++__first) if (__pred(*__first)) diff --git a/third_party/libcxx/__algorithm/binary_search.h b/third_party/libcxx/__algorithm/binary_search.h index 8f958c2c1..6065fc372 100644 --- a/third_party/libcxx/__algorithm/binary_search.h +++ b/third_party/libcxx/__algorithm/binary_search.h @@ -22,23 +22,16 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -bool -binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) -{ - __first = std::lower_bound<_ForwardIterator, _Tp, __comp_ref_type<_Compare> >(__first, __last, __value, __comp); - return __first != __last && !__comp(__value, *__first); +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { + __first = std::lower_bound<_ForwardIterator, _Tp, __comp_ref_type<_Compare> >(__first, __last, __value, __comp); + return __first != __last && !__comp(__value, *__first); } template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -bool -binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) -{ - return std::binary_search(__first, __last, __value, - __less::value_type, _Tp>()); +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { + return std::binary_search(__first, __last, __value, __less<>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/clamp.h b/third_party/libcxx/__algorithm/clamp.h index 336b93fd8..1a5a3d074 100644 --- a/third_party/libcxx/__algorithm/clamp.h +++ b/third_party/libcxx/__algorithm/clamp.h @@ -20,24 +20,22 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 17 -template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY constexpr -const _Tp& -clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi, _Compare __comp) -{ - _LIBCPP_ASSERT(!__comp(__hi, __lo), "Bad bounds passed to std::clamp"); - return __comp(__v, __lo) ? __lo : __comp(__hi, __v) ? __hi : __v; - +template +[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& +clamp(_LIBCPP_LIFETIMEBOUND const _Tp& __v, + _LIBCPP_LIFETIMEBOUND const _Tp& __lo, + _LIBCPP_LIFETIMEBOUND const _Tp& __hi, + _Compare __comp) { + _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(!__comp(__hi, __lo), "Bad bounds passed to std::clamp"); + return __comp(__v, __lo) ? __lo : __comp(__hi, __v) ? __hi : __v; } -template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY constexpr -const _Tp& -clamp(const _Tp& __v, const _Tp& __lo, const _Tp& __hi) -{ - return _VSTD::clamp(__v, __lo, __hi, __less<_Tp>()); +template +[[nodiscard]] inline _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& +clamp(_LIBCPP_LIFETIMEBOUND const _Tp& __v, + _LIBCPP_LIFETIMEBOUND const _Tp& __lo, + _LIBCPP_LIFETIMEBOUND const _Tp& __hi) { + return std::clamp(__v, __lo, __hi, __less<>()); } #endif diff --git a/third_party/libcxx/__algorithm/comp.h b/third_party/libcxx/__algorithm/comp.h index 1001e42a3..a0fa88d6d 100644 --- a/third_party/libcxx/__algorithm/comp.h +++ b/third_party/libcxx/__algorithm/comp.h @@ -10,8 +10,7 @@ #define _LIBCPP___ALGORITHM_COMP_H #include <__config> -#include <__type_traits/integral_constant.h> -#include <__type_traits/predicate_traits.h> +#include <__type_traits/desugars_to.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -26,45 +25,24 @@ struct __equal_to { } }; -template -struct __is_trivial_equality_predicate<__equal_to, _Lhs, _Rhs> : true_type {}; +template +inline const bool __desugars_to_v<__equal_tag, __equal_to, _Tp, _Up> = true; -template -struct __less -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 - bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} +// The definition is required because __less is part of the ABI, but it's empty +// because all comparisons should be transparent. +template +struct __less {}; - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 - bool operator()(const _T1& __x, const _T2& __y) const {return __x < __y;} - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 - bool operator()(const _T2& __x, const _T1& __y) const {return __x < __y;} - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 - bool operator()(const _T2& __x, const _T2& __y) const {return __x < __y;} +template <> +struct __less { + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(const _Tp& __lhs, const _Up& __rhs) const { + return __lhs < __rhs; + } }; -template -struct __less<_T1, _T1> -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 - bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} -}; - -template -struct __less -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 - bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} -}; - -template -struct __less<_T1, const _T1> -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 - bool operator()(const _T1& __x, const _T1& __y) const {return __x < __y;} -}; +template +inline const bool __desugars_to_v<__less_tag, __less<>, _Tp, _Tp> = true; _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/comp_ref_type.h b/third_party/libcxx/__algorithm/comp_ref_type.h index 55c5ce84a..c367fbb91 100644 --- a/third_party/libcxx/__algorithm/comp_ref_type.h +++ b/third_party/libcxx/__algorithm/comp_ref_type.h @@ -9,8 +9,8 @@ #ifndef _LIBCPP___ALGORITHM_COMP_REF_TYPE_H #define _LIBCPP___ALGORITHM_COMP_REF_TYPE_H +#include <__assert> #include <__config> -#include <__debug> #include <__utility/declval.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -20,52 +20,41 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -struct __debug_less -{ - _Compare &__comp_; - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI __debug_less(_Compare& __c) : __comp_(__c) {} +struct __debug_less { + _Compare& __comp_; + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI __debug_less(_Compare& __c) : __comp_(__c) {} - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - bool operator()(const _Tp& __x, const _Up& __y) - { - bool __r = __comp_(__x, __y); - if (__r) - __do_compare_assert(0, __y, __x); - return __r; - } + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Up& __y) { + bool __r = __comp_(__x, __y); + if (__r) + __do_compare_assert(0, __y, __x); + return __r; + } - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI - bool operator()(_Tp& __x, _Up& __y) - { - bool __r = __comp_(__x, __y); - if (__r) - __do_compare_assert(0, __y, __x); - return __r; - } + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(_Tp& __x, _Up& __y) { + bool __r = __comp_(__x, __y); + if (__r) + __do_compare_assert(0, __y, __x); + return __r; + } - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 - inline _LIBCPP_INLINE_VISIBILITY - decltype((void)std::declval<_Compare&>()( - std::declval<_LHS &>(), std::declval<_RHS &>())) - __do_compare_assert(int, _LHS & __l, _RHS & __r) { - _LIBCPP_DEBUG_ASSERT(!__comp_(__l, __r), - "Comparator does not induce a strict weak ordering"); - (void)__l; - (void)__r; - } + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 inline + _LIBCPP_HIDE_FROM_ABI decltype((void)std::declval<_Compare&>()(std::declval<_LHS&>(), std::declval<_RHS&>())) + __do_compare_assert(int, _LHS& __l, _RHS& __r) { + _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(!__comp_(__l, __r), "Comparator does not induce a strict weak ordering"); + (void)__l; + (void)__r; + } - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 - inline _LIBCPP_INLINE_VISIBILITY - void __do_compare_assert(long, _LHS &, _RHS &) {} + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 inline _LIBCPP_HIDE_FROM_ABI void __do_compare_assert(long, _LHS&, _RHS&) {} }; -// Pass the comparator by lvalue reference. Or in debug mode, using a -// debugging wrapper that stores a reference. -#ifdef _LIBCPP_ENABLE_DEBUG_MODE +// Pass the comparator by lvalue reference. Or in the debug mode, using a debugging wrapper that stores a reference. +#if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG template using __comp_ref_type = __debug_less<_Comp>; #else diff --git a/third_party/libcxx/__algorithm/copy.h b/third_party/libcxx/__algorithm/copy.h index c29ff8fa7..0890b895f 100644 --- a/third_party/libcxx/__algorithm/copy.h +++ b/third_party/libcxx/__algorithm/copy.h @@ -32,7 +32,7 @@ template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> __copy(_InIter, _Sent, _OutIter); template -struct __copy_loop { +struct __copy_impl { template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const { @@ -51,9 +51,10 @@ struct __copy_loop { _OutIter& __result_; - _LIBCPP_HIDE_FROM_ABI _CopySegment(_OutIter& __result) : __result_(__result) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit _CopySegment(_OutIter& __result) + : __result_(__result) {} - _LIBCPP_HIDE_FROM_ABI void + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void operator()(typename _Traits::__local_iterator __lfirst, typename _Traits::__local_iterator __llast) { __result_ = std::__copy<_AlgPolicy>(__lfirst, __llast, std::move(__result_)).second; } @@ -72,7 +73,7 @@ struct __copy_loop { !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> - operator()(_InIter __first, _InIter __last, _OutIter __result) { + operator()(_InIter __first, _InIter __last, _OutIter __result) const { using _Traits = __segmented_iterator_traits<_OutIter>; using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type; @@ -93,9 +94,7 @@ struct __copy_loop { __local_first = _Traits::__begin(++__segment_iterator); } } -}; -struct __copy_trivial { // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer. template ::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*> @@ -107,12 +106,12 @@ struct __copy_trivial { template pair<_InIter, _OutIter> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __copy(_InIter __first, _Sent __last, _OutIter __result) { - return std::__dispatch_copy_or_move<_AlgPolicy, __copy_loop<_AlgPolicy>, __copy_trivial>( + return std::__copy_move_unwrap_iters<__copy_impl<_AlgPolicy> >( std::move(__first), std::move(__last), std::move(__result)); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result) { return std::__copy<_ClassicAlgPolicy>(__first, __last, __result).second; } diff --git a/third_party/libcxx/__algorithm/copy_backward.h b/third_party/libcxx/__algorithm/copy_backward.h index 5bc93c625..73dc846a9 100644 --- a/third_party/libcxx/__algorithm/copy_backward.h +++ b/third_party/libcxx/__algorithm/copy_backward.h @@ -15,7 +15,7 @@ #include <__config> #include <__iterator/segmented_iterator.h> #include <__type_traits/common_type.h> -#include <__type_traits/is_copy_constructible.h> +#include <__type_traits/is_constructible.h> #include <__utility/move.h> #include <__utility/pair.h> @@ -33,7 +33,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InIter, _OutIter> __copy_backward(_InIter __first, _Sent __last, _OutIter __result); template -struct __copy_backward_loop { +struct __copy_backward_impl { template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const { @@ -80,7 +80,7 @@ struct __copy_backward_loop { !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> - operator()(_InIter __first, _InIter __last, _OutIter __result) { + operator()(_InIter __first, _InIter __last, _OutIter __result) const { using _Traits = __segmented_iterator_traits<_OutIter>; auto __orig_last = __last; auto __segment_iterator = _Traits::__segment(__result); @@ -104,12 +104,9 @@ struct __copy_backward_loop { __local_last = _Traits::__end(__segment_iterator); } } -}; -struct __copy_backward_trivial { // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer. - template ::value, int> = 0> + template ::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*> operator()(_In* __first, _In* __last, _Out* __result) const { return std::__copy_backward_trivial_impl(__first, __last, __result); @@ -119,21 +116,18 @@ struct __copy_backward_trivial { template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator1, _BidirectionalIterator2> __copy_backward(_BidirectionalIterator1 __first, _Sentinel __last, _BidirectionalIterator2 __result) { - return std::__dispatch_copy_or_move<_AlgPolicy, __copy_backward_loop<_AlgPolicy>, __copy_backward_trivial>( + return std::__copy_move_unwrap_iters<__copy_backward_impl<_AlgPolicy> >( std::move(__first), std::move(__last), std::move(__result)); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_BidirectionalIterator2 -copy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, - _BidirectionalIterator2 __result) -{ +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _BidirectionalIterator2 +copy_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, _BidirectionalIterator2 __result) { static_assert(std::is_copy_constructible<_BidirectionalIterator1>::value && - std::is_copy_constructible<_BidirectionalIterator1>::value, "Iterators must be copy constructible."); + std::is_copy_constructible<_BidirectionalIterator1>::value, + "Iterators must be copy constructible."); - return std::__copy_backward<_ClassicAlgPolicy>( - std::move(__first), std::move(__last), std::move(__result)).second; + return std::__copy_backward<_ClassicAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)).second; } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/copy_if.h b/third_party/libcxx/__algorithm/copy_if.h index a5938b871..228e4d223 100644 --- a/third_party/libcxx/__algorithm/copy_if.h +++ b/third_party/libcxx/__algorithm/copy_if.h @@ -17,21 +17,16 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -copy_if(_InputIterator __first, _InputIterator __last, - _OutputIterator __result, _Predicate __pred) -{ - for (; __first != __last; ++__first) - { - if (__pred(*__first)) - { - *__result = *__first; - ++__result; - } +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred) { + for (; __first != __last; ++__first) { + if (__pred(*__first)) { + *__result = *__first; + ++__result; } - return __result; + } + return __result; } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/copy_move_common.h b/third_party/libcxx/__algorithm/copy_move_common.h index b88c14911..8a98451a8 100644 --- a/third_party/libcxx/__algorithm/copy_move_common.h +++ b/third_party/libcxx/__algorithm/copy_move_common.h @@ -15,12 +15,12 @@ #include <__config> #include <__iterator/iterator_traits.h> #include <__memory/pointer_traits.h> +#include <__string/constexpr_c_functions.h> #include <__type_traits/enable_if.h> #include <__type_traits/is_always_bitcastable.h> #include <__type_traits/is_constant_evaluated.h> -#include <__type_traits/is_copy_constructible.h> +#include <__type_traits/is_constructible.h> #include <__type_traits/is_trivially_assignable.h> -#include <__type_traits/is_trivially_copyable.h> #include <__type_traits/is_volatile.h> #include <__utility/move.h> #include <__utility/pair.h> @@ -30,6 +30,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD // Type traits. @@ -37,22 +40,19 @@ _LIBCPP_BEGIN_NAMESPACE_STD template struct __can_lower_copy_assignment_to_memmove { static const bool value = - // If the types are always bitcastable, it's valid to do a bitwise copy between them. - __is_always_bitcastable<_From, _To>::value && - // Reject conversions that wouldn't be performed by the regular built-in assignment (e.g. between arrays). - is_trivially_assignable<_To&, const _From&>::value && - // `memmove` doesn't accept `volatile` pointers, make sure the optimization SFINAEs away in that case. - !is_volatile<_From>::value && - !is_volatile<_To>::value; + // If the types are always bitcastable, it's valid to do a bitwise copy between them. + __is_always_bitcastable<_From, _To>::value && + // Reject conversions that wouldn't be performed by the regular built-in assignment (e.g. between arrays). + is_trivially_assignable<_To&, const _From&>::value && + // `memmove` doesn't accept `volatile` pointers, make sure the optimization SFINAEs away in that case. + !is_volatile<_From>::value && !is_volatile<_To>::value; }; template struct __can_lower_move_assignment_to_memmove { static const bool value = - __is_always_bitcastable<_From, _To>::value && - is_trivially_assignable<_To&, _From&&>::value && - !is_volatile<_From>::value && - !is_volatile<_To>::value; + __is_always_bitcastable<_From, _To>::value && is_trivially_assignable<_To&, _From&&>::value && + !is_volatile<_From>::value && !is_volatile<_To>::value; }; // `memmove` algorithms implementation. @@ -61,7 +61,8 @@ template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*> __copy_trivial_impl(_In* __first, _In* __last, _Out* __result) { const size_t __n = static_cast(__last - __first); - ::__builtin_memmove(__result, __first, __n * sizeof(_Out)); + + std::__constexpr_memmove(__result, __first, __element_count(__n)); return std::make_pair(__last, __result + __n); } @@ -72,92 +73,42 @@ __copy_backward_trivial_impl(_In* __first, _In* __last, _Out* __result) { const size_t __n = static_cast(__last - __first); __result -= __n; - ::__builtin_memmove(__result, __first, __n * sizeof(_Out)); + std::__constexpr_memmove(__result, __first, __element_count(__n)); return std::make_pair(__last, __result); } // Iterator unwrapping and dispatching to the correct overload. -template -struct __overload : _F1, _F2 { - using _F1::operator(); - using _F2::operator(); -}; - -template -struct __can_rewrap : false_type {}; - -template -struct __can_rewrap<_InIter, - _Sent, - _OutIter, - // Note that sentinels are always copy-constructible. - __enable_if_t< is_copy_constructible<_InIter>::value && - is_copy_constructible<_OutIter>::value > > : true_type {}; +template +struct __can_rewrap + : integral_constant::value && is_copy_constructible<_OutIter>::value> {}; template ::value, int> = 0> + __enable_if_t<__can_rewrap<_InIter, _OutIter>::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pair<_InIter, _OutIter> -__unwrap_and_dispatch(_InIter __first, _Sent __last, _OutIter __out_first) { +__copy_move_unwrap_iters(_InIter __first, _Sent __last, _OutIter __out_first) { auto __range = std::__unwrap_range(__first, std::move(__last)); auto __result = _Algorithm()(std::move(__range.first), std::move(__range.second), std::__unwrap_iter(__out_first)); return std::make_pair(std::__rewrap_range<_Sent>(std::move(__first), std::move(__result.first)), - std::__rewrap_iter(std::move(__out_first), std::move(__result.second))); + std::__rewrap_iter(std::move(__out_first), std::move(__result.second))); } template ::value, int> = 0> + __enable_if_t::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pair<_InIter, _OutIter> -__unwrap_and_dispatch(_InIter __first, _Sent __last, _OutIter __out_first) { +__copy_move_unwrap_iters(_InIter __first, _Sent __last, _OutIter __out_first) { return _Algorithm()(std::move(__first), std::move(__last), std::move(__out_first)); } -template -struct __can_copy_without_conversion : false_type {}; - -template -struct __can_copy_without_conversion< - _IterOps, - _InValue, - _OutIter, - __enable_if_t >::value> > : true_type {}; - -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pair<_InIter, _OutIter> -__dispatch_copy_or_move(_InIter __first, _Sent __last, _OutIter __out_first) { -#ifdef _LIBCPP_COMPILER_GCC - // GCC doesn't support `__builtin_memmove` during constant evaluation. - if (__libcpp_is_constant_evaluated()) { - return std::__unwrap_and_dispatch<_NaiveAlgorithm>(std::move(__first), std::move(__last), std::move(__out_first)); - } -#else - // In Clang, `__builtin_memmove` only supports fully trivially copyable types (just having trivial copy assignment is - // insufficient). Also, conversions are not supported. - if (__libcpp_is_constant_evaluated()) { - using _InValue = typename _IterOps<_AlgPolicy>::template __value_type<_InIter>; - if (!is_trivially_copyable<_InValue>::value || - !__can_copy_without_conversion<_IterOps<_AlgPolicy>, _InValue, _OutIter>::value) { - return std::__unwrap_and_dispatch<_NaiveAlgorithm>(std::move(__first), std::move(__last), std::move(__out_first)); - } - } -#endif // _LIBCPP_COMPILER_GCC - - using _Algorithm = __overload<_NaiveAlgorithm, _OptimizedAlgorithm>; - return std::__unwrap_and_dispatch<_Algorithm>(std::move(__first), std::move(__last), std::move(__out_first)); -} - _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_COPY_MOVE_COMMON_H diff --git a/third_party/libcxx/__algorithm/copy_n.h b/third_party/libcxx/__algorithm/copy_n.h index f3701662a..f93f39203 100644 --- a/third_party/libcxx/__algorithm/copy_n.h +++ b/third_party/libcxx/__algorithm/copy_n.h @@ -21,45 +21,38 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -typename enable_if -< - __has_input_iterator_category<_InputIterator>::value && - !__has_random_access_iterator_category<_InputIterator>::value, - _OutputIterator ->::type -copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) -{ - typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize; - _IntegralSize __n = __orig_n; - if (__n > 0) - { - *__result = *__first; - ++__result; - for (--__n; __n > 0; --__n) - { - ++__first; - *__result = *__first; - ++__result; - } +template ::value && + !__has_random_access_iterator_category<_InputIterator>::value, + int> = 0> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) { + typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize; + _IntegralSize __n = __orig_n; + if (__n > 0) { + *__result = *__first; + ++__result; + for (--__n; __n > 0; --__n) { + ++__first; + *__result = *__first; + ++__result; } - return __result; + } + return __result; } -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -typename enable_if -< - __has_random_access_iterator_category<_InputIterator>::value, - _OutputIterator ->::type -copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) -{ - typedef typename iterator_traits<_InputIterator>::difference_type difference_type; - typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize; - _IntegralSize __n = __orig_n; - return _VSTD::copy(__first, __first + difference_type(__n), __result); +template ::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) { + typedef typename iterator_traits<_InputIterator>::difference_type difference_type; + typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize; + _IntegralSize __n = __orig_n; + return std::copy(__first, __first + difference_type(__n), __result); } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/count.h b/third_party/libcxx/__algorithm/count.h index 6c8c7fda3..1cfe7f631 100644 --- a/third_party/libcxx/__algorithm/count.h +++ b/third_party/libcxx/__algorithm/count.h @@ -10,26 +10,83 @@ #ifndef _LIBCPP___ALGORITHM_COUNT_H #define _LIBCPP___ALGORITHM_COUNT_H +#include <__algorithm/iterator_operations.h> +#include <__algorithm/min.h> +#include <__bit/invert_if.h> +#include <__bit/popcount.h> #include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__fwd/bit_reference.h> #include <__iterator/iterator_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 - typename iterator_traits<_InputIterator>::difference_type - count(_InputIterator __first, _InputIterator __last, const _Tp& __value) { - typename iterator_traits<_InputIterator>::difference_type __r(0); +// generic implementation +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename _IterOps<_AlgPolicy>::template __difference_type<_Iter> +__count(_Iter __first, _Sent __last, const _Tp& __value, _Proj& __proj) { + typename _IterOps<_AlgPolicy>::template __difference_type<_Iter> __r(0); for (; __first != __last; ++__first) - if (*__first == __value) + if (std::__invoke(__proj, *__first) == __value) ++__r; return __r; } +// __bit_iterator implementation +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __bit_iterator<_Cp, _IsConst>::difference_type +__count_bool(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) { + using _It = __bit_iterator<_Cp, _IsConst>; + using __storage_type = typename _It::__storage_type; + using difference_type = typename _It::difference_type; + + const int __bits_per_word = _It::__bits_per_word; + difference_type __r = 0; + // do first partial word + if (__first.__ctz_ != 0) { + __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); + __storage_type __dn = std::min(__clz_f, __n); + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + __r = std::__libcpp_popcount(std::__invert_if(*__first.__seg_) & __m); + __n -= __dn; + ++__first.__seg_; + } + // do middle whole words + for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) + __r += std::__libcpp_popcount(std::__invert_if(*__first.__seg_)); + // do last partial word + if (__n > 0) { + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + __r += std::__libcpp_popcount(std::__invert_if(*__first.__seg_) & __m); + } + return __r; +} + +template ::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __iter_diff_t<__bit_iterator<_Cp, _IsConst> > +__count(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value, _Proj&) { + if (__value) + return std::__count_bool(__first, static_cast(__last - __first)); + return std::__count_bool(__first, static_cast(__last - __first)); +} + +template +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __iter_diff_t<_InputIterator> +count(_InputIterator __first, _InputIterator __last, const _Tp& __value) { + __identity __proj; + return std::__count<_ClassicAlgPolicy>(__first, __last, __value, __proj); +} + _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_COUNT_H diff --git a/third_party/libcxx/__algorithm/count_if.h b/third_party/libcxx/__algorithm/count_if.h index b96521fe0..25782069d 100644 --- a/third_party/libcxx/__algorithm/count_if.h +++ b/third_party/libcxx/__algorithm/count_if.h @@ -20,9 +20,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 - typename iterator_traits<_InputIterator>::difference_type - count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +typename iterator_traits<_InputIterator>::difference_type +count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) { typename iterator_traits<_InputIterator>::difference_type __r(0); for (; __first != __last; ++__first) if (__pred(*__first)) diff --git a/third_party/libcxx/__algorithm/equal.h b/third_party/libcxx/__algorithm/equal.h index c07d4e208..bfc8f72f6 100644 --- a/third_party/libcxx/__algorithm/equal.h +++ b/third_party/libcxx/__algorithm/equal.h @@ -18,18 +18,20 @@ #include <__iterator/distance.h> #include <__iterator/iterator_traits.h> #include <__string/constexpr_c_functions.h> +#include <__type_traits/desugars_to.h> #include <__type_traits/enable_if.h> -#include <__type_traits/integral_constant.h> #include <__type_traits/is_constant_evaluated.h> #include <__type_traits/is_equality_comparable.h> #include <__type_traits/is_volatile.h> -#include <__type_traits/predicate_traits.h> #include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template @@ -41,41 +43,31 @@ _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 boo return true; } -template < - class _Tp, - class _Up, - class _BinaryPredicate, - __enable_if_t<__is_trivial_equality_predicate<_BinaryPredicate, _Tp, _Up>::value && !is_volatile<_Tp>::value && - !is_volatile<_Up>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value, - int> = 0> +template && !is_volatile<_Tp>::value && + !is_volatile<_Up>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value, + int> = 0> _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_iter_impl(_Tp* __first1, _Tp* __last1, _Up* __first2, _BinaryPredicate&) { - return std::__constexpr_memcmp_equal(__first1, __first2, (__last1 - __first1) * sizeof(_Tp)); + return std::__constexpr_memcmp_equal(__first1, __first2, __element_count(__last1 - __first1)); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) { return std::__equal_iter_impl( std::__unwrap_iter(__first1), std::__unwrap_iter(__last1), std::__unwrap_iter(__first2), __pred); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) { return std::equal(__first1, __last1, __first2, __equal_to()); } #if _LIBCPP_STD_VER >= 14 -template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool -__equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, - _BinaryPredicate __pred, input_iterator_tag, input_iterator_tag) { - for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2) - if (!__pred(*__first1, *__first2)) - return false; - return __first1 == __last1 && __first2 == __last2; -} template _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_impl( @@ -94,22 +86,27 @@ template ::value && __is_identity<_Proj1>::value && + __enable_if_t<__desugars_to_v<__equal_tag, _Pred, _Tp, _Up> && __is_identity<_Proj1>::value && __is_identity<_Proj2>::value && !is_volatile<_Tp>::value && !is_volatile<_Up>::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value, int> = 0> -_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_impl( - _Tp* __first1, _Tp* __last1, _Up* __first2, _Up*, _Pred&, _Proj1&, _Proj2&) { - return std::__constexpr_memcmp_equal(__first1, __first2, (__last1 - __first1) * sizeof(_Tp)); +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +__equal_impl(_Tp* __first1, _Tp* __last1, _Up* __first2, _Up*, _Pred&, _Proj1&, _Proj2&) { + return std::__constexpr_memcmp_equal(__first1, __first2, __element_count(__last1 - __first1)); } -template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool -__equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, - _RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag, - random_access_iterator_tag) { - if (_VSTD::distance(__first1, __last1) != _VSTD::distance(__first2, __last2)) - return false; +template +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +equal(_InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _BinaryPredicate __pred) { + if constexpr (__has_random_access_iterator_category<_InputIterator1>::value && + __has_random_access_iterator_category<_InputIterator2>::value) { + if (std::distance(__first1, __last1) != std::distance(__first2, __last2)) + return false; + } __identity __proj; return std::__equal_impl( std::__unwrap_iter(__first1), @@ -121,29 +118,16 @@ __equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _Random __proj); } -template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool -equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, - _BinaryPredicate __pred) { - return _VSTD::__equal<_BinaryPredicate&>( - __first1, __last1, __first2, __last2, __pred, typename iterator_traits<_InputIterator1>::iterator_category(), - typename iterator_traits<_InputIterator2>::iterator_category()); +template +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { + return std::equal(__first1, __last1, __first2, __last2, __equal_to()); } -template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool -equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { - return std::__equal( - __first1, - __last1, - __first2, - __last2, - __equal_to(), - typename iterator_traits<_InputIterator1>::iterator_category(), - typename iterator_traits<_InputIterator2>::iterator_category()); -} -#endif +#endif // _LIBCPP_STD_VER >= 14 _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_EQUAL_H diff --git a/third_party/libcxx/__algorithm/equal_range.h b/third_party/libcxx/__algorithm/equal_range.h index 2075b0341..09bbf8f00 100644 --- a/third_party/libcxx/__algorithm/equal_range.h +++ b/third_party/libcxx/__algorithm/equal_range.h @@ -23,7 +23,7 @@ #include <__iterator/iterator_traits.h> #include <__iterator/next.h> #include <__type_traits/is_callable.h> -#include <__type_traits/is_copy_constructible.h> +#include <__type_traits/is_constructible.h> #include <__utility/move.h> #include <__utility/pair.h> @@ -31,6 +31,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template @@ -49,21 +52,18 @@ __equal_range(_Iter __first, _Sent __last, const _Tp& __value, _Compare&& __comp __len = __half_len; } else { _Iter __mp1 = __mid; - return pair<_Iter, _Iter>( - std::__lower_bound_impl<_AlgPolicy>(__first, __mid, __value, __comp, __proj), - std::__upper_bound<_AlgPolicy>(++__mp1, __end, __value, __comp, __proj)); + return pair<_Iter, _Iter>(std::__lower_bound<_AlgPolicy>(__first, __mid, __value, __comp, __proj), + std::__upper_bound<_AlgPolicy>(++__mp1, __end, __value, __comp, __proj)); } } return pair<_Iter, _Iter>(__first, __first); } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { - static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value, - "The comparator has to be callable"); - static_assert(is_copy_constructible<_ForwardIterator>::value, - "Iterator has to be copy constructible"); + static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value, "The comparator has to be callable"); + static_assert(is_copy_constructible<_ForwardIterator>::value, "Iterator has to be copy constructible"); return std::__equal_range<_ClassicAlgPolicy>( std::move(__first), std::move(__last), @@ -73,15 +73,13 @@ equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __valu } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { - return std::equal_range( - std::move(__first), - std::move(__last), - __value, - __less::value_type, _Tp>()); + return std::equal_range(std::move(__first), std::move(__last), __value, __less<>()); } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_EQUAL_RANGE_H diff --git a/third_party/libcxx/__algorithm/fill.h b/third_party/libcxx/__algorithm/fill.h index 0753c427a..1ce3eadb0 100644 --- a/third_party/libcxx/__algorithm/fill.h +++ b/third_party/libcxx/__algorithm/fill.h @@ -22,28 +22,22 @@ _LIBCPP_BEGIN_NAMESPACE_STD // fill isn't specialized for std::memset, because the compiler already optimizes the loop to a call to std::memset. template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -void -__fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, forward_iterator_tag) -{ - for (; __first != __last; ++__first) - *__first = __value; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +__fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, forward_iterator_tag) { + for (; __first != __last; ++__first) + *__first = __value; } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -void -__fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value, random_access_iterator_tag) -{ - _VSTD::fill_n(__first, __last - __first, __value); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +__fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value, random_access_iterator_tag) { + std::fill_n(__first, __last - __first, __value); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -void -fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) -{ - _VSTD::__fill(__first, __last, __value, typename iterator_traits<_ForwardIterator>::iterator_category()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { + std::__fill(__first, __last, __value, typename iterator_traits<_ForwardIterator>::iterator_category()); } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/fill_n.h b/third_party/libcxx/__algorithm/fill_n.h index e7863ac7e..f29633f88 100644 --- a/third_party/libcxx/__algorithm/fill_n.h +++ b/third_party/libcxx/__algorithm/fill_n.h @@ -9,36 +9,90 @@ #ifndef _LIBCPP___ALGORITHM_FILL_N_H #define _LIBCPP___ALGORITHM_FILL_N_H +#include <__algorithm/min.h> #include <__config> +#include <__fwd/bit_reference.h> #include <__iterator/iterator_traits.h> +#include <__memory/pointer_traits.h> #include <__utility/convert_to_integral.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD // fill_n isn't specialized for std::memset, because the compiler already optimizes the loop to a call to std::memset. template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) -{ - for (; __n > 0; ++__first, (void) --__n) - *__first = __value; - return __first; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value); + +template +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void +__fill_n_bool(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n) { + using _It = __bit_iterator<_Cp, false>; + using __storage_type = typename _It::__storage_type; + + const int __bits_per_word = _It::__bits_per_word; + // do first partial word + if (__first.__ctz_ != 0) { + __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); + __storage_type __dn = std::min(__clz_f, __n); + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + if (_FillVal) + *__first.__seg_ |= __m; + else + *__first.__seg_ &= ~__m; + __n -= __dn; + ++__first.__seg_; + } + // do middle whole words + __storage_type __nw = __n / __bits_per_word; + std::__fill_n(std::__to_address(__first.__seg_), __nw, _FillVal ? static_cast<__storage_type>(-1) : 0); + __n -= __nw * __bits_per_word; + // do last partial word + if (__n > 0) { + __first.__seg_ += __nw; + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + if (_FillVal) + *__first.__seg_ |= __m; + else + *__first.__seg_ &= ~__m; + } +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false> +__fill_n(__bit_iterator<_Cp, false> __first, _Size __n, const bool& __value) { + if (__n > 0) { + if (__value) + std::__fill_n_bool(__first, __n); + else + std::__fill_n_bool(__first, __n); + } + return __first + __n; } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) -{ - return _VSTD::__fill_n(__first, _VSTD::__convert_to_integral(__n), __value); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) { + for (; __n > 0; ++__first, (void)--__n) + *__first = __value; + return __first; +} + +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +fill_n(_OutputIterator __first, _Size __n, const _Tp& __value) { + return std::__fill_n(__first, std::__convert_to_integral(__n), __value); } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_FILL_N_H diff --git a/third_party/libcxx/__algorithm/find.h b/third_party/libcxx/__algorithm/find.h index e0de50328..7f58dbb13 100644 --- a/third_party/libcxx/__algorithm/find.h +++ b/third_party/libcxx/__algorithm/find.h @@ -10,12 +10,22 @@ #ifndef _LIBCPP___ALGORITHM_FIND_H #define _LIBCPP___ALGORITHM_FIND_H +#include <__algorithm/find_segment_if.h> +#include <__algorithm/min.h> #include <__algorithm/unwrap_iter.h> +#include <__bit/countr.h> +#include <__bit/invert_if.h> #include <__config> #include <__functional/identity.h> #include <__functional/invoke.h> +#include <__fwd/bit_reference.h> +#include <__iterator/segmented_iterator.h> #include <__string/constexpr_c_functions.h> +#include <__type_traits/is_integral.h> #include <__type_traits/is_same.h> +#include <__type_traits/is_signed.h> +#include <__utility/move.h> +#include #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS # include @@ -25,25 +35,29 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD +// generic implementation template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter -__find_impl(_Iter __first, _Sent __last, const _Tp& __value, _Proj& __proj) { +__find(_Iter __first, _Sent __last, const _Tp& __value, _Proj& __proj) { for (; __first != __last; ++__first) if (std::__invoke(__proj, *__first) == __value) break; return __first; } +// trivially equality comparable implementations template ::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value && sizeof(_Tp) == 1, int> = 0> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* -__find_impl(_Tp* __first, _Tp* __last, const _Up& __value, _Proj&) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __find(_Tp* __first, _Tp* __last, const _Up& __value, _Proj&) { if (auto __ret = std::__constexpr_memchr(__first, __value, __last - __first)) return __ret; return __last; @@ -56,22 +70,112 @@ template ::value && __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value && sizeof(_Tp) == sizeof(wchar_t) && _LIBCPP_ALIGNOF(_Tp) >= _LIBCPP_ALIGNOF(wchar_t), int> = 0> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* -__find_impl(_Tp* __first, _Tp* __last, const _Up& __value, _Proj&) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* __find(_Tp* __first, _Tp* __last, const _Up& __value, _Proj&) { if (auto __ret = std::__constexpr_wmemchr(__first, __value, __last - __first)) return __ret; return __last; } #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS +// TODO: This should also be possible to get right with different signedness +// cast integral types to allow vectorization +template ::value && !__libcpp_is_trivially_equality_comparable<_Tp, _Up>::value && + is_integral<_Tp>::value && is_integral<_Up>::value && + is_signed<_Tp>::value == is_signed<_Up>::value, + int> = 0> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp* +__find(_Tp* __first, _Tp* __last, const _Up& __value, _Proj& __proj) { + if (__value < numeric_limits<_Tp>::min() || __value > numeric_limits<_Tp>::max()) + return __last; + return std::__find(__first, __last, _Tp(__value), __proj); +} + +// __bit_iterator implementation +template +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, _IsConst> +__find_bool(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) { + using _It = __bit_iterator<_Cp, _IsConst>; + using __storage_type = typename _It::__storage_type; + + const int __bits_per_word = _It::__bits_per_word; + // do first partial word + if (__first.__ctz_ != 0) { + __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); + __storage_type __dn = std::min(__clz_f, __n); + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + __storage_type __b = std::__invert_if(*__first.__seg_) & __m; + if (__b) + return _It(__first.__seg_, static_cast(std::__libcpp_ctz(__b))); + if (__n == __dn) + return __first + __n; + __n -= __dn; + ++__first.__seg_; + } + // do middle whole words + for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) { + __storage_type __b = std::__invert_if(*__first.__seg_); + if (__b) + return _It(__first.__seg_, static_cast(std::__libcpp_ctz(__b))); + } + // do last partial word + if (__n > 0) { + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + __storage_type __b = std::__invert_if(*__first.__seg_) & __m; + if (__b) + return _It(__first.__seg_, static_cast(std::__libcpp_ctz(__b))); + } + return _It(__first.__seg_, static_cast(__n)); +} + +template ::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, _IsConst> +__find(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value, _Proj&) { + if (static_cast(__value)) + return std::__find_bool(__first, static_cast(__last - __first)); + return std::__find_bool(__first, static_cast(__last - __first)); +} + +// segmented iterator implementation + +template +struct __find_segment; + +template ::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _SegmentedIterator +__find(_SegmentedIterator __first, _SegmentedIterator __last, const _Tp& __value, _Proj& __proj) { + return std::__find_segment_if(std::move(__first), std::move(__last), __find_segment<_Tp>(__value), __proj); +} + +template +struct __find_segment { + const _Tp& __value_; + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __find_segment(const _Tp& __value) : __value_(__value) {} + + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _InputIterator + operator()(_InputIterator __first, _InputIterator __last, _Proj& __proj) const { + return std::__find(__first, __last, __value_, __proj); + } +}; + +// public API template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator find(_InputIterator __first, _InputIterator __last, const _Tp& __value) { __identity __proj; return std::__rewrap_iter( - __first, std::__find_impl(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __value, __proj)); + __first, std::__find(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __value, __proj)); } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_FIND_H diff --git a/third_party/libcxx/__algorithm/find_end.h b/third_party/libcxx/__algorithm/find_end.h index edb9891c6..7e08e7953 100644 --- a/third_party/libcxx/__algorithm/find_end.h +++ b/third_party/libcxx/__algorithm/find_end.h @@ -28,15 +28,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template < - class _AlgPolicy, - class _Iter1, - class _Sent1, - class _Iter2, - class _Sent2, - class _Pred, - class _Proj1, - class _Proj2> +template < class _AlgPolicy, + class _Iter1, + class _Sent1, + class _Iter2, + class _Sent2, + class _Pred, + class _Proj1, + class _Proj2> _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __find_end_impl( _Iter1 __first1, _Sent1 __last1, @@ -49,7 +48,7 @@ _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> forward_iterator_tag) { // modeled after search algorithm _Iter1 __match_first = _IterOps<_AlgPolicy>::next(__first1, __last1); // __last1 is the "default" answer - _Iter1 __match_last = __match_first; + _Iter1 __match_last = __match_first; if (__first2 == __last2) return pair<_Iter1, _Iter1>(__match_last, __match_last); while (true) { @@ -66,15 +65,14 @@ _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> while (true) { if (++__m2 == __last2) { // Pattern exhaused, record answer and search for another one __match_first = __first1; - __match_last = ++__m1; + __match_last = ++__m1; ++__first1; break; } if (++__m1 == __last1) // Source exhausted, return last answer return pair<_Iter1, _Iter1>(__match_first, __match_last); - // mismatch, restart with a new __first - if (!std::__invoke(__pred, std::__invoke(__proj1, *__m1), std::__invoke(__proj2, *__m2))) - { + // mismatch, restart with a new __first + if (!std::__invoke(__pred, std::__invoke(__proj1, *__m1), std::__invoke(__proj2, *__m2))) { ++__first1; break; } // else there is a match, check next elements @@ -82,15 +80,14 @@ _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> } } -template < - class _IterOps, - class _Pred, - class _Iter1, - class _Sent1, - class _Iter2, - class _Sent2, - class _Proj1, - class _Proj2> +template < class _IterOps, + class _Pred, + class _Iter1, + class _Sent1, + class _Iter2, + class _Sent2, + class _Proj1, + class _Proj2> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter1 __find_end( _Iter1 __first1, _Sent1 __sent1, @@ -127,23 +124,21 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter1 __find_end( return __last1; // if there is a mismatch, restart with a new __l1 - if (!std::__invoke(__pred, std::__invoke(__proj1, *--__m1), std::__invoke(__proj2, *--__m2))) - { + if (!std::__invoke(__pred, std::__invoke(__proj1, *--__m1), std::__invoke(__proj2, *--__m2))) { break; } // else there is a match, check next elements } } } -template < - class _AlgPolicy, - class _Pred, - class _Iter1, - class _Sent1, - class _Iter2, - class _Sent2, - class _Proj1, - class _Proj2> +template < class _AlgPolicy, + class _Pred, + class _Iter1, + class _Sent1, + class _Iter2, + class _Sent2, + class _Proj1, + class _Proj2> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter1 __find_end( _Iter1 __first1, _Sent1 __sent1, @@ -165,8 +160,8 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter1 __find_end( if (__len1 < __len2) return __last1; const _Iter1 __s = __first1 + _D1(__len2 - 1); // End of pattern match can't go before here - _Iter1 __l1 = __last1; - _Iter2 __l2 = __last2; + _Iter1 __l1 = __last1; + _Iter2 __l2 = __last2; --__l2; while (true) { while (true) { @@ -189,10 +184,12 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter1 __find_end( } template -_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -_ForwardIterator1 __find_end_classic(_ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, - _BinaryPredicate& __pred) { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator1 __find_end_classic( + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _BinaryPredicate& __pred) { auto __proj = __identity(); return std::__find_end_impl<_ClassicAlgPolicy>( __first1, @@ -208,17 +205,18 @@ _ForwardIterator1 __find_end_classic(_ForwardIterator1 __first1, _ForwardIterato } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_ForwardIterator1 find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, - _BinaryPredicate __pred) { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_end( + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _BinaryPredicate __pred) { return std::__find_end_classic(__first1, __last1, __first2, __last2, __pred); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_ForwardIterator1 find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2) { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 +find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { return std::find_end(__first1, __last1, __first2, __last2, __equal_to()); } diff --git a/third_party/libcxx/__algorithm/find_first_of.h b/third_party/libcxx/__algorithm/find_first_of.h index 12f0109a6..6b99f562f 100644 --- a/third_party/libcxx/__algorithm/find_first_of.h +++ b/third_party/libcxx/__algorithm/find_first_of.h @@ -21,12 +21,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI -_LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator1 __find_first_of_ce(_ForwardIterator1 __first1, - _ForwardIterator1 __last1, - _ForwardIterator2 __first2, - _ForwardIterator2 __last2, - _BinaryPredicate&& __pred) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator1 __find_first_of_ce( + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _BinaryPredicate&& __pred) { for (; __first1 != __last1; ++__first1) for (_ForwardIterator2 __j = __first2; __j != __last2; ++__j) if (__pred(*__first1, *__j)) @@ -35,14 +35,17 @@ _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator1 __find_first_of_ce(_ForwardItera } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 -find_first_of(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _BinaryPredicate __pred) { - return _VSTD::__find_first_of_ce(__first1, __last1, __first2, __last2, __pred); +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_first_of( + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _BinaryPredicate __pred) { + return std::__find_first_of_ce(__first1, __last1, __first2, __last2, __pred); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_first_of( +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 find_first_of( _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { return std::__find_first_of_ce(__first1, __last1, __first2, __last2, __equal_to()); } diff --git a/third_party/libcxx/__algorithm/find_if.h b/third_party/libcxx/__algorithm/find_if.h index f4ef3ac31..22092d352 100644 --- a/third_party/libcxx/__algorithm/find_if.h +++ b/third_party/libcxx/__algorithm/find_if.h @@ -19,7 +19,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator find_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) { for (; __first != __last; ++__first) if (__pred(*__first)) diff --git a/third_party/libcxx/__algorithm/find_if_not.h b/third_party/libcxx/__algorithm/find_if_not.h index 96c159cf5..cc2001967 100644 --- a/third_party/libcxx/__algorithm/find_if_not.h +++ b/third_party/libcxx/__algorithm/find_if_not.h @@ -19,7 +19,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator find_if_not(_InputIterator __first, _InputIterator __last, _Predicate __pred) { for (; __first != __last; ++__first) if (!__pred(*__first)) diff --git a/third_party/libcxx/__algorithm/find_segment_if.h b/third_party/libcxx/__algorithm/find_segment_if.h new file mode 100644 index 000000000..9d6064f3e --- /dev/null +++ b/third_party/libcxx/__algorithm/find_segment_if.h @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_FIND_SEGMENT_IF_H +#define _LIBCPP___ALGORITHM_FIND_SEGMENT_IF_H + +#include <__config> +#include <__iterator/segmented_iterator.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// __find_segment_if is a utility function for optimizing iteration over segmented iterators linearly. +// [__first, __last) has to be a segmented range. __pred is expected to take a range of local iterators and the __proj. +// It returns an iterator to the first element that satisfies the predicate, or a one-past-the-end iterator if there was +// no match. __proj may be anything that should be passed to __pred, but is expected to be a projection to support +// ranges algorithms, or __identity for classic algorithms. + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _SegmentedIterator +__find_segment_if(_SegmentedIterator __first, _SegmentedIterator __last, _Pred __pred, _Proj& __proj) { + using _Traits = __segmented_iterator_traits<_SegmentedIterator>; + + auto __sfirst = _Traits::__segment(__first); + auto __slast = _Traits::__segment(__last); + + // We are in a single segment, so we might not be at the beginning or end + if (__sfirst == __slast) + return _Traits::__compose(__sfirst, __pred(_Traits::__local(__first), _Traits::__local(__last), __proj)); + + { // We have more than one segment. Iterate over the first segment, since we might not start at the beginning + auto __llast = _Traits::__end(__sfirst); + auto __liter = __pred(_Traits::__local(__first), __llast, __proj); + if (__liter != __llast) + return _Traits::__compose(__sfirst, __liter); + } + ++__sfirst; + + // Iterate over the segments which are guaranteed to be completely in the range + while (__sfirst != __slast) { + auto __llast = _Traits::__end(__sfirst); + auto __liter = __pred(_Traits::__begin(__sfirst), _Traits::__end(__sfirst), __proj); + if (__liter != __llast) + return _Traits::__compose(__sfirst, __liter); + ++__sfirst; + } + + // Iterate over the last segment + return _Traits::__compose(__sfirst, __pred(_Traits::__begin(__sfirst), _Traits::__local(__last), __proj)); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ALGORITHM_FIND_SEGMENT_IF_H diff --git a/third_party/libcxx/__algorithm/fold.h b/third_party/libcxx/__algorithm/fold.h new file mode 100644 index 000000000..255658f52 --- /dev/null +++ b/third_party/libcxx/__algorithm/fold.h @@ -0,0 +1,128 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_FOLD_H +#define _LIBCPP___ALGORITHM_FOLD_H + +#include <__concepts/assignable.h> +#include <__concepts/convertible_to.h> +#include <__concepts/invocable.h> +#include <__concepts/movable.h> +#include <__config> +#include <__functional/invoke.h> +#include <__functional/reference_wrapper.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__type_traits/decay.h> +#include <__type_traits/invoke.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER >= 23 + +namespace ranges { +template +struct in_value_result { + _LIBCPP_NO_UNIQUE_ADDRESS _Ip in; + _LIBCPP_NO_UNIQUE_ADDRESS _Tp value; + + template + requires convertible_to && convertible_to + _LIBCPP_HIDE_FROM_ABI constexpr operator in_value_result<_I2, _T2>() const& { + return {in, value}; + } + + template + requires convertible_to<_Ip, _I2> && convertible_to<_Tp, _T2> + _LIBCPP_HIDE_FROM_ABI constexpr operator in_value_result<_I2, _T2>() && { + return {std::move(in), std::move(value)}; + } +}; + +template +using fold_left_with_iter_result = in_value_result<_Ip, _Tp>; + +template > +concept __indirectly_binary_left_foldable_impl = + convertible_to<_Rp, _Up> && // + movable<_Tp> && // + movable<_Up> && // + convertible_to<_Tp, _Up> && // + invocable<_Fp&, _Up, iter_reference_t<_Ip>> && // + assignable_from<_Up&, invoke_result_t<_Fp&, _Up, iter_reference_t<_Ip>>>; + +template +concept __indirectly_binary_left_foldable = + copy_constructible<_Fp> && // + invocable<_Fp&, _Tp, iter_reference_t<_Ip>> && // + __indirectly_binary_left_foldable_impl<_Fp, _Tp, _Ip, invoke_result_t<_Fp&, _Tp, iter_reference_t<_Ip>>>; + +struct __fold_left_with_iter { + template _Sp, class _Tp, __indirectly_binary_left_foldable<_Tp, _Ip> _Fp> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Ip __first, _Sp __last, _Tp __init, _Fp __f) { + using _Up = decay_t>>; + + if (__first == __last) { + return fold_left_with_iter_result<_Ip, _Up>{std::move(__first), _Up(std::move(__init))}; + } + + _Up __result = std::invoke(__f, std::move(__init), *__first); + for (++__first; __first != __last; ++__first) { + __result = std::invoke(__f, std::move(__result), *__first); + } + + return fold_left_with_iter_result<_Ip, _Up>{std::move(__first), std::move(__result)}; + } + + template > _Fp> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Rp&& __r, _Tp __init, _Fp __f) { + auto __result = operator()(ranges::begin(__r), ranges::end(__r), std::move(__init), std::ref(__f)); + + using _Up = decay_t>>; + return fold_left_with_iter_result, _Up>{std::move(__result.in), std::move(__result.value)}; + } +}; + +inline constexpr auto fold_left_with_iter = __fold_left_with_iter(); + +struct __fold_left { + template _Sp, class _Tp, __indirectly_binary_left_foldable<_Tp, _Ip> _Fp> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Ip __first, _Sp __last, _Tp __init, _Fp __f) { + return fold_left_with_iter(std::move(__first), std::move(__last), std::move(__init), std::ref(__f)).value; + } + + template > _Fp> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Rp&& __r, _Tp __init, _Fp __f) { + return fold_left_with_iter(ranges::begin(__r), ranges::end(__r), std::move(__init), std::ref(__f)).value; + } +}; + +inline constexpr auto fold_left = __fold_left(); +} // namespace ranges + +#endif // _LIBCPP_STD_VER >= 23 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___ALGORITHM_FOLD_H diff --git a/third_party/libcxx/__algorithm/for_each.h b/third_party/libcxx/__algorithm/for_each.h index 5e273cf1b..259e527f8 100644 --- a/third_party/libcxx/__algorithm/for_each.h +++ b/third_party/libcxx/__algorithm/for_each.h @@ -13,13 +13,18 @@ #include <__algorithm/for_each_segment.h> #include <__config> #include <__iterator/segmented_iterator.h> +#include <__ranges/movable_box.h> #include <__type_traits/enable_if.h> +#include <__utility/in_place.h> #include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template @@ -30,18 +35,23 @@ for_each(_InputIterator __first, _InputIterator __last, _Function __f) { return __f; } -#if _LIBCPP_STD_VER >= 20 +// __movable_box is available in C++20, but is actually a copyable-box, so optimization is only correct in C++23 +#if _LIBCPP_STD_VER >= 23 template requires __is_segmented_iterator<_SegmentedIterator>::value -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Function +_LIBCPP_HIDE_FROM_ABI constexpr _Function for_each(_SegmentedIterator __first, _SegmentedIterator __last, _Function __func) { + ranges::__movable_box<_Function> __wrapped_func(in_place, std::move(__func)); std::__for_each_segment(__first, __last, [&](auto __lfirst, auto __llast) { - __func = std::for_each(__lfirst, __llast, std::move(__func)); + __wrapped_func = + ranges::__movable_box<_Function>(in_place, std::for_each(__lfirst, __llast, std::move(*__wrapped_func))); }); - return __func; + return std::move(*__wrapped_func); } -#endif // _LIBCPP_STD_VER >= 20 +#endif // _LIBCPP_STD_VER >= 23 _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_FOR_EACH_H diff --git a/third_party/libcxx/__algorithm/for_each_n.h b/third_party/libcxx/__algorithm/for_each_n.h index 5bd731822..fce380b49 100644 --- a/third_party/libcxx/__algorithm/for_each_n.h +++ b/third_party/libcxx/__algorithm/for_each_n.h @@ -22,10 +22,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 17 template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator for_each_n(_InputIterator __first, - _Size __orig_n, - _Function __f) { - typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _InputIterator +for_each_n(_InputIterator __first, _Size __orig_n, _Function __f) { + typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize; _IntegralSize __n = __orig_n; while (__n > 0) { __f(*__first); diff --git a/third_party/libcxx/__algorithm/generate.h b/third_party/libcxx/__algorithm/generate.h index 48e21b51e..c95b52740 100644 --- a/third_party/libcxx/__algorithm/generate.h +++ b/third_party/libcxx/__algorithm/generate.h @@ -18,12 +18,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -void -generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) -{ - for (; __first != __last; ++__first) - *__first = __gen(); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) { + for (; __first != __last; ++__first) + *__first = __gen(); } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/generate_n.h b/third_party/libcxx/__algorithm/generate_n.h index ff5c82d3e..f36403fd0 100644 --- a/third_party/libcxx/__algorithm/generate_n.h +++ b/third_party/libcxx/__algorithm/generate_n.h @@ -19,15 +19,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -generate_n(_OutputIterator __first, _Size __orig_n, _Generator __gen) -{ - typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize; - _IntegralSize __n = __orig_n; - for (; __n > 0; ++__first, (void) --__n) - *__first = __gen(); - return __first; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +generate_n(_OutputIterator __first, _Size __orig_n, _Generator __gen) { + typedef decltype(std::__convert_to_integral(__orig_n)) _IntegralSize; + _IntegralSize __n = __orig_n; + for (; __n > 0; ++__first, (void)--__n) + *__first = __gen(); + return __first; } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/half_positive.h b/third_party/libcxx/__algorithm/half_positive.h index 5a0f4baf6..ebda0da37 100644 --- a/third_party/libcxx/__algorithm/half_positive.h +++ b/third_party/libcxx/__algorithm/half_positive.h @@ -22,28 +22,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD // Perform division by two quickly for positive integers (llvm.org/PR39129) -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -typename enable_if -< - is_integral<_Integral>::value, - _Integral ->::type -__half_positive(_Integral __value) -{ - return static_cast<_Integral>(static_cast<__make_unsigned_t<_Integral> >(__value) / 2); +template ::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Integral __half_positive(_Integral __value) { + return static_cast<_Integral>(static_cast<__make_unsigned_t<_Integral> >(__value) / 2); } -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -typename enable_if -< - !is_integral<_Tp>::value, - _Tp ->::type -__half_positive(_Tp __value) -{ - return __value / 2; +template ::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp __half_positive(_Tp __value) { + return __value / 2; } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/in_found_result.h b/third_party/libcxx/__algorithm/in_found_result.h index d9ca287f0..a67ae3879 100644 --- a/third_party/libcxx/__algorithm/in_found_result.h +++ b/third_party/libcxx/__algorithm/in_found_result.h @@ -18,6 +18,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -30,7 +33,7 @@ struct in_found_result { template requires convertible_to - _LIBCPP_HIDE_FROM_ABI constexpr operator in_found_result<_InIter2>() const & { + _LIBCPP_HIDE_FROM_ABI constexpr operator in_found_result<_InIter2>() const& { return {in, found}; } @@ -46,4 +49,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_IN_FOUND_RESULT_H diff --git a/third_party/libcxx/__algorithm/in_fun_result.h b/third_party/libcxx/__algorithm/in_fun_result.h index 33374eddc..a22069a9a 100644 --- a/third_party/libcxx/__algorithm/in_fun_result.h +++ b/third_party/libcxx/__algorithm/in_fun_result.h @@ -18,6 +18,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 @@ -30,7 +33,7 @@ struct in_fun_result { template requires convertible_to && convertible_to - _LIBCPP_HIDE_FROM_ABI constexpr operator in_fun_result<_InIter2, _Func2>() const & { + _LIBCPP_HIDE_FROM_ABI constexpr operator in_fun_result<_InIter2, _Func2>() const& { return {in, fun}; } @@ -46,4 +49,6 @@ struct in_fun_result { _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_IN_FUN_RESULT_H diff --git a/third_party/libcxx/__algorithm/in_in_out_result.h b/third_party/libcxx/__algorithm/in_in_out_result.h index 6b50e0e24..ba0380b5c 100644 --- a/third_party/libcxx/__algorithm/in_in_out_result.h +++ b/third_party/libcxx/__algorithm/in_in_out_result.h @@ -18,6 +18,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 @@ -31,18 +34,16 @@ struct in_in_out_result { _LIBCPP_NO_UNIQUE_ADDRESS _OutIter1 out; template - requires convertible_to - && convertible_to && convertible_to - _LIBCPP_HIDE_FROM_ABI constexpr - operator in_in_out_result<_InIter3, _InIter4, _OutIter2>() const& { + requires convertible_to && convertible_to && + convertible_to + _LIBCPP_HIDE_FROM_ABI constexpr operator in_in_out_result<_InIter3, _InIter4, _OutIter2>() const& { return {in1, in2, out}; } template - requires convertible_to<_InIter1, _InIter3> - && convertible_to<_InIter2, _InIter4> && convertible_to<_OutIter1, _OutIter2> - _LIBCPP_HIDE_FROM_ABI constexpr - operator in_in_out_result<_InIter3, _InIter4, _OutIter2>() && { + requires convertible_to<_InIter1, _InIter3> && convertible_to<_InIter2, _InIter4> && + convertible_to<_OutIter1, _OutIter2> + _LIBCPP_HIDE_FROM_ABI constexpr operator in_in_out_result<_InIter3, _InIter4, _OutIter2>() && { return {std::move(in1), std::move(in2), std::move(out)}; } }; @@ -53,4 +54,6 @@ struct in_in_out_result { _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_IN_IN_OUT_RESULT_H diff --git a/third_party/libcxx/__algorithm/in_in_result.h b/third_party/libcxx/__algorithm/in_in_result.h index 1eceb9de0..994573fc7 100644 --- a/third_party/libcxx/__algorithm/in_in_result.h +++ b/third_party/libcxx/__algorithm/in_in_result.h @@ -18,6 +18,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 @@ -31,15 +34,13 @@ struct in_in_result { template requires convertible_to && convertible_to - _LIBCPP_HIDE_FROM_ABI constexpr - operator in_in_result<_InIter3, _InIter4>() const & { + _LIBCPP_HIDE_FROM_ABI constexpr operator in_in_result<_InIter3, _InIter4>() const& { return {in1, in2}; } template requires convertible_to<_InIter1, _InIter3> && convertible_to<_InIter2, _InIter4> - _LIBCPP_HIDE_FROM_ABI constexpr - operator in_in_result<_InIter3, _InIter4>() && { + _LIBCPP_HIDE_FROM_ABI constexpr operator in_in_result<_InIter3, _InIter4>() && { return {std::move(in1), std::move(in2)}; } }; @@ -50,4 +51,6 @@ struct in_in_result { _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_IN_IN_RESULT_H diff --git a/third_party/libcxx/__algorithm/in_out_out_result.h b/third_party/libcxx/__algorithm/in_out_out_result.h index 2f7a09b5c..8ceb45284 100644 --- a/third_party/libcxx/__algorithm/in_out_out_result.h +++ b/third_party/libcxx/__algorithm/in_out_out_result.h @@ -18,6 +18,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 @@ -30,18 +33,16 @@ struct in_out_out_result { _LIBCPP_NO_UNIQUE_ADDRESS _OutIter2 out2; template - requires convertible_to - && convertible_to && convertible_to - _LIBCPP_HIDE_FROM_ABI constexpr - operator in_out_out_result<_InIter2, _OutIter3, _OutIter4>() const& { + requires convertible_to && convertible_to && + convertible_to + _LIBCPP_HIDE_FROM_ABI constexpr operator in_out_out_result<_InIter2, _OutIter3, _OutIter4>() const& { return {in, out1, out2}; } template - requires convertible_to<_InIter1, _InIter2> - && convertible_to<_OutIter1, _OutIter3> && convertible_to<_OutIter2, _OutIter4> - _LIBCPP_HIDE_FROM_ABI constexpr - operator in_out_out_result<_InIter2, _OutIter3, _OutIter4>() && { + requires convertible_to<_InIter1, _InIter2> && convertible_to<_OutIter1, _OutIter3> && + convertible_to<_OutIter2, _OutIter4> + _LIBCPP_HIDE_FROM_ABI constexpr operator in_out_out_result<_InIter2, _OutIter3, _OutIter4>() && { return {std::move(in), std::move(out1), std::move(out2)}; } }; @@ -51,4 +52,6 @@ struct in_out_out_result { _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_IN_OUT_OUT_RESULT_H diff --git a/third_party/libcxx/__algorithm/in_out_result.h b/third_party/libcxx/__algorithm/in_out_result.h index 158b35532..a7a986cf8 100644 --- a/third_party/libcxx/__algorithm/in_out_result.h +++ b/third_party/libcxx/__algorithm/in_out_result.h @@ -18,28 +18,29 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 namespace ranges { -template +template struct in_out_result { _LIBCPP_NO_UNIQUE_ADDRESS _InIter1 in; _LIBCPP_NO_UNIQUE_ADDRESS _OutIter1 out; template requires convertible_to && convertible_to - _LIBCPP_HIDE_FROM_ABI - constexpr operator in_out_result<_InIter2, _OutIter2>() const & { + _LIBCPP_HIDE_FROM_ABI constexpr operator in_out_result<_InIter2, _OutIter2>() const& { return {in, out}; } template requires convertible_to<_InIter1, _InIter2> && convertible_to<_OutIter1, _OutIter2> - _LIBCPP_HIDE_FROM_ABI - constexpr operator in_out_result<_InIter2, _OutIter2>() && { + _LIBCPP_HIDE_FROM_ABI constexpr operator in_out_result<_InIter2, _OutIter2>() && { return {std::move(in), std::move(out)}; } }; @@ -50,4 +51,6 @@ struct in_out_result { _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_IN_OUT_RESULT_H diff --git a/third_party/libcxx/__algorithm/includes.h b/third_party/libcxx/__algorithm/includes.h index cc39f275b..62af03c37 100644 --- a/third_party/libcxx/__algorithm/includes.h +++ b/third_party/libcxx/__algorithm/includes.h @@ -22,15 +22,23 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool -__includes(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, - _Comp&& __comp, _Proj1&& __proj1, _Proj2&& __proj2) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __includes( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Comp&& __comp, + _Proj1&& __proj1, + _Proj2&& __proj2) { for (; __first2 != __last2; ++__first1) { - if (__first1 == __last1 || std::__invoke( - __comp, std::__invoke(__proj2, *__first2), std::__invoke(__proj1, *__first1))) + if (__first1 == __last1 || + std::__invoke(__comp, std::__invoke(__proj2, *__first2), std::__invoke(__proj1, *__first1))) return false; if (!std::__invoke(__comp, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2))) ++__first2; @@ -39,14 +47,14 @@ __includes(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool includes( - _InputIterator1 __first1, - _InputIterator1 __last1, - _InputIterator2 __first2, - _InputIterator2 __last2, - _Compare __comp) { - static_assert(__is_callable<_Compare, decltype(*__first1), decltype(*__first2)>::value, - "Comparator has to be callable"); +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +includes(_InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _Compare __comp) { + static_assert( + __is_callable<_Compare, decltype(*__first1), decltype(*__first2)>::value, "Comparator has to be callable"); return std::__includes( std::move(__first1), @@ -59,17 +67,13 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { - return std::includes( - std::move(__first1), - std::move(__last1), - std::move(__first2), - std::move(__last2), - __less::value_type, - typename iterator_traits<_InputIterator2>::value_type>()); + return std::includes(std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __less<>()); } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_INCLUDES_H diff --git a/third_party/libcxx/__algorithm/inplace_merge.h b/third_party/libcxx/__algorithm/inplace_merge.h index 5bbefc94b..a6bcc66a2 100644 --- a/third_party/libcxx/__algorithm/inplace_merge.h +++ b/third_party/libcxx/__algorithm/inplace_merge.h @@ -42,54 +42,57 @@ template class __invert // invert the sense of a comparison { private: - _Predicate __p_; + _Predicate __p_; + public: - _LIBCPP_INLINE_VISIBILITY __invert() {} + _LIBCPP_HIDE_FROM_ABI __invert() {} - _LIBCPP_INLINE_VISIBILITY - explicit __invert(_Predicate __p) : __p_(__p) {} + _LIBCPP_HIDE_FROM_ABI explicit __invert(_Predicate __p) : __p_(__p) {} - template - _LIBCPP_INLINE_VISIBILITY - bool operator()(const _T1& __x) {return !__p_(__x);} + template + _LIBCPP_HIDE_FROM_ABI bool operator()(const _T1& __x) { + return !__p_(__x); + } - template - _LIBCPP_INLINE_VISIBILITY - bool operator()(const _T1& __x, const _T2& __y) {return __p_(__y, __x);} + template + _LIBCPP_HIDE_FROM_ABI bool operator()(const _T1& __x, const _T2& __y) { + return __p_(__y, __x); + } }; -template -_LIBCPP_HIDE_FROM_ABI -void __half_inplace_merge(_InputIterator1 __first1, _Sent1 __last1, - _InputIterator2 __first2, _Sent2 __last2, - _OutputIterator __result, _Compare&& __comp) -{ - for (; __first1 != __last1; ++__result) - { - if (__first2 == __last2) - { - std::__move<_AlgPolicy>(__first1, __last1, __result); - return; - } - - if (__comp(*__first2, *__first1)) - { - *__result = _IterOps<_AlgPolicy>::__iter_move(__first2); - ++__first2; - } - else - { - *__result = _IterOps<_AlgPolicy>::__iter_move(__first1); - ++__first1; - } +template +_LIBCPP_HIDE_FROM_ABI void __half_inplace_merge( + _InputIterator1 __first1, + _Sent1 __last1, + _InputIterator2 __first2, + _Sent2 __last2, + _OutputIterator __result, + _Compare&& __comp) { + for (; __first1 != __last1; ++__result) { + if (__first2 == __last2) { + std::__move<_AlgPolicy>(__first1, __last1, __result); + return; } - // __first2 through __last2 are already in the right spot. + + if (__comp(*__first2, *__first1)) { + *__result = _IterOps<_AlgPolicy>::__iter_move(__first2); + ++__first2; + } else { + *__result = _IterOps<_AlgPolicy>::__iter_move(__first1); + ++__first1; + } + } + // __first2 through __last2 are already in the right spot. } template -_LIBCPP_HIDE_FROM_ABI -void __buffered_inplace_merge( +_LIBCPP_HIDE_FROM_ABI void __buffered_inplace_merge( _BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, @@ -98,27 +101,25 @@ void __buffered_inplace_merge( typename iterator_traits<_BidirectionalIterator>::difference_type __len2, typename iterator_traits<_BidirectionalIterator>::value_type* __buff) { typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; - __destruct_n __d(0); - unique_ptr __h2(__buff, __d); - if (__len1 <= __len2) - { - value_type* __p = __buff; - for (_BidirectionalIterator __i = __first; __i != __middle; __d.template __incr(), (void) ++__i, (void) ++__p) - ::new ((void*)__p) value_type(_IterOps<_AlgPolicy>::__iter_move(__i)); - std::__half_inplace_merge<_AlgPolicy>(__buff, __p, __middle, __last, __first, __comp); - } - else - { - value_type* __p = __buff; - for (_BidirectionalIterator __i = __middle; __i != __last; __d.template __incr(), (void) ++__i, (void) ++__p) - ::new ((void*)__p) value_type(_IterOps<_AlgPolicy>::__iter_move(__i)); - typedef __unconstrained_reverse_iterator<_BidirectionalIterator> _RBi; - typedef __unconstrained_reverse_iterator _Rv; - typedef __invert<_Compare> _Inverted; - std::__half_inplace_merge<_AlgPolicy>(_Rv(__p), _Rv(__buff), - _RBi(__middle), _RBi(__first), - _RBi(__last), _Inverted(__comp)); - } + __destruct_n __d(0); + unique_ptr __h2(__buff, __d); + if (__len1 <= __len2) { + value_type* __p = __buff; + for (_BidirectionalIterator __i = __first; __i != __middle; + __d.template __incr(), (void)++__i, (void)++__p) + ::new ((void*)__p) value_type(_IterOps<_AlgPolicy>::__iter_move(__i)); + std::__half_inplace_merge<_AlgPolicy>(__buff, __p, __middle, __last, __first, __comp); + } else { + value_type* __p = __buff; + for (_BidirectionalIterator __i = __middle; __i != __last; + __d.template __incr(), (void)++__i, (void)++__p) + ::new ((void*)__p) value_type(_IterOps<_AlgPolicy>::__iter_move(__i)); + typedef reverse_iterator<_BidirectionalIterator> _RBi; + typedef reverse_iterator _Rv; + typedef __invert<_Compare> _Inverted; + std::__half_inplace_merge<_AlgPolicy>( + _Rv(__p), _Rv(__buff), _RBi(__middle), _RBi(__first), _RBi(__last), _Inverted(__comp)); + } } template @@ -131,107 +132,92 @@ void __inplace_merge( typename iterator_traits<_BidirectionalIterator>::difference_type __len2, typename iterator_traits<_BidirectionalIterator>::value_type* __buff, ptrdiff_t __buff_size) { - using _Ops = _IterOps<_AlgPolicy>; + using _Ops = _IterOps<_AlgPolicy>; - typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; - while (true) - { - // if __middle == __last, we're done - if (__len2 == 0) - return; - if (__len1 <= __buff_size || __len2 <= __buff_size) - return std::__buffered_inplace_merge<_AlgPolicy> - (__first, __middle, __last, __comp, __len1, __len2, __buff); - // shrink [__first, __middle) as much as possible (with no moves), returning if it shrinks to 0 - for (; true; ++__first, (void) --__len1) - { - if (__len1 == 0) - return; - if (__comp(*__middle, *__first)) - break; - } - // __first < __middle < __last - // *__first > *__middle - // partition [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last) such that - // all elements in: - // [__first, __m1) <= [__middle, __m2) - // [__middle, __m2) < [__m1, __middle) - // [__m1, __middle) <= [__m2, __last) - // and __m1 or __m2 is in the middle of its range - _BidirectionalIterator __m1; // "median" of [__first, __middle) - _BidirectionalIterator __m2; // "median" of [__middle, __last) - difference_type __len11; // distance(__first, __m1) - difference_type __len21; // distance(__middle, __m2) - // binary search smaller range - if (__len1 < __len2) - { // __len >= 1, __len2 >= 2 - __len21 = __len2 / 2; - __m2 = __middle; - _Ops::advance(__m2, __len21); - __m1 = std::__upper_bound<_AlgPolicy>(__first, __middle, *__m2, __comp, std::__identity()); - __len11 = _Ops::distance(__first, __m1); - } - else - { - if (__len1 == 1) - { // __len1 >= __len2 && __len2 > 0, therefore __len2 == 1 - // It is known *__first > *__middle - _Ops::iter_swap(__first, __middle); - return; - } - // __len1 >= 2, __len2 >= 1 - __len11 = __len1 / 2; - __m1 = __first; - _Ops::advance(__m1, __len11); - __m2 = std::lower_bound(__middle, __last, *__m1, __comp); - __len21 = _Ops::distance(__middle, __m2); - } - difference_type __len12 = __len1 - __len11; // distance(__m1, __middle) - difference_type __len22 = __len2 - __len21; // distance(__m2, __last) - // [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last) - // swap middle two partitions - __middle = std::__rotate<_AlgPolicy>(__m1, __middle, __m2).first; - // __len12 and __len21 now have swapped meanings - // merge smaller range with recursive call and larger with tail recursion elimination - if (__len11 + __len21 < __len12 + __len22) - { - std::__inplace_merge<_AlgPolicy>( - __first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size); - __first = __middle; - __middle = __m2; - __len1 = __len12; - __len2 = __len22; - } - else - { - std::__inplace_merge<_AlgPolicy>( - __middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size); - __last = __middle; - __middle = __m1; - __len1 = __len11; - __len2 = __len21; - } + typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; + while (true) { + // if __middle == __last, we're done + if (__len2 == 0) + return; + if (__len1 <= __buff_size || __len2 <= __buff_size) + return std::__buffered_inplace_merge<_AlgPolicy>(__first, __middle, __last, __comp, __len1, __len2, __buff); + // shrink [__first, __middle) as much as possible (with no moves), returning if it shrinks to 0 + for (; true; ++__first, (void)--__len1) { + if (__len1 == 0) + return; + if (__comp(*__middle, *__first)) + break; } + // __first < __middle < __last + // *__first > *__middle + // partition [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last) such that + // all elements in: + // [__first, __m1) <= [__middle, __m2) + // [__middle, __m2) < [__m1, __middle) + // [__m1, __middle) <= [__m2, __last) + // and __m1 or __m2 is in the middle of its range + _BidirectionalIterator __m1; // "median" of [__first, __middle) + _BidirectionalIterator __m2; // "median" of [__middle, __last) + difference_type __len11; // distance(__first, __m1) + difference_type __len21; // distance(__middle, __m2) + // binary search smaller range + if (__len1 < __len2) { // __len >= 1, __len2 >= 2 + __len21 = __len2 / 2; + __m2 = __middle; + _Ops::advance(__m2, __len21); + __m1 = std::__upper_bound<_AlgPolicy>(__first, __middle, *__m2, __comp, std::__identity()); + __len11 = _Ops::distance(__first, __m1); + } else { + if (__len1 == 1) { // __len1 >= __len2 && __len2 > 0, therefore __len2 == 1 + // It is known *__first > *__middle + _Ops::iter_swap(__first, __middle); + return; + } + // __len1 >= 2, __len2 >= 1 + __len11 = __len1 / 2; + __m1 = __first; + _Ops::advance(__m1, __len11); + __m2 = std::lower_bound(__middle, __last, *__m1, __comp); + __len21 = _Ops::distance(__middle, __m2); + } + difference_type __len12 = __len1 - __len11; // distance(__m1, __middle) + difference_type __len22 = __len2 - __len21; // distance(__m2, __last) + // [__first, __m1) [__m1, __middle) [__middle, __m2) [__m2, __last) + // swap middle two partitions + __middle = std::__rotate<_AlgPolicy>(__m1, __middle, __m2).first; + // __len12 and __len21 now have swapped meanings + // merge smaller range with recursive call and larger with tail recursion elimination + if (__len11 + __len21 < __len12 + __len22) { + std::__inplace_merge<_AlgPolicy>(__first, __m1, __middle, __comp, __len11, __len21, __buff, __buff_size); + __first = __middle; + __middle = __m2; + __len1 = __len12; + __len2 = __len22; + } else { + std::__inplace_merge<_AlgPolicy>(__middle, __m2, __last, __comp, __len12, __len22, __buff, __buff_size); + __last = __middle; + __middle = __m1; + __len1 = __len11; + __len2 = __len21; + } + } } template -_LIBCPP_HIDE_FROM_ABI -void -__inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, - _Compare&& __comp) -{ - typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; - typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; - difference_type __len1 = _IterOps<_AlgPolicy>::distance(__first, __middle); - difference_type __len2 = _IterOps<_AlgPolicy>::distance(__middle, __last); - difference_type __buf_size = _VSTD::min(__len1, __len2); -// TODO: Remove the use of std::get_temporary_buffer -_LIBCPP_SUPPRESS_DEPRECATED_PUSH - pair __buf = _VSTD::get_temporary_buffer(__buf_size); -_LIBCPP_SUPPRESS_DEPRECATED_POP - unique_ptr __h(__buf.first); - return std::__inplace_merge<_AlgPolicy>( - std::move(__first), std::move(__middle), std::move(__last), __comp, __len1, __len2, __buf.first, __buf.second); +_LIBCPP_HIDE_FROM_ABI void __inplace_merge( + _BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, _Compare&& __comp) { + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; + difference_type __len1 = _IterOps<_AlgPolicy>::distance(__first, __middle); + difference_type __len2 = _IterOps<_AlgPolicy>::distance(__middle, __last); + difference_type __buf_size = std::min(__len1, __len2); + // TODO: Remove the use of std::get_temporary_buffer + _LIBCPP_SUPPRESS_DEPRECATED_PUSH + pair __buf = std::get_temporary_buffer(__buf_size); + _LIBCPP_SUPPRESS_DEPRECATED_POP + unique_ptr __h(__buf.first); + return std::__inplace_merge<_AlgPolicy>( + std::move(__first), std::move(__middle), std::move(__last), __comp, __len1, __len2, __buf.first, __buf.second); } template @@ -242,12 +228,9 @@ inline _LIBCPP_HIDE_FROM_ABI void inplace_merge( } template -inline _LIBCPP_HIDE_FROM_ABI -void -inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last) -{ - std::inplace_merge(std::move(__first), std::move(__middle), std::move(__last), - __less::value_type>()); +inline _LIBCPP_HIDE_FROM_ABI void +inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last) { + std::inplace_merge(std::move(__first), std::move(__middle), std::move(__last), __less<>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/is_heap.h b/third_party/libcxx/__algorithm/is_heap.h index 2dcb4a28e..c589b804a 100644 --- a/third_party/libcxx/__algorithm/is_heap.h +++ b/third_party/libcxx/__algorithm/is_heap.h @@ -22,21 +22,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -bool -is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) -{ - return std::__is_heap_until(__first, __last, static_cast<__comp_ref_type<_Compare> >(__comp)) == __last; +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + return std::__is_heap_until(__first, __last, static_cast<__comp_ref_type<_Compare> >(__comp)) == __last; } -template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -bool -is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) -{ - return _VSTD::is_heap(__first, __last, __less::value_type>()); +template +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { + return std::is_heap(__first, __last, __less<>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/is_heap_until.h b/third_party/libcxx/__algorithm/is_heap_until.h index 6ed4cb29c..a174f2453 100644 --- a/third_party/libcxx/__algorithm/is_heap_until.h +++ b/third_party/libcxx/__algorithm/is_heap_until.h @@ -22,43 +22,39 @@ _LIBCPP_BEGIN_NAMESPACE_STD template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator -__is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) -{ - typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; - difference_type __len = __last - __first; - difference_type __p = 0; - difference_type __c = 1; - _RandomAccessIterator __pp = __first; - while (__c < __len) - { - _RandomAccessIterator __cp = __first + __c; - if (__comp(*__pp, *__cp)) - return __cp; - ++__c; - ++__cp; - if (__c == __len) - return __last; - if (__comp(*__pp, *__cp)) - return __cp; - ++__p; - ++__pp; - __c = 2 * __p + 1; - } - return __last; +__is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) { + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + difference_type __len = __last - __first; + difference_type __p = 0; + difference_type __c = 1; + _RandomAccessIterator __pp = __first; + while (__c < __len) { + _RandomAccessIterator __cp = __first + __c; + if (__comp(*__pp, *__cp)) + return __cp; + ++__c; + ++__cp; + if (__c == __len) + return __last; + if (__comp(*__pp, *__cp)) + return __cp; + ++__p; + ++__pp; + __c = 2 * __p + 1; + } + return __last; } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator -is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) -{ - return std::__is_heap_until(__first, __last, static_cast<__comp_ref_type<_Compare> >(__comp)); +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator +is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + return std::__is_heap_until(__first, __last, static_cast<__comp_ref_type<_Compare> >(__comp)); } -template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator -is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last) -{ - return _VSTD::__is_heap_until(__first, __last, __less::value_type>()); +template +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator +is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last) { + return std::__is_heap_until(__first, __last, __less<>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/is_partitioned.h b/third_party/libcxx/__algorithm/is_partitioned.h index ab59d3cce..1f7c8b0b2 100644 --- a/third_party/libcxx/__algorithm/is_partitioned.h +++ b/third_party/libcxx/__algorithm/is_partitioned.h @@ -18,19 +18,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool -is_partitioned(_InputIterator __first, _InputIterator __last, _Predicate __pred) -{ - for (; __first != __last; ++__first) - if (!__pred(*__first)) - break; - if ( __first == __last ) - return true; - ++__first; - for (; __first != __last; ++__first) - if (__pred(*__first)) - return false; +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +is_partitioned(_InputIterator __first, _InputIterator __last, _Predicate __pred) { + for (; __first != __last; ++__first) + if (!__pred(*__first)) + break; + if (__first == __last) return true; + ++__first; + for (; __first != __last; ++__first) + if (__pred(*__first)) + return false; + return true; } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/is_permutation.h b/third_party/libcxx/__algorithm/is_permutation.h index 2a7c606b8..2ddfb32a2 100644 --- a/third_party/libcxx/__algorithm/is_permutation.h +++ b/third_party/libcxx/__algorithm/is_permutation.h @@ -26,6 +26,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template @@ -34,18 +37,24 @@ struct _ConstTimeDistance : false_type {}; #if _LIBCPP_STD_VER >= 20 template -struct _ConstTimeDistance<_Iter1, _Sent1, _Iter2, _Sent2, __enable_if_t< - sized_sentinel_for<_Sent1, _Iter1> && - sized_sentinel_for<_Sent2, _Iter2> ->> : true_type {}; +struct _ConstTimeDistance<_Iter1, + _Sent1, + _Iter2, + _Sent2, + __enable_if_t< sized_sentinel_for<_Sent1, _Iter1> && sized_sentinel_for<_Sent2, _Iter2> >> + : true_type {}; #else template -struct _ConstTimeDistance<_Iter1, _Iter1, _Iter2, _Iter2, __enable_if_t< - is_same::iterator_category, random_access_iterator_tag>::value && - is_same::iterator_category, random_access_iterator_tag>::value -> > : true_type {}; +struct _ConstTimeDistance< + _Iter1, + _Iter1, + _Iter2, + _Iter2, + __enable_if_t< is_same::iterator_category, random_access_iterator_tag>::value && + is_same::iterator_category, random_access_iterator_tag>::value > > + : true_type {}; #endif // _LIBCPP_STD_VER >= 20 @@ -53,11 +62,21 @@ struct _ConstTimeDistance<_Iter1, _Iter1, _Iter2, _Iter2, __enable_if_t< // For each element in [f1, l1) see if there are the same number of equal elements in [f2, l2) template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool -__is_permutation_impl(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, - _Pred&& __pred, _Proj1&& __proj1, _Proj2&& __proj2) { + class _Iter1, + class _Sent1, + class _Iter2, + class _Sent2, + class _Proj1, + class _Proj2, + class _Pred> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation_impl( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Pred&& __pred, + _Proj1&& __proj1, + _Proj2&& __proj2) { using _D1 = __iter_diff_t<_Iter1>; for (auto __i = __first1; __i != __last1; ++__i) { @@ -94,9 +113,8 @@ __is_permutation_impl(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 _ // 2+1 iterators, predicate. Not used by range algorithms. template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool -__is_permutation(_ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2 __first2, - _BinaryPredicate&& __pred) { +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation( + _ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2 __first2, _BinaryPredicate&& __pred) { // Shorten sequences as much as possible by lopping of any equal prefix. for (; __first1 != __last1; ++__first1, (void)++__first2) { if (!__pred(*__first1, *__first2)) @@ -108,24 +126,39 @@ __is_permutation(_ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterato // __first1 != __last1 && *__first1 != *__first2 using _D1 = __iter_diff_t<_ForwardIterator1>; - _D1 __l1 = _IterOps<_AlgPolicy>::distance(__first1, __last1); + _D1 __l1 = _IterOps<_AlgPolicy>::distance(__first1, __last1); if (__l1 == _D1(1)) return false; auto __last2 = _IterOps<_AlgPolicy>::next(__first2, __l1); return std::__is_permutation_impl<_AlgPolicy>( - std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), - __pred, __identity(), __identity()); + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + __pred, + __identity(), + __identity()); } // 2+2 iterators, predicate, non-constant time `distance`. template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool -__is_permutation(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, - _Pred&& __pred, _Proj1&& __proj1, _Proj2&& __proj2, - /*_ConstTimeDistance=*/false_type) { + class _Iter1, + class _Sent1, + class _Iter2, + class _Sent2, + class _Proj1, + class _Proj2, + class _Pred> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Pred&& __pred, + _Proj1&& __proj1, + _Proj2&& __proj2, + /*_ConstTimeDistance=*/false_type) { // Shorten sequences as much as possible by lopping of any equal prefix. while (__first1 != __last1 && __first2 != __last2) { if (!std::__invoke(__pred, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2))) @@ -140,44 +173,73 @@ __is_permutation(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last return false; using _D1 = __iter_diff_t<_Iter1>; - _D1 __l1 = _IterOps<_AlgPolicy>::distance(__first1, __last1); + _D1 __l1 = _IterOps<_AlgPolicy>::distance(__first1, __last1); using _D2 = __iter_diff_t<_Iter2>; - _D2 __l2 = _IterOps<_AlgPolicy>::distance(__first2, __last2); + _D2 __l2 = _IterOps<_AlgPolicy>::distance(__first2, __last2); if (__l1 != __l2) return false; return std::__is_permutation_impl<_AlgPolicy>( - std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), - __pred, __proj1, __proj2); + std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __pred, __proj1, __proj2); } // 2+2 iterators, predicate, specialization for constant-time `distance` call. template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool -__is_permutation(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, - _Pred&& __pred, _Proj1&& __proj1, _Proj2&& __proj2, - /*_ConstTimeDistance=*/true_type) { + class _Iter1, + class _Sent1, + class _Iter2, + class _Sent2, + class _Proj1, + class _Proj2, + class _Pred> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Pred&& __pred, + _Proj1&& __proj1, + _Proj2&& __proj2, + /*_ConstTimeDistance=*/true_type) { if (std::distance(__first1, __last1) != std::distance(__first2, __last2)) return false; return std::__is_permutation<_AlgPolicy>( - std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), - __pred, __proj1, __proj2, + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + __pred, + __proj1, + __proj2, /*_ConstTimeDistance=*/false_type()); } // 2+2 iterators, predicate template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool -__is_permutation(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, - _Pred&& __pred, _Proj1&& __proj1, _Proj2&& __proj2) { + class _Iter1, + class _Sent1, + class _Iter2, + class _Sent2, + class _Proj1, + class _Proj2, + class _Pred> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __is_permutation( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Pred&& __pred, + _Proj1&& __proj1, + _Proj2&& __proj2) { return std::__is_permutation<_AlgPolicy>( - std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), - __pred, __proj1, __proj2, + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + __pred, + __proj1, + __proj2, _ConstTimeDistance<_Iter1, _Sent1, _Iter2, _Sent2>()); } @@ -185,19 +247,17 @@ __is_permutation(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last // 2+1 iterators, predicate template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool -is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _BinaryPredicate __pred) { +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation( + _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _BinaryPredicate __pred) { static_assert(__is_callable<_BinaryPredicate, decltype(*__first1), decltype(*__first2)>::value, - "The predicate has to be callable"); + "The predicate has to be callable"); - return std::__is_permutation<_ClassicAlgPolicy>( - std::move(__first1), std::move(__last1), std::move(__first2), __pred); + return std::__is_permutation<_ClassicAlgPolicy>(std::move(__first1), std::move(__last1), std::move(__first2), __pred); } // 2+1 iterators template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) { return std::is_permutation(__first1, __last1, __first2, __equal_to()); } @@ -206,7 +266,7 @@ is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIt // 2+2 iterators template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation( +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation( _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { return std::__is_permutation<_ClassicAlgPolicy>( std::move(__first1), @@ -220,19 +280,29 @@ _LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 // 2+2 iterators, predicate template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool -is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _BinaryPredicate __pred) { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool is_permutation( + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _BinaryPredicate __pred) { static_assert(__is_callable<_BinaryPredicate, decltype(*__first1), decltype(*__first2)>::value, - "The predicate has to be callable"); + "The predicate has to be callable"); return std::__is_permutation<_ClassicAlgPolicy>( - std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), - __pred, __identity(), __identity()); + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + __pred, + __identity(), + __identity()); } #endif // _LIBCPP_STD_VER >= 14 _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_IS_PERMUTATION_H diff --git a/third_party/libcxx/__algorithm/is_sorted.h b/third_party/libcxx/__algorithm/is_sorted.h index bf44f4576..3befb1ac9 100644 --- a/third_party/libcxx/__algorithm/is_sorted.h +++ b/third_party/libcxx/__algorithm/is_sorted.h @@ -22,21 +22,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -bool -is_sorted(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) -{ - return _VSTD::__is_sorted_until<__comp_ref_type<_Compare> >(__first, __last, __comp) == __last; +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +is_sorted(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { + return std::__is_sorted_until<__comp_ref_type<_Compare> >(__first, __last, __comp) == __last; } -template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -bool -is_sorted(_ForwardIterator __first, _ForwardIterator __last) -{ - return _VSTD::is_sorted(__first, __last, __less::value_type>()); +template +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +is_sorted(_ForwardIterator __first, _ForwardIterator __last) { + return std::is_sorted(__first, __last, __less<>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/is_sorted_until.h b/third_party/libcxx/__algorithm/is_sorted_until.h index b6683000a..53a49f00d 100644 --- a/third_party/libcxx/__algorithm/is_sorted_until.h +++ b/third_party/libcxx/__algorithm/is_sorted_until.h @@ -22,33 +22,28 @@ _LIBCPP_BEGIN_NAMESPACE_STD template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator -__is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) -{ - if (__first != __last) - { - _ForwardIterator __i = __first; - while (++__i != __last) - { - if (__comp(*__i, *__first)) - return __i; - __first = __i; - } +__is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { + if (__first != __last) { + _ForwardIterator __i = __first; + while (++__i != __last) { + if (__comp(*__i, *__first)) + return __i; + __first = __i; } - return __last; + } + return __last; } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator -is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) -{ - return _VSTD::__is_sorted_until<__comp_ref_type<_Compare> >(__first, __last, __comp); +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +is_sorted_until(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { + return std::__is_sorted_until<__comp_ref_type<_Compare> >(__first, __last, __comp); } -template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator -is_sorted_until(_ForwardIterator __first, _ForwardIterator __last) -{ - return _VSTD::is_sorted_until(__first, __last, __less::value_type>()); +template +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +is_sorted_until(_ForwardIterator __first, _ForwardIterator __last) { + return std::is_sorted_until(__first, __last, __less<>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/iter_swap.h b/third_party/libcxx/__algorithm/iter_swap.h index 44422b5de..a1412e5d8 100644 --- a/third_party/libcxx/__algorithm/iter_swap.h +++ b/third_party/libcxx/__algorithm/iter_swap.h @@ -20,8 +20,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void iter_swap(_ForwardIterator1 __a, - _ForwardIterator2 __b) +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b) // _NOEXCEPT_(_NOEXCEPT_(swap(*__a, *__b))) _NOEXCEPT_(_NOEXCEPT_(swap(*std::declval<_ForwardIterator1>(), *std::declval<_ForwardIterator2>()))) { swap(*__a, *__b); diff --git a/third_party/libcxx/__algorithm/iterator_operations.h b/third_party/libcxx/__algorithm/iterator_operations.h index 2bdc0ac2f..8ced98923 100644 --- a/third_party/libcxx/__algorithm/iterator_operations.h +++ b/third_party/libcxx/__algorithm/iterator_operations.h @@ -11,6 +11,7 @@ #include <__algorithm/iter_swap.h> #include <__algorithm/ranges_iterator_concept.h> +#include <__assert> #include <__config> #include <__iterator/advance.h> #include <__iterator/distance.h> @@ -33,16 +34,19 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD -template struct _IterOps; +template +struct _IterOps; #if _LIBCPP_STD_VER >= 20 struct _RangeAlgPolicy {}; template <> struct _IterOps<_RangeAlgPolicy> { - template using __value_type = iter_value_t<_Iter>; @@ -52,12 +56,12 @@ struct _IterOps<_RangeAlgPolicy> { template using __difference_type = iter_difference_t<_Iter>; - static constexpr auto advance = ranges::advance; - static constexpr auto distance = ranges::distance; - static constexpr auto __iter_move = ranges::iter_move; - static constexpr auto iter_swap = ranges::iter_swap; - static constexpr auto next = ranges::next; - static constexpr auto prev = ranges::prev; + static constexpr auto advance = ranges::advance; + static constexpr auto distance = ranges::distance; + static constexpr auto __iter_move = ranges::iter_move; + static constexpr auto iter_swap = ranges::iter_swap; + static constexpr auto next = ranges::next; + static constexpr auto prev = ranges::prev; static constexpr auto __advance_to = ranges::advance; }; @@ -67,7 +71,6 @@ struct _ClassicAlgPolicy {}; template <> struct _IterOps<_ClassicAlgPolicy> { - template using __value_type = typename iterator_traits<_Iter>::value_type; @@ -79,15 +82,14 @@ struct _IterOps<_ClassicAlgPolicy> { // advance template - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 - static void advance(_Iter& __iter, _Distance __count) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static void advance(_Iter& __iter, _Distance __count) { std::advance(__iter, __count); } // distance template - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 - static typename iterator_traits<_Iter>::difference_type distance(_Iter __first, _Iter __last) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static typename iterator_traits<_Iter>::difference_type + distance(_Iter __first, _Iter __last) { return std::distance(__first, __last); } @@ -98,37 +100,33 @@ struct _IterOps<_ClassicAlgPolicy> { using __move_t = decltype(std::move(*std::declval<_Iter&>())); template - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 - static void __validate_iter_reference() { - static_assert(is_same<__deref_t<_Iter>, typename iterator_traits<__remove_cvref_t<_Iter> >::reference>::value, + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static void __validate_iter_reference() { + static_assert( + is_same<__deref_t<_Iter>, typename iterator_traits<__remove_cvref_t<_Iter> >::reference>::value, "It looks like your iterator's `iterator_traits::reference` does not match the return type of " "dereferencing the iterator, i.e., calling `*it`. This is undefined behavior according to [input.iterators] " "and can lead to dangling reference issues at runtime, so we are flagging this."); } // iter_move - template + template >::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static - // If the result of dereferencing `_Iter` is a reference type, deduce the result of calling `std::move` on it. Note - // that the C++03 mode doesn't support `decltype(auto)` as the return type. - __enable_if_t< - is_reference<__deref_t<_Iter> >::value, - __move_t<_Iter> > - __iter_move(_Iter&& __i) { + // If the result of dereferencing `_Iter` is a reference type, deduce the result of calling `std::move` on it. + // Note that the C++03 mode doesn't support `decltype(auto)` as the return type. + __move_t<_Iter> + __iter_move(_Iter&& __i) { __validate_iter_reference<_Iter>(); return std::move(*std::forward<_Iter>(__i)); } - template + template >::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static - // If the result of dereferencing `_Iter` is a value type, deduce the return value of this function to also be a - // value -- otherwise, after `operator*` returns a temporary, this function would return a dangling reference to that - // temporary. Note that the C++03 mode doesn't support `auto` as the return type. - __enable_if_t< - !is_reference<__deref_t<_Iter> >::value, - __deref_t<_Iter> > - __iter_move(_Iter&& __i) { + // If the result of dereferencing `_Iter` is a value type, deduce the return value of this function to also be a + // value -- otherwise, after `operator*` returns a temporary, this function would return a dangling reference to + // that temporary. Note that the C++03 mode doesn't support `auto` as the return type. + __deref_t<_Iter> + __iter_move(_Iter&& __i) { __validate_iter_reference<_Iter>(); return *std::forward<_Iter>(__i); @@ -136,40 +134,90 @@ struct _IterOps<_ClassicAlgPolicy> { // iter_swap template - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 - static void iter_swap(_Iter1&& __a, _Iter2&& __b) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static void iter_swap(_Iter1&& __a, _Iter2&& __b) { std::iter_swap(std::forward<_Iter1>(__a), std::forward<_Iter2>(__b)); } // next template - _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 - _Iterator next(_Iterator, _Iterator __last) { + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iterator next(_Iterator, _Iterator __last) { return __last; } template - _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 - __remove_cvref_t<_Iter> next(_Iter&& __it, - typename iterator_traits<__remove_cvref_t<_Iter> >::difference_type __n = 1) { + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 __remove_cvref_t<_Iter> + next(_Iter&& __it, typename iterator_traits<__remove_cvref_t<_Iter> >::difference_type __n = 1) { return std::next(std::forward<_Iter>(__it), __n); } // prev template - _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 - __remove_cvref_t<_Iter> prev(_Iter&& __iter, - typename iterator_traits<__remove_cvref_t<_Iter> >::difference_type __n = 1) { + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 __remove_cvref_t<_Iter> + prev(_Iter&& __iter, typename iterator_traits<__remove_cvref_t<_Iter> >::difference_type __n = 1) { return std::prev(std::forward<_Iter>(__iter), __n); } template - _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 - void __advance_to(_Iter& __first, _Iter __last) { + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 void __advance_to(_Iter& __first, _Iter __last) { __first = __last; } + + // advance with sentinel, a la std::ranges::advance + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static __difference_type<_Iter> + __advance_to(_Iter& __iter, __difference_type<_Iter> __count, const _Iter& __sentinel) { + return _IterOps::__advance_to(__iter, __count, __sentinel, typename iterator_traits<_Iter>::iterator_category()); + } + +private: + // advance with sentinel, a la std::ranges::advance -- InputIterator specialization + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static __difference_type<_InputIter> __advance_to( + _InputIter& __iter, __difference_type<_InputIter> __count, const _InputIter& __sentinel, input_iterator_tag) { + __difference_type<_InputIter> __dist = 0; + for (; __dist < __count && __iter != __sentinel; ++__dist) + ++__iter; + return __count - __dist; + } + + // advance with sentinel, a la std::ranges::advance -- BidirectionalIterator specialization + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static __difference_type<_BiDirIter> + __advance_to(_BiDirIter& __iter, + __difference_type<_BiDirIter> __count, + const _BiDirIter& __sentinel, + bidirectional_iterator_tag) { + __difference_type<_BiDirIter> __dist = 0; + if (__count >= 0) + for (; __dist < __count && __iter != __sentinel; ++__dist) + ++__iter; + else + for (__count = -__count; __dist < __count && __iter != __sentinel; ++__dist) + --__iter; + return __count - __dist; + } + + // advance with sentinel, a la std::ranges::advance -- RandomIterator specialization + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 static __difference_type<_RandIter> + __advance_to(_RandIter& __iter, + __difference_type<_RandIter> __count, + const _RandIter& __sentinel, + random_access_iterator_tag) { + auto __dist = _IterOps::distance(__iter, __sentinel); + _LIBCPP_ASSERT_VALID_INPUT_RANGE( + __count == 0 || (__dist < 0) == (__count < 0), "__sentinel must precede __iter when __count < 0"); + if (__count < 0) + __dist = __dist > __count ? __dist : __count; + else + __dist = __dist < __count ? __dist : __count; + __iter += __dist; + return __count - __dist; + } }; _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_ITERATOR_OPERATIONS_H diff --git a/third_party/libcxx/__algorithm/lexicographical_compare.h b/third_party/libcxx/__algorithm/lexicographical_compare.h index 0a13c5dd3..edc29e269 100644 --- a/third_party/libcxx/__algorithm/lexicographical_compare.h +++ b/third_party/libcxx/__algorithm/lexicographical_compare.h @@ -21,40 +21,35 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool -__lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) -{ - for (; __first2 != __last2; ++__first1, (void) ++__first2) - { - if (__first1 == __last1 || __comp(*__first1, *__first2)) - return true; - if (__comp(*__first2, *__first1)) - return false; - } - return false; +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __lexicographical_compare( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _Compare __comp) { + for (; __first2 != __last2; ++__first1, (void)++__first2) { + if (__first1 == __last1 || __comp(*__first1, *__first2)) + return true; + if (__comp(*__first2, *__first1)) + return false; + } + return false; } template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -bool -lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) -{ - return _VSTD::__lexicographical_compare<__comp_ref_type<_Compare> >(__first1, __last1, __first2, __last2, __comp); +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool lexicographical_compare( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _Compare __comp) { + return std::__lexicographical_compare<__comp_ref_type<_Compare> >(__first1, __last1, __first2, __last2, __comp); } template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -bool -lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2) -{ - return _VSTD::lexicographical_compare(__first1, __last1, __first2, __last2, - __less::value_type, - typename iterator_traits<_InputIterator2>::value_type>()); +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool lexicographical_compare( + _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { + return std::lexicographical_compare(__first1, __last1, __first2, __last2, __less<>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/lexicographical_compare_three_way.h b/third_party/libcxx/__algorithm/lexicographical_compare_three_way.h index 32de97d07..a5872e90c 100644 --- a/third_party/libcxx/__algorithm/lexicographical_compare_three_way.h +++ b/third_party/libcxx/__algorithm/lexicographical_compare_three_way.h @@ -17,7 +17,7 @@ #include <__config> #include <__iterator/iterator_traits.h> #include <__type_traits/common_type.h> -#include <__type_traits/is_copy_constructible.h> +#include <__type_traits/is_constructible.h> #include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -90,7 +90,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr auto __lexicographical_compare_three_way_slow_pa } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto lexicographical_compare_three_way( +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto lexicographical_compare_three_way( _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Cmp __comp) -> decltype(__comp(*__first1, *__first2)) { static_assert(__comparison_category, @@ -110,7 +110,7 @@ _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto lexicographical_compa } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto lexicographical_compare_three_way( +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto lexicographical_compare_three_way( _InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { return std::lexicographical_compare_three_way( std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), std::compare_three_way()); diff --git a/third_party/libcxx/__algorithm/lower_bound.h b/third_party/libcxx/__algorithm/lower_bound.h index 810939375..c417d8483 100644 --- a/third_party/libcxx/__algorithm/lower_bound.h +++ b/third_party/libcxx/__algorithm/lower_bound.h @@ -27,11 +27,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_Iter __lower_bound_impl(_Iter __first, _Sent __last, const _Type& __value, _Comp& __comp, _Proj& __proj) { - auto __len = _IterOps<_AlgPolicy>::distance(__first, __last); - +template +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter __lower_bound_bisecting( + _Iter __first, + const _Type& __value, + typename iterator_traits<_Iter>::difference_type __len, + _Comp& __comp, + _Proj& __proj) { while (__len != 0) { auto __l2 = std::__half_positive(__len); _Iter __m = __first; @@ -46,20 +48,60 @@ _Iter __lower_bound_impl(_Iter __first, _Sent __last, const _Type& __value, _Com return __first; } +// One-sided binary search, aka meta binary search, has been in the public domain for decades, and has the general +// advantage of being \Omega(1) rather than the classic algorithm's \Omega(log(n)), with the downside of executing at +// most 2*log(n) comparisons vs the classic algorithm's exact log(n). There are two scenarios in which it really shines: +// the first one is when operating over non-random-access iterators, because the classic algorithm requires knowing the +// container's size upfront, which adds \Omega(n) iterator increments to the complexity. The second one is when you're +// traversing the container in order, trying to fast-forward to the next value: in that case, the classic algorithm +// would yield \Omega(n*log(n)) comparisons and, for non-random-access iterators, \Omega(n^2) iterator increments, +// whereas the one-sided version will yield O(n) operations on both counts, with a \Omega(log(n)) bound on the number of +// comparisons. +template +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +__lower_bound_onesided(_ForwardIterator __first, _Sent __last, const _Type& __value, _Comp& __comp, _Proj& __proj) { + // step = 0, ensuring we can always short-circuit when distance is 1 later on + if (__first == __last || !std::__invoke(__comp, std::__invoke(__proj, *__first), __value)) + return __first; + + using _Distance = typename iterator_traits<_ForwardIterator>::difference_type; + for (_Distance __step = 1; __first != __last; __step <<= 1) { + auto __it = __first; + auto __dist = __step - _IterOps<_AlgPolicy>::__advance_to(__it, __step, __last); + // once we reach the last range where needle can be we must start + // looking inwards, bisecting that range + if (__it == __last || !std::__invoke(__comp, std::__invoke(__proj, *__it), __value)) { + // we've already checked the previous value and it was less, we can save + // one comparison by skipping bisection + if (__dist == 1) + return __it; + return std::__lower_bound_bisecting<_AlgPolicy>(__first, __value, __dist, __comp, __proj); + } + // range not found, move forward! + __first = __it; + } + return __first; +} + +template +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +__lower_bound(_ForwardIterator __first, _Sent __last, const _Type& __value, _Comp& __comp, _Proj& __proj) { + const auto __dist = _IterOps<_AlgPolicy>::distance(__first, __last); + return std::__lower_bound_bisecting<_AlgPolicy>(__first, __value, __dist, __comp, __proj); +} + template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { - static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value, - "The comparator has to be callable"); +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { + static_assert(__is_callable<_Compare, decltype(*__first), const _Tp&>::value, "The comparator has to be callable"); auto __proj = std::__identity(); - return std::__lower_bound_impl<_ClassicAlgPolicy>(__first, __last, __value, __comp, __proj); + return std::__lower_bound<_ClassicAlgPolicy>(__first, __last, __value, __comp, __proj); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { - return std::lower_bound(__first, __last, __value, - __less::value_type, _Tp>()); +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { + return std::lower_bound(__first, __last, __value, __less<>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/make_heap.h b/third_party/libcxx/__algorithm/make_heap.h index d66cfe2e5..e8f0cdb27 100644 --- a/third_party/libcxx/__algorithm/make_heap.h +++ b/third_party/libcxx/__algorithm/make_heap.h @@ -21,36 +21,40 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -void __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void +__make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) { __comp_ref_type<_Compare> __comp_ref = __comp; using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type; - difference_type __n = __last - __first; + difference_type __n = __last - __first; if (__n > 1) { // start from the first parent, there is no need to consider children for (difference_type __start = (__n - 2) / 2; __start >= 0; --__start) { - std::__sift_down<_AlgPolicy>(__first, __comp_ref, __n, __first + __start); + std::__sift_down<_AlgPolicy>(__first, __comp_ref, __n, __first + __start); } } } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { std::__make_heap<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { - std::make_heap(std::move(__first), std::move(__last), - __less::value_type>()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { + std::make_heap(std::move(__first), std::move(__last), __less<>()); } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_MAKE_HEAP_H diff --git a/third_party/libcxx/__algorithm/make_projected.h b/third_party/libcxx/__algorithm/make_projected.h index ec854763a..5245e523f 100644 --- a/third_party/libcxx/__algorithm/make_projected.h +++ b/third_party/libcxx/__algorithm/make_projected.h @@ -36,44 +36,38 @@ struct _ProjectedPred { : __pred(__pred_arg), __proj(__proj_arg) {} template - typename __invoke_of<_Pred&, - decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_Tp>())) - >::type - _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI operator()(_Tp&& __v) const { + typename __invoke_of<_Pred&, decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_Tp>()))>::type + _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI + operator()(_Tp&& __v) const { return std::__invoke(__pred, std::__invoke(__proj, std::forward<_Tp>(__v))); } template typename __invoke_of<_Pred&, decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T1>())), - decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T2>())) - >::type - _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI operator()(_T1&& __lhs, _T2&& __rhs) const { - return std::__invoke(__pred, - std::__invoke(__proj, std::forward<_T1>(__lhs)), - std::__invoke(__proj, std::forward<_T2>(__rhs))); + decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T2>()))>::type _LIBCPP_CONSTEXPR + _LIBCPP_HIDE_FROM_ABI + operator()(_T1&& __lhs, _T2&& __rhs) const { + return std::__invoke( + __pred, std::__invoke(__proj, std::forward<_T1>(__lhs)), std::__invoke(__proj, std::forward<_T2>(__rhs))); } - }; -template >::value && - __is_identity<__decay_t<_Proj> >::value), - int> = 0> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ProjectedPred<_Pred, _Proj> -__make_projected(_Pred& __pred, _Proj& __proj) { +template < + class _Pred, + class _Proj, + __enable_if_t >::value && __is_identity<__decay_t<_Proj> >::value), int> = 0> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ProjectedPred<_Pred, _Proj> __make_projected(_Pred& __pred, _Proj& __proj) { return _ProjectedPred<_Pred, _Proj>(__pred, __proj); } // Avoid creating the functor and just use the pristine comparator -- for certain algorithms, this would enable // optimizations that rely on the type of the comparator. Additionally, this results in less layers of indirection in // the call stack when the comparator is invoked, even in an unoptimized build. -template >::value && - __is_identity<__decay_t<_Proj> >::value, - int> = 0> +template < + class _Pred, + class _Proj, + __enable_if_t >::value && __is_identity<__decay_t<_Proj> >::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Pred& __make_projected(_Pred& __pred, _Proj&) { return __pred; } @@ -87,8 +81,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { template -_LIBCPP_HIDE_FROM_ABI constexpr -decltype(auto) __make_projected_comp(_Comp& __comp, _Proj1& __proj1, _Proj2& __proj2) { +_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) __make_projected_comp(_Comp& __comp, _Proj1& __proj1, _Proj2& __proj2) { if constexpr (__is_identity>::value && __is_identity>::value && !is_member_pointer_v>) { // Avoid creating the lambda and just use the pristine comparator -- for certain algorithms, this would enable @@ -96,10 +89,10 @@ decltype(auto) __make_projected_comp(_Comp& __comp, _Proj1& __proj1, _Proj2& __p return __comp; } else { - return [&](auto&& __lhs, auto&& __rhs) { + return [&](auto&& __lhs, auto&& __rhs) -> bool { return std::invoke(__comp, - std::invoke(__proj1, std::forward(__lhs)), - std::invoke(__proj2, std::forward(__rhs))); + std::invoke(__proj1, std::forward(__lhs)), + std::invoke(__proj2, std::forward(__rhs))); }; } } diff --git a/third_party/libcxx/__algorithm/max.h b/third_party/libcxx/__algorithm/max.h index 97f61f2aa..d4c99f6f3 100644 --- a/third_party/libcxx/__algorithm/max.h +++ b/third_party/libcxx/__algorithm/max.h @@ -25,41 +25,28 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -const _Tp& -max(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp) -{ - return __comp(__a, __b) ? __b : __a; +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& +max(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp) { + return __comp(__a, __b) ? __b : __a; } template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -const _Tp& -max(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) -{ - return _VSTD::max(__a, __b, __less<_Tp>()); +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& +max(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) { + return std::max(__a, __b, __less<>()); } #ifndef _LIBCPP_CXX03_LANG -template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -_Tp -max(initializer_list<_Tp> __t, _Compare __comp) -{ - return *_VSTD::__max_element<__comp_ref_type<_Compare> >(__t.begin(), __t.end(), __comp); +template +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp +max(initializer_list<_Tp> __t, _Compare __comp) { + return *std::__max_element<__comp_ref_type<_Compare> >(__t.begin(), __t.end(), __comp); } -template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -_Tp -max(initializer_list<_Tp> __t) -{ - return *_VSTD::max_element(__t.begin(), __t.end(), __less<_Tp>()); +template +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp max(initializer_list<_Tp> __t) { + return *std::max_element(__t.begin(), __t.end(), __less<>()); } #endif // _LIBCPP_CXX03_LANG diff --git a/third_party/libcxx/__algorithm/max_element.h b/third_party/libcxx/__algorithm/max_element.h index f816a17fa..c036726cb 100644 --- a/third_party/libcxx/__algorithm/max_element.h +++ b/third_party/libcxx/__algorithm/max_element.h @@ -22,34 +22,28 @@ _LIBCPP_BEGIN_NAMESPACE_STD template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator -__max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) -{ - static_assert(__has_forward_iterator_category<_ForwardIterator>::value, - "std::max_element requires a ForwardIterator"); - if (__first != __last) - { - _ForwardIterator __i = __first; - while (++__i != __last) - if (__comp(*__first, *__i)) - __first = __i; - } - return __first; +__max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { + static_assert( + __has_forward_iterator_category<_ForwardIterator>::value, "std::max_element requires a ForwardIterator"); + if (__first != __last) { + _ForwardIterator __i = __first; + while (++__i != __last) + if (__comp(*__first, *__i)) + __first = __i; + } + return __first; } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator -max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) -{ - return _VSTD::__max_element<__comp_ref_type<_Compare> >(__first, __last, __comp); +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator +max_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { + return std::__max_element<__comp_ref_type<_Compare> >(__first, __last, __comp); } - template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator -max_element(_ForwardIterator __first, _ForwardIterator __last) -{ - return _VSTD::max_element(__first, __last, - __less::value_type>()); +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator +max_element(_ForwardIterator __first, _ForwardIterator __last) { + return std::max_element(__first, __last, __less<>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/merge.h b/third_party/libcxx/__algorithm/merge.h index e54e430bc..bad663c4b 100644 --- a/third_party/libcxx/__algorithm/merge.h +++ b/third_party/libcxx/__algorithm/merge.h @@ -22,47 +22,46 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -__merge(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) -{ - for (; __first1 != __last1; ++__result) - { - if (__first2 == __last2) - return _VSTD::copy(__first1, __last1, __result); - if (__comp(*__first2, *__first1)) - { - *__result = *__first2; - ++__first2; - } - else - { - *__result = *__first1; - ++__first1; - } +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator __merge( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _OutputIterator __result, + _Compare __comp) { + for (; __first1 != __last1; ++__result) { + if (__first2 == __last2) + return std::copy(__first1, __last1, __result); + if (__comp(*__first2, *__first1)) { + *__result = *__first2; + ++__first2; + } else { + *__result = *__first1; + ++__first1; } - return _VSTD::copy(__first2, __last2, __result); + } + return std::copy(__first2, __last2, __result); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -merge(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) -{ - return _VSTD::__merge<__comp_ref_type<_Compare> >(__first1, __last1, __first2, __last2, __result, __comp); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +merge(_InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _OutputIterator __result, + _Compare __comp) { + return std::__merge<__comp_ref_type<_Compare> >(__first1, __last1, __first2, __last2, __result, __comp); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -merge(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) -{ - typedef typename iterator_traits<_InputIterator1>::value_type __v1; - typedef typename iterator_traits<_InputIterator2>::value_type __v2; - return _VSTD::merge(__first1, __last1, __first2, __last2, __result, __less<__v1, __v2>()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +merge(_InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _OutputIterator __result) { + return std::merge(__first1, __last1, __first2, __last2, __result, __less<>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/min.h b/third_party/libcxx/__algorithm/min.h index d073a1653..1bafad8a4 100644 --- a/third_party/libcxx/__algorithm/min.h +++ b/third_party/libcxx/__algorithm/min.h @@ -25,41 +25,28 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -const _Tp& -min(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp) -{ - return __comp(__b, __a) ? __b : __a; +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& +min(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp) { + return __comp(__b, __a) ? __b : __a; } template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -const _Tp& -min(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) -{ - return _VSTD::min(__a, __b, __less<_Tp>()); +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& +min(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) { + return std::min(__a, __b, __less<>()); } #ifndef _LIBCPP_CXX03_LANG -template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -_Tp -min(initializer_list<_Tp> __t, _Compare __comp) -{ - return *_VSTD::__min_element<__comp_ref_type<_Compare> >(__t.begin(), __t.end(), __comp); +template +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp +min(initializer_list<_Tp> __t, _Compare __comp) { + return *std::__min_element<__comp_ref_type<_Compare> >(__t.begin(), __t.end(), __comp); } -template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -_Tp -min(initializer_list<_Tp> __t) -{ - return *_VSTD::min_element(__t.begin(), __t.end(), __less<_Tp>()); +template +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp min(initializer_list<_Tp> __t) { + return *std::min_element(__t.begin(), __t.end(), __less<>()); } #endif // _LIBCPP_CXX03_LANG diff --git a/third_party/libcxx/__algorithm/min_element.h b/third_party/libcxx/__algorithm/min_element.h index aeabd30a7..65f3594d6 100644 --- a/third_party/libcxx/__algorithm/min_element.h +++ b/third_party/libcxx/__algorithm/min_element.h @@ -22,11 +22,14 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -_Iter __min_element(_Iter __first, _Sent __last, _Comp __comp, _Proj& __proj) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter +__min_element(_Iter __first, _Sent __last, _Comp __comp, _Proj& __proj) { if (__first == __last) return __first; @@ -39,32 +42,30 @@ _Iter __min_element(_Iter __first, _Sent __last, _Comp __comp, _Proj& __proj) { } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -_Iter __min_element(_Iter __first, _Sent __last, _Comp __comp) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter __min_element(_Iter __first, _Sent __last, _Comp __comp) { auto __proj = __identity(); return std::__min_element<_Comp>(std::move(__first), std::move(__last), __comp, __proj); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator -min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) -{ - static_assert(__has_forward_iterator_category<_ForwardIterator>::value, - "std::min_element requires a ForwardIterator"); - static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__first)>::value, - "The comparator has to be callable"); +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator +min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { + static_assert( + __has_forward_iterator_category<_ForwardIterator>::value, "std::min_element requires a ForwardIterator"); + static_assert( + __is_callable<_Compare, decltype(*__first), decltype(*__first)>::value, "The comparator has to be callable"); return std::__min_element<__comp_ref_type<_Compare> >(std::move(__first), std::move(__last), __comp); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator -min_element(_ForwardIterator __first, _ForwardIterator __last) -{ - return _VSTD::min_element(__first, __last, - __less::value_type>()); +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator +min_element(_ForwardIterator __first, _ForwardIterator __last) { + return std::min_element(__first, __last, __less<>()); } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_MIN_ELEMENT_H diff --git a/third_party/libcxx/__algorithm/min_max_result.h b/third_party/libcxx/__algorithm/min_max_result.h index ef2d99038..e988df7c1 100644 --- a/third_party/libcxx/__algorithm/min_max_result.h +++ b/third_party/libcxx/__algorithm/min_max_result.h @@ -34,7 +34,7 @@ struct min_max_result { template requires convertible_to - _LIBCPP_HIDE_FROM_ABI constexpr operator min_max_result<_T2>() const & { + _LIBCPP_HIDE_FROM_ABI constexpr operator min_max_result<_T2>() const& { return {min, max}; } diff --git a/third_party/libcxx/__algorithm/minmax.h b/third_party/libcxx/__algorithm/minmax.h index f486de2ef..9feda2b4c 100644 --- a/third_party/libcxx/__algorithm/minmax.h +++ b/third_party/libcxx/__algorithm/minmax.h @@ -23,43 +23,33 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -pair -minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp) -{ - return __comp(__b, __a) ? pair(__b, __a) : - pair(__a, __b); +template +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair +minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b, _Compare __comp) { + return __comp(__b, __a) ? pair(__b, __a) : pair(__a, __b); } -template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -pair -minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) -{ - return std::minmax(__a, __b, __less<_Tp>()); +template +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair +minmax(_LIBCPP_LIFETIMEBOUND const _Tp& __a, _LIBCPP_LIFETIMEBOUND const _Tp& __b) { + return std::minmax(__a, __b, __less<>()); } #ifndef _LIBCPP_CXX03_LANG -template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -pair<_Tp, _Tp> minmax(initializer_list<_Tp> __t, _Compare __comp) { - static_assert(__is_callable<_Compare, _Tp, _Tp>::value, "The comparator has to be callable"); - __identity __proj; - auto __ret = std::__minmax_element_impl(__t.begin(), __t.end(), __comp, __proj); - return pair<_Tp, _Tp>(*__ret.first, *__ret.second); +template +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Tp, _Tp> +minmax(initializer_list<_Tp> __t, _Compare __comp) { + static_assert(__is_callable<_Compare, _Tp, _Tp>::value, "The comparator has to be callable"); + __identity __proj; + auto __ret = std::__minmax_element_impl(__t.begin(), __t.end(), __comp, __proj); + return pair<_Tp, _Tp>(*__ret.first, *__ret.second); } -template -_LIBCPP_NODISCARD_EXT inline -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -pair<_Tp, _Tp> -minmax(initializer_list<_Tp> __t) -{ - return std::minmax(__t, __less<_Tp>()); +template +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Tp, _Tp> +minmax(initializer_list<_Tp> __t) { + return std::minmax(__t, __less<>()); } #endif // _LIBCPP_CXX03_LANG diff --git a/third_party/libcxx/__algorithm/minmax_element.h b/third_party/libcxx/__algorithm/minmax_element.h index eca460de3..43cb23347 100644 --- a/third_party/libcxx/__algorithm/minmax_element.h +++ b/third_party/libcxx/__algorithm/minmax_element.h @@ -29,19 +29,18 @@ class _MinmaxElementLessFunc { _Proj& __proj_; public: - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR - _MinmaxElementLessFunc(_Comp& __comp, _Proj& __proj) : __comp_(__comp), __proj_(__proj) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _MinmaxElementLessFunc(_Comp& __comp, _Proj& __proj) + : __comp_(__comp), __proj_(__proj) {} template - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 - bool operator()(_Iter& __it1, _Iter& __it2) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool operator()(_Iter& __it1, _Iter& __it2) { return std::__invoke(__comp_, std::__invoke(__proj_, *__it1), std::__invoke(__proj_, *__it2)); } }; template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -pair<_Iter, _Iter> __minmax_element_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter, _Iter> +__minmax_element_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { auto __less = _MinmaxElementLessFunc<_Comp, _Proj>(__comp, __proj); pair<_Iter, _Iter> __result(__first, __first); @@ -66,8 +65,8 @@ pair<_Iter, _Iter> __minmax_element_impl(_Iter __first, _Sent __last, _Comp& __c if (__less(__first, __i)) { if (__less(__first, __result.first)) __result.first = __first; - if (!__less(__i, __result.second)) - __result.second = __i; + if (!__less(__i, __result.second)) + __result.second = __i; } else { if (__less(__i, __result.first)) __result.first = __i; @@ -80,21 +79,20 @@ pair<_Iter, _Iter> __minmax_element_impl(_Iter __first, _Sent __last, _Comp& __c } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -pair<_ForwardIterator, _ForwardIterator> +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_ForwardIterator, _ForwardIterator> minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { - static_assert(__has_forward_iterator_category<_ForwardIterator>::value, - "std::minmax_element requires a ForwardIterator"); - static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__first)>::value, - "The comparator has to be callable"); + static_assert( + __has_forward_iterator_category<_ForwardIterator>::value, "std::minmax_element requires a ForwardIterator"); + static_assert( + __is_callable<_Compare, decltype(*__first), decltype(*__first)>::value, "The comparator has to be callable"); auto __proj = __identity(); return std::__minmax_element_impl(__first, __last, __comp, __proj); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -pair<_ForwardIterator, _ForwardIterator> minmax_element(_ForwardIterator __first, _ForwardIterator __last) { - return std::minmax_element(__first, __last, __less::value_type>()); +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_ForwardIterator, _ForwardIterator> +minmax_element(_ForwardIterator __first, _ForwardIterator __last) { + return std::minmax_element(__first, __last, __less<>()); } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/mismatch.h b/third_party/libcxx/__algorithm/mismatch.h index e5b014f45..632bec024 100644 --- a/third_party/libcxx/__algorithm/mismatch.h +++ b/third_party/libcxx/__algorithm/mismatch.h @@ -11,53 +11,207 @@ #define _LIBCPP___ALGORITHM_MISMATCH_H #include <__algorithm/comp.h> +#include <__algorithm/min.h> +#include <__algorithm/simd_utils.h> +#include <__algorithm/unwrap_iter.h> #include <__config> -#include <__iterator/iterator_traits.h> +#include <__functional/identity.h> +#include <__iterator/aliasing_iterator.h> +#include <__type_traits/desugars_to.h> +#include <__type_traits/invoke.h> +#include <__type_traits/is_constant_evaluated.h> +#include <__type_traits/is_equality_comparable.h> +#include <__type_traits/is_integral.h> +#include <__utility/move.h> #include <__utility/pair.h> +#include <__utility/unreachable.h> +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> - mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) { - for (; __first1 != __last1; ++__first1, (void)++__first2) - if (!__pred(*__first1, *__first2)) +template +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Iter1, _Iter2> +__mismatch_loop(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) { + while (__first1 != __last1) { + if (!std::__invoke(__pred, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2))) break; - return pair<_InputIterator1, _InputIterator2>(__first1, __first2); + ++__first1; + ++__first2; + } + return std::make_pair(std::move(__first1), std::move(__first2)); +} + +template +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Iter1, _Iter2> +__mismatch(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) { + return std::__mismatch_loop(__first1, __last1, __first2, __pred, __proj1, __proj2); +} + +#if _LIBCPP_VECTORIZE_ALGORITHMS + +template +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Iter, _Iter> +__mismatch_vectorized(_Iter __first1, _Iter __last1, _Iter __first2) { + using __value_type = __iter_value_type<_Iter>; + constexpr size_t __unroll_count = 4; + constexpr size_t __vec_size = __native_vector_size<__value_type>; + using __vec = __simd_vector<__value_type, __vec_size>; + + if (!__libcpp_is_constant_evaluated()) { + auto __orig_first1 = __first1; + auto __last2 = __first2 + (__last1 - __first1); + while (static_cast(__last1 - __first1) >= __unroll_count * __vec_size) [[__unlikely__]] { + __vec __lhs[__unroll_count]; + __vec __rhs[__unroll_count]; + + for (size_t __i = 0; __i != __unroll_count; ++__i) { + __lhs[__i] = std::__load_vector<__vec>(__first1 + __i * __vec_size); + __rhs[__i] = std::__load_vector<__vec>(__first2 + __i * __vec_size); + } + + for (size_t __i = 0; __i != __unroll_count; ++__i) { + if (auto __cmp_res = __lhs[__i] == __rhs[__i]; !std::__all_of(__cmp_res)) { + auto __offset = __i * __vec_size + std::__find_first_not_set(__cmp_res); + return {__first1 + __offset, __first2 + __offset}; + } + } + + __first1 += __unroll_count * __vec_size; + __first2 += __unroll_count * __vec_size; + } + + // check the remaining 0-3 vectors + while (static_cast(__last1 - __first1) >= __vec_size) { + if (auto __cmp_res = std::__load_vector<__vec>(__first1) == std::__load_vector<__vec>(__first2); + !std::__all_of(__cmp_res)) { + auto __offset = std::__find_first_not_set(__cmp_res); + return {__first1 + __offset, __first2 + __offset}; + } + __first1 += __vec_size; + __first2 += __vec_size; + } + + if (__last1 - __first1 == 0) + return {__first1, __first2}; + + // Check if we can load elements in front of the current pointer. If that's the case load a vector at + // (last - vector_size) to check the remaining elements + if (static_cast(__first1 - __orig_first1) >= __vec_size) { + __first1 = __last1 - __vec_size; + __first2 = __last2 - __vec_size; + auto __offset = + std::__find_first_not_set(std::__load_vector<__vec>(__first1) == std::__load_vector<__vec>(__first2)); + return {__first1 + __offset, __first2 + __offset}; + } // else loop over the elements individually + } + + __equal_to __pred; + __identity __proj; + return std::__mismatch_loop(__first1, __last1, __first2, __pred, __proj, __proj); +} + +template ::value && __desugars_to_v<__equal_tag, _Pred, _Tp, _Tp> && + __is_identity<_Proj1>::value && __is_identity<_Proj2>::value, + int> = 0> +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Tp*, _Tp*> +__mismatch(_Tp* __first1, _Tp* __last1, _Tp* __first2, _Pred&, _Proj1&, _Proj2&) { + return std::__mismatch_vectorized(__first1, __last1, __first2); +} + +template ::value && __desugars_to_v<__equal_tag, _Pred, _Tp, _Tp> && + __is_identity<_Proj1>::value && __is_identity<_Proj2>::value && + __can_map_to_integer_v<_Tp> && __libcpp_is_trivially_equality_comparable<_Tp, _Tp>::value, + int> = 0> +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Tp*, _Tp*> +__mismatch(_Tp* __first1, _Tp* __last1, _Tp* __first2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) { + if (__libcpp_is_constant_evaluated()) { + return std::__mismatch_loop(__first1, __last1, __first2, __pred, __proj1, __proj2); + } else { + using _Iter = __aliasing_iterator<_Tp*, __get_as_integer_type_t<_Tp>>; + auto __ret = std::__mismatch_vectorized(_Iter(__first1), _Iter(__last1), _Iter(__first2)); + return {__ret.first.__base(), __ret.second.__base()}; + } +} +#endif // _LIBCPP_VECTORIZE_ALGORITHMS + +template +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> +mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred) { + __identity __proj; + auto __res = std::__mismatch( + std::__unwrap_iter(__first1), std::__unwrap_iter(__last1), std::__unwrap_iter(__first2), __pred, __proj, __proj); + return std::make_pair(std::__rewrap_iter(__first1, __res.first), std::__rewrap_iter(__first2, __res.second)); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> - mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> +mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2) { return std::mismatch(__first1, __last1, __first2, __equal_to()); } #if _LIBCPP_STD_VER >= 14 -template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> - mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, - _BinaryPredicate __pred) { - for (; __first1 != __last1 && __first2 != __last2; ++__first1, (void)++__first2) - if (!__pred(*__first1, *__first2)) +template +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Iter1, _Iter2> __mismatch( + _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) { + while (__first1 != __last1 && __first2 != __last2) { + if (!std::__invoke(__pred, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2))) break; - return pair<_InputIterator1, _InputIterator2>(__first1, __first2); + ++__first1; + ++__first2; + } + return {std::move(__first1), std::move(__first2)}; +} + +template +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Tp*, _Tp*> +__mismatch(_Tp* __first1, _Tp* __last1, _Tp* __first2, _Tp* __last2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) { + auto __len = std::min(__last1 - __first1, __last2 - __first2); + return std::__mismatch(__first1, __first1 + __len, __first2, __pred, __proj1, __proj2); +} + +template +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> +mismatch(_InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _BinaryPredicate __pred) { + __identity __proj; + auto __res = std::__mismatch( + std::__unwrap_iter(__first1), + std::__unwrap_iter(__last1), + std::__unwrap_iter(__first2), + std::__unwrap_iter(__last2), + __pred, + __proj, + __proj); + return {std::__rewrap_iter(__first1, __res.first), std::__rewrap_iter(__first2, __res.second)}; } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> - mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator1, _InputIterator2> +mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2) { return std::mismatch(__first1, __last1, __first2, __last2, __equal_to()); } #endif _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_MISMATCH_H diff --git a/third_party/libcxx/__algorithm/move.h b/third_party/libcxx/__algorithm/move.h index b1b702a06..1716d43e2 100644 --- a/third_party/libcxx/__algorithm/move.h +++ b/third_party/libcxx/__algorithm/move.h @@ -16,7 +16,7 @@ #include <__config> #include <__iterator/segmented_iterator.h> #include <__type_traits/common_type.h> -#include <__type_traits/is_copy_constructible.h> +#include <__type_traits/is_constructible.h> #include <__utility/move.h> #include <__utility/pair.h> @@ -34,7 +34,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIte __move(_InIter __first, _Sent __last, _OutIter __result); template -struct __move_loop { +struct __move_impl { template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const { @@ -52,9 +52,10 @@ struct __move_loop { _OutIter& __result_; - _LIBCPP_HIDE_FROM_ABI _MoveSegment(_OutIter& __result) : __result_(__result) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit _MoveSegment(_OutIter& __result) + : __result_(__result) {} - _LIBCPP_HIDE_FROM_ABI void + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void operator()(typename _Traits::__local_iterator __lfirst, typename _Traits::__local_iterator __llast) { __result_ = std::__move<_AlgPolicy>(__lfirst, __llast, std::move(__result_)).second; } @@ -73,7 +74,7 @@ struct __move_loop { !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> - operator()(_InIter __first, _InIter __last, _OutIter __result) { + operator()(_InIter __first, _InIter __last, _OutIter __result) const { using _Traits = __segmented_iterator_traits<_OutIter>; using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type; @@ -94,12 +95,9 @@ struct __move_loop { __local_first = _Traits::__begin(++__segment_iterator); } } -}; -struct __move_trivial { // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer. - template ::value, int> = 0> + template ::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*> operator()(_In* __first, _In* __last, _Out* __result) const { return std::__copy_trivial_impl(__first, __last, __result); @@ -109,7 +107,7 @@ struct __move_trivial { template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> __move(_InIter __first, _Sent __last, _OutIter __result) { - return std::__dispatch_copy_or_move<_AlgPolicy, __move_loop<_AlgPolicy>, __move_trivial>( + return std::__copy_move_unwrap_iters<__move_impl<_AlgPolicy> >( std::move(__first), std::move(__last), std::move(__result)); } diff --git a/third_party/libcxx/__algorithm/move_backward.h b/third_party/libcxx/__algorithm/move_backward.h index db4c4db1c..4beb7bdba 100644 --- a/third_party/libcxx/__algorithm/move_backward.h +++ b/third_party/libcxx/__algorithm/move_backward.h @@ -15,7 +15,7 @@ #include <__config> #include <__iterator/segmented_iterator.h> #include <__type_traits/common_type.h> -#include <__type_traits/is_copy_constructible.h> +#include <__type_traits/is_constructible.h> #include <__utility/move.h> #include <__utility/pair.h> @@ -33,7 +33,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator1 __move_backward(_BidirectionalIterator1 __first, _Sentinel __last, _BidirectionalIterator2 __result); template -struct __move_backward_loop { +struct __move_backward_impl { template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const { @@ -80,7 +80,7 @@ struct __move_backward_loop { !__is_segmented_iterator<_InIter>::value && __is_segmented_iterator<_OutIter>::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter> - operator()(_InIter __first, _InIter __last, _OutIter __result) { + operator()(_InIter __first, _InIter __last, _OutIter __result) const { using _Traits = __segmented_iterator_traits<_OutIter>; using _DiffT = typename common_type<__iter_diff_t<_InIter>, __iter_diff_t<_OutIter> >::type; @@ -104,12 +104,9 @@ struct __move_backward_loop { __local_last = _Traits::__end(--__segment_iterator); } } -}; -struct __move_backward_trivial { // At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer. - template ::value, int> = 0> + template ::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*> operator()(_In* __first, _In* __last, _Out* __result) const { return std::__copy_backward_trivial_impl(__first, __last, __result); @@ -120,14 +117,15 @@ template __move_backward(_BidirectionalIterator1 __first, _Sentinel __last, _BidirectionalIterator2 __result) { static_assert(std::is_copy_constructible<_BidirectionalIterator1>::value && - std::is_copy_constructible<_BidirectionalIterator1>::value, "Iterators must be copy constructible."); + std::is_copy_constructible<_BidirectionalIterator1>::value, + "Iterators must be copy constructible."); - return std::__dispatch_copy_or_move<_AlgPolicy, __move_backward_loop<_AlgPolicy>, __move_backward_trivial>( + return std::__copy_move_unwrap_iters<__move_backward_impl<_AlgPolicy> >( std::move(__first), std::move(__last), std::move(__result)); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _BidirectionalIterator2 +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _BidirectionalIterator2 move_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, _BidirectionalIterator2 __result) { return std::__move_backward<_ClassicAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)).second; } diff --git a/third_party/libcxx/__algorithm/next_permutation.h b/third_party/libcxx/__algorithm/next_permutation.h index 73e8b99ab..011ee028c 100644 --- a/third_party/libcxx/__algorithm/next_permutation.h +++ b/third_party/libcxx/__algorithm/next_permutation.h @@ -22,57 +22,54 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator, bool> -__next_permutation(_BidirectionalIterator __first, _Sentinel __last, _Compare&& __comp) -{ - using _Result = pair<_BidirectionalIterator, bool>; +__next_permutation(_BidirectionalIterator __first, _Sentinel __last, _Compare&& __comp) { + using _Result = pair<_BidirectionalIterator, bool>; - _BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::next(__first, __last); - _BidirectionalIterator __i = __last_iter; - if (__first == __last || __first == --__i) - return _Result(std::move(__last_iter), false); + _BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::next(__first, __last); + _BidirectionalIterator __i = __last_iter; + if (__first == __last || __first == --__i) + return _Result(std::move(__last_iter), false); - while (true) - { - _BidirectionalIterator __ip1 = __i; - if (__comp(*--__i, *__ip1)) - { - _BidirectionalIterator __j = __last_iter; - while (!__comp(*__i, *--__j)) - ; - _IterOps<_AlgPolicy>::iter_swap(__i, __j); - std::__reverse<_AlgPolicy>(__ip1, __last_iter); - return _Result(std::move(__last_iter), true); - } - if (__i == __first) - { - std::__reverse<_AlgPolicy>(__first, __last_iter); - return _Result(std::move(__last_iter), false); - } + while (true) { + _BidirectionalIterator __ip1 = __i; + if (__comp(*--__i, *__ip1)) { + _BidirectionalIterator __j = __last_iter; + while (!__comp(*__i, *--__j)) + ; + _IterOps<_AlgPolicy>::iter_swap(__i, __j); + std::__reverse<_AlgPolicy>(__ip1, __last_iter); + return _Result(std::move(__last_iter), true); } + if (__i == __first) { + std::__reverse<_AlgPolicy>(__first, __last_iter); + return _Result(std::move(__last_iter), false); + } + } } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -bool -next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) -{ +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) { return std::__next_permutation<_ClassicAlgPolicy>( - std::move(__first), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp)).second; + std::move(__first), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp)) + .second; } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -bool -next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) -{ - return _VSTD::next_permutation(__first, __last, - __less::value_type>()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) { + return std::next_permutation(__first, __last, __less<>()); } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_NEXT_PERMUTATION_H diff --git a/third_party/libcxx/__algorithm/none_of.h b/third_party/libcxx/__algorithm/none_of.h index 19357eb23..50841ba17 100644 --- a/third_party/libcxx/__algorithm/none_of.h +++ b/third_party/libcxx/__algorithm/none_of.h @@ -19,7 +19,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { for (; __first != __last; ++__first) if (__pred(*__first)) diff --git a/third_party/libcxx/__algorithm/nth_element.h b/third_party/libcxx/__algorithm/nth_element.h index 9fdfb2cae..da748d725 100644 --- a/third_party/libcxx/__algorithm/nth_element.h +++ b/third_party/libcxx/__algorithm/nth_element.h @@ -13,8 +13,8 @@ #include <__algorithm/comp_ref_type.h> #include <__algorithm/iterator_operations.h> #include <__algorithm/sort.h> +#include <__assert> #include <__config> -#include <__debug> #include <__debug_utils/randomize_range.h> #include <__iterator/iterator_traits.h> #include <__utility/move.h> @@ -23,209 +23,212 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool -__nth_element_find_guard(_RandomAccessIterator& __i, _RandomAccessIterator& __j, - _RandomAccessIterator __m, _Compare __comp) -{ - // manually guard downward moving __j against __i - while (true) { - if (__i == --__j) { - return false; - } - if (__comp(*__j, *__m)) { - return true; // found guard for downward moving __j, now use unguarded partition - } +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool __nth_element_find_guard( + _RandomAccessIterator& __i, _RandomAccessIterator& __j, _RandomAccessIterator __m, _Compare __comp) { + // manually guard downward moving __j against __i + while (true) { + if (__i == --__j) { + return false; } + if (__comp(*__j, *__m)) { + return true; // found guard for downward moving __j, now use unguarded partition + } + } } template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void -__nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) -{ - using _Ops = _IterOps<_AlgPolicy>; +// NOLINTNEXTLINE(readability-function-cognitive-complexity) +__nth_element( + _RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) { + using _Ops = _IterOps<_AlgPolicy>; - // _Compare is known to be a reference type - typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; - const difference_type __limit = 7; - while (true) - { - if (__nth == __last) - return; - difference_type __len = __last - __first; - switch (__len) - { - case 0: - case 1: - return; - case 2: - if (__comp(*--__last, *__first)) - _Ops::iter_swap(__first, __last); - return; - case 3: - { - _RandomAccessIterator __m = __first; - std::__sort3<_AlgPolicy, _Compare>(__first, ++__m, --__last, __comp); - return; - } - } - if (__len <= __limit) - { - std::__selection_sort<_AlgPolicy, _Compare>(__first, __last, __comp); - return; - } - // __len > __limit >= 3 - _RandomAccessIterator __m = __first + __len/2; - _RandomAccessIterator __lm1 = __last; - unsigned __n_swaps = std::__sort3<_AlgPolicy, _Compare>(__first, __m, --__lm1, __comp); - // *__m is median - // partition [__first, __m) < *__m and *__m <= [__m, __last) - // (this inhibits tossing elements equivalent to __m around unnecessarily) - _RandomAccessIterator __i = __first; - _RandomAccessIterator __j = __lm1; - // j points beyond range to be tested, *__lm1 is known to be <= *__m - // The search going up is known to be guarded but the search coming down isn't. - // Prime the downward search with a guard. - if (!__comp(*__i, *__m)) // if *__first == *__m - { - // *__first == *__m, *__first doesn't go in first part - if (_VSTD::__nth_element_find_guard<_Compare>(__i, __j, __m, __comp)) { - _Ops::iter_swap(__i, __j); - ++__n_swaps; - } else { - // *__first == *__m, *__m <= all other elements - // Partition instead into [__first, __i) == *__first and *__first < [__i, __last) - ++__i; // __first + 1 - __j = __last; - if (!__comp(*__first, *--__j)) { // we need a guard if *__first == *(__last-1) - while (true) { - if (__i == __j) { - return; // [__first, __last) all equivalent elements - } else if (__comp(*__first, *__i)) { - _Ops::iter_swap(__i, __j); - ++__n_swaps; - ++__i; - break; - } - ++__i; - } - } - // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1 - if (__i == __j) { - return; - } - while (true) { - while (!__comp(*__first, *__i)) - ++__i; - while (__comp(*__first, *--__j)) - ; - if (__i >= __j) - break; - _Ops::iter_swap(__i, __j); - ++__n_swaps; - ++__i; - } - // [__first, __i) == *__first and *__first < [__i, __last) - // The first part is sorted, - if (__nth < __i) { - return; - } - // __nth_element the second part - // _VSTD::__nth_element<_Compare>(__i, __nth, __last, __comp); - __first = __i; - continue; - } - } - ++__i; - // j points beyond range to be tested, *__lm1 is known to be <= *__m - // if not yet partitioned... - if (__i < __j) - { - // known that *(__i - 1) < *__m - while (true) - { - // __m still guards upward moving __i - while (__comp(*__i, *__m)) - ++__i; - // It is now known that a guard exists for downward moving __j - while (!__comp(*--__j, *__m)) - ; - if (__i >= __j) - break; - _Ops::iter_swap(__i, __j); - ++__n_swaps; - // It is known that __m != __j - // If __m just moved, follow it - if (__m == __i) - __m = __j; - ++__i; - } - } - // [__first, __i) < *__m and *__m <= [__i, __last) - if (__i != __m && __comp(*__m, *__i)) - { - _Ops::iter_swap(__i, __m); - ++__n_swaps; - } - // [__first, __i) < *__i and *__i <= [__i+1, __last) - if (__nth == __i) - return; - if (__n_swaps == 0) - { - // We were given a perfectly partitioned sequence. Coincidence? - if (__nth < __i) - { - // Check for [__first, __i) already sorted - __j = __m = __first; - while (true) { - if (++__j == __i) { - // [__first, __i) sorted - return; - } - if (__comp(*__j, *__m)) { - // not yet sorted, so sort - break; - } - __m = __j; - } - } - else - { - // Check for [__i, __last) already sorted - __j = __m = __i; - while (true) { - if (++__j == __last) { - // [__i, __last) sorted - return; - } - if (__comp(*__j, *__m)) { - // not yet sorted, so sort - break; - } - __m = __j; - } - } - } - // __nth_element on range containing __nth - if (__nth < __i) - { - // _VSTD::__nth_element<_Compare>(__first, __nth, __i, __comp); - __last = __i; - } - else - { - // _VSTD::__nth_element<_Compare>(__i+1, __nth, __last, __comp); - __first = ++__i; - } + // _Compare is known to be a reference type + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + const difference_type __limit = 7; + while (true) { + if (__nth == __last) + return; + difference_type __len = __last - __first; + switch (__len) { + case 0: + case 1: + return; + case 2: + if (__comp(*--__last, *__first)) + _Ops::iter_swap(__first, __last); + return; + case 3: { + _RandomAccessIterator __m = __first; + std::__sort3<_AlgPolicy, _Compare>(__first, ++__m, --__last, __comp); + return; } + } + if (__len <= __limit) { + std::__selection_sort<_AlgPolicy, _Compare>(__first, __last, __comp); + return; + } + // __len > __limit >= 3 + _RandomAccessIterator __m = __first + __len / 2; + _RandomAccessIterator __lm1 = __last; + unsigned __n_swaps = std::__sort3<_AlgPolicy, _Compare>(__first, __m, --__lm1, __comp); + // *__m is median + // partition [__first, __m) < *__m and *__m <= [__m, __last) + // (this inhibits tossing elements equivalent to __m around unnecessarily) + _RandomAccessIterator __i = __first; + _RandomAccessIterator __j = __lm1; + // j points beyond range to be tested, *__lm1 is known to be <= *__m + // The search going up is known to be guarded but the search coming down isn't. + // Prime the downward search with a guard. + if (!__comp(*__i, *__m)) // if *__first == *__m + { + // *__first == *__m, *__first doesn't go in first part + if (std::__nth_element_find_guard<_Compare>(__i, __j, __m, __comp)) { + _Ops::iter_swap(__i, __j); + ++__n_swaps; + } else { + // *__first == *__m, *__m <= all other elements + // Partition instead into [__first, __i) == *__first and *__first < [__i, __last) + ++__i; // __first + 1 + __j = __last; + if (!__comp(*__first, *--__j)) { // we need a guard if *__first == *(__last-1) + while (true) { + if (__i == __j) { + return; // [__first, __last) all equivalent elements + } else if (__comp(*__first, *__i)) { + _Ops::iter_swap(__i, __j); + ++__n_swaps; + ++__i; + break; + } + ++__i; + } + } + // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1 + if (__i == __j) { + return; + } + while (true) { + while (!__comp(*__first, *__i)) { + ++__i; + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __i != __last, + "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); + } + do { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __j != __first, + "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); + --__j; + } while (__comp(*__first, *__j)); + if (__i >= __j) + break; + _Ops::iter_swap(__i, __j); + ++__n_swaps; + ++__i; + } + // [__first, __i) == *__first and *__first < [__i, __last) + // The first part is sorted, + if (__nth < __i) { + return; + } + // __nth_element the second part + // std::__nth_element<_Compare>(__i, __nth, __last, __comp); + __first = __i; + continue; + } + } + ++__i; + // j points beyond range to be tested, *__lm1 is known to be <= *__m + // if not yet partitioned... + if (__i < __j) { + // known that *(__i - 1) < *__m + while (true) { + // __m still guards upward moving __i + while (__comp(*__i, *__m)) { + ++__i; + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __i != __last, + "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); + } + // It is now known that a guard exists for downward moving __j + do { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __j != __first, + "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); + --__j; + } while (!__comp(*__j, *__m)); + if (__i >= __j) + break; + _Ops::iter_swap(__i, __j); + ++__n_swaps; + // It is known that __m != __j + // If __m just moved, follow it + if (__m == __i) + __m = __j; + ++__i; + } + } + // [__first, __i) < *__m and *__m <= [__i, __last) + if (__i != __m && __comp(*__m, *__i)) { + _Ops::iter_swap(__i, __m); + ++__n_swaps; + } + // [__first, __i) < *__i and *__i <= [__i+1, __last) + if (__nth == __i) + return; + if (__n_swaps == 0) { + // We were given a perfectly partitioned sequence. Coincidence? + if (__nth < __i) { + // Check for [__first, __i) already sorted + __j = __m = __first; + while (true) { + if (++__j == __i) { + // [__first, __i) sorted + return; + } + if (__comp(*__j, *__m)) { + // not yet sorted, so sort + break; + } + __m = __j; + } + } else { + // Check for [__i, __last) already sorted + __j = __m = __i; + while (true) { + if (++__j == __last) { + // [__i, __last) sorted + return; + } + if (__comp(*__j, *__m)) { + // not yet sorted, so sort + break; + } + __m = __j; + } + } + } + // __nth_element on range containing __nth + if (__nth < __i) { + // std::__nth_element<_Compare>(__first, __nth, __i, __comp); + __last = __i; + } else { + // std::__nth_element<_Compare>(__i+1, __nth, __last, __comp); + __first = ++__i; + } + } } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void __nth_element_impl(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, - _Compare& __comp) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __nth_element_impl( + _RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare& __comp) { if (__nth == __last) return; @@ -240,19 +243,19 @@ void __nth_element_impl(_RandomAccessIterator __first, _RandomAccessIterator __n } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, - _Compare __comp) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) { std::__nth_element_impl<_ClassicAlgPolicy>(std::move(__first), std::move(__nth), std::move(__last), __comp); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last) { - std::nth_element(std::move(__first), std::move(__nth), std::move(__last), __less::value_type>()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last) { + std::nth_element(std::move(__first), std::move(__nth), std::move(__last), __less<>()); } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_NTH_ELEMENT_H diff --git a/third_party/libcxx/__algorithm/partial_sort.h b/third_party/libcxx/__algorithm/partial_sort.h index 4b8e0e76b..7f8d0c491 100644 --- a/third_party/libcxx/__algorithm/partial_sort.h +++ b/third_party/libcxx/__algorithm/partial_sort.h @@ -16,22 +16,23 @@ #include <__algorithm/sift_down.h> #include <__algorithm/sort_heap.h> #include <__config> -#include <__debug> #include <__debug_utils/randomize_range.h> #include <__iterator/iterator_traits.h> -#include <__type_traits/is_copy_assignable.h> -#include <__type_traits/is_copy_constructible.h> +#include <__type_traits/is_assignable.h> +#include <__type_traits/is_constructible.h> #include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_RandomAccessIterator __partial_sort_impl( +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator __partial_sort_impl( _RandomAccessIterator __first, _RandomAccessIterator __middle, _Sentinel __last, _Compare&& __comp) { if (__first == __middle) { return _IterOps<_AlgPolicy>::next(__middle, __last); @@ -40,14 +41,12 @@ _RandomAccessIterator __partial_sort_impl( std::__make_heap<_AlgPolicy>(__first, __middle, __comp); typename iterator_traits<_RandomAccessIterator>::difference_type __len = __middle - __first; - _RandomAccessIterator __i = __middle; - for (; __i != __last; ++__i) - { - if (__comp(*__i, *__first)) - { - _IterOps<_AlgPolicy>::iter_swap(__i, __first); - std::__sift_down<_AlgPolicy>(__first, __comp, __len, __first); - } + _RandomAccessIterator __i = __middle; + for (; __i != __last; ++__i) { + if (__comp(*__i, *__first)) { + _IterOps<_AlgPolicy>::iter_swap(__i, __first); + std::__sift_down<_AlgPolicy>(__first, __comp, __len, __first); + } } std::__sort_heap<_AlgPolicy>(std::move(__first), std::move(__middle), __comp); @@ -55,11 +54,10 @@ _RandomAccessIterator __partial_sort_impl( } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_RandomAccessIterator __partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _Sentinel __last, - _Compare& __comp) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator +__partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _Sentinel __last, _Compare& __comp) { if (__first == __middle) - return _IterOps<_AlgPolicy>::next(__middle, __last); + return _IterOps<_AlgPolicy>::next(__middle, __last); std::__debug_randomize_range<_AlgPolicy>(__first, __last); @@ -72,11 +70,8 @@ _RandomAccessIterator __partial_sort(_RandomAccessIterator __first, _RandomAcces } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -void -partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, - _Compare __comp) -{ +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void partial_sort( + _RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, _Compare __comp) { static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible."); static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable."); @@ -84,14 +79,13 @@ partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _Ran } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -void -partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) -{ - _VSTD::partial_sort(__first, __middle, __last, - __less::value_type>()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) { + std::partial_sort(__first, __middle, __last, __less<>()); } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_PARTIAL_SORT_H diff --git a/third_party/libcxx/__algorithm/partial_sort_copy.h b/third_party/libcxx/__algorithm/partial_sort_copy.h index 1aba07105..ef7c9d34d 100644 --- a/third_party/libcxx/__algorithm/partial_sort_copy.h +++ b/third_party/libcxx/__algorithm/partial_sort_copy.h @@ -28,61 +28,79 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator, _RandomAccessIterator> -__partial_sort_copy(_InputIterator __first, _Sentinel1 __last, - _RandomAccessIterator __result_first, _Sentinel2 __result_last, - _Compare&& __comp, _Proj1&& __proj1, _Proj2&& __proj2) -{ - _RandomAccessIterator __r = __result_first; - auto&& __projected_comp = std::__make_projected(__comp, __proj2); +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator, _RandomAccessIterator> __partial_sort_copy( + _InputIterator __first, + _Sentinel1 __last, + _RandomAccessIterator __result_first, + _Sentinel2 __result_last, + _Compare&& __comp, + _Proj1&& __proj1, + _Proj2&& __proj2) { + _RandomAccessIterator __r = __result_first; + auto&& __projected_comp = std::__make_projected(__comp, __proj2); - if (__r != __result_last) - { - for (; __first != __last && __r != __result_last; ++__first, (void) ++__r) - *__r = *__first; - std::__make_heap<_AlgPolicy>(__result_first, __r, __projected_comp); - typename iterator_traits<_RandomAccessIterator>::difference_type __len = __r - __result_first; - for (; __first != __last; ++__first) - if (std::__invoke(__comp, std::__invoke(__proj1, *__first), std::__invoke(__proj2, *__result_first))) { - *__result_first = *__first; - std::__sift_down<_AlgPolicy>(__result_first, __projected_comp, __len, __result_first); - } - std::__sort_heap<_AlgPolicy>(__result_first, __r, __projected_comp); - } + if (__r != __result_last) { + for (; __first != __last && __r != __result_last; ++__first, (void)++__r) + *__r = *__first; + std::__make_heap<_AlgPolicy>(__result_first, __r, __projected_comp); + typename iterator_traits<_RandomAccessIterator>::difference_type __len = __r - __result_first; + for (; __first != __last; ++__first) + if (std::__invoke(__comp, std::__invoke(__proj1, *__first), std::__invoke(__proj2, *__result_first))) { + *__result_first = *__first; + std::__sift_down<_AlgPolicy>(__result_first, __projected_comp, __len, __result_first); + } + std::__sort_heap<_AlgPolicy>(__result_first, __r, __projected_comp); + } - return pair<_InputIterator, _RandomAccessIterator>( - _IterOps<_AlgPolicy>::next(std::move(__first), std::move(__last)), std::move(__r)); + return pair<_InputIterator, _RandomAccessIterator>( + _IterOps<_AlgPolicy>::next(std::move(__first), std::move(__last)), std::move(__r)); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -_RandomAccessIterator -partial_sort_copy(_InputIterator __first, _InputIterator __last, - _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp) -{ - static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__result_first)>::value, - "Comparator has to be callable"); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator partial_sort_copy( + _InputIterator __first, + _InputIterator __last, + _RandomAccessIterator __result_first, + _RandomAccessIterator __result_last, + _Compare __comp) { + static_assert( + __is_callable<_Compare, decltype(*__first), decltype(*__result_first)>::value, "Comparator has to be callable"); - auto __result = std::__partial_sort_copy<_ClassicAlgPolicy>(__first, __last, __result_first, __result_last, - static_cast<__comp_ref_type<_Compare> >(__comp), __identity(), __identity()); + auto __result = std::__partial_sort_copy<_ClassicAlgPolicy>( + __first, + __last, + __result_first, + __result_last, + static_cast<__comp_ref_type<_Compare> >(__comp), + __identity(), + __identity()); return __result.second; } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -_RandomAccessIterator -partial_sort_copy(_InputIterator __first, _InputIterator __last, - _RandomAccessIterator __result_first, _RandomAccessIterator __result_last) -{ - return _VSTD::partial_sort_copy(__first, __last, __result_first, __result_last, - __less::value_type>()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator partial_sort_copy( + _InputIterator __first, + _InputIterator __last, + _RandomAccessIterator __result_first, + _RandomAccessIterator __result_last) { + return std::partial_sort_copy(__first, __last, __result_first, __result_last, __less<>()); } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_PARTIAL_SORT_COPY_H diff --git a/third_party/libcxx/__algorithm/partition.h b/third_party/libcxx/__algorithm/partition.h index a58dd6464..824e49b9e 100644 --- a/third_party/libcxx/__algorithm/partition.h +++ b/third_party/libcxx/__algorithm/partition.h @@ -19,74 +19,65 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> -__partition_impl(_ForwardIterator __first, _Sentinel __last, _Predicate __pred, forward_iterator_tag) -{ - while (true) - { - if (__first == __last) - return std::make_pair(std::move(__first), std::move(__first)); - if (!__pred(*__first)) - break; - ++__first; - } +__partition_impl(_ForwardIterator __first, _Sentinel __last, _Predicate __pred, forward_iterator_tag) { + while (true) { + if (__first == __last) + return std::make_pair(std::move(__first), std::move(__first)); + if (!__pred(*__first)) + break; + ++__first; + } - _ForwardIterator __p = __first; - while (++__p != __last) - { - if (__pred(*__p)) - { - _IterOps<_AlgPolicy>::iter_swap(__first, __p); - ++__first; - } + _ForwardIterator __p = __first; + while (++__p != __last) { + if (__pred(*__p)) { + _IterOps<_AlgPolicy>::iter_swap(__first, __p); + ++__first; } - return std::make_pair(std::move(__first), std::move(__p)); + } + return std::make_pair(std::move(__first), std::move(__p)); } template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator, _BidirectionalIterator> -__partition_impl(_BidirectionalIterator __first, _Sentinel __sentinel, _Predicate __pred, - bidirectional_iterator_tag) -{ - _BidirectionalIterator __original_last = _IterOps<_AlgPolicy>::next(__first, __sentinel); - _BidirectionalIterator __last = __original_last; +__partition_impl(_BidirectionalIterator __first, _Sentinel __sentinel, _Predicate __pred, bidirectional_iterator_tag) { + _BidirectionalIterator __original_last = _IterOps<_AlgPolicy>::next(__first, __sentinel); + _BidirectionalIterator __last = __original_last; - while (true) - { - while (true) - { - if (__first == __last) - return std::make_pair(std::move(__first), std::move(__original_last)); - if (!__pred(*__first)) - break; - ++__first; - } - do - { - if (__first == --__last) - return std::make_pair(std::move(__first), std::move(__original_last)); - } while (!__pred(*__last)); - _IterOps<_AlgPolicy>::iter_swap(__first, __last); - ++__first; + while (true) { + while (true) { + if (__first == __last) + return std::make_pair(std::move(__first), std::move(__original_last)); + if (!__pred(*__first)) + break; + ++__first; } + do { + if (__first == --__last) + return std::make_pair(std::move(__first), std::move(__original_last)); + } while (!__pred(*__last)); + _IterOps<_AlgPolicy>::iter_swap(__first, __last); + ++__first; + } } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -pair<_ForwardIterator, _ForwardIterator> __partition( - _ForwardIterator __first, _Sentinel __last, _Predicate&& __pred, _IterCategory __iter_category) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator> +__partition(_ForwardIterator __first, _Sentinel __last, _Predicate&& __pred, _IterCategory __iter_category) { return std::__partition_impl<__remove_cvref_t<_Predicate>&, _AlgPolicy>( std::move(__first), std::move(__last), __pred, __iter_category); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -_ForwardIterator -partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) -{ +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { using _IterCategory = typename iterator_traits<_ForwardIterator>::iterator_category; auto __result = std::__partition<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __pred, _IterCategory()); return __result.first; @@ -94,4 +85,6 @@ partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_PARTITION_H diff --git a/third_party/libcxx/__algorithm/partition_copy.h b/third_party/libcxx/__algorithm/partition_copy.h index ff8826a93..147b45c78 100644 --- a/third_party/libcxx/__algorithm/partition_copy.h +++ b/third_party/libcxx/__algorithm/partition_copy.h @@ -19,27 +19,23 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_OutputIterator1, _OutputIterator2> -partition_copy(_InputIterator __first, _InputIterator __last, - _OutputIterator1 __out_true, _OutputIterator2 __out_false, - _Predicate __pred) -{ - for (; __first != __last; ++__first) - { - if (__pred(*__first)) - { - *__out_true = *__first; - ++__out_true; - } - else - { - *__out_false = *__first; - ++__out_false; - } +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_OutputIterator1, _OutputIterator2> partition_copy( + _InputIterator __first, + _InputIterator __last, + _OutputIterator1 __out_true, + _OutputIterator2 __out_false, + _Predicate __pred) { + for (; __first != __last; ++__first) { + if (__pred(*__first)) { + *__out_true = *__first; + ++__out_true; + } else { + *__out_false = *__first; + ++__out_false; } - return pair<_OutputIterator1, _OutputIterator2>(__out_true, __out_false); + } + return pair<_OutputIterator1, _OutputIterator2>(__out_true, __out_false); } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/partition_point.h b/third_party/libcxx/__algorithm/partition_point.h index 6ede71a26..504dbf1d1 100644 --- a/third_party/libcxx/__algorithm/partition_point.h +++ b/third_party/libcxx/__algorithm/partition_point.h @@ -21,26 +21,22 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template +template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator -partition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) -{ - typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; - difference_type __len = _VSTD::distance(__first, __last); - while (__len != 0) - { - difference_type __l2 = _VSTD::__half_positive(__len); - _ForwardIterator __m = __first; - _VSTD::advance(__m, __l2); - if (__pred(*__m)) - { - __first = ++__m; - __len -= __l2 + 1; - } - else - __len = __l2; - } - return __first; +partition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { + typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; + difference_type __len = std::distance(__first, __last); + while (__len != 0) { + difference_type __l2 = std::__half_positive(__len); + _ForwardIterator __m = __first; + std::advance(__m, __l2); + if (__pred(*__m)) { + __first = ++__m; + __len -= __l2 + 1; + } else + __len = __l2; + } + return __first; } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/pop_heap.h b/third_party/libcxx/__algorithm/pop_heap.h index 4187523ef..6d2383009 100644 --- a/third_party/libcxx/__algorithm/pop_heap.h +++ b/third_party/libcxx/__algorithm/pop_heap.h @@ -17,27 +17,33 @@ #include <__assert> #include <__config> #include <__iterator/iterator_traits.h> -#include <__type_traits/is_copy_assignable.h> -#include <__type_traits/is_copy_constructible.h> +#include <__type_traits/is_assignable.h> +#include <__type_traits/is_constructible.h> #include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp, - typename iterator_traits<_RandomAccessIterator>::difference_type __len) { - _LIBCPP_ASSERT(__len > 0, "The heap given to pop_heap must be non-empty"); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void +__pop_heap(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Compare& __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len) { + // Calling `pop_heap` on an empty range is undefined behavior, but in practice it will be a no-op. + _LIBCPP_ASSERT_PEDANTIC(__len > 0, "The heap given to pop_heap must be non-empty"); __comp_ref_type<_Compare> __comp_ref = __comp; using value_type = typename iterator_traits<_RandomAccessIterator>::value_type; if (__len > 1) { - value_type __top = _IterOps<_AlgPolicy>::__iter_move(__first); // create a hole at __first + value_type __top = _IterOps<_AlgPolicy>::__iter_move(__first); // create a hole at __first _RandomAccessIterator __hole = std::__floyd_sift_down<_AlgPolicy>(__first, __comp_ref, __len); --__last; @@ -53,8 +59,8 @@ void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Co } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible."); static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable."); @@ -63,12 +69,13 @@ void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { - std::pop_heap(std::move(__first), std::move(__last), - __less::value_type>()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { + std::pop_heap(std::move(__first), std::move(__last), __less<>()); } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_POP_HEAP_H diff --git a/third_party/libcxx/__algorithm/prev_permutation.h b/third_party/libcxx/__algorithm/prev_permutation.h index 0b86ab74e..8d15b6806 100644 --- a/third_party/libcxx/__algorithm/prev_permutation.h +++ b/third_party/libcxx/__algorithm/prev_permutation.h @@ -22,58 +22,54 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -pair<_BidirectionalIterator, bool> -__prev_permutation(_BidirectionalIterator __first, _Sentinel __last, _Compare&& __comp) -{ - using _Result = pair<_BidirectionalIterator, bool>; +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator, bool> +__prev_permutation(_BidirectionalIterator __first, _Sentinel __last, _Compare&& __comp) { + using _Result = pair<_BidirectionalIterator, bool>; - _BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::next(__first, __last); - _BidirectionalIterator __i = __last_iter; - if (__first == __last || __first == --__i) - return _Result(std::move(__last_iter), false); + _BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::next(__first, __last); + _BidirectionalIterator __i = __last_iter; + if (__first == __last || __first == --__i) + return _Result(std::move(__last_iter), false); - while (true) - { - _BidirectionalIterator __ip1 = __i; - if (__comp(*__ip1, *--__i)) - { - _BidirectionalIterator __j = __last_iter; - while (!__comp(*--__j, *__i)) - ; - _IterOps<_AlgPolicy>::iter_swap(__i, __j); - std::__reverse<_AlgPolicy>(__ip1, __last_iter); - return _Result(std::move(__last_iter), true); - } - if (__i == __first) - { - std::__reverse<_AlgPolicy>(__first, __last_iter); - return _Result(std::move(__last_iter), false); - } + while (true) { + _BidirectionalIterator __ip1 = __i; + if (__comp(*__ip1, *--__i)) { + _BidirectionalIterator __j = __last_iter; + while (!__comp(*--__j, *__i)) + ; + _IterOps<_AlgPolicy>::iter_swap(__i, __j); + std::__reverse<_AlgPolicy>(__ip1, __last_iter); + return _Result(std::move(__last_iter), true); } + if (__i == __first) { + std::__reverse<_AlgPolicy>(__first, __last_iter); + return _Result(std::move(__last_iter), false); + } + } } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -bool -prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) -{ +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) { return std::__prev_permutation<_ClassicAlgPolicy>( - std::move(__first), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp)).second; + std::move(__first), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp)) + .second; } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -bool -prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) -{ - return _VSTD::prev_permutation(__first, __last, - __less::value_type>()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) { + return std::prev_permutation(__first, __last, __less<>()); } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_PREV_PERMUTATION_H diff --git a/third_party/libcxx/__algorithm/pstl.h b/third_party/libcxx/__algorithm/pstl.h new file mode 100644 index 000000000..0bb052b3f --- /dev/null +++ b/third_party/libcxx/__algorithm/pstl.h @@ -0,0 +1,663 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_PSTL_H +#define _LIBCPP___ALGORITHM_PSTL_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 + +# include <__functional/operations.h> +# include <__iterator/cpp17_iterator_concepts.h> +# include <__iterator/iterator_traits.h> +# include <__pstl/backend.h> +# include <__pstl/dispatch.h> +# include <__pstl/handle_exception.h> +# include <__type_traits/enable_if.h> +# include <__type_traits/is_execution_policy.h> +# include <__type_traits/remove_cvref.h> +# include <__utility/forward.h> +# include <__utility/move.h> + +_LIBCPP_BEGIN_NAMESPACE_STD + +template , + enable_if_t, int> = 0> +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool +any_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "any_of requires a ForwardIterator"); + using _Implementation = __pstl::__dispatch<__pstl::__any_of, __pstl::__current_configuration, _RawPolicy>; + return __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred)); +} + +template , + enable_if_t, int> = 0> +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool +all_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "all_of requires a ForwardIterator"); + using _Implementation = __pstl::__dispatch<__pstl::__all_of, __pstl::__current_configuration, _RawPolicy>; + return __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred)); +} + +template , + enable_if_t, int> = 0> +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool +none_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "none_of requires a ForwardIterator"); + using _Implementation = __pstl::__dispatch<__pstl::__none_of, __pstl::__current_configuration, _RawPolicy>; + return __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred)); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator +copy(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __result) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR( + _ForwardIterator, "copy(first, last, result) requires [first, last) to be ForwardIterators"); + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR( + _ForwardOutIterator, "copy(first, last, result) requires result to be a ForwardIterator"); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR( + _ForwardOutIterator, decltype(*__first), "copy(first, last, result) requires result to be an OutputIterator"); + using _Implementation = __pstl::__dispatch<__pstl::__copy, __pstl::__current_configuration, _RawPolicy>; + return __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__result)); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator +copy_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, _ForwardOutIterator __result) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR( + _ForwardIterator, "copy_n(first, n, result) requires first to be a ForwardIterator"); + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR( + _ForwardOutIterator, "copy_n(first, n, result) requires result to be a ForwardIterator"); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR( + _ForwardOutIterator, decltype(*__first), "copy_n(first, n, result) requires result to be an OutputIterator"); + using _Implementation = __pstl::__dispatch<__pstl::__copy_n, __pstl::__current_configuration, _RawPolicy>; + return __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__n), std::move(__result)); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_HIDE_FROM_ABI __iter_diff_t<_ForwardIterator> +count_if(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR( + _ForwardIterator, "count_if(first, last, pred) requires [first, last) to be ForwardIterators"); + using _Implementation = __pstl::__dispatch<__pstl::__count_if, __pstl::__current_configuration, _RawPolicy>; + return __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred)); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_HIDE_FROM_ABI __iter_diff_t<_ForwardIterator> +count(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR( + _ForwardIterator, "count(first, last, val) requires [first, last) to be ForwardIterators"); + using _Implementation = __pstl::__dispatch<__pstl::__count, __pstl::__current_configuration, _RawPolicy>; + return __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), __value); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_HIDE_FROM_ABI bool +equal(_ExecutionPolicy&& __policy, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _Pred __pred) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "equal requires ForwardIterators"); + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "equal requires ForwardIterators"); + using _Implementation = __pstl::__dispatch<__pstl::__equal_3leg, __pstl::__current_configuration, _RawPolicy>; + return __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__pred)); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_HIDE_FROM_ABI bool +equal(_ExecutionPolicy&& __policy, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "equal requires ForwardIterators"); + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "equal requires ForwardIterators"); + using _Implementation = __pstl::__dispatch<__pstl::__equal_3leg, __pstl::__current_configuration, _RawPolicy>; + return __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), + std::move(__first1), + std::move(__last1), + std::move(__first2), + equal_to{}); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_HIDE_FROM_ABI bool +equal(_ExecutionPolicy&& __policy, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _Pred __pred) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "equal requires ForwardIterators"); + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "equal requires ForwardIterators"); + using _Implementation = __pstl::__dispatch<__pstl::__equal, __pstl::__current_configuration, _RawPolicy>; + return __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + std::move(__pred)); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_HIDE_FROM_ABI bool +equal(_ExecutionPolicy&& __policy, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "equal requires ForwardIterators"); + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "equal requires ForwardIterators"); + using _Implementation = __pstl::__dispatch<__pstl::__equal, __pstl::__current_configuration, _RawPolicy>; + return __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + equal_to{}); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_HIDE_FROM_ABI void +fill(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "fill requires ForwardIterators"); + using _Implementation = __pstl::__dispatch<__pstl::__fill, __pstl::__current_configuration, _RawPolicy>; + __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), __value); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_HIDE_FROM_ABI void +fill_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, const _Tp& __value) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "fill_n requires a ForwardIterator"); + using _Implementation = __pstl::__dispatch<__pstl::__fill_n, __pstl::__current_configuration, _RawPolicy>; + __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__n), __value); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_HIDE_FROM_ABI _ForwardIterator +find_if(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "find_if requires ForwardIterators"); + using _Implementation = __pstl::__dispatch<__pstl::__find_if, __pstl::__current_configuration, _RawPolicy>; + return __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred)); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_HIDE_FROM_ABI _ForwardIterator +find_if_not(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "find_if_not requires ForwardIterators"); + using _Implementation = __pstl::__dispatch<__pstl::__find_if_not, __pstl::__current_configuration, _RawPolicy>; + return __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred)); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_HIDE_FROM_ABI _ForwardIterator +find(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "find requires ForwardIterators"); + using _Implementation = __pstl::__dispatch<__pstl::__find, __pstl::__current_configuration, _RawPolicy>; + return __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), __value); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_HIDE_FROM_ABI void +for_each(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Function __func) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "for_each requires ForwardIterators"); + using _Implementation = __pstl::__dispatch<__pstl::__for_each, __pstl::__current_configuration, _RawPolicy>; + __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__func)); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_HIDE_FROM_ABI void +for_each_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __size, _Function __func) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "for_each_n requires a ForwardIterator"); + using _Implementation = __pstl::__dispatch<__pstl::__for_each_n, __pstl::__current_configuration, _RawPolicy>; + __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__size), std::move(__func)); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_HIDE_FROM_ABI void +generate(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Generator __gen) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "generate requires ForwardIterators"); + using _Implementation = __pstl::__dispatch<__pstl::__generate, __pstl::__current_configuration, _RawPolicy>; + __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__gen)); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_HIDE_FROM_ABI void +generate_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, _Generator __gen) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "generate_n requires a ForwardIterator"); + using _Implementation = __pstl::__dispatch<__pstl::__generate_n, __pstl::__current_configuration, _RawPolicy>; + __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__n), std::move(__gen)); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI bool +is_partitioned(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "is_partitioned requires ForwardIterators"); + using _Implementation = __pstl::__dispatch<__pstl::__is_partitioned, __pstl::__current_configuration, _RawPolicy>; + return __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred)); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator +merge(_ExecutionPolicy&& __policy, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _ForwardOutIterator __result, + _Comp __comp) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "merge requires ForwardIterators"); + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "merge requires ForwardIterators"); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first1), "merge requires an OutputIterator"); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first2), "merge requires an OutputIterator"); + using _Implementation = __pstl::__dispatch<__pstl::__merge, __pstl::__current_configuration, _RawPolicy>; + return __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + std::move(__result), + std::move(__comp)); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator +merge(_ExecutionPolicy&& __policy, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _ForwardOutIterator __result) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "merge requires ForwardIterators"); + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "merge requires ForwardIterators"); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first1), "merge requires an OutputIterator"); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, decltype(*__first2), "merge requires an OutputIterator"); + using _Implementation = __pstl::__dispatch<__pstl::__merge, __pstl::__current_configuration, _RawPolicy>; + return __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + std::move(__result), + less{}); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator +move(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __result) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "move requires ForwardIterators"); + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator, "move requires an OutputIterator"); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR( + _ForwardOutIterator, decltype(std::move(*__first)), "move requires an OutputIterator"); + using _Implementation = __pstl::__dispatch<__pstl::__move, __pstl::__current_configuration, _RawPolicy>; + return __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__result)); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_HIDE_FROM_ABI void +replace_if(_ExecutionPolicy&& __policy, + _ForwardIterator __first, + _ForwardIterator __last, + _Pred __pred, + const _Tp& __new_value) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "replace_if requires ForwardIterators"); + using _Implementation = __pstl::__dispatch<__pstl::__replace_if, __pstl::__current_configuration, _RawPolicy>; + __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__pred), __new_value); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_HIDE_FROM_ABI void +replace(_ExecutionPolicy&& __policy, + _ForwardIterator __first, + _ForwardIterator __last, + const _Tp& __old_value, + const _Tp& __new_value) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "replace requires ForwardIterators"); + using _Implementation = __pstl::__dispatch<__pstl::__replace, __pstl::__current_configuration, _RawPolicy>; + __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), __old_value, __new_value); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_HIDE_FROM_ABI void replace_copy_if( + _ExecutionPolicy&& __policy, + _ForwardIterator __first, + _ForwardIterator __last, + _ForwardOutIterator __result, + _Pred __pred, + const _Tp& __new_value) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "replace_copy_if requires ForwardIterators"); + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator, "replace_copy_if requires ForwardIterators"); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR( + _ForwardOutIterator, decltype(*__first), "replace_copy_if requires an OutputIterator"); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, const _Tp&, "replace_copy requires an OutputIterator"); + using _Implementation = __pstl::__dispatch<__pstl::__replace_copy_if, __pstl::__current_configuration, _RawPolicy>; + __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), + std::move(__first), + std::move(__last), + std::move(__result), + std::move(__pred), + __new_value); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_HIDE_FROM_ABI void replace_copy( + _ExecutionPolicy&& __policy, + _ForwardIterator __first, + _ForwardIterator __last, + _ForwardOutIterator __result, + const _Tp& __old_value, + const _Tp& __new_value) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "replace_copy requires ForwardIterators"); + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator, "replace_copy requires ForwardIterators"); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR( + _ForwardOutIterator, decltype(*__first), "replace_copy requires an OutputIterator"); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(_ForwardOutIterator, const _Tp&, "replace_copy requires an OutputIterator"); + using _Implementation = __pstl::__dispatch<__pstl::__replace_copy, __pstl::__current_configuration, _RawPolicy>; + __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), + std::move(__first), + std::move(__last), + std::move(__result), + __old_value, + __new_value); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator rotate_copy( + _ExecutionPolicy&& __policy, + _ForwardIterator __first, + _ForwardIterator __middle, + _ForwardIterator __last, + _ForwardOutIterator __result) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "rotate_copy requires ForwardIterators"); + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator, "rotate_copy requires ForwardIterators"); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR( + _ForwardOutIterator, decltype(*__first), "rotate_copy requires an OutputIterator"); + using _Implementation = __pstl::__dispatch<__pstl::__rotate_copy, __pstl::__current_configuration, _RawPolicy>; + return __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), + std::move(__first), + std::move(__middle), + std::move(__last), + std::move(__result)); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_HIDE_FROM_ABI void +sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) { + _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator, "sort requires RandomAccessIterators"); + using _Implementation = __pstl::__dispatch<__pstl::__sort, __pstl::__current_configuration, _RawPolicy>; + __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__comp)); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_HIDE_FROM_ABI void +sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last) { + _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator, "sort requires RandomAccessIterators"); + using _Implementation = __pstl::__dispatch<__pstl::__sort, __pstl::__current_configuration, _RawPolicy>; + __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), less{}); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_HIDE_FROM_ABI void +stable_sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) { + _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator, "stable_sort requires RandomAccessIterators"); + using _Implementation = __pstl::__dispatch<__pstl::__stable_sort, __pstl::__current_configuration, _RawPolicy>; + __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__comp)); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_HIDE_FROM_ABI void +stable_sort(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last) { + _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator, "stable_sort requires RandomAccessIterators"); + using _Implementation = __pstl::__dispatch<__pstl::__stable_sort, __pstl::__current_configuration, _RawPolicy>; + __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), less{}); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator transform( + _ExecutionPolicy&& __policy, + _ForwardIterator __first, + _ForwardIterator __last, + _ForwardOutIterator __result, + _UnaryOperation __op) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "transform requires ForwardIterators"); + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator, "transform requires an OutputIterator"); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR( + _ForwardOutIterator, decltype(__op(*__first)), "transform requires an OutputIterator"); + using _Implementation = __pstl::__dispatch<__pstl::__transform, __pstl::__current_configuration, _RawPolicy>; + return __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), + std::move(__first), + std::move(__last), + std::move(__result), + std::move(__op)); +} + +template , + enable_if_t, int> = 0> +_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator transform( + _ExecutionPolicy&& __policy, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardOutIterator __result, + _BinaryOperation __op) { + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator1, "transform requires ForwardIterators"); + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator2, "transform requires ForwardIterators"); + _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardOutIterator, "transform requires an OutputIterator"); + _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR( + _ForwardOutIterator, decltype(__op(*__first1, *__first2)), "transform requires an OutputIterator"); + using _Implementation = __pstl::__dispatch<__pstl::__transform_binary, __pstl::__current_configuration, _RawPolicy>; + return __pstl::__handle_exception<_Implementation>( + std::forward<_ExecutionPolicy>(__policy), + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__result), + std::move(__op)); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___ALGORITHM_PSTL_H diff --git a/third_party/libcxx/__algorithm/pstl_any_all_none_of.h b/third_party/libcxx/__algorithm/pstl_any_all_none_of.h deleted file mode 100644 index 374d9af17..000000000 --- a/third_party/libcxx/__algorithm/pstl_any_all_none_of.h +++ /dev/null @@ -1,95 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP___ALGORITHM_PSTL_ANY_ALL_NONE_OF_H -#define _LIBCPP___ALGORITHM_PSTL_ANY_ALL_NONE_OF_H - -#include <__algorithm/pstl_find.h> -#include <__algorithm/pstl_frontend_dispatch.h> -#include <__config> -#include <__iterator/iterator_traits.h> -#include <__type_traits/enable_if.h> -#include <__type_traits/is_execution_policy.h> -#include <__type_traits/remove_cvref.h> -#include <__utility/terminate_on_exception.h> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 - -_LIBCPP_BEGIN_NAMESPACE_STD - -template -void __pstl_any_of(); // declaration needed for the frontend dispatch below - -template , - enable_if_t, int> = 0> -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool -any_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { - return std::__pstl_frontend_dispatch( - _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_any_of), - [&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Predicate __g_pred) { - return std::find_if(__policy, __g_first, __g_last, __g_pred) != __g_last; - }, - std::move(__first), - std::move(__last), - std::move(__pred)); -} - -template -void __pstl_all_of(); // declaration needed for the frontend dispatch below - -template , - enable_if_t, int> = 0> -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool -all_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) { - return std::__pstl_frontend_dispatch( - _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_all_of), - [&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Pred __g_pred) { - return !std::any_of(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __value) { - return !__g_pred(__value); - }); - }, - std::move(__first), - std::move(__last), - std::move(__pred)); -} - -template -void __pstl_none_of(); // declaration needed for the frontend dispatch below - -template , - enable_if_t, int> = 0> -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI bool -none_of(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) { - return std::__pstl_frontend_dispatch( - _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_none_of), - [&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Pred __g_pred) { - return !std::any_of(__policy, __g_first, __g_last, __g_pred); - }, - std::move(__first), - std::move(__last), - std::move(__pred)); -} - -_LIBCPP_END_NAMESPACE_STD - -#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 - -#endif // _LIBCPP___ALGORITHM_PSTL_ANY_ALL_NONE_OF_H diff --git a/third_party/libcxx/__algorithm/pstl_backend.h b/third_party/libcxx/__algorithm/pstl_backend.h deleted file mode 100644 index ae37e56a7..000000000 --- a/third_party/libcxx/__algorithm/pstl_backend.h +++ /dev/null @@ -1,125 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP___ALGORITHM_PSTL_BACKEND_H -#define _LIBCPP___ALGORITHM_PSTL_BACKEND_H - -#include <__algorithm/pstl_backends/cpu_backend.h> -#include <__config> -#include - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 - -_LIBCPP_BEGIN_NAMESPACE_STD - -/* -TODO: Documentation of how backends work - -A PSTL parallel backend is a tag type to which the following functions are associated, at minimum: - - template - void __pstl_for_each(_Backend, _ExecutionPolicy&&, _Iterator __first, _Iterator __last, _Func __f); - - template - _Iterator __pstl_find_if(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred); - - template - _OutIterator __pstl_transform(_InIterator __first, _InIterator __last, _OutIterator __result, _UnaryOperation __op); - - template - _OutIterator __pstl_transform(_InIterator1 __first1, - _InIterator1 __last1, - _InIterator2 __first2, - _OutIterator __result, - _BinaryOperation __op); - -// TODO: Complete this list - -The following functions are optional but can be provided. If provided, they are used by the corresponding -algorithms, otherwise they are implemented in terms of other algorithms. If none of the optional algorithms are -implemented, all the algorithms will eventually forward to the basis algorithms listed above: - - template - void __pstl_for_each_n(_Backend, _Iterator __first, _Size __n, _Func __f); - - template - bool __pstl_any_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred); - - template - bool __pstl_all_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred); - - template - bool __pstl_none_of(_Backend, _Iterator __first, _iterator __last, _Predicate __pred); - - template - _Iterator __pstl_find(_Backend, _Iterator __first, _Iterator __last, const _Tp& __value); - - template - _Iterator __pstl_find_if_not(_Backend, _Iterator __first, _Iterator __last, _Predicate __pred); - - template - void __pstl_fill(_Backend, _Iterator __first, _Iterator __last, const _Tp& __value); - - template - void __pstl_fill_n(_Backend, _Iterator __first, _SizeT __n, const _Tp& __value); - - template - _OutIterator __pstl_merge(_Backend, - _Iterator1 __first1, - _Iterator1 __last1, - _Iterator2 __first2, - _Iterator2 __last2, - _OutIterator __result, - _Comp __comp); - -// TODO: Complete this list - -*/ - -template -struct __select_backend; - -template <> -struct __select_backend { - using type = __cpu_backend_tag; -}; - -# if _LIBCPP_STD_VER >= 20 -template <> -struct __select_backend { - using type = __cpu_backend_tag; -}; -# endif - -# if defined(_LIBCPP_PSTL_CPU_BACKEND_SERIAL) || defined(_LIBCPP_PSTL_CPU_BACKEND_THREAD) -template <> -struct __select_backend { - using type = __cpu_backend_tag; -}; - -template <> -struct __select_backend { - using type = __cpu_backend_tag; -}; - -# else - -// ...New vendors can add parallel backends here... - -# error "Invalid choice of a PSTL parallel backend" -# endif - -_LIBCPP_END_NAMESPACE_STD - -#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 - -#endif // _LIBCPP___ALGORITHM_PSTL_BACKEND_H diff --git a/third_party/libcxx/__algorithm/pstl_backends/cpu_backend.h b/third_party/libcxx/__algorithm/pstl_backends/cpu_backend.h deleted file mode 100644 index 3939b8211..000000000 --- a/third_party/libcxx/__algorithm/pstl_backends/cpu_backend.h +++ /dev/null @@ -1,47 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_H -#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_H - -#include <__config> - -/* - - // _Functor takes a subrange for [__first, __last) that should be executed in serial - template - void __parallel_for(_RandomAccessIterator __first, _RandomAccessIterator __last, _Functor __func); - - // Cancel the execution of other jobs - they aren't needed anymore - void __cancel_execution(); - - template - void __parallel_merge( - _RandomAccessIterator1 __first1, - _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, - _RandomAccessIterator2 __last2, - _RandomAccessIterator3 __outit, - _Compare __comp, - _LeafMerge __leaf_merge); - - TODO: Document the parallel backend -*/ - -#include <__algorithm/pstl_backends/cpu_backends/any_of.h> -#include <__algorithm/pstl_backends/cpu_backends/fill.h> -#include <__algorithm/pstl_backends/cpu_backends/find_if.h> -#include <__algorithm/pstl_backends/cpu_backends/for_each.h> -#include <__algorithm/pstl_backends/cpu_backends/merge.h> -#include <__algorithm/pstl_backends/cpu_backends/transform.h> - -#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_H diff --git a/third_party/libcxx/__algorithm/pstl_backends/cpu_backends/any_of.h b/third_party/libcxx/__algorithm/pstl_backends/cpu_backends/any_of.h deleted file mode 100644 index 8fe26797b..000000000 --- a/third_party/libcxx/__algorithm/pstl_backends/cpu_backends/any_of.h +++ /dev/null @@ -1,90 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_ANY_OF_H -#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_ANY_OF_H - -#include <__algorithm/any_of.h> -#include <__algorithm/find_if.h> -#include <__algorithm/pstl_backends/cpu_backends/backend.h> -#include <__atomic/atomic.h> -#include <__atomic/memory_order.h> -#include <__config> -#include <__functional/operations.h> -#include <__iterator/iterator_traits.h> -#include <__type_traits/is_execution_policy.h> -#include <__utility/pair.h> -#include <__utility/terminate_on_exception.h> -#include - -#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 - -_LIBCPP_BEGIN_NAMESPACE_STD - -template -_LIBCPP_HIDE_FROM_ABI bool __parallel_or(_Index __first, _Index __last, _Brick __f) { - std::atomic __found(false); - __par_backend::__parallel_for(__first, __last, [__f, &__found](_Index __i, _Index __j) { - if (!__found.load(std::memory_order_relaxed) && __f(__i, __j)) { - __found.store(true, std::memory_order_relaxed); - __par_backend::__cancel_execution(); - } - }); - return __found; -} - -// TODO: check whether __simd_first() can be used here -template -_LIBCPP_HIDE_FROM_ABI bool __simd_or(_Index __first, _DifferenceType __n, _Pred __pred) noexcept { - _DifferenceType __block_size = 4 < __n ? 4 : __n; - const _Index __last = __first + __n; - while (__last != __first) { - int32_t __flag = 1; - _PSTL_PRAGMA_SIMD_REDUCTION(& : __flag) - for (_DifferenceType __i = 0; __i < __block_size; ++__i) - if (__pred(*(__first + __i))) - __flag = 0; - if (!__flag) - return true; - - __first += __block_size; - if (__last - __first >= __block_size << 1) { - // Double the block _Size. Any unnecessary iterations can be amortized against work done so far. - __block_size <<= 1; - } else { - __block_size = __last - __first; - } - } - return false; -} - -template -_LIBCPP_HIDE_FROM_ABI bool -__pstl_any_of(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { - if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> && - __has_random_access_iterator_category<_ForwardIterator>::value) { - return std::__terminate_on_exception([&] { - return std::__parallel_or( - __first, __last, [&__pred](_ForwardIterator __brick_first, _ForwardIterator __brick_last) { - return std::__pstl_any_of<__remove_parallel_policy_t<_ExecutionPolicy>>( - __cpu_backend_tag{}, __brick_first, __brick_last, __pred); - }); - }); - } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> && - __has_random_access_iterator_category<_ForwardIterator>::value) { - return std::__simd_or(__first, __last - __first, __pred); - } else { - return std::any_of(__first, __last, __pred); - } -} - -_LIBCPP_END_NAMESPACE_STD - -#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 - -#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKEND_ANY_OF_H diff --git a/third_party/libcxx/__algorithm/pstl_backends/cpu_backends/fill.h b/third_party/libcxx/__algorithm/pstl_backends/cpu_backends/fill.h deleted file mode 100644 index 5e5e0a23b..000000000 --- a/third_party/libcxx/__algorithm/pstl_backends/cpu_backends/fill.h +++ /dev/null @@ -1,60 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FILL_H -#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FILL_H - -#include <__algorithm/fill.h> -#include <__algorithm/pstl_backends/cpu_backends/backend.h> -#include <__config> -#include <__iterator/iterator_traits.h> -#include <__type_traits/is_execution_policy.h> -#include <__utility/terminate_on_exception.h> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 - -_LIBCPP_BEGIN_NAMESPACE_STD - -template -_LIBCPP_HIDE_FROM_ABI _Index __simd_fill_n(_Index __first, _DifferenceType __n, const _Tp& __value) noexcept { - _PSTL_USE_NONTEMPORAL_STORES_IF_ALLOWED - _PSTL_PRAGMA_SIMD - for (_DifferenceType __i = 0; __i < __n; ++__i) - __first[__i] = __value; - return __first + __n; -} - -template -_LIBCPP_HIDE_FROM_ABI void -__pstl_fill(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { - if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> && - __has_random_access_iterator_category<_ForwardIterator>::value) { - std::__terminate_on_exception([&] { - __par_backend::__parallel_for( - __first, __last, [&__value](_ForwardIterator __brick_first, _ForwardIterator __brick_last) { - std::__pstl_fill<__remove_parallel_policy_t<_ExecutionPolicy>>( - __cpu_backend_tag{}, __brick_first, __brick_last, __value); - }); - }); - } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> && - __has_random_access_iterator_category<_ForwardIterator>::value) { - std::__simd_fill_n(__first, __last - __first, __value); - } else { - std::fill(__first, __last, __value); - } -} - -_LIBCPP_END_NAMESPACE_STD - -#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 - -#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FILL_H diff --git a/third_party/libcxx/__algorithm/pstl_backends/cpu_backends/find_if.h b/third_party/libcxx/__algorithm/pstl_backends/cpu_backends/find_if.h deleted file mode 100644 index 72059a48b..000000000 --- a/third_party/libcxx/__algorithm/pstl_backends/cpu_backends/find_if.h +++ /dev/null @@ -1,125 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FIND_IF_H -#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FIND_IF_H - -#include <__algorithm/find_if.h> -#include <__algorithm/pstl_backends/cpu_backends/backend.h> -#include <__atomic/atomic.h> -#include <__config> -#include <__functional/operations.h> -#include <__iterator/iterator_traits.h> -#include <__type_traits/is_execution_policy.h> -#include <__utility/pair.h> -#include <__utility/terminate_on_exception.h> -#include - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 - -_LIBCPP_BEGIN_NAMESPACE_STD - -template -_LIBCPP_HIDE_FROM_ABI _Index -__parallel_find(_Index __first, _Index __last, _Brick __f, _Compare __comp, bool __b_first) { - typedef typename std::iterator_traits<_Index>::difference_type _DifferenceType; - const _DifferenceType __n = __last - __first; - _DifferenceType __initial_dist = __b_first ? __n : -1; - std::atomic<_DifferenceType> __extremum(__initial_dist); - // TODO: find out what is better here: parallel_for or parallel_reduce - __par_backend::__parallel_for(__first, __last, [__comp, __f, __first, &__extremum](_Index __i, _Index __j) { - // See "Reducing Contention Through Priority Updates", PPoPP '13, for discussion of - // why using a shared variable scales fairly well in this situation. - if (__comp(__i - __first, __extremum)) { - _Index __res = __f(__i, __j); - // If not '__last' returned then we found what we want so put this to extremum - if (__res != __j) { - const _DifferenceType __k = __res - __first; - for (_DifferenceType __old = __extremum; __comp(__k, __old); __old = __extremum) { - __extremum.compare_exchange_weak(__old, __k); - } - } - } - }); - return __extremum != __initial_dist ? __first + __extremum : __last; -} - -const std::size_t __lane_size = 64; - -template -_LIBCPP_HIDE_FROM_ABI _Index -__simd_first(_Index __first, _DifferenceType __begin, _DifferenceType __end, _Compare __comp) noexcept { - // Experiments show good block sizes like this - const _DifferenceType __block_size = 8; - alignas(__lane_size) _DifferenceType __lane[__block_size] = {0}; - while (__end - __begin >= __block_size) { - _DifferenceType __found = 0; - _PSTL_PRAGMA_SIMD_REDUCTION(| : __found) for (_DifferenceType __i = __begin; __i < __begin + __block_size; ++__i) { - const _DifferenceType __t = __comp(__first, __i); - __lane[__i - __begin] = __t; - __found |= __t; - } - if (__found) { - _DifferenceType __i; - // This will vectorize - for (__i = 0; __i < __block_size; ++__i) { - if (__lane[__i]) { - break; - } - } - return __first + __begin + __i; - } - __begin += __block_size; - } - - // Keep remainder scalar - while (__begin != __end) { - if (__comp(__first, __begin)) { - return __first + __begin; - } - ++__begin; - } - return __first + __end; -} - -template -_LIBCPP_HIDE_FROM_ABI _ForwardIterator -__pstl_find_if(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { - if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> && - __has_random_access_iterator_category<_ForwardIterator>::value) { - return std::__terminate_on_exception([&] { - return std::__parallel_find( - __first, - __last, - [&__pred](_ForwardIterator __brick_first, _ForwardIterator __brick_last) { - return std::__pstl_find_if<__remove_parallel_policy_t<_ExecutionPolicy>>( - __cpu_backend_tag{}, __brick_first, __brick_last, __pred); - }, - less<>{}, - true); - }); - } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> && - __has_random_access_iterator_category<_ForwardIterator>::value) { - using __diff_t = __iter_diff_t<_ForwardIterator>; - return std::__simd_first(__first, __diff_t(0), __last - __first, [&__pred](_ForwardIterator __iter, __diff_t __i) { - return __pred(__iter[__i]); - }); - } else { - return std::find_if(__first, __last, __pred); - } -} - -_LIBCPP_END_NAMESPACE_STD - -#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 - -#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_FIND_IF_H diff --git a/third_party/libcxx/__algorithm/pstl_backends/cpu_backends/for_each.h b/third_party/libcxx/__algorithm/pstl_backends/cpu_backends/for_each.h deleted file mode 100644 index 36d0ac238..000000000 --- a/third_party/libcxx/__algorithm/pstl_backends/cpu_backends/for_each.h +++ /dev/null @@ -1,60 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKNEDS_FOR_EACH_H -#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKNEDS_FOR_EACH_H - -#include <__algorithm/for_each.h> -#include <__algorithm/pstl_backends/cpu_backends/backend.h> -#include <__config> -#include <__iterator/iterator_traits.h> -#include <__type_traits/is_execution_policy.h> -#include <__utility/terminate_on_exception.h> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 - -_LIBCPP_BEGIN_NAMESPACE_STD - -template -_LIBCPP_HIDE_FROM_ABI _Iterator __simd_walk_1(_Iterator __first, _DifferenceType __n, _Function __f) noexcept { - _PSTL_PRAGMA_SIMD - for (_DifferenceType __i = 0; __i < __n; ++__i) - __f(__first[__i]); - - return __first + __n; -} - -template -_LIBCPP_HIDE_FROM_ABI void -__pstl_for_each(__cpu_backend_tag, _ForwardIterator __first, _ForwardIterator __last, _Functor __func) { - if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> && - __has_random_access_iterator_category<_ForwardIterator>::value) { - std::__terminate_on_exception([&] { - std::__par_backend::__parallel_for( - __first, __last, [__func](_ForwardIterator __brick_first, _ForwardIterator __brick_last) { - std::__pstl_for_each<__remove_parallel_policy_t<_ExecutionPolicy>>( - __cpu_backend_tag{}, __brick_first, __brick_last, __func); - }); - }); - } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> && - __has_random_access_iterator_category<_ForwardIterator>::value) { - std::__simd_walk_1(__first, __last - __first, __func); - } else { - std::for_each(__first, __last, __func); - } -} - -_LIBCPP_END_NAMESPACE_STD - -#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 - -#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKNEDS_FOR_EACH_H diff --git a/third_party/libcxx/__algorithm/pstl_backends/cpu_backends/merge.h b/third_party/libcxx/__algorithm/pstl_backends/cpu_backends/merge.h deleted file mode 100644 index d5be1e302..000000000 --- a/third_party/libcxx/__algorithm/pstl_backends/cpu_backends/merge.h +++ /dev/null @@ -1,79 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_MERGE_H -#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_MERGE_H - -#include <__algorithm/merge.h> -#include <__algorithm/pstl_backends/cpu_backends/backend.h> -#include <__config> -#include <__iterator/iterator_traits.h> -#include <__type_traits/is_execution_policy.h> -#include <__utility/move.h> -#include <__utility/terminate_on_exception.h> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 - -_LIBCPP_BEGIN_NAMESPACE_STD - -template -_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator __pstl_merge( - __cpu_backend_tag, - _ForwardIterator1 __first1, - _ForwardIterator1 __last1, - _ForwardIterator2 __first2, - _ForwardIterator2 __last2, - _ForwardOutIterator __result, - _Comp __comp) { - if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> && - __has_random_access_iterator_category<_ForwardIterator1>::value && - __has_random_access_iterator_category<_ForwardIterator2>::value && - __has_random_access_iterator_category<_ForwardOutIterator>::value) { - return std::__terminate_on_exception([&] { - __par_backend::__parallel_merge( - __first1, - __last1, - __first2, - __last2, - __result, - __comp, - [](_ForwardIterator1 __g_first1, - _ForwardIterator1 __g_last1, - _ForwardIterator2 __g_first2, - _ForwardIterator2 __g_last2, - _ForwardOutIterator __g_result, - _Comp __g_comp) { - return std::__pstl_merge<__remove_parallel_policy_t<_ExecutionPolicy>>( - __cpu_backend_tag{}, - std::move(__g_first1), - std::move(__g_last1), - std::move(__g_first2), - std::move(__g_last2), - std::move(__g_result), - std::move(__g_comp)); - }); - return __result + (__last1 - __first1) + (__last2 - __first2); - }); - } else { - return std::merge(__first1, __last1, __first2, __last2, __result, __comp); - } -} - -_LIBCPP_END_NAMESPACE_STD - -#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 - -#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_MERGE_H diff --git a/third_party/libcxx/__algorithm/pstl_backends/cpu_backends/serial.h b/third_party/libcxx/__algorithm/pstl_backends/cpu_backends/serial.h deleted file mode 100644 index 0c3aafae6..000000000 --- a/third_party/libcxx/__algorithm/pstl_backends/cpu_backends/serial.h +++ /dev/null @@ -1,58 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_SERIAL_H -#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_SERIAL_H - -#include <__config> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 - -_LIBCPP_BEGIN_NAMESPACE_STD - -namespace __par_backend { -inline namespace __serial_cpu_backend { - -template -_LIBCPP_HIDE_FROM_ABI void __parallel_for(_RandomAccessIterator __first, _RandomAccessIterator __last, _Fp __f) { - __f(__first, __last); -} - -_LIBCPP_HIDE_FROM_ABI inline void __cancel_execution() {} - -template -_LIBCPP_HIDE_FROM_ABI void __parallel_merge( - _RandomAccessIterator1 __first1, - _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, - _RandomAccessIterator2 __last2, - _RandomAccessIterator3 __outit, - _Compare __comp, - _LeafMerge __leaf_merge) { - __leaf_merge(__first1, __last1, __first2, __last2, __outit, __comp); -} - -// TODO: Complete this list - -} // namespace __serial_cpu_backend -} // namespace __par_backend - -_LIBCPP_END_NAMESPACE_STD - -#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && && _LIBCPP_STD_VER >= 17 - -#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_SERIAL_H diff --git a/third_party/libcxx/__algorithm/pstl_backends/cpu_backends/thread.h b/third_party/libcxx/__algorithm/pstl_backends/cpu_backends/thread.h deleted file mode 100644 index 93745d306..000000000 --- a/third_party/libcxx/__algorithm/pstl_backends/cpu_backends/thread.h +++ /dev/null @@ -1,59 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_THREAD_H -#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_THREAD_H - -#include <__assert> -#include <__config> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 - -// This backend implementation is for testing purposes only and not meant for production use. This will be replaced -// by a proper implementation once the PSTL implementation is somewhat stable. - -_LIBCPP_BEGIN_NAMESPACE_STD - -namespace __par_backend { -inline namespace __thread_cpu_backend { - -template -_LIBCPP_HIDE_FROM_ABI void __parallel_for(_RandomAccessIterator __first, _RandomAccessIterator __last, _Fp __f) { - __f(__first, __last); -} - -_LIBCPP_HIDE_FROM_ABI inline void __cancel_execution() {} - -template -_LIBCPP_HIDE_FROM_ABI void __parallel_merge( - _RandomAccessIterator1 __first1, - _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, - _RandomAccessIterator2 __last2, - _RandomAccessIterator3 __outit, - _Compare __comp, - _LeafMerge __leaf_merge) { - __leaf_merge(__first1, __last1, __first2, __last2, __outit, __comp); -} - -} // namespace __thread_cpu_backend -} // namespace __par_backend - -_LIBCPP_END_NAMESPACE_STD - -#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && && _LIBCPP_STD_VER >= 17 - -#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_THREAD_H diff --git a/third_party/libcxx/__algorithm/pstl_backends/cpu_backends/transform.h b/third_party/libcxx/__algorithm/pstl_backends/cpu_backends/transform.h deleted file mode 100644 index ef25ff023..000000000 --- a/third_party/libcxx/__algorithm/pstl_backends/cpu_backends/transform.h +++ /dev/null @@ -1,132 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_H -#define _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_H - -#include <__algorithm/pstl_backends/cpu_backends/backend.h> -#include <__algorithm/transform.h> -#include <__config> -#include <__iterator/iterator_traits.h> -#include <__type_traits/enable_if.h> -#include <__type_traits/is_execution_policy.h> -#include <__type_traits/remove_cvref.h> -#include <__utility/terminate_on_exception.h> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 - -_LIBCPP_BEGIN_NAMESPACE_STD - -template -_LIBCPP_HIDE_FROM_ABI _Iterator2 -__simd_walk_2(_Iterator1 __first1, _DifferenceType __n, _Iterator2 __first2, _Function __f) noexcept { - _PSTL_PRAGMA_SIMD - for (_DifferenceType __i = 0; __i < __n; ++__i) - __f(__first1[__i], __first2[__i]); - return __first2 + __n; -} - -template -_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator __pstl_transform( - __cpu_backend_tag, - _ForwardIterator __first, - _ForwardIterator __last, - _ForwardOutIterator __result, - _UnaryOperation __op) { - if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> && - __has_random_access_iterator_category<_ForwardIterator>::value && - __has_random_access_iterator_category<_ForwardOutIterator>::value) { - std::__terminate_on_exception([&] { - std::__par_backend::__parallel_for( - __first, __last, [__op, __first, __result](_ForwardIterator __brick_first, _ForwardIterator __brick_last) { - return std::__pstl_transform<__remove_parallel_policy_t<_ExecutionPolicy>>( - __cpu_backend_tag{}, __brick_first, __brick_last, __result + (__brick_first - __first), __op); - }); - }); - return __result + (__last - __first); - } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> && - __has_random_access_iterator_category<_ForwardIterator>::value && - __has_random_access_iterator_category<_ForwardOutIterator>::value) { - return std::__simd_walk_2( - __first, - __last - __first, - __result, - [&](__iter_reference<_ForwardIterator> __in_value, __iter_reference<_ForwardOutIterator> __out_value) { - __out_value = __op(__in_value); - }); - } else { - return std::transform(__first, __last, __result, __op); - } -} - -template -_LIBCPP_HIDE_FROM_ABI _Iterator3 __simd_walk_3( - _Iterator1 __first1, _DifferenceType __n, _Iterator2 __first2, _Iterator3 __first3, _Function __f) noexcept { - _PSTL_PRAGMA_SIMD - for (_DifferenceType __i = 0; __i < __n; ++__i) - __f(__first1[__i], __first2[__i], __first3[__i]); - return __first3 + __n; -} -template >, int> = 0> -_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator __pstl_transform( - __cpu_backend_tag, - _ForwardIterator1 __first1, - _ForwardIterator1 __last1, - _ForwardIterator2 __first2, - _ForwardOutIterator __result, - _BinaryOperation __op) { - if constexpr (__is_parallel_execution_policy_v<_ExecutionPolicy> && - __has_random_access_iterator_category<_ForwardIterator1>::value && - __has_random_access_iterator_category<_ForwardIterator2>::value && - __has_random_access_iterator_category<_ForwardOutIterator>::value) { - std::__terminate_on_exception([&] { - std::__par_backend::__parallel_for( - __first1, - __last1, - [__op, __first1, __first2, __result](_ForwardIterator1 __brick_first, _ForwardIterator1 __brick_last) { - return std::__pstl_transform<__remove_parallel_policy_t<_ExecutionPolicy>>( - __cpu_backend_tag{}, - __brick_first, - __brick_last, - __first2 + (__brick_first - __first1), - __result + (__brick_first - __first1), - __op); - }); - }); - return __result + (__last1 - __first1); - } else if constexpr (__is_unsequenced_execution_policy_v<_ExecutionPolicy> && - __has_random_access_iterator_category<_ForwardIterator1>::value && - __has_random_access_iterator_category<_ForwardIterator2>::value && - __has_random_access_iterator_category<_ForwardOutIterator>::value) { - return std::__simd_walk_3( - __first1, - __last1 - __first1, - __first2, - __result, - [&](__iter_reference<_ForwardIterator1> __in1, - __iter_reference<_ForwardIterator2> __in2, - __iter_reference<_ForwardOutIterator> __out_value) { __out_value = __op(__in1, __in2); }); - } else { - return std::transform(__first1, __last1, __first2, __result, __op); - } -} - -_LIBCPP_END_NAMESPACE_STD - -#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 - -#endif // _LIBCPP___ALGORITHM_PSTL_BACKENDS_CPU_BACKENDS_TRANSFORM_H diff --git a/third_party/libcxx/__algorithm/pstl_copy.h b/third_party/libcxx/__algorithm/pstl_copy.h deleted file mode 100644 index 5b7d921d7..000000000 --- a/third_party/libcxx/__algorithm/pstl_copy.h +++ /dev/null @@ -1,57 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP___ALGORITHM_PSTL_COPY_H -#define _LIBCPP___ALGORITHM_PSTL_COPY_H - -#include <__algorithm/copy_n.h> -#include <__algorithm/pstl_transform.h> -#include <__config> -#include <__functional/identity.h> -#include <__iterator/iterator_traits.h> -#include <__type_traits/is_constant_evaluated.h> -#include <__type_traits/is_execution_policy.h> -#include <__type_traits/is_trivially_copyable.h> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 - -_LIBCPP_BEGIN_NAMESPACE_STD - -// TODO: Use the std::copy/move shenanigans to forward to std::memmove - -template >, int> = 0> -_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator -copy(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _ForwardOutIterator __result) { - return std::transform(__policy, __first, __last, __result, __identity()); -} - -template >, int> = 0> -_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator -copy_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __n, _ForwardOutIterator __result) { - if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) - return std::copy(__policy, __first, __first + __n, __result); - else - return std::copy_n(__first, __n, __result); -} - -_LIBCPP_END_NAMESPACE_STD - -#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 - -#endif // _LIBCPP___ALGORITHM_PSTL_COPY_H diff --git a/third_party/libcxx/__algorithm/pstl_fill.h b/third_party/libcxx/__algorithm/pstl_fill.h deleted file mode 100644 index 03217b36d..000000000 --- a/third_party/libcxx/__algorithm/pstl_fill.h +++ /dev/null @@ -1,79 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP___ALGORITHM_PSTL_FILL_H -#define _LIBCPP___ALGORITHM_PSTL_FILL_H - -#include <__algorithm/fill_n.h> -#include <__algorithm/pstl_for_each.h> -#include <__algorithm/pstl_frontend_dispatch.h> -#include <__config> -#include <__iterator/iterator_traits.h> -#include <__type_traits/is_execution_policy.h> -#include <__type_traits/remove_cvref.h> -#include <__utility/terminate_on_exception.h> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 - -_LIBCPP_BEGIN_NAMESPACE_STD - -template -void __pstl_fill(); // declaration needed for the frontend dispatch below - -template , - enable_if_t, int> = 0> -_LIBCPP_HIDE_FROM_ABI void -fill(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { - std::__pstl_frontend_dispatch( - _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_fill), - [&](_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_value) { - std::for_each(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __element) { - __element = __g_value; - }); - }, - std::move(__first), - std::move(__last), - __value); -} - -template -void __pstl_fill_n(); // declaration needed for the frontend dispatch below - -template , - enable_if_t, int> = 0> -_LIBCPP_HIDE_FROM_ABI void -fill_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _SizeT __n, const _Tp& __value) { - std::__pstl_frontend_dispatch( - _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_fill_n), - [&](_ForwardIterator __g_first, _SizeT __g_n, const _Tp& __g_value) { - if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) - std::fill(__policy, __g_first, __g_first + __g_n, __g_value); - else - std::fill_n(__g_first, __g_n, __g_value); - }, - std::move(__first), - __n, - __value); -} - -_LIBCPP_END_NAMESPACE_STD - -#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 - -#endif // _LIBCPP___ALGORITHM_PSTL_FILL_H diff --git a/third_party/libcxx/__algorithm/pstl_find.h b/third_party/libcxx/__algorithm/pstl_find.h deleted file mode 100644 index 6d69560dc..000000000 --- a/third_party/libcxx/__algorithm/pstl_find.h +++ /dev/null @@ -1,89 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP___ALGORITHM_PSTL_FIND_H -#define _LIBCPP___ALGORITHM_PSTL_FIND_H - -#include <__algorithm/comp.h> -#include <__algorithm/find.h> -#include <__algorithm/pstl_backend.h> -#include <__algorithm/pstl_frontend_dispatch.h> -#include <__config> -#include <__iterator/iterator_traits.h> -#include <__type_traits/is_execution_policy.h> -#include <__type_traits/remove_cvref.h> -#include <__utility/terminate_on_exception.h> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 - -_LIBCPP_BEGIN_NAMESPACE_STD - -template , - enable_if_t, int> = 0> -_LIBCPP_HIDE_FROM_ABI _ForwardIterator -find_if(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { - using _Backend = typename __select_backend<_RawPolicy>::type; - return std::__pstl_find_if<_RawPolicy>(_Backend{}, std::move(__first), std::move(__last), std::move(__pred)); -} - -template -void __pstl_find_if_not(); - -template , - enable_if_t, int> = 0> -_LIBCPP_HIDE_FROM_ABI _ForwardIterator -find_if_not(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { - return std::__pstl_frontend_dispatch( - _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_find_if_not), - [&](_ForwardIterator __g_first, _ForwardIterator __g_last, _Predicate __g_pred) { - return std::find_if(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __value) { - return !__g_pred(__value); - }); - }, - std::move(__first), - std::move(__last), - std::move(__pred)); -} - -template -void __pstl_find(); - -template , - enable_if_t, int> = 0> -_LIBCPP_HIDE_FROM_ABI _ForwardIterator -find(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { - return std::__pstl_frontend_dispatch( - _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_find), - [&](_ForwardIterator __g_first, _ForwardIterator __g_last, const _Tp& __g_value) { - return std::find_if(__policy, __g_first, __g_last, [&](__iter_reference<_ForwardIterator> __element) { - return __element == __g_value; - }); - }, - std::move(__first), - std::move(__last), - __value); -} - -_LIBCPP_END_NAMESPACE_STD - -#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 - -#endif // _LIBCPP___ALGORITHM_PSTL_FIND_H diff --git a/third_party/libcxx/__algorithm/pstl_for_each.h b/third_party/libcxx/__algorithm/pstl_for_each.h deleted file mode 100644 index 1c435385d..000000000 --- a/third_party/libcxx/__algorithm/pstl_for_each.h +++ /dev/null @@ -1,71 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP___ALGORITHM_PSTL_FOR_EACH_H -#define _LIBCPP___ALGORITHM_PSTL_FOR_EACH_H - -#include <__algorithm/for_each.h> -#include <__algorithm/for_each_n.h> -#include <__algorithm/pstl_backend.h> -#include <__algorithm/pstl_frontend_dispatch.h> -#include <__config> -#include <__iterator/iterator_traits.h> -#include <__type_traits/is_execution_policy.h> -#include <__type_traits/remove_cvref.h> -#include <__type_traits/void_t.h> -#include <__utility/terminate_on_exception.h> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 - -_LIBCPP_BEGIN_NAMESPACE_STD - -template , - enable_if_t, int> = 0> -_LIBCPP_HIDE_FROM_ABI void -for_each(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Function __func) { - using _Backend = typename __select_backend<_RawPolicy>::type; - std::__pstl_for_each<_RawPolicy>(_Backend{}, std::move(__first), std::move(__last), std::move(__func)); -} - -template -void __pstl_for_each_n(); // declaration needed for the frontend dispatch below - -template , - enable_if_t, int> = 0> -_LIBCPP_HIDE_FROM_ABI void -for_each_n(_ExecutionPolicy&& __policy, _ForwardIterator __first, _Size __size, _Function __func) { - return std::__pstl_frontend_dispatch( - _LIBCPP_PSTL_CUSTOMIZATION_POINT(__pstl_for_each_n), - [&](_ForwardIterator __g_first, _Size __g_size, _Function __g_func) { - if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) { - std::for_each(__policy, std::move(__g_first), __g_first + __g_size, std::move(__g_func)); - } else { - std::for_each_n(std::move(__g_first), __g_size, std::move(__g_func)); - } - }, - __first, - __size, - std::move(__func)); -} - -_LIBCPP_END_NAMESPACE_STD - -#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 - -#endif // _LIBCPP___ALGORITHM_PSTL_FOR_EACH_H diff --git a/third_party/libcxx/__algorithm/pstl_frontend_dispatch.h b/third_party/libcxx/__algorithm/pstl_frontend_dispatch.h deleted file mode 100644 index dc49f3e51..000000000 --- a/third_party/libcxx/__algorithm/pstl_frontend_dispatch.h +++ /dev/null @@ -1,45 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP___ALGORITHM_PSTL_FRONTEND_DISPATCH -#define _LIBCPP___ALGORITHM_PSTL_FRONTEND_DISPATCH - -#include <__config> -#include <__type_traits/is_callable.h> -#include <__utility/forward.h> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -#if _LIBCPP_STD_VER >= 17 - -_LIBCPP_BEGIN_NAMESPACE_STD - -# define _LIBCPP_PSTL_CUSTOMIZATION_POINT(name) \ - [](auto&&... __args) -> decltype(std::name<_RawPolicy>(typename __select_backend<_RawPolicy>::type{}, \ - std::forward(__args)...)) { \ - return std::name<_RawPolicy>( \ - typename __select_backend<_RawPolicy>::type{}, std::forward(__args)...); \ - } - -template -_LIBCPP_HIDE_FROM_ABI decltype(auto) -__pstl_frontend_dispatch(_SpecializedImpl __specialized_impl, _GenericImpl __generic_impl, _Args&&... __args) { - if constexpr (__is_callable<_SpecializedImpl, _Args...>::value) { - return __specialized_impl(std::forward<_Args>(__args)...); - } else { - return __generic_impl(std::forward<_Args>(__args)...); - } -} - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP_STD_VER >= 17 - -#endif // _LIBCPP___ALGORITHM_PSTL_FRONTEND_DISPATCH diff --git a/third_party/libcxx/__algorithm/pstl_merge.h b/third_party/libcxx/__algorithm/pstl_merge.h deleted file mode 100644 index b5585eeec..000000000 --- a/third_party/libcxx/__algorithm/pstl_merge.h +++ /dev/null @@ -1,56 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP___ALGORITHM_PSTL_MERGE_H -#define _LIBCPP___ALGORITHM_PSTL_MERGE_H - -#include <__algorithm/pstl_backend.h> -#include <__config> -#include <__functional/operations.h> -#include <__type_traits/is_execution_policy.h> -#include <__type_traits/remove_cvref.h> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 - -_LIBCPP_BEGIN_NAMESPACE_STD - -template , - class _RawPolicy = __remove_cvref_t<_ExecutionPolicy>, - enable_if_t, int> = 0> -_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator -merge(_ExecutionPolicy&&, - _ForwardIterator1 __first1, - _ForwardIterator1 __last1, - _ForwardIterator2 __first2, - _ForwardIterator2 __last2, - _ForwardOutIterator __result, - _Comp __comp = {}) { - using _Backend = typename __select_backend<_RawPolicy>::type; - return std::__pstl_merge<_RawPolicy>( - _Backend{}, - std::move(__first1), - std::move(__last1), - std::move(__first2), - std::move(__last2), - std::move(__result), - std::move(__comp)); -} - -_LIBCPP_END_NAMESPACE_STD - -#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 - -#endif // _LIBCPP___ALGORITHM_PSTL_MERGE_H diff --git a/third_party/libcxx/__algorithm/pstl_transform.h b/third_party/libcxx/__algorithm/pstl_transform.h deleted file mode 100644 index 9d2d731ee..000000000 --- a/third_party/libcxx/__algorithm/pstl_transform.h +++ /dev/null @@ -1,66 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP___ALGORITHM_PSTL_TRANSFORM_H -#define _LIBCPP___ALGORITHM_PSTL_TRANSFORM_H - -#include <__algorithm/pstl_backend.h> -#include <__config> -#include <__iterator/iterator_traits.h> -#include <__type_traits/is_execution_policy.h> -#include <__utility/terminate_on_exception.h> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 - -_LIBCPP_BEGIN_NAMESPACE_STD - -template , - enable_if_t, int> = 0> -_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator transform( - _ExecutionPolicy&&, - _ForwardIterator __first, - _ForwardIterator __last, - _ForwardOutIterator __result, - _UnaryOperation __op) { - using _Backend = typename __select_backend<_RawPolicy>::type; - return std::__pstl_transform<_RawPolicy>( - _Backend{}, std::move(__first), std::move(__last), std::move(__result), std::move(__op)); -} - -template , - enable_if_t, int> = 0> -_LIBCPP_HIDE_FROM_ABI _ForwardOutIterator transform( - _ExecutionPolicy&&, - _ForwardIterator1 __first1, - _ForwardIterator1 __last1, - _ForwardIterator2 __first2, - _ForwardOutIterator __result, - _BinaryOperation __op) { - using _Backend = typename __select_backend<_RawPolicy>::type; - return std::__pstl_transform<_RawPolicy>( - _Backend{}, std::move(__first1), std::move(__last1), std::move(__first2), std::move(__result), std::move(__op)); -} - -_LIBCPP_END_NAMESPACE_STD - -#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_PSTL) && _LIBCPP_STD_VER >= 17 - -#endif // _LIBCPP___ALGORITHM_PSTL_TRANSFORM_H diff --git a/third_party/libcxx/__algorithm/push_heap.h b/third_party/libcxx/__algorithm/push_heap.h index e831162a8..ec0b445f2 100644 --- a/third_party/libcxx/__algorithm/push_heap.h +++ b/third_party/libcxx/__algorithm/push_heap.h @@ -14,31 +14,36 @@ #include <__algorithm/iterator_operations.h> #include <__config> #include <__iterator/iterator_traits.h> -#include <__type_traits/is_copy_assignable.h> -#include <__type_traits/is_copy_constructible.h> +#include <__type_traits/is_assignable.h> +#include <__type_traits/is_constructible.h> #include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -void __sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp, - typename iterator_traits<_RandomAccessIterator>::difference_type __len) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void +__sift_up(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Compare&& __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len) { using value_type = typename iterator_traits<_RandomAccessIterator>::value_type; if (__len > 1) { - __len = (__len - 2) / 2; + __len = (__len - 2) / 2; _RandomAccessIterator __ptr = __first + __len; if (__comp(*__ptr, *--__last)) { value_type __t(_IterOps<_AlgPolicy>::__iter_move(__last)); do { *__last = _IterOps<_AlgPolicy>::__iter_move(__ptr); - __last = __ptr; + __last = __ptr; if (__len == 0) break; __len = (__len - 1) / 2; @@ -51,15 +56,15 @@ void __sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Com } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -void __push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void +__push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) { typename iterator_traits<_RandomAccessIterator>::difference_type __len = __last - __first; std::__sift_up<_AlgPolicy, __comp_ref_type<_Compare> >(std::move(__first), std::move(__last), __comp, __len); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible."); static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable."); @@ -67,12 +72,13 @@ void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Com } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { - std::push_heap(std::move(__first), std::move(__last), - __less::value_type>()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { + std::push_heap(std::move(__first), std::move(__last), __less<>()); } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_PUSH_HEAP_H diff --git a/third_party/libcxx/__algorithm/ranges_adjacent_find.h b/third_party/libcxx/__algorithm/ranges_adjacent_find.h index e3de36bbc..3c54f7233 100644 --- a/third_party/libcxx/__algorithm/ranges_adjacent_find.h +++ b/third_party/libcxx/__algorithm/ranges_adjacent_find.h @@ -24,6 +24,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -31,10 +34,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __adjacent_find { struct __fn { - template - _LIBCPP_HIDE_FROM_ABI constexpr static - _Iter __adjacent_find_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { + _LIBCPP_HIDE_FROM_ABI constexpr static _Iter + __adjacent_find_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { if (__first == __last) return __first; @@ -47,27 +49,28 @@ struct __fn { return __i; } - template _Sent, - class _Proj = identity, + template _Sent, + class _Proj = identity, indirect_binary_predicate, projected<_Iter, _Proj>> _Pred = ranges::equal_to> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - _Iter operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Iter + operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const { return __adjacent_find_impl(std::move(__first), std::move(__last), __pred, __proj); } template , _Proj>, - projected, _Proj>> _Pred = ranges::equal_to> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - borrowed_iterator_t<_Range> operator()(_Range&& __range, _Pred __pred = {}, _Proj __proj = {}) const { + indirect_binary_predicate, _Proj>, projected, _Proj>> + _Pred = ranges::equal_to> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> + operator()(_Range&& __range, _Pred __pred = {}, _Proj __proj = {}) const { return __adjacent_find_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); } }; } // namespace __adjacent_find inline namespace __cpo { - inline constexpr auto adjacent_find = __adjacent_find::__fn{}; +inline constexpr auto adjacent_find = __adjacent_find::__fn{}; } // namespace __cpo } // namespace ranges @@ -75,4 +78,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_ADJACENT_FIND_H diff --git a/third_party/libcxx/__algorithm/ranges_all_of.h b/third_party/libcxx/__algorithm/ranges_all_of.h index 494a77d74..2f603b32f 100644 --- a/third_party/libcxx/__algorithm/ranges_all_of.h +++ b/third_party/libcxx/__algorithm/ranges_all_of.h @@ -22,6 +22,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -29,10 +32,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __all_of { struct __fn { - template - _LIBCPP_HIDE_FROM_ABI constexpr static - bool __all_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { + _LIBCPP_HIDE_FROM_ABI constexpr static bool __all_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { for (; __first != __last; ++__first) { if (!std::invoke(__pred, std::invoke(__proj, *__first))) return false; @@ -40,24 +41,27 @@ struct __fn { return true; } - template _Sent, class _Proj = identity, + template _Sent, + class _Proj = identity, indirect_unary_predicate> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - bool operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool + operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { return __all_of_impl(std::move(__first), std::move(__last), __pred, __proj); } - template , _Proj>> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool + operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { return __all_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); } }; } // namespace __all_of inline namespace __cpo { - inline constexpr auto all_of = __all_of::__fn{}; +inline constexpr auto all_of = __all_of::__fn{}; } // namespace __cpo } // namespace ranges @@ -65,4 +69,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_ALL_OF_H diff --git a/third_party/libcxx/__algorithm/ranges_any_of.h b/third_party/libcxx/__algorithm/ranges_any_of.h index eb102bd85..205fcecc0 100644 --- a/third_party/libcxx/__algorithm/ranges_any_of.h +++ b/third_party/libcxx/__algorithm/ranges_any_of.h @@ -22,6 +22,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -29,10 +32,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __any_of { struct __fn { - template - _LIBCPP_HIDE_FROM_ABI constexpr static - bool __any_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { + _LIBCPP_HIDE_FROM_ABI constexpr static bool __any_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { for (; __first != __last; ++__first) { if (std::invoke(__pred, std::invoke(__proj, *__first))) return true; @@ -40,24 +41,27 @@ struct __fn { return false; } - template _Sent, class _Proj = identity, + template _Sent, + class _Proj = identity, indirect_unary_predicate> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - bool operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool + operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const { return __any_of_impl(std::move(__first), std::move(__last), __pred, __proj); } - template , _Proj>> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool + operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { return __any_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); } }; } // namespace __any_of inline namespace __cpo { - inline constexpr auto any_of = __any_of::__fn{}; +inline constexpr auto any_of = __any_of::__fn{}; } // namespace __cpo } // namespace ranges @@ -65,4 +69,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_ANY_OF_H diff --git a/third_party/libcxx/__algorithm/ranges_binary_search.h b/third_party/libcxx/__algorithm/ranges_binary_search.h index d89597e1b..1ef2bd62b 100644 --- a/third_party/libcxx/__algorithm/ranges_binary_search.h +++ b/third_party/libcxx/__algorithm/ranges_binary_search.h @@ -24,6 +24,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -31,28 +34,33 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __binary_search { struct __fn { - template _Sent, class _Type, class _Proj = identity, + template _Sent, + class _Type, + class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - bool operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { - auto __ret = std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj); + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool + operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { + auto __ret = std::__lower_bound<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj); return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__ret)); } - template , _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - bool operator()(_Range&& __r, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool + operator()(_Range&& __r, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { auto __first = ranges::begin(__r); - auto __last = ranges::end(__r); - auto __ret = std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj); + auto __last = ranges::end(__r); + auto __ret = std::__lower_bound<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj); return __ret != __last && !std::invoke(__comp, __value, std::invoke(__proj, *__ret)); } }; } // namespace __binary_search inline namespace __cpo { - inline constexpr auto binary_search = __binary_search::__fn{}; +inline constexpr auto binary_search = __binary_search::__fn{}; } // namespace __cpo } // namespace ranges @@ -60,4 +68,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_BINARY_SEARCH_H diff --git a/third_party/libcxx/__algorithm/ranges_clamp.h b/third_party/libcxx/__algorithm/ranges_clamp.h index 45a8464c9..e6181ef94 100644 --- a/third_party/libcxx/__algorithm/ranges_clamp.h +++ b/third_party/libcxx/__algorithm/ranges_clamp.h @@ -22,6 +22,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -29,32 +32,28 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __clamp { struct __fn { - template > _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - const _Type& operator()(const _Type& __value, - const _Type& __low, - const _Type& __high, - _Comp __comp = {}, - _Proj __proj = {}) const { - _LIBCPP_ASSERT(!bool(std::invoke(__comp, std::invoke(__proj, __high), std::invoke(__proj, __low))), - "Bad bounds passed to std::ranges::clamp"); + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Type& operator()( + const _Type& __value, const _Type& __low, const _Type& __high, _Comp __comp = {}, _Proj __proj = {}) const { + _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN( + !bool(std::invoke(__comp, std::invoke(__proj, __high), std::invoke(__proj, __low))), + "Bad bounds passed to std::ranges::clamp"); - if (std::invoke(__comp, std::invoke(__proj, __value), std::invoke(__proj, __low))) + auto&& __projected = std::invoke(__proj, __value); + if (std::invoke(__comp, std::forward(__projected), std::invoke(__proj, __low))) return __low; - else if (std::invoke(__comp, std::invoke(__proj, __high), std::invoke(__proj, __value))) + else if (std::invoke(__comp, std::invoke(__proj, __high), std::forward(__projected))) return __high; else return __value; } - }; } // namespace __clamp inline namespace __cpo { - inline constexpr auto clamp = __clamp::__fn{}; +inline constexpr auto clamp = __clamp::__fn{}; } // namespace __cpo } // namespace ranges @@ -62,4 +61,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_CLAMP_H diff --git a/third_party/libcxx/__algorithm/ranges_contains.h b/third_party/libcxx/__algorithm/ranges_contains.h new file mode 100644 index 000000000..4836c3bae --- /dev/null +++ b/third_party/libcxx/__algorithm/ranges_contains.h @@ -0,0 +1,66 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_CONTAINS_H +#define _LIBCPP___ALGORITHM_RANGES_CONTAINS_H + +#include <__algorithm/ranges_find.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__functional/reference_wrapper.h> +#include <__iterator/concepts.h> +#include <__iterator/indirectly_comparable.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +#if _LIBCPP_STD_VER >= 23 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __contains { +struct __fn { + template _Sent, class _Type, class _Proj = identity> + requires indirect_binary_predicate, const _Type*> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool static + operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) { + return ranges::find(std::move(__first), __last, __value, std::ref(__proj)) != __last; + } + + template + requires indirect_binary_predicate, _Proj>, const _Type*> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool static + operator()(_Range&& __range, const _Type& __value, _Proj __proj = {}) { + return ranges::find(ranges::begin(__range), ranges::end(__range), __value, std::ref(__proj)) != + ranges::end(__range); + } +}; +} // namespace __contains + +inline namespace __cpo { +inline constexpr auto contains = __contains::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER >= 23 + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___ALGORITHM_RANGES_CONTAINS_H diff --git a/third_party/libcxx/__algorithm/ranges_contains_subrange.h b/third_party/libcxx/__algorithm/ranges_contains_subrange.h new file mode 100644 index 000000000..4398c457f --- /dev/null +++ b/third_party/libcxx/__algorithm/ranges_contains_subrange.h @@ -0,0 +1,97 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_CONTAINS_SUBRANGE_H +#define _LIBCPP___ALGORITHM_RANGES_CONTAINS_SUBRANGE_H + +#include <__algorithm/ranges_search.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__functional/reference_wrapper.h> +#include <__iterator/concepts.h> +#include <__iterator/indirectly_comparable.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/size.h> +#include <__ranges/subrange.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +#if _LIBCPP_STD_VER >= 23 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __contains_subrange { +struct __fn { + template _Sent1, + forward_iterator _Iter2, + sentinel_for<_Iter2> _Sent2, + class _Pred = ranges::equal_to, + class _Proj1 = identity, + class _Proj2 = identity> + requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool static operator()( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Pred __pred = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) { + if (__first2 == __last2) + return true; + + auto __ret = ranges::search( + std::move(__first1), __last1, std::move(__first2), __last2, __pred, std::ref(__proj1), std::ref(__proj2)); + return __ret.empty() == false; + } + + template + requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool static + operator()(_Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) { + if constexpr (sized_range<_Range2>) { + if (ranges::size(__range2) == 0) + return true; + } else { + if (ranges::begin(__range2) == ranges::end(__range2)) + return true; + } + + auto __ret = ranges::search(__range1, __range2, __pred, std::ref(__proj1), std::ref(__proj2)); + return __ret.empty() == false; + } +}; +} // namespace __contains_subrange + +inline namespace __cpo { +inline constexpr auto contains_subrange = __contains_subrange::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER >= 23 + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___ALGORITHM_RANGES_CONTAINS_SUBRANGE_H diff --git a/third_party/libcxx/__algorithm/ranges_copy.h b/third_party/libcxx/__algorithm/ranges_copy.h index f5700c3d3..e1d6d32f0 100644 --- a/third_party/libcxx/__algorithm/ranges_copy.h +++ b/third_party/libcxx/__algorithm/ranges_copy.h @@ -25,6 +25,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -36,19 +39,18 @@ using copy_result = in_out_result<_InIter, _OutIter>; namespace __copy { struct __fn { - template _Sent, weakly_incrementable _OutIter> requires indirectly_copyable<_InIter, _OutIter> - _LIBCPP_HIDE_FROM_ABI constexpr - copy_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const { + _LIBCPP_HIDE_FROM_ABI constexpr copy_result<_InIter, _OutIter> + operator()(_InIter __first, _Sent __last, _OutIter __result) const { auto __ret = std::__copy<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)); return {std::move(__ret.first), std::move(__ret.second)}; } template requires indirectly_copyable, _OutIter> - _LIBCPP_HIDE_FROM_ABI constexpr - copy_result, _OutIter> operator()(_Range&& __r, _OutIter __result) const { + _LIBCPP_HIDE_FROM_ABI constexpr copy_result, _OutIter> + operator()(_Range&& __r, _OutIter __result) const { auto __ret = std::__copy<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), std::move(__result)); return {std::move(__ret.first), std::move(__ret.second)}; } @@ -56,7 +58,7 @@ struct __fn { } // namespace __copy inline namespace __cpo { - inline constexpr auto copy = __copy::__fn{}; +inline constexpr auto copy = __copy::__fn{}; } // namespace __cpo } // namespace ranges @@ -64,4 +66,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_COPY_H diff --git a/third_party/libcxx/__algorithm/ranges_copy_backward.h b/third_party/libcxx/__algorithm/ranges_copy_backward.h index b7b5b8879..93e326042 100644 --- a/third_party/libcxx/__algorithm/ranges_copy_backward.h +++ b/third_party/libcxx/__algorithm/ranges_copy_backward.h @@ -23,30 +23,32 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { -template +template using copy_backward_result = in_out_result<_Ip, _Op>; namespace __copy_backward { struct __fn { - template _Sent1, bidirectional_iterator _InIter2> requires indirectly_copyable<_InIter1, _InIter2> - _LIBCPP_HIDE_FROM_ABI constexpr - copy_backward_result<_InIter1, _InIter2> operator()(_InIter1 __first, _Sent1 __last, _InIter2 __result) const { + _LIBCPP_HIDE_FROM_ABI constexpr copy_backward_result<_InIter1, _InIter2> + operator()(_InIter1 __first, _Sent1 __last, _InIter2 __result) const { auto __ret = std::__copy_backward<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)); return {std::move(__ret.first), std::move(__ret.second)}; } template requires indirectly_copyable, _Iter> - _LIBCPP_HIDE_FROM_ABI constexpr - copy_backward_result, _Iter> operator()(_Range&& __r, _Iter __result) const { + _LIBCPP_HIDE_FROM_ABI constexpr copy_backward_result, _Iter> + operator()(_Range&& __r, _Iter __result) const { auto __ret = std::__copy_backward<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), std::move(__result)); return {std::move(__ret.first), std::move(__ret.second)}; } @@ -54,7 +56,7 @@ struct __fn { } // namespace __copy_backward inline namespace __cpo { - inline constexpr auto copy_backward = __copy_backward::__fn{}; +inline constexpr auto copy_backward = __copy_backward::__fn{}; } // namespace __cpo } // namespace ranges @@ -62,4 +64,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_COPY_BACKWARD_H diff --git a/third_party/libcxx/__algorithm/ranges_copy_if.h b/third_party/libcxx/__algorithm/ranges_copy_if.h index b714e4cd1..4b41d2154 100644 --- a/third_party/libcxx/__algorithm/ranges_copy_if.h +++ b/third_party/libcxx/__algorithm/ranges_copy_if.h @@ -24,21 +24,22 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { -template +template using copy_if_result = in_out_result<_Ip, _Op>; namespace __copy_if { struct __fn { - template - _LIBCPP_HIDE_FROM_ABI static constexpr - copy_if_result <_InIter, _OutIter> + _LIBCPP_HIDE_FROM_ABI static constexpr copy_if_result<_InIter, _OutIter> __copy_if_impl(_InIter __first, _Sent __last, _OutIter __result, _Pred& __pred, _Proj& __proj) { for (; __first != __last; ++__first) { if (std::invoke(__pred, std::invoke(__proj, *__first))) { @@ -49,20 +50,23 @@ struct __fn { return {std::move(__first), std::move(__result)}; } - template _Sent, weakly_incrementable _OutIter, class _Proj = identity, + template _Sent, + weakly_incrementable _OutIter, + class _Proj = identity, indirect_unary_predicate> _Pred> requires indirectly_copyable<_Iter, _OutIter> - _LIBCPP_HIDE_FROM_ABI constexpr - copy_if_result<_Iter, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr copy_if_result<_Iter, _OutIter> operator()(_Iter __first, _Sent __last, _OutIter __result, _Pred __pred, _Proj __proj = {}) const { return __copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj); } - template , _Proj>> _Pred> requires indirectly_copyable, _OutIter> - _LIBCPP_HIDE_FROM_ABI constexpr - copy_if_result, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr copy_if_result, _OutIter> operator()(_Range&& __r, _OutIter __result, _Pred __pred, _Proj __proj = {}) const { return __copy_if_impl(ranges::begin(__r), ranges::end(__r), std::move(__result), __pred, __proj); } @@ -70,7 +74,7 @@ struct __fn { } // namespace __copy_if inline namespace __cpo { - inline constexpr auto copy_if = __copy_if::__fn{}; +inline constexpr auto copy_if = __copy_if::__fn{}; } // namespace __cpo } // namespace ranges @@ -78,4 +82,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_COPY_IF_H diff --git a/third_party/libcxx/__algorithm/ranges_copy_n.h b/third_party/libcxx/__algorithm/ranges_copy_n.h index 30ee019ac..4353fa992 100644 --- a/third_party/libcxx/__algorithm/ranges_copy_n.h +++ b/third_party/libcxx/__algorithm/ranges_copy_n.h @@ -25,6 +25,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 @@ -36,10 +39,9 @@ using copy_n_result = in_out_result<_Ip, _Op>; namespace __copy_n { struct __fn { - template - _LIBCPP_HIDE_FROM_ABI constexpr static - copy_n_result<_InIter, _OutIter> __go(_InIter __first, _DiffType __n, _OutIter __result) { + _LIBCPP_HIDE_FROM_ABI constexpr static copy_n_result<_InIter, _OutIter> + __go(_InIter __first, _DiffType __n, _OutIter __result) { while (__n != 0) { *__result = *__first; ++__first; @@ -50,23 +52,23 @@ struct __fn { } template - _LIBCPP_HIDE_FROM_ABI constexpr static - copy_n_result<_InIter, _OutIter> __go(_InIter __first, _DiffType __n, _OutIter __result) { + _LIBCPP_HIDE_FROM_ABI constexpr static copy_n_result<_InIter, _OutIter> + __go(_InIter __first, _DiffType __n, _OutIter __result) { auto __ret = std::__copy<_RangeAlgPolicy>(__first, __first + __n, __result); return {__ret.first, __ret.second}; } template requires indirectly_copyable<_Ip, _Op> - _LIBCPP_HIDE_FROM_ABI constexpr - copy_n_result<_Ip, _Op> operator()(_Ip __first, iter_difference_t<_Ip> __n, _Op __result) const { + _LIBCPP_HIDE_FROM_ABI constexpr copy_n_result<_Ip, _Op> + operator()(_Ip __first, iter_difference_t<_Ip> __n, _Op __result) const { return __go(std::move(__first), __n, std::move(__result)); } }; } // namespace __copy_n inline namespace __cpo { - inline constexpr auto copy_n = __copy_n::__fn{}; +inline constexpr auto copy_n = __copy_n::__fn{}; } // namespace __cpo } // namespace ranges @@ -74,4 +76,6 @@ inline namespace __cpo { _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_COPY_N_H diff --git a/third_party/libcxx/__algorithm/ranges_count.h b/third_party/libcxx/__algorithm/ranges_count.h index 677ee3818..4f3511743 100644 --- a/third_party/libcxx/__algorithm/ranges_count.h +++ b/third_party/libcxx/__algorithm/ranges_count.h @@ -9,7 +9,8 @@ #ifndef _LIBCPP___ALGORITHM_RANGES_COUNT_H #define _LIBCPP___ALGORITHM_RANGES_COUNT_H -#include <__algorithm/ranges_count_if.h> +#include <__algorithm/count.h> +#include <__algorithm/iterator_operations.h> #include <__config> #include <__functional/identity.h> #include <__functional/ranges_operations.h> @@ -25,6 +26,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -34,24 +38,22 @@ namespace __count { struct __fn { template _Sent, class _Type, class _Proj = identity> requires indirect_binary_predicate, const _Type*> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - iter_difference_t<_Iter> operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) const { - auto __pred = [&](auto&& __e) { return __e == __value; }; - return ranges::__count_if_impl(std::move(__first), std::move(__last), __pred, __proj); + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter> + operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) const { + return std::__count<_RangeAlgPolicy>(std::move(__first), std::move(__last), __value, __proj); } template requires indirect_binary_predicate, _Proj>, const _Type*> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - range_difference_t<_Range> operator()(_Range&& __r, const _Type& __value, _Proj __proj = {}) const { - auto __pred = [&](auto&& __e) { return __e == __value; }; - return ranges::__count_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj); + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr range_difference_t<_Range> + operator()(_Range&& __r, const _Type& __value, _Proj __proj = {}) const { + return std::__count<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), __value, __proj); } }; } // namespace __count inline namespace __cpo { - inline constexpr auto count = __count::__fn{}; +inline constexpr auto count = __count::__fn{}; } // namespace __cpo } // namespace ranges @@ -59,4 +61,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_COUNT_H diff --git a/third_party/libcxx/__algorithm/ranges_count_if.h b/third_party/libcxx/__algorithm/ranges_count_if.h index 48c4370eb..5f2396ff7 100644 --- a/third_party/libcxx/__algorithm/ranges_count_if.h +++ b/third_party/libcxx/__algorithm/ranges_count_if.h @@ -25,15 +25,17 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { template -_LIBCPP_HIDE_FROM_ABI constexpr -iter_difference_t<_Iter> __count_if_impl(_Iter __first, _Sent __last, - _Pred& __pred, _Proj& __proj) { +_LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter> +__count_if_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { iter_difference_t<_Iter> __counter(0); for (; __first != __last; ++__first) { if (std::invoke(__pred, std::invoke(__proj, *__first))) @@ -44,24 +46,27 @@ iter_difference_t<_Iter> __count_if_impl(_Iter __first, _Sent __last, namespace __count_if { struct __fn { - template _Sent, class _Proj = identity, + template _Sent, + class _Proj = identity, indirect_unary_predicate> _Predicate> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - iter_difference_t<_Iter> operator()(_Iter __first, _Sent __last, _Predicate __pred, _Proj __proj = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter> + operator()(_Iter __first, _Sent __last, _Predicate __pred, _Proj __proj = {}) const { return ranges::__count_if_impl(std::move(__first), std::move(__last), __pred, __proj); } - template , _Proj>> _Predicate> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - range_difference_t<_Range> operator()(_Range&& __r, _Predicate __pred, _Proj __proj = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr range_difference_t<_Range> + operator()(_Range&& __r, _Predicate __pred, _Proj __proj = {}) const { return ranges::__count_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj); } }; } // namespace __count_if inline namespace __cpo { - inline constexpr auto count_if = __count_if::__fn{}; +inline constexpr auto count_if = __count_if::__fn{}; } // namespace __cpo } // namespace ranges @@ -69,4 +74,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_COUNT_IF_H diff --git a/third_party/libcxx/__algorithm/ranges_ends_with.h b/third_party/libcxx/__algorithm/ranges_ends_with.h new file mode 100644 index 000000000..06efdef36 --- /dev/null +++ b/third_party/libcxx/__algorithm/ranges_ends_with.h @@ -0,0 +1,201 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_ENDS_WITH_H +#define _LIBCPP___ALGORITHM_RANGES_ENDS_WITH_H + +#include <__algorithm/ranges_equal.h> +#include <__algorithm/ranges_starts_with.h> +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__functional/reference_wrapper.h> +#include <__iterator/advance.h> +#include <__iterator/concepts.h> +#include <__iterator/distance.h> +#include <__iterator/indirectly_comparable.h> +#include <__iterator/reverse_iterator.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +#if _LIBCPP_STD_VER >= 23 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { +namespace __ends_with { +struct __fn { + template + _LIBCPP_HIDE_FROM_ABI static constexpr bool __ends_with_fn_impl_bidirectional( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Pred& __pred, + _Proj1& __proj1, + _Proj2& __proj2) { + auto __rbegin1 = std::make_reverse_iterator(__last1); + auto __rend1 = std::make_reverse_iterator(__first1); + auto __rbegin2 = std::make_reverse_iterator(__last2); + auto __rend2 = std::make_reverse_iterator(__first2); + return ranges::starts_with( + __rbegin1, __rend1, __rbegin2, __rend2, std::ref(__pred), std::ref(__proj1), std::ref(__proj2)); + } + + template + _LIBCPP_HIDE_FROM_ABI static constexpr bool __ends_with_fn_impl( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Pred& __pred, + _Proj1& __proj1, + _Proj2& __proj2) { + if constexpr (std::bidirectional_iterator<_Sent1> && std::bidirectional_iterator<_Sent2> && + (!std::random_access_iterator<_Sent1>) && (!std::random_access_iterator<_Sent2>)) { + return __ends_with_fn_impl_bidirectional(__first1, __last1, __first2, __last2, __pred, __proj1, __proj2); + + } else { + auto __n1 = ranges::distance(__first1, __last1); + auto __n2 = ranges::distance(__first2, __last2); + if (__n2 == 0) + return true; + if (__n2 > __n1) + return false; + + return __ends_with_fn_impl_with_offset( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + __pred, + __proj1, + __proj2, + __n1 - __n2); + } + } + + template + static _LIBCPP_HIDE_FROM_ABI constexpr bool __ends_with_fn_impl_with_offset( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Pred& __pred, + _Proj1& __proj1, + _Proj2& __proj2, + _Offset __offset) { + if constexpr (std::bidirectional_iterator<_Sent1> && std::bidirectional_iterator<_Sent2> && + !std::random_access_iterator<_Sent1> && !std::random_access_iterator<_Sent2>) { + return __ends_with_fn_impl_bidirectional( + std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __pred, __proj1, __proj2); + + } else { + ranges::advance(__first1, __offset); + return ranges::equal( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + std::ref(__pred), + std::ref(__proj1), + std::ref(__proj2)); + } + } + + template _Sent1, + input_iterator _Iter2, + sentinel_for<_Iter2> _Sent2, + class _Pred = ranges::equal_to, + class _Proj1 = identity, + class _Proj2 = identity> + requires(forward_iterator<_Iter1> || sized_sentinel_for<_Sent1, _Iter1>) && + (forward_iterator<_Iter2> || sized_sentinel_for<_Sent2, _Iter2>) && + indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Pred __pred = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + return __ends_with_fn_impl( + std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __pred, __proj1, __proj2); + } + + template + requires(forward_range<_Range1> || sized_range<_Range1>) && (forward_range<_Range2> || sized_range<_Range2>) && + indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { + if constexpr (sized_range<_Range1> && sized_range<_Range2>) { + auto __n1 = ranges::size(__range1); + auto __n2 = ranges::size(__range2); + if (__n2 == 0) + return true; + if (__n2 > __n1) + return false; + auto __offset = __n1 - __n2; + + return __ends_with_fn_impl_with_offset( + ranges::begin(__range1), + ranges::end(__range1), + ranges::begin(__range2), + ranges::end(__range2), + __pred, + __proj1, + __proj2, + __offset); + + } else { + return __ends_with_fn_impl( + ranges::begin(__range1), + ranges::end(__range1), + ranges::begin(__range2), + ranges::end(__range2), + __pred, + __proj1, + __proj2); + } + } +}; +} // namespace __ends_with + +inline namespace __cpo { +inline constexpr auto ends_with = __ends_with::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER >= 23 + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___ALGORITHM_RANGES_ENDS_WITH_H diff --git a/third_party/libcxx/__algorithm/ranges_equal.h b/third_party/libcxx/__algorithm/ranges_equal.h index 87544531c..edbd0e364 100644 --- a/third_party/libcxx/__algorithm/ranges_equal.h +++ b/third_party/libcxx/__algorithm/ranges_equal.h @@ -26,6 +26,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -33,61 +36,67 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __equal { struct __fn { - template _Sent1, - input_iterator _Iter2, sentinel_for<_Iter2> _Sent2, - class _Pred = ranges::equal_to, + template _Sent1, + input_iterator _Iter2, + sentinel_for<_Iter2> _Sent2, + class _Pred = ranges::equal_to, class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - bool operator()(_Iter1 __first1, _Sent1 __last1, - _Iter2 __first2, _Sent2 __last2, - _Pred __pred = {}, - _Proj1 __proj1 = {}, - _Proj2 __proj2 = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Pred __pred = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { if constexpr (sized_sentinel_for<_Sent1, _Iter1> && sized_sentinel_for<_Sent2, _Iter2>) { if (__last1 - __first1 != __last2 - __first2) return false; } auto __unwrapped1 = std::__unwrap_range(std::move(__first1), std::move(__last1)); auto __unwrapped2 = std::__unwrap_range(std::move(__first2), std::move(__last2)); - return std::__equal_impl(std::move(__unwrapped1.first), std::move(__unwrapped1.second), - std::move(__unwrapped2.first), std::move(__unwrapped2.second), - __pred, - __proj1, - __proj2); + return std::__equal_impl( + std::move(__unwrapped1.first), + std::move(__unwrapped1.second), + std::move(__unwrapped2.first), + std::move(__unwrapped2.second), + __pred, + __proj1, + __proj2); } template requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - bool operator()(_Range1&& __range1, - _Range2&& __range2, - _Pred __pred = {}, - _Proj1 __proj1 = {}, - _Proj2 __proj2 = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { if constexpr (sized_range<_Range1> && sized_range<_Range2>) { if (ranges::distance(__range1) != ranges::distance(__range2)) return false; } auto __unwrapped1 = std::__unwrap_range(ranges::begin(__range1), ranges::end(__range1)); auto __unwrapped2 = std::__unwrap_range(ranges::begin(__range2), ranges::end(__range2)); - return std::__equal_impl(std::move(__unwrapped1.first), std::move(__unwrapped1.second), - std::move(__unwrapped2.first), std::move(__unwrapped2.second), - __pred, - __proj1, - __proj2); + return std::__equal_impl( + std::move(__unwrapped1.first), + std::move(__unwrapped1.second), + std::move(__unwrapped2.first), + std::move(__unwrapped2.second), + __pred, + __proj1, + __proj2); return false; } }; } // namespace __equal inline namespace __cpo { - inline constexpr auto equal = __equal::__fn{}; +inline constexpr auto equal = __equal::__fn{}; } // namespace __cpo } // namespace ranges @@ -95,4 +104,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_EQUAL_H diff --git a/third_party/libcxx/__algorithm/ranges_equal_range.h b/third_party/libcxx/__algorithm/ranges_equal_range.h index 075634ae9..4a308e016 100644 --- a/third_party/libcxx/__algorithm/ranges_equal_range.h +++ b/third_party/libcxx/__algorithm/ranges_equal_range.h @@ -1,6 +1,6 @@ //===----------------------------------------------------------------------===// // -// Part of the LLVM __project, under the Apache License v2.0 with LLVM Exceptions. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // @@ -30,6 +30,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -38,28 +41,25 @@ namespace ranges { namespace __equal_range { struct __fn { - template < - forward_iterator _Iter, - sentinel_for<_Iter> _Sent, - class _Tp, - class _Proj = identity, - indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> + template _Sent, + class _Tp, + class _Proj = identity, + indirect_strict_weak_order> _Comp = ranges::less> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> operator()(_Iter __first, _Sent __last, const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const { - auto __ret = std::__equal_range<_RangeAlgPolicy>( - std::move(__first), std::move(__last), __value, __comp, __proj); + auto __ret = std::__equal_range<_RangeAlgPolicy>(std::move(__first), std::move(__last), __value, __comp, __proj); return {std::move(__ret.first), std::move(__ret.second)}; } - template < - forward_range _Range, - class _Tp, - class _Proj = identity, - indirect_strict_weak_order, _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> + template , _Proj>> _Comp = ranges::less> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> operator()(_Range&& __range, const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const { - auto __ret = std::__equal_range<_RangeAlgPolicy>( - ranges::begin(__range), ranges::end(__range), __value, __comp, __proj); + auto __ret = + std::__equal_range<_RangeAlgPolicy>(ranges::begin(__range), ranges::end(__range), __value, __comp, __proj); return {std::move(__ret.first), std::move(__ret.second)}; } }; @@ -67,7 +67,7 @@ struct __fn { } // namespace __equal_range inline namespace __cpo { - inline constexpr auto equal_range = __equal_range::__fn{}; +inline constexpr auto equal_range = __equal_range::__fn{}; } // namespace __cpo } // namespace ranges @@ -75,4 +75,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_EQUAL_RANGE_H diff --git a/third_party/libcxx/__algorithm/ranges_fill.h b/third_party/libcxx/__algorithm/ranges_fill.h index 4e0594c6d..7a177d85e 100644 --- a/third_party/libcxx/__algorithm/ranges_fill.h +++ b/third_party/libcxx/__algorithm/ranges_fill.h @@ -20,6 +20,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -28,9 +31,8 @@ namespace ranges { namespace __fill { struct __fn { template _Iter, sentinel_for<_Iter> _Sent> - _LIBCPP_HIDE_FROM_ABI constexpr - _Iter operator()(_Iter __first, _Sent __last, const _Type& __value) const { - if constexpr(random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>) { + _LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(_Iter __first, _Sent __last, const _Type& __value) const { + if constexpr (random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>) { return ranges::fill_n(__first, __last - __first, __value); } else { for (; __first != __last; ++__first) @@ -40,15 +42,14 @@ struct __fn { } template _Range> - _LIBCPP_HIDE_FROM_ABI constexpr - borrowed_iterator_t<_Range> operator()(_Range&& __range, const _Type& __value) const { + _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> operator()(_Range&& __range, const _Type& __value) const { return (*this)(ranges::begin(__range), ranges::end(__range), __value); } }; } // namespace __fill inline namespace __cpo { - inline constexpr auto fill = __fill::__fn{}; +inline constexpr auto fill = __fill::__fn{}; } // namespace __cpo } // namespace ranges @@ -56,4 +57,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_FILL_H diff --git a/third_party/libcxx/__algorithm/ranges_fill_n.h b/third_party/libcxx/__algorithm/ranges_fill_n.h index c5f7e6ead..a6e988c00 100644 --- a/third_party/libcxx/__algorithm/ranges_fill_n.h +++ b/third_party/libcxx/__algorithm/ranges_fill_n.h @@ -17,6 +17,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -25,8 +28,8 @@ namespace ranges { namespace __fill_n { struct __fn { template _Iter> - _LIBCPP_HIDE_FROM_ABI constexpr - _Iter operator()(_Iter __first, iter_difference_t<_Iter> __n, const _Type& __value) const { + _LIBCPP_HIDE_FROM_ABI constexpr _Iter + operator()(_Iter __first, iter_difference_t<_Iter> __n, const _Type& __value) const { for (; __n != 0; --__n) { *__first = __value; ++__first; @@ -37,7 +40,7 @@ struct __fn { } // namespace __fill_n inline namespace __cpo { - inline constexpr auto fill_n = __fill_n::__fn{}; +inline constexpr auto fill_n = __fill_n::__fn{}; } // namespace __cpo } // namespace ranges @@ -45,4 +48,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_FILL_N_H diff --git a/third_party/libcxx/__algorithm/ranges_find.h b/third_party/libcxx/__algorithm/ranges_find.h index 084cdfff0..6b0d5efe3 100644 --- a/third_party/libcxx/__algorithm/ranges_find.h +++ b/third_party/libcxx/__algorithm/ranges_find.h @@ -28,6 +28,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -41,30 +44,30 @@ struct __fn { if constexpr (forward_iterator<_Iter>) { auto [__first_un, __last_un] = std::__unwrap_range(__first, std::move(__last)); return std::__rewrap_range<_Sent>( - std::move(__first), std::__find_impl(std::move(__first_un), std::move(__last_un), __value, __proj)); + std::move(__first), std::__find(std::move(__first_un), std::move(__last_un), __value, __proj)); } else { - return std::__find_impl(std::move(__first), std::move(__last), __value, __proj); + return std::__find(std::move(__first), std::move(__last), __value, __proj); } } template _Sp, class _Tp, class _Proj = identity> requires indirect_binary_predicate, const _Tp*> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - _Ip operator()(_Ip __first, _Sp __last, const _Tp& __value, _Proj __proj = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Ip + operator()(_Ip __first, _Sp __last, const _Tp& __value, _Proj __proj = {}) const { return __find_unwrap(std::move(__first), std::move(__last), __value, __proj); } template requires indirect_binary_predicate, _Proj>, const _Tp*> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - borrowed_iterator_t<_Rp> operator()(_Rp&& __r, const _Tp& __value, _Proj __proj = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp> + operator()(_Rp&& __r, const _Tp& __value, _Proj __proj = {}) const { return __find_unwrap(ranges::begin(__r), ranges::end(__r), __value, __proj); } }; } // namespace __find inline namespace __cpo { - inline constexpr auto find = __find::__fn{}; +inline constexpr auto find = __find::__fn{}; } // namespace __cpo } // namespace ranges @@ -72,4 +75,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_FIND_H diff --git a/third_party/libcxx/__algorithm/ranges_find_end.h b/third_party/libcxx/__algorithm/ranges_find_end.h index 2d46e8c38..e49e66dd4 100644 --- a/third_party/libcxx/__algorithm/ranges_find_end.h +++ b/third_party/libcxx/__algorithm/ranges_find_end.h @@ -27,6 +27,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -34,18 +37,22 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __find_end { struct __fn { - template _Sent1, - forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2, - class _Pred = ranges::equal_to, + template _Sent1, + forward_iterator _Iter2, + sentinel_for<_Iter2> _Sent2, + class _Pred = ranges::equal_to, class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - subrange<_Iter1> operator()(_Iter1 __first1, _Sent1 __last1, - _Iter2 __first2, _Sent2 __last2, - _Pred __pred = {}, - _Proj1 __proj1 = {}, - _Proj2 __proj2 = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter1> operator()( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Pred __pred = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { auto __ret = std::__find_end_impl<_RangeAlgPolicy>( __first1, __last1, @@ -61,16 +68,12 @@ struct __fn { template requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - borrowed_subrange_t<_Range1> operator()(_Range1&& __range1, - _Range2&& __range2, - _Pred __pred = {}, - _Proj1 __proj1 = {}, - _Proj2 __proj2 = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range1> operator()( + _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { auto __ret = std::__find_end_impl<_RangeAlgPolicy>( ranges::begin(__range1), ranges::end(__range1), @@ -87,7 +90,7 @@ struct __fn { } // namespace __find_end inline namespace __cpo { - inline constexpr auto find_end = __find_end::__fn{}; +inline constexpr auto find_end = __find_end::__fn{}; } // namespace __cpo } // namespace ranges @@ -95,4 +98,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_FIND_END_H diff --git a/third_party/libcxx/__algorithm/ranges_find_first_of.h b/third_party/libcxx/__algorithm/ranges_find_first_of.h index 5699583ba..d92d9686b 100644 --- a/third_party/libcxx/__algorithm/ranges_find_first_of.h +++ b/third_party/libcxx/__algorithm/ranges_find_first_of.h @@ -24,6 +24,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -31,14 +34,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __find_first_of { struct __fn { - template - _LIBCPP_HIDE_FROM_ABI constexpr static - _Iter1 __find_first_of_impl(_Iter1 __first1, _Sent1 __last1, - _Iter2 __first2, _Sent2 __last2, - _Pred& __pred, - _Proj1& __proj1, - _Proj2& __proj2) { + _LIBCPP_HIDE_FROM_ABI constexpr static _Iter1 __find_first_of_impl( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Pred& __pred, + _Proj1& __proj1, + _Proj2& __proj2) { for (; __first1 != __last1; ++__first1) { for (auto __j = __first2; __j != __last2; ++__j) { if (std::invoke(__pred, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__j))) @@ -48,49 +52,48 @@ struct __fn { return __first1; } - template _Sent1, - forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2, - class _Pred = ranges::equal_to, + template _Sent1, + forward_iterator _Iter2, + sentinel_for<_Iter2> _Sent2, + class _Pred = ranges::equal_to, class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - _Iter1 operator()(_Iter1 __first1, _Sent1 __last1, - _Iter2 __first2, _Sent2 __last2, - _Pred __pred = {}, - _Proj1 __proj1 = {}, - _Proj2 __proj2 = {}) const { - return __find_first_of_impl(std::move(__first1), std::move(__last1), - std::move(__first2), std::move(__last2), - __pred, - __proj1, - __proj2); + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Iter1 operator()( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Pred __pred = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + return __find_first_of_impl( + std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __pred, __proj1, __proj2); } template requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - borrowed_iterator_t<_Range1> operator()(_Range1&& __range1, - _Range2&& __range2, - _Pred __pred = {}, - _Proj1 __proj1 = {}, - _Proj2 __proj2 = {}) const { - return __find_first_of_impl(ranges::begin(__range1), ranges::end(__range1), - ranges::begin(__range2), ranges::end(__range2), - __pred, - __proj1, - __proj2); + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range1> operator()( + _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { + return __find_first_of_impl( + ranges::begin(__range1), + ranges::end(__range1), + ranges::begin(__range2), + ranges::end(__range2), + __pred, + __proj1, + __proj2); } - }; } // namespace __find_first_of inline namespace __cpo { - inline constexpr auto find_first_of = __find_first_of::__fn{}; +inline constexpr auto find_first_of = __find_first_of::__fn{}; } // namespace __cpo } // namespace ranges @@ -98,4 +101,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_FIND_FIRST_OF_H diff --git a/third_party/libcxx/__algorithm/ranges_find_if.h b/third_party/libcxx/__algorithm/ranges_find_if.h index 6e2bd4c3d..888f9ec3c 100644 --- a/third_party/libcxx/__algorithm/ranges_find_if.h +++ b/third_party/libcxx/__algorithm/ranges_find_if.h @@ -24,6 +24,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -31,8 +34,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { template -_LIBCPP_HIDE_FROM_ABI constexpr -_Ip __find_if_impl(_Ip __first, _Sp __last, _Pred& __pred, _Proj& __proj) { +_LIBCPP_HIDE_FROM_ABI constexpr _Ip __find_if_impl(_Ip __first, _Sp __last, _Pred& __pred, _Proj& __proj) { for (; __first != __last; ++__first) { if (std::invoke(__pred, std::invoke(__proj, *__first))) break; @@ -42,25 +44,25 @@ _Ip __find_if_impl(_Ip __first, _Sp __last, _Pred& __pred, _Proj& __proj) { namespace __find_if { struct __fn { - - template _Sp, class _Proj = identity, + template _Sp, + class _Proj = identity, indirect_unary_predicate> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - _Ip operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Ip + operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const { return ranges::__find_if_impl(std::move(__first), std::move(__last), __pred, __proj); } - template , _Proj>> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const { + template , _Proj>> _Pred> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp> + operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const { return ranges::__find_if_impl(ranges::begin(__r), ranges::end(__r), __pred, __proj); } }; } // namespace __find_if inline namespace __cpo { - inline constexpr auto find_if = __find_if::__fn{}; +inline constexpr auto find_if = __find_if::__fn{}; } // namespace __cpo } // namespace ranges @@ -68,4 +70,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_FIND_IF_H diff --git a/third_party/libcxx/__algorithm/ranges_find_if_not.h b/third_party/libcxx/__algorithm/ranges_find_if_not.h index e60ee2b49..ec19545b5 100644 --- a/third_party/libcxx/__algorithm/ranges_find_if_not.h +++ b/third_party/libcxx/__algorithm/ranges_find_if_not.h @@ -26,6 +26,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -33,26 +36,27 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __find_if_not { struct __fn { - template _Sp, class _Proj = identity, + template _Sp, + class _Proj = identity, indirect_unary_predicate> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - _Ip operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const { - auto __pred2 = [&](auto&& __e) { return !std::invoke(__pred, std::forward(__e)); }; + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Ip + operator()(_Ip __first, _Sp __last, _Pred __pred, _Proj __proj = {}) const { + auto __pred2 = [&](auto&& __e) -> bool { return !std::invoke(__pred, std::forward(__e)); }; return ranges::__find_if_impl(std::move(__first), std::move(__last), __pred2, __proj); } - template , _Proj>> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const { - auto __pred2 = [&](auto&& __e) { return !std::invoke(__pred, std::forward(__e)); }; + template , _Proj>> _Pred> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp> + operator()(_Rp&& __r, _Pred __pred, _Proj __proj = {}) const { + auto __pred2 = [&](auto&& __e) -> bool { return !std::invoke(__pred, std::forward(__e)); }; return ranges::__find_if_impl(ranges::begin(__r), ranges::end(__r), __pred2, __proj); } }; } // namespace __find_if_not inline namespace __cpo { - inline constexpr auto find_if_not = __find_if_not::__fn{}; +inline constexpr auto find_if_not = __find_if_not::__fn{}; } // namespace __cpo } // namespace ranges @@ -60,4 +64,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_FIND_IF_NOT_H diff --git a/third_party/libcxx/__algorithm/ranges_find_last.h b/third_party/libcxx/__algorithm/ranges_find_last.h new file mode 100644 index 000000000..95f7e77b8 --- /dev/null +++ b/third_party/libcxx/__algorithm/ranges_find_last.h @@ -0,0 +1,175 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_RANGES_FIND_LAST_H +#define _LIBCPP___ALGORITHM_RANGES_FIND_LAST_H + +#include <__config> +#include <__functional/identity.h> +#include <__functional/invoke.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/indirectly_comparable.h> +#include <__iterator/next.h> +#include <__iterator/prev.h> +#include <__iterator/projected.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/subrange.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +#if _LIBCPP_STD_VER >= 23 + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace ranges { + +template +_LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> +__find_last_impl(_Iter __first, _Sent __last, _Pred __pred, _Proj& __proj) { + if (__first == __last) { + return subrange<_Iter>(__first, __first); + } + + if constexpr (bidirectional_iterator<_Iter>) { + auto __last_it = ranges::next(__first, __last); + for (auto __it = ranges::prev(__last_it); __it != __first; --__it) { + if (__pred(std::invoke(__proj, *__it))) { + return subrange<_Iter>(std::move(__it), std::move(__last_it)); + } + } + if (__pred(std::invoke(__proj, *__first))) { + return subrange<_Iter>(std::move(__first), std::move(__last_it)); + } + return subrange<_Iter>(__last_it, __last_it); + } else { + bool __found = false; + _Iter __found_it; + for (; __first != __last; ++__first) { + if (__pred(std::invoke(__proj, *__first))) { + __found = true; + __found_it = __first; + } + } + + if (__found) { + return subrange<_Iter>(std::move(__found_it), std::move(__first)); + } else { + return subrange<_Iter>(__first, __first); + } + } +} + +namespace __find_last { +struct __fn { + template + struct __op { + const _Type& __value; + template + _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator()(_Elem&& __elem) const { + return std::forward<_Elem>(__elem) == __value; + } + }; + + template _Sent, class _Type, class _Proj = identity> + requires indirect_binary_predicate, const _Type*> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr static subrange<_Iter> + operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) { + return ranges::__find_last_impl(std::move(__first), std::move(__last), __op<_Type>{__value}, __proj); + } + + template + requires indirect_binary_predicate, _Proj>, const _Type*> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr static borrowed_subrange_t<_Range> + operator()(_Range&& __range, const _Type& __value, _Proj __proj = {}) { + return ranges::__find_last_impl(ranges::begin(__range), ranges::end(__range), __op<_Type>{__value}, __proj); + } +}; +} // namespace __find_last + +namespace __find_last_if { +struct __fn { + template + struct __op { + _Pred& __pred; + template + _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator()(_Elem&& __elem) const { + return std::invoke(__pred, std::forward<_Elem>(__elem)); + } + }; + + template _Sent, + class _Proj = identity, + indirect_unary_predicate> _Pred> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr static subrange<_Iter> + operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) { + return ranges::__find_last_impl(std::move(__first), std::move(__last), __op<_Pred>{__pred}, __proj); + } + + template , _Proj>> _Pred> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr static borrowed_subrange_t<_Range> + operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) { + return ranges::__find_last_impl(ranges::begin(__range), ranges::end(__range), __op<_Pred>{__pred}, __proj); + } +}; +} // namespace __find_last_if + +namespace __find_last_if_not { +struct __fn { + template + struct __op { + _Pred& __pred; + template + _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator()(_Elem&& __elem) const { + return !std::invoke(__pred, std::forward<_Elem>(__elem)); + } + }; + + template _Sent, + class _Proj = identity, + indirect_unary_predicate> _Pred> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr static subrange<_Iter> + operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) { + return ranges::__find_last_impl(std::move(__first), std::move(__last), __op<_Pred>{__pred}, __proj); + } + + template , _Proj>> _Pred> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr static borrowed_subrange_t<_Range> + operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) { + return ranges::__find_last_impl(ranges::begin(__range), ranges::end(__range), __op<_Pred>{__pred}, __proj); + } +}; +} // namespace __find_last_if_not + +inline namespace __cpo { +inline constexpr auto find_last = __find_last::__fn{}; +inline constexpr auto find_last_if = __find_last_if::__fn{}; +inline constexpr auto find_last_if_not = __find_last_if_not::__fn{}; +} // namespace __cpo +} // namespace ranges + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER >= 23 + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___ALGORITHM_RANGES_FIND_LAST_H diff --git a/third_party/libcxx/__algorithm/ranges_for_each.h b/third_party/libcxx/__algorithm/ranges_for_each.h index a72f77963..225dc774c 100644 --- a/third_party/libcxx/__algorithm/ranges_for_each.h +++ b/third_party/libcxx/__algorithm/ranges_for_each.h @@ -24,6 +24,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -37,37 +40,35 @@ namespace __for_each { struct __fn { private: template - _LIBCPP_HIDE_FROM_ABI constexpr static - for_each_result<_Iter, _Func> __for_each_impl(_Iter __first, _Sent __last, _Func& __func, _Proj& __proj) { + _LIBCPP_HIDE_FROM_ABI constexpr static for_each_result<_Iter, _Func> + __for_each_impl(_Iter __first, _Sent __last, _Func& __func, _Proj& __proj) { for (; __first != __last; ++__first) std::invoke(__func, std::invoke(__proj, *__first)); return {std::move(__first), std::move(__func)}; } public: - template _Sent, + template _Sent, class _Proj = identity, indirectly_unary_invocable> _Func> - _LIBCPP_HIDE_FROM_ABI constexpr - for_each_result<_Iter, _Func> operator()(_Iter __first, _Sent __last, _Func __func, _Proj __proj = {}) const { + _LIBCPP_HIDE_FROM_ABI constexpr for_each_result<_Iter, _Func> + operator()(_Iter __first, _Sent __last, _Func __func, _Proj __proj = {}) const { return __for_each_impl(std::move(__first), std::move(__last), __func, __proj); } template , _Proj>> _Func> - _LIBCPP_HIDE_FROM_ABI constexpr - for_each_result, _Func> operator()(_Range&& __range, - _Func __func, - _Proj __proj = {}) const { + _LIBCPP_HIDE_FROM_ABI constexpr for_each_result, _Func> + operator()(_Range&& __range, _Func __func, _Proj __proj = {}) const { return __for_each_impl(ranges::begin(__range), ranges::end(__range), __func, __proj); } - }; } // namespace __for_each inline namespace __cpo { - inline constexpr auto for_each = __for_each::__fn{}; +inline constexpr auto for_each = __for_each::__fn{}; } // namespace __cpo } // namespace ranges @@ -75,4 +76,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_FOR_EACH_H diff --git a/third_party/libcxx/__algorithm/ranges_for_each_n.h b/third_party/libcxx/__algorithm/ranges_for_each_n.h index daf0a5d82..d1fdca34c 100644 --- a/third_party/libcxx/__algorithm/ranges_for_each_n.h +++ b/third_party/libcxx/__algorithm/ranges_for_each_n.h @@ -24,6 +24,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -35,27 +38,20 @@ using for_each_n_result = in_fun_result<_Iter, _Func>; namespace __for_each_n { struct __fn { - - template > _Func> - _LIBCPP_HIDE_FROM_ABI constexpr - for_each_n_result<_Iter, _Func> operator()(_Iter __first, - iter_difference_t<_Iter> __count, - _Func __func, - _Proj __proj = {}) const { + template > _Func> + _LIBCPP_HIDE_FROM_ABI constexpr for_each_n_result<_Iter, _Func> + operator()(_Iter __first, iter_difference_t<_Iter> __count, _Func __func, _Proj __proj = {}) const { while (__count-- > 0) { std::invoke(__func, std::invoke(__proj, *__first)); ++__first; } return {std::move(__first), std::move(__func)}; } - }; } // namespace __for_each_n inline namespace __cpo { - inline constexpr auto for_each_n = __for_each_n::__fn{}; +inline constexpr auto for_each_n = __for_each_n::__fn{}; } // namespace __cpo } // namespace ranges @@ -63,4 +59,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_FOR_EACH_N_H diff --git a/third_party/libcxx/__algorithm/ranges_generate.h b/third_party/libcxx/__algorithm/ranges_generate.h index de0db1665..e6467198e 100644 --- a/third_party/libcxx/__algorithm/ranges_generate.h +++ b/third_party/libcxx/__algorithm/ranges_generate.h @@ -24,6 +24,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -32,10 +35,8 @@ namespace ranges { namespace __generate { struct __fn { - template - _LIBCPP_HIDE_FROM_ABI constexpr - static _OutIter __generate_fn_impl(_OutIter __first, _Sent __last, _Func& __gen) { + _LIBCPP_HIDE_FROM_ABI constexpr static _OutIter __generate_fn_impl(_OutIter __first, _Sent __last, _Func& __gen) { for (; __first != __last; ++__first) { *__first = __gen(); } @@ -44,25 +45,22 @@ struct __fn { } template _Sent, copy_constructible _Func> - requires invocable<_Func&> && indirectly_writable<_OutIter, invoke_result_t<_Func&>> - _LIBCPP_HIDE_FROM_ABI constexpr - _OutIter operator()(_OutIter __first, _Sent __last, _Func __gen) const { + requires invocable<_Func&> && indirectly_writable<_OutIter, invoke_result_t<_Func&>> + _LIBCPP_HIDE_FROM_ABI constexpr _OutIter operator()(_OutIter __first, _Sent __last, _Func __gen) const { return __generate_fn_impl(std::move(__first), std::move(__last), __gen); } template - requires invocable<_Func&> && output_range<_Range, invoke_result_t<_Func&>> - _LIBCPP_HIDE_FROM_ABI constexpr - borrowed_iterator_t<_Range> operator()(_Range&& __range, _Func __gen) const { + requires invocable<_Func&> && output_range<_Range, invoke_result_t<_Func&>> + _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> operator()(_Range&& __range, _Func __gen) const { return __generate_fn_impl(ranges::begin(__range), ranges::end(__range), __gen); } - }; } // namespace __generate inline namespace __cpo { - inline constexpr auto generate = __generate::__fn{}; +inline constexpr auto generate = __generate::__fn{}; } // namespace __cpo } // namespace ranges @@ -70,4 +68,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_GENERATE_H diff --git a/third_party/libcxx/__algorithm/ranges_generate_n.h b/third_party/libcxx/__algorithm/ranges_generate_n.h index 122cd8db7..cd5fd7483 100644 --- a/third_party/libcxx/__algorithm/ranges_generate_n.h +++ b/third_party/libcxx/__algorithm/ranges_generate_n.h @@ -25,6 +25,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -33,11 +36,10 @@ namespace ranges { namespace __generate_n { struct __fn { - template - requires invocable<_Func&> && indirectly_writable<_OutIter, invoke_result_t<_Func&>> - _LIBCPP_HIDE_FROM_ABI constexpr - _OutIter operator()(_OutIter __first, iter_difference_t<_OutIter> __n, _Func __gen) const { + requires invocable<_Func&> && indirectly_writable<_OutIter, invoke_result_t<_Func&>> + _LIBCPP_HIDE_FROM_ABI constexpr _OutIter + operator()(_OutIter __first, iter_difference_t<_OutIter> __n, _Func __gen) const { for (; __n > 0; --__n) { *__first = __gen(); ++__first; @@ -45,13 +47,12 @@ struct __fn { return __first; } - }; } // namespace __generate_n inline namespace __cpo { - inline constexpr auto generate_n = __generate_n::__fn{}; +inline constexpr auto generate_n = __generate_n::__fn{}; } // namespace __cpo } // namespace ranges @@ -59,4 +60,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_GENERATE_N_H diff --git a/third_party/libcxx/__algorithm/ranges_includes.h b/third_party/libcxx/__algorithm/ranges_includes.h index 314a92377..c4c3b8ed0 100644 --- a/third_party/libcxx/__algorithm/ranges_includes.h +++ b/third_party/libcxx/__algorithm/ranges_includes.h @@ -27,6 +27,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -35,15 +38,14 @@ namespace ranges { namespace __includes { struct __fn { - template < - input_iterator _Iter1, - sentinel_for<_Iter1> _Sent1, - input_iterator _Iter2, - sentinel_for<_Iter2> _Sent2, - class _Proj1 = identity, - class _Proj2 = identity, - indirect_strict_weak_order, projected<_Iter2, _Proj2>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + template _Sent1, + input_iterator _Iter2, + sentinel_for<_Iter2> _Sent2, + class _Proj1 = identity, + class _Proj2 = identity, + indirect_strict_weak_order, projected<_Iter2, _Proj2>> _Comp = ranges::less> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, @@ -61,14 +63,13 @@ struct __fn { std::move(__proj2)); } - template < - input_range _Range1, - input_range _Range2, - class _Proj1 = identity, - class _Proj2 = identity, - indirect_strict_weak_order, _Proj1>, projected, _Proj2>> - _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + template , _Proj1>, projected, _Proj2>> + _Comp = ranges::less> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( _Range1&& __range1, _Range2&& __range2, _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { return std::__includes( ranges::begin(__range1), @@ -84,7 +85,7 @@ struct __fn { } // namespace __includes inline namespace __cpo { - inline constexpr auto includes = __includes::__fn{}; +inline constexpr auto includes = __includes::__fn{}; } // namespace __cpo } // namespace ranges @@ -92,4 +93,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_INCLUDES_H diff --git a/third_party/libcxx/__algorithm/ranges_inplace_merge.h b/third_party/libcxx/__algorithm/ranges_inplace_merge.h index 8f78975d7..d94c0ad46 100644 --- a/third_party/libcxx/__algorithm/ranges_inplace_merge.h +++ b/third_party/libcxx/__algorithm/ranges_inplace_merge.h @@ -31,6 +31,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -38,43 +41,37 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __inplace_merge { - struct __fn { - template - _LIBCPP_HIDE_FROM_ABI static constexpr auto - __inplace_merge_impl(_Iter __first, _Iter __middle, _Sent __last, _Comp&& __comp, _Proj&& __proj) { - auto __last_iter = ranges::next(__middle, __last); - std::__inplace_merge<_RangeAlgPolicy>( - std::move(__first), std::move(__middle), __last_iter, std::__make_projected(__comp, __proj)); - return __last_iter; - } +struct __fn { + template + _LIBCPP_HIDE_FROM_ABI static constexpr auto + __inplace_merge_impl(_Iter __first, _Iter __middle, _Sent __last, _Comp&& __comp, _Proj&& __proj) { + auto __last_iter = ranges::next(__middle, __last); + std::__inplace_merge<_RangeAlgPolicy>( + std::move(__first), std::move(__middle), __last_iter, std::__make_projected(__comp, __proj)); + return __last_iter; + } - template < - bidirectional_iterator _Iter, - sentinel_for<_Iter> _Sent, - class _Comp = ranges::less, - class _Proj = identity> - requires sortable<_Iter, _Comp, _Proj> - _LIBCPP_HIDE_FROM_ABI _Iter - operator()(_Iter __first, _Iter __middle, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { - return __inplace_merge_impl( - std::move(__first), std::move(__middle), std::move(__last), std::move(__comp), std::move(__proj)); - } + template _Sent, class _Comp = ranges::less, class _Proj = identity> + requires sortable<_Iter, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI _Iter + operator()(_Iter __first, _Iter __middle, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + return __inplace_merge_impl( + std::move(__first), std::move(__middle), std::move(__last), std::move(__comp), std::move(__proj)); + } - template - requires sortable< - iterator_t<_Range>, - _Comp, - _Proj> _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_Range> - operator()(_Range&& __range, iterator_t<_Range> __middle, _Comp __comp = {}, _Proj __proj = {}) const { - return __inplace_merge_impl( - ranges::begin(__range), std::move(__middle), ranges::end(__range), std::move(__comp), std::move(__proj)); - } - }; + template + requires sortable, _Comp, _Proj> + _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_Range> + operator()(_Range&& __range, iterator_t<_Range> __middle, _Comp __comp = {}, _Proj __proj = {}) const { + return __inplace_merge_impl( + ranges::begin(__range), std::move(__middle), ranges::end(__range), std::move(__comp), std::move(__proj)); + } +}; } // namespace __inplace_merge inline namespace __cpo { - inline constexpr auto inplace_merge = __inplace_merge::__fn{}; +inline constexpr auto inplace_merge = __inplace_merge::__fn{}; } // namespace __cpo } // namespace ranges @@ -82,4 +79,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_INPLACE_MERGE_H diff --git a/third_party/libcxx/__algorithm/ranges_is_heap.h b/third_party/libcxx/__algorithm/ranges_is_heap.h index 9c77e0c3f..3d9e18ce1 100644 --- a/third_party/libcxx/__algorithm/ranges_is_heap.h +++ b/third_party/libcxx/__algorithm/ranges_is_heap.h @@ -26,6 +26,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -34,28 +37,30 @@ namespace ranges { namespace __is_heap { struct __fn { - template - _LIBCPP_HIDE_FROM_ABI constexpr - static bool __is_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { - auto __last_iter = ranges::next(__first, __last); + _LIBCPP_HIDE_FROM_ABI constexpr static bool + __is_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { + auto __last_iter = ranges::next(__first, __last); auto&& __projected_comp = std::__make_projected(__comp, __proj); auto __result = std::__is_heap_until(std::move(__first), std::move(__last_iter), __projected_comp); return __result == __last; } - template _Sent, class _Proj = identity, + template _Sent, + class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - bool operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool + operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { return __is_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj); } - template , _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - bool operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool + operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { return __is_heap_fn_impl(ranges::begin(__range), ranges::end(__range), __comp, __proj); } }; @@ -63,7 +68,7 @@ struct __fn { } // namespace __is_heap inline namespace __cpo { - inline constexpr auto is_heap = __is_heap::__fn{}; +inline constexpr auto is_heap = __is_heap::__fn{}; } // namespace __cpo } // namespace ranges @@ -71,4 +76,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_IS_HEAP_H diff --git a/third_party/libcxx/__algorithm/ranges_is_heap_until.h b/third_party/libcxx/__algorithm/ranges_is_heap_until.h index 3b1fec758..7a2e1fc77 100644 --- a/third_party/libcxx/__algorithm/ranges_is_heap_until.h +++ b/third_party/libcxx/__algorithm/ranges_is_heap_until.h @@ -27,6 +27,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -35,36 +38,37 @@ namespace ranges { namespace __is_heap_until { struct __fn { - template - _LIBCPP_HIDE_FROM_ABI constexpr - static _Iter __is_heap_until_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { - auto __last_iter = ranges::next(__first, __last); + _LIBCPP_HIDE_FROM_ABI constexpr static _Iter + __is_heap_until_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { + auto __last_iter = ranges::next(__first, __last); auto&& __projected_comp = std::__make_projected(__comp, __proj); return std::__is_heap_until(std::move(__first), std::move(__last_iter), __projected_comp); } - template _Sent, class _Proj = identity, + template _Sent, + class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Iter + operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { return __is_heap_until_fn_impl(std::move(__first), std::move(__last), __comp, __proj); } - template , _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - borrowed_iterator_t<_Range> operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> + operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { return __is_heap_until_fn_impl(ranges::begin(__range), ranges::end(__range), __comp, __proj); } - }; } // namespace __is_heap_until inline namespace __cpo { - inline constexpr auto is_heap_until = __is_heap_until::__fn{}; +inline constexpr auto is_heap_until = __is_heap_until::__fn{}; } // namespace __cpo } // namespace ranges @@ -72,4 +76,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_IS_HEAP_UNTIL_H diff --git a/third_party/libcxx/__algorithm/ranges_is_partitioned.h b/third_party/libcxx/__algorithm/ranges_is_partitioned.h index 6782717cc..5be6fba46 100644 --- a/third_party/libcxx/__algorithm/ranges_is_partitioned.h +++ b/third_party/libcxx/__algorithm/ranges_is_partitioned.h @@ -23,6 +23,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -30,10 +33,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __is_partitioned { struct __fn { - template - _LIBCPP_HIDE_FROM_ABI constexpr static - bool __is_parititioned_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { + _LIBCPP_HIDE_FROM_ABI constexpr static bool + __is_partitioned_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { for (; __first != __last; ++__first) { if (!std::invoke(__pred, std::invoke(__proj, *__first))) break; @@ -51,26 +53,27 @@ struct __fn { return true; } - template _Sent, + template _Sent, class _Proj = identity, indirect_unary_predicate> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - bool operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { - return __is_parititioned_impl(std::move(__first), std::move(__last), __pred, __proj); + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool + operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { + return __is_partitioned_impl(std::move(__first), std::move(__last), __pred, __proj); } template , _Proj>> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { - return __is_parititioned_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool + operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { + return __is_partitioned_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); } }; } // namespace __is_partitioned inline namespace __cpo { - inline constexpr auto is_partitioned = __is_partitioned::__fn{}; +inline constexpr auto is_partitioned = __is_partitioned::__fn{}; } // namespace __cpo } // namespace ranges @@ -78,4 +81,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_IS_PARTITIONED_H diff --git a/third_party/libcxx/__algorithm/ranges_is_permutation.h b/third_party/libcxx/__algorithm/ranges_is_permutation.h index 95a0a8251..1f8d67007 100644 --- a/third_party/libcxx/__algorithm/ranges_is_permutation.h +++ b/third_party/libcxx/__algorithm/ranges_is_permutation.h @@ -25,6 +25,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -32,53 +35,66 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __is_permutation { struct __fn { - - template - _LIBCPP_HIDE_FROM_ABI constexpr static - bool __is_permutation_func_impl(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, - _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) { + template + _LIBCPP_HIDE_FROM_ABI constexpr static bool __is_permutation_func_impl( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Pred& __pred, + _Proj1& __proj1, + _Proj2& __proj2) { return std::__is_permutation<_RangeAlgPolicy>( - std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), - __pred, __proj1, __proj2); + std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __pred, __proj1, __proj2); } - template _Sent1, - forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2, - class _Proj1 = identity, - class _Proj2 = identity, - indirect_equivalence_relation, - projected<_Iter2, _Proj2>> _Pred = ranges::equal_to> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - bool operator()(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, - _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { + template < + forward_iterator _Iter1, + sentinel_for<_Iter1> _Sent1, + forward_iterator _Iter2, + sentinel_for<_Iter2> _Sent2, + class _Proj1 = identity, + class _Proj2 = identity, + indirect_equivalence_relation, projected<_Iter2, _Proj2>> _Pred = ranges::equal_to> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Pred __pred = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { return __is_permutation_func_impl( - std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), - __pred, __proj1, __proj2); + std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __pred, __proj1, __proj2); } template , _Proj1>, projected, _Proj2>> _Pred = ranges::equal_to> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - bool operator()(_Range1&& __range1, _Range2&& __range2, - _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { + class _Proj1 = identity, + class _Proj2 = identity, + indirect_equivalence_relation, _Proj1>, + projected, _Proj2>> _Pred = ranges::equal_to> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { if constexpr (sized_range<_Range1> && sized_range<_Range2>) { if (ranges::distance(__range1) != ranges::distance(__range2)) return false; } return __is_permutation_func_impl( - ranges::begin(__range1), ranges::end(__range1), ranges::begin(__range2), ranges::end(__range2), - __pred, __proj1, __proj2); + ranges::begin(__range1), + ranges::end(__range1), + ranges::begin(__range2), + ranges::end(__range2), + __pred, + __proj1, + __proj2); } }; } // namespace __is_permutation inline namespace __cpo { - inline constexpr auto is_permutation = __is_permutation::__fn{}; +inline constexpr auto is_permutation = __is_permutation::__fn{}; } // namespace __cpo } // namespace ranges @@ -86,4 +102,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_IS_PERMUTATION_H diff --git a/third_party/libcxx/__algorithm/ranges_is_sorted.h b/third_party/libcxx/__algorithm/ranges_is_sorted.h index 50c97baa8..5b88d422b 100644 --- a/third_party/libcxx/__algorithm/ranges_is_sorted.h +++ b/third_party/libcxx/__algorithm/ranges_is_sorted.h @@ -23,6 +23,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -30,19 +33,20 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __is_sorted { struct __fn { - template _Sent, - class _Proj = identity, + template _Sent, + class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - bool operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool + operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { return ranges::__is_sorted_until_impl(std::move(__first), __last, __comp, __proj) == __last; } template , _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - bool operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool + operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { auto __last = ranges::end(__range); return ranges::__is_sorted_until_impl(ranges::begin(__range), __last, __comp, __proj) == __last; } @@ -50,7 +54,7 @@ struct __fn { } // namespace __is_sorted inline namespace __cpo { - inline constexpr auto is_sorted = __is_sorted::__fn{}; +inline constexpr auto is_sorted = __is_sorted::__fn{}; } // namespace __cpo } // namespace ranges @@ -58,4 +62,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP__ALGORITHM_RANGES_IS_SORTED_H diff --git a/third_party/libcxx/__algorithm/ranges_is_sorted_until.h b/third_party/libcxx/__algorithm/ranges_is_sorted_until.h index f139d0391..54de530c8 100644 --- a/third_party/libcxx/__algorithm/ranges_is_sorted_until.h +++ b/third_party/libcxx/__algorithm/ranges_is_sorted_until.h @@ -24,6 +24,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -31,8 +34,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { template -_LIBCPP_HIDE_FROM_ABI constexpr -_Iter __is_sorted_until_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { +_LIBCPP_HIDE_FROM_ABI constexpr _Iter +__is_sorted_until_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { if (__first == __last) return __first; auto __i = __first; @@ -46,26 +49,27 @@ _Iter __is_sorted_until_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& namespace __is_sorted_until { struct __fn { - template _Sent, - class _Proj = identity, + template _Sent, + class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Iter + operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { return ranges::__is_sorted_until_impl(std::move(__first), std::move(__last), __comp, __proj); } template , _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - borrowed_iterator_t<_Range> operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> + operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { return ranges::__is_sorted_until_impl(ranges::begin(__range), ranges::end(__range), __comp, __proj); } }; } // namespace __is_sorted_until inline namespace __cpo { - inline constexpr auto is_sorted_until = __is_sorted_until::__fn{}; +inline constexpr auto is_sorted_until = __is_sorted_until::__fn{}; } // namespace __cpo } // namespace ranges @@ -73,4 +77,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP__ALGORITHM_RANGES_IS_SORTED_UNTIL_H diff --git a/third_party/libcxx/__algorithm/ranges_iterator_concept.h b/third_party/libcxx/__algorithm/ranges_iterator_concept.h index 9a9203040..2af891d3a 100644 --- a/third_party/libcxx/__algorithm/ranges_iterator_concept.h +++ b/third_party/libcxx/__algorithm/ranges_iterator_concept.h @@ -18,6 +18,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -48,4 +51,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_ITERATOR_CONCEPT_H diff --git a/third_party/libcxx/__algorithm/ranges_lexicographical_compare.h b/third_party/libcxx/__algorithm/ranges_lexicographical_compare.h index c51f4d7e5..6d82017e3 100644 --- a/third_party/libcxx/__algorithm/ranges_lexicographical_compare.h +++ b/third_party/libcxx/__algorithm/ranges_lexicographical_compare.h @@ -23,6 +23,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -30,17 +33,17 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __lexicographical_compare { struct __fn { - template - _LIBCPP_HIDE_FROM_ABI constexpr static - bool __lexicographical_compare_impl(_Iter1 __first1, _Sent1 __last1, - _Iter2 __first2, _Sent2 __last2, - _Comp& __comp, - _Proj1& __proj1, - _Proj2& __proj2) { + _LIBCPP_HIDE_FROM_ABI constexpr static bool __lexicographical_compare_impl( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Comp& __comp, + _Proj1& __proj1, + _Proj2& __proj2) { while (__first2 != __last2) { - if (__first1 == __last1 - || std::invoke(__comp, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__first2))) + if (__first1 == __last1 || std::invoke(__comp, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__first2))) return true; if (std::invoke(__comp, std::invoke(__proj2, *__first2), std::invoke(__proj1, *__first1))) return false; @@ -50,44 +53,47 @@ struct __fn { return false; } - template _Sent1, - input_iterator _Iter2, sentinel_for<_Iter2> _Sent2, - class _Proj1 = identity, - class _Proj2 = identity, + template _Sent1, + input_iterator _Iter2, + sentinel_for<_Iter2> _Sent2, + class _Proj1 = identity, + class _Proj2 = identity, indirect_strict_weak_order, projected<_Iter2, _Proj2>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - bool operator()(_Iter1 __first1, _Sent1 __last1, - _Iter2 __first2, _Sent2 __last2, - _Comp __comp = {}, - _Proj1 __proj1 = {}, - _Proj2 __proj2 = {}) const { - return __lexicographical_compare_impl(std::move(__first1), std::move(__last1), - std::move(__first2), std::move(__last2), - __comp, - __proj1, - __proj2); + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { + return __lexicographical_compare_impl( + std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __comp, __proj1, __proj2); } template , _Proj1>, - projected, _Proj2>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - bool operator()(_Range1&& __range1, _Range2&& __range2, _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { - return __lexicographical_compare_impl(ranges::begin(__range1), ranges::end(__range1), - ranges::begin(__range2), ranges::end(__range2), - __comp, - __proj1, - __proj2); + indirect_strict_weak_order, _Proj1>, projected, _Proj2>> + _Comp = ranges::less> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + _Range1&& __range1, _Range2&& __range2, _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { + return __lexicographical_compare_impl( + ranges::begin(__range1), + ranges::end(__range1), + ranges::begin(__range2), + ranges::end(__range2), + __comp, + __proj1, + __proj2); } - }; } // namespace __lexicographical_compare inline namespace __cpo { - inline constexpr auto lexicographical_compare = __lexicographical_compare::__fn{}; +inline constexpr auto lexicographical_compare = __lexicographical_compare::__fn{}; } // namespace __cpo } // namespace ranges @@ -95,4 +101,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_LEXICOGRAPHICAL_COMPARE_H diff --git a/third_party/libcxx/__algorithm/ranges_lower_bound.h b/third_party/libcxx/__algorithm/ranges_lower_bound.h index 743563940..0651147e0 100644 --- a/third_party/libcxx/__algorithm/ranges_lower_bound.h +++ b/third_party/libcxx/__algorithm/ranges_lower_bound.h @@ -27,6 +27,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -35,27 +38,29 @@ namespace ranges { namespace __lower_bound { struct __fn { - template _Sent, class _Type, class _Proj = identity, + template _Sent, + class _Type, + class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - _Iter operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { - return std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj); + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Iter + operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { + return std::__lower_bound<_RangeAlgPolicy>(__first, __last, __value, __comp, __proj); } - template , _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - borrowed_iterator_t<_Range> operator()(_Range&& __r, - const _Type& __value, - _Comp __comp = {}, - _Proj __proj = {}) const { - return std::__lower_bound_impl<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), __value, __comp, __proj); + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> + operator()(_Range&& __r, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { + return std::__lower_bound<_RangeAlgPolicy>(ranges::begin(__r), ranges::end(__r), __value, __comp, __proj); } }; } // namespace __lower_bound inline namespace __cpo { - inline constexpr auto lower_bound = __lower_bound::__fn{}; +inline constexpr auto lower_bound = __lower_bound::__fn{}; } // namespace __cpo } // namespace ranges @@ -63,4 +68,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_LOWER_BOUND_H diff --git a/third_party/libcxx/__algorithm/ranges_make_heap.h b/third_party/libcxx/__algorithm/ranges_make_heap.h index 7f92fa310..fe9c024fb 100644 --- a/third_party/libcxx/__algorithm/ranges_make_heap.h +++ b/third_party/libcxx/__algorithm/ranges_make_heap.h @@ -32,6 +32,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -41,8 +44,8 @@ namespace __make_heap { struct __fn { template - _LIBCPP_HIDE_FROM_ABI constexpr static - _Iter __make_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { + _LIBCPP_HIDE_FROM_ABI constexpr static _Iter + __make_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { auto __last_iter = ranges::next(__first, __last); auto&& __projected_comp = std::__make_projected(__comp, __proj); @@ -53,15 +56,15 @@ struct __fn { template _Sent, class _Comp = ranges::less, class _Proj = identity> requires sortable<_Iter, _Comp, _Proj> - _LIBCPP_HIDE_FROM_ABI constexpr - _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + _LIBCPP_HIDE_FROM_ABI constexpr _Iter + operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { return __make_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj); } template requires sortable, _Comp, _Proj> - _LIBCPP_HIDE_FROM_ABI constexpr - borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> + operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { return __make_heap_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); } }; @@ -69,7 +72,7 @@ struct __fn { } // namespace __make_heap inline namespace __cpo { - inline constexpr auto make_heap = __make_heap::__fn{}; +inline constexpr auto make_heap = __make_heap::__fn{}; } // namespace __cpo } // namespace ranges @@ -77,4 +80,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_MAKE_HEAP_H diff --git a/third_party/libcxx/__algorithm/ranges_max.h b/third_party/libcxx/__algorithm/ranges_max.h index 2fd2970bb..d0ee6f314 100644 --- a/third_party/libcxx/__algorithm/ranges_max.h +++ b/third_party/libcxx/__algorithm/ranges_max.h @@ -31,45 +31,51 @@ #if _LIBCPP_STD_VER >= 20 _LIBCPP_PUSH_MACROS -#include <__undef_macros> +# include <__undef_macros> _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __max { struct __fn { - template > _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - const _Tp& operator()(_LIBCPP_LIFETIMEBOUND const _Tp& __a, - _LIBCPP_LIFETIMEBOUND const _Tp& __b, - _Comp __comp = {}, - _Proj __proj = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& + operator()(_LIBCPP_LIFETIMEBOUND const _Tp& __a, + _LIBCPP_LIFETIMEBOUND const _Tp& __b, + _Comp __comp = {}, + _Proj __proj = {}) const { return std::invoke(__comp, std::invoke(__proj, __a), std::invoke(__proj, __b)) ? __b : __a; } - template > _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - _Tp operator()(initializer_list<_Tp> __il, _Comp __comp = {}, _Proj __proj = {}) const { - _LIBCPP_ASSERT(__il.begin() != __il.end(), "initializer_list must contain at least one element"); + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp + operator()(initializer_list<_Tp> __il, _Comp __comp = {}, _Proj __proj = {}) const { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __il.begin() != __il.end(), "initializer_list must contain at least one element"); - auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); }; + auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) -> bool { return std::invoke(__comp, __rhs, __lhs); }; return *ranges::__min_element_impl(__il.begin(), __il.end(), __comp_lhs_rhs_swapped, __proj); } - template , _Proj>> _Comp = ranges::less> requires indirectly_copyable_storable, range_value_t<_Rp>*> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - range_value_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr range_value_t<_Rp> + operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { auto __first = ranges::begin(__r); - auto __last = ranges::end(__r); + auto __last = ranges::end(__r); - _LIBCPP_ASSERT(__first != __last, "range must contain at least one element"); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__first != __last, "range must contain at least one element"); if constexpr (forward_range<_Rp> && !__is_cheap_to_copy>) { - auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); }; + auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) -> bool { + return std::invoke(__comp, __rhs, __lhs); + }; return *ranges::__min_element_impl(std::move(__first), std::move(__last), __comp_lhs_rhs_swapped, __proj); } else { range_value_t<_Rp> __result = *__first; @@ -84,7 +90,7 @@ struct __fn { } // namespace __max inline namespace __cpo { - inline constexpr auto max = __max::__fn{}; +inline constexpr auto max = __max::__fn{}; } // namespace __cpo } // namespace ranges @@ -92,6 +98,6 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP_STD_VER >= 20 && +#endif // _LIBCPP_STD_VER >= 20 #endif // _LIBCPP___ALGORITHM_RANGES_MAX_H diff --git a/third_party/libcxx/__algorithm/ranges_max_element.h b/third_party/libcxx/__algorithm/ranges_max_element.h index 39e86d3b9..c57730927 100644 --- a/third_party/libcxx/__algorithm/ranges_max_element.h +++ b/third_party/libcxx/__algorithm/ranges_max_element.h @@ -24,6 +24,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -31,26 +34,29 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __max_element { struct __fn { - template _Sp, class _Proj = identity, + template _Sp, + class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - _Ip operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const { - auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); }; + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Ip + operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const { + auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) -> bool { return std::invoke(__comp, __rhs, __lhs); }; return ranges::__min_element_impl(__first, __last, __comp_lhs_rhs_swapped, __proj); } - template , _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { - auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) { return std::invoke(__comp, __rhs, __lhs); }; + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp> + operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + auto __comp_lhs_rhs_swapped = [&](auto&& __lhs, auto&& __rhs) -> bool { return std::invoke(__comp, __rhs, __lhs); }; return ranges::__min_element_impl(ranges::begin(__r), ranges::end(__r), __comp_lhs_rhs_swapped, __proj); } }; } // namespace __max_element inline namespace __cpo { - inline constexpr auto max_element = __max_element::__fn{}; +inline constexpr auto max_element = __max_element::__fn{}; } // namespace __cpo } // namespace ranges @@ -58,4 +64,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_MAX_ELEMENT_H diff --git a/third_party/libcxx/__algorithm/ranges_merge.h b/third_party/libcxx/__algorithm/ranges_merge.h index c5797b0e7..bdf9a62d9 100644 --- a/third_party/libcxx/__algorithm/ranges_merge.h +++ b/third_party/libcxx/__algorithm/ranges_merge.h @@ -27,6 +27,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -38,25 +41,25 @@ using merge_result = in_in_out_result<_InIter1, _InIter2, _OutIter>; namespace __merge { -template < - class _InIter1, - class _Sent1, - class _InIter2, - class _Sent2, - class _OutIter, - class _Comp, - class _Proj1, - class _Proj2> -_LIBCPP_HIDE_FROM_ABI constexpr merge_result<__remove_cvref_t<_InIter1>, __remove_cvref_t<_InIter2>, __remove_cvref_t<_OutIter>> -__merge_impl( - _InIter1&& __first1, - _Sent1&& __last1, - _InIter2&& __first2, - _Sent2&& __last2, - _OutIter&& __result, - _Comp&& __comp, - _Proj1&& __proj1, - _Proj2&& __proj2) { +template < class _InIter1, + class _Sent1, + class _InIter2, + class _Sent2, + class _OutIter, + class _Comp, + class _Proj1, + class _Proj2> +_LIBCPP_HIDE_FROM_ABI constexpr merge_result<__remove_cvref_t<_InIter1>, + __remove_cvref_t<_InIter2>, + __remove_cvref_t<_OutIter>> +__merge_impl(_InIter1&& __first1, + _Sent1&& __last1, + _InIter2&& __first2, + _Sent2&& __last2, + _OutIter&& __result, + _Comp&& __comp, + _Proj1&& __proj1, + _Proj2&& __proj2) { for (; __first1 != __last1 && __first2 != __last2; ++__result) { if (std::invoke(__comp, std::invoke(__proj2, *__first2), std::invoke(__proj1, *__first1))) { *__result = *__first2; @@ -72,15 +75,14 @@ __merge_impl( } struct __fn { - template < - input_iterator _InIter1, - sentinel_for<_InIter1> _Sent1, - input_iterator _InIter2, - sentinel_for<_InIter2> _Sent2, - weakly_incrementable _OutIter, - class _Comp = less, - class _Proj1 = identity, - class _Proj2 = identity> + template _Sent1, + input_iterator _InIter2, + sentinel_for<_InIter2> _Sent2, + weakly_incrementable _OutIter, + class _Comp = less, + class _Proj1 = identity, + class _Proj2 = identity> requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2> _LIBCPP_HIDE_FROM_ABI constexpr merge_result<_InIter1, _InIter2, _OutIter> operator()( _InIter1 __first1, @@ -94,28 +96,20 @@ struct __fn { return __merge::__merge_impl(__first1, __last1, __first2, __last2, __result, __comp, __proj1, __proj2); } - template < - input_range _Range1, - input_range _Range2, - weakly_incrementable _OutIter, - class _Comp = less, - class _Proj1 = identity, - class _Proj2 = identity> - requires mergeable< - iterator_t<_Range1>, - iterator_t<_Range2>, - _OutIter, - _Comp, - _Proj1, - _Proj2> + template + requires mergeable, iterator_t<_Range2>, _OutIter, _Comp, _Proj1, _Proj2> _LIBCPP_HIDE_FROM_ABI constexpr merge_result, borrowed_iterator_t<_Range2>, _OutIter> - operator()( - _Range1&& __range1, - _Range2&& __range2, - _OutIter __result, - _Comp __comp = {}, - _Proj1 __proj1 = {}, - _Proj2 __proj2 = {}) const { + operator()(_Range1&& __range1, + _Range2&& __range2, + _OutIter __result, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { return __merge::__merge_impl( ranges::begin(__range1), ranges::end(__range1), @@ -131,7 +125,7 @@ struct __fn { } // namespace __merge inline namespace __cpo { - inline constexpr auto merge = __merge::__fn{}; +inline constexpr auto merge = __merge::__fn{}; } // namespace __cpo } // namespace ranges @@ -139,4 +133,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_MERGE_H diff --git a/third_party/libcxx/__algorithm/ranges_min.h b/third_party/libcxx/__algorithm/ranges_min.h index 5e941a1db..cc569d2a0 100644 --- a/third_party/libcxx/__algorithm/ranges_min.h +++ b/third_party/libcxx/__algorithm/ranges_min.h @@ -30,39 +30,43 @@ #if _LIBCPP_STD_VER >= 20 _LIBCPP_PUSH_MACROS -#include <__undef_macros> +# include <__undef_macros> _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __min { struct __fn { - template > _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - const _Tp& operator()(_LIBCPP_LIFETIMEBOUND const _Tp& __a, - _LIBCPP_LIFETIMEBOUND const _Tp& __b, - _Comp __comp = {}, - _Proj __proj = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& + operator()(_LIBCPP_LIFETIMEBOUND const _Tp& __a, + _LIBCPP_LIFETIMEBOUND const _Tp& __b, + _Comp __comp = {}, + _Proj __proj = {}) const { return std::invoke(__comp, std::invoke(__proj, __b), std::invoke(__proj, __a)) ? __b : __a; } - template > _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - _Tp operator()(initializer_list<_Tp> __il, _Comp __comp = {}, _Proj __proj = {}) const { - _LIBCPP_ASSERT(__il.begin() != __il.end(), "initializer_list must contain at least one element"); + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp + operator()(initializer_list<_Tp> __il, _Comp __comp = {}, _Proj __proj = {}) const { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __il.begin() != __il.end(), "initializer_list must contain at least one element"); return *ranges::__min_element_impl(__il.begin(), __il.end(), __comp, __proj); } - template , _Proj>> _Comp = ranges::less> requires indirectly_copyable_storable, range_value_t<_Rp>*> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - range_value_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr range_value_t<_Rp> + operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { auto __first = ranges::begin(__r); - auto __last = ranges::end(__r); - _LIBCPP_ASSERT(__first != __last, "range must contain at least one element"); + auto __last = ranges::end(__r); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__first != __last, "range must contain at least one element"); if constexpr (forward_range<_Rp> && !__is_cheap_to_copy>) { return *ranges::__min_element_impl(__first, __last, __comp, __proj); } else { @@ -78,7 +82,7 @@ struct __fn { } // namespace __min inline namespace __cpo { - inline constexpr auto min = __min::__fn{}; +inline constexpr auto min = __min::__fn{}; } // namespace __cpo } // namespace ranges @@ -86,6 +90,6 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP_STD_VER >= 20 && +#endif // _LIBCPP_STD_VER >= 20 #endif // _LIBCPP___ALGORITHM_RANGES_MIN_H diff --git a/third_party/libcxx/__algorithm/ranges_min_element.h b/third_party/libcxx/__algorithm/ranges_min_element.h index 4c58adb31..588ef258e 100644 --- a/third_party/libcxx/__algorithm/ranges_min_element.h +++ b/third_party/libcxx/__algorithm/ranges_min_element.h @@ -24,6 +24,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -32,8 +35,7 @@ namespace ranges { // TODO(ranges): `ranges::min_element` can now simply delegate to `std::__min_element`. template -_LIBCPP_HIDE_FROM_ABI constexpr -_Ip __min_element_impl(_Ip __first, _Sp __last, _Comp& __comp, _Proj& __proj) { +_LIBCPP_HIDE_FROM_ABI constexpr _Ip __min_element_impl(_Ip __first, _Sp __last, _Comp& __comp, _Proj& __proj) { if (__first == __last) return __first; @@ -46,24 +48,27 @@ _Ip __min_element_impl(_Ip __first, _Sp __last, _Comp& __comp, _Proj& __proj) { namespace __min_element { struct __fn { - template _Sp, class _Proj = identity, + template _Sp, + class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - _Ip operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Ip + operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const { return ranges::__min_element_impl(__first, __last, __comp, __proj); } - template , _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - borrowed_iterator_t<_Rp> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Rp> + operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { return ranges::__min_element_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); } }; } // namespace __min_element inline namespace __cpo { - inline constexpr auto min_element = __min_element::__fn{}; +inline constexpr auto min_element = __min_element::__fn{}; } // namespace __cpo } // namespace ranges @@ -71,4 +76,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_MIN_ELEMENT_H diff --git a/third_party/libcxx/__algorithm/ranges_minmax.h b/third_party/libcxx/__algorithm/ranges_minmax.h index 2a966bbee..09cbefd91 100644 --- a/third_party/libcxx/__algorithm/ranges_minmax.h +++ b/third_party/libcxx/__algorithm/ranges_minmax.h @@ -23,7 +23,9 @@ #include <__iterator/projected.h> #include <__ranges/access.h> #include <__ranges/concepts.h> +#include <__type_traits/desugars_to.h> #include <__type_traits/is_reference.h> +#include <__type_traits/is_trivially_copyable.h> #include <__type_traits/remove_cvref.h> #include <__utility/forward.h> #include <__utility/move.h> @@ -37,7 +39,7 @@ #if _LIBCPP_STD_VER >= 20 _LIBCPP_PUSH_MACROS -#include <__undef_macros> +# include <__undef_macros> _LIBCPP_BEGIN_NAMESPACE_STD @@ -47,9 +49,10 @@ using minmax_result = min_max_result<_T1>; namespace __minmax { struct __fn { - template > _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_result + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_result operator()(_LIBCPP_LIFETIMEBOUND const _Type& __a, _LIBCPP_LIFETIMEBOUND const _Type& __b, _Comp __comp = {}, @@ -59,27 +62,43 @@ struct __fn { return {__a, __b}; } - template > _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - ranges::minmax_result<_Type> operator()(initializer_list<_Type> __il, _Comp __comp = {}, _Proj __proj = {}) const { - _LIBCPP_ASSERT(__il.begin() != __il.end(), "initializer_list has to contain at least one element"); + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_result<_Type> + operator()(initializer_list<_Type> __il, _Comp __comp = {}, _Proj __proj = {}) const { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __il.begin() != __il.end(), "initializer_list has to contain at least one element"); auto __iters = std::__minmax_element_impl(__il.begin(), __il.end(), __comp, __proj); - return ranges::minmax_result<_Type> { *__iters.first, *__iters.second }; + return ranges::minmax_result<_Type>{*__iters.first, *__iters.second}; } - template , _Proj>> _Comp = ranges::less> requires indirectly_copyable_storable, range_value_t<_Range>*> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - ranges::minmax_result> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { - auto __first = ranges::begin(__r); - auto __last = ranges::end(__r); + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_result> + operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + auto __first = ranges::begin(__r); + auto __last = ranges::end(__r); using _ValueT = range_value_t<_Range>; - _LIBCPP_ASSERT(__first != __last, "range has to contain at least one element"); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__first != __last, "range has to contain at least one element"); - if constexpr (forward_range<_Range>) { + // This optimiation is not in minmax_element because clang doesn't see through the pointers and as a result doesn't + // vectorize the code. + if constexpr (contiguous_range<_Range> && is_integral_v<_ValueT> && + __is_cheap_to_copy<_ValueT> & __is_identity<_Proj>::value && + __desugars_to_v<__less_tag, _Comp, _ValueT, _ValueT>) { + minmax_result<_ValueT> __result = {__r[0], __r[0]}; + for (auto __e : __r) { + if (__e < __result.min) + __result.min = __e; + if (__result.max < __e) + __result.max = __e; + } + return __result; + } else if constexpr (forward_range<_Range>) { // Special-case the one element case. Avoid repeatedly initializing objects from the result of an iterator // dereference when doing so might not be idempotent. The `if constexpr` avoids the extra branch in cases where // it's not needed. @@ -98,8 +117,9 @@ struct __fn { // input_iterators can't be copied, so the implementation for input_iterators has to store // the values instead of a pointer to the correct values auto __less = [&](auto&& __a, auto&& __b) -> bool { - return std::invoke(__comp, std::invoke(__proj, std::forward(__a)), - std::invoke(__proj, std::forward(__b))); + return std::invoke(__comp, + std::invoke(__proj, std::forward(__a)), + std::invoke(__proj, std::forward(__b))); }; // During initialization, members are allowed to refer to already initialized members @@ -142,7 +162,7 @@ struct __fn { } // namespace __minmax inline namespace __cpo { - inline constexpr auto minmax = __minmax::__fn{}; +inline constexpr auto minmax = __minmax::__fn{}; } // namespace __cpo } // namespace ranges diff --git a/third_party/libcxx/__algorithm/ranges_minmax_element.h b/third_party/libcxx/__algorithm/ranges_minmax_element.h index cbf350557..4bf6d2404 100644 --- a/third_party/libcxx/__algorithm/ranges_minmax_element.h +++ b/third_party/libcxx/__algorithm/ranges_minmax_element.h @@ -28,6 +28,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -39,18 +42,20 @@ using minmax_element_result = min_max_result<_T1>; namespace __minmax_element { struct __fn { - template _Sp, class _Proj = identity, + template _Sp, + class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - ranges::minmax_element_result<_Ip> operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_element_result<_Ip> + operator()(_Ip __first, _Sp __last, _Comp __comp = {}, _Proj __proj = {}) const { auto __ret = std::__minmax_element_impl(std::move(__first), std::move(__last), __comp, __proj); return {__ret.first, __ret.second}; } - template , _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - ranges::minmax_element_result> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr ranges::minmax_element_result> operator()(_Rp&& __r, _Comp __comp = {}, _Proj __proj = {}) const { auto __ret = std::__minmax_element_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); return {__ret.first, __ret.second}; @@ -59,7 +64,7 @@ struct __fn { } // namespace __minmax_element inline namespace __cpo { - inline constexpr auto minmax_element = __minmax_element::__fn{}; +inline constexpr auto minmax_element = __minmax_element::__fn{}; } // namespace __cpo } // namespace ranges @@ -68,4 +73,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_MINMAX_H diff --git a/third_party/libcxx/__algorithm/ranges_mismatch.h b/third_party/libcxx/__algorithm/ranges_mismatch.h index 098c4151c..c4bf0022a 100644 --- a/third_party/libcxx/__algorithm/ranges_mismatch.h +++ b/third_party/libcxx/__algorithm/ranges_mismatch.h @@ -10,6 +10,8 @@ #define _LIBCPP___ALGORITHM_RANGES_MISMATCH_H #include <__algorithm/in_in_result.h> +#include <__algorithm/mismatch.h> +#include <__algorithm/unwrap_range.h> #include <__config> #include <__functional/identity.h> #include <__functional/invoke.h> @@ -25,6 +27,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 @@ -36,45 +41,53 @@ using mismatch_result = in_in_result<_I1, _I2>; namespace __mismatch { struct __fn { - template - static _LIBCPP_HIDE_FROM_ABI constexpr - mismatch_result<_I1, _I2> - __go(_I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2, - _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) { - while (__first1 != __last1 && __first2 != __last2) { - if (!std::invoke(__pred, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__first2))) - break; - ++__first1; - ++__first2; + template + static _LIBCPP_HIDE_FROM_ABI constexpr mismatch_result<_I1, _I2> + __go(_I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) { + if constexpr (forward_iterator<_I1> && forward_iterator<_I2>) { + auto __range1 = std::__unwrap_range(__first1, __last1); + auto __range2 = std::__unwrap_range(__first2, __last2); + auto __res = + std::__mismatch(__range1.first, __range1.second, __range2.first, __range2.second, __pred, __proj1, __proj2); + return {std::__rewrap_range<_S1>(__first1, __res.first), std::__rewrap_range<_S2>(__first2, __res.second)}; + } else { + auto __res = std::__mismatch( + std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __pred, __proj1, __proj2); + return {std::move(__res.first), std::move(__res.second)}; } - return {std::move(__first1), std::move(__first2)}; } - template _S1, - input_iterator _I2, sentinel_for<_I2> _S2, - class _Pred = ranges::equal_to, class _Proj1 = identity, class _Proj2 = identity> + template _S1, + input_iterator _I2, + sentinel_for<_I2> _S2, + class _Pred = ranges::equal_to, + class _Proj1 = identity, + class _Proj2 = identity> requires indirectly_comparable<_I1, _I2, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - mismatch_result<_I1, _I2> operator()(_I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2, - _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr mismatch_result<_I1, _I2> operator()( + _I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) + const { return __go(std::move(__first1), __last1, std::move(__first2), __last2, __pred, __proj1, __proj2); } - template + template requires indirectly_comparable, iterator_t<_R2>, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - mismatch_result, borrowed_iterator_t<_R2>> + [[nodiscard]] + _LIBCPP_HIDE_FROM_ABI constexpr mismatch_result, borrowed_iterator_t<_R2>> operator()(_R1&& __r1, _R2&& __r2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { - return __go(ranges::begin(__r1), ranges::end(__r1), ranges::begin(__r2), ranges::end(__r2), - __pred, __proj1, __proj2); + return __go( + ranges::begin(__r1), ranges::end(__r1), ranges::begin(__r2), ranges::end(__r2), __pred, __proj1, __proj2); } }; } // namespace __mismatch inline namespace __cpo { - constexpr inline auto mismatch = __mismatch::__fn{}; +constexpr inline auto mismatch = __mismatch::__fn{}; } // namespace __cpo } // namespace ranges @@ -82,4 +95,6 @@ inline namespace __cpo { _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_MISMATCH_H diff --git a/third_party/libcxx/__algorithm/ranges_move.h b/third_party/libcxx/__algorithm/ranges_move.h index 5e06e903f..be869f36c 100644 --- a/third_party/libcxx/__algorithm/ranges_move.h +++ b/third_party/libcxx/__algorithm/ranges_move.h @@ -23,6 +23,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -34,33 +37,31 @@ using move_result = in_out_result<_InIter, _OutIter>; namespace __move { struct __fn { - template - _LIBCPP_HIDE_FROM_ABI constexpr static - move_result<_InIter, _OutIter> __move_impl(_InIter __first, _Sent __last, _OutIter __result) { + _LIBCPP_HIDE_FROM_ABI constexpr static move_result<_InIter, _OutIter> + __move_impl(_InIter __first, _Sent __last, _OutIter __result) { auto __ret = std::__move<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)); return {std::move(__ret.first), std::move(__ret.second)}; } template _Sent, weakly_incrementable _OutIter> requires indirectly_movable<_InIter, _OutIter> - _LIBCPP_HIDE_FROM_ABI constexpr - move_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const { + _LIBCPP_HIDE_FROM_ABI constexpr move_result<_InIter, _OutIter> + operator()(_InIter __first, _Sent __last, _OutIter __result) const { return __move_impl(std::move(__first), std::move(__last), std::move(__result)); } template requires indirectly_movable, _OutIter> - _LIBCPP_HIDE_FROM_ABI constexpr - move_result, _OutIter> operator()(_Range&& __range, _OutIter __result) const { + _LIBCPP_HIDE_FROM_ABI constexpr move_result, _OutIter> + operator()(_Range&& __range, _OutIter __result) const { return __move_impl(ranges::begin(__range), ranges::end(__range), std::move(__result)); } - }; } // namespace __move inline namespace __cpo { - inline constexpr auto move = __move::__fn{}; +inline constexpr auto move = __move::__fn{}; } // namespace __cpo } // namespace ranges @@ -68,4 +69,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_MOVE_H diff --git a/third_party/libcxx/__algorithm/ranges_move_backward.h b/third_party/libcxx/__algorithm/ranges_move_backward.h index 95c2c6612..6d4071a33 100644 --- a/third_party/libcxx/__algorithm/ranges_move_backward.h +++ b/third_party/libcxx/__algorithm/ranges_move_backward.h @@ -25,6 +25,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -36,33 +39,31 @@ using move_backward_result = in_out_result<_InIter, _OutIter>; namespace __move_backward { struct __fn { - template - _LIBCPP_HIDE_FROM_ABI constexpr static - move_backward_result<_InIter, _OutIter> __move_backward_impl(_InIter __first, _Sent __last, _OutIter __result) { + _LIBCPP_HIDE_FROM_ABI constexpr static move_backward_result<_InIter, _OutIter> + __move_backward_impl(_InIter __first, _Sent __last, _OutIter __result) { auto __ret = std::__move_backward<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::move(__result)); return {std::move(__ret.first), std::move(__ret.second)}; } template _Sent, bidirectional_iterator _OutIter> requires indirectly_movable<_InIter, _OutIter> - _LIBCPP_HIDE_FROM_ABI constexpr - move_backward_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const { + _LIBCPP_HIDE_FROM_ABI constexpr move_backward_result<_InIter, _OutIter> + operator()(_InIter __first, _Sent __last, _OutIter __result) const { return __move_backward_impl(std::move(__first), std::move(__last), std::move(__result)); } template requires indirectly_movable, _Iter> - _LIBCPP_HIDE_FROM_ABI constexpr - move_backward_result, _Iter> operator()(_Range&& __range, _Iter __result) const { + _LIBCPP_HIDE_FROM_ABI constexpr move_backward_result, _Iter> + operator()(_Range&& __range, _Iter __result) const { return __move_backward_impl(ranges::begin(__range), ranges::end(__range), std::move(__result)); } - }; } // namespace __move_backward inline namespace __cpo { - inline constexpr auto move_backward = __move_backward::__fn{}; +inline constexpr auto move_backward = __move_backward::__fn{}; } // namespace __cpo } // namespace ranges @@ -70,4 +71,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_MOVE_BACKWARD_H diff --git a/third_party/libcxx/__algorithm/ranges_next_permutation.h b/third_party/libcxx/__algorithm/ranges_next_permutation.h index 9ebab3ea7..18535e0a6 100644 --- a/third_party/libcxx/__algorithm/ranges_next_permutation.h +++ b/third_party/libcxx/__algorithm/ranges_next_permutation.h @@ -28,6 +28,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -70,4 +73,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_NEXT_PERMUTATION_H diff --git a/third_party/libcxx/__algorithm/ranges_none_of.h b/third_party/libcxx/__algorithm/ranges_none_of.h index 39940adbb..7df3c1829 100644 --- a/third_party/libcxx/__algorithm/ranges_none_of.h +++ b/third_party/libcxx/__algorithm/ranges_none_of.h @@ -22,6 +22,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -29,10 +32,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __none_of { struct __fn { - template - _LIBCPP_HIDE_FROM_ABI constexpr static - bool __none_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { + _LIBCPP_HIDE_FROM_ABI constexpr static bool + __none_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { for (; __first != __last; ++__first) { if (std::invoke(__pred, std::invoke(__proj, *__first))) return false; @@ -40,24 +42,27 @@ struct __fn { return true; } - template _Sent, class _Proj = identity, + template _Sent, + class _Proj = identity, indirect_unary_predicate> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - bool operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool + operator()(_Iter __first, _Sent __last, _Pred __pred = {}, _Proj __proj = {}) const { return __none_of_impl(std::move(__first), std::move(__last), __pred, __proj); } - template , _Proj>> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - bool operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool + operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { return __none_of_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); } }; } // namespace __none_of inline namespace __cpo { - inline constexpr auto none_of = __none_of::__fn{}; +inline constexpr auto none_of = __none_of::__fn{}; } // namespace __cpo } // namespace ranges @@ -65,4 +70,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_NONE_OF_H diff --git a/third_party/libcxx/__algorithm/ranges_nth_element.h b/third_party/libcxx/__algorithm/ranges_nth_element.h index 96bf33b07..90ade9efe 100644 --- a/third_party/libcxx/__algorithm/ranges_nth_element.h +++ b/third_party/libcxx/__algorithm/ranges_nth_element.h @@ -31,6 +31,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -40,8 +43,8 @@ namespace __nth_element { struct __fn { template - _LIBCPP_HIDE_FROM_ABI constexpr static - _Iter __nth_element_fn_impl(_Iter __first, _Iter __nth, _Sent __last, _Comp& __comp, _Proj& __proj) { + _LIBCPP_HIDE_FROM_ABI constexpr static _Iter + __nth_element_fn_impl(_Iter __first, _Iter __nth, _Sent __last, _Comp& __comp, _Proj& __proj) { auto __last_iter = ranges::next(__first, __last); auto&& __projected_comp = std::__make_projected(__comp, __proj); @@ -52,16 +55,15 @@ struct __fn { template _Sent, class _Comp = ranges::less, class _Proj = identity> requires sortable<_Iter, _Comp, _Proj> - _LIBCPP_HIDE_FROM_ABI constexpr - _Iter operator()(_Iter __first, _Iter __nth, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + _LIBCPP_HIDE_FROM_ABI constexpr _Iter + operator()(_Iter __first, _Iter __nth, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { return __nth_element_fn_impl(std::move(__first), std::move(__nth), std::move(__last), __comp, __proj); } template requires sortable, _Comp, _Proj> - _LIBCPP_HIDE_FROM_ABI constexpr - borrowed_iterator_t<_Range> operator()(_Range&& __r, iterator_t<_Range> __nth, _Comp __comp = {}, - _Proj __proj = {}) const { + _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> + operator()(_Range&& __r, iterator_t<_Range> __nth, _Comp __comp = {}, _Proj __proj = {}) const { return __nth_element_fn_impl(ranges::begin(__r), std::move(__nth), ranges::end(__r), __comp, __proj); } }; @@ -69,7 +71,7 @@ struct __fn { } // namespace __nth_element inline namespace __cpo { - inline constexpr auto nth_element = __nth_element::__fn{}; +inline constexpr auto nth_element = __nth_element::__fn{}; } // namespace __cpo } // namespace ranges @@ -77,4 +79,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_NTH_ELEMENT_H diff --git a/third_party/libcxx/__algorithm/ranges_partial_sort.h b/third_party/libcxx/__algorithm/ranges_partial_sort.h index 4562c3544..c67247d2e 100644 --- a/third_party/libcxx/__algorithm/ranges_partial_sort.h +++ b/third_party/libcxx/__algorithm/ranges_partial_sort.h @@ -33,6 +33,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -42,24 +45,23 @@ namespace __partial_sort { struct __fn { template - _LIBCPP_HIDE_FROM_ABI constexpr static - _Iter __partial_sort_fn_impl(_Iter __first, _Iter __middle, _Sent __last, _Comp& __comp, _Proj& __proj) { + _LIBCPP_HIDE_FROM_ABI constexpr static _Iter + __partial_sort_fn_impl(_Iter __first, _Iter __middle, _Sent __last, _Comp& __comp, _Proj& __proj) { auto&& __projected_comp = std::__make_projected(__comp, __proj); return std::__partial_sort<_RangeAlgPolicy>(std::move(__first), std::move(__middle), __last, __projected_comp); } template _Sent, class _Comp = ranges::less, class _Proj = identity> requires sortable<_Iter, _Comp, _Proj> - _LIBCPP_HIDE_FROM_ABI constexpr - _Iter operator()(_Iter __first, _Iter __middle, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + _LIBCPP_HIDE_FROM_ABI constexpr _Iter + operator()(_Iter __first, _Iter __middle, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { return __partial_sort_fn_impl(std::move(__first), std::move(__middle), std::move(__last), __comp, __proj); } template requires sortable, _Comp, _Proj> - _LIBCPP_HIDE_FROM_ABI constexpr - borrowed_iterator_t<_Range> operator()(_Range&& __r, iterator_t<_Range> __middle, _Comp __comp = {}, - _Proj __proj = {}) const { + _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> + operator()(_Range&& __r, iterator_t<_Range> __middle, _Comp __comp = {}, _Proj __proj = {}) const { return __partial_sort_fn_impl(ranges::begin(__r), std::move(__middle), ranges::end(__r), __comp, __proj); } }; @@ -67,7 +69,7 @@ struct __fn { } // namespace __partial_sort inline namespace __cpo { - inline constexpr auto partial_sort = __partial_sort::__fn{}; +inline constexpr auto partial_sort = __partial_sort::__fn{}; } // namespace __cpo } // namespace ranges @@ -75,4 +77,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_PARTIAL_SORT_H diff --git a/third_party/libcxx/__algorithm/ranges_partial_sort_copy.h b/third_party/libcxx/__algorithm/ranges_partial_sort_copy.h index 5401a374e..b3bdeb78f 100644 --- a/third_party/libcxx/__algorithm/ranges_partial_sort_copy.h +++ b/third_party/libcxx/__algorithm/ranges_partial_sort_copy.h @@ -30,6 +30,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -42,46 +45,63 @@ using partial_sort_copy_result = in_out_result<_InIter, _OutIter>; namespace __partial_sort_copy { struct __fn { - - template _Sent1, - random_access_iterator _Iter2, sentinel_for<_Iter2> _Sent2, - class _Comp = ranges::less, class _Proj1 = identity, class _Proj2 = identity> - requires indirectly_copyable<_Iter1, _Iter2> && sortable<_Iter2, _Comp, _Proj2> && - indirect_strict_weak_order<_Comp, projected<_Iter1, _Proj1>, projected<_Iter2, _Proj2>> - _LIBCPP_HIDE_FROM_ABI constexpr - partial_sort_copy_result<_Iter1, _Iter2> - operator()(_Iter1 __first, _Sent1 __last, _Iter2 __result_first, _Sent2 __result_last, - _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { + template _Sent1, + random_access_iterator _Iter2, + sentinel_for<_Iter2> _Sent2, + class _Comp = ranges::less, + class _Proj1 = identity, + class _Proj2 = identity> + requires indirectly_copyable<_Iter1, _Iter2> && sortable<_Iter2, _Comp, _Proj2> && + indirect_strict_weak_order<_Comp, projected<_Iter1, _Proj1>, projected<_Iter2, _Proj2>> + _LIBCPP_HIDE_FROM_ABI constexpr partial_sort_copy_result<_Iter1, _Iter2> operator()( + _Iter1 __first, + _Sent1 __last, + _Iter2 __result_first, + _Sent2 __result_last, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { auto __result = std::__partial_sort_copy<_RangeAlgPolicy>( - std::move(__first), std::move(__last), std::move(__result_first), std::move(__result_last), - __comp, __proj1, __proj2 - ); + std::move(__first), + std::move(__last), + std::move(__result_first), + std::move(__result_last), + __comp, + __proj1, + __proj2); return {std::move(__result.first), std::move(__result.second)}; } - template - requires indirectly_copyable, iterator_t<_Range2>> && - sortable, _Comp, _Proj2> && - indirect_strict_weak_order<_Comp, projected, _Proj1>, - projected, _Proj2>> - _LIBCPP_HIDE_FROM_ABI constexpr - partial_sort_copy_result, borrowed_iterator_t<_Range2>> - operator()(_Range1&& __range, _Range2&& __result_range, _Comp __comp = {}, - _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { + template + requires indirectly_copyable, iterator_t<_Range2>> && + sortable, _Comp, _Proj2> && + indirect_strict_weak_order<_Comp, + projected, _Proj1>, + projected, _Proj2>> + _LIBCPP_HIDE_FROM_ABI constexpr partial_sort_copy_result, borrowed_iterator_t<_Range2>> + operator()( + _Range1&& __range, _Range2&& __result_range, _Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { auto __result = std::__partial_sort_copy<_RangeAlgPolicy>( - ranges::begin(__range), ranges::end(__range), ranges::begin(__result_range), ranges::end(__result_range), - __comp, __proj1, __proj2 - ); + ranges::begin(__range), + ranges::end(__range), + ranges::begin(__result_range), + ranges::end(__result_range), + __comp, + __proj1, + __proj2); return {std::move(__result.first), std::move(__result.second)}; } - }; } // namespace __partial_sort_copy inline namespace __cpo { - inline constexpr auto partial_sort_copy = __partial_sort_copy::__fn{}; +inline constexpr auto partial_sort_copy = __partial_sort_copy::__fn{}; } // namespace __cpo } // namespace ranges @@ -89,4 +109,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_PARTIAL_SORT_COPY_H diff --git a/third_party/libcxx/__algorithm/ranges_partition.h b/third_party/libcxx/__algorithm/ranges_partition.h index de839de12..a67ac4c96 100644 --- a/third_party/libcxx/__algorithm/ranges_partition.h +++ b/third_party/libcxx/__algorithm/ranges_partition.h @@ -32,6 +32,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -40,38 +43,39 @@ namespace ranges { namespace __partition { struct __fn { - template - _LIBCPP_HIDE_FROM_ABI static constexpr - subrange<__remove_cvref_t<_Iter>> __partition_fn_impl(_Iter&& __first, _Sent&& __last, _Pred&& __pred, _Proj&& __proj) { + _LIBCPP_HIDE_FROM_ABI static constexpr subrange<__remove_cvref_t<_Iter>> + __partition_fn_impl(_Iter&& __first, _Sent&& __last, _Pred&& __pred, _Proj&& __proj) { auto&& __projected_pred = std::__make_projected(__pred, __proj); - auto __result = std::__partition<_RangeAlgPolicy>( + auto __result = std::__partition<_RangeAlgPolicy>( std::move(__first), std::move(__last), __projected_pred, __iterator_concept<_Iter>()); return {std::move(__result.first), std::move(__result.second)}; } - template _Sent, class _Proj = identity, + template _Sent, + class _Proj = identity, indirect_unary_predicate> _Pred> - _LIBCPP_HIDE_FROM_ABI constexpr - subrange<_Iter> operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { + _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> + operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { return __partition_fn_impl(__first, __last, __pred, __proj); } - template , _Proj>> _Pred> - requires permutable> - _LIBCPP_HIDE_FROM_ABI constexpr - borrowed_subrange_t<_Range> operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { + requires permutable> + _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> + operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { return __partition_fn_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); } - }; } // namespace __partition inline namespace __cpo { - inline constexpr auto partition = __partition::__fn{}; +inline constexpr auto partition = __partition::__fn{}; } // namespace __cpo } // namespace ranges @@ -79,4 +83,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_PARTITION_H diff --git a/third_party/libcxx/__algorithm/ranges_partition_copy.h b/third_party/libcxx/__algorithm/ranges_partition_copy.h index e398387bf..d60c865dd 100644 --- a/third_party/libcxx/__algorithm/ranges_partition_copy.h +++ b/third_party/libcxx/__algorithm/ranges_partition_copy.h @@ -26,6 +26,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -38,14 +41,18 @@ using partition_copy_result = in_out_out_result<_InIter, _OutIter1, _OutIter2>; namespace __partition_copy { struct __fn { - // TODO(ranges): delegate to the classic algorithm. template - _LIBCPP_HIDE_FROM_ABI constexpr - static partition_copy_result< - __remove_cvref_t<_InIter>, __remove_cvref_t<_OutIter1>, __remove_cvref_t<_OutIter2> - > __partition_copy_fn_impl( _InIter&& __first, _Sent&& __last, _OutIter1&& __out_true, _OutIter2&& __out_false, - _Pred& __pred, _Proj& __proj) { + _LIBCPP_HIDE_FROM_ABI constexpr static partition_copy_result<__remove_cvref_t<_InIter>, + __remove_cvref_t<_OutIter1>, + __remove_cvref_t<_OutIter2> > + __partition_copy_fn_impl( + _InIter&& __first, + _Sent&& __last, + _OutIter1&& __out_true, + _OutIter2&& __out_false, + _Pred& __pred, + _Proj& __proj) { for (; __first != __last; ++__first) { if (std::invoke(__pred, std::invoke(__proj, *__first))) { *__out_true = *__first; @@ -60,34 +67,37 @@ struct __fn { return {std::move(__first), std::move(__out_true), std::move(__out_false)}; } - template _Sent, - weakly_incrementable _OutIter1, weakly_incrementable _OutIter2, - class _Proj = identity, indirect_unary_predicate> _Pred> - requires indirectly_copyable<_InIter, _OutIter1> && indirectly_copyable<_InIter, _OutIter2> - _LIBCPP_HIDE_FROM_ABI constexpr - partition_copy_result<_InIter, _OutIter1, _OutIter2> - operator()(_InIter __first, _Sent __last, _OutIter1 __out_true, _OutIter2 __out_false, - _Pred __pred, _Proj __proj = {}) const { + template _Sent, + weakly_incrementable _OutIter1, + weakly_incrementable _OutIter2, + class _Proj = identity, + indirect_unary_predicate> _Pred> + requires indirectly_copyable<_InIter, _OutIter1> && indirectly_copyable<_InIter, _OutIter2> + _LIBCPP_HIDE_FROM_ABI constexpr partition_copy_result<_InIter, _OutIter1, _OutIter2> operator()( + _InIter __first, _Sent __last, _OutIter1 __out_true, _OutIter2 __out_false, _Pred __pred, _Proj __proj = {}) + const { return __partition_copy_fn_impl( std::move(__first), std::move(__last), std::move(__out_true), std::move(__out_false), __pred, __proj); } - template , _Proj>> _Pred> - requires indirectly_copyable, _OutIter1> && indirectly_copyable, _OutIter2> - _LIBCPP_HIDE_FROM_ABI constexpr - partition_copy_result, _OutIter1, _OutIter2> + template , _Proj>> _Pred> + requires indirectly_copyable, _OutIter1> && indirectly_copyable, _OutIter2> + _LIBCPP_HIDE_FROM_ABI constexpr partition_copy_result, _OutIter1, _OutIter2> operator()(_Range&& __range, _OutIter1 __out_true, _OutIter2 __out_false, _Pred __pred, _Proj __proj = {}) const { return __partition_copy_fn_impl( ranges::begin(__range), ranges::end(__range), std::move(__out_true), std::move(__out_false), __pred, __proj); } - }; } // namespace __partition_copy inline namespace __cpo { - inline constexpr auto partition_copy = __partition_copy::__fn{}; +inline constexpr auto partition_copy = __partition_copy::__fn{}; } // namespace __cpo } // namespace ranges @@ -95,4 +105,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_PARTITION_COPY_H diff --git a/third_party/libcxx/__algorithm/ranges_partition_point.h b/third_party/libcxx/__algorithm/ranges_partition_point.h index 129ebb6c6..c5b11b5fe 100644 --- a/third_party/libcxx/__algorithm/ranges_partition_point.h +++ b/third_party/libcxx/__algorithm/ranges_partition_point.h @@ -27,6 +27,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -35,16 +38,15 @@ namespace ranges { namespace __partition_point { struct __fn { - // TODO(ranges): delegate to the classic algorithm. template - _LIBCPP_HIDE_FROM_ABI constexpr - static _Iter __partition_point_fn_impl(_Iter&& __first, _Sent&& __last, _Pred& __pred, _Proj& __proj) { + _LIBCPP_HIDE_FROM_ABI constexpr static _Iter + __partition_point_fn_impl(_Iter&& __first, _Sent&& __last, _Pred& __pred, _Proj& __proj) { auto __len = ranges::distance(__first, __last); while (__len != 0) { auto __half_len = std::__half_positive(__len); - auto __mid = ranges::next(__first, __half_len); + auto __mid = ranges::next(__first, __half_len); if (std::invoke(__pred, std::invoke(__proj, *__mid))) { __first = ++__mid; @@ -58,26 +60,27 @@ struct __fn { return __first; } - template _Sent, class _Proj = identity, + template _Sent, + class _Proj = identity, indirect_unary_predicate> _Pred> - _LIBCPP_HIDE_FROM_ABI constexpr - _Iter operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { + _LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { return __partition_point_fn_impl(std::move(__first), std::move(__last), __pred, __proj); } - template , _Proj>> _Pred> - _LIBCPP_HIDE_FROM_ABI constexpr - borrowed_iterator_t<_Range> operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { + _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> + operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { return __partition_point_fn_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); } - }; } // namespace __partition_point inline namespace __cpo { - inline constexpr auto partition_point = __partition_point::__fn{}; +inline constexpr auto partition_point = __partition_point::__fn{}; } // namespace __cpo } // namespace ranges @@ -85,4 +88,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_PARTITION_POINT_H diff --git a/third_party/libcxx/__algorithm/ranges_pop_heap.h b/third_party/libcxx/__algorithm/ranges_pop_heap.h index 54ea97db7..01f92c0f2 100644 --- a/third_party/libcxx/__algorithm/ranges_pop_heap.h +++ b/third_party/libcxx/__algorithm/ranges_pop_heap.h @@ -32,6 +32,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -41,10 +44,10 @@ namespace __pop_heap { struct __fn { template - _LIBCPP_HIDE_FROM_ABI constexpr static - _Iter __pop_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { + _LIBCPP_HIDE_FROM_ABI constexpr static _Iter + __pop_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { auto __last_iter = ranges::next(__first, __last); - auto __len = __last_iter - __first; + auto __len = __last_iter - __first; auto&& __projected_comp = std::__make_projected(__comp, __proj); std::__pop_heap<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp, __len); @@ -54,15 +57,15 @@ struct __fn { template _Sent, class _Comp = ranges::less, class _Proj = identity> requires sortable<_Iter, _Comp, _Proj> - _LIBCPP_HIDE_FROM_ABI constexpr - _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + _LIBCPP_HIDE_FROM_ABI constexpr _Iter + operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { return __pop_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj); } template requires sortable, _Comp, _Proj> - _LIBCPP_HIDE_FROM_ABI constexpr - borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> + operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { return __pop_heap_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); } }; @@ -70,7 +73,7 @@ struct __fn { } // namespace __pop_heap inline namespace __cpo { - inline constexpr auto pop_heap = __pop_heap::__fn{}; +inline constexpr auto pop_heap = __pop_heap::__fn{}; } // namespace __cpo } // namespace ranges @@ -78,4 +81,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_POP_HEAP_H diff --git a/third_party/libcxx/__algorithm/ranges_prev_permutation.h b/third_party/libcxx/__algorithm/ranges_prev_permutation.h index bf062874a..225cee9b7 100644 --- a/third_party/libcxx/__algorithm/ranges_prev_permutation.h +++ b/third_party/libcxx/__algorithm/ranges_prev_permutation.h @@ -28,6 +28,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -40,9 +43,7 @@ using prev_permutation_result = in_found_result<_InIter>; namespace __prev_permutation { struct __fn { - - template _Sent, - class _Comp = ranges::less, class _Proj = identity> + template _Sent, class _Comp = ranges::less, class _Proj = identity> requires sortable<_Iter, _Comp, _Proj> _LIBCPP_HIDE_FROM_ABI constexpr prev_permutation_result<_Iter> operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { @@ -51,8 +52,7 @@ struct __fn { return {std::move(__result.first), std::move(__result.second)}; } - template + template requires sortable, _Comp, _Proj> _LIBCPP_HIDE_FROM_ABI constexpr prev_permutation_result> operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { @@ -60,7 +60,6 @@ struct __fn { ranges::begin(__range), ranges::end(__range), std::__make_projected(__comp, __proj)); return {std::move(__result.first), std::move(__result.second)}; } - }; } // namespace __prev_permutation @@ -74,4 +73,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_PREV_PERMUTATION_H diff --git a/third_party/libcxx/__algorithm/ranges_push_heap.h b/third_party/libcxx/__algorithm/ranges_push_heap.h index 6e65d11d0..9d187af38 100644 --- a/third_party/libcxx/__algorithm/ranges_push_heap.h +++ b/third_party/libcxx/__algorithm/ranges_push_heap.h @@ -32,6 +32,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -41,8 +44,8 @@ namespace __push_heap { struct __fn { template - _LIBCPP_HIDE_FROM_ABI constexpr static - _Iter __push_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { + _LIBCPP_HIDE_FROM_ABI constexpr static _Iter + __push_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { auto __last_iter = ranges::next(__first, __last); auto&& __projected_comp = std::__make_projected(__comp, __proj); @@ -53,15 +56,15 @@ struct __fn { template _Sent, class _Comp = ranges::less, class _Proj = identity> requires sortable<_Iter, _Comp, _Proj> - _LIBCPP_HIDE_FROM_ABI constexpr - _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + _LIBCPP_HIDE_FROM_ABI constexpr _Iter + operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { return __push_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj); } template requires sortable, _Comp, _Proj> - _LIBCPP_HIDE_FROM_ABI constexpr - borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> + operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { return __push_heap_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); } }; @@ -69,7 +72,7 @@ struct __fn { } // namespace __push_heap inline namespace __cpo { - inline constexpr auto push_heap = __push_heap::__fn{}; +inline constexpr auto push_heap = __push_heap::__fn{}; } // namespace __cpo } // namespace ranges @@ -77,4 +80,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_PUSH_HEAP_H diff --git a/third_party/libcxx/__algorithm/ranges_remove.h b/third_party/libcxx/__algorithm/ranges_remove.h index 6dd48e087..17c3a2c5c 100644 --- a/third_party/libcxx/__algorithm/ranges_remove.h +++ b/third_party/libcxx/__algorithm/ranges_remove.h @@ -25,6 +25,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -32,28 +35,27 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __remove { struct __fn { - template _Sent, class _Type, class _Proj = identity> requires indirect_binary_predicate, const _Type*> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - subrange<_Iter> operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) const { - auto __pred = [&](auto&& __other) { return __value == __other; }; + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> + operator()(_Iter __first, _Sent __last, const _Type& __value, _Proj __proj = {}) const { + auto __pred = [&](auto&& __other) -> bool { return __value == __other; }; return ranges::__remove_if_impl(std::move(__first), std::move(__last), __pred, __proj); } template - requires permutable> - && indirect_binary_predicate, _Proj>, const _Type*> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - borrowed_subrange_t<_Range> operator()(_Range&& __range, const _Type& __value, _Proj __proj = {}) const { - auto __pred = [&](auto&& __other) { return __value == __other; }; + requires permutable> && + indirect_binary_predicate, _Proj>, const _Type*> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> + operator()(_Range&& __range, const _Type& __value, _Proj __proj = {}) const { + auto __pred = [&](auto&& __other) -> bool { return __value == __other; }; return ranges::__remove_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); } }; } // namespace __remove inline namespace __cpo { - inline constexpr auto remove = __remove::__fn{}; +inline constexpr auto remove = __remove::__fn{}; } // namespace __cpo } // namespace ranges @@ -61,4 +63,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_H diff --git a/third_party/libcxx/__algorithm/ranges_remove_copy.h b/third_party/libcxx/__algorithm/ranges_remove_copy.h index a9a19c17f..84529ecea 100644 --- a/third_party/libcxx/__algorithm/ranges_remove_copy.h +++ b/third_party/libcxx/__algorithm/ranges_remove_copy.h @@ -26,6 +26,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -37,35 +40,35 @@ using remove_copy_result = in_out_result<_InIter, _OutIter>; namespace __remove_copy { - struct __fn { - template _Sent, - weakly_incrementable _OutIter, - class _Type, - class _Proj = identity> - requires indirectly_copyable<_InIter, _OutIter> && - indirect_binary_predicate, const _Type*> - _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_result<_InIter, _OutIter> - operator()(_InIter __first, _Sent __last, _OutIter __result, const _Type& __value, _Proj __proj = {}) const { - auto __pred = [&](auto&& __val) { return __value == __val; }; - return ranges::__remove_copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj); - } +struct __fn { + template _Sent, + weakly_incrementable _OutIter, + class _Type, + class _Proj = identity> + requires indirectly_copyable<_InIter, _OutIter> && + indirect_binary_predicate, const _Type*> + _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_result<_InIter, _OutIter> + operator()(_InIter __first, _Sent __last, _OutIter __result, const _Type& __value, _Proj __proj = {}) const { + auto __pred = [&](auto&& __val) -> bool { return __value == __val; }; + return ranges::__remove_copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj); + } - template - requires indirectly_copyable, _OutIter> && - indirect_binary_predicate, _Proj>, const _Type*> - _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_result, _OutIter> - operator()(_Range&& __range, _OutIter __result, const _Type& __value, _Proj __proj = {}) const { - auto __pred = [&](auto&& __val) { return __value == __val; }; - return ranges::__remove_copy_if_impl( - ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __proj); - } - }; + template + requires indirectly_copyable, _OutIter> && + indirect_binary_predicate, _Proj>, const _Type*> + _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_result, _OutIter> + operator()(_Range&& __range, _OutIter __result, const _Type& __value, _Proj __proj = {}) const { + auto __pred = [&](auto&& __val) -> bool { return __value == __val; }; + return ranges::__remove_copy_if_impl( + ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __proj); + } +}; } // namespace __remove_copy inline namespace __cpo { - inline constexpr auto remove_copy = __remove_copy::__fn{}; +inline constexpr auto remove_copy = __remove_copy::__fn{}; } // namespace __cpo } // namespace ranges @@ -73,4 +76,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_COPY_H diff --git a/third_party/libcxx/__algorithm/ranges_remove_copy_if.h b/third_party/libcxx/__algorithm/ranges_remove_copy_if.h index e6d043e36..56fe01753 100644 --- a/third_party/libcxx/__algorithm/ranges_remove_copy_if.h +++ b/third_party/libcxx/__algorithm/ranges_remove_copy_if.h @@ -29,6 +29,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -52,34 +55,34 @@ __remove_copy_if_impl(_InIter __first, _Sent __last, _OutIter __result, _Pred& _ namespace __remove_copy_if { - struct __fn { - template _Sent, - weakly_incrementable _OutIter, - class _Proj = identity, - indirect_unary_predicate> _Pred> - requires indirectly_copyable<_InIter, _OutIter> - _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_if_result<_InIter, _OutIter> - operator()(_InIter __first, _Sent __last, _OutIter __result, _Pred __pred, _Proj __proj = {}) const { - return ranges::__remove_copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj); - } +struct __fn { + template _Sent, + weakly_incrementable _OutIter, + class _Proj = identity, + indirect_unary_predicate> _Pred> + requires indirectly_copyable<_InIter, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_if_result<_InIter, _OutIter> + operator()(_InIter __first, _Sent __last, _OutIter __result, _Pred __pred, _Proj __proj = {}) const { + return ranges::__remove_copy_if_impl(std::move(__first), std::move(__last), std::move(__result), __pred, __proj); + } - template , _Proj>> _Pred> - requires indirectly_copyable, _OutIter> - _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_if_result, _OutIter> - operator()(_Range&& __range, _OutIter __result, _Pred __pred, _Proj __proj = {}) const { - return ranges::__remove_copy_if_impl( - ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __proj); - } - }; + template , _Proj>> _Pred> + requires indirectly_copyable, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr remove_copy_if_result, _OutIter> + operator()(_Range&& __range, _OutIter __result, _Pred __pred, _Proj __proj = {}) const { + return ranges::__remove_copy_if_impl( + ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __proj); + } +}; } // namespace __remove_copy_if inline namespace __cpo { - inline constexpr auto remove_copy_if = __remove_copy_if::__fn{}; +inline constexpr auto remove_copy_if = __remove_copy_if::__fn{}; } // namespace __cpo } // namespace ranges @@ -87,4 +90,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_COPY_IF_H diff --git a/third_party/libcxx/__algorithm/ranges_remove_if.h b/third_party/libcxx/__algorithm/ranges_remove_if.h index 7507c21b8..0ea5d9a01 100644 --- a/third_party/libcxx/__algorithm/ranges_remove_if.h +++ b/third_party/libcxx/__algorithm/ranges_remove_if.h @@ -27,6 +27,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -34,8 +37,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { template -_LIBCPP_HIDE_FROM_ABI constexpr -subrange<_Iter> __remove_if_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { +_LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> +__remove_if_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) { auto __new_end = ranges::__find_if_impl(__first, __last, __pred, __proj); if (__new_end == __last) return {__new_end, __new_end}; @@ -52,12 +55,12 @@ subrange<_Iter> __remove_if_impl(_Iter __first, _Sent __last, _Pred& __pred, _Pr namespace __remove_if { struct __fn { - - template _Sent, + template _Sent, class _Proj = identity, indirect_unary_predicate> _Pred> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - subrange<_Iter> operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> + operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { return ranges::__remove_if_impl(std::move(__first), std::move(__last), __pred, __proj); } @@ -65,16 +68,15 @@ struct __fn { class _Proj = identity, indirect_unary_predicate, _Proj>> _Pred> requires permutable> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - borrowed_subrange_t<_Range> operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> + operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { return ranges::__remove_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); } - }; } // namespace __remove_if inline namespace __cpo { - inline constexpr auto remove_if = __remove_if::__fn{}; +inline constexpr auto remove_if = __remove_if::__fn{}; } // namespace __cpo } // namespace ranges @@ -82,4 +84,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_IF_H diff --git a/third_party/libcxx/__algorithm/ranges_replace.h b/third_party/libcxx/__algorithm/ranges_replace.h index 258e25d05..2b88dc032 100644 --- a/third_party/libcxx/__algorithm/ranges_replace.h +++ b/third_party/libcxx/__algorithm/ranges_replace.h @@ -24,6 +24,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -31,39 +34,28 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __replace { struct __fn { - - template _Sent, - class _Type1, - class _Type2, - class _Proj = identity> - requires indirectly_writable<_Iter, const _Type2&> - && indirect_binary_predicate, const _Type1*> - _LIBCPP_HIDE_FROM_ABI constexpr - _Iter operator()(_Iter __first, _Sent __last, - const _Type1& __old_value, - const _Type2& __new_value, - _Proj __proj = {}) const { - auto __pred = [&](const auto& __val) { return __val == __old_value; }; + template _Sent, class _Type1, class _Type2, class _Proj = identity> + requires indirectly_writable<_Iter, const _Type2&> && + indirect_binary_predicate, const _Type1*> + _LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()( + _Iter __first, _Sent __last, const _Type1& __old_value, const _Type2& __new_value, _Proj __proj = {}) const { + auto __pred = [&](const auto& __val) -> bool { return __val == __old_value; }; return ranges::__replace_if_impl(std::move(__first), std::move(__last), __pred, __new_value, __proj); } - template - requires indirectly_writable, const _Type2&> - && indirect_binary_predicate, _Proj>, const _Type1*> + template + requires indirectly_writable, const _Type2&> && + indirect_binary_predicate, _Proj>, const _Type1*> _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> operator()(_Range&& __range, const _Type1& __old_value, const _Type2& __new_value, _Proj __proj = {}) const { - auto __pred = [&](auto&& __val) { return __val == __old_value; }; + auto __pred = [&](auto&& __val) -> bool { return __val == __old_value; }; return ranges::__replace_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __new_value, __proj); } - }; } // namespace __replace inline namespace __cpo { - inline constexpr auto replace = __replace::__fn{}; +inline constexpr auto replace = __replace::__fn{}; } // namespace __cpo } // namespace ranges @@ -71,4 +63,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_H diff --git a/third_party/libcxx/__algorithm/ranges_replace_copy.h b/third_party/libcxx/__algorithm/ranges_replace_copy.h index 79eaebb41..633f993e5 100644 --- a/third_party/libcxx/__algorithm/ranges_replace_copy.h +++ b/third_party/libcxx/__algorithm/ranges_replace_copy.h @@ -26,6 +26,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -37,50 +40,47 @@ using replace_copy_result = in_out_result<_InIter, _OutIter>; namespace __replace_copy { - struct __fn { - template _Sent, - class _OldType, - class _NewType, - output_iterator _OutIter, - class _Proj = identity> - requires indirectly_copyable<_InIter, _OutIter> && - indirect_binary_predicate, const _OldType*> - _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_result<_InIter, _OutIter> - operator()(_InIter __first, - _Sent __last, - _OutIter __result, - const _OldType& __old_value, - const _NewType& __new_value, - _Proj __proj = {}) const { - auto __pred = [&](const auto& __value) { return __value == __old_value; }; - return ranges::__replace_copy_if_impl( - std::move(__first), std::move(__last), std::move(__result), __pred, __new_value, __proj); - } +struct __fn { + template _Sent, + class _OldType, + class _NewType, + output_iterator _OutIter, + class _Proj = identity> + requires indirectly_copyable<_InIter, _OutIter> && + indirect_binary_predicate, const _OldType*> + _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_result<_InIter, _OutIter> + operator()(_InIter __first, + _Sent __last, + _OutIter __result, + const _OldType& __old_value, + const _NewType& __new_value, + _Proj __proj = {}) const { + auto __pred = [&](const auto& __value) -> bool { return __value == __old_value; }; + return ranges::__replace_copy_if_impl( + std::move(__first), std::move(__last), std::move(__result), __pred, __new_value, __proj); + } - template _OutIter, - class _Proj = identity> - requires indirectly_copyable, _OutIter> && - indirect_binary_predicate, _Proj>, const _OldType*> - _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_result, _OutIter> - operator()(_Range&& __range, - _OutIter __result, - const _OldType& __old_value, - const _NewType& __new_value, - _Proj __proj = {}) const { - auto __pred = [&](const auto& __value) { return __value == __old_value; }; - return ranges::__replace_copy_if_impl( - ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __new_value, __proj); - } - }; + template _OutIter, + class _Proj = identity> + requires indirectly_copyable, _OutIter> && + indirect_binary_predicate, _Proj>, const _OldType*> + _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_result, _OutIter> operator()( + _Range&& __range, _OutIter __result, const _OldType& __old_value, const _NewType& __new_value, _Proj __proj = {}) + const { + auto __pred = [&](const auto& __value) -> bool { return __value == __old_value; }; + return ranges::__replace_copy_if_impl( + ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __new_value, __proj); + } +}; } // namespace __replace_copy inline namespace __cpo { - inline constexpr auto replace_copy = __replace_copy::__fn{}; +inline constexpr auto replace_copy = __replace_copy::__fn{}; } // namespace __cpo } // namespace ranges @@ -88,4 +88,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_H diff --git a/third_party/libcxx/__algorithm/ranges_replace_copy_if.h b/third_party/libcxx/__algorithm/ranges_replace_copy_if.h index 8ff2eba8f..e065c3ac0 100644 --- a/third_party/libcxx/__algorithm/ranges_replace_copy_if.h +++ b/third_party/libcxx/__algorithm/ranges_replace_copy_if.h @@ -24,6 +24,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -51,38 +54,38 @@ _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_if_result<_InIter, _OutIter> __repl namespace __replace_copy_if { - struct __fn { - template _Sent, - class _Type, - output_iterator _OutIter, - class _Proj = identity, - indirect_unary_predicate> _Pred> - requires indirectly_copyable<_InIter, _OutIter> - _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_if_result<_InIter, _OutIter> operator()( - _InIter __first, _Sent __last, _OutIter __result, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) - const { - return ranges::__replace_copy_if_impl( - std::move(__first), std::move(__last), std::move(__result), __pred, __new_value, __proj); - } +struct __fn { + template _Sent, + class _Type, + output_iterator _OutIter, + class _Proj = identity, + indirect_unary_predicate> _Pred> + requires indirectly_copyable<_InIter, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_if_result<_InIter, _OutIter> operator()( + _InIter __first, _Sent __last, _OutIter __result, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) + const { + return ranges::__replace_copy_if_impl( + std::move(__first), std::move(__last), std::move(__result), __pred, __new_value, __proj); + } - template _OutIter, - class _Proj = identity, - indirect_unary_predicate, _Proj>> _Pred> - requires indirectly_copyable, _OutIter> - _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_if_result, _OutIter> - operator()(_Range&& __range, _OutIter __result, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const { - return ranges::__replace_copy_if_impl( - ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __new_value, __proj); - } - }; + template _OutIter, + class _Proj = identity, + indirect_unary_predicate, _Proj>> _Pred> + requires indirectly_copyable, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_if_result, _OutIter> + operator()(_Range&& __range, _OutIter __result, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const { + return ranges::__replace_copy_if_impl( + ranges::begin(__range), ranges::end(__range), std::move(__result), __pred, __new_value, __proj); + } +}; } // namespace __replace_copy_if inline namespace __cpo { - inline constexpr auto replace_copy_if = __replace_copy_if::__fn{}; +inline constexpr auto replace_copy_if = __replace_copy_if::__fn{}; } // namespace __cpo } // namespace ranges @@ -90,4 +93,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_IF_H diff --git a/third_party/libcxx/__algorithm/ranges_replace_if.h b/third_party/libcxx/__algorithm/ranges_replace_if.h index 2b7dda9e6..6445f42ae 100644 --- a/third_party/libcxx/__algorithm/ranges_replace_if.h +++ b/third_party/libcxx/__algorithm/ranges_replace_if.h @@ -23,6 +23,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -30,8 +33,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { template -_LIBCPP_HIDE_FROM_ABI constexpr -_Iter __replace_if_impl(_Iter __first, _Sent __last, _Pred& __pred, const _Type& __new_value, _Proj& __proj) { +_LIBCPP_HIDE_FROM_ABI constexpr _Iter +__replace_if_impl(_Iter __first, _Sent __last, _Pred& __pred, const _Type& __new_value, _Proj& __proj) { for (; __first != __last; ++__first) { if (std::invoke(__pred, std::invoke(__proj, *__first))) *__first = __new_value; @@ -41,14 +44,14 @@ _Iter __replace_if_impl(_Iter __first, _Sent __last, _Pred& __pred, const _Type& namespace __replace_if { struct __fn { - - template _Sent, + template _Sent, class _Type, class _Proj = identity, indirect_unary_predicate> _Pred> requires indirectly_writable<_Iter, const _Type&> - _LIBCPP_HIDE_FROM_ABI constexpr - _Iter operator()(_Iter __first, _Sent __last, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const { + _LIBCPP_HIDE_FROM_ABI constexpr _Iter + operator()(_Iter __first, _Sent __last, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const { return ranges::__replace_if_impl(std::move(__first), std::move(__last), __pred, __new_value, __proj); } @@ -61,12 +64,11 @@ struct __fn { operator()(_Range&& __range, _Pred __pred, const _Type& __new_value, _Proj __proj = {}) const { return ranges::__replace_if_impl(ranges::begin(__range), ranges::end(__range), __pred, __new_value, __proj); } - }; } // namespace __replace_if inline namespace __cpo { - inline constexpr auto replace_if = __replace_if::__fn{}; +inline constexpr auto replace_if = __replace_if::__fn{}; } // namespace __cpo } // namespace ranges @@ -74,4 +76,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_IF_H diff --git a/third_party/libcxx/__algorithm/ranges_reverse.h b/third_party/libcxx/__algorithm/ranges_reverse.h index 801fccb85..9ec865995 100644 --- a/third_party/libcxx/__algorithm/ranges_reverse.h +++ b/third_party/libcxx/__algorithm/ranges_reverse.h @@ -29,11 +29,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __reverse { struct __fn { - template _Sent> requires permutable<_Iter> - _LIBCPP_HIDE_FROM_ABI constexpr - _Iter operator()(_Iter __first, _Sent __last) const { + _LIBCPP_HIDE_FROM_ABI constexpr _Iter operator()(_Iter __first, _Sent __last) const { if constexpr (random_access_iterator<_Iter>) { if (__first == __last) return __first; @@ -63,16 +61,14 @@ struct __fn { template requires permutable> - _LIBCPP_HIDE_FROM_ABI constexpr - borrowed_iterator_t<_Range> operator()(_Range&& __range) const { + _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> operator()(_Range&& __range) const { return (*this)(ranges::begin(__range), ranges::end(__range)); } - }; } // namespace __reverse inline namespace __cpo { - inline constexpr auto reverse = __reverse::__fn{}; +inline constexpr auto reverse = __reverse::__fn{}; } // namespace __cpo } // namespace ranges diff --git a/third_party/libcxx/__algorithm/ranges_reverse_copy.h b/third_party/libcxx/__algorithm/ranges_reverse_copy.h index c23039976..60043787a 100644 --- a/third_party/libcxx/__algorithm/ranges_reverse_copy.h +++ b/third_party/libcxx/__algorithm/ranges_reverse_copy.h @@ -25,6 +25,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -36,27 +39,25 @@ using reverse_copy_result = in_out_result<_InIter, _OutIter>; namespace __reverse_copy { struct __fn { - template _Sent, weakly_incrementable _OutIter> requires indirectly_copyable<_InIter, _OutIter> - _LIBCPP_HIDE_FROM_ABI constexpr - reverse_copy_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, _OutIter __result) const { + _LIBCPP_HIDE_FROM_ABI constexpr reverse_copy_result<_InIter, _OutIter> + operator()(_InIter __first, _Sent __last, _OutIter __result) const { return (*this)(subrange(std::move(__first), std::move(__last)), std::move(__result)); } template requires indirectly_copyable, _OutIter> - _LIBCPP_HIDE_FROM_ABI constexpr - reverse_copy_result, _OutIter> operator()(_Range&& __range, _OutIter __result) const { + _LIBCPP_HIDE_FROM_ABI constexpr reverse_copy_result, _OutIter> + operator()(_Range&& __range, _OutIter __result) const { auto __ret = ranges::copy(std::__reverse_range(__range), std::move(__result)); return {ranges::next(ranges::begin(__range), ranges::end(__range)), std::move(__ret.out)}; } - }; } // namespace __reverse_copy inline namespace __cpo { - inline constexpr auto reverse_copy = __reverse_copy::__fn{}; +inline constexpr auto reverse_copy = __reverse_copy::__fn{}; } // namespace __cpo } // namespace ranges @@ -64,4 +65,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_REVERSE_COPY_H diff --git a/third_party/libcxx/__algorithm/ranges_rotate.h b/third_party/libcxx/__algorithm/ranges_rotate.h index 99e6ca67e..8d33a6f07 100644 --- a/third_party/libcxx/__algorithm/ranges_rotate.h +++ b/third_party/libcxx/__algorithm/ranges_rotate.h @@ -25,6 +25,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -33,34 +36,29 @@ namespace ranges { namespace __rotate { struct __fn { - template - _LIBCPP_HIDE_FROM_ABI constexpr - static subrange<_Iter> __rotate_fn_impl(_Iter __first, _Iter __middle, _Sent __last) { - auto __ret = std::__rotate<_RangeAlgPolicy>( - std::move(__first), std::move(__middle), std::move(__last)); + _LIBCPP_HIDE_FROM_ABI constexpr static subrange<_Iter> __rotate_fn_impl(_Iter __first, _Iter __middle, _Sent __last) { + auto __ret = std::__rotate<_RangeAlgPolicy>(std::move(__first), std::move(__middle), std::move(__last)); return {std::move(__ret.first), std::move(__ret.second)}; } template _Sent> - _LIBCPP_HIDE_FROM_ABI constexpr - subrange<_Iter> operator()(_Iter __first, _Iter __middle, _Sent __last) const { + _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> operator()(_Iter __first, _Iter __middle, _Sent __last) const { return __rotate_fn_impl(std::move(__first), std::move(__middle), std::move(__last)); } template - requires permutable> - _LIBCPP_HIDE_FROM_ABI constexpr - borrowed_subrange_t<_Range> operator()(_Range&& __range, iterator_t<_Range> __middle) const { + requires permutable> + _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> + operator()(_Range&& __range, iterator_t<_Range> __middle) const { return __rotate_fn_impl(ranges::begin(__range), std::move(__middle), ranges::end(__range)); } - }; } // namespace __rotate inline namespace __cpo { - inline constexpr auto rotate = __rotate::__fn{}; +inline constexpr auto rotate = __rotate::__fn{}; } // namespace __cpo } // namespace ranges @@ -68,4 +66,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_ROTATE_H diff --git a/third_party/libcxx/__algorithm/ranges_rotate_copy.h b/third_party/libcxx/__algorithm/ranges_rotate_copy.h index 5b9321f90..26fe110b5 100644 --- a/third_party/libcxx/__algorithm/ranges_rotate_copy.h +++ b/third_party/libcxx/__algorithm/ranges_rotate_copy.h @@ -13,7 +13,6 @@ #include <__algorithm/ranges_copy.h> #include <__config> #include <__iterator/concepts.h> -#include <__iterator/reverse_iterator.h> #include <__ranges/access.h> #include <__ranges/concepts.h> #include <__ranges/dangling.h> @@ -23,6 +22,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -34,30 +36,26 @@ using rotate_copy_result = in_out_result<_InIter, _OutIter>; namespace __rotate_copy { struct __fn { - - template _Sent, weakly_incrementable _OutIter> + template _Sent, weakly_incrementable _OutIter> requires indirectly_copyable<_InIter, _OutIter> - _LIBCPP_HIDE_FROM_ABI constexpr - rotate_copy_result<_InIter, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr rotate_copy_result<_InIter, _OutIter> operator()(_InIter __first, _InIter __middle, _Sent __last, _OutIter __result) const { auto __res1 = ranges::copy(__middle, __last, std::move(__result)); auto __res2 = ranges::copy(__first, __middle, std::move(__res1.out)); return {std::move(__res1.in), std::move(__res2.out)}; } - template + template requires indirectly_copyable, _OutIter> - _LIBCPP_HIDE_FROM_ABI constexpr - rotate_copy_result, _OutIter> + _LIBCPP_HIDE_FROM_ABI constexpr rotate_copy_result, _OutIter> operator()(_Range&& __range, iterator_t<_Range> __middle, _OutIter __result) const { return (*this)(ranges::begin(__range), std::move(__middle), ranges::end(__range), std::move(__result)); } - }; } // namespace __rotate_copy inline namespace __cpo { - inline constexpr auto rotate_copy = __rotate_copy::__fn{}; +inline constexpr auto rotate_copy = __rotate_copy::__fn{}; } // namespace __cpo } // namespace ranges @@ -65,4 +63,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_ROTATE_COPY_H diff --git a/third_party/libcxx/__algorithm/ranges_sample.h b/third_party/libcxx/__algorithm/ranges_sample.h index a5ff2d0c8..e4f60a7b6 100644 --- a/third_party/libcxx/__algorithm/ranges_sample.h +++ b/third_party/libcxx/__algorithm/ranges_sample.h @@ -27,6 +27,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -35,35 +38,30 @@ namespace ranges { namespace __sample { struct __fn { - template _Sent, weakly_incrementable _OutIter, class _Gen> - requires (forward_iterator<_Iter> || random_access_iterator<_OutIter>) && - indirectly_copyable<_Iter, _OutIter> && - uniform_random_bit_generator> - _LIBCPP_HIDE_FROM_ABI - _OutIter operator()(_Iter __first, _Sent __last, - _OutIter __out_first, iter_difference_t<_Iter> __n, _Gen&& __gen) const { + requires(forward_iterator<_Iter> || random_access_iterator<_OutIter>) && indirectly_copyable<_Iter, _OutIter> && + uniform_random_bit_generator> + _LIBCPP_HIDE_FROM_ABI _OutIter + operator()(_Iter __first, _Sent __last, _OutIter __out_first, iter_difference_t<_Iter> __n, _Gen&& __gen) const { _ClassicGenAdaptor<_Gen> __adapted_gen(__gen); return std::__sample<_RangeAlgPolicy>( std::move(__first), std::move(__last), std::move(__out_first), __n, __adapted_gen); } template - requires (forward_range<_Range> || random_access_iterator<_OutIter>) && - indirectly_copyable, _OutIter> && - uniform_random_bit_generator> - _LIBCPP_HIDE_FROM_ABI - _OutIter operator()(_Range&& __range, _OutIter __out_first, range_difference_t<_Range> __n, _Gen&& __gen) const { - return (*this)(ranges::begin(__range), ranges::end(__range), - std::move(__out_first), __n, std::forward<_Gen>(__gen)); + requires(forward_range<_Range> || random_access_iterator<_OutIter>) && + indirectly_copyable, _OutIter> && uniform_random_bit_generator> + _LIBCPP_HIDE_FROM_ABI _OutIter + operator()(_Range&& __range, _OutIter __out_first, range_difference_t<_Range> __n, _Gen&& __gen) const { + return (*this)( + ranges::begin(__range), ranges::end(__range), std::move(__out_first), __n, std::forward<_Gen>(__gen)); } - }; } // namespace __sample inline namespace __cpo { - inline constexpr auto sample = __sample::__fn{}; +inline constexpr auto sample = __sample::__fn{}; } // namespace __cpo } // namespace ranges @@ -71,4 +69,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_SAMPLE_H diff --git a/third_party/libcxx/__algorithm/ranges_search.h b/third_party/libcxx/__algorithm/ranges_search.h index 6d3e31868..55294c606 100644 --- a/third_party/libcxx/__algorithm/ranges_search.h +++ b/third_party/libcxx/__algorithm/ranges_search.h @@ -69,33 +69,33 @@ struct __fn { return {__ret.first, __ret.second}; } - template _Sent1, - forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2, - class _Pred = ranges::equal_to, + template _Sent1, + forward_iterator _Iter2, + sentinel_for<_Iter2> _Sent2, + class _Pred = ranges::equal_to, class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - subrange<_Iter1> operator()(_Iter1 __first1, _Sent1 __last1, - _Iter2 __first2, _Sent2 __last2, - _Pred __pred = {}, - _Proj1 __proj1 = {}, - _Proj2 __proj2 = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter1> operator()( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Pred __pred = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { return __ranges_search_impl(__first1, __last1, __first2, __last2, __pred, __proj1, __proj2); } template requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - borrowed_subrange_t<_Range1> operator()(_Range1&& __range1, - _Range2&& __range2, - _Pred __pred = {}, - _Proj1 __proj1 = {}, - _Proj2 __proj2 = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range1> operator()( + _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { auto __first1 = ranges::begin(__range1); if constexpr (sized_range<_Range2>) { auto __size2 = ranges::size(__range2); @@ -119,12 +119,11 @@ struct __fn { __proj1, __proj2); } - }; } // namespace __search inline namespace __cpo { - inline constexpr auto search = __search::__fn{}; +inline constexpr auto search = __search::__fn{}; } // namespace __cpo } // namespace ranges diff --git a/third_party/libcxx/__algorithm/ranges_search_n.h b/third_party/libcxx/__algorithm/ranges_search_n.h index ed5ec34f0..56e12755b 100644 --- a/third_party/libcxx/__algorithm/ranges_search_n.h +++ b/third_party/libcxx/__algorithm/ranges_search_n.h @@ -31,6 +31,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -38,7 +41,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __search_n { struct __fn { - template _LIBCPP_HIDE_FROM_ABI static constexpr subrange<_Iter1> __ranges_search_n_impl( _Iter1 __first, _Sent1 __last, _SizeT __count, const _Type& __value, _Pred& __pred, _Proj& __proj) { @@ -59,36 +61,31 @@ struct __fn { } } - auto __ret = std::__search_n_forward_impl<_RangeAlgPolicy>(__first, __last, - __count, - __value, - __pred, - __proj); + auto __ret = std::__search_n_forward_impl<_RangeAlgPolicy>(__first, __last, __count, __value, __pred, __proj); return {std::move(__ret.first), std::move(__ret.second)}; } - template _Sent, + template _Sent, class _Type, class _Pred = ranges::equal_to, class _Proj = identity> requires indirectly_comparable<_Iter, const _Type*, _Pred, _Proj> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - subrange<_Iter> operator()(_Iter __first, _Sent __last, - iter_difference_t<_Iter> __count, - const _Type& __value, - _Pred __pred = {}, - _Proj __proj = _Proj{}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> + operator()(_Iter __first, + _Sent __last, + iter_difference_t<_Iter> __count, + const _Type& __value, + _Pred __pred = {}, + _Proj __proj = _Proj{}) const { return __ranges_search_n_impl(__first, __last, __count, __value, __pred, __proj); } template requires indirectly_comparable, const _Type*, _Pred, _Proj> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - borrowed_subrange_t<_Range> operator()(_Range&& __range, - range_difference_t<_Range> __count, - const _Type& __value, - _Pred __pred = {}, - _Proj __proj = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> operator()( + _Range&& __range, range_difference_t<_Range> __count, const _Type& __value, _Pred __pred = {}, _Proj __proj = {}) + const { auto __first = ranges::begin(__range); if (__count <= 0) return {__first, __first}; @@ -106,7 +103,7 @@ struct __fn { } // namespace __search_n inline namespace __cpo { - inline constexpr auto search_n = __search_n::__fn{}; +inline constexpr auto search_n = __search_n::__fn{}; } // namespace __cpo } // namespace ranges @@ -114,4 +111,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_SEARCH_N_H diff --git a/third_party/libcxx/__algorithm/ranges_set_difference.h b/third_party/libcxx/__algorithm/ranges_set_difference.h index 6b9af876b..0841fb4ff 100644 --- a/third_party/libcxx/__algorithm/ranges_set_difference.h +++ b/third_party/libcxx/__algorithm/ranges_set_difference.h @@ -30,6 +30,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -42,15 +45,14 @@ using set_difference_result = in_out_result<_InIter, _OutIter>; namespace __set_difference { struct __fn { - template < - input_iterator _InIter1, - sentinel_for<_InIter1> _Sent1, - input_iterator _InIter2, - sentinel_for<_InIter2> _Sent2, - weakly_incrementable _OutIter, - class _Comp = less, - class _Proj1 = identity, - class _Proj2 = identity> + template _Sent1, + input_iterator _InIter2, + sentinel_for<_InIter2> _Sent2, + weakly_incrementable _OutIter, + class _Comp = less, + class _Proj1 = identity, + class _Proj2 = identity> requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2> _LIBCPP_HIDE_FROM_ABI constexpr set_difference_result<_InIter1, _OutIter> operator()( _InIter1 __first1, @@ -66,22 +68,20 @@ struct __fn { return {std::move(__ret.first), std::move(__ret.second)}; } - template < - input_range _Range1, - input_range _Range2, - weakly_incrementable _OutIter, - class _Comp = less, - class _Proj1 = identity, - class _Proj2 = identity> + template requires mergeable, iterator_t<_Range2>, _OutIter, _Comp, _Proj1, _Proj2> _LIBCPP_HIDE_FROM_ABI constexpr set_difference_result, _OutIter> - operator()( - _Range1&& __range1, - _Range2&& __range2, - _OutIter __result, - _Comp __comp = {}, - _Proj1 __proj1 = {}, - _Proj2 __proj2 = {}) const { + operator()(_Range1&& __range1, + _Range2&& __range2, + _OutIter __result, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { auto __ret = std::__set_difference<_RangeAlgPolicy>( ranges::begin(__range1), ranges::end(__range1), @@ -96,11 +96,14 @@ struct __fn { } // namespace __set_difference inline namespace __cpo { - inline constexpr auto set_difference = __set_difference::__fn{}; +inline constexpr auto set_difference = __set_difference::__fn{}; } // namespace __cpo } // namespace ranges _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 + +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_SET_DIFFERENCE_H diff --git a/third_party/libcxx/__algorithm/ranges_set_intersection.h b/third_party/libcxx/__algorithm/ranges_set_intersection.h index 5848656ce..942737974 100644 --- a/third_party/libcxx/__algorithm/ranges_set_intersection.h +++ b/third_party/libcxx/__algorithm/ranges_set_intersection.h @@ -28,6 +28,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -40,15 +43,14 @@ using set_intersection_result = in_in_out_result<_InIter1, _InIter2, _OutIter>; namespace __set_intersection { struct __fn { - template < - input_iterator _InIter1, - sentinel_for<_InIter1> _Sent1, - input_iterator _InIter2, - sentinel_for<_InIter2> _Sent2, - weakly_incrementable _OutIter, - class _Comp = less, - class _Proj1 = identity, - class _Proj2 = identity> + template _Sent1, + input_iterator _InIter2, + sentinel_for<_InIter2> _Sent2, + weakly_incrementable _OutIter, + class _Comp = less, + class _Proj1 = identity, + class _Proj2 = identity> requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2> _LIBCPP_HIDE_FROM_ABI constexpr set_intersection_result<_InIter1, _InIter2, _OutIter> operator()( _InIter1 __first1, @@ -69,30 +71,22 @@ struct __fn { return {std::move(__ret.__in1_), std::move(__ret.__in2_), std::move(__ret.__out_)}; } - template < - input_range _Range1, - input_range _Range2, - weakly_incrementable _OutIter, - class _Comp = less, - class _Proj1 = identity, - class _Proj2 = identity> - requires mergeable< - iterator_t<_Range1>, - iterator_t<_Range2>, - _OutIter, - _Comp, - _Proj1, - _Proj2> - _LIBCPP_HIDE_FROM_ABI constexpr set_intersection_result, - borrowed_iterator_t<_Range2>, - _OutIter> - operator()( - _Range1&& __range1, - _Range2&& __range2, - _OutIter __result, - _Comp __comp = {}, - _Proj1 __proj1 = {}, - _Proj2 __proj2 = {}) const { + template + requires mergeable, iterator_t<_Range2>, _OutIter, _Comp, _Proj1, _Proj2> + _LIBCPP_HIDE_FROM_ABI constexpr set_intersection_result, + borrowed_iterator_t<_Range2>, + _OutIter> + operator()(_Range1&& __range1, + _Range2&& __range2, + _OutIter __result, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { auto __ret = std::__set_intersection<_RangeAlgPolicy>( ranges::begin(__range1), ranges::end(__range1), @@ -107,11 +101,14 @@ struct __fn { } // namespace __set_intersection inline namespace __cpo { - inline constexpr auto set_intersection = __set_intersection::__fn{}; +inline constexpr auto set_intersection = __set_intersection::__fn{}; } // namespace __cpo } // namespace ranges _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 + +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_SET_INTERSECTION_H diff --git a/third_party/libcxx/__algorithm/ranges_set_symmetric_difference.h b/third_party/libcxx/__algorithm/ranges_set_symmetric_difference.h index f8bcf3795..995eb0999 100644 --- a/third_party/libcxx/__algorithm/ranges_set_symmetric_difference.h +++ b/third_party/libcxx/__algorithm/ranges_set_symmetric_difference.h @@ -28,6 +28,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -40,15 +43,14 @@ using set_symmetric_difference_result = in_in_out_result<_InIter1, _InIter2, _Ou namespace __set_symmetric_difference { struct __fn { - template < - input_iterator _InIter1, - sentinel_for<_InIter1> _Sent1, - input_iterator _InIter2, - sentinel_for<_InIter2> _Sent2, - weakly_incrementable _OutIter, - class _Comp = ranges::less, - class _Proj1 = identity, - class _Proj2 = identity> + template _Sent1, + input_iterator _InIter2, + sentinel_for<_InIter2> _Sent2, + weakly_incrementable _OutIter, + class _Comp = ranges::less, + class _Proj1 = identity, + class _Proj2 = identity> requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2> _LIBCPP_HIDE_FROM_ABI constexpr set_symmetric_difference_result<_InIter1, _InIter2, _OutIter> operator()( _InIter1 __first1, @@ -69,30 +71,22 @@ struct __fn { return {std::move(__ret.__in1_), std::move(__ret.__in2_), std::move(__ret.__out_)}; } - template < - input_range _Range1, - input_range _Range2, - weakly_incrementable _OutIter, - class _Comp = ranges::less, - class _Proj1 = identity, - class _Proj2 = identity> - requires mergeable< - iterator_t<_Range1>, - iterator_t<_Range2>, - _OutIter, - _Comp, - _Proj1, - _Proj2> + template + requires mergeable, iterator_t<_Range2>, _OutIter, _Comp, _Proj1, _Proj2> _LIBCPP_HIDE_FROM_ABI constexpr set_symmetric_difference_result, borrowed_iterator_t<_Range2>, _OutIter> - operator()( - _Range1&& __range1, - _Range2&& __range2, - _OutIter __result, - _Comp __comp = {}, - _Proj1 __proj1 = {}, - _Proj2 __proj2 = {}) const { + operator()(_Range1&& __range1, + _Range2&& __range2, + _OutIter __result, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { auto __ret = std::__set_symmetric_difference<_RangeAlgPolicy>( ranges::begin(__range1), ranges::end(__range1), @@ -107,11 +101,14 @@ struct __fn { } // namespace __set_symmetric_difference inline namespace __cpo { - inline constexpr auto set_symmetric_difference = __set_symmetric_difference::__fn{}; +inline constexpr auto set_symmetric_difference = __set_symmetric_difference::__fn{}; } // namespace __cpo } // namespace ranges _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 + +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_SET_SYMMETRIC_DIFFERENCE_H diff --git a/third_party/libcxx/__algorithm/ranges_set_union.h b/third_party/libcxx/__algorithm/ranges_set_union.h index bc669cc83..e870e390c 100644 --- a/third_party/libcxx/__algorithm/ranges_set_union.h +++ b/third_party/libcxx/__algorithm/ranges_set_union.h @@ -31,6 +31,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -43,15 +46,14 @@ using set_union_result = in_in_out_result<_InIter1, _InIter2, _OutIter>; namespace __set_union { struct __fn { - template < - input_iterator _InIter1, - sentinel_for<_InIter1> _Sent1, - input_iterator _InIter2, - sentinel_for<_InIter2> _Sent2, - weakly_incrementable _OutIter, - class _Comp = ranges::less, - class _Proj1 = identity, - class _Proj2 = identity> + template _Sent1, + input_iterator _InIter2, + sentinel_for<_InIter2> _Sent2, + weakly_incrementable _OutIter, + class _Comp = ranges::less, + class _Proj1 = identity, + class _Proj2 = identity> requires mergeable<_InIter1, _InIter2, _OutIter, _Comp, _Proj1, _Proj2> _LIBCPP_HIDE_FROM_ABI constexpr set_union_result<_InIter1, _InIter2, _OutIter> operator()( _InIter1 __first1, @@ -72,30 +74,20 @@ struct __fn { return {std::move(__ret.__in1_), std::move(__ret.__in2_), std::move(__ret.__out_)}; } - template < - input_range _Range1, - input_range _Range2, - weakly_incrementable _OutIter, - class _Comp = ranges::less, - class _Proj1 = identity, - class _Proj2 = identity> - requires mergeable< - iterator_t<_Range1>, - iterator_t<_Range2>, - _OutIter, - _Comp, - _Proj1, - _Proj2> - _LIBCPP_HIDE_FROM_ABI constexpr set_union_result, - borrowed_iterator_t<_Range2>, - _OutIter> - operator()( - _Range1&& __range1, - _Range2&& __range2, - _OutIter __result, - _Comp __comp = {}, - _Proj1 __proj1 = {}, - _Proj2 __proj2 = {}) const { + template + requires mergeable, iterator_t<_Range2>, _OutIter, _Comp, _Proj1, _Proj2> + _LIBCPP_HIDE_FROM_ABI constexpr set_union_result, borrowed_iterator_t<_Range2>, _OutIter> + operator()(_Range1&& __range1, + _Range2&& __range2, + _OutIter __result, + _Comp __comp = {}, + _Proj1 __proj1 = {}, + _Proj2 __proj2 = {}) const { auto __ret = std::__set_union<_RangeAlgPolicy>( ranges::begin(__range1), ranges::end(__range1), @@ -110,7 +102,7 @@ struct __fn { } // namespace __set_union inline namespace __cpo { - inline constexpr auto set_union = __set_union::__fn{}; +inline constexpr auto set_union = __set_union::__fn{}; } // namespace __cpo } // namespace ranges @@ -118,4 +110,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_SET_UNION_H diff --git a/third_party/libcxx/__algorithm/ranges_shuffle.h b/third_party/libcxx/__algorithm/ranges_shuffle.h index 2f45fb00f..ab98ea22c 100644 --- a/third_party/libcxx/__algorithm/ranges_shuffle.h +++ b/third_party/libcxx/__algorithm/ranges_shuffle.h @@ -31,6 +31,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -39,28 +42,24 @@ namespace ranges { namespace __shuffle { struct __fn { - template _Sent, class _Gen> - requires permutable<_Iter> && uniform_random_bit_generator> - _LIBCPP_HIDE_FROM_ABI - _Iter operator()(_Iter __first, _Sent __last, _Gen&& __gen) const { + requires permutable<_Iter> && uniform_random_bit_generator> + _LIBCPP_HIDE_FROM_ABI _Iter operator()(_Iter __first, _Sent __last, _Gen&& __gen) const { _ClassicGenAdaptor<_Gen> __adapted_gen(__gen); return std::__shuffle<_RangeAlgPolicy>(std::move(__first), std::move(__last), __adapted_gen); } - template - requires permutable> && uniform_random_bit_generator> - _LIBCPP_HIDE_FROM_ABI - borrowed_iterator_t<_Range> operator()(_Range&& __range, _Gen&& __gen) const { + template + requires permutable> && uniform_random_bit_generator> + _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_Range> operator()(_Range&& __range, _Gen&& __gen) const { return (*this)(ranges::begin(__range), ranges::end(__range), std::forward<_Gen>(__gen)); } - }; } // namespace __shuffle inline namespace __cpo { - inline constexpr auto shuffle = __shuffle::__fn{}; +inline constexpr auto shuffle = __shuffle::__fn{}; } // namespace __cpo } // namespace ranges @@ -68,4 +67,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_SHUFFLE_H diff --git a/third_party/libcxx/__algorithm/ranges_sort.h b/third_party/libcxx/__algorithm/ranges_sort.h index 60305b10a..0296c146b 100644 --- a/third_party/libcxx/__algorithm/ranges_sort.h +++ b/third_party/libcxx/__algorithm/ranges_sort.h @@ -31,6 +31,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -40,8 +43,8 @@ namespace __sort { struct __fn { template - _LIBCPP_HIDE_FROM_ABI constexpr static - _Iter __sort_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { + _LIBCPP_HIDE_FROM_ABI constexpr static _Iter + __sort_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { auto __last_iter = ranges::next(__first, __last); auto&& __projected_comp = std::__make_projected(__comp, __proj); @@ -52,15 +55,15 @@ struct __fn { template _Sent, class _Comp = ranges::less, class _Proj = identity> requires sortable<_Iter, _Comp, _Proj> - _LIBCPP_HIDE_FROM_ABI constexpr - _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + _LIBCPP_HIDE_FROM_ABI constexpr _Iter + operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { return __sort_fn_impl(std::move(__first), std::move(__last), __comp, __proj); } template requires sortable, _Comp, _Proj> - _LIBCPP_HIDE_FROM_ABI constexpr - borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> + operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { return __sort_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); } }; @@ -68,7 +71,7 @@ struct __fn { } // namespace __sort inline namespace __cpo { - inline constexpr auto sort = __sort::__fn{}; +inline constexpr auto sort = __sort::__fn{}; } // namespace __cpo } // namespace ranges @@ -76,4 +79,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_SORT_H diff --git a/third_party/libcxx/__algorithm/ranges_sort_heap.h b/third_party/libcxx/__algorithm/ranges_sort_heap.h index b40eef976..bab30df17 100644 --- a/third_party/libcxx/__algorithm/ranges_sort_heap.h +++ b/third_party/libcxx/__algorithm/ranges_sort_heap.h @@ -32,6 +32,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -41,8 +44,8 @@ namespace __sort_heap { struct __fn { template - _LIBCPP_HIDE_FROM_ABI constexpr static - _Iter __sort_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { + _LIBCPP_HIDE_FROM_ABI constexpr static _Iter + __sort_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { auto __last_iter = ranges::next(__first, __last); auto&& __projected_comp = std::__make_projected(__comp, __proj); @@ -53,15 +56,15 @@ struct __fn { template _Sent, class _Comp = ranges::less, class _Proj = identity> requires sortable<_Iter, _Comp, _Proj> - _LIBCPP_HIDE_FROM_ABI constexpr - _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + _LIBCPP_HIDE_FROM_ABI constexpr _Iter + operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { return __sort_heap_fn_impl(std::move(__first), std::move(__last), __comp, __proj); } template requires sortable, _Comp, _Proj> - _LIBCPP_HIDE_FROM_ABI constexpr - borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> + operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { return __sort_heap_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); } }; @@ -69,7 +72,7 @@ struct __fn { } // namespace __sort_heap inline namespace __cpo { - inline constexpr auto sort_heap = __sort_heap::__fn{}; +inline constexpr auto sort_heap = __sort_heap::__fn{}; } // namespace __cpo } // namespace ranges @@ -77,4 +80,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_SORT_HEAP_H diff --git a/third_party/libcxx/__algorithm/ranges_stable_partition.h b/third_party/libcxx/__algorithm/ranges_stable_partition.h index 77bef850a..f34027ff7 100644 --- a/third_party/libcxx/__algorithm/ranges_stable_partition.h +++ b/third_party/libcxx/__algorithm/ranges_stable_partition.h @@ -34,6 +34,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -42,42 +45,41 @@ namespace ranges { namespace __stable_partition { struct __fn { - template - _LIBCPP_HIDE_FROM_ABI static - subrange<__remove_cvref_t<_Iter>> __stable_partition_fn_impl( - _Iter&& __first, _Sent&& __last, _Pred&& __pred, _Proj&& __proj) { + _LIBCPP_HIDE_FROM_ABI static subrange<__remove_cvref_t<_Iter>> + __stable_partition_fn_impl(_Iter&& __first, _Sent&& __last, _Pred&& __pred, _Proj&& __proj) { auto __last_iter = ranges::next(__first, __last); auto&& __projected_pred = std::__make_projected(__pred, __proj); - auto __result = std::__stable_partition<_RangeAlgPolicy>( + auto __result = std::__stable_partition<_RangeAlgPolicy>( std::move(__first), __last_iter, __projected_pred, __iterator_concept<_Iter>()); return {std::move(__result), std::move(__last_iter)}; } - template _Sent, class _Proj = identity, + template _Sent, + class _Proj = identity, indirect_unary_predicate> _Pred> - requires permutable<_Iter> - _LIBCPP_HIDE_FROM_ABI - subrange<_Iter> operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { + requires permutable<_Iter> + _LIBCPP_HIDE_FROM_ABI subrange<_Iter> operator()(_Iter __first, _Sent __last, _Pred __pred, _Proj __proj = {}) const { return __stable_partition_fn_impl(__first, __last, __pred, __proj); } - template , _Proj>> _Pred> - requires permutable> - _LIBCPP_HIDE_FROM_ABI - borrowed_subrange_t<_Range> operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { + requires permutable> + _LIBCPP_HIDE_FROM_ABI borrowed_subrange_t<_Range> + operator()(_Range&& __range, _Pred __pred, _Proj __proj = {}) const { return __stable_partition_fn_impl(ranges::begin(__range), ranges::end(__range), __pred, __proj); } - }; } // namespace __stable_partition inline namespace __cpo { - inline constexpr auto stable_partition = __stable_partition::__fn{}; +inline constexpr auto stable_partition = __stable_partition::__fn{}; } // namespace __cpo } // namespace ranges @@ -85,4 +87,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_STABLE_PARTITION_H diff --git a/third_party/libcxx/__algorithm/ranges_stable_sort.h b/third_party/libcxx/__algorithm/ranges_stable_sort.h index b823e3bcb..93909e253 100644 --- a/third_party/libcxx/__algorithm/ranges_stable_sort.h +++ b/third_party/libcxx/__algorithm/ranges_stable_sort.h @@ -31,6 +31,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -40,8 +43,7 @@ namespace __stable_sort { struct __fn { template - _LIBCPP_HIDE_FROM_ABI - static _Iter __stable_sort_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { + _LIBCPP_HIDE_FROM_ABI static _Iter __stable_sort_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) { auto __last_iter = ranges::next(__first, __last); auto&& __projected_comp = std::__make_projected(__comp, __proj); @@ -52,15 +54,14 @@ struct __fn { template _Sent, class _Comp = ranges::less, class _Proj = identity> requires sortable<_Iter, _Comp, _Proj> - _LIBCPP_HIDE_FROM_ABI - _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + _LIBCPP_HIDE_FROM_ABI _Iter operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { return __stable_sort_fn_impl(std::move(__first), std::move(__last), __comp, __proj); } template requires sortable, _Comp, _Proj> - _LIBCPP_HIDE_FROM_ABI - borrowed_iterator_t<_Range> operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { + _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_Range> + operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const { return __stable_sort_fn_impl(ranges::begin(__r), ranges::end(__r), __comp, __proj); } }; @@ -68,7 +69,7 @@ struct __fn { } // namespace __stable_sort inline namespace __cpo { - inline constexpr auto stable_sort = __stable_sort::__fn{}; +inline constexpr auto stable_sort = __stable_sort::__fn{}; } // namespace __cpo } // namespace ranges @@ -76,4 +77,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_STABLE_SORT_H diff --git a/third_party/libcxx/__algorithm/ranges_starts_with.h b/third_party/libcxx/__algorithm/ranges_starts_with.h index 7da78001d..17084e4f2 100644 --- a/third_party/libcxx/__algorithm/ranges_starts_with.h +++ b/third_party/libcxx/__algorithm/ranges_starts_with.h @@ -24,6 +24,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 23 _LIBCPP_BEGIN_NAMESPACE_STD @@ -39,14 +42,14 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr bool operator()( _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Pred __pred = {}, _Proj1 __proj1 = {}, - _Proj2 __proj2 = {}) const { + _Proj2 __proj2 = {}) { return __mismatch::__fn::__go( std::move(__first1), std::move(__last1), @@ -64,8 +67,8 @@ struct __fn { class _Proj1 = identity, class _Proj2 = identity> requires indirectly_comparable, iterator_t<_Range2>, _Pred, _Proj1, _Proj2> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr bool operator()( - _Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr bool + operator()(_Range1&& __range1, _Range2&& __range2, _Pred __pred = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) { return __mismatch::__fn::__go( ranges::begin(__range1), ranges::end(__range1), @@ -87,4 +90,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 23 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_STARTS_WITH_H diff --git a/third_party/libcxx/__algorithm/ranges_swap_ranges.h b/third_party/libcxx/__algorithm/ranges_swap_ranges.h index 34124dbd8..b6d9f6183 100644 --- a/third_party/libcxx/__algorithm/ranges_swap_ranges.h +++ b/third_party/libcxx/__algorithm/ranges_swap_ranges.h @@ -24,6 +24,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -35,8 +38,7 @@ using swap_ranges_result = in_in_result<_I1, _I2>; namespace __swap_ranges { struct __fn { - template _S1, - input_iterator _I2, sentinel_for<_I2> _S2> + template _S1, input_iterator _I2, sentinel_for<_I2> _S2> requires indirectly_swappable<_I1, _I2> _LIBCPP_HIDE_FROM_ABI constexpr swap_ranges_result<_I1, _I2> operator()(_I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2) const { @@ -47,17 +49,15 @@ struct __fn { template requires indirectly_swappable, iterator_t<_R2>> - _LIBCPP_HIDE_FROM_ABI constexpr - swap_ranges_result, borrowed_iterator_t<_R2>> + _LIBCPP_HIDE_FROM_ABI constexpr swap_ranges_result, borrowed_iterator_t<_R2>> operator()(_R1&& __r1, _R2&& __r2) const { - return operator()(ranges::begin(__r1), ranges::end(__r1), - ranges::begin(__r2), ranges::end(__r2)); + return operator()(ranges::begin(__r1), ranges::end(__r1), ranges::begin(__r2), ranges::end(__r2)); } }; } // namespace __swap_ranges inline namespace __cpo { - inline constexpr auto swap_ranges = __swap_ranges::__fn{}; +inline constexpr auto swap_ranges = __swap_ranges::__fn{}; } // namespace __cpo } // namespace ranges @@ -65,4 +65,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_SWAP_RANGES_H diff --git a/third_party/libcxx/__algorithm/ranges_transform.h b/third_party/libcxx/__algorithm/ranges_transform.h index 1bba756fe..7850ec4f8 100644 --- a/third_party/libcxx/__algorithm/ranges_transform.h +++ b/third_party/libcxx/__algorithm/ranges_transform.h @@ -26,6 +26,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -41,15 +44,9 @@ using binary_transform_result = in_in_out_result<_I1, _I2, _O1>; namespace __transform { struct __fn { private: - template - _LIBCPP_HIDE_FROM_ABI static constexpr - unary_transform_result<_InIter, _OutIter> __unary(_InIter __first, _Sent __last, - _OutIter __result, - _Func& __operation, - _Proj& __projection) { + template + _LIBCPP_HIDE_FROM_ABI static constexpr unary_transform_result<_InIter, _OutIter> + __unary(_InIter __first, _Sent __last, _OutIter __result, _Func& __operation, _Proj& __projection) { while (__first != __last) { *__result = std::invoke(__operation, std::invoke(__projection, *__first)); ++__first; @@ -59,76 +56,80 @@ private: return {std::move(__first), std::move(__result)}; } - template _LIBCPP_HIDE_FROM_ABI static constexpr binary_transform_result<_InIter1, _InIter2, _OutIter> - __binary(_InIter1 __first1, _Sent1 __last1, - _InIter2 __first2, _Sent2 __last2, + __binary(_InIter1 __first1, + _Sent1 __last1, + _InIter2 __first2, + _Sent2 __last2, _OutIter __result, _Func& __binary_operation, _Proj1& __projection1, _Proj2& __projection2) { while (__first1 != __last1 && __first2 != __last2) { - *__result = std::invoke(__binary_operation, std::invoke(__projection1, *__first1), - std::invoke(__projection2, *__first2)); + *__result = + std::invoke(__binary_operation, std::invoke(__projection1, *__first1), std::invoke(__projection2, *__first2)); ++__first1; ++__first2; ++__result; } return {std::move(__first1), std::move(__first2), std::move(__result)}; } + public: - template _Sent, + template _Sent, weakly_incrementable _OutIter, copy_constructible _Func, class _Proj = identity> requires indirectly_writable<_OutIter, indirect_result_t<_Func&, projected<_InIter, _Proj>>> - _LIBCPP_HIDE_FROM_ABI constexpr - unary_transform_result<_InIter, _OutIter> operator()(_InIter __first, _Sent __last, - _OutIter __result, - _Func __operation, - _Proj __proj = {}) const { + _LIBCPP_HIDE_FROM_ABI constexpr unary_transform_result<_InIter, _OutIter> + operator()(_InIter __first, _Sent __last, _OutIter __result, _Func __operation, _Proj __proj = {}) const { return __unary(std::move(__first), std::move(__last), std::move(__result), __operation, __proj); } - template + template requires indirectly_writable<_OutIter, indirect_result_t<_Func, projected, _Proj>>> - _LIBCPP_HIDE_FROM_ABI constexpr - unary_transform_result, _OutIter> operator()(_Range&& __range, - _OutIter __result, - _Func __operation, - _Proj __projection = {}) const { + _LIBCPP_HIDE_FROM_ABI constexpr unary_transform_result, _OutIter> + operator()(_Range&& __range, _OutIter __result, _Func __operation, _Proj __projection = {}) const { return __unary(ranges::begin(__range), ranges::end(__range), std::move(__result), __operation, __projection); } - template _Sent1, - input_iterator _InIter2, sentinel_for<_InIter2> _Sent2, + template _Sent1, + input_iterator _InIter2, + sentinel_for<_InIter2> _Sent2, weakly_incrementable _OutIter, copy_constructible _Func, class _Proj1 = identity, class _Proj2 = identity> - requires indirectly_writable<_OutIter, indirect_result_t<_Func&, projected<_InIter1, _Proj1>, - projected<_InIter2, _Proj2>>> - _LIBCPP_HIDE_FROM_ABI constexpr - binary_transform_result<_InIter1, _InIter2, _OutIter> operator()(_InIter1 __first1, _Sent1 __last1, - _InIter2 __first2, _Sent2 __last2, - _OutIter __result, - _Func __binary_operation, - _Proj1 __projection1 = {}, - _Proj2 __projection2 = {}) const { - return __binary(std::move(__first1), std::move(__last1), - std::move(__first2), std::move(__last2), - std::move(__result), - __binary_operation, - __projection1, - __projection2); + requires indirectly_writable<_OutIter, + indirect_result_t<_Func&, projected<_InIter1, _Proj1>, projected<_InIter2, _Proj2>>> + _LIBCPP_HIDE_FROM_ABI constexpr binary_transform_result<_InIter1, _InIter2, _OutIter> operator()( + _InIter1 __first1, + _Sent1 __last1, + _InIter2 __first2, + _Sent2 __last2, + _OutIter __result, + _Func __binary_operation, + _Proj1 __projection1 = {}, + _Proj2 __projection2 = {}) const { + return __binary( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + std::move(__result), + __binary_operation, + __projection1, + __projection2); } template - requires indirectly_writable<_OutIter, indirect_result_t<_Func&, projected, _Proj1>, - projected, _Proj2>>> - _LIBCPP_HIDE_FROM_ABI constexpr - binary_transform_result, borrowed_iterator_t<_Range2>, _OutIter> + requires indirectly_writable< + _OutIter, + indirect_result_t<_Func&, projected, _Proj1>, projected, _Proj2>>> + _LIBCPP_HIDE_FROM_ABI constexpr binary_transform_result, + borrowed_iterator_t<_Range2>, + _OutIter> operator()(_Range1&& __range1, _Range2&& __range2, _OutIter __result, _Func __binary_operation, _Proj1 __projection1 = {}, _Proj2 __projection2 = {}) const { - return __binary(ranges::begin(__range1), ranges::end(__range1), - ranges::begin(__range2), ranges::end(__range2), - std::move(__result), - __binary_operation, - __projection1, - __projection2); + return __binary( + ranges::begin(__range1), + ranges::end(__range1), + ranges::begin(__range2), + ranges::end(__range2), + std::move(__result), + __binary_operation, + __projection1, + __projection2); } - }; } // namespace __transform inline namespace __cpo { - inline constexpr auto transform = __transform::__fn{}; +inline constexpr auto transform = __transform::__fn{}; } // namespace __cpo } // namespace ranges @@ -167,4 +172,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_TRANSFORM_H diff --git a/third_party/libcxx/__algorithm/ranges_unique.h b/third_party/libcxx/__algorithm/ranges_unique.h index 9e05c09fe..7a9b78432 100644 --- a/third_party/libcxx/__algorithm/ranges_unique.h +++ b/third_party/libcxx/__algorithm/ranges_unique.h @@ -32,6 +32,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -39,36 +42,34 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __unique { - struct __fn { - template < - permutable _Iter, - sentinel_for<_Iter> _Sent, - class _Proj = identity, - indirect_equivalence_relation> _Comp = ranges::equal_to> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> - operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { - auto __ret = std::__unique<_RangeAlgPolicy>( - std::move(__first), std::move(__last), std::__make_projected(__comp, __proj)); - return {std::move(__ret.first), std::move(__ret.second)}; - } +struct __fn { + template _Sent, + class _Proj = identity, + indirect_equivalence_relation> _Comp = ranges::equal_to> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter> + operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const { + auto __ret = + std::__unique<_RangeAlgPolicy>(std::move(__first), std::move(__last), std::__make_projected(__comp, __proj)); + return {std::move(__ret.first), std::move(__ret.second)}; + } - template < - forward_range _Range, - class _Proj = identity, - indirect_equivalence_relation, _Proj>> _Comp = ranges::equal_to> - requires permutable> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> - operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { - auto __ret = std::__unique<_RangeAlgPolicy>( - ranges::begin(__range), ranges::end(__range), std::__make_projected(__comp, __proj)); - return {std::move(__ret.first), std::move(__ret.second)}; - } - }; + template , _Proj>> _Comp = ranges::equal_to> + requires permutable> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range> + operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const { + auto __ret = std::__unique<_RangeAlgPolicy>( + ranges::begin(__range), ranges::end(__range), std::__make_projected(__comp, __proj)); + return {std::move(__ret.first), std::move(__ret.second)}; + } +}; } // namespace __unique inline namespace __cpo { - inline constexpr auto unique = __unique::__fn{}; +inline constexpr auto unique = __unique::__fn{}; } // namespace __cpo } // namespace ranges @@ -76,4 +77,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_UNIQUE_H diff --git a/third_party/libcxx/__algorithm/ranges_unique_copy.h b/third_party/libcxx/__algorithm/ranges_unique_copy.h index 2aaa879ea..61133885a 100644 --- a/third_party/libcxx/__algorithm/ranges_unique_copy.h +++ b/third_party/libcxx/__algorithm/ranges_unique_copy.h @@ -21,7 +21,6 @@ #include <__iterator/concepts.h> #include <__iterator/iterator_traits.h> #include <__iterator/projected.h> -#include <__iterator/readable_traits.h> #include <__ranges/access.h> #include <__ranges/concepts.h> #include <__ranges/dangling.h> @@ -33,6 +32,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -87,9 +89,9 @@ struct __fn { class _Proj = identity, indirect_equivalence_relation, _Proj>> _Comp = ranges::equal_to> requires indirectly_copyable, _OutIter> && - (forward_iterator> || - (input_iterator<_OutIter> && same_as, iter_value_t<_OutIter>>) || - indirectly_copyable_storable, _OutIter>) + (forward_iterator> || + (input_iterator<_OutIter> && same_as, iter_value_t<_OutIter>>) || + indirectly_copyable_storable, _OutIter>) _LIBCPP_HIDE_FROM_ABI constexpr unique_copy_result, _OutIter> operator()(_Range&& __range, _OutIter __result, _Comp __comp = {}, _Proj __proj = {}) const { auto __ret = std::__unique_copy<_RangeAlgPolicy>( @@ -113,4 +115,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_RANGES_UNIQUE_COPY_H diff --git a/third_party/libcxx/__algorithm/ranges_upper_bound.h b/third_party/libcxx/__algorithm/ranges_upper_bound.h index 43ce89b89..fa6fa7f70 100644 --- a/third_party/libcxx/__algorithm/ranges_upper_bound.h +++ b/third_party/libcxx/__algorithm/ranges_upper_bound.h @@ -32,39 +32,38 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __upper_bound { struct __fn { - template _Sent, class _Type, class _Proj = identity, + template _Sent, + class _Type, + class _Proj = identity, indirect_strict_weak_order> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - _Iter operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { - auto __comp_lhs_rhs_swapped = [&](const auto& __lhs, const auto& __rhs) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Iter + operator()(_Iter __first, _Sent __last, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { + auto __comp_lhs_rhs_swapped = [&](const auto& __lhs, const auto& __rhs) -> bool { return !std::invoke(__comp, __rhs, __lhs); }; - return std::__lower_bound_impl<_RangeAlgPolicy>(__first, __last, __value, __comp_lhs_rhs_swapped, __proj); + return std::__lower_bound<_RangeAlgPolicy>(__first, __last, __value, __comp_lhs_rhs_swapped, __proj); } - template , _Proj>> _Comp = ranges::less> - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr - borrowed_iterator_t<_Range> operator()(_Range&& __r, - const _Type& __value, - _Comp __comp = {}, - _Proj __proj = {}) const { - auto __comp_lhs_rhs_swapped = [&](const auto& __lhs, const auto& __rhs) { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr borrowed_iterator_t<_Range> + operator()(_Range&& __r, const _Type& __value, _Comp __comp = {}, _Proj __proj = {}) const { + auto __comp_lhs_rhs_swapped = [&](const auto& __lhs, const auto& __rhs) -> bool { return !std::invoke(__comp, __rhs, __lhs); }; - return std::__lower_bound_impl<_RangeAlgPolicy>(ranges::begin(__r), - ranges::end(__r), - __value, - __comp_lhs_rhs_swapped, - __proj); + return std::__lower_bound<_RangeAlgPolicy>( + ranges::begin(__r), ranges::end(__r), __value, __comp_lhs_rhs_swapped, __proj); } }; } // namespace __upper_bound inline namespace __cpo { - inline constexpr auto upper_bound = __upper_bound::__fn{}; +inline constexpr auto upper_bound = __upper_bound::__fn{}; } // namespace __cpo } // namespace ranges diff --git a/third_party/libcxx/__algorithm/remove.h b/third_party/libcxx/__algorithm/remove.h index 533e41b54..fd01c23cb 100644 --- a/third_party/libcxx/__algorithm/remove.h +++ b/third_party/libcxx/__algorithm/remove.h @@ -18,28 +18,29 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator -remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) -{ - __first = _VSTD::find(__first, __last, __value); - if (__first != __last) - { - _ForwardIterator __i = __first; - while (++__i != __last) - { - if (!(*__i == __value)) - { - *__first = _VSTD::move(*__i); - ++__first; - } - } +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { + __first = std::find(__first, __last, __value); + if (__first != __last) { + _ForwardIterator __i = __first; + while (++__i != __last) { + if (!(*__i == __value)) { + *__first = std::move(*__i); + ++__first; + } } - return __first; + } + return __first; } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_REMOVE_H diff --git a/third_party/libcxx/__algorithm/remove_copy.h b/third_party/libcxx/__algorithm/remove_copy.h index ecba08a05..7be4c166c 100644 --- a/third_party/libcxx/__algorithm/remove_copy.h +++ b/third_party/libcxx/__algorithm/remove_copy.h @@ -18,19 +18,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -remove_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __value) -{ - for (; __first != __last; ++__first) - { - if (!(*__first == __value)) - { - *__result = *__first; - ++__result; - } +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +remove_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __value) { + for (; __first != __last; ++__first) { + if (!(*__first == __value)) { + *__result = *__first; + ++__result; } - return __result; + } + return __result; } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/remove_copy_if.h b/third_party/libcxx/__algorithm/remove_copy_if.h index 2f235fd32..dcafed169 100644 --- a/third_party/libcxx/__algorithm/remove_copy_if.h +++ b/third_party/libcxx/__algorithm/remove_copy_if.h @@ -18,19 +18,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -remove_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred) -{ - for (; __first != __last; ++__first) - { - if (!__pred(*__first)) - { - *__result = *__first; - ++__result; - } +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +remove_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred) { + for (; __first != __last; ++__first) { + if (!__pred(*__first)) { + *__result = *__first; + ++__result; } - return __result; + } + return __result; } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/remove_if.h b/third_party/libcxx/__algorithm/remove_if.h index 27350728d..b14f3c0ef 100644 --- a/third_party/libcxx/__algorithm/remove_if.h +++ b/third_party/libcxx/__algorithm/remove_if.h @@ -17,28 +17,29 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator -remove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) -{ - __first = _VSTD::find_if<_ForwardIterator, _Predicate&>(__first, __last, __pred); - if (__first != __last) - { - _ForwardIterator __i = __first; - while (++__i != __last) - { - if (!__pred(*__i)) - { - *__first = _VSTD::move(*__i); - ++__first; - } - } +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +remove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { + __first = std::find_if<_ForwardIterator, _Predicate&>(__first, __last, __pred); + if (__first != __last) { + _ForwardIterator __i = __first; + while (++__i != __last) { + if (!__pred(*__i)) { + *__first = std::move(*__i); + ++__first; + } } - return __first; + } + return __first; } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_REMOVE_IF_H diff --git a/third_party/libcxx/__algorithm/replace.h b/third_party/libcxx/__algorithm/replace.h index ce6215066..8057c7868 100644 --- a/third_party/libcxx/__algorithm/replace.h +++ b/third_party/libcxx/__algorithm/replace.h @@ -18,13 +18,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -void -replace(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_value, const _Tp& __new_value) -{ - for (; __first != __last; ++__first) - if (*__first == __old_value) - *__first = __new_value; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +replace(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_value, const _Tp& __new_value) { + for (; __first != __last; ++__first) + if (*__first == __old_value) + *__first = __new_value; } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/replace_copy.h b/third_party/libcxx/__algorithm/replace_copy.h index bebb14cbe..9a2258d9f 100644 --- a/third_party/libcxx/__algorithm/replace_copy.h +++ b/third_party/libcxx/__algorithm/replace_copy.h @@ -18,17 +18,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -replace_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, - const _Tp& __old_value, const _Tp& __new_value) -{ - for (; __first != __last; ++__first, (void) ++__result) - if (*__first == __old_value) - *__result = __new_value; - else - *__result = *__first; - return __result; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator replace_copy( + _InputIterator __first, + _InputIterator __last, + _OutputIterator __result, + const _Tp& __old_value, + const _Tp& __new_value) { + for (; __first != __last; ++__first, (void)++__result) + if (*__first == __old_value) + *__result = __new_value; + else + *__result = *__first; + return __result; } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/replace_copy_if.h b/third_party/libcxx/__algorithm/replace_copy_if.h index e1ddb527b..c2ed30f08 100644 --- a/third_party/libcxx/__algorithm/replace_copy_if.h +++ b/third_party/libcxx/__algorithm/replace_copy_if.h @@ -18,17 +18,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -replace_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, - _Predicate __pred, const _Tp& __new_value) -{ - for (; __first != __last; ++__first, (void) ++__result) - if (__pred(*__first)) - *__result = __new_value; - else - *__result = *__first; - return __result; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator replace_copy_if( + _InputIterator __first, + _InputIterator __last, + _OutputIterator __result, + _Predicate __pred, + const _Tp& __new_value) { + for (; __first != __last; ++__first, (void)++__result) + if (__pred(*__first)) + *__result = __new_value; + else + *__result = *__first; + return __result; } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/replace_if.h b/third_party/libcxx/__algorithm/replace_if.h index b3a3367d2..78487e3de 100644 --- a/third_party/libcxx/__algorithm/replace_if.h +++ b/third_party/libcxx/__algorithm/replace_if.h @@ -18,13 +18,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -void -replace_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, const _Tp& __new_value) -{ - for (; __first != __last; ++__first) - if (__pred(*__first)) - *__first = __new_value; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +replace_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, const _Tp& __new_value) { + for (; __first != __last; ++__first) + if (__pred(*__first)) + *__first = __new_value; } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/reverse.h b/third_party/libcxx/__algorithm/reverse.h index aa7695170..4167c9116 100644 --- a/third_party/libcxx/__algorithm/reverse.h +++ b/third_party/libcxx/__algorithm/reverse.h @@ -19,47 +19,44 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -void -__reverse_impl(_BidirectionalIterator __first, _BidirectionalIterator __last, bidirectional_iterator_tag) -{ - while (__first != __last) - { - if (__first == --__last) - break; - _IterOps<_AlgPolicy>::iter_swap(__first, __last); - ++__first; - } +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +__reverse_impl(_BidirectionalIterator __first, _BidirectionalIterator __last, bidirectional_iterator_tag) { + while (__first != __last) { + if (__first == --__last) + break; + _IterOps<_AlgPolicy>::iter_swap(__first, __last); + ++__first; + } } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -void -__reverse_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag) -{ - if (__first != __last) - for (; __first < --__last; ++__first) - _IterOps<_AlgPolicy>::iter_swap(__first, __last); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +__reverse_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag) { + if (__first != __last) + for (; __first < --__last; ++__first) + _IterOps<_AlgPolicy>::iter_swap(__first, __last); } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void __reverse(_BidirectionalIterator __first, _Sentinel __last) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __reverse(_BidirectionalIterator __first, _Sentinel __last) { using _IterCategory = typename _IterOps<_AlgPolicy>::template __iterator_category<_BidirectionalIterator>; std::__reverse_impl<_AlgPolicy>(std::move(__first), std::move(__last), _IterCategory()); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -void -reverse(_BidirectionalIterator __first, _BidirectionalIterator __last) -{ +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +reverse(_BidirectionalIterator __first, _BidirectionalIterator __last) { std::__reverse<_ClassicAlgPolicy>(std::move(__first), std::move(__last)); } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_REVERSE_H diff --git a/third_party/libcxx/__algorithm/reverse_copy.h b/third_party/libcxx/__algorithm/reverse_copy.h index f4a0e9713..0fcecc392 100644 --- a/third_party/libcxx/__algorithm/reverse_copy.h +++ b/third_party/libcxx/__algorithm/reverse_copy.h @@ -18,13 +18,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) -{ - for (; __first != __last; ++__result) - *__result = *--__last; - return __result; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) { + for (; __first != __last; ++__result) + *__result = *--__last; + return __result; } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/rotate.h b/third_party/libcxx/__algorithm/rotate.h index 7ed6f1862..df4ca95aa 100644 --- a/third_party/libcxx/__algorithm/rotate.h +++ b/third_party/libcxx/__algorithm/rotate.h @@ -15,7 +15,7 @@ #include <__algorithm/swap_ranges.h> #include <__config> #include <__iterator/iterator_traits.h> -#include <__type_traits/is_trivially_move_assignable.h> +#include <__type_traits/is_trivially_assignable.h> #include <__utility/move.h> #include <__utility/pair.h> @@ -23,199 +23,176 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator -__rotate_left(_ForwardIterator __first, _ForwardIterator __last) -{ - typedef typename iterator_traits<_ForwardIterator>::value_type value_type; - using _Ops = _IterOps<_AlgPolicy>; +__rotate_left(_ForwardIterator __first, _ForwardIterator __last) { + typedef typename iterator_traits<_ForwardIterator>::value_type value_type; + using _Ops = _IterOps<_AlgPolicy>; - value_type __tmp = _Ops::__iter_move(__first); - _ForwardIterator __lm1 = std::__move<_AlgPolicy>( - _Ops::next(__first), __last, __first).second; - *__lm1 = _VSTD::move(__tmp); - return __lm1; + value_type __tmp = _Ops::__iter_move(__first); + _ForwardIterator __lm1 = std::__move<_AlgPolicy>(_Ops::next(__first), __last, __first).second; + *__lm1 = std::move(__tmp); + return __lm1; } template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _BidirectionalIterator -__rotate_right(_BidirectionalIterator __first, _BidirectionalIterator __last) -{ - typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; - using _Ops = _IterOps<_AlgPolicy>; +__rotate_right(_BidirectionalIterator __first, _BidirectionalIterator __last) { + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + using _Ops = _IterOps<_AlgPolicy>; - _BidirectionalIterator __lm1 = _Ops::prev(__last); - value_type __tmp = _Ops::__iter_move(__lm1); - _BidirectionalIterator __fp1 = std::__move_backward<_AlgPolicy>(__first, __lm1, std::move(__last)).second; - *__first = _VSTD::move(__tmp); - return __fp1; + _BidirectionalIterator __lm1 = _Ops::prev(__last); + value_type __tmp = _Ops::__iter_move(__lm1); + _BidirectionalIterator __fp1 = std::__move_backward<_AlgPolicy>(__first, __lm1, std::move(__last)).second; + *__first = std::move(__tmp); + return __fp1; } template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _ForwardIterator -__rotate_forward(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) -{ - _ForwardIterator __i = __middle; - while (true) - { - _IterOps<_AlgPolicy>::iter_swap(__first, __i); - ++__first; - if (++__i == __last) - break; +__rotate_forward(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) { + _ForwardIterator __i = __middle; + while (true) { + _IterOps<_AlgPolicy>::iter_swap(__first, __i); + ++__first; + if (++__i == __last) + break; + if (__first == __middle) + __middle = __i; + } + _ForwardIterator __r = __first; + if (__first != __middle) { + __i = __middle; + while (true) { + _IterOps<_AlgPolicy>::iter_swap(__first, __i); + ++__first; + if (++__i == __last) { if (__first == __middle) - __middle = __i; - } - _ForwardIterator __r = __first; - if (__first != __middle) - { + break; __i = __middle; - while (true) - { - _IterOps<_AlgPolicy>::iter_swap(__first, __i); - ++__first; - if (++__i == __last) - { - if (__first == __middle) - break; - __i = __middle; - } - else if (__first == __middle) - __middle = __i; - } + } else if (__first == __middle) + __middle = __i; } - return __r; + } + return __r; } -template -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR_SINCE_CXX17 _Integral -__algo_gcd(_Integral __x, _Integral __y) -{ - do - { - _Integral __t = __x % __y; - __x = __y; - __y = __t; - } while (__y); - return __x; +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _Integral __algo_gcd(_Integral __x, _Integral __y) { + do { + _Integral __t = __x % __y; + __x = __y; + __y = __t; + } while (__y); + return __x; } template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _RandomAccessIterator -__rotate_gcd(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) -{ - typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; - typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; - using _Ops = _IterOps<_AlgPolicy>; +__rotate_gcd(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) { + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + using _Ops = _IterOps<_AlgPolicy>; - const difference_type __m1 = __middle - __first; - const difference_type __m2 = _Ops::distance(__middle, __last); - if (__m1 == __m2) - { - std::__swap_ranges<_AlgPolicy>(__first, __middle, __middle, __last); - return __middle; - } - const difference_type __g = _VSTD::__algo_gcd(__m1, __m2); - for (_RandomAccessIterator __p = __first + __g; __p != __first;) - { - value_type __t(_Ops::__iter_move(--__p)); - _RandomAccessIterator __p1 = __p; - _RandomAccessIterator __p2 = __p1 + __m1; - do - { - *__p1 = _Ops::__iter_move(__p2); - __p1 = __p2; - const difference_type __d = _Ops::distance(__p2, __last); - if (__m1 < __d) - __p2 += __m1; - else - __p2 = __first + (__m1 - __d); - } while (__p2 != __p); - *__p1 = _VSTD::move(__t); - } - return __first + __m2; + const difference_type __m1 = __middle - __first; + const difference_type __m2 = _Ops::distance(__middle, __last); + if (__m1 == __m2) { + std::__swap_ranges<_AlgPolicy>(__first, __middle, __middle, __last); + return __middle; + } + const difference_type __g = std::__algo_gcd(__m1, __m2); + for (_RandomAccessIterator __p = __first + __g; __p != __first;) { + value_type __t(_Ops::__iter_move(--__p)); + _RandomAccessIterator __p1 = __p; + _RandomAccessIterator __p2 = __p1 + __m1; + do { + *__p1 = _Ops::__iter_move(__p2); + __p1 = __p2; + const difference_type __d = _Ops::distance(__p2, __last); + if (__m1 < __d) + __p2 += __m1; + else + __p2 = __first + (__m1 - __d); + } while (__p2 != __p); + *__p1 = std::move(__t); + } + return __first + __m2; } template -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator -__rotate_impl(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, - _VSTD::forward_iterator_tag) -{ - typedef typename iterator_traits<_ForwardIterator>::value_type value_type; - if (is_trivially_move_assignable::value) - { - if (_IterOps<_AlgPolicy>::next(__first) == __middle) - return std::__rotate_left<_AlgPolicy>(__first, __last); - } - return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator +__rotate_impl(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, std::forward_iterator_tag) { + typedef typename iterator_traits<_ForwardIterator>::value_type value_type; + if (is_trivially_move_assignable::value) { + if (_IterOps<_AlgPolicy>::next(__first) == __middle) + return std::__rotate_left<_AlgPolicy>(__first, __last); + } + return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last); } template -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR_SINCE_CXX14 _BidirectionalIterator -__rotate_impl(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, - bidirectional_iterator_tag) -{ - typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; - if (is_trivially_move_assignable::value) - { - if (_IterOps<_AlgPolicy>::next(__first) == __middle) - return std::__rotate_left<_AlgPolicy>(__first, __last); - if (_IterOps<_AlgPolicy>::next(__middle) == __last) - return std::__rotate_right<_AlgPolicy>(__first, __last); - } - return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _BidirectionalIterator __rotate_impl( + _BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + bidirectional_iterator_tag) { + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + if (is_trivially_move_assignable::value) { + if (_IterOps<_AlgPolicy>::next(__first) == __middle) + return std::__rotate_left<_AlgPolicy>(__first, __last); + if (_IterOps<_AlgPolicy>::next(__middle) == __last) + return std::__rotate_right<_AlgPolicy>(__first, __last); + } + return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last); } template -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR_SINCE_CXX14 _RandomAccessIterator -__rotate_impl(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, - random_access_iterator_tag) -{ - typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; - if (is_trivially_move_assignable::value) - { - if (_IterOps<_AlgPolicy>::next(__first) == __middle) - return std::__rotate_left<_AlgPolicy>(__first, __last); - if (_IterOps<_AlgPolicy>::next(__middle) == __last) - return std::__rotate_right<_AlgPolicy>(__first, __last); - return std::__rotate_gcd<_AlgPolicy>(__first, __middle, __last); - } - return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _RandomAccessIterator __rotate_impl( + _RandomAccessIterator __first, + _RandomAccessIterator __middle, + _RandomAccessIterator __last, + random_access_iterator_tag) { + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + if (is_trivially_move_assignable::value) { + if (_IterOps<_AlgPolicy>::next(__first) == __middle) + return std::__rotate_left<_AlgPolicy>(__first, __last); + if (_IterOps<_AlgPolicy>::next(__middle) == __last) + return std::__rotate_right<_AlgPolicy>(__first, __last); + return std::__rotate_gcd<_AlgPolicy>(__first, __middle, __last); + } + return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last); } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -pair<_Iterator, _Iterator> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iterator, _Iterator> __rotate(_Iterator __first, _Iterator __middle, _Sentinel __last) { - using _Ret = pair<_Iterator, _Iterator>; + using _Ret = pair<_Iterator, _Iterator>; _Iterator __last_iter = _IterOps<_AlgPolicy>::next(__middle, __last); if (__first == __middle) - return _Ret(__last_iter, __last_iter); + return _Ret(__last_iter, __last_iter); if (__middle == __last) - return _Ret(std::move(__first), std::move(__last_iter)); + return _Ret(std::move(__first), std::move(__last_iter)); using _IterCategory = typename _IterOps<_AlgPolicy>::template __iterator_category<_Iterator>; - auto __result = std::__rotate_impl<_AlgPolicy>( - std::move(__first), std::move(__middle), __last_iter, _IterCategory()); + auto __result = std::__rotate_impl<_AlgPolicy>(std::move(__first), std::move(__middle), __last_iter, _IterCategory()); return _Ret(std::move(__result), std::move(__last_iter)); } template -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator -rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) -{ - return std::__rotate<_ClassicAlgPolicy>( - std::move(__first), std::move(__middle), std::move(__last)).first; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) { + return std::__rotate<_ClassicAlgPolicy>(std::move(__first), std::move(__middle), std::move(__last)).first; } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_ROTATE_H diff --git a/third_party/libcxx/__algorithm/rotate_copy.h b/third_party/libcxx/__algorithm/rotate_copy.h index c154649ab..cddcadd23 100644 --- a/third_party/libcxx/__algorithm/rotate_copy.h +++ b/third_party/libcxx/__algorithm/rotate_copy.h @@ -19,11 +19,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, _OutputIterator __result) -{ - return _VSTD::copy(__first, __middle, _VSTD::copy(__middle, __last, __result)); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, _OutputIterator __result) { + return std::copy(__first, __middle, std::copy(__middle, __last, __result)); } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/sample.h b/third_party/libcxx/__algorithm/sample.h index 8769d494e..ebe5180b7 100644 --- a/third_party/libcxx/__algorithm/sample.h +++ b/third_party/libcxx/__algorithm/sample.h @@ -29,38 +29,45 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_INLINE_VISIBILITY -_SampleIterator __sample(_PopulationIterator __first, - _PopulationSentinel __last, _SampleIterator __output_iter, - _Distance __n, - _UniformRandomNumberGenerator& __g, - input_iterator_tag) { - +_LIBCPP_HIDE_FROM_ABI _SampleIterator __sample( + _PopulationIterator __first, + _PopulationSentinel __last, + _SampleIterator __output_iter, + _Distance __n, + _UniformRandomNumberGenerator& __g, + input_iterator_tag) { _Distance __k = 0; - for (; __first != __last && __k < __n; ++__first, (void) ++__k) + for (; __first != __last && __k < __n; ++__first, (void)++__k) __output_iter[__k] = *__first; _Distance __sz = __k; - for (; __first != __last; ++__first, (void) ++__k) { + for (; __first != __last; ++__first, (void)++__k) { _Distance __r = uniform_int_distribution<_Distance>(0, __k)(__g); if (__r < __sz) __output_iter[__r] = *__first; } - return __output_iter + _VSTD::min(__n, __k); + return __output_iter + std::min(__n, __k); } template -_LIBCPP_INLINE_VISIBILITY -_SampleIterator __sample(_PopulationIterator __first, - _PopulationSentinel __last, _SampleIterator __output_iter, - _Distance __n, - _UniformRandomNumberGenerator& __g, - forward_iterator_tag) { +_LIBCPP_HIDE_FROM_ABI _SampleIterator __sample( + _PopulationIterator __first, + _PopulationSentinel __last, + _SampleIterator __output_iter, + _Distance __n, + _UniformRandomNumberGenerator& __g, + forward_iterator_tag) { _Distance __unsampled_sz = _IterOps<_AlgPolicy>::distance(__first, __last); - for (__n = _VSTD::min(__n, __unsampled_sz); __n != 0; ++__first) { + for (__n = std::min(__n, __unsampled_sz); __n != 0; ++__first) { _Distance __r = uniform_int_distribution<_Distance>(0, --__unsampled_sz)(__g); if (__r < __n) { *__output_iter++ = *__first; @@ -71,36 +78,40 @@ _SampleIterator __sample(_PopulationIterator __first, } template -_LIBCPP_INLINE_VISIBILITY -_SampleIterator __sample(_PopulationIterator __first, - _PopulationSentinel __last, _SampleIterator __output_iter, - _Distance __n, _UniformRandomNumberGenerator& __g) { - _LIBCPP_ASSERT(__n >= 0, "N must be a positive number."); +_LIBCPP_HIDE_FROM_ABI _SampleIterator __sample( + _PopulationIterator __first, + _PopulationSentinel __last, + _SampleIterator __output_iter, + _Distance __n, + _UniformRandomNumberGenerator& __g) { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n >= 0, "N must be a positive number."); using _PopIterCategory = typename _IterOps<_AlgPolicy>::template __iterator_category<_PopulationIterator>; - using _Difference = typename _IterOps<_AlgPolicy>::template __difference_type<_PopulationIterator>; - using _CommonType = typename common_type<_Distance, _Difference>::type; + using _Difference = typename _IterOps<_AlgPolicy>::template __difference_type<_PopulationIterator>; + using _CommonType = typename common_type<_Distance, _Difference>::type; return std::__sample<_AlgPolicy>( - std::move(__first), std::move(__last), std::move(__output_iter), _CommonType(__n), - __g, _PopIterCategory()); + std::move(__first), std::move(__last), std::move(__output_iter), _CommonType(__n), __g, _PopIterCategory()); } #if _LIBCPP_STD_VER >= 17 -template -inline _LIBCPP_INLINE_VISIBILITY -_SampleIterator sample(_PopulationIterator __first, - _PopulationIterator __last, _SampleIterator __output_iter, - _Distance __n, _UniformRandomNumberGenerator&& __g) { +template +inline _LIBCPP_HIDE_FROM_ABI _SampleIterator +sample(_PopulationIterator __first, + _PopulationIterator __last, + _SampleIterator __output_iter, + _Distance __n, + _UniformRandomNumberGenerator&& __g) { static_assert(__has_forward_iterator_category<_PopulationIterator>::value || - __has_random_access_iterator_category<_SampleIterator>::value, + __has_random_access_iterator_category<_SampleIterator>::value, "SampleIterator must meet the requirements of RandomAccessIterator"); - return std::__sample<_ClassicAlgPolicy>( - std::move(__first), std::move(__last), std::move(__output_iter), __n, __g); + return std::__sample<_ClassicAlgPolicy>(std::move(__first), std::move(__last), std::move(__output_iter), __n, __g); } #endif // _LIBCPP_STD_VER >= 17 diff --git a/third_party/libcxx/__algorithm/search.h b/third_party/libcxx/__algorithm/search.h index 5882a0480..b82ca7809 100644 --- a/third_party/libcxx/__algorithm/search.h +++ b/third_party/libcxx/__algorithm/search.h @@ -29,17 +29,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -pair<_Iter1, _Iter1> __search_forward_impl(_Iter1 __first1, _Sent1 __last1, - _Iter2 __first2, _Sent2 __last2, - _Pred& __pred, - _Proj1& __proj1, - _Proj2& __proj2) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __search_forward_impl( + _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) { if (__first2 == __last2) return std::make_pair(__first1, __first1); // Everything matches an empty sequence while (true) { @@ -64,8 +62,7 @@ pair<_Iter1, _Iter1> __search_forward_impl(_Iter1 __first1, _Sent1 __last1, } // if there is a mismatch, restart with a new __first1 - if (!std::__invoke(__pred, std::__invoke(__proj1, *__m1), std::__invoke(__proj2, *__m2))) - { + if (!std::__invoke(__pred, std::__invoke(__proj1, *__m1), std::__invoke(__proj2, *__m2))) { ++__first1; break; } // else there is a match, check next elements @@ -74,21 +71,25 @@ pair<_Iter1, _Iter1> __search_forward_impl(_Iter1 __first1, _Sent1 __last1, } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -pair<_Iter1, _Iter1> __search_random_access_impl(_Iter1 __first1, _Sent1 __last1, - _Iter2 __first2, _Sent2 __last2, - _Pred& __pred, - _Proj1& __proj1, - _Proj2& __proj2, - _DiffT1 __size1, - _DiffT2 __size2) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __search_random_access_impl( + _Iter1 __first1, + _Sent1 __last1, + _Iter2 __first2, + _Sent2 __last2, + _Pred& __pred, + _Proj1& __proj1, + _Proj2& __proj2, + _DiffT1 __size1, + _DiffT2 __size2) { const _Iter1 __s = __first1 + __size1 - _DiffT1(__size2 - 1); // Start of pattern match can't go beyond here while (true) { @@ -116,20 +117,18 @@ pair<_Iter1, _Iter1> __search_random_access_impl(_Iter1 __first1, _Sent1 __last1 } } -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -pair<_Iter1, _Iter1> __search_impl(_Iter1 __first1, _Sent1 __last1, - _Iter2 __first2, _Sent2 __last2, - _Pred& __pred, - _Proj1& __proj1, - _Proj2& __proj2, - __enable_if_t<__has_random_access_iterator_category<_Iter1>::value - && __has_random_access_iterator_category<_Iter2>::value>* = nullptr) { - + class _Proj2, + __enable_if_t<__has_random_access_iterator_category<_Iter1>::value && + __has_random_access_iterator_category<_Iter2>::value, + int> = 0> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __search_impl( + _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) { auto __size2 = __last2 - __first2; if (__size2 == 0) return std::make_pair(__first1, __first1); @@ -139,42 +138,34 @@ pair<_Iter1, _Iter1> __search_impl(_Iter1 __first1, _Sent1 __last1, return std::make_pair(__last1, __last1); } - return std::__search_random_access_impl<_ClassicAlgPolicy>(__first1, __last1, - __first2, __last2, - __pred, - __proj1, - __proj2, - __size1, - __size2); + return std::__search_random_access_impl<_ClassicAlgPolicy>( + __first1, __last1, __first2, __last2, __pred, __proj1, __proj2, __size1, __size2); } -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -pair<_Iter1, _Iter1> __search_impl(_Iter1 __first1, _Sent1 __last1, - _Iter2 __first2, _Sent2 __last2, - _Pred& __pred, - _Proj1& __proj1, - _Proj2& __proj2, - __enable_if_t<__has_forward_iterator_category<_Iter1>::value - && __has_forward_iterator_category<_Iter2>::value - && !(__has_random_access_iterator_category<_Iter1>::value - && __has_random_access_iterator_category<_Iter2>::value)>* = nullptr) { - return std::__search_forward_impl<_ClassicAlgPolicy>(__first1, __last1, - __first2, __last2, - __pred, - __proj1, - __proj2); +template < + class _Iter1, + class _Sent1, + class _Iter2, + class _Sent2, + class _Pred, + class _Proj1, + class _Proj2, + __enable_if_t<__has_forward_iterator_category<_Iter1>::value && __has_forward_iterator_category<_Iter2>::value && + !(__has_random_access_iterator_category<_Iter1>::value && + __has_random_access_iterator_category<_Iter2>::value), + int> = 0> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __search_impl( + _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) { + return std::__search_forward_impl<_ClassicAlgPolicy>(__first1, __last1, __first2, __last2, __pred, __proj1, __proj2); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -_ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, - _BinaryPredicate __pred) { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 +search(_ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _BinaryPredicate __pred) { static_assert(__is_callable<_BinaryPredicate, decltype(*__first1), decltype(*__first2)>::value, "BinaryPredicate has to be callable"); auto __proj = __identity(); @@ -182,15 +173,14 @@ _ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -_ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2) { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1 +search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { return std::search(__first1, __last1, __first2, __last2, __equal_to()); } #if _LIBCPP_STD_VER >= 17 template -_LIBCPP_NODISCARD_EXT _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator search(_ForwardIterator __f, _ForwardIterator __l, const _Searcher& __s) { return __s(__f, __l).first; } diff --git a/third_party/libcxx/__algorithm/search_n.h b/third_party/libcxx/__algorithm/search_n.h index 7e3ddf48a..771647d31 100644 --- a/third_party/libcxx/__algorithm/search_n.h +++ b/third_party/libcxx/__algorithm/search_n.h @@ -31,12 +31,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -pair<_Iter, _Iter> __search_n_forward_impl(_Iter __first, _Sent __last, - _SizeT __count, - const _Type& __value, - _Pred& __pred, - _Proj& __proj) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter, _Iter> __search_n_forward_impl( + _Iter __first, _Sent __last, _SizeT __count, const _Type& __value, _Pred& __pred, _Proj& __proj) { if (__count <= 0) return std::make_pair(__first, __first); while (true) { @@ -62,8 +58,7 @@ pair<_Iter, _Iter> __search_n_forward_impl(_Iter __first, _Sent __last, } // if there is a mismatch, restart with a new __first - if (!std::__invoke(__pred, std::__invoke(__proj, *__m), __value)) - { + if (!std::__invoke(__pred, std::__invoke(__proj, *__m), __value)) { __first = __m; ++__first; break; @@ -73,13 +68,8 @@ pair<_Iter, _Iter> __search_n_forward_impl(_Iter __first, _Sent __last, } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -std::pair<_Iter, _Iter> __search_n_random_access_impl(_Iter __first, _Sent __last, - _SizeT __count, - const _Type& __value, - _Pred& __pred, - _Proj& __proj, - _DiffT __size1) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 std::pair<_Iter, _Iter> __search_n_random_access_impl( + _Iter __first, _Sent __last, _SizeT __count, const _Type& __value, _Pred& __pred, _Proj& __proj, _DiffT __size1) { using difference_type = typename iterator_traits<_Iter>::difference_type; if (__count == 0) return std::make_pair(__first, __first); @@ -109,8 +99,7 @@ std::pair<_Iter, _Iter> __search_n_random_access_impl(_Iter __first, _Sent __las ++__m; // no need to check range on __m because __s guarantees we have enough source // if there is a mismatch, restart with a new __first - if (!std::__invoke(__pred, std::__invoke(__proj, *__m), __value)) - { + if (!std::__invoke(__pred, std::__invoke(__proj, *__m), __value)) { __first = __m; ++__first; break; @@ -119,61 +108,45 @@ std::pair<_Iter, _Iter> __search_n_random_access_impl(_Iter __first, _Sent __las } } -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -pair<_Iter, _Iter> __search_n_impl(_Iter __first, _Sent __last, - _DiffT __count, - const _Type& __value, - _Pred& __pred, - _Proj& __proj, - __enable_if_t<__has_random_access_iterator_category<_Iter>::value>* = nullptr) { - return std::__search_n_random_access_impl<_ClassicAlgPolicy>(__first, __last, - __count, - __value, - __pred, - __proj, - __last - __first); + class _Proj, + __enable_if_t<__has_random_access_iterator_category<_Iter>::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter, _Iter> +__search_n_impl(_Iter __first, _Sent __last, _DiffT __count, const _Type& __value, _Pred& __pred, _Proj& __proj) { + return std::__search_n_random_access_impl<_ClassicAlgPolicy>( + __first, __last, __count, __value, __pred, __proj, __last - __first); } -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -pair<_Iter1, _Iter1> __search_n_impl(_Iter1 __first, _Sent1 __last, - _DiffT __count, - const _Type& __value, - _Pred& __pred, - _Proj& __proj, - __enable_if_t<__has_forward_iterator_category<_Iter1>::value - && !__has_random_access_iterator_category<_Iter1>::value>* = nullptr) { - return std::__search_n_forward_impl<_ClassicAlgPolicy>(__first, __last, - __count, - __value, - __pred, - __proj); + class _Proj, + __enable_if_t<__has_forward_iterator_category<_Iter1>::value && + !__has_random_access_iterator_category<_Iter1>::value, + int> = 0> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> +__search_n_impl(_Iter1 __first, _Sent1 __last, _DiffT __count, const _Type& __value, _Pred& __pred, _Proj& __proj) { + return std::__search_n_forward_impl<_ClassicAlgPolicy>(__first, __last, __count, __value, __pred, __proj); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_ForwardIterator search_n(_ForwardIterator __first, _ForwardIterator __last, - _Size __count, - const _Tp& __value, - _BinaryPredicate __pred) { - static_assert(__is_callable<_BinaryPredicate, decltype(*__first), const _Tp&>::value, - "BinaryPredicate has to be callable"); +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator search_n( + _ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value, _BinaryPredicate __pred) { + static_assert( + __is_callable<_BinaryPredicate, decltype(*__first), const _Tp&>::value, "BinaryPredicate has to be callable"); auto __proj = __identity(); return std::__search_n_impl(__first, __last, std::__convert_to_integral(__count), __value, __pred, __proj).first; } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -_ForwardIterator search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value) { +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value) { return std::search_n(__first, __last, std::__convert_to_integral(__count), __value, __equal_to()); } diff --git a/third_party/libcxx/__algorithm/set_difference.h b/third_party/libcxx/__algorithm/set_difference.h index 5a7d3bc18..f414bcecb 100644 --- a/third_party/libcxx/__algorithm/set_difference.h +++ b/third_party/libcxx/__algorithm/set_difference.h @@ -25,6 +25,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template @@ -55,7 +58,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_d _OutputIterator __result, _Compare __comp) { return std::__set_difference<_ClassicAlgPolicy, __comp_ref_type<_Compare> >( - __first1, __last1, __first2, __last2, __result, __comp) + __first1, __last1, __first2, __last2, __result, __comp) .second; } @@ -66,16 +69,11 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_d _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result) { - return std::__set_difference<_ClassicAlgPolicy>( - __first1, - __last1, - __first2, - __last2, - __result, - __less::value_type, - typename iterator_traits<_InputIterator2>::value_type>()).second; + return std::__set_difference<_ClassicAlgPolicy>(__first1, __last1, __first2, __last2, __result, __less<>()).second; } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_SET_DIFFERENCE_H diff --git a/third_party/libcxx/__algorithm/set_intersection.h b/third_party/libcxx/__algorithm/set_intersection.h index 9fa7799ae..bb0d86cd0 100644 --- a/third_party/libcxx/__algorithm/set_intersection.h +++ b/third_party/libcxx/__algorithm/set_intersection.h @@ -12,15 +12,23 @@ #include <__algorithm/comp.h> #include <__algorithm/comp_ref_type.h> #include <__algorithm/iterator_operations.h> +#include <__algorithm/lower_bound.h> #include <__config> +#include <__functional/identity.h> #include <__iterator/iterator_traits.h> #include <__iterator/next.h> +#include <__type_traits/is_same.h> +#include <__utility/exchange.h> #include <__utility/move.h> +#include <__utility/swap.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template @@ -35,10 +43,103 @@ struct __set_intersection_result { : __in1_(std::move(__in_iter1)), __in2_(std::move(__in_iter2)), __out_(std::move(__out_iter)) {} }; -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __set_intersection_result<_InIter1, _InIter2, _OutIter> +// Helper for __set_intersection() with one-sided binary search: populate result and advance input iterators if they +// are found to potentially contain the same value in two consecutive calls. This function is very intimately related to +// the way it is used and doesn't attempt to abstract that, it's not appropriate for general usage outside of its +// context. +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __set_intersection_add_output_if_equal( + bool __may_be_equal, + _InForwardIter1& __first1, + _InForwardIter2& __first2, + _OutIter& __result, + bool& __prev_may_be_equal) { + if (__may_be_equal && __prev_may_be_equal) { + *__result = *__first1; + ++__result; + ++__first1; + ++__first2; + __prev_may_be_equal = false; + } else { + __prev_may_be_equal = __may_be_equal; + } +} + +// With forward iterators we can make multiple passes over the data, allowing the use of one-sided binary search to +// reduce best-case complexity to log(N). Understanding how we can use binary search and still respect complexity +// guarantees is _not_ straightforward: the guarantee is "at most 2*(N+M)-1 comparisons", and one-sided binary search +// will necessarily overshoot depending on the position of the needle in the haystack -- for instance, if we're +// searching for 3 in (1, 2, 3, 4), we'll check if 3<1, then 3<2, then 3<4, and, finally, 3<3, for a total of 4 +// comparisons, when linear search would have yielded 3. However, because we won't need to perform the intervening +// reciprocal comparisons (ie 1<3, 2<3, 4<3), that extra comparison doesn't run afoul of the guarantee. Additionally, +// this type of scenario can only happen for match distances of up to 5 elements, because 2*log2(8) is 6, and we'll +// still be worse-off at position 5 of an 8-element set. From then onwards these scenarios can't happen. TL;DR: we'll be +// 1 comparison worse-off compared to the classic linear-searching algorithm if matching position 3 of a set with 4 +// elements, or position 5 if the set has 7 or 8 elements, but we'll never exceed the complexity guarantees from the +// standard. +template +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI +_LIBCPP_CONSTEXPR_SINCE_CXX20 __set_intersection_result<_InForwardIter1, _InForwardIter2, _OutIter> __set_intersection( - _InIter1 __first1, _Sent1 __last1, _InIter2 __first2, _Sent2 __last2, _OutIter __result, _Compare&& __comp) { + _InForwardIter1 __first1, + _Sent1 __last1, + _InForwardIter2 __first2, + _Sent2 __last2, + _OutIter __result, + _Compare&& __comp, + std::forward_iterator_tag, + std::forward_iterator_tag) { + _LIBCPP_CONSTEXPR std::__identity __proj; + bool __prev_may_be_equal = false; + + while (__first2 != __last2) { + _InForwardIter1 __first1_next = + std::__lower_bound_onesided<_AlgPolicy>(__first1, __last1, *__first2, __comp, __proj); + std::swap(__first1_next, __first1); + // keeping in mind that a==b iff !(a(__first2, __last2, *__first1, __comp, __proj); + std::swap(__first2_next, __first2); + std::__set_intersection_add_output_if_equal( + __first2 == __first2_next, __first1, __first2, __result, __prev_may_be_equal); + } + return __set_intersection_result<_InForwardIter1, _InForwardIter2, _OutIter>( + _IterOps<_AlgPolicy>::next(std::move(__first1), std::move(__last1)), + _IterOps<_AlgPolicy>::next(std::move(__first2), std::move(__last2)), + std::move(__result)); +} + +// input iterators are not suitable for multipass algorithms, so we stick to the classic single-pass version +template +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI +_LIBCPP_CONSTEXPR_SINCE_CXX20 __set_intersection_result<_InInputIter1, _InInputIter2, _OutIter> +__set_intersection( + _InInputIter1 __first1, + _Sent1 __last1, + _InInputIter2 __first2, + _Sent2 __last2, + _OutIter __result, + _Compare&& __comp, + std::input_iterator_tag, + std::input_iterator_tag) { while (__first1 != __last1 && __first2 != __last2) { if (__comp(*__first1, *__first2)) ++__first1; @@ -52,12 +153,28 @@ __set_intersection( } } - return __set_intersection_result<_InIter1, _InIter2, _OutIter>( + return __set_intersection_result<_InInputIter1, _InInputIter2, _OutIter>( _IterOps<_AlgPolicy>::next(std::move(__first1), std::move(__last1)), _IterOps<_AlgPolicy>::next(std::move(__first2), std::move(__last2)), std::move(__result)); } +template +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI +_LIBCPP_CONSTEXPR_SINCE_CXX20 __set_intersection_result<_InIter1, _InIter2, _OutIter> +__set_intersection( + _InIter1 __first1, _Sent1 __last1, _InIter2 __first2, _Sent2 __last2, _OutIter __result, _Compare&& __comp) { + return std::__set_intersection<_AlgPolicy>( + std::move(__first1), + std::move(__last1), + std::move(__first2), + std::move(__last2), + std::move(__result), + std::forward<_Compare>(__comp), + typename std::_IterOps<_AlgPolicy>::template __iterator_category<_InIter1>(), + typename std::_IterOps<_AlgPolicy>::template __iterator_category<_InIter2>()); +} + template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_intersection( _InputIterator1 __first1, @@ -89,11 +206,12 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_i std::move(__first2), std::move(__last2), std::move(__result), - __less::value_type, - typename iterator_traits<_InputIterator2>::value_type>()) + __less<>()) .__out_; } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_SET_INTERSECTION_H diff --git a/third_party/libcxx/__algorithm/set_symmetric_difference.h b/third_party/libcxx/__algorithm/set_symmetric_difference.h index bcb095870..db36665a6 100644 --- a/third_party/libcxx/__algorithm/set_symmetric_difference.h +++ b/third_party/libcxx/__algorithm/set_symmetric_difference.h @@ -22,6 +22,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template @@ -96,10 +99,11 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_symmetri std::move(__first2), std::move(__last2), std::move(__result), - __less::value_type, - typename iterator_traits<_InputIterator2>::value_type>()); + __less<>()); } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_SET_SYMMETRIC_DIFFERENCE_H diff --git a/third_party/libcxx/__algorithm/set_union.h b/third_party/libcxx/__algorithm/set_union.h index 4d154b81e..a79c50fd3 100644 --- a/third_party/libcxx/__algorithm/set_union.h +++ b/third_party/libcxx/__algorithm/set_union.h @@ -22,6 +22,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template @@ -92,10 +95,11 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_union( std::move(__first2), std::move(__last2), std::move(__result), - __less::value_type, - typename iterator_traits<_InputIterator2>::value_type>()); + __less<>()); } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_SET_UNION_H diff --git a/third_party/libcxx/__algorithm/shift_left.h b/third_party/libcxx/__algorithm/shift_left.h index 023b56dcf..06cd7c5f8 100644 --- a/third_party/libcxx/__algorithm/shift_left.h +++ b/third_party/libcxx/__algorithm/shift_left.h @@ -17,39 +17,43 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 template -inline _LIBCPP_INLINE_VISIBILITY constexpr -_ForwardIterator -shift_left(_ForwardIterator __first, _ForwardIterator __last, - typename iterator_traits<_ForwardIterator>::difference_type __n) -{ - if (__n == 0) { - return __last; - } +inline _LIBCPP_HIDE_FROM_ABI constexpr _ForwardIterator +shift_left(_ForwardIterator __first, + _ForwardIterator __last, + typename iterator_traits<_ForwardIterator>::difference_type __n) { + if (__n == 0) { + return __last; + } - _ForwardIterator __m = __first; - if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) { - if (__n >= __last - __first) { - return __first; - } - __m += __n; - } else { - for (; __n > 0; --__n) { - if (__m == __last) { - return __first; - } - ++__m; - } + _ForwardIterator __m = __first; + if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) { + if (__n >= __last - __first) { + return __first; } - return _VSTD::move(__m, __last, __first); + __m += __n; + } else { + for (; __n > 0; --__n) { + if (__m == __last) { + return __first; + } + ++__m; + } + } + return std::move(__m, __last, __first); } #endif // _LIBCPP_STD_VER >= 20 _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_SHIFT_LEFT_H diff --git a/third_party/libcxx/__algorithm/shift_right.h b/third_party/libcxx/__algorithm/shift_right.h index 70aff45fe..01853057f 100644 --- a/third_party/libcxx/__algorithm/shift_right.h +++ b/third_party/libcxx/__algorithm/shift_right.h @@ -20,82 +20,86 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 template -inline _LIBCPP_INLINE_VISIBILITY constexpr -_ForwardIterator -shift_right(_ForwardIterator __first, _ForwardIterator __last, - typename iterator_traits<_ForwardIterator>::difference_type __n) -{ - if (__n == 0) { - return __first; +inline _LIBCPP_HIDE_FROM_ABI constexpr _ForwardIterator +shift_right(_ForwardIterator __first, + _ForwardIterator __last, + typename iterator_traits<_ForwardIterator>::difference_type __n) { + if (__n == 0) { + return __first; + } + + if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) { + decltype(__n) __d = __last - __first; + if (__n >= __d) { + return __last; + } + _ForwardIterator __m = __first + (__d - __n); + return std::move_backward(__first, __m, __last); + } else if constexpr (__has_bidirectional_iterator_category<_ForwardIterator>::value) { + _ForwardIterator __m = __last; + for (; __n > 0; --__n) { + if (__m == __first) { + return __last; + } + --__m; + } + return std::move_backward(__first, __m, __last); + } else { + _ForwardIterator __ret = __first; + for (; __n > 0; --__n) { + if (__ret == __last) { + return __last; + } + ++__ret; } - if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) { - decltype(__n) __d = __last - __first; - if (__n >= __d) { - return __last; - } - _ForwardIterator __m = __first + (__d - __n); - return _VSTD::move_backward(__first, __m, __last); - } else if constexpr (__has_bidirectional_iterator_category<_ForwardIterator>::value) { - _ForwardIterator __m = __last; - for (; __n > 0; --__n) { - if (__m == __first) { - return __last; - } - --__m; - } - return _VSTD::move_backward(__first, __m, __last); - } else { - _ForwardIterator __ret = __first; - for (; __n > 0; --__n) { - if (__ret == __last) { - return __last; - } - ++__ret; - } + // We have an __n-element scratch space from __first to __ret. + // Slide an __n-element window [__trail, __lead) from left to right. + // We're essentially doing swap_ranges(__first, __ret, __trail, __lead) + // over and over; but once __lead reaches __last we needn't bother + // to save the values of elements [__trail, __last). - // We have an __n-element scratch space from __first to __ret. - // Slide an __n-element window [__trail, __lead) from left to right. - // We're essentially doing swap_ranges(__first, __ret, __trail, __lead) - // over and over; but once __lead reaches __last we needn't bother - // to save the values of elements [__trail, __last). - - auto __trail = __first; - auto __lead = __ret; - while (__trail != __ret) { - if (__lead == __last) { - _VSTD::move(__first, __trail, __ret); - return __ret; - } - ++__trail; - ++__lead; - } - - _ForwardIterator __mid = __first; - while (true) { - if (__lead == __last) { - __trail = _VSTD::move(__mid, __ret, __trail); - _VSTD::move(__first, __mid, __trail); - return __ret; - } - swap(*__mid, *__trail); - ++__mid; - ++__trail; - ++__lead; - if (__mid == __ret) { - __mid = __first; - } - } + auto __trail = __first; + auto __lead = __ret; + while (__trail != __ret) { + if (__lead == __last) { + std::move(__first, __trail, __ret); + return __ret; + } + ++__trail; + ++__lead; } + + _ForwardIterator __mid = __first; + while (true) { + if (__lead == __last) { + __trail = std::move(__mid, __ret, __trail); + std::move(__first, __mid, __trail); + return __ret; + } + swap(*__mid, *__trail); + ++__mid; + ++__trail; + ++__lead; + if (__mid == __ret) { + __mid = __first; + } + } + } } #endif // _LIBCPP_STD_VER >= 20 _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_SHIFT_RIGHT_H diff --git a/third_party/libcxx/__algorithm/shuffle.h b/third_party/libcxx/__algorithm/shuffle.h index d6cc3401a..c9c56ce8c 100644 --- a/third_party/libcxx/__algorithm/shuffle.h +++ b/third_party/libcxx/__algorithm/shuffle.h @@ -11,7 +11,6 @@ #include <__algorithm/iterator_operations.h> #include <__config> -#include <__debug> #include <__iterator/iterator_traits.h> #include <__random/uniform_int_distribution.h> #include <__utility/forward.h> @@ -29,12 +28,12 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD -class _LIBCPP_TYPE_VIS __libcpp_debug_randomizer { +class _LIBCPP_EXPORTED_FROM_ABI __libcpp_debug_randomizer { public: _LIBCPP_HIDE_FROM_ABI __libcpp_debug_randomizer() { __state_ = __seed(); - __inc_ = __state_ + 0xda3e39cb94b95bdbULL; - __inc_ = (__inc_ << 1) | 1; + __inc_ = __state_ + 0xda3e39cb94b95bdbULL; + __inc_ = (__inc_ << 1) | 1; } typedef uint_fast32_t result_type; @@ -43,7 +42,7 @@ public: _LIBCPP_HIDE_FROM_ABI result_type operator()() { uint_fast64_t __oldstate = __state_; - __state_ = __oldstate * 6364136223846793005ULL + __inc_; + __state_ = __oldstate * 6364136223846793005ULL + __inc_; return __oldstate >> 32; } @@ -63,102 +62,95 @@ private: } }; -#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE) \ - || defined(_LIBCPP_BUILDING_LIBRARY) -class _LIBCPP_TYPE_VIS __rs_default; +#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE) || defined(_LIBCPP_BUILDING_LIBRARY) +class _LIBCPP_EXPORTED_FROM_ABI __rs_default; -_LIBCPP_FUNC_VIS __rs_default __rs_get(); +_LIBCPP_EXPORTED_FROM_ABI __rs_default __rs_get(); -class _LIBCPP_TYPE_VIS __rs_default -{ - static unsigned __c_; +class _LIBCPP_EXPORTED_FROM_ABI __rs_default { + static unsigned __c_; + + __rs_default(); - __rs_default(); public: - typedef uint_fast32_t result_type; + typedef uint_fast32_t result_type; - static const result_type _Min = 0; - static const result_type _Max = 0xFFFFFFFF; + static const result_type _Min = 0; + static const result_type _Max = 0xFFFFFFFF; - __rs_default(const __rs_default&); - ~__rs_default(); + __rs_default(const __rs_default&); + ~__rs_default(); - result_type operator()(); + result_type operator()(); - static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR result_type min() {return _Min;} - static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR result_type max() {return _Max;} + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR result_type min() { return _Min; } + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR result_type max() { return _Max; } - friend _LIBCPP_FUNC_VIS __rs_default __rs_get(); + friend _LIBCPP_EXPORTED_FROM_ABI __rs_default __rs_get(); }; -_LIBCPP_FUNC_VIS __rs_default __rs_get(); +_LIBCPP_EXPORTED_FROM_ABI __rs_default __rs_get(); template _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX14 void -random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last) -{ - typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; - typedef uniform_int_distribution _Dp; - typedef typename _Dp::param_type _Pp; - difference_type __d = __last - __first; - if (__d > 1) - { - _Dp __uid; - __rs_default __g = __rs_get(); - for (--__last, (void) --__d; __first < __last; ++__first, (void) --__d) - { - difference_type __i = __uid(__g, _Pp(0, __d)); - if (__i != difference_type(0)) - swap(*__first, *(__first + __i)); - } +random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last) { + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + typedef uniform_int_distribution _Dp; + typedef typename _Dp::param_type _Pp; + difference_type __d = __last - __first; + if (__d > 1) { + _Dp __uid; + __rs_default __g = __rs_get(); + for (--__last, (void)--__d; __first < __last; ++__first, (void)--__d) { + difference_type __i = __uid(__g, _Pp(0, __d)); + if (__i != difference_type(0)) + swap(*__first, *(__first + __i)); } + } } template _LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX14 void -random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, -#ifndef _LIBCPP_CXX03_LANG +random_shuffle(_RandomAccessIterator __first, + _RandomAccessIterator __last, +# ifndef _LIBCPP_CXX03_LANG _RandomNumberGenerator&& __rand) -#else +# else _RandomNumberGenerator& __rand) -#endif +# endif { - typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; - difference_type __d = __last - __first; - if (__d > 1) - { - for (--__last; __first < __last; ++__first, (void) --__d) - { - difference_type __i = __rand(__d); - if (__i != difference_type(0)) - swap(*__first, *(__first + __i)); - } + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + difference_type __d = __last - __first; + if (__d > 1) { + for (--__last; __first < __last; ++__first, (void)--__d) { + difference_type __i = __rand(__d); + if (__i != difference_type(0)) + swap(*__first, *(__first + __i)); } + } } #endif template -_LIBCPP_HIDE_FROM_ABI _RandomAccessIterator __shuffle( - _RandomAccessIterator __first, _Sentinel __last_sentinel, _UniformRandomNumberGenerator&& __g) { - typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; - typedef uniform_int_distribution _Dp; - typedef typename _Dp::param_type _Pp; +_LIBCPP_HIDE_FROM_ABI _RandomAccessIterator +__shuffle(_RandomAccessIterator __first, _Sentinel __last_sentinel, _UniformRandomNumberGenerator&& __g) { + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + typedef uniform_int_distribution _Dp; + typedef typename _Dp::param_type _Pp; - auto __original_last = _IterOps<_AlgPolicy>::next(__first, __last_sentinel); - auto __last = __original_last; - difference_type __d = __last - __first; - if (__d > 1) - { - _Dp __uid; - for (--__last, (void) --__d; __first < __last; ++__first, (void) --__d) - { - difference_type __i = __uid(__g, _Pp(0, __d)); - if (__i != difference_type(0)) - _IterOps<_AlgPolicy>::iter_swap(__first, __first + __i); - } + auto __original_last = _IterOps<_AlgPolicy>::next(__first, __last_sentinel); + auto __last = __original_last; + difference_type __d = __last - __first; + if (__d > 1) { + _Dp __uid; + for (--__last, (void)--__d; __first < __last; ++__first, (void)--__d) { + difference_type __i = __uid(__g, _Pp(0, __d)); + if (__i != difference_type(0)) + _IterOps<_AlgPolicy>::iter_swap(__first, __first + __i); } + } - return __original_last; + return __original_last; } template diff --git a/third_party/libcxx/__algorithm/sift_down.h b/third_party/libcxx/__algorithm/sift_down.h index e3972fb6f..42803e306 100644 --- a/third_party/libcxx/__algorithm/sift_down.h +++ b/third_party/libcxx/__algorithm/sift_down.h @@ -19,96 +19,100 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void -__sift_down(_RandomAccessIterator __first, _Compare&& __comp, +__sift_down(_RandomAccessIterator __first, + _Compare&& __comp, typename iterator_traits<_RandomAccessIterator>::difference_type __len, - _RandomAccessIterator __start) -{ - using _Ops = _IterOps<_AlgPolicy>; + _RandomAccessIterator __start) { + using _Ops = _IterOps<_AlgPolicy>; - typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; - typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; - // left-child of __start is at 2 * __start + 1 - // right-child of __start is at 2 * __start + 2 - difference_type __child = __start - __first; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + // left-child of __start is at 2 * __start + 1 + // right-child of __start is at 2 * __start + 2 + difference_type __child = __start - __first; - if (__len < 2 || (__len - 2) / 2 < __child) - return; + if (__len < 2 || (__len - 2) / 2 < __child) + return; - __child = 2 * __child + 1; - _RandomAccessIterator __child_i = __first + __child; + __child = 2 * __child + 1; + _RandomAccessIterator __child_i = __first + __child; + + if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) { + // right-child exists and is greater than left-child + ++__child_i; + ++__child; + } + + // check if we are in heap-order + if (__comp(*__child_i, *__start)) + // we are, __start is larger than its largest child + return; + + value_type __top(_Ops::__iter_move(__start)); + do { + // we are not in heap-order, swap the parent with its largest child + *__start = _Ops::__iter_move(__child_i); + __start = __child_i; + + if ((__len - 2) / 2 < __child) + break; + + // recompute the child based off of the updated parent + __child = 2 * __child + 1; + __child_i = __first + __child; if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) { - // right-child exists and is greater than left-child - ++__child_i; - ++__child; + // right-child exists and is greater than left-child + ++__child_i; + ++__child; } // check if we are in heap-order - if (__comp(*__child_i, *__start)) - // we are, __start is larger than its largest child - return; - - value_type __top(_Ops::__iter_move(__start)); - do - { - // we are not in heap-order, swap the parent with its largest child - *__start = _Ops::__iter_move(__child_i); - __start = __child_i; - - if ((__len - 2) / 2 < __child) - break; - - // recompute the child based off of the updated parent - __child = 2 * __child + 1; - __child_i = __first + __child; - - if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) { - // right-child exists and is greater than left-child - ++__child_i; - ++__child; - } - - // check if we are in heap-order - } while (!__comp(*__child_i, __top)); - *__start = _VSTD::move(__top); + } while (!__comp(*__child_i, __top)); + *__start = std::move(__top); } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _RandomAccessIterator -__floyd_sift_down(_RandomAccessIterator __first, _Compare&& __comp, - typename iterator_traits<_RandomAccessIterator>::difference_type __len) -{ - using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type; - _LIBCPP_ASSERT(__len >= 2, "shouldn't be called unless __len >= 2"); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _RandomAccessIterator __floyd_sift_down( + _RandomAccessIterator __first, + _Compare&& __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len) { + using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type; + _LIBCPP_ASSERT_INTERNAL(__len >= 2, "shouldn't be called unless __len >= 2"); - _RandomAccessIterator __hole = __first; - _RandomAccessIterator __child_i = __first; - difference_type __child = 0; + _RandomAccessIterator __hole = __first; + _RandomAccessIterator __child_i = __first; + difference_type __child = 0; - while (true) { - __child_i += difference_type(__child + 1); - __child = 2 * __child + 1; + while (true) { + __child_i += difference_type(__child + 1); + __child = 2 * __child + 1; - if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) { - // right-child exists and is greater than left-child - ++__child_i; - ++__child; - } - - // swap __hole with its largest child - *__hole = _IterOps<_AlgPolicy>::__iter_move(__child_i); - __hole = __child_i; - - // if __hole is now a leaf, we're done - if (__child > (__len - 2) / 2) - return __hole; + if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) { + // right-child exists and is greater than left-child + ++__child_i; + ++__child; } + + // swap __hole with its largest child + *__hole = _IterOps<_AlgPolicy>::__iter_move(__child_i); + __hole = __child_i; + + // if __hole is now a leaf, we're done + if (__child > (__len - 2) / 2) + return __hole; + } } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_SIFT_DOWN_H diff --git a/third_party/libcxx/__algorithm/simd_utils.h b/third_party/libcxx/__algorithm/simd_utils.h new file mode 100644 index 000000000..549197be8 --- /dev/null +++ b/third_party/libcxx/__algorithm/simd_utils.h @@ -0,0 +1,164 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ALGORITHM_SIMD_UTILS_H +#define _LIBCPP___ALGORITHM_SIMD_UTILS_H + +#include <__algorithm/min.h> +#include <__bit/bit_cast.h> +#include <__bit/countl.h> +#include <__bit/countr.h> +#include <__config> +#include <__type_traits/is_arithmetic.h> +#include <__type_traits/is_same.h> +#include <__utility/integer_sequence.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +// TODO: Find out how altivec changes things and allow vectorizations there too. +#if _LIBCPP_STD_VER >= 14 && defined(_LIBCPP_CLANG_VER) && !defined(__ALTIVEC__) +# define _LIBCPP_HAS_ALGORITHM_VECTOR_UTILS 1 +#else +# define _LIBCPP_HAS_ALGORITHM_VECTOR_UTILS 0 +#endif + +#if _LIBCPP_HAS_ALGORITHM_VECTOR_UTILS && !defined(__OPTIMIZE_SIZE__) +# define _LIBCPP_VECTORIZE_ALGORITHMS 1 +#else +# define _LIBCPP_VECTORIZE_ALGORITHMS 0 +#endif + +#if _LIBCPP_HAS_ALGORITHM_VECTOR_UTILS + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +inline constexpr bool __can_map_to_integer_v = + sizeof(_Tp) == alignof(_Tp) && (sizeof(_Tp) == 1 || sizeof(_Tp) == 2 || sizeof(_Tp) == 4 || sizeof(_Tp) == 8); + +template +struct __get_as_integer_type_impl; + +template <> +struct __get_as_integer_type_impl<1> { + using type = uint8_t; +}; + +template <> +struct __get_as_integer_type_impl<2> { + using type = uint16_t; +}; +template <> +struct __get_as_integer_type_impl<4> { + using type = uint32_t; +}; +template <> +struct __get_as_integer_type_impl<8> { + using type = uint64_t; +}; + +template +using __get_as_integer_type_t = typename __get_as_integer_type_impl::type; + +// This isn't specialized for 64 byte vectors on purpose. They have the potential to significantly reduce performance +// in mixed simd/non-simd workloads and don't provide any performance improvement for currently vectorized algorithms +// as far as benchmarks are concerned. +# if defined(__AVX__) || defined(__MVS__) +template +inline constexpr size_t __native_vector_size = 32 / sizeof(_Tp); +# elif defined(__SSE__) || defined(__ARM_NEON__) +template +inline constexpr size_t __native_vector_size = 16 / sizeof(_Tp); +# elif defined(__MMX__) +template +inline constexpr size_t __native_vector_size = 8 / sizeof(_Tp); +# else +template +inline constexpr size_t __native_vector_size = 1; +# endif + +template +using __simd_vector __attribute__((__ext_vector_type__(_Np))) = _ArithmeticT; + +template +inline constexpr size_t __simd_vector_size_v = []() -> size_t { + static_assert(_False, "Not a vector!"); +}(); + +template +inline constexpr size_t __simd_vector_size_v<__simd_vector<_Tp, _Np>> = _Np; + +template +_LIBCPP_HIDE_FROM_ABI _Tp __simd_vector_underlying_type_impl(__simd_vector<_Tp, _Np>) { + return _Tp{}; +} + +template +using __simd_vector_underlying_type_t = decltype(std::__simd_vector_underlying_type_impl(_VecT{})); + +// This isn't inlined without always_inline when loading chars. +template +_LIBCPP_NODISCARD _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _VecT __load_vector(_Iter __iter) noexcept { + return [=](index_sequence<_Indices...>) _LIBCPP_ALWAYS_INLINE noexcept { + return _VecT{__iter[_Indices]...}; + }(make_index_sequence<__simd_vector_size_v<_VecT>>{}); +} + +template +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI bool __all_of(__simd_vector<_Tp, _Np> __vec) noexcept { + return __builtin_reduce_and(__builtin_convertvector(__vec, __simd_vector)); +} + +template +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI size_t __find_first_set(__simd_vector<_Tp, _Np> __vec) noexcept { + using __mask_vec = __simd_vector; + + // This has MSan disabled du to https://github.com/llvm/llvm-project/issues/85876 + auto __impl = [&](_MaskT) _LIBCPP_NO_SANITIZE("memory") noexcept { +# if defined(_LIBCPP_BIG_ENDIAN) + return std::min( + _Np, std::__countl_zero(__builtin_bit_cast(_MaskT, __builtin_convertvector(__vec, __mask_vec)))); +# else + return std::min( + _Np, std::__countr_zero(__builtin_bit_cast(_MaskT, __builtin_convertvector(__vec, __mask_vec)))); +# endif + }; + + if constexpr (sizeof(__mask_vec) == sizeof(uint8_t)) { + return __impl(uint8_t{}); + } else if constexpr (sizeof(__mask_vec) == sizeof(uint16_t)) { + return __impl(uint16_t{}); + } else if constexpr (sizeof(__mask_vec) == sizeof(uint32_t)) { + return __impl(uint32_t{}); + } else if constexpr (sizeof(__mask_vec) == sizeof(uint64_t)) { + return __impl(uint64_t{}); + } else { + static_assert(sizeof(__mask_vec) == 0, "unexpected required size for mask integer type"); + return 0; + } +} + +template +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI size_t __find_first_not_set(__simd_vector<_Tp, _Np> __vec) noexcept { + return std::__find_first_set(~__vec); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_HAS_ALGORITHM_VECTOR_UTILS + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___ALGORITHM_SIMD_UTILS_H diff --git a/third_party/libcxx/__algorithm/sort.h b/third_party/libcxx/__algorithm/sort.h index 77e0b2e92..07b581463 100644 --- a/third_party/libcxx/__algorithm/sort.h +++ b/third_party/libcxx/__algorithm/sort.h @@ -21,14 +21,15 @@ #include <__bit/countl.h> #include <__bit/countr.h> #include <__config> -#include <__debug> #include <__debug_utils/randomize_range.h> +#include <__debug_utils/strict_weak_ordering_check.h> #include <__functional/operations.h> #include <__functional/ranges_operations.h> #include <__iterator/iterator_traits.h> #include <__type_traits/conditional.h> #include <__type_traits/disjunction.h> #include <__type_traits/is_arithmetic.h> +#include <__type_traits/is_constant_evaluated.h> #include <__utility/move.h> #include <__utility/pair.h> #include @@ -38,54 +39,55 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD // stable, 2-3 compares, 0-2 swaps template -_LIBCPP_HIDE_FROM_ABI -_LIBCPP_CONSTEXPR_SINCE_CXX14 unsigned __sort3(_ForwardIterator __x, _ForwardIterator __y, _ForwardIterator __z, - _Compare __c) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 unsigned +__sort3(_ForwardIterator __x, _ForwardIterator __y, _ForwardIterator __z, _Compare __c) { using _Ops = _IterOps<_AlgPolicy>; unsigned __r = 0; - if (!__c(*__y, *__x)) // if x <= y + if (!__c(*__y, *__x)) // if x <= y { - if (!__c(*__z, *__y)) // if y <= z - return __r; // x <= y && y <= z - // x <= y && y > z - _Ops::iter_swap(__y, __z); // x <= z && y < z + if (!__c(*__z, *__y)) // if y <= z + return __r; // x <= y && y <= z + // x <= y && y > z + _Ops::iter_swap(__y, __z); // x <= z && y < z __r = 1; - if (__c(*__y, *__x)) // if x > y + if (__c(*__y, *__x)) // if x > y { - _Ops::iter_swap(__x, __y); // x < y && y <= z + _Ops::iter_swap(__x, __y); // x < y && y <= z __r = 2; } - return __r; // x <= y && y < z + return __r; // x <= y && y < z } - if (__c(*__z, *__y)) // x > y, if y > z + if (__c(*__z, *__y)) // x > y, if y > z { - _Ops::iter_swap(__x, __z); // x < y && y < z + _Ops::iter_swap(__x, __z); // x < y && y < z __r = 1; return __r; } - _Ops::iter_swap(__x, __y); // x > y && y <= z - __r = 1; // x < y && x <= z - if (__c(*__z, *__y)) // if y > z + _Ops::iter_swap(__x, __y); // x > y && y <= z + __r = 1; // x < y && x <= z + if (__c(*__z, *__y)) // if y > z { - _Ops::iter_swap(__y, __z); // x <= y && y < z + _Ops::iter_swap(__y, __z); // x <= y && y < z __r = 2; } return __r; -} // x <= y && y <= z +} // x <= y && y <= z // stable, 3-6 compares, 0-5 swaps template -_LIBCPP_HIDE_FROM_ABI -void __sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, _ForwardIterator __x4, - _Compare __c) { - using _Ops = _IterOps<_AlgPolicy>; +_LIBCPP_HIDE_FROM_ABI void +__sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, _ForwardIterator __x4, _Compare __c) { + using _Ops = _IterOps<_AlgPolicy>; std::__sort3<_AlgPolicy, _Compare>(__x1, __x2, __x3, __c); if (__c(*__x4, *__x3)) { _Ops::iter_swap(__x3, __x4); @@ -101,8 +103,13 @@ void __sort4(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3 // stable, 4-10 compares, 0-9 swaps template -_LIBCPP_HIDE_FROM_ABI void __sort5(_ForwardIterator __x1, _ForwardIterator __x2, _ForwardIterator __x3, - _ForwardIterator __x4, _ForwardIterator __x5, _Comp __comp) { +_LIBCPP_HIDE_FROM_ABI void +__sort5(_ForwardIterator __x1, + _ForwardIterator __x2, + _ForwardIterator __x3, + _ForwardIterator __x4, + _ForwardIterator __x5, + _Comp __comp) { using _Ops = _IterOps<_AlgPolicy>; std::__sort4<_AlgPolicy, _Comp>(__x1, __x2, __x3, __x4, __comp); @@ -123,8 +130,8 @@ _LIBCPP_HIDE_FROM_ABI void __sort5(_ForwardIterator __x1, _ForwardIterator __x2, // The comparator being simple is a prerequisite for using the branchless optimization. template struct __is_simple_comparator : false_type {}; -template -struct __is_simple_comparator<__less<_Tp>&> : true_type {}; +template <> +struct __is_simple_comparator<__less<>&> : true_type {}; template struct __is_simple_comparator&> : true_type {}; template @@ -138,8 +145,9 @@ struct __is_simple_comparator : true_type {}; template ::value_type> using __use_branchless_sort = - integral_constant::value && sizeof(_Tp) <= sizeof(void*) && - is_arithmetic<_Tp>::value && __is_simple_comparator<_Compare>::value>; + integral_constant::value && sizeof(_Tp) <= sizeof(void*) && + is_arithmetic<_Tp>::value && __is_simple_comparator<_Compare>::value>; namespace __detail { @@ -153,46 +161,56 @@ template inline _LIBCPP_HIDE_FROM_ABI void __cond_swap(_RandomAccessIterator __x, _RandomAccessIterator __y, _Compare __c) { // Note: this function behaves correctly even with proxy iterators (because it relies on `value_type`). using value_type = typename iterator_traits<_RandomAccessIterator>::value_type; - bool __r = __c(*__x, *__y); + bool __r = __c(*__x, *__y); value_type __tmp = __r ? *__x : *__y; - *__y = __r ? *__y : *__x; - *__x = __tmp; + *__y = __r ? *__y : *__x; + *__x = __tmp; } // Ensures that *__x, *__y and *__z are ordered according to the comparator __c, // under the assumption that *__y and *__z are already ordered. template -inline _LIBCPP_HIDE_FROM_ABI void __partially_sorted_swap(_RandomAccessIterator __x, _RandomAccessIterator __y, - _RandomAccessIterator __z, _Compare __c) { +inline _LIBCPP_HIDE_FROM_ABI void +__partially_sorted_swap(_RandomAccessIterator __x, _RandomAccessIterator __y, _RandomAccessIterator __z, _Compare __c) { // Note: this function behaves correctly even with proxy iterators (because it relies on `value_type`). using value_type = typename iterator_traits<_RandomAccessIterator>::value_type; - bool __r = __c(*__z, *__x); + bool __r = __c(*__z, *__x); value_type __tmp = __r ? *__z : *__x; - *__z = __r ? *__x : *__z; - __r = __c(__tmp, *__y); - *__x = __r ? *__x : *__y; - *__y = __r ? *__y : __tmp; + *__z = __r ? *__x : *__z; + __r = __c(__tmp, *__y); + *__x = __r ? *__x : *__y; + *__y = __r ? *__y : __tmp; } -template -inline _LIBCPP_HIDE_FROM_ABI __enable_if_t<__use_branchless_sort<_Compare, _RandomAccessIterator>::value, void> -__sort3_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, - _Compare __c) { +template ::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI void __sort3_maybe_branchless( + _RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, _Compare __c) { std::__cond_swap<_Compare>(__x2, __x3, __c); std::__partially_sorted_swap<_Compare>(__x1, __x2, __x3, __c); } -template -inline _LIBCPP_HIDE_FROM_ABI __enable_if_t::value, void> -__sort3_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, - _Compare __c) { +template ::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI void __sort3_maybe_branchless( + _RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, _Compare __c) { std::__sort3<_AlgPolicy, _Compare>(__x1, __x2, __x3, __c); } -template -inline _LIBCPP_HIDE_FROM_ABI __enable_if_t<__use_branchless_sort<_Compare, _RandomAccessIterator>::value, void> -__sort4_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, - _RandomAccessIterator __x4, _Compare __c) { +template ::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI void __sort4_maybe_branchless( + _RandomAccessIterator __x1, + _RandomAccessIterator __x2, + _RandomAccessIterator __x3, + _RandomAccessIterator __x4, + _Compare __c) { std::__cond_swap<_Compare>(__x1, __x3, __c); std::__cond_swap<_Compare>(__x2, __x4, __c); std::__cond_swap<_Compare>(__x1, __x2, __c); @@ -200,16 +218,24 @@ __sort4_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, std::__cond_swap<_Compare>(__x2, __x3, __c); } -template -inline _LIBCPP_HIDE_FROM_ABI __enable_if_t::value, void> -__sort4_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, - _RandomAccessIterator __x4, _Compare __c) { +template ::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI void __sort4_maybe_branchless( + _RandomAccessIterator __x1, + _RandomAccessIterator __x2, + _RandomAccessIterator __x3, + _RandomAccessIterator __x4, + _Compare __c) { std::__sort4<_AlgPolicy, _Compare>(__x1, __x2, __x3, __x4, __c); } -template -inline _LIBCPP_HIDE_FROM_ABI __enable_if_t<__use_branchless_sort<_Compare, _RandomAccessIterator>::value, void> -__sort5_maybe_branchless( +template ::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI void __sort5_maybe_branchless( _RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, @@ -224,19 +250,25 @@ __sort5_maybe_branchless( std::__partially_sorted_swap<_Compare>(__x2, __x3, __x4, __c); } -template -inline _LIBCPP_HIDE_FROM_ABI __enable_if_t::value, void> -__sort5_maybe_branchless(_RandomAccessIterator __x1, _RandomAccessIterator __x2, _RandomAccessIterator __x3, - _RandomAccessIterator __x4, _RandomAccessIterator __x5, _Compare __c) { +template ::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI void __sort5_maybe_branchless( + _RandomAccessIterator __x1, + _RandomAccessIterator __x2, + _RandomAccessIterator __x3, + _RandomAccessIterator __x4, + _RandomAccessIterator __x5, + _Compare __c) { std::__sort5<_AlgPolicy, _Compare, _RandomAccessIterator>( std::move(__x1), std::move(__x2), std::move(__x3), std::move(__x4), std::move(__x5), __c); } // Assumes size > 0 template -_LIBCPP_HIDE_FROM_ABI -_LIBCPP_CONSTEXPR_SINCE_CXX14 void __selection_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, - _Compare __comp) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void +__selection_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) { _BidirectionalIterator __lm1 = __last; for (--__lm1; __first != __lm1; ++__first) { _BidirectionalIterator __i = std::__min_element<_Compare>(__first, __last, __comp); @@ -248,8 +280,8 @@ _LIBCPP_CONSTEXPR_SINCE_CXX14 void __selection_sort(_BidirectionalIterator __fir // Sort the iterator range [__first, __last) using the comparator __comp using // the insertion sort algorithm. template -_LIBCPP_HIDE_FROM_ABI -void __insertion_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) { +_LIBCPP_HIDE_FROM_ABI void +__insertion_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) { using _Ops = _IterOps<_AlgPolicy>; typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; @@ -285,17 +317,20 @@ __insertion_sort_unguarded(_RandomAccessIterator const __first, _RandomAccessIte typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; if (__first == __last) return; - const _RandomAccessIterator __leftmost = __first - difference_type(1); (void)__leftmost; // can be unused when assertions are disabled + const _RandomAccessIterator __leftmost = __first - difference_type(1); + (void)__leftmost; // can be unused when assertions are disabled for (_RandomAccessIterator __i = __first + difference_type(1); __i != __last; ++__i) { _RandomAccessIterator __j = __i - difference_type(1); if (__comp(*__i, *__j)) { value_type __t(_Ops::__iter_move(__i)); _RandomAccessIterator __k = __j; - __j = __i; + __j = __i; do { *__j = _Ops::__iter_move(__k); - __j = __k; - _LIBCPP_ASSERT(__k != __leftmost, "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); + __j = __k; + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __k != __leftmost, + "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); } while (__comp(__t, *--__k)); // No need for bounds check due to the assumption stated above. *__j = std::move(__t); } @@ -303,8 +338,8 @@ __insertion_sort_unguarded(_RandomAccessIterator const __first, _RandomAccessIte } template -_LIBCPP_HIDE_FROM_ABI bool __insertion_sort_incomplete( - _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) { +_LIBCPP_HIDE_FROM_ABI bool +__insertion_sort_incomplete(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) { using _Ops = _IterOps<_AlgPolicy>; typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; @@ -325,23 +360,27 @@ _LIBCPP_HIDE_FROM_ABI bool __insertion_sort_incomplete( return true; case 5: std::__sort5_maybe_branchless<_AlgPolicy, _Comp>( - __first, __first + difference_type(1), __first + difference_type(2), __first + difference_type(3), - --__last, __comp); + __first, + __first + difference_type(1), + __first + difference_type(2), + __first + difference_type(3), + --__last, + __comp); return true; } typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; _RandomAccessIterator __j = __first + difference_type(2); std::__sort3_maybe_branchless<_AlgPolicy, _Comp>(__first, __first + difference_type(1), __j, __comp); const unsigned __limit = 8; - unsigned __count = 0; + unsigned __count = 0; for (_RandomAccessIterator __i = __j + difference_type(1); __i != __last; ++__i) { if (__comp(*__i, *__j)) { value_type __t(_Ops::__iter_move(__i)); _RandomAccessIterator __k = __j; - __j = __i; + __j = __i; do { *__j = _Ops::__iter_move(__k); - __j = __k; + __j = __k; } while (__j != __first && __comp(__t, *--__k)); *__j = std::move(__t); if (++__count == __limit) @@ -497,9 +536,10 @@ __bitset_partition(_RandomAccessIterator __first, _RandomAccessIterator __last, using _Ops = _IterOps<_AlgPolicy>; typedef typename std::iterator_traits<_RandomAccessIterator>::value_type value_type; typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type difference_type; - _LIBCPP_ASSERT(__last - __first >= difference_type(3), ""); - const _RandomAccessIterator __begin = __first; // used for bounds checking, those are not moved around - const _RandomAccessIterator __end = __last; (void)__end; // + _LIBCPP_ASSERT_INTERNAL(__last - __first >= difference_type(3), ""); + const _RandomAccessIterator __begin = __first; // used for bounds checking, those are not moved around + const _RandomAccessIterator __end = __last; + (void)__end; // value_type __pivot(_Ops::__iter_move(__first)); // Find the first element greater than the pivot. @@ -507,7 +547,9 @@ __bitset_partition(_RandomAccessIterator __first, _RandomAccessIterator __last, // Not guarded since we know the last element is greater than the pivot. do { ++__first; - _LIBCPP_ASSERT(__first != __end, "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __first != __end, + "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); } while (!__comp(__pivot, *__first)); } else { while (++__first < __last && !__comp(__pivot, *__first)) { @@ -518,7 +560,9 @@ __bitset_partition(_RandomAccessIterator __first, _RandomAccessIterator __last, // It will be always guarded because __introsort will do the median-of-three // before calling this. do { - _LIBCPP_ASSERT(__last != __begin, "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __last != __begin, + "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); --__last; } while (__comp(__pivot, *__last)); } @@ -584,16 +628,19 @@ __partition_with_equals_on_right(_RandomAccessIterator __first, _RandomAccessIte using _Ops = _IterOps<_AlgPolicy>; typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; typedef typename std::iterator_traits<_RandomAccessIterator>::value_type value_type; - _LIBCPP_ASSERT(__last - __first >= difference_type(3), ""); - const _RandomAccessIterator __begin = __first; // used for bounds checking, those are not moved around - const _RandomAccessIterator __end = __last; (void)__end; // + _LIBCPP_ASSERT_INTERNAL(__last - __first >= difference_type(3), ""); + const _RandomAccessIterator __begin = __first; // used for bounds checking, those are not moved around + const _RandomAccessIterator __end = __last; + (void)__end; // value_type __pivot(_Ops::__iter_move(__first)); // Find the first element greater or equal to the pivot. It will be always // guarded because __introsort will do the median-of-three before calling // this. do { ++__first; - _LIBCPP_ASSERT(__first != __end, "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __first != __end, + "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); } while (__comp(*__first, __pivot)); // Find the last element less than the pivot. @@ -603,7 +650,9 @@ __partition_with_equals_on_right(_RandomAccessIterator __first, _RandomAccessIte } else { // Guarded. do { - _LIBCPP_ASSERT(__last != __begin, "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __last != __begin, + "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); --__last; } while (!__comp(*__last, __pivot)); } @@ -619,10 +668,14 @@ __partition_with_equals_on_right(_RandomAccessIterator __first, _RandomAccessIte _Ops::iter_swap(__first, __last); do { ++__first; - _LIBCPP_ASSERT(__first != __end, "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __first != __end, + "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); } while (__comp(*__first, __pivot)); do { - _LIBCPP_ASSERT(__last != __begin, "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __last != __begin, + "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); --__last; } while (!__comp(*__last, __pivot)); } @@ -643,15 +696,17 @@ __partition_with_equals_on_left(_RandomAccessIterator __first, _RandomAccessIter using _Ops = _IterOps<_AlgPolicy>; typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; typedef typename std::iterator_traits<_RandomAccessIterator>::value_type value_type; - // TODO(LLVM18): Make __begin const, see https://reviews.llvm.org/D147089#4349748 - _RandomAccessIterator __begin = __first; // used for bounds checking, those are not moved around - const _RandomAccessIterator __end = __last; (void)__end; // + const _RandomAccessIterator __begin = __first; // used for bounds checking, those are not moved around + const _RandomAccessIterator __end = __last; + (void)__end; // value_type __pivot(_Ops::__iter_move(__first)); if (__comp(__pivot, *(__last - difference_type(1)))) { // Guarded. do { ++__first; - _LIBCPP_ASSERT(__first != __end, "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __first != __end, + "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); } while (!__comp(__pivot, *__first)); } else { while (++__first < __last && !__comp(__pivot, *__first)) { @@ -662,7 +717,9 @@ __partition_with_equals_on_left(_RandomAccessIterator __first, _RandomAccessIter // It will be always guarded because __introsort will do the // median-of-three before calling this. do { - _LIBCPP_ASSERT(__last != __begin, "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __last != __begin, + "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); --__last; } while (__comp(__pivot, *__last)); } @@ -670,10 +727,14 @@ __partition_with_equals_on_left(_RandomAccessIterator __first, _RandomAccessIter _Ops::iter_swap(__first, __last); do { ++__first; - _LIBCPP_ASSERT(__first != __end, "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __first != __end, + "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); } while (!__comp(__pivot, *__first)); do { - _LIBCPP_ASSERT(__last != __begin, "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __last != __begin, + "Would read out of bounds, does your comparator satisfy the strict-weak ordering requirement?"); --__last; } while (__comp(__pivot, *__last)); } @@ -724,8 +785,12 @@ void __introsort(_RandomAccessIterator __first, return; case 5: std::__sort5_maybe_branchless<_AlgPolicy, _Compare>( - __first, __first + difference_type(1), __first + difference_type(2), __first + difference_type(3), - --__last, __comp); + __first, + __first + difference_type(1), + __first + difference_type(2), + __first + difference_type(3), + --__last, + __comp); return; } // Use insertion sort if the length of the range is below the specified limit. @@ -774,10 +839,10 @@ void __introsort(_RandomAccessIterator __first, continue; } // Use bitset partition only if asked for. - auto __ret = - _UseBitSetPartition - ? std::__bitset_partition<_AlgPolicy, _RandomAccessIterator, _Compare>(__first, __last, __comp) - : std::__partition_with_equals_on_right<_AlgPolicy, _RandomAccessIterator, _Compare>(__first, __last, __comp); + auto __ret = _UseBitSetPartition + ? std::__bitset_partition<_AlgPolicy, _RandomAccessIterator, _Compare>(__first, __last, __comp) + : std::__partition_with_equals_on_right<_AlgPolicy, _RandomAccessIterator, _Compare>( + __first, __last, __comp); _RandomAccessIterator __i = __ret.first; // [__first, __i) < *__i and *__i <= [__i+1, __last) // If we were given a perfect partition, see if insertion sort is quick... @@ -825,23 +890,31 @@ inline _LIBCPP_HIDE_FROM_ABI _Number __log2i(_Number __n) { template void __sort(_RandomAccessIterator, _RandomAccessIterator, _Comp); -extern template _LIBCPP_FUNC_VIS void __sort<__less&, char*>(char*, char*, __less&); +extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less&, char*>(char*, char*, __less&); #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -extern template _LIBCPP_FUNC_VIS void __sort<__less&, wchar_t*>(wchar_t*, wchar_t*, __less&); +extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less&, wchar_t*>(wchar_t*, wchar_t*, __less&); #endif -extern template _LIBCPP_FUNC_VIS void __sort<__less&, signed char*>(signed char*, signed char*, __less&); -extern template _LIBCPP_FUNC_VIS void __sort<__less&, unsigned char*>(unsigned char*, unsigned char*, __less&); -extern template _LIBCPP_FUNC_VIS void __sort<__less&, short*>(short*, short*, __less&); -extern template _LIBCPP_FUNC_VIS void __sort<__less&, unsigned short*>(unsigned short*, unsigned short*, __less&); -extern template _LIBCPP_FUNC_VIS void __sort<__less&, int*>(int*, int*, __less&); -extern template _LIBCPP_FUNC_VIS void __sort<__less&, unsigned*>(unsigned*, unsigned*, __less&); -extern template _LIBCPP_FUNC_VIS void __sort<__less&, long*>(long*, long*, __less&); -extern template _LIBCPP_FUNC_VIS void __sort<__less&, unsigned long*>(unsigned long*, unsigned long*, __less&); -extern template _LIBCPP_FUNC_VIS void __sort<__less&, long long*>(long long*, long long*, __less&); -extern template _LIBCPP_FUNC_VIS void __sort<__less&, unsigned long long*>(unsigned long long*, unsigned long long*, __less&); -extern template _LIBCPP_FUNC_VIS void __sort<__less&, float*>(float*, float*, __less&); -extern template _LIBCPP_FUNC_VIS void __sort<__less&, double*>(double*, double*, __less&); -extern template _LIBCPP_FUNC_VIS void __sort<__less&, long double*>(long double*, long double*, __less&); +extern template _LIBCPP_EXPORTED_FROM_ABI void +__sort<__less&, signed char*>(signed char*, signed char*, __less&); +extern template _LIBCPP_EXPORTED_FROM_ABI void +__sort<__less&, unsigned char*>(unsigned char*, unsigned char*, __less&); +extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less&, short*>(short*, short*, __less&); +extern template _LIBCPP_EXPORTED_FROM_ABI void +__sort<__less&, unsigned short*>(unsigned short*, unsigned short*, __less&); +extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less&, int*>(int*, int*, __less&); +extern template _LIBCPP_EXPORTED_FROM_ABI void +__sort<__less&, unsigned*>(unsigned*, unsigned*, __less&); +extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less&, long*>(long*, long*, __less&); +extern template _LIBCPP_EXPORTED_FROM_ABI void +__sort<__less&, unsigned long*>(unsigned long*, unsigned long*, __less&); +extern template _LIBCPP_EXPORTED_FROM_ABI void +__sort<__less&, long long*>(long long*, long long*, __less&); +extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less&, unsigned long long*>( + unsigned long long*, unsigned long long*, __less&); +extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less&, float*>(float*, float*, __less&); +extern template _LIBCPP_EXPORTED_FROM_ABI void __sort<__less&, double*>(double*, double*, __less&); +extern template _LIBCPP_EXPORTED_FROM_ABI void +__sort<__less&, long double*>(long double*, long double*, __less&); template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void @@ -855,8 +928,7 @@ __sort_dispatch(_RandomAccessIterator __first, _RandomAccessIterator __last, _Co std::__introsort<_AlgPolicy, _Comp&, _RandomAccessIterator, - __use_branchless_sort<_Comp, _RandomAccessIterator>::value>( - __first, __last, __comp, __depth_limit); + __use_branchless_sort<_Comp, _RandomAccessIterator>::value>(__first, __last, __comp, __depth_limit); } template @@ -884,7 +956,8 @@ using __sort_is_specialized_in_library = __is_any_of< long double>; template ::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI void __sort_dispatch(_Type* __first, _Type* __last, __less<_Type>& __comp) { +_LIBCPP_HIDE_FROM_ABI void __sort_dispatch(_Type* __first, _Type* __last, __less<>&) { + __less<_Type> __comp; std::__sort<__less<_Type>&, _Type*>(__first, __last, __comp); } @@ -911,8 +984,8 @@ _LIBCPP_HIDE_FROM_ABI void __sort_dispatch(_Type* __first, _Type* __last, ranges #endif template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void __sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +__sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) { std::__debug_randomize_range<_AlgPolicy>(__first, __last); if (__libcpp_is_constant_evaluated()) { @@ -921,20 +994,23 @@ void __sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _C } else { std::__sort_dispatch<_AlgPolicy>(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __comp); } + std::__check_strict_weak_ordering_sorted(std::__unwrap_iter(__first), std::__unwrap_iter(__last), __comp); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) { std::__sort_impl<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void sort(_RandomAccessIterator __first, _RandomAccessIterator __last) { - std::sort(__first, __last, __less::value_type>()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +sort(_RandomAccessIterator __first, _RandomAccessIterator __last) { + std::sort(__first, __last, __less<>()); } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_SORT_H diff --git a/third_party/libcxx/__algorithm/sort_heap.h b/third_party/libcxx/__algorithm/sort_heap.h index 0dc9acced..f20b110c7 100644 --- a/third_party/libcxx/__algorithm/sort_heap.h +++ b/third_party/libcxx/__algorithm/sort_heap.h @@ -14,30 +14,36 @@ #include <__algorithm/iterator_operations.h> #include <__algorithm/pop_heap.h> #include <__config> +#include <__debug_utils/strict_weak_ordering_check.h> #include <__iterator/iterator_traits.h> -#include <__type_traits/is_copy_assignable.h> -#include <__type_traits/is_copy_constructible.h> +#include <__type_traits/is_assignable.h> +#include <__type_traits/is_constructible.h> #include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -void __sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void +__sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) { + _RandomAccessIterator __saved_last = __last; __comp_ref_type<_Compare> __comp_ref = __comp; using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type; - for (difference_type __n = __last - __first; __n > 1; --__last, (void) --__n) + for (difference_type __n = __last - __first; __n > 1; --__last, (void)--__n) std::__pop_heap<_AlgPolicy>(__first, __last, __comp_ref, __n); + std::__check_strict_weak_ordering_sorted(__first, __saved_last, __comp_ref); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible."); static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable."); @@ -45,12 +51,13 @@ void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Com } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { - std::sort_heap(std::move(__first), std::move(__last), - __less::value_type>()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { + std::sort_heap(std::move(__first), std::move(__last), __less<>()); } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_SORT_HEAP_H diff --git a/third_party/libcxx/__algorithm/stable_partition.h b/third_party/libcxx/__algorithm/stable_partition.h index 3b68bd306..8bb1eaf2d 100644 --- a/third_party/libcxx/__algorithm/stable_partition.h +++ b/third_party/libcxx/__algorithm/stable_partition.h @@ -26,298 +26,275 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI _ForwardIterator -__stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, - _Distance __len, _Pair __p, forward_iterator_tag __fit) -{ - using _Ops = _IterOps<_AlgPolicy>; +_LIBCPP_HIDE_FROM_ABI _ForwardIterator __stable_partition_impl( + _ForwardIterator __first, + _ForwardIterator __last, + _Predicate __pred, + _Distance __len, + _Pair __p, + forward_iterator_tag __fit) { + using _Ops = _IterOps<_AlgPolicy>; - // *__first is known to be false - // __len >= 1 - if (__len == 1) - return __first; - if (__len == 2) - { - _ForwardIterator __m = __first; - if (__pred(*++__m)) - { - _Ops::iter_swap(__first, __m); - return __m; - } - return __first; + // *__first is known to be false + // __len >= 1 + if (__len == 1) + return __first; + if (__len == 2) { + _ForwardIterator __m = __first; + if (__pred(*++__m)) { + _Ops::iter_swap(__first, __m); + return __m; } - if (__len <= __p.second) - { // The buffer is big enough to use - typedef typename iterator_traits<_ForwardIterator>::value_type value_type; - __destruct_n __d(0); - unique_ptr __h(__p.first, __d); - // Move the falses into the temporary buffer, and the trues to the front of the line - // Update __first to always point to the end of the trues - value_type* __t = __p.first; - ::new ((void*)__t) value_type(_Ops::__iter_move(__first)); + return __first; + } + if (__len <= __p.second) { // The buffer is big enough to use + typedef typename iterator_traits<_ForwardIterator>::value_type value_type; + __destruct_n __d(0); + unique_ptr __h(__p.first, __d); + // Move the falses into the temporary buffer, and the trues to the front of the line + // Update __first to always point to the end of the trues + value_type* __t = __p.first; + ::new ((void*)__t) value_type(_Ops::__iter_move(__first)); + __d.template __incr(); + ++__t; + _ForwardIterator __i = __first; + while (++__i != __last) { + if (__pred(*__i)) { + *__first = _Ops::__iter_move(__i); + ++__first; + } else { + ::new ((void*)__t) value_type(_Ops::__iter_move(__i)); __d.template __incr(); ++__t; - _ForwardIterator __i = __first; - while (++__i != __last) - { - if (__pred(*__i)) - { - *__first = _Ops::__iter_move(__i); - ++__first; - } - else - { - ::new ((void*)__t) value_type(_Ops::__iter_move(__i)); - __d.template __incr(); - ++__t; - } - } - // All trues now at start of range, all falses in buffer - // Move falses back into range, but don't mess up __first which points to first false - __i = __first; - for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, (void) ++__i) - *__i = _Ops::__iter_move(__t2); - // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer - return __first; + } } - // Else not enough buffer, do in place - // __len >= 3 - _ForwardIterator __m = __first; - _Distance __len2 = __len / 2; // __len2 >= 2 - _Ops::advance(__m, __len2); - // recurse on [__first, __m), *__first know to be false - // F????????????????? - // f m l - _ForwardIterator __first_false = std::__stable_partition_impl<_AlgPolicy, _Predicate&>( - __first, __m, __pred, __len2, __p, __fit); - // TTTFFFFF?????????? - // f ff m l - // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true - _ForwardIterator __m1 = __m; - _ForwardIterator __second_false = __last; - _Distance __len_half = __len - __len2; - while (__pred(*__m1)) - { - if (++__m1 == __last) - goto __second_half_done; - --__len_half; - } - // TTTFFFFFTTTF?????? - // f ff m m1 l - __second_false = std::__stable_partition_impl<_AlgPolicy, _Predicate&>( - __m1, __last, __pred, __len_half, __p, __fit); + // All trues now at start of range, all falses in buffer + // Move falses back into range, but don't mess up __first which points to first false + __i = __first; + for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, (void)++__i) + *__i = _Ops::__iter_move(__t2); + // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer + return __first; + } + // Else not enough buffer, do in place + // __len >= 3 + _ForwardIterator __m = __first; + _Distance __len2 = __len / 2; // __len2 >= 2 + _Ops::advance(__m, __len2); + // recurse on [__first, __m), *__first know to be false + // F????????????????? + // f m l + _ForwardIterator __first_false = + std::__stable_partition_impl<_AlgPolicy, _Predicate&>(__first, __m, __pred, __len2, __p, __fit); + // TTTFFFFF?????????? + // f ff m l + // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true + _ForwardIterator __m1 = __m; + _ForwardIterator __second_false = __last; + _Distance __len_half = __len - __len2; + while (__pred(*__m1)) { + if (++__m1 == __last) + goto __second_half_done; + --__len_half; + } + // TTTFFFFFTTTF?????? + // f ff m m1 l + __second_false = std::__stable_partition_impl<_AlgPolicy, _Predicate&>(__m1, __last, __pred, __len_half, __p, __fit); __second_half_done: - // TTTFFFFFTTTTTFFFFF - // f ff m sf l - return std::__rotate<_AlgPolicy>(__first_false, __m, __second_false).first; - // TTTTTTTTFFFFFFFFFF - // | + // TTTFFFFFTTTTTFFFFF + // f ff m sf l + return std::__rotate<_AlgPolicy>(__first_false, __m, __second_false).first; + // TTTTTTTTFFFFFFFFFF + // | } template _LIBCPP_HIDE_FROM_ABI _ForwardIterator -__stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, - forward_iterator_tag) -{ - const unsigned __alloc_limit = 3; // might want to make this a function of trivial assignment - // Either prove all true and return __first or point to first false - while (true) - { - if (__first == __last) - return __first; - if (!__pred(*__first)) - break; - ++__first; - } - // We now have a reduced range [__first, __last) - // *__first is known to be false - typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; - typedef typename iterator_traits<_ForwardIterator>::value_type value_type; - difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last); - pair __p(0, 0); - unique_ptr __h; - if (__len >= __alloc_limit) - { -// TODO: Remove the use of std::get_temporary_buffer -_LIBCPP_SUPPRESS_DEPRECATED_PUSH - __p = _VSTD::get_temporary_buffer(__len); -_LIBCPP_SUPPRESS_DEPRECATED_POP - __h.reset(__p.first); - } - return std::__stable_partition_impl<_AlgPolicy, _Predicate&>( - std::move(__first), std::move(__last), __pred, __len, __p, forward_iterator_tag()); +__stable_partition_impl(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, forward_iterator_tag) { + typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type; + typedef typename iterator_traits<_ForwardIterator>::value_type value_type; + + const difference_type __alloc_limit = 3; // might want to make this a function of trivial assignment + // Either prove all true and return __first or point to first false + while (true) { + if (__first == __last) + return __first; + if (!__pred(*__first)) + break; + ++__first; + } + // We now have a reduced range [__first, __last) + // *__first is known to be false + difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last); + pair __p(0, 0); + unique_ptr __h; + if (__len >= __alloc_limit) { + // TODO: Remove the use of std::get_temporary_buffer + _LIBCPP_SUPPRESS_DEPRECATED_PUSH + __p = std::get_temporary_buffer(__len); + _LIBCPP_SUPPRESS_DEPRECATED_POP + __h.reset(__p.first); + } + return std::__stable_partition_impl<_AlgPolicy, _Predicate&>( + std::move(__first), std::move(__last), __pred, __len, __p, forward_iterator_tag()); } template -_BidirectionalIterator -__stable_partition_impl(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, - _Distance __len, _Pair __p, bidirectional_iterator_tag __bit) -{ - using _Ops = _IterOps<_AlgPolicy>; +_BidirectionalIterator __stable_partition_impl( + _BidirectionalIterator __first, + _BidirectionalIterator __last, + _Predicate __pred, + _Distance __len, + _Pair __p, + bidirectional_iterator_tag __bit) { + using _Ops = _IterOps<_AlgPolicy>; - // *__first is known to be false - // *__last is known to be true - // __len >= 2 - if (__len == 2) - { - _Ops::iter_swap(__first, __last); - return __last; + // *__first is known to be false + // *__last is known to be true + // __len >= 2 + if (__len == 2) { + _Ops::iter_swap(__first, __last); + return __last; + } + if (__len == 3) { + _BidirectionalIterator __m = __first; + if (__pred(*++__m)) { + _Ops::iter_swap(__first, __m); + _Ops::iter_swap(__m, __last); + return __last; } - if (__len == 3) - { - _BidirectionalIterator __m = __first; - if (__pred(*++__m)) - { - _Ops::iter_swap(__first, __m); - _Ops::iter_swap(__m, __last); - return __last; - } - _Ops::iter_swap(__m, __last); - _Ops::iter_swap(__first, __m); - return __m; - } - if (__len <= __p.second) - { // The buffer is big enough to use - typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; - __destruct_n __d(0); - unique_ptr __h(__p.first, __d); - // Move the falses into the temporary buffer, and the trues to the front of the line - // Update __first to always point to the end of the trues - value_type* __t = __p.first; - ::new ((void*)__t) value_type(_Ops::__iter_move(__first)); + _Ops::iter_swap(__m, __last); + _Ops::iter_swap(__first, __m); + return __m; + } + if (__len <= __p.second) { // The buffer is big enough to use + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + __destruct_n __d(0); + unique_ptr __h(__p.first, __d); + // Move the falses into the temporary buffer, and the trues to the front of the line + // Update __first to always point to the end of the trues + value_type* __t = __p.first; + ::new ((void*)__t) value_type(_Ops::__iter_move(__first)); + __d.template __incr(); + ++__t; + _BidirectionalIterator __i = __first; + while (++__i != __last) { + if (__pred(*__i)) { + *__first = _Ops::__iter_move(__i); + ++__first; + } else { + ::new ((void*)__t) value_type(_Ops::__iter_move(__i)); __d.template __incr(); ++__t; - _BidirectionalIterator __i = __first; - while (++__i != __last) - { - if (__pred(*__i)) - { - *__first = _Ops::__iter_move(__i); - ++__first; - } - else - { - ::new ((void*)__t) value_type(_Ops::__iter_move(__i)); - __d.template __incr(); - ++__t; - } - } - // move *__last, known to be true - *__first = _Ops::__iter_move(__i); - __i = ++__first; - // All trues now at start of range, all falses in buffer - // Move falses back into range, but don't mess up __first which points to first false - for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, (void) ++__i) - *__i = _Ops::__iter_move(__t2); - // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer - return __first; + } } - // Else not enough buffer, do in place - // __len >= 4 - _BidirectionalIterator __m = __first; - _Distance __len2 = __len / 2; // __len2 >= 2 - _Ops::advance(__m, __len2); - // recurse on [__first, __m-1], except reduce __m-1 until *(__m-1) is true, *__first know to be false - // F????????????????T - // f m l - _BidirectionalIterator __m1 = __m; - _BidirectionalIterator __first_false = __first; - _Distance __len_half = __len2; - while (!__pred(*--__m1)) - { - if (__m1 == __first) - goto __first_half_done; - --__len_half; - } - // F???TFFF?????????T - // f m1 m l - __first_false = std::__stable_partition_impl<_AlgPolicy, _Predicate&>( - __first, __m1, __pred, __len_half, __p, __bit); + // move *__last, known to be true + *__first = _Ops::__iter_move(__i); + __i = ++__first; + // All trues now at start of range, all falses in buffer + // Move falses back into range, but don't mess up __first which points to first false + for (value_type* __t2 = __p.first; __t2 < __t; ++__t2, (void)++__i) + *__i = _Ops::__iter_move(__t2); + // __h destructs moved-from values out of the temp buffer, but doesn't deallocate buffer + return __first; + } + // Else not enough buffer, do in place + // __len >= 4 + _BidirectionalIterator __m = __first; + _Distance __len2 = __len / 2; // __len2 >= 2 + _Ops::advance(__m, __len2); + // recurse on [__first, __m-1], except reduce __m-1 until *(__m-1) is true, *__first know to be false + // F????????????????T + // f m l + _BidirectionalIterator __m1 = __m; + _BidirectionalIterator __first_false = __first; + _Distance __len_half = __len2; + while (!__pred(*--__m1)) { + if (__m1 == __first) + goto __first_half_done; + --__len_half; + } + // F???TFFF?????????T + // f m1 m l + __first_false = std::__stable_partition_impl<_AlgPolicy, _Predicate&>(__first, __m1, __pred, __len_half, __p, __bit); __first_half_done: - // TTTFFFFF?????????T - // f ff m l - // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true - __m1 = __m; - _BidirectionalIterator __second_false = __last; - ++__second_false; - __len_half = __len - __len2; - while (__pred(*__m1)) - { - if (++__m1 == __last) - goto __second_half_done; - --__len_half; - } - // TTTFFFFFTTTF?????T - // f ff m m1 l - __second_false = std::__stable_partition_impl<_AlgPolicy, _Predicate&>( - __m1, __last, __pred, __len_half, __p, __bit); + // TTTFFFFF?????????T + // f ff m l + // recurse on [__m, __last], except increase __m until *(__m) is false, *__last know to be true + __m1 = __m; + _BidirectionalIterator __second_false = __last; + ++__second_false; + __len_half = __len - __len2; + while (__pred(*__m1)) { + if (++__m1 == __last) + goto __second_half_done; + --__len_half; + } + // TTTFFFFFTTTF?????T + // f ff m m1 l + __second_false = std::__stable_partition_impl<_AlgPolicy, _Predicate&>(__m1, __last, __pred, __len_half, __p, __bit); __second_half_done: - // TTTFFFFFTTTTTFFFFF - // f ff m sf l - return std::__rotate<_AlgPolicy>(__first_false, __m, __second_false).first; - // TTTTTTTTFFFFFFFFFF - // | + // TTTFFFFFTTTTTFFFFF + // f ff m sf l + return std::__rotate<_AlgPolicy>(__first_false, __m, __second_false).first; + // TTTTTTTTFFFFFFFFFF + // | } template -_LIBCPP_HIDE_FROM_ABI _BidirectionalIterator -__stable_partition_impl(_BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, - bidirectional_iterator_tag) -{ - typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; - typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; - const difference_type __alloc_limit = 4; // might want to make this a function of trivial assignment - // Either prove all true and return __first or point to first false - while (true) - { - if (__first == __last) - return __first; - if (!__pred(*__first)) - break; - ++__first; - } - // __first points to first false, everything prior to __first is already set. - // Either prove [__first, __last) is all false and return __first, or point __last to last true - do - { - if (__first == --__last) - return __first; - } while (!__pred(*__last)); - // We now have a reduced range [__first, __last] - // *__first is known to be false - // *__last is known to be true - // __len >= 2 - difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last) + 1; - pair __p(0, 0); - unique_ptr __h; - if (__len >= __alloc_limit) - { -// TODO: Remove the use of std::get_temporary_buffer -_LIBCPP_SUPPRESS_DEPRECATED_PUSH - __p = _VSTD::get_temporary_buffer(__len); -_LIBCPP_SUPPRESS_DEPRECATED_POP - __h.reset(__p.first); - } - return std::__stable_partition_impl<_AlgPolicy, _Predicate&>( - std::move(__first), std::move(__last), __pred, __len, __p, bidirectional_iterator_tag()); +_LIBCPP_HIDE_FROM_ABI _BidirectionalIterator __stable_partition_impl( + _BidirectionalIterator __first, _BidirectionalIterator __last, _Predicate __pred, bidirectional_iterator_tag) { + typedef typename iterator_traits<_BidirectionalIterator>::difference_type difference_type; + typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; + const difference_type __alloc_limit = 4; // might want to make this a function of trivial assignment + // Either prove all true and return __first or point to first false + while (true) { + if (__first == __last) + return __first; + if (!__pred(*__first)) + break; + ++__first; + } + // __first points to first false, everything prior to __first is already set. + // Either prove [__first, __last) is all false and return __first, or point __last to last true + do { + if (__first == --__last) + return __first; + } while (!__pred(*__last)); + // We now have a reduced range [__first, __last] + // *__first is known to be false + // *__last is known to be true + // __len >= 2 + difference_type __len = _IterOps<_AlgPolicy>::distance(__first, __last) + 1; + pair __p(0, 0); + unique_ptr __h; + if (__len >= __alloc_limit) { + // TODO: Remove the use of std::get_temporary_buffer + _LIBCPP_SUPPRESS_DEPRECATED_PUSH + __p = std::get_temporary_buffer(__len); + _LIBCPP_SUPPRESS_DEPRECATED_POP + __h.reset(__p.first); + } + return std::__stable_partition_impl<_AlgPolicy, _Predicate&>( + std::move(__first), std::move(__last), __pred, __len, __p, bidirectional_iterator_tag()); } template -_LIBCPP_HIDE_FROM_ABI -_ForwardIterator __stable_partition( +_LIBCPP_HIDE_FROM_ABI _ForwardIterator __stable_partition( _ForwardIterator __first, _ForwardIterator __last, _Predicate&& __pred, _IterCategory __iter_category) { return std::__stable_partition_impl<_AlgPolicy, __remove_cvref_t<_Predicate>&>( std::move(__first), std::move(__last), __pred, __iter_category); } template -inline _LIBCPP_INLINE_VISIBILITY -_ForwardIterator -stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) -{ +inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator +stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { using _IterCategory = typename iterator_traits<_ForwardIterator>::iterator_category; return std::__stable_partition<_ClassicAlgPolicy, _Predicate&>( std::move(__first), std::move(__last), __pred, _IterCategory()); @@ -325,4 +302,6 @@ stable_partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate _ _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_STABLE_PARTITION_H diff --git a/third_party/libcxx/__algorithm/stable_sort.h b/third_party/libcxx/__algorithm/stable_sort.h index 0c9daa2ad..726e7e16b 100644 --- a/third_party/libcxx/__algorithm/stable_sort.h +++ b/third_party/libcxx/__algorithm/stable_sort.h @@ -15,11 +15,12 @@ #include <__algorithm/iterator_operations.h> #include <__algorithm/sort.h> #include <__config> +#include <__debug_utils/strict_weak_ordering_check.h> #include <__iterator/iterator_traits.h> #include <__memory/destruct_n.h> #include <__memory/temporary_buffer.h> #include <__memory/unique_ptr.h> -#include <__type_traits/is_trivially_copy_assignable.h> +#include <__type_traits/is_trivially_assignable.h> #include <__utility/move.h> #include <__utility/pair.h> #include @@ -28,12 +29,17 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI -void __insertion_sort_move(_BidirectionalIterator __first1, _BidirectionalIterator __last1, - typename iterator_traits<_BidirectionalIterator>::value_type* __first2, _Compare __comp) { +_LIBCPP_HIDE_FROM_ABI void __insertion_sort_move( + _BidirectionalIterator __first1, + _BidirectionalIterator __last1, + typename iterator_traits<_BidirectionalIterator>::value_type* __first2, + _Compare __comp) { using _Ops = _IterOps<_AlgPolicy>; typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type; @@ -62,217 +68,206 @@ void __insertion_sort_move(_BidirectionalIterator __first1, _BidirectionalIterat } template -_LIBCPP_HIDE_FROM_ABI void -__merge_move_construct(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, - typename iterator_traits<_InputIterator1>::value_type* __result, _Compare __comp) -{ - using _Ops = _IterOps<_AlgPolicy>; +_LIBCPP_HIDE_FROM_ABI void __merge_move_construct( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + typename iterator_traits<_InputIterator1>::value_type* __result, + _Compare __comp) { + using _Ops = _IterOps<_AlgPolicy>; - typedef typename iterator_traits<_InputIterator1>::value_type value_type; - __destruct_n __d(0); - unique_ptr __h(__result, __d); - for (; true; ++__result) - { - if (__first1 == __last1) - { - for (; __first2 != __last2; ++__first2, (void) ++__result, __d.template __incr()) - ::new ((void*)__result) value_type(_Ops::__iter_move(__first2)); - __h.release(); - return; - } - if (__first2 == __last2) - { - for (; __first1 != __last1; ++__first1, (void) ++__result, __d.template __incr()) - ::new ((void*)__result) value_type(_Ops::__iter_move(__first1)); - __h.release(); - return; - } - if (__comp(*__first2, *__first1)) - { - ::new ((void*)__result) value_type(_Ops::__iter_move(__first2)); - __d.template __incr(); - ++__first2; - } - else - { - ::new ((void*)__result) value_type(_Ops::__iter_move(__first1)); - __d.template __incr(); - ++__first1; - } + typedef typename iterator_traits<_InputIterator1>::value_type value_type; + __destruct_n __d(0); + unique_ptr __h(__result, __d); + for (; true; ++__result) { + if (__first1 == __last1) { + for (; __first2 != __last2; ++__first2, (void)++__result, __d.template __incr()) + ::new ((void*)__result) value_type(_Ops::__iter_move(__first2)); + __h.release(); + return; } + if (__first2 == __last2) { + for (; __first1 != __last1; ++__first1, (void)++__result, __d.template __incr()) + ::new ((void*)__result) value_type(_Ops::__iter_move(__first1)); + __h.release(); + return; + } + if (__comp(*__first2, *__first1)) { + ::new ((void*)__result) value_type(_Ops::__iter_move(__first2)); + __d.template __incr(); + ++__first2; + } else { + ::new ((void*)__result) value_type(_Ops::__iter_move(__first1)); + __d.template __incr(); + ++__first1; + } + } } template -_LIBCPP_HIDE_FROM_ABI void -__merge_move_assign(_InputIterator1 __first1, _InputIterator1 __last1, - _InputIterator2 __first2, _InputIterator2 __last2, - _OutputIterator __result, _Compare __comp) -{ - using _Ops = _IterOps<_AlgPolicy>; +_LIBCPP_HIDE_FROM_ABI void __merge_move_assign( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _InputIterator2 __last2, + _OutputIterator __result, + _Compare __comp) { + using _Ops = _IterOps<_AlgPolicy>; - for (; __first1 != __last1; ++__result) - { - if (__first2 == __last2) - { - for (; __first1 != __last1; ++__first1, (void) ++__result) - *__result = _Ops::__iter_move(__first1); - return; - } - if (__comp(*__first2, *__first1)) - { - *__result = _Ops::__iter_move(__first2); - ++__first2; - } - else - { - *__result = _Ops::__iter_move(__first1); - ++__first1; - } + for (; __first1 != __last1; ++__result) { + if (__first2 == __last2) { + for (; __first1 != __last1; ++__first1, (void)++__result) + *__result = _Ops::__iter_move(__first1); + return; } - for (; __first2 != __last2; ++__first2, (void) ++__result) - *__result = _Ops::__iter_move(__first2); + if (__comp(*__first2, *__first1)) { + *__result = _Ops::__iter_move(__first2); + ++__first2; + } else { + *__result = _Ops::__iter_move(__first1); + ++__first1; + } + } + for (; __first2 != __last2; ++__first2, (void)++__result) + *__result = _Ops::__iter_move(__first2); } template -void -__stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, - typename iterator_traits<_RandomAccessIterator>::difference_type __len, - typename iterator_traits<_RandomAccessIterator>::value_type* __buff, ptrdiff_t __buff_size); +void __stable_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Compare __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len, + typename iterator_traits<_RandomAccessIterator>::value_type* __buff, + ptrdiff_t __buff_size); template -void -__stable_sort_move(_RandomAccessIterator __first1, _RandomAccessIterator __last1, _Compare __comp, - typename iterator_traits<_RandomAccessIterator>::difference_type __len, - typename iterator_traits<_RandomAccessIterator>::value_type* __first2) -{ - using _Ops = _IterOps<_AlgPolicy>; +void __stable_sort_move(_RandomAccessIterator __first1, + _RandomAccessIterator __last1, + _Compare __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len, + typename iterator_traits<_RandomAccessIterator>::value_type* __first2) { + using _Ops = _IterOps<_AlgPolicy>; - typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; - switch (__len) - { - case 0: - return; - case 1: - ::new ((void*)__first2) value_type(_Ops::__iter_move(__first1)); - return; - case 2: - __destruct_n __d(0); - unique_ptr __h2(__first2, __d); - if (__comp(*--__last1, *__first1)) - { - ::new ((void*)__first2) value_type(_Ops::__iter_move(__last1)); - __d.template __incr(); - ++__first2; - ::new ((void*)__first2) value_type(_Ops::__iter_move(__first1)); - } - else - { - ::new ((void*)__first2) value_type(_Ops::__iter_move(__first1)); - __d.template __incr(); - ++__first2; - ::new ((void*)__first2) value_type(_Ops::__iter_move(__last1)); - } - __h2.release(); - return; + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + switch (__len) { + case 0: + return; + case 1: + ::new ((void*)__first2) value_type(_Ops::__iter_move(__first1)); + return; + case 2: + __destruct_n __d(0); + unique_ptr __h2(__first2, __d); + if (__comp(*--__last1, *__first1)) { + ::new ((void*)__first2) value_type(_Ops::__iter_move(__last1)); + __d.template __incr(); + ++__first2; + ::new ((void*)__first2) value_type(_Ops::__iter_move(__first1)); + } else { + ::new ((void*)__first2) value_type(_Ops::__iter_move(__first1)); + __d.template __incr(); + ++__first2; + ::new ((void*)__first2) value_type(_Ops::__iter_move(__last1)); } - if (__len <= 8) - { - std::__insertion_sort_move<_AlgPolicy, _Compare>(__first1, __last1, __first2, __comp); - return; - } - typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2; - _RandomAccessIterator __m = __first1 + __l2; - std::__stable_sort<_AlgPolicy, _Compare>(__first1, __m, __comp, __l2, __first2, __l2); - std::__stable_sort<_AlgPolicy, _Compare>(__m, __last1, __comp, __len - __l2, __first2 + __l2, __len - __l2); - std::__merge_move_construct<_AlgPolicy, _Compare>(__first1, __m, __m, __last1, __first2, __comp); + __h2.release(); + return; + } + if (__len <= 8) { + std::__insertion_sort_move<_AlgPolicy, _Compare>(__first1, __last1, __first2, __comp); + return; + } + typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2; + _RandomAccessIterator __m = __first1 + __l2; + std::__stable_sort<_AlgPolicy, _Compare>(__first1, __m, __comp, __l2, __first2, __l2); + std::__stable_sort<_AlgPolicy, _Compare>(__m, __last1, __comp, __len - __l2, __first2 + __l2, __len - __l2); + std::__merge_move_construct<_AlgPolicy, _Compare>(__first1, __m, __m, __last1, __first2, __comp); } template -struct __stable_sort_switch -{ - static const unsigned value = 128*is_trivially_copy_assignable<_Tp>::value; +struct __stable_sort_switch { + static const unsigned value = 128 * is_trivially_copy_assignable<_Tp>::value; }; template -void -__stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, - typename iterator_traits<_RandomAccessIterator>::difference_type __len, - typename iterator_traits<_RandomAccessIterator>::value_type* __buff, ptrdiff_t __buff_size) -{ - typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; - typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; - switch (__len) - { - case 0: - case 1: - return; - case 2: - if (__comp(*--__last, *__first)) - _IterOps<_AlgPolicy>::iter_swap(__first, __last); - return; - } - if (__len <= static_cast(__stable_sort_switch::value)) - { - std::__insertion_sort<_AlgPolicy, _Compare>(__first, __last, __comp); - return; - } - typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2; - _RandomAccessIterator __m = __first + __l2; - if (__len <= __buff_size) - { - __destruct_n __d(0); - unique_ptr __h2(__buff, __d); - std::__stable_sort_move<_AlgPolicy, _Compare>(__first, __m, __comp, __l2, __buff); - __d.__set(__l2, (value_type*)nullptr); - std::__stable_sort_move<_AlgPolicy, _Compare>(__m, __last, __comp, __len - __l2, __buff + __l2); - __d.__set(__len, (value_type*)nullptr); - std::__merge_move_assign<_AlgPolicy, _Compare>( - __buff, __buff + __l2, __buff + __l2, __buff + __len, __first, __comp); -// _VSTD::__merge<_Compare>(move_iterator(__buff), -// move_iterator(__buff + __l2), -// move_iterator<_RandomAccessIterator>(__buff + __l2), -// move_iterator<_RandomAccessIterator>(__buff + __len), -// __first, __comp); - return; - } - std::__stable_sort<_AlgPolicy, _Compare>(__first, __m, __comp, __l2, __buff, __buff_size); - std::__stable_sort<_AlgPolicy, _Compare>(__m, __last, __comp, __len - __l2, __buff, __buff_size); - std::__inplace_merge<_AlgPolicy>(__first, __m, __last, __comp, __l2, __len - __l2, __buff, __buff_size); +void __stable_sort(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Compare __comp, + typename iterator_traits<_RandomAccessIterator>::difference_type __len, + typename iterator_traits<_RandomAccessIterator>::value_type* __buff, + ptrdiff_t __buff_size) { + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + switch (__len) { + case 0: + case 1: + return; + case 2: + if (__comp(*--__last, *__first)) + _IterOps<_AlgPolicy>::iter_swap(__first, __last); + return; + } + if (__len <= static_cast(__stable_sort_switch::value)) { + std::__insertion_sort<_AlgPolicy, _Compare>(__first, __last, __comp); + return; + } + typename iterator_traits<_RandomAccessIterator>::difference_type __l2 = __len / 2; + _RandomAccessIterator __m = __first + __l2; + if (__len <= __buff_size) { + __destruct_n __d(0); + unique_ptr __h2(__buff, __d); + std::__stable_sort_move<_AlgPolicy, _Compare>(__first, __m, __comp, __l2, __buff); + __d.__set(__l2, (value_type*)nullptr); + std::__stable_sort_move<_AlgPolicy, _Compare>(__m, __last, __comp, __len - __l2, __buff + __l2); + __d.__set(__len, (value_type*)nullptr); + std::__merge_move_assign<_AlgPolicy, _Compare>( + __buff, __buff + __l2, __buff + __l2, __buff + __len, __first, __comp); + // std::__merge<_Compare>(move_iterator(__buff), + // move_iterator(__buff + __l2), + // move_iterator<_RandomAccessIterator>(__buff + __l2), + // move_iterator<_RandomAccessIterator>(__buff + __len), + // __first, __comp); + return; + } + std::__stable_sort<_AlgPolicy, _Compare>(__first, __m, __comp, __l2, __buff, __buff_size); + std::__stable_sort<_AlgPolicy, _Compare>(__m, __last, __comp, __len - __l2, __buff, __buff_size); + std::__inplace_merge<_AlgPolicy>(__first, __m, __last, __comp, __l2, __len - __l2, __buff, __buff_size); } template -inline _LIBCPP_HIDE_FROM_ABI -void __stable_sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) { - using value_type = typename iterator_traits<_RandomAccessIterator>::value_type; +inline _LIBCPP_HIDE_FROM_ABI void +__stable_sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) { + using value_type = typename iterator_traits<_RandomAccessIterator>::value_type; using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type; difference_type __len = __last - __first; pair __buf(0, 0); unique_ptr __h; if (__len > static_cast(__stable_sort_switch::value)) { -// TODO: Remove the use of std::get_temporary_buffer -_LIBCPP_SUPPRESS_DEPRECATED_PUSH - __buf = std::get_temporary_buffer(__len); -_LIBCPP_SUPPRESS_DEPRECATED_POP - __h.reset(__buf.first); + // TODO: Remove the use of std::get_temporary_buffer + _LIBCPP_SUPPRESS_DEPRECATED_PUSH + __buf = std::get_temporary_buffer(__len); + _LIBCPP_SUPPRESS_DEPRECATED_POP + __h.reset(__buf.first); } std::__stable_sort<_AlgPolicy, __comp_ref_type<_Compare> >(__first, __last, __comp, __len, __buf.first, __buf.second); + std::__check_strict_weak_ordering_sorted(__first, __last, __comp); } template -inline _LIBCPP_HIDE_FROM_ABI -void stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { +inline _LIBCPP_HIDE_FROM_ABI void +stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { std::__stable_sort_impl<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp); } template -inline _LIBCPP_HIDE_FROM_ABI -void stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) { - std::stable_sort(__first, __last, __less::value_type>()); +inline _LIBCPP_HIDE_FROM_ABI void stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) { + std::stable_sort(__first, __last, __less<>()); } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_STABLE_SORT_H diff --git a/third_party/libcxx/__algorithm/swap_ranges.h b/third_party/libcxx/__algorithm/swap_ranges.h index 5ce5ed8c8..54b453b72 100644 --- a/third_party/libcxx/__algorithm/swap_ranges.h +++ b/third_party/libcxx/__algorithm/swap_ranges.h @@ -18,12 +18,14 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD // 2+2 iterators: the shorter size will be used. template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -pair<_ForwardIterator1, _ForwardIterator2> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator1, _ForwardIterator2> __swap_ranges(_ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2 __first2, _Sentinel2 __last2) { while (__first1 != __last1 && __first2 != __last2) { _IterOps<_AlgPolicy>::iter_swap(__first1, __first2); @@ -36,8 +38,7 @@ __swap_ranges(_ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2 // 2+1 iterators: size2 >= size1. template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -pair<_ForwardIterator1, _ForwardIterator2> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator1, _ForwardIterator2> __swap_ranges(_ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2 __first2) { while (__first1 != __last1) { _IterOps<_AlgPolicy>::iter_swap(__first1, __first2); @@ -49,12 +50,13 @@ __swap_ranges(_ForwardIterator1 __first1, _Sentinel1 __last1, _ForwardIterator2 } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator2 +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator2 swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) { - return std::__swap_ranges<_ClassicAlgPolicy>( - std::move(__first1), std::move(__last1), std::move(__first2)).second; + return std::__swap_ranges<_ClassicAlgPolicy>(std::move(__first1), std::move(__last1), std::move(__first2)).second; } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_SWAP_RANGES_H diff --git a/third_party/libcxx/__algorithm/three_way_comp_ref_type.h b/third_party/libcxx/__algorithm/three_way_comp_ref_type.h index 10396e068..70c581897 100644 --- a/third_party/libcxx/__algorithm/three_way_comp_ref_type.h +++ b/third_party/libcxx/__algorithm/three_way_comp_ref_type.h @@ -11,8 +11,8 @@ #include <__compare/ordering.h> #include <__config> -#include <__debug> #include <__utility/declval.h> +#include <__utility/forward.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -27,35 +27,38 @@ struct __debug_three_way_comp { _Comp& __comp_; _LIBCPP_HIDE_FROM_ABI constexpr __debug_three_way_comp(_Comp& __c) : __comp_(__c) {} + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(const _Tp& __x, const _Up& __y) { + auto __r = __comp_(__x, __y); + if constexpr (__comparison_category) + __do_compare_assert(__y, __x, __r); + return __r; + } + template _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp& __x, _Up& __y) { auto __r = __comp_(__x, __y); - __do_compare_assert(0, __y, __x, __r); + if constexpr (__comparison_category) + __do_compare_assert(__y, __x, __r); return __r; } template - _LIBCPP_HIDE_FROM_ABI constexpr inline void __do_compare_assert(int, _LHS& __l, _RHS& __r, _Order __o) - requires __comparison_category()(std::declval<_LHS&>(), std::declval<_RHS&>()))> - { + _LIBCPP_HIDE_FROM_ABI constexpr void __do_compare_assert(_LHS& __l, _RHS& __r, _Order __o) { _Order __expected = __o; if (__o == _Order::less) __expected = _Order::greater; if (__o == _Order::greater) __expected = _Order::less; - _LIBCPP_DEBUG_ASSERT(__comp_(__l, __r) == __expected, "Comparator does not induce a strict weak ordering"); + _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT( + __comp_(__l, __r) == __expected, "Comparator does not induce a strict weak ordering"); (void)__l; (void)__r; - (void)__expected; } - - template - _LIBCPP_HIDE_FROM_ABI constexpr inline void __do_compare_assert(long, _LHS&, _RHS&, _Order) {} }; -// Pass the comparator by lvalue reference. Or in debug mode, using a -// debugging wrapper that stores a reference. -# ifndef _LIBCPP_ENABLE_DEBUG_MODE +// Pass the comparator by lvalue reference. Or in the debug mode, using a debugging wrapper that stores a reference. +# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG template using __three_way_comp_ref_type = __debug_three_way_comp<_Comp>; # else diff --git a/third_party/libcxx/__algorithm/transform.h b/third_party/libcxx/__algorithm/transform.h index 4722c154c..1b4244095 100644 --- a/third_party/libcxx/__algorithm/transform.h +++ b/third_party/libcxx/__algorithm/transform.h @@ -18,24 +18,23 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -transform(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _UnaryOperation __op) -{ - for (; __first != __last; ++__first, (void) ++__result) - *__result = __op(*__first); - return __result; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator +transform(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _UnaryOperation __op) { + for (; __first != __last; ++__first, (void)++__result) + *__result = __op(*__first); + return __result; } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -_OutputIterator -transform(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, - _OutputIterator __result, _BinaryOperation __binary_op) -{ - for (; __first1 != __last1; ++__first1, (void) ++__first2, ++__result) - *__result = __binary_op(*__first1, *__first2); - return __result; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator transform( + _InputIterator1 __first1, + _InputIterator1 __last1, + _InputIterator2 __first2, + _OutputIterator __result, + _BinaryOperation __binary_op) { + for (; __first1 != __last1; ++__first1, (void)++__first2, ++__result) + *__result = __binary_op(*__first1, *__first2); + return __result; } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/uniform_random_bit_generator_adaptor.h b/third_party/libcxx/__algorithm/uniform_random_bit_generator_adaptor.h index 1f2039949..aef0fbfb7 100644 --- a/third_party/libcxx/__algorithm/uniform_random_bit_generator_adaptor.h +++ b/third_party/libcxx/__algorithm/uniform_random_bit_generator_adaptor.h @@ -20,7 +20,7 @@ #if _LIBCPP_STD_VER >= 20 _LIBCPP_PUSH_MACROS -#include <__undef_macros> +# include <__undef_macros> _LIBCPP_BEGIN_NAMESPACE_STD @@ -41,16 +41,12 @@ private: public: using result_type = invoke_result_t<_Gen&>; - _LIBCPP_HIDE_FROM_ABI - static constexpr auto min() { return __remove_cvref_t<_Gen>::min(); } - _LIBCPP_HIDE_FROM_ABI - static constexpr auto max() { return __remove_cvref_t<_Gen>::max(); } + _LIBCPP_HIDE_FROM_ABI static constexpr auto min() { return __remove_cvref_t<_Gen>::min(); } + _LIBCPP_HIDE_FROM_ABI static constexpr auto max() { return __remove_cvref_t<_Gen>::max(); } - _LIBCPP_HIDE_FROM_ABI - constexpr explicit _ClassicGenAdaptor(_Gen& __g) : __gen_(__g) {} + _LIBCPP_HIDE_FROM_ABI constexpr explicit _ClassicGenAdaptor(_Gen& __g) : __gen_(__g) {} - _LIBCPP_HIDE_FROM_ABI - constexpr auto operator()() const { return __gen_(); } + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()() const { return __gen_(); } }; _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__algorithm/unique.h b/third_party/libcxx/__algorithm/unique.h index 1717a00c8..d59701459 100644 --- a/third_party/libcxx/__algorithm/unique.h +++ b/third_party/libcxx/__algorithm/unique.h @@ -21,12 +21,15 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD // unique template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 std::pair<_Iter, _Iter> +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 std::pair<_Iter, _Iter> __unique(_Iter __first, _Sent __last, _BinaryPredicate&& __pred) { __first = std::__adjacent_find(__first, __last, __pred); if (__first != __last) { @@ -43,17 +46,19 @@ __unique(_Iter __first, _Sent __last, _BinaryPredicate&& __pred) { } template -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator unique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) { return std::__unique<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __pred).first; } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator unique(_ForwardIterator __first, _ForwardIterator __last) { return std::unique(__first, __last, __equal_to()); } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_UNIQUE_H diff --git a/third_party/libcxx/__algorithm/unique_copy.h b/third_party/libcxx/__algorithm/unique_copy.h index 81fcd50f0..16ce80cab 100644 --- a/third_party/libcxx/__algorithm/unique_copy.h +++ b/third_party/libcxx/__algorithm/unique_copy.h @@ -23,6 +23,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD namespace __unique_copy_tags { @@ -119,4 +122,6 @@ unique_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __res _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_UNIQUE_COPY_H diff --git a/third_party/libcxx/__algorithm/unwrap_iter.h b/third_party/libcxx/__algorithm/unwrap_iter.h index c93b3443c..8cc0d22d4 100644 --- a/third_party/libcxx/__algorithm/unwrap_iter.h +++ b/third_party/libcxx/__algorithm/unwrap_iter.h @@ -13,7 +13,7 @@ #include <__iterator/iterator_traits.h> #include <__memory/pointer_traits.h> #include <__type_traits/enable_if.h> -#include <__type_traits/is_copy_constructible.h> +#include <__type_traits/is_constructible.h> #include <__utility/declval.h> #include <__utility/move.h> @@ -21,12 +21,14 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD // TODO: Change the name of __unwrap_iter_impl to something more appropriate // The job of __unwrap_iter is to remove iterator wrappers (like reverse_iterator or __wrap_iter), // to reduce the number of template instantiations and to enable pointer-based optimizations e.g. in std::copy. -// In debug mode, we don't do this. // // Some algorithms (e.g. std::copy, but not std::sort) need to convert an // "unwrapped" result back into the original iterator type. Doing that is the job of __rewrap_iter. @@ -38,7 +40,8 @@ struct __unwrap_iter_impl { static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iter __unwrap(_Iter __i) _NOEXCEPT { return __i; } }; -#ifndef _LIBCPP_ENABLE_DEBUG_MODE +// TODO(hardening): make sure that the following unwrapping doesn't unexpectedly turn hardened iterators into raw +// pointers. // It's a contiguous iterator, so we can use a raw pointer instead template @@ -54,13 +57,11 @@ struct __unwrap_iter_impl<_Iter, true> { } }; -#endif // !_LIBCPP_ENABLE_DEBUG_MODE - -template, - __enable_if_t::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -decltype(_Impl::__unwrap(std::declval<_Iter>())) __unwrap_iter(_Iter __i) _NOEXCEPT { +template , + __enable_if_t::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 decltype(_Impl::__unwrap(std::declval<_Iter>())) +__unwrap_iter(_Iter __i) _NOEXCEPT { return _Impl::__unwrap(__i); } @@ -79,4 +80,6 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _OrigIter __rewrap_iter(_OrigIter __orig _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_UNWRAP_ITER_H diff --git a/third_party/libcxx/__algorithm/unwrap_range.h b/third_party/libcxx/__algorithm/unwrap_range.h index 2c75c8f49..2d4b9bb55 100644 --- a/third_party/libcxx/__algorithm/unwrap_range.h +++ b/third_party/libcxx/__algorithm/unwrap_range.h @@ -22,6 +22,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD // __unwrap_range and __rewrap_range are used to unwrap ranges which may have different iterator and sentinel types. @@ -50,7 +53,7 @@ struct __unwrap_range_impl { } _LIBCPP_HIDE_FROM_ABI static constexpr auto __rewrap(const _Iter&, _Iter __iter) - requires (!(random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>)) + requires(!(random_access_iterator<_Iter> && sized_sentinel_for<_Sent, _Iter>)) { return __iter; } @@ -73,10 +76,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr auto __unwrap_range(_Iter __first, _Sent __last) return __unwrap_range_impl<_Iter, _Sent>::__unwrap(std::move(__first), std::move(__last)); } -template < - class _Sent, - class _Iter, - class _Unwrapped = decltype(std::__unwrap_range(std::declval<_Iter>(), std::declval<_Sent>()))> +template < class _Sent, class _Iter, class _Unwrapped> _LIBCPP_HIDE_FROM_ABI constexpr _Iter __rewrap_range(_Iter __orig_iter, _Unwrapped __iter) { return __unwrap_range_impl<_Iter, _Sent>::__rewrap(std::move(__orig_iter), std::move(__iter)); } @@ -86,7 +86,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR pair<_Unwrapped, _Unwrapped> __unwrap_ra return std::make_pair(std::__unwrap_iter(std::move(__first)), std::__unwrap_iter(std::move(__last))); } -template ()))> +template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iter __rewrap_range(_Iter __orig_iter, _Unwrapped __iter) { return std::__rewrap_iter(std::move(__orig_iter), std::move(__iter)); } @@ -94,4 +94,6 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Iter __rewrap_range(_Iter __orig_iter, _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_UNWRAP_RANGE_H diff --git a/third_party/libcxx/__algorithm/upper_bound.h b/third_party/libcxx/__algorithm/upper_bound.h index 96552ce1f..c39dec2e8 100644 --- a/third_party/libcxx/__algorithm/upper_bound.h +++ b/third_party/libcxx/__algorithm/upper_bound.h @@ -18,13 +18,16 @@ #include <__iterator/advance.h> #include <__iterator/distance.h> #include <__iterator/iterator_traits.h> -#include <__type_traits/is_copy_constructible.h> +#include <__type_traits/is_constructible.h> #include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template @@ -45,24 +48,21 @@ __upper_bound(_Iter __first, _Sent __last, const _Tp& __value, _Compare&& __comp } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { - static_assert(is_copy_constructible<_ForwardIterator>::value, - "Iterator has to be copy constructible"); + static_assert(is_copy_constructible<_ForwardIterator>::value, "Iterator has to be copy constructible"); return std::__upper_bound<_ClassicAlgPolicy>( std::move(__first), std::move(__last), __value, std::move(__comp), std::__identity()); } template -_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { - return std::upper_bound( - std::move(__first), - std::move(__last), - __value, - __less<_Tp, typename iterator_traits<_ForwardIterator>::value_type>()); + return std::upper_bound(std::move(__first), std::move(__last), __value, __less<>()); } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ALGORITHM_UPPER_BOUND_H diff --git a/third_party/libcxx/__assert b/third_party/libcxx/__assert index e20ee50b1..49769fb4d 100644 --- a/third_party/libcxx/__assert +++ b/third_party/libcxx/__assert @@ -10,40 +10,109 @@ #ifndef _LIBCPP___ASSERT #define _LIBCPP___ASSERT +#include <__assertion_handler> // Note: this include is generated by CMake and is potentially vendor-provided. #include <__config> -#include <__verbose_abort> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif -// Automatically enable assertions when the debug mode is enabled. -#if defined(_LIBCPP_ENABLE_DEBUG_MODE) -# ifndef _LIBCPP_ENABLE_ASSERTIONS -# define _LIBCPP_ENABLE_ASSERTIONS 1 -# endif -#endif +#define _LIBCPP_ASSERT(expression, message) \ + (__builtin_expect(static_cast(expression), 1) \ + ? (void)0 \ + : _LIBCPP_ASSERTION_HANDLER(__FILE__ ":" _LIBCPP_TOSTRING(__LINE__) ": assertion " _LIBCPP_TOSTRING( \ + expression) " failed: " message "\n")) -#ifndef _LIBCPP_ENABLE_ASSERTIONS -# define _LIBCPP_ENABLE_ASSERTIONS _LIBCPP_ENABLE_ASSERTIONS_DEFAULT -#endif - -#if _LIBCPP_ENABLE_ASSERTIONS != 0 && _LIBCPP_ENABLE_ASSERTIONS != 1 -# error "_LIBCPP_ENABLE_ASSERTIONS must be set to 0 or 1" -#endif - -#if _LIBCPP_ENABLE_ASSERTIONS -# define _LIBCPP_ASSERT(expression, message) \ - (__builtin_expect(static_cast(expression), 1) \ - ? (void)0 \ - : _LIBCPP_VERBOSE_ABORT( \ - "%s:%d: assertion %s failed: %s", __builtin_FILE(), __builtin_LINE(), #expression, message)) -#elif !defined(_LIBCPP_ASSERTIONS_DISABLE_ASSUME) && __has_builtin(__builtin_assume) -# define _LIBCPP_ASSERT(expression, message) \ +// TODO: __builtin_assume can currently inhibit optimizations. Until this has been fixed and we can add +// assumptions without a clear optimization intent, disable that to avoid worsening the code generation. +// See https://discourse.llvm.org/t/llvm-assume-blocks-optimization/71609 for a discussion. +#if 0 && __has_builtin(__builtin_assume) +# define _LIBCPP_ASSUME(expression) \ (_LIBCPP_DIAGNOSTIC_PUSH _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wassume") \ __builtin_assume(static_cast(expression)) _LIBCPP_DIAGNOSTIC_POP) #else -# define _LIBCPP_ASSERT(expression, message) ((void)0) +# define _LIBCPP_ASSUME(expression) ((void)0) #endif +// clang-format off +// Fast hardening mode checks. + +#if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_FAST + +// Enabled checks. +# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSERT(expression, message) +# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSERT(expression, message) +// Disabled checks. +// On most modern platforms, dereferencing a null pointer does not lead to an actual memory access. +# define _LIBCPP_ASSERT_NON_NULL(expression, message) _LIBCPP_ASSUME(expression) +// Overlapping ranges will make algorithms produce incorrect results but don't directly lead to a security +// vulnerability. +# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSUME(expression) +# define _LIBCPP_ASSERT_VALID_DEALLOCATION(expression, message) _LIBCPP_ASSUME(expression) +# define _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(expression, message) _LIBCPP_ASSUME(expression) +# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSUME(expression) +# define _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(expression, message) _LIBCPP_ASSUME(expression) +# define _LIBCPP_ASSERT_PEDANTIC(expression, message) _LIBCPP_ASSUME(expression) +# define _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(expression, message) _LIBCPP_ASSUME(expression) +# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSUME(expression) +# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSUME(expression) + +// Extensive hardening mode checks. + +#elif _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_EXTENSIVE + +// Enabled checks. +# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSERT(expression, message) +# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSERT(expression, message) +# define _LIBCPP_ASSERT_NON_NULL(expression, message) _LIBCPP_ASSERT(expression, message) +# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSERT(expression, message) +# define _LIBCPP_ASSERT_VALID_DEALLOCATION(expression, message) _LIBCPP_ASSERT(expression, message) +# define _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(expression, message) _LIBCPP_ASSERT(expression, message) +# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSERT(expression, message) +# define _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(expression, message) _LIBCPP_ASSERT(expression, message) +# define _LIBCPP_ASSERT_PEDANTIC(expression, message) _LIBCPP_ASSERT(expression, message) +# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSERT(expression, message) +// Disabled checks. +# define _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(expression, message) _LIBCPP_ASSUME(expression) +# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSUME(expression) + +// Debug hardening mode checks. + +#elif _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG + +// All checks enabled. +# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSERT(expression, message) +# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSERT(expression, message) +# define _LIBCPP_ASSERT_NON_NULL(expression, message) _LIBCPP_ASSERT(expression, message) +# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSERT(expression, message) +# define _LIBCPP_ASSERT_VALID_DEALLOCATION(expression, message) _LIBCPP_ASSERT(expression, message) +# define _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(expression, message) _LIBCPP_ASSERT(expression, message) +# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSERT(expression, message) +# define _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(expression, message) _LIBCPP_ASSERT(expression, message) +# define _LIBCPP_ASSERT_PEDANTIC(expression, message) _LIBCPP_ASSERT(expression, message) +# define _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(expression, message) _LIBCPP_ASSERT(expression, message) +# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSERT(expression, message) +# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSERT(expression, message) + +// Disable all checks if hardening is not enabled. + +#else + +// All checks disabled. +# define _LIBCPP_ASSERT_VALID_INPUT_RANGE(expression, message) _LIBCPP_ASSUME(expression) +# define _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(expression, message) _LIBCPP_ASSUME(expression) +# define _LIBCPP_ASSERT_NON_NULL(expression, message) _LIBCPP_ASSUME(expression) +# define _LIBCPP_ASSERT_NON_OVERLAPPING_RANGES(expression, message) _LIBCPP_ASSUME(expression) +# define _LIBCPP_ASSERT_VALID_DEALLOCATION(expression, message) _LIBCPP_ASSUME(expression) +# define _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(expression, message) _LIBCPP_ASSUME(expression) +# define _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(expression, message) _LIBCPP_ASSUME(expression) +# define _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(expression, message) _LIBCPP_ASSUME(expression) +# define _LIBCPP_ASSERT_PEDANTIC(expression, message) _LIBCPP_ASSUME(expression) +# define _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(expression, message) _LIBCPP_ASSUME(expression) +# define _LIBCPP_ASSERT_INTERNAL(expression, message) _LIBCPP_ASSUME(expression) +# define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message) _LIBCPP_ASSUME(expression) + +#endif // _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_FAST +// clang-format on + #endif // _LIBCPP___ASSERT diff --git a/third_party/libcxx/__assertion_handler b/third_party/libcxx/__assertion_handler new file mode 100644 index 000000000..8bc0553c0 --- /dev/null +++ b/third_party/libcxx/__assertion_handler @@ -0,0 +1,31 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ASSERTION_HANDLER +#define _LIBCPP___ASSERTION_HANDLER + +#include <__config> +#include <__verbose_abort> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG + +# define _LIBCPP_ASSERTION_HANDLER(message) _LIBCPP_VERBOSE_ABORT("%s", message) + +#else + +// TODO(hardening): use `__builtin_verbose_trap(message)` once that becomes available. +# define _LIBCPP_ASSERTION_HANDLER(message) ((void)message, __builtin_trap()) + +#endif // _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG + +#endif // _LIBCPP___ASSERTION_HANDLER diff --git a/third_party/libcxx/__atomic/aliases.h b/third_party/libcxx/__atomic/aliases.h index e2f9fae40..e27e09af6 100644 --- a/third_party/libcxx/__atomic/aliases.h +++ b/third_party/libcxx/__atomic/aliases.h @@ -15,9 +15,9 @@ #include <__atomic/is_always_lock_free.h> #include <__config> #include <__type_traits/conditional.h> +#include <__type_traits/make_unsigned.h> #include #include -#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -80,36 +80,30 @@ using atomic_ptrdiff_t = atomic; using atomic_intmax_t = atomic; using atomic_uintmax_t = atomic; -// atomic_*_lock_free : prefer the contention type most highly, then the largest lock-free type +// C++20 atomic_{signed,unsigned}_lock_free: prefer the contention type most highly, then the largest lock-free type +#if _LIBCPP_STD_VER >= 20 +# if ATOMIC_LLONG_LOCK_FREE == 2 +using __largest_lock_free_type = long long; +# elif ATOMIC_INT_LOCK_FREE == 2 +using __largest_lock_free_type = int; +# elif ATOMIC_SHORT_LOCK_FREE == 2 +using __largest_lock_free_type = short; +# elif ATOMIC_CHAR_LOCK_FREE == 2 +using __largest_lock_free_type = char; +# else +# define _LIBCPP_NO_LOCK_FREE_TYPES // There are no lockfree types (this can happen on unusual platforms) +# endif -#if _LIBCPP_STD_VER >= 17 -# define _LIBCPP_CONTENTION_LOCK_FREE ::std::__libcpp_is_always_lock_free<__cxx_contention_t>::__value -#else -# define _LIBCPP_CONTENTION_LOCK_FREE false -#endif +# ifndef _LIBCPP_NO_LOCK_FREE_TYPES +using __contention_t_or_largest = + __conditional_t<__libcpp_is_always_lock_free<__cxx_contention_t>::__value, + __cxx_contention_t, + __largest_lock_free_type>; -#if ATOMIC_LLONG_LOCK_FREE == 2 -using __libcpp_signed_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, long long>; -using __libcpp_unsigned_lock_free = - __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned long long>; -#elif ATOMIC_INT_LOCK_FREE == 2 -using __libcpp_signed_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, int>; -using __libcpp_unsigned_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned int>; -#elif ATOMIC_SHORT_LOCK_FREE == 2 -using __libcpp_signed_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, short>; -using __libcpp_unsigned_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned short>; -#elif ATOMIC_CHAR_LOCK_FREE == 2 -using __libcpp_signed_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, char>; -using __libcpp_unsigned_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned char>; -#else -// No signed/unsigned lock-free types -# define _LIBCPP_NO_LOCK_FREE_TYPES -#endif - -#if !defined(_LIBCPP_NO_LOCK_FREE_TYPES) -using atomic_signed_lock_free = atomic<__libcpp_signed_lock_free>; -using atomic_unsigned_lock_free = atomic<__libcpp_unsigned_lock_free>; -#endif +using atomic_signed_lock_free = atomic<__contention_t_or_largest>; +using atomic_unsigned_lock_free = atomic>; +# endif // !_LIBCPP_NO_LOCK_FREE_TYPES +#endif // C++20 _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__atomic/atomic.h b/third_party/libcxx/__atomic/atomic.h index 68df7f12c..bd3f659c2 100644 --- a/third_party/libcxx/__atomic/atomic.h +++ b/third_party/libcxx/__atomic/atomic.h @@ -14,11 +14,17 @@ #include <__atomic/cxx_atomic_impl.h> #include <__atomic/memory_order.h> #include <__config> +#include <__functional/operations.h> #include <__memory/addressof.h> +#include <__type_traits/is_floating_point.h> #include <__type_traits/is_function.h> #include <__type_traits/is_same.h> +#include <__type_traits/remove_const.h> #include <__type_traits/remove_pointer.h> +#include <__type_traits/remove_volatile.h> +#include <__utility/forward.h> #include +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -27,636 +33,588 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -struct atomic - : public __atomic_base<_Tp> -{ +struct atomic : public __atomic_base<_Tp> { using __base = __atomic_base<_Tp>; using value_type = _Tp; using difference_type = value_type; #if _LIBCPP_STD_VER >= 20 - _LIBCPP_HIDE_FROM_ABI - atomic() = default; + _LIBCPP_HIDE_FROM_ABI atomic() = default; #else - _LIBCPP_HIDE_FROM_ABI - atomic() _NOEXCEPT = default; + _LIBCPP_HIDE_FROM_ABI atomic() _NOEXCEPT = default; #endif - _LIBCPP_HIDE_FROM_ABI - _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {} - _LIBCPP_HIDE_FROM_ABI - _Tp operator=(_Tp __d) volatile _NOEXCEPT - {__base::store(__d); return __d;} - _LIBCPP_HIDE_FROM_ABI - _Tp operator=(_Tp __d) _NOEXCEPT - {__base::store(__d); return __d;} + _LIBCPP_HIDE_FROM_ABI _Tp operator=(_Tp __d) volatile _NOEXCEPT { + __base::store(__d); + return __d; + } + _LIBCPP_HIDE_FROM_ABI _Tp operator=(_Tp __d) _NOEXCEPT { + __base::store(__d); + return __d; + } - atomic& operator=(const atomic&) = delete; - atomic& operator=(const atomic&) volatile = delete; + atomic& operator=(const atomic&) = delete; + atomic& operator=(const atomic&) volatile = delete; }; // atomic template -struct atomic<_Tp*> - : public __atomic_base<_Tp*> -{ - using __base = __atomic_base<_Tp*>; - using value_type = _Tp*; - using difference_type = ptrdiff_t; +struct atomic<_Tp*> : public __atomic_base<_Tp*> { + using __base = __atomic_base<_Tp*>; + using value_type = _Tp*; + using difference_type = ptrdiff_t; - _LIBCPP_HIDE_FROM_ABI - atomic() _NOEXCEPT = default; + _LIBCPP_HIDE_FROM_ABI atomic() _NOEXCEPT = default; - _LIBCPP_HIDE_FROM_ABI - _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {} - _LIBCPP_HIDE_FROM_ABI - _Tp* operator=(_Tp* __d) volatile _NOEXCEPT - {__base::store(__d); return __d;} - _LIBCPP_HIDE_FROM_ABI - _Tp* operator=(_Tp* __d) _NOEXCEPT - {__base::store(__d); return __d;} + _LIBCPP_HIDE_FROM_ABI _Tp* operator=(_Tp* __d) volatile _NOEXCEPT { + __base::store(__d); + return __d; + } + _LIBCPP_HIDE_FROM_ABI _Tp* operator=(_Tp* __d) _NOEXCEPT { + __base::store(__d); + return __d; + } - _LIBCPP_HIDE_FROM_ABI - _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { - // __atomic_fetch_add accepts function pointers, guard against them. - static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); - return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m); - } + _LIBCPP_HIDE_FROM_ABI _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { + // __atomic_fetch_add accepts function pointers, guard against them. + static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); + return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m); + } - _LIBCPP_HIDE_FROM_ABI - _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { - // __atomic_fetch_add accepts function pointers, guard against them. - static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); - return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m); - } + _LIBCPP_HIDE_FROM_ABI _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { + // __atomic_fetch_add accepts function pointers, guard against them. + static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); + return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m); + } - _LIBCPP_HIDE_FROM_ABI - _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { - // __atomic_fetch_add accepts function pointers, guard against them. - static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); - return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m); - } + _LIBCPP_HIDE_FROM_ABI _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { + // __atomic_fetch_add accepts function pointers, guard against them. + static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); + return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m); + } - _LIBCPP_HIDE_FROM_ABI - _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { - // __atomic_fetch_add accepts function pointers, guard against them. - static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); - return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m); - } + _LIBCPP_HIDE_FROM_ABI _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { + // __atomic_fetch_add accepts function pointers, guard against them. + static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); + return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m); + } - _LIBCPP_HIDE_FROM_ABI - _Tp* operator++(int) volatile _NOEXCEPT {return fetch_add(1);} - _LIBCPP_HIDE_FROM_ABI - _Tp* operator++(int) _NOEXCEPT {return fetch_add(1);} - _LIBCPP_HIDE_FROM_ABI - _Tp* operator--(int) volatile _NOEXCEPT {return fetch_sub(1);} - _LIBCPP_HIDE_FROM_ABI - _Tp* operator--(int) _NOEXCEPT {return fetch_sub(1);} - _LIBCPP_HIDE_FROM_ABI - _Tp* operator++() volatile _NOEXCEPT {return fetch_add(1) + 1;} - _LIBCPP_HIDE_FROM_ABI - _Tp* operator++() _NOEXCEPT {return fetch_add(1) + 1;} - _LIBCPP_HIDE_FROM_ABI - _Tp* operator--() volatile _NOEXCEPT {return fetch_sub(1) - 1;} - _LIBCPP_HIDE_FROM_ABI - _Tp* operator--() _NOEXCEPT {return fetch_sub(1) - 1;} - _LIBCPP_HIDE_FROM_ABI - _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;} - _LIBCPP_HIDE_FROM_ABI - _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT {return fetch_add(__op) + __op;} - _LIBCPP_HIDE_FROM_ABI - _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;} - _LIBCPP_HIDE_FROM_ABI - _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT {return fetch_sub(__op) - __op;} + _LIBCPP_HIDE_FROM_ABI _Tp* operator++(int) volatile _NOEXCEPT { return fetch_add(1); } + _LIBCPP_HIDE_FROM_ABI _Tp* operator++(int) _NOEXCEPT { return fetch_add(1); } + _LIBCPP_HIDE_FROM_ABI _Tp* operator--(int) volatile _NOEXCEPT { return fetch_sub(1); } + _LIBCPP_HIDE_FROM_ABI _Tp* operator--(int) _NOEXCEPT { return fetch_sub(1); } + _LIBCPP_HIDE_FROM_ABI _Tp* operator++() volatile _NOEXCEPT { return fetch_add(1) + 1; } + _LIBCPP_HIDE_FROM_ABI _Tp* operator++() _NOEXCEPT { return fetch_add(1) + 1; } + _LIBCPP_HIDE_FROM_ABI _Tp* operator--() volatile _NOEXCEPT { return fetch_sub(1) - 1; } + _LIBCPP_HIDE_FROM_ABI _Tp* operator--() _NOEXCEPT { return fetch_sub(1) - 1; } + _LIBCPP_HIDE_FROM_ABI _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT { return fetch_add(__op) + __op; } + _LIBCPP_HIDE_FROM_ABI _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT { return fetch_add(__op) + __op; } + _LIBCPP_HIDE_FROM_ABI _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT { return fetch_sub(__op) - __op; } + _LIBCPP_HIDE_FROM_ABI _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT { return fetch_sub(__op) - __op; } - atomic& operator=(const atomic&) = delete; - atomic& operator=(const atomic&) volatile = delete; + atomic& operator=(const atomic&) = delete; + atomic& operator=(const atomic&) volatile = delete; }; +#if _LIBCPP_STD_VER >= 20 +template + requires is_floating_point_v<_Tp> +struct atomic<_Tp> : __atomic_base<_Tp> { +private: + _LIBCPP_HIDE_FROM_ABI static constexpr bool __is_fp80_long_double() { + // Only x87-fp80 long double has 64-bit mantissa + return __LDBL_MANT_DIG__ == 64 && std::is_same_v<_Tp, long double>; + } + + _LIBCPP_HIDE_FROM_ABI static constexpr bool __has_rmw_builtin() { +# ifndef _LIBCPP_COMPILER_CLANG_BASED + return false; +# else + // The builtin __cxx_atomic_fetch_add errors during compilation for + // long double on platforms with fp80 format. + // For more details, see + // lib/Sema/SemaChecking.cpp function IsAllowedValueType + // LLVM Parser does not allow atomicrmw with x86_fp80 type. + // if (ValType->isSpecificBuiltinType(BuiltinType::LongDouble) && + // &Context.getTargetInfo().getLongDoubleFormat() == + // &llvm::APFloat::x87DoubleExtended()) + // For more info + // https://github.com/llvm/llvm-project/issues/68602 + // https://reviews.llvm.org/D53965 + return !__is_fp80_long_double(); +# endif + } + + template + _LIBCPP_HIDE_FROM_ABI static _Tp + __rmw_op(_This&& __self, _Tp __operand, memory_order __m, _Operation __operation, _BuiltinOp __builtin_op) { + if constexpr (__has_rmw_builtin()) { + return __builtin_op(std::addressof(std::forward<_This>(__self).__a_), __operand, __m); + } else { + _Tp __old = __self.load(memory_order_relaxed); + _Tp __new = __operation(__old, __operand); + while (!__self.compare_exchange_weak(__old, __new, __m, memory_order_relaxed)) { +# ifdef _LIBCPP_COMPILER_CLANG_BASED + if constexpr (__is_fp80_long_double()) { + // https://github.com/llvm/llvm-project/issues/47978 + // clang bug: __old is not updated on failure for atomic::compare_exchange_weak + // Note __old = __self.load(memory_order_relaxed) will not work + std::__cxx_atomic_load_inplace(std::addressof(__self.__a_), &__old, memory_order_relaxed); + } +# endif + __new = __operation(__old, __operand); + } + return __old; + } + } + + template + _LIBCPP_HIDE_FROM_ABI static _Tp __fetch_add(_This&& __self, _Tp __operand, memory_order __m) { + auto __builtin_op = [](auto __a, auto __builtin_operand, auto __order) { + return std::__cxx_atomic_fetch_add(__a, __builtin_operand, __order); + }; + return __rmw_op(std::forward<_This>(__self), __operand, __m, std::plus<>{}, __builtin_op); + } + + template + _LIBCPP_HIDE_FROM_ABI static _Tp __fetch_sub(_This&& __self, _Tp __operand, memory_order __m) { + auto __builtin_op = [](auto __a, auto __builtin_operand, auto __order) { + return std::__cxx_atomic_fetch_sub(__a, __builtin_operand, __order); + }; + return __rmw_op(std::forward<_This>(__self), __operand, __m, std::minus<>{}, __builtin_op); + } + +public: + using __base = __atomic_base<_Tp>; + using value_type = _Tp; + using difference_type = value_type; + + _LIBCPP_HIDE_FROM_ABI constexpr atomic() noexcept = default; + _LIBCPP_HIDE_FROM_ABI constexpr atomic(_Tp __d) noexcept : __base(__d) {} + + atomic(const atomic&) = delete; + atomic& operator=(const atomic&) = delete; + atomic& operator=(const atomic&) volatile = delete; + + _LIBCPP_HIDE_FROM_ABI _Tp operator=(_Tp __d) volatile noexcept + requires __base::is_always_lock_free + { + __base::store(__d); + return __d; + } + _LIBCPP_HIDE_FROM_ABI _Tp operator=(_Tp __d) noexcept { + __base::store(__d); + return __d; + } + + _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile noexcept + requires __base::is_always_lock_free + { + return __fetch_add(*this, __op, __m); + } + + _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) noexcept { + return __fetch_add(*this, __op, __m); + } + + _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile noexcept + requires __base::is_always_lock_free + { + return __fetch_sub(*this, __op, __m); + } + + _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) noexcept { + return __fetch_sub(*this, __op, __m); + } + + _LIBCPP_HIDE_FROM_ABI _Tp operator+=(_Tp __op) volatile noexcept + requires __base::is_always_lock_free + { + return fetch_add(__op) + __op; + } + + _LIBCPP_HIDE_FROM_ABI _Tp operator+=(_Tp __op) noexcept { return fetch_add(__op) + __op; } + + _LIBCPP_HIDE_FROM_ABI _Tp operator-=(_Tp __op) volatile noexcept + requires __base::is_always_lock_free + { + return fetch_sub(__op) - __op; + } + + _LIBCPP_HIDE_FROM_ABI _Tp operator-=(_Tp __op) noexcept { return fetch_sub(__op) - __op; } +}; + +#endif // _LIBCPP_STD_VER >= 20 + // atomic_is_lock_free template -_LIBCPP_HIDE_FROM_ABI -bool -atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT -{ - return __o->is_lock_free(); +_LIBCPP_HIDE_FROM_ABI bool atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT { + return __o->is_lock_free(); } template -_LIBCPP_HIDE_FROM_ABI -bool -atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT -{ - return __o->is_lock_free(); +_LIBCPP_HIDE_FROM_ABI bool atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT { + return __o->is_lock_free(); } // atomic_init template -_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI -void -atomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT -{ - std::__cxx_atomic_init(std::addressof(__o->__a_), __d); +_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI void +atomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT { + std::__cxx_atomic_init(std::addressof(__o->__a_), __d); } template -_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI -void -atomic_init(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT -{ - std::__cxx_atomic_init(std::addressof(__o->__a_), __d); +_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI void +atomic_init(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT { + std::__cxx_atomic_init(std::addressof(__o->__a_), __d); } // atomic_store template -_LIBCPP_HIDE_FROM_ABI -void -atomic_store(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT -{ - __o->store(__d); +_LIBCPP_HIDE_FROM_ABI void atomic_store(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT { + __o->store(__d); } template -_LIBCPP_HIDE_FROM_ABI -void -atomic_store(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT -{ - __o->store(__d); +_LIBCPP_HIDE_FROM_ABI void atomic_store(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT { + __o->store(__d); } // atomic_store_explicit template -_LIBCPP_HIDE_FROM_ABI -void +_LIBCPP_HIDE_FROM_ABI void atomic_store_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT - _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) -{ - __o->store(__d, __m); + _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) { + __o->store(__d, __m); } template -_LIBCPP_HIDE_FROM_ABI -void +_LIBCPP_HIDE_FROM_ABI void atomic_store_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT - _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) -{ - __o->store(__d, __m); + _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) { + __o->store(__d, __m); } // atomic_load template -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT -{ - return __o->load(); +_LIBCPP_HIDE_FROM_ABI _Tp atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT { + return __o->load(); } template -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_load(const atomic<_Tp>* __o) _NOEXCEPT -{ - return __o->load(); +_LIBCPP_HIDE_FROM_ABI _Tp atomic_load(const atomic<_Tp>* __o) _NOEXCEPT { + return __o->load(); } // atomic_load_explicit template -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT - _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) -{ - return __o->load(__m); +_LIBCPP_HIDE_FROM_ABI _Tp atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT + _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) { + return __o->load(__m); } template -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT - _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) -{ - return __o->load(__m); +_LIBCPP_HIDE_FROM_ABI _Tp atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT + _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) { + return __o->load(__m); } // atomic_exchange template -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_exchange(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT -{ - return __o->exchange(__d); +_LIBCPP_HIDE_FROM_ABI _Tp atomic_exchange(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT { + return __o->exchange(__d); } template -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_exchange(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT -{ - return __o->exchange(__d); +_LIBCPP_HIDE_FROM_ABI _Tp atomic_exchange(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT { + return __o->exchange(__d); } // atomic_exchange_explicit template -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_exchange_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT -{ - return __o->exchange(__d, __m); +_LIBCPP_HIDE_FROM_ABI _Tp +atomic_exchange_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT { + return __o->exchange(__d, __m); } template -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_exchange_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT -{ - return __o->exchange(__d, __m); +_LIBCPP_HIDE_FROM_ABI _Tp +atomic_exchange_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT { + return __o->exchange(__d, __m); } // atomic_compare_exchange_weak template -_LIBCPP_HIDE_FROM_ABI -bool -atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT -{ - return __o->compare_exchange_weak(*__e, __d); +_LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_weak( + volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT { + return __o->compare_exchange_weak(*__e, __d); } template -_LIBCPP_HIDE_FROM_ABI -bool -atomic_compare_exchange_weak(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT -{ - return __o->compare_exchange_weak(*__e, __d); +_LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_weak( + atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT { + return __o->compare_exchange_weak(*__e, __d); } // atomic_compare_exchange_strong template -_LIBCPP_HIDE_FROM_ABI -bool -atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT -{ - return __o->compare_exchange_strong(*__e, __d); +_LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_strong( + volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT { + return __o->compare_exchange_strong(*__e, __d); } template -_LIBCPP_HIDE_FROM_ABI -bool -atomic_compare_exchange_strong(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT -{ - return __o->compare_exchange_strong(*__e, __d); +_LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_strong( + atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT { + return __o->compare_exchange_strong(*__e, __d); } // atomic_compare_exchange_weak_explicit template -_LIBCPP_HIDE_FROM_ABI -bool -atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, - typename atomic<_Tp>::value_type __d, - memory_order __s, memory_order __f) _NOEXCEPT - _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) -{ - return __o->compare_exchange_weak(*__e, __d, __s, __f); +_LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_weak_explicit( + volatile atomic<_Tp>* __o, + typename atomic<_Tp>::value_type* __e, + typename atomic<_Tp>::value_type __d, + memory_order __s, + memory_order __f) _NOEXCEPT _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { + return __o->compare_exchange_weak(*__e, __d, __s, __f); } template -_LIBCPP_HIDE_FROM_ABI -bool -atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d, - memory_order __s, memory_order __f) _NOEXCEPT - _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) -{ - return __o->compare_exchange_weak(*__e, __d, __s, __f); +_LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_weak_explicit( + atomic<_Tp>* __o, + typename atomic<_Tp>::value_type* __e, + typename atomic<_Tp>::value_type __d, + memory_order __s, + memory_order __f) _NOEXCEPT _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { + return __o->compare_exchange_weak(*__e, __d, __s, __f); } // atomic_compare_exchange_strong_explicit template -_LIBCPP_HIDE_FROM_ABI -bool -atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o, - typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d, - memory_order __s, memory_order __f) _NOEXCEPT - _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) -{ - return __o->compare_exchange_strong(*__e, __d, __s, __f); +_LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_strong_explicit( + volatile atomic<_Tp>* __o, + typename atomic<_Tp>::value_type* __e, + typename atomic<_Tp>::value_type __d, + memory_order __s, + memory_order __f) _NOEXCEPT _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { + return __o->compare_exchange_strong(*__e, __d, __s, __f); } template -_LIBCPP_HIDE_FROM_ABI -bool -atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, - typename atomic<_Tp>::value_type __d, - memory_order __s, memory_order __f) _NOEXCEPT - _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) -{ - return __o->compare_exchange_strong(*__e, __d, __s, __f); +_LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_strong_explicit( + atomic<_Tp>* __o, + typename atomic<_Tp>::value_type* __e, + typename atomic<_Tp>::value_type __d, + memory_order __s, + memory_order __f) _NOEXCEPT _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { + return __o->compare_exchange_strong(*__e, __d, __s, __f); } // atomic_wait template -_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI -void atomic_wait(const volatile atomic<_Tp>* __o, - typename atomic<_Tp>::value_type __v) _NOEXCEPT -{ - return __o->wait(__v); +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void +atomic_wait(const volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v) _NOEXCEPT { + return __o->wait(__v); } template -_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI -void atomic_wait(const atomic<_Tp>* __o, - typename atomic<_Tp>::value_type __v) _NOEXCEPT -{ - return __o->wait(__v); +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void +atomic_wait(const atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v) _NOEXCEPT { + return __o->wait(__v); } // atomic_wait_explicit template -_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI -void atomic_wait_explicit(const volatile atomic<_Tp>* __o, - typename atomic<_Tp>::value_type __v, - memory_order __m) _NOEXCEPT - _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) -{ - return __o->wait(__v, __m); +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void +atomic_wait_explicit(const volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v, memory_order __m) _NOEXCEPT + _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) { + return __o->wait(__v, __m); } template -_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI -void atomic_wait_explicit(const atomic<_Tp>* __o, - typename atomic<_Tp>::value_type __v, - memory_order __m) _NOEXCEPT - _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) -{ - return __o->wait(__v, __m); +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void +atomic_wait_explicit(const atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v, memory_order __m) _NOEXCEPT + _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) { + return __o->wait(__v, __m); } // atomic_notify_one template -_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI -void atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT -{ - __o->notify_one(); +_LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void +atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT { + __o->notify_one(); } template -_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI -void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT -{ - __o->notify_one(); +_LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void +atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT { + __o->notify_one(); } // atomic_notify_all template -_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI -void atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT -{ - __o->notify_all(); +_LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void +atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT { + __o->notify_all(); } template -_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI -void atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT -{ - __o->notify_all(); +_LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void +atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT { + __o->notify_all(); } // atomic_fetch_add template -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_fetch_add(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT -{ - return __o->fetch_add(__op); +_LIBCPP_HIDE_FROM_ABI _Tp +atomic_fetch_add(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT { + return __o->fetch_add(__op); } template -_LIBCPP_HIDE_FROM_ABI -_Tp -atomic_fetch_add(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT -{ - return __o->fetch_add(__op); +_LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_add(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT { + return __o->fetch_add(__op); } // atomic_fetch_add_explicit template -_LIBCPP_HIDE_FROM_ABI -_Tp atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT -{ - return __o->fetch_add(__op, __m); +_LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_add_explicit( + volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT { + return __o->fetch_add(__op, __m); } template -_LIBCPP_HIDE_FROM_ABI -_Tp atomic_fetch_add_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT -{ - return __o->fetch_add(__op, __m); +_LIBCPP_HIDE_FROM_ABI _Tp +atomic_fetch_add_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT { + return __o->fetch_add(__op, __m); } // atomic_fetch_sub template -_LIBCPP_HIDE_FROM_ABI -_Tp atomic_fetch_sub(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT -{ - return __o->fetch_sub(__op); +_LIBCPP_HIDE_FROM_ABI _Tp +atomic_fetch_sub(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT { + return __o->fetch_sub(__op); } template -_LIBCPP_HIDE_FROM_ABI -_Tp atomic_fetch_sub(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT -{ - return __o->fetch_sub(__op); +_LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_sub(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT { + return __o->fetch_sub(__op); } // atomic_fetch_sub_explicit template -_LIBCPP_HIDE_FROM_ABI -_Tp atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT -{ - return __o->fetch_sub(__op, __m); +_LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_sub_explicit( + volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT { + return __o->fetch_sub(__op, __m); } template -_LIBCPP_HIDE_FROM_ABI -_Tp atomic_fetch_sub_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT -{ - return __o->fetch_sub(__op, __m); +_LIBCPP_HIDE_FROM_ABI _Tp +atomic_fetch_sub_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT { + return __o->fetch_sub(__op, __m); } // atomic_fetch_and -template -_LIBCPP_HIDE_FROM_ABI -typename enable_if -< - is_integral<_Tp>::value && !is_same<_Tp, bool>::value, - _Tp ->::type -atomic_fetch_and(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT -{ - return __o->fetch_and(__op); +template ::value && !is_same<_Tp, bool>::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_and(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT { + return __o->fetch_and(__op); } -template -_LIBCPP_HIDE_FROM_ABI -typename enable_if -< - is_integral<_Tp>::value && !is_same<_Tp, bool>::value, - _Tp ->::type -atomic_fetch_and(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT -{ - return __o->fetch_and(__op); +template ::value && !is_same<_Tp, bool>::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_and(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT { + return __o->fetch_and(__op); } // atomic_fetch_and_explicit -template -_LIBCPP_HIDE_FROM_ABI -typename enable_if -< - is_integral<_Tp>::value && !is_same<_Tp, bool>::value, - _Tp ->::type -atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT -{ - return __o->fetch_and(__op, __m); +template ::value && !is_same<_Tp, bool>::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_and_explicit( + volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT { + return __o->fetch_and(__op, __m); } -template -_LIBCPP_HIDE_FROM_ABI -typename enable_if -< - is_integral<_Tp>::value && !is_same<_Tp, bool>::value, - _Tp ->::type -atomic_fetch_and_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT -{ - return __o->fetch_and(__op, __m); +template ::value && !is_same<_Tp, bool>::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI _Tp +atomic_fetch_and_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT { + return __o->fetch_and(__op, __m); } // atomic_fetch_or -template -_LIBCPP_HIDE_FROM_ABI -typename enable_if -< - is_integral<_Tp>::value && !is_same<_Tp, bool>::value, - _Tp ->::type -atomic_fetch_or(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT -{ - return __o->fetch_or(__op); +template ::value && !is_same<_Tp, bool>::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_or(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT { + return __o->fetch_or(__op); } -template -_LIBCPP_HIDE_FROM_ABI -typename enable_if -< - is_integral<_Tp>::value && !is_same<_Tp, bool>::value, - _Tp ->::type -atomic_fetch_or(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT -{ - return __o->fetch_or(__op); +template ::value && !is_same<_Tp, bool>::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_or(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT { + return __o->fetch_or(__op); } // atomic_fetch_or_explicit -template -_LIBCPP_HIDE_FROM_ABI -typename enable_if -< - is_integral<_Tp>::value && !is_same<_Tp, bool>::value, - _Tp ->::type -atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT -{ - return __o->fetch_or(__op, __m); +template ::value && !is_same<_Tp, bool>::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI _Tp +atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT { + return __o->fetch_or(__op, __m); } -template -_LIBCPP_HIDE_FROM_ABI -typename enable_if -< - is_integral<_Tp>::value && !is_same<_Tp, bool>::value, - _Tp ->::type -atomic_fetch_or_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT -{ - return __o->fetch_or(__op, __m); +template ::value && !is_same<_Tp, bool>::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI _Tp +atomic_fetch_or_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT { + return __o->fetch_or(__op, __m); } // atomic_fetch_xor -template -_LIBCPP_HIDE_FROM_ABI -typename enable_if -< - is_integral<_Tp>::value && !is_same<_Tp, bool>::value, - _Tp ->::type -atomic_fetch_xor(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT -{ - return __o->fetch_xor(__op); +template ::value && !is_same<_Tp, bool>::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_xor(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT { + return __o->fetch_xor(__op); } -template -_LIBCPP_HIDE_FROM_ABI -typename enable_if -< - is_integral<_Tp>::value && !is_same<_Tp, bool>::value, - _Tp ->::type -atomic_fetch_xor(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT -{ - return __o->fetch_xor(__op); +template ::value && !is_same<_Tp, bool>::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_xor(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT { + return __o->fetch_xor(__op); } // atomic_fetch_xor_explicit -template -_LIBCPP_HIDE_FROM_ABI -typename enable_if -< - is_integral<_Tp>::value && !is_same<_Tp, bool>::value, - _Tp ->::type -atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT -{ - return __o->fetch_xor(__op, __m); +template ::value && !is_same<_Tp, bool>::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_xor_explicit( + volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT { + return __o->fetch_xor(__op, __m); } -template -_LIBCPP_HIDE_FROM_ABI -typename enable_if -< - is_integral<_Tp>::value && !is_same<_Tp, bool>::value, - _Tp ->::type -atomic_fetch_xor_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT -{ - return __o->fetch_xor(__op, __m); +template ::value && !is_same<_Tp, bool>::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI _Tp +atomic_fetch_xor_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT { + return __o->fetch_xor(__op, __m); } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__atomic/atomic_base.h b/third_party/libcxx/__atomic/atomic_base.h index 87100ba5d..7e26434c9 100644 --- a/third_party/libcxx/__atomic/atomic_base.h +++ b/third_party/libcxx/__atomic/atomic_base.h @@ -14,11 +14,10 @@ #include <__atomic/cxx_atomic_impl.h> #include <__atomic/is_always_lock_free.h> #include <__atomic/memory_order.h> -#include <__availability> #include <__config> #include <__memory/addressof.h> #include <__type_traits/is_integral.h> -#include <__type_traits/is_nothrow_default_constructible.h> +#include <__type_traits/is_nothrow_constructible.h> #include <__type_traits/is_same.h> #include @@ -29,202 +28,192 @@ _LIBCPP_BEGIN_NAMESPACE_STD template ::value && !is_same<_Tp, bool>::value> -struct __atomic_base // false +struct __atomic_base // false { - mutable __cxx_atomic_impl<_Tp> __a_; + mutable __cxx_atomic_impl<_Tp> __a_; #if _LIBCPP_STD_VER >= 17 - static _LIBCPP_CONSTEXPR bool is_always_lock_free = __libcpp_is_always_lock_free<__cxx_atomic_impl<_Tp> >::__value; + static constexpr bool is_always_lock_free = __libcpp_is_always_lock_free<__cxx_atomic_impl<_Tp> >::__value; #endif - _LIBCPP_HIDE_FROM_ABI - bool is_lock_free() const volatile _NOEXCEPT - {return __cxx_atomic_is_lock_free(sizeof(_Tp));} - _LIBCPP_HIDE_FROM_ABI - bool is_lock_free() const _NOEXCEPT - {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();} - _LIBCPP_HIDE_FROM_ABI void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT - _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) { - std::__cxx_atomic_store(std::addressof(__a_), __d, __m); - } - _LIBCPP_HIDE_FROM_ABI void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT - _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) { - std::__cxx_atomic_store(std::addressof(__a_), __d, __m); - } - _LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT - _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) { - return std::__cxx_atomic_load(std::addressof(__a_), __m); - } - _LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT - _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) { - return std::__cxx_atomic_load(std::addressof(__a_), __m); - } - _LIBCPP_HIDE_FROM_ABI - operator _Tp() const volatile _NOEXCEPT {return load();} - _LIBCPP_HIDE_FROM_ABI - operator _Tp() const _NOEXCEPT {return load();} - _LIBCPP_HIDE_FROM_ABI _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { - return std::__cxx_atomic_exchange(std::addressof(__a_), __d, __m); - } - _LIBCPP_HIDE_FROM_ABI _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT { - return std::__cxx_atomic_exchange(std::addressof(__a_), __d, __m); - } - _LIBCPP_HIDE_FROM_ABI bool - compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) volatile _NOEXCEPT - _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { - return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __s, __f); - } - _LIBCPP_HIDE_FROM_ABI bool compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) _NOEXCEPT - _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { - return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __s, __f); - } - _LIBCPP_HIDE_FROM_ABI bool - compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) volatile _NOEXCEPT - _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { - return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __s, __f); - } - _LIBCPP_HIDE_FROM_ABI bool compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) _NOEXCEPT - _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { - return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __s, __f); - } - _LIBCPP_HIDE_FROM_ABI bool - compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { - return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __m, __m); - } - _LIBCPP_HIDE_FROM_ABI bool - compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT { - return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __m, __m); - } - _LIBCPP_HIDE_FROM_ABI bool - compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { - return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __m, __m); - } - _LIBCPP_HIDE_FROM_ABI bool - compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT { - return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __m, __m); - } + _LIBCPP_HIDE_FROM_ABI bool is_lock_free() const volatile _NOEXCEPT { + return __cxx_atomic_is_lock_free(sizeof(__cxx_atomic_impl<_Tp>)); + } + _LIBCPP_HIDE_FROM_ABI bool is_lock_free() const _NOEXCEPT { + return static_cast<__atomic_base const volatile*>(this)->is_lock_free(); + } + _LIBCPP_HIDE_FROM_ABI void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT + _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) { + std::__cxx_atomic_store(std::addressof(__a_), __d, __m); + } + _LIBCPP_HIDE_FROM_ABI void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT + _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) { + std::__cxx_atomic_store(std::addressof(__a_), __d, __m); + } + _LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT + _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) { + return std::__cxx_atomic_load(std::addressof(__a_), __m); + } + _LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT + _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) { + return std::__cxx_atomic_load(std::addressof(__a_), __m); + } + _LIBCPP_HIDE_FROM_ABI operator _Tp() const volatile _NOEXCEPT { return load(); } + _LIBCPP_HIDE_FROM_ABI operator _Tp() const _NOEXCEPT { return load(); } + _LIBCPP_HIDE_FROM_ABI _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { + return std::__cxx_atomic_exchange(std::addressof(__a_), __d, __m); + } + _LIBCPP_HIDE_FROM_ABI _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT { + return std::__cxx_atomic_exchange(std::addressof(__a_), __d, __m); + } + _LIBCPP_HIDE_FROM_ABI bool + compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) volatile _NOEXCEPT + _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { + return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __s, __f); + } + _LIBCPP_HIDE_FROM_ABI bool compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) _NOEXCEPT + _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { + return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __s, __f); + } + _LIBCPP_HIDE_FROM_ABI bool + compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) volatile _NOEXCEPT + _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { + return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __s, __f); + } + _LIBCPP_HIDE_FROM_ABI bool compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) _NOEXCEPT + _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) { + return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __s, __f); + } + _LIBCPP_HIDE_FROM_ABI bool + compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { + return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __m, __m); + } + _LIBCPP_HIDE_FROM_ABI bool + compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT { + return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __m, __m); + } + _LIBCPP_HIDE_FROM_ABI bool + compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { + return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __m, __m); + } + _LIBCPP_HIDE_FROM_ABI bool + compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT { + return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __m, __m); + } - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const - volatile _NOEXCEPT { - std::__cxx_atomic_wait(std::addressof(__a_), __v, __m); - } - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void - wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT { - std::__cxx_atomic_wait(std::addressof(__a_), __v, __m); - } - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT { - std::__cxx_atomic_notify_one(std::addressof(__a_)); - } - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT { - std::__cxx_atomic_notify_one(std::addressof(__a_)); - } - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT { - std::__cxx_atomic_notify_all(std::addressof(__a_)); - } - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT { - std::__cxx_atomic_notify_all(std::addressof(__a_)); - } + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const + volatile _NOEXCEPT { + std::__atomic_wait(*this, __v, __m); + } + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void + wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT { + std::__atomic_wait(*this, __v, __m); + } + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT { + std::__atomic_notify_one(*this); + } + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT { std::__atomic_notify_one(*this); } + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT { + std::__atomic_notify_all(*this); + } + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT { std::__atomic_notify_all(*this); } #if _LIBCPP_STD_VER >= 20 - _LIBCPP_HIDE_FROM_ABI constexpr - __atomic_base() noexcept(is_nothrow_default_constructible_v<_Tp>) : __a_(_Tp()) {} + _LIBCPP_HIDE_FROM_ABI constexpr __atomic_base() noexcept(is_nothrow_default_constructible_v<_Tp>) : __a_(_Tp()) {} #else - _LIBCPP_HIDE_FROM_ABI - __atomic_base() _NOEXCEPT = default; + _LIBCPP_HIDE_FROM_ABI __atomic_base() _NOEXCEPT = default; #endif - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR - __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {} - __atomic_base(const __atomic_base&) = delete; + __atomic_base(const __atomic_base&) = delete; }; -#if _LIBCPP_STD_VER >= 17 -template -_LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free; -#endif - // atomic template -struct __atomic_base<_Tp, true> - : public __atomic_base<_Tp, false> -{ - using __base = __atomic_base<_Tp, false>; +struct __atomic_base<_Tp, true> : public __atomic_base<_Tp, false> { + using __base = __atomic_base<_Tp, false>; - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - __atomic_base() _NOEXCEPT = default; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __atomic_base() _NOEXCEPT = default; - _LIBCPP_HIDE_FROM_ABI - _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {} - _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { - return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m); - } - _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { - return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m); - } - _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { - return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m); - } - _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { - return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m); - } - _LIBCPP_HIDE_FROM_ABI _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { - return std::__cxx_atomic_fetch_and(std::addressof(this->__a_), __op, __m); - } - _LIBCPP_HIDE_FROM_ABI _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { - return std::__cxx_atomic_fetch_and(std::addressof(this->__a_), __op, __m); - } - _LIBCPP_HIDE_FROM_ABI _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { - return std::__cxx_atomic_fetch_or(std::addressof(this->__a_), __op, __m); - } - _LIBCPP_HIDE_FROM_ABI _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { - return std::__cxx_atomic_fetch_or(std::addressof(this->__a_), __op, __m); - } - _LIBCPP_HIDE_FROM_ABI _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { - return std::__cxx_atomic_fetch_xor(std::addressof(this->__a_), __op, __m); - } - _LIBCPP_HIDE_FROM_ABI _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { - return std::__cxx_atomic_fetch_xor(std::addressof(this->__a_), __op, __m); - } + _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { + return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m); + } + _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { + return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m); + } + _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { + return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m); + } + _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { + return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m); + } + _LIBCPP_HIDE_FROM_ABI _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { + return std::__cxx_atomic_fetch_and(std::addressof(this->__a_), __op, __m); + } + _LIBCPP_HIDE_FROM_ABI _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { + return std::__cxx_atomic_fetch_and(std::addressof(this->__a_), __op, __m); + } + _LIBCPP_HIDE_FROM_ABI _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { + return std::__cxx_atomic_fetch_or(std::addressof(this->__a_), __op, __m); + } + _LIBCPP_HIDE_FROM_ABI _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { + return std::__cxx_atomic_fetch_or(std::addressof(this->__a_), __op, __m); + } + _LIBCPP_HIDE_FROM_ABI _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { + return std::__cxx_atomic_fetch_xor(std::addressof(this->__a_), __op, __m); + } + _LIBCPP_HIDE_FROM_ABI _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { + return std::__cxx_atomic_fetch_xor(std::addressof(this->__a_), __op, __m); + } - _LIBCPP_HIDE_FROM_ABI - _Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));} - _LIBCPP_HIDE_FROM_ABI - _Tp operator++(int) _NOEXCEPT {return fetch_add(_Tp(1));} - _LIBCPP_HIDE_FROM_ABI - _Tp operator--(int) volatile _NOEXCEPT {return fetch_sub(_Tp(1));} - _LIBCPP_HIDE_FROM_ABI - _Tp operator--(int) _NOEXCEPT {return fetch_sub(_Tp(1));} - _LIBCPP_HIDE_FROM_ABI - _Tp operator++() volatile _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);} - _LIBCPP_HIDE_FROM_ABI - _Tp operator++() _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);} - _LIBCPP_HIDE_FROM_ABI - _Tp operator--() volatile _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);} - _LIBCPP_HIDE_FROM_ABI - _Tp operator--() _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);} - _LIBCPP_HIDE_FROM_ABI - _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;} - _LIBCPP_HIDE_FROM_ABI - _Tp operator+=(_Tp __op) _NOEXCEPT {return fetch_add(__op) + __op;} - _LIBCPP_HIDE_FROM_ABI - _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;} - _LIBCPP_HIDE_FROM_ABI - _Tp operator-=(_Tp __op) _NOEXCEPT {return fetch_sub(__op) - __op;} - _LIBCPP_HIDE_FROM_ABI - _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;} - _LIBCPP_HIDE_FROM_ABI - _Tp operator&=(_Tp __op) _NOEXCEPT {return fetch_and(__op) & __op;} - _LIBCPP_HIDE_FROM_ABI - _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;} - _LIBCPP_HIDE_FROM_ABI - _Tp operator|=(_Tp __op) _NOEXCEPT {return fetch_or(__op) | __op;} - _LIBCPP_HIDE_FROM_ABI - _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;} - _LIBCPP_HIDE_FROM_ABI - _Tp operator^=(_Tp __op) _NOEXCEPT {return fetch_xor(__op) ^ __op;} + _LIBCPP_HIDE_FROM_ABI _Tp operator++(int) volatile _NOEXCEPT { return fetch_add(_Tp(1)); } + _LIBCPP_HIDE_FROM_ABI _Tp operator++(int) _NOEXCEPT { return fetch_add(_Tp(1)); } + _LIBCPP_HIDE_FROM_ABI _Tp operator--(int) volatile _NOEXCEPT { return fetch_sub(_Tp(1)); } + _LIBCPP_HIDE_FROM_ABI _Tp operator--(int) _NOEXCEPT { return fetch_sub(_Tp(1)); } + _LIBCPP_HIDE_FROM_ABI _Tp operator++() volatile _NOEXCEPT { return fetch_add(_Tp(1)) + _Tp(1); } + _LIBCPP_HIDE_FROM_ABI _Tp operator++() _NOEXCEPT { return fetch_add(_Tp(1)) + _Tp(1); } + _LIBCPP_HIDE_FROM_ABI _Tp operator--() volatile _NOEXCEPT { return fetch_sub(_Tp(1)) - _Tp(1); } + _LIBCPP_HIDE_FROM_ABI _Tp operator--() _NOEXCEPT { return fetch_sub(_Tp(1)) - _Tp(1); } + _LIBCPP_HIDE_FROM_ABI _Tp operator+=(_Tp __op) volatile _NOEXCEPT { return fetch_add(__op) + __op; } + _LIBCPP_HIDE_FROM_ABI _Tp operator+=(_Tp __op) _NOEXCEPT { return fetch_add(__op) + __op; } + _LIBCPP_HIDE_FROM_ABI _Tp operator-=(_Tp __op) volatile _NOEXCEPT { return fetch_sub(__op) - __op; } + _LIBCPP_HIDE_FROM_ABI _Tp operator-=(_Tp __op) _NOEXCEPT { return fetch_sub(__op) - __op; } + _LIBCPP_HIDE_FROM_ABI _Tp operator&=(_Tp __op) volatile _NOEXCEPT { return fetch_and(__op) & __op; } + _LIBCPP_HIDE_FROM_ABI _Tp operator&=(_Tp __op) _NOEXCEPT { return fetch_and(__op) & __op; } + _LIBCPP_HIDE_FROM_ABI _Tp operator|=(_Tp __op) volatile _NOEXCEPT { return fetch_or(__op) | __op; } + _LIBCPP_HIDE_FROM_ABI _Tp operator|=(_Tp __op) _NOEXCEPT { return fetch_or(__op) | __op; } + _LIBCPP_HIDE_FROM_ABI _Tp operator^=(_Tp __op) volatile _NOEXCEPT { return fetch_xor(__op) ^ __op; } + _LIBCPP_HIDE_FROM_ABI _Tp operator^=(_Tp __op) _NOEXCEPT { return fetch_xor(__op) ^ __op; } +}; + +// Here we need _IsIntegral because the default template argument is not enough +// e.g __atomic_base is __atomic_base, which inherits from +// __atomic_base and the caller of the wait function is +// __atomic_base. So specializing __atomic_base<_Tp> does not work +template +struct __atomic_waitable_traits<__atomic_base<_Tp, _IsIntegral> > { + static _LIBCPP_HIDE_FROM_ABI _Tp __atomic_load(const __atomic_base<_Tp, _IsIntegral>& __a, memory_order __order) { + return __a.load(__order); + } + + static _LIBCPP_HIDE_FROM_ABI _Tp + __atomic_load(const volatile __atomic_base<_Tp, _IsIntegral>& __this, memory_order __order) { + return __this.load(__order); + } + + static _LIBCPP_HIDE_FROM_ABI const __cxx_atomic_impl<_Tp>* + __atomic_contention_address(const __atomic_base<_Tp, _IsIntegral>& __a) { + return std::addressof(__a.__a_); + } + + static _LIBCPP_HIDE_FROM_ABI const volatile __cxx_atomic_impl<_Tp>* + __atomic_contention_address(const volatile __atomic_base<_Tp, _IsIntegral>& __this) { + return std::addressof(__this.__a_); + } }; _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__atomic/atomic_flag.h b/third_party/libcxx/__atomic/atomic_flag.h index edfa978f9..00b157cdf 100644 --- a/third_party/libcxx/__atomic/atomic_flag.h +++ b/third_party/libcxx/__atomic/atomic_flag.h @@ -15,7 +15,8 @@ #include <__atomic/memory_order.h> #include <__chrono/duration.h> #include <__config> -#include <__threading_support> +#include <__memory/addressof.h> +#include <__thread/support.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -24,205 +25,163 @@ _LIBCPP_BEGIN_NAMESPACE_STD -struct atomic_flag -{ - __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_; +struct atomic_flag { + __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_; - _LIBCPP_HIDE_FROM_ABI - bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT - {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);} - _LIBCPP_HIDE_FROM_ABI - bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT - {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);} + _LIBCPP_HIDE_FROM_ABI bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT { + return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m); + } + _LIBCPP_HIDE_FROM_ABI bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT { + return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m); + } - _LIBCPP_HIDE_FROM_ABI - bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT - {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);} - _LIBCPP_HIDE_FROM_ABI - bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT - {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);} - _LIBCPP_HIDE_FROM_ABI - void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT - {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);} - _LIBCPP_HIDE_FROM_ABI - void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT - {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);} + _LIBCPP_HIDE_FROM_ABI bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { + return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m); + } + _LIBCPP_HIDE_FROM_ABI bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT { + return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m); + } + _LIBCPP_HIDE_FROM_ABI void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { + __cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m); + } + _LIBCPP_HIDE_FROM_ABI void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT { + __cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m); + } - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI - void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT - {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);} - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI - void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT - {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);} - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI - void notify_one() volatile _NOEXCEPT - {__cxx_atomic_notify_one(&__a_);} - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI - void notify_one() _NOEXCEPT - {__cxx_atomic_notify_one(&__a_);} - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI - void notify_all() volatile _NOEXCEPT - {__cxx_atomic_notify_all(&__a_);} - _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI - void notify_all() _NOEXCEPT - {__cxx_atomic_notify_all(&__a_);} + _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void + wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT { + std::__atomic_wait(*this, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m); + } + _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void + wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT { + std::__atomic_wait(*this, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m); + } + _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT { + std::__atomic_notify_one(*this); + } + _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT { + std::__atomic_notify_one(*this); + } + _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT { + std::__atomic_notify_all(*this); + } + _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT { + std::__atomic_notify_all(*this); + } #if _LIBCPP_STD_VER >= 20 - _LIBCPP_HIDE_FROM_ABI constexpr - atomic_flag() _NOEXCEPT : __a_(false) {} + _LIBCPP_HIDE_FROM_ABI constexpr atomic_flag() _NOEXCEPT : __a_(false) {} #else - atomic_flag() _NOEXCEPT = default; + atomic_flag() _NOEXCEPT = default; #endif - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR - atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION - - atomic_flag(const atomic_flag&) = delete; - atomic_flag& operator=(const atomic_flag&) = delete; - atomic_flag& operator=(const atomic_flag&) volatile = delete; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION + atomic_flag(const atomic_flag&) = delete; + atomic_flag& operator=(const atomic_flag&) = delete; + atomic_flag& operator=(const atomic_flag&) volatile = delete; }; -inline _LIBCPP_HIDE_FROM_ABI -bool -atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT -{ - return __o->test(); +template <> +struct __atomic_waitable_traits { + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATOMIC_FLAG_TYPE __atomic_load(const atomic_flag& __a, memory_order __order) { + return std::__cxx_atomic_load(&__a.__a_, __order); + } + + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATOMIC_FLAG_TYPE + __atomic_load(const volatile atomic_flag& __a, memory_order __order) { + return std::__cxx_atomic_load(&__a.__a_, __order); + } + + static _LIBCPP_HIDE_FROM_ABI const __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE>* + __atomic_contention_address(const atomic_flag& __a) { + return std::addressof(__a.__a_); + } + + static _LIBCPP_HIDE_FROM_ABI const volatile __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE>* + __atomic_contention_address(const volatile atomic_flag& __a) { + return std::addressof(__a.__a_); + } +}; + +inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT { return __o->test(); } + +inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test(const atomic_flag* __o) _NOEXCEPT { return __o->test(); } + +inline _LIBCPP_HIDE_FROM_ABI bool +atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT { + return __o->test(__m); } -inline _LIBCPP_HIDE_FROM_ABI -bool -atomic_flag_test(const atomic_flag* __o) _NOEXCEPT -{ - return __o->test(); +inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT { + return __o->test(__m); } -inline _LIBCPP_HIDE_FROM_ABI -bool -atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT -{ - return __o->test(__m); +inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT { + return __o->test_and_set(); } -inline _LIBCPP_HIDE_FROM_ABI -bool -atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT -{ - return __o->test(__m); +inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT { return __o->test_and_set(); } + +inline _LIBCPP_HIDE_FROM_ABI bool +atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT { + return __o->test_and_set(__m); } -inline _LIBCPP_HIDE_FROM_ABI -bool -atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT -{ - return __o->test_and_set(); +inline _LIBCPP_HIDE_FROM_ABI bool atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT { + return __o->test_and_set(__m); } -inline _LIBCPP_HIDE_FROM_ABI -bool -atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT -{ - return __o->test_and_set(); +inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT { __o->clear(); } + +inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear(atomic_flag* __o) _NOEXCEPT { __o->clear(); } + +inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT { + __o->clear(__m); } -inline _LIBCPP_HIDE_FROM_ABI -bool -atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT -{ - return __o->test_and_set(__m); +inline _LIBCPP_HIDE_FROM_ABI void atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT { + __o->clear(__m); } -inline _LIBCPP_HIDE_FROM_ABI -bool -atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT -{ - return __o->test_and_set(__m); +inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void +atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT { + __o->wait(__v); } -inline _LIBCPP_HIDE_FROM_ABI -void -atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT -{ - __o->clear(); +inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void +atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT { + __o->wait(__v); } -inline _LIBCPP_HIDE_FROM_ABI -void -atomic_flag_clear(atomic_flag* __o) _NOEXCEPT -{ - __o->clear(); +inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void +atomic_flag_wait_explicit(const volatile atomic_flag* __o, bool __v, memory_order __m) _NOEXCEPT { + __o->wait(__v, __m); } -inline _LIBCPP_HIDE_FROM_ABI -void -atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT -{ - __o->clear(__m); +inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void +atomic_flag_wait_explicit(const atomic_flag* __o, bool __v, memory_order __m) _NOEXCEPT { + __o->wait(__v, __m); } -inline _LIBCPP_HIDE_FROM_ABI -void -atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT -{ - __o->clear(__m); +inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void +atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT { + __o->notify_one(); } -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC -void -atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT -{ - __o->wait(__v); +inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void +atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT { + __o->notify_one(); } -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC -void -atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT -{ - __o->wait(__v); +inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void +atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT { + __o->notify_all(); } -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC -void -atomic_flag_wait_explicit(const volatile atomic_flag* __o, - bool __v, memory_order __m) _NOEXCEPT -{ - __o->wait(__v, __m); -} - -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC -void -atomic_flag_wait_explicit(const atomic_flag* __o, - bool __v, memory_order __m) _NOEXCEPT -{ - __o->wait(__v, __m); -} - -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC -void -atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT -{ - __o->notify_one(); -} - -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC -void -atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT -{ - __o->notify_one(); -} - -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC -void -atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT -{ - __o->notify_all(); -} - -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC -void -atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT -{ - __o->notify_all(); +inline _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_SYNC void +atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT { + __o->notify_all(); } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__atomic/atomic_init.h b/third_party/libcxx/__atomic/atomic_init.h index 14310aee1..8e86ba31b 100644 --- a/third_party/libcxx/__atomic/atomic_init.h +++ b/third_party/libcxx/__atomic/atomic_init.h @@ -18,10 +18,8 @@ #define ATOMIC_FLAG_INIT {false} #define ATOMIC_VAR_INIT(__v) {__v} -#if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS) -# if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 1400 +#if _LIBCPP_STD_VER >= 20 && defined(_LIBCPP_COMPILER_CLANG_BASED) && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS) # pragma clang deprecated(ATOMIC_VAR_INIT) -# endif -#endif // _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS) +#endif #endif // _LIBCPP___ATOMIC_ATOMIC_INIT_H diff --git a/third_party/libcxx/__atomic/atomic_lock_free.h b/third_party/libcxx/__atomic/atomic_lock_free.h index d607569ed..0715439db 100644 --- a/third_party/libcxx/__atomic/atomic_lock_free.h +++ b/third_party/libcxx/__atomic/atomic_lock_free.h @@ -16,33 +16,33 @@ #endif #if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE) -# define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE -# define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE -#ifndef _LIBCPP_HAS_NO_CHAR8_T -# define ATOMIC_CHAR8_T_LOCK_FREE __CLANG_ATOMIC_CHAR8_T_LOCK_FREE -#endif -# define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE -# define ATOMIC_CHAR32_T_LOCK_FREE __CLANG_ATOMIC_CHAR32_T_LOCK_FREE -# define ATOMIC_WCHAR_T_LOCK_FREE __CLANG_ATOMIC_WCHAR_T_LOCK_FREE -# define ATOMIC_SHORT_LOCK_FREE __CLANG_ATOMIC_SHORT_LOCK_FREE -# define ATOMIC_INT_LOCK_FREE __CLANG_ATOMIC_INT_LOCK_FREE -# define ATOMIC_LONG_LOCK_FREE __CLANG_ATOMIC_LONG_LOCK_FREE -# define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE -# define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE +# define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE +# define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE +# ifndef _LIBCPP_HAS_NO_CHAR8_T +# define ATOMIC_CHAR8_T_LOCK_FREE __CLANG_ATOMIC_CHAR8_T_LOCK_FREE +# endif +# define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE +# define ATOMIC_CHAR32_T_LOCK_FREE __CLANG_ATOMIC_CHAR32_T_LOCK_FREE +# define ATOMIC_WCHAR_T_LOCK_FREE __CLANG_ATOMIC_WCHAR_T_LOCK_FREE +# define ATOMIC_SHORT_LOCK_FREE __CLANG_ATOMIC_SHORT_LOCK_FREE +# define ATOMIC_INT_LOCK_FREE __CLANG_ATOMIC_INT_LOCK_FREE +# define ATOMIC_LONG_LOCK_FREE __CLANG_ATOMIC_LONG_LOCK_FREE +# define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE +# define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE #elif defined(__GCC_ATOMIC_BOOL_LOCK_FREE) -# define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE -# define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE -#ifndef _LIBCPP_HAS_NO_CHAR8_T -# define ATOMIC_CHAR8_T_LOCK_FREE __GCC_ATOMIC_CHAR8_T_LOCK_FREE -#endif -# define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE -# define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE -# define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE -# define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE -# define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE -# define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE -# define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE -# define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE +# define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE +# define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE +# ifndef _LIBCPP_HAS_NO_CHAR8_T +# define ATOMIC_CHAR8_T_LOCK_FREE __GCC_ATOMIC_CHAR8_T_LOCK_FREE +# endif +# define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE +# define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE +# define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE +# define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE +# define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE +# define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE +# define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE +# define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE #endif #endif // _LIBCPP___ATOMIC_ATOMIC_LOCK_FREE_H diff --git a/third_party/libcxx/__atomic/atomic_ref.h b/third_party/libcxx/__atomic/atomic_ref.h new file mode 100644 index 000000000..156f19611 --- /dev/null +++ b/third_party/libcxx/__atomic/atomic_ref.h @@ -0,0 +1,360 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// Kokkos v. 4.0 +// Copyright (2022) National Technology & Engineering +// Solutions of Sandia, LLC (NTESS). +// +// Under the terms of Contract DE-NA0003525 with NTESS, +// the U.S. Government retains certain rights in this software. +// +//===---------------------------------------------------------------------===// + +#ifndef _LIBCPP___ATOMIC_ATOMIC_REF_H +#define _LIBCPP___ATOMIC_ATOMIC_REF_H + +#include <__assert> +#include <__atomic/atomic_sync.h> +#include <__atomic/check_memory_order.h> +#include <__atomic/to_gcc_order.h> +#include <__concepts/arithmetic.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__memory/addressof.h> +#include <__type_traits/has_unique_object_representation.h> +#include <__type_traits/is_trivially_copyable.h> +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER >= 20 + +template +struct __atomic_ref_base { +protected: + _Tp* __ptr_; + + _LIBCPP_HIDE_FROM_ABI __atomic_ref_base(_Tp& __obj) : __ptr_(std::addressof(__obj)) {} + +private: + _LIBCPP_HIDE_FROM_ABI static _Tp* __clear_padding(_Tp& __val) noexcept { + _Tp* __ptr = std::addressof(__val); +# if __has_builtin(__builtin_clear_padding) + __builtin_clear_padding(__ptr); +# endif + return __ptr; + } + + _LIBCPP_HIDE_FROM_ABI static bool __compare_exchange( + _Tp* __ptr, _Tp* __expected, _Tp* __desired, bool __is_weak, int __success, int __failure) noexcept { + if constexpr ( +# if __has_builtin(__builtin_clear_padding) + has_unique_object_representations_v<_Tp> || floating_point<_Tp> +# else + true // NOLINT(readability-simplify-boolean-expr) +# endif + ) { + return __atomic_compare_exchange(__ptr, __expected, __desired, __is_weak, __success, __failure); + } else { // _Tp has padding bits and __builtin_clear_padding is available + __clear_padding(*__desired); + _Tp __copy = *__expected; + __clear_padding(__copy); + // The algorithm we use here is basically to perform `__atomic_compare_exchange` on the + // values until it has either succeeded, or failed because the value representation of the + // objects involved was different. This is why we loop around __atomic_compare_exchange: + // we basically loop until its failure is caused by the value representation of the objects + // being different, not only their object representation. + while (true) { + _Tp __prev = __copy; + if (__atomic_compare_exchange(__ptr, std::addressof(__copy), __desired, __is_weak, __success, __failure)) { + return true; + } + _Tp __curr = __copy; + if (std::memcmp(__clear_padding(__prev), __clear_padding(__curr), sizeof(_Tp)) != 0) { + // Value representation without padding bits do not compare equal -> + // write the current content of *ptr into *expected + std::memcpy(__expected, std::addressof(__copy), sizeof(_Tp)); + return false; + } + } + } + } + + friend struct __atomic_waitable_traits<__atomic_ref_base<_Tp>>; + +public: + using value_type = _Tp; + + static constexpr size_t required_alignment = alignof(_Tp); + + // The __atomic_always_lock_free builtin takes into account the alignment of the pointer if provided, + // so we create a fake pointer with a suitable alignment when querying it. Note that we are guaranteed + // that the pointer is going to be aligned properly at runtime because that is a (checked) precondition + // of atomic_ref's constructor. + static constexpr bool is_always_lock_free = + __atomic_always_lock_free(sizeof(_Tp), reinterpret_cast(-required_alignment)); + + _LIBCPP_HIDE_FROM_ABI bool is_lock_free() const noexcept { return __atomic_is_lock_free(sizeof(_Tp), __ptr_); } + + _LIBCPP_HIDE_FROM_ABI void store(_Tp __desired, memory_order __order = memory_order::seq_cst) const noexcept + _LIBCPP_CHECK_STORE_MEMORY_ORDER(__order) { + _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN( + __order == memory_order::relaxed || __order == memory_order::release || __order == memory_order::seq_cst, + "atomic_ref: memory order argument to atomic store operation is invalid"); + __atomic_store(__ptr_, __clear_padding(__desired), std::__to_gcc_order(__order)); + } + + _LIBCPP_HIDE_FROM_ABI _Tp operator=(_Tp __desired) const noexcept { + store(__desired); + return __desired; + } + + _LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __order = memory_order::seq_cst) const noexcept + _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__order) { + _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN( + __order == memory_order::relaxed || __order == memory_order::consume || __order == memory_order::acquire || + __order == memory_order::seq_cst, + "atomic_ref: memory order argument to atomic load operation is invalid"); + alignas(_Tp) byte __mem[sizeof(_Tp)]; + auto* __ret = reinterpret_cast<_Tp*>(__mem); + __atomic_load(__ptr_, __ret, std::__to_gcc_order(__order)); + return *__ret; + } + + _LIBCPP_HIDE_FROM_ABI operator _Tp() const noexcept { return load(); } + + _LIBCPP_HIDE_FROM_ABI _Tp exchange(_Tp __desired, memory_order __order = memory_order::seq_cst) const noexcept { + alignas(_Tp) byte __mem[sizeof(_Tp)]; + auto* __ret = reinterpret_cast<_Tp*>(__mem); + __atomic_exchange(__ptr_, __clear_padding(__desired), __ret, std::__to_gcc_order(__order)); + return *__ret; + } + + _LIBCPP_HIDE_FROM_ABI bool + compare_exchange_weak(_Tp& __expected, _Tp __desired, memory_order __success, memory_order __failure) const noexcept + _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__success, __failure) { + _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN( + __failure == memory_order::relaxed || __failure == memory_order::consume || + __failure == memory_order::acquire || __failure == memory_order::seq_cst, + "atomic_ref: failure memory order argument to weak atomic compare-and-exchange operation is invalid"); + return __compare_exchange( + __ptr_, + std::addressof(__expected), + std::addressof(__desired), + true, + std::__to_gcc_order(__success), + std::__to_gcc_order(__failure)); + } + _LIBCPP_HIDE_FROM_ABI bool + compare_exchange_strong(_Tp& __expected, _Tp __desired, memory_order __success, memory_order __failure) const noexcept + _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__success, __failure) { + _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN( + __failure == memory_order::relaxed || __failure == memory_order::consume || + __failure == memory_order::acquire || __failure == memory_order::seq_cst, + "atomic_ref: failure memory order argument to strong atomic compare-and-exchange operation is invalid"); + return __compare_exchange( + __ptr_, + std::addressof(__expected), + std::addressof(__desired), + false, + std::__to_gcc_order(__success), + std::__to_gcc_order(__failure)); + } + + _LIBCPP_HIDE_FROM_ABI bool + compare_exchange_weak(_Tp& __expected, _Tp __desired, memory_order __order = memory_order::seq_cst) const noexcept { + return __compare_exchange( + __ptr_, + std::addressof(__expected), + std::addressof(__desired), + true, + std::__to_gcc_order(__order), + std::__to_gcc_failure_order(__order)); + } + _LIBCPP_HIDE_FROM_ABI bool + compare_exchange_strong(_Tp& __expected, _Tp __desired, memory_order __order = memory_order::seq_cst) const noexcept { + return __compare_exchange( + __ptr_, + std::addressof(__expected), + std::addressof(__desired), + false, + std::__to_gcc_order(__order), + std::__to_gcc_failure_order(__order)); + } + + _LIBCPP_HIDE_FROM_ABI void wait(_Tp __old, memory_order __order = memory_order::seq_cst) const noexcept + _LIBCPP_CHECK_WAIT_MEMORY_ORDER(__order) { + _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN( + __order == memory_order::relaxed || __order == memory_order::consume || __order == memory_order::acquire || + __order == memory_order::seq_cst, + "atomic_ref: memory order argument to atomic wait operation is invalid"); + std::__atomic_wait(*this, __old, __order); + } + _LIBCPP_HIDE_FROM_ABI void notify_one() const noexcept { std::__atomic_notify_one(*this); } + _LIBCPP_HIDE_FROM_ABI void notify_all() const noexcept { std::__atomic_notify_all(*this); } +}; + +template +struct __atomic_waitable_traits<__atomic_ref_base<_Tp>> { + static _LIBCPP_HIDE_FROM_ABI _Tp __atomic_load(const __atomic_ref_base<_Tp>& __a, memory_order __order) { + return __a.load(__order); + } + static _LIBCPP_HIDE_FROM_ABI const _Tp* __atomic_contention_address(const __atomic_ref_base<_Tp>& __a) { + return __a.__ptr_; + } +}; + +template +struct atomic_ref : public __atomic_ref_base<_Tp> { + static_assert(is_trivially_copyable_v<_Tp>, "std::atomic_ref requires that 'T' be a trivially copyable type"); + + using __base = __atomic_ref_base<_Tp>; + + _LIBCPP_HIDE_FROM_ABI explicit atomic_ref(_Tp& __obj) : __base(__obj) { + _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN( + reinterpret_cast(std::addressof(__obj)) % __base::required_alignment == 0, + "atomic_ref ctor: referenced object must be aligned to required_alignment"); + } + + _LIBCPP_HIDE_FROM_ABI atomic_ref(const atomic_ref&) noexcept = default; + + _LIBCPP_HIDE_FROM_ABI _Tp operator=(_Tp __desired) const noexcept { return __base::operator=(__desired); } + + atomic_ref& operator=(const atomic_ref&) = delete; +}; + +template + requires(std::integral<_Tp> && !std::same_as) +struct atomic_ref<_Tp> : public __atomic_ref_base<_Tp> { + using __base = __atomic_ref_base<_Tp>; + + using difference_type = __base::value_type; + + _LIBCPP_HIDE_FROM_ABI explicit atomic_ref(_Tp& __obj) : __base(__obj) { + _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN( + reinterpret_cast(std::addressof(__obj)) % __base::required_alignment == 0, + "atomic_ref ctor: referenced object must be aligned to required_alignment"); + } + + _LIBCPP_HIDE_FROM_ABI atomic_ref(const atomic_ref&) noexcept = default; + + _LIBCPP_HIDE_FROM_ABI _Tp operator=(_Tp __desired) const noexcept { return __base::operator=(__desired); } + + atomic_ref& operator=(const atomic_ref&) = delete; + + _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __arg, memory_order __order = memory_order_seq_cst) const noexcept { + return __atomic_fetch_add(this->__ptr_, __arg, std::__to_gcc_order(__order)); + } + _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __arg, memory_order __order = memory_order_seq_cst) const noexcept { + return __atomic_fetch_sub(this->__ptr_, __arg, std::__to_gcc_order(__order)); + } + _LIBCPP_HIDE_FROM_ABI _Tp fetch_and(_Tp __arg, memory_order __order = memory_order_seq_cst) const noexcept { + return __atomic_fetch_and(this->__ptr_, __arg, std::__to_gcc_order(__order)); + } + _LIBCPP_HIDE_FROM_ABI _Tp fetch_or(_Tp __arg, memory_order __order = memory_order_seq_cst) const noexcept { + return __atomic_fetch_or(this->__ptr_, __arg, std::__to_gcc_order(__order)); + } + _LIBCPP_HIDE_FROM_ABI _Tp fetch_xor(_Tp __arg, memory_order __order = memory_order_seq_cst) const noexcept { + return __atomic_fetch_xor(this->__ptr_, __arg, std::__to_gcc_order(__order)); + } + + _LIBCPP_HIDE_FROM_ABI _Tp operator++(int) const noexcept { return fetch_add(_Tp(1)); } + _LIBCPP_HIDE_FROM_ABI _Tp operator--(int) const noexcept { return fetch_sub(_Tp(1)); } + _LIBCPP_HIDE_FROM_ABI _Tp operator++() const noexcept { return fetch_add(_Tp(1)) + _Tp(1); } + _LIBCPP_HIDE_FROM_ABI _Tp operator--() const noexcept { return fetch_sub(_Tp(1)) - _Tp(1); } + _LIBCPP_HIDE_FROM_ABI _Tp operator+=(_Tp __arg) const noexcept { return fetch_add(__arg) + __arg; } + _LIBCPP_HIDE_FROM_ABI _Tp operator-=(_Tp __arg) const noexcept { return fetch_sub(__arg) - __arg; } + _LIBCPP_HIDE_FROM_ABI _Tp operator&=(_Tp __arg) const noexcept { return fetch_and(__arg) & __arg; } + _LIBCPP_HIDE_FROM_ABI _Tp operator|=(_Tp __arg) const noexcept { return fetch_or(__arg) | __arg; } + _LIBCPP_HIDE_FROM_ABI _Tp operator^=(_Tp __arg) const noexcept { return fetch_xor(__arg) ^ __arg; } +}; + +template + requires std::floating_point<_Tp> +struct atomic_ref<_Tp> : public __atomic_ref_base<_Tp> { + using __base = __atomic_ref_base<_Tp>; + + using difference_type = __base::value_type; + + _LIBCPP_HIDE_FROM_ABI explicit atomic_ref(_Tp& __obj) : __base(__obj) { + _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN( + reinterpret_cast(std::addressof(__obj)) % __base::required_alignment == 0, + "atomic_ref ctor: referenced object must be aligned to required_alignment"); + } + + _LIBCPP_HIDE_FROM_ABI atomic_ref(const atomic_ref&) noexcept = default; + + _LIBCPP_HIDE_FROM_ABI _Tp operator=(_Tp __desired) const noexcept { return __base::operator=(__desired); } + + atomic_ref& operator=(const atomic_ref&) = delete; + + _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __arg, memory_order __order = memory_order_seq_cst) const noexcept { + _Tp __old = this->load(memory_order_relaxed); + _Tp __new = __old + __arg; + while (!this->compare_exchange_weak(__old, __new, __order, memory_order_relaxed)) { + __new = __old + __arg; + } + return __old; + } + _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __arg, memory_order __order = memory_order_seq_cst) const noexcept { + _Tp __old = this->load(memory_order_relaxed); + _Tp __new = __old - __arg; + while (!this->compare_exchange_weak(__old, __new, __order, memory_order_relaxed)) { + __new = __old - __arg; + } + return __old; + } + + _LIBCPP_HIDE_FROM_ABI _Tp operator+=(_Tp __arg) const noexcept { return fetch_add(__arg) + __arg; } + _LIBCPP_HIDE_FROM_ABI _Tp operator-=(_Tp __arg) const noexcept { return fetch_sub(__arg) - __arg; } +}; + +template +struct atomic_ref<_Tp*> : public __atomic_ref_base<_Tp*> { + using __base = __atomic_ref_base<_Tp*>; + + using difference_type = ptrdiff_t; + + _LIBCPP_HIDE_FROM_ABI explicit atomic_ref(_Tp*& __ptr) : __base(__ptr) {} + + _LIBCPP_HIDE_FROM_ABI _Tp* operator=(_Tp* __desired) const noexcept { return __base::operator=(__desired); } + + atomic_ref& operator=(const atomic_ref&) = delete; + + _LIBCPP_HIDE_FROM_ABI _Tp* fetch_add(ptrdiff_t __arg, memory_order __order = memory_order_seq_cst) const noexcept { + return __atomic_fetch_add(this->__ptr_, __arg * sizeof(_Tp), std::__to_gcc_order(__order)); + } + _LIBCPP_HIDE_FROM_ABI _Tp* fetch_sub(ptrdiff_t __arg, memory_order __order = memory_order_seq_cst) const noexcept { + return __atomic_fetch_sub(this->__ptr_, __arg * sizeof(_Tp), std::__to_gcc_order(__order)); + } + + _LIBCPP_HIDE_FROM_ABI _Tp* operator++(int) const noexcept { return fetch_add(1); } + _LIBCPP_HIDE_FROM_ABI _Tp* operator--(int) const noexcept { return fetch_sub(1); } + _LIBCPP_HIDE_FROM_ABI _Tp* operator++() const noexcept { return fetch_add(1) + 1; } + _LIBCPP_HIDE_FROM_ABI _Tp* operator--() const noexcept { return fetch_sub(1) - 1; } + _LIBCPP_HIDE_FROM_ABI _Tp* operator+=(ptrdiff_t __arg) const noexcept { return fetch_add(__arg) + __arg; } + _LIBCPP_HIDE_FROM_ABI _Tp* operator-=(ptrdiff_t __arg) const noexcept { return fetch_sub(__arg) - __arg; } +}; + +_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(atomic_ref); + +#endif // _LIBCPP_STD_VER >= 20 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP__ATOMIC_ATOMIC_REF_H diff --git a/third_party/libcxx/__atomic/atomic_sync.h b/third_party/libcxx/__atomic/atomic_sync.h index d55450bb5..aaf81f587 100644 --- a/third_party/libcxx/__atomic/atomic_sync.h +++ b/third_party/libcxx/__atomic/atomic_sync.h @@ -12,13 +12,17 @@ #include <__atomic/contention_t.h> #include <__atomic/cxx_atomic_impl.h> #include <__atomic/memory_order.h> -#include <__availability> +#include <__atomic/to_gcc_order.h> #include <__chrono/duration.h> #include <__config> #include <__memory/addressof.h> #include <__thread/poll_with_backoff.h> -#include <__threading_support> +#include <__thread/support.h> +#include <__type_traits/conjunction.h> #include <__type_traits/decay.h> +#include <__type_traits/invoke.h> +#include <__type_traits/void_t.h> +#include <__utility/declval.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -27,84 +31,173 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#ifndef _LIBCPP_HAS_NO_THREADS +// The customisation points to enable the following functions: +// - __atomic_wait +// - __atomic_wait_unless +// - __atomic_notify_one +// - __atomic_notify_all +// Note that std::atomic::wait was back-ported to C++03 +// The below implementations look ugly to support C++03 +template +struct __atomic_waitable_traits { + template + static void __atomic_load(_AtomicWaitable&&, memory_order) = delete; -_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*); -_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*); -_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile*); -_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(void const volatile*, __cxx_contention_t); - -_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*); -_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*); -_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*); -_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(__cxx_atomic_contention_t const volatile*, __cxx_contention_t); - -template -struct __libcpp_atomic_wait_backoff_impl { - _Atp* __a; - _Fn __test_fn; - _LIBCPP_AVAILABILITY_SYNC - _LIBCPP_HIDE_FROM_ABI bool operator()(chrono::nanoseconds __elapsed) const - { - if(__elapsed > chrono::microseconds(64)) - { - auto const __monitor = std::__libcpp_atomic_monitor(__a); - if(__test_fn()) - return true; - std::__libcpp_atomic_wait(__a, __monitor); - } - else if(__elapsed > chrono::microseconds(4)) - __libcpp_thread_yield(); - else - {} // poll - return false; - } + template + static void __atomic_contention_address(_AtomicWaitable&&) = delete; }; -template -_LIBCPP_AVAILABILITY_SYNC -_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_wait(_Atp* __a, _Fn && __test_fn) -{ - __libcpp_atomic_wait_backoff_impl<_Atp, __decay_t<_Fn> > __backoff_fn = {__a, __test_fn}; - return std::__libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn); +template +struct __atomic_waitable : false_type {}; + +template +struct __atomic_waitable< _Tp, + __void_t >::__atomic_load( + std::declval(), std::declval())), + decltype(__atomic_waitable_traits<__decay_t<_Tp> >::__atomic_contention_address( + std::declval()))> > : true_type {}; + +template +struct __atomic_wait_poll_impl { + const _AtomicWaitable& __a_; + _Poll __poll_; + memory_order __order_; + + _LIBCPP_HIDE_FROM_ABI bool operator()() const { + auto __current_val = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__atomic_load(__a_, __order_); + return __poll_(__current_val); + } +}; + +#ifndef _LIBCPP_HAS_NO_THREADS + +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*) _NOEXCEPT; +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*) _NOEXCEPT; +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t +__libcpp_atomic_monitor(void const volatile*) _NOEXCEPT; +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void +__libcpp_atomic_wait(void const volatile*, __cxx_contention_t) _NOEXCEPT; + +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void +__cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*) _NOEXCEPT; +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void +__cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*) _NOEXCEPT; +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t +__libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*) _NOEXCEPT; +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void +__libcpp_atomic_wait(__cxx_atomic_contention_t const volatile*, __cxx_contention_t) _NOEXCEPT; + +template +struct __atomic_wait_backoff_impl { + const _AtomicWaitable& __a_; + _Poll __poll_; + memory_order __order_; + + using __waitable_traits = __atomic_waitable_traits<__decay_t<_AtomicWaitable> >; + + _LIBCPP_AVAILABILITY_SYNC + _LIBCPP_HIDE_FROM_ABI bool + __update_monitor_val_and_poll(__cxx_atomic_contention_t const volatile*, __cxx_contention_t& __monitor_val) const { + // In case the contention type happens to be __cxx_atomic_contention_t, i.e. __cxx_atomic_impl, + // the platform wait is directly monitoring the atomic value itself. + // `__poll_` takes the current value of the atomic as an in-out argument + // to potentially modify it. After it returns, `__monitor` has a value + // which can be safely waited on by `std::__libcpp_atomic_wait` without any + // ABA style issues. + __monitor_val = __waitable_traits::__atomic_load(__a_, __order_); + return __poll_(__monitor_val); + } + + _LIBCPP_AVAILABILITY_SYNC + _LIBCPP_HIDE_FROM_ABI bool + __update_monitor_val_and_poll(void const volatile* __contention_address, __cxx_contention_t& __monitor_val) const { + // In case the contention type is anything else, platform wait is monitoring a __cxx_atomic_contention_t + // from the global pool, the monitor comes from __libcpp_atomic_monitor + __monitor_val = std::__libcpp_atomic_monitor(__contention_address); + auto __current_val = __waitable_traits::__atomic_load(__a_, __order_); + return __poll_(__current_val); + } + + _LIBCPP_AVAILABILITY_SYNC + _LIBCPP_HIDE_FROM_ABI bool operator()(chrono::nanoseconds __elapsed) const { + if (__elapsed > chrono::microseconds(64)) { + auto __contention_address = __waitable_traits::__atomic_contention_address(__a_); + __cxx_contention_t __monitor_val; + if (__update_monitor_val_and_poll(__contention_address, __monitor_val)) + return true; + std::__libcpp_atomic_wait(__contention_address, __monitor_val); + } else if (__elapsed > chrono::microseconds(4)) + __libcpp_thread_yield(); + else { + } // poll + return false; + } +}; + +// The semantics of this function are similar to `atomic`'s +// `.wait(T old, std::memory_order order)`, but instead of having a hardcoded +// predicate (is the loaded value unequal to `old`?), the predicate function is +// specified as an argument. The loaded value is given as an in-out argument to +// the predicate. If the predicate function returns `true`, +// `__atomic_wait_unless` will return. If the predicate function returns +// `false`, it must set the argument to its current understanding of the atomic +// value. The predicate function must not return `false` spuriously. +template +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void +__atomic_wait_unless(const _AtomicWaitable& __a, _Poll&& __poll, memory_order __order) { + static_assert(__atomic_waitable<_AtomicWaitable>::value, ""); + __atomic_wait_poll_impl<_AtomicWaitable, __decay_t<_Poll> > __poll_impl = {__a, __poll, __order}; + __atomic_wait_backoff_impl<_AtomicWaitable, __decay_t<_Poll> > __backoff_fn = {__a, __poll, __order}; + std::__libcpp_thread_poll_with_backoff(__poll_impl, __backoff_fn); +} + +template +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void __atomic_notify_one(const _AtomicWaitable& __a) { + static_assert(__atomic_waitable<_AtomicWaitable>::value, ""); + std::__cxx_atomic_notify_one(__atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__atomic_contention_address(__a)); +} + +template +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void __atomic_notify_all(const _AtomicWaitable& __a) { + static_assert(__atomic_waitable<_AtomicWaitable>::value, ""); + std::__cxx_atomic_notify_all(__atomic_waitable_traits<__decay_t<_AtomicWaitable> >::__atomic_contention_address(__a)); } #else // _LIBCPP_HAS_NO_THREADS -template -_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_impl<_Tp> const volatile*) { } -template -_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_impl<_Tp> const volatile*) { } -template -_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_wait(_Atp*, _Fn && __test_fn) -{ - return std::__libcpp_thread_poll_with_backoff(__test_fn, __spinning_backoff_policy()); +template +_LIBCPP_HIDE_FROM_ABI void __atomic_wait_unless(const _AtomicWaitable& __a, _Poll&& __poll, memory_order __order) { + __atomic_wait_poll_impl<_AtomicWaitable, __decay_t<_Poll> > __poll_fn = {__a, __poll, __order}; + std::__libcpp_thread_poll_with_backoff(__poll_fn, __spinning_backoff_policy()); } +template +_LIBCPP_HIDE_FROM_ABI void __atomic_notify_one(const _AtomicWaitable&) {} + +template +_LIBCPP_HIDE_FROM_ABI void __atomic_notify_all(const _AtomicWaitable&) {} + #endif // _LIBCPP_HAS_NO_THREADS -template _LIBCPP_HIDE_FROM_ABI -bool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp const& __rhs) { - return std::memcmp(std::addressof(__lhs), std::addressof(__rhs), sizeof(_Tp)) == 0; +template +_LIBCPP_HIDE_FROM_ABI bool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp const& __rhs) { + return std::memcmp(std::addressof(__lhs), std::addressof(__rhs), sizeof(_Tp)) == 0; } -template -struct __cxx_atomic_wait_test_fn_impl { - _Atp* __a; - _Tp __val; - memory_order __order; - _LIBCPP_HIDE_FROM_ABI bool operator()() const - { - return !std::__cxx_nonatomic_compare_equal(std::__cxx_atomic_load(__a, __order), __val); - } +template +struct __atomic_compare_unequal_to { + _Tp __val_; + _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __arg) const { + return !std::__cxx_nonatomic_compare_equal(__arg, __val_); + } }; -template -_LIBCPP_AVAILABILITY_SYNC -_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_wait(_Atp* __a, _Tp const __val, memory_order __order) -{ - __cxx_atomic_wait_test_fn_impl<_Atp, _Tp> __test_fn = {__a, __val, __order}; - return std::__cxx_atomic_wait(__a, __test_fn); +template +_LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void +__atomic_wait(_AtomicWaitable& __a, _Up __val, memory_order __order) { + static_assert(__atomic_waitable<_AtomicWaitable>::value, ""); + __atomic_compare_unequal_to<_Up> __nonatomic_equal = {__val}; + std::__atomic_wait_unless(__a, __nonatomic_equal, __order); } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__atomic/check_memory_order.h b/third_party/libcxx/__atomic/check_memory_order.h index d74431212..536f764a6 100644 --- a/third_party/libcxx/__atomic/check_memory_order.h +++ b/third_party/libcxx/__atomic/check_memory_order.h @@ -15,20 +15,20 @@ # pragma GCC system_header #endif -#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \ - _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \ - __m == memory_order_acquire || \ - __m == memory_order_acq_rel, \ - "memory order argument to atomic operation is invalid") +#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \ + _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || __m == memory_order_acquire || __m == memory_order_acq_rel, \ + "memory order argument to atomic operation is invalid") -#define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \ - _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || \ - __m == memory_order_acq_rel, \ - "memory order argument to atomic operation is invalid") +#define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \ + _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || __m == memory_order_acq_rel, \ + "memory order argument to atomic operation is invalid") -#define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \ - _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || \ - __f == memory_order_acq_rel, \ - "memory order argument to atomic operation is invalid") +#define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \ + _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || __f == memory_order_acq_rel, \ + "memory order argument to atomic operation is invalid") + +#define _LIBCPP_CHECK_WAIT_MEMORY_ORDER(__m) \ + _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || __m == memory_order_acq_rel, \ + "memory order argument to atomic operation is invalid") #endif // _LIBCPP___ATOMIC_CHECK_MEMORY_ORDER_H diff --git a/third_party/libcxx/__atomic/contention_t.h b/third_party/libcxx/__atomic/contention_t.h index 1d8d02430..65890f338 100644 --- a/third_party/libcxx/__atomic/contention_t.h +++ b/third_party/libcxx/__atomic/contention_t.h @@ -20,9 +20,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if defined(__linux__) || (defined(_AIX) && !defined(__64BIT__)) - using __cxx_contention_t = int32_t; +using __cxx_contention_t = int32_t; #else - using __cxx_contention_t = int64_t; +using __cxx_contention_t = int64_t; #endif // __linux__ || (_AIX && !__64BIT__) using __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>; diff --git a/third_party/libcxx/__atomic/cxx_atomic_impl.h b/third_party/libcxx/__atomic/cxx_atomic_impl.h index 167cee7f0..18e88aa97 100644 --- a/third_party/libcxx/__atomic/cxx_atomic_impl.h +++ b/third_party/libcxx/__atomic/cxx_atomic_impl.h @@ -9,16 +9,14 @@ #ifndef _LIBCPP___ATOMIC_CXX_ATOMIC_IMPL_H #define _LIBCPP___ATOMIC_CXX_ATOMIC_IMPL_H -#include <__atomic/is_always_lock_free.h> #include <__atomic/memory_order.h> +#include <__atomic/to_gcc_order.h> #include <__config> #include <__memory/addressof.h> -#include <__type_traits/conditional.h> #include <__type_traits/is_assignable.h> #include <__type_traits/is_trivially_copyable.h> #include <__type_traits/remove_const.h> #include -#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -26,122 +24,95 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) || \ - defined(_LIBCPP_ATOMIC_ONLY_USE_BUILTINS) +#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) // [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because // the default operator= in an object is not volatile, a byte-by-byte copy // is required. -template _LIBCPP_HIDE_FROM_ABI -typename enable_if::value>::type -__cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) { +template ::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) { __a_value = __val; } -template _LIBCPP_HIDE_FROM_ABI -typename enable_if::value>::type -__cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) { +template ::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) { volatile char* __to = reinterpret_cast(std::addressof(__a_value)); - volatile char* __end = __to + sizeof(_Tp); + volatile char* __end = __to + sizeof(_Tp); volatile const char* __from = reinterpret_cast(std::addressof(__val)); while (__to != __end) *__to++ = *__from++; } -#endif - -#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) - template struct __cxx_atomic_base_impl { - _LIBCPP_HIDE_FROM_ABI -#ifndef _LIBCPP_CXX03_LANG - __cxx_atomic_base_impl() _NOEXCEPT = default; -#else - __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {} -#endif // _LIBCPP_CXX03_LANG - _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT - : __a_value(value) {} +# ifndef _LIBCPP_CXX03_LANG + __cxx_atomic_base_impl() _NOEXCEPT = default; +# else + __cxx_atomic_base_impl() _NOEXCEPT : __a_value() { + } +# endif // _LIBCPP_CXX03_LANG + _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT : __a_value(value) {} _Tp __a_value; }; -_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) { - // Avoid switch statement to make this a constexpr. - return __order == memory_order_relaxed ? __ATOMIC_RELAXED: - (__order == memory_order_acquire ? __ATOMIC_ACQUIRE: - (__order == memory_order_release ? __ATOMIC_RELEASE: - (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST: - (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL: - __ATOMIC_CONSUME)))); -} - -_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) { - // Avoid switch statement to make this a constexpr. - return __order == memory_order_relaxed ? __ATOMIC_RELAXED: - (__order == memory_order_acquire ? __ATOMIC_ACQUIRE: - (__order == memory_order_release ? __ATOMIC_RELAXED: - (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST: - (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE: - __ATOMIC_CONSUME)))); -} - template -_LIBCPP_HIDE_FROM_ABI -void __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val) { +_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val) { __cxx_atomic_assign_volatile(__a->__a_value, __val); } template -_LIBCPP_HIDE_FROM_ABI -void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) { +_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) { __a->__a_value = __val; } -_LIBCPP_HIDE_FROM_ABI inline -void __cxx_atomic_thread_fence(memory_order __order) { +_LIBCPP_HIDE_FROM_ABI inline void __cxx_atomic_thread_fence(memory_order __order) { __atomic_thread_fence(__to_gcc_order(__order)); } -_LIBCPP_HIDE_FROM_ABI inline -void __cxx_atomic_signal_fence(memory_order __order) { +_LIBCPP_HIDE_FROM_ABI inline void __cxx_atomic_signal_fence(memory_order __order) { __atomic_signal_fence(__to_gcc_order(__order)); } template -_LIBCPP_HIDE_FROM_ABI -void __cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val, - memory_order __order) { +_LIBCPP_HIDE_FROM_ABI void +__cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val, memory_order __order) { __atomic_store(std::addressof(__a->__a_value), std::addressof(__val), __to_gcc_order(__order)); } template -_LIBCPP_HIDE_FROM_ABI -void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val, - memory_order __order) { +_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val, memory_order __order) { __atomic_store(std::addressof(__a->__a_value), std::addressof(__val), __to_gcc_order(__order)); } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a, - memory_order __order) { +_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) { _Tp __ret; __atomic_load(std::addressof(__a->__a_value), std::addressof(__ret), __to_gcc_order(__order)); return __ret; } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) { +_LIBCPP_HIDE_FROM_ABI void +__cxx_atomic_load_inplace(const volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __dst, memory_order __order) { + __atomic_load(std::addressof(__a->__a_value), __dst, __to_gcc_order(__order)); +} + +template +_LIBCPP_HIDE_FROM_ABI void +__cxx_atomic_load_inplace(const __cxx_atomic_base_impl<_Tp>* __a, _Tp* __dst, memory_order __order) { + __atomic_load(std::addressof(__a->__a_value), __dst, __to_gcc_order(__order)); +} + +template +_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) { _Tp __ret; __atomic_load(std::addressof(__a->__a_value), std::addressof(__ret), __to_gcc_order(__order)); return __ret; } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a, - _Tp __value, memory_order __order) { +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __value, memory_order __order) { _Tp __ret; __atomic_exchange( std::addressof(__a->__a_value), std::addressof(__value), std::addressof(__ret), __to_gcc_order(__order)); @@ -149,9 +120,7 @@ _Tp __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a, } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value, - memory_order __order) { +_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value, memory_order __order) { _Tp __ret; __atomic_exchange( std::addressof(__a->__a_value), std::addressof(__value), std::addressof(__ret), __to_gcc_order(__order)); @@ -159,23 +128,11 @@ _Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value, } template -_LIBCPP_HIDE_FROM_ABI -bool __cxx_atomic_compare_exchange_strong( - volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, - memory_order __success, memory_order __failure) { - return __atomic_compare_exchange( - std::addressof(__a->__a_value), - __expected, - std::addressof(__value), - false, - __to_gcc_order(__success), - __to_gcc_failure_order(__failure)); -} - -template -_LIBCPP_HIDE_FROM_ABI -bool __cxx_atomic_compare_exchange_strong( - __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, +_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_strong( + volatile __cxx_atomic_base_impl<_Tp>* __a, + _Tp* __expected, + _Tp __value, + memory_order __success, memory_order __failure) { return __atomic_compare_exchange( std::addressof(__a->__a_value), @@ -187,23 +144,23 @@ bool __cxx_atomic_compare_exchange_strong( } template -_LIBCPP_HIDE_FROM_ABI -bool __cxx_atomic_compare_exchange_weak( - volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, - memory_order __success, memory_order __failure) { +_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_strong( + __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) { return __atomic_compare_exchange( std::addressof(__a->__a_value), __expected, std::addressof(__value), - true, + false, __to_gcc_order(__success), __to_gcc_failure_order(__failure)); } template -_LIBCPP_HIDE_FROM_ABI -bool __cxx_atomic_compare_exchange_weak( - __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, +_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_weak( + volatile __cxx_atomic_base_impl<_Tp>* __a, + _Tp* __expected, + _Tp __value, + memory_order __success, memory_order __failure) { return __atomic_compare_exchange( std::addressof(__a->__a_value), @@ -215,178 +172,194 @@ bool __cxx_atomic_compare_exchange_weak( } template -struct __skip_amt { enum {value = 1}; }; +_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_weak( + __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) { + return __atomic_compare_exchange( + std::addressof(__a->__a_value), + __expected, + std::addressof(__value), + true, + __to_gcc_order(__success), + __to_gcc_failure_order(__failure)); +} template -struct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; }; +struct __skip_amt { + enum { value = 1 }; +}; + +template +struct __skip_amt<_Tp*> { + enum { value = sizeof(_Tp) }; +}; // FIXME: Haven't figured out what the spec says about using arrays with // atomic_fetch_add. Force a failure rather than creating bad behavior. template -struct __skip_amt<_Tp[]> { }; +struct __skip_amt<_Tp[]> {}; template -struct __skip_amt<_Tp[n]> { }; +struct __skip_amt<_Tp[n]> {}; template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a, - _Td __delta, memory_order __order) { +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a, _Td __delta, memory_order __order) { return __atomic_fetch_add(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order)); } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta, - memory_order __order) { +_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta, memory_order __order) { return __atomic_fetch_add(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order)); } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a, - _Td __delta, memory_order __order) { +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a, _Td __delta, memory_order __order) { return __atomic_fetch_sub(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order)); } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta, - memory_order __order) { +_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta, memory_order __order) { return __atomic_fetch_sub(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order)); } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a, - _Tp __pattern, memory_order __order) { +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) { return __atomic_fetch_and(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order)); } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a, - _Tp __pattern, memory_order __order) { +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) { return __atomic_fetch_and(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order)); } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a, - _Tp __pattern, memory_order __order) { +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) { return __atomic_fetch_or(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order)); } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, - memory_order __order) { +_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) { return __atomic_fetch_or(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order)); } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a, - _Tp __pattern, memory_order __order) { +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) { return __atomic_fetch_xor(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order)); } template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, - memory_order __order) { +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) { return __atomic_fetch_xor(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order)); } -#define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0) +# define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0) #elif defined(_LIBCPP_HAS_C_ATOMIC_IMP) template struct __cxx_atomic_base_impl { - _LIBCPP_HIDE_FROM_ABI -#ifndef _LIBCPP_CXX03_LANG - __cxx_atomic_base_impl() _NOEXCEPT = default; -#else - __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {} -#endif // _LIBCPP_CXX03_LANG - _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp __value) _NOEXCEPT - : __a_value(__value) {} +# ifndef _LIBCPP_CXX03_LANG + __cxx_atomic_base_impl() _NOEXCEPT = default; +# else + __cxx_atomic_base_impl() _NOEXCEPT : __a_value() { + } +# endif // _LIBCPP_CXX03_LANG + _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp __value) _NOEXCEPT : __a_value(__value) {} _LIBCPP_DISABLE_EXTENSION_WARNING _Atomic(_Tp) __a_value; }; -#define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s) +# define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s) -_LIBCPP_HIDE_FROM_ABI inline -void __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT { - __c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order)); +_LIBCPP_HIDE_FROM_ABI inline void __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT { + __c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order)); } -_LIBCPP_HIDE_FROM_ABI inline -void __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT { - __c11_atomic_signal_fence(static_cast<__memory_order_underlying_t>(__order)); +_LIBCPP_HIDE_FROM_ABI inline void __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT { + __c11_atomic_signal_fence(static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT { - __c11_atomic_init(std::addressof(__a->__a_value), __val); +template +_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT { + __c11_atomic_init(std::addressof(__a->__a_value), __val); } -template -_LIBCPP_HIDE_FROM_ABI -void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val) _NOEXCEPT { - __c11_atomic_init(std::addressof(__a->__a_value), __val); +template +_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) _NOEXCEPT { + __c11_atomic_init(std::addressof(__a->__a_value), __val); } -template -_LIBCPP_HIDE_FROM_ABI -void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT { - __c11_atomic_store(std::addressof(__a->__a_value), __val, static_cast<__memory_order_underlying_t>(__order)); +template +_LIBCPP_HIDE_FROM_ABI void +__cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT { + __c11_atomic_store(std::addressof(__a->__a_value), __val, static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val, memory_order __order) _NOEXCEPT { - __c11_atomic_store(std::addressof(__a->__a_value), __val, static_cast<__memory_order_underlying_t>(__order)); +template +_LIBCPP_HIDE_FROM_ABI void +__cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val, memory_order __order) _NOEXCEPT { + __c11_atomic_store(std::addressof(__a->__a_value), __val, static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT { - using __ptr_type = __remove_const_t__a_value)>*; - return __c11_atomic_load( - const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order)); +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT { + using __ptr_type = __remove_const_t__a_value)>*; + return __c11_atomic_load( + const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT { - using __ptr_type = __remove_const_t__a_value)>*; - return __c11_atomic_load( - const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order)); +template +_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT { + using __ptr_type = __remove_const_t__a_value)>*; + return __c11_atomic_load( + const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT { - return __c11_atomic_exchange( - std::addressof(__a->__a_value), __value, static_cast<__memory_order_underlying_t>(__order)); +template +_LIBCPP_HIDE_FROM_ABI void +__cxx_atomic_load_inplace(__cxx_atomic_base_impl<_Tp> const volatile* __a, _Tp* __dst, memory_order __order) _NOEXCEPT { + using __ptr_type = __remove_const_t__a_value)>*; + *__dst = __c11_atomic_load( + const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> * __a, _Tp __value, memory_order __order) _NOEXCEPT { - return __c11_atomic_exchange( - std::addressof(__a->__a_value), __value, static_cast<__memory_order_underlying_t>(__order)); +template +_LIBCPP_HIDE_FROM_ABI void +__cxx_atomic_load_inplace(__cxx_atomic_base_impl<_Tp> const* __a, _Tp* __dst, memory_order __order) _NOEXCEPT { + using __ptr_type = __remove_const_t__a_value)>*; + *__dst = __c11_atomic_load( + const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order)); +} + +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT { + return __c11_atomic_exchange( + std::addressof(__a->__a_value), __value, static_cast<__memory_order_underlying_t>(__order)); +} +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value, memory_order __order) _NOEXCEPT { + return __c11_atomic_exchange( + std::addressof(__a->__a_value), __value, static_cast<__memory_order_underlying_t>(__order)); } _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR memory_order __to_failure_order(memory_order __order) { // Avoid switch statement to make this a constexpr. - return __order == memory_order_release ? memory_order_relaxed: - (__order == memory_order_acq_rel ? memory_order_acquire: - __order); + return __order == memory_order_release + ? memory_order_relaxed + : (__order == memory_order_acq_rel ? memory_order_acquire : __order); } -template -_LIBCPP_HIDE_FROM_ABI -bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_strong( + __cxx_atomic_base_impl<_Tp> volatile* __a, + _Tp* __expected, + _Tp __value, + memory_order __success, + memory_order __failure) _NOEXCEPT { return __c11_atomic_compare_exchange_strong( std::addressof(__a->__a_value), __expected, @@ -394,9 +367,10 @@ bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> volatile* static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure))); } -template -_LIBCPP_HIDE_FROM_ABI -bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_strong( + __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) + _NOEXCEPT { return __c11_atomic_compare_exchange_strong( std::addressof(__a->__a_value), __expected, @@ -405,9 +379,13 @@ bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> * __a, _Tp static_cast<__memory_order_underlying_t>(__to_failure_order(__failure))); } -template -_LIBCPP_HIDE_FROM_ABI -bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_weak( + __cxx_atomic_base_impl<_Tp> volatile* __a, + _Tp* __expected, + _Tp __value, + memory_order __success, + memory_order __failure) _NOEXCEPT { return __c11_atomic_compare_exchange_weak( std::addressof(__a->__a_value), __expected, @@ -415,9 +393,10 @@ bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> volatile* __ static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure))); } -template -_LIBCPP_HIDE_FROM_ABI -bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_weak( + __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) + _NOEXCEPT { return __c11_atomic_compare_exchange_weak( std::addressof(__a->__a_value), __expected, @@ -426,404 +405,104 @@ bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> * __a, _Tp* static_cast<__memory_order_underlying_t>(__to_failure_order(__failure))); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT { return __c11_atomic_fetch_add( std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Tp __delta, memory_order __order) _NOEXCEPT { return __c11_atomic_fetch_add( std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI _Tp* +__cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { return __c11_atomic_fetch_add( std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI _Tp* +__cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*>* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { return __c11_atomic_fetch_add( std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT { return __c11_atomic_fetch_sub( std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Tp __delta, memory_order __order) _NOEXCEPT { return __c11_atomic_fetch_sub( std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI _Tp* +__cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { return __c11_atomic_fetch_sub( std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI _Tp* +__cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*>* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { return __c11_atomic_fetch_sub( std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT { return __c11_atomic_fetch_and( std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) _NOEXCEPT { return __c11_atomic_fetch_and( std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT { return __c11_atomic_fetch_or( std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) _NOEXCEPT { return __c11_atomic_fetch_or( std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT { return __c11_atomic_fetch_xor( std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order)); } -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT { +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) _NOEXCEPT { return __c11_atomic_fetch_xor( std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order)); } #endif // _LIBCPP_HAS_GCC_ATOMIC_IMP, _LIBCPP_HAS_C_ATOMIC_IMP -#ifdef _LIBCPP_ATOMIC_ONLY_USE_BUILTINS - -template -struct __cxx_atomic_lock_impl { - - _LIBCPP_HIDE_FROM_ABI - __cxx_atomic_lock_impl() _NOEXCEPT - : __a_value(), __a_lock(0) {} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit - __cxx_atomic_lock_impl(_Tp value) _NOEXCEPT - : __a_value(value), __a_lock(0) {} - - _Tp __a_value; - mutable __cxx_atomic_base_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_lock; - - _LIBCPP_HIDE_FROM_ABI void __lock() const volatile { - while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire)) - /*spin*/; - } - _LIBCPP_HIDE_FROM_ABI void __lock() const { - while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire)) - /*spin*/; - } - _LIBCPP_HIDE_FROM_ABI void __unlock() const volatile { - __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release); - } - _LIBCPP_HIDE_FROM_ABI void __unlock() const { - __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release); - } - _LIBCPP_HIDE_FROM_ABI _Tp __read() const volatile { - __lock(); - _Tp __old; - __cxx_atomic_assign_volatile(__old, __a_value); - __unlock(); - return __old; - } - _LIBCPP_HIDE_FROM_ABI _Tp __read() const { - __lock(); - _Tp __old = __a_value; - __unlock(); - return __old; - } -}; - -template -_LIBCPP_HIDE_FROM_ABI -void __cxx_atomic_init(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) { - __cxx_atomic_assign_volatile(__a->__a_value, __val); -} -template -_LIBCPP_HIDE_FROM_ABI -void __cxx_atomic_init(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) { - __a->__a_value = __val; -} - -template -_LIBCPP_HIDE_FROM_ABI -void __cxx_atomic_store(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) { - __a->__lock(); - __cxx_atomic_assign_volatile(__a->__a_value, __val); - __a->__unlock(); -} -template -_LIBCPP_HIDE_FROM_ABI -void __cxx_atomic_store(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) { - __a->__lock(); - __a->__a_value = __val; - __a->__unlock(); -} - -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_load(const volatile __cxx_atomic_lock_impl<_Tp>* __a, memory_order) { - return __a->__read(); -} -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_load(const __cxx_atomic_lock_impl<_Tp>* __a, memory_order) { - return __a->__read(); -} - -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_exchange(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) { - __a->__lock(); - _Tp __old; - __cxx_atomic_assign_volatile(__old, __a->__a_value); - __cxx_atomic_assign_volatile(__a->__a_value, __value); - __a->__unlock(); - return __old; -} -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_exchange(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) { - __a->__lock(); - _Tp __old = __a->__a_value; - __a->__a_value = __value; - __a->__unlock(); - return __old; -} - -template -_LIBCPP_HIDE_FROM_ABI -bool __cxx_atomic_compare_exchange_strong(volatile __cxx_atomic_lock_impl<_Tp>* __a, - _Tp* __expected, _Tp __value, memory_order, memory_order) { - _Tp __temp; - __a->__lock(); - __cxx_atomic_assign_volatile(__temp, __a->__a_value); - bool __ret = (std::memcmp(&__temp, __expected, sizeof(_Tp)) == 0); - if(__ret) - __cxx_atomic_assign_volatile(__a->__a_value, __value); - else - __cxx_atomic_assign_volatile(*__expected, __a->__a_value); - __a->__unlock(); - return __ret; -} -template -_LIBCPP_HIDE_FROM_ABI -bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_lock_impl<_Tp>* __a, - _Tp* __expected, _Tp __value, memory_order, memory_order) { - __a->__lock(); - bool __ret = (std::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0); - if(__ret) - std::memcpy(&__a->__a_value, &__value, sizeof(_Tp)); - else - std::memcpy(__expected, &__a->__a_value, sizeof(_Tp)); - __a->__unlock(); - return __ret; -} - -template -_LIBCPP_HIDE_FROM_ABI -bool __cxx_atomic_compare_exchange_weak(volatile __cxx_atomic_lock_impl<_Tp>* __a, - _Tp* __expected, _Tp __value, memory_order, memory_order) { - _Tp __temp; - __a->__lock(); - __cxx_atomic_assign_volatile(__temp, __a->__a_value); - bool __ret = (std::memcmp(&__temp, __expected, sizeof(_Tp)) == 0); - if(__ret) - __cxx_atomic_assign_volatile(__a->__a_value, __value); - else - __cxx_atomic_assign_volatile(*__expected, __a->__a_value); - __a->__unlock(); - return __ret; -} -template -_LIBCPP_HIDE_FROM_ABI -bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_lock_impl<_Tp>* __a, - _Tp* __expected, _Tp __value, memory_order, memory_order) { - __a->__lock(); - bool __ret = (std::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0); - if(__ret) - std::memcpy(&__a->__a_value, &__value, sizeof(_Tp)); - else - std::memcpy(__expected, &__a->__a_value, sizeof(_Tp)); - __a->__unlock(); - return __ret; -} - -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp>* __a, - _Td __delta, memory_order) { - __a->__lock(); - _Tp __old; - __cxx_atomic_assign_volatile(__old, __a->__a_value); - __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old + __delta)); - __a->__unlock(); - return __old; -} -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp>* __a, - _Td __delta, memory_order) { - __a->__lock(); - _Tp __old = __a->__a_value; - __a->__a_value += __delta; - __a->__unlock(); - return __old; -} - -template -_LIBCPP_HIDE_FROM_ABI -_Tp* __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp*>* __a, - ptrdiff_t __delta, memory_order) { - __a->__lock(); - _Tp* __old; - __cxx_atomic_assign_volatile(__old, __a->__a_value); - __cxx_atomic_assign_volatile(__a->__a_value, __old + __delta); - __a->__unlock(); - return __old; -} -template -_LIBCPP_HIDE_FROM_ABI -_Tp* __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp*>* __a, - ptrdiff_t __delta, memory_order) { - __a->__lock(); - _Tp* __old = __a->__a_value; - __a->__a_value += __delta; - __a->__unlock(); - return __old; -} - -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_lock_impl<_Tp>* __a, - _Td __delta, memory_order) { - __a->__lock(); - _Tp __old; - __cxx_atomic_assign_volatile(__old, __a->__a_value); - __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old - __delta)); - __a->__unlock(); - return __old; -} -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_sub(__cxx_atomic_lock_impl<_Tp>* __a, - _Td __delta, memory_order) { - __a->__lock(); - _Tp __old = __a->__a_value; - __a->__a_value -= __delta; - __a->__unlock(); - return __old; -} - -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_lock_impl<_Tp>* __a, - _Tp __pattern, memory_order) { - __a->__lock(); - _Tp __old; - __cxx_atomic_assign_volatile(__old, __a->__a_value); - __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old & __pattern)); - __a->__unlock(); - return __old; -} -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_and(__cxx_atomic_lock_impl<_Tp>* __a, - _Tp __pattern, memory_order) { - __a->__lock(); - _Tp __old = __a->__a_value; - __a->__a_value &= __pattern; - __a->__unlock(); - return __old; -} - -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_lock_impl<_Tp>* __a, - _Tp __pattern, memory_order) { - __a->__lock(); - _Tp __old; - __cxx_atomic_assign_volatile(__old, __a->__a_value); - __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old | __pattern)); - __a->__unlock(); - return __old; -} -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_or(__cxx_atomic_lock_impl<_Tp>* __a, - _Tp __pattern, memory_order) { - __a->__lock(); - _Tp __old = __a->__a_value; - __a->__a_value |= __pattern; - __a->__unlock(); - return __old; -} - -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_lock_impl<_Tp>* __a, - _Tp __pattern, memory_order) { - __a->__lock(); - _Tp __old; - __cxx_atomic_assign_volatile(__old, __a->__a_value); - __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old ^ __pattern)); - __a->__unlock(); - return __old; -} -template -_LIBCPP_HIDE_FROM_ABI -_Tp __cxx_atomic_fetch_xor(__cxx_atomic_lock_impl<_Tp>* __a, - _Tp __pattern, memory_order) { - __a->__lock(); - _Tp __old = __a->__a_value; - __a->__a_value ^= __pattern; - __a->__unlock(); - return __old; -} - -template ::__value, - __cxx_atomic_base_impl<_Tp>, - __cxx_atomic_lock_impl<_Tp> >::type> -#else -template > -#endif //_LIBCPP_ATOMIC_ONLY_USE_BUILTINS +template > struct __cxx_atomic_impl : public _Base { - static_assert(is_trivially_copyable<_Tp>::value, - "std::atomic requires that 'T' be a trivially copyable type"); + static_assert(is_trivially_copyable<_Tp>::value, "std::atomic requires that 'T' be a trivially copyable type"); _LIBCPP_HIDE_FROM_ABI __cxx_atomic_impl() _NOEXCEPT = default; - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp __value) _NOEXCEPT - : _Base(__value) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp __value) _NOEXCEPT : _Base(__value) {} }; _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__atomic/fence.h b/third_party/libcxx/__atomic/fence.h index c62f38f21..8c27ea54d 100644 --- a/third_party/libcxx/__atomic/fence.h +++ b/third_party/libcxx/__atomic/fence.h @@ -19,19 +19,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD -inline _LIBCPP_HIDE_FROM_ABI -void -atomic_thread_fence(memory_order __m) _NOEXCEPT -{ - __cxx_atomic_thread_fence(__m); -} +inline _LIBCPP_HIDE_FROM_ABI void atomic_thread_fence(memory_order __m) _NOEXCEPT { __cxx_atomic_thread_fence(__m); } -inline _LIBCPP_HIDE_FROM_ABI -void -atomic_signal_fence(memory_order __m) _NOEXCEPT -{ - __cxx_atomic_signal_fence(__m); -} +inline _LIBCPP_HIDE_FROM_ABI void atomic_signal_fence(memory_order __m) _NOEXCEPT { __cxx_atomic_signal_fence(__m); } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__atomic/is_always_lock_free.h b/third_party/libcxx/__atomic/is_always_lock_free.h index fbbd43707..f928e79f7 100644 --- a/third_party/libcxx/__atomic/is_always_lock_free.h +++ b/third_party/libcxx/__atomic/is_always_lock_free.h @@ -20,7 +20,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template struct __libcpp_is_always_lock_free { // __atomic_always_lock_free is available in all Standard modes - static const bool __value = __atomic_always_lock_free(sizeof(_Tp), 0); + static const bool __value = __atomic_always_lock_free(sizeof(_Tp), nullptr); }; _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__atomic/kill_dependency.h b/third_party/libcxx/__atomic/kill_dependency.h index 1bd5c8ca7..103d52d35 100644 --- a/third_party/libcxx/__atomic/kill_dependency.h +++ b/third_party/libcxx/__atomic/kill_dependency.h @@ -18,10 +18,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI -_Tp kill_dependency(_Tp __y) _NOEXCEPT -{ - return __y; +_LIBCPP_HIDE_FROM_ABI _Tp kill_dependency(_Tp __y) _NOEXCEPT { + return __y; } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__atomic/memory_order.h b/third_party/libcxx/__atomic/memory_order.h index 3671dc3cf..294121d1c 100644 --- a/third_party/libcxx/__atomic/memory_order.h +++ b/third_party/libcxx/__atomic/memory_order.h @@ -22,14 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD // Figure out what the underlying type for `memory_order` would be if it were // declared as an unscoped enum (accounting for -fshort-enums). Use this result // to pin the underlying type in C++20. -enum __legacy_memory_order { - __mo_relaxed, - __mo_consume, - __mo_acquire, - __mo_release, - __mo_acq_rel, - __mo_seq_cst -}; +enum __legacy_memory_order { __mo_relaxed, __mo_consume, __mo_acquire, __mo_release, __mo_acq_rel, __mo_seq_cst }; using __memory_order_underlying_t = underlying_type<__legacy_memory_order>::type; @@ -44,8 +37,8 @@ enum class memory_order : __memory_order_underlying_t { seq_cst = __mo_seq_cst }; -static_assert((is_same::type, __memory_order_underlying_t>::value), - "unexpected underlying type for std::memory_order"); +static_assert(is_same::type, __memory_order_underlying_t>::value, + "unexpected underlying type for std::memory_order"); inline constexpr auto memory_order_relaxed = memory_order::relaxed; inline constexpr auto memory_order_consume = memory_order::consume; diff --git a/third_party/libcxx/__atomic/to_gcc_order.h b/third_party/libcxx/__atomic/to_gcc_order.h new file mode 100644 index 000000000..d04c111ad --- /dev/null +++ b/third_party/libcxx/__atomic/to_gcc_order.h @@ -0,0 +1,54 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ATOMIC_TO_GCC_ORDER_H +#define _LIBCPP___ATOMIC_TO_GCC_ORDER_H + +#include <__atomic/memory_order.h> +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if defined(__ATOMIC_RELAXED) && defined(__ATOMIC_CONSUME) && defined(__ATOMIC_ACQUIRE) && \ + defined(__ATOMIC_RELEASE) && defined(__ATOMIC_ACQ_REL) && defined(__ATOMIC_SEQ_CST) + +_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) { + // Avoid switch statement to make this a constexpr. + return __order == memory_order_relaxed + ? __ATOMIC_RELAXED + : (__order == memory_order_acquire + ? __ATOMIC_ACQUIRE + : (__order == memory_order_release + ? __ATOMIC_RELEASE + : (__order == memory_order_seq_cst + ? __ATOMIC_SEQ_CST + : (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL : __ATOMIC_CONSUME)))); +} + +_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) { + // Avoid switch statement to make this a constexpr. + return __order == memory_order_relaxed + ? __ATOMIC_RELAXED + : (__order == memory_order_acquire + ? __ATOMIC_ACQUIRE + : (__order == memory_order_release + ? __ATOMIC_RELAXED + : (__order == memory_order_seq_cst + ? __ATOMIC_SEQ_CST + : (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE : __ATOMIC_CONSUME)))); +} + +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ATOMIC_TO_GCC_ORDER_H diff --git a/third_party/libcxx/__availability b/third_party/libcxx/__availability deleted file mode 100644 index 3c4c5cc7b..000000000 --- a/third_party/libcxx/__availability +++ /dev/null @@ -1,348 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP___AVAILABILITY -#define _LIBCPP___AVAILABILITY - -#include <__config> - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -// Libc++ is shipped by various vendors. In particular, it is used as a system -// library on macOS, iOS and other Apple platforms. In order for users to be -// able to compile a binary that is intended to be deployed to an older version -// of a platform, Clang provides availability attributes [1]. These attributes -// can be placed on declarations and are used to describe the life cycle of a -// symbol in the library. -// -// The main goal is to ensure a compile-time error if a symbol that hasn't been -// introduced in a previously released library is used in a program that targets -// that previously released library. Normally, this would be a load-time error -// when one tries to launch the program against the older library. -// -// For example, the filesystem library was introduced in the dylib in macOS 10.15. -// If a user compiles on a macOS 10.15 host but targets macOS 10.13 with their -// program, the compiler would normally not complain (because the required -// declarations are in the headers), but the dynamic loader would fail to find -// the symbols when actually trying to launch the program on macOS 10.13. To -// turn this into a compile-time issue instead, declarations are annotated with -// when they were introduced, and the compiler can produce a diagnostic if the -// program references something that isn't available on the deployment target. -// -// This mechanism is general in nature, and any vendor can add their markup to -// the library (see below). Whenever a new feature is added that requires support -// in the shared library, two macros are added below to allow marking the feature -// as unavailable: -// 1. A macro named `_LIBCPP_AVAILABILITY_HAS_NO_` which must be defined -// exactly when compiling for a target that doesn't support the feature. -// 2. A macro named `_LIBCPP_AVAILABILITY_`, which must always be defined -// and must expand to the proper availability attribute for the platform. -// -// When vendors decide to ship the feature as part of their shared library, they -// can update these macros appropriately for their platform, and the library will -// use those to provide an optimal user experience. -// -// Furthermore, many features in the standard library have corresponding -// feature-test macros. The `_LIBCPP_AVAILABILITY_HAS_NO_` macros -// are checked by the corresponding feature-test macros generated by -// generate_feature_test_macro_components.py to ensure that the library -// doesn't announce a feature as being implemented if it is unavailable on -// the deployment target. -// -// Note that this mechanism is disabled by default in the "upstream" libc++. -// Availability annotations are only meaningful when shipping libc++ inside -// a platform (i.e. as a system library), and so vendors that want them should -// turn those annotations on at CMake configuration time. -// -// [1]: https://clang.llvm.org/docs/AttributeReference.html#availability - - -// For backwards compatibility, allow users to define _LIBCPP_DISABLE_AVAILABILITY -// for a while. -#if defined(_LIBCPP_DISABLE_AVAILABILITY) -# if !defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS) -# define _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS -# endif -#endif - -// Availability markup is disabled when building the library, or when the compiler -// doesn't support the proper attributes. -#if defined(_LIBCPP_BUILDING_LIBRARY) || \ - defined(_LIBCXXABI_BUILDING_LIBRARY) || \ - !__has_feature(attribute_availability_with_strict) || \ - !__has_feature(attribute_availability_in_templates) || \ - !__has_extension(pragma_clang_attribute_external_declaration) -# if !defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS) -# define _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS -# endif -#endif - -#if defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS) - - // This controls the availability of std::shared_mutex and std::shared_timed_mutex, - // which were added to the dylib later. -// # define _LIBCPP_AVAILABILITY_HAS_NO_SHARED_MUTEX -# define _LIBCPP_AVAILABILITY_SHARED_MUTEX - - // These macros control the availability of std::bad_optional_access and - // other exception types. These were put in the shared library to prevent - // code bloat from every user program defining the vtable for these exception - // types. - // - // Note that when exceptions are disabled, the methods that normally throw - // these exceptions can be used even on older deployment targets, but those - // methods will abort instead of throwing. -// # define _LIBCPP_AVAILABILITY_HAS_NO_BAD_OPTIONAL_ACCESS -# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS - -// # define _LIBCPP_AVAILABILITY_HAS_NO_BAD_VARIANT_ACCESS -# define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS - -// # define _LIBCPP_AVAILABILITY_HAS_NO_BAD_ANY_CAST -# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST - - // This controls the availability of std::uncaught_exceptions(). -// # define _LIBCPP_AVAILABILITY_HAS_NO_UNCAUGHT_EXCEPTIONS -# define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS - - // This controls the availability of the sized version of ::operator delete, - // ::operator delete[], and their align_val_t variants, which were all added - // in C++17, and hence not present in early dylibs. -// # define _LIBCPP_AVAILABILITY_HAS_NO_SIZED_NEW_DELETE -# define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE - - // This controls the availability of the std::future_error exception. - // - // Note that when exceptions are disabled, the methods that normally throw - // std::future_error can be used even on older deployment targets, but those - // methods will abort instead of throwing. -// # define _LIBCPP_AVAILABILITY_HAS_NO_FUTURE_ERROR -# define _LIBCPP_AVAILABILITY_FUTURE_ERROR - - // This controls the availability of std::type_info's vtable. - // I can't imagine how using std::type_info can work at all if - // this isn't supported. -// # define _LIBCPP_AVAILABILITY_HAS_NO_TYPEINFO_VTABLE -# define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE - - // This controls the availability of std::locale::category members - // (e.g. std::locale::collate), which are defined in the dylib. -// # define _LIBCPP_AVAILABILITY_HAS_NO_LOCALE_CATEGORY -# define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY - - // This controls the availability of atomic operations on std::shared_ptr - // (e.g. `std::atomic_store(std::shared_ptr)`), which require a shared - // lock table located in the dylib. -// # define _LIBCPP_AVAILABILITY_HAS_NO_ATOMIC_SHARED_PTR -# define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR - - // These macros control the availability of all parts of that - // depend on something in the dylib. -// # define _LIBCPP_AVAILABILITY_HAS_NO_FILESYSTEM -# define _LIBCPP_AVAILABILITY_FILESYSTEM -# define _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH -# define _LIBCPP_AVAILABILITY_FILESYSTEM_POP - - // This controls the availability of floating-point std::to_chars functions. - // These overloads were added later than the integer overloads. -// # define _LIBCPP_AVAILABILITY_HAS_NO_TO_CHARS_FLOATING_POINT -# define _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT - - // This controls the availability of the C++20 synchronization library, - // which requires shared library support for various operations - // (see libcxx/src/atomic.cpp). This includes , , - // , and notification functions on std::atomic. -// # define _LIBCPP_AVAILABILITY_HAS_NO_SYNC -# define _LIBCPP_AVAILABILITY_SYNC - - // This controls whether the library claims to provide a default verbose - // termination function, and consequently whether the headers will try - // to use it when the mechanism isn't overriden at compile-time. -// # define _LIBCPP_AVAILABILITY_HAS_NO_VERBOSE_ABORT -# define _LIBCPP_AVAILABILITY_VERBOSE_ABORT - -#elif defined(__APPLE__) - - // shared_mutex and shared_timed_mutex -# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200) || \ - (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 100000) || \ - (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 100000) || \ - (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 30000) -# define _LIBCPP_AVAILABILITY_HAS_NO_SHARED_MUTEX -# endif -# define _LIBCPP_AVAILABILITY_SHARED_MUTEX \ - __attribute__((availability(macos,strict,introduced=10.12))) \ - __attribute__((availability(ios,strict,introduced=10.0))) \ - __attribute__((availability(tvos,strict,introduced=10.0))) \ - __attribute__((availability(watchos,strict,introduced=3.0))) - - // bad_optional_access, bad_variant_access and bad_any_cast - // Note: bad_optional_access & friends were not introduced in the matching - // macOS and iOS versions, so the version mismatch between macOS and others - // is intended. -# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101300) || \ - (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 120000) || \ - (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 120000) || \ - (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 50000) -# define _LIBCPP_AVAILABILITY_HAS_NO_BAD_OPTIONAL_ACCESS -# define _LIBCPP_AVAILABILITY_HAS_NO_BAD_VARIANT_ACCESS -# define _LIBCPP_AVAILABILITY_HAS_NO_BAD_ANY_CAST -# endif -# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS \ - __attribute__((availability(macos,strict,introduced=10.13))) \ - __attribute__((availability(ios,strict,introduced=12.0))) \ - __attribute__((availability(tvos,strict,introduced=12.0))) \ - __attribute__((availability(watchos,strict,introduced=5.0))) -# define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS \ - _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS -# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST \ - _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS - - // uncaught_exceptions -# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200) || \ - (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 100000) || \ - (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 100000) || \ - (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 30000) -# define _LIBCPP_AVAILABILITY_HAS_NO_UNCAUGHT_EXCEPTIONS -# endif -# define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS \ - __attribute__((availability(macos,strict,introduced=10.12))) \ - __attribute__((availability(ios,strict,introduced=10.0))) \ - __attribute__((availability(tvos,strict,introduced=10.0))) \ - __attribute__((availability(watchos,strict,introduced=3.0))) - - // sized operator new and sized operator delete -# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200) || \ - (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 100000) || \ - (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 100000) || \ - (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 30000) -# define _LIBCPP_AVAILABILITY_HAS_NO_SIZED_NEW_DELETE -# endif -# define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE \ - __attribute__((availability(macos,strict,introduced=10.12))) \ - __attribute__((availability(ios,strict,introduced=10.0))) \ - __attribute__((availability(tvos,strict,introduced=10.0))) \ - __attribute__((availability(watchos,strict,introduced=3.0))) - - // future_error -# if (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 60000) -# define _LIBCPP_AVAILABILITY_HAS_NO_FUTURE_ERROR -# endif -# define _LIBCPP_AVAILABILITY_FUTURE_ERROR \ - __attribute__((availability(ios,strict,introduced=6.0))) - - // type_info's vtable -# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 100900) || \ - (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 70000) -# define _LIBCPP_AVAILABILITY_HAS_NO_TYPEINFO_VTABLE -# endif -# define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE \ - __attribute__((availability(macos,strict,introduced=10.9))) \ - __attribute__((availability(ios,strict,introduced=7.0))) - - // locale::category -# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 100900) || \ - (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 70000) -# define _LIBCPP_AVAILABILITY_HAS_NO_LOCALE_CATEGORY -# endif -# define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY \ - __attribute__((availability(macos,strict,introduced=10.9))) \ - __attribute__((availability(ios,strict,introduced=7.0))) - - // atomic operations on shared_ptr -# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 100900) || \ - (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 70000) -# define _LIBCPP_AVAILABILITY_HAS_NO_ATOMIC_SHARED_PTR -# endif -# define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR \ - __attribute__((availability(macos,strict,introduced=10.9))) \ - __attribute__((availability(ios,strict,introduced=7.0))) - - // -# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101500) || \ - (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 130000) || \ - (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 130000) || \ - (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 60000) -# define _LIBCPP_AVAILABILITY_HAS_NO_FILESYSTEM -# endif -# define _LIBCPP_AVAILABILITY_FILESYSTEM \ - __attribute__((availability(macos,strict,introduced=10.15))) \ - __attribute__((availability(ios,strict,introduced=13.0))) \ - __attribute__((availability(tvos,strict,introduced=13.0))) \ - __attribute__((availability(watchos,strict,introduced=6.0))) -# define _LIBCPP_AVAILABILITY_FILESYSTEM_PUSH \ - _Pragma("clang attribute push(__attribute__((availability(macos,strict,introduced=10.15))), apply_to=any(function,record))") \ - _Pragma("clang attribute push(__attribute__((availability(ios,strict,introduced=13.0))), apply_to=any(function,record))") \ - _Pragma("clang attribute push(__attribute__((availability(tvos,strict,introduced=13.0))), apply_to=any(function,record))") \ - _Pragma("clang attribute push(__attribute__((availability(watchos,strict,introduced=6.0))), apply_to=any(function,record))") -# define _LIBCPP_AVAILABILITY_FILESYSTEM_POP \ - _Pragma("clang attribute pop") \ - _Pragma("clang attribute pop") \ - _Pragma("clang attribute pop") \ - _Pragma("clang attribute pop") - - // std::to_chars(floating-point) -# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 130300) || \ - (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 160300) || \ - (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 160300) || \ - (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 90300) -# define _LIBCPP_AVAILABILITY_HAS_NO_TO_CHARS_FLOATING_POINT -# endif -# define _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT \ - __attribute__((availability(macos,strict,introduced=13.3))) \ - __attribute__((availability(ios,strict,introduced=16.3))) \ - __attribute__((availability(tvos,strict,introduced=16.3))) \ - __attribute__((availability(watchos,strict,introduced=9.3))) - - // c++20 synchronization library -# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 110000) || \ - (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 140000) || \ - (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 140000) || \ - (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 70000) -# define _LIBCPP_AVAILABILITY_HAS_NO_SYNC -# endif -# define _LIBCPP_AVAILABILITY_SYNC \ - __attribute__((availability(macos,strict,introduced=11.0))) \ - __attribute__((availability(ios,strict,introduced=14.0))) \ - __attribute__((availability(tvos,strict,introduced=14.0))) \ - __attribute__((availability(watchos,strict,introduced=7.0))) - - // __libcpp_verbose_abort -# if 1 // TODO: Update once this is released -# define _LIBCPP_AVAILABILITY_HAS_NO_VERBOSE_ABORT -# endif -# define _LIBCPP_AVAILABILITY_VERBOSE_ABORT \ - __attribute__((unavailable)) - -#else - -// ...New vendors can add availability markup here... - -# error "It looks like you're trying to enable vendor availability markup, but you haven't defined the corresponding macros yet!" - -#endif - -// Define availability attributes that depend on _LIBCPP_HAS_NO_EXCEPTIONS. -// Those are defined in terms of the availability attributes above, and -// should not be vendor-specific. -#if defined(_LIBCPP_HAS_NO_EXCEPTIONS) -# define _LIBCPP_AVAILABILITY_FUTURE -# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST -# define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS -# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS -#else -# define _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_AVAILABILITY_FUTURE_ERROR -# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _LIBCPP_AVAILABILITY_BAD_ANY_CAST -# define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS -# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS -#endif - -#endif // _LIBCPP___AVAILABILITY diff --git a/third_party/libcxx/__bit/bit_cast.h b/third_party/libcxx/__bit/bit_cast.h index 39842465e..cd0456738 100644 --- a/third_party/libcxx/__bit/bit_cast.h +++ b/third_party/libcxx/__bit/bit_cast.h @@ -19,13 +19,21 @@ _LIBCPP_BEGIN_NAMESPACE_STD +#ifndef _LIBCPP_CXX03_LANG + +template +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr _ToType __bit_cast(const _FromType& __from) noexcept { + return __builtin_bit_cast(_ToType, __from); +} + +#endif // _LIBCPP_CXX03_LANG + #if _LIBCPP_STD_VER >= 20 template - requires(sizeof(_ToType) == sizeof(_FromType) && - is_trivially_copyable_v<_ToType> && + requires(sizeof(_ToType) == sizeof(_FromType) && is_trivially_copyable_v<_ToType> && is_trivially_copyable_v<_FromType>) -_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _ToType bit_cast(const _FromType& __from) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _ToType bit_cast(const _FromType& __from) noexcept { return __builtin_bit_cast(_ToType, __from); } diff --git a/third_party/libcxx/__bit/bit_ceil.h b/third_party/libcxx/__bit/bit_ceil.h index 1332900ae..cfd792dc2 100644 --- a/third_party/libcxx/__bit/bit_ceil.h +++ b/third_party/libcxx/__bit/bit_ceil.h @@ -21,25 +21,33 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if _LIBCPP_STD_VER >= 20 +#if _LIBCPP_STD_VER >= 17 -template <__libcpp_unsigned_integer _Tp> -_LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_ceil(_Tp __t) noexcept { +template +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp __bit_ceil(_Tp __t) noexcept { if (__t < 2) return 1; - const unsigned __n = numeric_limits<_Tp>::digits - std::countl_zero((_Tp)(__t - 1u)); - _LIBCPP_ASSERT(__n != numeric_limits<_Tp>::digits, "Bad input to bit_ceil"); + const unsigned __n = numeric_limits<_Tp>::digits - std::__countl_zero((_Tp)(__t - 1u)); + _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(__n != numeric_limits<_Tp>::digits, "Bad input to bit_ceil"); if constexpr (sizeof(_Tp) >= sizeof(unsigned)) return _Tp{1} << __n; else { - const unsigned __extra = numeric_limits::digits - numeric_limits<_Tp>::digits; + const unsigned __extra = numeric_limits::digits - numeric_limits<_Tp>::digits; const unsigned __ret_val = 1u << (__n + __extra); return (_Tp)(__ret_val >> __extra); } } -#endif // _LIBCPP_STD_VER >= 20 +# if _LIBCPP_STD_VER >= 20 + +template <__libcpp_unsigned_integer _Tp> +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_ceil(_Tp __t) noexcept { + return std::__bit_ceil(__t); +} + +# endif // _LIBCPP_STD_VER >= 20 +#endif // _LIBCPP_STD_VER >= 17 _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__bit/bit_floor.h b/third_party/libcxx/__bit/bit_floor.h index b2e38092f..133e36950 100644 --- a/third_party/libcxx/__bit/bit_floor.h +++ b/third_party/libcxx/__bit/bit_floor.h @@ -23,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 template <__libcpp_unsigned_integer _Tp> -_LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_floor(_Tp __t) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_floor(_Tp __t) noexcept { return __t == 0 ? 0 : _Tp{1} << std::__bit_log2(__t); } diff --git a/third_party/libcxx/__bit/bit_width.h b/third_party/libcxx/__bit/bit_width.h index 4381f227f..853e48177 100644 --- a/third_party/libcxx/__bit/bit_width.h +++ b/third_party/libcxx/__bit/bit_width.h @@ -22,7 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template <__libcpp_unsigned_integer _Tp> -_LIBCPP_HIDE_FROM_ABI constexpr int bit_width(_Tp __t) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int bit_width(_Tp __t) noexcept { return __t == 0 ? 0 : std::__bit_log2(__t) + 1; } diff --git a/third_party/libcxx/__bit/blsr.h b/third_party/libcxx/__bit/blsr.h index de991e9ad..76bd521f5 100644 --- a/third_party/libcxx/__bit/blsr.h +++ b/third_party/libcxx/__bit/blsr.h @@ -17,15 +17,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unsigned __libcpp_blsr(unsigned __x) _NOEXCEPT { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR unsigned __libcpp_blsr(unsigned __x) _NOEXCEPT { return __x ^ (__x & -__x); } -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unsigned long __libcpp_blsr(unsigned long __x) _NOEXCEPT { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR unsigned long __libcpp_blsr(unsigned long __x) _NOEXCEPT { return __x ^ (__x & -__x); } -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR unsigned long long __libcpp_blsr(unsigned long long __x) _NOEXCEPT { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR unsigned long long __libcpp_blsr(unsigned long long __x) _NOEXCEPT { return __x ^ (__x & -__x); } diff --git a/third_party/libcxx/__bit/byteswap.h b/third_party/libcxx/__bit/byteswap.h index b290e80a5..6225ecf2f 100644 --- a/third_party/libcxx/__bit/byteswap.h +++ b/third_party/libcxx/__bit/byteswap.h @@ -23,8 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 23 template -_LIBCPP_HIDE_FROM_ABI constexpr _Tp byteswap(_Tp __val) noexcept { - +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp byteswap(_Tp __val) noexcept { if constexpr (sizeof(_Tp) == 1) { return __val; } else if constexpr (sizeof(_Tp) == 2) { @@ -33,15 +32,15 @@ _LIBCPP_HIDE_FROM_ABI constexpr _Tp byteswap(_Tp __val) noexcept { return __builtin_bswap32(__val); } else if constexpr (sizeof(_Tp) == 8) { return __builtin_bswap64(__val); -#ifndef _LIBCPP_HAS_NO_INT128 +# ifndef _LIBCPP_HAS_NO_INT128 } else if constexpr (sizeof(_Tp) == 16) { -#if __has_builtin(__builtin_bswap128) +# if __has_builtin(__builtin_bswap128) return __builtin_bswap128(__val); -#else +# else return static_cast<_Tp>(byteswap(static_cast(__val))) << 64 | static_cast<_Tp>(byteswap(static_cast(__val >> 64))); -#endif // __has_builtin(__builtin_bswap128) -#endif // _LIBCPP_HAS_NO_INT128 +# endif // __has_builtin(__builtin_bswap128) +# endif // _LIBCPP_HAS_NO_INT128 } else { static_assert(sizeof(_Tp) == 0, "byteswap is unimplemented for integral types of this size"); } diff --git a/third_party/libcxx/__bit/countl.h b/third_party/libcxx/__bit/countl.h index 86eaee0c1..998a0b44c 100644 --- a/third_party/libcxx/__bit/countl.h +++ b/third_party/libcxx/__bit/countl.h @@ -6,6 +6,9 @@ // //===----------------------------------------------------------------------===// +// TODO: __builtin_clzg is available since Clang 19 and GCC 14. When support for older versions is dropped, we can +// refactor this code to exclusively use __builtin_clzg. + #ifndef _LIBCPP___BIT_COUNTL_H #define _LIBCPP___BIT_COUNTL_H @@ -24,18 +27,23 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -int __libcpp_clz(unsigned __x) _NOEXCEPT { return __builtin_clz(__x); } +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_clz(unsigned __x) _NOEXCEPT { + return __builtin_clz(__x); +} -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -int __libcpp_clz(unsigned long __x) _NOEXCEPT { return __builtin_clzl(__x); } +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_clz(unsigned long __x) _NOEXCEPT { + return __builtin_clzl(__x); +} -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -int __libcpp_clz(unsigned long long __x) _NOEXCEPT { return __builtin_clzll(__x); } +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_clz(unsigned long long __x) _NOEXCEPT { + return __builtin_clzll(__x); +} -# ifndef _LIBCPP_HAS_NO_INT128 -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -int __libcpp_clz(__uint128_t __x) _NOEXCEPT { +#ifndef _LIBCPP_HAS_NO_INT128 +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_clz(__uint128_t __x) _NOEXCEPT { +# if __has_builtin(__builtin_clzg) + return __builtin_clzg(__x); +# else // The function is written in this form due to C++ constexpr limitations. // The algorithm: // - Test whether any bit in the high 64-bits is set @@ -45,53 +53,54 @@ int __libcpp_clz(__uint128_t __x) _NOEXCEPT { // - Any bits set: // - The number of leading zeros of the input is the number of leading // zeros in the high 64-bits. - return ((__x >> 64) == 0) - ? (64 + __builtin_clzll(static_cast(__x))) - : __builtin_clzll(static_cast(__x >> 64)); + return ((__x >> 64) == 0) ? (64 + __builtin_clzll(static_cast(__x))) + : __builtin_clzll(static_cast(__x >> 64)); +# endif } -# endif // _LIBCPP_HAS_NO_INT128 +#endif // _LIBCPP_HAS_NO_INT128 -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -int __countl_zero(_Tp __t) _NOEXCEPT -{ - static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__countl_zero requires an unsigned integer type"); - if (__t == 0) - return numeric_limits<_Tp>::digits; +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int __countl_zero(_Tp __t) _NOEXCEPT { + static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__countl_zero requires an unsigned integer type"); +#if __has_builtin(__builtin_clzg) + return __builtin_clzg(__t, numeric_limits<_Tp>::digits); +#else // __has_builtin(__builtin_clzg) + if (__t == 0) + return numeric_limits<_Tp>::digits; - if (sizeof(_Tp) <= sizeof(unsigned int)) - return std::__libcpp_clz(static_cast(__t)) - - (numeric_limits::digits - numeric_limits<_Tp>::digits); - else if (sizeof(_Tp) <= sizeof(unsigned long)) - return std::__libcpp_clz(static_cast(__t)) - - (numeric_limits::digits - numeric_limits<_Tp>::digits); - else if (sizeof(_Tp) <= sizeof(unsigned long long)) - return std::__libcpp_clz(static_cast(__t)) - - (numeric_limits::digits - numeric_limits<_Tp>::digits); - else - { - int __ret = 0; - int __iter = 0; - const unsigned int __ulldigits = numeric_limits::digits; - while (true) { - __t = std::__rotr(__t, __ulldigits); - if ((__iter = std::__countl_zero(static_cast(__t))) != __ulldigits) - break; - __ret += __iter; - } - return __ret + __iter; + if (sizeof(_Tp) <= sizeof(unsigned int)) + return std::__libcpp_clz(static_cast(__t)) - + (numeric_limits::digits - numeric_limits<_Tp>::digits); + else if (sizeof(_Tp) <= sizeof(unsigned long)) + return std::__libcpp_clz(static_cast(__t)) - + (numeric_limits::digits - numeric_limits<_Tp>::digits); + else if (sizeof(_Tp) <= sizeof(unsigned long long)) + return std::__libcpp_clz(static_cast(__t)) - + (numeric_limits::digits - numeric_limits<_Tp>::digits); + else { + int __ret = 0; + int __iter = 0; + const unsigned int __ulldigits = numeric_limits::digits; + while (true) { + __t = std::__rotl(__t, __ulldigits); + if ((__iter = std::__countl_zero(static_cast(__t))) != __ulldigits) + break; + __ret += __iter; } + return __ret + __iter; + } +#endif // __has_builtin(__builtin_clzg) } #if _LIBCPP_STD_VER >= 20 template <__libcpp_unsigned_integer _Tp> -_LIBCPP_HIDE_FROM_ABI constexpr int countl_zero(_Tp __t) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int countl_zero(_Tp __t) noexcept { return std::__countl_zero(__t); } template <__libcpp_unsigned_integer _Tp> -_LIBCPP_HIDE_FROM_ABI constexpr int countl_one(_Tp __t) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int countl_one(_Tp __t) noexcept { return __t != numeric_limits<_Tp>::max() ? std::countl_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits; } diff --git a/third_party/libcxx/__bit/countr.h b/third_party/libcxx/__bit/countr.h index d3ca5b6c9..9e92021fb 100644 --- a/third_party/libcxx/__bit/countr.h +++ b/third_party/libcxx/__bit/countr.h @@ -6,6 +6,9 @@ // //===----------------------------------------------------------------------===// +// TODO: __builtin_ctzg is available since Clang 19 and GCC 14. When support for older versions is dropped, we can +// refactor this code to exclusively use __builtin_ctzg. + #ifndef _LIBCPP___BIT_COUNTR_H #define _LIBCPP___BIT_COUNTR_H @@ -23,22 +26,25 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -int __libcpp_ctz(unsigned __x) _NOEXCEPT { return __builtin_ctz(__x); } +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_ctz(unsigned __x) _NOEXCEPT { + return __builtin_ctz(__x); +} -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -int __libcpp_ctz(unsigned long __x) _NOEXCEPT { return __builtin_ctzl(__x); } +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_ctz(unsigned long __x) _NOEXCEPT { + return __builtin_ctzl(__x); +} -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -int __libcpp_ctz(unsigned long long __x) _NOEXCEPT { return __builtin_ctzll(__x); } +_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_ctz(unsigned long long __x) _NOEXCEPT { + return __builtin_ctzll(__x); +} -#if _LIBCPP_STD_VER >= 20 - -template <__libcpp_unsigned_integer _Tp> -_LIBCPP_HIDE_FROM_ABI constexpr int countr_zero(_Tp __t) noexcept { +template +_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int __countr_zero(_Tp __t) _NOEXCEPT { +#if __has_builtin(__builtin_ctzg) + return __builtin_ctzg(__t, numeric_limits<_Tp>::digits); +#else // __has_builtin(__builtin_ctzg) if (__t == 0) return numeric_limits<_Tp>::digits; - if (sizeof(_Tp) <= sizeof(unsigned int)) return std::__libcpp_ctz(static_cast(__t)); else if (sizeof(_Tp) <= sizeof(unsigned long)) @@ -46,7 +52,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr int countr_zero(_Tp __t) noexcept { else if (sizeof(_Tp) <= sizeof(unsigned long long)) return std::__libcpp_ctz(static_cast(__t)); else { - int __ret = 0; + int __ret = 0; const unsigned int __ulldigits = numeric_limits::digits; while (static_cast(__t) == 0uLL) { __ret += __ulldigits; @@ -54,10 +60,18 @@ _LIBCPP_HIDE_FROM_ABI constexpr int countr_zero(_Tp __t) noexcept { } return __ret + std::__libcpp_ctz(static_cast(__t)); } +#endif // __has_builtin(__builtin_ctzg) +} + +#if _LIBCPP_STD_VER >= 20 + +template <__libcpp_unsigned_integer _Tp> +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int countr_zero(_Tp __t) noexcept { + return std::__countr_zero(__t); } template <__libcpp_unsigned_integer _Tp> -_LIBCPP_HIDE_FROM_ABI constexpr int countr_one(_Tp __t) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int countr_one(_Tp __t) noexcept { return __t != numeric_limits<_Tp>::max() ? std::countr_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits; } diff --git a/third_party/libcxx/__bit/endian.h b/third_party/libcxx/__bit/endian.h index 52635f2d2..2d31e5ddf 100644 --- a/third_party/libcxx/__bit/endian.h +++ b/third_party/libcxx/__bit/endian.h @@ -21,7 +21,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD enum class endian { little = 0xDEAD, - big = 0xFACE, + big = 0xFACE, # if defined(_LIBCPP_LITTLE_ENDIAN) native = little # elif defined(_LIBCPP_BIG_ENDIAN) diff --git a/third_party/libcxx/__bit/has_single_bit.h b/third_party/libcxx/__bit/has_single_bit.h index b89f5995b..52f5853a1 100644 --- a/third_party/libcxx/__bit/has_single_bit.h +++ b/third_party/libcxx/__bit/has_single_bit.h @@ -24,7 +24,7 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD template <__libcpp_unsigned_integer _Tp> -_LIBCPP_HIDE_FROM_ABI constexpr bool has_single_bit(_Tp __t) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool has_single_bit(_Tp __t) noexcept { return __t != 0 && (((__t & (__t - 1)) == 0)); } diff --git a/third_party/libcxx/setjmp.h b/third_party/libcxx/__bit/invert_if.h similarity index 56% rename from third_party/libcxx/setjmp.h rename to third_party/libcxx/__bit/invert_if.h index f4a2bbcb0..f7606ede2 100644 --- a/third_party/libcxx/setjmp.h +++ b/third_party/libcxx/__bit/invert_if.h @@ -1,4 +1,3 @@ -// -*- C++ -*- //===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. @@ -7,40 +6,25 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP_SETJMP_H -#define _LIBCPP_SETJMP_H - -/* - setjmp.h synopsis - -Macros: - - setjmp - -Types: - - jmp_buf - -void longjmp(jmp_buf env, int val); - -*/ +#ifndef _LIBCPP___BIT_INVERT_IF_H +#define _LIBCPP___BIT_INVERT_IF_H +#include <__concepts/arithmetic.h> #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif -#if __has_include_next() -# include_next -#endif +_LIBCPP_BEGIN_NAMESPACE_STD -#ifdef __cplusplus +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __invert_if(_Tp __v) { + if (_Invert) + return ~__v; + return __v; +} -#ifndef setjmp -#define setjmp(env) setjmp(env) -#endif +_LIBCPP_END_NAMESPACE_STD -#endif // __cplusplus - -#endif // _LIBCPP_SETJMP_H +#endif // _LIBCPP___BIT_INVERT_IF_H diff --git a/third_party/libcxx/__bit/popcount.h b/third_party/libcxx/__bit/popcount.h index 33b94cff7..5cf0a01d0 100644 --- a/third_party/libcxx/__bit/popcount.h +++ b/third_party/libcxx/__bit/popcount.h @@ -6,6 +6,9 @@ // //===----------------------------------------------------------------------===// +// TODO: __builtin_popcountg is available since Clang 19 and GCC 14. When support for older versions is dropped, we can +// refactor this code to exclusively use __builtin_popcountg. + #ifndef _LIBCPP___BIT_POPCOUNT_H #define _LIBCPP___BIT_POPCOUNT_H @@ -23,19 +26,25 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -int __libcpp_popcount(unsigned __x) _NOEXCEPT { return __builtin_popcount(__x); } +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_popcount(unsigned __x) _NOEXCEPT { + return __builtin_popcount(__x); +} -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -int __libcpp_popcount(unsigned long __x) _NOEXCEPT { return __builtin_popcountl(__x); } +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_popcount(unsigned long __x) _NOEXCEPT { + return __builtin_popcountl(__x); +} -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -int __libcpp_popcount(unsigned long long __x) _NOEXCEPT { return __builtin_popcountll(__x); } +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_popcount(unsigned long long __x) _NOEXCEPT { + return __builtin_popcountll(__x); +} #if _LIBCPP_STD_VER >= 20 template <__libcpp_unsigned_integer _Tp> -_LIBCPP_HIDE_FROM_ABI constexpr int popcount(_Tp __t) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int popcount(_Tp __t) noexcept { +# if __has_builtin(__builtin_popcountg) + return __builtin_popcountg(__t); +# else // __has_builtin(__builtin_popcountg) if (sizeof(_Tp) <= sizeof(unsigned int)) return std::__libcpp_popcount(static_cast(__t)); else if (sizeof(_Tp) <= sizeof(unsigned long)) @@ -50,6 +59,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr int popcount(_Tp __t) noexcept { } return __ret; } +# endif // __has_builtin(__builtin_popcountg) } #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__bit/rotate.h b/third_party/libcxx/__bit/rotate.h index 5aa7518b3..d848056c3 100644 --- a/third_party/libcxx/__bit/rotate.h +++ b/third_party/libcxx/__bit/rotate.h @@ -20,29 +20,35 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -_Tp __rotr(_Tp __t, unsigned int __cnt) _NOEXCEPT -{ - static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__rotr requires an unsigned integer type"); - const unsigned int __dig = numeric_limits<_Tp>::digits; - if ((__cnt % __dig) == 0) - return __t; - return (__t >> (__cnt % __dig)) | (__t << (__dig - (__cnt % __dig))); +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __rotr(_Tp __t, int __cnt) _NOEXCEPT { + static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__rotr requires an unsigned integer type"); + const unsigned int __dig = numeric_limits<_Tp>::digits; + if ((__cnt % __dig) == 0) + return __t; + + if (__cnt < 0) { + __cnt *= -1; + return (__t << (__cnt % __dig)) | (__t >> (__dig - (__cnt % __dig))); // rotr with negative __cnt is similar to rotl + } + + return (__t >> (__cnt % __dig)) | (__t << (__dig - (__cnt % __dig))); +} + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __rotl(_Tp __t, int __cnt) _NOEXCEPT { + return std::__rotr(__t, -__cnt); } #if _LIBCPP_STD_VER >= 20 template <__libcpp_unsigned_integer _Tp> -_LIBCPP_HIDE_FROM_ABI constexpr _Tp rotl(_Tp __t, unsigned int __cnt) noexcept { - const unsigned int __dig = numeric_limits<_Tp>::digits; - if ((__cnt % __dig) == 0) - return __t; - return (__t << (__cnt % __dig)) | (__t >> (__dig - (__cnt % __dig))); +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotl(_Tp __t, int __cnt) noexcept { + return std::__rotl(__t, __cnt); } template <__libcpp_unsigned_integer _Tp> -_LIBCPP_HIDE_FROM_ABI constexpr _Tp rotr(_Tp __t, unsigned int __cnt) noexcept { +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotr(_Tp __t, int __cnt) noexcept { return std::__rotr(__t, __cnt); } diff --git a/third_party/libcxx/__bit_reference b/third_party/libcxx/__bit_reference index 95188ff68..606069d98 100644 --- a/third_party/libcxx/__bit_reference +++ b/third_party/libcxx/__bit_reference @@ -14,8 +14,10 @@ #include <__algorithm/fill_n.h> #include <__algorithm/min.h> #include <__bit/countr.h> +#include <__bit/invert_if.h> #include <__bit/popcount.h> #include <__config> +#include <__fwd/bit_reference.h> #include <__iterator/iterator_traits.h> #include <__memory/construct_at.h> #include <__memory/pointer_traits.h> @@ -30,1330 +32,975 @@ _LIBCPP_PUSH_MACROS #include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD -template class __bit_iterator; -template class __bit_const_reference; +template +class __bit_const_reference; template -struct __has_storage_type -{ - static const bool value = false; +struct __has_storage_type { + static const bool value = false; }; template ::value> -class __bit_reference -{ - typedef typename _Cp::__storage_type __storage_type; - typedef typename _Cp::__storage_pointer __storage_pointer; +class __bit_reference { + using __storage_type = typename _Cp::__storage_type; + using __storage_pointer = typename _Cp::__storage_pointer; - __storage_pointer __seg_; - __storage_type __mask_; + __storage_pointer __seg_; + __storage_type __mask_; - friend typename _Cp::__self; + friend typename _Cp::__self; + + friend class __bit_const_reference<_Cp>; + friend class __bit_iterator<_Cp, false>; - friend class __bit_const_reference<_Cp>; - friend class __bit_iterator<_Cp, false>; public: - using __container = typename _Cp::__self; + using __container = typename _Cp::__self; - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 - __bit_reference(const __bit_reference&) = default; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_reference(const __bit_reference&) = default; - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 operator bool() const _NOEXCEPT - {return static_cast(*__seg_ & __mask_);} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 bool operator ~() const _NOEXCEPT - {return !static_cast(*this);} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 operator bool() const _NOEXCEPT { + return static_cast(*__seg_ & __mask_); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool operator~() const _NOEXCEPT { + return !static_cast(*this); + } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 - __bit_reference& operator=(bool __x) _NOEXCEPT - { - if (__x) - *__seg_ |= __mask_; - else - *__seg_ &= ~__mask_; - return *this; - } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_reference& operator=(bool __x) _NOEXCEPT { + if (__x) + *__seg_ |= __mask_; + else + *__seg_ &= ~__mask_; + return *this; + } #if _LIBCPP_STD_VER >= 23 - _LIBCPP_HIDE_FROM_ABI constexpr const __bit_reference& operator=(bool __x) const noexcept { - if (__x) - *__seg_ |= __mask_; - else - *__seg_ &= ~__mask_; - return *this; - } + _LIBCPP_HIDE_FROM_ABI constexpr const __bit_reference& operator=(bool __x) const noexcept { + if (__x) + *__seg_ |= __mask_; + else + *__seg_ &= ~__mask_; + return *this; + } #endif - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 - __bit_reference& operator=(const __bit_reference& __x) _NOEXCEPT - {return operator=(static_cast(__x));} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_reference& operator=(const __bit_reference& __x) _NOEXCEPT { + return operator=(static_cast(__x)); + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void flip() _NOEXCEPT { *__seg_ ^= __mask_; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false> operator&() const _NOEXCEPT { + return __bit_iterator<_Cp, false>(__seg_, static_cast(std::__libcpp_ctz(__mask_))); + } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 void flip() _NOEXCEPT {*__seg_ ^= __mask_;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false> operator&() const _NOEXCEPT - {return __bit_iterator<_Cp, false>(__seg_, static_cast(std::__libcpp_ctz(__mask_)));} private: - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 - explicit __bit_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT - : __seg_(__s), __mask_(__m) {} + _LIBCPP_HIDE_FROM_ABI + _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __bit_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT + : __seg_(__s), + __mask_(__m) {} }; template -class __bit_reference<_Cp, false> -{ -}; +class __bit_reference<_Cp, false> {}; template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -void -swap(__bit_reference<_Cp> __x, __bit_reference<_Cp> __y) _NOEXCEPT -{ - bool __t = __x; - __x = __y; - __y = __t; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +swap(__bit_reference<_Cp> __x, __bit_reference<_Cp> __y) _NOEXCEPT { + bool __t = __x; + __x = __y; + __y = __t; } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -void -swap(__bit_reference<_Cp> __x, __bit_reference<_Dp> __y) _NOEXCEPT -{ - bool __t = __x; - __x = __y; - __y = __t; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void +swap(__bit_reference<_Cp> __x, __bit_reference<_Dp> __y) _NOEXCEPT { + bool __t = __x; + __x = __y; + __y = __t; } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -void -swap(__bit_reference<_Cp> __x, bool& __y) _NOEXCEPT -{ - bool __t = __x; - __x = __y; - __y = __t; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(__bit_reference<_Cp> __x, bool& __y) _NOEXCEPT { + bool __t = __x; + __x = __y; + __y = __t; } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -void -swap(bool& __x, __bit_reference<_Cp> __y) _NOEXCEPT -{ - bool __t = __x; - __x = __y; - __y = __t; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(bool& __x, __bit_reference<_Cp> __y) _NOEXCEPT { + bool __t = __x; + __x = __y; + __y = __t; } template -class __bit_const_reference -{ - typedef typename _Cp::__storage_type __storage_type; - typedef typename _Cp::__const_storage_pointer __storage_pointer; +class __bit_const_reference { + using __storage_type = typename _Cp::__storage_type; + using __storage_pointer = typename _Cp::__const_storage_pointer; - __storage_pointer __seg_; - __storage_type __mask_; + __storage_pointer __seg_; + __storage_type __mask_; + + friend typename _Cp::__self; + friend class __bit_iterator<_Cp, true>; - friend typename _Cp::__self; - friend class __bit_iterator<_Cp, true>; public: - using __container = typename _Cp::__self; + using __container = typename _Cp::__self; - _LIBCPP_INLINE_VISIBILITY - __bit_const_reference(const __bit_const_reference&) = default; + _LIBCPP_HIDE_FROM_ABI __bit_const_reference(const __bit_const_reference&) = default; + __bit_const_reference& operator=(const __bit_const_reference&) = delete; - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 - __bit_const_reference(const __bit_reference<_Cp>& __x) _NOEXCEPT - : __seg_(__x.__seg_), __mask_(__x.__mask_) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_const_reference(const __bit_reference<_Cp>& __x) _NOEXCEPT + : __seg_(__x.__seg_), + __mask_(__x.__mask_) {} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator bool() const _NOEXCEPT - {return static_cast(*__seg_ & __mask_);} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR operator bool() const _NOEXCEPT { + return static_cast(*__seg_ & __mask_); + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, true> operator&() const _NOEXCEPT { + return __bit_iterator<_Cp, true>(__seg_, static_cast(std::__libcpp_ctz(__mask_))); + } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, true> operator&() const _NOEXCEPT - {return __bit_iterator<_Cp, true>(__seg_, static_cast(std::__libcpp_ctz(__mask_)));} private: - _LIBCPP_INLINE_VISIBILITY - _LIBCPP_CONSTEXPR - explicit __bit_const_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT - : __seg_(__s), __mask_(__m) {} - - __bit_const_reference& operator=(const __bit_const_reference&) = delete; + _LIBCPP_HIDE_FROM_ABI + _LIBCPP_CONSTEXPR explicit __bit_const_reference(__storage_pointer __s, __storage_type __m) _NOEXCEPT + : __seg_(__s), + __mask_(__m) {} }; -// find - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, _IsConst> -__find_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) -{ - typedef __bit_iterator<_Cp, _IsConst> _It; - typedef typename _It::__storage_type __storage_type; - const int __bits_per_word = _It::__bits_per_word; - // do first partial word - if (__first.__ctz_ != 0) - { - __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); - __storage_type __dn = _VSTD::min(__clz_f, __n); - __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); - __storage_type __b = *__first.__seg_ & __m; - if (__b) - return _It(__first.__seg_, static_cast(_VSTD::__libcpp_ctz(__b))); - if (__n == __dn) - return __first + __n; - __n -= __dn; - ++__first.__seg_; - } - // do middle whole words - for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) - if (*__first.__seg_) - return _It(__first.__seg_, static_cast(_VSTD::__libcpp_ctz(*__first.__seg_))); - // do last partial word - if (__n > 0) - { - __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); - __storage_type __b = *__first.__seg_ & __m; - if (__b) - return _It(__first.__seg_, static_cast(_VSTD::__libcpp_ctz(__b))); - } - return _It(__first.__seg_, static_cast(__n)); -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, _IsConst> -__find_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) -{ - typedef __bit_iterator<_Cp, _IsConst> _It; - typedef typename _It::__storage_type __storage_type; - const int __bits_per_word = _It::__bits_per_word; - // do first partial word - if (__first.__ctz_ != 0) - { - __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); - __storage_type __dn = _VSTD::min(__clz_f, __n); - __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); - __storage_type __b = ~*__first.__seg_ & __m; - if (__b) - return _It(__first.__seg_, static_cast(_VSTD::__libcpp_ctz(__b))); - if (__n == __dn) - return __first + __n; - __n -= __dn; - ++__first.__seg_; - } - // do middle whole words - for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) - { - __storage_type __b = ~*__first.__seg_; - if (__b) - return _It(__first.__seg_, static_cast(_VSTD::__libcpp_ctz(__b))); - } - // do last partial word - if (__n > 0) - { - __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); - __storage_type __b = ~*__first.__seg_ & __m; - if (__b) - return _It(__first.__seg_, static_cast(_VSTD::__libcpp_ctz(__b))); - } - return _It(__first.__seg_, static_cast(__n)); -} - -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -__bit_iterator<_Cp, _IsConst> -find(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value) -{ - if (static_cast(__value)) - return _VSTD::__find_bool_true(__first, static_cast(__last - __first)); - return _VSTD::__find_bool_false(__first, static_cast(__last - __first)); -} - -// count - -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 typename __bit_iterator<_Cp, _IsConst>::difference_type -__count_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) -{ - typedef __bit_iterator<_Cp, _IsConst> _It; - typedef typename _It::__storage_type __storage_type; - typedef typename _It::difference_type difference_type; - const int __bits_per_word = _It::__bits_per_word; - difference_type __r = 0; - // do first partial word - if (__first.__ctz_ != 0) - { - __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); - __storage_type __dn = _VSTD::min(__clz_f, __n); - __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); - __r = _VSTD::__libcpp_popcount(*__first.__seg_ & __m); - __n -= __dn; - ++__first.__seg_; - } - // do middle whole words - for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) - __r += _VSTD::__libcpp_popcount(*__first.__seg_); - // do last partial word - if (__n > 0) - { - __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); - __r += _VSTD::__libcpp_popcount(*__first.__seg_ & __m); - } - return __r; -} - -template -_LIBCPP_HIDE_FROM_ABI typename __bit_iterator<_Cp, _IsConst>::difference_type -__count_bool_false(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n) -{ - typedef __bit_iterator<_Cp, _IsConst> _It; - typedef typename _It::__storage_type __storage_type; - typedef typename _It::difference_type difference_type; - const int __bits_per_word = _It::__bits_per_word; - difference_type __r = 0; - // do first partial word - if (__first.__ctz_ != 0) - { - __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); - __storage_type __dn = _VSTD::min(__clz_f, __n); - __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); - __r = _VSTD::__libcpp_popcount(~*__first.__seg_ & __m); - __n -= __dn; - ++__first.__seg_; - } - // do middle whole words - for (; __n >= __bits_per_word; ++__first.__seg_, __n -= __bits_per_word) - __r += _VSTD::__libcpp_popcount(~*__first.__seg_); - // do last partial word - if (__n > 0) - { - __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); - __r += _VSTD::__libcpp_popcount(~*__first.__seg_ & __m); - } - return __r; -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename __bit_iterator<_Cp, _IsConst>::difference_type -count(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, const _Tp& __value) -{ - if (static_cast(__value)) - return _VSTD::__count_bool_true(__first, static_cast(__last - __first)); - return _VSTD::__count_bool_false(__first, static_cast(__last - __first)); -} - -// fill_n - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void -__fill_n_false(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n) -{ - typedef __bit_iterator<_Cp, false> _It; - typedef typename _It::__storage_type __storage_type; - const int __bits_per_word = _It::__bits_per_word; - // do first partial word - if (__first.__ctz_ != 0) - { - __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); - __storage_type __dn = _VSTD::min(__clz_f, __n); - __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); - *__first.__seg_ &= ~__m; - __n -= __dn; - ++__first.__seg_; - } - // do middle whole words - __storage_type __nw = __n / __bits_per_word; - std::fill_n(std::__to_address(__first.__seg_), __nw, 0); - __n -= __nw * __bits_per_word; - // do last partial word - if (__n > 0) - { - __first.__seg_ += __nw; - __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); - *__first.__seg_ &= ~__m; - } -} - -template -_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void -__fill_n_true(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n) -{ - typedef __bit_iterator<_Cp, false> _It; - typedef typename _It::__storage_type __storage_type; - const int __bits_per_word = _It::__bits_per_word; - // do first partial word - if (__first.__ctz_ != 0) - { - __storage_type __clz_f = static_cast<__storage_type>(__bits_per_word - __first.__ctz_); - __storage_type __dn = _VSTD::min(__clz_f, __n); - __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); - *__first.__seg_ |= __m; - __n -= __dn; - ++__first.__seg_; - } - // do middle whole words - __storage_type __nw = __n / __bits_per_word; - // __storage_type is always an unsigned type, so -1 sets all bits - std::fill_n(std::__to_address(__first.__seg_), __nw, static_cast<__storage_type>(-1)); - __n -= __nw * __bits_per_word; - // do last partial word - if (__n > 0) - { - __first.__seg_ += __nw; - __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); - *__first.__seg_ |= __m; - } -} - -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -void -fill_n(__bit_iterator<_Cp, false> __first, typename _Cp::size_type __n, bool __value) -{ - if (__n > 0) - { - if (__value) - _VSTD::__fill_n_true(__first, __n); - else - _VSTD::__fill_n_false(__first, __n); - } -} - -// fill - -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -void -fill(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __last, bool __value) -{ - _VSTD::fill_n(__first, static_cast(__last - __first), __value); -} - // copy template -_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> -__copy_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, - __bit_iterator<_Cp, false> __result) -{ - typedef __bit_iterator<_Cp, _IsConst> _In; - typedef typename _In::difference_type difference_type; - typedef typename _In::__storage_type __storage_type; - const int __bits_per_word = _In::__bits_per_word; - difference_type __n = __last - __first; - if (__n > 0) - { - // do first word - if (__first.__ctz_ != 0) - { - unsigned __clz = __bits_per_word - __first.__ctz_; - difference_type __dn = _VSTD::min(static_cast(__clz), __n); - __n -= __dn; - __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); - __storage_type __b = *__first.__seg_ & __m; - *__result.__seg_ &= ~__m; - *__result.__seg_ |= __b; - __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; - __result.__ctz_ = static_cast((__dn + __result.__ctz_) % __bits_per_word); - ++__first.__seg_; - // __first.__ctz_ = 0; - } - // __first.__ctz_ == 0; - // do middle words - __storage_type __nw = __n / __bits_per_word; - std::copy_n(std::__to_address(__first.__seg_), __nw, std::__to_address(__result.__seg_)); - __n -= __nw * __bits_per_word; - __result.__seg_ += __nw; - // do last word - if (__n > 0) - { - __first.__seg_ += __nw; - __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); - __storage_type __b = *__first.__seg_ & __m; - *__result.__seg_ &= ~__m; - *__result.__seg_ |= __b; - __result.__ctz_ = static_cast(__n); - } +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_aligned( + __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { + using _In = __bit_iterator<_Cp, _IsConst>; + using difference_type = typename _In::difference_type; + using __storage_type = typename _In::__storage_type; + + const int __bits_per_word = _In::__bits_per_word; + difference_type __n = __last - __first; + if (__n > 0) { + // do first word + if (__first.__ctz_ != 0) { + unsigned __clz = __bits_per_word - __first.__ctz_; + difference_type __dn = std::min(static_cast(__clz), __n); + __n -= __dn; + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); + __storage_type __b = *__first.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b; + __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; + __result.__ctz_ = static_cast((__dn + __result.__ctz_) % __bits_per_word); + ++__first.__seg_; + // __first.__ctz_ = 0; } - return __result; + // __first.__ctz_ == 0; + // do middle words + __storage_type __nw = __n / __bits_per_word; + std::copy_n(std::__to_address(__first.__seg_), __nw, std::__to_address(__result.__seg_)); + __n -= __nw * __bits_per_word; + __result.__seg_ += __nw; + // do last word + if (__n > 0) { + __first.__seg_ += __nw; + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + __storage_type __b = *__first.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b; + __result.__ctz_ = static_cast(__n); + } + } + return __result; } template -_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> -__copy_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, - __bit_iterator<_Cp, false> __result) -{ - typedef __bit_iterator<_Cp, _IsConst> _In; - typedef typename _In::difference_type difference_type; - typedef typename _In::__storage_type __storage_type; - const int __bits_per_word = _In::__bits_per_word; - difference_type __n = __last - __first; - if (__n > 0) - { - // do first word - if (__first.__ctz_ != 0) - { - unsigned __clz_f = __bits_per_word - __first.__ctz_; - difference_type __dn = _VSTD::min(static_cast(__clz_f), __n); - __n -= __dn; - __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); - __storage_type __b = *__first.__seg_ & __m; - unsigned __clz_r = __bits_per_word - __result.__ctz_; - __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r); - __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); - *__result.__seg_ &= ~__m; - if (__result.__ctz_ > __first.__ctz_) - *__result.__seg_ |= __b << (__result.__ctz_ - __first.__ctz_); - else - *__result.__seg_ |= __b >> (__first.__ctz_ - __result.__ctz_); - __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word; - __result.__ctz_ = static_cast((__ddn + __result.__ctz_) % __bits_per_word); - __dn -= __ddn; - if (__dn > 0) - { - __m = ~__storage_type(0) >> (__bits_per_word - __dn); - *__result.__seg_ &= ~__m; - *__result.__seg_ |= __b >> (__first.__ctz_ + __ddn); - __result.__ctz_ = static_cast(__dn); - } - ++__first.__seg_; - // __first.__ctz_ = 0; - } - // __first.__ctz_ == 0; - // do middle words - unsigned __clz_r = __bits_per_word - __result.__ctz_; - __storage_type __m = ~__storage_type(0) << __result.__ctz_; - for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) - { - __storage_type __b = *__first.__seg_; - *__result.__seg_ &= ~__m; - *__result.__seg_ |= __b << __result.__ctz_; - ++__result.__seg_; - *__result.__seg_ &= __m; - *__result.__seg_ |= __b >> __clz_r; - } - // do last word - if (__n > 0) - { - __m = ~__storage_type(0) >> (__bits_per_word - __n); - __storage_type __b = *__first.__seg_ & __m; - __storage_type __dn = _VSTD::min(__n, static_cast(__clz_r)); - __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); - *__result.__seg_ &= ~__m; - *__result.__seg_ |= __b << __result.__ctz_; - __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; - __result.__ctz_ = static_cast((__dn + __result.__ctz_) % __bits_per_word); - __n -= __dn; - if (__n > 0) - { - __m = ~__storage_type(0) >> (__bits_per_word - __n); - *__result.__seg_ &= ~__m; - *__result.__seg_ |= __b >> __dn; - __result.__ctz_ = static_cast(__n); - } - } +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_unaligned( + __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { + using _In = __bit_iterator<_Cp, _IsConst>; + using difference_type = typename _In::difference_type; + using __storage_type = typename _In::__storage_type; + + const int __bits_per_word = _In::__bits_per_word; + difference_type __n = __last - __first; + if (__n > 0) { + // do first word + if (__first.__ctz_ != 0) { + unsigned __clz_f = __bits_per_word - __first.__ctz_; + difference_type __dn = std::min(static_cast(__clz_f), __n); + __n -= __dn; + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + __storage_type __b = *__first.__seg_ & __m; + unsigned __clz_r = __bits_per_word - __result.__ctz_; + __storage_type __ddn = std::min<__storage_type>(__dn, __clz_r); + __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); + *__result.__seg_ &= ~__m; + if (__result.__ctz_ > __first.__ctz_) + *__result.__seg_ |= __b << (__result.__ctz_ - __first.__ctz_); + else + *__result.__seg_ |= __b >> (__first.__ctz_ - __result.__ctz_); + __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word; + __result.__ctz_ = static_cast((__ddn + __result.__ctz_) % __bits_per_word); + __dn -= __ddn; + if (__dn > 0) { + __m = ~__storage_type(0) >> (__bits_per_word - __dn); + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b >> (__first.__ctz_ + __ddn); + __result.__ctz_ = static_cast(__dn); + } + ++__first.__seg_; + // __first.__ctz_ = 0; } - return __result; + // __first.__ctz_ == 0; + // do middle words + unsigned __clz_r = __bits_per_word - __result.__ctz_; + __storage_type __m = ~__storage_type(0) << __result.__ctz_; + for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) { + __storage_type __b = *__first.__seg_; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b << __result.__ctz_; + ++__result.__seg_; + *__result.__seg_ &= __m; + *__result.__seg_ |= __b >> __clz_r; + } + // do last word + if (__n > 0) { + __m = ~__storage_type(0) >> (__bits_per_word - __n); + __storage_type __b = *__first.__seg_ & __m; + __storage_type __dn = std::min(__n, static_cast(__clz_r)); + __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b << __result.__ctz_; + __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; + __result.__ctz_ = static_cast((__dn + __result.__ctz_) % __bits_per_word); + __n -= __dn; + if (__n > 0) { + __m = ~__storage_type(0) >> (__bits_per_word - __n); + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b >> __dn; + __result.__ctz_ = static_cast(__n); + } + } + } + return __result; } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -__bit_iterator<_Cp, false> -copy(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) -{ - if (__first.__ctz_ == __result.__ctz_) - return _VSTD::__copy_aligned(__first, __last, __result); - return _VSTD::__copy_unaligned(__first, __last, __result); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false> +copy(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { + if (__first.__ctz_ == __result.__ctz_) + return std::__copy_aligned(__first, __last, __result); + return std::__copy_unaligned(__first, __last, __result); } // copy_backward template -_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> -__copy_backward_aligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, - __bit_iterator<_Cp, false> __result) -{ - typedef __bit_iterator<_Cp, _IsConst> _In; - typedef typename _In::difference_type difference_type; - typedef typename _In::__storage_type __storage_type; - const int __bits_per_word = _In::__bits_per_word; - difference_type __n = __last - __first; - if (__n > 0) - { - // do first word - if (__last.__ctz_ != 0) - { - difference_type __dn = _VSTD::min(static_cast(__last.__ctz_), __n); - __n -= __dn; - unsigned __clz = __bits_per_word - __last.__ctz_; - __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz); - __storage_type __b = *__last.__seg_ & __m; - *__result.__seg_ &= ~__m; - *__result.__seg_ |= __b; - __result.__ctz_ = static_cast(((-__dn & (__bits_per_word - 1)) + - __result.__ctz_) % __bits_per_word); - // __last.__ctz_ = 0 - } - // __last.__ctz_ == 0 || __n == 0 - // __result.__ctz_ == 0 || __n == 0 - // do middle words - __storage_type __nw = __n / __bits_per_word; - __result.__seg_ -= __nw; - __last.__seg_ -= __nw; - std::copy_n(std::__to_address(__last.__seg_), __nw, std::__to_address(__result.__seg_)); - __n -= __nw * __bits_per_word; - // do last word - if (__n > 0) - { - __storage_type __m = ~__storage_type(0) << (__bits_per_word - __n); - __storage_type __b = *--__last.__seg_ & __m; - *--__result.__seg_ &= ~__m; - *__result.__seg_ |= __b; - __result.__ctz_ = static_cast(-__n & (__bits_per_word - 1)); - } +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_backward_aligned( + __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { + using _In = __bit_iterator<_Cp, _IsConst>; + using difference_type = typename _In::difference_type; + using __storage_type = typename _In::__storage_type; + + const int __bits_per_word = _In::__bits_per_word; + difference_type __n = __last - __first; + if (__n > 0) { + // do first word + if (__last.__ctz_ != 0) { + difference_type __dn = std::min(static_cast(__last.__ctz_), __n); + __n -= __dn; + unsigned __clz = __bits_per_word - __last.__ctz_; + __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz); + __storage_type __b = *__last.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b; + __result.__ctz_ = static_cast(((-__dn & (__bits_per_word - 1)) + __result.__ctz_) % __bits_per_word); + // __last.__ctz_ = 0 } - return __result; + // __last.__ctz_ == 0 || __n == 0 + // __result.__ctz_ == 0 || __n == 0 + // do middle words + __storage_type __nw = __n / __bits_per_word; + __result.__seg_ -= __nw; + __last.__seg_ -= __nw; + std::copy_n(std::__to_address(__last.__seg_), __nw, std::__to_address(__result.__seg_)); + __n -= __nw * __bits_per_word; + // do last word + if (__n > 0) { + __storage_type __m = ~__storage_type(0) << (__bits_per_word - __n); + __storage_type __b = *--__last.__seg_ & __m; + *--__result.__seg_ &= ~__m; + *__result.__seg_ |= __b; + __result.__ctz_ = static_cast(-__n & (__bits_per_word - 1)); + } + } + return __result; } template -_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> -__copy_backward_unaligned(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, - __bit_iterator<_Cp, false> __result) -{ - typedef __bit_iterator<_Cp, _IsConst> _In; - typedef typename _In::difference_type difference_type; - typedef typename _In::__storage_type __storage_type; - const int __bits_per_word = _In::__bits_per_word; - difference_type __n = __last - __first; - if (__n > 0) - { - // do first word - if (__last.__ctz_ != 0) - { - difference_type __dn = _VSTD::min(static_cast(__last.__ctz_), __n); - __n -= __dn; - unsigned __clz_l = __bits_per_word - __last.__ctz_; - __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_l); - __storage_type __b = *__last.__seg_ & __m; - unsigned __clz_r = __bits_per_word - __result.__ctz_; - __storage_type __ddn = _VSTD::min(__dn, static_cast(__result.__ctz_)); - if (__ddn > 0) - { - __m = (~__storage_type(0) << (__result.__ctz_ - __ddn)) & (~__storage_type(0) >> __clz_r); - *__result.__seg_ &= ~__m; - if (__result.__ctz_ > __last.__ctz_) - *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_); - else - *__result.__seg_ |= __b >> (__last.__ctz_ - __result.__ctz_); - __result.__ctz_ = static_cast(((-__ddn & (__bits_per_word - 1)) + - __result.__ctz_) % __bits_per_word); - __dn -= __ddn; - } - if (__dn > 0) - { - // __result.__ctz_ == 0 - --__result.__seg_; - __result.__ctz_ = static_cast(-__dn & (__bits_per_word - 1)); - __m = ~__storage_type(0) << __result.__ctz_; - *__result.__seg_ &= ~__m; - __last.__ctz_ -= __dn + __ddn; - *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_); - } - // __last.__ctz_ = 0 - } - // __last.__ctz_ == 0 || __n == 0 - // __result.__ctz_ != 0 || __n == 0 - // do middle words - unsigned __clz_r = __bits_per_word - __result.__ctz_; - __storage_type __m = ~__storage_type(0) >> __clz_r; - for (; __n >= __bits_per_word; __n -= __bits_per_word) - { - __storage_type __b = *--__last.__seg_; - *__result.__seg_ &= ~__m; - *__result.__seg_ |= __b >> __clz_r; - *--__result.__seg_ &= __m; - *__result.__seg_ |= __b << __result.__ctz_; - } - // do last word - if (__n > 0) - { - __m = ~__storage_type(0) << (__bits_per_word - __n); - __storage_type __b = *--__last.__seg_ & __m; - __clz_r = __bits_per_word - __result.__ctz_; - __storage_type __dn = _VSTD::min(__n, static_cast(__result.__ctz_)); - __m = (~__storage_type(0) << (__result.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_r); - *__result.__seg_ &= ~__m; - *__result.__seg_ |= __b >> (__bits_per_word - __result.__ctz_); - __result.__ctz_ = static_cast(((-__dn & (__bits_per_word - 1)) + - __result.__ctz_) % __bits_per_word); - __n -= __dn; - if (__n > 0) - { - // __result.__ctz_ == 0 - --__result.__seg_; - __result.__ctz_ = static_cast(-__n & (__bits_per_word - 1)); - __m = ~__storage_type(0) << __result.__ctz_; - *__result.__seg_ &= ~__m; - *__result.__seg_ |= __b << (__result.__ctz_ - (__bits_per_word - __n - __dn)); - } - } +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> __copy_backward_unaligned( + __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { + using _In = __bit_iterator<_Cp, _IsConst>; + using difference_type = typename _In::difference_type; + using __storage_type = typename _In::__storage_type; + + const int __bits_per_word = _In::__bits_per_word; + difference_type __n = __last - __first; + if (__n > 0) { + // do first word + if (__last.__ctz_ != 0) { + difference_type __dn = std::min(static_cast(__last.__ctz_), __n); + __n -= __dn; + unsigned __clz_l = __bits_per_word - __last.__ctz_; + __storage_type __m = (~__storage_type(0) << (__last.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_l); + __storage_type __b = *__last.__seg_ & __m; + unsigned __clz_r = __bits_per_word - __result.__ctz_; + __storage_type __ddn = std::min(__dn, static_cast(__result.__ctz_)); + if (__ddn > 0) { + __m = (~__storage_type(0) << (__result.__ctz_ - __ddn)) & (~__storage_type(0) >> __clz_r); + *__result.__seg_ &= ~__m; + if (__result.__ctz_ > __last.__ctz_) + *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_); + else + *__result.__seg_ |= __b >> (__last.__ctz_ - __result.__ctz_); + __result.__ctz_ = static_cast(((-__ddn & (__bits_per_word - 1)) + __result.__ctz_) % __bits_per_word); + __dn -= __ddn; + } + if (__dn > 0) { + // __result.__ctz_ == 0 + --__result.__seg_; + __result.__ctz_ = static_cast(-__dn & (__bits_per_word - 1)); + __m = ~__storage_type(0) << __result.__ctz_; + *__result.__seg_ &= ~__m; + __last.__ctz_ -= __dn + __ddn; + *__result.__seg_ |= __b << (__result.__ctz_ - __last.__ctz_); + } + // __last.__ctz_ = 0 } - return __result; + // __last.__ctz_ == 0 || __n == 0 + // __result.__ctz_ != 0 || __n == 0 + // do middle words + unsigned __clz_r = __bits_per_word - __result.__ctz_; + __storage_type __m = ~__storage_type(0) >> __clz_r; + for (; __n >= __bits_per_word; __n -= __bits_per_word) { + __storage_type __b = *--__last.__seg_; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b >> __clz_r; + *--__result.__seg_ &= __m; + *__result.__seg_ |= __b << __result.__ctz_; + } + // do last word + if (__n > 0) { + __m = ~__storage_type(0) << (__bits_per_word - __n); + __storage_type __b = *--__last.__seg_ & __m; + __clz_r = __bits_per_word - __result.__ctz_; + __storage_type __dn = std::min(__n, static_cast(__result.__ctz_)); + __m = (~__storage_type(0) << (__result.__ctz_ - __dn)) & (~__storage_type(0) >> __clz_r); + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b >> (__bits_per_word - __result.__ctz_); + __result.__ctz_ = static_cast(((-__dn & (__bits_per_word - 1)) + __result.__ctz_) % __bits_per_word); + __n -= __dn; + if (__n > 0) { + // __result.__ctz_ == 0 + --__result.__seg_; + __result.__ctz_ = static_cast(-__n & (__bits_per_word - 1)); + __m = ~__storage_type(0) << __result.__ctz_; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b << (__result.__ctz_ - (__bits_per_word - __n - __dn)); + } + } + } + return __result; } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -__bit_iterator<_Cp, false> -copy_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) -{ - if (__last.__ctz_ == __result.__ctz_) - return _VSTD::__copy_backward_aligned(__first, __last, __result); - return _VSTD::__copy_backward_unaligned(__first, __last, __result); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator<_Cp, false> copy_backward( + __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { + if (__last.__ctz_ == __result.__ctz_) + return std::__copy_backward_aligned(__first, __last, __result); + return std::__copy_backward_unaligned(__first, __last, __result); } // move template -inline _LIBCPP_INLINE_VISIBILITY -__bit_iterator<_Cp, false> -move(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) -{ - return _VSTD::copy(__first, __last, __result); +inline _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> +move(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { + return std::copy(__first, __last, __result); } // move_backward template -inline _LIBCPP_INLINE_VISIBILITY -__bit_iterator<_Cp, false> -move_backward(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) -{ - return _VSTD::copy_backward(__first, __last, __result); +inline _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> move_backward( + __bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last, __bit_iterator<_Cp, false> __result) { + return std::copy_backward(__first, __last, __result); } // swap_ranges -template -_LIBCPP_HIDE_FROM_ABI __bit_iterator<__C2, false> -__swap_ranges_aligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last, - __bit_iterator<__C2, false> __result) -{ - typedef __bit_iterator<__C1, false> _I1; - typedef typename _I1::difference_type difference_type; - typedef typename _I1::__storage_type __storage_type; - const int __bits_per_word = _I1::__bits_per_word; - difference_type __n = __last - __first; - if (__n > 0) - { - // do first word - if (__first.__ctz_ != 0) - { - unsigned __clz = __bits_per_word - __first.__ctz_; - difference_type __dn = _VSTD::min(static_cast(__clz), __n); - __n -= __dn; - __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); - __storage_type __b1 = *__first.__seg_ & __m; - *__first.__seg_ &= ~__m; - __storage_type __b2 = *__result.__seg_ & __m; - *__result.__seg_ &= ~__m; - *__result.__seg_ |= __b1; - *__first.__seg_ |= __b2; - __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; - __result.__ctz_ = static_cast((__dn + __result.__ctz_) % __bits_per_word); - ++__first.__seg_; - // __first.__ctz_ = 0; - } - // __first.__ctz_ == 0; - // do middle words - for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_, ++__result.__seg_) - swap(*__first.__seg_, *__result.__seg_); - // do last word - if (__n > 0) - { - __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); - __storage_type __b1 = *__first.__seg_ & __m; - *__first.__seg_ &= ~__m; - __storage_type __b2 = *__result.__seg_ & __m; - *__result.__seg_ &= ~__m; - *__result.__seg_ |= __b1; - *__first.__seg_ |= __b2; - __result.__ctz_ = static_cast(__n); - } +template +_LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false> __swap_ranges_aligned( + __bit_iterator<_Cl, false> __first, __bit_iterator<_Cl, false> __last, __bit_iterator<_Cr, false> __result) { + using _I1 = __bit_iterator<_Cl, false>; + using difference_type = typename _I1::difference_type; + using __storage_type = typename _I1::__storage_type; + + const int __bits_per_word = _I1::__bits_per_word; + difference_type __n = __last - __first; + if (__n > 0) { + // do first word + if (__first.__ctz_ != 0) { + unsigned __clz = __bits_per_word - __first.__ctz_; + difference_type __dn = std::min(static_cast(__clz), __n); + __n -= __dn; + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); + __storage_type __b1 = *__first.__seg_ & __m; + *__first.__seg_ &= ~__m; + __storage_type __b2 = *__result.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b1; + *__first.__seg_ |= __b2; + __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; + __result.__ctz_ = static_cast((__dn + __result.__ctz_) % __bits_per_word); + ++__first.__seg_; + // __first.__ctz_ = 0; } - return __result; + // __first.__ctz_ == 0; + // do middle words + for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_, ++__result.__seg_) + swap(*__first.__seg_, *__result.__seg_); + // do last word + if (__n > 0) { + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + __storage_type __b1 = *__first.__seg_ & __m; + *__first.__seg_ &= ~__m; + __storage_type __b2 = *__result.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b1; + *__first.__seg_ |= __b2; + __result.__ctz_ = static_cast(__n); + } + } + return __result; } -template -_LIBCPP_HIDE_FROM_ABI __bit_iterator<__C2, false> -__swap_ranges_unaligned(__bit_iterator<__C1, false> __first, __bit_iterator<__C1, false> __last, - __bit_iterator<__C2, false> __result) -{ - typedef __bit_iterator<__C1, false> _I1; - typedef typename _I1::difference_type difference_type; - typedef typename _I1::__storage_type __storage_type; - const int __bits_per_word = _I1::__bits_per_word; - difference_type __n = __last - __first; - if (__n > 0) - { - // do first word - if (__first.__ctz_ != 0) - { - unsigned __clz_f = __bits_per_word - __first.__ctz_; - difference_type __dn = _VSTD::min(static_cast(__clz_f), __n); - __n -= __dn; - __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); - __storage_type __b1 = *__first.__seg_ & __m; - *__first.__seg_ &= ~__m; - unsigned __clz_r = __bits_per_word - __result.__ctz_; - __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r); - __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); - __storage_type __b2 = *__result.__seg_ & __m; - *__result.__seg_ &= ~__m; - if (__result.__ctz_ > __first.__ctz_) - { - unsigned __s = __result.__ctz_ - __first.__ctz_; - *__result.__seg_ |= __b1 << __s; - *__first.__seg_ |= __b2 >> __s; - } - else - { - unsigned __s = __first.__ctz_ - __result.__ctz_; - *__result.__seg_ |= __b1 >> __s; - *__first.__seg_ |= __b2 << __s; - } - __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word; - __result.__ctz_ = static_cast((__ddn + __result.__ctz_) % __bits_per_word); - __dn -= __ddn; - if (__dn > 0) - { - __m = ~__storage_type(0) >> (__bits_per_word - __dn); - __b2 = *__result.__seg_ & __m; - *__result.__seg_ &= ~__m; - unsigned __s = __first.__ctz_ + __ddn; - *__result.__seg_ |= __b1 >> __s; - *__first.__seg_ |= __b2 << __s; - __result.__ctz_ = static_cast(__dn); - } - ++__first.__seg_; - // __first.__ctz_ = 0; - } - // __first.__ctz_ == 0; - // do middle words - __storage_type __m = ~__storage_type(0) << __result.__ctz_; - unsigned __clz_r = __bits_per_word - __result.__ctz_; - for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) - { - __storage_type __b1 = *__first.__seg_; - __storage_type __b2 = *__result.__seg_ & __m; - *__result.__seg_ &= ~__m; - *__result.__seg_ |= __b1 << __result.__ctz_; - *__first.__seg_ = __b2 >> __result.__ctz_; - ++__result.__seg_; - __b2 = *__result.__seg_ & ~__m; - *__result.__seg_ &= __m; - *__result.__seg_ |= __b1 >> __clz_r; - *__first.__seg_ |= __b2 << __clz_r; - } - // do last word - if (__n > 0) - { - __m = ~__storage_type(0) >> (__bits_per_word - __n); - __storage_type __b1 = *__first.__seg_ & __m; - *__first.__seg_ &= ~__m; - __storage_type __dn = _VSTD::min<__storage_type>(__n, __clz_r); - __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); - __storage_type __b2 = *__result.__seg_ & __m; - *__result.__seg_ &= ~__m; - *__result.__seg_ |= __b1 << __result.__ctz_; - *__first.__seg_ |= __b2 >> __result.__ctz_; - __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; - __result.__ctz_ = static_cast((__dn + __result.__ctz_) % __bits_per_word); - __n -= __dn; - if (__n > 0) - { - __m = ~__storage_type(0) >> (__bits_per_word - __n); - __b2 = *__result.__seg_ & __m; - *__result.__seg_ &= ~__m; - *__result.__seg_ |= __b1 >> __dn; - *__first.__seg_ |= __b2 << __dn; - __result.__ctz_ = static_cast(__n); - } - } +template +_LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false> __swap_ranges_unaligned( + __bit_iterator<_Cl, false> __first, __bit_iterator<_Cl, false> __last, __bit_iterator<_Cr, false> __result) { + using _I1 = __bit_iterator<_Cl, false>; + using difference_type = typename _I1::difference_type; + using __storage_type = typename _I1::__storage_type; + + const int __bits_per_word = _I1::__bits_per_word; + difference_type __n = __last - __first; + if (__n > 0) { + // do first word + if (__first.__ctz_ != 0) { + unsigned __clz_f = __bits_per_word - __first.__ctz_; + difference_type __dn = std::min(static_cast(__clz_f), __n); + __n -= __dn; + __storage_type __m = (~__storage_type(0) << __first.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + __storage_type __b1 = *__first.__seg_ & __m; + *__first.__seg_ &= ~__m; + unsigned __clz_r = __bits_per_word - __result.__ctz_; + __storage_type __ddn = std::min<__storage_type>(__dn, __clz_r); + __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); + __storage_type __b2 = *__result.__seg_ & __m; + *__result.__seg_ &= ~__m; + if (__result.__ctz_ > __first.__ctz_) { + unsigned __s = __result.__ctz_ - __first.__ctz_; + *__result.__seg_ |= __b1 << __s; + *__first.__seg_ |= __b2 >> __s; + } else { + unsigned __s = __first.__ctz_ - __result.__ctz_; + *__result.__seg_ |= __b1 >> __s; + *__first.__seg_ |= __b2 << __s; + } + __result.__seg_ += (__ddn + __result.__ctz_) / __bits_per_word; + __result.__ctz_ = static_cast((__ddn + __result.__ctz_) % __bits_per_word); + __dn -= __ddn; + if (__dn > 0) { + __m = ~__storage_type(0) >> (__bits_per_word - __dn); + __b2 = *__result.__seg_ & __m; + *__result.__seg_ &= ~__m; + unsigned __s = __first.__ctz_ + __ddn; + *__result.__seg_ |= __b1 >> __s; + *__first.__seg_ |= __b2 << __s; + __result.__ctz_ = static_cast(__dn); + } + ++__first.__seg_; + // __first.__ctz_ = 0; } - return __result; + // __first.__ctz_ == 0; + // do middle words + __storage_type __m = ~__storage_type(0) << __result.__ctz_; + unsigned __clz_r = __bits_per_word - __result.__ctz_; + for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first.__seg_) { + __storage_type __b1 = *__first.__seg_; + __storage_type __b2 = *__result.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b1 << __result.__ctz_; + *__first.__seg_ = __b2 >> __result.__ctz_; + ++__result.__seg_; + __b2 = *__result.__seg_ & ~__m; + *__result.__seg_ &= __m; + *__result.__seg_ |= __b1 >> __clz_r; + *__first.__seg_ |= __b2 << __clz_r; + } + // do last word + if (__n > 0) { + __m = ~__storage_type(0) >> (__bits_per_word - __n); + __storage_type __b1 = *__first.__seg_ & __m; + *__first.__seg_ &= ~__m; + __storage_type __dn = std::min<__storage_type>(__n, __clz_r); + __m = (~__storage_type(0) << __result.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); + __storage_type __b2 = *__result.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b1 << __result.__ctz_; + *__first.__seg_ |= __b2 >> __result.__ctz_; + __result.__seg_ += (__dn + __result.__ctz_) / __bits_per_word; + __result.__ctz_ = static_cast((__dn + __result.__ctz_) % __bits_per_word); + __n -= __dn; + if (__n > 0) { + __m = ~__storage_type(0) >> (__bits_per_word - __n); + __b2 = *__result.__seg_ & __m; + *__result.__seg_ &= ~__m; + *__result.__seg_ |= __b1 >> __dn; + *__first.__seg_ |= __b2 << __dn; + __result.__ctz_ = static_cast(__n); + } + } + } + return __result; } -template -inline _LIBCPP_INLINE_VISIBILITY -__bit_iterator<__C2, false> -swap_ranges(__bit_iterator<__C1, false> __first1, __bit_iterator<__C1, false> __last1, - __bit_iterator<__C2, false> __first2) -{ - if (__first1.__ctz_ == __first2.__ctz_) - return _VSTD::__swap_ranges_aligned(__first1, __last1, __first2); - return _VSTD::__swap_ranges_unaligned(__first1, __last1, __first2); +template +inline _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cr, false> swap_ranges( + __bit_iterator<_Cl, false> __first1, __bit_iterator<_Cl, false> __last1, __bit_iterator<_Cr, false> __first2) { + if (__first1.__ctz_ == __first2.__ctz_) + return std::__swap_ranges_aligned(__first1, __last1, __first2); + return std::__swap_ranges_unaligned(__first1, __last1, __first2); } // rotate template -struct __bit_array -{ - typedef typename _Cp::difference_type difference_type; - typedef typename _Cp::__storage_type __storage_type; - typedef typename _Cp::__storage_pointer __storage_pointer; - typedef typename _Cp::iterator iterator; - static const unsigned __bits_per_word = _Cp::__bits_per_word; - static const unsigned _Np = 4; +struct __bit_array { + using difference_type = typename _Cp::difference_type; + using __storage_type = typename _Cp::__storage_type; + using __storage_pointer = typename _Cp::__storage_pointer; + using iterator = typename _Cp::iterator; - difference_type __size_; - __storage_type __word_[_Np]; + static const unsigned __bits_per_word = _Cp::__bits_per_word; + static const unsigned _Np = 4; - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 static difference_type capacity() - {return static_cast(_Np * __bits_per_word);} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __bit_array(difference_type __s) : __size_(__s) { - if (__libcpp_is_constant_evaluated()) { - for (size_t __i = 0; __i != __bit_array<_Cp>::_Np; ++__i) - std::__construct_at(__word_ + __i, 0); - } - } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator begin() - { - return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]), 0); - } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator end() - { - return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]) + __size_ / __bits_per_word, - static_cast(__size_ % __bits_per_word)); + difference_type __size_; + __storage_type __word_[_Np]; + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 static difference_type capacity() { + return static_cast(_Np * __bits_per_word); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __bit_array(difference_type __s) : __size_(__s) { + if (__libcpp_is_constant_evaluated()) { + for (size_t __i = 0; __i != __bit_array<_Cp>::_Np; ++__i) + std::__construct_at(__word_ + __i, 0); } + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator begin() { + return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]), 0); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator end() { + return iterator(pointer_traits<__storage_pointer>::pointer_to(__word_[0]) + __size_ / __bits_per_word, + static_cast(__size_ % __bits_per_word)); + } }; template _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __bit_iterator<_Cp, false> -rotate(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __middle, __bit_iterator<_Cp, false> __last) -{ - typedef __bit_iterator<_Cp, false> _I1; - typedef typename _I1::difference_type difference_type; - difference_type __d1 = __middle - __first; - difference_type __d2 = __last - __middle; - _I1 __r = __first + __d2; - while (__d1 != 0 && __d2 != 0) - { - if (__d1 <= __d2) - { - if (__d1 <= __bit_array<_Cp>::capacity()) - { - __bit_array<_Cp> __b(__d1); - _VSTD::copy(__first, __middle, __b.begin()); - _VSTD::copy(__b.begin(), __b.end(), _VSTD::copy(__middle, __last, __first)); - break; - } - else - { - __bit_iterator<_Cp, false> __mp = _VSTD::swap_ranges(__first, __middle, __middle); - __first = __middle; - __middle = __mp; - __d2 -= __d1; - } - } - else - { - if (__d2 <= __bit_array<_Cp>::capacity()) - { - __bit_array<_Cp> __b(__d2); - _VSTD::copy(__middle, __last, __b.begin()); - _VSTD::copy_backward(__b.begin(), __b.end(), _VSTD::copy_backward(__first, __middle, __last)); - break; - } - else - { - __bit_iterator<_Cp, false> __mp = __first + __d2; - _VSTD::swap_ranges(__first, __mp, __middle); - __first = __mp; - __d1 -= __d2; - } - } +rotate(__bit_iterator<_Cp, false> __first, __bit_iterator<_Cp, false> __middle, __bit_iterator<_Cp, false> __last) { + using _I1 = __bit_iterator<_Cp, false>; + using difference_type = typename _I1::difference_type; + + difference_type __d1 = __middle - __first; + difference_type __d2 = __last - __middle; + _I1 __r = __first + __d2; + while (__d1 != 0 && __d2 != 0) { + if (__d1 <= __d2) { + if (__d1 <= __bit_array<_Cp>::capacity()) { + __bit_array<_Cp> __b(__d1); + std::copy(__first, __middle, __b.begin()); + std::copy(__b.begin(), __b.end(), std::copy(__middle, __last, __first)); + break; + } else { + __bit_iterator<_Cp, false> __mp = std::swap_ranges(__first, __middle, __middle); + __first = __middle; + __middle = __mp; + __d2 -= __d1; + } + } else { + if (__d2 <= __bit_array<_Cp>::capacity()) { + __bit_array<_Cp> __b(__d2); + std::copy(__middle, __last, __b.begin()); + std::copy_backward(__b.begin(), __b.end(), std::copy_backward(__first, __middle, __last)); + break; + } else { + __bit_iterator<_Cp, false> __mp = __first + __d2; + std::swap_ranges(__first, __mp, __middle); + __first = __mp; + __d1 -= __d2; + } } - return __r; + } + return __r; } // equal template -_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool -__equal_unaligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, - __bit_iterator<_Cp, _IC2> __first2) -{ - typedef __bit_iterator<_Cp, _IC1> _It; - typedef typename _It::difference_type difference_type; - typedef typename _It::__storage_type __storage_type; - const int __bits_per_word = _It::__bits_per_word; - difference_type __n = __last1 - __first1; - if (__n > 0) - { - // do first word - if (__first1.__ctz_ != 0) - { - unsigned __clz_f = __bits_per_word - __first1.__ctz_; - difference_type __dn = _VSTD::min(static_cast(__clz_f), __n); - __n -= __dn; - __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); - __storage_type __b = *__first1.__seg_ & __m; - unsigned __clz_r = __bits_per_word - __first2.__ctz_; - __storage_type __ddn = _VSTD::min<__storage_type>(__dn, __clz_r); - __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); - if (__first2.__ctz_ > __first1.__ctz_) - { - if ((*__first2.__seg_ & __m) != (__b << (__first2.__ctz_ - __first1.__ctz_))) - return false; - } - else - { - if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ - __first2.__ctz_))) - return false; - } - __first2.__seg_ += (__ddn + __first2.__ctz_) / __bits_per_word; - __first2.__ctz_ = static_cast((__ddn + __first2.__ctz_) % __bits_per_word); - __dn -= __ddn; - if (__dn > 0) - { - __m = ~__storage_type(0) >> (__bits_per_word - __dn); - if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ + __ddn))) - return false; - __first2.__ctz_ = static_cast(__dn); - } - ++__first1.__seg_; - // __first1.__ctz_ = 0; - } - // __first1.__ctz_ == 0; - // do middle words - unsigned __clz_r = __bits_per_word - __first2.__ctz_; - __storage_type __m = ~__storage_type(0) << __first2.__ctz_; - for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_) - { - __storage_type __b = *__first1.__seg_; - if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_)) - return false; - ++__first2.__seg_; - if ((*__first2.__seg_ & ~__m) != (__b >> __clz_r)) - return false; - } - // do last word - if (__n > 0) - { - __m = ~__storage_type(0) >> (__bits_per_word - __n); - __storage_type __b = *__first1.__seg_ & __m; - __storage_type __dn = _VSTD::min(__n, static_cast(__clz_r)); - __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); - if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_)) - return false; - __first2.__seg_ += (__dn + __first2.__ctz_) / __bits_per_word; - __first2.__ctz_ = static_cast((__dn + __first2.__ctz_) % __bits_per_word); - __n -= __dn; - if (__n > 0) - { - __m = ~__storage_type(0) >> (__bits_per_word - __n); - if ((*__first2.__seg_ & __m) != (__b >> __dn)) - return false; - } - } +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __equal_unaligned( + __bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) { + using _It = __bit_iterator<_Cp, _IC1>; + using difference_type = typename _It::difference_type; + using __storage_type = typename _It::__storage_type; + + const int __bits_per_word = _It::__bits_per_word; + difference_type __n = __last1 - __first1; + if (__n > 0) { + // do first word + if (__first1.__ctz_ != 0) { + unsigned __clz_f = __bits_per_word - __first1.__ctz_; + difference_type __dn = std::min(static_cast(__clz_f), __n); + __n -= __dn; + __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz_f - __dn)); + __storage_type __b = *__first1.__seg_ & __m; + unsigned __clz_r = __bits_per_word - __first2.__ctz_; + __storage_type __ddn = std::min<__storage_type>(__dn, __clz_r); + __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __ddn)); + if (__first2.__ctz_ > __first1.__ctz_) { + if ((*__first2.__seg_ & __m) != (__b << (__first2.__ctz_ - __first1.__ctz_))) + return false; + } else { + if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ - __first2.__ctz_))) + return false; + } + __first2.__seg_ += (__ddn + __first2.__ctz_) / __bits_per_word; + __first2.__ctz_ = static_cast((__ddn + __first2.__ctz_) % __bits_per_word); + __dn -= __ddn; + if (__dn > 0) { + __m = ~__storage_type(0) >> (__bits_per_word - __dn); + if ((*__first2.__seg_ & __m) != (__b >> (__first1.__ctz_ + __ddn))) + return false; + __first2.__ctz_ = static_cast(__dn); + } + ++__first1.__seg_; + // __first1.__ctz_ = 0; } - return true; + // __first1.__ctz_ == 0; + // do middle words + unsigned __clz_r = __bits_per_word - __first2.__ctz_; + __storage_type __m = ~__storage_type(0) << __first2.__ctz_; + for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_) { + __storage_type __b = *__first1.__seg_; + if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_)) + return false; + ++__first2.__seg_; + if ((*__first2.__seg_ & ~__m) != (__b >> __clz_r)) + return false; + } + // do last word + if (__n > 0) { + __m = ~__storage_type(0) >> (__bits_per_word - __n); + __storage_type __b = *__first1.__seg_ & __m; + __storage_type __dn = std::min(__n, static_cast(__clz_r)); + __m = (~__storage_type(0) << __first2.__ctz_) & (~__storage_type(0) >> (__clz_r - __dn)); + if ((*__first2.__seg_ & __m) != (__b << __first2.__ctz_)) + return false; + __first2.__seg_ += (__dn + __first2.__ctz_) / __bits_per_word; + __first2.__ctz_ = static_cast((__dn + __first2.__ctz_) % __bits_per_word); + __n -= __dn; + if (__n > 0) { + __m = ~__storage_type(0) >> (__bits_per_word - __n); + if ((*__first2.__seg_ & __m) != (__b >> __dn)) + return false; + } + } + } + return true; } template -_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool -__equal_aligned(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, - __bit_iterator<_Cp, _IC2> __first2) -{ - typedef __bit_iterator<_Cp, _IC1> _It; - typedef typename _It::difference_type difference_type; - typedef typename _It::__storage_type __storage_type; - const int __bits_per_word = _It::__bits_per_word; - difference_type __n = __last1 - __first1; - if (__n > 0) - { - // do first word - if (__first1.__ctz_ != 0) - { - unsigned __clz = __bits_per_word - __first1.__ctz_; - difference_type __dn = _VSTD::min(static_cast(__clz), __n); - __n -= __dn; - __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); - if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m)) - return false; - ++__first2.__seg_; - ++__first1.__seg_; - // __first1.__ctz_ = 0; - // __first2.__ctz_ = 0; - } - // __first1.__ctz_ == 0; - // __first2.__ctz_ == 0; - // do middle words - for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_, ++__first2.__seg_) - if (*__first2.__seg_ != *__first1.__seg_) - return false; - // do last word - if (__n > 0) - { - __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); - if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m)) - return false; - } +_LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __equal_aligned( + __bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) { + using _It = __bit_iterator<_Cp, _IC1>; + using difference_type = typename _It::difference_type; + using __storage_type = typename _It::__storage_type; + + const int __bits_per_word = _It::__bits_per_word; + difference_type __n = __last1 - __first1; + if (__n > 0) { + // do first word + if (__first1.__ctz_ != 0) { + unsigned __clz = __bits_per_word - __first1.__ctz_; + difference_type __dn = std::min(static_cast(__clz), __n); + __n -= __dn; + __storage_type __m = (~__storage_type(0) << __first1.__ctz_) & (~__storage_type(0) >> (__clz - __dn)); + if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m)) + return false; + ++__first2.__seg_; + ++__first1.__seg_; + // __first1.__ctz_ = 0; + // __first2.__ctz_ = 0; } - return true; + // __first1.__ctz_ == 0; + // __first2.__ctz_ == 0; + // do middle words + for (; __n >= __bits_per_word; __n -= __bits_per_word, ++__first1.__seg_, ++__first2.__seg_) + if (*__first2.__seg_ != *__first1.__seg_) + return false; + // do last word + if (__n > 0) { + __storage_type __m = ~__storage_type(0) >> (__bits_per_word - __n); + if ((*__first2.__seg_ & __m) != (*__first1.__seg_ & __m)) + return false; + } + } + return true; } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -bool -equal(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) -{ - if (__first1.__ctz_ == __first2.__ctz_) - return _VSTD::__equal_aligned(__first1, __last1, __first2); - return _VSTD::__equal_unaligned(__first1, __last1, __first2); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool +equal(__bit_iterator<_Cp, _IC1> __first1, __bit_iterator<_Cp, _IC1> __last1, __bit_iterator<_Cp, _IC2> __first2) { + if (__first1.__ctz_ == __first2.__ctz_) + return std::__equal_aligned(__first1, __last1, __first2); + return std::__equal_unaligned(__first1, __last1, __first2); } -template -class __bit_iterator -{ +template +class __bit_iterator { public: - typedef typename _Cp::difference_type difference_type; - typedef bool value_type; - typedef __bit_iterator pointer; + using difference_type = typename _Cp::difference_type; + using value_type = bool; + using pointer = __bit_iterator; #ifndef _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL - typedef __conditional_t<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> > reference; + using reference = __conditional_t<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >; #else - using reference = __conditional_t<_IsConst, bool, __bit_reference<_Cp> >; + using reference = __conditional_t<_IsConst, bool, __bit_reference<_Cp> >; #endif - typedef random_access_iterator_tag iterator_category; + using iterator_category = random_access_iterator_tag; private: - typedef typename _Cp::__storage_type __storage_type; - typedef __conditional_t<_IsConst, typename _Cp::__const_storage_pointer, typename _Cp::__storage_pointer> - __storage_pointer; - static const unsigned __bits_per_word = _Cp::__bits_per_word; + using __storage_type = typename _Cp::__storage_type; + using __storage_pointer = + __conditional_t<_IsConst, typename _Cp::__const_storage_pointer, typename _Cp::__storage_pointer>; - __storage_pointer __seg_; - unsigned __ctz_; + static const unsigned __bits_per_word = _Cp::__bits_per_word; + + __storage_pointer __seg_; + unsigned __ctz_; public: - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator() _NOEXCEPT + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator() _NOEXCEPT #if _LIBCPP_STD_VER >= 14 - : __seg_(nullptr), __ctz_(0) + : __seg_(nullptr), + __ctz_(0) #endif - {} + { + } - // When _IsConst=false, this is the copy constructor. - // It is non-trivial. Making it trivial would break ABI. - // When _IsConst=true, this is a converting constructor; - // the copy and move constructors are implicitly generated - // and trivial. - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 - __bit_iterator(const __bit_iterator<_Cp, false>& __it) _NOEXCEPT - : __seg_(__it.__seg_), __ctz_(__it.__ctz_) {} + // When _IsConst=false, this is the copy constructor. + // It is non-trivial. Making it trivial would break ABI. + // When _IsConst=true, this is a converting constructor; + // the copy and move constructors are implicitly generated + // and trivial. + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator(const __bit_iterator<_Cp, false>& __it) _NOEXCEPT + : __seg_(__it.__seg_), + __ctz_(__it.__ctz_) {} - // When _IsConst=false, we have a user-provided copy constructor, - // so we must also provide a copy assignment operator because - // the implicit generation of a defaulted one is deprecated. - // When _IsConst=true, the assignment operators are - // implicitly generated and trivial. - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 - __bit_iterator& operator=(const _If<_IsConst, struct __private_nat, __bit_iterator>& __it) { - __seg_ = __it.__seg_; - __ctz_ = __it.__ctz_; - return *this; + // When _IsConst=false, we have a user-provided copy constructor, + // so we must also provide a copy assignment operator because + // the implicit generation of a defaulted one is deprecated. + // When _IsConst=true, the assignment operators are + // implicitly generated and trivial. + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& + operator=(const _If<_IsConst, struct __private_nat, __bit_iterator>& __it) { + __seg_ = __it.__seg_; + __ctz_ = __it.__ctz_; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator*() const _NOEXCEPT { + return __conditional_t<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >( + __seg_, __storage_type(1) << __ctz_); + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator++() { + if (__ctz_ != __bits_per_word - 1) + ++__ctz_; + else { + __ctz_ = 0; + ++__seg_; } + return *this; + } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator*() const _NOEXCEPT { - return __conditional_t<_IsConst, __bit_const_reference<_Cp>, __bit_reference<_Cp> >( - __seg_, __storage_type(1) << __ctz_); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator++(int) { + __bit_iterator __tmp = *this; + ++(*this); + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator--() { + if (__ctz_ != 0) + --__ctz_; + else { + __ctz_ = __bits_per_word - 1; + --__seg_; } + return *this; + } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator++() - { - if (__ctz_ != __bits_per_word-1) - ++__ctz_; - else - { - __ctz_ = 0; - ++__seg_; - } - return *this; - } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator--(int) { + __bit_iterator __tmp = *this; + --(*this); + return __tmp; + } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator++(int) - { - __bit_iterator __tmp = *this; - ++(*this); - return __tmp; - } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator+=(difference_type __n) { + if (__n >= 0) + __seg_ += (__n + __ctz_) / __bits_per_word; + else + __seg_ += static_cast(__n - __bits_per_word + __ctz_ + 1) / + static_cast(__bits_per_word); + __n &= (__bits_per_word - 1); + __ctz_ = static_cast((__n + __ctz_) % __bits_per_word); + return *this; + } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator--() - { - if (__ctz_ != 0) - --__ctz_; - else - { - __ctz_ = __bits_per_word - 1; - --__seg_; - } - return *this; - } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator-=(difference_type __n) { + return *this += -__n; + } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator--(int) - { - __bit_iterator __tmp = *this; - --(*this); - return __tmp; - } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator+(difference_type __n) const { + __bit_iterator __t(*this); + __t += __n; + return __t; + } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator+=(difference_type __n) - { - if (__n >= 0) - __seg_ += (__n + __ctz_) / __bits_per_word; - else - __seg_ += static_cast(__n - __bits_per_word + __ctz_ + 1) - / static_cast(__bits_per_word); - __n &= (__bits_per_word - 1); - __ctz_ = static_cast((__n + __ctz_) % __bits_per_word); - return *this; - } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator-(difference_type __n) const { + __bit_iterator __t(*this); + __t -= __n; + return __t; + } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator& operator-=(difference_type __n) - { - return *this += -__n; - } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator + operator+(difference_type __n, const __bit_iterator& __it) { + return __it + __n; + } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator+(difference_type __n) const - { - __bit_iterator __t(*this); - __t += __n; - return __t; - } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend difference_type + operator-(const __bit_iterator& __x, const __bit_iterator& __y) { + return (__x.__seg_ - __y.__seg_) * __bits_per_word + __x.__ctz_ - __y.__ctz_; + } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 __bit_iterator operator-(difference_type __n) const - { - __bit_iterator __t(*this); - __t -= __n; - return __t; - } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](difference_type __n) const { + return *(*this + __n); + } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 - friend __bit_iterator operator+(difference_type __n, const __bit_iterator& __it) {return __it + __n;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool + operator==(const __bit_iterator& __x, const __bit_iterator& __y) { + return __x.__seg_ == __y.__seg_ && __x.__ctz_ == __y.__ctz_; + } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 - friend difference_type operator-(const __bit_iterator& __x, const __bit_iterator& __y) - {return (__x.__seg_ - __y.__seg_) * __bits_per_word + __x.__ctz_ - __y.__ctz_;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool + operator!=(const __bit_iterator& __x, const __bit_iterator& __y) { + return !(__x == __y); + } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 reference operator[](difference_type __n) const {return *(*this + __n);} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool + operator<(const __bit_iterator& __x, const __bit_iterator& __y) { + return __x.__seg_ < __y.__seg_ || (__x.__seg_ == __y.__seg_ && __x.__ctz_ < __y.__ctz_); + } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool operator==(const __bit_iterator& __x, const __bit_iterator& __y) - {return __x.__seg_ == __y.__seg_ && __x.__ctz_ == __y.__ctz_;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool + operator>(const __bit_iterator& __x, const __bit_iterator& __y) { + return __y < __x; + } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool operator!=(const __bit_iterator& __x, const __bit_iterator& __y) - {return !(__x == __y);} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool + operator<=(const __bit_iterator& __x, const __bit_iterator& __y) { + return !(__y < __x); + } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool operator<(const __bit_iterator& __x, const __bit_iterator& __y) - {return __x.__seg_ < __y.__seg_ || (__x.__seg_ == __y.__seg_ && __x.__ctz_ < __y.__ctz_);} - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool operator>(const __bit_iterator& __x, const __bit_iterator& __y) - {return __y < __x;} - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool operator<=(const __bit_iterator& __x, const __bit_iterator& __y) - {return !(__y < __x);} - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool operator>=(const __bit_iterator& __x, const __bit_iterator& __y) - {return !(__x < __y);} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool + operator>=(const __bit_iterator& __x, const __bit_iterator& __y) { + return !(__x < __y); + } private: - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 - explicit __bit_iterator(__storage_pointer __s, unsigned __ctz) _NOEXCEPT - : __seg_(__s), __ctz_(__ctz) {} + _LIBCPP_HIDE_FROM_ABI + _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __bit_iterator(__storage_pointer __s, unsigned __ctz) _NOEXCEPT + : __seg_(__s), + __ctz_(__ctz) {} - friend typename _Cp::__self; + friend typename _Cp::__self; - friend class __bit_reference<_Cp>; - friend class __bit_const_reference<_Cp>; - friend class __bit_iterator<_Cp, true>; - template friend struct __bit_array; - template - _LIBCPP_CONSTEXPR_SINCE_CXX20 - friend void __fill_n_false(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n); + friend class __bit_reference<_Cp>; + friend class __bit_const_reference<_Cp>; + friend class __bit_iterator<_Cp, true>; + template + friend struct __bit_array; - template - _LIBCPP_CONSTEXPR_SINCE_CXX20 - friend void __fill_n_true(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 friend void + __fill_n_bool(__bit_iterator<_Dp, false> __first, typename _Dp::size_type __n); - template - _LIBCPP_CONSTEXPR_SINCE_CXX20 - friend __bit_iterator<_Dp, false> __copy_aligned(__bit_iterator<_Dp, _IC> __first, - __bit_iterator<_Dp, _IC> __last, - __bit_iterator<_Dp, false> __result); - template - _LIBCPP_CONSTEXPR_SINCE_CXX20 - friend __bit_iterator<_Dp, false> __copy_unaligned(__bit_iterator<_Dp, _IC> __first, - __bit_iterator<_Dp, _IC> __last, - __bit_iterator<_Dp, false> __result); - template - _LIBCPP_CONSTEXPR_SINCE_CXX20 - friend __bit_iterator<_Dp, false> copy(__bit_iterator<_Dp, _IC> __first, - __bit_iterator<_Dp, _IC> __last, - __bit_iterator<_Dp, false> __result); - template - _LIBCPP_CONSTEXPR_SINCE_CXX20 - friend __bit_iterator<_Dp, false> __copy_backward_aligned(__bit_iterator<_Dp, _IC> __first, - __bit_iterator<_Dp, _IC> __last, - __bit_iterator<_Dp, false> __result); - template - _LIBCPP_CONSTEXPR_SINCE_CXX20 - friend __bit_iterator<_Dp, false> __copy_backward_unaligned(__bit_iterator<_Dp, _IC> __first, - __bit_iterator<_Dp, _IC> __last, - __bit_iterator<_Dp, false> __result); - template - _LIBCPP_CONSTEXPR_SINCE_CXX20 - friend __bit_iterator<_Dp, false> copy_backward(__bit_iterator<_Dp, _IC> __first, - __bit_iterator<_Dp, _IC> __last, - __bit_iterator<_Dp, false> __result); - template friend __bit_iterator<__C2, false> __swap_ranges_aligned(__bit_iterator<__C1, false>, - __bit_iterator<__C1, false>, - __bit_iterator<__C2, false>); - template friend __bit_iterator<__C2, false> __swap_ranges_unaligned(__bit_iterator<__C1, false>, - __bit_iterator<__C1, false>, - __bit_iterator<__C2, false>); - template friend __bit_iterator<__C2, false> swap_ranges(__bit_iterator<__C1, false>, - __bit_iterator<__C1, false>, - __bit_iterator<__C2, false>); - template - _LIBCPP_CONSTEXPR_SINCE_CXX20 - friend __bit_iterator<_Dp, false> rotate(__bit_iterator<_Dp, false>, - __bit_iterator<_Dp, false>, - __bit_iterator<_Dp, false>); - template - _LIBCPP_CONSTEXPR_SINCE_CXX20 - friend bool __equal_aligned(__bit_iterator<_Dp, _IC1>, - __bit_iterator<_Dp, _IC1>, - __bit_iterator<_Dp, _IC2>); - template - _LIBCPP_CONSTEXPR_SINCE_CXX20 - friend bool __equal_unaligned(__bit_iterator<_Dp, _IC1>, - __bit_iterator<_Dp, _IC1>, - __bit_iterator<_Dp, _IC2>); - template - _LIBCPP_CONSTEXPR_SINCE_CXX20 - friend bool equal(__bit_iterator<_Dp, _IC1>, - __bit_iterator<_Dp, _IC1>, - __bit_iterator<_Dp, _IC2>); - template - _LIBCPP_CONSTEXPR_SINCE_CXX20 - friend __bit_iterator<_Dp, _IC> __find_bool_true(__bit_iterator<_Dp, _IC>, typename _Dp::size_type); - template - _LIBCPP_CONSTEXPR_SINCE_CXX20 - friend __bit_iterator<_Dp, _IC> __find_bool_false(__bit_iterator<_Dp, _IC>, typename _Dp::size_type); - template friend typename __bit_iterator<_Dp, _IC>::difference_type - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 - __count_bool_true(__bit_iterator<_Dp, _IC>, typename _Dp::size_type); - template friend typename __bit_iterator<_Dp, _IC>::difference_type - __count_bool_false(__bit_iterator<_Dp, _IC>, typename _Dp::size_type); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_aligned( + __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_unaligned( + __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> + copy(__bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_backward_aligned( + __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> __copy_backward_unaligned( + __bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> + copy_backward(__bit_iterator<_Dp, _IC> __first, __bit_iterator<_Dp, _IC> __last, __bit_iterator<_Dp, false> __result); + template + friend __bit_iterator<_Cr, false> + __swap_ranges_aligned(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>); + template + friend __bit_iterator<_Cr, false> + __swap_ranges_unaligned(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>); + template + friend __bit_iterator<_Cr, false> + swap_ranges(__bit_iterator<_Cl, false>, __bit_iterator<_Cl, false>, __bit_iterator<_Cr, false>); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, false> + rotate(__bit_iterator<_Dp, false>, __bit_iterator<_Dp, false>, __bit_iterator<_Dp, false>); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool + __equal_aligned(__bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC2>); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool + __equal_unaligned(__bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC2>); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 friend bool + equal(__bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC1>, __bit_iterator<_Dp, _IC2>); + template + _LIBCPP_CONSTEXPR_SINCE_CXX20 friend __bit_iterator<_Dp, _IC> + __find_bool(__bit_iterator<_Dp, _IC>, typename _Dp::size_type); + template + friend typename __bit_iterator<_Dp, _IC>::difference_type _LIBCPP_HIDE_FROM_ABI + _LIBCPP_CONSTEXPR_SINCE_CXX20 __count_bool(__bit_iterator<_Dp, _IC>, typename _Dp::size_type); }; _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__charconv/chars_format.h b/third_party/libcxx/__charconv/chars_format.h index 0e781c047..c76cebd5d 100644 --- a/third_party/libcxx/__charconv/chars_format.h +++ b/third_party/libcxx/__charconv/chars_format.h @@ -21,7 +21,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 17 -enum class _LIBCPP_ENUM_VIS chars_format { scientific = 0x1, fixed = 0x2, hex = 0x4, general = fixed | scientific }; +enum class chars_format { scientific = 0x1, fixed = 0x2, hex = 0x4, general = fixed | scientific }; inline _LIBCPP_HIDE_FROM_ABI constexpr chars_format operator~(chars_format __x) { return chars_format(~std::__to_underlying(__x)); @@ -39,20 +39,17 @@ inline _LIBCPP_HIDE_FROM_ABI constexpr chars_format operator^(chars_format __x, return chars_format(std::__to_underlying(__x) ^ std::__to_underlying(__y)); } -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 chars_format& -operator&=(chars_format& __x, chars_format __y) { +inline _LIBCPP_HIDE_FROM_ABI constexpr chars_format& operator&=(chars_format& __x, chars_format __y) { __x = __x & __y; return __x; } -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 chars_format& -operator|=(chars_format& __x, chars_format __y) { +inline _LIBCPP_HIDE_FROM_ABI constexpr chars_format& operator|=(chars_format& __x, chars_format __y) { __x = __x | __y; return __x; } -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 chars_format& -operator^=(chars_format& __x, chars_format __y) { +inline _LIBCPP_HIDE_FROM_ABI constexpr chars_format& operator^=(chars_format& __x, chars_format __y) { __x = __x ^ __y; return __x; } diff --git a/third_party/libcxx/__charconv/from_chars_integral.h b/third_party/libcxx/__charconv/from_chars_integral.h index 990aa2174..c1f033b37 100644 --- a/third_party/libcxx/__charconv/from_chars_integral.h +++ b/third_party/libcxx/__charconv/from_chars_integral.h @@ -11,6 +11,7 @@ #define _LIBCPP___CHARCONV_FROM_CHARS_INTEGRAL_H #include <__algorithm/copy_n.h> +#include <__assert> #include <__charconv/from_chars_result.h> #include <__charconv/traits.h> #include <__config> @@ -124,7 +125,7 @@ __subject_seq_combinator(_It __first, _It __last, _Tp& __value, _Fn __f, _Ts... return __r; } -template ::value, int>::type = 0> +template ::value, int> = 0> inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result __from_chars_atoi(const char* __first, const char* __last, _Tp& __value) { using __tx = __itoa::__traits<_Tp>; @@ -145,7 +146,7 @@ __from_chars_atoi(const char* __first, const char* __last, _Tp& __value) { }); } -template ::value, int>::type = 0> +template ::value, int> = 0> inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result __from_chars_atoi(const char* __first, const char* __last, _Tp& __value) { using __t = decltype(std::__to_unsigned_like(__value)); @@ -170,7 +171,7 @@ inline constexpr float __from_chars_log2f_lut[35] = { 4.321928, 4.3923173, 4.4594316, 4.523562, 4.5849624, 4.643856, 4.70044, 4.7548876, 4.807355, 4.857981, 4.9068904, 4.9541965, 5, 5.044394, 5.087463, 5.129283, 5.169925}; -template ::value, int>::type = 0> +template ::value, int> = 0> inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result __from_chars_integral(const char* __first, const char* __last, _Tp& __value, int __base) { if (__base == 10) @@ -211,23 +212,23 @@ __from_chars_integral(const char* __first, const char* __last, _Tp& __value, int __base); } -template ::value, int>::type = 0> +template ::value, int> = 0> inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result __from_chars_integral(const char* __first, const char* __last, _Tp& __value, int __base) { using __t = decltype(std::__to_unsigned_like(__value)); return std::__sign_combinator(__first, __last, __value, __from_chars_integral<__t>, __base); } -template ::value, int>::type = 0> +template ::value, int> = 0> inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result from_chars(const char* __first, const char* __last, _Tp& __value) { return std::__from_chars_atoi(__first, __last, __value); } -template ::value, int>::type = 0> +template ::value, int> = 0> inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI from_chars_result from_chars(const char* __first, const char* __last, _Tp& __value, int __base) { - _LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]"); + _LIBCPP_ASSERT_UNCATEGORIZED(2 <= __base && __base <= 36, "base not in [2, 36]"); return std::__from_chars_integral(__first, __last, __value, __base); } #endif // _LIBCPP_STD_VER >= 17 diff --git a/third_party/libcxx/__charconv/from_chars_result.h b/third_party/libcxx/__charconv/from_chars_result.h index 7eeb9ec81..a7bfd6530 100644 --- a/third_party/libcxx/__charconv/from_chars_result.h +++ b/third_party/libcxx/__charconv/from_chars_result.h @@ -21,12 +21,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 17 -struct _LIBCPP_TYPE_VIS from_chars_result { +struct _LIBCPP_EXPORTED_FROM_ABI from_chars_result { const char* ptr; errc ec; # if _LIBCPP_STD_VER >= 20 _LIBCPP_HIDE_FROM_ABI friend bool operator==(const from_chars_result&, const from_chars_result&) = default; # endif +# if _LIBCPP_STD_VER >= 26 + _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return ec == errc{}; } +# endif }; #endif // _LIBCPP_STD_VER >= 17 diff --git a/third_party/libcxx/__charconv/to_chars_base_10.h b/third_party/libcxx/__charconv/to_chars_base_10.h index 028ff3352..c49f4f679 100644 --- a/third_party/libcxx/__charconv/to_chars_base_10.h +++ b/third_party/libcxx/__charconv/to_chars_base_10.h @@ -11,6 +11,7 @@ #define _LIBCPP___CHARCONV_TO_CHARS_BASE_10_H #include <__algorithm/copy_n.h> +#include <__assert> #include <__charconv/tables.h> #include <__config> #include @@ -132,14 +133,14 @@ __base_10_u64(char* __buffer, uint64_t __value) noexcept { /// range that can be used. However the range is sufficient for /// \ref __base_10_u128. _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline __uint128_t __pow_10(int __exp) noexcept { - _LIBCPP_ASSERT(__exp >= __pow10_128_offset, "Index out of bounds"); + _LIBCPP_ASSERT_INTERNAL(__exp >= __pow10_128_offset, "Index out of bounds"); return __pow10_128[__exp - __pow10_128_offset]; } _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI inline char* __base_10_u128(char* __buffer, __uint128_t __value) noexcept { - _LIBCPP_ASSERT( - __value > numeric_limits::max(), "The optimizations for this algorithm fail when this isn't true."); + _LIBCPP_ASSERT_INTERNAL( + __value > numeric_limits::max(), "The optimizations for this algorithm fails when this isn't true."); // Unlike the 64 to 32 bit case the 128 bit case the "upper half" can't be // stored in the "lower half". Instead we first need to handle the top most diff --git a/third_party/libcxx/__charconv/to_chars_floating_point.h b/third_party/libcxx/__charconv/to_chars_floating_point.h index 6ede36e88..118f316b2 100644 --- a/third_party/libcxx/__charconv/to_chars_floating_point.h +++ b/third_party/libcxx/__charconv/to_chars_floating_point.h @@ -10,7 +10,6 @@ #ifndef _LIBCPP___CHARCONV_TO_CHARS_FLOATING_POINT_H #define _LIBCPP___CHARCONV_TO_CHARS_FLOATING_POINT_H -#include <__availability> #include <__charconv/chars_format.h> #include <__charconv/to_chars_result.h> #include <__config> @@ -23,31 +22,31 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 17 -_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS to_chars_result +_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result to_chars(char* __first, char* __last, float __value); -_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS to_chars_result +_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result to_chars(char* __first, char* __last, double __value); -_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS to_chars_result +_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result to_chars(char* __first, char* __last, long double __value); -_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS to_chars_result +_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result to_chars(char* __first, char* __last, float __value, chars_format __fmt); -_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS to_chars_result +_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result to_chars(char* __first, char* __last, double __value, chars_format __fmt); -_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS to_chars_result +_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result to_chars(char* __first, char* __last, long double __value, chars_format __fmt); -_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS to_chars_result +_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result to_chars(char* __first, char* __last, float __value, chars_format __fmt, int __precision); -_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS to_chars_result +_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result to_chars(char* __first, char* __last, double __value, chars_format __fmt, int __precision); -_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_FUNC_VIS to_chars_result +_LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_EXPORTED_FROM_ABI to_chars_result to_chars(char* __first, char* __last, long double __value, chars_format __fmt, int __precision); #endif // _LIBCPP_STD_VER >= 17 diff --git a/third_party/libcxx/__charconv/to_chars_integral.h b/third_party/libcxx/__charconv/to_chars_integral.h index 6c726c088..0369f4dfb 100644 --- a/third_party/libcxx/__charconv/to_chars_integral.h +++ b/third_party/libcxx/__charconv/to_chars_integral.h @@ -11,6 +11,7 @@ #define _LIBCPP___CHARCONV_TO_CHARS_INTEGRAL_H #include <__algorithm/copy_n.h> +#include <__assert> #include <__bit/countl.h> #include <__charconv/tables.h> #include <__charconv/to_chars_base_10.h> @@ -222,23 +223,23 @@ struct _LIBCPP_HIDDEN __integral<16> { } // namespace __itoa -template = sizeof(unsigned)), int>::type = 0> +template = sizeof(unsigned)), int> = 0> _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __to_chars_integral_width(_Tp __value) { return __itoa::__integral<_Base>::__width(__value); } -template ::type = 0> +template = 0> _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __to_chars_integral_width(_Tp __value) { return std::__to_chars_integral_width<_Base>(static_cast(__value)); } -template = sizeof(unsigned)), int>::type = 0> +template = sizeof(unsigned)), int> = 0> _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result __to_chars_integral(char* __first, char* __last, _Tp __value) { return __itoa::__integral<_Base>::__to_chars(__first, __last, __value); } -template ::type = 0> +template = 0> _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result __to_chars_integral(char* __first, char* __last, _Tp __value) { return std::__to_chars_integral<_Base>(__first, __last, static_cast(__value)); @@ -246,7 +247,7 @@ __to_chars_integral(char* __first, char* __last, _Tp __value) { template _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI int __to_chars_integral_width(_Tp __value, unsigned __base) { - _LIBCPP_ASSERT(__value >= 0, "The function requires a non-negative value."); + _LIBCPP_ASSERT_INTERNAL(__value >= 0, "The function requires a non-negative value."); unsigned __base_2 = __base * __base; unsigned __base_3 = __base_2 * __base; @@ -300,7 +301,7 @@ __to_chars_integral(char* __first, char* __last, _Tp __value, int __base, false_ return {__last, errc(0)}; } -template ::value, int>::type = 0> +template ::value, int> = 0> inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result to_chars(char* __first, char* __last, _Tp __value) { using _Type = __make_32_64_or_128_bit_t<_Tp>; @@ -308,10 +309,10 @@ to_chars(char* __first, char* __last, _Tp __value) { return std::__to_chars_itoa(__first, __last, static_cast<_Type>(__value), is_signed<_Tp>()); } -template ::value, int>::type = 0> +template ::value, int> = 0> inline _LIBCPP_CONSTEXPR_SINCE_CXX23 _LIBCPP_HIDE_FROM_ABI to_chars_result to_chars(char* __first, char* __last, _Tp __value, int __base) { - _LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]"); + _LIBCPP_ASSERT_UNCATEGORIZED(2 <= __base && __base <= 36, "base not in [2, 36]"); using _Type = __make_32_64_or_128_bit_t<_Tp>; return std::__to_chars_integral(__first, __last, static_cast<_Type>(__value), __base, is_signed<_Tp>()); diff --git a/third_party/libcxx/__charconv/to_chars_result.h b/third_party/libcxx/__charconv/to_chars_result.h index 67221b398..8df0897a4 100644 --- a/third_party/libcxx/__charconv/to_chars_result.h +++ b/third_party/libcxx/__charconv/to_chars_result.h @@ -21,12 +21,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 17 -struct _LIBCPP_TYPE_VIS to_chars_result { +struct _LIBCPP_EXPORTED_FROM_ABI to_chars_result { char* ptr; errc ec; # if _LIBCPP_STD_VER >= 20 _LIBCPP_HIDE_FROM_ABI friend bool operator==(const to_chars_result&, const to_chars_result&) = default; # endif +# if _LIBCPP_STD_VER >= 26 + _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return ec == errc{}; } +# endif }; #endif // _LIBCPP_STD_VER >= 17 diff --git a/third_party/libcxx/__charconv/traits.h b/third_party/libcxx/__charconv/traits.h index 505a0b1ac..c91c6da32 100644 --- a/third_party/libcxx/__charconv/traits.h +++ b/third_party/libcxx/__charconv/traits.h @@ -10,6 +10,7 @@ #ifndef _LIBCPP___CHARCONV_TRAITS #define _LIBCPP___CHARCONV_TRAITS +#include <__assert> #include <__bit/countl.h> #include <__charconv/tables.h> #include <__charconv/to_chars_base_10.h> @@ -101,11 +102,11 @@ struct _LIBCPP_HIDDEN __traits_base<_Tp, __enable_if_t numeric_limits::max(), "The optimizations for this algorithm fail when this isn't true."); // There's always a bit set in the upper 64-bits. auto __t = (128 - std::__libcpp_clz(static_cast(__v >> 64))) * 1233 >> 12; - _LIBCPP_ASSERT(__t >= __itoa::__pow10_128_offset, "Index out of bounds"); + _LIBCPP_ASSERT_INTERNAL(__t >= __itoa::__pow10_128_offset, "Index out of bounds"); // __t is adjusted since the lookup table misses the lower entries. return __t - (__v < __itoa::__pow10_128[__t - __itoa::__pow10_128_offset]) + 1; } diff --git a/third_party/libcxx/__chrono/calendar.h b/third_party/libcxx/__chrono/calendar.h index 94b5e315c..bb1c5e7eb 100644 --- a/third_party/libcxx/__chrono/calendar.h +++ b/third_party/libcxx/__chrono/calendar.h @@ -22,19 +22,19 @@ _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { struct local_t {}; -template -using local_time = time_point; +template +using local_time = time_point; using local_seconds = local_time; using local_days = local_time; -struct last_spec { explicit last_spec() = default; }; +struct last_spec { + explicit last_spec() = default; +}; inline constexpr last_spec last{}; - } // namespace chrono _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__chrono/convert_to_timespec.h b/third_party/libcxx/__chrono/convert_to_timespec.h index fab07f256..11e0b826d 100644 --- a/third_party/libcxx/__chrono/convert_to_timespec.h +++ b/third_party/libcxx/__chrono/convert_to_timespec.h @@ -26,23 +26,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD // Convert a nanoseconds duration to the given TimeSpec type, which must have // the same properties as std::timespec. template -_LIBCPP_HIDE_FROM_ABI inline -_TimeSpec __convert_to_timespec(const chrono::nanoseconds& __ns) -{ +_LIBCPP_HIDE_FROM_ABI inline _TimeSpec __convert_to_timespec(const chrono::nanoseconds& __ns) { using namespace chrono; seconds __s = duration_cast(__ns); _TimeSpec __ts; typedef decltype(__ts.tv_sec) __ts_sec; const __ts_sec __ts_sec_max = numeric_limits<__ts_sec>::max(); - if (__s.count() < __ts_sec_max) - { - __ts.tv_sec = static_cast<__ts_sec>(__s.count()); + if (__s.count() < __ts_sec_max) { + __ts.tv_sec = static_cast<__ts_sec>(__s.count()); __ts.tv_nsec = static_cast((__ns - __s).count()); - } - else - { - __ts.tv_sec = __ts_sec_max; + } else { + __ts.tv_sec = __ts_sec_max; __ts.tv_nsec = 999999999; // (10^9 - 1) } diff --git a/third_party/libcxx/__chrono/convert_to_tm.h b/third_party/libcxx/__chrono/convert_to_tm.h index f4dcddece..3a51019b8 100644 --- a/third_party/libcxx/__chrono/convert_to_tm.h +++ b/third_party/libcxx/__chrono/convert_to_tm.h @@ -16,10 +16,12 @@ #include <__chrono/duration.h> #include <__chrono/file_clock.h> #include <__chrono/hh_mm_ss.h> +#include <__chrono/local_info.h> #include <__chrono/month.h> #include <__chrono/month_weekday.h> #include <__chrono/monthday.h> #include <__chrono/statically_widen.h> +#include <__chrono/sys_info.h> #include <__chrono/system_clock.h> #include <__chrono/time_point.h> #include <__chrono/weekday.h> @@ -27,10 +29,13 @@ #include <__chrono/year_month.h> #include <__chrono/year_month_day.h> #include <__chrono/year_month_weekday.h> +#include <__chrono/zoned_time.h> #include <__concepts/same_as.h> #include <__config> #include <__format/format_error.h> #include <__memory/addressof.h> +#include <__type_traits/is_convertible.h> +#include <__type_traits/is_specialization.h> #include #include #include @@ -77,7 +82,7 @@ _LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(const _Date& __date, chrono::weekday _ template _LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(const chrono::sys_time<_Duration> __tp) { - chrono::sys_days __days = chrono::time_point_cast(__tp); + chrono::sys_days __days = chrono::floor(__tp); chrono::year_month_day __ymd{__days}; _Tm __result = std::__convert_to_tm<_Tm>(chrono::year_month_day{__ymd}, chrono::weekday{__days}); @@ -116,12 +121,23 @@ _LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(const _ChronoT& __value) { // ... However, if a flag refers to a "time of day" (e.g. %H, %I, %p, // etc.), then a specialization of duration is interpreted as the time of // day elapsed since midnight. - uint64_t __sec = chrono::duration_cast(__value).count(); - __sec %= 24 * 3600; - __result.tm_hour = __sec / 3600; - __sec %= 3600; - __result.tm_min = __sec / 60; - __result.tm_sec = __sec % 60; + + // Not all values can be converted to hours, it may run into ratio + // conversion errors. In that case the conversion to seconds works. + if constexpr (is_convertible_v<_ChronoT, chrono::hours>) { + auto __hour = chrono::floor(__value); + auto __sec = chrono::duration_cast(__value - __hour); + __result.tm_hour = __hour.count() % 24; + __result.tm_min = __sec.count() / 60; + __result.tm_sec = __sec.count() % 60; + } else { + uint64_t __sec = chrono::duration_cast(__value).count(); + __sec %= 24 * 3600; + __result.tm_hour = __sec / 3600; + __sec %= 3600; + __result.tm_min = __sec / 60; + __result.tm_sec = __sec % 60; + } } else if constexpr (same_as<_ChronoT, chrono::day>) __result.tm_mday = static_cast(__value); else if constexpr (same_as<_ChronoT, chrono::month>) @@ -159,6 +175,18 @@ _LIBCPP_HIDE_FROM_ABI _Tm __convert_to_tm(const _ChronoT& __value) { if (__value.hours().count() > std::numeric_limits::max()) std::__throw_format_error("Formatting hh_mm_ss, encountered an hour overflow"); __result.tm_hour = __value.hours().count(); +# if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) + } else if constexpr (same_as<_ChronoT, chrono::sys_info>) { + // Has no time information. + } else if constexpr (same_as<_ChronoT, chrono::local_info>) { + // Has no time information. +# if !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) && \ + !defined(_LIBCPP_HAS_NO_LOCALIZATION) + } else if constexpr (__is_specialization_v<_ChronoT, chrono::zoned_time>) { + return std::__convert_to_tm<_Tm>( + chrono::sys_time{__value.get_local_time().time_since_epoch()}); +# endif +# endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) } else static_assert(sizeof(_ChronoT) == 0, "Add the missing type specialization"); diff --git a/third_party/libcxx/__chrono/day.h b/third_party/libcxx/__chrono/day.h index c907c036c..7342084b0 100644 --- a/third_party/libcxx/__chrono/day.h +++ b/third_party/libcxx/__chrono/day.h @@ -22,58 +22,73 @@ _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { class day { private: - unsigned char __d_; + unsigned char __d_; + public: - day() = default; - _LIBCPP_HIDE_FROM_ABI explicit inline constexpr day(unsigned __val) noexcept : __d_(static_cast(__val)) {} - _LIBCPP_HIDE_FROM_ABI inline constexpr day& operator++() noexcept { ++__d_; return *this; } - _LIBCPP_HIDE_FROM_ABI inline constexpr day operator++(int) noexcept { day __tmp = *this; ++(*this); return __tmp; } - _LIBCPP_HIDE_FROM_ABI inline constexpr day& operator--() noexcept { --__d_; return *this; } - _LIBCPP_HIDE_FROM_ABI inline constexpr day operator--(int) noexcept { day __tmp = *this; --(*this); return __tmp; } - _LIBCPP_HIDE_FROM_ABI constexpr day& operator+=(const days& __dd) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr day& operator-=(const days& __dd) noexcept; - _LIBCPP_HIDE_FROM_ABI explicit inline constexpr operator unsigned() const noexcept { return __d_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __d_ >= 1 && __d_ <= 31; } - }; + day() = default; + _LIBCPP_HIDE_FROM_ABI explicit inline constexpr day(unsigned __val) noexcept + : __d_(static_cast(__val)) {} + _LIBCPP_HIDE_FROM_ABI inline constexpr day& operator++() noexcept { + ++__d_; + return *this; + } + _LIBCPP_HIDE_FROM_ABI inline constexpr day operator++(int) noexcept { + day __tmp = *this; + ++(*this); + return __tmp; + } + _LIBCPP_HIDE_FROM_ABI inline constexpr day& operator--() noexcept { + --__d_; + return *this; + } + _LIBCPP_HIDE_FROM_ABI inline constexpr day operator--(int) noexcept { + day __tmp = *this; + --(*this); + return __tmp; + } + _LIBCPP_HIDE_FROM_ABI constexpr day& operator+=(const days& __dd) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr day& operator-=(const days& __dd) noexcept; + _LIBCPP_HIDE_FROM_ABI explicit inline constexpr operator unsigned() const noexcept { return __d_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __d_ >= 1 && __d_ <= 31; } +}; +_LIBCPP_HIDE_FROM_ABI inline constexpr bool operator==(const day& __lhs, const day& __rhs) noexcept { + return static_cast(__lhs) == static_cast(__rhs); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator==(const day& __lhs, const day& __rhs) noexcept -{ return static_cast(__lhs) == static_cast(__rhs); } - -_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const day& __lhs, const day& __rhs) noexcept { +_LIBCPP_HIDE_FROM_ABI inline constexpr strong_ordering operator<=>(const day& __lhs, const day& __rhs) noexcept { return static_cast(__lhs) <=> static_cast(__rhs); } -_LIBCPP_HIDE_FROM_ABI inline constexpr -day operator+ (const day& __lhs, const days& __rhs) noexcept -{ return day(static_cast(__lhs) + __rhs.count()); } +_LIBCPP_HIDE_FROM_ABI inline constexpr day operator+(const day& __lhs, const days& __rhs) noexcept { + return day(static_cast(__lhs) + __rhs.count()); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -day operator+ (const days& __lhs, const day& __rhs) noexcept -{ return __rhs + __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr day operator+(const days& __lhs, const day& __rhs) noexcept { + return __rhs + __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -day operator- (const day& __lhs, const days& __rhs) noexcept -{ return __lhs + -__rhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr day operator-(const day& __lhs, const days& __rhs) noexcept { + return __lhs + -__rhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -days operator-(const day& __lhs, const day& __rhs) noexcept -{ return days(static_cast(static_cast(__lhs)) - - static_cast(static_cast(__rhs))); } +_LIBCPP_HIDE_FROM_ABI inline constexpr days operator-(const day& __lhs, const day& __rhs) noexcept { + return days(static_cast(static_cast(__lhs)) - static_cast(static_cast(__rhs))); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -day& day::operator+=(const days& __dd) noexcept -{ *this = *this + __dd; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr day& day::operator+=(const days& __dd) noexcept { + *this = *this + __dd; + return *this; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -day& day::operator-=(const days& __dd) noexcept -{ *this = *this - __dd; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr day& day::operator-=(const days& __dd) noexcept { + *this = *this - __dd; + return *this; +} } // namespace chrono diff --git a/third_party/libcxx/__chrono/duration.h b/third_party/libcxx/__chrono/duration.h index 96e9671eb..1e36d7342 100644 --- a/third_party/libcxx/__chrono/duration.h +++ b/third_party/libcxx/__chrono/duration.h @@ -29,104 +29,82 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { -template > class _LIBCPP_TEMPLATE_VIS duration; +template > +class _LIBCPP_TEMPLATE_VIS duration; template struct __is_duration : false_type {}; template -struct __is_duration > : true_type {}; +struct __is_duration > : true_type {}; template -struct __is_duration > : true_type {}; +struct __is_duration > : true_type {}; template -struct __is_duration > : true_type {}; +struct __is_duration > : true_type {}; template -struct __is_duration > : true_type {}; +struct __is_duration > : true_type {}; } // namespace chrono template -struct _LIBCPP_TEMPLATE_VIS common_type, - chrono::duration<_Rep2, _Period2> > -{ - typedef chrono::duration::type, - typename __ratio_gcd<_Period1, _Period2>::type> type; +struct _LIBCPP_TEMPLATE_VIS common_type, chrono::duration<_Rep2, _Period2> > { + typedef chrono::duration::type, typename __ratio_gcd<_Period1, _Period2>::type> + type; }; namespace chrono { // duration_cast -template ::type, - bool = _Period::num == 1, - bool = _Period::den == 1> + bool = _Period::num == 1, + bool = _Period::den == 1> struct __duration_cast; template -struct __duration_cast<_FromDuration, _ToDuration, _Period, true, true> -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - _ToDuration operator()(const _FromDuration& __fd) const - { - return _ToDuration(static_cast(__fd.count())); - } +struct __duration_cast<_FromDuration, _ToDuration, _Period, true, true> { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration operator()(const _FromDuration& __fd) const { + return _ToDuration(static_cast(__fd.count())); + } }; template -struct __duration_cast<_FromDuration, _ToDuration, _Period, true, false> -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - _ToDuration operator()(const _FromDuration& __fd) const - { - typedef typename common_type::type _Ct; - return _ToDuration(static_cast( - static_cast<_Ct>(__fd.count()) / static_cast<_Ct>(_Period::den))); - } +struct __duration_cast<_FromDuration, _ToDuration, _Period, true, false> { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration operator()(const _FromDuration& __fd) const { + typedef typename common_type::type _Ct; + return _ToDuration( + static_cast(static_cast<_Ct>(__fd.count()) / static_cast<_Ct>(_Period::den))); + } }; template -struct __duration_cast<_FromDuration, _ToDuration, _Period, false, true> -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - _ToDuration operator()(const _FromDuration& __fd) const - { - typedef typename common_type::type _Ct; - return _ToDuration(static_cast( - static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num))); - } +struct __duration_cast<_FromDuration, _ToDuration, _Period, false, true> { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration operator()(const _FromDuration& __fd) const { + typedef typename common_type::type _Ct; + return _ToDuration( + static_cast(static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num))); + } }; template -struct __duration_cast<_FromDuration, _ToDuration, _Period, false, false> -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - _ToDuration operator()(const _FromDuration& __fd) const - { - typedef typename common_type::type _Ct; - return _ToDuration(static_cast( - static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num) - / static_cast<_Ct>(_Period::den))); - } +struct __duration_cast<_FromDuration, _ToDuration, _Period, false, false> { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration operator()(const _FromDuration& __fd) const { + typedef typename common_type::type _Ct; + return _ToDuration(static_cast( + static_cast<_Ct>(__fd.count()) * static_cast<_Ct>(_Period::num) / static_cast<_Ct>(_Period::den))); + } }; -template -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -typename enable_if -< - __is_duration<_ToDuration>::value, - _ToDuration ->::type -duration_cast(const duration<_Rep, _Period>& __fd) -{ - return __duration_cast, _ToDuration>()(__fd); +template ::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration duration_cast(const duration<_Rep, _Period>& __fd) { + return __duration_cast, _ToDuration>()(__fd); } template @@ -138,210 +116,204 @@ inline constexpr bool treat_as_floating_point_v = treat_as_floating_point<_Rep>: #endif template -struct _LIBCPP_TEMPLATE_VIS duration_values -{ +struct _LIBCPP_TEMPLATE_VIS duration_values { public: - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep zero() _NOEXCEPT {return _Rep(0);} - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep max() _NOEXCEPT {return numeric_limits<_Rep>::max();} - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR _Rep min() _NOEXCEPT {return numeric_limits<_Rep>::lowest();} + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR _Rep zero() _NOEXCEPT { return _Rep(0); } + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR _Rep max() _NOEXCEPT { return numeric_limits<_Rep>::max(); } + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR _Rep min() _NOEXCEPT { return numeric_limits<_Rep>::lowest(); } }; #if _LIBCPP_STD_VER >= 17 -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -typename enable_if -< - __is_duration<_ToDuration>::value, - _ToDuration ->::type -floor(const duration<_Rep, _Period>& __d) -{ - _ToDuration __t = chrono::duration_cast<_ToDuration>(__d); - if (__t > __d) - __t = __t - _ToDuration{1}; - return __t; +template ::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration floor(const duration<_Rep, _Period>& __d) { + _ToDuration __t = chrono::duration_cast<_ToDuration>(__d); + if (__t > __d) + __t = __t - _ToDuration{1}; + return __t; } -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -typename enable_if -< - __is_duration<_ToDuration>::value, - _ToDuration ->::type -ceil(const duration<_Rep, _Period>& __d) -{ - _ToDuration __t = chrono::duration_cast<_ToDuration>(__d); - if (__t < __d) - __t = __t + _ToDuration{1}; - return __t; +template ::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration ceil(const duration<_Rep, _Period>& __d) { + _ToDuration __t = chrono::duration_cast<_ToDuration>(__d); + if (__t < __d) + __t = __t + _ToDuration{1}; + return __t; } -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -typename enable_if -< - __is_duration<_ToDuration>::value, - _ToDuration ->::type -round(const duration<_Rep, _Period>& __d) -{ - _ToDuration __lower = chrono::floor<_ToDuration>(__d); - _ToDuration __upper = __lower + _ToDuration{1}; - auto __lower_diff = __d - __lower; - auto __upper_diff = __upper - __d; - if (__lower_diff < __upper_diff) - return __lower; - if (__lower_diff > __upper_diff) - return __upper; - return __lower.count() & 1 ? __upper : __lower; +template ::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ToDuration round(const duration<_Rep, _Period>& __d) { + _ToDuration __lower = chrono::floor<_ToDuration>(__d); + _ToDuration __upper = __lower + _ToDuration{1}; + auto __lower_diff = __d - __lower; + auto __upper_diff = __upper - __d; + if (__lower_diff < __upper_diff) + return __lower; + if (__lower_diff > __upper_diff) + return __upper; + return __lower.count() & 1 ? __upper : __lower; } #endif // duration template -class _LIBCPP_TEMPLATE_VIS duration -{ - static_assert(!__is_duration<_Rep>::value, "A duration representation can not be a duration"); - static_assert(__is_ratio<_Period>::value, "Second template parameter of duration must be a std::ratio"); - static_assert(_Period::num > 0, "duration period must be positive"); +class _LIBCPP_TEMPLATE_VIS duration { + static_assert(!__is_duration<_Rep>::value, "A duration representation can not be a duration"); + static_assert(__is_ratio<_Period>::value, "Second template parameter of duration must be a std::ratio"); + static_assert(_Period::num > 0, "duration period must be positive"); - template - struct __no_overflow + template + struct __no_overflow { + private: + static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value; + static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value; + static const intmax_t __n1 = _R1::num / __gcd_n1_n2; + static const intmax_t __d1 = _R1::den / __gcd_d1_d2; + static const intmax_t __n2 = _R2::num / __gcd_n1_n2; + static const intmax_t __d2 = _R2::den / __gcd_d1_d2; + static const intmax_t max = -((intmax_t(1) << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1); + + template + struct __mul // __overflow == false { - private: - static const intmax_t __gcd_n1_n2 = __static_gcd<_R1::num, _R2::num>::value; - static const intmax_t __gcd_d1_d2 = __static_gcd<_R1::den, _R2::den>::value; - static const intmax_t __n1 = _R1::num / __gcd_n1_n2; - static const intmax_t __d1 = _R1::den / __gcd_d1_d2; - static const intmax_t __n2 = _R2::num / __gcd_n1_n2; - static const intmax_t __d2 = _R2::den / __gcd_d1_d2; - static const intmax_t max = -((intmax_t(1) << (sizeof(intmax_t) * CHAR_BIT - 1)) + 1); - - template - struct __mul // __overflow == false - { - static const intmax_t value = _Xp * _Yp; - }; - - template - struct __mul<_Xp, _Yp, true> - { - static const intmax_t value = 1; - }; - - public: - static const bool value = (__n1 <= max / __d2) && (__n2 <= max / __d1); - typedef ratio<__mul<__n1, __d2, !value>::value, - __mul<__n2, __d1, !value>::value> type; + static const intmax_t value = _Xp * _Yp; }; -public: - typedef _Rep rep; - typedef typename _Period::type period; -private: - rep __rep_; -public: + template + struct __mul<_Xp, _Yp, true> { + static const intmax_t value = 1; + }; + public: + static const bool value = (__n1 <= max / __d2) && (__n2 <= max / __d1); + typedef ratio<__mul<__n1, __d2, !value>::value, __mul<__n2, __d1, !value>::value> type; + }; + +public: + typedef _Rep rep; + typedef typename _Period::type period; + +private: + rep __rep_; + +public: #ifndef _LIBCPP_CXX03_LANG - constexpr duration() = default; + constexpr duration() = default; #else - _LIBCPP_HIDE_FROM_ABI duration() {} + _LIBCPP_HIDE_FROM_ABI duration() {} #endif - template - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - explicit duration(const _Rep2& __r, - typename enable_if - < - is_convertible::value && - (treat_as_floating_point::value || - !treat_as_floating_point<_Rep2>::value) - >::type* = nullptr) - : __rep_(__r) {} + template ::value && + (treat_as_floating_point::value || !treat_as_floating_point<_Rep2>::value), + int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit duration(const _Rep2& __r) : __rep_(__r) {} - // conversions - template - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - duration(const duration<_Rep2, _Period2>& __d, - typename enable_if - < - __no_overflow<_Period2, period>::value && ( - treat_as_floating_point::value || - (__no_overflow<_Period2, period>::type::den == 1 && - !treat_as_floating_point<_Rep2>::value)) - >::type* = nullptr) - : __rep_(chrono::duration_cast(__d).count()) {} + // conversions + template ::value && (treat_as_floating_point::value || + (__no_overflow<_Period2, period>::type::den == 1 && + !treat_as_floating_point<_Rep2>::value)), + int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR duration(const duration<_Rep2, _Period2>& __d) + : __rep_(chrono::duration_cast(__d).count()) {} - // observer + // observer - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR rep count() const {return __rep_;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR rep count() const { return __rep_; } - // arithmetic + // arithmetic - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename common_type::type operator+() const {return typename common_type::type(*this);} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR typename common_type::type operator-() const {return typename common_type::type(-__rep_);} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator++() {++__rep_; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration operator++(int) {return duration(__rep_++);} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator--() {--__rep_; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration operator--(int) {return duration(__rep_--);} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR typename common_type::type operator+() const { + return typename common_type::type(*this); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR typename common_type::type operator-() const { + return typename common_type::type(-__rep_); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator++() { + ++__rep_; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration operator++(int) { return duration(__rep_++); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator--() { + --__rep_; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration operator--(int) { return duration(__rep_--); } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator+=(const duration& __d) {__rep_ += __d.count(); return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator-=(const duration& __d) {__rep_ -= __d.count(); return *this;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator+=(const duration& __d) { + __rep_ += __d.count(); + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator-=(const duration& __d) { + __rep_ -= __d.count(); + return *this; + } - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator*=(const rep& __rhs) {__rep_ *= __rhs; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator/=(const rep& __rhs) {__rep_ /= __rhs; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator%=(const rep& __rhs) {__rep_ %= __rhs; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator%=(const duration& __rhs) {__rep_ %= __rhs.count(); return *this;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator*=(const rep& __rhs) { + __rep_ *= __rhs; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator/=(const rep& __rhs) { + __rep_ /= __rhs; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator%=(const rep& __rhs) { + __rep_ %= __rhs; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 duration& operator%=(const duration& __rhs) { + __rep_ %= __rhs.count(); + return *this; + } - // special values + // special values - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration zero() _NOEXCEPT {return duration(duration_values::zero());} - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration min() _NOEXCEPT {return duration(duration_values::min());} - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR duration max() _NOEXCEPT {return duration(duration_values::max());} + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR duration zero() _NOEXCEPT { + return duration(duration_values::zero()); + } + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR duration min() _NOEXCEPT { + return duration(duration_values::min()); + } + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR duration max() _NOEXCEPT { + return duration(duration_values::max()); + } }; -typedef duration nanoseconds; -typedef duration microseconds; -typedef duration milliseconds; -typedef duration seconds; -typedef duration< long, ratio< 60> > minutes; -typedef duration< long, ratio<3600> > hours; +typedef duration nanoseconds; +typedef duration microseconds; +typedef duration milliseconds; +typedef duration seconds; +typedef duration< long, ratio< 60> > minutes; +typedef duration< long, ratio<3600> > hours; #if _LIBCPP_STD_VER >= 20 -typedef duration< int, ratio_multiply, hours::period>> days; -typedef duration< int, ratio_multiply, days::period>> weeks; -typedef duration< int, ratio_multiply, days::period>> years; -typedef duration< int, ratio_divide>> months; +typedef duration< int, ratio_multiply, hours::period>> days; +typedef duration< int, ratio_multiply, days::period>> weeks; +typedef duration< int, ratio_multiply, days::period>> years; +typedef duration< int, ratio_divide>> months; #endif // Duration == template -struct __duration_eq -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const - { - typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct; - return _Ct(__lhs).count() == _Ct(__rhs).count(); - } +struct __duration_eq { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const { + typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct; + return _Ct(__lhs).count() == _Ct(__rhs).count(); + } }; template -struct __duration_eq<_LhsDuration, _LhsDuration> -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const - {return __lhs.count() == __rhs.count();} +struct __duration_eq<_LhsDuration, _LhsDuration> { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const { + return __lhs.count() == __rhs.count(); + } }; template -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -bool -operator==(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - return __duration_eq, duration<_Rep2, _Period2> >()(__lhs, __rhs); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool +operator==(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { + return __duration_eq, duration<_Rep2, _Period2> >()(__lhs, __rhs); } #if _LIBCPP_STD_VER <= 17 @@ -349,12 +321,9 @@ operator==(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period // Duration != template -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -bool -operator!=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - return !(__lhs == __rhs); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool +operator!=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { + return !(__lhs == __rhs); } #endif // _LIBCPP_STD_VER <= 17 @@ -362,76 +331,58 @@ operator!=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period // Duration < template -struct __duration_lt -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const - { - typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct; - return _Ct(__lhs).count() < _Ct(__rhs).count(); - } +struct __duration_lt { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator()(const _LhsDuration& __lhs, const _RhsDuration& __rhs) const { + typedef typename common_type<_LhsDuration, _RhsDuration>::type _Ct; + return _Ct(__lhs).count() < _Ct(__rhs).count(); + } }; template -struct __duration_lt<_LhsDuration, _LhsDuration> -{ - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR - bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const - {return __lhs.count() < __rhs.count();} +struct __duration_lt<_LhsDuration, _LhsDuration> { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator()(const _LhsDuration& __lhs, const _LhsDuration& __rhs) const { + return __lhs.count() < __rhs.count(); + } }; template -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -bool -operator< (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - return __duration_lt, duration<_Rep2, _Period2> >()(__lhs, __rhs); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool +operator<(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { + return __duration_lt, duration<_Rep2, _Period2> >()(__lhs, __rhs); } // Duration > template -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -bool -operator> (const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - return __rhs < __lhs; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool +operator>(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { + return __rhs < __lhs; } // Duration <= template -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -bool -operator<=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - return !(__rhs < __lhs); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool +operator<=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { + return !(__rhs < __lhs); } // Duration >= template -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -bool -operator>=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - return !(__lhs < __rhs); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool +operator>=(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { + return !(__lhs < __rhs); } #if _LIBCPP_STD_VER >= 20 -template +template requires three_way_comparable> -_LIBCPP_HIDE_FROM_ABI -constexpr auto operator<=>(const duration<_Rep1, _Period1>& __lhs, - const duration<_Rep2, _Period2>& __rhs) -{ - using _Ct = common_type_t, duration<_Rep2, _Period2>>; - return _Ct(__lhs).count() <=> _Ct(__rhs).count(); +_LIBCPP_HIDE_FROM_ABI constexpr auto +operator<=>(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { + using _Ct = common_type_t, duration<_Rep2, _Period2>>; + return _Ct(__lhs).count() <=> _Ct(__rhs).count(); } #endif // _LIBCPP_STD_VER >= 20 @@ -439,193 +390,151 @@ constexpr auto operator<=>(const duration<_Rep1, _Period1>& __lhs, // Duration + template -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR typename common_type, duration<_Rep2, _Period2> >::type -operator+(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - typedef typename common_type, duration<_Rep2, _Period2> >::type _Cd; - return _Cd(_Cd(__lhs).count() + _Cd(__rhs).count()); +operator+(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { + typedef typename common_type, duration<_Rep2, _Period2> >::type _Cd; + return _Cd(_Cd(__lhs).count() + _Cd(__rhs).count()); } // Duration - template -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR typename common_type, duration<_Rep2, _Period2> >::type -operator-(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - typedef typename common_type, duration<_Rep2, _Period2> >::type _Cd; - return _Cd(_Cd(__lhs).count() - _Cd(__rhs).count()); +operator-(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { + typedef typename common_type, duration<_Rep2, _Period2> >::type _Cd; + return _Cd(_Cd(__lhs).count() - _Cd(__rhs).count()); } // Duration * -template -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -typename enable_if -< - is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value, - duration::type, _Period> ->::type -operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s) -{ - typedef typename common_type<_Rep1, _Rep2>::type _Cr; - typedef duration<_Cr, _Period> _Cd; - return _Cd(_Cd(__d).count() * static_cast<_Cr>(__s)); +template ::type>::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR duration::type, _Period> +operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s) { + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef duration<_Cr, _Period> _Cd; + return _Cd(_Cd(__d).count() * static_cast<_Cr>(__s)); } -template -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -typename enable_if -< - is_convertible<_Rep1, typename common_type<_Rep1, _Rep2>::type>::value, - duration::type, _Period> ->::type -operator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d) -{ - return __d * __s; +template ::type>::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR duration::type, _Period> +operator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d) { + return __d * __s; } // Duration / -template -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -typename enable_if -< - !__is_duration<_Rep2>::value && - is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value, - duration::type, _Period> ->::type -operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s) -{ - typedef typename common_type<_Rep1, _Rep2>::type _Cr; - typedef duration<_Cr, _Period> _Cd; - return _Cd(_Cd(__d).count() / static_cast<_Cr>(__s)); +template ::value && + is_convertible::type>::value, + int> = 0> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR duration::type, _Period> +operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s) { + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef duration<_Cr, _Period> _Cd; + return _Cd(_Cd(__d).count() / static_cast<_Cr>(__s)); } template -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -typename common_type<_Rep1, _Rep2>::type -operator/(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - typedef typename common_type, duration<_Rep2, _Period2> >::type _Ct; - return _Ct(__lhs).count() / _Ct(__rhs).count(); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR typename common_type<_Rep1, _Rep2>::type +operator/(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { + typedef typename common_type, duration<_Rep2, _Period2> >::type _Ct; + return _Ct(__lhs).count() / _Ct(__rhs).count(); } // Duration % -template -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR -typename enable_if -< - !__is_duration<_Rep2>::value && - is_convertible<_Rep2, typename common_type<_Rep1, _Rep2>::type>::value, - duration::type, _Period> ->::type -operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s) -{ - typedef typename common_type<_Rep1, _Rep2>::type _Cr; - typedef duration<_Cr, _Period> _Cd; - return _Cd(_Cd(__d).count() % static_cast<_Cr>(__s)); +template ::value && + is_convertible::type>::value, + int> = 0> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR duration::type, _Period> +operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s) { + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef duration<_Cr, _Period> _Cd; + return _Cd(_Cd(__d).count() % static_cast<_Cr>(__s)); } template -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR typename common_type, duration<_Rep2, _Period2> >::type -operator%(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - typedef typename common_type<_Rep1, _Rep2>::type _Cr; - typedef typename common_type, duration<_Rep2, _Period2> >::type _Cd; - return _Cd(static_cast<_Cr>(_Cd(__lhs).count()) % static_cast<_Cr>(_Cd(__rhs).count())); +operator%(const duration<_Rep1, _Period1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { + typedef typename common_type<_Rep1, _Rep2>::type _Cr; + typedef typename common_type, duration<_Rep2, _Period2> >::type _Cd; + return _Cd(static_cast<_Cr>(_Cd(__lhs).count()) % static_cast<_Cr>(_Cd(__rhs).count())); } } // namespace chrono #if _LIBCPP_STD_VER >= 14 // Suffixes for duration literals [time.duration.literals] -inline namespace literals -{ - inline namespace chrono_literals - { +inline namespace literals { +inline namespace chrono_literals { - _LIBCPP_HIDE_FROM_ABI constexpr chrono::hours operator""h(unsigned long long __h) - { - return chrono::hours(static_cast(__h)); - } +_LIBCPP_HIDE_FROM_ABI constexpr chrono::hours operator""h(unsigned long long __h) { + return chrono::hours(static_cast(__h)); +} - _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration> operator""h(long double __h) - { - return chrono::duration>(__h); - } +_LIBCPP_HIDE_FROM_ABI constexpr chrono::duration> operator""h(long double __h) { + return chrono::duration>(__h); +} +_LIBCPP_HIDE_FROM_ABI constexpr chrono::minutes operator""min(unsigned long long __m) { + return chrono::minutes(static_cast(__m)); +} - _LIBCPP_HIDE_FROM_ABI constexpr chrono::minutes operator""min(unsigned long long __m) - { - return chrono::minutes(static_cast(__m)); - } +_LIBCPP_HIDE_FROM_ABI constexpr chrono::duration> operator""min(long double __m) { + return chrono::duration>(__m); +} - _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration> operator""min(long double __m) - { - return chrono::duration> (__m); - } +_LIBCPP_HIDE_FROM_ABI constexpr chrono::seconds operator""s(unsigned long long __s) { + return chrono::seconds(static_cast(__s)); +} +_LIBCPP_HIDE_FROM_ABI constexpr chrono::duration operator""s(long double __s) { + return chrono::duration(__s); +} - _LIBCPP_HIDE_FROM_ABI constexpr chrono::seconds operator""s(unsigned long long __s) - { - return chrono::seconds(static_cast(__s)); - } +_LIBCPP_HIDE_FROM_ABI constexpr chrono::milliseconds operator""ms(unsigned long long __ms) { + return chrono::milliseconds(static_cast(__ms)); +} - _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration operator""s(long double __s) - { - return chrono::duration (__s); - } +_LIBCPP_HIDE_FROM_ABI constexpr chrono::duration operator""ms(long double __ms) { + return chrono::duration(__ms); +} +_LIBCPP_HIDE_FROM_ABI constexpr chrono::microseconds operator""us(unsigned long long __us) { + return chrono::microseconds(static_cast(__us)); +} - _LIBCPP_HIDE_FROM_ABI constexpr chrono::milliseconds operator""ms(unsigned long long __ms) - { - return chrono::milliseconds(static_cast(__ms)); - } +_LIBCPP_HIDE_FROM_ABI constexpr chrono::duration operator""us(long double __us) { + return chrono::duration(__us); +} - _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration operator""ms(long double __ms) - { - return chrono::duration(__ms); - } +_LIBCPP_HIDE_FROM_ABI constexpr chrono::nanoseconds operator""ns(unsigned long long __ns) { + return chrono::nanoseconds(static_cast(__ns)); +} - - _LIBCPP_HIDE_FROM_ABI constexpr chrono::microseconds operator""us(unsigned long long __us) - { - return chrono::microseconds(static_cast(__us)); - } - - _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration operator""us(long double __us) - { - return chrono::duration (__us); - } - - - _LIBCPP_HIDE_FROM_ABI constexpr chrono::nanoseconds operator""ns(unsigned long long __ns) - { - return chrono::nanoseconds(static_cast(__ns)); - } - - _LIBCPP_HIDE_FROM_ABI constexpr chrono::duration operator""ns(long double __ns) - { - return chrono::duration (__ns); - } +_LIBCPP_HIDE_FROM_ABI constexpr chrono::duration operator""ns(long double __ns) { + return chrono::duration(__ns); +} } // namespace chrono_literals } // namespace literals namespace chrono { // hoist the literals into namespace std::chrono - using namespace literals::chrono_literals; +using namespace literals::chrono_literals; } // namespace chrono #endif // _LIBCPP_STD_VER >= 14 diff --git a/third_party/libcxx/__chrono/exception.h b/third_party/libcxx/__chrono/exception.h new file mode 100644 index 000000000..266f8fac4 --- /dev/null +++ b/third_party/libcxx/__chrono/exception.h @@ -0,0 +1,135 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html + +#ifndef _LIBCPP___CHRONO_EXCEPTION_H +#define _LIBCPP___CHRONO_EXCEPTION_H + +#include +// Enable the contents of the header only when libc++ was built with experimental features enabled. +#if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) + +# include <__chrono/calendar.h> +# include <__chrono/local_info.h> +# include <__chrono/time_point.h> +# include <__config> +# include <__configuration/availability.h> +# include <__verbose_abort> +# include +# include +# include + +# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +# endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +# if _LIBCPP_STD_VER >= 20 + +namespace chrono { + +class nonexistent_local_time : public runtime_error { +public: + template + _LIBCPP_HIDE_FROM_ABI nonexistent_local_time(const local_time<_Duration>& __time, const local_info& __info) + : runtime_error{__create_message(__time, __info)} { + // [time.zone.exception.nonexist]/2 + // Preconditions: i.result == local_info::nonexistent is true. + // The value of __info.result is not used. + _LIBCPP_ASSERT_PEDANTIC(__info.result == local_info::nonexistent, + "creating an nonexistent_local_time from a local_info that is not non-existent"); + } + + _LIBCPP_HIDE_FROM_ABI nonexistent_local_time(const nonexistent_local_time&) = default; + _LIBCPP_HIDE_FROM_ABI nonexistent_local_time& operator=(const nonexistent_local_time&) = default; + + _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI ~nonexistent_local_time() override; // exported as key function + +private: + template + _LIBCPP_HIDE_FROM_ABI string __create_message(const local_time<_Duration>& __time, const local_info& __info) { + return std::format( + R"({} is in a gap between +{} {} and +{} {} which are both equivalent to +{} UTC)", + __time, + local_seconds{__info.first.end.time_since_epoch()} + __info.first.offset, + __info.first.abbrev, + local_seconds{__info.second.begin.time_since_epoch()} + __info.second.offset, + __info.second.abbrev, + __info.first.end); + } +}; + +template +_LIBCPP_NORETURN _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI void __throw_nonexistent_local_time( + [[maybe_unused]] const local_time<_Duration>& __time, [[maybe_unused]] const local_info& __info) { +# ifndef _LIBCPP_HAS_NO_EXCEPTIONS + throw nonexistent_local_time(__time, __info); +# else + _LIBCPP_VERBOSE_ABORT("nonexistent_local_time was thrown in -fno-exceptions mode"); +# endif +} + +class ambiguous_local_time : public runtime_error { +public: + template + _LIBCPP_HIDE_FROM_ABI ambiguous_local_time(const local_time<_Duration>& __time, const local_info& __info) + : runtime_error{__create_message(__time, __info)} { + // [time.zone.exception.ambig]/2 + // Preconditions: i.result == local_info::ambiguous is true. + // The value of __info.result is not used. + _LIBCPP_ASSERT_PEDANTIC(__info.result == local_info::ambiguous, + "creating an ambiguous_local_time from a local_info that is not ambiguous"); + } + + _LIBCPP_HIDE_FROM_ABI ambiguous_local_time(const ambiguous_local_time&) = default; + _LIBCPP_HIDE_FROM_ABI ambiguous_local_time& operator=(const ambiguous_local_time&) = default; + + _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI ~ambiguous_local_time() override; // exported as key function + +private: + template + _LIBCPP_HIDE_FROM_ABI string __create_message(const local_time<_Duration>& __time, const local_info& __info) { + return std::format( + // There are two spaces after the full-stop; this has been verified + // in the sources of the Standard. + R"({0} is ambiguous. It could be +{0} {1} == {2} UTC or +{0} {3} == {4} UTC)", + __time, + __info.first.abbrev, + __time - __info.first.offset, + __info.second.abbrev, + __time - __info.second.offset); + } +}; + +template +_LIBCPP_NORETURN _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI void __throw_ambiguous_local_time( + [[maybe_unused]] const local_time<_Duration>& __time, [[maybe_unused]] const local_info& __info) { +# ifndef _LIBCPP_HAS_NO_EXCEPTIONS + throw ambiguous_local_time(__time, __info); +# else + _LIBCPP_VERBOSE_ABORT("ambiguous_local_time was thrown in -fno-exceptions mode"); +# endif +} + +} // namespace chrono + +# endif // _LIBCPP_STD_VER >= 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) + +#endif // _LIBCPP___CHRONO_EXCEPTION_H diff --git a/third_party/libcxx/__chrono/file_clock.h b/third_party/libcxx/__chrono/file_clock.h index 7a4dce9d5..4dd3f88ce 100644 --- a/third_party/libcxx/__chrono/file_clock.h +++ b/third_party/libcxx/__chrono/file_clock.h @@ -10,7 +10,6 @@ #ifndef _LIBCPP___CHRONO_FILE_CLOCK_H #define _LIBCPP___CHRONO_FILE_CLOCK_H -#include <__availability> #include <__chrono/duration.h> #include <__chrono/system_clock.h> #include <__chrono/time_point.h> @@ -31,13 +30,12 @@ _LIBCPP_END_NAMESPACE_FILESYSTEM _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { // [time.clock.file], type file_clock -using file_clock = _VSTD_FS::_FilesystemClock; +using file_clock = filesystem::_FilesystemClock; -template +template using file_time = time_point; } // namespace chrono @@ -49,35 +47,32 @@ _LIBCPP_END_NAMESPACE_STD #ifndef _LIBCPP_CXX03_LANG _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM struct _FilesystemClock { -#if !defined(_LIBCPP_HAS_NO_INT128) +# if !defined(_LIBCPP_HAS_NO_INT128) typedef __int128_t rep; typedef nano period; -#else +# else typedef long long rep; typedef nano period; -#endif +# endif typedef chrono::duration duration; typedef chrono::time_point<_FilesystemClock> time_point; - _LIBCPP_EXPORTED_FROM_ABI - static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = false; + _LIBCPP_EXPORTED_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = false; - _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_FUNC_VIS static time_point now() noexcept; + _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_EXPORTED_FROM_ABI static time_point now() noexcept; -#if _LIBCPP_STD_VER >= 20 +# if _LIBCPP_STD_VER >= 20 template - _LIBCPP_HIDE_FROM_ABI - static chrono::sys_time<_Duration> to_sys(const chrono::file_time<_Duration>& __t) { + _LIBCPP_HIDE_FROM_ABI static chrono::sys_time<_Duration> to_sys(const chrono::file_time<_Duration>& __t) { return chrono::sys_time<_Duration>(__t.time_since_epoch()); } template - _LIBCPP_HIDE_FROM_ABI - static chrono::file_time<_Duration> from_sys(const chrono::sys_time<_Duration>& __t) { + _LIBCPP_HIDE_FROM_ABI static chrono::file_time<_Duration> from_sys(const chrono::sys_time<_Duration>& __t) { return chrono::file_time<_Duration>(__t.time_since_epoch()); } -#endif // _LIBCPP_STD_VER >= 20 +# endif // _LIBCPP_STD_VER >= 20 }; _LIBCPP_END_NAMESPACE_FILESYSTEM #endif // !_LIBCPP_CXX03_LANG diff --git a/third_party/libcxx/__chrono/formatter.h b/third_party/libcxx/__chrono/formatter.h index 679edf39c..449c415e9 100644 --- a/third_party/libcxx/__chrono/formatter.h +++ b/third_party/libcxx/__chrono/formatter.h @@ -10,6 +10,7 @@ #ifndef _LIBCPP___CHRONO_FORMATTER_H #define _LIBCPP___CHRONO_FORMATTER_H +#include <__algorithm/ranges_copy.h> #include <__chrono/calendar.h> #include <__chrono/concepts.h> #include <__chrono/convert_to_tm.h> @@ -17,12 +18,14 @@ #include <__chrono/duration.h> #include <__chrono/file_clock.h> #include <__chrono/hh_mm_ss.h> +#include <__chrono/local_info.h> #include <__chrono/month.h> #include <__chrono/month_weekday.h> #include <__chrono/monthday.h> #include <__chrono/ostream.h> #include <__chrono/parser_std_format_spec.h> #include <__chrono/statically_widen.h> +#include <__chrono/sys_info.h> #include <__chrono/system_clock.h> #include <__chrono/time_point.h> #include <__chrono/weekday.h> @@ -30,6 +33,7 @@ #include <__chrono/year_month.h> #include <__chrono/year_month_day.h> #include <__chrono/year_month_weekday.h> +#include <__chrono/zoned_time.h> #include <__concepts/arithmetic.h> #include <__concepts/same_as.h> #include <__config> @@ -38,13 +42,14 @@ #include <__format/format_functions.h> #include <__format/format_parse_context.h> #include <__format/formatter.h> -#include <__format/formatter_output.h> #include <__format/parser_std_format_spec.h> +#include <__format/write_escaped.h> #include <__memory/addressof.h> +#include <__type_traits/is_specialization.h> #include #include +#include #include -#include #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -80,12 +85,15 @@ namespace __formatter { // small). Therefore a duration uses its own conversion. template _LIBCPP_HIDE_FROM_ABI void -__format_sub_seconds(const chrono::duration<_Rep, _Period>& __value, basic_stringstream<_CharT>& __sstr) { +__format_sub_seconds(basic_stringstream<_CharT>& __sstr, const chrono::duration<_Rep, _Period>& __value) { __sstr << std::use_facet>(__sstr.getloc()).decimal_point(); using __duration = chrono::duration<_Rep, _Period>; auto __fraction = __value - chrono::duration_cast(__value); + // Converts a negative fraction to its positive value. + if (__value < chrono::seconds{0} && __fraction != __duration{0}) + __fraction += chrono::seconds{1}; if constexpr (chrono::treat_as_floating_point_v<_Rep>) // When the floating-point value has digits itself they are ignored based // on the wording in [tab:time.format.spec] @@ -101,23 +109,23 @@ __format_sub_seconds(const chrono::duration<_Rep, _Period>& __value, basic_strin // https://godbolt.org/z/6dsbnW8ba std::format_to(std::ostreambuf_iterator<_CharT>{__sstr}, _LIBCPP_STATICALLY_WIDEN(_CharT, "{:0{}.0f}"), - __fraction.count(), + chrono::duration_cast::precision>(__fraction).count(), chrono::hh_mm_ss<__duration>::fractional_width); else std::format_to(std::ostreambuf_iterator<_CharT>{__sstr}, _LIBCPP_STATICALLY_WIDEN(_CharT, "{:0{}}"), - __fraction.count(), + chrono::duration_cast::precision>(__fraction).count(), chrono::hh_mm_ss<__duration>::fractional_width); } template -_LIBCPP_HIDE_FROM_ABI void __format_sub_seconds(const _Tp& __value, basic_stringstream<_CharT>& __sstr) { - __formatter::__format_sub_seconds(__value.time_since_epoch(), __sstr); +_LIBCPP_HIDE_FROM_ABI void __format_sub_seconds(basic_stringstream<_CharT>& __sstr, const _Tp& __value) { + __formatter::__format_sub_seconds(__sstr, __value.time_since_epoch()); } template _LIBCPP_HIDE_FROM_ABI void -__format_sub_seconds(const chrono::hh_mm_ss<_Duration>& __value, basic_stringstream<_CharT>& __sstr) { +__format_sub_seconds(basic_stringstream<_CharT>& __sstr, const chrono::hh_mm_ss<_Duration>& __value) { __sstr << std::use_facet>(__sstr.getloc()).decimal_point(); if constexpr (chrono::treat_as_floating_point_v) std::format_to(std::ostreambuf_iterator<_CharT>{__sstr}, @@ -131,10 +139,24 @@ __format_sub_seconds(const chrono::hh_mm_ss<_Duration>& __value, basic_stringstr __value.fractional_width); } +# if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) && !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && \ + !defined(_LIBCPP_HAS_NO_FILESYSTEM) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) +template +_LIBCPP_HIDE_FROM_ABI void +__format_sub_seconds(basic_stringstream<_CharT>& __sstr, const chrono::zoned_time<_Duration, _TimeZonePtr>& __value) { + __formatter::__format_sub_seconds(__sstr, __value.get_local_time().time_since_epoch()); +} +# endif + template consteval bool __use_fraction() { if constexpr (__is_time_point<_Tp>) return chrono::hh_mm_ss::fractional_width; +# if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) && !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && \ + !defined(_LIBCPP_HAS_NO_FILESYSTEM) && !defined(_LIBCPP_HAS_NO_LOCALIZATION) + else if constexpr (__is_specialization_v<_Tp, chrono::zoned_time>) + return chrono::hh_mm_ss::fractional_width; +# endif else if constexpr (chrono::__is_duration<_Tp>::value) return chrono::hh_mm_ss<_Tp>::fractional_width; else if constexpr (__is_hh_mm_ss<_Tp>) @@ -144,7 +166,7 @@ consteval bool __use_fraction() { } template -_LIBCPP_HIDE_FROM_ABI void __format_year(int __year, basic_stringstream<_CharT>& __sstr) { +_LIBCPP_HIDE_FROM_ABI void __format_year(basic_stringstream<_CharT>& __sstr, int __year) { if (__year < 0) { __sstr << _CharT('-'); __year = -__year; @@ -160,7 +182,7 @@ _LIBCPP_HIDE_FROM_ABI void __format_year(int __year, basic_stringstream<_CharT>& } template -_LIBCPP_HIDE_FROM_ABI void __format_century(int __year, basic_stringstream<_CharT>& __sstr) { +_LIBCPP_HIDE_FROM_ABI void __format_century(basic_stringstream<_CharT>& __sstr, int __year) { // TODO FMT Write an issue // [tab:time.format.spec] // %C The year divided by 100 using floored division. If the result is a @@ -171,10 +193,56 @@ _LIBCPP_HIDE_FROM_ABI void __format_century(int __year, basic_stringstream<_Char __sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "{:02}"), __century); } +// Implements the %z format specifier according to [tab:time.format.spec], where +// '__modifier' signals %Oz or %Ez were used. (Both modifiers behave the same, +// so there is no need to distinguish between them.) +template +_LIBCPP_HIDE_FROM_ABI void +__format_zone_offset(basic_stringstream<_CharT>& __sstr, chrono::seconds __offset, bool __modifier) { + if (__offset < 0s) { + __sstr << _CharT('-'); + __offset = -__offset; + } else { + __sstr << _CharT('+'); + } + + chrono::hh_mm_ss __hms{__offset}; + std::ostreambuf_iterator<_CharT> __out_it{__sstr}; + // Note HMS does not allow formatting hours > 23, but the offset is not limited to 24H. + std::format_to(__out_it, _LIBCPP_STATICALLY_WIDEN(_CharT, "{:02}"), __hms.hours().count()); + if (__modifier) + __sstr << _CharT(':'); + std::format_to(__out_it, _LIBCPP_STATICALLY_WIDEN(_CharT, "{:02}"), __hms.minutes().count()); +} + +// Helper to store the time zone information needed for formatting. +struct _LIBCPP_HIDE_FROM_ABI __time_zone { + // Typically these abbreviations are short and fit in the string's internal + // buffer. + string __abbrev; + chrono::seconds __offset; +}; + +template +_LIBCPP_HIDE_FROM_ABI __time_zone __convert_to_time_zone([[maybe_unused]] const _Tp& __value) { +# if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) + if constexpr (same_as<_Tp, chrono::sys_info>) + return {__value.abbrev, __value.offset}; +# if !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) && \ + !defined(_LIBCPP_HAS_NO_LOCALIZATION) + else if constexpr (__is_specialization_v<_Tp, chrono::zoned_time>) + return __formatter::__convert_to_time_zone(__value.get_info()); +# endif + else +# endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) + return {"UTC", chrono::seconds{0}}; +} + template _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs( - const _Tp& __value, basic_stringstream<_CharT>& __sstr, basic_string_view<_CharT> __chrono_specs) { + basic_stringstream<_CharT>& __sstr, const _Tp& __value, basic_string_view<_CharT> __chrono_specs) { tm __t = std::__convert_to_tm(__value); + __time_zone __z = __formatter::__convert_to_time_zone(__value); const auto& __facet = std::use_facet>(__sstr.getloc()); for (auto __it = __chrono_specs.begin(); __it != __chrono_specs.end(); ++__it) { if (*__it == _CharT('%')) { @@ -197,9 +265,10 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs( // strftime's output is only defined in the range [00, 99]. int __year = __t.tm_year + 1900; if (__year < 1000 || __year > 9999) - __formatter::__format_century(__year, __sstr); + __formatter::__format_century(__sstr, __year); else - __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1)); + __facet.put( + {__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1)); } break; case _CharT('j'): @@ -210,7 +279,8 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs( // an intemediate step. __sstr << chrono::duration_cast(chrono::duration_cast(__value)).count(); else - __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1)); + __facet.put( + {__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1)); break; case _CharT('q'): @@ -238,9 +308,10 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs( case _CharT('S'): case _CharT('T'): - __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1)); + __facet.put( + {__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1)); if constexpr (__use_fraction<_Tp>()) - __formatter::__format_sub_seconds(__value, __sstr); + __formatter::__format_sub_seconds(__sstr, __value); break; // Unlike time_put and strftime the formatting library requires %Y @@ -281,21 +352,24 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs( // Depending on the platform's libc the range of supported years is // limited. Intead of of testing all conditions use the internal // implementation unconditionally. - __formatter::__format_year(__t.tm_year + 1900, __sstr); + __formatter::__format_year(__sstr, __t.tm_year + 1900); break; - case _CharT('F'): { - int __year = __t.tm_year + 1900; - if (__year < 1000) { - __formatter::__format_year(__year, __sstr); - __sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "-{:02}-{:02}"), __t.tm_mon + 1, __t.tm_mday); - } else - __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1)); - } break; + case _CharT('F'): + // Depending on the platform's libc the range of supported years is + // limited. Instead of testing all conditions use the internal + // implementation unconditionally. + __formatter::__format_year(__sstr, __t.tm_year + 1900); + __sstr << std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "-{:02}-{:02}"), __t.tm_mon + 1, __t.tm_mday); + break; + + case _CharT('z'): + __formatter::__format_zone_offset(__sstr, __z.__offset, false); + break; case _CharT('Z'): - // TODO FMT Add proper timezone support. - __sstr << _LIBCPP_STATICALLY_WIDEN(_CharT, "UTC"); + // __abbrev is always a char so the copy may convert. + ranges::copy(__z.__abbrev, std::ostreambuf_iterator<_CharT>{__sstr}); break; case _CharT('O'): @@ -305,17 +379,25 @@ _LIBCPP_HIDE_FROM_ABI void __format_chrono_using_chrono_specs( // fractional part should be formatted. if (*(__it + 1) == 'S') { ++__it; - __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1)); - __formatter::__format_sub_seconds(__value, __sstr); + __facet.put( + {__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1)); + __formatter::__format_sub_seconds(__sstr, __value); break; } } + + // Oz produces the same output as Ez below. [[fallthrough]]; case _CharT('E'): ++__it; + if (*__it == 'z') { + __formatter::__format_zone_offset(__sstr, __z.__offset, true); + break; + } [[fallthrough]]; default: - __facet.put({__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1)); + __facet.put( + {__sstr}, __sstr, _CharT(' '), std::addressof(__t), std::to_address(__s), std::to_address(__it + 1)); break; } } else { @@ -360,6 +442,17 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __weekday_ok(const _Tp& __value) { return __value.weekday().ok(); else if constexpr (__is_hh_mm_ss<_Tp>) return true; +# if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) + else if constexpr (same_as<_Tp, chrono::sys_info>) + return true; + else if constexpr (same_as<_Tp, chrono::local_info>) + return true; +# if !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) && \ + !defined(_LIBCPP_HAS_NO_LOCALIZATION) + else if constexpr (__is_specialization_v<_Tp, chrono::zoned_time>) + return true; +# endif +# endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) else static_assert(sizeof(_Tp) == 0, "Add the missing type specialization"); } @@ -400,6 +493,17 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __weekday_name_ok(const _Tp& __value) { return __value.weekday().ok(); else if constexpr (__is_hh_mm_ss<_Tp>) return true; +# if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) + else if constexpr (same_as<_Tp, chrono::sys_info>) + return true; + else if constexpr (same_as<_Tp, chrono::local_info>) + return true; +# if !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) && \ + !defined(_LIBCPP_HAS_NO_LOCALIZATION) + else if constexpr (__is_specialization_v<_Tp, chrono::zoned_time>) + return true; +# endif +# endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) else static_assert(sizeof(_Tp) == 0, "Add the missing type specialization"); } @@ -440,6 +544,17 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __date_ok(const _Tp& __value) { return __value.ok(); else if constexpr (__is_hh_mm_ss<_Tp>) return true; +# if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) + else if constexpr (same_as<_Tp, chrono::sys_info>) + return true; + else if constexpr (same_as<_Tp, chrono::local_info>) + return true; +# if !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) && \ + !defined(_LIBCPP_HAS_NO_LOCALIZATION) + else if constexpr (__is_specialization_v<_Tp, chrono::zoned_time>) + return true; +# endif +# endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) else static_assert(sizeof(_Tp) == 0, "Add the missing type specialization"); } @@ -480,6 +595,17 @@ _LIBCPP_HIDE_FROM_ABI constexpr bool __month_name_ok(const _Tp& __value) { return __value.month().ok(); else if constexpr (__is_hh_mm_ss<_Tp>) return true; +# if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) + else if constexpr (same_as<_Tp, chrono::sys_info>) + return true; + else if constexpr (same_as<_Tp, chrono::local_info>) + return true; +# if !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) && \ + !defined(_LIBCPP_HAS_NO_LOCALIZATION) + else if constexpr (__is_specialization_v<_Tp, chrono::zoned_time>) + return true; +# endif +# endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) else static_assert(sizeof(_Tp) == 0, "Add the missing type specialization"); } @@ -505,28 +631,35 @@ __format_chrono(const _Tp& __value, __sstr << __value; else { if constexpr (chrono::__is_duration<_Tp>::value) { - if (__value < __value.zero()) - __sstr << _CharT('-'); - __formatter::__format_chrono_using_chrono_specs(chrono::abs(__value), __sstr, __chrono_specs); + // A duration can be a user defined arithmetic type. Users may specialize + // numeric_limits, but they may not specialize is_signed. + if constexpr (numeric_limits::is_signed) { + if (__value < __value.zero()) { + __sstr << _CharT('-'); + __formatter::__format_chrono_using_chrono_specs(__sstr, -__value, __chrono_specs); + } else + __formatter::__format_chrono_using_chrono_specs(__sstr, __value, __chrono_specs); + } else + __formatter::__format_chrono_using_chrono_specs(__sstr, __value, __chrono_specs); // TODO FMT When keeping the precision it will truncate the string. // Note that the behaviour what the precision does isn't specified. __specs.__precision_ = -1; } else { // Test __weekday_name_ before __weekday_ to give a better error. if (__specs.__chrono_.__weekday_name_ && !__formatter::__weekday_name_ok(__value)) - std::__throw_format_error("formatting a weekday name needs a valid weekday"); + std::__throw_format_error("Formatting a weekday name needs a valid weekday"); if (__specs.__chrono_.__weekday_ && !__formatter::__weekday_ok(__value)) - std::__throw_format_error("formatting a weekday needs a valid weekday"); + std::__throw_format_error("Formatting a weekday needs a valid weekday"); if (__specs.__chrono_.__day_of_year_ && !__formatter::__date_ok(__value)) - std::__throw_format_error("formatting a day of year needs a valid date"); + std::__throw_format_error("Formatting a day of year needs a valid date"); if (__specs.__chrono_.__week_of_year_ && !__formatter::__date_ok(__value)) - std::__throw_format_error("formatting a week of year needs a valid date"); + std::__throw_format_error("Formatting a week of year needs a valid date"); if (__specs.__chrono_.__month_name_ && !__formatter::__month_name_ok(__value)) - std::__throw_format_error("formatting a month name from an invalid month number"); + std::__throw_format_error("Formatting a month name from an invalid month number"); if constexpr (__is_hh_mm_ss<_Tp>) { // Note this is a pedantic intepretation of the Standard. A hh_mm_ss @@ -545,13 +678,13 @@ __format_chrono(const _Tp& __value, // - Write it as not valid, // - or write the number of days. if (__specs.__chrono_.__hour_ && __value.hours().count() > 23) - std::__throw_format_error("formatting a hour needs a valid value"); + std::__throw_format_error("Formatting a hour needs a valid value"); if (__value.is_negative()) __sstr << _CharT('-'); } - __formatter::__format_chrono_using_chrono_specs(__value, __sstr, __chrono_specs); + __formatter::__format_chrono_using_chrono_specs(__sstr, __value, __chrono_specs); } } @@ -635,8 +768,7 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_chrono<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_chrono<_CharT> { public: using _Base = __formatter_chrono<_CharT>; @@ -647,8 +779,7 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_chrono<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_chrono<_CharT> { public: using _Base = __formatter_chrono<_CharT>; @@ -659,8 +790,7 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_chrono<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_chrono<_CharT> { public: using _Base = __formatter_chrono<_CharT>; @@ -671,8 +801,7 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_chrono<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_chrono<_CharT> { public: using _Base = __formatter_chrono<_CharT>; @@ -683,8 +812,7 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_chrono<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_chrono<_CharT> { public: using _Base = __formatter_chrono<_CharT>; @@ -695,8 +823,7 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_chrono<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_chrono<_CharT> { public: using _Base = __formatter_chrono<_CharT>; @@ -707,8 +834,7 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_chrono<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_chrono<_CharT> { public: using _Base = __formatter_chrono<_CharT>; @@ -719,8 +845,7 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_chrono<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_chrono<_CharT> { public: using _Base = __formatter_chrono<_CharT>; @@ -731,8 +856,7 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_chrono<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_chrono<_CharT> { public: using _Base = __formatter_chrono<_CharT>; @@ -743,8 +867,7 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_chrono<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_chrono<_CharT> { public: using _Base = __formatter_chrono<_CharT>; @@ -755,8 +878,7 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_chrono<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_chrono<_CharT> { public: using _Base = __formatter_chrono<_CharT>; @@ -767,8 +889,7 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_chrono<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_chrono<_CharT> { public: using _Base = __formatter_chrono<_CharT>; @@ -779,8 +900,7 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_chrono<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_chrono<_CharT> { public: using _Base = __formatter_chrono<_CharT>; @@ -791,8 +911,7 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_chrono<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_chrono<_CharT> { public: using _Base = __formatter_chrono<_CharT>; @@ -803,8 +922,7 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_chrono<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_chrono<_CharT> { public: using _Base = __formatter_chrono<_CharT>; @@ -824,6 +942,47 @@ public: return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__time); } }; + +# if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) +template <__fmt_char_type _CharT> +struct formatter : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + template + _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { + return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__time_zone); + } +}; + +template <__fmt_char_type _CharT> +struct formatter : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + template + _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { + return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags{}); + } +}; +# if !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) && \ + !defined(_LIBCPP_HAS_NO_LOCALIZATION) +// Note due to how libc++'s formatters are implemented there is no need to add +// the exposition only local-time-format-t abstraction. +template +struct formatter, _CharT> : public __formatter_chrono<_CharT> { +public: + using _Base = __formatter_chrono<_CharT>; + + template + _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { + return _Base::__parse(__ctx, __format_spec::__fields_chrono, __format_spec::__flags::__clock); + } +}; +# endif // !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) && + // !defined(_LIBCPP_HAS_NO_LOCALIZATION) +# endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) + #endif // if _LIBCPP_STD_VER >= 20 _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__chrono/hh_mm_ss.h b/third_party/libcxx/__chrono/hh_mm_ss.h index 5bd452e57..57d2247fe 100644 --- a/third_party/libcxx/__chrono/hh_mm_ss.h +++ b/third_party/libcxx/__chrono/hh_mm_ss.h @@ -24,85 +24,84 @@ _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { template -class hh_mm_ss -{ +class hh_mm_ss { private: - static_assert(__is_duration<_Duration>::value, "template parameter of hh_mm_ss must be a std::chrono::duration"); - using __CommonType = common_type_t<_Duration, chrono::seconds>; + static_assert(__is_duration<_Duration>::value, "template parameter of hh_mm_ss must be a std::chrono::duration"); + using __CommonType = common_type_t<_Duration, chrono::seconds>; - _LIBCPP_HIDE_FROM_ABI static constexpr uint64_t __pow10(unsigned __exp) - { - uint64_t __ret = 1; - for (unsigned __i = 0; __i < __exp; ++__i) - __ret *= 10U; - return __ret; - } + _LIBCPP_HIDE_FROM_ABI static constexpr uint64_t __pow10(unsigned __exp) { + uint64_t __ret = 1; + for (unsigned __i = 0; __i < __exp; ++__i) + __ret *= 10U; + return __ret; + } - _LIBCPP_HIDE_FROM_ABI static constexpr unsigned __width(uint64_t __n, uint64_t __d = 10, unsigned __w = 0) - { - if (__n >= 2 && __d != 0 && __w < 19) - return 1 + __width(__n, __d % __n * 10, __w+1); - return 0; - } + _LIBCPP_HIDE_FROM_ABI static constexpr unsigned __width(uint64_t __n, uint64_t __d = 10, unsigned __w = 0) { + if (__n >= 2 && __d != 0 && __w < 19) + return 1 + __width(__n, __d % __n * 10, __w + 1); + return 0; + } public: - _LIBCPP_HIDE_FROM_ABI static unsigned constexpr fractional_width = __width(__CommonType::period::den) < 19 ? - __width(__CommonType::period::den) : 6u; - using precision = duration>; + _LIBCPP_HIDE_FROM_ABI static unsigned constexpr fractional_width = + __width(__CommonType::period::den) < 19 ? __width(__CommonType::period::den) : 6u; + using precision = duration>; - _LIBCPP_HIDE_FROM_ABI constexpr hh_mm_ss() noexcept : hh_mm_ss{_Duration::zero()} {} + _LIBCPP_HIDE_FROM_ABI constexpr hh_mm_ss() noexcept : hh_mm_ss{_Duration::zero()} {} - _LIBCPP_HIDE_FROM_ABI constexpr explicit hh_mm_ss(_Duration __d) noexcept : - __is_neg_(__d < _Duration(0)), - __h_(chrono::duration_cast (chrono::abs(__d))), + _LIBCPP_HIDE_FROM_ABI constexpr explicit hh_mm_ss(_Duration __d) noexcept + : __is_neg_(__d < _Duration(0)), + __h_(chrono::duration_cast(chrono::abs(__d))), __m_(chrono::duration_cast(chrono::abs(__d) - hours())), __s_(chrono::duration_cast(chrono::abs(__d) - hours() - minutes())), - __f_(chrono::duration_cast (chrono::abs(__d) - hours() - minutes() - seconds())) - {} + __f_(chrono::duration_cast(chrono::abs(__d) - hours() - minutes() - seconds())) {} - _LIBCPP_HIDE_FROM_ABI constexpr bool is_negative() const noexcept { return __is_neg_; } - _LIBCPP_HIDE_FROM_ABI constexpr chrono::hours hours() const noexcept { return __h_; } - _LIBCPP_HIDE_FROM_ABI constexpr chrono::minutes minutes() const noexcept { return __m_; } - _LIBCPP_HIDE_FROM_ABI constexpr chrono::seconds seconds() const noexcept { return __s_; } - _LIBCPP_HIDE_FROM_ABI constexpr precision subseconds() const noexcept { return __f_; } + _LIBCPP_HIDE_FROM_ABI constexpr bool is_negative() const noexcept { return __is_neg_; } + _LIBCPP_HIDE_FROM_ABI constexpr chrono::hours hours() const noexcept { return __h_; } + _LIBCPP_HIDE_FROM_ABI constexpr chrono::minutes minutes() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI constexpr chrono::seconds seconds() const noexcept { return __s_; } + _LIBCPP_HIDE_FROM_ABI constexpr precision subseconds() const noexcept { return __f_; } - _LIBCPP_HIDE_FROM_ABI constexpr precision to_duration() const noexcept - { - auto __dur = __h_ + __m_ + __s_ + __f_; - return __is_neg_ ? -__dur : __dur; - } + _LIBCPP_HIDE_FROM_ABI constexpr precision to_duration() const noexcept { + auto __dur = __h_ + __m_ + __s_ + __f_; + return __is_neg_ ? -__dur : __dur; + } - _LIBCPP_HIDE_FROM_ABI constexpr explicit operator precision() const noexcept { return to_duration(); } + _LIBCPP_HIDE_FROM_ABI constexpr explicit operator precision() const noexcept { return to_duration(); } private: - bool __is_neg_; - chrono::hours __h_; - chrono::minutes __m_; - chrono::seconds __s_; - precision __f_; + bool __is_neg_; + chrono::hours __h_; + chrono::minutes __m_; + chrono::seconds __s_; + precision __f_; }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(hh_mm_ss); -_LIBCPP_HIDE_FROM_ABI constexpr bool is_am(const hours& __h) noexcept { return __h >= hours( 0) && __h < hours(12); } -_LIBCPP_HIDE_FROM_ABI constexpr bool is_pm(const hours& __h) noexcept { return __h >= hours(12) && __h < hours(24); } - -_LIBCPP_HIDE_FROM_ABI constexpr hours make12(const hours& __h) noexcept -{ - if (__h == hours( 0)) return hours(12); - else if (__h <= hours(12)) return __h; - else return __h - hours(12); +_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_am(const hours& __h) noexcept { + return __h >= hours(0) && __h < hours(12); +} +_LIBCPP_HIDE_FROM_ABI inline constexpr bool is_pm(const hours& __h) noexcept { + return __h >= hours(12) && __h < hours(24); } -_LIBCPP_HIDE_FROM_ABI constexpr hours make24(const hours& __h, bool __is_pm) noexcept -{ - if (__is_pm) - return __h == hours(12) ? __h : __h + hours(12); - else - return __h == hours(12) ? hours(0) : __h; +_LIBCPP_HIDE_FROM_ABI inline constexpr hours make12(const hours& __h) noexcept { + if (__h == hours(0)) + return hours(12); + else if (__h <= hours(12)) + return __h; + else + return __h - hours(12); +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr hours make24(const hours& __h, bool __is_pm) noexcept { + if (__is_pm) + return __h == hours(12) ? __h : __h + hours(12); + else + return __h == hours(12) ? hours(0) : __h; } } // namespace chrono diff --git a/third_party/libcxx/__chrono/high_resolution_clock.h b/third_party/libcxx/__chrono/high_resolution_clock.h index 778ff44f3..0697fd2de 100644 --- a/third_party/libcxx/__chrono/high_resolution_clock.h +++ b/third_party/libcxx/__chrono/high_resolution_clock.h @@ -20,8 +20,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { #ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK typedef steady_clock high_resolution_clock; diff --git a/third_party/libcxx/__chrono/leap_second.h b/third_party/libcxx/__chrono/leap_second.h new file mode 100644 index 000000000..1a0e7f310 --- /dev/null +++ b/third_party/libcxx/__chrono/leap_second.h @@ -0,0 +1,126 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html + +#ifndef _LIBCPP___CHRONO_LEAP_SECOND_H +#define _LIBCPP___CHRONO_LEAP_SECOND_H + +#include +// Enable the contents of the header only when libc++ was built with experimental features enabled. +#if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) + +# include <__chrono/duration.h> +# include <__chrono/system_clock.h> +# include <__chrono/time_point.h> +# include <__compare/ordering.h> +# include <__compare/three_way_comparable.h> +# include <__config> +# include <__utility/private_constructor_tag.h> + +# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +# endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +# if _LIBCPP_STD_VER >= 20 + +namespace chrono { + +class leap_second { +public: + [[nodiscard]] + _LIBCPP_HIDE_FROM_ABI explicit constexpr leap_second(__private_constructor_tag, sys_seconds __date, seconds __value) + : __date_(__date), __value_(__value) {} + + _LIBCPP_HIDE_FROM_ABI leap_second(const leap_second&) = default; + _LIBCPP_HIDE_FROM_ABI leap_second& operator=(const leap_second&) = default; + + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr sys_seconds date() const noexcept { return __date_; } + + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr seconds value() const noexcept { return __value_; } + +private: + sys_seconds __date_; + seconds __value_; +}; + +_LIBCPP_HIDE_FROM_ABI inline constexpr bool operator==(const leap_second& __x, const leap_second& __y) { + return __x.date() == __y.date(); +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr strong_ordering operator<=>(const leap_second& __x, const leap_second& __y) { + return __x.date() <=> __y.date(); +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const leap_second& __x, const sys_time<_Duration>& __y) { + return __x.date() == __y; +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const leap_second& __x, const sys_time<_Duration>& __y) { + return __x.date() < __y; +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr bool operator<(const sys_time<_Duration>& __x, const leap_second& __y) { + return __x < __y.date(); +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const leap_second& __x, const sys_time<_Duration>& __y) { + return __y < __x; +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr bool operator>(const sys_time<_Duration>& __x, const leap_second& __y) { + return __y < __x; +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const leap_second& __x, const sys_time<_Duration>& __y) { + return !(__y < __x); +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr bool operator<=(const sys_time<_Duration>& __x, const leap_second& __y) { + return !(__y < __x); +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const leap_second& __x, const sys_time<_Duration>& __y) { + return !(__x < __y); +} + +template +_LIBCPP_HIDE_FROM_ABI constexpr bool operator>=(const sys_time<_Duration>& __x, const leap_second& __y) { + return !(__x < __y); +} + +# ifndef _LIBCPP_COMPILER_GCC +// This requirement cause a compilation loop in GCC-13 and running out of memory. +// TODO TZDB Test whether GCC-14 fixes this. +template + requires three_way_comparable_with> +_LIBCPP_HIDE_FROM_ABI constexpr auto operator<=>(const leap_second& __x, const sys_time<_Duration>& __y) { + return __x.date() <=> __y; +} +# endif + +} // namespace chrono + +# endif //_LIBCPP_STD_VER >= 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) + +#endif // _LIBCPP___CHRONO_LEAP_SECOND_H diff --git a/third_party/libcxx/__chrono/literals.h b/third_party/libcxx/__chrono/literals.h index 28ddc43a2..89800440e 100644 --- a/third_party/libcxx/__chrono/literals.h +++ b/third_party/libcxx/__chrono/literals.h @@ -22,24 +22,20 @@ _LIBCPP_BEGIN_NAMESPACE_STD -inline namespace literals -{ - inline namespace chrono_literals - { - _LIBCPP_HIDE_FROM_ABI constexpr chrono::day operator ""d(unsigned long long __d) noexcept - { - return chrono::day(static_cast(__d)); - } +inline namespace literals { +inline namespace chrono_literals { +_LIBCPP_HIDE_FROM_ABI constexpr chrono::day operator""d(unsigned long long __d) noexcept { + return chrono::day(static_cast(__d)); +} - _LIBCPP_HIDE_FROM_ABI constexpr chrono::year operator ""y(unsigned long long __y) noexcept - { - return chrono::year(static_cast(__y)); - } +_LIBCPP_HIDE_FROM_ABI constexpr chrono::year operator""y(unsigned long long __y) noexcept { + return chrono::year(static_cast(__y)); +} } // namespace chrono_literals } // namespace literals namespace chrono { // hoist the literals into namespace std::chrono - using namespace literals::chrono_literals; +using namespace literals::chrono_literals; } // namespace chrono _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__chrono/local_info.h b/third_party/libcxx/__chrono/local_info.h new file mode 100644 index 000000000..cfe144890 --- /dev/null +++ b/third_party/libcxx/__chrono/local_info.h @@ -0,0 +1,50 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html + +#ifndef _LIBCPP___CHRONO_LOCAL_INFO_H +#define _LIBCPP___CHRONO_LOCAL_INFO_H + +#include +// Enable the contents of the header only when libc++ was built with experimental features enabled. +#if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) + +# include <__chrono/sys_info.h> +# include <__config> + +# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +# endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +# if _LIBCPP_STD_VER >= 20 + +namespace chrono { + +struct local_info { + static constexpr int unique = 0; + static constexpr int nonexistent = 1; + static constexpr int ambiguous = 2; + + int result; + sys_info first; + sys_info second; +}; + +} // namespace chrono + +# endif // _LIBCPP_STD_VER >= 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) + +#endif // _LIBCPP___CHRONO_LOCAL_INFO_H diff --git a/third_party/libcxx/__chrono/month.h b/third_party/libcxx/__chrono/month.h index 5dff7ce33..ce5cc21aa 100644 --- a/third_party/libcxx/__chrono/month.h +++ b/third_party/libcxx/__chrono/month.h @@ -22,64 +22,76 @@ _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { class month { private: - unsigned char __m_; + unsigned char __m_; + public: - month() = default; - _LIBCPP_HIDE_FROM_ABI explicit inline constexpr month(unsigned __val) noexcept : __m_(static_cast(__val)) {} - _LIBCPP_HIDE_FROM_ABI inline constexpr month& operator++() noexcept { ++__m_; return *this; } - _LIBCPP_HIDE_FROM_ABI inline constexpr month operator++(int) noexcept { month __tmp = *this; ++(*this); return __tmp; } - _LIBCPP_HIDE_FROM_ABI inline constexpr month& operator--() noexcept { --__m_; return *this; } - _LIBCPP_HIDE_FROM_ABI inline constexpr month operator--(int) noexcept { month __tmp = *this; --(*this); return __tmp; } - _LIBCPP_HIDE_FROM_ABI constexpr month& operator+=(const months& __m1) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr month& operator-=(const months& __m1) noexcept; - _LIBCPP_HIDE_FROM_ABI explicit inline constexpr operator unsigned() const noexcept { return __m_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __m_ >= 1 && __m_ <= 12; } + month() = default; + _LIBCPP_HIDE_FROM_ABI explicit inline constexpr month(unsigned __val) noexcept + : __m_(static_cast(__val)) {} + _LIBCPP_HIDE_FROM_ABI inline constexpr month& operator++() noexcept { + *this += months{1}; + return *this; + } + _LIBCPP_HIDE_FROM_ABI inline constexpr month operator++(int) noexcept { + month __tmp = *this; + ++(*this); + return __tmp; + } + _LIBCPP_HIDE_FROM_ABI inline constexpr month& operator--() noexcept { + *this -= months{1}; + return *this; + } + _LIBCPP_HIDE_FROM_ABI inline constexpr month operator--(int) noexcept { + month __tmp = *this; + --(*this); + return __tmp; + } + _LIBCPP_HIDE_FROM_ABI constexpr month& operator+=(const months& __m1) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr month& operator-=(const months& __m1) noexcept; + _LIBCPP_HIDE_FROM_ABI explicit inline constexpr operator unsigned() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __m_ >= 1 && __m_ <= 12; } }; - -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator==(const month& __lhs, const month& __rhs) noexcept -{ return static_cast(__lhs) == static_cast(__rhs); } - -_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const month& __lhs, const month& __rhs) noexcept { - return static_cast(__lhs) <=> static_cast(__rhs); +_LIBCPP_HIDE_FROM_ABI inline constexpr bool operator==(const month& __lhs, const month& __rhs) noexcept { + return static_cast(__lhs) == static_cast(__rhs); } -_LIBCPP_HIDE_FROM_ABI inline constexpr -month operator+ (const month& __lhs, const months& __rhs) noexcept -{ - auto const __mu = static_cast(static_cast(__lhs)) + (__rhs.count() - 1); - auto const __yr = (__mu >= 0 ? __mu : __mu - 11) / 12; - return month{static_cast(__mu - __yr * 12 + 1)}; +_LIBCPP_HIDE_FROM_ABI inline constexpr strong_ordering operator<=>(const month& __lhs, const month& __rhs) noexcept { + return static_cast(__lhs) <=> static_cast(__rhs); } -_LIBCPP_HIDE_FROM_ABI inline constexpr -month operator+ (const months& __lhs, const month& __rhs) noexcept -{ return __rhs + __lhs; } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -month operator- (const month& __lhs, const months& __rhs) noexcept -{ return __lhs + -__rhs; } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -months operator-(const month& __lhs, const month& __rhs) noexcept -{ - auto const __dm = static_cast(__lhs) - static_cast(__rhs); - return months(__dm <= 11 ? __dm : __dm + 12); +_LIBCPP_HIDE_FROM_ABI inline constexpr month operator+(const month& __lhs, const months& __rhs) noexcept { + auto const __mu = static_cast(static_cast(__lhs)) + (__rhs.count() - 1); + auto const __yr = (__mu >= 0 ? __mu : __mu - 11) / 12; + return month{static_cast(__mu - __yr * 12 + 1)}; } -_LIBCPP_HIDE_FROM_ABI inline constexpr -month& month::operator+=(const months& __dm) noexcept -{ *this = *this + __dm; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr month operator+(const months& __lhs, const month& __rhs) noexcept { + return __rhs + __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -month& month::operator-=(const months& __dm) noexcept -{ *this = *this - __dm; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr month operator-(const month& __lhs, const months& __rhs) noexcept { + return __lhs + -__rhs; +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr months operator-(const month& __lhs, const month& __rhs) noexcept { + auto const __dm = static_cast(__lhs) - static_cast(__rhs); + return months(__dm <= 11 ? __dm : __dm + 12); +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr month& month::operator+=(const months& __dm) noexcept { + *this = *this + __dm; + return *this; +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr month& month::operator-=(const months& __dm) noexcept { + *this = *this - __dm; + return *this; +} inline constexpr month January{1}; inline constexpr month February{2}; diff --git a/third_party/libcxx/__chrono/month_weekday.h b/third_party/libcxx/__chrono/month_weekday.h index 802cbd74f..791987965 100644 --- a/third_party/libcxx/__chrono/month_weekday.h +++ b/third_party/libcxx/__chrono/month_weekday.h @@ -22,81 +22,80 @@ _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { class month_weekday { private: - chrono::month __m_; - chrono::weekday_indexed __wdi_; + chrono::month __m_; + chrono::weekday_indexed __wdi_; + public: - _LIBCPP_HIDE_FROM_ABI constexpr month_weekday(const chrono::month& __mval, const chrono::weekday_indexed& __wdival) noexcept - : __m_{__mval}, __wdi_{__wdival} {} - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __m_.ok() && __wdi_.ok(); } + _LIBCPP_HIDE_FROM_ABI constexpr month_weekday(const chrono::month& __mval, + const chrono::weekday_indexed& __wdival) noexcept + : __m_{__mval}, __wdi_{__wdival} {} + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __m_.ok() && __wdi_.ok(); } }; -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator==(const month_weekday& __lhs, const month_weekday& __rhs) noexcept -{ return __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool +operator==(const month_weekday& __lhs, const month_weekday& __rhs) noexcept { + return __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator!=(const month_weekday& __lhs, const month_weekday& __rhs) noexcept -{ return !(__lhs == __rhs); } +_LIBCPP_HIDE_FROM_ABI inline constexpr month_weekday +operator/(const month& __lhs, const weekday_indexed& __rhs) noexcept { + return month_weekday{__lhs, __rhs}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -month_weekday operator/(const month& __lhs, const weekday_indexed& __rhs) noexcept -{ return month_weekday{__lhs, __rhs}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr month_weekday operator/(int __lhs, const weekday_indexed& __rhs) noexcept { + return month_weekday{month(__lhs), __rhs}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -month_weekday operator/(int __lhs, const weekday_indexed& __rhs) noexcept -{ return month_weekday{month(__lhs), __rhs}; } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -month_weekday operator/(const weekday_indexed& __lhs, const month& __rhs) noexcept -{ return month_weekday{__rhs, __lhs}; } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -month_weekday operator/(const weekday_indexed& __lhs, int __rhs) noexcept -{ return month_weekday{month(__rhs), __lhs}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr month_weekday +operator/(const weekday_indexed& __lhs, const month& __rhs) noexcept { + return month_weekday{__rhs, __lhs}; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr month_weekday operator/(const weekday_indexed& __lhs, int __rhs) noexcept { + return month_weekday{month(__rhs), __lhs}; +} class month_weekday_last { - chrono::month __m_; - chrono::weekday_last __wdl_; - public: - _LIBCPP_HIDE_FROM_ABI constexpr month_weekday_last(const chrono::month& __mval, const chrono::weekday_last& __wdlval) noexcept - : __m_{__mval}, __wdl_{__wdlval} {} - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __m_.ok() && __wdl_.ok(); } + chrono::month __m_; + chrono::weekday_last __wdl_; + +public: + _LIBCPP_HIDE_FROM_ABI constexpr month_weekday_last(const chrono::month& __mval, + const chrono::weekday_last& __wdlval) noexcept + : __m_{__mval}, __wdl_{__wdlval} {} + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __m_.ok() && __wdl_.ok(); } }; -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator==(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept -{ return __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool +operator==(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept { + return __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator!=(const month_weekday_last& __lhs, const month_weekday_last& __rhs) noexcept -{ return !(__lhs == __rhs); } +_LIBCPP_HIDE_FROM_ABI inline constexpr month_weekday_last +operator/(const month& __lhs, const weekday_last& __rhs) noexcept { + return month_weekday_last{__lhs, __rhs}; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr month_weekday_last operator/(int __lhs, const weekday_last& __rhs) noexcept { + return month_weekday_last{month(__lhs), __rhs}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -month_weekday_last operator/(const month& __lhs, const weekday_last& __rhs) noexcept -{ return month_weekday_last{__lhs, __rhs}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr month_weekday_last +operator/(const weekday_last& __lhs, const month& __rhs) noexcept { + return month_weekday_last{__rhs, __lhs}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -month_weekday_last operator/(int __lhs, const weekday_last& __rhs) noexcept -{ return month_weekday_last{month(__lhs), __rhs}; } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -month_weekday_last operator/(const weekday_last& __lhs, const month& __rhs) noexcept -{ return month_weekday_last{__rhs, __lhs}; } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -month_weekday_last operator/(const weekday_last& __lhs, int __rhs) noexcept -{ return month_weekday_last{month(__rhs), __lhs}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr month_weekday_last operator/(const weekday_last& __lhs, int __rhs) noexcept { + return month_weekday_last{month(__rhs), __lhs}; +} } // namespace chrono _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__chrono/monthday.h b/third_party/libcxx/__chrono/monthday.h index 03fd7503a..a89d16e51 100644 --- a/third_party/libcxx/__chrono/monthday.h +++ b/third_party/libcxx/__chrono/monthday.h @@ -24,101 +24,105 @@ _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { class month_day { private: - chrono::month __m_; - chrono::day __d_; + chrono::month __m_; + chrono::day __d_; + public: - month_day() = default; - _LIBCPP_HIDE_FROM_ABI constexpr month_day(const chrono::month& __mval, const chrono::day& __dval) noexcept - : __m_{__mval}, __d_{__dval} {} - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::day day() const noexcept { return __d_; } - _LIBCPP_HIDE_FROM_ABI constexpr bool ok() const noexcept; + month_day() = default; + _LIBCPP_HIDE_FROM_ABI constexpr month_day(const chrono::month& __mval, const chrono::day& __dval) noexcept + : __m_{__mval}, __d_{__dval} {} + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::day day() const noexcept { return __d_; } + _LIBCPP_HIDE_FROM_ABI constexpr bool ok() const noexcept; }; -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool month_day::ok() const noexcept -{ - if (!__m_.ok()) return false; - const unsigned __dval = static_cast(__d_); - if (__dval < 1 || __dval > 31) return false; - if (__dval <= 29) return true; -// Now we've got either 30 or 31 - const unsigned __mval = static_cast(__m_); - if (__mval == 2) return false; - if (__mval == 4 || __mval == 6 || __mval == 9 || __mval == 11) - return __dval == 30; +_LIBCPP_HIDE_FROM_ABI inline constexpr bool month_day::ok() const noexcept { + if (!__m_.ok()) + return false; + const unsigned __dval = static_cast(__d_); + if (__dval < 1 || __dval > 31) + return false; + if (__dval <= 29) return true; + // Now we've got either 30 or 31 + const unsigned __mval = static_cast(__m_); + if (__mval == 2) + return false; + if (__mval == 4 || __mval == 6 || __mval == 9 || __mval == 11) + return __dval == 30; + return true; } -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator==(const month_day& __lhs, const month_day& __rhs) noexcept -{ return __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); } - -_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const month_day& __lhs, const month_day& __rhs) noexcept { - if (auto __c = __lhs.month() <=> __rhs.month(); __c != 0) - return __c; - return __lhs.day() <=> __rhs.day(); +_LIBCPP_HIDE_FROM_ABI inline constexpr bool operator==(const month_day& __lhs, const month_day& __rhs) noexcept { + return __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); } -_LIBCPP_HIDE_FROM_ABI inline constexpr -month_day operator/(const month& __lhs, const day& __rhs) noexcept -{ return month_day{__lhs, __rhs}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr strong_ordering +operator<=>(const month_day& __lhs, const month_day& __rhs) noexcept { + if (auto __c = __lhs.month() <=> __rhs.month(); __c != 0) + return __c; + return __lhs.day() <=> __rhs.day(); +} -_LIBCPP_HIDE_FROM_ABI constexpr -month_day operator/(const day& __lhs, const month& __rhs) noexcept -{ return __rhs / __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr month_day operator/(const month& __lhs, const day& __rhs) noexcept { + return month_day{__lhs, __rhs}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -month_day operator/(const month& __lhs, int __rhs) noexcept -{ return __lhs / day(__rhs); } +_LIBCPP_HIDE_FROM_ABI inline constexpr month_day operator/(const day& __lhs, const month& __rhs) noexcept { + return __rhs / __lhs; +} -_LIBCPP_HIDE_FROM_ABI constexpr -month_day operator/(int __lhs, const day& __rhs) noexcept -{ return month(__lhs) / __rhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr month_day operator/(const month& __lhs, int __rhs) noexcept { + return __lhs / day(__rhs); +} -_LIBCPP_HIDE_FROM_ABI constexpr -month_day operator/(const day& __lhs, int __rhs) noexcept -{ return month(__rhs) / __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr month_day operator/(int __lhs, const day& __rhs) noexcept { + return month(__lhs) / __rhs; +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr month_day operator/(const day& __lhs, int __rhs) noexcept { + return month(__rhs) / __lhs; +} class month_day_last { private: - chrono::month __m_; + chrono::month __m_; + public: - _LIBCPP_HIDE_FROM_ABI explicit constexpr month_day_last(const chrono::month& __val) noexcept - : __m_{__val} {} - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __m_.ok(); } + _LIBCPP_HIDE_FROM_ABI explicit constexpr month_day_last(const chrono::month& __val) noexcept : __m_{__val} {} + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __m_.ok(); } }; -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator==(const month_day_last& __lhs, const month_day_last& __rhs) noexcept -{ return __lhs.month() == __rhs.month(); } - -_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering -operator<=>(const month_day_last& __lhs, const month_day_last& __rhs) noexcept { - return __lhs.month() <=> __rhs.month(); +_LIBCPP_HIDE_FROM_ABI inline constexpr bool +operator==(const month_day_last& __lhs, const month_day_last& __rhs) noexcept { + return __lhs.month() == __rhs.month(); } -_LIBCPP_HIDE_FROM_ABI inline constexpr -month_day_last operator/(const month& __lhs, last_spec) noexcept -{ return month_day_last{__lhs}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr strong_ordering +operator<=>(const month_day_last& __lhs, const month_day_last& __rhs) noexcept { + return __lhs.month() <=> __rhs.month(); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -month_day_last operator/(last_spec, const month& __rhs) noexcept -{ return month_day_last{__rhs}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr month_day_last operator/(const month& __lhs, last_spec) noexcept { + return month_day_last{__lhs}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -month_day_last operator/(int __lhs, last_spec) noexcept -{ return month_day_last{month(__lhs)}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr month_day_last operator/(last_spec, const month& __rhs) noexcept { + return month_day_last{__rhs}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -month_day_last operator/(last_spec, int __rhs) noexcept -{ return month_day_last{month(__rhs)}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr month_day_last operator/(int __lhs, last_spec) noexcept { + return month_day_last{month(__lhs)}; +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr month_day_last operator/(last_spec, int __rhs) noexcept { + return month_day_last{month(__rhs)}; +} } // namespace chrono diff --git a/third_party/libcxx/__chrono/ostream.h b/third_party/libcxx/__chrono/ostream.h index f171944b5..e6c43254e 100644 --- a/third_party/libcxx/__chrono/ostream.h +++ b/third_party/libcxx/__chrono/ostream.h @@ -15,20 +15,23 @@ #include <__chrono/duration.h> #include <__chrono/file_clock.h> #include <__chrono/hh_mm_ss.h> +#include <__chrono/local_info.h> #include <__chrono/month.h> #include <__chrono/month_weekday.h> #include <__chrono/monthday.h> #include <__chrono/statically_widen.h> +#include <__chrono/sys_info.h> #include <__chrono/system_clock.h> #include <__chrono/weekday.h> #include <__chrono/year.h> #include <__chrono/year_month.h> #include <__chrono/year_month_day.h> #include <__chrono/year_month_weekday.h> +#include <__chrono/zoned_time.h> #include <__concepts/same_as.h> #include <__config> #include <__format/format_functions.h> -#include +#include <__fwd/ostream.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -42,11 +45,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace chrono { template + requires(!treat_as_floating_point_v && _Duration{1} < days{1}) _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& -operator<<(basic_ostream<_CharT, _Traits>& __os, const sys_time<_Duration> __tp) { +operator<<(basic_ostream<_CharT, _Traits>& __os, const sys_time<_Duration>& __tp) { return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%F %T}"), __tp); } +template +_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const sys_days& __dp) { + return __os << year_month_day{__dp}; +} + template _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const file_time<_Duration> __tp) { @@ -255,6 +265,54 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const hh_mm_ss<_Duration> __hms return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%T}"), __hms); } +# if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) + +template +_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const sys_info& __info) { + // __info.abbrev is always std::basic_string. + // Since these strings typically are short the conversion should be cheap. + std::basic_string<_CharT> __abbrev{__info.abbrev.begin(), __info.abbrev.end()}; + return __os << std::format( + _LIBCPP_STATICALLY_WIDEN(_CharT, "[{:%F %T}, {:%F %T}) {:%T} {:%Q%q} \"{}\""), + __info.begin, + __info.end, + hh_mm_ss{__info.offset}, + __info.save, + __abbrev); +} + +template +_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const local_info& __info) { + auto __result = [&]() -> basic_string<_CharT> { + switch (__info.result) { + case local_info::unique: + return _LIBCPP_STATICALLY_WIDEN(_CharT, "unique"); + case local_info::nonexistent: + return _LIBCPP_STATICALLY_WIDEN(_CharT, "non-existent"); + case local_info::ambiguous: + return _LIBCPP_STATICALLY_WIDEN(_CharT, "ambiguous"); + + default: + return std::format(_LIBCPP_STATICALLY_WIDEN(_CharT, "unspecified result ({})"), __info.result); + }; + }; + + return __os << std::format( + _LIBCPP_STATICALLY_WIDEN(_CharT, "{}: {{{}, {}}}"), __result(), __info.first, __info.second); +} + +# if !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) && \ + !defined(_LIBCPP_HAS_NO_LOCALIZATION) +template +_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const zoned_time<_Duration, _TimeZonePtr>& __tp) { + return __os << std::format(__os.getloc(), _LIBCPP_STATICALLY_WIDEN(_CharT, "{:L%F %T %Z}"), __tp); +} +# endif +# endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) + } // namespace chrono #endif // if _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__chrono/parser_std_format_spec.h b/third_party/libcxx/__chrono/parser_std_format_spec.h index fb6528a47..785bbae19 100644 --- a/third_party/libcxx/__chrono/parser_std_format_spec.h +++ b/third_party/libcxx/__chrono/parser_std_format_spec.h @@ -160,17 +160,17 @@ public: private: _LIBCPP_HIDE_FROM_ABI constexpr _ConstIterator __parse_chrono_specs(_ConstIterator __begin, _ConstIterator __end, __flags __flags) { - _LIBCPP_ASSERT(__begin != __end, - "When called with an empty input the function will cause " - "undefined behavior by evaluating data not in the input"); + _LIBCPP_ASSERT_INTERNAL(__begin != __end, + "When called with an empty input the function will cause " + "undefined behavior by evaluating data not in the input"); if (*__begin != _CharT('%') && *__begin != _CharT('}')) - std::__throw_format_error("Expected '%' or '}' in the chrono format-string"); + std::__throw_format_error("The format specifier expects a '%' or a '}'"); do { switch (*__begin) { case _CharT('{'): - std::__throw_format_error("The chrono-specs contains a '{'"); + std::__throw_format_error("The chrono specifiers contain a '{'"); case _CharT('}'): return __begin; @@ -195,7 +195,7 @@ private: __parse_conversion_spec(_ConstIterator& __begin, _ConstIterator __end, __flags __flags) { ++__begin; if (__begin == __end) - std::__throw_format_error("End of input while parsing the modifier chrono conversion-spec"); + std::__throw_format_error("End of input while parsing a conversion specifier"); switch (*__begin) { case _CharT('n'): diff --git a/third_party/libcxx/__chrono/steady_clock.h b/third_party/libcxx/__chrono/steady_clock.h index ba8335173..612a7f156 100644 --- a/third_party/libcxx/__chrono/steady_clock.h +++ b/third_party/libcxx/__chrono/steady_clock.h @@ -20,20 +20,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { #ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK -class _LIBCPP_TYPE_VIS steady_clock -{ +class _LIBCPP_EXPORTED_FROM_ABI steady_clock { public: - typedef nanoseconds duration; - typedef duration::rep rep; - typedef duration::period period; - typedef chrono::time_point time_point; - static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = true; + typedef nanoseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point time_point; + static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = true; - static time_point now() _NOEXCEPT; + static time_point now() _NOEXCEPT; }; #endif diff --git a/third_party/libcxx/__chrono/sys_info.h b/third_party/libcxx/__chrono/sys_info.h new file mode 100644 index 000000000..11536cbde --- /dev/null +++ b/third_party/libcxx/__chrono/sys_info.h @@ -0,0 +1,51 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html + +#ifndef _LIBCPP___CHRONO_SYS_INFO_H +#define _LIBCPP___CHRONO_SYS_INFO_H + +#include +// Enable the contents of the header only when libc++ was built with experimental features enabled. +#if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) + +# include <__chrono/duration.h> +# include <__chrono/system_clock.h> +# include <__chrono/time_point.h> +# include <__config> +# include + +# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +# endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +# if _LIBCPP_STD_VER >= 20 + +namespace chrono { + +struct sys_info { + sys_seconds begin; + sys_seconds end; + seconds offset; + minutes save; + string abbrev; +}; + +} // namespace chrono + +# endif // _LIBCPP_STD_VER >= 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) + +#endif // _LIBCPP___CHRONO_SYS_INFO_H diff --git a/third_party/libcxx/__chrono/system_clock.h b/third_party/libcxx/__chrono/system_clock.h index e8a41ceab..5a9eb65bd 100644 --- a/third_party/libcxx/__chrono/system_clock.h +++ b/third_party/libcxx/__chrono/system_clock.h @@ -21,21 +21,19 @@ _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { -class _LIBCPP_TYPE_VIS system_clock -{ +class _LIBCPP_EXPORTED_FROM_ABI system_clock { public: - typedef microseconds duration; - typedef duration::rep rep; - typedef duration::period period; - typedef chrono::time_point time_point; - static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = false; + typedef microseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef chrono::time_point time_point; + static _LIBCPP_CONSTEXPR_SINCE_CXX14 const bool is_steady = false; - static time_point now() _NOEXCEPT; - static time_t to_time_t (const time_point& __t) _NOEXCEPT; - static time_point from_time_t(time_t __t) _NOEXCEPT; + static time_point now() _NOEXCEPT; + static time_t to_time_t(const time_point& __t) _NOEXCEPT; + static time_point from_time_t(time_t __t) _NOEXCEPT; }; #if _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__chrono/time_point.h b/third_party/libcxx/__chrono/time_point.h index c14835401..aaf0b098f 100644 --- a/third_party/libcxx/__chrono/time_point.h +++ b/third_party/libcxx/__chrono/time_point.h @@ -28,128 +28,96 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { template -class _LIBCPP_TEMPLATE_VIS time_point -{ - static_assert(__is_duration<_Duration>::value, - "Second template parameter of time_point must be a std::chrono::duration"); +class _LIBCPP_TEMPLATE_VIS time_point { + static_assert(__is_duration<_Duration>::value, + "Second template parameter of time_point must be a std::chrono::duration"); + public: - typedef _Clock clock; - typedef _Duration duration; - typedef typename duration::rep rep; - typedef typename duration::period period; + typedef _Clock clock; + typedef _Duration duration; + typedef typename duration::rep rep; + typedef typename duration::period period; + private: - duration __d_; + duration __d_; public: - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 time_point() : __d_(duration::zero()) {} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit time_point(const duration& __d) : __d_(__d) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 time_point() : __d_(duration::zero()) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit time_point(const duration& __d) : __d_(__d) {} - // conversions - template - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 - time_point(const time_point& __t, - typename enable_if - < - is_convertible<_Duration2, duration>::value - >::type* = nullptr) - : __d_(__t.time_since_epoch()) {} + // conversions + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 time_point(const time_point& __t) + : __d_(__t.time_since_epoch()) {} - // observer + // observer - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 duration time_since_epoch() const {return __d_;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 duration time_since_epoch() const { return __d_; } - // arithmetic + // arithmetic - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 time_point& operator+=(const duration& __d) {__d_ += __d; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 time_point& operator-=(const duration& __d) {__d_ -= __d; return *this;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 time_point& operator+=(const duration& __d) { + __d_ += __d; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 time_point& operator-=(const duration& __d) { + __d_ -= __d; + return *this; + } - // special values + // special values - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR time_point min() _NOEXCEPT {return time_point(duration::min());} - _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR time_point max() _NOEXCEPT {return time_point(duration::max());} + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR time_point min() _NOEXCEPT { return time_point(duration::min()); } + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR time_point max() _NOEXCEPT { return time_point(duration::max()); } }; } // namespace chrono template -struct _LIBCPP_TEMPLATE_VIS common_type, - chrono::time_point<_Clock, _Duration2> > -{ - typedef chrono::time_point<_Clock, typename common_type<_Duration1, _Duration2>::type> type; +struct _LIBCPP_TEMPLATE_VIS +common_type, chrono::time_point<_Clock, _Duration2> > { + typedef chrono::time_point<_Clock, typename common_type<_Duration1, _Duration2>::type> type; }; namespace chrono { template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -time_point<_Clock, _ToDuration> -time_point_cast(const time_point<_Clock, _Duration>& __t) -{ - return time_point<_Clock, _ToDuration>(chrono::duration_cast<_ToDuration>(__t.time_since_epoch())); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, _ToDuration> +time_point_cast(const time_point<_Clock, _Duration>& __t) { + return time_point<_Clock, _ToDuration>(chrono::duration_cast<_ToDuration>(__t.time_since_epoch())); } #if _LIBCPP_STD_VER >= 17 -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -typename enable_if -< - __is_duration<_ToDuration>::value, - time_point<_Clock, _ToDuration> ->::type -floor(const time_point<_Clock, _Duration>& __t) -{ - return time_point<_Clock, _ToDuration>{chrono::floor<_ToDuration>(__t.time_since_epoch())}; +template ::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI constexpr time_point<_Clock, _ToDuration> floor(const time_point<_Clock, _Duration>& __t) { + return time_point<_Clock, _ToDuration>{chrono::floor<_ToDuration>(__t.time_since_epoch())}; } -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -typename enable_if -< - __is_duration<_ToDuration>::value, - time_point<_Clock, _ToDuration> ->::type -ceil(const time_point<_Clock, _Duration>& __t) -{ - return time_point<_Clock, _ToDuration>{chrono::ceil<_ToDuration>(__t.time_since_epoch())}; +template ::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI constexpr time_point<_Clock, _ToDuration> ceil(const time_point<_Clock, _Duration>& __t) { + return time_point<_Clock, _ToDuration>{chrono::ceil<_ToDuration>(__t.time_since_epoch())}; } -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -typename enable_if -< - __is_duration<_ToDuration>::value, - time_point<_Clock, _ToDuration> ->::type -round(const time_point<_Clock, _Duration>& __t) -{ - return time_point<_Clock, _ToDuration>{chrono::round<_ToDuration>(__t.time_since_epoch())}; +template ::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI constexpr time_point<_Clock, _ToDuration> round(const time_point<_Clock, _Duration>& __t) { + return time_point<_Clock, _ToDuration>{chrono::round<_ToDuration>(__t.time_since_epoch())}; } -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR -typename enable_if -< - numeric_limits<_Rep>::is_signed, - duration<_Rep, _Period> ->::type -abs(duration<_Rep, _Period> __d) -{ - return __d >= __d.zero() ? +__d : -__d; +template ::is_signed, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI constexpr duration<_Rep, _Period> abs(duration<_Rep, _Period> __d) { + return __d >= __d.zero() ? +__d : -__d; } #endif // _LIBCPP_STD_VER >= 17 // time_point == template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -bool -operator==(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return __lhs.time_since_epoch() == __rhs.time_since_epoch(); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool +operator==(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) { + return __lhs.time_since_epoch() == __rhs.time_since_epoch(); } #if _LIBCPP_STD_VER <= 17 @@ -157,11 +125,9 @@ operator==(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, // time_point != template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -bool -operator!=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return !(__lhs == __rhs); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool +operator!=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) { + return !(__lhs == __rhs); } #endif // _LIBCPP_STD_VER <= 17 @@ -169,41 +135,33 @@ operator!=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, // time_point < template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -bool -operator<(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return __lhs.time_since_epoch() < __rhs.time_since_epoch(); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool +operator<(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) { + return __lhs.time_since_epoch() < __rhs.time_since_epoch(); } // time_point > template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -bool -operator>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return __rhs < __lhs; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool +operator>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) { + return __rhs < __lhs; } // time_point <= template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -bool -operator<=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return !(__rhs < __lhs); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool +operator<=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) { + return !(__rhs < __lhs); } // time_point >= template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -bool -operator>=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return !(__lhs < __rhs); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool +operator>=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) { + return !(__lhs < __rhs); } #if _LIBCPP_STD_VER >= 20 @@ -211,7 +169,7 @@ operator>=(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, template _Duration2> _LIBCPP_HIDE_FROM_ABI constexpr auto operator<=>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) { - return __lhs.time_since_epoch() <=> __rhs.time_since_epoch(); + return __lhs.time_since_epoch() <=> __rhs.time_since_epoch(); } #endif // _LIBCPP_STD_VER >= 20 @@ -219,43 +177,38 @@ operator<=>(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock // time_point operator+(time_point x, duration y); template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> -operator+(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Tr; - return _Tr (__lhs.time_since_epoch() + __rhs); +inline _LIBCPP_HIDE_FROM_ABI +_LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> +operator+(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { + typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Tr; + return _Tr(__lhs.time_since_epoch() + __rhs); } // time_point operator+(duration x, time_point y); template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -time_point<_Clock, typename common_type, _Duration2>::type> -operator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return __rhs + __lhs; +inline _LIBCPP_HIDE_FROM_ABI +_LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, typename common_type, _Duration2>::type> +operator+(const duration<_Rep1, _Period1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) { + return __rhs + __lhs; } // time_point operator-(time_point x, duration y); template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> -operator-(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) -{ - typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Ret; - return _Ret(__lhs.time_since_epoch() -__rhs); +inline _LIBCPP_HIDE_FROM_ABI +_LIBCPP_CONSTEXPR_SINCE_CXX14 time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> +operator-(const time_point<_Clock, _Duration1>& __lhs, const duration<_Rep2, _Period2>& __rhs) { + typedef time_point<_Clock, typename common_type<_Duration1, duration<_Rep2, _Period2> >::type> _Ret; + return _Ret(__lhs.time_since_epoch() - __rhs); } // duration operator-(time_point x, time_point y); template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -typename common_type<_Duration1, _Duration2>::type -operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) -{ - return __lhs.time_since_epoch() - __rhs.time_since_epoch(); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename common_type<_Duration1, _Duration2>::type +operator-(const time_point<_Clock, _Duration1>& __lhs, const time_point<_Clock, _Duration2>& __rhs) { + return __lhs.time_since_epoch() - __rhs.time_since_epoch(); } } // namespace chrono diff --git a/third_party/libcxx/__chrono/time_zone.h b/third_party/libcxx/__chrono/time_zone.h new file mode 100644 index 000000000..de11dac1e --- /dev/null +++ b/third_party/libcxx/__chrono/time_zone.h @@ -0,0 +1,182 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html + +#ifndef _LIBCPP___CHRONO_TIME_ZONE_H +#define _LIBCPP___CHRONO_TIME_ZONE_H + +#include +// Enable the contents of the header only when libc++ was built with experimental features enabled. +#if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) + +# include <__chrono/calendar.h> +# include <__chrono/duration.h> +# include <__chrono/exception.h> +# include <__chrono/local_info.h> +# include <__chrono/sys_info.h> +# include <__chrono/system_clock.h> +# include <__compare/strong_order.h> +# include <__config> +# include <__memory/unique_ptr.h> +# include <__type_traits/common_type.h> +# include + +# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +# endif + +_LIBCPP_PUSH_MACROS +# include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +# if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) && \ + !defined(_LIBCPP_HAS_NO_LOCALIZATION) + +namespace chrono { + +enum class choose { earliest, latest }; + +class _LIBCPP_AVAILABILITY_TZDB time_zone { + _LIBCPP_HIDE_FROM_ABI time_zone() = default; + +public: + class __impl; // public so it can be used by make_unique. + + // The "constructor". + // + // The default constructor is private to avoid the constructor from being + // part of the ABI. Instead use an __ugly_named function as an ABI interface, + // since that gives us the ability to change it in the future. + [[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI static time_zone __create(unique_ptr<__impl>&& __p); + + _LIBCPP_EXPORTED_FROM_ABI ~time_zone(); + + _LIBCPP_HIDE_FROM_ABI time_zone(time_zone&&) = default; + _LIBCPP_HIDE_FROM_ABI time_zone& operator=(time_zone&&) = default; + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI string_view name() const noexcept { return __name(); } + + template + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI sys_info get_info(const sys_time<_Duration>& __time) const { + return __get_info(chrono::time_point_cast(__time)); + } + + template + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI local_info get_info(const local_time<_Duration>& __time) const { + return __get_info(chrono::time_point_cast(__time)); + } + + // We don't apply nodiscard here since this function throws on many inputs, + // so it could be used as a validation. + template + _LIBCPP_HIDE_FROM_ABI sys_time> to_sys(const local_time<_Duration>& __time) const { + local_info __info = get_info(__time); + switch (__info.result) { + case local_info::unique: + return sys_time>{__time.time_since_epoch() - __info.first.offset}; + + case local_info::nonexistent: + chrono::__throw_nonexistent_local_time(__time, __info); + + case local_info::ambiguous: + chrono::__throw_ambiguous_local_time(__time, __info); + } + + // TODO TZDB The Standard does not specify anything in these cases. + _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN( + __info.result != -1, "cannot convert the local time; it would be before the minimum system clock value"); + _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN( + __info.result != -2, "cannot convert the local time; it would be after the maximum system clock value"); + + return {}; + } + + template + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI sys_time> + to_sys(const local_time<_Duration>& __time, choose __z) const { + local_info __info = get_info(__time); + switch (__info.result) { + case local_info::unique: + case local_info::nonexistent: // first and second are the same + return sys_time>{__time.time_since_epoch() - __info.first.offset}; + + case local_info::ambiguous: + switch (__z) { + case choose::earliest: + return sys_time>{__time.time_since_epoch() - __info.first.offset}; + + case choose::latest: + return sys_time>{__time.time_since_epoch() - __info.second.offset}; + + // Note a value out of bounds is not specified. + } + } + + // TODO TZDB The standard does not specify anything in these cases. + _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN( + __info.result != -1, "cannot convert the local time; it would be before the minimum system clock value"); + _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN( + __info.result != -2, "cannot convert the local time; it would be after the maximum system clock value"); + + return {}; + } + + template + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI local_time> + to_local(const sys_time<_Duration>& __time) const { + using _Dp = common_type_t<_Duration, seconds>; + + sys_info __info = get_info(__time); + + _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN( + __info.offset >= chrono::seconds{0} || __time.time_since_epoch() >= _Dp::min() - __info.offset, + "cannot convert the system time; it would be before the minimum local clock value"); + + _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN( + __info.offset <= chrono::seconds{0} || __time.time_since_epoch() <= _Dp::max() - __info.offset, + "cannot convert the system time; it would be after the maximum local clock value"); + + return local_time<_Dp>{__time.time_since_epoch() + __info.offset}; + } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const __impl& __implementation() const noexcept { return *__impl_; } + +private: + [[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI string_view __name() const noexcept; + + [[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI sys_info __get_info(sys_seconds __time) const; + [[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI local_info __get_info(local_seconds __time) const; + + unique_ptr<__impl> __impl_; +}; + +[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline bool +operator==(const time_zone& __x, const time_zone& __y) noexcept { + return __x.name() == __y.name(); +} + +[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline strong_ordering +operator<=>(const time_zone& __x, const time_zone& __y) noexcept { + return __x.name() <=> __y.name(); +} + +} // namespace chrono + +# endif // _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) + // && !defined(_LIBCPP_HAS_NO_LOCALIZATION) + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) + +#endif // _LIBCPP___CHRONO_TIME_ZONE_H diff --git a/third_party/libcxx/__chrono/time_zone_link.h b/third_party/libcxx/__chrono/time_zone_link.h new file mode 100644 index 000000000..b2d365c5f --- /dev/null +++ b/third_party/libcxx/__chrono/time_zone_link.h @@ -0,0 +1,79 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html + +#ifndef _LIBCPP___CHRONO_TIME_ZONE_LINK_H +#define _LIBCPP___CHRONO_TIME_ZONE_LINK_H + +#include +// Enable the contents of the header only when libc++ was built with experimental features enabled. +#if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) + +# include <__compare/strong_order.h> +# include <__config> +# include <__utility/private_constructor_tag.h> +# include +# include + +# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +# endif + +_LIBCPP_PUSH_MACROS +# include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +# if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) && \ + !defined(_LIBCPP_HAS_NO_LOCALIZATION) + +namespace chrono { + +class time_zone_link { +public: + [[nodiscard]] + _LIBCPP_HIDE_FROM_ABI explicit time_zone_link(__private_constructor_tag, string_view __name, string_view __target) + : __name_{__name}, __target_{__target} {} + + _LIBCPP_HIDE_FROM_ABI time_zone_link(time_zone_link&&) = default; + _LIBCPP_HIDE_FROM_ABI time_zone_link& operator=(time_zone_link&&) = default; + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI string_view name() const noexcept { return __name_; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI string_view target() const noexcept { return __target_; } + +private: + string __name_; + // TODO TZDB instead of the name we can store the pointer to a zone. These + // pointers are immutable. This makes it possible to directly return a + // pointer in the time_zone in the 'locate_zone' function. + string __target_; +}; + +[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline bool +operator==(const time_zone_link& __x, const time_zone_link& __y) noexcept { + return __x.name() == __y.name(); +} + +[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline strong_ordering +operator<=>(const time_zone_link& __x, const time_zone_link& __y) noexcept { + return __x.name() <=> __y.name(); +} + +} // namespace chrono + +# endif //_LIBCPP_STD_VER >= 20 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) + +#endif // _LIBCPP___CHRONO_TIME_ZONE_LINK_H diff --git a/third_party/libcxx/__chrono/tzdb.h b/third_party/libcxx/__chrono/tzdb.h new file mode 100644 index 000000000..f731f8c31 --- /dev/null +++ b/third_party/libcxx/__chrono/tzdb.h @@ -0,0 +1,94 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html + +#ifndef _LIBCPP___CHRONO_TZDB_H +#define _LIBCPP___CHRONO_TZDB_H + +#include +// Enable the contents of the header only when libc++ was built with experimental features enabled. +#if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) + +# include <__algorithm/ranges_lower_bound.h> +# include <__chrono/leap_second.h> +# include <__chrono/time_zone.h> +# include <__chrono/time_zone_link.h> +# include <__config> +# include +# include + +# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +# endif + +_LIBCPP_PUSH_MACROS +# include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +# if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) && \ + !defined(_LIBCPP_HAS_NO_LOCALIZATION) + +namespace chrono { + +struct tzdb { + string version; + vector zones; + vector links; + + vector leap_seconds; + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const time_zone* __locate_zone(string_view __name) const { + if (const time_zone* __result = __find_in_zone(__name)) + return __result; + + if (auto __it = ranges::lower_bound(links, __name, {}, &time_zone_link::name); + __it != links.end() && __it->name() == __name) + if (const time_zone* __result = __find_in_zone(__it->target())) + return __result; + + return nullptr; + } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const time_zone* locate_zone(string_view __name) const { + if (const time_zone* __result = __locate_zone(__name)) + return __result; + + std::__throw_runtime_error("tzdb: requested time zone not found"); + } + + [[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI const time_zone* current_zone() const { + return __current_zone(); + } + +private: + _LIBCPP_HIDE_FROM_ABI const time_zone* __find_in_zone(string_view __name) const noexcept { + if (auto __it = ranges::lower_bound(zones, __name, {}, &time_zone::name); + __it != zones.end() && __it->name() == __name) + return std::addressof(*__it); + + return nullptr; + } + + [[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI const time_zone* __current_zone() const; +}; + +} // namespace chrono + +# endif // _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) + // && !defined(_LIBCPP_HAS_NO_LOCALIZATION) + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) + +#endif // _LIBCPP___CHRONO_TZDB_H diff --git a/third_party/libcxx/__chrono/tzdb_list.h b/third_party/libcxx/__chrono/tzdb_list.h new file mode 100644 index 000000000..aeef4fe1a --- /dev/null +++ b/third_party/libcxx/__chrono/tzdb_list.h @@ -0,0 +1,108 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html + +#ifndef _LIBCPP___CHRONO_TZDB_LIST_H +#define _LIBCPP___CHRONO_TZDB_LIST_H + +#include +// Enable the contents of the header only when libc++ was built with experimental features enabled. +#if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) + +# include <__chrono/time_zone.h> +# include <__chrono/tzdb.h> +# include <__config> +# include <__fwd/string.h> +# include + +# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +# endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +# if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) && \ + !defined(_LIBCPP_HAS_NO_LOCALIZATION) + +namespace chrono { + +// TODO TZDB +// Libc++ recently switched to only export __ugly_names from the dylib. +// Since the library is still experimental the functions in this header +// should be adapted to this new style. The other tzdb headers should be +// evaluated too. + +class _LIBCPP_AVAILABILITY_TZDB tzdb_list { +public: + class __impl; // public to allow construction in dylib + _LIBCPP_HIDE_FROM_ABI explicit tzdb_list(__impl* __p) : __impl_(__p) { + _LIBCPP_ASSERT_NON_NULL(__impl_ != nullptr, "initialized time_zone without a valid pimpl object"); + } + _LIBCPP_EXPORTED_FROM_ABI ~tzdb_list(); + + tzdb_list(const tzdb_list&) = delete; + tzdb_list& operator=(const tzdb_list&) = delete; + + using const_iterator = forward_list::const_iterator; + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const tzdb& front() const noexcept { return __front(); } + + _LIBCPP_HIDE_FROM_ABI const_iterator erase_after(const_iterator __p) { return __erase_after(__p); } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const_iterator begin() const noexcept { return __begin(); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const_iterator end() const noexcept { return __end(); } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const noexcept { return __cbegin(); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const_iterator cend() const noexcept { return __cend(); } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI __impl& __implementation() { return *__impl_; } + +private: + [[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI const tzdb& __front() const noexcept; + + _LIBCPP_EXPORTED_FROM_ABI const_iterator __erase_after(const_iterator __p); + + [[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI const_iterator __begin() const noexcept; + [[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI const_iterator __end() const noexcept; + + [[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI const_iterator __cbegin() const noexcept; + [[nodiscard]] _LIBCPP_EXPORTED_FROM_ABI const_iterator __cend() const noexcept; + + __impl* __impl_; +}; + +[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI tzdb_list& get_tzdb_list(); + +[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline const tzdb& get_tzdb() { + return get_tzdb_list().front(); +} + +[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline const time_zone* locate_zone(string_view __name) { + return get_tzdb().locate_zone(__name); +} + +[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_HIDE_FROM_ABI inline const time_zone* current_zone() { + return get_tzdb().current_zone(); +} + +_LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI const tzdb& reload_tzdb(); + +[[nodiscard]] _LIBCPP_AVAILABILITY_TZDB _LIBCPP_EXPORTED_FROM_ABI string remote_version(); + +} // namespace chrono + +# endif // _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) + // && !defined(_LIBCPP_HAS_NO_LOCALIZATION) + +_LIBCPP_END_NAMESPACE_STD + +#endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) + +#endif // _LIBCPP___CHRONO_TZDB_LIST_H diff --git a/third_party/libcxx/__chrono/weekday.h b/third_party/libcxx/__chrono/weekday.h index 84b4a3802..86c780cc7 100644 --- a/third_party/libcxx/__chrono/weekday.h +++ b/third_party/libcxx/__chrono/weekday.h @@ -24,157 +24,158 @@ _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { class weekday_indexed; class weekday_last; class weekday { private: - unsigned char __wd_; - _LIBCPP_HIDE_FROM_ABI static constexpr unsigned char __weekday_from_days(int __days) noexcept; + unsigned char __wd_; + _LIBCPP_HIDE_FROM_ABI static constexpr unsigned char __weekday_from_days(int __days) noexcept; + public: weekday() = default; - _LIBCPP_HIDE_FROM_ABI inline explicit constexpr weekday(unsigned __val) noexcept : __wd_(static_cast(__val == 7 ? 0 : __val)) {} - _LIBCPP_HIDE_FROM_ABI inline constexpr weekday(const sys_days& __sysd) noexcept - : __wd_(__weekday_from_days(__sysd.time_since_epoch().count())) {} + _LIBCPP_HIDE_FROM_ABI inline explicit constexpr weekday(unsigned __val) noexcept + : __wd_(static_cast(__val == 7 ? 0 : __val)) {} + _LIBCPP_HIDE_FROM_ABI inline constexpr weekday(const sys_days& __sysd) noexcept + : __wd_(__weekday_from_days(__sysd.time_since_epoch().count())) {} _LIBCPP_HIDE_FROM_ABI inline explicit constexpr weekday(const local_days& __locd) noexcept - : __wd_(__weekday_from_days(__locd.time_since_epoch().count())) {} + : __wd_(__weekday_from_days(__locd.time_since_epoch().count())) {} - _LIBCPP_HIDE_FROM_ABI inline constexpr weekday& operator++() noexcept { __wd_ = (__wd_ == 6 ? 0 : __wd_ + 1); return *this; } - _LIBCPP_HIDE_FROM_ABI inline constexpr weekday operator++(int) noexcept { weekday __tmp = *this; ++(*this); return __tmp; } - _LIBCPP_HIDE_FROM_ABI inline constexpr weekday& operator--() noexcept { __wd_ = (__wd_ == 0 ? 6 : __wd_ - 1); return *this; } - _LIBCPP_HIDE_FROM_ABI inline constexpr weekday operator--(int) noexcept { weekday __tmp = *this; --(*this); return __tmp; } - _LIBCPP_HIDE_FROM_ABI constexpr weekday& operator+=(const days& __dd) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr weekday& operator-=(const days& __dd) noexcept; - _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned c_encoding() const noexcept { return __wd_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr weekday& operator++() noexcept { + __wd_ = (__wd_ == 6 ? 0 : __wd_ + 1); + return *this; + } + _LIBCPP_HIDE_FROM_ABI inline constexpr weekday operator++(int) noexcept { + weekday __tmp = *this; + ++(*this); + return __tmp; + } + _LIBCPP_HIDE_FROM_ABI inline constexpr weekday& operator--() noexcept { + __wd_ = (__wd_ == 0 ? 6 : __wd_ - 1); + return *this; + } + _LIBCPP_HIDE_FROM_ABI inline constexpr weekday operator--(int) noexcept { + weekday __tmp = *this; + --(*this); + return __tmp; + } + _LIBCPP_HIDE_FROM_ABI constexpr weekday& operator+=(const days& __dd) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr weekday& operator-=(const days& __dd) noexcept; + _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned c_encoding() const noexcept { return __wd_; } _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned iso_encoding() const noexcept { return __wd_ == 0u ? 7 : __wd_; } _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __wd_ <= 6; } - _LIBCPP_HIDE_FROM_ABI constexpr weekday_indexed operator[](unsigned __index) const noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr weekday_last operator[](last_spec) const noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr weekday_indexed operator[](unsigned __index) const noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr weekday_last operator[](last_spec) const noexcept; }; - // https://howardhinnant.github.io/date_algorithms.html#weekday_from_days -_LIBCPP_HIDE_FROM_ABI inline constexpr -unsigned char weekday::__weekday_from_days(int __days) noexcept -{ - return static_cast( - static_cast(__days >= -4 ? (__days+4) % 7 : (__days+5) % 7 + 6) - ); +_LIBCPP_HIDE_FROM_ABI inline constexpr unsigned char weekday::__weekday_from_days(int __days) noexcept { + return static_cast(static_cast(__days >= -4 ? (__days + 4) % 7 : (__days + 5) % 7 + 6)); } -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator==(const weekday& __lhs, const weekday& __rhs) noexcept -{ return __lhs.c_encoding() == __rhs.c_encoding(); } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator!=(const weekday& __lhs, const weekday& __rhs) noexcept -{ return !(__lhs == __rhs); } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator< (const weekday& __lhs, const weekday& __rhs) noexcept -{ return __lhs.c_encoding() < __rhs.c_encoding(); } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator> (const weekday& __lhs, const weekday& __rhs) noexcept -{ return __rhs < __lhs; } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator<=(const weekday& __lhs, const weekday& __rhs) noexcept -{ return !(__rhs < __lhs);} - -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator>=(const weekday& __lhs, const weekday& __rhs) noexcept -{ return !(__lhs < __rhs); } - -_LIBCPP_HIDE_FROM_ABI constexpr -weekday operator+(const weekday& __lhs, const days& __rhs) noexcept -{ - auto const __mu = static_cast(__lhs.c_encoding()) + __rhs.count(); - auto const __yr = (__mu >= 0 ? __mu : __mu - 6) / 7; - return weekday{static_cast(__mu - __yr * 7)}; +_LIBCPP_HIDE_FROM_ABI inline constexpr bool operator==(const weekday& __lhs, const weekday& __rhs) noexcept { + return __lhs.c_encoding() == __rhs.c_encoding(); } -_LIBCPP_HIDE_FROM_ABI constexpr -weekday operator+(const days& __lhs, const weekday& __rhs) noexcept -{ return __rhs + __lhs; } - -_LIBCPP_HIDE_FROM_ABI constexpr -weekday operator-(const weekday& __lhs, const days& __rhs) noexcept -{ return __lhs + -__rhs; } - -_LIBCPP_HIDE_FROM_ABI constexpr -days operator-(const weekday& __lhs, const weekday& __rhs) noexcept -{ - const int __wdu = __lhs.c_encoding() - __rhs.c_encoding(); - const int __wk = (__wdu >= 0 ? __wdu : __wdu-6) / 7; - return days{__wdu - __wk * 7}; +// TODO(LLVM 20): Remove the escape hatch +# ifdef _LIBCPP_ENABLE_REMOVED_WEEKDAY_RELATIONAL_OPERATORS +_LIBCPP_HIDE_FROM_ABI inline constexpr bool operator<(const weekday& __lhs, const weekday& __rhs) noexcept { + return __lhs.c_encoding() < __rhs.c_encoding(); } -_LIBCPP_HIDE_FROM_ABI inline constexpr -weekday& weekday::operator+=(const days& __dd) noexcept -{ *this = *this + __dd; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool operator>(const weekday& __lhs, const weekday& __rhs) noexcept { + return __rhs < __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -weekday& weekday::operator-=(const days& __dd) noexcept -{ *this = *this - __dd; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool operator<=(const weekday& __lhs, const weekday& __rhs) noexcept { + return !(__rhs < __lhs); +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr bool operator>=(const weekday& __lhs, const weekday& __rhs) noexcept { + return !(__lhs < __rhs); +} +# endif // _LIBCPP_ENABLE_REMOVED_WEEKDAY_RELATIONAL_OPERATORS + +_LIBCPP_HIDE_FROM_ABI inline constexpr weekday operator+(const weekday& __lhs, const days& __rhs) noexcept { + auto const __mu = static_cast(__lhs.c_encoding()) + __rhs.count(); + auto const __yr = (__mu >= 0 ? __mu : __mu - 6) / 7; + return weekday{static_cast(__mu - __yr * 7)}; +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr weekday operator+(const days& __lhs, const weekday& __rhs) noexcept { + return __rhs + __lhs; +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr weekday operator-(const weekday& __lhs, const days& __rhs) noexcept { + return __lhs + -__rhs; +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr days operator-(const weekday& __lhs, const weekday& __rhs) noexcept { + const int __wdu = __lhs.c_encoding() - __rhs.c_encoding(); + const int __wk = (__wdu >= 0 ? __wdu : __wdu - 6) / 7; + return days{__wdu - __wk * 7}; +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr weekday& weekday::operator+=(const days& __dd) noexcept { + *this = *this + __dd; + return *this; +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr weekday& weekday::operator-=(const days& __dd) noexcept { + *this = *this - __dd; + return *this; +} class weekday_indexed { private: - chrono::weekday __wd_; - unsigned char __idx_; + chrono::weekday __wd_; + unsigned char __idx_; + public: - weekday_indexed() = default; - _LIBCPP_HIDE_FROM_ABI inline constexpr weekday_indexed(const chrono::weekday& __wdval, unsigned __idxval) noexcept - : __wd_{__wdval}, __idx_(__idxval) {} - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday weekday() const noexcept { return __wd_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned index() const noexcept { return __idx_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __wd_.ok() && __idx_ >= 1 && __idx_ <= 5; } + weekday_indexed() = default; + _LIBCPP_HIDE_FROM_ABI inline constexpr weekday_indexed(const chrono::weekday& __wdval, unsigned __idxval) noexcept + : __wd_{__wdval}, __idx_(__idxval) {} + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday weekday() const noexcept { return __wd_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned index() const noexcept { return __idx_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __wd_.ok() && __idx_ >= 1 && __idx_ <= 5; } }; -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator==(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept -{ return __lhs.weekday() == __rhs.weekday() && __lhs.index() == __rhs.index(); } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator!=(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept -{ return !(__lhs == __rhs); } - +_LIBCPP_HIDE_FROM_ABI inline constexpr bool +operator==(const weekday_indexed& __lhs, const weekday_indexed& __rhs) noexcept { + return __lhs.weekday() == __rhs.weekday() && __lhs.index() == __rhs.index(); +} class weekday_last { private: - chrono::weekday __wd_; + chrono::weekday __wd_; + public: - _LIBCPP_HIDE_FROM_ABI explicit constexpr weekday_last(const chrono::weekday& __val) noexcept - : __wd_{__val} {} - _LIBCPP_HIDE_FROM_ABI constexpr chrono::weekday weekday() const noexcept { return __wd_; } - _LIBCPP_HIDE_FROM_ABI constexpr bool ok() const noexcept { return __wd_.ok(); } + _LIBCPP_HIDE_FROM_ABI explicit constexpr weekday_last(const chrono::weekday& __val) noexcept : __wd_{__val} {} + _LIBCPP_HIDE_FROM_ABI constexpr chrono::weekday weekday() const noexcept { return __wd_; } + _LIBCPP_HIDE_FROM_ABI constexpr bool ok() const noexcept { return __wd_.ok(); } }; -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator==(const weekday_last& __lhs, const weekday_last& __rhs) noexcept -{ return __lhs.weekday() == __rhs.weekday(); } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool operator==(const weekday_last& __lhs, const weekday_last& __rhs) noexcept { + return __lhs.weekday() == __rhs.weekday(); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator!=(const weekday_last& __lhs, const weekday_last& __rhs) noexcept -{ return !(__lhs == __rhs); } +_LIBCPP_HIDE_FROM_ABI inline constexpr weekday_indexed weekday::operator[](unsigned __index) const noexcept { + return weekday_indexed{*this, __index}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -weekday_indexed weekday::operator[](unsigned __index) const noexcept { return weekday_indexed{*this, __index}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr weekday_last weekday::operator[](last_spec) const noexcept { + return weekday_last{*this}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -weekday_last weekday::operator[](last_spec) const noexcept { return weekday_last{*this}; } - - -inline constexpr weekday Sunday{0}; -inline constexpr weekday Monday{1}; -inline constexpr weekday Tuesday{2}; -inline constexpr weekday Wednesday{3}; -inline constexpr weekday Thursday{4}; -inline constexpr weekday Friday{5}; -inline constexpr weekday Saturday{6}; +inline constexpr weekday Sunday{0}; +inline constexpr weekday Monday{1}; +inline constexpr weekday Tuesday{2}; +inline constexpr weekday Wednesday{3}; +inline constexpr weekday Thursday{4}; +inline constexpr weekday Friday{5}; +inline constexpr weekday Saturday{6}; } // namespace chrono diff --git a/third_party/libcxx/__chrono/year.h b/third_party/libcxx/__chrono/year.h index 14bcbdafd..1899d09f3 100644 --- a/third_party/libcxx/__chrono/year.h +++ b/third_party/libcxx/__chrono/year.h @@ -26,65 +26,81 @@ _LIBCPP_PUSH_MACROS _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { class year { private: - short __y_; + short __y_; + public: - year() = default; - _LIBCPP_HIDE_FROM_ABI explicit inline constexpr year(int __val) noexcept : __y_(static_cast(__val)) {} + year() = default; + _LIBCPP_HIDE_FROM_ABI explicit inline constexpr year(int __val) noexcept : __y_(static_cast(__val)) {} - _LIBCPP_HIDE_FROM_ABI inline constexpr year& operator++() noexcept { ++__y_; return *this; } - _LIBCPP_HIDE_FROM_ABI inline constexpr year operator++(int) noexcept { year __tmp = *this; ++(*this); return __tmp; } - _LIBCPP_HIDE_FROM_ABI inline constexpr year& operator--() noexcept { --__y_; return *this; } - _LIBCPP_HIDE_FROM_ABI inline constexpr year operator--(int) noexcept { year __tmp = *this; --(*this); return __tmp; } - _LIBCPP_HIDE_FROM_ABI constexpr year& operator+=(const years& __dy) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr year& operator-=(const years& __dy) noexcept; - _LIBCPP_HIDE_FROM_ABI inline constexpr year operator+() const noexcept { return *this; } - _LIBCPP_HIDE_FROM_ABI inline constexpr year operator-() const noexcept { return year{-__y_}; } + _LIBCPP_HIDE_FROM_ABI inline constexpr year& operator++() noexcept { + ++__y_; + return *this; + } + _LIBCPP_HIDE_FROM_ABI inline constexpr year operator++(int) noexcept { + year __tmp = *this; + ++(*this); + return __tmp; + } + _LIBCPP_HIDE_FROM_ABI inline constexpr year& operator--() noexcept { + --__y_; + return *this; + } + _LIBCPP_HIDE_FROM_ABI inline constexpr year operator--(int) noexcept { + year __tmp = *this; + --(*this); + return __tmp; + } + _LIBCPP_HIDE_FROM_ABI constexpr year& operator+=(const years& __dy) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year& operator-=(const years& __dy) noexcept; + _LIBCPP_HIDE_FROM_ABI inline constexpr year operator+() const noexcept { return *this; } + _LIBCPP_HIDE_FROM_ABI inline constexpr year operator-() const noexcept { return year{-__y_}; } - _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_leap() const noexcept { return __y_ % 4 == 0 && (__y_ % 100 != 0 || __y_ % 400 == 0); } - _LIBCPP_HIDE_FROM_ABI explicit inline constexpr operator int() const noexcept { return __y_; } - _LIBCPP_HIDE_FROM_ABI constexpr bool ok() const noexcept; - _LIBCPP_HIDE_FROM_ABI static inline constexpr year min() noexcept { return year{-32767}; } - _LIBCPP_HIDE_FROM_ABI static inline constexpr year max() noexcept { return year{ 32767}; } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_leap() const noexcept { + return __y_ % 4 == 0 && (__y_ % 100 != 0 || __y_ % 400 == 0); + } + _LIBCPP_HIDE_FROM_ABI explicit inline constexpr operator int() const noexcept { return __y_; } + _LIBCPP_HIDE_FROM_ABI constexpr bool ok() const noexcept; + _LIBCPP_HIDE_FROM_ABI static inline constexpr year min() noexcept { return year{-32767}; } + _LIBCPP_HIDE_FROM_ABI static inline constexpr year max() noexcept { return year{32767}; } }; - -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator==(const year& __lhs, const year& __rhs) noexcept -{ return static_cast(__lhs) == static_cast(__rhs); } - -_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const year& __lhs, const year& __rhs) noexcept { - return static_cast(__lhs) <=> static_cast(__rhs); +_LIBCPP_HIDE_FROM_ABI inline constexpr bool operator==(const year& __lhs, const year& __rhs) noexcept { + return static_cast(__lhs) == static_cast(__rhs); } -_LIBCPP_HIDE_FROM_ABI inline constexpr -year operator+ (const year& __lhs, const years& __rhs) noexcept -{ return year(static_cast(__lhs) + __rhs.count()); } +_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const year& __lhs, const year& __rhs) noexcept { + return static_cast(__lhs) <=> static_cast(__rhs); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year operator+ (const years& __lhs, const year& __rhs) noexcept -{ return __rhs + __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year operator+(const year& __lhs, const years& __rhs) noexcept { + return year(static_cast(__lhs) + __rhs.count()); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year operator- (const year& __lhs, const years& __rhs) noexcept -{ return __lhs + -__rhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year operator+(const years& __lhs, const year& __rhs) noexcept { + return __rhs + __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -years operator-(const year& __lhs, const year& __rhs) noexcept -{ return years{static_cast(__lhs) - static_cast(__rhs)}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year operator-(const year& __lhs, const years& __rhs) noexcept { + return __lhs + -__rhs; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr years operator-(const year& __lhs, const year& __rhs) noexcept { + return years{static_cast(__lhs) - static_cast(__rhs)}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year& year::operator+=(const years& __dy) noexcept -{ *this = *this + __dy; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year& year::operator+=(const years& __dy) noexcept { + *this = *this + __dy; + return *this; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year& year::operator-=(const years& __dy) noexcept -{ *this = *this - __dy; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year& year::operator-=(const years& __dy) noexcept { + *this = *this - __dy; + return *this; +} _LIBCPP_HIDE_FROM_ABI constexpr bool year::ok() const noexcept { static_assert(static_cast(std::numeric_limits::max()) == static_cast(max())); diff --git a/third_party/libcxx/__chrono/year_month.h b/third_party/libcxx/__chrono/year_month.h index f4eea8427..369ea38f7 100644 --- a/third_party/libcxx/__chrono/year_month.h +++ b/third_party/libcxx/__chrono/year_month.h @@ -24,73 +24,95 @@ _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { class year_month { - chrono::year __y_; - chrono::month __m_; + chrono::year __y_; + chrono::month __m_; + public: - year_month() = default; - _LIBCPP_HIDE_FROM_ABI constexpr year_month(const chrono::year& __yval, const chrono::month& __mval) noexcept - : __y_{__yval}, __m_{__mval} {} - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator+=(const months& __dm) noexcept { this->__m_ += __dm; return *this; } - _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator-=(const months& __dm) noexcept { this->__m_ -= __dm; return *this; } - _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator+=(const years& __dy) noexcept { this->__y_ += __dy; return *this; } - _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator-=(const years& __dy) noexcept { this->__y_ -= __dy; return *this; } - _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __y_.ok() && __m_.ok(); } + year_month() = default; + _LIBCPP_HIDE_FROM_ABI constexpr year_month(const chrono::year& __yval, const chrono::month& __mval) noexcept + : __y_{__yval}, __m_{__mval} {} + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator+=(const months& __dm) noexcept; + _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator-=(const months& __dm) noexcept; + _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator+=(const years& __dy) noexcept; + _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator-=(const years& __dy) noexcept; + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __y_.ok() && __m_.ok(); } }; -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month operator/(const year& __y, const month& __m) noexcept { return year_month{__y, __m}; } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month operator/(const year& __y, int __m) noexcept { return year_month{__y, month(__m)}; } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator==(const year_month& __lhs, const year_month& __rhs) noexcept -{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month(); } - -_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering operator<=>(const year_month& __lhs, const year_month& __rhs) noexcept { - if (auto __c = __lhs.year() <=> __rhs.year(); __c != 0) - return __c; - return __lhs.month() <=> __rhs.month(); +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month operator/(const year& __y, const month& __m) noexcept { + return year_month{__y, __m}; } -_LIBCPP_HIDE_FROM_ABI constexpr -year_month operator+(const year_month& __lhs, const months& __rhs) noexcept -{ - int __dmi = static_cast(static_cast(__lhs.month())) - 1 + __rhs.count(); - const int __dy = (__dmi >= 0 ? __dmi : __dmi-11) / 12; - __dmi = __dmi - __dy * 12 + 1; - return (__lhs.year() + years(__dy)) / month(static_cast(__dmi)); +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month operator/(const year& __y, int __m) noexcept { + return year_month{__y, month(__m)}; } -_LIBCPP_HIDE_FROM_ABI constexpr -year_month operator+(const months& __lhs, const year_month& __rhs) noexcept -{ return __rhs + __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool operator==(const year_month& __lhs, const year_month& __rhs) noexcept { + return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month(); +} -_LIBCPP_HIDE_FROM_ABI constexpr -year_month operator+(const year_month& __lhs, const years& __rhs) noexcept -{ return (__lhs.year() + __rhs) / __lhs.month(); } +_LIBCPP_HIDE_FROM_ABI inline constexpr strong_ordering +operator<=>(const year_month& __lhs, const year_month& __rhs) noexcept { + if (auto __c = __lhs.year() <=> __rhs.year(); __c != 0) + return __c; + return __lhs.month() <=> __rhs.month(); +} -_LIBCPP_HIDE_FROM_ABI constexpr -year_month operator+(const years& __lhs, const year_month& __rhs) noexcept -{ return __rhs + __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month operator+(const year_month& __lhs, const months& __rhs) noexcept { + int __dmi = static_cast(static_cast(__lhs.month())) - 1 + __rhs.count(); + const int __dy = (__dmi >= 0 ? __dmi : __dmi - 11) / 12; + __dmi = __dmi - __dy * 12 + 1; + return (__lhs.year() + years(__dy)) / month(static_cast(__dmi)); +} -_LIBCPP_HIDE_FROM_ABI constexpr -months operator-(const year_month& __lhs, const year_month& __rhs) noexcept -{ return (__lhs.year() - __rhs.year()) + months(static_cast(__lhs.month()) - static_cast(__rhs.month())); } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month operator+(const months& __lhs, const year_month& __rhs) noexcept { + return __rhs + __lhs; +} -_LIBCPP_HIDE_FROM_ABI constexpr -year_month operator-(const year_month& __lhs, const months& __rhs) noexcept -{ return __lhs + -__rhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month operator+(const year_month& __lhs, const years& __rhs) noexcept { + return (__lhs.year() + __rhs) / __lhs.month(); +} -_LIBCPP_HIDE_FROM_ABI constexpr -year_month operator-(const year_month& __lhs, const years& __rhs) noexcept -{ return __lhs + -__rhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month operator+(const years& __lhs, const year_month& __rhs) noexcept { + return __rhs + __lhs; +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr months operator-(const year_month& __lhs, const year_month& __rhs) noexcept { + return (__lhs.year() - __rhs.year()) + + months(static_cast(__lhs.month()) - static_cast(__rhs.month())); +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month operator-(const year_month& __lhs, const months& __rhs) noexcept { + return __lhs + -__rhs; +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month operator-(const year_month& __lhs, const years& __rhs) noexcept { + return __lhs + -__rhs; +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month& year_month::operator+=(const months& __dm) noexcept { + *this = *this + __dm; + return *this; +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month& year_month::operator-=(const months& __dm) noexcept { + *this = *this - __dm; + return *this; +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month& year_month::operator+=(const years& __dy) noexcept { + *this = *this + __dy; + return *this; +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month& year_month::operator-=(const years& __dy) noexcept { + *this = *this - __dy; + return *this; +} } // namespace chrono diff --git a/third_party/libcxx/__chrono/year_month_day.h b/third_party/libcxx/__chrono/year_month_day.h index ed5903f7d..b06c0be03 100644 --- a/third_party/libcxx/__chrono/year_month_day.h +++ b/third_party/libcxx/__chrono/year_month_day.h @@ -31,271 +31,301 @@ _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { class year_month_day_last; class year_month_day { private: - chrono::year __y_; - chrono::month __m_; - chrono::day __d_; + chrono::year __y_; + chrono::month __m_; + chrono::day __d_; + public: - year_month_day() = default; - _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day( - const chrono::year& __yval, const chrono::month& __mval, const chrono::day& __dval) noexcept - : __y_{__yval}, __m_{__mval}, __d_{__dval} {} - _LIBCPP_HIDE_FROM_ABI constexpr year_month_day(const year_month_day_last& __ymdl) noexcept; - _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day(const sys_days& __sysd) noexcept - : year_month_day(__from_days(__sysd.time_since_epoch())) {} - _LIBCPP_HIDE_FROM_ABI inline explicit constexpr year_month_day(const local_days& __locd) noexcept - : year_month_day(__from_days(__locd.time_since_epoch())) {} + year_month_day() = default; + _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day( + const chrono::year& __yval, const chrono::month& __mval, const chrono::day& __dval) noexcept + : __y_{__yval}, __m_{__mval}, __d_{__dval} {} + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day(const year_month_day_last& __ymdl) noexcept; + _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day(const sys_days& __sysd) noexcept + : year_month_day(__from_days(__sysd.time_since_epoch())) {} + _LIBCPP_HIDE_FROM_ABI inline explicit constexpr year_month_day(const local_days& __locd) noexcept + : year_month_day(__from_days(__locd.time_since_epoch())) {} - _LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator+=(const months& __dm) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator-=(const months& __dm) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator+=(const years& __dy) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator-=(const years& __dy) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator+=(const months& __dm) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator-=(const months& __dm) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator+=(const years& __dy) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator-=(const years& __dy) noexcept; - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::day day() const noexcept { return __d_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } - _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::day day() const noexcept { return __d_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } + _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { + return local_days{__to_days()}; + } - _LIBCPP_HIDE_FROM_ABI constexpr bool ok() const noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr bool ok() const noexcept; - _LIBCPP_HIDE_FROM_ABI static constexpr year_month_day __from_days(days __d) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr days __to_days() const noexcept; + _LIBCPP_HIDE_FROM_ABI static constexpr year_month_day __from_days(days __d) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr days __to_days() const noexcept; }; - // https://howardhinnant.github.io/date_algorithms.html#civil_from_days -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day year_month_day::__from_days(days __d) noexcept -{ - static_assert(numeric_limits::digits >= 18, ""); - static_assert(numeric_limits::digits >= 20 , ""); - const int __z = __d.count() + 719468; - const int __era = (__z >= 0 ? __z : __z - 146096) / 146097; - const unsigned __doe = static_cast(__z - __era * 146097); // [0, 146096] - const unsigned __yoe = (__doe - __doe/1460 + __doe/36524 - __doe/146096) / 365; // [0, 399] - const int __yr = static_cast(__yoe) + __era * 400; - const unsigned __doy = __doe - (365 * __yoe + __yoe/4 - __yoe/100); // [0, 365] - const unsigned __mp = (5 * __doy + 2)/153; // [0, 11] - const unsigned __dy = __doy - (153 * __mp + 2)/5 + 1; // [1, 31] - const unsigned __mth = __mp + (__mp < 10 ? 3 : -9); // [1, 12] - return year_month_day{chrono::year{__yr + (__mth <= 2)}, chrono::month{__mth}, chrono::day{__dy}}; +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day year_month_day::__from_days(days __d) noexcept { + static_assert(numeric_limits::digits >= 18, ""); + static_assert(numeric_limits::digits >= 20, ""); + const int __z = __d.count() + 719468; + const int __era = (__z >= 0 ? __z : __z - 146096) / 146097; + const unsigned __doe = static_cast(__z - __era * 146097); // [0, 146096] + const unsigned __yoe = (__doe - __doe / 1460 + __doe / 36524 - __doe / 146096) / 365; // [0, 399] + const int __yr = static_cast(__yoe) + __era * 400; + const unsigned __doy = __doe - (365 * __yoe + __yoe / 4 - __yoe / 100); // [0, 365] + const unsigned __mp = (5 * __doy + 2) / 153; // [0, 11] + const unsigned __dy = __doy - (153 * __mp + 2) / 5 + 1; // [1, 31] + const unsigned __mth = __mp + (__mp < 10 ? 3 : -9); // [1, 12] + return year_month_day{chrono::year{__yr + (__mth <= 2)}, chrono::month{__mth}, chrono::day{__dy}}; } // https://howardhinnant.github.io/date_algorithms.html#days_from_civil -_LIBCPP_HIDE_FROM_ABI inline constexpr -days year_month_day::__to_days() const noexcept -{ - static_assert(numeric_limits::digits >= 18, ""); - static_assert(numeric_limits::digits >= 20 , ""); +_LIBCPP_HIDE_FROM_ABI inline constexpr days year_month_day::__to_days() const noexcept { + static_assert(numeric_limits::digits >= 18, ""); + static_assert(numeric_limits::digits >= 20, ""); - const int __yr = static_cast(__y_) - (__m_ <= February); - const unsigned __mth = static_cast(__m_); - const unsigned __dy = static_cast(__d_); + const int __yr = static_cast(__y_) - (__m_ <= February); + const unsigned __mth = static_cast(__m_); + const unsigned __dy = static_cast(__d_); - const int __era = (__yr >= 0 ? __yr : __yr - 399) / 400; - const unsigned __yoe = static_cast(__yr - __era * 400); // [0, 399] - const unsigned __doy = (153 * (__mth + (__mth > 2 ? -3 : 9)) + 2) / 5 + __dy-1; // [0, 365] - const unsigned __doe = __yoe * 365 + __yoe/4 - __yoe/100 + __doy; // [0, 146096] - return days{__era * 146097 + static_cast(__doe) - 719468}; + const int __era = (__yr >= 0 ? __yr : __yr - 399) / 400; + const unsigned __yoe = static_cast(__yr - __era * 400); // [0, 399] + const unsigned __doy = (153 * (__mth + (__mth > 2 ? -3 : 9)) + 2) / 5 + __dy - 1; // [0, 365] + const unsigned __doe = __yoe * 365 + __yoe / 4 - __yoe / 100 + __doy; // [0, 146096] + return days{__era * 146097 + static_cast(__doe) - 719468}; } -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator==(const year_month_day& __lhs, const year_month_day& __rhs) noexcept -{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool +operator==(const year_month_day& __lhs, const year_month_day& __rhs) noexcept { + return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day(); +} -_LIBCPP_HIDE_FROM_ABI constexpr strong_ordering +_LIBCPP_HIDE_FROM_ABI inline constexpr strong_ordering operator<=>(const year_month_day& __lhs, const year_month_day& __rhs) noexcept { - if (auto __c = __lhs.year() <=> __rhs.year(); __c != 0) - return __c; - if (auto __c = __lhs.month() <=> __rhs.month(); __c != 0) - return __c; - return __lhs.day() <=> __rhs.day(); + if (auto __c = __lhs.year() <=> __rhs.year(); __c != 0) + return __c; + if (auto __c = __lhs.month() <=> __rhs.month(); __c != 0) + return __c; + return __lhs.day() <=> __rhs.day(); } -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day operator/(const year_month& __lhs, const day& __rhs) noexcept -{ return year_month_day{__lhs.year(), __lhs.month(), __rhs}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day operator/(const year_month& __lhs, const day& __rhs) noexcept { + return year_month_day{__lhs.year(), __lhs.month(), __rhs}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day operator/(const year_month& __lhs, int __rhs) noexcept -{ return __lhs / day(__rhs); } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day operator/(const year_month& __lhs, int __rhs) noexcept { + return __lhs / day(__rhs); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day operator/(const year& __lhs, const month_day& __rhs) noexcept -{ return __lhs / __rhs.month() / __rhs.day(); } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day operator/(const year& __lhs, const month_day& __rhs) noexcept { + return __lhs / __rhs.month() / __rhs.day(); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day operator/(int __lhs, const month_day& __rhs) noexcept -{ return year(__lhs) / __rhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day operator/(int __lhs, const month_day& __rhs) noexcept { + return year(__lhs) / __rhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day operator/(const month_day& __lhs, const year& __rhs) noexcept -{ return __rhs / __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day operator/(const month_day& __lhs, const year& __rhs) noexcept { + return __rhs / __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day operator/(const month_day& __lhs, int __rhs) noexcept -{ return year(__rhs) / __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day operator/(const month_day& __lhs, int __rhs) noexcept { + return year(__rhs) / __lhs; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day +operator+(const year_month_day& __lhs, const months& __rhs) noexcept { + return (__lhs.year() / __lhs.month() + __rhs) / __lhs.day(); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day operator+(const year_month_day& __lhs, const months& __rhs) noexcept -{ return (__lhs.year()/__lhs.month() + __rhs)/__lhs.day(); } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day +operator+(const months& __lhs, const year_month_day& __rhs) noexcept { + return __rhs + __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day operator+(const months& __lhs, const year_month_day& __rhs) noexcept -{ return __rhs + __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day +operator-(const year_month_day& __lhs, const months& __rhs) noexcept { + return __lhs + -__rhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day operator-(const year_month_day& __lhs, const months& __rhs) noexcept -{ return __lhs + -__rhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day +operator+(const year_month_day& __lhs, const years& __rhs) noexcept { + return (__lhs.year() + __rhs) / __lhs.month() / __lhs.day(); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day operator+(const year_month_day& __lhs, const years& __rhs) noexcept -{ return (__lhs.year() + __rhs) / __lhs.month() / __lhs.day(); } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day +operator+(const years& __lhs, const year_month_day& __rhs) noexcept { + return __rhs + __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day operator+(const years& __lhs, const year_month_day& __rhs) noexcept -{ return __rhs + __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day +operator-(const year_month_day& __lhs, const years& __rhs) noexcept { + return __lhs + -__rhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day operator-(const year_month_day& __lhs, const years& __rhs) noexcept -{ return __lhs + -__rhs; } - -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator+=(const months& __dm) noexcept { + *this = *this + __dm; + return *this; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator-=(const months& __dm) noexcept { + *this = *this - __dm; + return *this; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator+=(const years& __dy) noexcept { + *this = *this + __dy; + return *this; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator-=(const years& __dy) noexcept { + *this = *this - __dy; + return *this; +} class year_month_day_last { private: - chrono::year __y_; - chrono::month_day_last __mdl_; + chrono::year __y_; + chrono::month_day_last __mdl_; + public: - _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last(const year& __yval, const month_day_last& __mdlval) noexcept - : __y_{__yval}, __mdl_{__mdlval} {} + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last(const year& __yval, const month_day_last& __mdlval) noexcept + : __y_{__yval}, __mdl_{__mdlval} {} - _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator+=(const months& __m) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator-=(const months& __m) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator+=(const years& __y) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator-=(const years& __y) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator+=(const months& __m) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator-=(const months& __m) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator+=(const years& __y) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator-=(const years& __y) noexcept; - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __mdl_.month(); } - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month_day_last month_day_last() const noexcept { return __mdl_; } - _LIBCPP_HIDE_FROM_ABI constexpr chrono::day day() const noexcept; - _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{year()/month()/day()}; } - _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { return local_days{year()/month()/day()}; } - _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __y_.ok() && __mdl_.ok(); } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __mdl_.month(); } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month_day_last month_day_last() const noexcept { return __mdl_; } + _LIBCPP_HIDE_FROM_ABI constexpr chrono::day day() const noexcept; + _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { + return sys_days{year() / month() / day()}; + } + _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { + return local_days{year() / month() / day()}; + } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __y_.ok() && __mdl_.ok(); } }; -_LIBCPP_HIDE_FROM_ABI inline constexpr -chrono::day year_month_day_last::day() const noexcept -{ - constexpr chrono::day __d[] = - { - chrono::day(31), chrono::day(28), chrono::day(31), - chrono::day(30), chrono::day(31), chrono::day(30), - chrono::day(31), chrono::day(31), chrono::day(30), - chrono::day(31), chrono::day(30), chrono::day(31) - }; - return (month() != February || !__y_.is_leap()) && month().ok() ? - __d[static_cast(month()) - 1] : chrono::day{29}; +_LIBCPP_HIDE_FROM_ABI inline constexpr chrono::day year_month_day_last::day() const noexcept { + constexpr chrono::day __d[] = { + chrono::day(31), + chrono::day(28), + chrono::day(31), + chrono::day(30), + chrono::day(31), + chrono::day(30), + chrono::day(31), + chrono::day(31), + chrono::day(30), + chrono::day(31), + chrono::day(30), + chrono::day(31)}; + return (month() != February || !__y_.is_leap()) && month().ok() + ? __d[static_cast(month()) - 1] + : chrono::day{29}; } -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator==(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept -{ return __lhs.year() == __rhs.year() && __lhs.month_day_last() == __rhs.month_day_last(); } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator!=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept -{ return !(__lhs == __rhs); } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator< (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept -{ - if (__lhs.year() < __rhs.year()) return true; - if (__lhs.year() > __rhs.year()) return false; - return __lhs.month_day_last() < __rhs.month_day_last(); +_LIBCPP_HIDE_FROM_ABI inline constexpr bool +operator==(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept { + return __lhs.year() == __rhs.year() && __lhs.month_day_last() == __rhs.month_day_last(); } -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator> (const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept -{ return __rhs < __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr strong_ordering +operator<=>(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept { + if (auto __c = __lhs.year() <=> __rhs.year(); __c != 0) + return __c; + return __lhs.month_day_last() <=> __rhs.month_day_last(); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator<=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept -{ return !(__rhs < __lhs);} - -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator>=(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept -{ return !(__lhs < __rhs); } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day_last operator/(const year_month& __lhs, last_spec) noexcept -{ return year_month_day_last{__lhs.year(), month_day_last{__lhs.month()}}; } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day_last operator/(const year& __lhs, const month_day_last& __rhs) noexcept -{ return year_month_day_last{__lhs, __rhs}; } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day_last operator/(int __lhs, const month_day_last& __rhs) noexcept -{ return year_month_day_last{year{__lhs}, __rhs}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last operator/(const year_month& __lhs, last_spec) noexcept { + return year_month_day_last{__lhs.year(), month_day_last{__lhs.month()}}; +} _LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last -operator/(const month_day_last& __lhs, const year& __rhs) noexcept -{ return __rhs / __lhs; } +operator/(const year& __lhs, const month_day_last& __rhs) noexcept { + return year_month_day_last{__lhs, __rhs}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day_last operator/(const month_day_last& __lhs, int __rhs) noexcept -{ return year{__rhs} / __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last operator/(int __lhs, const month_day_last& __rhs) noexcept { + return year_month_day_last{year{__lhs}, __rhs}; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last +operator/(const month_day_last& __lhs, const year& __rhs) noexcept { + return __rhs / __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day_last operator+(const year_month_day_last& __lhs, const months& __rhs) noexcept -{ return (__lhs.year() / __lhs.month() + __rhs) / last; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last operator/(const month_day_last& __lhs, int __rhs) noexcept { + return year{__rhs} / __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day_last operator+(const months& __lhs, const year_month_day_last& __rhs) noexcept -{ return __rhs + __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last +operator+(const year_month_day_last& __lhs, const months& __rhs) noexcept { + return (__lhs.year() / __lhs.month() + __rhs) / last; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day_last operator-(const year_month_day_last& __lhs, const months& __rhs) noexcept -{ return __lhs + (-__rhs); } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last +operator+(const months& __lhs, const year_month_day_last& __rhs) noexcept { + return __rhs + __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day_last operator+(const year_month_day_last& __lhs, const years& __rhs) noexcept -{ return year_month_day_last{__lhs.year() + __rhs, __lhs.month_day_last()}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last +operator-(const year_month_day_last& __lhs, const months& __rhs) noexcept { + return __lhs + (-__rhs); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day_last operator+(const years& __lhs, const year_month_day_last& __rhs) noexcept -{ return __rhs + __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last +operator+(const year_month_day_last& __lhs, const years& __rhs) noexcept { + return year_month_day_last{__lhs.year() + __rhs, __lhs.month_day_last()}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day_last operator-(const year_month_day_last& __lhs, const years& __rhs) noexcept -{ return __lhs + (-__rhs); } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last +operator+(const years& __lhs, const year_month_day_last& __rhs) noexcept { + return __rhs + __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last& year_month_day_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last& year_month_day_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last& year_month_day_last::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last& year_month_day_last::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last +operator-(const year_month_day_last& __lhs, const years& __rhs) noexcept { + return __lhs + (-__rhs); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_day::year_month_day(const year_month_day_last& __ymdl) noexcept +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last& +year_month_day_last::operator+=(const months& __dm) noexcept { + *this = *this + __dm; + return *this; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last& +year_month_day_last::operator-=(const months& __dm) noexcept { + *this = *this - __dm; + return *this; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last& +year_month_day_last::operator+=(const years& __dy) noexcept { + *this = *this + __dy; + return *this; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last& +year_month_day_last::operator-=(const years& __dy) noexcept { + *this = *this - __dy; + return *this; +} + +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day::year_month_day(const year_month_day_last& __ymdl) noexcept : __y_{__ymdl.year()}, __m_{__ymdl.month()}, __d_{__ymdl.day()} {} -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool year_month_day::ok() const noexcept -{ - if (!__y_.ok() || !__m_.ok()) return false; - return chrono::day{1} <= __d_ && __d_ <= (__y_ / __m_ / last).day(); +_LIBCPP_HIDE_FROM_ABI inline constexpr bool year_month_day::ok() const noexcept { + if (!__y_.ok() || !__m_.ok()) + return false; + return chrono::day{1} <= __d_ && __d_ <= (__y_ / __m_ / last).day(); } } // namespace chrono diff --git a/third_party/libcxx/__chrono/year_month_weekday.h b/third_party/libcxx/__chrono/year_month_weekday.h index 28de10c94..0c3dd494c 100644 --- a/third_party/libcxx/__chrono/year_month_weekday.h +++ b/third_party/libcxx/__chrono/year_month_weekday.h @@ -31,220 +31,252 @@ _LIBCPP_BEGIN_NAMESPACE_STD -namespace chrono -{ +namespace chrono { class year_month_weekday { - chrono::year __y_; - chrono::month __m_; - chrono::weekday_indexed __wdi_; + chrono::year __y_; + chrono::month __m_; + chrono::weekday_indexed __wdi_; + public: - year_month_weekday() = default; - _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday(const chrono::year& __yval, const chrono::month& __mval, - const chrono::weekday_indexed& __wdival) noexcept - : __y_{__yval}, __m_{__mval}, __wdi_{__wdival} {} - _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday(const sys_days& __sysd) noexcept - : year_month_weekday(__from_days(__sysd.time_since_epoch())) {} - _LIBCPP_HIDE_FROM_ABI inline explicit constexpr year_month_weekday(const local_days& __locd) noexcept - : year_month_weekday(__from_days(__locd.time_since_epoch())) {} - _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator+=(const months&) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator-=(const months&) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator+=(const years&) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator-=(const years&) noexcept; + year_month_weekday() = default; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday( + const chrono::year& __yval, const chrono::month& __mval, const chrono::weekday_indexed& __wdival) noexcept + : __y_{__yval}, __m_{__mval}, __wdi_{__wdival} {} + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday(const sys_days& __sysd) noexcept + : year_month_weekday(__from_days(__sysd.time_since_epoch())) {} + _LIBCPP_HIDE_FROM_ABI inline explicit constexpr year_month_weekday(const local_days& __locd) noexcept + : year_month_weekday(__from_days(__locd.time_since_epoch())) {} + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator+=(const months&) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator-=(const months&) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator+=(const years&) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday& operator-=(const years&) noexcept; - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday weekday() const noexcept { return __wdi_.weekday(); } - _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned index() const noexcept { return __wdi_.index(); } - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday weekday() const noexcept { return __wdi_.weekday(); } + _LIBCPP_HIDE_FROM_ABI inline constexpr unsigned index() const noexcept { return __wdi_.index(); } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_indexed weekday_indexed() const noexcept { return __wdi_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } - _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } - _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept - { - if (!__y_.ok() || !__m_.ok() || !__wdi_.ok()) return false; - if (__wdi_.index() <= 4) return true; - auto __nth_weekday_day = - __wdi_.weekday() - - chrono::weekday{static_cast(__y_ / __m_ / 1)} + - days{(__wdi_.index() - 1) * 7 + 1}; - return static_cast(__nth_weekday_day.count()) <= - static_cast((__y_ / __m_ / last).day()); - } + _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } + _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { + return local_days{__to_days()}; + } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { + if (!__y_.ok() || !__m_.ok() || !__wdi_.ok()) + return false; + if (__wdi_.index() <= 4) + return true; + auto __nth_weekday_day = + __wdi_.weekday() - chrono::weekday{static_cast(__y_ / __m_ / 1)} + days{(__wdi_.index() - 1) * 7 + 1}; + return static_cast(__nth_weekday_day.count()) <= static_cast((__y_ / __m_ / last).day()); + } - _LIBCPP_HIDE_FROM_ABI static constexpr year_month_weekday __from_days(days __d) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr days __to_days() const noexcept; + _LIBCPP_HIDE_FROM_ABI static constexpr year_month_weekday __from_days(days __d) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr days __to_days() const noexcept; }; -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday year_month_weekday::__from_days(days __d) noexcept -{ - const sys_days __sysd{__d}; - const chrono::weekday __wd = chrono::weekday(__sysd); - const year_month_day __ymd = year_month_day(__sysd); - return year_month_weekday{__ymd.year(), __ymd.month(), - __wd[(static_cast(__ymd.day())-1)/7+1]}; +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday year_month_weekday::__from_days(days __d) noexcept { + const sys_days __sysd{__d}; + const chrono::weekday __wd = chrono::weekday(__sysd); + const year_month_day __ymd = year_month_day(__sysd); + return year_month_weekday{__ymd.year(), __ymd.month(), __wd[(static_cast(__ymd.day()) - 1) / 7 + 1]}; } -_LIBCPP_HIDE_FROM_ABI inline constexpr -days year_month_weekday::__to_days() const noexcept -{ - const sys_days __sysd = sys_days(__y_/__m_/1); - return (__sysd + (__wdi_.weekday() - chrono::weekday(__sysd) + days{(__wdi_.index()-1)*7})) - .time_since_epoch(); +_LIBCPP_HIDE_FROM_ABI inline constexpr days year_month_weekday::__to_days() const noexcept { + const sys_days __sysd = sys_days(__y_ / __m_ / 1); + return (__sysd + (__wdi_.weekday() - chrono::weekday(__sysd) + days{(__wdi_.index() - 1) * 7})).time_since_epoch(); } -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator==(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept -{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_indexed() == __rhs.weekday_indexed(); } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool +operator==(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept { + return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && + __lhs.weekday_indexed() == __rhs.weekday_indexed(); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator!=(const year_month_weekday& __lhs, const year_month_weekday& __rhs) noexcept -{ return !(__lhs == __rhs); } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday +operator/(const year_month& __lhs, const weekday_indexed& __rhs) noexcept { + return year_month_weekday{__lhs.year(), __lhs.month(), __rhs}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday operator/(const year_month& __lhs, const weekday_indexed& __rhs) noexcept -{ return year_month_weekday{__lhs.year(), __lhs.month(), __rhs}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday +operator/(const year& __lhs, const month_weekday& __rhs) noexcept { + return year_month_weekday{__lhs, __rhs.month(), __rhs.weekday_indexed()}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday operator/(const year& __lhs, const month_weekday& __rhs) noexcept -{ return year_month_weekday{__lhs, __rhs.month(), __rhs.weekday_indexed()}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday operator/(int __lhs, const month_weekday& __rhs) noexcept { + return year(__lhs) / __rhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday operator/(int __lhs, const month_weekday& __rhs) noexcept -{ return year(__lhs) / __rhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday +operator/(const month_weekday& __lhs, const year& __rhs) noexcept { + return __rhs / __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday operator/(const month_weekday& __lhs, const year& __rhs) noexcept -{ return __rhs / __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday operator/(const month_weekday& __lhs, int __rhs) noexcept { + return year(__rhs) / __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday operator/(const month_weekday& __lhs, int __rhs) noexcept -{ return year(__rhs) / __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday +operator+(const year_month_weekday& __lhs, const months& __rhs) noexcept { + return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_indexed(); +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday +operator+(const months& __lhs, const year_month_weekday& __rhs) noexcept { + return __rhs + __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday operator+(const year_month_weekday& __lhs, const months& __rhs) noexcept -{ return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_indexed(); } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday +operator-(const year_month_weekday& __lhs, const months& __rhs) noexcept { + return __lhs + (-__rhs); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday operator+(const months& __lhs, const year_month_weekday& __rhs) noexcept -{ return __rhs + __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday +operator+(const year_month_weekday& __lhs, const years& __rhs) noexcept { + return year_month_weekday{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_indexed()}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday operator-(const year_month_weekday& __lhs, const months& __rhs) noexcept -{ return __lhs + (-__rhs); } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday +operator+(const years& __lhs, const year_month_weekday& __rhs) noexcept { + return __rhs + __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday operator+(const year_month_weekday& __lhs, const years& __rhs) noexcept -{ return year_month_weekday{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_indexed()}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday +operator-(const year_month_weekday& __lhs, const years& __rhs) noexcept { + return __lhs + (-__rhs); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday operator+(const years& __lhs, const year_month_weekday& __rhs) noexcept -{ return __rhs + __lhs; } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday operator-(const year_month_weekday& __lhs, const years& __rhs) noexcept -{ return __lhs + (-__rhs); } - - -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator+=(const months& __dm) noexcept { + *this = *this + __dm; + return *this; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator-=(const months& __dm) noexcept { + *this = *this - __dm; + return *this; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator+=(const years& __dy) noexcept { + *this = *this + __dy; + return *this; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday& year_month_weekday::operator-=(const years& __dy) noexcept { + *this = *this - __dy; + return *this; +} class year_month_weekday_last { private: - chrono::year __y_; - chrono::month __m_; - chrono::weekday_last __wdl_; + chrono::year __y_; + chrono::month __m_; + chrono::weekday_last __wdl_; + public: - _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last(const chrono::year& __yval, const chrono::month& __mval, - const chrono::weekday_last& __wdlval) noexcept - : __y_{__yval}, __m_{__mval}, __wdl_{__wdlval} {} - _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator+=(const months& __dm) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator-=(const months& __dm) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator+=(const years& __dy) noexcept; - _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator-=(const years& __dy) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last( + const chrono::year& __yval, const chrono::month& __mval, const chrono::weekday_last& __wdlval) noexcept + : __y_{__yval}, __m_{__mval}, __wdl_{__wdlval} {} + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator+=(const months& __dm) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator-=(const months& __dm) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator+=(const years& __dy) noexcept; + _LIBCPP_HIDE_FROM_ABI constexpr year_month_weekday_last& operator-=(const years& __dy) noexcept; - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday weekday() const noexcept { return __wdl_.weekday(); } - _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl_; } - _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } - _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { return local_days{__to_days()}; } - _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __y_.ok() && __m_.ok() && __wdl_.ok(); } - - _LIBCPP_HIDE_FROM_ABI constexpr days __to_days() const noexcept; + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday weekday() const noexcept { return __wdl_.weekday(); } + _LIBCPP_HIDE_FROM_ABI inline constexpr chrono::weekday_last weekday_last() const noexcept { return __wdl_; } + _LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; } + _LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept { + return local_days{__to_days()}; + } + _LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __y_.ok() && __m_.ok() && __wdl_.ok(); } + _LIBCPP_HIDE_FROM_ABI constexpr days __to_days() const noexcept; }; -_LIBCPP_HIDE_FROM_ABI inline constexpr -days year_month_weekday_last::__to_days() const noexcept -{ - const sys_days __last = sys_days{__y_/__m_/last}; - return (__last - (chrono::weekday{__last} - __wdl_.weekday())).time_since_epoch(); - +_LIBCPP_HIDE_FROM_ABI inline constexpr days year_month_weekday_last::__to_days() const noexcept { + const sys_days __last = sys_days{__y_ / __m_ / last}; + return (__last - (chrono::weekday{__last} - __wdl_.weekday())).time_since_epoch(); } -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator==(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept -{ return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); } +_LIBCPP_HIDE_FROM_ABI inline constexpr bool +operator==(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept { + return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.weekday_last() == __rhs.weekday_last(); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -bool operator!=(const year_month_weekday_last& __lhs, const year_month_weekday_last& __rhs) noexcept -{ return !(__lhs == __rhs); } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last +operator/(const year_month& __lhs, const weekday_last& __rhs) noexcept { + return year_month_weekday_last{__lhs.year(), __lhs.month(), __rhs}; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last +operator/(const year& __lhs, const month_weekday_last& __rhs) noexcept { + return year_month_weekday_last{__lhs, __rhs.month(), __rhs.weekday_last()}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday_last operator/(const year_month& __lhs, const weekday_last& __rhs) noexcept -{ return year_month_weekday_last{__lhs.year(), __lhs.month(), __rhs}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last +operator/(int __lhs, const month_weekday_last& __rhs) noexcept { + return year(__lhs) / __rhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday_last operator/(const year& __lhs, const month_weekday_last& __rhs) noexcept -{ return year_month_weekday_last{__lhs, __rhs.month(), __rhs.weekday_last()}; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last +operator/(const month_weekday_last& __lhs, const year& __rhs) noexcept { + return __rhs / __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday_last operator/(int __lhs, const month_weekday_last& __rhs) noexcept -{ return year(__lhs) / __rhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last +operator/(const month_weekday_last& __lhs, int __rhs) noexcept { + return year(__rhs) / __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday_last operator/(const month_weekday_last& __lhs, const year& __rhs) noexcept -{ return __rhs / __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last +operator+(const year_month_weekday_last& __lhs, const months& __rhs) noexcept { + return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_last(); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday_last operator/(const month_weekday_last& __lhs, int __rhs) noexcept -{ return year(__rhs) / __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last +operator+(const months& __lhs, const year_month_weekday_last& __rhs) noexcept { + return __rhs + __lhs; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last +operator-(const year_month_weekday_last& __lhs, const months& __rhs) noexcept { + return __lhs + (-__rhs); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday_last operator+(const year_month_weekday_last& __lhs, const months& __rhs) noexcept -{ return (__lhs.year() / __lhs.month() + __rhs) / __lhs.weekday_last(); } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last +operator+(const year_month_weekday_last& __lhs, const years& __rhs) noexcept { + return year_month_weekday_last{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_last()}; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday_last operator+(const months& __lhs, const year_month_weekday_last& __rhs) noexcept -{ return __rhs + __lhs; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last +operator+(const years& __lhs, const year_month_weekday_last& __rhs) noexcept { + return __rhs + __lhs; +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday_last operator-(const year_month_weekday_last& __lhs, const months& __rhs) noexcept -{ return __lhs + (-__rhs); } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last +operator-(const year_month_weekday_last& __lhs, const years& __rhs) noexcept { + return __lhs + (-__rhs); +} -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday_last operator+(const year_month_weekday_last& __lhs, const years& __rhs) noexcept -{ return year_month_weekday_last{__lhs.year() + __rhs, __lhs.month(), __lhs.weekday_last()}; } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday_last operator+(const years& __lhs, const year_month_weekday_last& __rhs) noexcept -{ return __rhs + __lhs; } - -_LIBCPP_HIDE_FROM_ABI inline constexpr -year_month_weekday_last operator-(const year_month_weekday_last& __lhs, const years& __rhs) noexcept -{ return __lhs + (-__rhs); } - -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const months& __dm) noexcept { *this = *this + __dm; return *this; } -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const months& __dm) noexcept { *this = *this - __dm; return *this; } -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const years& __dy) noexcept { *this = *this + __dy; return *this; } -_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const years& __dy) noexcept { *this = *this - __dy; return *this; } +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& +year_month_weekday_last::operator+=(const months& __dm) noexcept { + *this = *this + __dm; + return *this; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& +year_month_weekday_last::operator-=(const months& __dm) noexcept { + *this = *this - __dm; + return *this; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& +year_month_weekday_last::operator+=(const years& __dy) noexcept { + *this = *this + __dy; + return *this; +} +_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_weekday_last& +year_month_weekday_last::operator-=(const years& __dy) noexcept { + *this = *this - __dy; + return *this; +} } // namespace chrono diff --git a/third_party/libcxx/__chrono/zoned_time.h b/third_party/libcxx/__chrono/zoned_time.h new file mode 100644 index 000000000..8cfa21226 --- /dev/null +++ b/third_party/libcxx/__chrono/zoned_time.h @@ -0,0 +1,227 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html + +#ifndef _LIBCPP___CHRONO_ZONED_TIME_H +#define _LIBCPP___CHRONO_ZONED_TIME_H + +#include +// Enable the contents of the header only when libc++ was built with experimental features enabled. +#if !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) + +# include <__chrono/calendar.h> +# include <__chrono/duration.h> +# include <__chrono/sys_info.h> +# include <__chrono/system_clock.h> +# include <__chrono/time_zone.h> +# include <__chrono/tzdb_list.h> +# include <__config> +# include <__fwd/string_view.h> +# include <__type_traits/common_type.h> +# include <__type_traits/conditional.h> +# include <__type_traits/remove_cvref.h> +# include <__utility/move.h> + +# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +# endif + +_LIBCPP_PUSH_MACROS +# include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +# if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) && \ + !defined(_LIBCPP_HAS_NO_LOCALIZATION) + +namespace chrono { + +template +struct zoned_traits {}; + +template <> +struct zoned_traits { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static const time_zone* default_zone() { return chrono::locate_zone("UTC"); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static const time_zone* locate_zone(string_view __name) { + return chrono::locate_zone(__name); + } +}; + +template +class zoned_time { + // [time.zone.zonedtime.ctor]/2 + static_assert(__is_duration<_Duration>::value, + "the program is ill-formed since _Duration is not a specialization of std::chrono::duration"); + + // The wording uses the constraints like + // constructible_from + // Using these constraints in the code causes the compiler to give an + // error that the constraint depends on itself. To avoid that issue use + // the fact it is possible to create this object from a _TimeZonePtr. + using __traits = zoned_traits<_TimeZonePtr>; + +public: + using duration = common_type_t<_Duration, seconds>; + + _LIBCPP_HIDE_FROM_ABI zoned_time() + requires requires { __traits::default_zone(); } + : __zone_{__traits::default_zone()}, __tp_{} {} + + _LIBCPP_HIDE_FROM_ABI zoned_time(const zoned_time&) = default; + _LIBCPP_HIDE_FROM_ABI zoned_time& operator=(const zoned_time&) = default; + + _LIBCPP_HIDE_FROM_ABI zoned_time(const sys_time<_Duration>& __tp) + requires requires { __traits::default_zone(); } + : __zone_{__traits::default_zone()}, __tp_{__tp} {} + + _LIBCPP_HIDE_FROM_ABI explicit zoned_time(_TimeZonePtr __zone) : __zone_{std::move(__zone)}, __tp_{} {} + + _LIBCPP_HIDE_FROM_ABI explicit zoned_time(string_view __name) + requires(requires { __traits::locate_zone(string_view{}); } && + constructible_from<_TimeZonePtr, decltype(__traits::locate_zone(string_view{}))>) + : __zone_{__traits::locate_zone(__name)}, __tp_{} {} + + template + _LIBCPP_HIDE_FROM_ABI zoned_time(const zoned_time<_Duration2, _TimeZonePtr>& __zt) + requires is_convertible_v, sys_time<_Duration>> + : __zone_{__zt.get_time_zone()}, __tp_{__zt.get_sys_time()} {} + + _LIBCPP_HIDE_FROM_ABI zoned_time(_TimeZonePtr __zone, const sys_time<_Duration>& __tp) + : __zone_{std::move(__zone)}, __tp_{__tp} {} + + _LIBCPP_HIDE_FROM_ABI zoned_time(string_view __name, const sys_time<_Duration>& __tp) + requires requires { _TimeZonePtr{__traits::locate_zone(string_view{})}; } + : zoned_time{__traits::locate_zone(__name), __tp} {} + + _LIBCPP_HIDE_FROM_ABI zoned_time(_TimeZonePtr __zone, const local_time<_Duration>& __tp) + requires(is_convertible_v() -> to_sys(local_time<_Duration>{})), + sys_time>) + : __zone_{std::move(__zone)}, __tp_{__zone_->to_sys(__tp)} {} + + _LIBCPP_HIDE_FROM_ABI zoned_time(string_view __name, const local_time<_Duration>& __tp) + requires(requires { + _TimeZonePtr{__traits::locate_zone(string_view{})}; + } && is_convertible_v() -> to_sys(local_time<_Duration>{})), + sys_time>) + : zoned_time{__traits::locate_zone(__name), __tp} {} + + _LIBCPP_HIDE_FROM_ABI zoned_time(_TimeZonePtr __zone, const local_time<_Duration>& __tp, choose __c) + requires(is_convertible_v< + decltype(std::declval<_TimeZonePtr&>() -> to_sys(local_time<_Duration>{}, choose::earliest)), + sys_time>) + : __zone_{std::move(__zone)}, __tp_{__zone_->to_sys(__tp, __c)} {} + + _LIBCPP_HIDE_FROM_ABI zoned_time(string_view __name, const local_time<_Duration>& __tp, choose __c) + requires(requires { + _TimeZonePtr{__traits::locate_zone(string_view{})}; + } && is_convertible_v() -> to_sys(local_time<_Duration>{}, choose::earliest)), + sys_time>) + : zoned_time{__traits::locate_zone(__name), __tp, __c} {} + + template + _LIBCPP_HIDE_FROM_ABI zoned_time(_TimeZonePtr __zone, const zoned_time<_Duration2, _TimeZonePtr2>& __zt) + requires is_convertible_v, sys_time<_Duration>> + : __zone_{std::move(__zone)}, __tp_{__zt.get_sys_time()} {} + + // per wording choose has no effect + template + _LIBCPP_HIDE_FROM_ABI zoned_time(_TimeZonePtr __zone, const zoned_time<_Duration2, _TimeZonePtr2>& __zt, choose) + requires is_convertible_v, sys_time<_Duration>> + : __zone_{std::move(__zone)}, __tp_{__zt.get_sys_time()} {} + + template + _LIBCPP_HIDE_FROM_ABI zoned_time(string_view __name, const zoned_time<_Duration2, _TimeZonePtr2>& __zt) + requires(requires { + _TimeZonePtr{__traits::locate_zone(string_view{})}; + } && is_convertible_v, sys_time<_Duration>>) + : zoned_time{__traits::locate_zone(__name), __zt} {} + + template + _LIBCPP_HIDE_FROM_ABI zoned_time(string_view __name, const zoned_time<_Duration2, _TimeZonePtr2>& __zt, choose __c) + requires(requires { + _TimeZonePtr{__traits::locate_zone(string_view{})}; + } && is_convertible_v, sys_time<_Duration>>) + : zoned_time{__traits::locate_zone(__name), __zt, __c} {} + + _LIBCPP_HIDE_FROM_ABI zoned_time& operator=(const sys_time<_Duration>& __tp) { + __tp_ = __tp; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI zoned_time& operator=(const local_time<_Duration>& __tp) { + // TODO TZDB This seems wrong. + // Assigning a non-existent or ambiguous time will throw and not satisfy + // the post condition. This seems quite odd; I constructed an object with + // choose::earliest and that choice is not respected. + // what did LEWG do with this. + // MSVC STL and libstdc++ behave the same + __tp_ = __zone_->to_sys(__tp); + return *this; + } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI operator sys_time() const { return get_sys_time(); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit operator local_time() const { return get_local_time(); } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI _TimeZonePtr get_time_zone() const { return __zone_; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI local_time get_local_time() const { return __zone_->to_local(__tp_); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI sys_time get_sys_time() const { return __tp_; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI sys_info get_info() const { return __zone_->get_info(__tp_); } + +private: + _TimeZonePtr __zone_; + sys_time __tp_; +}; + +zoned_time() -> zoned_time; + +template +zoned_time(sys_time<_Duration>) -> zoned_time>; + +template +using __time_zone_representation = + conditional_t, + const time_zone*, + remove_cvref_t<_TimeZonePtrOrName>>; + +template +zoned_time(_TimeZonePtrOrName&&) -> zoned_time>; + +template +zoned_time(_TimeZonePtrOrName&&, sys_time<_Duration>) + -> zoned_time, __time_zone_representation<_TimeZonePtrOrName>>; + +template +zoned_time(_TimeZonePtrOrName&&, local_time<_Duration>, choose = choose::earliest) + -> zoned_time, __time_zone_representation<_TimeZonePtrOrName>>; + +template +zoned_time(_TimeZonePtrOrName&&, zoned_time<_Duration, TimeZonePtr2>, choose = choose::earliest) + -> zoned_time, __time_zone_representation<_TimeZonePtrOrName>>; + +using zoned_seconds = zoned_time; + +template +_LIBCPP_HIDE_FROM_ABI bool +operator==(const zoned_time<_Duration1, _TimeZonePtr>& __lhs, const zoned_time<_Duration2, _TimeZonePtr>& __rhs) { + return __lhs.get_time_zone() == __rhs.get_time_zone() && __lhs.get_sys_time() == __rhs.get_sys_time(); +} + +} // namespace chrono + +# endif // _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_TIME_ZONE_DATABASE) && !defined(_LIBCPP_HAS_NO_FILESYSTEM) + // && !defined(_LIBCPP_HAS_NO_LOCALIZATION) + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) + +#endif // _LIBCPP___CHRONO_ZONED_TIME_H diff --git a/third_party/libcxx/__compare/common_comparison_category.h b/third_party/libcxx/__compare/common_comparison_category.h index 5fad99bf5..7aeb3da03 100644 --- a/third_party/libcxx/__compare/common_comparison_category.h +++ b/third_party/libcxx/__compare/common_comparison_category.h @@ -24,17 +24,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace __comp_detail { -enum _ClassifyCompCategory : unsigned { - _None, - _PartialOrd, - _WeakOrd, - _StrongOrd, - _CCC_Size -}; +enum _ClassifyCompCategory : unsigned { _None, _PartialOrd, _WeakOrd, _StrongOrd, _CCC_Size }; template -_LIBCPP_HIDE_FROM_ABI -constexpr _ClassifyCompCategory __type_to_enum() noexcept { +_LIBCPP_HIDE_FROM_ABI constexpr _ClassifyCompCategory __type_to_enum() noexcept { if (is_same_v<_Tp, partial_ordering>) return _PartialOrd; if (is_same_v<_Tp, weak_ordering>) @@ -45,8 +38,7 @@ constexpr _ClassifyCompCategory __type_to_enum() noexcept { } template -_LIBCPP_HIDE_FROM_ABI -constexpr _ClassifyCompCategory +_LIBCPP_HIDE_FROM_ABI constexpr _ClassifyCompCategory __compute_comp_type(const _ClassifyCompCategory (&__types)[_Size]) { int __seen[_CCC_Size] = {}; for (auto __type : __types) @@ -60,12 +52,11 @@ __compute_comp_type(const _ClassifyCompCategory (&__types)[_Size]) { return _StrongOrd; } -template -_LIBCPP_HIDE_FROM_ABI -constexpr auto __get_comp_type() { - using _CCC = _ClassifyCompCategory; +template +_LIBCPP_HIDE_FROM_ABI constexpr auto __get_comp_type() { + using _CCC = _ClassifyCompCategory; constexpr _CCC __type_kinds[] = {_StrongOrd, __type_to_enum<_Ts>()...}; - constexpr _CCC __cat = __comp_detail::__compute_comp_type(__type_kinds); + constexpr _CCC __cat = __comp_detail::__compute_comp_type(__type_kinds); if constexpr (__cat == _None) return void(); else if constexpr (__cat == _PartialOrd) @@ -80,12 +71,12 @@ constexpr auto __get_comp_type() { } // namespace __comp_detail // [cmp.common], common comparison category type -template +template struct _LIBCPP_TEMPLATE_VIS common_comparison_category { using type = decltype(__comp_detail::__get_comp_type<_Ts...>()); }; -template +template using common_comparison_category_t = typename common_comparison_category<_Ts...>::type; #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__compare/compare_partial_order_fallback.h b/third_party/libcxx/__compare/compare_partial_order_fallback.h index fb2921ed5..e0efa3ccb 100644 --- a/third_party/libcxx/__compare/compare_partial_order_fallback.h +++ b/third_party/libcxx/__compare/compare_partial_order_fallback.h @@ -27,44 +27,46 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [cmp.alg] namespace __compare_partial_order_fallback { - struct __fn { - template - requires is_same_v, decay_t<_Up>> - _LIBCPP_HIDE_FROM_ABI static constexpr auto - __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) - noexcept(noexcept(_VSTD::partial_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) - -> decltype( _VSTD::partial_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))) - { return _VSTD::partial_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); } +struct __fn { + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) noexcept( + noexcept(std::partial_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) + -> decltype(std::partial_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))) { + return std::partial_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)); + } - template - requires is_same_v, decay_t<_Up>> - _LIBCPP_HIDE_FROM_ABI static constexpr auto - __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) - noexcept(noexcept(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? partial_ordering::equivalent : - _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? partial_ordering::less : - _VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t) ? partial_ordering::greater : - partial_ordering::unordered)) - -> decltype( _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? partial_ordering::equivalent : - _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? partial_ordering::less : - _VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t) ? partial_ordering::greater : - partial_ordering::unordered) - { - return _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? partial_ordering::equivalent : - _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? partial_ordering::less : - _VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t) ? partial_ordering::greater : - partial_ordering::unordered; - } + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) noexcept(noexcept( + std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? partial_ordering::equivalent + : std::forward<_Tp>(__t) < std::forward<_Up>(__u) ? partial_ordering::less + : std::forward<_Up>(__u) < std::forward<_Tp>(__t) + ? partial_ordering::greater + : partial_ordering::unordered)) + -> decltype(std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? partial_ordering::equivalent + : std::forward<_Tp>(__t) < std::forward<_Up>(__u) ? partial_ordering::less + : std::forward<_Up>(__u) < std::forward<_Tp>(__t) + ? partial_ordering::greater + : partial_ordering::unordered) { + return std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? partial_ordering::equivalent + : std::forward<_Tp>(__t) < std::forward<_Up>(__u) ? partial_ordering::less + : std::forward<_Up>(__u) < std::forward<_Tp>(__t) + ? partial_ordering::greater + : partial_ordering::unordered; + } - template - _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const - noexcept(noexcept(__go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>()))) - -> decltype( __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>())) - { return __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>()); } - }; + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<1>()))) + -> decltype(__go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<1>())) { + return __go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<1>()); + } +}; } // namespace __compare_partial_order_fallback inline namespace __cpo { - inline constexpr auto compare_partial_order_fallback = __compare_partial_order_fallback::__fn{}; +inline constexpr auto compare_partial_order_fallback = __compare_partial_order_fallback::__fn{}; } // namespace __cpo #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__compare/compare_strong_order_fallback.h b/third_party/libcxx/__compare/compare_strong_order_fallback.h index d84d065e4..a94d517ed 100644 --- a/third_party/libcxx/__compare/compare_strong_order_fallback.h +++ b/third_party/libcxx/__compare/compare_strong_order_fallback.h @@ -27,41 +27,43 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [cmp.alg] namespace __compare_strong_order_fallback { - struct __fn { - template - requires is_same_v, decay_t<_Up>> - _LIBCPP_HIDE_FROM_ABI static constexpr auto - __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) - noexcept(noexcept(_VSTD::strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) - -> decltype( _VSTD::strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))) - { return _VSTD::strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); } +struct __fn { + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) noexcept( + noexcept(std::strong_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) + -> decltype(std::strong_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))) { + return std::strong_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)); + } - template - requires is_same_v, decay_t<_Up>> - _LIBCPP_HIDE_FROM_ABI static constexpr auto - __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) - noexcept(noexcept(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? strong_ordering::equal : - _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? strong_ordering::less : - strong_ordering::greater)) - -> decltype( _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? strong_ordering::equal : - _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? strong_ordering::less : - strong_ordering::greater) - { - return _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? strong_ordering::equal : - _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? strong_ordering::less : - strong_ordering::greater; - } + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) noexcept(noexcept( + std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? strong_ordering::equal + : std::forward<_Tp>(__t) < std::forward<_Up>(__u) + ? strong_ordering::less + : strong_ordering::greater)) + -> decltype(std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? strong_ordering::equal + : std::forward<_Tp>(__t) < std::forward<_Up>(__u) + ? strong_ordering::less + : strong_ordering::greater) { + return std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? strong_ordering::equal + : std::forward<_Tp>(__t) < std::forward<_Up>(__u) + ? strong_ordering::less + : strong_ordering::greater; + } - template - _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const - noexcept(noexcept(__go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>()))) - -> decltype( __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>())) - { return __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>()); } - }; + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<1>()))) + -> decltype(__go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<1>())) { + return __go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<1>()); + } +}; } // namespace __compare_strong_order_fallback inline namespace __cpo { - inline constexpr auto compare_strong_order_fallback = __compare_strong_order_fallback::__fn{}; +inline constexpr auto compare_strong_order_fallback = __compare_strong_order_fallback::__fn{}; } // namespace __cpo #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__compare/compare_three_way.h b/third_party/libcxx/__compare/compare_three_way.h index 2bc63a00e..01c12076c 100644 --- a/third_party/libcxx/__compare/compare_three_way.h +++ b/third_party/libcxx/__compare/compare_three_way.h @@ -22,16 +22,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 -struct _LIBCPP_TEMPLATE_VIS compare_three_way -{ - template - requires three_way_comparable_with<_T1, _T2> - constexpr _LIBCPP_HIDE_FROM_ABI - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(_VSTD::forward<_T1>(__t) <=> _VSTD::forward<_T2>(__u))) - { return _VSTD::forward<_T1>(__t) <=> _VSTD::forward<_T2>(__u); } +struct _LIBCPP_TEMPLATE_VIS compare_three_way { + template + requires three_way_comparable_with<_T1, _T2> + constexpr _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) <=> std::forward<_T2>(__u))) { + return std::forward<_T1>(__t) <=> std::forward<_T2>(__u); + } - using is_transparent = void; + using is_transparent = void; }; #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__compare/compare_three_way_result.h b/third_party/libcxx/__compare/compare_three_way_result.h index 632ebdce1..d75080734 100644 --- a/third_party/libcxx/__compare/compare_three_way_result.h +++ b/third_party/libcxx/__compare/compare_three_way_result.h @@ -21,20 +21,21 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 -template -struct _LIBCPP_HIDE_FROM_ABI __compare_three_way_result { }; +template +struct _LIBCPP_HIDE_FROM_ABI __compare_three_way_result {}; -template -struct _LIBCPP_HIDE_FROM_ABI __compare_three_way_result<_Tp, _Up, decltype( - std::declval<__make_const_lvalue_ref<_Tp>>() <=> std::declval<__make_const_lvalue_ref<_Up>>(), void() -)> { - using type = decltype(std::declval<__make_const_lvalue_ref<_Tp>>() <=> std::declval<__make_const_lvalue_ref<_Up>>()); +template +struct _LIBCPP_HIDE_FROM_ABI __compare_three_way_result< + _Tp, + _Up, + decltype(std::declval<__make_const_lvalue_ref<_Tp>>() <=> std::declval<__make_const_lvalue_ref<_Up>>(), void())> { + using type = decltype(std::declval<__make_const_lvalue_ref<_Tp>>() <=> std::declval<__make_const_lvalue_ref<_Up>>()); }; -template -struct _LIBCPP_TEMPLATE_VIS compare_three_way_result : __compare_three_way_result<_Tp, _Up, void> { }; +template +struct _LIBCPP_TEMPLATE_VIS compare_three_way_result : __compare_three_way_result<_Tp, _Up, void> {}; -template +template using compare_three_way_result_t = typename compare_three_way_result<_Tp, _Up>::type; #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__compare/compare_weak_order_fallback.h b/third_party/libcxx/__compare/compare_weak_order_fallback.h index d3ba04a86..062b7b582 100644 --- a/third_party/libcxx/__compare/compare_weak_order_fallback.h +++ b/third_party/libcxx/__compare/compare_weak_order_fallback.h @@ -27,41 +27,43 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [cmp.alg] namespace __compare_weak_order_fallback { - struct __fn { - template - requires is_same_v, decay_t<_Up>> - _LIBCPP_HIDE_FROM_ABI static constexpr auto - __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) - noexcept(noexcept(_VSTD::weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) - -> decltype( _VSTD::weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))) - { return _VSTD::weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); } +struct __fn { + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) noexcept( + noexcept(std::weak_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) + -> decltype(std::weak_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))) { + return std::weak_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)); + } - template - requires is_same_v, decay_t<_Up>> - _LIBCPP_HIDE_FROM_ABI static constexpr auto - __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) - noexcept(noexcept(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? weak_ordering::equivalent : - _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? weak_ordering::less : - weak_ordering::greater)) - -> decltype( _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? weak_ordering::equivalent : - _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? weak_ordering::less : - weak_ordering::greater) - { - return _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u) ? weak_ordering::equivalent : - _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u) ? weak_ordering::less : - weak_ordering::greater; - } + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) noexcept(noexcept( + std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? weak_ordering::equivalent + : std::forward<_Tp>(__t) < std::forward<_Up>(__u) + ? weak_ordering::less + : weak_ordering::greater)) + -> decltype(std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? weak_ordering::equivalent + : std::forward<_Tp>(__t) < std::forward<_Up>(__u) + ? weak_ordering::less + : weak_ordering::greater) { + return std::forward<_Tp>(__t) == std::forward<_Up>(__u) ? weak_ordering::equivalent + : std::forward<_Tp>(__t) < std::forward<_Up>(__u) + ? weak_ordering::less + : weak_ordering::greater; + } - template - _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const - noexcept(noexcept(__go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>()))) - -> decltype( __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>())) - { return __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<1>()); } - }; + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<1>()))) + -> decltype(__go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<1>())) { + return __go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<1>()); + } +}; } // namespace __compare_weak_order_fallback inline namespace __cpo { - inline constexpr auto compare_weak_order_fallback = __compare_weak_order_fallback::__fn{}; +inline constexpr auto compare_weak_order_fallback = __compare_weak_order_fallback::__fn{}; } // namespace __cpo #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__compare/ordering.h b/third_party/libcxx/__compare/ordering.h index c348f0433..2995d3813 100644 --- a/third_party/libcxx/__compare/ordering.h +++ b/third_party/libcxx/__compare/ordering.h @@ -22,46 +22,35 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 // exposition only -enum class _LIBCPP_ENUM_VIS _OrdResult : signed char { - __less = -1, - __equiv = 0, - __greater = 1 -}; +enum class _OrdResult : signed char { __less = -1, __equiv = 0, __greater = 1 }; -enum class _LIBCPP_ENUM_VIS _NCmpResult : signed char { - __unordered = -127 -}; +enum class _NCmpResult : signed char { __unordered = -127 }; class partial_ordering; class weak_ordering; class strong_ordering; -template +template inline constexpr bool __one_of_v = (is_same_v<_Tp, _Args> || ...); struct _CmpUnspecifiedParam { - _LIBCPP_HIDE_FROM_ABI constexpr - _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {} + _LIBCPP_HIDE_FROM_ABI constexpr _CmpUnspecifiedParam(int _CmpUnspecifiedParam::*) noexcept {} - template>> + template >> _CmpUnspecifiedParam(_Tp) = delete; }; class partial_ordering { using _ValueT = signed char; - _LIBCPP_HIDE_FROM_ABI - explicit constexpr partial_ordering(_OrdResult __v) noexcept - : __value_(_ValueT(__v)) {} + _LIBCPP_HIDE_FROM_ABI explicit constexpr partial_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} - _LIBCPP_HIDE_FROM_ABI - explicit constexpr partial_ordering(_NCmpResult __v) noexcept - : __value_(_ValueT(__v)) {} + _LIBCPP_HIDE_FROM_ABI explicit constexpr partial_ordering(_NCmpResult __v) noexcept : __value_(_ValueT(__v)) {} - _LIBCPP_HIDE_FROM_ABI - constexpr bool __is_ordered() const noexcept { + _LIBCPP_HIDE_FROM_ABI constexpr bool __is_ordered() const noexcept { return __value_ != _ValueT(_NCmpResult::__unordered); } + public: // valid values static const partial_ordering less; @@ -70,63 +59,54 @@ public: static const partial_ordering unordered; // comparisons - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(partial_ordering, partial_ordering) noexcept = default; + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(partial_ordering, partial_ordering) noexcept = default; - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(partial_ordering __v, _CmpUnspecifiedParam) noexcept { return __v.__is_ordered() && __v.__value_ == 0; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator< (partial_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(partial_ordering __v, _CmpUnspecifiedParam) noexcept { return __v.__is_ordered() && __v.__value_ < 0; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { return __v.__is_ordered() && __v.__value_ <= 0; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator> (partial_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(partial_ordering __v, _CmpUnspecifiedParam) noexcept { return __v.__is_ordered() && __v.__value_ > 0; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(partial_ordering __v, _CmpUnspecifiedParam) noexcept { return __v.__is_ordered() && __v.__value_ >= 0; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator< (_CmpUnspecifiedParam, partial_ordering __v) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(_CmpUnspecifiedParam, partial_ordering __v) noexcept { return __v.__is_ordered() && 0 < __v.__value_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { return __v.__is_ordered() && 0 <= __v.__value_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator> (_CmpUnspecifiedParam, partial_ordering __v) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(_CmpUnspecifiedParam, partial_ordering __v) noexcept { return __v.__is_ordered() && 0 > __v.__value_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(_CmpUnspecifiedParam, partial_ordering __v) noexcept { return __v.__is_ordered() && 0 >= __v.__value_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr partial_ordering operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr partial_ordering + operator<=>(partial_ordering __v, _CmpUnspecifiedParam) noexcept { return __v; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr partial_ordering operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr partial_ordering + operator<=>(_CmpUnspecifiedParam, partial_ordering __v) noexcept { return __v < 0 ? partial_ordering::greater : (__v > 0 ? partial_ordering::less : __v); } + private: _ValueT __value_; }; @@ -139,76 +119,62 @@ inline constexpr partial_ordering partial_ordering::unordered(_NCmpResult ::__un class weak_ordering { using _ValueT = signed char; - _LIBCPP_HIDE_FROM_ABI - explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} + _LIBCPP_HIDE_FROM_ABI explicit constexpr weak_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} public: static const weak_ordering less; static const weak_ordering equivalent; static const weak_ordering greater; - _LIBCPP_HIDE_FROM_ABI - constexpr operator partial_ordering() const noexcept { + _LIBCPP_HIDE_FROM_ABI constexpr operator partial_ordering() const noexcept { return __value_ == 0 ? partial_ordering::equivalent - : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); + : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); } // comparisons - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(weak_ordering, weak_ordering) noexcept = default; + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(weak_ordering, weak_ordering) noexcept = default; - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(weak_ordering __v, _CmpUnspecifiedParam) noexcept { return __v.__value_ == 0; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator< (weak_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(weak_ordering __v, _CmpUnspecifiedParam) noexcept { return __v.__value_ < 0; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { return __v.__value_ <= 0; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator> (weak_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(weak_ordering __v, _CmpUnspecifiedParam) noexcept { return __v.__value_ > 0; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(weak_ordering __v, _CmpUnspecifiedParam) noexcept { return __v.__value_ >= 0; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator< (_CmpUnspecifiedParam, weak_ordering __v) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(_CmpUnspecifiedParam, weak_ordering __v) noexcept { return 0 < __v.__value_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { return 0 <= __v.__value_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator> (_CmpUnspecifiedParam, weak_ordering __v) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(_CmpUnspecifiedParam, weak_ordering __v) noexcept { return 0 > __v.__value_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(_CmpUnspecifiedParam, weak_ordering __v) noexcept { return 0 >= __v.__value_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr weak_ordering operator<=>(weak_ordering __v, _CmpUnspecifiedParam) noexcept { return __v; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr weak_ordering operator<=>(_CmpUnspecifiedParam, weak_ordering __v) noexcept { return __v < 0 ? weak_ordering::greater : (__v > 0 ? weak_ordering::less : __v); } @@ -223,8 +189,7 @@ inline constexpr weak_ordering weak_ordering::greater(_OrdResult::__greater); class strong_ordering { using _ValueT = signed char; - _LIBCPP_HIDE_FROM_ABI - explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} + _LIBCPP_HIDE_FROM_ABI explicit constexpr strong_ordering(_OrdResult __v) noexcept : __value_(_ValueT(__v)) {} public: static const strong_ordering less; @@ -233,74 +198,61 @@ public: static const strong_ordering greater; // conversions - _LIBCPP_HIDE_FROM_ABI - constexpr operator partial_ordering() const noexcept { + _LIBCPP_HIDE_FROM_ABI constexpr operator partial_ordering() const noexcept { return __value_ == 0 ? partial_ordering::equivalent - : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); + : (__value_ < 0 ? partial_ordering::less : partial_ordering::greater); } - _LIBCPP_HIDE_FROM_ABI - constexpr operator weak_ordering() const noexcept { - return __value_ == 0 ? weak_ordering::equivalent - : (__value_ < 0 ? weak_ordering::less : weak_ordering::greater); + _LIBCPP_HIDE_FROM_ABI constexpr operator weak_ordering() const noexcept { + return __value_ == 0 ? weak_ordering::equivalent : (__value_ < 0 ? weak_ordering::less : weak_ordering::greater); } // comparisons - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(strong_ordering, strong_ordering) noexcept = default; + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(strong_ordering, strong_ordering) noexcept = default; - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(strong_ordering __v, _CmpUnspecifiedParam) noexcept { return __v.__value_ == 0; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator< (strong_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(strong_ordering __v, _CmpUnspecifiedParam) noexcept { return __v.__value_ < 0; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { return __v.__value_ <= 0; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator> (strong_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(strong_ordering __v, _CmpUnspecifiedParam) noexcept { return __v.__value_ > 0; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(strong_ordering __v, _CmpUnspecifiedParam) noexcept { return __v.__value_ >= 0; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator< (_CmpUnspecifiedParam, strong_ordering __v) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(_CmpUnspecifiedParam, strong_ordering __v) noexcept { return 0 < __v.__value_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { return 0 <= __v.__value_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator> (_CmpUnspecifiedParam, strong_ordering __v) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(_CmpUnspecifiedParam, strong_ordering __v) noexcept { return 0 > __v.__value_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(_CmpUnspecifiedParam, strong_ordering __v) noexcept { return 0 >= __v.__value_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr strong_ordering operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr strong_ordering + operator<=>(strong_ordering __v, _CmpUnspecifiedParam) noexcept { return __v; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr strong_ordering operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept { + _LIBCPP_HIDE_FROM_ABI friend constexpr strong_ordering + operator<=>(_CmpUnspecifiedParam, strong_ordering __v) noexcept { return __v < 0 ? strong_ordering::greater : (__v > 0 ? strong_ordering::less : __v); } diff --git a/third_party/libcxx/__compare/partial_order.h b/third_party/libcxx/__compare/partial_order.h index 9cb76cc5b..1d2fae63e 100644 --- a/third_party/libcxx/__compare/partial_order.h +++ b/third_party/libcxx/__compare/partial_order.h @@ -28,43 +28,46 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [cmp.alg] namespace __partial_order { - struct __fn { - // NOLINTBEGIN(libcpp-robust-against-adl) partial_order should use ADL, but only here - template - requires is_same_v, decay_t<_Up>> - _LIBCPP_HIDE_FROM_ABI static constexpr auto - __go(_Tp&& __t, _Up&& __u, __priority_tag<2>) - noexcept(noexcept(partial_ordering(partial_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) - -> decltype( partial_ordering(partial_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) - { return partial_ordering(partial_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } - // NOLINTEND(libcpp-robust-against-adl) +void partial_order() = delete; - template - requires is_same_v, decay_t<_Up>> - _LIBCPP_HIDE_FROM_ABI static constexpr auto - __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) - noexcept(noexcept(partial_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) - -> decltype( partial_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) - { return partial_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } +struct __fn { + // NOLINTBEGIN(libcpp-robust-against-adl) partial_order should use ADL, but only here + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_Tp&& __t, _Up&& __u, __priority_tag<2>) noexcept( + noexcept(partial_ordering(partial_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))))) + -> decltype(partial_ordering(partial_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) { + return partial_ordering(partial_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))); + } + // NOLINTEND(libcpp-robust-against-adl) - template - requires is_same_v, decay_t<_Up>> - _LIBCPP_HIDE_FROM_ABI static constexpr auto - __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) - noexcept(noexcept(partial_ordering(_VSTD::weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) - -> decltype( partial_ordering(_VSTD::weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) - { return partial_ordering(_VSTD::weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) noexcept( + noexcept(partial_ordering(compare_three_way()(std::forward<_Tp>(__t), std::forward<_Up>(__u))))) + -> decltype(partial_ordering(compare_three_way()(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) { + return partial_ordering(compare_three_way()(std::forward<_Tp>(__t), std::forward<_Up>(__u))); + } - template - _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const - noexcept(noexcept(__go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<2>()))) - -> decltype( __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<2>())) - { return __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<2>()); } - }; + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) noexcept( + noexcept(partial_ordering(std::weak_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))))) + -> decltype(partial_ordering(std::weak_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) { + return partial_ordering(std::weak_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))); + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<2>()))) + -> decltype(__go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<2>())) { + return __go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<2>()); + } +}; } // namespace __partial_order inline namespace __cpo { - inline constexpr auto partial_order = __partial_order::__fn{}; +inline constexpr auto partial_order = __partial_order::__fn{}; } // namespace __cpo #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__compare/strong_order.h b/third_party/libcxx/__compare/strong_order.h index b6e0cfaaa..8c363b563 100644 --- a/third_party/libcxx/__compare/strong_order.h +++ b/third_party/libcxx/__compare/strong_order.h @@ -13,11 +13,14 @@ #include <__compare/compare_three_way.h> #include <__compare/ordering.h> #include <__config> +#include <__math/exponential_functions.h> +#include <__math/traits.h> #include <__type_traits/conditional.h> #include <__type_traits/decay.h> +#include <__type_traits/is_floating_point.h> +#include <__type_traits/is_same.h> #include <__utility/forward.h> #include <__utility/priority_tag.h> -#include #include #include @@ -34,100 +37,101 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [cmp.alg] namespace __strong_order { - struct __fn { - // NOLINTBEGIN(libcpp-robust-against-adl) strong_order should use ADL, but only here - template - requires is_same_v, decay_t<_Up>> - _LIBCPP_HIDE_FROM_ABI static constexpr auto - __go(_Tp&& __t, _Up&& __u, __priority_tag<2>) - noexcept(noexcept(strong_ordering(strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) - -> decltype( strong_ordering(strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) - { return strong_ordering(strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } - // NOLINTEND(libcpp-robust-against-adl) +void strong_order() = delete; - template> - requires is_same_v<_Dp, decay_t<_Up>> && is_floating_point_v<_Dp> - _LIBCPP_HIDE_FROM_ABI static constexpr strong_ordering - __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) noexcept - { - if constexpr (numeric_limits<_Dp>::is_iec559 && sizeof(_Dp) == sizeof(int32_t)) { - int32_t __rx = _VSTD::bit_cast(__t); - int32_t __ry = _VSTD::bit_cast(__u); - __rx = (__rx < 0) ? (numeric_limits::min() - __rx - 1) : __rx; - __ry = (__ry < 0) ? (numeric_limits::min() - __ry - 1) : __ry; - return (__rx <=> __ry); - } else if constexpr (numeric_limits<_Dp>::is_iec559 && sizeof(_Dp) == sizeof(int64_t)) { - int64_t __rx = _VSTD::bit_cast(__t); - int64_t __ry = _VSTD::bit_cast(__u); - __rx = (__rx < 0) ? (numeric_limits::min() - __rx - 1) : __rx; - __ry = (__ry < 0) ? (numeric_limits::min() - __ry - 1) : __ry; - return (__rx <=> __ry); - } else if (__t < __u) { - return strong_ordering::less; - } else if (__t > __u) { - return strong_ordering::greater; - } else if (__t == __u) { - if constexpr (numeric_limits<_Dp>::radix == 2) { - return _VSTD::signbit(__u) <=> _VSTD::signbit(__t); - } else { - // This is bullet 3 of the IEEE754 algorithm, relevant - // only for decimal floating-point; - // see https://stackoverflow.com/questions/69068075/ - if (__t == 0 || _VSTD::isinf(__t)) { - return _VSTD::signbit(__u) <=> _VSTD::signbit(__t); - } else { - int __texp, __uexp; - (void)_VSTD::frexp(__t, &__texp); - (void)_VSTD::frexp(__u, &__uexp); - return (__t < 0) ? (__texp <=> __uexp) : (__uexp <=> __texp); - } - } - } else { - // They're unordered, so one of them must be a NAN. - // The order is -QNAN, -SNAN, numbers, +SNAN, +QNAN. - bool __t_is_nan = _VSTD::isnan(__t); - bool __u_is_nan = _VSTD::isnan(__u); - bool __t_is_negative = _VSTD::signbit(__t); - bool __u_is_negative = _VSTD::signbit(__u); - using _IntType = conditional_t< - sizeof(__t) == sizeof(int32_t), int32_t, conditional_t< - sizeof(__t) == sizeof(int64_t), int64_t, void> - >; - if constexpr (is_same_v<_IntType, void>) { - static_assert(sizeof(_Dp) == 0, "std::strong_order is unimplemented for this floating-point type"); - } else if (__t_is_nan && __u_is_nan) { - // Order by sign bit, then by "payload bits" (we'll just use bit_cast). - if (__t_is_negative != __u_is_negative) { - return (__u_is_negative <=> __t_is_negative); - } else { - return _VSTD::bit_cast<_IntType>(__t) <=> _VSTD::bit_cast<_IntType>(__u); - } - } else if (__t_is_nan) { - return __t_is_negative ? strong_ordering::less : strong_ordering::greater; - } else { - return __u_is_negative ? strong_ordering::greater : strong_ordering::less; - } - } +struct __fn { + // NOLINTBEGIN(libcpp-robust-against-adl) strong_order should use ADL, but only here + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_Tp&& __t, _Up&& __u, __priority_tag<2>) noexcept( + noexcept(strong_ordering(strong_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))))) + -> decltype(strong_ordering(strong_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) { + return strong_ordering(strong_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))); + } + // NOLINTEND(libcpp-robust-against-adl) + + template > + requires is_same_v<_Dp, decay_t<_Up>> && is_floating_point_v<_Dp> + _LIBCPP_HIDE_FROM_ABI static constexpr strong_ordering __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) noexcept { + if constexpr (numeric_limits<_Dp>::is_iec559 && sizeof(_Dp) == sizeof(int32_t)) { + int32_t __rx = std::bit_cast(__t); + int32_t __ry = std::bit_cast(__u); + __rx = (__rx < 0) ? (numeric_limits::min() - __rx - 1) : __rx; + __ry = (__ry < 0) ? (numeric_limits::min() - __ry - 1) : __ry; + return (__rx <=> __ry); + } else if constexpr (numeric_limits<_Dp>::is_iec559 && sizeof(_Dp) == sizeof(int64_t)) { + int64_t __rx = std::bit_cast(__t); + int64_t __ry = std::bit_cast(__u); + __rx = (__rx < 0) ? (numeric_limits::min() - __rx - 1) : __rx; + __ry = (__ry < 0) ? (numeric_limits::min() - __ry - 1) : __ry; + return (__rx <=> __ry); + } else if (__t < __u) { + return strong_ordering::less; + } else if (__t > __u) { + return strong_ordering::greater; + } else if (__t == __u) { + if constexpr (numeric_limits<_Dp>::radix == 2) { + return __math::signbit(__u) <=> __math::signbit(__t); + } else { + // This is bullet 3 of the IEEE754 algorithm, relevant + // only for decimal floating-point; + // see https://stackoverflow.com/questions/69068075/ + if (__t == 0 || __math::isinf(__t)) { + return __math::signbit(__u) <=> __math::signbit(__t); + } else { + int __texp, __uexp; + (void)__math::frexp(__t, &__texp); + (void)__math::frexp(__u, &__uexp); + return (__t < 0) ? (__texp <=> __uexp) : (__uexp <=> __texp); } + } + } else { + // They're unordered, so one of them must be a NAN. + // The order is -QNAN, -SNAN, numbers, +SNAN, +QNAN. + bool __t_is_nan = __math::isnan(__t); + bool __u_is_nan = __math::isnan(__u); + bool __t_is_negative = __math::signbit(__t); + bool __u_is_negative = __math::signbit(__u); + using _IntType = + conditional_t< sizeof(__t) == sizeof(int32_t), + int32_t, + conditional_t< sizeof(__t) == sizeof(int64_t), int64_t, void> >; + if constexpr (is_same_v<_IntType, void>) { + static_assert(sizeof(_Dp) == 0, "std::strong_order is unimplemented for this floating-point type"); + } else if (__t_is_nan && __u_is_nan) { + // Order by sign bit, then by "payload bits" (we'll just use bit_cast). + if (__t_is_negative != __u_is_negative) { + return (__u_is_negative <=> __t_is_negative); + } else { + return std::bit_cast<_IntType>(__t) <=> std::bit_cast<_IntType>(__u); + } + } else if (__t_is_nan) { + return __t_is_negative ? strong_ordering::less : strong_ordering::greater; + } else { + return __u_is_negative ? strong_ordering::greater : strong_ordering::less; + } + } + } - template - requires is_same_v, decay_t<_Up>> - _LIBCPP_HIDE_FROM_ABI static constexpr auto - __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) - noexcept(noexcept(strong_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) - -> decltype( strong_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) - { return strong_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) noexcept( + noexcept(strong_ordering(compare_three_way()(std::forward<_Tp>(__t), std::forward<_Up>(__u))))) + -> decltype(strong_ordering(compare_three_way()(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) { + return strong_ordering(compare_three_way()(std::forward<_Tp>(__t), std::forward<_Up>(__u))); + } - template - _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const - noexcept(noexcept(__go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<2>()))) - -> decltype( __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<2>())) - { return __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<2>()); } - }; + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<2>()))) + -> decltype(__go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<2>())) { + return __go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<2>()); + } +}; } // namespace __strong_order inline namespace __cpo { - inline constexpr auto strong_order = __strong_order::__fn{}; +inline constexpr auto strong_order = __strong_order::__fn{}; } // namespace __cpo #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__compare/synth_three_way.h b/third_party/libcxx/__compare/synth_three_way.h index 6420d1362..e48ce4979 100644 --- a/third_party/libcxx/__compare/synth_three_way.h +++ b/third_party/libcxx/__compare/synth_three_way.h @@ -25,12 +25,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [expos.only.func] -// TODO MODULES restore the lamba to match the Standard. -// See https://github.com/llvm/llvm-project/issues/57222 -//_LIBCPP_HIDE_FROM_ABI inline constexpr auto __synth_three_way = -// [](const _Tp& __t, const _Up& __u) -template -_LIBCPP_HIDE_FROM_ABI constexpr auto __synth_three_way(const _Tp& __t, const _Up& __u) +_LIBCPP_HIDE_FROM_ABI inline constexpr auto __synth_three_way = [](const _Tp& __t, const _Up& __u) requires requires { { __t < __u } -> __boolean_testable; { __u < __t } -> __boolean_testable; @@ -45,7 +40,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr auto __synth_three_way(const _Tp& __t, const _Up return weak_ordering::greater; return weak_ordering::equivalent; } -} +}; template using __synth_three_way_result = decltype(std::__synth_three_way(std::declval<_Tp&>(), std::declval<_Up&>())); diff --git a/third_party/libcxx/__compare/three_way_comparable.h b/third_party/libcxx/__compare/three_way_comparable.h index 2b77bc3f5..7a44ea915 100644 --- a/third_party/libcxx/__compare/three_way_comparable.h +++ b/third_party/libcxx/__compare/three_way_comparable.h @@ -27,30 +27,26 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 -template -concept __compares_as = - same_as, _Cat>; +template +concept __compares_as = same_as, _Cat>; -template +template concept three_way_comparable = - __weakly_equality_comparable_with<_Tp, _Tp> && - __partially_ordered_with<_Tp, _Tp> && - requires(__make_const_lvalue_ref<_Tp> __a, __make_const_lvalue_ref<_Tp> __b) { - { __a <=> __b } -> __compares_as<_Cat>; - }; + __weakly_equality_comparable_with<_Tp, _Tp> && __partially_ordered_with<_Tp, _Tp> && + requires(__make_const_lvalue_ref<_Tp> __a, __make_const_lvalue_ref<_Tp> __b) { + { __a <=> __b } -> __compares_as<_Cat>; + }; -template +template concept three_way_comparable_with = - three_way_comparable<_Tp, _Cat> && - three_way_comparable<_Up, _Cat> && - common_reference_with<__make_const_lvalue_ref<_Tp>, __make_const_lvalue_ref<_Up>> && - three_way_comparable, __make_const_lvalue_ref<_Up>>, _Cat> && - __weakly_equality_comparable_with<_Tp, _Up> && - __partially_ordered_with<_Tp, _Up> && - requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) { - { __t <=> __u } -> __compares_as<_Cat>; - { __u <=> __t } -> __compares_as<_Cat>; - }; + three_way_comparable<_Tp, _Cat> && three_way_comparable<_Up, _Cat> && + common_reference_with<__make_const_lvalue_ref<_Tp>, __make_const_lvalue_ref<_Up>> && + three_way_comparable, __make_const_lvalue_ref<_Up>>, _Cat> && + __weakly_equality_comparable_with<_Tp, _Up> && __partially_ordered_with<_Tp, _Up> && + requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) { + { __t <=> __u } -> __compares_as<_Cat>; + { __u <=> __t } -> __compares_as<_Cat>; + }; #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__compare/weak_order.h b/third_party/libcxx/__compare/weak_order.h index 9cbc1d24a..1a3e85feb 100644 --- a/third_party/libcxx/__compare/weak_order.h +++ b/third_party/libcxx/__compare/weak_order.h @@ -13,10 +13,12 @@ #include <__compare/ordering.h> #include <__compare/strong_order.h> #include <__config> +#include <__math/traits.h> #include <__type_traits/decay.h> +#include <__type_traits/is_floating_point.h> +#include <__type_traits/is_same.h> #include <__utility/forward.h> #include <__utility/priority_tag.h> -#include #ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER # pragma GCC system_header @@ -28,71 +30,72 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [cmp.alg] namespace __weak_order { - struct __fn { - // NOLINTBEGIN(libcpp-robust-against-adl) weak_order should use ADL, but only here - template - requires is_same_v, decay_t<_Up>> - _LIBCPP_HIDE_FROM_ABI static constexpr auto - __go(_Tp&& __t, _Up&& __u, __priority_tag<3>) - noexcept(noexcept(weak_ordering(weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) - -> decltype( weak_ordering(weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) - { return weak_ordering(weak_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } - // NOLINTEND(libcpp-robust-against-adl) +void weak_order() = delete; - template> - requires is_same_v<_Dp, decay_t<_Up>> && is_floating_point_v<_Dp> - _LIBCPP_HIDE_FROM_ABI static constexpr weak_ordering - __go(_Tp&& __t, _Up&& __u, __priority_tag<2>) noexcept - { - partial_ordering __po = (__t <=> __u); - if (__po == partial_ordering::less) { - return weak_ordering::less; - } else if (__po == partial_ordering::equivalent) { - return weak_ordering::equivalent; - } else if (__po == partial_ordering::greater) { - return weak_ordering::greater; - } else { - // Otherwise, at least one of them is a NaN. - bool __t_is_nan = _VSTD::isnan(__t); - bool __u_is_nan = _VSTD::isnan(__u); - bool __t_is_negative = _VSTD::signbit(__t); - bool __u_is_negative = _VSTD::signbit(__u); - if (__t_is_nan && __u_is_nan) { - return (__u_is_negative <=> __t_is_negative); - } else if (__t_is_nan) { - return __t_is_negative ? weak_ordering::less : weak_ordering::greater; - } else { - return __u_is_negative ? weak_ordering::greater : weak_ordering::less; - } - } - } +struct __fn { + // NOLINTBEGIN(libcpp-robust-against-adl) weak_order should use ADL, but only here + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_Tp&& __t, _Up&& __u, __priority_tag<3>) noexcept( + noexcept(weak_ordering(weak_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))))) + -> decltype(weak_ordering(weak_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) { + return weak_ordering(weak_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))); + } + // NOLINTEND(libcpp-robust-against-adl) - template - requires is_same_v, decay_t<_Up>> - _LIBCPP_HIDE_FROM_ABI static constexpr auto - __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) - noexcept(noexcept(weak_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) - -> decltype( weak_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) - { return weak_ordering(compare_three_way()(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + template > + requires is_same_v<_Dp, decay_t<_Up>> && is_floating_point_v<_Dp> + _LIBCPP_HIDE_FROM_ABI static constexpr weak_ordering __go(_Tp&& __t, _Up&& __u, __priority_tag<2>) noexcept { + partial_ordering __po = (__t <=> __u); + if (__po == partial_ordering::less) { + return weak_ordering::less; + } else if (__po == partial_ordering::equivalent) { + return weak_ordering::equivalent; + } else if (__po == partial_ordering::greater) { + return weak_ordering::greater; + } else { + // Otherwise, at least one of them is a NaN. + bool __t_is_nan = __math::isnan(__t); + bool __u_is_nan = __math::isnan(__u); + bool __t_is_negative = __math::signbit(__t); + bool __u_is_negative = __math::signbit(__u); + if (__t_is_nan && __u_is_nan) { + return (__u_is_negative <=> __t_is_negative); + } else if (__t_is_nan) { + return __t_is_negative ? weak_ordering::less : weak_ordering::greater; + } else { + return __u_is_negative ? weak_ordering::greater : weak_ordering::less; + } + } + } - template - requires is_same_v, decay_t<_Up>> - _LIBCPP_HIDE_FROM_ABI static constexpr auto - __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) - noexcept(noexcept(weak_ordering(_VSTD::strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))))) - -> decltype( weak_ordering(_VSTD::strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) - { return weak_ordering(_VSTD::strong_order(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u))); } + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_Tp&& __t, _Up&& __u, __priority_tag<1>) noexcept( + noexcept(weak_ordering(compare_three_way()(std::forward<_Tp>(__t), std::forward<_Up>(__u))))) + -> decltype(weak_ordering(compare_three_way()(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) { + return weak_ordering(compare_three_way()(std::forward<_Tp>(__t), std::forward<_Up>(__u))); + } - template - _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const - noexcept(noexcept(__go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<3>()))) - -> decltype( __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<3>())) - { return __go(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u), __priority_tag<3>()); } - }; + template + requires is_same_v, decay_t<_Up>> + _LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_Tp&& __t, _Up&& __u, __priority_tag<0>) noexcept( + noexcept(weak_ordering(std::strong_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))))) + -> decltype(weak_ordering(std::strong_order(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) { + return weak_ordering(std::strong_order(std::forward<_Tp>(__t), std::forward<_Up>(__u))); + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(__go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<3>()))) + -> decltype(__go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<3>())) { + return __go(std::forward<_Tp>(__t), std::forward<_Up>(__u), __priority_tag<3>()); + } +}; } // namespace __weak_order inline namespace __cpo { - inline constexpr auto weak_order = __weak_order::__fn{}; +inline constexpr auto weak_order = __weak_order::__fn{}; } // namespace __cpo #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__concepts/arithmetic.h b/third_party/libcxx/__concepts/arithmetic.h index 91a0b184b..0c44f1178 100644 --- a/third_party/libcxx/__concepts/arithmetic.h +++ b/third_party/libcxx/__concepts/arithmetic.h @@ -26,25 +26,29 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [concepts.arithmetic], arithmetic concepts -template +template concept integral = is_integral_v<_Tp>; -template +template concept signed_integral = integral<_Tp> && is_signed_v<_Tp>; -template +template concept unsigned_integral = integral<_Tp> && !signed_integral<_Tp>; -template +template concept floating_point = is_floating_point_v<_Tp>; // Concept helpers for the internal type traits for the fundamental types. template concept __libcpp_unsigned_integer = __libcpp_is_unsigned_integer<_Tp>::value; + template concept __libcpp_signed_integer = __libcpp_is_signed_integer<_Tp>::value; +template +concept __libcpp_integer = __libcpp_unsigned_integer<_Tp> || __libcpp_signed_integer<_Tp>; + #endif // _LIBCPP_STD_VER >= 20 _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__concepts/assignable.h b/third_party/libcxx/__concepts/assignable.h index 2dabae576..7423daabb 100644 --- a/third_party/libcxx/__concepts/assignable.h +++ b/third_party/libcxx/__concepts/assignable.h @@ -26,13 +26,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [concept.assignable] -template +template concept assignable_from = - is_lvalue_reference_v<_Lhs> && - common_reference_with<__make_const_lvalue_ref<_Lhs>, __make_const_lvalue_ref<_Rhs>> && - requires (_Lhs __lhs, _Rhs&& __rhs) { - { __lhs = _VSTD::forward<_Rhs>(__rhs) } -> same_as<_Lhs>; - }; + is_lvalue_reference_v<_Lhs> && + common_reference_with<__make_const_lvalue_ref<_Lhs>, __make_const_lvalue_ref<_Rhs>> && + requires(_Lhs __lhs, _Rhs&& __rhs) { + { __lhs = std::forward<_Rhs>(__rhs) } -> same_as<_Lhs>; + }; #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__concepts/boolean_testable.h b/third_party/libcxx/__concepts/boolean_testable.h index 8efb6e5ff..b379fe9c5 100644 --- a/third_party/libcxx/__concepts/boolean_testable.h +++ b/third_party/libcxx/__concepts/boolean_testable.h @@ -23,12 +23,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [concepts.booleantestable] -template +template concept __boolean_testable_impl = convertible_to<_Tp, bool>; -template +template concept __boolean_testable = __boolean_testable_impl<_Tp> && requires(_Tp&& __t) { - { !_VSTD::forward<_Tp>(__t) } -> __boolean_testable_impl; + { !std::forward<_Tp>(__t) } -> __boolean_testable_impl; }; #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__concepts/class_or_enum.h b/third_party/libcxx/__concepts/class_or_enum.h index 04c24bd98..2739e31e1 100644 --- a/third_party/libcxx/__concepts/class_or_enum.h +++ b/third_party/libcxx/__concepts/class_or_enum.h @@ -25,14 +25,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD // Whether a type is a class type or enumeration type according to the Core wording. -template +template concept __class_or_enum = is_class_v<_Tp> || is_union_v<_Tp> || is_enum_v<_Tp>; -// Work around Clang bug https://llvm.org/PR52970 -// TODO: remove this workaround once libc++ no longer has to support Clang 13 (it was fixed in Clang 14). -template -concept __workaround_52970 = is_class_v<__remove_cvref_t<_Tp>> || is_union_v<__remove_cvref_t<_Tp>>; - #endif // _LIBCPP_STD_VER >= 20 _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__concepts/common_reference_with.h b/third_party/libcxx/__concepts/common_reference_with.h index 6ad0db224..4eb687e07 100644 --- a/third_party/libcxx/__concepts/common_reference_with.h +++ b/third_party/libcxx/__concepts/common_reference_with.h @@ -24,11 +24,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [concept.commonref] -template +template concept common_reference_with = - same_as, common_reference_t<_Up, _Tp>> && - convertible_to<_Tp, common_reference_t<_Tp, _Up>> && - convertible_to<_Up, common_reference_t<_Tp, _Up>>; + same_as, common_reference_t<_Up, _Tp>> && + convertible_to<_Tp, common_reference_t<_Tp, _Up>> && convertible_to<_Up, common_reference_t<_Tp, _Up>>; #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__concepts/common_with.h b/third_party/libcxx/__concepts/common_with.h index e159bcce9..85abb05ef 100644 --- a/third_party/libcxx/__concepts/common_with.h +++ b/third_party/libcxx/__concepts/common_with.h @@ -27,21 +27,23 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [concept.common] -template +// clang-format off +template concept common_with = - same_as, common_type_t<_Up, _Tp>> && - requires { - static_cast>(std::declval<_Tp>()); - static_cast>(std::declval<_Up>()); - } && - common_reference_with< - add_lvalue_reference_t, - add_lvalue_reference_t> && - common_reference_with< - add_lvalue_reference_t>, - common_reference_t< - add_lvalue_reference_t, - add_lvalue_reference_t>>; + same_as, common_type_t<_Up, _Tp>> && + requires { + static_cast>(std::declval<_Tp>()); + static_cast>(std::declval<_Up>()); + } && + common_reference_with< + add_lvalue_reference_t, + add_lvalue_reference_t> && + common_reference_with< + add_lvalue_reference_t>, + common_reference_t< + add_lvalue_reference_t, + add_lvalue_reference_t>>; +// clang-format on #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__concepts/constructible.h b/third_party/libcxx/__concepts/constructible.h index 6e3862c51..835a44429 100644 --- a/third_party/libcxx/__concepts/constructible.h +++ b/third_party/libcxx/__concepts/constructible.h @@ -23,31 +23,30 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 // [concept.constructible] -template -concept constructible_from = - destructible<_Tp> && is_constructible_v<_Tp, _Args...>; +template +concept constructible_from = destructible<_Tp> && is_constructible_v<_Tp, _Args...>; // [concept.default.init] -template +template concept __default_initializable = requires { ::new _Tp; }; -template -concept default_initializable = constructible_from<_Tp> && - requires { _Tp{}; } && __default_initializable<_Tp>; +template +concept default_initializable = constructible_from<_Tp> && requires { _Tp{}; } && __default_initializable<_Tp>; // [concept.moveconstructible] -template -concept move_constructible = - constructible_from<_Tp, _Tp> && convertible_to<_Tp, _Tp>; +template +concept move_constructible = constructible_from<_Tp, _Tp> && convertible_to<_Tp, _Tp>; // [concept.copyconstructible] -template +// clang-format off +template concept copy_constructible = - move_constructible<_Tp> && - constructible_from<_Tp, _Tp&> && convertible_to<_Tp&, _Tp> && - constructible_from<_Tp, const _Tp&> && convertible_to && - constructible_from<_Tp, const _Tp> && convertible_to; + move_constructible<_Tp> && + constructible_from<_Tp, _Tp&> && convertible_to<_Tp&, _Tp> && + constructible_from<_Tp, const _Tp&> && convertible_to && + constructible_from<_Tp, const _Tp> && convertible_to; +// clang-format on #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__concepts/convertible_to.h b/third_party/libcxx/__concepts/convertible_to.h index 20ee31bc0..6d5b6c126 100644 --- a/third_party/libcxx/__concepts/convertible_to.h +++ b/third_party/libcxx/__concepts/convertible_to.h @@ -23,12 +23,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [concept.convertible] -template -concept convertible_to = - is_convertible_v<_From, _To> && - requires { - static_cast<_To>(std::declval<_From>()); - }; +template +concept convertible_to = is_convertible_v<_From, _To> && requires { static_cast<_To>(std::declval<_From>()); }; #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__concepts/copyable.h b/third_party/libcxx/__concepts/copyable.h index 0d6dd50cf..2bf0ad42f 100644 --- a/third_party/libcxx/__concepts/copyable.h +++ b/third_party/libcxx/__concepts/copyable.h @@ -24,13 +24,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [concepts.object] -template +// clang-format off +template concept copyable = - copy_constructible<_Tp> && - movable<_Tp> && - assignable_from<_Tp&, _Tp&> && - assignable_from<_Tp&, const _Tp&> && - assignable_from<_Tp&, const _Tp>; + copy_constructible<_Tp> && + movable<_Tp> && + assignable_from<_Tp&, _Tp&> && + assignable_from<_Tp&, const _Tp&> && + assignable_from<_Tp&, const _Tp>; +// clang-format on #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__concepts/derived_from.h b/third_party/libcxx/__concepts/derived_from.h index 1cbe458e2..9875faee8 100644 --- a/third_party/libcxx/__concepts/derived_from.h +++ b/third_party/libcxx/__concepts/derived_from.h @@ -23,10 +23,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [concept.derived] -template -concept derived_from = - is_base_of_v<_Bp, _Dp> && - is_convertible_v; +template +concept derived_from = is_base_of_v<_Bp, _Dp> && is_convertible_v; #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__concepts/destructible.h b/third_party/libcxx/__concepts/destructible.h index 8da9c378b..28b4b1bc2 100644 --- a/third_party/libcxx/__concepts/destructible.h +++ b/third_party/libcxx/__concepts/destructible.h @@ -22,7 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [concept.destructible] -template +template concept destructible = is_nothrow_destructible_v<_Tp>; #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__concepts/different_from.h b/third_party/libcxx/__concepts/different_from.h index 5ef1467ac..fd31f6e25 100644 --- a/third_party/libcxx/__concepts/different_from.h +++ b/third_party/libcxx/__concepts/different_from.h @@ -21,7 +21,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 -template +template concept __different_from = !same_as, remove_cvref_t<_Up>>; #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__concepts/equality_comparable.h b/third_party/libcxx/__concepts/equality_comparable.h index f1062884e..278fc7640 100644 --- a/third_party/libcxx/__concepts/equality_comparable.h +++ b/third_party/libcxx/__concepts/equality_comparable.h @@ -25,27 +25,29 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [concept.equalitycomparable] -template +template concept __weakly_equality_comparable_with = - requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) { - { __t == __u } -> __boolean_testable; - { __t != __u } -> __boolean_testable; - { __u == __t } -> __boolean_testable; - { __u != __t } -> __boolean_testable; - }; + requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) { + { __t == __u } -> __boolean_testable; + { __t != __u } -> __boolean_testable; + { __u == __t } -> __boolean_testable; + { __u != __t } -> __boolean_testable; + }; -template +template concept equality_comparable = __weakly_equality_comparable_with<_Tp, _Tp>; -template +// clang-format off +template concept equality_comparable_with = - equality_comparable<_Tp> && equality_comparable<_Up> && - common_reference_with<__make_const_lvalue_ref<_Tp>, __make_const_lvalue_ref<_Up>> && - equality_comparable< - common_reference_t< - __make_const_lvalue_ref<_Tp>, - __make_const_lvalue_ref<_Up>>> && - __weakly_equality_comparable_with<_Tp, _Up>; + equality_comparable<_Tp> && equality_comparable<_Up> && + common_reference_with<__make_const_lvalue_ref<_Tp>, __make_const_lvalue_ref<_Up>> && + equality_comparable< + common_reference_t< + __make_const_lvalue_ref<_Tp>, + __make_const_lvalue_ref<_Up>>> && + __weakly_equality_comparable_with<_Tp, _Up>; +// clang-format on #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__concepts/invocable.h b/third_party/libcxx/__concepts/invocable.h index 59eab01f8..8a29398b3 100644 --- a/third_party/libcxx/__concepts/invocable.h +++ b/third_party/libcxx/__concepts/invocable.h @@ -23,14 +23,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [concept.invocable] -template +template concept invocable = requires(_Fn&& __fn, _Args&&... __args) { - _VSTD::invoke(_VSTD::forward<_Fn>(__fn), _VSTD::forward<_Args>(__args)...); // not required to be equality preserving + std::invoke(std::forward<_Fn>(__fn), std::forward<_Args>(__args)...); // not required to be equality preserving }; // [concept.regular.invocable] -template +template concept regular_invocable = invocable<_Fn, _Args...>; #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__concepts/movable.h b/third_party/libcxx/__concepts/movable.h index f37d49f04..bc5b9d767 100644 --- a/third_party/libcxx/__concepts/movable.h +++ b/third_party/libcxx/__concepts/movable.h @@ -25,12 +25,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [concepts.object] -template -concept movable = - is_object_v<_Tp> && - move_constructible<_Tp> && - assignable_from<_Tp&, _Tp> && - swappable<_Tp>; +template +concept movable = is_object_v<_Tp> && move_constructible<_Tp> && assignable_from<_Tp&, _Tp> && swappable<_Tp>; #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__concepts/predicate.h b/third_party/libcxx/__concepts/predicate.h index b09183c5c..00731efc8 100644 --- a/third_party/libcxx/__concepts/predicate.h +++ b/third_party/libcxx/__concepts/predicate.h @@ -24,9 +24,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [concept.predicate] -template -concept predicate = - regular_invocable<_Fn, _Args...> && __boolean_testable>; +template +concept predicate = regular_invocable<_Fn, _Args...> && __boolean_testable>; #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__concepts/regular.h b/third_party/libcxx/__concepts/regular.h index 93fb7016c..9f3d8bf30 100644 --- a/third_party/libcxx/__concepts/regular.h +++ b/third_party/libcxx/__concepts/regular.h @@ -23,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [concept.object] -template +template concept regular = semiregular<_Tp> && equality_comparable<_Tp>; #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__concepts/relation.h b/third_party/libcxx/__concepts/relation.h index 218afef21..7545a7db9 100644 --- a/third_party/libcxx/__concepts/relation.h +++ b/third_party/libcxx/__concepts/relation.h @@ -22,19 +22,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [concept.relation] -template +template concept relation = - predicate<_Rp, _Tp, _Tp> && predicate<_Rp, _Up, _Up> && - predicate<_Rp, _Tp, _Up> && predicate<_Rp, _Up, _Tp>; + predicate<_Rp, _Tp, _Tp> && predicate<_Rp, _Up, _Up> && predicate<_Rp, _Tp, _Up> && predicate<_Rp, _Up, _Tp>; // [concept.equiv] -template +template concept equivalence_relation = relation<_Rp, _Tp, _Up>; // [concept.strictweakorder] -template +template concept strict_weak_order = relation<_Rp, _Tp, _Up>; #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__concepts/same_as.h b/third_party/libcxx/__concepts/same_as.h index b86cadaa1..4241131c7 100644 --- a/third_party/libcxx/__concepts/same_as.h +++ b/third_party/libcxx/__concepts/same_as.h @@ -22,10 +22,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [concept.same] -template +template concept __same_as_impl = _IsSame<_Tp, _Up>::value; -template +template concept same_as = __same_as_impl<_Tp, _Up> && __same_as_impl<_Up, _Tp>; #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__concepts/semiregular.h b/third_party/libcxx/__concepts/semiregular.h index ae2f3c669..7a159d17d 100644 --- a/third_party/libcxx/__concepts/semiregular.h +++ b/third_party/libcxx/__concepts/semiregular.h @@ -23,7 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [concept.object] -template +template concept semiregular = copyable<_Tp> && default_initializable<_Tp>; #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__concepts/swappable.h b/third_party/libcxx/__concepts/swappable.h index 859255dec..d339488a0 100644 --- a/third_party/libcxx/__concepts/swappable.h +++ b/third_party/libcxx/__concepts/swappable.h @@ -15,8 +15,8 @@ #include <__concepts/constructible.h> #include <__config> #include <__type_traits/extent.h> -#include <__type_traits/is_nothrow_move_assignable.h> -#include <__type_traits/is_nothrow_move_constructible.h> +#include <__type_traits/is_nothrow_assignable.h> +#include <__type_traits/is_nothrow_constructible.h> #include <__type_traits/remove_cvref.h> #include <__utility/exchange.h> #include <__utility/forward.h> @@ -28,6 +28,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 @@ -37,85 +40,84 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __swap { - template - void swap(_Tp&, _Tp&) = delete; +template +void swap(_Tp&, _Tp&) = delete; - template - concept __unqualified_swappable_with = +// clang-format off +template +concept __unqualified_swappable_with = (__class_or_enum> || __class_or_enum>) && requires(_Tp&& __t, _Up&& __u) { - swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); + swap(std::forward<_Tp>(__t), std::forward<_Up>(__u)); }; +// clang-format on - struct __fn; +struct __fn; - template - concept __swappable_arrays = - !__unqualified_swappable_with<_Tp(&)[_Size], _Up(&)[_Size]> && +// clang-format off +template +concept __swappable_arrays = + !__unqualified_swappable_with<_Tp (&)[_Size], _Up (&)[_Size]> && extent_v<_Tp> == extent_v<_Up> && - requires(_Tp(& __t)[_Size], _Up(& __u)[_Size], const __fn& __swap) { - __swap(__t[0], __u[0]); + requires(_Tp (&__t)[_Size], _Up (&__u)[_Size], const __fn& __swap) { + __swap(__t[0], __u[0]); }; +// clang-format on - template - concept __exchangeable = - !__unqualified_swappable_with<_Tp&, _Tp&> && - move_constructible<_Tp> && - assignable_from<_Tp&, _Tp>; +template +concept __exchangeable = + !__unqualified_swappable_with<_Tp&, _Tp&> && move_constructible<_Tp> && assignable_from<_Tp&, _Tp>; - struct __fn { - // 2.1 `S` is `(void)swap(E1, E2)`* if `E1` or `E2` has class or enumeration type and... - // *The name `swap` is used here unqualified. - template - requires __unqualified_swappable_with<_Tp, _Up> - _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_Tp&& __t, _Up&& __u) const - noexcept(noexcept(swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)))) - { - swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); +struct __fn { + // 2.1 `S` is `(void)swap(E1, E2)`* if `E1` or `E2` has class or enumeration type and... + // *The name `swap` is used here unqualified. + template + requires __unqualified_swappable_with<_Tp, _Up> + _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(swap(std::forward<_Tp>(__t), std::forward<_Up>(__u)))) { + swap(std::forward<_Tp>(__t), std::forward<_Up>(__u)); + } + + // 2.2 Otherwise, if `E1` and `E2` are lvalues of array types with equal extent and... + template + requires __swappable_arrays<_Tp, _Up, _Size> + _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_Tp (&__t)[_Size], _Up (&__u)[_Size]) const + noexcept(noexcept((*this)(*__t, *__u))) { + // TODO(cjdb): replace with `ranges::swap_ranges`. + for (size_t __i = 0; __i < _Size; ++__i) { + (*this)(__t[__i], __u[__i]); } + } - // 2.2 Otherwise, if `E1` and `E2` are lvalues of array types with equal extent and... - template - requires __swappable_arrays<_Tp, _Up, _Size> - _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_Tp(& __t)[_Size], _Up(& __u)[_Size]) const - noexcept(noexcept((*this)(*__t, *__u))) - { - // TODO(cjdb): replace with `ranges::swap_ranges`. - for (size_t __i = 0; __i < _Size; ++__i) { - (*this)(__t[__i], __u[__i]); - } - } - - // 2.3 Otherwise, if `E1` and `E2` are lvalues of the same type `T` that models... - template<__exchangeable _Tp> - _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_Tp& __x, _Tp& __y) const - noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_assignable_v<_Tp>) - { - __y = _VSTD::exchange(__x, _VSTD::move(__y)); - } - }; + // 2.3 Otherwise, if `E1` and `E2` are lvalues of the same type `T` that models... + template <__exchangeable _Tp> + _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_Tp& __x, _Tp& __y) const + noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_assignable_v<_Tp>) { + __y = std::exchange(__x, std::move(__y)); + } +}; } // namespace __swap inline namespace __cpo { - inline constexpr auto swap = __swap::__fn{}; +inline constexpr auto swap = __swap::__fn{}; } // namespace __cpo } // namespace ranges -template +template concept swappable = requires(_Tp& __a, _Tp& __b) { ranges::swap(__a, __b); }; -template -concept swappable_with = - common_reference_with<_Tp, _Up> && - requires(_Tp&& __t, _Up&& __u) { - ranges::swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Tp>(__t)); - ranges::swap(_VSTD::forward<_Up>(__u), _VSTD::forward<_Up>(__u)); - ranges::swap(_VSTD::forward<_Tp>(__t), _VSTD::forward<_Up>(__u)); - ranges::swap(_VSTD::forward<_Up>(__u), _VSTD::forward<_Tp>(__t)); - }; +template +concept swappable_with = common_reference_with<_Tp, _Up> && requires(_Tp&& __t, _Up&& __u) { + ranges::swap(std::forward<_Tp>(__t), std::forward<_Tp>(__t)); + ranges::swap(std::forward<_Up>(__u), std::forward<_Up>(__u)); + ranges::swap(std::forward<_Tp>(__t), std::forward<_Up>(__u)); + ranges::swap(std::forward<_Up>(__u), std::forward<_Tp>(__t)); +}; #endif // _LIBCPP_STD_VER >= 20 _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___CONCEPTS_SWAPPABLE_H diff --git a/third_party/libcxx/__concepts/totally_ordered.h b/third_party/libcxx/__concepts/totally_ordered.h index 350eff338..186c3b430 100644 --- a/third_party/libcxx/__concepts/totally_ordered.h +++ b/third_party/libcxx/__concepts/totally_ordered.h @@ -25,31 +25,32 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [concept.totallyordered] -template -concept __partially_ordered_with = - requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) { - { __t < __u } -> __boolean_testable; - { __t > __u } -> __boolean_testable; - { __t <= __u } -> __boolean_testable; - { __t >= __u } -> __boolean_testable; - { __u < __t } -> __boolean_testable; - { __u > __t } -> __boolean_testable; - { __u <= __t } -> __boolean_testable; - { __u >= __t } -> __boolean_testable; - }; +template +concept __partially_ordered_with = requires(__make_const_lvalue_ref<_Tp> __t, __make_const_lvalue_ref<_Up> __u) { + { __t < __u } -> __boolean_testable; + { __t > __u } -> __boolean_testable; + { __t <= __u } -> __boolean_testable; + { __t >= __u } -> __boolean_testable; + { __u < __t } -> __boolean_testable; + { __u > __t } -> __boolean_testable; + { __u <= __t } -> __boolean_testable; + { __u >= __t } -> __boolean_testable; +}; -template +template concept totally_ordered = equality_comparable<_Tp> && __partially_ordered_with<_Tp, _Tp>; -template +// clang-format off +template concept totally_ordered_with = - totally_ordered<_Tp> && totally_ordered<_Up> && - equality_comparable_with<_Tp, _Up> && - totally_ordered< - common_reference_t< - __make_const_lvalue_ref<_Tp>, - __make_const_lvalue_ref<_Up>>> && - __partially_ordered_with<_Tp, _Up>; + totally_ordered<_Tp> && totally_ordered<_Up> && + equality_comparable_with<_Tp, _Up> && + totally_ordered< + common_reference_t< + __make_const_lvalue_ref<_Tp>, + __make_const_lvalue_ref<_Up>>> && + __partially_ordered_with<_Tp, _Up>; +// clang-format on #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__condition_variable/condition_variable.h b/third_party/libcxx/__condition_variable/condition_variable.h index 8fc80b633..de35aaca1 100644 --- a/third_party/libcxx/__condition_variable/condition_variable.h +++ b/third_party/libcxx/__condition_variable/condition_variable.h @@ -9,6 +9,7 @@ #ifndef _LIBCPP___CONDITION_VARIABLE_CONDITION_VARIABLE_H #define _LIBCPP___CONDITION_VARIABLE_CONDITION_VARIABLE_H +#include <__chrono/duration.h> #include <__chrono/steady_clock.h> #include <__chrono/system_clock.h> #include <__chrono/time_point.h> @@ -16,10 +17,11 @@ #include <__mutex/mutex.h> #include <__mutex/unique_lock.h> #include <__system_error/system_error.h> -#include <__threading_support> +#include <__thread/support.h> #include <__type_traits/enable_if.h> #include <__type_traits/is_floating_point.h> #include <__utility/move.h> +#include #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -37,7 +39,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_DECLARE_STRONG_ENUM(cv_status){no_timeout, timeout}; _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(cv_status) -class _LIBCPP_TYPE_VIS condition_variable { +class _LIBCPP_EXPORTED_FROM_ABI condition_variable { __libcpp_condvar_t __cv_ = _LIBCPP_CONDVAR_INITIALIZER; public: @@ -91,9 +93,8 @@ private: }; #endif // !_LIBCPP_HAS_NO_THREADS -template -inline _LIBCPP_HIDE_FROM_ABI __enable_if_t::value, chrono::nanoseconds> -__safe_nanosecond_cast(chrono::duration<_Rep, _Period> __d) { +template ::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI chrono::nanoseconds __safe_nanosecond_cast(chrono::duration<_Rep, _Period> __d) { using namespace chrono; using __ratio = ratio_divide<_Period, nano>; using __ns_rep = nanoseconds::rep; @@ -112,9 +113,8 @@ __safe_nanosecond_cast(chrono::duration<_Rep, _Period> __d) { return nanoseconds(static_cast<__ns_rep>(__result_float)); } -template -inline _LIBCPP_HIDE_FROM_ABI __enable_if_t::value, chrono::nanoseconds> -__safe_nanosecond_cast(chrono::duration<_Rep, _Period> __d) { +template ::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI chrono::nanoseconds __safe_nanosecond_cast(chrono::duration<_Rep, _Period> __d) { using namespace chrono; if (__d.count() == 0) { return nanoseconds(0); diff --git a/third_party/libcxx/__config b/third_party/libcxx/__config index f474f9880..108f70082 100644 --- a/third_party/libcxx/__config +++ b/third_party/libcxx/__config @@ -11,184 +11,149 @@ #define _LIBCPP___CONFIG #include <__config_site> - -#if defined(_MSC_VER) && !defined(__clang__) -# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# define _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER -# endif -#endif +#include <__configuration/abi.h> +#include <__configuration/availability.h> +#include <__configuration/compiler.h> +#include <__configuration/platform.h> #ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER # pragma GCC system_header #endif -#if defined(__apple_build_version__) -// Given AppleClang XX.Y.Z, _LIBCPP_APPLE_CLANG_VER is XXYZ (e.g. AppleClang 14.0.3 => 1403) -# define _LIBCPP_COMPILER_CLANG_BASED -# define _LIBCPP_APPLE_CLANG_VER (__apple_build_version__ / 10000) -#elif defined(__clang__) -# define _LIBCPP_COMPILER_CLANG_BASED -# define _LIBCPP_CLANG_VER (__clang_major__ * 100 + __clang_minor__) -#elif defined(__GNUC__) -# define _LIBCPP_COMPILER_GCC -#endif - #ifdef __cplusplus +// The attributes supported by clang are documented at https://clang.llvm.org/docs/AttributeReference.html + // _LIBCPP_VERSION represents the version of libc++, which matches the version of LLVM. // Given a LLVM release LLVM XX.YY.ZZ (e.g. LLVM 17.0.1 == 17.00.01), _LIBCPP_VERSION is // defined to XXYYZZ. -# define _LIBCPP_VERSION 170000 +# define _LIBCPP_VERSION 190000 # define _LIBCPP_CONCAT_IMPL(_X, _Y) _X##_Y # define _LIBCPP_CONCAT(_X, _Y) _LIBCPP_CONCAT_IMPL(_X, _Y) -// Valid C++ identifier that revs with every libc++ version. This can be used to -// generate identifiers that must be unique for every released libc++ version. -# define _LIBCPP_VERSIONED_IDENTIFIER _LIBCPP_CONCAT(v, _LIBCPP_VERSION) - # if __STDC_HOSTED__ == 0 # define _LIBCPP_FREESTANDING # endif -// NOLINTBEGIN(libcpp-cpp-version-check) -# ifndef _LIBCPP_STD_VER -# if __cplusplus <= 201103L -# define _LIBCPP_STD_VER 11 -# elif __cplusplus <= 201402L -# define _LIBCPP_STD_VER 14 -# elif __cplusplus <= 201703L -# define _LIBCPP_STD_VER 17 -# elif __cplusplus <= 202002L -# define _LIBCPP_STD_VER 20 -# elif __cplusplus <= 202302L -# define _LIBCPP_STD_VER 23 -# else -// Expected release year of the next C++ standard -# define _LIBCPP_STD_VER 26 -# endif -# endif // _LIBCPP_STD_VER -// NOLINTEND(libcpp-cpp-version-check) +// HARDENING { -# if defined(__ELF__) -# define _LIBCPP_OBJECT_FORMAT_ELF 1 -# elif defined(__MACH__) -# define _LIBCPP_OBJECT_FORMAT_MACHO 1 -# elif defined(_WIN32) -# define _LIBCPP_OBJECT_FORMAT_COFF 1 -# elif defined(__wasm__) -# define _LIBCPP_OBJECT_FORMAT_WASM 1 -# elif defined(_AIX) -# define _LIBCPP_OBJECT_FORMAT_XCOFF 1 -# else -// ... add new file formats here ... +// This is for backward compatibility -- make enabling `_LIBCPP_ENABLE_ASSERTIONS` (which predates hardening modes) +// equivalent to setting the extensive mode. This is deprecated and will be removed in LLVM 20. +# ifdef _LIBCPP_ENABLE_ASSERTIONS +# warning "_LIBCPP_ENABLE_ASSERTIONS is deprecated, please use _LIBCPP_HARDENING_MODE instead" +# if _LIBCPP_ENABLE_ASSERTIONS != 0 && _LIBCPP_ENABLE_ASSERTIONS != 1 +# error "_LIBCPP_ENABLE_ASSERTIONS must be set to 0 or 1" +# endif +# if _LIBCPP_ENABLE_ASSERTIONS +# define _LIBCPP_HARDENING_MODE _LIBCPP_HARDENING_MODE_EXTENSIVE +# endif # endif -# if _LIBCPP_ABI_VERSION >= 2 -// Change short string representation so that string data starts at offset 0, -// improving its alignment in some cases. -# define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT -// Fix deque iterator type in order to support incomplete types. -# define _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE -// Fix undefined behavior in how std::list stores its linked nodes. -# define _LIBCPP_ABI_LIST_REMOVE_NODE_POINTER_UB -// Fix undefined behavior in how __tree stores its end and parent nodes. -# define _LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB -// Fix undefined behavior in how __hash_table stores its pointer types. -# define _LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB -# define _LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB -# define _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE -// Define a key function for `bad_function_call` in the library, to centralize -// its vtable and typeinfo to libc++ rather than having all other libraries -// using that class define their own copies. -# define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION -// Override the default return value of exception::what() for -// bad_function_call::what() with a string that is specific to -// bad_function_call (see http://wg21.link/LWG2233). This is an ABI break -// because it changes the vtable layout of bad_function_call. -# define _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE -// Enable optimized version of __do_get_(un)signed which avoids redundant copies. -# define _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET -// Give reverse_iterator one data member of type T, not two. -// Also, in C++17 and later, don't derive iterator types from std::iterator. -# define _LIBCPP_ABI_NO_ITERATOR_BASES -// Use the smallest possible integer type to represent the index of the variant. -// Previously libc++ used "unsigned int" exclusively. -# define _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION -// Unstable attempt to provide a more optimized std::function -# define _LIBCPP_ABI_OPTIMIZED_FUNCTION -// All the regex constants must be distinct and nonzero. -# define _LIBCPP_ABI_REGEX_CONSTANTS_NONZERO -// Re-worked external template instantiations for std::string with a focus on -// performance and fast-path inlining. -# define _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION -// Enable clang::trivial_abi on std::unique_ptr. -# define _LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI -// Enable clang::trivial_abi on std::shared_ptr and std::weak_ptr -# define _LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI -// std::random_device holds some state when it uses an implementation that gets -// entropy from a file (see _LIBCPP_USING_DEV_RANDOM). When switching from this -// implementation to another one on a platform that has already shipped -// std::random_device, one needs to retain the same object layout to remain ABI -// compatible. This switch removes these workarounds for platforms that don't care -// about ABI compatibility. -# define _LIBCPP_ABI_NO_RANDOM_DEVICE_COMPATIBILITY_LAYOUT -// Don't export the legacy __basic_string_common class and its methods from the built library. -# define _LIBCPP_ABI_DO_NOT_EXPORT_BASIC_STRING_COMMON -// Don't export the legacy __vector_base_common class and its methods from the built library. -# define _LIBCPP_ABI_DO_NOT_EXPORT_VECTOR_BASE_COMMON -// According to the Standard, `bitset::operator[] const` returns bool -# define _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL -// Fix the implementation of CityHash used for std::hash. -// This is an ABI break because `std::hash` will return a different result, -// which means that hashing the same object in translation units built against -// different versions of libc++ can return inconsistent results. This is especially -// tricky since std::hash is used in the implementation of unordered containers. +// The library provides the macro `_LIBCPP_HARDENING_MODE` which can be set to one of the following values: // -// The incorrect implementation of CityHash has the problem that it drops some -// bits on the floor. -# define _LIBCPP_ABI_FIX_CITYHASH_IMPLEMENTATION -// Remove the base 10 implementation of std::to_chars from the dylib. -// The implementation moved to the header, but we still export the symbols from -// the dylib for backwards compatibility. -# define _LIBCPP_ABI_DO_NOT_EXPORT_TO_CHARS_BASE_10 -# elif _LIBCPP_ABI_VERSION == 1 -# if !(defined(_LIBCPP_OBJECT_FORMAT_COFF) || defined(_LIBCPP_OBJECT_FORMAT_XCOFF)) -// Enable compiling copies of now inline methods into the dylib to support -// applications compiled against older libraries. This is unnecessary with -// COFF dllexport semantics, since dllexport forces a non-inline definition -// of inline functions to be emitted anyway. Our own non-inline copy would -// conflict with the dllexport-emitted copy, so we disable it. For XCOFF, -// the linker will take issue with the symbols in the shared object if the -// weak inline methods get visibility (such as from -fvisibility-inlines-hidden), -// so disable it. -# define _LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS -# endif -// Feature macros for disabling pre ABI v1 features. All of these options -// are deprecated. -# if defined(__FreeBSD__) -# define _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR -# endif -// For XCOFF linkers, we have problems if we see a weak hidden version of a symbol -// in user code (like you get with -fvisibility-inlines-hidden) and then a strong def -// in the library, so we need to always rely on the library version. -# if defined(_AIX) -# define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION +// - `_LIBCPP_HARDENING_MODE_NONE`; +// - `_LIBCPP_HARDENING_MODE_FAST`; +// - `_LIBCPP_HARDENING_MODE_EXTENSIVE`; +// - `_LIBCPP_HARDENING_MODE_DEBUG`. +// +// These values have the following effects: +// +// - `_LIBCPP_HARDENING_MODE_NONE` -- sets the hardening mode to "none" which disables all runtime hardening checks; +// +// - `_LIBCPP_HARDENING_MODE_FAST` -- sets that hardening mode to "fast". The fast mode enables security-critical checks +// that can be done with relatively little runtime overhead in constant time; +// +// - `_LIBCPP_HARDENING_MODE_EXTENSIVE` -- sets the hardening mode to "extensive". The extensive mode is a superset of +// the fast mode that additionally enables checks that are relatively cheap and prevent common types of logic errors +// but are not necessarily security-critical; +// +// - `_LIBCPP_HARDENING_MODE_DEBUG` -- sets the hardening mode to "debug". The debug mode is a superset of the extensive +// mode and enables all checks available in the library, including internal assertions. Checks that are part of the +// debug mode can be very expensive and thus the debug mode is intended to be used for testing, not in production. + +// Inside the library, assertions are categorized so they can be cherry-picked based on the chosen hardening mode. These +// macros are only for internal use -- users should only pick one of the high-level hardening modes described above. +// +// - `_LIBCPP_ASSERT_VALID_INPUT_RANGE` -- checks that ranges (whether expressed as an iterator pair, an iterator and +// a sentinel, an iterator and a count, or a `std::range`) given as input to library functions are valid: +// - the sentinel is reachable from the begin iterator; +// - TODO(hardening): both iterators refer to the same container. +// +// - `_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS` -- checks that any attempts to access a container element, whether through +// the container object or through an iterator, are valid and do not attempt to go out of bounds or otherwise access +// a non-existent element. For iterator checks to work, bounded iterators must be enabled in the ABI. Types like +// `optional` and `function` are considered one-element containers for the purposes of this check. +// +// - `_LIBCPP_ASSERT_NON_NULL` -- checks that the pointer being dereferenced is not null. On most modern platforms zero +// address does not refer to an actual location in memory, so a null pointer dereference would not compromize the +// memory security of a program (however, it is still undefined behavior that can result in strange errors due to +// compiler optimizations). +// +// - `_LIBCPP_ASSERT_NON_OVERLAPPING_RANGES` -- for functions that take several ranges as arguments, checks that the +// given ranges do not overlap. +// +// - `_LIBCPP_ASSERT_VALID_DEALLOCATION` -- checks that an attempt to deallocate memory is valid (e.g. the given object +// was allocated by the given allocator). Violating this category typically results in a memory leak. +// +// - `_LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL` -- checks that a call to an external API doesn't fail in +// an unexpected manner. This includes triggering documented cases of undefined behavior in an external library (like +// attempting to unlock an unlocked mutex in pthreads). Any API external to the library falls under this category +// (from system calls to compiler intrinsics). We generally don't expect these failures to compromize memory safety or +// otherwise create an immediate security issue. +// +// - `_LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR` -- checks any operations that exchange nodes between containers to make sure +// the containers have compatible allocators. +// +// - `_LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN` -- checks that the given argument is within the domain of valid arguments +// for the function. Violating this typically produces an incorrect result (e.g. the clamp algorithm returns the +// original value without clamping it due to incorrect functors) or puts an object into an invalid state (e.g. +// a string view where only a subset of elements is possible to access). This category is for assertions violating +// which doesn't cause any immediate issues in the library -- whatever the consequences are, they will happen in the +// user code. +// +// - `_LIBCPP_ASSERT_PEDANTIC` -- checks prerequisites which are imposed by the Standard, but violating which happens to +// be benign in our implementation. +// +// - `_LIBCPP_ASSERT_SEMANTIC_REQUIREMENT` -- checks that the given argument satisfies the semantic requirements imposed +// by the Standard. Typically, there is no simple way to completely prove that a semantic requirement is satisfied; +// thus, this would often be a heuristic check and it might be quite expensive. +// +// - `_LIBCPP_ASSERT_INTERNAL` -- checks that internal invariants of the library hold. These assertions don't depend on +// user input. +// +// - `_LIBCPP_ASSERT_UNCATEGORIZED` -- for assertions that haven't been properly classified yet. + +// clang-format off +# define _LIBCPP_HARDENING_MODE_NONE (1 << 1) +# define _LIBCPP_HARDENING_MODE_FAST (1 << 2) +# define _LIBCPP_HARDENING_MODE_EXTENSIVE (1 << 4) // Deliberately not ordered. +# define _LIBCPP_HARDENING_MODE_DEBUG (1 << 3) +// clang-format on + +# ifndef _LIBCPP_HARDENING_MODE + +# ifndef _LIBCPP_HARDENING_MODE_DEFAULT +# error _LIBCPP_HARDENING_MODE_DEFAULT is not defined. This definition should be set at configuration time in the \ +`__config_site` header, please make sure your installation of libc++ is not broken. # endif + +# define _LIBCPP_HARDENING_MODE _LIBCPP_HARDENING_MODE_DEFAULT # endif -# if defined(_LIBCPP_BUILDING_LIBRARY) || _LIBCPP_ABI_VERSION >= 2 -// Enable additional explicit instantiations of iostreams components. This -// reduces the number of weak definitions generated in programs that use -// iostreams by providing a single strong definition in the shared library. -# define _LIBCPP_ABI_ENABLE_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1 - -// Define a key function for `bad_function_call` in the library, to centralize -// its vtable and typeinfo to libc++ rather than having all other libraries -// using that class define their own copies. -# define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION +# if _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_NONE && \ + _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_FAST && \ + _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_EXTENSIVE && \ + _LIBCPP_HARDENING_MODE != _LIBCPP_HARDENING_MODE_DEBUG +# error _LIBCPP_HARDENING_MODE must be set to one of the following values: \ +_LIBCPP_HARDENING_MODE_NONE, \ +_LIBCPP_HARDENING_MODE_FAST, \ +_LIBCPP_HARDENING_MODE_EXTENSIVE, \ +_LIBCPP_HARDENING_MODE_DEBUG # endif +// } HARDENING + # define _LIBCPP_TOSTRING2(x) #x # define _LIBCPP_TOSTRING(x) _LIBCPP_TOSTRING2(x) @@ -197,30 +162,15 @@ # define _LIBCPP_CXX03_LANG # endif -# ifndef __has_attribute -# define __has_attribute(__x) 0 -# endif - -# ifndef __has_builtin -# define __has_builtin(__x) 0 -# endif - -# ifndef __has_extension -# define __has_extension(__x) 0 -# endif - -# ifndef __has_feature -# define __has_feature(__x) 0 -# endif - -# ifndef __has_cpp_attribute -# define __has_cpp_attribute(__x) 0 -# endif - # ifndef __has_constexpr_builtin # define __has_constexpr_builtin(x) 0 # endif +// This checks wheter a Clang module is built +# ifndef __building_module +# define __building_module(...) 0 +# endif + // '__is_identifier' returns '0' if '__x' is a reserved identifier provided by // the compiler and '1' otherwise. # ifndef __is_identifier @@ -233,8 +183,8 @@ # define __has_keyword(__x) !(__is_identifier(__x)) -# ifndef __has_include -# define __has_include(...) 0 +# ifndef __has_warning +# define __has_warning(...) 0 # endif # if !defined(_LIBCPP_COMPILER_CLANG_BASED) && __cplusplus < 201103L @@ -274,64 +224,17 @@ // easier to grep for target specific flags once the feature is complete. # if !defined(_LIBCPP_ENABLE_EXPERIMENTAL) && !defined(_LIBCPP_BUILDING_LIBRARY) # define _LIBCPP_HAS_NO_INCOMPLETE_PSTL +# define _LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN +# define _LIBCPP_HAS_NO_EXPERIMENTAL_TZDB +# define _LIBCPP_HAS_NO_EXPERIMENTAL_SYNCSTREAM # endif -// Need to detect which libc we're using if we're on Linux. -# if defined(__linux__) -# include -# if defined(__GLIBC_PREREQ) -# define _LIBCPP_GLIBC_PREREQ(a, b) __GLIBC_PREREQ(a, b) -# else -# define _LIBCPP_GLIBC_PREREQ(a, b) 0 -# endif // defined(__GLIBC_PREREQ) -# endif // defined(__linux__) - # if defined(__MVS__) # include // for __NATIVE_ASCII_F # endif -# ifdef __LITTLE_ENDIAN__ -# if __LITTLE_ENDIAN__ -# define _LIBCPP_LITTLE_ENDIAN -# endif // __LITTLE_ENDIAN__ -# endif // __LITTLE_ENDIAN__ - -# ifdef __BIG_ENDIAN__ -# if __BIG_ENDIAN__ -# define _LIBCPP_BIG_ENDIAN -# endif // __BIG_ENDIAN__ -# endif // __BIG_ENDIAN__ - -# ifdef __BYTE_ORDER__ -# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -# define _LIBCPP_LITTLE_ENDIAN -# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -# define _LIBCPP_BIG_ENDIAN -# endif // __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -# endif // __BYTE_ORDER__ - -# ifdef __FreeBSD__ -# include -# include -# if _BYTE_ORDER == _LITTLE_ENDIAN -# define _LIBCPP_LITTLE_ENDIAN -# else // _BYTE_ORDER == _LITTLE_ENDIAN -# define _LIBCPP_BIG_ENDIAN -# endif // _BYTE_ORDER == _LITTLE_ENDIAN -# endif // __FreeBSD__ - -# if defined(__NetBSD__) || defined(__OpenBSD__) -# include -# if _BYTE_ORDER == _LITTLE_ENDIAN -# define _LIBCPP_LITTLE_ENDIAN -# else // _BYTE_ORDER == _LITTLE_ENDIAN -# define _LIBCPP_BIG_ENDIAN -# endif // _BYTE_ORDER == _LITTLE_ENDIAN -# endif // defined(__NetBSD__) || defined(__OpenBSD__) - # if defined(_WIN32) # define _LIBCPP_WIN32API -# define _LIBCPP_LITTLE_ENDIAN # define _LIBCPP_SHORT_WCHAR 1 // Both MinGW and native MSVC provide a "MSVC"-like environment # define _LIBCPP_MSVCRT_LIKE @@ -404,23 +307,6 @@ # define _LIBCPP_USING_DEV_RANDOM # endif -# if !defined(_LIBCPP_LITTLE_ENDIAN) && !defined(_LIBCPP_BIG_ENDIAN) -# include -# if __BYTE_ORDER == __LITTLE_ENDIAN -# define _LIBCPP_LITTLE_ENDIAN -# elif __BYTE_ORDER == __BIG_ENDIAN -# define _LIBCPP_BIG_ENDIAN -# else // __BYTE_ORDER == __BIG_ENDIAN -# error unable to determine endian -# endif -# endif // !defined(_LIBCPP_LITTLE_ENDIAN) && !defined(_LIBCPP_BIG_ENDIAN) - -# if __has_attribute(__no_sanitize__) && !defined(_LIBCPP_COMPILER_GCC) -# define _LIBCPP_NO_CFI __attribute__((__no_sanitize__("cfi"))) -# else -# define _LIBCPP_NO_CFI -# endif - # ifndef _LIBCPP_CXX03_LANG # define _LIBCPP_ALIGNOF(_Tp) alignof(_Tp) @@ -428,7 +314,7 @@ # define _ALIGNAS(x) alignas(x) # define _LIBCPP_NORETURN [[noreturn]] # define _NOEXCEPT noexcept -# define _NOEXCEPT_(x) noexcept(x) +# define _NOEXCEPT_(...) noexcept(__VA_ARGS__) # define _LIBCPP_CONSTEXPR constexpr # else @@ -440,7 +326,7 @@ # define _LIBCPP_HAS_NO_NOEXCEPT # define nullptr __nullptr # define _NOEXCEPT throw() -# define _NOEXCEPT_(x) +# define _NOEXCEPT_(...) # define static_assert(...) _Static_assert(__VA_ARGS__) # define decltype(...) __decltype(__VA_ARGS__) # define _LIBCPP_CONSTEXPR @@ -450,59 +336,32 @@ typedef __char32_t char32_t; # endif -# if !defined(__cpp_exceptions) || __cpp_exceptions < 199711L -# define _LIBCPP_HAS_NO_EXCEPTIONS -# endif - # define _LIBCPP_PREFERRED_ALIGNOF(_Tp) __alignof(_Tp) -# if defined(_LIBCPP_COMPILER_CLANG_BASED) - -# if defined(__APPLE__) && !defined(__i386__) && !defined(__x86_64__) && (!defined(__arm__) || __ARM_ARCH_7K__ >= 2) -# define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT -# endif - // Objective-C++ features (opt-in) -# if __has_feature(objc_arc) -# define _LIBCPP_HAS_OBJC_ARC -# endif +# if __has_feature(objc_arc) +# define _LIBCPP_HAS_OBJC_ARC +# endif -# if __has_feature(objc_arc_weak) -# define _LIBCPP_HAS_OBJC_ARC_WEAK -# endif +# if __has_feature(objc_arc_weak) +# define _LIBCPP_HAS_OBJC_ARC_WEAK +# endif -# if __has_extension(blocks) -# define _LIBCPP_HAS_EXTENSION_BLOCKS -# endif +# if __has_extension(blocks) +# define _LIBCPP_HAS_EXTENSION_BLOCKS +# endif -# if defined(_LIBCPP_HAS_EXTENSION_BLOCKS) && defined(__APPLE__) -# define _LIBCPP_HAS_BLOCKS_RUNTIME -# endif +# if defined(_LIBCPP_HAS_EXTENSION_BLOCKS) && defined(__APPLE__) +# define _LIBCPP_HAS_BLOCKS_RUNTIME +# endif -# if !__has_feature(address_sanitizer) -# define _LIBCPP_HAS_NO_ASAN -# endif +# if !__has_feature(address_sanitizer) +# define _LIBCPP_HAS_NO_ASAN +# endif -// Allow for build-time disabling of unsigned integer sanitization -# if __has_attribute(no_sanitize) -# define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK __attribute__((__no_sanitize__("unsigned-integer-overflow"))) -# endif +# define _LIBCPP_ALWAYS_INLINE __attribute__((__always_inline__)) -# define _LIBCPP_ALWAYS_INLINE __attribute__((__always_inline__)) - -# define _LIBCPP_DISABLE_EXTENSION_WARNING __extension__ - -# elif defined(_LIBCPP_COMPILER_GCC) - -# if !defined(__SANITIZE_ADDRESS__) -# define _LIBCPP_HAS_NO_ASAN -# endif - -# define _LIBCPP_ALWAYS_INLINE __attribute__((__always_inline__)) - -# define _LIBCPP_DISABLE_EXTENSION_WARNING __extension__ - -# endif // _LIBCPP_COMPILER_[CLANG|GCC] +# define _LIBCPP_DISABLE_EXTENSION_WARNING __extension__ # if defined(_LIBCPP_OBJECT_FORMAT_COFF) @@ -537,14 +396,11 @@ typedef __char32_t char32_t; # define _LIBCPP_EXPORTED_FROM_ABI __declspec(dllimport) # endif -# define _LIBCPP_TYPE_VIS _LIBCPP_DLL_VIS -# define _LIBCPP_FUNC_VIS _LIBCPP_DLL_VIS -# define _LIBCPP_EXCEPTION_ABI _LIBCPP_DLL_VIS # define _LIBCPP_HIDDEN # define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS # define _LIBCPP_TEMPLATE_VIS # define _LIBCPP_TEMPLATE_DATA_VIS -# define _LIBCPP_ENUM_VIS +# define _LIBCPP_TYPE_VISIBILITY_DEFAULT # else @@ -555,11 +411,8 @@ typedef __char32_t char32_t; # endif # define _LIBCPP_HIDDEN _LIBCPP_VISIBILITY("hidden") -# define _LIBCPP_FUNC_VIS _LIBCPP_VISIBILITY("default") -# define _LIBCPP_TYPE_VIS _LIBCPP_VISIBILITY("default") # define _LIBCPP_TEMPLATE_DATA_VIS _LIBCPP_VISIBILITY("default") # define _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_VISIBILITY("default") -# define _LIBCPP_EXCEPTION_ABI _LIBCPP_VISIBILITY("default") # define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS _LIBCPP_VISIBILITY("default") # define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS @@ -575,20 +428,17 @@ typedef __char32_t char32_t; # define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS # endif -# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) -# if __has_attribute(__type_visibility__) -# define _LIBCPP_TEMPLATE_VIS __attribute__((__type_visibility__("default"))) -# else -# define _LIBCPP_TEMPLATE_VIS __attribute__((__visibility__("default"))) -# endif +// GCC doesn't support the type_visibility attribute, so we have to keep the visibility attribute on templates +# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) && !__has_attribute(__type_visibility__) +# define _LIBCPP_TEMPLATE_VIS __attribute__((__visibility__("default"))) # else # define _LIBCPP_TEMPLATE_VIS # endif # if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) && __has_attribute(__type_visibility__) -# define _LIBCPP_ENUM_VIS __attribute__((__type_visibility__("default"))) +# define _LIBCPP_TYPE_VISIBILITY_DEFAULT __attribute__((__type_visibility__("default"))) # else -# define _LIBCPP_ENUM_VIS +# define _LIBCPP_TYPE_VISIBILITY_DEFAULT # endif # endif // defined(_LIBCPP_OBJECT_FORMAT_COFF) @@ -602,22 +452,71 @@ typedef __char32_t char32_t; # define _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION _LIBCPP_ALWAYS_INLINE # endif +# ifdef _LIBCPP_COMPILER_CLANG_BASED +# define _LIBCPP_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push") +# define _LIBCPP_DIAGNOSTIC_POP _Pragma("clang diagnostic pop") +# define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED(str) _Pragma(_LIBCPP_TOSTRING(clang diagnostic ignored str)) +# define _LIBCPP_GCC_DIAGNOSTIC_IGNORED(str) +# elif defined(_LIBCPP_COMPILER_GCC) +# define _LIBCPP_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push") +# define _LIBCPP_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop") +# define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED(str) +# define _LIBCPP_GCC_DIAGNOSTIC_IGNORED(str) _Pragma(_LIBCPP_TOSTRING(GCC diagnostic ignored str)) +# else +# define _LIBCPP_DIAGNOSTIC_PUSH +# define _LIBCPP_DIAGNOSTIC_POP +# define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED(str) +# define _LIBCPP_GCC_DIAGNOSTIC_IGNORED(str) +# endif + +# if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_FAST +# define _LIBCPP_HARDENING_SIG f +# elif _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_EXTENSIVE +# define _LIBCPP_HARDENING_SIG s +# elif _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG +# define _LIBCPP_HARDENING_SIG d +# else +# define _LIBCPP_HARDENING_SIG n // "none" +# endif + +# ifdef _LIBCPP_HAS_NO_EXCEPTIONS +# define _LIBCPP_EXCEPTIONS_SIG n +# else +# define _LIBCPP_EXCEPTIONS_SIG e +# endif + +# define _LIBCPP_ODR_SIGNATURE \ + _LIBCPP_CONCAT(_LIBCPP_CONCAT(_LIBCPP_HARDENING_SIG, _LIBCPP_EXCEPTIONS_SIG), _LIBCPP_VERSION) + // This macro marks a symbol as being hidden from libc++'s ABI. This is achieved // on two levels: // 1. The symbol is given hidden visibility, which ensures that users won't start exporting // symbols from their dynamic library by means of using the libc++ headers. This ensures // that those symbols stay private to the dynamic library in which it is defined. // -// 2. The symbol is given an ABI tag that changes with each version of libc++. This ensures -// that no ODR violation can arise from mixing two TUs compiled with different versions -// of libc++ where we would have changed the definition of a symbol. If the symbols shared -// the same name, the ODR would require that their definitions be token-by-token equivalent, -// which basically prevents us from being able to make any change to any function in our -// headers. Using this ABI tag ensures that the symbol name is "bumped" artificially at -// each release, which lets us change the definition of these symbols at our leisure. -// Note that historically, this has been achieved in various ways, including force-inlining -// all functions or giving internal linkage to all functions. Both these (previous) solutions -// suffer from drawbacks that lead notably to code bloat. +// 2. The symbol is given an ABI tag that encodes the ODR-relevant properties of the library. +// This ensures that no ODR violation can arise from mixing two TUs compiled with different +// versions or configurations of libc++ (such as exceptions vs no-exceptions). Indeed, if the +// program contains two definitions of a function, the ODR requires them to be token-by-token +// equivalent, and the linker is allowed to pick either definition and discard the other one. +// +// For example, if a program contains a copy of `vector::at()` compiled with exceptions enabled +// *and* a copy of `vector::at()` compiled with exceptions disabled (by means of having two TUs +// compiled with different settings), the two definitions are both visible by the linker and they +// have the same name, but they have a meaningfully different implementation (one throws an exception +// and the other aborts the program). This violates the ODR and makes the program ill-formed, and in +// practice what will happen is that the linker will pick one of the definitions at random and will +// discard the other one. This can quite clearly lead to incorrect program behavior. +// +// A similar reasoning holds for many other properties that are ODR-affecting. Essentially any +// property that causes the code of a function to differ from the code in another configuration +// can be considered ODR-affecting. In practice, we don't encode all such properties in the ABI +// tag, but we encode the ones that we think are most important: library version, exceptions, and +// hardening mode. +// +// Note that historically, solving this problem has been achieved in various ways, including +// force-inlining all functions or giving internal linkage to all functions. Both these previous +// solutions suffer from drawbacks that lead notably to code bloat. // // Note that we use _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION to ensure that we don't depend // on _LIBCPP_HIDE_FROM_ABI methods of classes explicitly instantiated in the dynamic library. @@ -631,22 +530,24 @@ typedef __char32_t char32_t; // the implementation of a virtual function in an ABI-incompatible way in the first place, // since that would be an ABI break anyway. Hence, the lack of ABI tag should not be noticeable. // +// The macro can be applied to record and enum types. When the tagged type is nested in +// a record this "parent" record needs to have the macro too. Another use case for applying +// this macro to records and unions is to apply an ABI tag to inline constexpr variables. +// This can be useful for inline variables that are implementation details which are expected +// to change in the future. +// // TODO: We provide a escape hatch with _LIBCPP_NO_ABI_TAG for folks who want to avoid increasing // the length of symbols with an ABI tag. In practice, we should remove the escape hatch and // use compression mangling instead, see https://github.com/itanium-cxx-abi/cxx-abi/issues/70. # ifndef _LIBCPP_NO_ABI_TAG # define _LIBCPP_HIDE_FROM_ABI \ _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION \ - __attribute__((__abi_tag__(_LIBCPP_TOSTRING(_LIBCPP_VERSIONED_IDENTIFIER)))) + __attribute__((__abi_tag__(_LIBCPP_TOSTRING(_LIBCPP_ODR_SIGNATURE)))) # else # define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION # endif # define _LIBCPP_HIDE_FROM_ABI_VIRTUAL _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION -// This macro provides a HIDE_FROM_ABI equivalent that can be applied to extern -// "C" function, as those lack mangling. -# define _LIBCPP_HIDE_FROM_ABI_C _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION - # ifdef _LIBCPP_BUILDING_LIBRARY # if _LIBCPP_ABI_VERSION > 1 # define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 _LIBCPP_HIDE_FROM_ABI @@ -657,65 +558,76 @@ typedef __char32_t char32_t; # define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 _LIBCPP_HIDE_FROM_ABI # endif -// Just so we can migrate to the new macros gradually. -# define _LIBCPP_INLINE_VISIBILITY _LIBCPP_HIDE_FROM_ABI +// TODO: Remove this workaround once we drop support for Clang 16 +# if __has_warning("-Wc++23-extensions") +# define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED_CXX23_EXTENSION _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++23-extensions") +# else +# define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED_CXX23_EXTENSION _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++2b-extensions") +# endif + +// Clang modules take a significant compile time hit when pushing and popping diagnostics. +// Since all the headers are marked as system headers in the modulemap, we can simply disable this +// pushing and popping when building with clang modules. +# if !__has_feature(modules) +# define _LIBCPP_PUSH_EXTENSION_DIAGNOSTICS \ + _LIBCPP_DIAGNOSTIC_PUSH \ + _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++11-extensions") \ + _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++14-extensions") \ + _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++17-extensions") \ + _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++20-extensions") \ + _LIBCPP_CLANG_DIAGNOSTIC_IGNORED_CXX23_EXTENSION \ + _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wc++14-extensions") \ + _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wc++17-extensions") \ + _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wc++20-extensions") \ + _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wc++23-extensions") +# define _LIBCPP_POP_EXTENSION_DIAGNOSTICS _LIBCPP_DIAGNOSTIC_POP +# else +# define _LIBCPP_PUSH_EXTENSION_DIAGNOSTICS +# define _LIBCPP_POP_EXTENSION_DIAGNOSTICS +# endif // Inline namespaces are available in Clang/GCC/MSVC regardless of C++ dialect. // clang-format off -# define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { inline namespace _LIBCPP_ABI_NAMESPACE { -# define _LIBCPP_END_NAMESPACE_STD }} -# define _VSTD std +# define _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_PUSH_EXTENSION_DIAGNOSTICS \ + namespace _LIBCPP_TYPE_VISIBILITY_DEFAULT std { \ + inline namespace _LIBCPP_ABI_NAMESPACE { +# define _LIBCPP_END_NAMESPACE_STD }} _LIBCPP_POP_EXTENSION_DIAGNOSTICS -_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD +#ifdef _LIBCPP_ABI_NO_FILESYSTEM_INLINE_NAMESPACE +# define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM _LIBCPP_BEGIN_NAMESPACE_STD namespace filesystem { +# define _LIBCPP_END_NAMESPACE_FILESYSTEM } _LIBCPP_END_NAMESPACE_STD +#else +# define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM _LIBCPP_BEGIN_NAMESPACE_STD \ + inline namespace __fs { namespace filesystem { -# if _LIBCPP_STD_VER >= 17 -# define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM \ - _LIBCPP_BEGIN_NAMESPACE_STD inline namespace __fs { namespace filesystem { -# else -# define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM \ - _LIBCPP_BEGIN_NAMESPACE_STD namespace __fs { namespace filesystem { -# endif +# define _LIBCPP_END_NAMESPACE_FILESYSTEM }} _LIBCPP_END_NAMESPACE_STD +#endif -# define _LIBCPP_END_NAMESPACE_FILESYSTEM _LIBCPP_END_NAMESPACE_STD }} // clang-format on -# define _VSTD_FS std::__fs::filesystem - # if __has_attribute(__enable_if__) # define _LIBCPP_PREFERRED_OVERLOAD __attribute__((__enable_if__(true, ""))) # endif -# ifndef __SIZEOF_INT128__ +# if !defined(__SIZEOF_INT128__) || defined(_MSC_VER) # define _LIBCPP_HAS_NO_INT128 # endif -# if __has_attribute(__malloc__) -# define _LIBCPP_NOALIAS __attribute__((__malloc__)) -# else -# define _LIBCPP_NOALIAS -# endif - -# if __has_attribute(__using_if_exists__) -# define _LIBCPP_USING_IF_EXISTS __attribute__((__using_if_exists__)) -# else -# define _LIBCPP_USING_IF_EXISTS -# endif - # ifdef _LIBCPP_CXX03_LANG # define _LIBCPP_DECLARE_STRONG_ENUM(x) \ - struct _LIBCPP_TYPE_VIS x { \ + struct _LIBCPP_EXPORTED_FROM_ABI x { \ enum __lx // clang-format off # define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x) \ __lx __v_; \ - _LIBCPP_INLINE_VISIBILITY x(__lx __v) : __v_(__v) {} \ - _LIBCPP_INLINE_VISIBILITY explicit x(int __v) : __v_(static_cast<__lx>(__v)) {} \ - _LIBCPP_INLINE_VISIBILITY operator int() const { return __v_; } \ + _LIBCPP_HIDE_FROM_ABI x(__lx __v) : __v_(__v) {} \ + _LIBCPP_HIDE_FROM_ABI explicit x(int __v) : __v_(static_cast<__lx>(__v)) {} \ + _LIBCPP_HIDE_FROM_ABI operator int() const { return __v_; } \ }; // clang-format on # else // _LIBCPP_CXX03_LANG -# define _LIBCPP_DECLARE_STRONG_ENUM(x) enum class _LIBCPP_ENUM_VIS x +# define _LIBCPP_DECLARE_STRONG_ENUM(x) enum class x # define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x) # endif // _LIBCPP_CXX03_LANG @@ -787,6 +699,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD # define _LIBCPP_DEPRECATED_(m) # endif +# if _LIBCPP_STD_VER < 20 +# define _LIBCPP_DEPRECATED_ATOMIC_SYNC \ + _LIBCPP_DEPRECATED_("The C++20 synchronization library has been deprecated prior to C++20. Please update to " \ + "using -std=c++20 if you need to use these facilities.") +# else +# define _LIBCPP_DEPRECATED_ATOMIC_SYNC /* nothing */ +# endif + # if !defined(_LIBCPP_CXX03_LANG) # define _LIBCPP_DEPRECATED_IN_CXX11 _LIBCPP_DEPRECATED # else @@ -811,11 +731,17 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD # define _LIBCPP_DEPRECATED_IN_CXX20 # endif -#if _LIBCPP_STD_VER >= 23 -# define _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_DEPRECATED -#else -# define _LIBCPP_DEPRECATED_IN_CXX23 -#endif +# if _LIBCPP_STD_VER >= 23 +# define _LIBCPP_DEPRECATED_IN_CXX23 _LIBCPP_DEPRECATED +# else +# define _LIBCPP_DEPRECATED_IN_CXX23 +# endif + +# if _LIBCPP_STD_VER >= 26 +# define _LIBCPP_DEPRECATED_IN_CXX26 _LIBCPP_DEPRECATED +# else +# define _LIBCPP_DEPRECATED_IN_CXX26 +# endif # if !defined(_LIBCPP_HAS_NO_CHAR8_T) # define _LIBCPP_DEPRECATED_WITH_CHAR8_T _LIBCPP_DEPRECATED @@ -870,45 +796,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD # define _LIBCPP_CONSTEXPR_SINCE_CXX23 # endif -# if __has_cpp_attribute(nodiscard) -# define _LIBCPP_NODISCARD [[__nodiscard__]] -# else -// We can't use GCC's [[gnu::warn_unused_result]] and -// __attribute__((warn_unused_result)), because GCC does not silence them via -// (void) cast. -# define _LIBCPP_NODISCARD -# endif - -// _LIBCPP_NODISCARD_EXT may be used to apply [[nodiscard]] to entities not -// specified as such as an extension. -# if !defined(_LIBCPP_DISABLE_NODISCARD_EXT) -# define _LIBCPP_NODISCARD_EXT _LIBCPP_NODISCARD -# else -# define _LIBCPP_NODISCARD_EXT -# endif - -# if _LIBCPP_STD_VER >= 20 || !defined(_LIBCPP_DISABLE_NODISCARD_EXT) -# define _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_NODISCARD -# else -# define _LIBCPP_NODISCARD_AFTER_CXX17 -# endif - -# if __has_attribute(__no_destroy__) -# define _LIBCPP_NO_DESTROY __attribute__((__no_destroy__)) -# else -# define _LIBCPP_NO_DESTROY -# endif - -# ifndef _LIBCPP_HAS_NO_ASAN - extern "C" _LIBCPP_FUNC_VIS void - __sanitizer_annotate_contiguous_container(const void*, const void*, const void*, const void*); -# endif - -// Try to find out if RTTI is disabled. -# if !defined(__cpp_rtti) || __cpp_rtti < 199711L -# define _LIBCPP_HAS_NO_RTTI -# endif - # ifndef _LIBCPP_WEAK # define _LIBCPP_WEAK __attribute__((__weak__)) # endif @@ -930,8 +817,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD defined(__APPLE__) || \ defined(__MVS__) || \ defined(_AIX) || \ - defined(__EMSCRIPTEN__) || \ - defined(__COSMOPOLITAN__) + defined(__EMSCRIPTEN__) // clang-format on # define _LIBCPP_HAS_THREAD_API_PTHREAD # elif defined(__Fuchsia__) @@ -986,7 +872,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD // clang-format off # if (defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && defined(__GLIBC__)) || \ (defined(_LIBCPP_HAS_THREAD_API_C11) && defined(__Fuchsia__)) || \ - defined(_LIBCPP_HAS_THREAD_API_WIN32) || defined(__COSMOPOLITAN__) + defined(_LIBCPP_HAS_THREAD_API_WIN32) // clang-format on # define _LIBCPP_HAS_TRIVIAL_MUTEX_DESTRUCTION # endif @@ -1003,13 +889,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD # define _LIBCPP_HAS_TRIVIAL_CONDVAR_DESTRUCTION # endif -// Some systems do not provide gets() in their C library, for security reasons. -# if defined(_LIBCPP_MSVCRT) || (defined(__FreeBSD_version) && __FreeBSD_version >= 1300043) || defined(__OpenBSD__) -# define _LIBCPP_C_HAS_NO_GETS -# endif - # if defined(__BIONIC__) || defined(__NuttX__) || defined(__Fuchsia__) || defined(__wasi__) || \ - defined(_LIBCPP_HAS_MUSL_LIBC) || defined(__OpenBSD__) || defined(__COSMOPOLITAN__) + defined(_LIBCPP_HAS_MUSL_LIBC) || defined(__OpenBSD__) # define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE # endif @@ -1026,13 +907,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD # ifndef _LIBCPP_ATOMIC_FLAG_TYPE # define _LIBCPP_ATOMIC_FLAG_TYPE bool # endif -# ifdef _LIBCPP_FREESTANDING -# define _LIBCPP_ATOMIC_ONLY_USE_BUILTINS -# endif # endif -# ifndef _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK -# define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK +# if defined(__FreeBSD__) && defined(__clang__) && __has_attribute(__no_thread_safety_analysis__) +# define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS __attribute__((__no_thread_safety_analysis__)) +# else +# define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS # endif # if defined(_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS) @@ -1053,10 +933,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD # define _LIBCPP_THREAD_SAFETY_ANNOTATION(x) # endif -#ifdef _LIBCPP_CONSTINIT -#undef _LIBCPP_CONSTINIT // TODO(jart): wut -#endif - # if _LIBCPP_STD_VER >= 20 # define _LIBCPP_CONSTINIT constinit # elif __has_attribute(__require_constant_initialization__) @@ -1065,43 +941,21 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD # define _LIBCPP_CONSTINIT # endif -# if __has_attribute(__diagnose_if__) && !defined(_LIBCPP_DISABLE_ADDITIONAL_DIAGNOSTICS) -# define _LIBCPP_DIAGNOSE_WARNING(...) __attribute__((__diagnose_if__(__VA_ARGS__, "warning"))) +# if defined(__CUDACC__) || defined(__CUDA_ARCH__) || defined(__CUDA_LIBDEVICE__) +// The CUDA SDK contains an unfortunate definition for the __noinline__ macro, +// which breaks the regular __attribute__((__noinline__)) syntax. Therefore, +// when compiling for CUDA we use the non-underscored version of the noinline +// attribute. +// +// This is a temporary workaround and we still expect the CUDA SDK team to solve +// this issue properly in the SDK headers. +// +// See https://github.com/llvm/llvm-project/pull/73838 for more details. +# define _LIBCPP_NOINLINE __attribute__((noinline)) +# elif __has_attribute(__noinline__) +# define _LIBCPP_NOINLINE __attribute__((__noinline__)) # else -# define _LIBCPP_DIAGNOSE_WARNING(...) -# endif - -// Use a function like macro to imply that it must be followed by a semicolon -# if __has_cpp_attribute(fallthrough) -# define _LIBCPP_FALLTHROUGH() [[fallthrough]] -# elif __has_attribute(__fallthrough__) -# define _LIBCPP_FALLTHROUGH() __attribute__((__fallthrough__)) -# else -# define _LIBCPP_FALLTHROUGH() ((void)0) -# endif - -# if __has_cpp_attribute(_Clang::__lifetimebound__) -# define _LIBCPP_LIFETIMEBOUND [[_Clang::__lifetimebound__]] -# else -# define _LIBCPP_LIFETIMEBOUND -# endif - -# if __has_attribute(__nodebug__) -# define _LIBCPP_NODEBUG __attribute__((__nodebug__)) -# else -# define _LIBCPP_NODEBUG -# endif - -# if __has_attribute(__standalone_debug__) -# define _LIBCPP_STANDALONE_DEBUG __attribute__((__standalone_debug__)) -# else -# define _LIBCPP_STANDALONE_DEBUG -# endif - -# if __has_attribute(__preferred_name__) -# define _LIBCPP_PREFERRED_NAME(x) __attribute__((__preferred_name__(x))) -# else -# define _LIBCPP_PREFERRED_NAME(x) +# define _LIBCPP_NOINLINE # endif // We often repeat things just for handling wide characters in the library. @@ -1114,31 +968,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD # define _LIBCPP_IF_WIDE_CHARACTERS(...) __VA_ARGS__ # endif -# if defined(_LIBCPP_ABI_MICROSOFT) && __has_declspec_attribute(empty_bases) -# define _LIBCPP_DECLSPEC_EMPTY_BASES __declspec(empty_bases) -# else -# define _LIBCPP_DECLSPEC_EMPTY_BASES -# endif - -# if defined(_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES) -# define _LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR -# define _LIBCPP_ENABLE_CXX17_REMOVED_BINDERS -# define _LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE -# define _LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS -# define _LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION -# endif // _LIBCPP_ENABLE_CXX17_REMOVED_FEATURES - -# if defined(_LIBCPP_ENABLE_CXX20_REMOVED_FEATURES) -# define _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS -# define _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_VOID_SPECIALIZATION -# define _LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS -# define _LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS -# define _LIBCPP_ENABLE_CXX20_REMOVED_RAW_STORAGE_ITERATOR -# define _LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS -# endif // _LIBCPP_ENABLE_CXX20_REMOVED_FEATURES - -# define _LIBCPP_PUSH_MACROS _Pragma("push_macro(\"min\")") _Pragma("push_macro(\"max\")") -# define _LIBCPP_POP_MACROS _Pragma("pop_macro(\"min\")") _Pragma("pop_macro(\"max\")") +// clang-format off +# define _LIBCPP_PUSH_MACROS _Pragma("push_macro(\"min\")") _Pragma("push_macro(\"max\")") _Pragma("push_macro(\"refresh\")") _Pragma("push_macro(\"move\")") _Pragma("push_macro(\"erase\")") +# define _LIBCPP_POP_MACROS _Pragma("pop_macro(\"min\")") _Pragma("pop_macro(\"max\")") _Pragma("pop_macro(\"refresh\")") _Pragma("pop_macro(\"move\")") _Pragma("pop_macro(\"erase\")") +// clang-format on # ifndef _LIBCPP_NO_AUTO_LINK # if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_BUILDING_LIBRARY) @@ -1155,34 +988,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD // // Not all platforms support this, but it helps avoid fd-leaks on platforms that // do. -# if defined(__BIONIC__) || defined(__COSMOPOLITAN__) +# if defined(__BIONIC__) # define _LIBCPP_FOPEN_CLOEXEC_MODE "e" # else # define _LIBCPP_FOPEN_CLOEXEC_MODE # endif -// Support for _FILE_OFFSET_BITS=64 landed gradually in Android, so the full set -// of functions used in cstdio may not be available for low API levels when -// using 64-bit file offsets on LP32. -# if defined(__BIONIC__) && defined(__USE_FILE_OFFSET64) && __ANDROID_API__ < 24 -# define _LIBCPP_HAS_NO_FGETPOS_FSETPOS -# endif - -# if __has_attribute(__init_priority__) -# define _LIBCPP_INIT_PRIORITY_MAX __attribute__((__init_priority__(100))) -# else -# define _LIBCPP_INIT_PRIORITY_MAX -# endif - -# if __has_attribute(__format__) -// The attribute uses 1-based indices for ordinary and static member functions. -// The attribute uses 2-based indices for non-static member functions. -# define _LIBCPP_ATTRIBUTE_FORMAT(archetype, format_string_index, first_format_arg_index) \ - __attribute__((__format__(archetype, format_string_index, first_format_arg_index))) -# else -# define _LIBCPP_ATTRIBUTE_FORMAT(archetype, format_string_index, first_format_arg_index) /* nothing */ -# endif - # if __has_cpp_attribute(msvc::no_unique_address) // MSVC implements [[no_unique_address]] as a silent no-op currently. // (If/when MSVC breaks its C++ ABI, it will be changed to work as intended.) @@ -1205,37 +1016,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD // the ABI inconsistent. # endif -# ifdef _LIBCPP_COMPILER_CLANG_BASED -# define _LIBCPP_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push") -# define _LIBCPP_DIAGNOSTIC_POP _Pragma("clang diagnostic pop") -# define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED(str) _Pragma(_LIBCPP_TOSTRING(clang diagnostic ignored str)) -# define _LIBCPP_GCC_DIAGNOSTIC_IGNORED(str) -# elif defined(_LIBCPP_COMPILER_GCC) -# define _LIBCPP_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push") -# define _LIBCPP_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop") -# define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED(str) -# define _LIBCPP_GCC_DIAGNOSTIC_IGNORED(str) _Pragma(_LIBCPP_TOSTRING(GCC diagnostic ignored str)) -# else -# define _LIBCPP_DIAGNOSTIC_PUSH -# define _LIBCPP_DIAGNOSTIC_POP -# define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED(str) -# define _LIBCPP_GCC_DIAGNOSTIC_IGNORED(str) -# endif - -# if defined(_AIX) && !defined(_LIBCPP_COMPILER_GCC) -# define _LIBCPP_PACKED_BYTE_FOR_AIX _Pragma("pack(1)") -# define _LIBCPP_PACKED_BYTE_FOR_AIX_END _Pragma("pack(pop)") -# else -# define _LIBCPP_PACKED_BYTE_FOR_AIX /* empty */ -# define _LIBCPP_PACKED_BYTE_FOR_AIX_END /* empty */ -# endif - -# if __has_attribute(__packed__) -# define _LIBCPP_PACKED __attribute__((__packed__)) -# else -# define _LIBCPP_PACKED -# endif - // c8rtomb() and mbrtoc8() were added in C++20 and C23. Support for these // functions is gradually being added to existing C libraries. The conditions // below check for known C library versions and conditions under which these @@ -1277,21 +1057,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD # define _LIBCPP_WORKAROUND_OBJCXX_COMPILER_INTRINSICS # endif -// TODO: Make this a proper configuration option -#define _PSTL_PAR_BACKEND_SERIAL - -#define _PSTL_PRAGMA(x) _Pragma(# x) +# define _PSTL_PRAGMA(x) _Pragma(#x) // Enable SIMD for compilers that support OpenMP 4.0 -#if (defined(_OPENMP) && _OPENMP >= 201307) +# if (defined(_OPENMP) && _OPENMP >= 201307) -# define _PSTL_UDR_PRESENT -# define _PSTL_PRAGMA_SIMD _PSTL_PRAGMA(omp simd) -# define _PSTL_PRAGMA_DECLARE_SIMD _PSTL_PRAGMA(omp declare simd) -# define _PSTL_PRAGMA_SIMD_REDUCTION(PRM) _PSTL_PRAGMA(omp simd reduction(PRM)) -# define _PSTL_PRAGMA_SIMD_SCAN(PRM) _PSTL_PRAGMA(omp simd reduction(inscan, PRM)) -# define _PSTL_PRAGMA_SIMD_INCLUSIVE_SCAN(PRM) _PSTL_PRAGMA(omp scan inclusive(PRM)) -# define _PSTL_PRAGMA_SIMD_EXCLUSIVE_SCAN(PRM) _PSTL_PRAGMA(omp scan exclusive(PRM)) +# define _PSTL_UDR_PRESENT +# define _PSTL_PRAGMA_SIMD _PSTL_PRAGMA(omp simd) +# define _PSTL_PRAGMA_DECLARE_SIMD _PSTL_PRAGMA(omp declare simd) +# define _PSTL_PRAGMA_SIMD_REDUCTION(PRM) _PSTL_PRAGMA(omp simd reduction(PRM)) +# define _PSTL_PRAGMA_SIMD_SCAN(PRM) _PSTL_PRAGMA(omp simd reduction(inscan, PRM)) +# define _PSTL_PRAGMA_SIMD_INCLUSIVE_SCAN(PRM) _PSTL_PRAGMA(omp scan inclusive(PRM)) +# define _PSTL_PRAGMA_SIMD_EXCLUSIVE_SCAN(PRM) _PSTL_PRAGMA(omp scan exclusive(PRM)) // Declaration of reduction functor, where // NAME - the name of the functor @@ -1300,22 +1077,151 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD // omp_out - refers to the final value of the combiner operator // omp_priv - refers to the private copy of the initial value // omp_orig - refers to the original variable to be reduced -# define _PSTL_PRAGMA_DECLARE_REDUCTION(NAME, OP) \ - _PSTL_PRAGMA(omp declare reduction(NAME:OP : omp_out(omp_in)) initializer(omp_priv = omp_orig)) +# define _PSTL_PRAGMA_DECLARE_REDUCTION(NAME, OP) \ + _PSTL_PRAGMA(omp declare reduction(NAME:OP : omp_out(omp_in)) initializer(omp_priv = omp_orig)) -#else // (defined(_OPENMP) && _OPENMP >= 201307) +# elif defined(_LIBCPP_COMPILER_CLANG_BASED) -# define _PSTL_PRAGMA_SIMD -# define _PSTL_PRAGMA_DECLARE_SIMD -# define _PSTL_PRAGMA_SIMD_REDUCTION(PRM) -# define _PSTL_PRAGMA_SIMD_SCAN(PRM) -# define _PSTL_PRAGMA_SIMD_INCLUSIVE_SCAN(PRM) -# define _PSTL_PRAGMA_SIMD_EXCLUSIVE_SCAN(PRM) -# define _PSTL_PRAGMA_DECLARE_REDUCTION(NAME, OP) +# define _PSTL_PRAGMA_SIMD _Pragma("clang loop vectorize(enable) interleave(enable)") +# define _PSTL_PRAGMA_DECLARE_SIMD +# define _PSTL_PRAGMA_SIMD_REDUCTION(PRM) _Pragma("clang loop vectorize(enable) interleave(enable)") +# define _PSTL_PRAGMA_SIMD_SCAN(PRM) _Pragma("clang loop vectorize(enable) interleave(enable)") +# define _PSTL_PRAGMA_SIMD_INCLUSIVE_SCAN(PRM) +# define _PSTL_PRAGMA_SIMD_EXCLUSIVE_SCAN(PRM) +# define _PSTL_PRAGMA_DECLARE_REDUCTION(NAME, OP) -#endif // (defined(_OPENMP) && _OPENMP >= 201307) +# else // (defined(_OPENMP) && _OPENMP >= 201307) -#define _PSTL_USE_NONTEMPORAL_STORES_IF_ALLOWED +# define _PSTL_PRAGMA_SIMD +# define _PSTL_PRAGMA_DECLARE_SIMD +# define _PSTL_PRAGMA_SIMD_REDUCTION(PRM) +# define _PSTL_PRAGMA_SIMD_SCAN(PRM) +# define _PSTL_PRAGMA_SIMD_INCLUSIVE_SCAN(PRM) +# define _PSTL_PRAGMA_SIMD_EXCLUSIVE_SCAN(PRM) +# define _PSTL_PRAGMA_DECLARE_REDUCTION(NAME, OP) + +# endif // (defined(_OPENMP) && _OPENMP >= 201307) + +# define _PSTL_USE_NONTEMPORAL_STORES_IF_ALLOWED + +// Optional attributes - these are useful for a better QoI, but not required to be available + +# if __has_attribute(__no_sanitize__) && !defined(_LIBCPP_COMPILER_GCC) +# define _LIBCPP_NO_CFI __attribute__((__no_sanitize__("cfi"))) +# else +# define _LIBCPP_NO_CFI +# endif + +# if __has_attribute(__malloc__) +# define _LIBCPP_NOALIAS __attribute__((__malloc__)) +# else +# define _LIBCPP_NOALIAS +# endif + +# if __has_attribute(__using_if_exists__) +# define _LIBCPP_USING_IF_EXISTS __attribute__((__using_if_exists__)) +# else +# define _LIBCPP_USING_IF_EXISTS +# endif + +# if __has_cpp_attribute(__nodiscard__) +# define _LIBCPP_NODISCARD [[__nodiscard__]] +# else +// We can't use GCC's [[gnu::warn_unused_result]] and +// __attribute__((warn_unused_result)), because GCC does not silence them via +// (void) cast. +# define _LIBCPP_NODISCARD +# endif + +# if __has_attribute(__no_destroy__) +# define _LIBCPP_NO_DESTROY __attribute__((__no_destroy__)) +# else +# define _LIBCPP_NO_DESTROY +# endif + +# if __has_attribute(__diagnose_if__) +# define _LIBCPP_DIAGNOSE_WARNING(...) __attribute__((__diagnose_if__(__VA_ARGS__, "warning"))) +# else +# define _LIBCPP_DIAGNOSE_WARNING(...) +# endif + +// Use a function like macro to imply that it must be followed by a semicolon +# if __has_cpp_attribute(fallthrough) +# define _LIBCPP_FALLTHROUGH() [[fallthrough]] +# elif __has_attribute(__fallthrough__) +# define _LIBCPP_FALLTHROUGH() __attribute__((__fallthrough__)) +# else +# define _LIBCPP_FALLTHROUGH() ((void)0) +# endif + +# if __has_cpp_attribute(_Clang::__lifetimebound__) +# define _LIBCPP_LIFETIMEBOUND [[_Clang::__lifetimebound__]] +# else +# define _LIBCPP_LIFETIMEBOUND +# endif + +# if __has_attribute(__nodebug__) +# define _LIBCPP_NODEBUG __attribute__((__nodebug__)) +# else +# define _LIBCPP_NODEBUG +# endif + +# if __has_attribute(__standalone_debug__) +# define _LIBCPP_STANDALONE_DEBUG __attribute__((__standalone_debug__)) +# else +# define _LIBCPP_STANDALONE_DEBUG +# endif + +# if __has_attribute(__preferred_name__) +# define _LIBCPP_PREFERRED_NAME(x) __attribute__((__preferred_name__(x))) +# else +# define _LIBCPP_PREFERRED_NAME(x) +# endif + +# if __has_attribute(__no_sanitize__) +# define _LIBCPP_NO_SANITIZE(...) __attribute__((__no_sanitize__(__VA_ARGS__))) +# else +# define _LIBCPP_NO_SANITIZE(...) +# endif + +# if __has_attribute(__init_priority__) +# define _LIBCPP_INIT_PRIORITY_MAX __attribute__((__init_priority__(100))) +# else +# define _LIBCPP_INIT_PRIORITY_MAX +# endif + +# if __has_attribute(__format__) +// The attribute uses 1-based indices for ordinary and static member functions. +// The attribute uses 2-based indices for non-static member functions. +# define _LIBCPP_ATTRIBUTE_FORMAT(archetype, format_string_index, first_format_arg_index) \ + __attribute__((__format__(archetype, format_string_index, first_format_arg_index))) +# else +# define _LIBCPP_ATTRIBUTE_FORMAT(archetype, format_string_index, first_format_arg_index) /* nothing */ +# endif + +# if __has_attribute(__packed__) +# define _LIBCPP_PACKED __attribute__((__packed__)) +# else +# define _LIBCPP_PACKED +# endif + +# if defined(_LIBCPP_ABI_MICROSOFT) && __has_declspec_attribute(empty_bases) +# define _LIBCPP_DECLSPEC_EMPTY_BASES __declspec(empty_bases) +# else +# define _LIBCPP_DECLSPEC_EMPTY_BASES +# endif + +// Allow for build-time disabling of unsigned integer sanitization +# if __has_attribute(no_sanitize) && !defined(_LIBCPP_COMPILER_GCC) +# define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK __attribute__((__no_sanitize__("unsigned-integer-overflow"))) +# else +# define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK +# endif + +// Clang-18 has support for deducing this, but it does not set the FTM. +# if defined(__cpp_explicit_this_parameter) || (defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 1800) +# define _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER +# endif #endif // __cplusplus diff --git a/third_party/libcxx/__config_site b/third_party/libcxx/__config_site index 82b354a8f..008419465 100644 --- a/third_party/libcxx/__config_site +++ b/third_party/libcxx/__config_site @@ -35,6 +35,12 @@ __static_yoink("__demangle"); #define _LIBCPP_NO_VCRUNTIME #define _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION 1 #define _LIBCPP_REMOVE_TRANSITIVE_INCLUDES +#define _LIBCPP_HAS_THREAD_API_PTHREAD +#define _LIBCPP_NO_VCRUNTIME +#define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE +#define _LIBCPP_HAS_CLOCK_GETTIME + +#define _LIBCPP_HARDENING_MODE_DEFAULT 2 #ifdef MODE_DBG #define _LIBCPP_ENABLE_DEBUG_MODE @@ -44,8 +50,7 @@ __static_yoink("__demangle"); #endif // PSTL backends -#define _LIBCPP_PSTL_CPU_BACKEND_SERIAL -#define _LIBCPP_PSTL_CPU_BACKEND_THREAD +#define _LIBCPP_PSTL_BACKEND_STD_THREAD // __USE_MINGW_ANSI_STDIO gets redefined on MinGW #ifdef __clang__ diff --git a/third_party/libcxx/__configuration/abi.h b/third_party/libcxx/__configuration/abi.h new file mode 100644 index 000000000..710548d90 --- /dev/null +++ b/third_party/libcxx/__configuration/abi.h @@ -0,0 +1,159 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONFIGURATION_ABI_H +#define _LIBCPP___CONFIGURATION_ABI_H + +#include <__config_site> +#include <__configuration/compiler.h> +#include <__configuration/platform.h> + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +# pragma GCC system_header +#endif + +#if _LIBCPP_ABI_VERSION >= 2 +// Change short string representation so that string data starts at offset 0, +// improving its alignment in some cases. +# define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT +// Fix deque iterator type in order to support incomplete types. +# define _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE +// Fix undefined behavior in how std::list stores its linked nodes. +# define _LIBCPP_ABI_LIST_REMOVE_NODE_POINTER_UB +// Fix undefined behavior in how __tree stores its end and parent nodes. +# define _LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB +// Fix undefined behavior in how __hash_table stores its pointer types. +# define _LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB +# define _LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB +# define _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE +// Override the default return value of exception::what() for bad_function_call::what() +// with a string that is specific to bad_function_call (see http://wg21.link/LWG2233). +// This is an ABI break on platforms that sign and authenticate vtable function pointers +// because it changes the mangling of the virtual function located in the vtable, which +// changes how it gets signed. +# define _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE +// Enable optimized version of __do_get_(un)signed which avoids redundant copies. +# define _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET +// Give reverse_iterator one data member of type T, not two. +// Also, in C++17 and later, don't derive iterator types from std::iterator. +# define _LIBCPP_ABI_NO_ITERATOR_BASES +// Use the smallest possible integer type to represent the index of the variant. +// Previously libc++ used "unsigned int" exclusively. +# define _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION +// Unstable attempt to provide a more optimized std::function +# define _LIBCPP_ABI_OPTIMIZED_FUNCTION +// All the regex constants must be distinct and nonzero. +# define _LIBCPP_ABI_REGEX_CONSTANTS_NONZERO +// Re-worked external template instantiations for std::string with a focus on +// performance and fast-path inlining. +# define _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION +// Enable clang::trivial_abi on std::unique_ptr. +# define _LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI +// Enable clang::trivial_abi on std::shared_ptr and std::weak_ptr +# define _LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI +// std::random_device holds some state when it uses an implementation that gets +// entropy from a file (see _LIBCPP_USING_DEV_RANDOM). When switching from this +// implementation to another one on a platform that has already shipped +// std::random_device, one needs to retain the same object layout to remain ABI +// compatible. This switch removes these workarounds for platforms that don't care +// about ABI compatibility. +# define _LIBCPP_ABI_NO_RANDOM_DEVICE_COMPATIBILITY_LAYOUT +// Don't export the legacy __basic_string_common class and its methods from the built library. +# define _LIBCPP_ABI_DO_NOT_EXPORT_BASIC_STRING_COMMON +// Don't export the legacy __vector_base_common class and its methods from the built library. +# define _LIBCPP_ABI_DO_NOT_EXPORT_VECTOR_BASE_COMMON +// According to the Standard, `bitset::operator[] const` returns bool +# define _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL +// Fix the implementation of CityHash used for std::hash. +// This is an ABI break because `std::hash` will return a different result, +// which means that hashing the same object in translation units built against +// different versions of libc++ can return inconsistent results. This is especially +// tricky since std::hash is used in the implementation of unordered containers. +// +// The incorrect implementation of CityHash has the problem that it drops some +// bits on the floor. +# define _LIBCPP_ABI_FIX_CITYHASH_IMPLEMENTATION +// Remove the base 10 implementation of std::to_chars from the dylib. +// The implementation moved to the header, but we still export the symbols from +// the dylib for backwards compatibility. +# define _LIBCPP_ABI_DO_NOT_EXPORT_TO_CHARS_BASE_10 +// Define std::array/std::string_view iterators to be __wrap_iters instead of raw +// pointers, which prevents people from relying on a non-portable implementation +// detail. This is especially useful because enabling bounded iterators hardening +// requires code not to make these assumptions. +# define _LIBCPP_ABI_USE_WRAP_ITER_IN_STD_ARRAY +# define _LIBCPP_ABI_USE_WRAP_ITER_IN_STD_STRING_VIEW +// Dont' add an inline namespace for `std::filesystem` +# define _LIBCPP_ABI_NO_FILESYSTEM_INLINE_NAMESPACE +// std::basic_ios uses WEOF to indicate that the fill value is +// uninitialized. However, on platforms where the size of char_type is +// equal to or greater than the size of int_type and char_type is unsigned, +// std::char_traits::eq_int_type() cannot distinguish between WEOF +// and WCHAR_MAX. This ABI setting determines whether we should instead track whether the fill +// value has been initialized using a separate boolean, which changes the ABI. +# define _LIBCPP_ABI_IOS_ALLOW_ARBITRARY_FILL_VALUE +// Make a std::pair of trivially copyable types trivially copyable. +// While this technically doesn't change the layout of pair itself, other types may decide to programatically change +// their representation based on whether something is trivially copyable. +# define _LIBCPP_ABI_TRIVIALLY_COPYABLE_PAIR +#elif _LIBCPP_ABI_VERSION == 1 +# if !(defined(_LIBCPP_OBJECT_FORMAT_COFF) || defined(_LIBCPP_OBJECT_FORMAT_XCOFF)) +// Enable compiling copies of now inline methods into the dylib to support +// applications compiled against older libraries. This is unnecessary with +// COFF dllexport semantics, since dllexport forces a non-inline definition +// of inline functions to be emitted anyway. Our own non-inline copy would +// conflict with the dllexport-emitted copy, so we disable it. For XCOFF, +// the linker will take issue with the symbols in the shared object if the +// weak inline methods get visibility (such as from -fvisibility-inlines-hidden), +// so disable it. +# define _LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS +# endif +// Feature macros for disabling pre ABI v1 features. All of these options +// are deprecated. +# if defined(__FreeBSD__) && __FreeBSD__ < 14 +# define _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR +# endif +#endif + +// We had some bugs where we use [[no_unique_address]] together with construct_at, +// which causes UB as the call on construct_at could write to overlapping subobjects +// +// https://github.com/llvm/llvm-project/issues/70506 +// https://github.com/llvm/llvm-project/issues/70494 +// +// To fix the bug we had to change the ABI of some classes to remove [[no_unique_address]] under certain conditions. +// The macro below is used for all classes whose ABI have changed as part of fixing these bugs. +#define _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS __attribute__((__abi_tag__("llvm18_nua"))) + +// Changes the iterator type of select containers (see below) to a bounded iterator that keeps track of whether it's +// within the bounds of the original container and asserts it on every dereference. +// +// ABI impact: changes the iterator type of the relevant containers. +// +// Supported containers: +// - `span`; +// - `string_view`. +// #define _LIBCPP_ABI_BOUNDED_ITERATORS + +#if defined(_LIBCPP_COMPILER_CLANG_BASED) +# if defined(__APPLE__) +# if defined(__i386__) || defined(__x86_64__) +// use old string layout on x86_64 and i386 +# elif defined(__arm__) +// use old string layout on arm (which does not include aarch64/arm64), except on watch ABIs +# if defined(__ARM_ARCH_7K__) && __ARM_ARCH_7K__ >= 2 +# define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT +# endif +# else +# define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT +# endif +# endif +#endif + +#endif // _LIBCPP___CONFIGURATION_ABI_H diff --git a/third_party/libcxx/__configuration/availability.h b/third_party/libcxx/__configuration/availability.h new file mode 100644 index 000000000..ab483a07c --- /dev/null +++ b/third_party/libcxx/__configuration/availability.h @@ -0,0 +1,400 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONFIGURATION_AVAILABILITY_H +#define _LIBCPP___CONFIGURATION_AVAILABILITY_H + +#include <__configuration/compiler.h> +#include <__configuration/language.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +// Libc++ is shipped by various vendors. In particular, it is used as a system +// library on macOS, iOS and other Apple platforms. In order for users to be +// able to compile a binary that is intended to be deployed to an older version +// of a platform, Clang provides availability attributes [1]. These attributes +// can be placed on declarations and are used to describe the life cycle of a +// symbol in the library. +// +// The main goal is to ensure a compile-time error if a symbol that hasn't been +// introduced in a previously released library is used in a program that targets +// that previously released library. Normally, this would be a load-time error +// when one tries to launch the program against the older library. +// +// For example, the filesystem library was introduced in the dylib in LLVM 9. +// On Apple platforms, this corresponds to macOS 10.15. If a user compiles on +// a macOS 10.15 host but targets macOS 10.13 with their program, the compiler +// would normally not complain (because the required declarations are in the +// headers), but the dynamic loader would fail to find the symbols when actually +// trying to launch the program on macOS 10.13. To turn this into a compile-time +// issue instead, declarations are annotated with when they were introduced, and +// the compiler can produce a diagnostic if the program references something that +// isn't available on the deployment target. +// +// This mechanism is general in nature, and any vendor can add their markup to +// the library (see below). Whenever a new feature is added that requires support +// in the shared library, two macros are added below to allow marking the feature +// as unavailable: +// 1. A macro named `_LIBCPP_AVAILABILITY_HAS_` which must be defined +// to `_LIBCPP_INTRODUCED_IN_` for the appropriate LLVM version. +// 2. A macro named `_LIBCPP_AVAILABILITY_`, which must be defined to +// `_LIBCPP_INTRODUCED_IN__MARKUP` for the appropriate LLVM version. +// +// When vendors decide to ship the feature as part of their shared library, they +// can update the `_LIBCPP_INTRODUCED_IN_` macro (and the markup counterpart) +// based on the platform version they shipped that version of LLVM in. The library +// will then use this markup to provide an optimal user experience on these platforms. +// +// Furthermore, many features in the standard library have corresponding +// feature-test macros. The `_LIBCPP_AVAILABILITY_HAS_` macros +// are checked by the corresponding feature-test macros generated by +// generate_feature_test_macro_components.py to ensure that the library +// doesn't announce a feature as being implemented if it is unavailable on +// the deployment target. +// +// Note that this mechanism is disabled by default in the "upstream" libc++. +// Availability annotations are only meaningful when shipping libc++ inside +// a platform (i.e. as a system library), and so vendors that want them should +// turn those annotations on at CMake configuration time. +// +// [1]: https://clang.llvm.org/docs/AttributeReference.html#availability + +// For backwards compatibility, allow users to define _LIBCPP_DISABLE_AVAILABILITY +// for a while. +#if defined(_LIBCPP_DISABLE_AVAILABILITY) +# if !defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS) +# define _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS +# endif +#endif + +// Availability markup is disabled when building the library, or when a non-Clang +// compiler is used because only Clang supports the necessary attributes. +#if defined(_LIBCPP_BUILDING_LIBRARY) || defined(_LIBCXXABI_BUILDING_LIBRARY) || !defined(_LIBCPP_COMPILER_CLANG_BASED) +# if !defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS) +# define _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS +# endif +#endif + +// When availability annotations are disabled, we take for granted that features introduced +// in all versions of the library are available. +#if defined(_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS) + +# define _LIBCPP_INTRODUCED_IN_LLVM_19 1 +# define _LIBCPP_INTRODUCED_IN_LLVM_19_ATTRIBUTE /* nothing */ + +# define _LIBCPP_INTRODUCED_IN_LLVM_18 1 +# define _LIBCPP_INTRODUCED_IN_LLVM_18_ATTRIBUTE /* nothing */ + +# define _LIBCPP_INTRODUCED_IN_LLVM_17 1 +# define _LIBCPP_INTRODUCED_IN_LLVM_17_ATTRIBUTE /* nothing */ + +# define _LIBCPP_INTRODUCED_IN_LLVM_16 1 +# define _LIBCPP_INTRODUCED_IN_LLVM_16_ATTRIBUTE /* nothing */ + +# define _LIBCPP_INTRODUCED_IN_LLVM_15 1 +# define _LIBCPP_INTRODUCED_IN_LLVM_15_ATTRIBUTE /* nothing */ + +# define _LIBCPP_INTRODUCED_IN_LLVM_14 1 +# define _LIBCPP_INTRODUCED_IN_LLVM_14_ATTRIBUTE /* nothing */ + +# define _LIBCPP_INTRODUCED_IN_LLVM_13 1 +# define _LIBCPP_INTRODUCED_IN_LLVM_13_ATTRIBUTE /* nothing */ + +# define _LIBCPP_INTRODUCED_IN_LLVM_12 1 +# define _LIBCPP_INTRODUCED_IN_LLVM_12_ATTRIBUTE /* nothing */ + +# define _LIBCPP_INTRODUCED_IN_LLVM_11 1 +# define _LIBCPP_INTRODUCED_IN_LLVM_11_ATTRIBUTE /* nothing */ + +# define _LIBCPP_INTRODUCED_IN_LLVM_10 1 +# define _LIBCPP_INTRODUCED_IN_LLVM_10_ATTRIBUTE /* nothing */ + +# define _LIBCPP_INTRODUCED_IN_LLVM_9 1 +# define _LIBCPP_INTRODUCED_IN_LLVM_9_ATTRIBUTE /* nothing */ +# define _LIBCPP_INTRODUCED_IN_LLVM_9_ATTRIBUTE_PUSH /* nothing */ +# define _LIBCPP_INTRODUCED_IN_LLVM_9_ATTRIBUTE_POP /* nothing */ + +# define _LIBCPP_INTRODUCED_IN_LLVM_8 1 +# define _LIBCPP_INTRODUCED_IN_LLVM_8_ATTRIBUTE /* nothing */ + +# define _LIBCPP_INTRODUCED_IN_LLVM_4 1 +# define _LIBCPP_INTRODUCED_IN_LLVM_4_ATTRIBUTE /* nothing */ + +#elif defined(__APPLE__) + +// clang-format off + +// LLVM 19 +// TODO: Fill this in +# define _LIBCPP_INTRODUCED_IN_LLVM_19 0 +# define _LIBCPP_INTRODUCED_IN_LLVM_19_ATTRIBUTE __attribute__((unavailable)) + +// LLVM 18 +// TODO: Fill this in +# define _LIBCPP_INTRODUCED_IN_LLVM_18 0 +# define _LIBCPP_INTRODUCED_IN_LLVM_18_ATTRIBUTE __attribute__((unavailable)) + +// LLVM 17 +# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 140400) || \ + (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 170400) || \ + (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 170400) || \ + (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 100400) +# define _LIBCPP_INTRODUCED_IN_LLVM_17 0 +# else +# define _LIBCPP_INTRODUCED_IN_LLVM_17 1 +# endif +# define _LIBCPP_INTRODUCED_IN_LLVM_17_ATTRIBUTE \ + __attribute__((availability(macos, strict, introduced = 14.4))) \ + __attribute__((availability(ios, strict, introduced = 17.4))) \ + __attribute__((availability(tvos, strict, introduced = 17.4))) \ + __attribute__((availability(watchos, strict, introduced = 10.4))) + +// LLVM 16 +# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 140000) || \ + (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 170000) || \ + (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 170000) || \ + (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 100000) +# define _LIBCPP_INTRODUCED_IN_LLVM_16 0 +# else +# define _LIBCPP_INTRODUCED_IN_LLVM_16 1 +# endif +# define _LIBCPP_INTRODUCED_IN_LLVM_16_ATTRIBUTE \ + __attribute__((availability(macos, strict, introduced = 14.0))) \ + __attribute__((availability(ios, strict, introduced = 17.0))) \ + __attribute__((availability(tvos, strict, introduced = 17.0))) \ + __attribute__((availability(watchos, strict, introduced = 10.0))) + +// LLVM 15 +# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 130400) || \ + (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 160500) || \ + (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 160500) || \ + (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 90500) +# define _LIBCPP_INTRODUCED_IN_LLVM_15 0 +# else +# define _LIBCPP_INTRODUCED_IN_LLVM_15 1 +# endif +# define _LIBCPP_INTRODUCED_IN_LLVM_15_ATTRIBUTE \ + __attribute__((availability(macos, strict, introduced = 13.4))) \ + __attribute__((availability(ios, strict, introduced = 16.5))) \ + __attribute__((availability(tvos, strict, introduced = 16.5))) \ + __attribute__((availability(watchos, strict, introduced = 9.5))) + +// LLVM 14 +# define _LIBCPP_INTRODUCED_IN_LLVM_14 _LIBCPP_INTRODUCED_IN_LLVM_15 +# define _LIBCPP_INTRODUCED_IN_LLVM_14_ATTRIBUTE _LIBCPP_INTRODUCED_IN_LLVM_15_ATTRIBUTE + +// LLVM 13 +# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 130000) || \ + (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 160000) || \ + (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 160000) || \ + (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 90000) +# define _LIBCPP_INTRODUCED_IN_LLVM_13 0 +# else +# define _LIBCPP_INTRODUCED_IN_LLVM_13 1 +# endif +# define _LIBCPP_INTRODUCED_IN_LLVM_13_ATTRIBUTE \ + __attribute__((availability(macos, strict, introduced = 13.0))) \ + __attribute__((availability(ios, strict, introduced = 16.0))) \ + __attribute__((availability(tvos, strict, introduced = 16.0))) \ + __attribute__((availability(watchos, strict, introduced = 9.0))) + +// LLVM 12 +# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 120300) || \ + (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 150300) || \ + (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 150300) || \ + (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 80300) +# define _LIBCPP_INTRODUCED_IN_LLVM_12 0 +# else +# define _LIBCPP_INTRODUCED_IN_LLVM_12 1 +# endif +# define _LIBCPP_INTRODUCED_IN_LLVM_12_ATTRIBUTE \ + __attribute__((availability(macos, strict, introduced = 12.3))) \ + __attribute__((availability(ios, strict, introduced = 15.3))) \ + __attribute__((availability(tvos, strict, introduced = 15.3))) \ + __attribute__((availability(watchos, strict, introduced = 8.3))) + +// LLVM 11 +# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 110000) || \ + (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 140000) || \ + (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 140000) || \ + (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 70000) +# define _LIBCPP_INTRODUCED_IN_LLVM_11 0 +# else +# define _LIBCPP_INTRODUCED_IN_LLVM_11 1 +# endif +# define _LIBCPP_INTRODUCED_IN_LLVM_11_ATTRIBUTE \ + __attribute__((availability(macos, strict, introduced = 11.0))) \ + __attribute__((availability(ios, strict, introduced = 14.0))) \ + __attribute__((availability(tvos, strict, introduced = 14.0))) \ + __attribute__((availability(watchos, strict, introduced = 7.0))) + +// LLVM 10 +# define _LIBCPP_INTRODUCED_IN_LLVM_10 _LIBCPP_INTRODUCED_IN_LLVM_11 +# define _LIBCPP_INTRODUCED_IN_LLVM_10_ATTRIBUTE _LIBCPP_INTRODUCED_IN_LLVM_11_ATTRIBUTE + +// LLVM 9 +# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101500) || \ + (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 130000) || \ + (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 130000) || \ + (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 60000) +# define _LIBCPP_INTRODUCED_IN_LLVM_9 0 +# else +# define _LIBCPP_INTRODUCED_IN_LLVM_9 1 +# endif +# define _LIBCPP_INTRODUCED_IN_LLVM_9_ATTRIBUTE \ + __attribute__((availability(macos, strict, introduced = 10.15))) \ + __attribute__((availability(ios, strict, introduced = 13.0))) \ + __attribute__((availability(tvos, strict, introduced = 13.0))) \ + __attribute__((availability(watchos, strict, introduced = 6.0))) +# define _LIBCPP_INTRODUCED_IN_LLVM_9_ATTRIBUTE_PUSH \ + _Pragma("clang attribute push(__attribute__((availability(macos,strict,introduced=10.15))), apply_to=any(function,record))") \ + _Pragma("clang attribute push(__attribute__((availability(ios,strict,introduced=13.0))), apply_to=any(function,record))") \ + _Pragma("clang attribute push(__attribute__((availability(tvos,strict,introduced=13.0))), apply_to=any(function,record))") \ + _Pragma("clang attribute push(__attribute__((availability(watchos,strict,introduced=6.0))), apply_to=any(function,record))") +# define _LIBCPP_INTRODUCED_IN_LLVM_9_ATTRIBUTE_POP \ + _Pragma("clang attribute pop") \ + _Pragma("clang attribute pop") \ + _Pragma("clang attribute pop") \ + _Pragma("clang attribute pop") + +// LLVM 4 +# if defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 50000 +# define _LIBCPP_INTRODUCED_IN_LLVM_4 0 +# else +# define _LIBCPP_INTRODUCED_IN_LLVM_4 1 +# endif +# define _LIBCPP_INTRODUCED_IN_LLVM_4_ATTRIBUTE __attribute__((availability(watchos, strict, introduced = 5.0))) + +// clang-format on + +#else + +// ...New vendors can add availability markup here... + +# error \ + "It looks like you're trying to enable vendor availability markup, but you haven't defined the corresponding macros yet!" + +#endif + +// These macros control the availability of std::bad_optional_access and +// other exception types. These were put in the shared library to prevent +// code bloat from every user program defining the vtable for these exception +// types. +// +// Note that when exceptions are disabled, the methods that normally throw +// these exceptions can be used even on older deployment targets, but those +// methods will abort instead of throwing. +#define _LIBCPP_AVAILABILITY_HAS_BAD_OPTIONAL_ACCESS _LIBCPP_INTRODUCED_IN_LLVM_4 +#define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS _LIBCPP_INTRODUCED_IN_LLVM_4_ATTRIBUTE + +#define _LIBCPP_AVAILABILITY_HAS_BAD_VARIANT_ACCESS _LIBCPP_INTRODUCED_IN_LLVM_4 +#define _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS _LIBCPP_INTRODUCED_IN_LLVM_4_ATTRIBUTE + +#define _LIBCPP_AVAILABILITY_HAS_BAD_ANY_CAST _LIBCPP_INTRODUCED_IN_LLVM_4 +#define _LIBCPP_AVAILABILITY_BAD_ANY_CAST _LIBCPP_INTRODUCED_IN_LLVM_4_ATTRIBUTE + +// These macros control the availability of all parts of that +// depend on something in the dylib. +#define _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY _LIBCPP_INTRODUCED_IN_LLVM_9 +#define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_INTRODUCED_IN_LLVM_9_ATTRIBUTE +#define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH _LIBCPP_INTRODUCED_IN_LLVM_9_ATTRIBUTE_PUSH +#define _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP _LIBCPP_INTRODUCED_IN_LLVM_9_ATTRIBUTE_POP + +// This controls the availability of the C++20 synchronization library, +// which requires shared library support for various operations +// (see libcxx/src/atomic.cpp). This includes , , +// , and notification functions on std::atomic. +#define _LIBCPP_AVAILABILITY_HAS_SYNC _LIBCPP_INTRODUCED_IN_LLVM_11 +#define _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INTRODUCED_IN_LLVM_11_ATTRIBUTE + +// Enable additional explicit instantiations of iostreams components. This +// reduces the number of weak definitions generated in programs that use +// iostreams by providing a single strong definition in the shared library. +// +// TODO: Enable additional explicit instantiations on GCC once it supports exclude_from_explicit_instantiation, +// or once libc++ doesn't use the attribute anymore. +// TODO: Enable them on Windows once https://llvm.org/PR41018 has been fixed. +#if !defined(_LIBCPP_COMPILER_GCC) && !defined(_WIN32) +# define _LIBCPP_AVAILABILITY_HAS_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1 _LIBCPP_INTRODUCED_IN_LLVM_12 +#else +# define _LIBCPP_AVAILABILITY_HAS_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1 0 +#endif + +// This controls the availability of floating-point std::to_chars functions. +// These overloads were added later than the integer overloads. +#define _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT _LIBCPP_INTRODUCED_IN_LLVM_14 +#define _LIBCPP_AVAILABILITY_TO_CHARS_FLOATING_POINT _LIBCPP_INTRODUCED_IN_LLVM_14_ATTRIBUTE + +// This controls whether the library claims to provide a default verbose +// termination function, and consequently whether the headers will try +// to use it when the mechanism isn't overriden at compile-time. +#define _LIBCPP_AVAILABILITY_HAS_VERBOSE_ABORT _LIBCPP_INTRODUCED_IN_LLVM_15 +#define _LIBCPP_AVAILABILITY_VERBOSE_ABORT _LIBCPP_INTRODUCED_IN_LLVM_15_ATTRIBUTE + +// This controls the availability of the C++17 std::pmr library, +// which is implemented in large part in the built library. +// +// TODO: Enable std::pmr markup once https://github.com/llvm/llvm-project/issues/40340 has been fixed +// Until then, it is possible for folks to try to use `std::pmr` when back-deploying to targets that don't support +// it and it'll be a load-time error, but we don't have a good alternative because the library won't compile if we +// use availability annotations until that bug has been fixed. +#define _LIBCPP_AVAILABILITY_HAS_PMR _LIBCPP_INTRODUCED_IN_LLVM_16 +#define _LIBCPP_AVAILABILITY_PMR + +// These macros controls the availability of __cxa_init_primary_exception +// in the built library, which std::make_exception_ptr might use +// (see libcxx/include/__exception/exception_ptr.h). +#define _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION _LIBCPP_INTRODUCED_IN_LLVM_18 +#define _LIBCPP_AVAILABILITY_INIT_PRIMARY_EXCEPTION _LIBCPP_INTRODUCED_IN_LLVM_18_ATTRIBUTE + +// This controls the availability of C++23 , which +// has a dependency on the built library (it needs access to +// the underlying buffer types of std::cout, std::cerr, and std::clog. +#define _LIBCPP_AVAILABILITY_HAS_PRINT _LIBCPP_INTRODUCED_IN_LLVM_18 +#define _LIBCPP_AVAILABILITY_PRINT _LIBCPP_INTRODUCED_IN_LLVM_18_ATTRIBUTE + +// This controls the availability of the C++20 time zone database. +// The parser code is built in the library. +#define _LIBCPP_AVAILABILITY_HAS_TZDB _LIBCPP_INTRODUCED_IN_LLVM_19 +#define _LIBCPP_AVAILABILITY_TZDB _LIBCPP_INTRODUCED_IN_LLVM_19_ATTRIBUTE + +// These macros determine whether we assume that std::bad_function_call and +// std::bad_expected_access provide a key function in the dylib. This allows +// centralizing their vtable and typeinfo instead of having all TUs provide +// a weak definition that then gets deduplicated. +#define _LIBCPP_AVAILABILITY_HAS_BAD_FUNCTION_CALL_KEY_FUNCTION _LIBCPP_INTRODUCED_IN_LLVM_19 +#define _LIBCPP_AVAILABILITY_BAD_FUNCTION_CALL_KEY_FUNCTION _LIBCPP_INTRODUCED_IN_LLVM_19_ATTRIBUTE +#define _LIBCPP_AVAILABILITY_HAS_BAD_EXPECTED_ACCESS_KEY_FUNCTION _LIBCPP_INTRODUCED_IN_LLVM_19 +#define _LIBCPP_AVAILABILITY_BAD_EXPECTED_ACCESS_KEY_FUNCTION _LIBCPP_INTRODUCED_IN_LLVM_19_ATTRIBUTE + +// Define availability attributes that depend on _LIBCPP_HAS_NO_EXCEPTIONS. +// Those are defined in terms of the availability attributes above, and +// should not be vendor-specific. +#if defined(_LIBCPP_HAS_NO_EXCEPTIONS) +# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST +# define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS +# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS +#else +# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST _LIBCPP_AVAILABILITY_BAD_ANY_CAST +# define _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS +# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS +#endif + +// Define availability attributes that depend on both +// _LIBCPP_HAS_NO_EXCEPTIONS and _LIBCPP_HAS_NO_RTTI. +#if defined(_LIBCPP_HAS_NO_EXCEPTIONS) || defined(_LIBCPP_HAS_NO_RTTI) +# undef _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION +# undef _LIBCPP_AVAILABILITY_INIT_PRIMARY_EXCEPTION +# define _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION 0 +# define _LIBCPP_AVAILABILITY_INIT_PRIMARY_EXCEPTION +#endif + +#endif // _LIBCPP___CONFIGURATION_AVAILABILITY_H diff --git a/third_party/libcxx/__configuration/compiler.h b/third_party/libcxx/__configuration/compiler.h new file mode 100644 index 000000000..80ece22bb --- /dev/null +++ b/third_party/libcxx/__configuration/compiler.h @@ -0,0 +1,51 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONFIGURATION_COMPILER_H +#define _LIBCPP___CONFIGURATION_COMPILER_H + +#include <__config_site> + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +# pragma GCC system_header +#endif + +#if defined(__apple_build_version__) +// Given AppleClang XX.Y.Z, _LIBCPP_APPLE_CLANG_VER is XXYZ (e.g. AppleClang 14.0.3 => 1403) +# define _LIBCPP_COMPILER_CLANG_BASED +# define _LIBCPP_APPLE_CLANG_VER (__apple_build_version__ / 10000) +#elif defined(__clang__) +# define _LIBCPP_COMPILER_CLANG_BASED +# define _LIBCPP_CLANG_VER (__clang_major__ * 100 + __clang_minor__) +#elif defined(__GNUC__) +# define _LIBCPP_COMPILER_GCC +# define _LIBCPP_GCC_VER (__GNUC__ * 100 + __GNUC_MINOR__) +#endif + +#ifdef __cplusplus + +// Warn if a compiler version is used that is not supported anymore +// LLVM RELEASE Update the minimum compiler versions +# if defined(_LIBCPP_CLANG_VER) +# if _LIBCPP_CLANG_VER < 1700 +# warning "Libc++ only supports Clang 17 and later" +# endif +# elif defined(_LIBCPP_APPLE_CLANG_VER) +# if _LIBCPP_APPLE_CLANG_VER < 1500 +# warning "Libc++ only supports AppleClang 15 and later" +# endif +# elif defined(_LIBCPP_GCC_VER) +# if _LIBCPP_GCC_VER < 1400 +# warning "Libc++ only supports GCC 14 and later" +# endif +# endif + +#endif + +#endif // _LIBCPP___CONFIGURATION_COMPILER_H diff --git a/third_party/libcxx/__configuration/language.h b/third_party/libcxx/__configuration/language.h new file mode 100644 index 000000000..fa62a7b6f --- /dev/null +++ b/third_party/libcxx/__configuration/language.h @@ -0,0 +1,46 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONFIGURATION_LANGUAGE_H +#define _LIBCPP___CONFIGURATION_LANGUAGE_H + +#include <__config_site> + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +# pragma GCC system_header +#endif + +// NOLINTBEGIN(libcpp-cpp-version-check) +#ifdef __cplusplus +# if __cplusplus <= 201103L +# define _LIBCPP_STD_VER 11 +# elif __cplusplus <= 201402L +# define _LIBCPP_STD_VER 14 +# elif __cplusplus <= 201703L +# define _LIBCPP_STD_VER 17 +# elif __cplusplus <= 202002L +# define _LIBCPP_STD_VER 20 +# elif __cplusplus <= 202302L +# define _LIBCPP_STD_VER 23 +# else +// Expected release year of the next C++ standard +# define _LIBCPP_STD_VER 26 +# endif +#endif // __cplusplus +// NOLINTEND(libcpp-cpp-version-check) + +#if !defined(__cpp_rtti) || __cpp_rtti < 199711L +# define _LIBCPP_HAS_NO_RTTI +#endif + +#if !defined(__cpp_exceptions) || __cpp_exceptions < 199711L +# define _LIBCPP_HAS_NO_EXCEPTIONS +#endif + +#endif // _LIBCPP___CONFIGURATION_LANGUAGE_H diff --git a/third_party/libcxx/__configuration/platform.h b/third_party/libcxx/__configuration/platform.h new file mode 100644 index 000000000..27f68d04e --- /dev/null +++ b/third_party/libcxx/__configuration/platform.h @@ -0,0 +1,54 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONFIGURATION_PLATFORM_H +#define _LIBCPP___CONFIGURATION_PLATFORM_H + +#include <__config_site> + +#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +# pragma GCC system_header +#endif + +#if defined(__ELF__) +# define _LIBCPP_OBJECT_FORMAT_ELF 1 +#elif defined(__MACH__) +# define _LIBCPP_OBJECT_FORMAT_MACHO 1 +#elif defined(_WIN32) +# define _LIBCPP_OBJECT_FORMAT_COFF 1 +#elif defined(__wasm__) +# define _LIBCPP_OBJECT_FORMAT_WASM 1 +#elif defined(_AIX) +# define _LIBCPP_OBJECT_FORMAT_XCOFF 1 +#else +// ... add new file formats here ... +#endif + +// Need to detect which libc we're using if we're on Linux. +#if defined(__linux__) +# include +# if defined(__GLIBC_PREREQ) +# define _LIBCPP_GLIBC_PREREQ(a, b) __GLIBC_PREREQ(a, b) +# else +# define _LIBCPP_GLIBC_PREREQ(a, b) 0 +# endif // defined(__GLIBC_PREREQ) +#endif // defined(__linux__) + +#ifndef __BYTE_ORDER__ +# error \ + "Your compiler doesn't seem to define __BYTE_ORDER__, which is required by libc++ to know the endianness of your target platform" +#endif + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define _LIBCPP_LITTLE_ENDIAN +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define _LIBCPP_BIG_ENDIAN +#endif // __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + +#endif // _LIBCPP___CONFIGURATION_PLATFORM_H diff --git a/third_party/libcxx/__coroutine/coroutine_handle.h b/third_party/libcxx/__coroutine/coroutine_handle.h index 2135111e4..4557a6643 100644 --- a/third_party/libcxx/__coroutine/coroutine_handle.h +++ b/third_party/libcxx/__coroutine/coroutine_handle.h @@ -32,166 +32,141 @@ struct _LIBCPP_TEMPLATE_VIS coroutine_handle; template <> struct _LIBCPP_TEMPLATE_VIS coroutine_handle { public: - // [coroutine.handle.con], construct/reset - constexpr coroutine_handle() noexcept = default; + // [coroutine.handle.con], construct/reset + constexpr coroutine_handle() noexcept = default; - _LIBCPP_HIDE_FROM_ABI - constexpr coroutine_handle(nullptr_t) noexcept {} + _LIBCPP_HIDE_FROM_ABI constexpr coroutine_handle(nullptr_t) noexcept {} - _LIBCPP_HIDE_FROM_ABI - coroutine_handle& operator=(nullptr_t) noexcept { - __handle_ = nullptr; - return *this; - } + _LIBCPP_HIDE_FROM_ABI coroutine_handle& operator=(nullptr_t) noexcept { + __handle_ = nullptr; + return *this; + } - // [coroutine.handle.export.import], export/import - _LIBCPP_HIDE_FROM_ABI - constexpr void* address() const noexcept { return __handle_; } + // [coroutine.handle.export.import], export/import + _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; } - _LIBCPP_HIDE_FROM_ABI - static constexpr coroutine_handle from_address(void* __addr) noexcept { - coroutine_handle __tmp; - __tmp.__handle_ = __addr; - return __tmp; - } + _LIBCPP_HIDE_FROM_ABI static constexpr coroutine_handle from_address(void* __addr) noexcept { + coroutine_handle __tmp; + __tmp.__handle_ = __addr; + return __tmp; + } - // [coroutine.handle.observers], observers - _LIBCPP_HIDE_FROM_ABI - constexpr explicit operator bool() const noexcept { - return __handle_ != nullptr; - } + // [coroutine.handle.observers], observers + _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __handle_ != nullptr; } - _LIBCPP_HIDE_FROM_ABI - bool done() const { - _LIBCPP_ASSERT(__is_suspended(), "done() can be called only on suspended coroutines"); - return __builtin_coro_done(__handle_); - } + _LIBCPP_HIDE_FROM_ABI bool done() const { + _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(__is_suspended(), "done() can be called only on suspended coroutines"); + return __builtin_coro_done(__handle_); + } - // [coroutine.handle.resumption], resumption - _LIBCPP_HIDE_FROM_ABI - void operator()() const { resume(); } + // [coroutine.handle.resumption], resumption + _LIBCPP_HIDE_FROM_ABI void operator()() const { resume(); } - _LIBCPP_HIDE_FROM_ABI - void resume() const { - _LIBCPP_ASSERT(__is_suspended(), "resume() can be called only on suspended coroutines"); - _LIBCPP_ASSERT(!done(), "resume() has undefined behavior when the coroutine is done"); - __builtin_coro_resume(__handle_); - } + _LIBCPP_HIDE_FROM_ABI void resume() const { + _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(__is_suspended(), "resume() can be called only on suspended coroutines"); + _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(!done(), "resume() has undefined behavior when the coroutine is done"); + __builtin_coro_resume(__handle_); + } - _LIBCPP_HIDE_FROM_ABI - void destroy() const { - _LIBCPP_ASSERT(__is_suspended(), "destroy() can be called only on suspended coroutines"); - __builtin_coro_destroy(__handle_); - } + _LIBCPP_HIDE_FROM_ABI void destroy() const { + _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(__is_suspended(), "destroy() can be called only on suspended coroutines"); + __builtin_coro_destroy(__handle_); + } private: - _LIBCPP_HIDE_FROM_ABI bool __is_suspended() const { - // FIXME actually implement a check for if the coro is suspended. - return __handle_ != nullptr; - } + _LIBCPP_HIDE_FROM_ABI bool __is_suspended() const { + // FIXME actually implement a check for if the coro is suspended. + return __handle_ != nullptr; + } - void* __handle_ = nullptr; + void* __handle_ = nullptr; }; // [coroutine.handle.compare] -inline _LIBCPP_HIDE_FROM_ABI -constexpr bool operator==(coroutine_handle<> __x, coroutine_handle<> __y) noexcept { - return __x.address() == __y.address(); +inline _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(coroutine_handle<> __x, coroutine_handle<> __y) noexcept { + return __x.address() == __y.address(); } -inline _LIBCPP_HIDE_FROM_ABI -constexpr strong_ordering operator<=>(coroutine_handle<> __x, coroutine_handle<> __y) noexcept { - return compare_three_way()(__x.address(), __y.address()); +inline _LIBCPP_HIDE_FROM_ABI constexpr strong_ordering +operator<=>(coroutine_handle<> __x, coroutine_handle<> __y) noexcept { + return compare_three_way()(__x.address(), __y.address()); } template struct _LIBCPP_TEMPLATE_VIS coroutine_handle { public: - // [coroutine.handle.con], construct/reset - constexpr coroutine_handle() noexcept = default; + // [coroutine.handle.con], construct/reset + constexpr coroutine_handle() noexcept = default; - _LIBCPP_HIDE_FROM_ABI - constexpr coroutine_handle(nullptr_t) noexcept {} + _LIBCPP_HIDE_FROM_ABI constexpr coroutine_handle(nullptr_t) noexcept {} - _LIBCPP_HIDE_FROM_ABI - static coroutine_handle from_promise(_Promise& __promise) { - using _RawPromise = __remove_cv_t<_Promise>; - coroutine_handle __tmp; - __tmp.__handle_ = - __builtin_coro_promise(_VSTD::addressof(const_cast<_RawPromise&>(__promise)), alignof(_Promise), true); - return __tmp; - } + _LIBCPP_HIDE_FROM_ABI static coroutine_handle from_promise(_Promise& __promise) { + using _RawPromise = __remove_cv_t<_Promise>; + coroutine_handle __tmp; + __tmp.__handle_ = + __builtin_coro_promise(std::addressof(const_cast<_RawPromise&>(__promise)), alignof(_Promise), true); + return __tmp; + } - _LIBCPP_HIDE_FROM_ABI - coroutine_handle& operator=(nullptr_t) noexcept { - __handle_ = nullptr; - return *this; - } + _LIBCPP_HIDE_FROM_ABI coroutine_handle& operator=(nullptr_t) noexcept { + __handle_ = nullptr; + return *this; + } - // [coroutine.handle.export.import], export/import - _LIBCPP_HIDE_FROM_ABI - constexpr void* address() const noexcept { return __handle_; } + // [coroutine.handle.export.import], export/import + _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; } - _LIBCPP_HIDE_FROM_ABI - static constexpr coroutine_handle from_address(void* __addr) noexcept { - coroutine_handle __tmp; - __tmp.__handle_ = __addr; - return __tmp; - } + _LIBCPP_HIDE_FROM_ABI static constexpr coroutine_handle from_address(void* __addr) noexcept { + coroutine_handle __tmp; + __tmp.__handle_ = __addr; + return __tmp; + } - // [coroutine.handle.conv], conversion - _LIBCPP_HIDE_FROM_ABI - constexpr operator coroutine_handle<>() const noexcept { - return coroutine_handle<>::from_address(address()); - } + // [coroutine.handle.conv], conversion + _LIBCPP_HIDE_FROM_ABI constexpr operator coroutine_handle<>() const noexcept { + return coroutine_handle<>::from_address(address()); + } - // [coroutine.handle.observers], observers - _LIBCPP_HIDE_FROM_ABI - constexpr explicit operator bool() const noexcept { - return __handle_ != nullptr; - } + // [coroutine.handle.observers], observers + _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __handle_ != nullptr; } - _LIBCPP_HIDE_FROM_ABI - bool done() const { - _LIBCPP_ASSERT(__is_suspended(), "done() can be called only on suspended coroutines"); - return __builtin_coro_done(__handle_); - } + _LIBCPP_HIDE_FROM_ABI bool done() const { + _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(__is_suspended(), "done() can be called only on suspended coroutines"); + return __builtin_coro_done(__handle_); + } - // [coroutine.handle.resumption], resumption - _LIBCPP_HIDE_FROM_ABI - void operator()() const { resume(); } + // [coroutine.handle.resumption], resumption + _LIBCPP_HIDE_FROM_ABI void operator()() const { resume(); } - _LIBCPP_HIDE_FROM_ABI - void resume() const { - _LIBCPP_ASSERT(__is_suspended(), "resume() can be called only on suspended coroutines"); - _LIBCPP_ASSERT(!done(), "resume() has undefined behavior when the coroutine is done"); - __builtin_coro_resume(__handle_); - } + _LIBCPP_HIDE_FROM_ABI void resume() const { + _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(__is_suspended(), "resume() can be called only on suspended coroutines"); + _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(!done(), "resume() has undefined behavior when the coroutine is done"); + __builtin_coro_resume(__handle_); + } - _LIBCPP_HIDE_FROM_ABI - void destroy() const { - _LIBCPP_ASSERT(__is_suspended(), "destroy() can be called only on suspended coroutines"); - __builtin_coro_destroy(__handle_); - } + _LIBCPP_HIDE_FROM_ABI void destroy() const { + _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(__is_suspended(), "destroy() can be called only on suspended coroutines"); + __builtin_coro_destroy(__handle_); + } - // [coroutine.handle.promise], promise access - _LIBCPP_HIDE_FROM_ABI - _Promise& promise() const { - return *static_cast<_Promise*>(__builtin_coro_promise(this->__handle_, alignof(_Promise), false)); - } + // [coroutine.handle.promise], promise access + _LIBCPP_HIDE_FROM_ABI _Promise& promise() const { + return *static_cast<_Promise*>(__builtin_coro_promise(this->__handle_, alignof(_Promise), false)); + } private: - _LIBCPP_HIDE_FROM_ABI bool __is_suspended() const { - // FIXME actually implement a check for if the coro is suspended. - return __handle_ != nullptr; - } - void* __handle_ = nullptr; + _LIBCPP_HIDE_FROM_ABI bool __is_suspended() const { + // FIXME actually implement a check for if the coro is suspended. + return __handle_ != nullptr; + } + void* __handle_ = nullptr; }; // [coroutine.handle.hash] template struct hash> { - _LIBCPP_HIDE_FROM_ABI - size_t operator()(const coroutine_handle<_Tp>& __v) const noexcept { return hash()(__v.address()); } + _LIBCPP_HIDE_FROM_ABI size_t operator()(const coroutine_handle<_Tp>& __v) const noexcept { + return hash()(__v.address()); + } }; _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__coroutine/coroutine_traits.h b/third_party/libcxx/__coroutine/coroutine_traits.h index 7122cc8ea..78f05341f 100644 --- a/third_party/libcxx/__coroutine/coroutine_traits.h +++ b/third_party/libcxx/__coroutine/coroutine_traits.h @@ -34,17 +34,12 @@ template struct __coroutine_traits_sfinae {}; template -struct __coroutine_traits_sfinae< - _Tp, __void_t > -{ +struct __coroutine_traits_sfinae< _Tp, __void_t > { using promise_type = typename _Tp::promise_type; }; template -struct coroutine_traits - : public __coroutine_traits_sfinae<_Ret> -{ -}; +struct coroutine_traits : public __coroutine_traits_sfinae<_Ret> {}; _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__coroutine/noop_coroutine_handle.h b/third_party/libcxx/__coroutine/noop_coroutine_handle.h index 9b7802d1e..da13d5796 100644 --- a/third_party/libcxx/__coroutine/noop_coroutine_handle.h +++ b/third_party/libcxx/__coroutine/noop_coroutine_handle.h @@ -20,7 +20,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if __has_builtin(__builtin_coro_noop) || defined(_LIBCPP_COMPILER_GCC) +# if __has_builtin(__builtin_coro_noop) || defined(_LIBCPP_COMPILER_GCC) // [coroutine.noop] // [coroutine.promise.noop] @@ -30,80 +30,67 @@ struct noop_coroutine_promise {}; template <> struct _LIBCPP_TEMPLATE_VIS coroutine_handle { public: - // [coroutine.handle.noop.conv], conversion - _LIBCPP_HIDE_FROM_ABI - constexpr operator coroutine_handle<>() const noexcept { - return coroutine_handle<>::from_address(address()); - } + // [coroutine.handle.noop.conv], conversion + _LIBCPP_HIDE_FROM_ABI constexpr operator coroutine_handle<>() const noexcept { + return coroutine_handle<>::from_address(address()); + } - // [coroutine.handle.noop.observers], observers - _LIBCPP_HIDE_FROM_ABI - constexpr explicit operator bool() const noexcept { return true; } - _LIBCPP_HIDE_FROM_ABI - constexpr bool done() const noexcept { return false; } + // [coroutine.handle.noop.observers], observers + _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return true; } + _LIBCPP_HIDE_FROM_ABI constexpr bool done() const noexcept { return false; } - // [coroutine.handle.noop.resumption], resumption - _LIBCPP_HIDE_FROM_ABI - constexpr void operator()() const noexcept {} - _LIBCPP_HIDE_FROM_ABI - constexpr void resume() const noexcept {} - _LIBCPP_HIDE_FROM_ABI - constexpr void destroy() const noexcept {} + // [coroutine.handle.noop.resumption], resumption + _LIBCPP_HIDE_FROM_ABI constexpr void operator()() const noexcept {} + _LIBCPP_HIDE_FROM_ABI constexpr void resume() const noexcept {} + _LIBCPP_HIDE_FROM_ABI constexpr void destroy() const noexcept {} - // [coroutine.handle.noop.promise], promise access - _LIBCPP_HIDE_FROM_ABI - noop_coroutine_promise& promise() const noexcept { - return *static_cast( - __builtin_coro_promise(this->__handle_, alignof(noop_coroutine_promise), false)); - } + // [coroutine.handle.noop.promise], promise access + _LIBCPP_HIDE_FROM_ABI noop_coroutine_promise& promise() const noexcept { + return *static_cast( + __builtin_coro_promise(this->__handle_, alignof(noop_coroutine_promise), false)); + } - // [coroutine.handle.noop.address], address - _LIBCPP_HIDE_FROM_ABI - constexpr void* address() const noexcept { return __handle_; } + // [coroutine.handle.noop.address], address + _LIBCPP_HIDE_FROM_ABI constexpr void* address() const noexcept { return __handle_; } private: - _LIBCPP_HIDE_FROM_ABI - friend coroutine_handle noop_coroutine() noexcept; + _LIBCPP_HIDE_FROM_ABI friend coroutine_handle noop_coroutine() noexcept; -#if __has_builtin(__builtin_coro_noop) - _LIBCPP_HIDE_FROM_ABI coroutine_handle() noexcept { - this->__handle_ = __builtin_coro_noop(); - } +# if __has_builtin(__builtin_coro_noop) + _LIBCPP_HIDE_FROM_ABI coroutine_handle() noexcept { this->__handle_ = __builtin_coro_noop(); } - void* __handle_ = nullptr; + void* __handle_ = nullptr; -#elif defined(_LIBCPP_COMPILER_GCC) - // GCC doesn't implement __builtin_coro_noop(). - // Construct the coroutine frame manually instead. - struct __noop_coroutine_frame_ty_ { - static void __dummy_resume_destroy_func() { } +# elif defined(_LIBCPP_COMPILER_GCC) + // GCC doesn't implement __builtin_coro_noop(). + // Construct the coroutine frame manually instead. + struct __noop_coroutine_frame_ty_ { + static void __dummy_resume_destroy_func() {} - void (*__resume_)() = __dummy_resume_destroy_func; - void (*__destroy_)() = __dummy_resume_destroy_func; - struct noop_coroutine_promise __promise_; - }; + void (*__resume_)() = __dummy_resume_destroy_func; + void (*__destroy_)() = __dummy_resume_destroy_func; + struct noop_coroutine_promise __promise_; + }; - static __noop_coroutine_frame_ty_ __noop_coroutine_frame_; + static __noop_coroutine_frame_ty_ __noop_coroutine_frame_; - void* __handle_ = &__noop_coroutine_frame_; + void* __handle_ = &__noop_coroutine_frame_; - _LIBCPP_HIDE_FROM_ABI coroutine_handle() noexcept = default; + _LIBCPP_HIDE_FROM_ABI coroutine_handle() noexcept = default; -#endif // __has_builtin(__builtin_coro_noop) +# endif // __has_builtin(__builtin_coro_noop) }; using noop_coroutine_handle = coroutine_handle; -#if defined(_LIBCPP_COMPILER_GCC) -inline noop_coroutine_handle::__noop_coroutine_frame_ty_ - noop_coroutine_handle::__noop_coroutine_frame_{}; -#endif +# if defined(_LIBCPP_COMPILER_GCC) +inline noop_coroutine_handle::__noop_coroutine_frame_ty_ noop_coroutine_handle::__noop_coroutine_frame_{}; +# endif // [coroutine.noop.coroutine] -inline _LIBCPP_HIDE_FROM_ABI -noop_coroutine_handle noop_coroutine() noexcept { return noop_coroutine_handle(); } +inline _LIBCPP_HIDE_FROM_ABI noop_coroutine_handle noop_coroutine() noexcept { return noop_coroutine_handle(); } -#endif // __has_builtin(__builtin_coro_noop) || defined(_LIBCPP_COMPILER_GCC) +# endif // __has_builtin(__builtin_coro_noop) || defined(_LIBCPP_COMPILER_GCC) _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__coroutine/trivial_awaitables.h b/third_party/libcxx/__coroutine/trivial_awaitables.h index 0e4b08e37..b604bd3c2 100644 --- a/third_party/libcxx/__coroutine/trivial_awaitables.h +++ b/third_party/libcxx/__coroutine/trivial_awaitables.h @@ -22,21 +22,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD // [coroutine.trivial.awaitables] struct suspend_never { - _LIBCPP_HIDE_FROM_ABI - constexpr bool await_ready() const noexcept { return true; } - _LIBCPP_HIDE_FROM_ABI - constexpr void await_suspend(coroutine_handle<>) const noexcept {} - _LIBCPP_HIDE_FROM_ABI - constexpr void await_resume() const noexcept {} + _LIBCPP_HIDE_FROM_ABI constexpr bool await_ready() const noexcept { return true; } + _LIBCPP_HIDE_FROM_ABI constexpr void await_suspend(coroutine_handle<>) const noexcept {} + _LIBCPP_HIDE_FROM_ABI constexpr void await_resume() const noexcept {} }; struct suspend_always { - _LIBCPP_HIDE_FROM_ABI - constexpr bool await_ready() const noexcept { return false; } - _LIBCPP_HIDE_FROM_ABI - constexpr void await_suspend(coroutine_handle<>) const noexcept {} - _LIBCPP_HIDE_FROM_ABI - constexpr void await_resume() const noexcept {} + _LIBCPP_HIDE_FROM_ABI constexpr bool await_ready() const noexcept { return false; } + _LIBCPP_HIDE_FROM_ABI constexpr void await_suspend(coroutine_handle<>) const noexcept {} + _LIBCPP_HIDE_FROM_ABI constexpr void await_resume() const noexcept {} }; _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__debug b/third_party/libcxx/__debug deleted file mode 100644 index ccbfae723..000000000 --- a/third_party/libcxx/__debug +++ /dev/null @@ -1,266 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP___DEBUG -#define _LIBCPP___DEBUG - -#include <__assert> -#include <__config> -#include <__type_traits/is_constant_evaluated.h> -#include - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -#if defined(_LIBCPP_ENABLE_DEBUG_MODE) && !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY) -# define _LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY -#endif - -#if defined(_LIBCPP_ENABLE_DEBUG_MODE) && !defined(_LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING) -# define _LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING -#endif - -#ifdef _LIBCPP_ENABLE_DEBUG_MODE -# define _LIBCPP_DEBUG_ASSERT(x, m) _LIBCPP_ASSERT(::std::__libcpp_is_constant_evaluated() || (x), m) -#else -# define _LIBCPP_DEBUG_ASSERT(x, m) ((void)0) -#endif - -#if defined(_LIBCPP_ENABLE_DEBUG_MODE) || defined(_LIBCPP_BUILDING_LIBRARY) - -_LIBCPP_BEGIN_NAMESPACE_STD - -struct _LIBCPP_TYPE_VIS __c_node; - -struct _LIBCPP_TYPE_VIS __i_node -{ - void* __i_; - __i_node* __next_; - __c_node* __c_; - - __i_node(const __i_node&) = delete; - __i_node& operator=(const __i_node&) = delete; - - _LIBCPP_INLINE_VISIBILITY - __i_node(void* __i, __i_node* __next, __c_node* __c) - : __i_(__i), __next_(__next), __c_(__c) {} - ~__i_node(); -}; - -struct _LIBCPP_TYPE_VIS __c_node -{ - void* __c_; - __c_node* __next_; - __i_node** beg_; - __i_node** end_; - __i_node** cap_; - - __c_node(const __c_node&) = delete; - __c_node& operator=(const __c_node&) = delete; - - _LIBCPP_INLINE_VISIBILITY - explicit __c_node(void* __c, __c_node* __next) - : __c_(__c), __next_(__next), beg_(nullptr), end_(nullptr), cap_(nullptr) {} - virtual ~__c_node(); - - virtual bool __dereferenceable(const void*) const = 0; - virtual bool __decrementable(const void*) const = 0; - virtual bool __addable(const void*, ptrdiff_t) const = 0; - virtual bool __subscriptable(const void*, ptrdiff_t) const = 0; - - void __add(__i_node* __i); - _LIBCPP_HIDDEN void __remove(__i_node* __i); -}; - -template -struct _C_node - : public __c_node -{ - explicit _C_node(void* __c, __c_node* __n) - : __c_node(__c, __n) {} - - bool __dereferenceable(const void*) const override; - bool __decrementable(const void*) const override; - bool __addable(const void*, ptrdiff_t) const override; - bool __subscriptable(const void*, ptrdiff_t) const override; -}; - -template -inline bool -_C_node<_Cont>::__dereferenceable(const void* __i) const -{ - typedef typename _Cont::const_iterator iterator; - const iterator* __j = static_cast(__i); - _Cont* __cp = static_cast<_Cont*>(__c_); - return __cp->__dereferenceable(__j); -} - -template -inline bool -_C_node<_Cont>::__decrementable(const void* __i) const -{ - typedef typename _Cont::const_iterator iterator; - const iterator* __j = static_cast(__i); - _Cont* __cp = static_cast<_Cont*>(__c_); - return __cp->__decrementable(__j); -} - -template -inline bool -_C_node<_Cont>::__addable(const void* __i, ptrdiff_t __n) const -{ - typedef typename _Cont::const_iterator iterator; - const iterator* __j = static_cast(__i); - _Cont* __cp = static_cast<_Cont*>(__c_); - return __cp->__addable(__j, __n); -} - -template -inline bool -_C_node<_Cont>::__subscriptable(const void* __i, ptrdiff_t __n) const -{ - typedef typename _Cont::const_iterator iterator; - const iterator* __j = static_cast(__i); - _Cont* __cp = static_cast<_Cont*>(__c_); - return __cp->__subscriptable(__j, __n); -} - -class _LIBCPP_TYPE_VIS __libcpp_db -{ - __c_node** __cbeg_; - __c_node** __cend_; - size_t __csz_; - __i_node** __ibeg_; - __i_node** __iend_; - size_t __isz_; - - explicit __libcpp_db(); -public: - __libcpp_db(const __libcpp_db&) = delete; - __libcpp_db& operator=(const __libcpp_db&) = delete; - - ~__libcpp_db(); - - class __db_c_iterator; - class __db_c_const_iterator; - class __db_i_iterator; - class __db_i_const_iterator; - - __db_c_const_iterator __c_end() const; - __db_i_const_iterator __i_end() const; - - typedef __c_node*(_InsertConstruct)(void*, void*, __c_node*); - - template - _LIBCPP_INLINE_VISIBILITY static __c_node* __create_C_node(void *__mem, void *__c, __c_node *__next) { - return ::new (__mem) _C_node<_Cont>(__c, __next); - } - - template - _LIBCPP_INLINE_VISIBILITY - void __insert_c(_Cont* __c) - { - __insert_c(static_cast(__c), &__create_C_node<_Cont>); - } - - void __insert_i(void* __i); - void __insert_c(void* __c, _InsertConstruct* __fn); - void __erase_c(void* __c); - - void __insert_ic(void* __i, const void* __c); - void __iterator_copy(void* __i, const void* __i0); - void __erase_i(void* __i); - - void* __find_c_from_i(void* __i) const; - void __invalidate_all(void* __c); - __c_node* __find_c_and_lock(void* __c) const; - __c_node* __find_c(void* __c) const; - void unlock() const; - - void swap(void* __c1, void* __c2); - - - bool __dereferenceable(const void* __i) const; - bool __decrementable(const void* __i) const; - bool __addable(const void* __i, ptrdiff_t __n) const; - bool __subscriptable(const void* __i, ptrdiff_t __n) const; - bool __less_than_comparable(const void* __i, const void* __j) const; -private: - _LIBCPP_HIDDEN - __i_node* __insert_iterator(void* __i); - _LIBCPP_HIDDEN - __i_node* __find_iterator(const void* __i) const; - - friend _LIBCPP_FUNC_VIS __libcpp_db* __get_db(); -}; - -_LIBCPP_FUNC_VIS __libcpp_db* __get_db(); -_LIBCPP_FUNC_VIS const __libcpp_db* __get_const_db(); - -_LIBCPP_END_NAMESPACE_STD - -#endif // defined(_LIBCPP_ENABLE_DEBUG_MODE) || defined(_LIBCPP_BUILDING_LIBRARY) - -_LIBCPP_BEGIN_NAMESPACE_STD - -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_insert_c(_Tp* __c) { -#ifdef _LIBCPP_ENABLE_DEBUG_MODE - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_c(__c); -#else - (void)(__c); -#endif -} - -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_insert_i(_Tp* __i) { -#ifdef _LIBCPP_ENABLE_DEBUG_MODE - if (!__libcpp_is_constant_evaluated()) - __get_db()->__insert_i(__i); -#else - (void)(__i); -#endif -} - -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_erase_c(_Tp* __c) { -#ifdef _LIBCPP_ENABLE_DEBUG_MODE - if (!__libcpp_is_constant_evaluated()) - __get_db()->__erase_c(__c); -#else - (void)(__c); -#endif -} - -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_swap(_Tp* __lhs, _Tp* __rhs) { -#ifdef _LIBCPP_ENABLE_DEBUG_MODE - if (!__libcpp_is_constant_evaluated()) - __get_db()->swap(__lhs, __rhs); -#else - (void)(__lhs); - (void)(__rhs); -#endif -} - -template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 inline void __debug_db_invalidate_all(_Tp* __c) { -#ifdef _LIBCPP_ENABLE_DEBUG_MODE - if (!__libcpp_is_constant_evaluated()) - __get_db()->__invalidate_all(__c); -#else - (void)(__c); -#endif -} - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___DEBUG diff --git a/third_party/libcxx/__debug_utils/randomize_range.h b/third_party/libcxx/__debug_utils/randomize_range.h index dce61923b..7eb77d81a 100644 --- a/third_party/libcxx/__debug_utils/randomize_range.h +++ b/third_party/libcxx/__debug_utils/randomize_range.h @@ -23,8 +23,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 -void __debug_randomize_range(_Iterator __first, _Sentinel __last) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __debug_randomize_range(_Iterator __first, _Sentinel __last) { #ifdef _LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY # ifdef _LIBCPP_CXX03_LANG # error Support for unspecified stability is only for C++11 and higher diff --git a/third_party/libcxx/__debug_utils/sanitizers.h b/third_party/libcxx/__debug_utils/sanitizers.h new file mode 100644 index 000000000..d8547e324 --- /dev/null +++ b/third_party/libcxx/__debug_utils/sanitizers.h @@ -0,0 +1,104 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___LIBCXX_DEBUG_UTILS_SANITIZERS_H +#define _LIBCPP___LIBCXX_DEBUG_UTILS_SANITIZERS_H + +#include <__config> +#include <__type_traits/integral_constant.h> +#include <__type_traits/is_constant_evaluated.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#ifndef _LIBCPP_HAS_NO_ASAN + +extern "C" { +_LIBCPP_EXPORTED_FROM_ABI void +__sanitizer_annotate_contiguous_container(const void*, const void*, const void*, const void*); +_LIBCPP_EXPORTED_FROM_ABI void __sanitizer_annotate_double_ended_contiguous_container( + const void*, const void*, const void*, const void*, const void*, const void*); +_LIBCPP_EXPORTED_FROM_ABI int +__sanitizer_verify_double_ended_contiguous_container(const void*, const void*, const void*, const void*); +} + +#endif // _LIBCPP_HAS_NO_ASAN + +_LIBCPP_BEGIN_NAMESPACE_STD + +// ASan choices +#ifndef _LIBCPP_HAS_NO_ASAN +# define _LIBCPP_HAS_ASAN_CONTAINER_ANNOTATIONS_FOR_ALL_ALLOCATORS 1 +#endif + +#ifdef _LIBCPP_HAS_ASAN_CONTAINER_ANNOTATIONS_FOR_ALL_ALLOCATORS +// __asan_annotate_container_with_allocator determines whether containers with custom allocators are annotated. This is +// a public customization point to disable annotations if the custom allocator assumes that the memory isn't poisoned. +// See the https://libcxx.llvm.org/UsingLibcxx.html#turning-off-asan-annotation-in-containers for more information. +template +struct __asan_annotate_container_with_allocator : true_type {}; +#endif + +// Annotate a double-ended contiguous range. +// - [__first_storage, __last_storage) is the allocated memory region, +// - [__first_old_contained, __last_old_contained) is the previously allowed (unpoisoned) range, and +// - [__first_new_contained, __last_new_contained) is the new allowed (unpoisoned) range. +template +_LIBCPP_HIDE_FROM_ABI void __annotate_double_ended_contiguous_container( + const void* __first_storage, + const void* __last_storage, + const void* __first_old_contained, + const void* __last_old_contained, + const void* __first_new_contained, + const void* __last_new_contained) { +#ifdef _LIBCPP_HAS_NO_ASAN + (void)__first_storage; + (void)__last_storage; + (void)__first_old_contained; + (void)__last_old_contained; + (void)__first_new_contained; + (void)__last_new_contained; +#else + if (__asan_annotate_container_with_allocator<_Allocator>::value && __first_storage != nullptr) + __sanitizer_annotate_double_ended_contiguous_container( + __first_storage, + __last_storage, + __first_old_contained, + __last_old_contained, + __first_new_contained, + __last_new_contained); +#endif +} + +// Annotate a contiguous range. +// [__first_storage, __last_storage) is the allocated memory region, +// __old_last_contained is the previously last allowed (unpoisoned) element, and +// __new_last_contained is the new last allowed (unpoisoned) element. +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __annotate_contiguous_container( + const void* __first_storage, + const void* __last_storage, + const void* __old_last_contained, + const void* __new_last_contained) { +#ifdef _LIBCPP_HAS_NO_ASAN + (void)__first_storage; + (void)__last_storage; + (void)__old_last_contained; + (void)__new_last_contained; +#else + if (!__libcpp_is_constant_evaluated() && __asan_annotate_container_with_allocator<_Allocator>::value && + __first_storage != nullptr) + __sanitizer_annotate_contiguous_container( + __first_storage, __last_storage, __old_last_contained, __new_last_contained); +#endif +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___LIBCXX_DEBUG_UTILS_SANITIZERS_H diff --git a/third_party/libcxx/__debug_utils/strict_weak_ordering_check.h b/third_party/libcxx/__debug_utils/strict_weak_ordering_check.h new file mode 100644 index 000000000..3a9d88728 --- /dev/null +++ b/third_party/libcxx/__debug_utils/strict_weak_ordering_check.h @@ -0,0 +1,77 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___LIBCXX_DEBUG_STRICT_WEAK_ORDERING_CHECK +#define _LIBCPP___LIBCXX_DEBUG_STRICT_WEAK_ORDERING_CHECK + +#include <__config> + +#include <__algorithm/comp_ref_type.h> +#include <__algorithm/is_sorted.h> +#include <__assert> +#include <__iterator/iterator_traits.h> +#include <__type_traits/is_constant_evaluated.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void +__check_strict_weak_ordering_sorted(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) { +#if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG + using __diff_t = __iter_diff_t<_RandomAccessIterator>; + using _Comp_ref = __comp_ref_type<_Comp>; + if (!__libcpp_is_constant_evaluated()) { + // Check if the range is actually sorted. + _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT( + (std::is_sorted<_RandomAccessIterator, _Comp_ref>(__first, __last, _Comp_ref(__comp))), + "The range is not sorted after the sort, your comparator is not a valid strict-weak ordering"); + // Limit the number of elements we need to check. + __diff_t __size = __last - __first > __diff_t(100) ? __diff_t(100) : __last - __first; + __diff_t __p = 0; + while (__p < __size) { + __diff_t __q = __p + __diff_t(1); + // Find first element that is greater than *(__first+__p). + while (__q < __size && !__comp(*(__first + __p), *(__first + __q))) { + ++__q; + } + // Check that the elements from __p to __q are equal between each other. + for (__diff_t __b = __p; __b < __q; ++__b) { + for (__diff_t __a = __p; __a <= __b; ++__a) { + _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT( + !__comp(*(__first + __a), *(__first + __b)), "Your comparator is not a valid strict-weak ordering"); + _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT( + !__comp(*(__first + __b), *(__first + __a)), "Your comparator is not a valid strict-weak ordering"); + } + } + // Check that elements between __p and __q are less than between __q and __size. + for (__diff_t __a = __p; __a < __q; ++__a) { + for (__diff_t __b = __q; __b < __size; ++__b) { + _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT( + __comp(*(__first + __a), *(__first + __b)), "Your comparator is not a valid strict-weak ordering"); + _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT( + !__comp(*(__first + __b), *(__first + __a)), "Your comparator is not a valid strict-weak ordering"); + } + } + // Skip these equal elements. + __p = __q; + } + } +#else + (void)__first; + (void)__last; + (void)__comp; +#endif // _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___LIBCXX_DEBUG_STRICT_WEAK_ORDERING_CHECK diff --git a/third_party/libcxx/__exception/exception.h b/third_party/libcxx/__exception/exception.h index 49a58dd16..e724e1b99 100644 --- a/third_party/libcxx/__exception/exception.h +++ b/third_party/libcxx/__exception/exception.h @@ -69,18 +69,21 @@ public: // On all other platforms, we define our own std::exception and std::bad_exception types // regardless of whether exceptions are turned on as a language feature. -class _LIBCPP_EXCEPTION_ABI exception { +class _LIBCPP_EXPORTED_FROM_ABI exception { public: _LIBCPP_HIDE_FROM_ABI exception() _NOEXCEPT {} - _LIBCPP_HIDE_FROM_ABI exception(const exception&) _NOEXCEPT = default; + _LIBCPP_HIDE_FROM_ABI exception(const exception&) _NOEXCEPT = default; + _LIBCPP_HIDE_FROM_ABI exception& operator=(const exception&) _NOEXCEPT = default; virtual ~exception() _NOEXCEPT; virtual const char* what() const _NOEXCEPT; }; -class _LIBCPP_EXCEPTION_ABI bad_exception : public exception { +class _LIBCPP_EXPORTED_FROM_ABI bad_exception : public exception { public: _LIBCPP_HIDE_FROM_ABI bad_exception() _NOEXCEPT {} + _LIBCPP_HIDE_FROM_ABI bad_exception(const bad_exception&) _NOEXCEPT = default; + _LIBCPP_HIDE_FROM_ABI bad_exception& operator=(const bad_exception&) _NOEXCEPT = default; ~bad_exception() _NOEXCEPT override; const char* what() const _NOEXCEPT override; }; diff --git a/third_party/libcxx/__exception/exception_ptr.h b/third_party/libcxx/__exception/exception_ptr.h index 1307481f0..beadd9212 100644 --- a/third_party/libcxx/__exception/exception_ptr.h +++ b/third_party/libcxx/__exception/exception_ptr.h @@ -12,21 +12,63 @@ #include <__config> #include <__exception/operations.h> #include <__memory/addressof.h> +#include <__memory/construct_at.h> +#include <__type_traits/decay.h> #include #include +#include +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif +#ifndef _LIBCPP_ABI_MICROSOFT + +# if _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION + +namespace __cxxabiv1 { + +extern "C" { +_LIBCPP_OVERRIDABLE_FUNC_VIS void* __cxa_allocate_exception(size_t) throw(); +_LIBCPP_OVERRIDABLE_FUNC_VIS void __cxa_free_exception(void*) throw(); + +struct __cxa_exception; +_LIBCPP_OVERRIDABLE_FUNC_VIS __cxa_exception* __cxa_init_primary_exception( + void*, + std::type_info*, +# if defined(_WIN32) + void(__thiscall*)(void*)) throw(); +# elif defined(__wasm__) + // In Wasm, a destructor returns its argument + void* (*)(void*)) throw(); +# else + void (*)(void*)) throw(); +# endif +} + +} // namespace __cxxabiv1 + +# endif + +#endif + namespace std { // purposefully not using versioning namespace #ifndef _LIBCPP_ABI_MICROSOFT -class _LIBCPP_TYPE_VIS exception_ptr { +class _LIBCPP_EXPORTED_FROM_ABI exception_ptr { void* __ptr_; + static exception_ptr __from_native_exception_pointer(void*) _NOEXCEPT; + + template + friend _LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep) _NOEXCEPT; + public: + // exception_ptr is basically a COW string. + using __trivially_relocatable = exception_ptr; + _LIBCPP_HIDE_FROM_ABI exception_ptr() _NOEXCEPT : __ptr_() {} _LIBCPP_HIDE_FROM_ABI exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {} @@ -44,18 +86,44 @@ public: return !(__x == __y); } - friend _LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT; - friend _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr); + friend _LIBCPP_EXPORTED_FROM_ABI exception_ptr current_exception() _NOEXCEPT; + friend _LIBCPP_EXPORTED_FROM_ABI void rethrow_exception(exception_ptr); }; template _LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep __e) _NOEXCEPT { # ifndef _LIBCPP_HAS_NO_EXCEPTIONS +# if _LIBCPP_AVAILABILITY_HAS_INIT_PRIMARY_EXCEPTION && __cplusplus >= 201103L + using _Ep2 = __decay_t<_Ep>; + + void* __ex = __cxxabiv1::__cxa_allocate_exception(sizeof(_Ep)); +# ifdef __wasm__ + // In Wasm, a destructor returns its argument + (void)__cxxabiv1::__cxa_init_primary_exception( + __ex, const_cast(&typeid(_Ep)), [](void* __p) -> void* { +# else + (void)__cxxabiv1::__cxa_init_primary_exception(__ex, const_cast(&typeid(_Ep)), [](void* __p) { +# endif + std::__destroy_at(static_cast<_Ep2*>(__p)); +# ifdef __wasm__ + return __p; +# endif + }); + + try { + ::new (__ex) _Ep2(__e); + return exception_ptr::__from_native_exception_pointer(__ex); + } catch (...) { + __cxxabiv1::__cxa_free_exception(__ex); + return current_exception(); + } +# else try { throw __e; } catch (...) { return current_exception(); } +# endif # else ((void)__e); std::abort(); @@ -64,7 +132,7 @@ _LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep __e) _NOEXCEPT { #else // _LIBCPP_ABI_MICROSOFT -class _LIBCPP_TYPE_VIS exception_ptr { +class _LIBCPP_EXPORTED_FROM_ABI exception_ptr { _LIBCPP_DIAGNOSTIC_PUSH _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-private-field") void* __ptr1_; @@ -81,17 +149,17 @@ public: explicit operator bool() const _NOEXCEPT; }; -_LIBCPP_FUNC_VIS bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT; +_LIBCPP_EXPORTED_FROM_ABI bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT; inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT { return !(__x == __y); } -_LIBCPP_FUNC_VIS void swap(exception_ptr&, exception_ptr&) _NOEXCEPT; +_LIBCPP_EXPORTED_FROM_ABI void swap(exception_ptr&, exception_ptr&) _NOEXCEPT; -_LIBCPP_FUNC_VIS exception_ptr __copy_exception_ptr(void* __except, const void* __ptr); -_LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT; -_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr); +_LIBCPP_EXPORTED_FROM_ABI exception_ptr __copy_exception_ptr(void* __except, const void* __ptr); +_LIBCPP_EXPORTED_FROM_ABI exception_ptr current_exception() _NOEXCEPT; +_LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void rethrow_exception(exception_ptr); // This is a built-in template function which automagically extracts the required // information. diff --git a/third_party/libcxx/__exception/nested_exception.h b/third_party/libcxx/__exception/nested_exception.h index 182c7ddda..feb489f87 100644 --- a/third_party/libcxx/__exception/nested_exception.h +++ b/third_party/libcxx/__exception/nested_exception.h @@ -15,8 +15,8 @@ #include <__type_traits/decay.h> #include <__type_traits/is_base_of.h> #include <__type_traits/is_class.h> +#include <__type_traits/is_constructible.h> #include <__type_traits/is_convertible.h> -#include <__type_traits/is_copy_constructible.h> #include <__type_traits/is_final.h> #include <__type_traits/is_polymorphic.h> #include <__utility/forward.h> @@ -28,13 +28,13 @@ namespace std { // purposefully not using versioning namespace -class _LIBCPP_EXCEPTION_ABI nested_exception { +class _LIBCPP_EXPORTED_FROM_ABI nested_exception { exception_ptr __ptr_; public: nested_exception() _NOEXCEPT; - // nested_exception(const nested_exception&) noexcept = default; - // nested_exception& operator=(const nested_exception&) noexcept = default; + _LIBCPP_HIDE_FROM_ABI nested_exception(const nested_exception&) _NOEXCEPT = default; + _LIBCPP_HIDE_FROM_ABI nested_exception& operator=(const nested_exception&) _NOEXCEPT = default; virtual ~nested_exception() _NOEXCEPT; // access functions @@ -53,14 +53,14 @@ struct __throw_with_nested; template struct __throw_with_nested<_Tp, _Up, true> { - _LIBCPP_NORETURN static inline _LIBCPP_INLINE_VISIBILITY void __do_throw(_Tp&& __t) { + _LIBCPP_NORETURN static inline _LIBCPP_HIDE_FROM_ABI void __do_throw(_Tp&& __t) { throw __nested<_Up>(std::forward<_Tp>(__t)); } }; template struct __throw_with_nested<_Tp, _Up, false> { - _LIBCPP_NORETURN static inline _LIBCPP_INLINE_VISIBILITY void __do_throw(_Tp&& __t) { throw std::forward<_Tp>(__t); } + _LIBCPP_NORETURN static inline _LIBCPP_HIDE_FROM_ABI void __do_throw(_Tp&& __t) { throw std::forward<_Tp>(__t); } }; #endif @@ -84,17 +84,15 @@ struct __can_dynamic_cast : _BoolConstant< is_polymorphic<_From>::value && (!is_base_of<_To, _From>::value || is_convertible::value)> {}; -template -inline _LIBCPP_HIDE_FROM_ABI void -rethrow_if_nested(const _Ep& __e, __enable_if_t< __can_dynamic_cast<_Ep, nested_exception>::value>* = 0) { +template ::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI void rethrow_if_nested(const _Ep& __e) { const nested_exception* __nep = dynamic_cast(std::addressof(__e)); if (__nep) __nep->rethrow_nested(); } -template -inline _LIBCPP_HIDE_FROM_ABI void -rethrow_if_nested(const _Ep&, __enable_if_t::value>* = 0) {} +template ::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI void rethrow_if_nested(const _Ep&) {} } // namespace std diff --git a/third_party/libcxx/__exception/operations.h b/third_party/libcxx/__exception/operations.h index e8c5ba61e..0a9c7a7c7 100644 --- a/third_party/libcxx/__exception/operations.h +++ b/third_party/libcxx/__exception/operations.h @@ -9,7 +9,6 @@ #ifndef _LIBCPP___EXCEPTION_OPERATIONS_H #define _LIBCPP___EXCEPTION_OPERATIONS_H -#include <__availability> #include <__config> #include @@ -21,22 +20,22 @@ namespace std { // purposefully not using versioning namespace #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS) || \ defined(_LIBCPP_BUILDING_LIBRARY) using unexpected_handler = void (*)(); -_LIBCPP_FUNC_VIS unexpected_handler set_unexpected(unexpected_handler) _NOEXCEPT; -_LIBCPP_FUNC_VIS unexpected_handler get_unexpected() _NOEXCEPT; -_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void unexpected(); +_LIBCPP_EXPORTED_FROM_ABI unexpected_handler set_unexpected(unexpected_handler) _NOEXCEPT; +_LIBCPP_EXPORTED_FROM_ABI unexpected_handler get_unexpected() _NOEXCEPT; +_LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void unexpected(); #endif using terminate_handler = void (*)(); -_LIBCPP_FUNC_VIS terminate_handler set_terminate(terminate_handler) _NOEXCEPT; -_LIBCPP_FUNC_VIS terminate_handler get_terminate() _NOEXCEPT; +_LIBCPP_EXPORTED_FROM_ABI terminate_handler set_terminate(terminate_handler) _NOEXCEPT; +_LIBCPP_EXPORTED_FROM_ABI terminate_handler get_terminate() _NOEXCEPT; -_LIBCPP_FUNC_VIS bool uncaught_exception() _NOEXCEPT; -_LIBCPP_FUNC_VIS _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS int uncaught_exceptions() _NOEXCEPT; +_LIBCPP_EXPORTED_FROM_ABI bool uncaught_exception() _NOEXCEPT; +_LIBCPP_EXPORTED_FROM_ABI int uncaught_exceptions() _NOEXCEPT; -class _LIBCPP_TYPE_VIS exception_ptr; +class _LIBCPP_EXPORTED_FROM_ABI exception_ptr; -_LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT; -_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr); +_LIBCPP_EXPORTED_FROM_ABI exception_ptr current_exception() _NOEXCEPT; +_LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void rethrow_exception(exception_ptr); } // namespace std #endif // _LIBCPP___EXCEPTION_OPERATIONS_H diff --git a/third_party/libcxx/__exception/terminate.h b/third_party/libcxx/__exception/terminate.h index d8dd9642b..e672471dc 100644 --- a/third_party/libcxx/__exception/terminate.h +++ b/third_party/libcxx/__exception/terminate.h @@ -16,7 +16,7 @@ #endif namespace std { // purposefully not using versioning namespace -_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void terminate() _NOEXCEPT; +_LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void terminate() _NOEXCEPT; } // namespace std #endif // _LIBCPP___EXCEPTION_TERMINATE_H diff --git a/third_party/libcxx/__expected/bad_expected_access.h b/third_party/libcxx/__expected/bad_expected_access.h index 1b88ab2be..1b734389e 100644 --- a/third_party/libcxx/__expected/bad_expected_access.h +++ b/third_party/libcxx/__expected/bad_expected_access.h @@ -17,6 +17,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 23 _LIBCPP_BEGIN_NAMESPACE_STD @@ -24,23 +27,28 @@ _LIBCPP_BEGIN_NAMESPACE_STD template class bad_expected_access; +_LIBCPP_DIAGNOSTIC_PUSH +# if !_LIBCPP_AVAILABILITY_HAS_BAD_EXPECTED_ACCESS_KEY_FUNCTION +_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables") +# endif template <> -class bad_expected_access : public exception { +class _LIBCPP_EXPORTED_FROM_ABI bad_expected_access : public exception { protected: - _LIBCPP_HIDE_FROM_ABI bad_expected_access() noexcept = default; - _LIBCPP_HIDE_FROM_ABI bad_expected_access(const bad_expected_access&) = default; - _LIBCPP_HIDE_FROM_ABI bad_expected_access(bad_expected_access&&) = default; - _LIBCPP_HIDE_FROM_ABI bad_expected_access& operator=(const bad_expected_access&) = default; - _LIBCPP_HIDE_FROM_ABI bad_expected_access& operator=(bad_expected_access&&) = default; - _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~bad_expected_access() override = default; + _LIBCPP_HIDE_FROM_ABI bad_expected_access() noexcept = default; + _LIBCPP_HIDE_FROM_ABI bad_expected_access(const bad_expected_access&) noexcept = default; + _LIBCPP_HIDE_FROM_ABI bad_expected_access(bad_expected_access&&) noexcept = default; + _LIBCPP_HIDE_FROM_ABI bad_expected_access& operator=(const bad_expected_access&) noexcept = default; + _LIBCPP_HIDE_FROM_ABI bad_expected_access& operator=(bad_expected_access&&) noexcept = default; + _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~bad_expected_access() override = default; public: - // The way this has been designed (by using a class template below) means that we'll already - // have a profusion of these vtables in TUs, and the dynamic linker will already have a bunch - // of work to do. So it is not worth hiding the specialization in the dylib, given that - // it adds deployment target restrictions. +# if _LIBCPP_AVAILABILITY_HAS_BAD_EXPECTED_ACCESS_KEY_FUNCTION + const char* what() const noexcept override; +# else _LIBCPP_HIDE_FROM_ABI_VIRTUAL const char* what() const noexcept override { return "bad access to std::expected"; } +# endif }; +_LIBCPP_DIAGNOSTIC_POP template class bad_expected_access : public bad_expected_access { @@ -60,4 +68,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 23 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___EXPECTED_BAD_EXPECTED_ACCESS_H diff --git a/third_party/libcxx/__expected/expected.h b/third_party/libcxx/__expected/expected.h index 668e23f21..f618b2060 100644 --- a/third_party/libcxx/__expected/expected.h +++ b/third_party/libcxx/__expected/expected.h @@ -23,29 +23,21 @@ #include <__type_traits/is_assignable.h> #include <__type_traits/is_constructible.h> #include <__type_traits/is_convertible.h> -#include <__type_traits/is_copy_assignable.h> -#include <__type_traits/is_copy_constructible.h> -#include <__type_traits/is_default_constructible.h> #include <__type_traits/is_function.h> -#include <__type_traits/is_move_assignable.h> -#include <__type_traits/is_move_constructible.h> +#include <__type_traits/is_nothrow_assignable.h> #include <__type_traits/is_nothrow_constructible.h> -#include <__type_traits/is_nothrow_copy_assignable.h> -#include <__type_traits/is_nothrow_copy_constructible.h> -#include <__type_traits/is_nothrow_default_constructible.h> -#include <__type_traits/is_nothrow_move_assignable.h> -#include <__type_traits/is_nothrow_move_constructible.h> #include <__type_traits/is_reference.h> #include <__type_traits/is_same.h> #include <__type_traits/is_swappable.h> -#include <__type_traits/is_trivially_copy_constructible.h> +#include <__type_traits/is_trivially_constructible.h> #include <__type_traits/is_trivially_destructible.h> -#include <__type_traits/is_trivially_move_constructible.h> +#include <__type_traits/is_trivially_relocatable.h> #include <__type_traits/is_void.h> #include <__type_traits/lazy.h> #include <__type_traits/negation.h> #include <__type_traits/remove_cv.h> #include <__type_traits/remove_cvref.h> +#include <__utility/as_const.h> #include <__utility/exception_guard.h> #include <__utility/forward.h> #include <__utility/in_place.h> @@ -58,6 +50,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 23 _LIBCPP_BEGIN_NAMESPACE_STD @@ -84,93 +79,445 @@ _LIBCPP_HIDE_FROM_ABI void __throw_bad_expected_access(_Arg&& __arg) { # endif } +// If parameter type `_Tp` of `__conditional_no_unique_address` is neither +// copyable nor movable, a constructor with this tag is provided. For that +// constructor, the user has to provide a function and arguments. The function +// must return an object of type `_Tp`. When the function is invoked by the +// constructor, guaranteed copy elision kicks in and the `_Tp` is constructed +// in place. +struct __conditional_no_unique_address_invoke_tag {}; + +// This class implements an object with `[[no_unique_address]]` conditionally applied to it, +// based on the value of `_NoUnique`. +// +// A member of this class must always have `[[no_unique_address]]` applied to +// it. Otherwise, the `[[no_unique_address]]` in the "`_NoUnique == true`" case +// would not have any effect. In the `false` case, the `__v` is not +// `[[no_unique_address]]`, so nullifies the effects of the "outer" +// `[[no_unique_address]]` regarding data layout. +// +// If we had a language feature, this class would basically be replaced by `[[no_unique_address(condition)]]`. +template +struct __conditional_no_unique_address; + +template +struct __conditional_no_unique_address { + template + _LIBCPP_HIDE_FROM_ABI constexpr explicit __conditional_no_unique_address(in_place_t, _Args&&... __args) + : __v(std::forward<_Args>(__args)...) {} + + template + _LIBCPP_HIDE_FROM_ABI constexpr explicit __conditional_no_unique_address( + __conditional_no_unique_address_invoke_tag, _Func&& __f, _Args&&... __args) + : __v(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {} + + _LIBCPP_NO_UNIQUE_ADDRESS _Tp __v; +}; + +template +struct __conditional_no_unique_address { + template + _LIBCPP_HIDE_FROM_ABI constexpr explicit __conditional_no_unique_address(in_place_t, _Args&&... __args) + : __v(std::forward<_Args>(__args)...) {} + + template + _LIBCPP_HIDE_FROM_ABI constexpr explicit __conditional_no_unique_address( + __conditional_no_unique_address_invoke_tag, _Func&& __f, _Args&&... __args) + : __v(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {} + + _Tp __v; +}; + +// This function returns whether the type `_Second` can be stuffed into the tail padding +// of the `_First` type if both of them are given `[[no_unique_address]]`. +template +inline constexpr bool __fits_in_tail_padding = []() { + struct __x { + _LIBCPP_NO_UNIQUE_ADDRESS _First __first; + _LIBCPP_NO_UNIQUE_ADDRESS _Second __second; + }; + return sizeof(__x) == sizeof(_First); +}(); + +// This class implements the storage used by `std::expected`. We have a few +// goals for this storage: +// 1. Whenever the underlying {_Tp | _Unex} combination has free bytes in its +// tail padding, we should reuse it to store the bool discriminator of the +// expected, so as to save space. +// 2. Whenever the `expected<_Tp, _Unex>` as a whole has free bytes in its tail +// padding, we should allow an object following the expected to be stored in +// its tail padding. +// 3. However, we never want a user object (say `X`) that would follow an +// `expected<_Tp, _Unex>` to be stored in the padding bytes of the +// underlying {_Tp | _Unex} union, if any. That is because we use +// `construct_at` on that union, which would end up overwriting the `X` +// member if it is stored in the tail padding of the union. +// +// To achieve this, `__expected_base`'s logic is implemented in an inner +// `__repr` class. `__expected_base` holds one `__repr` member which is +// conditionally `[[no_unique_address]]`. The `__repr` class holds the +// underlying {_Tp | _Unex} union and a boolean "has value" flag. +// +// Which one of the `__repr_`/`__union_` members is `[[no_unique_address]]` +// depends on whether the "has value" boolean fits into the tail padding of +// the underlying {_Tp | _Unex} union: +// +// - In case the "has value" bool fits into the tail padding of the union, the +// whole `__repr_` member is _not_ `[[no_unique_address]]` as it needs to be +// transparently replaced on `emplace()`/`swap()` etc. +// - In case the "has value" bool does not fit into the tail padding of the +// union, only the union member must be transparently replaced (therefore is +// _not_ `[[no_unique_address]]`) and the "has value" flag must be adjusted +// manually. +// +// This way, the member that is transparently replaced on mutating operations +// is never `[[no_unique_address]]`, satisfying the requirements from +// "[basic.life]" in the standard. +// +// Stripped away of all superfluous elements, the layout of `__expected_base` +// then looks like this: +// +// template +// class expected_base { +// union union_t { +// [[no_unique_address]] Tp val; +// [[no_unique_address]] Err unex; +// }; +// +// static constexpr bool put_flag_in_tail = fits_in_tail_padding; +// static constexpr bool allow_reusing_expected_tail_padding = !put_flag_in_tail; +// +// struct repr { +// private: +// // If "has value" fits into the tail, this should be +// // `[[no_unique_address]]`, otherwise not. +// [[no_unique_address]] conditional_no_unique_address< +// put_flag_in_tail, +// union_t>::type union_; +// [[no_unique_address]] bool has_val_; +// }; +// +// protected: +// // If "has value" fits into the tail, this must _not_ be +// // `[[no_unique_address]]` so that we fill out the +// // complete `expected` object. +// [[no_unique_address]] conditional_no_unique_address< +// allow_reusing_expected_tail_padding, +// repr>::type repr_; +// }; +// template -class expected { - static_assert( - !is_reference_v<_Tp> && - !is_function_v<_Tp> && - !is_same_v, in_place_t> && - !is_same_v, unexpect_t> && - !__is_std_unexpected>::value && - __valid_std_unexpected<_Err>::value - , - "[expected.object.general] A program that instantiates the definition of template expected for a " - "reference type, a function type, or for possibly cv-qualified types in_place_t, unexpect_t, or a " - "specialization of unexpected for the T parameter is ill-formed. A program that instantiates the " - "definition of the template expected with a type for the E parameter that is not a valid " - "template argument for unexpected is ill-formed."); +class __expected_base { + // use named union because [[no_unique_address]] cannot be applied to an unnamed union, + // also guaranteed elision into a potentially-overlapping subobject is unsettled (and + // it's not clear that it's implementable, given that the function is allowed to clobber + // the tail padding) - see https://github.com/itanium-cxx-abi/cxx-abi/issues/107. + union __union_t { + _LIBCPP_HIDE_FROM_ABI constexpr __union_t(const __union_t&) = delete; + _LIBCPP_HIDE_FROM_ABI constexpr __union_t(const __union_t&) + requires(is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Err> && + is_trivially_copy_constructible_v<_Tp> && is_trivially_copy_constructible_v<_Err>) + = default; + _LIBCPP_HIDE_FROM_ABI constexpr __union_t(__union_t&&) = delete; + _LIBCPP_HIDE_FROM_ABI constexpr __union_t(__union_t&&) + requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> && + is_trivially_move_constructible_v<_Tp> && is_trivially_move_constructible_v<_Err>) + = default; + _LIBCPP_HIDE_FROM_ABI constexpr __union_t& operator=(const __union_t&) = delete; + _LIBCPP_HIDE_FROM_ABI constexpr __union_t& operator=(__union_t&&) = delete; + + template + _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(in_place_t, _Args&&... __args) + : __val_(std::forward<_Args>(__args)...) {} + + template + _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(unexpect_t, _Args&&... __args) + : __unex_(std::forward<_Args>(__args)...) {} + + template + _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t( + std::__expected_construct_in_place_from_invoke_tag, _Func&& __f, _Args&&... __args) + : __val_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {} + + template + _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t( + std::__expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args) + : __unex_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {} + + _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() + requires(is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>) + = default; + + // __repr's destructor handles this + _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() {} + + _LIBCPP_NO_UNIQUE_ADDRESS _Tp __val_; + _LIBCPP_NO_UNIQUE_ADDRESS _Err __unex_; + }; + + static constexpr bool __put_flag_in_tail = __fits_in_tail_padding<__union_t, bool>; + static constexpr bool __allow_reusing_expected_tail_padding = !__put_flag_in_tail; + + struct __repr { + _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr() = delete; + + template + _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(in_place_t __tag, _Args&&... __args) + : __union_(in_place, __tag, std::forward<_Args>(__args)...), __has_val_(true) {} + + template + _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(unexpect_t __tag, _Args&&... __args) + : __union_(in_place, __tag, std::forward<_Args>(__args)...), __has_val_(false) {} + + template + _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(std::__expected_construct_in_place_from_invoke_tag __tag, + _Args&&... __args) + : __union_(in_place, __tag, std::forward<_Args>(__args)...), __has_val_(true) {} + + template + _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(std::__expected_construct_unexpected_from_invoke_tag __tag, + _Args&&... __args) + : __union_(in_place, __tag, std::forward<_Args>(__args)...), __has_val_(false) {} + + // The return value of `__make_union` must be constructed in place in the + // `__v` member of `__union_`, relying on guaranteed copy elision. To do + // this, the `__conditional_no_unique_address_invoke_tag` constructor is + // called with a lambda that is immediately called inside + // `__conditional_no_unique_address`'s constructor. + template + _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(bool __has_val, _OtherUnion&& __other) + requires(__allow_reusing_expected_tail_padding) + : __union_(__conditional_no_unique_address_invoke_tag{}, + [&] { return __make_union(__has_val, std::forward<_OtherUnion>(__other)); }), + __has_val_(__has_val) {} + + _LIBCPP_HIDE_FROM_ABI constexpr __repr(const __repr&) = delete; + _LIBCPP_HIDE_FROM_ABI constexpr __repr(const __repr&) + requires(is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Err> && + is_trivially_copy_constructible_v<_Tp> && is_trivially_copy_constructible_v<_Err>) + = default; + _LIBCPP_HIDE_FROM_ABI constexpr __repr(__repr&&) = delete; + _LIBCPP_HIDE_FROM_ABI constexpr __repr(__repr&&) + requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> && + is_trivially_move_constructible_v<_Tp> && is_trivially_move_constructible_v<_Err>) + = default; + + _LIBCPP_HIDE_FROM_ABI constexpr __repr& operator=(const __repr&) = delete; + _LIBCPP_HIDE_FROM_ABI constexpr __repr& operator=(__repr&&) = delete; + + _LIBCPP_HIDE_FROM_ABI constexpr ~__repr() + requires(is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>) + = default; + + _LIBCPP_HIDE_FROM_ABI constexpr ~__repr() + requires(!is_trivially_destructible_v<_Tp> || !is_trivially_destructible_v<_Err>) + { + __destroy_union_member(); + } + + _LIBCPP_HIDE_FROM_ABI constexpr void __destroy_union() + requires(__allow_reusing_expected_tail_padding && + (is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>)) + { + // Note: Since the destructor of the union is trivial, this does nothing + // except to end the lifetime of the union. + std::destroy_at(&__union_.__v); + } + + _LIBCPP_HIDE_FROM_ABI constexpr void __destroy_union() + requires(__allow_reusing_expected_tail_padding && + (!is_trivially_destructible_v<_Tp> || !is_trivially_destructible_v<_Err>)) + { + __destroy_union_member(); + std::destroy_at(&__union_.__v); + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr void __construct_union(in_place_t, _Args&&... __args) + requires(__allow_reusing_expected_tail_padding) + { + std::construct_at(&__union_.__v, in_place, std::forward<_Args>(__args)...); + __has_val_ = true; + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr void __construct_union(unexpect_t, _Args&&... __args) + requires(__allow_reusing_expected_tail_padding) + { + std::construct_at(&__union_.__v, unexpect, std::forward<_Args>(__args)...); + __has_val_ = false; + } + + private: + template + friend class __expected_base; + + _LIBCPP_HIDE_FROM_ABI constexpr void __destroy_union_member() + requires(!is_trivially_destructible_v<_Tp> || !is_trivially_destructible_v<_Err>) + { + if (__has_val_) { + std::destroy_at(std::addressof(__union_.__v.__val_)); + } else { + std::destroy_at(std::addressof(__union_.__v.__unex_)); + } + } + + template + _LIBCPP_HIDE_FROM_ABI static constexpr __union_t __make_union(bool __has_val, _OtherUnion&& __other) + requires(__allow_reusing_expected_tail_padding) + { + if (__has_val) + return __union_t(in_place, std::forward<_OtherUnion>(__other).__val_); + else + return __union_t(unexpect, std::forward<_OtherUnion>(__other).__unex_); + } + + _LIBCPP_NO_UNIQUE_ADDRESS __conditional_no_unique_address<__put_flag_in_tail, __union_t> __union_; + _LIBCPP_NO_UNIQUE_ADDRESS bool __has_val_; + }; + + template + _LIBCPP_HIDE_FROM_ABI static constexpr __repr __make_repr(bool __has_val, _OtherUnion&& __other) + requires(__put_flag_in_tail) + { + if (__has_val) + return __repr(in_place, std::forward<_OtherUnion>(__other).__val_); + else + return __repr(unexpect, std::forward<_OtherUnion>(__other).__unex_); + } + +protected: + template + _LIBCPP_HIDE_FROM_ABI constexpr explicit __expected_base(_Args&&... __args) + : __repr_(in_place, std::forward<_Args>(__args)...) {} + + // In case we copy/move construct from another `expected` we need to create + // our `expected` so that it either has a value or not, depending on the "has + // value" flag of the other `expected`. To do this without falling back on + // `std::construct_at` we rely on guaranteed copy elision using two helper + // functions `__make_repr` and `__make_union`. There have to be two since + // there are two data layouts with different members being + // `[[no_unique_address]]`. GCC (as of version 13) does not do guaranteed + // copy elision when initializing `[[no_unique_address]]` members. The two + // cases are: + // + // - `__make_repr`: This is used when the "has value" flag lives in the tail + // of the union. In this case, the `__repr` member is _not_ + // `[[no_unique_address]]`. + // - `__make_union`: When the "has value" flag does _not_ fit in the tail of + // the union, the `__repr` member is `[[no_unique_address]]` and the union + // is not. + // + // This constructor "catches" the first case and leaves the second case to + // `__union_t`, its constructors and `__make_union`. + template + _LIBCPP_HIDE_FROM_ABI constexpr explicit __expected_base(bool __has_val, _OtherUnion&& __other) + requires(__put_flag_in_tail) + : __repr_(__conditional_no_unique_address_invoke_tag{}, + [&] { return __make_repr(__has_val, std::forward<_OtherUnion>(__other)); }) {} + + _LIBCPP_HIDE_FROM_ABI constexpr void __destroy() { + if constexpr (__put_flag_in_tail) + std::destroy_at(&__repr_.__v); + else + __repr_.__v.__destroy_union(); + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr void __construct(_Tag __tag, _Args&&... __args) { + if constexpr (__put_flag_in_tail) + std::construct_at(&__repr_.__v, __tag, std::forward<_Args>(__args)...); + else + __repr_.__v.__construct_union(__tag, std::forward<_Args>(__args)...); + } + + _LIBCPP_HIDE_FROM_ABI constexpr bool __has_val() const { return __repr_.__v.__has_val_; } + _LIBCPP_HIDE_FROM_ABI constexpr __union_t& __union() { return __repr_.__v.__union_.__v; } + _LIBCPP_HIDE_FROM_ABI constexpr const __union_t& __union() const { return __repr_.__v.__union_.__v; } + _LIBCPP_HIDE_FROM_ABI constexpr _Tp& __val() { return __repr_.__v.__union_.__v.__val_; } + _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& __val() const { return __repr_.__v.__union_.__v.__val_; } + _LIBCPP_HIDE_FROM_ABI constexpr _Err& __unex() { return __repr_.__v.__union_.__v.__unex_; } + _LIBCPP_HIDE_FROM_ABI constexpr const _Err& __unex() const { return __repr_.__v.__union_.__v.__unex_; } + +private: + _LIBCPP_NO_UNIQUE_ADDRESS __conditional_no_unique_address<__allow_reusing_expected_tail_padding, __repr> __repr_; +}; + +template +class expected : private __expected_base<_Tp, _Err> { + static_assert(!is_reference_v<_Tp> && !is_function_v<_Tp> && !is_same_v, in_place_t> && + !is_same_v, unexpect_t> && !__is_std_unexpected>::value && + __valid_std_unexpected<_Err>::value, + "[expected.object.general] A program that instantiates the definition of template expected for a " + "reference type, a function type, or for possibly cv-qualified types in_place_t, unexpect_t, or a " + "specialization of unexpected for the T parameter is ill-formed. A program that instantiates the " + "definition of the template expected with a type for the E parameter that is not a valid " + "template argument for unexpected is ill-formed."); template friend class expected; + using __base = __expected_base<_Tp, _Err>; + public: using value_type = _Tp; using error_type = _Err; using unexpected_type = unexpected<_Err>; + using __trivially_relocatable = + __conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value && __libcpp_is_trivially_relocatable<_Err>::value, + expected, + void>; + template using rebind = expected<_Up, error_type>; // [expected.object.ctor], constructors - _LIBCPP_HIDE_FROM_ABI constexpr expected() - noexcept(is_nothrow_default_constructible_v<_Tp>) // strengthened + _LIBCPP_HIDE_FROM_ABI constexpr expected() noexcept(is_nothrow_default_constructible_v<_Tp>) // strengthened requires is_default_constructible_v<_Tp> - : __has_val_(true) { - std::construct_at(std::addressof(__union_.__val_)); - } + : __base(in_place) {} _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) = delete; _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) - requires(is_copy_constructible_v<_Tp> && - is_copy_constructible_v<_Err> && - is_trivially_copy_constructible_v<_Tp> && + requires(is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Err> && is_trivially_copy_constructible_v<_Tp> && is_trivially_copy_constructible_v<_Err>) = default; - _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected& __other) - noexcept(is_nothrow_copy_constructible_v<_Tp> && is_nothrow_copy_constructible_v<_Err>) // strengthened + _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected& __other) noexcept( + is_nothrow_copy_constructible_v<_Tp> && is_nothrow_copy_constructible_v<_Err>) // strengthened requires(is_copy_constructible_v<_Tp> && is_copy_constructible_v<_Err> && !(is_trivially_copy_constructible_v<_Tp> && is_trivially_copy_constructible_v<_Err>)) - : __has_val_(__other.__has_val_) { - if (__has_val_) { - std::construct_at(std::addressof(__union_.__val_), __other.__union_.__val_); - } else { - std::construct_at(std::addressof(__union_.__unex_), __other.__union_.__unex_); - } - } - + : __base(__other.__has_val(), __other.__union()) {} _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&&) - requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> - && is_trivially_move_constructible_v<_Tp> && is_trivially_move_constructible_v<_Err>) + requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> && is_trivially_move_constructible_v<_Tp> && + is_trivially_move_constructible_v<_Err>) = default; - _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&& __other) - noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_constructible_v<_Err>) + _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&& __other) noexcept( + is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_constructible_v<_Err>) requires(is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> && !(is_trivially_move_constructible_v<_Tp> && is_trivially_move_constructible_v<_Err>)) - : __has_val_(__other.__has_val_) { - if (__has_val_) { - std::construct_at(std::addressof(__union_.__val_), std::move(__other.__union_.__val_)); - } else { - std::construct_at(std::addressof(__union_.__unex_), std::move(__other.__union_.__unex_)); - } - } + : __base(__other.__has_val(), std::move(__other.__union())) {} private: template using __can_convert = _And< is_constructible<_Tp, _UfQual>, is_constructible<_Err, _OtherErrQual>, - _Not&>>, - _Not>>, - _Not&>>, - _Not>>, - _Not&, _Tp>>, - _Not&&, _Tp>>, - _Not&, _Tp>>, - _Not&&, _Tp>>, + _If<_Not, bool>>::value, + _And< + _Not<_And, is_same<_Err, _OtherErr>>>, // use the copy constructor instead, see #92676 + _Not&>>, + _Not>>, + _Not&>>, + _Not>>, + _Not&, _Tp>>, + _Not&&, _Tp>>, + _Not&, _Tp>>, + _Not&&, _Tp>>>, + true_type>, _Not, expected<_Up, _OtherErr>&>>, _Not, expected<_Up, _OtherErr>>>, _Not, const expected<_Up, _OtherErr>&>>, @@ -179,141 +526,97 @@ private: template _LIBCPP_HIDE_FROM_ABI constexpr explicit expected( std::__expected_construct_in_place_from_invoke_tag __tag, _Func&& __f, _Args&&... __args) - : __union_(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...), __has_val_(true) {} + : __base(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...) {} template _LIBCPP_HIDE_FROM_ABI constexpr explicit expected( std::__expected_construct_unexpected_from_invoke_tag __tag, _Func&& __f, _Args&&... __args) - : __union_(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...), __has_val_(false) {} + : __base(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...) {} public: template requires __can_convert<_Up, _OtherErr, const _Up&, const _OtherErr&>::value _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v || !is_convertible_v) - expected(const expected<_Up, _OtherErr>& __other) - noexcept(is_nothrow_constructible_v<_Tp, const _Up&> && - is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened - : __has_val_(__other.__has_val_) { - if (__has_val_) { - std::construct_at(std::addressof(__union_.__val_), __other.__union_.__val_); - } else { - std::construct_at(std::addressof(__union_.__unex_), __other.__union_.__unex_); - } - } + expected(const expected<_Up, _OtherErr>& __other) noexcept( + is_nothrow_constructible_v<_Tp, const _Up&> && + is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened + : __base(__other.__has_val(), __other.__union()) {} template requires __can_convert<_Up, _OtherErr, _Up, _OtherErr>::value _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_Up, _Tp> || !is_convertible_v<_OtherErr, _Err>) - expected(expected<_Up, _OtherErr>&& __other) - noexcept(is_nothrow_constructible_v<_Tp, _Up> && is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened - : __has_val_(__other.__has_val_) { - if (__has_val_) { - std::construct_at(std::addressof(__union_.__val_), std::move(__other.__union_.__val_)); - } else { - std::construct_at(std::addressof(__union_.__unex_), std::move(__other.__union_.__unex_)); - } - } + expected(expected<_Up, _OtherErr>&& __other) noexcept( + is_nothrow_constructible_v<_Tp, _Up> && is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened + : __base(__other.__has_val(), std::move(__other.__union())) {} template requires(!is_same_v, in_place_t> && !is_same_v> && - !__is_std_unexpected>::value && is_constructible_v<_Tp, _Up>) + is_constructible_v<_Tp, _Up> && !__is_std_unexpected>::value && + (!is_same_v, bool> || !__is_std_expected>::value)) _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_Up, _Tp>) - expected(_Up&& __u) - noexcept(is_nothrow_constructible_v<_Tp, _Up>) // strengthened - : __has_val_(true) { - std::construct_at(std::addressof(__union_.__val_), std::forward<_Up>(__u)); - } - + expected(_Up&& __u) noexcept(is_nothrow_constructible_v<_Tp, _Up>) // strengthened + : __base(in_place, std::forward<_Up>(__u)) {} template requires is_constructible_v<_Err, const _OtherErr&> - _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v) - expected(const unexpected<_OtherErr>& __unex) - noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened - : __has_val_(false) { - std::construct_at(std::addressof(__union_.__unex_), __unex.error()); - } + _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v) expected( + const unexpected<_OtherErr>& __unex) noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened + : __base(unexpect, __unex.error()) {} template requires is_constructible_v<_Err, _OtherErr> _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>) - expected(unexpected<_OtherErr>&& __unex) - noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened - : __has_val_(false) { - std::construct_at(std::addressof(__union_.__unex_), std::move(__unex.error())); - } + expected(unexpected<_OtherErr>&& __unex) noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened + : __base(unexpect, std::move(__unex.error())) {} template requires is_constructible_v<_Tp, _Args...> - _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t, _Args&&... __args) - noexcept(is_nothrow_constructible_v<_Tp, _Args...>) // strengthened - : __has_val_(true) { - std::construct_at(std::addressof(__union_.__val_), std::forward<_Args>(__args)...); - } + _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t, _Args&&... __args) noexcept( + is_nothrow_constructible_v<_Tp, _Args...>) // strengthened + : __base(in_place, std::forward<_Args>(__args)...) {} template requires is_constructible_v< _Tp, initializer_list<_Up>&, _Args... > - _LIBCPP_HIDE_FROM_ABI constexpr explicit - expected(in_place_t, initializer_list<_Up> __il, _Args&&... __args) - noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>) // strengthened - : __has_val_(true) { - std::construct_at(std::addressof(__union_.__val_), __il, std::forward<_Args>(__args)...); - } + _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t, initializer_list<_Up> __il, _Args&&... __args) noexcept( + is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...>) // strengthened + : __base(in_place, __il, std::forward<_Args>(__args)...) {} template requires is_constructible_v<_Err, _Args...> - _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, _Args&&... __args) - noexcept(is_nothrow_constructible_v<_Err, _Args...>) // strengthened - : __has_val_(false) { - std::construct_at(std::addressof(__union_.__unex_), std::forward<_Args>(__args)...); - } + _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, _Args&&... __args) noexcept( + is_nothrow_constructible_v<_Err, _Args...>) // strengthened + : __base(unexpect, std::forward<_Args>(__args)...) {} template requires is_constructible_v< _Err, initializer_list<_Up>&, _Args... > - _LIBCPP_HIDE_FROM_ABI constexpr explicit - expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args) - noexcept(is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened - : __has_val_(false) { - std::construct_at(std::addressof(__union_.__unex_), __il, std::forward<_Args>(__args)...); - } + _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args) noexcept( + is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened + : __base(unexpect, __il, std::forward<_Args>(__args)...) {} // [expected.object.dtor], destructor - _LIBCPP_HIDE_FROM_ABI constexpr ~expected() - requires(is_trivially_destructible_v<_Tp> && is_trivially_destructible_v<_Err>) - = default; - - _LIBCPP_HIDE_FROM_ABI constexpr ~expected() - requires(!is_trivially_destructible_v<_Tp> || !is_trivially_destructible_v<_Err>) - { - if (__has_val_) { - std::destroy_at(std::addressof(__union_.__val_)); - } else { - std::destroy_at(std::addressof(__union_.__unex_)); - } - } + _LIBCPP_HIDE_FROM_ABI constexpr ~expected() = default; private: - template - _LIBCPP_HIDE_FROM_ABI static constexpr void __reinit_expected(_T1& __newval, _T2& __oldval, _Args&&... __args) { + template + _LIBCPP_HIDE_FROM_ABI constexpr void __reinit_expected(_T2& __oldval, _Args&&... __args) { if constexpr (is_nothrow_constructible_v<_T1, _Args...>) { - std::destroy_at(std::addressof(__oldval)); - std::construct_at(std::addressof(__newval), std::forward<_Args>(__args)...); + this->__destroy(); + this->__construct(_Tag{}, std::forward<_Args>(__args)...); } else if constexpr (is_nothrow_move_constructible_v<_T1>) { _T1 __tmp(std::forward<_Args>(__args)...); - std::destroy_at(std::addressof(__oldval)); - std::construct_at(std::addressof(__newval), std::move(__tmp)); + this->__destroy(); + this->__construct(_Tag{}, std::move(__tmp)); } else { static_assert( is_nothrow_move_constructible_v<_T2>, "To provide strong exception guarantee, T2 has to satisfy `is_nothrow_move_constructible_v` so that it can " "be reverted to the previous state in case an exception is thrown during the assignment."); _T2 __tmp(std::move(__oldval)); - std::destroy_at(std::addressof(__oldval)); - auto __trans = - std::__make_exception_guard([&] { std::construct_at(std::addressof(__oldval), std::move(__tmp)); }); - std::construct_at(std::addressof(__newval), std::forward<_Args>(__args)...); + this->__destroy(); + auto __trans = std::__make_exception_guard([&] { this->__construct(_OtherTag{}, std::move(__tmp)); }); + this->__construct(_Tag{}, std::forward<_Args>(__args)...); __trans.__complete(); } } @@ -322,73 +625,55 @@ public: // [expected.object.assign], assignment _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected&) = delete; - _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected& __rhs) - noexcept(is_nothrow_copy_assignable_v<_Tp> && - is_nothrow_copy_constructible_v<_Tp> && - is_nothrow_copy_assignable_v<_Err> && - is_nothrow_copy_constructible_v<_Err>) // strengthened - requires(is_copy_assignable_v<_Tp> && - is_copy_constructible_v<_Tp> && - is_copy_assignable_v<_Err> && + _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected& __rhs) noexcept( + is_nothrow_copy_assignable_v<_Tp> && is_nothrow_copy_constructible_v<_Tp> && is_nothrow_copy_assignable_v<_Err> && + is_nothrow_copy_constructible_v<_Err>) // strengthened + requires(is_copy_assignable_v<_Tp> && is_copy_constructible_v<_Tp> && is_copy_assignable_v<_Err> && is_copy_constructible_v<_Err> && - (is_nothrow_move_constructible_v<_Tp> || - is_nothrow_move_constructible_v<_Err>)) + (is_nothrow_move_constructible_v<_Tp> || is_nothrow_move_constructible_v<_Err>)) { - if (__has_val_ && __rhs.__has_val_) { - __union_.__val_ = __rhs.__union_.__val_; - } else if (__has_val_) { - __reinit_expected(__union_.__unex_, __union_.__val_, __rhs.__union_.__unex_); - } else if (__rhs.__has_val_) { - __reinit_expected(__union_.__val_, __union_.__unex_, __rhs.__union_.__val_); + if (this->__has_val() && __rhs.__has_val()) { + this->__val() = __rhs.__val(); + } else if (this->__has_val()) { + __reinit_expected(this->__val(), __rhs.__unex()); + } else if (__rhs.__has_val()) { + __reinit_expected(this->__unex(), __rhs.__val()); } else { - __union_.__unex_ = __rhs.__union_.__unex_; + this->__unex() = __rhs.__unex(); } - // note: only reached if no exception+rollback was done inside __reinit_expected - __has_val_ = __rhs.__has_val_; return *this; } - _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(expected&& __rhs) - noexcept(is_nothrow_move_assignable_v<_Tp> && - is_nothrow_move_constructible_v<_Tp> && - is_nothrow_move_assignable_v<_Err> && - is_nothrow_move_constructible_v<_Err>) - requires(is_move_constructible_v<_Tp> && - is_move_assignable_v<_Tp> && - is_move_constructible_v<_Err> && + _LIBCPP_HIDE_FROM_ABI constexpr expected& + operator=(expected&& __rhs) noexcept(is_nothrow_move_assignable_v<_Tp> && is_nothrow_move_constructible_v<_Tp> && + is_nothrow_move_assignable_v<_Err> && is_nothrow_move_constructible_v<_Err>) + requires(is_move_constructible_v<_Tp> && is_move_assignable_v<_Tp> && is_move_constructible_v<_Err> && is_move_assignable_v<_Err> && - (is_nothrow_move_constructible_v<_Tp> || - is_nothrow_move_constructible_v<_Err>)) + (is_nothrow_move_constructible_v<_Tp> || is_nothrow_move_constructible_v<_Err>)) { - if (__has_val_ && __rhs.__has_val_) { - __union_.__val_ = std::move(__rhs.__union_.__val_); - } else if (__has_val_) { - __reinit_expected(__union_.__unex_, __union_.__val_, std::move(__rhs.__union_.__unex_)); - } else if (__rhs.__has_val_) { - __reinit_expected(__union_.__val_, __union_.__unex_, std::move(__rhs.__union_.__val_)); + if (this->__has_val() && __rhs.__has_val()) { + this->__val() = std::move(__rhs.__val()); + } else if (this->__has_val()) { + __reinit_expected(this->__val(), std::move(__rhs.__unex())); + } else if (__rhs.__has_val()) { + __reinit_expected(this->__unex(), std::move(__rhs.__val())); } else { - __union_.__unex_ = std::move(__rhs.__union_.__unex_); + this->__unex() = std::move(__rhs.__unex()); } - // note: only reached if no exception+rollback was done inside __reinit_expected - __has_val_ = __rhs.__has_val_; return *this; } template _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(_Up&& __v) - requires(!is_same_v> && - !__is_std_unexpected>::value && - is_constructible_v<_Tp, _Up> && - is_assignable_v<_Tp&, _Up> && - (is_nothrow_constructible_v<_Tp, _Up> || - is_nothrow_move_constructible_v<_Tp> || + requires(!is_same_v> && !__is_std_unexpected>::value && + is_constructible_v<_Tp, _Up> && is_assignable_v<_Tp&, _Up> && + (is_nothrow_constructible_v<_Tp, _Up> || is_nothrow_move_constructible_v<_Tp> || is_nothrow_move_constructible_v<_Err>)) { - if (__has_val_) { - __union_.__val_ = std::forward<_Up>(__v); + if (this->__has_val()) { + this->__val() = std::forward<_Up>(__v); } else { - __reinit_expected(__union_.__val_, __union_.__unex_, std::forward<_Up>(__v)); - __has_val_ = true; + __reinit_expected(this->__unex(), std::forward<_Up>(__v)); } return *this; } @@ -407,11 +692,10 @@ public: template requires(__can_assign_from_unexpected) _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const unexpected<_OtherErr>& __un) { - if (__has_val_) { - __reinit_expected(__union_.__unex_, __union_.__val_, __un.error()); - __has_val_ = false; + if (this->__has_val()) { + __reinit_expected(this->__val(), __un.error()); } else { - __union_.__unex_ = __un.error(); + this->__unex() = __un.error(); } return *this; } @@ -419,11 +703,10 @@ public: template requires(__can_assign_from_unexpected<_OtherErr>) _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(unexpected<_OtherErr>&& __un) { - if (__has_val_) { - __reinit_expected(__union_.__unex_, __union_.__val_, std::move(__un.error())); - __has_val_ = false; + if (this->__has_val()) { + __reinit_expected(this->__val(), std::move(__un.error())); } else { - __union_.__unex_ = std::move(__un.error()); + this->__unex() = std::move(__un.error()); } return *this; } @@ -431,90 +714,69 @@ public: template requires is_nothrow_constructible_v<_Tp, _Args...> _LIBCPP_HIDE_FROM_ABI constexpr _Tp& emplace(_Args&&... __args) noexcept { - if (__has_val_) { - std::destroy_at(std::addressof(__union_.__val_)); - } else { - std::destroy_at(std::addressof(__union_.__unex_)); - __has_val_ = true; - } - return *std::construct_at(std::addressof(__union_.__val_), std::forward<_Args>(__args)...); + this->__destroy(); + this->__construct(in_place, std::forward<_Args>(__args)...); + return this->__val(); } template - requires is_nothrow_constructible_v< _Tp, initializer_list<_Up>&, _Args... > + requires is_nothrow_constructible_v<_Tp, initializer_list<_Up>&, _Args...> _LIBCPP_HIDE_FROM_ABI constexpr _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args) noexcept { - if (__has_val_) { - std::destroy_at(std::addressof(__union_.__val_)); - } else { - std::destroy_at(std::addressof(__union_.__unex_)); - __has_val_ = true; - } - return *std::construct_at(std::addressof(__union_.__val_), __il, std::forward<_Args>(__args)...); + this->__destroy(); + this->__construct(in_place, __il, std::forward<_Args>(__args)...); + return this->__val(); } - public: // [expected.object.swap], swap - _LIBCPP_HIDE_FROM_ABI constexpr void swap(expected& __rhs) - noexcept(is_nothrow_move_constructible_v<_Tp> && - is_nothrow_swappable_v<_Tp> && - is_nothrow_move_constructible_v<_Err> && - is_nothrow_swappable_v<_Err>) - requires(is_swappable_v<_Tp> && - is_swappable_v<_Err> && - is_move_constructible_v<_Tp> && + _LIBCPP_HIDE_FROM_ABI constexpr void + swap(expected& __rhs) noexcept(is_nothrow_move_constructible_v<_Tp> && is_nothrow_swappable_v<_Tp> && + is_nothrow_move_constructible_v<_Err> && is_nothrow_swappable_v<_Err>) + requires(is_swappable_v<_Tp> && is_swappable_v<_Err> && is_move_constructible_v<_Tp> && is_move_constructible_v<_Err> && - (is_nothrow_move_constructible_v<_Tp> || - is_nothrow_move_constructible_v<_Err>)) + (is_nothrow_move_constructible_v<_Tp> || is_nothrow_move_constructible_v<_Err>)) { - auto __swap_val_unex_impl = [&](expected& __with_val, expected& __with_err) { + auto __swap_val_unex_impl = [](expected& __with_val, expected& __with_err) { if constexpr (is_nothrow_move_constructible_v<_Err>) { - _Err __tmp(std::move(__with_err.__union_.__unex_)); - std::destroy_at(std::addressof(__with_err.__union_.__unex_)); - auto __trans = std::__make_exception_guard([&] { - std::construct_at(std::addressof(__with_err.__union_.__unex_), std::move(__tmp)); - }); - std::construct_at(std::addressof(__with_err.__union_.__val_), std::move(__with_val.__union_.__val_)); + _Err __tmp(std::move(__with_err.__unex())); + __with_err.__destroy(); + auto __trans = std::__make_exception_guard([&] { __with_err.__construct(unexpect, std::move(__tmp)); }); + __with_err.__construct(in_place, std::move(__with_val.__val())); __trans.__complete(); - std::destroy_at(std::addressof(__with_val.__union_.__val_)); - std::construct_at(std::addressof(__with_val.__union_.__unex_), std::move(__tmp)); + __with_val.__destroy(); + __with_val.__construct(unexpect, std::move(__tmp)); } else { static_assert(is_nothrow_move_constructible_v<_Tp>, "To provide strong exception guarantee, Tp has to satisfy `is_nothrow_move_constructible_v` so " "that it can be reverted to the previous state in case an exception is thrown during swap."); - _Tp __tmp(std::move(__with_val.__union_.__val_)); - std::destroy_at(std::addressof(__with_val.__union_.__val_)); - auto __trans = std::__make_exception_guard([&] { - std::construct_at(std::addressof(__with_val.__union_.__val_), std::move(__tmp)); - }); - std::construct_at(std::addressof(__with_val.__union_.__unex_), std::move(__with_err.__union_.__unex_)); + _Tp __tmp(std::move(__with_val.__val())); + __with_val.__destroy(); + auto __trans = std::__make_exception_guard([&] { __with_val.__construct(in_place, std::move(__tmp)); }); + __with_val.__construct(unexpect, std::move(__with_err.__unex())); __trans.__complete(); - std::destroy_at(std::addressof(__with_err.__union_.__unex_)); - std::construct_at(std::addressof(__with_err.__union_.__val_), std::move(__tmp)); + __with_err.__destroy(); + __with_err.__construct(in_place, std::move(__tmp)); } - __with_val.__has_val_ = false; - __with_err.__has_val_ = true; }; - if (__has_val_) { - if (__rhs.__has_val_) { + if (this->__has_val()) { + if (__rhs.__has_val()) { using std::swap; - swap(__union_.__val_, __rhs.__union_.__val_); + swap(this->__val(), __rhs.__val()); } else { __swap_val_unex_impl(*this, __rhs); } } else { - if (__rhs.__has_val_) { + if (__rhs.__has_val()) { __swap_val_unex_impl(__rhs, *this); } else { using std::swap; - swap(__union_.__unex_, __rhs.__union_.__unex_); + swap(this->__unex(), __rhs.__unex()); } } } - _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(expected& __x, expected& __y) - noexcept(noexcept(__x.swap(__y))) + _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(expected& __x, expected& __y) noexcept(noexcept(__x.swap(__y))) requires requires { __x.swap(__y); } { __x.swap(__y); @@ -522,99 +784,115 @@ public: // [expected.object.obs], observers _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* operator->() const noexcept { - _LIBCPP_ASSERT(__has_val_, "expected::operator-> requires the expected to contain a value"); - return std::addressof(__union_.__val_); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + this->__has_val(), "expected::operator-> requires the expected to contain a value"); + return std::addressof(this->__val()); } _LIBCPP_HIDE_FROM_ABI constexpr _Tp* operator->() noexcept { - _LIBCPP_ASSERT(__has_val_, "expected::operator-> requires the expected to contain a value"); - return std::addressof(__union_.__val_); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + this->__has_val(), "expected::operator-> requires the expected to contain a value"); + return std::addressof(this->__val()); } _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator*() const& noexcept { - _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value"); - return __union_.__val_; + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + this->__has_val(), "expected::operator* requires the expected to contain a value"); + return this->__val(); } _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() & noexcept { - _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value"); - return __union_.__val_; + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + this->__has_val(), "expected::operator* requires the expected to contain a value"); + return this->__val(); } _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& operator*() const&& noexcept { - _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value"); - return std::move(__union_.__val_); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + this->__has_val(), "expected::operator* requires the expected to contain a value"); + return std::move(this->__val()); } _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator*() && noexcept { - _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value"); - return std::move(__union_.__val_); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + this->__has_val(), "expected::operator* requires the expected to contain a value"); + return std::move(this->__val()); } - _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __has_val_; } + _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return this->__has_val(); } - _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __has_val_; } + _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return this->__has_val(); } _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& value() const& { - if (!__has_val_) { - std::__throw_bad_expected_access<_Err>(__union_.__unex_); + static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible"); + if (!this->__has_val()) { + std::__throw_bad_expected_access<_Err>(std::as_const(error())); } - return __union_.__val_; + return this->__val(); } _LIBCPP_HIDE_FROM_ABI constexpr _Tp& value() & { - if (!__has_val_) { - std::__throw_bad_expected_access<_Err>(__union_.__unex_); + static_assert(is_copy_constructible_v<_Err>, "error_type has to be copy constructible"); + if (!this->__has_val()) { + std::__throw_bad_expected_access<_Err>(std::as_const(error())); } - return __union_.__val_; + return this->__val(); } _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& value() const&& { - if (!__has_val_) { - std::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_)); + static_assert(is_copy_constructible_v<_Err> && is_constructible_v<_Err, decltype(std::move(error()))>, + "error_type has to be both copy constructible and constructible from decltype(std::move(error()))"); + if (!this->__has_val()) { + std::__throw_bad_expected_access<_Err>(std::move(error())); } - return std::move(__union_.__val_); + return std::move(this->__val()); } _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& value() && { - if (!__has_val_) { - std::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_)); + static_assert(is_copy_constructible_v<_Err> && is_constructible_v<_Err, decltype(std::move(error()))>, + "error_type has to be both copy constructible and constructible from decltype(std::move(error()))"); + if (!this->__has_val()) { + std::__throw_bad_expected_access<_Err>(std::move(error())); } - return std::move(__union_.__val_); + return std::move(this->__val()); } _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept { - _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); - return __union_.__unex_; + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + !this->__has_val(), "expected::error requires the expected to contain an error"); + return this->__unex(); } _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept { - _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); - return __union_.__unex_; + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + !this->__has_val(), "expected::error requires the expected to contain an error"); + return this->__unex(); } _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept { - _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); - return std::move(__union_.__unex_); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + !this->__has_val(), "expected::error requires the expected to contain an error"); + return std::move(this->__unex()); } _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept { - _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); - return std::move(__union_.__unex_); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + !this->__has_val(), "expected::error requires the expected to contain an error"); + return std::move(this->__unex()); } template _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) const& { static_assert(is_copy_constructible_v<_Tp>, "value_type has to be copy constructible"); static_assert(is_convertible_v<_Up, _Tp>, "argument has to be convertible to value_type"); - return __has_val_ ? __union_.__val_ : static_cast<_Tp>(std::forward<_Up>(__v)); + return this->__has_val() ? this->__val() : static_cast<_Tp>(std::forward<_Up>(__v)); } template _LIBCPP_HIDE_FROM_ABI constexpr _Tp value_or(_Up&& __v) && { static_assert(is_move_constructible_v<_Tp>, "value_type has to be move constructible"); static_assert(is_convertible_v<_Up, _Tp>, "argument has to be convertible to value_type"); - return __has_val_ ? std::move(__union_.__val_) : static_cast<_Tp>(std::forward<_Up>(__v)); + return this->__has_val() ? std::move(this->__val()) : static_cast<_Tp>(std::forward<_Up>(__v)); } template @@ -640,11 +918,11 @@ public: requires is_constructible_v<_Err, _Err&> _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) & { using _Up = remove_cvref_t>; - static_assert(__is_std_expected<_Up>::value, "The result of f(value()) must be a specialization of std::expected"); + static_assert(__is_std_expected<_Up>::value, "The result of f(**this) must be a specialization of std::expected"); static_assert(is_same_v, - "The result of f(value()) must have the same error_type as this expected"); + "The result of f(**this) must have the same error_type as this expected"); if (has_value()) { - return std::invoke(std::forward<_Func>(__f), value()); + return std::invoke(std::forward<_Func>(__f), this->__val()); } return _Up(unexpect, error()); } @@ -653,11 +931,11 @@ public: requires is_constructible_v<_Err, const _Err&> _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const& { using _Up = remove_cvref_t>; - static_assert(__is_std_expected<_Up>::value, "The result of f(value()) must be a specialization of std::expected"); + static_assert(__is_std_expected<_Up>::value, "The result of f(**this) must be a specialization of std::expected"); static_assert(is_same_v, - "The result of f(value()) must have the same error_type as this expected"); + "The result of f(**this) must have the same error_type as this expected"); if (has_value()) { - return std::invoke(std::forward<_Func>(__f), value()); + return std::invoke(std::forward<_Func>(__f), this->__val()); } return _Up(unexpect, error()); } @@ -667,11 +945,11 @@ public: _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) && { using _Up = remove_cvref_t>; static_assert( - __is_std_expected<_Up>::value, "The result of f(std::move(value())) must be a specialization of std::expected"); + __is_std_expected<_Up>::value, "The result of f(std::move(**this)) must be a specialization of std::expected"); static_assert(is_same_v, - "The result of f(std::move(value())) must have the same error_type as this expected"); + "The result of f(std::move(**this)) must have the same error_type as this expected"); if (has_value()) { - return std::invoke(std::forward<_Func>(__f), std::move(value())); + return std::invoke(std::forward<_Func>(__f), std::move(this->__val())); } return _Up(unexpect, std::move(error())); } @@ -681,11 +959,11 @@ public: _LIBCPP_HIDE_FROM_ABI constexpr auto and_then(_Func&& __f) const&& { using _Up = remove_cvref_t>; static_assert( - __is_std_expected<_Up>::value, "The result of f(std::move(value())) must be a specialization of std::expected"); + __is_std_expected<_Up>::value, "The result of f(std::move(**this)) must be a specialization of std::expected"); static_assert(is_same_v, - "The result of f(std::move(value())) must have the same error_type as this expected"); + "The result of f(std::move(**this)) must have the same error_type as this expected"); if (has_value()) { - return std::invoke(std::forward<_Func>(__f), std::move(value())); + return std::invoke(std::forward<_Func>(__f), std::move(this->__val())); } return _Up(unexpect, std::move(error())); } @@ -698,7 +976,7 @@ public: static_assert(is_same_v, "The result of f(error()) must have the same value_type as this expected"); if (has_value()) { - return _Gp(in_place, value()); + return _Gp(in_place, this->__val()); } return std::invoke(std::forward<_Func>(__f), error()); } @@ -711,7 +989,7 @@ public: static_assert(is_same_v, "The result of f(error()) must have the same value_type as this expected"); if (has_value()) { - return _Gp(in_place, value()); + return _Gp(in_place, this->__val()); } return std::invoke(std::forward<_Func>(__f), error()); } @@ -725,7 +1003,7 @@ public: static_assert(is_same_v, "The result of f(std::move(error())) must have the same value_type as this expected"); if (has_value()) { - return _Gp(in_place, std::move(value())); + return _Gp(in_place, std::move(this->__val())); } return std::invoke(std::forward<_Func>(__f), std::move(error())); } @@ -739,7 +1017,7 @@ public: static_assert(is_same_v, "The result of f(std::move(error())) must have the same value_type as this expected"); if (has_value()) { - return _Gp(in_place, std::move(value())); + return _Gp(in_place, std::move(this->__val())); } return std::invoke(std::forward<_Func>(__f), std::move(error())); } @@ -752,9 +1030,10 @@ public: return expected<_Up, _Err>(unexpect, error()); } if constexpr (!is_void_v<_Up>) { - return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), value()); + return expected<_Up, _Err>( + __expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), this->__val()); } else { - std::invoke(std::forward<_Func>(__f), value()); + std::invoke(std::forward<_Func>(__f), this->__val()); return expected<_Up, _Err>(); } } @@ -767,9 +1046,10 @@ public: return expected<_Up, _Err>(unexpect, error()); } if constexpr (!is_void_v<_Up>) { - return expected<_Up, _Err>(__expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), value()); + return expected<_Up, _Err>( + __expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), this->__val()); } else { - std::invoke(std::forward<_Func>(__f), value()); + std::invoke(std::forward<_Func>(__f), this->__val()); return expected<_Up, _Err>(); } } @@ -783,9 +1063,9 @@ public: } if constexpr (!is_void_v<_Up>) { return expected<_Up, _Err>( - __expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), std::move(value())); + __expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), std::move(this->__val())); } else { - std::invoke(std::forward<_Func>(__f), std::move(value())); + std::invoke(std::forward<_Func>(__f), std::move(this->__val())); return expected<_Up, _Err>(); } } @@ -799,9 +1079,9 @@ public: } if constexpr (!is_void_v<_Up>) { return expected<_Up, _Err>( - __expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), std::move(value())); + __expected_construct_in_place_from_invoke_tag{}, std::forward<_Func>(__f), std::move(this->__val())); } else { - std::invoke(std::forward<_Func>(__f), std::move(value())); + std::invoke(std::forward<_Func>(__f), std::move(this->__val())); return expected<_Up, _Err>(); } } @@ -813,7 +1093,7 @@ public: static_assert(__valid_std_unexpected<_Gp>::value, "The result of f(error()) must be a valid template argument for unexpected"); if (has_value()) { - return expected<_Tp, _Gp>(in_place, value()); + return expected<_Tp, _Gp>(in_place, this->__val()); } return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error()); } @@ -825,7 +1105,7 @@ public: static_assert(__valid_std_unexpected<_Gp>::value, "The result of f(error()) must be a valid template argument for unexpected"); if (has_value()) { - return expected<_Tp, _Gp>(in_place, value()); + return expected<_Tp, _Gp>(in_place, this->__val()); } return expected<_Tp, _Gp>(__expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), error()); } @@ -837,7 +1117,7 @@ public: static_assert(__valid_std_unexpected<_Gp>::value, "The result of f(std::move(error())) must be a valid template argument for unexpected"); if (has_value()) { - return expected<_Tp, _Gp>(in_place, std::move(value())); + return expected<_Tp, _Gp>(in_place, std::move(this->__val())); } return expected<_Tp, _Gp>( __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error())); @@ -850,7 +1130,7 @@ public: static_assert(__valid_std_unexpected<_Gp>::value, "The result of f(std::move(error())) must be a valid template argument for unexpected"); if (has_value()) { - return expected<_Tp, _Gp>(in_place, std::move(value())); + return expected<_Tp, _Gp>(in_place, std::move(this->__val())); } return expected<_Tp, _Gp>( __expected_construct_unexpected_from_invoke_tag{}, std::forward<_Func>(__f), std::move(error())); @@ -860,95 +1140,220 @@ public: template requires(!is_void_v<_T2>) _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const expected<_T2, _E2>& __y) { - if (__x.__has_val_ != __y.__has_val_) { + if (__x.__has_val() != __y.__has_val()) { return false; } else { - if (__x.__has_val_) { - return __x.__union_.__val_ == __y.__union_.__val_; + if (__x.__has_val()) { + return __x.__val() == __y.__val(); } else { - return __x.__union_.__unex_ == __y.__union_.__unex_; + return __x.__unex() == __y.__unex(); } } } template _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const _T2& __v) { - return __x.__has_val_ && static_cast(__x.__union_.__val_ == __v); + return __x.__has_val() && static_cast(__x.__val() == __v); } template _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const unexpected<_E2>& __e) { - return !__x.__has_val_ && static_cast(__x.__union_.__unex_ == __e.error()); + return !__x.__has_val() && static_cast(__x.__unex() == __e.error()); } +}; -private: +template +class __expected_void_base { struct __empty_t {}; - - template - union __union_t { - _LIBCPP_HIDE_FROM_ABI constexpr __union_t() {} - - template - _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t( - std::__expected_construct_in_place_from_invoke_tag, _Func&& __f, _Args&&... __args) - : __val_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {} - - template - _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t( - std::__expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args) - : __unex_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {} - - _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() - requires(is_trivially_destructible_v<_ValueType> && is_trivially_destructible_v<_ErrorType>) - = default; - - // the expected's destructor handles this - _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() {} - - _ValueType __val_; - _ErrorType __unex_; - }; - // use named union because [[no_unique_address]] cannot be applied to an unnamed union, // also guaranteed elision into a potentially-overlapping subobject is unsettled (and // it's not clear that it's implementable, given that the function is allowed to clobber // the tail padding) - see https://github.com/itanium-cxx-abi/cxx-abi/issues/107. - template - requires(is_trivially_move_constructible_v<_ValueType> && is_trivially_move_constructible_v<_ErrorType>) - union __union_t<_ValueType, _ErrorType> { - _LIBCPP_HIDE_FROM_ABI constexpr __union_t() : __empty_() {} + union __union_t { + _LIBCPP_HIDE_FROM_ABI constexpr __union_t(const __union_t&) = delete; + _LIBCPP_HIDE_FROM_ABI constexpr __union_t(const __union_t&) + requires(is_copy_constructible_v<_Err> && is_trivially_copy_constructible_v<_Err>) + = default; + _LIBCPP_HIDE_FROM_ABI constexpr __union_t(__union_t&&) = delete; + _LIBCPP_HIDE_FROM_ABI constexpr __union_t(__union_t&&) + requires(is_move_constructible_v<_Err> && is_trivially_move_constructible_v<_Err>) + = default; + _LIBCPP_HIDE_FROM_ABI constexpr __union_t& operator=(const __union_t&) = delete; + _LIBCPP_HIDE_FROM_ABI constexpr __union_t& operator=(__union_t&&) = delete; + + _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(in_place_t) : __empty_() {} + + template + _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t(unexpect_t, _Args&&... __args) + : __unex_(std::forward<_Args>(__args)...) {} template _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t( - std::__expected_construct_in_place_from_invoke_tag, _Func&& __f, _Args&&... __args) - : __val_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {} - - template - _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t( - std::__expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args) + __expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args) : __unex_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {} _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() - requires(is_trivially_destructible_v<_ValueType> && is_trivially_destructible_v<_ErrorType>) + requires(is_trivially_destructible_v<_Err>) = default; - // the expected's destructor handles this + // __repr's destructor handles this _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() - requires(!is_trivially_destructible_v<_ValueType> || !is_trivially_destructible_v<_ErrorType>) + requires(!is_trivially_destructible_v<_Err>) {} _LIBCPP_NO_UNIQUE_ADDRESS __empty_t __empty_; - _LIBCPP_NO_UNIQUE_ADDRESS _ValueType __val_; - _LIBCPP_NO_UNIQUE_ADDRESS _ErrorType __unex_; + _LIBCPP_NO_UNIQUE_ADDRESS _Err __unex_; }; - _LIBCPP_NO_UNIQUE_ADDRESS __union_t<_Tp, _Err> __union_; - bool __has_val_; + static constexpr bool __put_flag_in_tail = __fits_in_tail_padding<__union_t, bool>; + static constexpr bool __allow_reusing_expected_tail_padding = !__put_flag_in_tail; + + struct __repr { + _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr() = delete; + + template + _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(in_place_t __tag) : __union_(in_place, __tag), __has_val_(true) {} + + template + _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(unexpect_t __tag, _Args&&... __args) + : __union_(in_place, __tag, std::forward<_Args>(__args)...), __has_val_(false) {} + + template + _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(std::__expected_construct_unexpected_from_invoke_tag __tag, + _Args&&... __args) + : __union_(in_place, __tag, std::forward<_Args>(__args)...), __has_val_(false) {} + + template + _LIBCPP_HIDE_FROM_ABI constexpr explicit __repr(bool __has_val, _OtherUnion&& __other) + requires(__allow_reusing_expected_tail_padding) + : __union_(__conditional_no_unique_address_invoke_tag{}, + [&] { return __make_union(__has_val, std::forward<_OtherUnion>(__other)); }), + __has_val_(__has_val) {} + + _LIBCPP_HIDE_FROM_ABI constexpr __repr(const __repr&) = delete; + _LIBCPP_HIDE_FROM_ABI constexpr __repr(const __repr&) + requires(is_copy_constructible_v<_Err> && is_trivially_copy_constructible_v<_Err>) + = default; + _LIBCPP_HIDE_FROM_ABI constexpr __repr(__repr&&) = delete; + _LIBCPP_HIDE_FROM_ABI constexpr __repr(__repr&&) + requires(is_move_constructible_v<_Err> && is_trivially_move_constructible_v<_Err>) + = default; + + _LIBCPP_HIDE_FROM_ABI constexpr __repr& operator=(const __repr&) = delete; + _LIBCPP_HIDE_FROM_ABI constexpr __repr& operator=(__repr&&) = delete; + + _LIBCPP_HIDE_FROM_ABI constexpr ~__repr() + requires(is_trivially_destructible_v<_Err>) + = default; + + _LIBCPP_HIDE_FROM_ABI constexpr ~__repr() + requires(!is_trivially_destructible_v<_Err>) + { + __destroy_union_member(); + } + + _LIBCPP_HIDE_FROM_ABI constexpr void __destroy_union() + requires(__allow_reusing_expected_tail_padding && is_trivially_destructible_v<_Err>) + { + std::destroy_at(&__union_.__v); + } + + _LIBCPP_HIDE_FROM_ABI constexpr void __destroy_union() + requires(__allow_reusing_expected_tail_padding && !is_trivially_destructible_v<_Err>) + { + __destroy_union_member(); + std::destroy_at(&__union_.__v); + } + + _LIBCPP_HIDE_FROM_ABI constexpr void __construct_union(in_place_t) + requires(__allow_reusing_expected_tail_padding) + { + std::construct_at(&__union_.__v, in_place); + __has_val_ = true; + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr void __construct_union(unexpect_t, _Args&&... __args) + requires(__allow_reusing_expected_tail_padding) + { + std::construct_at(&__union_.__v, unexpect, std::forward<_Args>(__args)...); + __has_val_ = false; + } + + private: + template + friend class __expected_void_base; + + _LIBCPP_HIDE_FROM_ABI constexpr void __destroy_union_member() + requires(!is_trivially_destructible_v<_Err>) + { + if (!__has_val_) + std::destroy_at(std::addressof(__union_.__v.__unex_)); + } + + template + _LIBCPP_HIDE_FROM_ABI static constexpr __union_t __make_union(bool __has_val, _OtherUnion&& __other) + requires(__allow_reusing_expected_tail_padding) + { + if (__has_val) + return __union_t(in_place); + else + return __union_t(unexpect, std::forward<_OtherUnion>(__other).__unex_); + } + + _LIBCPP_NO_UNIQUE_ADDRESS __conditional_no_unique_address<__put_flag_in_tail, __union_t> __union_; + _LIBCPP_NO_UNIQUE_ADDRESS bool __has_val_; + }; + + template + _LIBCPP_HIDE_FROM_ABI static constexpr __repr __make_repr(bool __has_val, _OtherUnion&& __other) + requires(__put_flag_in_tail) + { + if (__has_val) + return __repr(in_place); + else + return __repr(unexpect, std::forward<_OtherUnion>(__other).__unex_); + } + +protected: + template + _LIBCPP_HIDE_FROM_ABI constexpr explicit __expected_void_base(_Args&&... __args) + : __repr_(in_place, std::forward<_Args>(__args)...) {} + + template + _LIBCPP_HIDE_FROM_ABI constexpr explicit __expected_void_base(bool __has_val, _OtherUnion&& __other) + requires(__put_flag_in_tail) + : __repr_(__conditional_no_unique_address_invoke_tag{}, + [&] { return __make_repr(__has_val, std::forward<_OtherUnion>(__other)); }) {} + + _LIBCPP_HIDE_FROM_ABI constexpr void __destroy() { + if constexpr (__put_flag_in_tail) + std::destroy_at(&__repr_.__v); + else + __repr_.__v.__destroy_union(); + } + + template + _LIBCPP_HIDE_FROM_ABI constexpr void __construct(_Tag __tag, _Args&&... __args) { + if constexpr (__put_flag_in_tail) + std::construct_at(&__repr_.__v, __tag, std::forward<_Args>(__args)...); + else + __repr_.__v.__construct_union(__tag, std::forward<_Args>(__args)...); + } + + _LIBCPP_HIDE_FROM_ABI constexpr bool __has_val() const { return __repr_.__v.__has_val_; } + _LIBCPP_HIDE_FROM_ABI constexpr __union_t& __union() { return __repr_.__v.__union_.__v; } + _LIBCPP_HIDE_FROM_ABI constexpr const __union_t& __union() const { return __repr_.__v.__union_.__v; } + _LIBCPP_HIDE_FROM_ABI constexpr _Err& __unex() { return __repr_.__v.__union_.__v.__unex_; } + _LIBCPP_HIDE_FROM_ABI constexpr const _Err& __unex() const { return __repr_.__v.__union_.__v.__unex_; } + +private: + _LIBCPP_NO_UNIQUE_ADDRESS __conditional_no_unique_address<__allow_reusing_expected_tail_padding, __repr> __repr_; }; template requires is_void_v<_Tp> -class expected<_Tp, _Err> { +class expected<_Tp, _Err> : private __expected_void_base<_Err> { static_assert(__valid_std_unexpected<_Err>::value, "[expected.void.general] A program that instantiates expected with a E that is not a " "valid argument for unexpected is ill-formed"); @@ -965,6 +1370,8 @@ class expected<_Tp, _Err> { _Not, const expected<_Up, _OtherErr>&>>, _Not, const expected<_Up, _OtherErr>>>>; + using __base = __expected_void_base<_Err>; + public: using value_type = _Tp; using error_type = _Err; @@ -974,7 +1381,7 @@ public: using rebind = expected<_Up, error_type>; // [expected.void.ctor], constructors - _LIBCPP_HIDE_FROM_ABI constexpr expected() noexcept : __has_val_(true) {} + _LIBCPP_HIDE_FROM_ABI constexpr expected() noexcept : __base(in_place) {} _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected&) = delete; @@ -982,132 +1389,104 @@ public: requires(is_copy_constructible_v<_Err> && is_trivially_copy_constructible_v<_Err>) = default; - _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected& __rhs) - noexcept(is_nothrow_copy_constructible_v<_Err>) // strengthened + _LIBCPP_HIDE_FROM_ABI constexpr expected(const expected& __rhs) noexcept( + is_nothrow_copy_constructible_v<_Err>) // strengthened requires(is_copy_constructible_v<_Err> && !is_trivially_copy_constructible_v<_Err>) - : __has_val_(__rhs.__has_val_) { - if (!__rhs.__has_val_) { - std::construct_at(std::addressof(__union_.__unex_), __rhs.__union_.__unex_); - } - } + : __base(__rhs.__has_val(), __rhs.__union()) {} _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&&) requires(is_move_constructible_v<_Err> && is_trivially_move_constructible_v<_Err>) = default; - _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&& __rhs) - noexcept(is_nothrow_move_constructible_v<_Err>) + _LIBCPP_HIDE_FROM_ABI constexpr expected(expected&& __rhs) noexcept(is_nothrow_move_constructible_v<_Err>) requires(is_move_constructible_v<_Err> && !is_trivially_move_constructible_v<_Err>) - : __has_val_(__rhs.__has_val_) { - if (!__rhs.__has_val_) { - std::construct_at(std::addressof(__union_.__unex_), std::move(__rhs.__union_.__unex_)); - } - } + : __base(__rhs.__has_val(), std::move(__rhs.__union())) {} template requires __can_convert<_Up, _OtherErr, const _OtherErr&>::value _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v) - expected(const expected<_Up, _OtherErr>& __rhs) - noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened - : __has_val_(__rhs.__has_val_) { - if (!__rhs.__has_val_) { - std::construct_at(std::addressof(__union_.__unex_), __rhs.__union_.__unex_); - } - } + expected(const expected<_Up, _OtherErr>& __rhs) noexcept( + is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened + : __base(__rhs.__has_val(), __rhs.__union()) {} template requires __can_convert<_Up, _OtherErr, _OtherErr>::value _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>) - expected(expected<_Up, _OtherErr>&& __rhs) - noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened - : __has_val_(__rhs.__has_val_) { - if (!__rhs.__has_val_) { - std::construct_at(std::addressof(__union_.__unex_), std::move(__rhs.__union_.__unex_)); - } - } + expected(expected<_Up, _OtherErr>&& __rhs) noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened + : __base(__rhs.__has_val(), std::move(__rhs.__union())) {} template requires is_constructible_v<_Err, const _OtherErr&> - _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v) - expected(const unexpected<_OtherErr>& __unex) - noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened - : __has_val_(false) { - std::construct_at(std::addressof(__union_.__unex_), __unex.error()); - } + _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v) expected( + const unexpected<_OtherErr>& __unex) noexcept(is_nothrow_constructible_v<_Err, const _OtherErr&>) // strengthened + : __base(unexpect, __unex.error()) {} template requires is_constructible_v<_Err, _OtherErr> _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherErr, _Err>) - expected(unexpected<_OtherErr>&& __unex) - noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened - : __has_val_(false) { - std::construct_at(std::addressof(__union_.__unex_), std::move(__unex.error())); - } + expected(unexpected<_OtherErr>&& __unex) noexcept(is_nothrow_constructible_v<_Err, _OtherErr>) // strengthened + : __base(unexpect, std::move(__unex.error())) {} - _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t) noexcept : __has_val_(true) {} + _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(in_place_t) noexcept : __base(in_place) {} template requires is_constructible_v<_Err, _Args...> - _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, _Args&&... __args) - noexcept(is_nothrow_constructible_v<_Err, _Args...>) // strengthened - : __has_val_(false) { - std::construct_at(std::addressof(__union_.__unex_), std::forward<_Args>(__args)...); - } + _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, _Args&&... __args) noexcept( + is_nothrow_constructible_v<_Err, _Args...>) // strengthened + : __base(unexpect, std::forward<_Args>(__args)...) {} template requires is_constructible_v< _Err, initializer_list<_Up>&, _Args... > - _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args) - noexcept(is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened - : __has_val_(false) { - std::construct_at(std::addressof(__union_.__unex_), __il, std::forward<_Args>(__args)...); - } + _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(unexpect_t, initializer_list<_Up> __il, _Args&&... __args) noexcept( + is_nothrow_constructible_v<_Err, initializer_list<_Up>&, _Args...>) // strengthened + : __base(unexpect, __il, std::forward<_Args>(__args)...) {} private: - template - _LIBCPP_HIDE_FROM_ABI constexpr explicit expected(__expected_construct_in_place_from_invoke_tag, _Func&& __f) - : __has_val_(true) { - std::invoke(std::forward<_Func>(__f)); - } - template _LIBCPP_HIDE_FROM_ABI constexpr explicit expected( __expected_construct_unexpected_from_invoke_tag __tag, _Func&& __f, _Args&&... __args) - : __union_(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...), __has_val_(false) {} + : __base(__tag, std::forward<_Func>(__f), std::forward<_Args>(__args)...) {} public: // [expected.void.dtor], destructor - _LIBCPP_HIDE_FROM_ABI constexpr ~expected() - requires is_trivially_destructible_v<_Err> - = default; + _LIBCPP_HIDE_FROM_ABI constexpr ~expected() = default; - _LIBCPP_HIDE_FROM_ABI constexpr ~expected() - requires(!is_trivially_destructible_v<_Err>) - { - if (!__has_val_) { - std::destroy_at(std::addressof(__union_.__unex_)); - } +private: + template + _LIBCPP_HIDE_FROM_ABI constexpr void __reinit_expected(unexpect_t, _Args&&... __args) { + _LIBCPP_ASSERT_INTERNAL(this->__has_val(), "__reinit_expected(unexpect_t, ...) needs value to be set"); + + this->__destroy(); + auto __trans = std::__make_exception_guard([&] { this->__construct(in_place); }); + this->__construct(unexpect, std::forward<_Args>(__args)...); + __trans.__complete(); } - // [expected.void.assign], assignment + _LIBCPP_HIDE_FROM_ABI constexpr void __reinit_expected(in_place_t) { + _LIBCPP_ASSERT_INTERNAL(!this->__has_val(), "__reinit_expected(in_place_t, ...) needs value to be unset"); + this->__destroy(); + this->__construct(in_place); + } + +public: + // [expected.void.assign], assignment _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected&) = delete; - _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected& __rhs) - noexcept(is_nothrow_copy_assignable_v<_Err> && is_nothrow_copy_constructible_v<_Err>) // strengthened + _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const expected& __rhs) noexcept( + is_nothrow_copy_assignable_v<_Err> && is_nothrow_copy_constructible_v<_Err>) // strengthened requires(is_copy_assignable_v<_Err> && is_copy_constructible_v<_Err>) { - if (__has_val_) { - if (!__rhs.__has_val_) { - std::construct_at(std::addressof(__union_.__unex_), __rhs.__union_.__unex_); - __has_val_ = false; + if (this->__has_val()) { + if (!__rhs.__has_val()) { + __reinit_expected(unexpect, __rhs.__unex()); } } else { - if (__rhs.__has_val_) { - std::destroy_at(std::addressof(__union_.__unex_)); - __has_val_ = true; + if (__rhs.__has_val()) { + __reinit_expected(in_place); } else { - __union_.__unex_ = __rhs.__union_.__unex_; + this->__unex() = __rhs.__unex(); } } return *this; @@ -1115,23 +1494,19 @@ public: _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(expected&&) = delete; - _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(expected&& __rhs) - noexcept(is_nothrow_move_assignable_v<_Err> && - is_nothrow_move_constructible_v<_Err>) - requires(is_move_assignable_v<_Err> && - is_move_constructible_v<_Err>) + _LIBCPP_HIDE_FROM_ABI constexpr expected& + operator=(expected&& __rhs) noexcept(is_nothrow_move_assignable_v<_Err> && is_nothrow_move_constructible_v<_Err>) + requires(is_move_assignable_v<_Err> && is_move_constructible_v<_Err>) { - if (__has_val_) { - if (!__rhs.__has_val_) { - std::construct_at(std::addressof(__union_.__unex_), std::move(__rhs.__union_.__unex_)); - __has_val_ = false; + if (this->__has_val()) { + if (!__rhs.__has_val()) { + __reinit_expected(unexpect, std::move(__rhs.__unex())); } } else { - if (__rhs.__has_val_) { - std::destroy_at(std::addressof(__union_.__unex_)); - __has_val_ = true; + if (__rhs.__has_val()) { + __reinit_expected(in_place); } else { - __union_.__unex_ = std::move(__rhs.__union_.__unex_); + this->__unex() = std::move(__rhs.__unex()); } } return *this; @@ -1140,11 +1515,10 @@ public: template requires(is_constructible_v<_Err, const _OtherErr&> && is_assignable_v<_Err&, const _OtherErr&>) _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(const unexpected<_OtherErr>& __un) { - if (__has_val_) { - std::construct_at(std::addressof(__union_.__unex_), __un.error()); - __has_val_ = false; + if (this->__has_val()) { + __reinit_expected(unexpect, __un.error()); } else { - __union_.__unex_ = __un.error(); + this->__unex() = __un.error(); } return *this; } @@ -1152,94 +1526,98 @@ public: template requires(is_constructible_v<_Err, _OtherErr> && is_assignable_v<_Err&, _OtherErr>) _LIBCPP_HIDE_FROM_ABI constexpr expected& operator=(unexpected<_OtherErr>&& __un) { - if (__has_val_) { - std::construct_at(std::addressof(__union_.__unex_), std::move(__un.error())); - __has_val_ = false; + if (this->__has_val()) { + __reinit_expected(unexpect, std::move(__un.error())); } else { - __union_.__unex_ = std::move(__un.error()); + this->__unex() = std::move(__un.error()); } return *this; } _LIBCPP_HIDE_FROM_ABI constexpr void emplace() noexcept { - if (!__has_val_) { - std::destroy_at(std::addressof(__union_.__unex_)); - __has_val_ = true; + if (!this->__has_val()) { + __reinit_expected(in_place); } } // [expected.void.swap], swap - _LIBCPP_HIDE_FROM_ABI constexpr void swap(expected& __rhs) - noexcept(is_nothrow_move_constructible_v<_Err> && is_nothrow_swappable_v<_Err>) + _LIBCPP_HIDE_FROM_ABI constexpr void + swap(expected& __rhs) noexcept(is_nothrow_move_constructible_v<_Err> && is_nothrow_swappable_v<_Err>) requires(is_swappable_v<_Err> && is_move_constructible_v<_Err>) { - auto __swap_val_unex_impl = [&](expected& __with_val, expected& __with_err) { - std::construct_at(std::addressof(__with_val.__union_.__unex_), std::move(__with_err.__union_.__unex_)); - std::destroy_at(std::addressof(__with_err.__union_.__unex_)); - __with_val.__has_val_ = false; - __with_err.__has_val_ = true; + auto __swap_val_unex_impl = [](expected& __with_val, expected& __with_err) { + // May throw, but will re-engage `__with_val` in that case. + __with_val.__reinit_expected(unexpect, std::move(__with_err.__unex())); + // Will not throw. + __with_err.__reinit_expected(in_place); }; - if (__has_val_) { - if (!__rhs.__has_val_) { + if (this->__has_val()) { + if (!__rhs.__has_val()) { __swap_val_unex_impl(*this, __rhs); } } else { - if (__rhs.__has_val_) { + if (__rhs.__has_val()) { __swap_val_unex_impl(__rhs, *this); } else { using std::swap; - swap(__union_.__unex_, __rhs.__union_.__unex_); + swap(this->__unex(), __rhs.__unex()); } } } - _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(expected& __x, expected& __y) - noexcept(noexcept(__x.swap(__y))) + _LIBCPP_HIDE_FROM_ABI friend constexpr void swap(expected& __x, expected& __y) noexcept(noexcept(__x.swap(__y))) requires requires { __x.swap(__y); } { __x.swap(__y); } // [expected.void.obs], observers - _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __has_val_; } + _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return this->__has_val(); } - _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return __has_val_; } + _LIBCPP_HIDE_FROM_ABI constexpr bool has_value() const noexcept { return this->__has_val(); } _LIBCPP_HIDE_FROM_ABI constexpr void operator*() const noexcept { - _LIBCPP_ASSERT(__has_val_, "expected::operator* requires the expected to contain a value"); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + this->__has_val(), "expected::operator* requires the expected to contain a value"); } _LIBCPP_HIDE_FROM_ABI constexpr void value() const& { - if (!__has_val_) { - std::__throw_bad_expected_access<_Err>(__union_.__unex_); + static_assert(is_copy_constructible_v<_Err>); + if (!this->__has_val()) { + std::__throw_bad_expected_access<_Err>(this->__unex()); } } _LIBCPP_HIDE_FROM_ABI constexpr void value() && { - if (!__has_val_) { - std::__throw_bad_expected_access<_Err>(std::move(__union_.__unex_)); + static_assert(is_copy_constructible_v<_Err> && is_move_constructible_v<_Err>); + if (!this->__has_val()) { + std::__throw_bad_expected_access<_Err>(std::move(this->__unex())); } } _LIBCPP_HIDE_FROM_ABI constexpr const _Err& error() const& noexcept { - _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); - return __union_.__unex_; + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + !this->__has_val(), "expected::error requires the expected to contain an error"); + return this->__unex(); } _LIBCPP_HIDE_FROM_ABI constexpr _Err& error() & noexcept { - _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); - return __union_.__unex_; + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + !this->__has_val(), "expected::error requires the expected to contain an error"); + return this->__unex(); } _LIBCPP_HIDE_FROM_ABI constexpr const _Err&& error() const&& noexcept { - _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); - return std::move(__union_.__unex_); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + !this->__has_val(), "expected::error requires the expected to contain an error"); + return std::move(this->__unex()); } _LIBCPP_HIDE_FROM_ABI constexpr _Err&& error() && noexcept { - _LIBCPP_ASSERT(!__has_val_, "expected::error requires the expected to contain an error"); - return std::move(__union_.__unex_); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + !this->__has_val(), "expected::error requires the expected to contain an error"); + return std::move(this->__unex()); } template @@ -1342,8 +1720,8 @@ public: template _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) && { using _Gp = remove_cvref_t>; - static_assert(__is_std_expected<_Gp>::value, - "The result of f(std::move(error())) must be a specialization of std::expected"); + static_assert( + __is_std_expected<_Gp>::value, "The result of f(std::move(error())) must be a specialization of std::expected"); static_assert(is_same_v, "The result of f(std::move(error())) must have the same value_type as this expected"); if (has_value()) { @@ -1355,8 +1733,8 @@ public: template _LIBCPP_HIDE_FROM_ABI constexpr auto or_else(_Func&& __f) const&& { using _Gp = remove_cvref_t>; - static_assert(__is_std_expected<_Gp>::value, - "The result of f(std::move(error())) must be a specialization of std::expected"); + static_assert( + __is_std_expected<_Gp>::value, "The result of f(std::move(error())) must be a specialization of std::expected"); static_assert(is_same_v, "The result of f(std::move(error())) must have the same value_type as this expected"); if (has_value()) { @@ -1475,74 +1853,23 @@ public: template requires is_void_v<_T2> _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const expected<_T2, _E2>& __y) { - if (__x.__has_val_ != __y.__has_val_) { + if (__x.__has_val() != __y.__has_val()) { return false; } else { - return __x.__has_val_ || static_cast(__x.__union_.__unex_ == __y.__union_.__unex_); + return __x.__has_val() || static_cast(__x.__unex() == __y.__unex()); } } template _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const expected& __x, const unexpected<_E2>& __y) { - return !__x.__has_val_ && static_cast(__x.__union_.__unex_ == __y.error()); + return !__x.__has_val() && static_cast(__x.__unex() == __y.error()); } - -private: - struct __empty_t {}; - - template - union __union_t { - _LIBCPP_HIDE_FROM_ABI constexpr __union_t() : __empty_() {} - - template - _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t( - __expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args) - : __unex_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {} - - _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() - requires(is_trivially_destructible_v<_ErrorType>) - = default; - - // the expected's destructor handles this - _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() {} - - __empty_t __empty_; - _ErrorType __unex_; - }; - - // use named union because [[no_unique_address]] cannot be applied to an unnamed union, - // also guaranteed elision into a potentially-overlapping subobject is unsettled (and - // it's not clear that it's implementable, given that the function is allowed to clobber - // the tail padding) - see https://github.com/itanium-cxx-abi/cxx-abi/issues/107. - template - requires is_trivially_move_constructible_v<_ErrorType> - union __union_t<_ErrorType> { - _LIBCPP_HIDE_FROM_ABI constexpr __union_t() : __empty_() {} - - template - _LIBCPP_HIDE_FROM_ABI constexpr explicit __union_t( - __expected_construct_unexpected_from_invoke_tag, _Func&& __f, _Args&&... __args) - : __unex_(std::invoke(std::forward<_Func>(__f), std::forward<_Args>(__args)...)) {} - - _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() - requires(is_trivially_destructible_v<_ErrorType>) - = default; - - // the expected's destructor handles this - _LIBCPP_HIDE_FROM_ABI constexpr ~__union_t() - requires(!is_trivially_destructible_v<_ErrorType>) - {} - - _LIBCPP_NO_UNIQUE_ADDRESS __empty_t __empty_; - _LIBCPP_NO_UNIQUE_ADDRESS _ErrorType __unex_; - }; - - _LIBCPP_NO_UNIQUE_ADDRESS __union_t<_Err> __union_; - bool __has_val_; }; _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 23 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___EXPECTED_EXPECTED_H diff --git a/third_party/libcxx/__expected/unexpected.h b/third_party/libcxx/__expected/unexpected.h index 075963a84..c7fe3c52e 100644 --- a/third_party/libcxx/__expected/unexpected.h +++ b/third_party/libcxx/__expected/unexpected.h @@ -31,6 +31,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 23 _LIBCPP_BEGIN_NAMESPACE_STD @@ -119,4 +122,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 23 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___EXPECTED_UNEXPECTED_H diff --git a/third_party/libcxx/__filesystem/copy_options.h b/third_party/libcxx/__filesystem/copy_options.h index 96c753581..097eebe61 100644 --- a/third_party/libcxx/__filesystem/copy_options.h +++ b/third_party/libcxx/__filesystem/copy_options.h @@ -10,75 +10,60 @@ #ifndef _LIBCPP___FILESYSTEM_COPY_OPTIONS_H #define _LIBCPP___FILESYSTEM_COPY_OPTIONS_H -#include <__availability> #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif -#ifndef _LIBCPP_CXX03_LANG +#if _LIBCPP_STD_VER >= 17 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM -_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH - -enum class _LIBCPP_ENUM_VIS copy_options : unsigned short { - none = 0, - skip_existing = 1, - overwrite_existing = 2, - update_existing = 4, - recursive = 8, - copy_symlinks = 16, - skip_symlinks = 32, - directories_only = 64, - create_symlinks = 128, - create_hard_links = 256, +enum class copy_options : unsigned short { + none = 0, + skip_existing = 1, + overwrite_existing = 2, + update_existing = 4, + recursive = 8, + copy_symlinks = 16, + skip_symlinks = 32, + directories_only = 64, + create_symlinks = 128, + create_hard_links = 256, __in_recursive_copy = 512, }; -_LIBCPP_INLINE_VISIBILITY -inline constexpr copy_options operator&(copy_options __lhs, copy_options __rhs) { - return static_cast(static_cast(__lhs) & - static_cast(__rhs)); +_LIBCPP_HIDE_FROM_ABI inline constexpr copy_options operator&(copy_options __lhs, copy_options __rhs) { + return static_cast(static_cast(__lhs) & static_cast(__rhs)); } -_LIBCPP_INLINE_VISIBILITY -inline constexpr copy_options operator|(copy_options __lhs, copy_options __rhs) { - return static_cast(static_cast(__lhs) | - static_cast(__rhs)); +_LIBCPP_HIDE_FROM_ABI inline constexpr copy_options operator|(copy_options __lhs, copy_options __rhs) { + return static_cast(static_cast(__lhs) | static_cast(__rhs)); } -_LIBCPP_INLINE_VISIBILITY -inline constexpr copy_options operator^(copy_options __lhs, copy_options __rhs) { - return static_cast(static_cast(__lhs) ^ - static_cast(__rhs)); +_LIBCPP_HIDE_FROM_ABI inline constexpr copy_options operator^(copy_options __lhs, copy_options __rhs) { + return static_cast(static_cast(__lhs) ^ static_cast(__rhs)); } -_LIBCPP_INLINE_VISIBILITY -inline constexpr copy_options operator~(copy_options __lhs) { +_LIBCPP_HIDE_FROM_ABI inline constexpr copy_options operator~(copy_options __lhs) { return static_cast(~static_cast(__lhs)); } -_LIBCPP_INLINE_VISIBILITY -inline copy_options& operator&=(copy_options& __lhs, copy_options __rhs) { +_LIBCPP_HIDE_FROM_ABI inline copy_options& operator&=(copy_options& __lhs, copy_options __rhs) { return __lhs = __lhs & __rhs; } -_LIBCPP_INLINE_VISIBILITY -inline copy_options& operator|=(copy_options& __lhs, copy_options __rhs) { +_LIBCPP_HIDE_FROM_ABI inline copy_options& operator|=(copy_options& __lhs, copy_options __rhs) { return __lhs = __lhs | __rhs; } -_LIBCPP_INLINE_VISIBILITY -inline copy_options& operator^=(copy_options& __lhs, copy_options __rhs) { +_LIBCPP_HIDE_FROM_ABI inline copy_options& operator^=(copy_options& __lhs, copy_options __rhs) { return __lhs = __lhs ^ __rhs; } -_LIBCPP_AVAILABILITY_FILESYSTEM_POP - _LIBCPP_END_NAMESPACE_FILESYSTEM -#endif // _LIBCPP_CXX03_LANG +#endif // _LIBCPP_STD_VER >= 17 #endif // _LIBCPP___FILESYSTEM_COPY_OPTIONS_H diff --git a/third_party/libcxx/__filesystem/directory_entry.h b/third_party/libcxx/__filesystem/directory_entry.h index bd9dbdc76..96d88dcd9 100644 --- a/third_party/libcxx/__filesystem/directory_entry.h +++ b/third_party/libcxx/__filesystem/directory_entry.h @@ -10,7 +10,6 @@ #ifndef _LIBCPP___FILESYSTEM_DIRECTORY_ENTRY_H #define _LIBCPP___FILESYSTEM_DIRECTORY_ENTRY_H -#include <__availability> #include <__chrono/time_point.h> #include <__compare/ordering.h> #include <__config> @@ -26,7 +25,6 @@ #include <__utility/move.h> #include <__utility/unreachable.h> #include -#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -35,231 +33,160 @@ _LIBCPP_PUSH_MACROS #include <__undef_macros> -#ifndef _LIBCPP_CXX03_LANG +#if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM) _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM -_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH - +_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH class directory_entry { - typedef _VSTD_FS::path _Path; + typedef filesystem::path _Path; public: // constructors and destructors - _LIBCPP_HIDE_FROM_ABI directory_entry() noexcept = default; - _LIBCPP_HIDE_FROM_ABI directory_entry(directory_entry const&) = default; + _LIBCPP_HIDE_FROM_ABI directory_entry() noexcept = default; + _LIBCPP_HIDE_FROM_ABI directory_entry(directory_entry const&) = default; _LIBCPP_HIDE_FROM_ABI directory_entry(directory_entry&&) noexcept = default; - _LIBCPP_INLINE_VISIBILITY - explicit directory_entry(_Path const& __p) : __p_(__p) { + _LIBCPP_HIDE_FROM_ABI explicit directory_entry(_Path const& __p) : __p_(__p) { error_code __ec; __refresh(&__ec); } - _LIBCPP_INLINE_VISIBILITY - directory_entry(_Path const& __p, error_code& __ec) : __p_(__p) { - __refresh(&__ec); - } + _LIBCPP_HIDE_FROM_ABI directory_entry(_Path const& __p, error_code& __ec) : __p_(__p) { __refresh(&__ec); } _LIBCPP_HIDE_FROM_ABI ~directory_entry() {} - _LIBCPP_HIDE_FROM_ABI directory_entry& operator=(directory_entry const&) = default; + _LIBCPP_HIDE_FROM_ABI directory_entry& operator=(directory_entry const&) = default; _LIBCPP_HIDE_FROM_ABI directory_entry& operator=(directory_entry&&) noexcept = default; - _LIBCPP_INLINE_VISIBILITY - void assign(_Path const& __p) { + _LIBCPP_HIDE_FROM_ABI void assign(_Path const& __p) { __p_ = __p; error_code __ec; __refresh(&__ec); } - _LIBCPP_INLINE_VISIBILITY - void assign(_Path const& __p, error_code& __ec) { + _LIBCPP_HIDE_FROM_ABI void assign(_Path const& __p, error_code& __ec) { __p_ = __p; __refresh(&__ec); } - _LIBCPP_INLINE_VISIBILITY - void replace_filename(_Path const& __p) { + _LIBCPP_HIDE_FROM_ABI void replace_filename(_Path const& __p) { __p_.replace_filename(__p); error_code __ec; __refresh(&__ec); } - _LIBCPP_INLINE_VISIBILITY - void replace_filename(_Path const& __p, error_code& __ec) { + _LIBCPP_HIDE_FROM_ABI void replace_filename(_Path const& __p, error_code& __ec) { __p_ = __p_.parent_path() / __p; __refresh(&__ec); } - _LIBCPP_INLINE_VISIBILITY - void refresh() { __refresh(); } + _LIBCPP_HIDE_FROM_ABI void refresh() { __refresh(); } - _LIBCPP_INLINE_VISIBILITY - void refresh(error_code& __ec) noexcept { __refresh(&__ec); } + _LIBCPP_HIDE_FROM_ABI void refresh(error_code& __ec) noexcept { __refresh(&__ec); } - _LIBCPP_INLINE_VISIBILITY - _Path const& path() const noexcept { return __p_; } + _LIBCPP_HIDE_FROM_ABI _Path const& path() const noexcept { return __p_; } - _LIBCPP_INLINE_VISIBILITY - operator const _Path&() const noexcept { return __p_; } + _LIBCPP_HIDE_FROM_ABI operator const _Path&() const noexcept { return __p_; } - _LIBCPP_INLINE_VISIBILITY - bool exists() const { return _VSTD_FS::exists(file_status{__get_ft()}); } + _LIBCPP_HIDE_FROM_ABI bool exists() const { return filesystem::exists(file_status{__get_ft()}); } - _LIBCPP_INLINE_VISIBILITY - bool exists(error_code& __ec) const noexcept { - return _VSTD_FS::exists(file_status{__get_ft(&__ec)}); + _LIBCPP_HIDE_FROM_ABI bool exists(error_code& __ec) const noexcept { + return filesystem::exists(file_status{__get_ft(&__ec)}); } - _LIBCPP_INLINE_VISIBILITY - bool is_block_file() const { return __get_ft() == file_type::block; } + _LIBCPP_HIDE_FROM_ABI bool is_block_file() const { return __get_ft() == file_type::block; } - _LIBCPP_INLINE_VISIBILITY - bool is_block_file(error_code& __ec) const noexcept { + _LIBCPP_HIDE_FROM_ABI bool is_block_file(error_code& __ec) const noexcept { return __get_ft(&__ec) == file_type::block; } - _LIBCPP_INLINE_VISIBILITY - bool is_character_file() const { return __get_ft() == file_type::character; } + _LIBCPP_HIDE_FROM_ABI bool is_character_file() const { return __get_ft() == file_type::character; } - _LIBCPP_INLINE_VISIBILITY - bool is_character_file(error_code& __ec) const noexcept { + _LIBCPP_HIDE_FROM_ABI bool is_character_file(error_code& __ec) const noexcept { return __get_ft(&__ec) == file_type::character; } - _LIBCPP_INLINE_VISIBILITY - bool is_directory() const { return __get_ft() == file_type::directory; } + _LIBCPP_HIDE_FROM_ABI bool is_directory() const { return __get_ft() == file_type::directory; } - _LIBCPP_INLINE_VISIBILITY - bool is_directory(error_code& __ec) const noexcept { + _LIBCPP_HIDE_FROM_ABI bool is_directory(error_code& __ec) const noexcept { return __get_ft(&__ec) == file_type::directory; } - _LIBCPP_INLINE_VISIBILITY - bool is_fifo() const { return __get_ft() == file_type::fifo; } + _LIBCPP_HIDE_FROM_ABI bool is_fifo() const { return __get_ft() == file_type::fifo; } - _LIBCPP_INLINE_VISIBILITY - bool is_fifo(error_code& __ec) const noexcept { - return __get_ft(&__ec) == file_type::fifo; + _LIBCPP_HIDE_FROM_ABI bool is_fifo(error_code& __ec) const noexcept { return __get_ft(&__ec) == file_type::fifo; } + + _LIBCPP_HIDE_FROM_ABI bool is_other() const { return filesystem::is_other(file_status{__get_ft()}); } + + _LIBCPP_HIDE_FROM_ABI bool is_other(error_code& __ec) const noexcept { + return filesystem::is_other(file_status{__get_ft(&__ec)}); } - _LIBCPP_INLINE_VISIBILITY - bool is_other() const { return _VSTD_FS::is_other(file_status{__get_ft()}); } + _LIBCPP_HIDE_FROM_ABI bool is_regular_file() const { return __get_ft() == file_type::regular; } - _LIBCPP_INLINE_VISIBILITY - bool is_other(error_code& __ec) const noexcept { - return _VSTD_FS::is_other(file_status{__get_ft(&__ec)}); - } - - _LIBCPP_INLINE_VISIBILITY - bool is_regular_file() const { return __get_ft() == file_type::regular; } - - _LIBCPP_INLINE_VISIBILITY - bool is_regular_file(error_code& __ec) const noexcept { + _LIBCPP_HIDE_FROM_ABI bool is_regular_file(error_code& __ec) const noexcept { return __get_ft(&__ec) == file_type::regular; } - _LIBCPP_INLINE_VISIBILITY - bool is_socket() const { return __get_ft() == file_type::socket; } + _LIBCPP_HIDE_FROM_ABI bool is_socket() const { return __get_ft() == file_type::socket; } - _LIBCPP_INLINE_VISIBILITY - bool is_socket(error_code& __ec) const noexcept { - return __get_ft(&__ec) == file_type::socket; - } + _LIBCPP_HIDE_FROM_ABI bool is_socket(error_code& __ec) const noexcept { return __get_ft(&__ec) == file_type::socket; } - _LIBCPP_INLINE_VISIBILITY - bool is_symlink() const { return __get_sym_ft() == file_type::symlink; } + _LIBCPP_HIDE_FROM_ABI bool is_symlink() const { return __get_sym_ft() == file_type::symlink; } - _LIBCPP_INLINE_VISIBILITY - bool is_symlink(error_code& __ec) const noexcept { + _LIBCPP_HIDE_FROM_ABI bool is_symlink(error_code& __ec) const noexcept { return __get_sym_ft(&__ec) == file_type::symlink; } - _LIBCPP_INLINE_VISIBILITY - uintmax_t file_size() const { return __get_size(); } + _LIBCPP_HIDE_FROM_ABI uintmax_t file_size() const { return __get_size(); } - _LIBCPP_INLINE_VISIBILITY - uintmax_t file_size(error_code& __ec) const noexcept { - return __get_size(&__ec); - } + _LIBCPP_HIDE_FROM_ABI uintmax_t file_size(error_code& __ec) const noexcept { return __get_size(&__ec); } - _LIBCPP_INLINE_VISIBILITY - uintmax_t hard_link_count() const { return __get_nlink(); } + _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count() const { return __get_nlink(); } - _LIBCPP_INLINE_VISIBILITY - uintmax_t hard_link_count(error_code& __ec) const noexcept { - return __get_nlink(&__ec); - } + _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count(error_code& __ec) const noexcept { return __get_nlink(&__ec); } - _LIBCPP_INLINE_VISIBILITY - file_time_type last_write_time() const { return __get_write_time(); } + _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time() const { return __get_write_time(); } - _LIBCPP_INLINE_VISIBILITY - file_time_type last_write_time(error_code& __ec) const noexcept { + _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time(error_code& __ec) const noexcept { return __get_write_time(&__ec); } - _LIBCPP_INLINE_VISIBILITY - file_status status() const { return __get_status(); } + _LIBCPP_HIDE_FROM_ABI file_status status() const { return __get_status(); } - _LIBCPP_INLINE_VISIBILITY - file_status status(error_code& __ec) const noexcept { - return __get_status(&__ec); - } + _LIBCPP_HIDE_FROM_ABI file_status status(error_code& __ec) const noexcept { return __get_status(&__ec); } - _LIBCPP_INLINE_VISIBILITY - file_status symlink_status() const { return __get_symlink_status(); } + _LIBCPP_HIDE_FROM_ABI file_status symlink_status() const { return __get_symlink_status(); } - _LIBCPP_INLINE_VISIBILITY - file_status symlink_status(error_code& __ec) const noexcept { + _LIBCPP_HIDE_FROM_ABI file_status symlink_status(error_code& __ec) const noexcept { return __get_symlink_status(&__ec); } + _LIBCPP_HIDE_FROM_ABI bool operator==(directory_entry const& __rhs) const noexcept { return __p_ == __rhs.__p_; } - _LIBCPP_INLINE_VISIBILITY - bool operator==(directory_entry const& __rhs) const noexcept { - return __p_ == __rhs.__p_; - } +# if _LIBCPP_STD_VER <= 17 + _LIBCPP_HIDE_FROM_ABI bool operator!=(directory_entry const& __rhs) const noexcept { return __p_ != __rhs.__p_; } -#if _LIBCPP_STD_VER <= 17 - _LIBCPP_INLINE_VISIBILITY - bool operator!=(directory_entry const& __rhs) const noexcept { - return __p_ != __rhs.__p_; - } + _LIBCPP_HIDE_FROM_ABI bool operator<(directory_entry const& __rhs) const noexcept { return __p_ < __rhs.__p_; } - _LIBCPP_INLINE_VISIBILITY - bool operator<(directory_entry const& __rhs) const noexcept { - return __p_ < __rhs.__p_; - } + _LIBCPP_HIDE_FROM_ABI bool operator<=(directory_entry const& __rhs) const noexcept { return __p_ <= __rhs.__p_; } - _LIBCPP_INLINE_VISIBILITY - bool operator<=(directory_entry const& __rhs) const noexcept { - return __p_ <= __rhs.__p_; - } + _LIBCPP_HIDE_FROM_ABI bool operator>(directory_entry const& __rhs) const noexcept { return __p_ > __rhs.__p_; } - _LIBCPP_INLINE_VISIBILITY - bool operator>(directory_entry const& __rhs) const noexcept { - return __p_ > __rhs.__p_; - } + _LIBCPP_HIDE_FROM_ABI bool operator>=(directory_entry const& __rhs) const noexcept { return __p_ >= __rhs.__p_; } - _LIBCPP_INLINE_VISIBILITY - bool operator>=(directory_entry const& __rhs) const noexcept { - return __p_ >= __rhs.__p_; - } +# else // _LIBCPP_STD_VER <= 17 -#else // _LIBCPP_STD_VER <= 17 - - _LIBCPP_HIDE_FROM_ABI - strong_ordering operator<=>(const directory_entry& __rhs) const noexcept { + _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(const directory_entry& __rhs) const noexcept { return __p_ <=> __rhs.__p_; } -#endif // _LIBCPP_STD_VER <= 17 +# endif // _LIBCPP_STD_VER <= 17 template - _LIBCPP_INLINE_VISIBILITY - friend basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& __os, const directory_entry& __d) { + _LIBCPP_HIDE_FROM_ABI friend basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, const directory_entry& __d) { return __os << __d.path(); } @@ -286,23 +213,20 @@ private: file_type __type_; _CacheType __cache_type_; - _LIBCPP_INLINE_VISIBILITY - __cached_data() noexcept { __reset(); } + _LIBCPP_HIDE_FROM_ABI __cached_data() noexcept { __reset(); } - _LIBCPP_INLINE_VISIBILITY - void __reset() { + _LIBCPP_HIDE_FROM_ABI void __reset() { __cache_type_ = _Empty; - __type_ = file_type::none; + __type_ = file_type::none; __sym_perms_ = __non_sym_perms_ = perms::unknown; __size_ = __nlink_ = uintmax_t(-1); - __write_time_ = file_time_type::min(); + __write_time_ = file_time_type::min(); } }; - _LIBCPP_INLINE_VISIBILITY - static __cached_data __create_iter_result(file_type __ft) { + _LIBCPP_HIDE_FROM_ABI static __cached_data __create_iter_result(file_type __ft) { __cached_data __data; - __data.__type_ = __ft; + __data.__type_ = __ft; __data.__cache_type_ = [&]() { switch (__ft) { case file_type::none: @@ -316,17 +240,14 @@ private: return __data; } - _LIBCPP_INLINE_VISIBILITY - void __assign_iter_entry(_Path&& __p, __cached_data __dt) { - __p_ = _VSTD::move(__p); + _LIBCPP_HIDE_FROM_ABI void __assign_iter_entry(_Path&& __p, __cached_data __dt) { + __p_ = std::move(__p); __data_ = __dt; } - _LIBCPP_FUNC_VIS - error_code __do_refresh() noexcept; + _LIBCPP_EXPORTED_FROM_ABI error_code __do_refresh() noexcept; - _LIBCPP_INLINE_VISIBILITY - static bool __is_dne_error(error_code const& __ec) { + _LIBCPP_HIDE_FROM_ABI static bool __is_dne_error(error_code const& __ec) { if (!__ec) return true; switch (static_cast(__ec.value())) { @@ -338,9 +259,8 @@ private: } } - _LIBCPP_INLINE_VISIBILITY - void __handle_error(const char* __msg, error_code* __dest_ec, - error_code const& __ec, bool __allow_dne = false) const { + _LIBCPP_HIDE_FROM_ABI void + __handle_error(const char* __msg, error_code* __dest_ec, error_code const& __ec, bool __allow_dne = false) const { if (__dest_ec) { *__dest_ec = __ec; return; @@ -349,14 +269,14 @@ private: __throw_filesystem_error(__msg, __p_, __ec); } - _LIBCPP_INLINE_VISIBILITY - void __refresh(error_code* __ec = nullptr) { - __handle_error("in directory_entry::refresh", __ec, __do_refresh(), + _LIBCPP_HIDE_FROM_ABI void __refresh(error_code* __ec = nullptr) { + __handle_error("in directory_entry::refresh", + __ec, + __do_refresh(), /*allow_dne*/ true); } - _LIBCPP_INLINE_VISIBILITY - file_type __get_sym_ft(error_code* __ec = nullptr) const { + _LIBCPP_HIDE_FROM_ABI file_type __get_sym_ft(error_code* __ec = nullptr) const { switch (__data_.__cache_type_) { case _Empty: return __symlink_status(__p_, __ec).type(); @@ -369,7 +289,7 @@ private: case _IterNonSymlink: case _RefreshNonSymlink: file_status __st(__data_.__type_); - if (__ec && !_VSTD_FS::exists(__st)) + if (__ec && !filesystem::exists(__st)) *__ec = make_error_code(errc::no_such_file_or_directory); else if (__ec) __ec->clear(); @@ -378,8 +298,7 @@ private: __libcpp_unreachable(); } - _LIBCPP_INLINE_VISIBILITY - file_type __get_ft(error_code* __ec = nullptr) const { + _LIBCPP_HIDE_FROM_ABI file_type __get_ft(error_code* __ec = nullptr) const { switch (__data_.__cache_type_) { case _Empty: case _IterSymlink: @@ -389,7 +308,7 @@ private: case _RefreshNonSymlink: case _RefreshSymlink: { file_status __st(__data_.__type_); - if (__ec && !_VSTD_FS::exists(__st)) + if (__ec && !filesystem::exists(__st)) *__ec = make_error_code(errc::no_such_file_or_directory); else if (__ec) __ec->clear(); @@ -399,8 +318,7 @@ private: __libcpp_unreachable(); } - _LIBCPP_INLINE_VISIBILITY - file_status __get_status(error_code* __ec = nullptr) const { + _LIBCPP_HIDE_FROM_ABI file_status __get_status(error_code* __ec = nullptr) const { switch (__data_.__cache_type_) { case _Empty: case _IterNonSymlink: @@ -414,8 +332,7 @@ private: __libcpp_unreachable(); } - _LIBCPP_INLINE_VISIBILITY - file_status __get_symlink_status(error_code* __ec = nullptr) const { + _LIBCPP_HIDE_FROM_ABI file_status __get_symlink_status(error_code* __ec = nullptr) const { switch (__data_.__cache_type_) { case _Empty: case _IterNonSymlink: @@ -430,24 +347,21 @@ private: __libcpp_unreachable(); } - _LIBCPP_INLINE_VISIBILITY - uintmax_t __get_size(error_code* __ec = nullptr) const { + _LIBCPP_HIDE_FROM_ABI uintmax_t __get_size(error_code* __ec = nullptr) const { switch (__data_.__cache_type_) { case _Empty: case _IterNonSymlink: case _IterSymlink: case _RefreshSymlinkUnresolved: - return _VSTD_FS::__file_size(__p_, __ec); + return filesystem::__file_size(__p_, __ec); case _RefreshSymlink: case _RefreshNonSymlink: { error_code __m_ec; file_status __st(__get_ft(&__m_ec)); __handle_error("in directory_entry::file_size", __ec, __m_ec); - if (_VSTD_FS::exists(__st) && !_VSTD_FS::is_regular_file(__st)) { - errc __err_kind = _VSTD_FS::is_directory(__st) ? errc::is_a_directory - : errc::not_supported; - __handle_error("in directory_entry::file_size", __ec, - make_error_code(__err_kind)); + if (filesystem::exists(__st) && !filesystem::is_regular_file(__st)) { + errc __err_kind = filesystem::is_directory(__st) ? errc::is_a_directory : errc::not_supported; + __handle_error("in directory_entry::file_size", __ec, make_error_code(__err_kind)); } return __data_.__size_; } @@ -455,14 +369,13 @@ private: __libcpp_unreachable(); } - _LIBCPP_INLINE_VISIBILITY - uintmax_t __get_nlink(error_code* __ec = nullptr) const { + _LIBCPP_HIDE_FROM_ABI uintmax_t __get_nlink(error_code* __ec = nullptr) const { switch (__data_.__cache_type_) { case _Empty: case _IterNonSymlink: case _IterSymlink: case _RefreshSymlinkUnresolved: - return _VSTD_FS::__hard_link_count(__p_, __ec); + return filesystem::__hard_link_count(__p_, __ec); case _RefreshSymlink: case _RefreshNonSymlink: { error_code __m_ec; @@ -474,23 +387,20 @@ private: __libcpp_unreachable(); } - _LIBCPP_INLINE_VISIBILITY - file_time_type __get_write_time(error_code* __ec = nullptr) const { + _LIBCPP_HIDE_FROM_ABI file_time_type __get_write_time(error_code* __ec = nullptr) const { switch (__data_.__cache_type_) { case _Empty: case _IterNonSymlink: case _IterSymlink: case _RefreshSymlinkUnresolved: - return _VSTD_FS::__last_write_time(__p_, __ec); + return filesystem::__last_write_time(__p_, __ec); case _RefreshSymlink: case _RefreshNonSymlink: { error_code __m_ec; file_status __st(__get_ft(&__m_ec)); __handle_error("in directory_entry::last_write_time", __ec, __m_ec); - if (_VSTD_FS::exists(__st) && - __data_.__write_time_ == file_time_type::min()) - __handle_error("in directory_entry::last_write_time", __ec, - make_error_code(errc::value_too_large)); + if (filesystem::exists(__st) && __data_.__write_time_ == file_time_type::min()) + __handle_error("in directory_entry::last_write_time", __ec, make_error_code(errc::value_too_large)); return __data_.__write_time_; } } @@ -504,24 +414,21 @@ private: class __dir_element_proxy { public: - inline _LIBCPP_INLINE_VISIBILITY directory_entry operator*() { - return _VSTD::move(__elem_); - } + inline _LIBCPP_HIDE_FROM_ABI directory_entry operator*() { return std::move(__elem_); } private: friend class directory_iterator; friend class recursive_directory_iterator; _LIBCPP_HIDE_FROM_ABI explicit __dir_element_proxy(directory_entry const& __e) : __elem_(__e) {} - _LIBCPP_HIDE_FROM_ABI __dir_element_proxy(__dir_element_proxy&& __o) - : __elem_(_VSTD::move(__o.__elem_)) {} + _LIBCPP_HIDE_FROM_ABI __dir_element_proxy(__dir_element_proxy&& __o) : __elem_(std::move(__o.__elem_)) {} directory_entry __elem_; }; -_LIBCPP_AVAILABILITY_FILESYSTEM_POP +_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP _LIBCPP_END_NAMESPACE_FILESYSTEM -#endif // _LIBCPP_CXX03_LANG +#endif // _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM) _LIBCPP_POP_MACROS diff --git a/third_party/libcxx/__filesystem/directory_iterator.h b/third_party/libcxx/__filesystem/directory_iterator.h index d74c8be10..e0246d800 100644 --- a/third_party/libcxx/__filesystem/directory_iterator.h +++ b/third_party/libcxx/__filesystem/directory_iterator.h @@ -11,11 +11,11 @@ #define _LIBCPP___FILESYSTEM_DIRECTORY_ITERATOR_H #include <__assert> -#include <__availability> #include <__config> #include <__filesystem/directory_entry.h> #include <__filesystem/directory_options.h> #include <__filesystem/path.h> +#include <__iterator/default_sentinel.h> #include <__iterator/iterator_traits.h> #include <__memory/shared_ptr.h> #include <__ranges/enable_borrowed_range.h> @@ -28,11 +28,14 @@ # pragma GCC system_header #endif -#ifndef _LIBCPP_CXX03_LANG +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +#if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM) _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM -_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH +_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH class _LIBCPP_HIDDEN __dir_stream; class directory_iterator { @@ -44,123 +47,105 @@ public: typedef input_iterator_tag iterator_category; public: - //ctor & dtor - _LIBCPP_HIDE_FROM_ABI - directory_iterator() noexcept {} + // ctor & dtor + _LIBCPP_HIDE_FROM_ABI directory_iterator() noexcept {} - _LIBCPP_HIDE_FROM_ABI - explicit directory_iterator(const path& __p) - : directory_iterator(__p, nullptr) {} + _LIBCPP_HIDE_FROM_ABI explicit directory_iterator(const path& __p) : directory_iterator(__p, nullptr) {} - _LIBCPP_HIDE_FROM_ABI - directory_iterator(const path& __p, directory_options __opts) + _LIBCPP_HIDE_FROM_ABI directory_iterator(const path& __p, directory_options __opts) : directory_iterator(__p, nullptr, __opts) {} - _LIBCPP_HIDE_FROM_ABI - directory_iterator(const path& __p, error_code& __ec) - : directory_iterator(__p, &__ec) {} + _LIBCPP_HIDE_FROM_ABI directory_iterator(const path& __p, error_code& __ec) : directory_iterator(__p, &__ec) {} - _LIBCPP_HIDE_FROM_ABI - directory_iterator(const path& __p, directory_options __opts, - error_code& __ec) + _LIBCPP_HIDE_FROM_ABI directory_iterator(const path& __p, directory_options __opts, error_code& __ec) : directory_iterator(__p, &__ec, __opts) {} - _LIBCPP_HIDE_FROM_ABI directory_iterator(const directory_iterator&) = default; - _LIBCPP_HIDE_FROM_ABI directory_iterator(directory_iterator&&) = default; + _LIBCPP_HIDE_FROM_ABI directory_iterator(const directory_iterator&) = default; + _LIBCPP_HIDE_FROM_ABI directory_iterator(directory_iterator&&) = default; _LIBCPP_HIDE_FROM_ABI directory_iterator& operator=(const directory_iterator&) = default; - _LIBCPP_HIDE_FROM_ABI - directory_iterator& operator=(directory_iterator&& __o) noexcept { + _LIBCPP_HIDE_FROM_ABI directory_iterator& operator=(directory_iterator&& __o) noexcept { // non-default implementation provided to support self-move assign. if (this != &__o) { - __imp_ = _VSTD::move(__o.__imp_); + __imp_ = std::move(__o.__imp_); } return *this; } _LIBCPP_HIDE_FROM_ABI ~directory_iterator() = default; - _LIBCPP_HIDE_FROM_ABI - const directory_entry& operator*() const { - _LIBCPP_ASSERT(__imp_, "The end iterator cannot be dereferenced"); + _LIBCPP_HIDE_FROM_ABI const directory_entry& operator*() const { + // Note: this check duplicates a check in `__dereference()`. + _LIBCPP_ASSERT_NON_NULL(__imp_, "The end iterator cannot be dereferenced"); return __dereference(); } - _LIBCPP_HIDE_FROM_ABI - const directory_entry* operator->() const { return &**this; } + _LIBCPP_HIDE_FROM_ABI const directory_entry* operator->() const { return &**this; } - _LIBCPP_HIDE_FROM_ABI - directory_iterator& operator++() { return __increment(); } + _LIBCPP_HIDE_FROM_ABI directory_iterator& operator++() { return __increment(); } - _LIBCPP_HIDE_FROM_ABI - __dir_element_proxy operator++(int) { + _LIBCPP_HIDE_FROM_ABI __dir_element_proxy operator++(int) { __dir_element_proxy __p(**this); __increment(); return __p; } - _LIBCPP_HIDE_FROM_ABI - directory_iterator& increment(error_code& __ec) { return __increment(&__ec); } + _LIBCPP_HIDE_FROM_ABI directory_iterator& increment(error_code& __ec) { return __increment(&__ec); } + +# if _LIBCPP_STD_VER >= 20 + + _LIBCPP_HIDE_FROM_ABI bool operator==(default_sentinel_t) const noexcept { return *this == directory_iterator(); } + +# endif private: inline _LIBCPP_HIDE_FROM_ABI friend bool - operator==(const directory_iterator& __lhs, - const directory_iterator& __rhs) noexcept; + operator==(const directory_iterator& __lhs, const directory_iterator& __rhs) noexcept; // construct the dir_stream - _LIBCPP_FUNC_VIS - directory_iterator(const path&, error_code*, - directory_options = directory_options::none); + _LIBCPP_EXPORTED_FROM_ABI directory_iterator(const path&, error_code*, directory_options = directory_options::none); - _LIBCPP_FUNC_VIS - directory_iterator& __increment(error_code* __ec = nullptr); + _LIBCPP_EXPORTED_FROM_ABI directory_iterator& __increment(error_code* __ec = nullptr); - _LIBCPP_FUNC_VIS - const directory_entry& __dereference() const; + _LIBCPP_EXPORTED_FROM_ABI const directory_entry& __dereference() const; private: shared_ptr<__dir_stream> __imp_; }; inline _LIBCPP_HIDE_FROM_ABI bool -operator==(const directory_iterator& __lhs, - const directory_iterator& __rhs) noexcept { +operator==(const directory_iterator& __lhs, const directory_iterator& __rhs) noexcept { return __lhs.__imp_ == __rhs.__imp_; } inline _LIBCPP_HIDE_FROM_ABI bool -operator!=(const directory_iterator& __lhs, - const directory_iterator& __rhs) noexcept { +operator!=(const directory_iterator& __lhs, const directory_iterator& __rhs) noexcept { return !(__lhs == __rhs); } // enable directory_iterator range-based for statements -inline _LIBCPP_HIDE_FROM_ABI directory_iterator -begin(directory_iterator __iter) noexcept { - return __iter; -} +inline _LIBCPP_HIDE_FROM_ABI directory_iterator begin(directory_iterator __iter) noexcept { return __iter; } -inline _LIBCPP_HIDE_FROM_ABI directory_iterator -end(directory_iterator) noexcept { - return directory_iterator(); -} +inline _LIBCPP_HIDE_FROM_ABI directory_iterator end(directory_iterator) noexcept { return directory_iterator(); } -_LIBCPP_AVAILABILITY_FILESYSTEM_POP +_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP _LIBCPP_END_NAMESPACE_FILESYSTEM -#if _LIBCPP_STD_VER >= 20 +# if _LIBCPP_STD_VER >= 20 template <> -_LIBCPP_AVAILABILITY_FILESYSTEM -inline constexpr bool _VSTD::ranges::enable_borrowed_range<_VSTD_FS::directory_iterator> = true; +_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY inline constexpr bool + std::ranges::enable_borrowed_range = true; template <> -_LIBCPP_AVAILABILITY_FILESYSTEM -inline constexpr bool _VSTD::ranges::enable_view<_VSTD_FS::directory_iterator> = true; +_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY inline constexpr bool + std::ranges::enable_view = true; -#endif // _LIBCPP_STD_VER >= 20 +# endif // _LIBCPP_STD_VER >= 20 -#endif // _LIBCPP_CXX03_LANG +#endif // _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM) + +_LIBCPP_POP_MACROS #endif // _LIBCPP___FILESYSTEM_DIRECTORY_ITERATOR_H diff --git a/third_party/libcxx/__filesystem/directory_options.h b/third_party/libcxx/__filesystem/directory_options.h index c5c031a56..d0cd3ebfd 100644 --- a/third_party/libcxx/__filesystem/directory_options.h +++ b/third_party/libcxx/__filesystem/directory_options.h @@ -10,73 +10,48 @@ #ifndef _LIBCPP___FILESYSTEM_DIRECTORY_OPTIONS_H #define _LIBCPP___FILESYSTEM_DIRECTORY_OPTIONS_H -#include <__availability> #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif -#ifndef _LIBCPP_CXX03_LANG +#if _LIBCPP_STD_VER >= 17 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM -_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH +enum class directory_options : unsigned char { none = 0, follow_directory_symlink = 1, skip_permission_denied = 2 }; -enum class _LIBCPP_ENUM_VIS directory_options : unsigned char { - none = 0, - follow_directory_symlink = 1, - skip_permission_denied = 2 -}; - -_LIBCPP_INLINE_VISIBILITY -inline constexpr directory_options operator&(directory_options __lhs, - directory_options __rhs) { - return static_cast(static_cast(__lhs) & - static_cast(__rhs)); +_LIBCPP_HIDE_FROM_ABI inline constexpr directory_options operator&(directory_options __lhs, directory_options __rhs) { + return static_cast(static_cast(__lhs) & static_cast(__rhs)); } -_LIBCPP_INLINE_VISIBILITY -inline constexpr directory_options operator|(directory_options __lhs, - directory_options __rhs) { - return static_cast(static_cast(__lhs) | - static_cast(__rhs)); +_LIBCPP_HIDE_FROM_ABI inline constexpr directory_options operator|(directory_options __lhs, directory_options __rhs) { + return static_cast(static_cast(__lhs) | static_cast(__rhs)); } -_LIBCPP_INLINE_VISIBILITY -inline constexpr directory_options operator^(directory_options __lhs, - directory_options __rhs) { - return static_cast(static_cast(__lhs) ^ - static_cast(__rhs)); +_LIBCPP_HIDE_FROM_ABI inline constexpr directory_options operator^(directory_options __lhs, directory_options __rhs) { + return static_cast(static_cast(__lhs) ^ static_cast(__rhs)); } -_LIBCPP_INLINE_VISIBILITY -inline constexpr directory_options operator~(directory_options __lhs) { +_LIBCPP_HIDE_FROM_ABI inline constexpr directory_options operator~(directory_options __lhs) { return static_cast(~static_cast(__lhs)); } -_LIBCPP_INLINE_VISIBILITY -inline directory_options& operator&=(directory_options& __lhs, - directory_options __rhs) { +_LIBCPP_HIDE_FROM_ABI inline directory_options& operator&=(directory_options& __lhs, directory_options __rhs) { return __lhs = __lhs & __rhs; } -_LIBCPP_INLINE_VISIBILITY -inline directory_options& operator|=(directory_options& __lhs, - directory_options __rhs) { +_LIBCPP_HIDE_FROM_ABI inline directory_options& operator|=(directory_options& __lhs, directory_options __rhs) { return __lhs = __lhs | __rhs; } -_LIBCPP_INLINE_VISIBILITY -inline directory_options& operator^=(directory_options& __lhs, - directory_options __rhs) { +_LIBCPP_HIDE_FROM_ABI inline directory_options& operator^=(directory_options& __lhs, directory_options __rhs) { return __lhs = __lhs ^ __rhs; } -_LIBCPP_AVAILABILITY_FILESYSTEM_POP - _LIBCPP_END_NAMESPACE_FILESYSTEM -#endif // _LIBCPP_CXX03_LANG +#endif // _LIBCPP_STD_VER >= 17 #endif // _LIBCPP___FILESYSTEM_DIRECTORY_OPTIONS_H diff --git a/third_party/libcxx/__filesystem/file_status.h b/third_party/libcxx/__filesystem/file_status.h index 350b0fcc8..da316c8b0 100644 --- a/third_party/libcxx/__filesystem/file_status.h +++ b/third_party/libcxx/__filesystem/file_status.h @@ -10,7 +10,6 @@ #ifndef _LIBCPP___FILESYSTEM_FILE_STATUS_H #define _LIBCPP___FILESYSTEM_FILE_STATUS_H -#include <__availability> #include <__config> #include <__filesystem/file_type.h> #include <__filesystem/perms.h> @@ -19,54 +18,50 @@ # pragma GCC system_header #endif -#ifndef _LIBCPP_CXX03_LANG +#if _LIBCPP_STD_VER >= 17 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM -_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH - -class _LIBCPP_TYPE_VIS file_status { +class _LIBCPP_EXPORTED_FROM_ABI file_status { public: // constructors - _LIBCPP_INLINE_VISIBILITY - file_status() noexcept : file_status(file_type::none) {} - _LIBCPP_INLINE_VISIBILITY - explicit file_status(file_type __ft, perms __prms = perms::unknown) noexcept - : __ft_(__ft), - __prms_(__prms) {} + _LIBCPP_HIDE_FROM_ABI file_status() noexcept : file_status(file_type::none) {} + _LIBCPP_HIDE_FROM_ABI explicit file_status(file_type __ft, perms __prms = perms::unknown) noexcept + : __ft_(__ft), __prms_(__prms) {} _LIBCPP_HIDE_FROM_ABI file_status(const file_status&) noexcept = default; - _LIBCPP_HIDE_FROM_ABI file_status(file_status&&) noexcept = default; + _LIBCPP_HIDE_FROM_ABI file_status(file_status&&) noexcept = default; - _LIBCPP_INLINE_VISIBILITY - ~file_status() {} + _LIBCPP_HIDE_FROM_ABI ~file_status() {} _LIBCPP_HIDE_FROM_ABI file_status& operator=(const file_status&) noexcept = default; - _LIBCPP_HIDE_FROM_ABI file_status& operator=(file_status&&) noexcept = default; + _LIBCPP_HIDE_FROM_ABI file_status& operator=(file_status&&) noexcept = default; // observers - _LIBCPP_INLINE_VISIBILITY - file_type type() const noexcept { return __ft_; } + _LIBCPP_HIDE_FROM_ABI file_type type() const noexcept { return __ft_; } - _LIBCPP_INLINE_VISIBILITY - perms permissions() const noexcept { return __prms_; } + _LIBCPP_HIDE_FROM_ABI perms permissions() const noexcept { return __prms_; } // modifiers - _LIBCPP_INLINE_VISIBILITY - void type(file_type __ft) noexcept { __ft_ = __ft; } + _LIBCPP_HIDE_FROM_ABI void type(file_type __ft) noexcept { __ft_ = __ft; } - _LIBCPP_INLINE_VISIBILITY - void permissions(perms __p) noexcept { __prms_ = __p; } + _LIBCPP_HIDE_FROM_ABI void permissions(perms __p) noexcept { __prms_ = __p; } + +# if _LIBCPP_STD_VER >= 20 + + _LIBCPP_HIDE_FROM_ABI friend bool operator==(const file_status& __lhs, const file_status& __rhs) noexcept { + return __lhs.type() == __rhs.type() && __lhs.permissions() == __rhs.permissions(); + } + +# endif private: file_type __ft_; perms __prms_; }; -_LIBCPP_AVAILABILITY_FILESYSTEM_POP - _LIBCPP_END_NAMESPACE_FILESYSTEM -#endif // _LIBCPP_CXX03_LANG +#endif // _LIBCPP_STD_VER >= 17 #endif // _LIBCPP___FILESYSTEM_FILE_STATUS_H diff --git a/third_party/libcxx/__filesystem/file_time_type.h b/third_party/libcxx/__filesystem/file_time_type.h index 7c4932e60..63e4ae157 100644 --- a/third_party/libcxx/__filesystem/file_time_type.h +++ b/third_party/libcxx/__filesystem/file_time_type.h @@ -10,7 +10,6 @@ #ifndef _LIBCPP___FILESYSTEM_FILE_TIME_TYPE_H #define _LIBCPP___FILESYSTEM_FILE_TIME_TYPE_H -#include <__availability> #include <__chrono/file_clock.h> #include <__chrono/time_point.h> #include <__config> @@ -19,7 +18,7 @@ # pragma GCC system_header #endif -#ifndef _LIBCPP_CXX03_LANG +#if _LIBCPP_STD_VER >= 17 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM @@ -27,6 +26,6 @@ typedef chrono::time_point<_FilesystemClock> file_time_type; _LIBCPP_END_NAMESPACE_FILESYSTEM -#endif // _LIBCPP_CXX03_LANG +#endif // _LIBCPP_STD_VER >= 17 #endif // _LIBCPP___FILESYSTEM_FILE_TIME_TYPE_H diff --git a/third_party/libcxx/__filesystem/file_type.h b/third_party/libcxx/__filesystem/file_type.h index c756a05c8..e4ac1dfee 100644 --- a/third_party/libcxx/__filesystem/file_type.h +++ b/third_party/libcxx/__filesystem/file_type.h @@ -10,34 +10,33 @@ #ifndef _LIBCPP___FILESYSTEM_FILE_TYPE_H #define _LIBCPP___FILESYSTEM_FILE_TYPE_H -#include <__availability> #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif -#ifndef _LIBCPP_CXX03_LANG +#if _LIBCPP_STD_VER >= 17 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM // On Windows, the library never identifies files as block, character, fifo // or socket. -enum class _LIBCPP_ENUM_VIS file_type : signed char { - none = 0, +enum class file_type : signed char { + none = 0, not_found = -1, - regular = 1, + regular = 1, directory = 2, - symlink = 3, - block = 4, + symlink = 3, + block = 4, character = 5, - fifo = 6, - socket = 7, - unknown = 8 + fifo = 6, + socket = 7, + unknown = 8 }; _LIBCPP_END_NAMESPACE_FILESYSTEM -#endif // _LIBCPP_CXX03_LANG +#endif // _LIBCPP_STD_VER >= 17 #endif // _LIBCPP___FILESYSTEM_FILE_TYPE_H diff --git a/third_party/libcxx/__filesystem/filesystem_error.h b/third_party/libcxx/__filesystem/filesystem_error.h index d345dab76..80a11e3b1 100644 --- a/third_party/libcxx/__filesystem/filesystem_error.h +++ b/third_party/libcxx/__filesystem/filesystem_error.h @@ -10,7 +10,6 @@ #ifndef _LIBCPP___FILESYSTEM_FILESYSTEM_ERROR_H #define _LIBCPP___FILESYSTEM_FILESYSTEM_ERROR_H -#include <__availability> #include <__config> #include <__filesystem/path.h> #include <__memory/shared_ptr.h> @@ -18,62 +17,48 @@ #include <__system_error/system_error.h> #include <__utility/forward.h> #include <__verbose_abort> -#include -#include #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif -#ifndef _LIBCPP_CXX03_LANG +#if _LIBCPP_STD_VER >= 17 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM -class _LIBCPP_AVAILABILITY_FILESYSTEM _LIBCPP_EXCEPTION_ABI filesystem_error : public system_error { +class _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY _LIBCPP_EXPORTED_FROM_ABI filesystem_error : public system_error { public: - _LIBCPP_INLINE_VISIBILITY - filesystem_error(const string& __what, error_code __ec) - : system_error(__ec, __what), - __storage_(make_shared<_Storage>(path(), path())) { + _LIBCPP_HIDE_FROM_ABI filesystem_error(const string& __what, error_code __ec) + : system_error(__ec, __what), __storage_(make_shared<_Storage>(path(), path())) { __create_what(0); } - _LIBCPP_INLINE_VISIBILITY - filesystem_error(const string& __what, const path& __p1, error_code __ec) - : system_error(__ec, __what), - __storage_(make_shared<_Storage>(__p1, path())) { + _LIBCPP_HIDE_FROM_ABI filesystem_error(const string& __what, const path& __p1, error_code __ec) + : system_error(__ec, __what), __storage_(make_shared<_Storage>(__p1, path())) { __create_what(1); } - _LIBCPP_INLINE_VISIBILITY - filesystem_error(const string& __what, const path& __p1, const path& __p2, - error_code __ec) - : system_error(__ec, __what), - __storage_(make_shared<_Storage>(__p1, __p2)) { + _LIBCPP_HIDE_FROM_ABI filesystem_error(const string& __what, const path& __p1, const path& __p2, error_code __ec) + : system_error(__ec, __what), __storage_(make_shared<_Storage>(__p1, __p2)) { __create_what(2); } - _LIBCPP_INLINE_VISIBILITY - const path& path1() const noexcept { return __storage_->__p1_; } + _LIBCPP_HIDE_FROM_ABI const path& path1() const noexcept { return __storage_->__p1_; } - _LIBCPP_INLINE_VISIBILITY - const path& path2() const noexcept { return __storage_->__p2_; } + _LIBCPP_HIDE_FROM_ABI const path& path2() const noexcept { return __storage_->__p2_; } _LIBCPP_HIDE_FROM_ABI filesystem_error(const filesystem_error&) = default; ~filesystem_error() override; // key function _LIBCPP_HIDE_FROM_ABI_VIRTUAL - const char* what() const noexcept override { - return __storage_->__what_.c_str(); - } + const char* what() const noexcept override { return __storage_->__what_.c_str(); } void __create_what(int __num_paths); private: struct _LIBCPP_HIDDEN _Storage { - _LIBCPP_INLINE_VISIBILITY - _Storage(const path& __p1, const path& __p2) : __p1_(__p1), __p2_(__p2) {} + _LIBCPP_HIDE_FROM_ABI _Storage(const path& __p1, const path& __p2) : __p1_(__p1), __p2_(__p2) {} path __p1_; path __p2_; @@ -82,25 +67,22 @@ private: shared_ptr<_Storage> __storage_; }; -// TODO(ldionne): We need to pop the pragma and push it again after -// filesystem_error to work around PR41078. -_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH - +# ifndef _LIBCPP_HAS_NO_EXCEPTIONS template -_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY -#ifndef _LIBCPP_HAS_NO_EXCEPTIONS -void __throw_filesystem_error(_Args&&... __args) { - throw filesystem_error(_VSTD::forward<_Args>(__args)...); +_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY void +__throw_filesystem_error(_Args&&... __args) { + throw filesystem_error(std::forward<_Args>(__args)...); } -#else -void __throw_filesystem_error(_Args&&...) { - _LIBCPP_VERBOSE_ABORT("filesystem_error was thrown in -fno-exceptions mode"); +# else +template +_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY void +__throw_filesystem_error(_Args&&...) { + _LIBCPP_VERBOSE_ABORT("filesystem_error was thrown in -fno-exceptions mode"); } -#endif -_LIBCPP_AVAILABILITY_FILESYSTEM_POP +# endif _LIBCPP_END_NAMESPACE_FILESYSTEM -#endif // _LIBCPP_CXX03_LANG +#endif // _LIBCPP_STD_VER >= 17 #endif // _LIBCPP___FILESYSTEM_FILESYSTEM_ERROR_H diff --git a/third_party/libcxx/__filesystem/operations.h b/third_party/libcxx/__filesystem/operations.h index 6bf58d8a7..f588189ed 100644 --- a/third_party/libcxx/__filesystem/operations.h +++ b/third_party/libcxx/__filesystem/operations.h @@ -10,7 +10,6 @@ #ifndef _LIBCPP___FILESYSTEM_OPERATIONS_H #define _LIBCPP___FILESYSTEM_OPERATIONS_H -#include <__availability> #include <__chrono/time_point.h> #include <__config> #include <__filesystem/copy_options.h> @@ -28,77 +27,130 @@ # pragma GCC system_header #endif -#ifndef _LIBCPP_CXX03_LANG +#if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM) _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM -_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH +_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH -_LIBCPP_FUNC_VIS path __absolute(const path&, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS path __canonical(const path&, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS bool __copy_file(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS void __copy_symlink(const path& __existing_symlink, const path& __new_symlink, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS void __copy(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS bool __create_directories(const path&, error_code* = nullptr); -_LIBCPP_FUNC_VIS void __create_directory_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS bool __create_directory(const path&, error_code* = nullptr); -_LIBCPP_FUNC_VIS bool __create_directory(const path&, const path& __attributes, error_code* = nullptr); -_LIBCPP_FUNC_VIS void __create_hard_link(const path& __to, const path& __new_hard_link, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS void __create_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS path __current_path(error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS void __current_path(const path&, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS bool __equivalent(const path&, const path&, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS file_status __status(const path&, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS uintmax_t __file_size(const path&, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS uintmax_t __hard_link_count(const path&, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS file_status __symlink_status(const path&, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS file_time_type __last_write_time(const path&, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS void __last_write_time(const path&, file_time_type __new_time, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS path __weakly_canonical(path const& __p, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS path __read_symlink(const path&, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS uintmax_t __remove_all(const path&, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS bool __remove(const path&, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS void __rename(const path& __from, const path& __to, error_code* __ec = nullptr); -_LIBCPP_FUNC_VIS void __resize_file(const path&, uintmax_t __size, error_code* = nullptr); -_LIBCPP_FUNC_VIS path __temp_directory_path(error_code* __ec = nullptr); +_LIBCPP_EXPORTED_FROM_ABI path __absolute(const path&, error_code* __ec = nullptr); +_LIBCPP_EXPORTED_FROM_ABI path __canonical(const path&, error_code* __ec = nullptr); +_LIBCPP_EXPORTED_FROM_ABI bool +__copy_file(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr); +_LIBCPP_EXPORTED_FROM_ABI void +__copy_symlink(const path& __existing_symlink, const path& __new_symlink, error_code* __ec = nullptr); +_LIBCPP_EXPORTED_FROM_ABI void +__copy(const path& __from, const path& __to, copy_options __opt, error_code* __ec = nullptr); +_LIBCPP_EXPORTED_FROM_ABI bool __create_directories(const path&, error_code* = nullptr); +_LIBCPP_EXPORTED_FROM_ABI void +__create_directory_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr); +_LIBCPP_EXPORTED_FROM_ABI bool __create_directory(const path&, error_code* = nullptr); +_LIBCPP_EXPORTED_FROM_ABI bool __create_directory(const path&, const path& __attributes, error_code* = nullptr); +_LIBCPP_EXPORTED_FROM_ABI void +__create_hard_link(const path& __to, const path& __new_hard_link, error_code* __ec = nullptr); +_LIBCPP_EXPORTED_FROM_ABI void +__create_symlink(const path& __to, const path& __new_symlink, error_code* __ec = nullptr); +_LIBCPP_EXPORTED_FROM_ABI path __current_path(error_code* __ec = nullptr); +_LIBCPP_EXPORTED_FROM_ABI void __current_path(const path&, error_code* __ec = nullptr); +_LIBCPP_EXPORTED_FROM_ABI bool __equivalent(const path&, const path&, error_code* __ec = nullptr); +_LIBCPP_EXPORTED_FROM_ABI file_status __status(const path&, error_code* __ec = nullptr); +_LIBCPP_EXPORTED_FROM_ABI uintmax_t __file_size(const path&, error_code* __ec = nullptr); +_LIBCPP_EXPORTED_FROM_ABI uintmax_t __hard_link_count(const path&, error_code* __ec = nullptr); +_LIBCPP_EXPORTED_FROM_ABI file_status __symlink_status(const path&, error_code* __ec = nullptr); +_LIBCPP_EXPORTED_FROM_ABI file_time_type __last_write_time(const path&, error_code* __ec = nullptr); +_LIBCPP_EXPORTED_FROM_ABI void __last_write_time(const path&, file_time_type __new_time, error_code* __ec = nullptr); +_LIBCPP_EXPORTED_FROM_ABI path __weakly_canonical(path const& __p, error_code* __ec = nullptr); +_LIBCPP_EXPORTED_FROM_ABI path __read_symlink(const path&, error_code* __ec = nullptr); +_LIBCPP_EXPORTED_FROM_ABI uintmax_t __remove_all(const path&, error_code* __ec = nullptr); +_LIBCPP_EXPORTED_FROM_ABI bool __remove(const path&, error_code* __ec = nullptr); +_LIBCPP_EXPORTED_FROM_ABI void __rename(const path& __from, const path& __to, error_code* __ec = nullptr); +_LIBCPP_EXPORTED_FROM_ABI void __resize_file(const path&, uintmax_t __size, error_code* = nullptr); +_LIBCPP_EXPORTED_FROM_ABI path __temp_directory_path(error_code* __ec = nullptr); inline _LIBCPP_HIDE_FROM_ABI path absolute(const path& __p) { return __absolute(__p); } inline _LIBCPP_HIDE_FROM_ABI path absolute(const path& __p, error_code& __ec) { return __absolute(__p, &__ec); } -inline _LIBCPP_HIDE_FROM_ABI path canonical(const path& __p) { return __canonical(__p); } +inline _LIBCPP_HIDE_FROM_ABI path canonical(const path& __p) { return __canonical(__p); } inline _LIBCPP_HIDE_FROM_ABI path canonical(const path& __p, error_code& __ec) { return __canonical(__p, &__ec); } -inline _LIBCPP_HIDE_FROM_ABI bool copy_file(const path& __from, const path& __to) { return __copy_file(__from, __to, copy_options::none); } -inline _LIBCPP_HIDE_FROM_ABI bool copy_file(const path& __from, const path& __to, error_code& __ec) { return __copy_file(__from, __to, copy_options::none, &__ec); } -inline _LIBCPP_HIDE_FROM_ABI bool copy_file(const path& __from, const path& __to, copy_options __opt) { return __copy_file(__from, __to, __opt); } -inline _LIBCPP_HIDE_FROM_ABI bool copy_file(const path& __from, const path& __to, copy_options __opt, error_code& __ec) { return __copy_file(__from, __to, __opt, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI bool copy_file(const path& __from, const path& __to) { + return __copy_file(__from, __to, copy_options::none); +} +inline _LIBCPP_HIDE_FROM_ABI bool copy_file(const path& __from, const path& __to, error_code& __ec) { + return __copy_file(__from, __to, copy_options::none, &__ec); +} +inline _LIBCPP_HIDE_FROM_ABI bool copy_file(const path& __from, const path& __to, copy_options __opt) { + return __copy_file(__from, __to, __opt); +} +inline _LIBCPP_HIDE_FROM_ABI bool +copy_file(const path& __from, const path& __to, copy_options __opt, error_code& __ec) { + return __copy_file(__from, __to, __opt, &__ec); +} inline _LIBCPP_HIDE_FROM_ABI void copy_symlink(const path& __from, const path& __to) { __copy_symlink(__from, __to); } -inline _LIBCPP_HIDE_FROM_ABI void copy_symlink(const path& __from, const path& __to, error_code& __ec) noexcept { __copy_symlink(__from, __to, &__ec); } -inline _LIBCPP_HIDE_FROM_ABI void copy(const path& __from, const path& __to) { __copy(__from, __to, copy_options::none); } -inline _LIBCPP_HIDE_FROM_ABI void copy(const path& __from, const path& __to, error_code& __ec) { __copy(__from, __to, copy_options::none, &__ec); } -inline _LIBCPP_HIDE_FROM_ABI void copy(const path& __from, const path& __to, copy_options __opt) { __copy(__from, __to, __opt); } -inline _LIBCPP_HIDE_FROM_ABI void copy(const path& __from, const path& __to, copy_options __opt, error_code& __ec) { __copy(__from, __to, __opt, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI void copy_symlink(const path& __from, const path& __to, error_code& __ec) noexcept { + __copy_symlink(__from, __to, &__ec); +} +inline _LIBCPP_HIDE_FROM_ABI void copy(const path& __from, const path& __to) { + __copy(__from, __to, copy_options::none); +} +inline _LIBCPP_HIDE_FROM_ABI void copy(const path& __from, const path& __to, error_code& __ec) { + __copy(__from, __to, copy_options::none, &__ec); +} +inline _LIBCPP_HIDE_FROM_ABI void copy(const path& __from, const path& __to, copy_options __opt) { + __copy(__from, __to, __opt); +} +inline _LIBCPP_HIDE_FROM_ABI void copy(const path& __from, const path& __to, copy_options __opt, error_code& __ec) { + __copy(__from, __to, __opt, &__ec); +} inline _LIBCPP_HIDE_FROM_ABI bool create_directories(const path& __p) { return __create_directories(__p); } -inline _LIBCPP_HIDE_FROM_ABI bool create_directories(const path& __p, error_code& __ec) { return __create_directories(__p, &__ec); } -inline _LIBCPP_HIDE_FROM_ABI void create_directory_symlink(const path& __target, const path& __link) { __create_directory_symlink(__target, __link); } -inline _LIBCPP_HIDE_FROM_ABI void create_directory_symlink(const path& __target, const path& __link, error_code& __ec) noexcept { __create_directory_symlink(__target, __link, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI bool create_directories(const path& __p, error_code& __ec) { + return __create_directories(__p, &__ec); +} +inline _LIBCPP_HIDE_FROM_ABI void create_directory_symlink(const path& __target, const path& __link) { + __create_directory_symlink(__target, __link); +} +inline _LIBCPP_HIDE_FROM_ABI void +create_directory_symlink(const path& __target, const path& __link, error_code& __ec) noexcept { + __create_directory_symlink(__target, __link, &__ec); +} inline _LIBCPP_HIDE_FROM_ABI bool create_directory(const path& __p) { return __create_directory(__p); } -inline _LIBCPP_HIDE_FROM_ABI bool create_directory(const path& __p, error_code& __ec) noexcept { return __create_directory(__p, &__ec); } -inline _LIBCPP_HIDE_FROM_ABI bool create_directory(const path& __p, const path& __attrs) { return __create_directory(__p, __attrs); } -inline _LIBCPP_HIDE_FROM_ABI bool create_directory(const path& __p, const path& __attrs, error_code& __ec) noexcept { return __create_directory(__p, __attrs, &__ec); } -inline _LIBCPP_HIDE_FROM_ABI void create_hard_link(const path& __target, const path& __link) { __create_hard_link(__target, __link); } -inline _LIBCPP_HIDE_FROM_ABI void create_hard_link(const path& __target, const path& __link, error_code& __ec) noexcept { __create_hard_link(__target, __link, &__ec); } -inline _LIBCPP_HIDE_FROM_ABI void create_symlink(const path& __target, const path& __link) { __create_symlink(__target, __link); } -inline _LIBCPP_HIDE_FROM_ABI void create_symlink(const path& __target, const path& __link, error_code& __ec) noexcept { return __create_symlink(__target, __link, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI bool create_directory(const path& __p, error_code& __ec) noexcept { + return __create_directory(__p, &__ec); +} +inline _LIBCPP_HIDE_FROM_ABI bool create_directory(const path& __p, const path& __attrs) { + return __create_directory(__p, __attrs); +} +inline _LIBCPP_HIDE_FROM_ABI bool create_directory(const path& __p, const path& __attrs, error_code& __ec) noexcept { + return __create_directory(__p, __attrs, &__ec); +} +inline _LIBCPP_HIDE_FROM_ABI void create_hard_link(const path& __target, const path& __link) { + __create_hard_link(__target, __link); +} +inline _LIBCPP_HIDE_FROM_ABI void +create_hard_link(const path& __target, const path& __link, error_code& __ec) noexcept { + __create_hard_link(__target, __link, &__ec); +} +inline _LIBCPP_HIDE_FROM_ABI void create_symlink(const path& __target, const path& __link) { + __create_symlink(__target, __link); +} +inline _LIBCPP_HIDE_FROM_ABI void create_symlink(const path& __target, const path& __link, error_code& __ec) noexcept { + return __create_symlink(__target, __link, &__ec); +} inline _LIBCPP_HIDE_FROM_ABI path current_path() { return __current_path(); } inline _LIBCPP_HIDE_FROM_ABI path current_path(error_code& __ec) { return __current_path(&__ec); } inline _LIBCPP_HIDE_FROM_ABI void current_path(const path& __p) { __current_path(__p); } -inline _LIBCPP_HIDE_FROM_ABI void current_path(const path& __p, error_code& __ec) noexcept { __current_path(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI void current_path(const path& __p, error_code& __ec) noexcept { + __current_path(__p, &__ec); +} inline _LIBCPP_HIDE_FROM_ABI bool equivalent(const path& __p1, const path& __p2) { return __equivalent(__p1, __p2); } -inline _LIBCPP_HIDE_FROM_ABI bool equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept { return __equivalent(__p1, __p2, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI bool equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept { + return __equivalent(__p1, __p2, &__ec); +} inline _LIBCPP_HIDE_FROM_ABI bool status_known(file_status __s) noexcept { return __s.type() != file_type::none; } -inline _LIBCPP_HIDE_FROM_ABI bool exists(file_status __s) noexcept { return status_known(__s) && __s.type() != file_type::not_found; } +inline _LIBCPP_HIDE_FROM_ABI bool exists(file_status __s) noexcept { + return status_known(__s) && __s.type() != file_type::not_found; +} inline _LIBCPP_HIDE_FROM_ABI bool exists(const path& __p) { return exists(__status(__p)); } -inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p, error_code& __ec) noexcept { +inline _LIBCPP_HIDE_FROM_ABI bool exists(const path& __p, error_code& __ec) noexcept { auto __s = __status(__p, &__ec); if (status_known(__s)) __ec.clear(); @@ -106,46 +158,81 @@ inline _LIBCPP_INLINE_VISIBILITY bool exists(const path& __p, error_code& __ec) } inline _LIBCPP_HIDE_FROM_ABI uintmax_t file_size(const path& __p) { return __file_size(__p); } -inline _LIBCPP_HIDE_FROM_ABI uintmax_t file_size(const path& __p, error_code& __ec) noexcept { return __file_size(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI uintmax_t file_size(const path& __p, error_code& __ec) noexcept { + return __file_size(__p, &__ec); +} inline _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count(const path& __p) { return __hard_link_count(__p); } -inline _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count(const path& __p, error_code& __ec) noexcept { return __hard_link_count(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI uintmax_t hard_link_count(const path& __p, error_code& __ec) noexcept { + return __hard_link_count(__p, &__ec); +} inline _LIBCPP_HIDE_FROM_ABI bool is_block_file(file_status __s) noexcept { return __s.type() == file_type::block; } inline _LIBCPP_HIDE_FROM_ABI bool is_block_file(const path& __p) { return is_block_file(__status(__p)); } -inline _LIBCPP_HIDE_FROM_ABI bool is_block_file(const path& __p, error_code& __ec) noexcept { return is_block_file(__status(__p, &__ec)); } -inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(file_status __s) noexcept { return __s.type() == file_type::character; } +inline _LIBCPP_HIDE_FROM_ABI bool is_block_file(const path& __p, error_code& __ec) noexcept { + return is_block_file(__status(__p, &__ec)); +} +inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(file_status __s) noexcept { + return __s.type() == file_type::character; +} inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(const path& __p) { return is_character_file(__status(__p)); } -inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(const path& __p, error_code& __ec) noexcept { return is_character_file(__status(__p, &__ec)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_character_file(const path& __p, error_code& __ec) noexcept { + return is_character_file(__status(__p, &__ec)); +} inline _LIBCPP_HIDE_FROM_ABI bool is_directory(file_status __s) noexcept { return __s.type() == file_type::directory; } inline _LIBCPP_HIDE_FROM_ABI bool is_directory(const path& __p) { return is_directory(__status(__p)); } -inline _LIBCPP_HIDE_FROM_ABI bool is_directory(const path& __p, error_code& __ec) noexcept { return is_directory(__status(__p, &__ec)); } -_LIBCPP_FUNC_VIS bool __fs_is_empty(const path& __p, error_code* __ec = nullptr); +inline _LIBCPP_HIDE_FROM_ABI bool is_directory(const path& __p, error_code& __ec) noexcept { + return is_directory(__status(__p, &__ec)); +} +_LIBCPP_EXPORTED_FROM_ABI bool __fs_is_empty(const path& __p, error_code* __ec = nullptr); inline _LIBCPP_HIDE_FROM_ABI bool is_empty(const path& __p) { return __fs_is_empty(__p); } inline _LIBCPP_HIDE_FROM_ABI bool is_empty(const path& __p, error_code& __ec) { return __fs_is_empty(__p, &__ec); } inline _LIBCPP_HIDE_FROM_ABI bool is_fifo(file_status __s) noexcept { return __s.type() == file_type::fifo; } inline _LIBCPP_HIDE_FROM_ABI bool is_fifo(const path& __p) { return is_fifo(__status(__p)); } -inline _LIBCPP_HIDE_FROM_ABI bool is_fifo(const path& __p, error_code& __ec) noexcept { return is_fifo(__status(__p, &__ec)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_fifo(const path& __p, error_code& __ec) noexcept { + return is_fifo(__status(__p, &__ec)); +} inline _LIBCPP_HIDE_FROM_ABI bool is_regular_file(file_status __s) noexcept { return __s.type() == file_type::regular; } inline _LIBCPP_HIDE_FROM_ABI bool is_regular_file(const path& __p) { return is_regular_file(__status(__p)); } -inline _LIBCPP_HIDE_FROM_ABI bool is_regular_file(const path& __p, error_code& __ec) noexcept { return is_regular_file(__status(__p, &__ec)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_regular_file(const path& __p, error_code& __ec) noexcept { + return is_regular_file(__status(__p, &__ec)); +} inline _LIBCPP_HIDE_FROM_ABI bool is_symlink(file_status __s) noexcept { return __s.type() == file_type::symlink; } inline _LIBCPP_HIDE_FROM_ABI bool is_symlink(const path& __p) { return is_symlink(__symlink_status(__p)); } -inline _LIBCPP_HIDE_FROM_ABI bool is_symlink(const path& __p, error_code& __ec) noexcept { return is_symlink(__symlink_status(__p, &__ec)); } -inline _LIBCPP_HIDE_FROM_ABI bool is_other(file_status __s) noexcept { return exists(__s) && !is_regular_file(__s) && !is_directory(__s) && !is_symlink(__s); } +inline _LIBCPP_HIDE_FROM_ABI bool is_symlink(const path& __p, error_code& __ec) noexcept { + return is_symlink(__symlink_status(__p, &__ec)); +} +inline _LIBCPP_HIDE_FROM_ABI bool is_other(file_status __s) noexcept { + return exists(__s) && !is_regular_file(__s) && !is_directory(__s) && !is_symlink(__s); +} inline _LIBCPP_HIDE_FROM_ABI bool is_other(const path& __p) { return is_other(__status(__p)); } -inline _LIBCPP_HIDE_FROM_ABI bool is_other(const path& __p, error_code& __ec) noexcept { return is_other(__status(__p, &__ec)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_other(const path& __p, error_code& __ec) noexcept { + return is_other(__status(__p, &__ec)); +} inline _LIBCPP_HIDE_FROM_ABI bool is_socket(file_status __s) noexcept { return __s.type() == file_type::socket; } inline _LIBCPP_HIDE_FROM_ABI bool is_socket(const path& __p) { return is_socket(__status(__p)); } -inline _LIBCPP_HIDE_FROM_ABI bool is_socket(const path& __p, error_code& __ec) noexcept { return is_socket(__status(__p, &__ec)); } +inline _LIBCPP_HIDE_FROM_ABI bool is_socket(const path& __p, error_code& __ec) noexcept { + return is_socket(__status(__p, &__ec)); +} inline _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time(const path& __p) { return __last_write_time(__p); } -inline _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time(const path& __p, error_code& __ec) noexcept { return __last_write_time(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI file_time_type last_write_time(const path& __p, error_code& __ec) noexcept { + return __last_write_time(__p, &__ec); +} inline _LIBCPP_HIDE_FROM_ABI void last_write_time(const path& __p, file_time_type __t) { __last_write_time(__p, __t); } -inline _LIBCPP_HIDE_FROM_ABI void last_write_time(const path& __p, file_time_type __t, error_code& __ec) noexcept { __last_write_time(__p, __t, &__ec); } -_LIBCPP_FUNC_VIS void __permissions(const path&, perms, perm_options, error_code* = nullptr); -inline _LIBCPP_HIDE_FROM_ABI void permissions(const path& __p, perms __prms, perm_options __opts = perm_options::replace) { __permissions(__p, __prms, __opts); } -inline _LIBCPP_HIDE_FROM_ABI void permissions(const path& __p, perms __prms, error_code& __ec) noexcept { __permissions(__p, __prms, perm_options::replace, &__ec); } -inline _LIBCPP_HIDE_FROM_ABI void permissions(const path& __p, perms __prms, perm_options __opts, error_code& __ec) { __permissions(__p, __prms, __opts, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI void last_write_time(const path& __p, file_time_type __t, error_code& __ec) noexcept { + __last_write_time(__p, __t, &__ec); +} +_LIBCPP_EXPORTED_FROM_ABI void __permissions(const path&, perms, perm_options, error_code* = nullptr); +inline _LIBCPP_HIDE_FROM_ABI void +permissions(const path& __p, perms __prms, perm_options __opts = perm_options::replace) { + __permissions(__p, __prms, __opts); +} +inline _LIBCPP_HIDE_FROM_ABI void permissions(const path& __p, perms __prms, error_code& __ec) noexcept { + __permissions(__p, __prms, perm_options::replace, &__ec); +} +inline _LIBCPP_HIDE_FROM_ABI void permissions(const path& __p, perms __prms, perm_options __opts, error_code& __ec) { + __permissions(__p, __prms, __opts, &__ec); +} -inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p, const path& __base, error_code& __ec) { +inline _LIBCPP_HIDE_FROM_ABI path proximate(const path& __p, const path& __base, error_code& __ec) { path __tmp = __weakly_canonical(__p, &__ec); if (__ec) return {}; @@ -155,12 +242,16 @@ inline _LIBCPP_INLINE_VISIBILITY path proximate(const path& __p, const path& __b return __tmp.lexically_proximate(__tmp_base); } -inline _LIBCPP_HIDE_FROM_ABI path proximate(const path& __p, error_code& __ec) { return proximate(__p, current_path(), __ec); } -inline _LIBCPP_HIDE_FROM_ABI path proximate(const path& __p, const path& __base = current_path()) { return __weakly_canonical(__p).lexically_proximate(__weakly_canonical(__base)); } +inline _LIBCPP_HIDE_FROM_ABI path proximate(const path& __p, error_code& __ec) { + return proximate(__p, current_path(), __ec); +} +inline _LIBCPP_HIDE_FROM_ABI path proximate(const path& __p, const path& __base = current_path()) { + return __weakly_canonical(__p).lexically_proximate(__weakly_canonical(__base)); +} inline _LIBCPP_HIDE_FROM_ABI path read_symlink(const path& __p) { return __read_symlink(__p); } inline _LIBCPP_HIDE_FROM_ABI path read_symlink(const path& __p, error_code& __ec) { return __read_symlink(__p, &__ec); } -inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p, const path& __base, error_code& __ec) { +inline _LIBCPP_HIDE_FROM_ABI path relative(const path& __p, const path& __base, error_code& __ec) { path __tmp = __weakly_canonical(__p, &__ec); if (__ec) return path(); @@ -170,32 +261,50 @@ inline _LIBCPP_INLINE_VISIBILITY path relative(const path& __p, const path& __ba return __tmp.lexically_relative(__tmpbase); } -inline _LIBCPP_HIDE_FROM_ABI path relative(const path& __p, error_code& __ec) { return relative(__p, current_path(), __ec); } -inline _LIBCPP_HIDE_FROM_ABI path relative(const path& __p, const path& __base = current_path()) { return __weakly_canonical(__p).lexically_relative(__weakly_canonical(__base)); } +inline _LIBCPP_HIDE_FROM_ABI path relative(const path& __p, error_code& __ec) { + return relative(__p, current_path(), __ec); +} +inline _LIBCPP_HIDE_FROM_ABI path relative(const path& __p, const path& __base = current_path()) { + return __weakly_canonical(__p).lexically_relative(__weakly_canonical(__base)); +} inline _LIBCPP_HIDE_FROM_ABI uintmax_t remove_all(const path& __p) { return __remove_all(__p); } -inline _LIBCPP_HIDE_FROM_ABI uintmax_t remove_all(const path& __p, error_code& __ec) { return __remove_all(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI uintmax_t remove_all(const path& __p, error_code& __ec) { + return __remove_all(__p, &__ec); +} inline _LIBCPP_HIDE_FROM_ABI bool remove(const path& __p) { return __remove(__p); } inline _LIBCPP_HIDE_FROM_ABI bool remove(const path& __p, error_code& __ec) noexcept { return __remove(__p, &__ec); } inline _LIBCPP_HIDE_FROM_ABI void rename(const path& __from, const path& __to) { return __rename(__from, __to); } -inline _LIBCPP_HIDE_FROM_ABI void rename(const path& __from, const path& __to, error_code& __ec) noexcept { return __rename(__from, __to, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI void rename(const path& __from, const path& __to, error_code& __ec) noexcept { + return __rename(__from, __to, &__ec); +} inline _LIBCPP_HIDE_FROM_ABI void resize_file(const path& __p, uintmax_t __ns) { return __resize_file(__p, __ns); } -inline _LIBCPP_HIDE_FROM_ABI void resize_file(const path& __p, uintmax_t __ns, error_code& __ec) noexcept { return __resize_file(__p, __ns, &__ec); } -_LIBCPP_FUNC_VIS space_info __space(const path&, error_code* __ec = nullptr); +inline _LIBCPP_HIDE_FROM_ABI void resize_file(const path& __p, uintmax_t __ns, error_code& __ec) noexcept { + return __resize_file(__p, __ns, &__ec); +} +_LIBCPP_EXPORTED_FROM_ABI space_info __space(const path&, error_code* __ec = nullptr); inline _LIBCPP_HIDE_FROM_ABI space_info space(const path& __p) { return __space(__p); } -inline _LIBCPP_HIDE_FROM_ABI space_info space(const path& __p, error_code& __ec) noexcept { return __space(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI space_info space(const path& __p, error_code& __ec) noexcept { + return __space(__p, &__ec); +} inline _LIBCPP_HIDE_FROM_ABI file_status status(const path& __p) { return __status(__p); } -inline _LIBCPP_HIDE_FROM_ABI file_status status(const path& __p, error_code& __ec) noexcept { return __status(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI file_status status(const path& __p, error_code& __ec) noexcept { + return __status(__p, &__ec); +} inline _LIBCPP_HIDE_FROM_ABI file_status symlink_status(const path& __p) { return __symlink_status(__p); } -inline _LIBCPP_HIDE_FROM_ABI file_status symlink_status(const path& __p, error_code& __ec) noexcept { return __symlink_status(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI file_status symlink_status(const path& __p, error_code& __ec) noexcept { + return __symlink_status(__p, &__ec); +} inline _LIBCPP_HIDE_FROM_ABI path temp_directory_path() { return __temp_directory_path(); } inline _LIBCPP_HIDE_FROM_ABI path temp_directory_path(error_code& __ec) { return __temp_directory_path(&__ec); } inline _LIBCPP_HIDE_FROM_ABI path weakly_canonical(path const& __p) { return __weakly_canonical(__p); } -inline _LIBCPP_HIDE_FROM_ABI path weakly_canonical(path const& __p, error_code& __ec) { return __weakly_canonical(__p, &__ec); } +inline _LIBCPP_HIDE_FROM_ABI path weakly_canonical(path const& __p, error_code& __ec) { + return __weakly_canonical(__p, &__ec); +} -_LIBCPP_AVAILABILITY_FILESYSTEM_POP +_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP _LIBCPP_END_NAMESPACE_FILESYSTEM -#endif // _LIBCPP_CXX03_LANG +#endif // _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM) #endif // _LIBCPP___FILESYSTEM_OPERATIONS_H diff --git a/third_party/libcxx/__filesystem/path.h b/third_party/libcxx/__filesystem/path.h index bf36ad9b5..ff468d517 100644 --- a/third_party/libcxx/__filesystem/path.h +++ b/third_party/libcxx/__filesystem/path.h @@ -12,10 +12,9 @@ #include <__algorithm/replace.h> #include <__algorithm/replace_copy.h> -#include <__availability> #include <__config> #include <__functional/unary_function.h> -#include <__fwd/hash.h> +#include <__fwd/functional.h> #include <__iterator/back_insert_iterator.h> #include <__iterator/iterator_traits.h> #include <__type_traits/decay.h> @@ -27,19 +26,22 @@ #include #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) -# include // for quoted -# include +# include // for quoted +# include #endif #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif -#ifndef _LIBCPP_CXX03_LANG +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +#if _LIBCPP_STD_VER >= 17 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM -_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH +_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH template struct __can_convert_char { @@ -50,47 +52,45 @@ struct __can_convert_char : public __can_convert_char<_Tp> {}; template <> struct __can_convert_char { static const bool value = true; - using __char_type = char; + using __char_type = char; }; template <> struct __can_convert_char { static const bool value = true; - using __char_type = wchar_t; + using __char_type = wchar_t; }; -#ifndef _LIBCPP_HAS_NO_CHAR8_T +# ifndef _LIBCPP_HAS_NO_CHAR8_T template <> struct __can_convert_char { static const bool value = true; - using __char_type = char8_t; + using __char_type = char8_t; }; -#endif +# endif template <> struct __can_convert_char { static const bool value = true; - using __char_type = char16_t; + using __char_type = char16_t; }; template <> struct __can_convert_char { static const bool value = true; - using __char_type = char32_t; + using __char_type = char32_t; }; -template -_LIBCPP_HIDE_FROM_ABI -typename enable_if<__can_convert_char<_ECharT>::value, bool>::type -__is_separator(_ECharT __e) { -#if defined(_LIBCPP_WIN32API) +template ::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI bool __is_separator(_ECharT __e) { +# if defined(_LIBCPP_WIN32API) return __e == _ECharT('/') || __e == _ECharT('\\'); -#else +# else return __e == _ECharT('/'); -#endif +# endif } -#ifndef _LIBCPP_HAS_NO_CHAR8_T +# ifndef _LIBCPP_HAS_NO_CHAR8_T typedef u8string __u8_string; -#else +# else typedef string __u8_string; -#endif +# endif struct _NullSentinel {}; @@ -101,104 +101,75 @@ template struct __is_pathable_string : public false_type {}; template -struct __is_pathable_string< - basic_string<_ECharT, _Traits, _Alloc>, - _Void::__char_type> > +struct __is_pathable_string< basic_string<_ECharT, _Traits, _Alloc>, + _Void::__char_type> > : public __can_convert_char<_ECharT> { using _Str = basic_string<_ECharT, _Traits, _Alloc>; - using _Base = __can_convert_char<_ECharT>; - _LIBCPP_HIDE_FROM_ABI - static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); } + _LIBCPP_HIDE_FROM_ABI static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); } - _LIBCPP_HIDE_FROM_ABI - static _ECharT const* __range_end(_Str const& __s) { - return __s.data() + __s.length(); - } + _LIBCPP_HIDE_FROM_ABI static _ECharT const* __range_end(_Str const& __s) { return __s.data() + __s.length(); } - _LIBCPP_HIDE_FROM_ABI - static _ECharT __first_or_null(_Str const& __s) { - return __s.empty() ? _ECharT{} : __s[0]; - } + _LIBCPP_HIDE_FROM_ABI static _ECharT __first_or_null(_Str const& __s) { return __s.empty() ? _ECharT{} : __s[0]; } }; template -struct __is_pathable_string< - basic_string_view<_ECharT, _Traits>, - _Void::__char_type> > +struct __is_pathable_string< basic_string_view<_ECharT, _Traits>, + _Void::__char_type> > : public __can_convert_char<_ECharT> { using _Str = basic_string_view<_ECharT, _Traits>; - using _Base = __can_convert_char<_ECharT>; - _LIBCPP_HIDE_FROM_ABI - static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); } + _LIBCPP_HIDE_FROM_ABI static _ECharT const* __range_begin(_Str const& __s) { return __s.data(); } - _LIBCPP_HIDE_FROM_ABI - static _ECharT const* __range_end(_Str const& __s) { - return __s.data() + __s.length(); - } + _LIBCPP_HIDE_FROM_ABI static _ECharT const* __range_end(_Str const& __s) { return __s.data() + __s.length(); } - _LIBCPP_HIDE_FROM_ABI - static _ECharT __first_or_null(_Str const& __s) { - return __s.empty() ? _ECharT{} : __s[0]; - } + _LIBCPP_HIDE_FROM_ABI static _ECharT __first_or_null(_Str const& __s) { return __s.empty() ? _ECharT{} : __s[0]; } }; -template , - class _UnqualPtrType = - __remove_const_t<__remove_pointer_t<_DS> >, - bool _IsCharPtr = is_pointer<_DS>::value&& - __can_convert_char<_UnqualPtrType>::value> +template , + class _UnqualPtrType = __remove_const_t<__remove_pointer_t<_DS> >, + bool _IsCharPtr = is_pointer<_DS>::value && __can_convert_char<_UnqualPtrType>::value> struct __is_pathable_char_array : false_type {}; template -struct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true> - : __can_convert_char<__remove_const_t<_ECharT> > { - using _Base = __can_convert_char<__remove_const_t<_ECharT> >; +struct __is_pathable_char_array<_Source, _ECharT*, _UPtr, true> : __can_convert_char<__remove_const_t<_ECharT> > { + _LIBCPP_HIDE_FROM_ABI static _ECharT const* __range_begin(const _ECharT* __b) { return __b; } - _LIBCPP_HIDE_FROM_ABI - static _ECharT const* __range_begin(const _ECharT* __b) { return __b; } - - _LIBCPP_HIDE_FROM_ABI - static _ECharT const* __range_end(const _ECharT* __b) { - using _Iter = const _ECharT*; + _LIBCPP_HIDE_FROM_ABI static _ECharT const* __range_end(const _ECharT* __b) { + using _Iter = const _ECharT*; const _ECharT __sentinel = _ECharT{}; - _Iter __e = __b; + _Iter __e = __b; for (; *__e != __sentinel; ++__e) ; return __e; } - _LIBCPP_HIDE_FROM_ABI - static _ECharT __first_or_null(const _ECharT* __b) { return *__b; } + _LIBCPP_HIDE_FROM_ABI static _ECharT __first_or_null(const _ECharT* __b) { return *__b; } }; -template ::value, - class = void> +template ::value, class = void> struct __is_pathable_iter : false_type {}; template struct __is_pathable_iter< - _Iter, true, - _Void::value_type>::__char_type> > + _Iter, + true, + _Void::value_type>::__char_type> > : __can_convert_char::value_type> { using _ECharT = typename iterator_traits<_Iter>::value_type; - using _Base = __can_convert_char<_ECharT>; - _LIBCPP_HIDE_FROM_ABI - static _Iter __range_begin(_Iter __b) { return __b; } + _LIBCPP_HIDE_FROM_ABI static _Iter __range_begin(_Iter __b) { return __b; } - _LIBCPP_HIDE_FROM_ABI - static _NullSentinel __range_end(_Iter) { return _NullSentinel{}; } + _LIBCPP_HIDE_FROM_ABI static _NullSentinel __range_end(_Iter) { return _NullSentinel{}; } - _LIBCPP_HIDE_FROM_ABI - static _ECharT __first_or_null(_Iter __b) { return *__b; } + _LIBCPP_HIDE_FROM_ABI static _ECharT __first_or_null(_Iter __b) { return *__b; } }; -template ::value, +template ::value, bool _IsCharIterT = __is_pathable_char_array<_Tp>::value, - bool _IsIterT = !_IsCharIterT && __is_pathable_iter<_Tp>::value> + bool _IsIterT = !_IsCharIterT && __is_pathable_iter<_Tp>::value> struct __is_pathable : false_type { static_assert(!_IsStringT && !_IsCharIterT && !_IsIterT, "Must all be false"); }; @@ -207,74 +178,64 @@ template struct __is_pathable<_Tp, true, false, false> : __is_pathable_string<_Tp> {}; template -struct __is_pathable<_Tp, false, true, false> : __is_pathable_char_array<_Tp> { -}; +struct __is_pathable<_Tp, false, true, false> : __is_pathable_char_array<_Tp> {}; template struct __is_pathable<_Tp, false, false, true> : __is_pathable_iter<_Tp> {}; -#if defined(_LIBCPP_WIN32API) +# if defined(_LIBCPP_WIN32API) typedef wstring __path_string; typedef wchar_t __path_value; -#else +# else typedef string __path_string; typedef char __path_value; -#endif +# endif -#if defined(_LIBCPP_WIN32API) -_LIBCPP_FUNC_VIS -size_t __wide_to_char(const wstring&, char*, size_t); -_LIBCPP_FUNC_VIS -size_t __char_to_wide(const string&, wchar_t*, size_t); -#endif +# if defined(_LIBCPP_WIN32API) +_LIBCPP_EXPORTED_FROM_ABI size_t __wide_to_char(const wstring&, char*, size_t); +_LIBCPP_EXPORTED_FROM_ABI size_t __char_to_wide(const string&, wchar_t*, size_t); +# endif template struct _PathCVT; -#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) +# if !defined(_LIBCPP_HAS_NO_LOCALIZATION) template struct _PathCVT { - static_assert(__can_convert_char<_ECharT>::value, - "Char type not convertible"); + static_assert(__can_convert_char<_ECharT>::value, "Char type not convertible"); typedef __narrow_to_utf8 _Narrower; -#if defined(_LIBCPP_WIN32API) +# if defined(_LIBCPP_WIN32API) typedef __widen_from_utf8 _Widener; -#endif +# endif - _LIBCPP_HIDE_FROM_ABI - static void __append_range(__path_string& __dest, _ECharT const* __b, - _ECharT const* __e) { -#if defined(_LIBCPP_WIN32API) + _LIBCPP_HIDE_FROM_ABI static void __append_range(__path_string& __dest, _ECharT const* __b, _ECharT const* __e) { +# if defined(_LIBCPP_WIN32API) string __utf8; _Narrower()(back_inserter(__utf8), __b, __e); _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size()); -#else +# else _Narrower()(back_inserter(__dest), __b, __e); -#endif +# endif } template - _LIBCPP_HIDE_FROM_ABI - static void __append_range(__path_string& __dest, _Iter __b, _Iter __e) { + _LIBCPP_HIDE_FROM_ABI static void __append_range(__path_string& __dest, _Iter __b, _Iter __e) { static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload"); if (__b == __e) return; basic_string<_ECharT> __tmp(__b, __e); -#if defined(_LIBCPP_WIN32API) +# if defined(_LIBCPP_WIN32API) string __utf8; - _Narrower()(back_inserter(__utf8), __tmp.data(), - __tmp.data() + __tmp.length()); + _Narrower()(back_inserter(__utf8), __tmp.data(), __tmp.data() + __tmp.length()); _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size()); -#else - _Narrower()(back_inserter(__dest), __tmp.data(), - __tmp.data() + __tmp.length()); -#endif +# else + _Narrower()(back_inserter(__dest), __tmp.data(), __tmp.data() + __tmp.length()); +# endif } template - _LIBCPP_HIDE_FROM_ABI - static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) { + _LIBCPP_HIDE_FROM_ABI static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) { static_assert(!is_same<_Iter, _ECharT*>::value, "Call const overload"); const _ECharT __sentinel = _ECharT{}; if (*__b == __sentinel) @@ -282,94 +243,74 @@ struct _PathCVT { basic_string<_ECharT> __tmp; for (; *__b != __sentinel; ++__b) __tmp.push_back(*__b); -#if defined(_LIBCPP_WIN32API) +# if defined(_LIBCPP_WIN32API) string __utf8; - _Narrower()(back_inserter(__utf8), __tmp.data(), - __tmp.data() + __tmp.length()); + _Narrower()(back_inserter(__utf8), __tmp.data(), __tmp.data() + __tmp.length()); _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size()); -#else - _Narrower()(back_inserter(__dest), __tmp.data(), - __tmp.data() + __tmp.length()); -#endif +# else + _Narrower()(back_inserter(__dest), __tmp.data(), __tmp.data() + __tmp.length()); +# endif } template - _LIBCPP_HIDE_FROM_ABI - static void __append_source(__path_string& __dest, _Source const& __s) { + _LIBCPP_HIDE_FROM_ABI static void __append_source(__path_string& __dest, _Source const& __s) { using _Traits = __is_pathable<_Source>; - __append_range(__dest, _Traits::__range_begin(__s), - _Traits::__range_end(__s)); + __append_range(__dest, _Traits::__range_begin(__s), _Traits::__range_end(__s)); } }; -#endif // !_LIBCPP_HAS_NO_LOCALIZATION +# endif // !_LIBCPP_HAS_NO_LOCALIZATION template <> struct _PathCVT<__path_value> { - - template - _LIBCPP_HIDE_FROM_ABI - static typename enable_if<__has_exactly_input_iterator_category<_Iter>::value>::type - __append_range(__path_string& __dest, _Iter __b, _Iter __e) { + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI static void __append_range(__path_string& __dest, _Iter __b, _Iter __e) { for (; __b != __e; ++__b) __dest.push_back(*__b); } - template - _LIBCPP_HIDE_FROM_ABI - static typename enable_if<__has_forward_iterator_category<_Iter>::value>::type - __append_range(__path_string& __dest, _Iter __b, _Iter __e) { + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI static void __append_range(__path_string& __dest, _Iter __b, _Iter __e) { __dest.append(__b, __e); } template - _LIBCPP_HIDE_FROM_ABI - static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) { + _LIBCPP_HIDE_FROM_ABI static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) { const char __sentinel = char{}; for (; *__b != __sentinel; ++__b) __dest.push_back(*__b); } template - _LIBCPP_HIDE_FROM_ABI - static void __append_source(__path_string& __dest, _Source const& __s) { + _LIBCPP_HIDE_FROM_ABI static void __append_source(__path_string& __dest, _Source const& __s) { using _Traits = __is_pathable<_Source>; - __append_range(__dest, _Traits::__range_begin(__s), - _Traits::__range_end(__s)); + __append_range(__dest, _Traits::__range_begin(__s), _Traits::__range_end(__s)); } }; -#if defined(_LIBCPP_WIN32API) +# if defined(_LIBCPP_WIN32API) template <> struct _PathCVT { - - _LIBCPP_HIDE_FROM_ABI - static void - __append_string(__path_string& __dest, const basic_string &__str) { - size_t __size = __char_to_wide(__str, nullptr, 0); - size_t __pos = __dest.size(); - __dest.resize(__pos + __size); - __char_to_wide(__str, const_cast<__path_value*>(__dest.data()) + __pos, __size); + _LIBCPP_HIDE_FROM_ABI static void __append_string(__path_string& __dest, const basic_string& __str) { + size_t __size = __char_to_wide(__str, nullptr, 0); + size_t __pos = __dest.size(); + __dest.resize(__pos + __size); + __char_to_wide(__str, const_cast<__path_value*>(__dest.data()) + __pos, __size); } - template - _LIBCPP_HIDE_FROM_ABI - static typename enable_if<__has_exactly_input_iterator_category<_Iter>::value>::type - __append_range(__path_string& __dest, _Iter __b, _Iter __e) { + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI static void __append_range(__path_string& __dest, _Iter __b, _Iter __e) { + basic_string __tmp(__b, __e); + __append_string(__dest, __tmp); + } + + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI static void __append_range(__path_string& __dest, _Iter __b, _Iter __e) { basic_string __tmp(__b, __e); __append_string(__dest, __tmp); } template - _LIBCPP_HIDE_FROM_ABI - static typename enable_if<__has_forward_iterator_category<_Iter>::value>::type - __append_range(__path_string& __dest, _Iter __b, _Iter __e) { - basic_string __tmp(__b, __e); - __append_string(__dest, __tmp); - } - - template - _LIBCPP_HIDE_FROM_ABI - static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) { + _LIBCPP_HIDE_FROM_ABI static void __append_range(__path_string& __dest, _Iter __b, _NullSentinel) { const char __sentinel = char{}; basic_string __tmp; for (; *__b != __sentinel; ++__b) @@ -378,11 +319,9 @@ struct _PathCVT { } template - _LIBCPP_HIDE_FROM_ABI - static void __append_source(__path_string& __dest, _Source const& __s) { + _LIBCPP_HIDE_FROM_ABI static void __append_source(__path_string& __dest, _Source const& __s) { using _Traits = __is_pathable<_Source>; - __append_range(__dest, _Traits::__range_begin(__s), - _Traits::__range_end(__s)); + __append_range(__dest, _Traits::__range_begin(__s), _Traits::__range_end(__s)); } }; @@ -392,8 +331,7 @@ struct _PathExport { typedef __widen_from_utf8 _Widener; template - _LIBCPP_HIDE_FROM_ABI - static void __append(_Str& __dest, const __path_string& __src) { + _LIBCPP_HIDE_FROM_ABI static void __append(_Str& __dest, const __path_string& __src) { string __utf8; _Narrower()(back_inserter(__utf8), __src.data(), __src.data() + __src.size()); _Widener()(back_inserter(__dest), __utf8.data(), __utf8.data() + __utf8.size()); @@ -403,10 +341,9 @@ struct _PathExport { template <> struct _PathExport { template - _LIBCPP_HIDE_FROM_ABI - static void __append(_Str& __dest, const __path_string& __src) { + _LIBCPP_HIDE_FROM_ABI static void __append(_Str& __dest, const __path_string& __src) { size_t __size = __wide_to_char(__src, nullptr, 0); - size_t __pos = __dest.size(); + size_t __pos = __dest.size(); __dest.resize(__size); __wide_to_char(__src, const_cast(__dest.data()) + __pos, __size); } @@ -415,8 +352,7 @@ struct _PathExport { template <> struct _PathExport { template - _LIBCPP_HIDE_FROM_ABI - static void __append(_Str& __dest, const __path_string& __src) { + _LIBCPP_HIDE_FROM_ABI static void __append(_Str& __dest, const __path_string& __src) { __dest.append(__src.begin(), __src.end()); } }; @@ -424,30 +360,27 @@ struct _PathExport { template <> struct _PathExport { template - _LIBCPP_HIDE_FROM_ABI - static void __append(_Str& __dest, const __path_string& __src) { + _LIBCPP_HIDE_FROM_ABI static void __append(_Str& __dest, const __path_string& __src) { __dest.append(__src.begin(), __src.end()); } }; -#ifndef _LIBCPP_HAS_NO_CHAR8_T +# ifndef _LIBCPP_HAS_NO_CHAR8_T template <> struct _PathExport { typedef __narrow_to_utf8 _Narrower; template - _LIBCPP_HIDE_FROM_ABI - static void __append(_Str& __dest, const __path_string& __src) { + _LIBCPP_HIDE_FROM_ABI static void __append(_Str& __dest, const __path_string& __src) { _Narrower()(back_inserter(__dest), __src.data(), __src.data() + __src.size()); } }; -#endif /* !_LIBCPP_HAS_NO_CHAR8_T */ -#endif /* _LIBCPP_WIN32API */ +# endif /* !_LIBCPP_HAS_NO_CHAR8_T */ +# endif /* _LIBCPP_WIN32API */ -class _LIBCPP_TYPE_VIS path { +class _LIBCPP_EXPORTED_FROM_ABI path { template - using _EnableIfPathable = - typename enable_if<__is_pathable<_SourceOrIter>::value, _Tp>::type; + using _EnableIfPathable = __enable_if_t<__is_pathable<_SourceOrIter>::value, _Tp>; template using _SourceChar = typename __is_pathable<_Tp>::__char_type; @@ -456,101 +389,84 @@ class _LIBCPP_TYPE_VIS path { using _SourceCVT = _PathCVT<_SourceChar<_Tp> >; public: -#if defined(_LIBCPP_WIN32API) +# if defined(_LIBCPP_WIN32API) typedef wchar_t value_type; static constexpr value_type preferred_separator = L'\\'; -#else +# else typedef char value_type; static constexpr value_type preferred_separator = '/'; -#endif +# endif typedef basic_string string_type; typedef basic_string_view __string_view; - enum _LIBCPP_ENUM_VIS format : unsigned char { - auto_format, - native_format, - generic_format - }; + enum format : unsigned char { auto_format, native_format, generic_format }; // constructors and destructor _LIBCPP_HIDE_FROM_ABI path() noexcept {} _LIBCPP_HIDE_FROM_ABI path(const path& __p) : __pn_(__p.__pn_) {} - _LIBCPP_HIDE_FROM_ABI path(path&& __p) noexcept - : __pn_(_VSTD::move(__p.__pn_)) {} + _LIBCPP_HIDE_FROM_ABI path(path&& __p) noexcept : __pn_(std::move(__p.__pn_)) {} - _LIBCPP_HIDE_FROM_ABI - path(string_type&& __s, format = format::auto_format) noexcept - : __pn_(_VSTD::move(__s)) {} + _LIBCPP_HIDE_FROM_ABI path(string_type&& __s, format = format::auto_format) noexcept : __pn_(std::move(__s)) {} template > - _LIBCPP_HIDE_FROM_ABI - path(const _Source& __src, format = format::auto_format) { + _LIBCPP_HIDE_FROM_ABI path(const _Source& __src, format = format::auto_format) { _SourceCVT<_Source>::__append_source(__pn_, __src); } template - _LIBCPP_HIDE_FROM_ABI - path(_InputIt __first, _InputIt __last, format = format::auto_format) { + _LIBCPP_HIDE_FROM_ABI path(_InputIt __first, _InputIt __last, format = format::auto_format) { typedef typename iterator_traits<_InputIt>::value_type _ItVal; _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); } -/* -#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) - // TODO Implement locale conversions. - template > - path(const _Source& __src, const locale& __loc, format = format::auto_format); - template - path(_InputIt __first, _InputIt _last, const locale& __loc, - format = format::auto_format); -#endif -*/ + /* + #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) + // TODO Implement locale conversions. + template > + path(const _Source& __src, const locale& __loc, format = format::auto_format); + template + path(_InputIt __first, _InputIt _last, const locale& __loc, + format = format::auto_format); + #endif + */ - _LIBCPP_HIDE_FROM_ABI - ~path() = default; + _LIBCPP_HIDE_FROM_ABI ~path() = default; // assignments - _LIBCPP_HIDE_FROM_ABI - path& operator=(const path& __p) { + _LIBCPP_HIDE_FROM_ABI path& operator=(const path& __p) { __pn_ = __p.__pn_; return *this; } - _LIBCPP_HIDE_FROM_ABI - path& operator=(path&& __p) noexcept { - __pn_ = _VSTD::move(__p.__pn_); + _LIBCPP_HIDE_FROM_ABI path& operator=(path&& __p) noexcept { + __pn_ = std::move(__p.__pn_); return *this; } - _LIBCPP_HIDE_FROM_ABI - path& operator=(string_type&& __s) noexcept { - __pn_ = _VSTD::move(__s); + _LIBCPP_HIDE_FROM_ABI path& operator=(string_type&& __s) noexcept { + __pn_ = std::move(__s); return *this; } - _LIBCPP_HIDE_FROM_ABI - path& assign(string_type&& __s) noexcept { - __pn_ = _VSTD::move(__s); + _LIBCPP_HIDE_FROM_ABI path& assign(string_type&& __s) noexcept { + __pn_ = std::move(__s); return *this; } template - _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> - operator=(const _Source& __src) { + _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> operator=(const _Source& __src) { return this->assign(__src); } template - _LIBCPP_HIDE_FROM_ABI - _EnableIfPathable<_Source> assign(const _Source& __src) { + _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> assign(const _Source& __src) { __pn_.clear(); _SourceCVT<_Source>::__append_source(__pn_, __src); return *this; } template - _LIBCPP_HIDE_FROM_ABI - path& assign(_InputIt __first, _InputIt __last) { + _LIBCPP_HIDE_FROM_ABI path& assign(_InputIt __first, _InputIt __last) { typedef typename iterator_traits<_InputIt>::value_type _ItVal; __pn_.clear(); _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); @@ -559,19 +475,17 @@ public: public: // appends -#if defined(_LIBCPP_WIN32API) - _LIBCPP_HIDE_FROM_ABI - path& operator/=(const path& __p) { - auto __p_root_name = __p.__root_name(); +# if defined(_LIBCPP_WIN32API) + _LIBCPP_HIDE_FROM_ABI path& operator/=(const path& __p) { + auto __p_root_name = __p.__root_name(); auto __p_root_name_size = __p_root_name.size(); - if (__p.is_absolute() || - (!__p_root_name.empty() && __p_root_name != __string_view(root_name().__pn_))) { + if (__p.is_absolute() || (!__p_root_name.empty() && __p_root_name != __string_view(root_name().__pn_))) { __pn_ = __p.__pn_; return *this; } if (__p.has_root_directory()) { path __root_name_str = root_name(); - __pn_ = __root_name_str.native(); + __pn_ = __root_name_str.native(); __pn_ += __string_view(__p.__pn_).substr(__p_root_name_size); return *this; } @@ -581,25 +495,21 @@ public: return *this; } template - _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source> - operator/=(const _Source& __src) { + _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> operator/=(const _Source& __src) { return operator/=(path(__src)); } template - _LIBCPP_HIDE_FROM_ABI - _EnableIfPathable<_Source> append(const _Source& __src) { + _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> append(const _Source& __src) { return operator/=(path(__src)); } template - _LIBCPP_HIDE_FROM_ABI - path& append(_InputIt __first, _InputIt __last) { + _LIBCPP_HIDE_FROM_ABI path& append(_InputIt __first, _InputIt __last) { return operator/=(path(__first, __last)); } -#else - _LIBCPP_HIDE_FROM_ABI - path& operator/=(const path& __p) { +# else + _LIBCPP_HIDE_FROM_ABI path& operator/=(const path& __p) { if (__p.is_absolute()) { __pn_ = __p.__pn_; return *this; @@ -614,17 +524,15 @@ public: // is known at compile time to be "/' since the user almost certainly intended // to append a separator instead of overwriting the path with "/" template - _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> - operator/=(const _Source& __src) { + _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> operator/=(const _Source& __src) { return this->append(__src); } template - _LIBCPP_HIDE_FROM_ABI - _EnableIfPathable<_Source> append(const _Source& __src) { - using _Traits = __is_pathable<_Source>; - using _CVT = _PathCVT<_SourceChar<_Source> >; - bool __source_is_absolute = _VSTD_FS::__is_separator(_Traits::__first_or_null(__src)); + _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> append(const _Source& __src) { + using _Traits = __is_pathable<_Source>; + using _CVT = _PathCVT<_SourceChar<_Source> >; + bool __source_is_absolute = filesystem::__is_separator(_Traits::__first_or_null(__src)); if (__source_is_absolute) __pn_.clear(); else if (has_filename()) @@ -634,103 +542,87 @@ public: } template - _LIBCPP_HIDE_FROM_ABI - path& append(_InputIt __first, _InputIt __last) { + _LIBCPP_HIDE_FROM_ABI path& append(_InputIt __first, _InputIt __last) { typedef typename iterator_traits<_InputIt>::value_type _ItVal; static_assert(__can_convert_char<_ItVal>::value, "Must convertible"); using _CVT = _PathCVT<_ItVal>; - if (__first != __last && _VSTD_FS::__is_separator(*__first)) + if (__first != __last && filesystem::__is_separator(*__first)) __pn_.clear(); else if (has_filename()) __pn_ += preferred_separator; _CVT::__append_range(__pn_, __first, __last); return *this; } -#endif +# endif // concatenation - _LIBCPP_HIDE_FROM_ABI - path& operator+=(const path& __x) { + _LIBCPP_HIDE_FROM_ABI path& operator+=(const path& __x) { __pn_ += __x.__pn_; return *this; } - _LIBCPP_HIDE_FROM_ABI - path& operator+=(const string_type& __x) { + _LIBCPP_HIDE_FROM_ABI path& operator+=(const string_type& __x) { __pn_ += __x; return *this; } - _LIBCPP_HIDE_FROM_ABI - path& operator+=(__string_view __x) { + _LIBCPP_HIDE_FROM_ABI path& operator+=(__string_view __x) { __pn_ += __x; return *this; } - _LIBCPP_HIDE_FROM_ABI - path& operator+=(const value_type* __x) { + _LIBCPP_HIDE_FROM_ABI path& operator+=(const value_type* __x) { __pn_ += __x; return *this; } - _LIBCPP_HIDE_FROM_ABI - path& operator+=(value_type __x) { + _LIBCPP_HIDE_FROM_ABI path& operator+=(value_type __x) { __pn_ += __x; return *this; } - template - _LIBCPP_HIDE_FROM_ABI - typename enable_if<__can_convert_char<_ECharT>::value, path&>::type - operator+=(_ECharT __x) { - _PathCVT<_ECharT>::__append_source(__pn_, - basic_string_view<_ECharT>(&__x, 1)); + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI path& operator+=(_ECharT __x) { + _PathCVT<_ECharT>::__append_source(__pn_, basic_string_view<_ECharT>(&__x, 1)); return *this; } template - _LIBCPP_HIDE_FROM_ABI - _EnableIfPathable<_Source> operator+=(const _Source& __x) { + _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> operator+=(const _Source& __x) { return this->concat(__x); } template - _LIBCPP_HIDE_FROM_ABI - _EnableIfPathable<_Source> concat(const _Source& __x) { + _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> concat(const _Source& __x) { _SourceCVT<_Source>::__append_source(__pn_, __x); return *this; } template - _LIBCPP_HIDE_FROM_ABI - path& concat(_InputIt __first, _InputIt __last) { + _LIBCPP_HIDE_FROM_ABI path& concat(_InputIt __first, _InputIt __last) { typedef typename iterator_traits<_InputIt>::value_type _ItVal; _PathCVT<_ItVal>::__append_range(__pn_, __first, __last); return *this; } // modifiers - _LIBCPP_HIDE_FROM_ABI - void clear() noexcept { __pn_.clear(); } + _LIBCPP_HIDE_FROM_ABI void clear() noexcept { __pn_.clear(); } - _LIBCPP_HIDE_FROM_ABI - path& make_preferred() { -#if defined(_LIBCPP_WIN32API) - _VSTD::replace(__pn_.begin(), __pn_.end(), L'/', L'\\'); -#endif + _LIBCPP_HIDE_FROM_ABI path& make_preferred() { +# if defined(_LIBCPP_WIN32API) + std::replace(__pn_.begin(), __pn_.end(), L'/', L'\\'); +# endif return *this; } - _LIBCPP_HIDE_FROM_ABI - path& remove_filename() { + _LIBCPP_HIDE_FROM_ABI path& remove_filename() { auto __fname = __filename(); if (!__fname.empty()) __pn_.erase(__fname.data() - __pn_.data()); return *this; } - _LIBCPP_HIDE_FROM_ABI - path& replace_filename(const path& __replacement) { + _LIBCPP_HIDE_FROM_ABI path& replace_filename(const path& __replacement) { remove_filename(); return (*this /= __replacement); } @@ -756,7 +648,7 @@ public: friend _LIBCPP_HIDE_FROM_ABI bool operator>=(const path& __lhs, const path& __rhs) noexcept { return __lhs.__compare(__rhs.__pn_) >= 0; } -# else // _LIBCPP_STD_VER <= 17 +# else // _LIBCPP_STD_VER <= 17 friend _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(const path& __lhs, const path& __rhs) noexcept { return __lhs.__compare(__rhs.__pn_) <=> 0; } @@ -768,39 +660,31 @@ public: return __result; } - _LIBCPP_HIDE_FROM_ABI - void swap(path& __rhs) noexcept { __pn_.swap(__rhs.__pn_); } + _LIBCPP_HIDE_FROM_ABI void swap(path& __rhs) noexcept { __pn_.swap(__rhs.__pn_); } // private helper to allow reserving memory in the path - _LIBCPP_HIDE_FROM_ABI - void __reserve(size_t __s) { __pn_.reserve(__s); } + _LIBCPP_HIDE_FROM_ABI void __reserve(size_t __s) { __pn_.reserve(__s); } // native format observers - _LIBCPP_HIDE_FROM_ABI - const string_type& native() const noexcept { return __pn_; } + _LIBCPP_HIDE_FROM_ABI const string_type& native() const noexcept { return __pn_; } - _LIBCPP_HIDE_FROM_ABI - const value_type* c_str() const noexcept { return __pn_.c_str(); } + _LIBCPP_HIDE_FROM_ABI const value_type* c_str() const noexcept { return __pn_.c_str(); } _LIBCPP_HIDE_FROM_ABI operator string_type() const { return __pn_; } -#if defined(_LIBCPP_WIN32API) - _LIBCPP_HIDE_FROM_ABI _VSTD::wstring wstring() const { return __pn_; } +# if defined(_LIBCPP_WIN32API) + _LIBCPP_HIDE_FROM_ABI std::wstring wstring() const { return __pn_; } - _LIBCPP_HIDE_FROM_ABI - _VSTD::wstring generic_wstring() const { - _VSTD::wstring __s; + _LIBCPP_HIDE_FROM_ABI std::wstring generic_wstring() const { + std::wstring __s; __s.resize(__pn_.size()); - _VSTD::replace_copy(__pn_.begin(), __pn_.end(), __s.begin(), '\\', '/'); + std::replace_copy(__pn_.begin(), __pn_.end(), __s.begin(), '\\', '/'); return __s; } -#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) - template , - class _Allocator = allocator<_ECharT> > - _LIBCPP_HIDE_FROM_ABI - basic_string<_ECharT, _Traits, _Allocator> - string(const _Allocator& __a = _Allocator()) const { +# if !defined(_LIBCPP_HAS_NO_LOCALIZATION) + template , class _Allocator = allocator<_ECharT> > + _LIBCPP_HIDE_FROM_ABI basic_string<_ECharT, _Traits, _Allocator> string(const _Allocator& __a = _Allocator()) const { using _Str = basic_string<_ECharT, _Traits, _Allocator>; _Str __s(__a); __s.reserve(__pn_.size()); @@ -808,9 +692,7 @@ public: return __s; } - _LIBCPP_HIDE_FROM_ABI _VSTD::string string() const { - return string(); - } + _LIBCPP_HIDE_FROM_ABI std::string string() const { return string(); } _LIBCPP_HIDE_FROM_ABI __u8_string u8string() const { using _CVT = __narrow_to_utf8; __u8_string __s; @@ -819,54 +701,43 @@ public: return __s; } - _LIBCPP_HIDE_FROM_ABI _VSTD::u16string u16string() const { - return string(); - } - _LIBCPP_HIDE_FROM_ABI _VSTD::u32string u32string() const { - return string(); - } + _LIBCPP_HIDE_FROM_ABI std::u16string u16string() const { return string(); } + _LIBCPP_HIDE_FROM_ABI std::u32string u32string() const { return string(); } // generic format observers - template , - class _Allocator = allocator<_ECharT> > - _LIBCPP_HIDE_FROM_ABI - basic_string<_ECharT, _Traits, _Allocator> + template , class _Allocator = allocator<_ECharT> > + _LIBCPP_HIDE_FROM_ABI basic_string<_ECharT, _Traits, _Allocator> generic_string(const _Allocator& __a = _Allocator()) const { using _Str = basic_string<_ECharT, _Traits, _Allocator>; - _Str __s = string<_ECharT, _Traits, _Allocator>(__a); + _Str __s = string<_ECharT, _Traits, _Allocator>(__a); // Note: This (and generic_u8string below) is slightly suboptimal as // it iterates twice over the string; once to convert it to the right // character type, and once to replace path delimiters. - _VSTD::replace(__s.begin(), __s.end(), - static_cast<_ECharT>('\\'), static_cast<_ECharT>('/')); + std::replace(__s.begin(), __s.end(), static_cast<_ECharT>('\\'), static_cast<_ECharT>('/')); return __s; } - _LIBCPP_HIDE_FROM_ABI _VSTD::string generic_string() const { return generic_string(); } - _LIBCPP_HIDE_FROM_ABI _VSTD::u16string generic_u16string() const { return generic_string(); } - _LIBCPP_HIDE_FROM_ABI _VSTD::u32string generic_u32string() const { return generic_string(); } - _LIBCPP_HIDE_FROM_ABI - __u8_string generic_u8string() const { + _LIBCPP_HIDE_FROM_ABI std::string generic_string() const { return generic_string(); } + _LIBCPP_HIDE_FROM_ABI std::u16string generic_u16string() const { return generic_string(); } + _LIBCPP_HIDE_FROM_ABI std::u32string generic_u32string() const { return generic_string(); } + _LIBCPP_HIDE_FROM_ABI __u8_string generic_u8string() const { __u8_string __s = u8string(); - _VSTD::replace(__s.begin(), __s.end(), '\\', '/'); + std::replace(__s.begin(), __s.end(), '\\', '/'); return __s; } -#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */ -#else /* _LIBCPP_WIN32API */ +# endif /* !_LIBCPP_HAS_NO_LOCALIZATION */ +# else /* _LIBCPP_WIN32API */ - _LIBCPP_HIDE_FROM_ABI _VSTD::string string() const { return __pn_; } -#ifndef _LIBCPP_HAS_NO_CHAR8_T - _LIBCPP_HIDE_FROM_ABI _VSTD::u8string u8string() const { return _VSTD::u8string(__pn_.begin(), __pn_.end()); } -#else - _LIBCPP_HIDE_FROM_ABI _VSTD::string u8string() const { return __pn_; } -#endif + _LIBCPP_HIDE_FROM_ABI std::string string() const { return __pn_; } +# ifndef _LIBCPP_HAS_NO_CHAR8_T + _LIBCPP_HIDE_FROM_ABI std::u8string u8string() const { return std::u8string(__pn_.begin(), __pn_.end()); } +# else + _LIBCPP_HIDE_FROM_ABI std::string u8string() const { return __pn_; } +# endif -#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) - template , - class _Allocator = allocator<_ECharT> > - _LIBCPP_HIDE_FROM_ABI - basic_string<_ECharT, _Traits, _Allocator> - string(const _Allocator& __a = _Allocator()) const { +# if !defined(_LIBCPP_HAS_NO_LOCALIZATION) + template , class _Allocator = allocator<_ECharT> > + _LIBCPP_HIDE_FROM_ABI basic_string<_ECharT, _Traits, _Allocator> string(const _Allocator& __a = _Allocator()) const { using _CVT = __widen_from_utf8; using _Str = basic_string<_ECharT, _Traits, _Allocator>; _Str __s(__a); @@ -875,43 +746,35 @@ public: return __s; } -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS - _LIBCPP_HIDE_FROM_ABI _VSTD::wstring wstring() const { - return string(); - } -#endif - _LIBCPP_HIDE_FROM_ABI _VSTD::u16string u16string() const { - return string(); - } - _LIBCPP_HIDE_FROM_ABI _VSTD::u32string u32string() const { - return string(); - } -#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */ +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS + _LIBCPP_HIDE_FROM_ABI std::wstring wstring() const { return string(); } +# endif + _LIBCPP_HIDE_FROM_ABI std::u16string u16string() const { return string(); } + _LIBCPP_HIDE_FROM_ABI std::u32string u32string() const { return string(); } +# endif /* !_LIBCPP_HAS_NO_LOCALIZATION */ // generic format observers - _LIBCPP_HIDE_FROM_ABI _VSTD::string generic_string() const { return __pn_; } -#ifndef _LIBCPP_HAS_NO_CHAR8_T - _LIBCPP_HIDE_FROM_ABI _VSTD::u8string generic_u8string() const { return _VSTD::u8string(__pn_.begin(), __pn_.end()); } -#else - _LIBCPP_HIDE_FROM_ABI _VSTD::string generic_u8string() const { return __pn_; } -#endif + _LIBCPP_HIDE_FROM_ABI std::string generic_string() const { return __pn_; } +# ifndef _LIBCPP_HAS_NO_CHAR8_T + _LIBCPP_HIDE_FROM_ABI std::u8string generic_u8string() const { return std::u8string(__pn_.begin(), __pn_.end()); } +# else + _LIBCPP_HIDE_FROM_ABI std::string generic_u8string() const { return __pn_; } +# endif -#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) - template , - class _Allocator = allocator<_ECharT> > - _LIBCPP_HIDE_FROM_ABI - basic_string<_ECharT, _Traits, _Allocator> +# if !defined(_LIBCPP_HAS_NO_LOCALIZATION) + template , class _Allocator = allocator<_ECharT> > + _LIBCPP_HIDE_FROM_ABI basic_string<_ECharT, _Traits, _Allocator> generic_string(const _Allocator& __a = _Allocator()) const { return string<_ECharT, _Traits, _Allocator>(__a); } -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS - _LIBCPP_HIDE_FROM_ABI _VSTD::wstring generic_wstring() const { return string(); } -#endif - _LIBCPP_HIDE_FROM_ABI _VSTD::u16string generic_u16string() const { return string(); } - _LIBCPP_HIDE_FROM_ABI _VSTD::u32string generic_u32string() const { return string(); } -#endif /* !_LIBCPP_HAS_NO_LOCALIZATION */ -#endif /* !_LIBCPP_WIN32API */ +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS + _LIBCPP_HIDE_FROM_ABI std::wstring generic_wstring() const { return string(); } +# endif + _LIBCPP_HIDE_FROM_ABI std::u16string generic_u16string() const { return string(); } + _LIBCPP_HIDE_FROM_ABI std::u32string generic_u32string() const { return string(); } +# endif /* !_LIBCPP_HAS_NO_LOCALIZATION */ +# endif /* !_LIBCPP_WIN32API */ private: int __compare(__string_view) const; @@ -926,80 +789,43 @@ private: public: // compare - _LIBCPP_HIDE_FROM_ABI int compare(const path& __p) const noexcept { - return __compare(__p.__pn_); - } - _LIBCPP_HIDE_FROM_ABI int compare(const string_type& __s) const { - return __compare(__s); - } - _LIBCPP_HIDE_FROM_ABI int compare(__string_view __s) const { - return __compare(__s); - } - _LIBCPP_HIDE_FROM_ABI int compare(const value_type* __s) const { - return __compare(__s); - } + _LIBCPP_HIDE_FROM_ABI int compare(const path& __p) const noexcept { return __compare(__p.__pn_); } + _LIBCPP_HIDE_FROM_ABI int compare(const string_type& __s) const { return __compare(__s); } + _LIBCPP_HIDE_FROM_ABI int compare(__string_view __s) const { return __compare(__s); } + _LIBCPP_HIDE_FROM_ABI int compare(const value_type* __s) const { return __compare(__s); } // decomposition - _LIBCPP_HIDE_FROM_ABI path root_name() const { - return string_type(__root_name()); - } - _LIBCPP_HIDE_FROM_ABI path root_directory() const { - return string_type(__root_directory()); - } + _LIBCPP_HIDE_FROM_ABI path root_name() const { return string_type(__root_name()); } + _LIBCPP_HIDE_FROM_ABI path root_directory() const { return string_type(__root_directory()); } _LIBCPP_HIDE_FROM_ABI path root_path() const { -#if defined(_LIBCPP_WIN32API) +# if defined(_LIBCPP_WIN32API) return string_type(__root_path_raw()); -#else +# else return root_name().append(string_type(__root_directory())); -#endif - } - _LIBCPP_HIDE_FROM_ABI path relative_path() const { - return string_type(__relative_path()); - } - _LIBCPP_HIDE_FROM_ABI path parent_path() const { - return string_type(__parent_path()); - } - _LIBCPP_HIDE_FROM_ABI path filename() const { - return string_type(__filename()); +# endif } + _LIBCPP_HIDE_FROM_ABI path relative_path() const { return string_type(__relative_path()); } + _LIBCPP_HIDE_FROM_ABI path parent_path() const { return string_type(__parent_path()); } + _LIBCPP_HIDE_FROM_ABI path filename() const { return string_type(__filename()); } _LIBCPP_HIDE_FROM_ABI path stem() const { return string_type(__stem()); } - _LIBCPP_HIDE_FROM_ABI path extension() const { - return string_type(__extension()); - } + _LIBCPP_HIDE_FROM_ABI path extension() const { return string_type(__extension()); } // query - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI bool - empty() const noexcept { - return __pn_.empty(); - } + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI bool empty() const noexcept { return __pn_.empty(); } - _LIBCPP_HIDE_FROM_ABI bool has_root_name() const { - return !__root_name().empty(); - } - _LIBCPP_HIDE_FROM_ABI bool has_root_directory() const { - return !__root_directory().empty(); - } - _LIBCPP_HIDE_FROM_ABI bool has_root_path() const { - return !__root_path_raw().empty(); - } - _LIBCPP_HIDE_FROM_ABI bool has_relative_path() const { - return !__relative_path().empty(); - } - _LIBCPP_HIDE_FROM_ABI bool has_parent_path() const { - return !__parent_path().empty(); - } - _LIBCPP_HIDE_FROM_ABI bool has_filename() const { - return !__filename().empty(); - } + _LIBCPP_HIDE_FROM_ABI bool has_root_name() const { return !__root_name().empty(); } + _LIBCPP_HIDE_FROM_ABI bool has_root_directory() const { return !__root_directory().empty(); } + _LIBCPP_HIDE_FROM_ABI bool has_root_path() const { return !__root_path_raw().empty(); } + _LIBCPP_HIDE_FROM_ABI bool has_relative_path() const { return !__relative_path().empty(); } + _LIBCPP_HIDE_FROM_ABI bool has_parent_path() const { return !__parent_path().empty(); } + _LIBCPP_HIDE_FROM_ABI bool has_filename() const { return !__filename().empty(); } _LIBCPP_HIDE_FROM_ABI bool has_stem() const { return !__stem().empty(); } - _LIBCPP_HIDE_FROM_ABI bool has_extension() const { - return !__extension().empty(); - } + _LIBCPP_HIDE_FROM_ABI bool has_extension() const { return !__extension().empty(); } _LIBCPP_HIDE_FROM_ABI bool is_absolute() const { -#if defined(_LIBCPP_WIN32API) +# if defined(_LIBCPP_WIN32API) __string_view __root_name_str = __root_name(); - __string_view __root_dir = __root_directory(); + __string_view __root_dir = __root_directory(); if (__root_name_str.size() == 2 && __root_name_str[1] == ':') { // A drive letter with no root directory is relative, e.g. x:example. return !__root_dir.empty(); @@ -1016,9 +842,9 @@ public: return false; // Seems to be a server root name return true; -#else +# else return has_root_directory(); -#endif +# endif } _LIBCPP_HIDE_FROM_ABI bool is_relative() const { return !is_absolute(); } @@ -1034,30 +860,30 @@ public: } // iterators - class _LIBCPP_TYPE_VIS iterator; + class _LIBCPP_EXPORTED_FROM_ABI iterator; typedef iterator const_iterator; iterator begin() const; iterator end() const; -#if !defined(_LIBCPP_HAS_NO_LOCALIZATION) - template - _LIBCPP_HIDE_FROM_ABI friend - typename enable_if::value && - is_same<_Traits, char_traits >::value, - basic_ostream<_CharT, _Traits>&>::type - operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { - __os << _VSTD::__quoted(__p.native()); +# if !defined(_LIBCPP_HAS_NO_LOCALIZATION) + template < + class _CharT, + class _Traits, + __enable_if_t::value && is_same<_Traits, char_traits >::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI friend basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { + __os << std::__quoted(__p.native()); return __os; } - template - _LIBCPP_HIDE_FROM_ABI friend - typename enable_if::value || - !is_same<_Traits, char_traits >::value, - basic_ostream<_CharT, _Traits>&>::type - operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { - __os << _VSTD::__quoted(__p.string<_CharT, _Traits>()); + template < + class _CharT, + class _Traits, + __enable_if_t::value || !is_same<_Traits, char_traits >::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI friend basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { + __os << std::__quoted(__p.string<_CharT, _Traits>()); return __os; } @@ -1065,43 +891,41 @@ public: _LIBCPP_HIDE_FROM_ABI friend basic_istream<_CharT, _Traits>& operator>>(basic_istream<_CharT, _Traits>& __is, path& __p) { basic_string<_CharT, _Traits> __tmp; - __is >> _VSTD::__quoted(__tmp); + __is >> std::__quoted(__tmp); __p = __tmp; return __is; } -#endif // !_LIBCPP_HAS_NO_LOCALIZATION +# endif // !_LIBCPP_HAS_NO_LOCALIZATION private: - inline _LIBCPP_HIDE_FROM_ABI path& - __assign_view(__string_view const& __s) noexcept { + inline _LIBCPP_HIDE_FROM_ABI path& __assign_view(__string_view const& __s) { __pn_ = string_type(__s); return *this; } string_type __pn_; }; -inline _LIBCPP_HIDE_FROM_ABI void swap(path& __lhs, path& __rhs) noexcept { - __lhs.swap(__rhs); -} +inline _LIBCPP_HIDE_FROM_ABI void swap(path& __lhs, path& __rhs) noexcept { __lhs.swap(__rhs); } -_LIBCPP_FUNC_VIS -size_t hash_value(const path& __p) noexcept; +_LIBCPP_EXPORTED_FROM_ABI size_t hash_value(const path& __p) noexcept; -_LIBCPP_AVAILABILITY_FILESYSTEM_POP +_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP _LIBCPP_END_NAMESPACE_FILESYSTEM _LIBCPP_BEGIN_NAMESPACE_STD template <> -struct _LIBCPP_AVAILABILITY_FILESYSTEM hash<_VSTD_FS::path> : __unary_function<_VSTD_FS::path, size_t> { - _LIBCPP_HIDE_FROM_ABI size_t operator()(_VSTD_FS::path const& __p) const noexcept { - return _VSTD_FS::hash_value(__p); +struct _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY hash : __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(filesystem::path const& __p) const noexcept { + return filesystem::hash_value(__p); } }; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP_CXX03_LANG +#endif // _LIBCPP_STD_VER >= 17 + +_LIBCPP_POP_MACROS #endif // _LIBCPP___FILESYSTEM_PATH_H diff --git a/third_party/libcxx/__filesystem/path_iterator.h b/third_party/libcxx/__filesystem/path_iterator.h index d754fdce2..f4d486d86 100644 --- a/third_party/libcxx/__filesystem/path_iterator.h +++ b/third_party/libcxx/__filesystem/path_iterator.h @@ -11,7 +11,6 @@ #define _LIBCPP___FILESYSTEM_PATH_ITERATOR_H #include <__assert> -#include <__availability> #include <__config> #include <__filesystem/path.h> #include <__iterator/iterator_traits.h> @@ -23,13 +22,11 @@ # pragma GCC system_header #endif -#ifndef _LIBCPP_CXX03_LANG +#if _LIBCPP_STD_VER >= 17 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM -_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH - -class _LIBCPP_TYPE_VIS path::iterator { +class _LIBCPP_EXPORTED_FROM_ABI path::iterator { public: enum _ParserState : unsigned char { _Singular, @@ -51,49 +48,37 @@ public: typedef path reference; public: - _LIBCPP_INLINE_VISIBILITY - iterator() - : __stashed_elem_(), __path_ptr_(nullptr), __entry_(), - __state_(_Singular) {} + _LIBCPP_HIDE_FROM_ABI iterator() : __stashed_elem_(), __path_ptr_(nullptr), __entry_(), __state_(_Singular) {} _LIBCPP_HIDE_FROM_ABI iterator(const iterator&) = default; - _LIBCPP_HIDE_FROM_ABI ~iterator() = default; + _LIBCPP_HIDE_FROM_ABI ~iterator() = default; _LIBCPP_HIDE_FROM_ABI iterator& operator=(const iterator&) = default; - _LIBCPP_INLINE_VISIBILITY - reference operator*() const { return __stashed_elem_; } + _LIBCPP_HIDE_FROM_ABI reference operator*() const { return __stashed_elem_; } - _LIBCPP_INLINE_VISIBILITY - pointer operator->() const { return &__stashed_elem_; } + _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return &__stashed_elem_; } - _LIBCPP_INLINE_VISIBILITY - iterator& operator++() { - _LIBCPP_ASSERT(__state_ != _Singular, - "attempting to increment a singular iterator"); - _LIBCPP_ASSERT(__state_ != _AtEnd, - "attempting to increment the end iterator"); + _LIBCPP_HIDE_FROM_ABI iterator& operator++() { + _LIBCPP_ASSERT_NON_NULL(__state_ != _Singular, "attempting to increment a singular iterator"); + _LIBCPP_ASSERT_UNCATEGORIZED(__state_ != _AtEnd, "attempting to increment the end iterator"); return __increment(); } - _LIBCPP_INLINE_VISIBILITY - iterator operator++(int) { + _LIBCPP_HIDE_FROM_ABI iterator operator++(int) { iterator __it(*this); this->operator++(); return __it; } - _LIBCPP_INLINE_VISIBILITY - iterator& operator--() { - _LIBCPP_ASSERT(__state_ != _Singular, - "attempting to decrement a singular iterator"); - _LIBCPP_ASSERT(__entry_.data() != __path_ptr_->native().data(), - "attempting to decrement the begin iterator"); + _LIBCPP_HIDE_FROM_ABI iterator& operator--() { + _LIBCPP_ASSERT_NON_NULL(__state_ != _Singular, "attempting to decrement a singular iterator"); + _LIBCPP_ASSERT_UNCATEGORIZED( + __entry_.data() != __path_ptr_->native().data(), "attempting to decrement the begin iterator"); return __decrement(); } - _LIBCPP_INLINE_VISIBILITY - iterator operator--(int) { + _LIBCPP_HIDE_FROM_ABI iterator operator--(int) { iterator __it(*this); this->operator--(); return __it; @@ -102,8 +87,7 @@ public: private: friend class path; - inline _LIBCPP_INLINE_VISIBILITY friend bool operator==(const iterator&, - const iterator&); + inline _LIBCPP_HIDE_FROM_ABI friend bool operator==(const iterator&, const iterator&); iterator& __increment(); iterator& __decrement(); @@ -114,21 +98,18 @@ private: _ParserState __state_; }; -inline _LIBCPP_INLINE_VISIBILITY bool operator==(const path::iterator& __lhs, - const path::iterator& __rhs) { - return __lhs.__path_ptr_ == __rhs.__path_ptr_ && - __lhs.__entry_.data() == __rhs.__entry_.data(); +_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY +inline _LIBCPP_HIDE_FROM_ABI bool operator==(const path::iterator& __lhs, const path::iterator& __rhs) { + return __lhs.__path_ptr_ == __rhs.__path_ptr_ && __lhs.__entry_.data() == __rhs.__entry_.data(); } -inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const path::iterator& __lhs, - const path::iterator& __rhs) { +_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY +inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const path::iterator& __lhs, const path::iterator& __rhs) { return !(__lhs == __rhs); } -_LIBCPP_AVAILABILITY_FILESYSTEM_POP - _LIBCPP_END_NAMESPACE_FILESYSTEM -#endif // _LIBCPP_CXX03_LANG +#endif // _LIBCPP_STD_VER >= 17 #endif // _LIBCPP___FILESYSTEM_PATH_ITERATOR_H diff --git a/third_party/libcxx/__filesystem/perm_options.h b/third_party/libcxx/__filesystem/perm_options.h index 4aba302ed..64c16ee60 100644 --- a/third_party/libcxx/__filesystem/perm_options.h +++ b/third_party/libcxx/__filesystem/perm_options.h @@ -10,68 +10,48 @@ #ifndef _LIBCPP___FILESYSTEM_PERM_OPTIONS_H #define _LIBCPP___FILESYSTEM_PERM_OPTIONS_H -#include <__availability> #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif -#ifndef _LIBCPP_CXX03_LANG +#if _LIBCPP_STD_VER >= 17 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM -_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH +enum class perm_options : unsigned char { replace = 1, add = 2, remove = 4, nofollow = 8 }; -enum class _LIBCPP_ENUM_VIS perm_options : unsigned char { - replace = 1, - add = 2, - remove = 4, - nofollow = 8 -}; - -_LIBCPP_INLINE_VISIBILITY -inline constexpr perm_options operator&(perm_options __lhs, perm_options __rhs) { - return static_cast(static_cast(__lhs) & - static_cast(__rhs)); +_LIBCPP_HIDE_FROM_ABI inline constexpr perm_options operator&(perm_options __lhs, perm_options __rhs) { + return static_cast(static_cast(__lhs) & static_cast(__rhs)); } -_LIBCPP_INLINE_VISIBILITY -inline constexpr perm_options operator|(perm_options __lhs, perm_options __rhs) { - return static_cast(static_cast(__lhs) | - static_cast(__rhs)); +_LIBCPP_HIDE_FROM_ABI inline constexpr perm_options operator|(perm_options __lhs, perm_options __rhs) { + return static_cast(static_cast(__lhs) | static_cast(__rhs)); } -_LIBCPP_INLINE_VISIBILITY -inline constexpr perm_options operator^(perm_options __lhs, perm_options __rhs) { - return static_cast(static_cast(__lhs) ^ - static_cast(__rhs)); +_LIBCPP_HIDE_FROM_ABI inline constexpr perm_options operator^(perm_options __lhs, perm_options __rhs) { + return static_cast(static_cast(__lhs) ^ static_cast(__rhs)); } -_LIBCPP_INLINE_VISIBILITY -inline constexpr perm_options operator~(perm_options __lhs) { +_LIBCPP_HIDE_FROM_ABI inline constexpr perm_options operator~(perm_options __lhs) { return static_cast(~static_cast(__lhs)); } -_LIBCPP_INLINE_VISIBILITY -inline perm_options& operator&=(perm_options& __lhs, perm_options __rhs) { +_LIBCPP_HIDE_FROM_ABI inline perm_options& operator&=(perm_options& __lhs, perm_options __rhs) { return __lhs = __lhs & __rhs; } -_LIBCPP_INLINE_VISIBILITY -inline perm_options& operator|=(perm_options& __lhs, perm_options __rhs) { +_LIBCPP_HIDE_FROM_ABI inline perm_options& operator|=(perm_options& __lhs, perm_options __rhs) { return __lhs = __lhs | __rhs; } -_LIBCPP_INLINE_VISIBILITY -inline perm_options& operator^=(perm_options& __lhs, perm_options __rhs) { +_LIBCPP_HIDE_FROM_ABI inline perm_options& operator^=(perm_options& __lhs, perm_options __rhs) { return __lhs = __lhs ^ __rhs; } -_LIBCPP_AVAILABILITY_FILESYSTEM_POP - _LIBCPP_END_NAMESPACE_FILESYSTEM -#endif // _LIBCPP_CXX03_LANG +#endif // _LIBCPP_STD_VER >= 17 #endif // _LIBCPP___FILESYSTEM_PERM_OPTIONS_H diff --git a/third_party/libcxx/__filesystem/perms.h b/third_party/libcxx/__filesystem/perms.h index df4590057..458f1e6e5 100644 --- a/third_party/libcxx/__filesystem/perms.h +++ b/third_party/libcxx/__filesystem/perms.h @@ -10,86 +10,71 @@ #ifndef _LIBCPP___FILESYSTEM_PERMS_H #define _LIBCPP___FILESYSTEM_PERMS_H -#include <__availability> #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif -#ifndef _LIBCPP_CXX03_LANG +#if _LIBCPP_STD_VER >= 17 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM -_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH - // On Windows, these permission bits map to one single readonly flag per // file, and the executable bit is always returned as set. When setting // permissions, as long as the write bit is set for either owner, group or // others, the readonly flag is cleared. -enum class _LIBCPP_ENUM_VIS perms : unsigned { +enum class perms : unsigned { none = 0, - owner_read = 0400, + owner_read = 0400, owner_write = 0200, - owner_exec = 0100, - owner_all = 0700, + owner_exec = 0100, + owner_all = 0700, - group_read = 040, + group_read = 040, group_write = 020, - group_exec = 010, - group_all = 070, + group_exec = 010, + group_all = 070, - others_read = 04, + others_read = 04, others_write = 02, - others_exec = 01, - others_all = 07, + others_exec = 01, + others_all = 07, all = 0777, - set_uid = 04000, - set_gid = 02000, + set_uid = 04000, + set_gid = 02000, sticky_bit = 01000, - mask = 07777, - unknown = 0xFFFF, + mask = 07777, + unknown = 0xFFFF, }; -_LIBCPP_INLINE_VISIBILITY -inline constexpr perms operator&(perms __lhs, perms __rhs) { - return static_cast(static_cast(__lhs) & - static_cast(__rhs)); +_LIBCPP_HIDE_FROM_ABI inline constexpr perms operator&(perms __lhs, perms __rhs) { + return static_cast(static_cast(__lhs) & static_cast(__rhs)); } -_LIBCPP_INLINE_VISIBILITY -inline constexpr perms operator|(perms __lhs, perms __rhs) { - return static_cast(static_cast(__lhs) | - static_cast(__rhs)); +_LIBCPP_HIDE_FROM_ABI inline constexpr perms operator|(perms __lhs, perms __rhs) { + return static_cast(static_cast(__lhs) | static_cast(__rhs)); } -_LIBCPP_INLINE_VISIBILITY -inline constexpr perms operator^(perms __lhs, perms __rhs) { - return static_cast(static_cast(__lhs) ^ - static_cast(__rhs)); +_LIBCPP_HIDE_FROM_ABI inline constexpr perms operator^(perms __lhs, perms __rhs) { + return static_cast(static_cast(__lhs) ^ static_cast(__rhs)); } -_LIBCPP_INLINE_VISIBILITY -inline constexpr perms operator~(perms __lhs) { +_LIBCPP_HIDE_FROM_ABI inline constexpr perms operator~(perms __lhs) { return static_cast(~static_cast(__lhs)); } -_LIBCPP_INLINE_VISIBILITY -inline perms& operator&=(perms& __lhs, perms __rhs) { return __lhs = __lhs & __rhs; } +_LIBCPP_HIDE_FROM_ABI inline perms& operator&=(perms& __lhs, perms __rhs) { return __lhs = __lhs & __rhs; } -_LIBCPP_INLINE_VISIBILITY -inline perms& operator|=(perms& __lhs, perms __rhs) { return __lhs = __lhs | __rhs; } +_LIBCPP_HIDE_FROM_ABI inline perms& operator|=(perms& __lhs, perms __rhs) { return __lhs = __lhs | __rhs; } -_LIBCPP_INLINE_VISIBILITY -inline perms& operator^=(perms& __lhs, perms __rhs) { return __lhs = __lhs ^ __rhs; } - -_LIBCPP_AVAILABILITY_FILESYSTEM_POP +_LIBCPP_HIDE_FROM_ABI inline perms& operator^=(perms& __lhs, perms __rhs) { return __lhs = __lhs ^ __rhs; } _LIBCPP_END_NAMESPACE_FILESYSTEM -#endif // _LIBCPP_CXX03_LANG +#endif // _LIBCPP_STD_VER >= 17 #endif // _LIBCPP___FILESYSTEM_PERMS_H diff --git a/third_party/libcxx/__filesystem/recursive_directory_iterator.h b/third_party/libcxx/__filesystem/recursive_directory_iterator.h index 3d5c02540..caa1396eb 100644 --- a/third_party/libcxx/__filesystem/recursive_directory_iterator.h +++ b/third_party/libcxx/__filesystem/recursive_directory_iterator.h @@ -10,11 +10,11 @@ #ifndef _LIBCPP___FILESYSTEM_RECURSIVE_DIRECTORY_ITERATOR_H #define _LIBCPP___FILESYSTEM_RECURSIVE_DIRECTORY_ITERATOR_H -#include <__availability> #include <__config> #include <__filesystem/directory_entry.h> #include <__filesystem/directory_options.h> #include <__filesystem/path.h> +#include <__iterator/default_sentinel.h> #include <__iterator/iterator_traits.h> #include <__memory/shared_ptr.h> #include <__ranges/enable_borrowed_range.h> @@ -27,51 +27,46 @@ # pragma GCC system_header #endif -#ifndef _LIBCPP_CXX03_LANG +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +#if _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM) _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM -_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH +_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH class recursive_directory_iterator { public: - using value_type = directory_entry; - using difference_type = ptrdiff_t; - using pointer = directory_entry const*; - using reference = directory_entry const&; + using value_type = directory_entry; + using difference_type = ptrdiff_t; + using pointer = directory_entry const*; + using reference = directory_entry const&; using iterator_category = input_iterator_tag; public: // constructors and destructor - _LIBCPP_INLINE_VISIBILITY - recursive_directory_iterator() noexcept : __rec_(false) {} + _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator() noexcept : __rec_(false) {} - _LIBCPP_INLINE_VISIBILITY - explicit recursive_directory_iterator( + _LIBCPP_HIDE_FROM_ABI explicit recursive_directory_iterator( const path& __p, directory_options __xoptions = directory_options::none) : recursive_directory_iterator(__p, __xoptions, nullptr) {} - _LIBCPP_INLINE_VISIBILITY - recursive_directory_iterator(const path& __p, directory_options __xoptions, - error_code& __ec) + _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator(const path& __p, directory_options __xoptions, error_code& __ec) : recursive_directory_iterator(__p, __xoptions, &__ec) {} - _LIBCPP_INLINE_VISIBILITY - recursive_directory_iterator(const path& __p, error_code& __ec) + _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator(const path& __p, error_code& __ec) : recursive_directory_iterator(__p, directory_options::none, &__ec) {} _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator(const recursive_directory_iterator&) = default; - _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator(recursive_directory_iterator&&) = default; + _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator(recursive_directory_iterator&&) = default; - _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator& - operator=(const recursive_directory_iterator&) = default; + _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator& operator=(const recursive_directory_iterator&) = default; - _LIBCPP_INLINE_VISIBILITY - recursive_directory_iterator& - operator=(recursive_directory_iterator&& __o) noexcept { + _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator& operator=(recursive_directory_iterator&& __o) noexcept { // non-default implementation provided to support self-move assign. if (this != &__o) { - __imp_ = _VSTD::move(__o.__imp_); + __imp_ = std::move(__o.__imp_); __rec_ = __o.__rec_; } return *this; @@ -79,108 +74,91 @@ public: _LIBCPP_HIDE_FROM_ABI ~recursive_directory_iterator() = default; - _LIBCPP_INLINE_VISIBILITY - const directory_entry& operator*() const { return __dereference(); } + _LIBCPP_HIDE_FROM_ABI const directory_entry& operator*() const { return __dereference(); } - _LIBCPP_INLINE_VISIBILITY - const directory_entry* operator->() const { return &__dereference(); } + _LIBCPP_HIDE_FROM_ABI const directory_entry* operator->() const { return &__dereference(); } _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator& operator++() { return __increment(); } - _LIBCPP_INLINE_VISIBILITY - __dir_element_proxy operator++(int) { + _LIBCPP_HIDE_FROM_ABI __dir_element_proxy operator++(int) { __dir_element_proxy __p(**this); __increment(); return __p; } - _LIBCPP_INLINE_VISIBILITY - recursive_directory_iterator& increment(error_code& __ec) { - return __increment(&__ec); + _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator& increment(error_code& __ec) { return __increment(&__ec); } + + _LIBCPP_EXPORTED_FROM_ABI directory_options options() const; + _LIBCPP_EXPORTED_FROM_ABI int depth() const; + + _LIBCPP_HIDE_FROM_ABI void pop() { __pop(); } + + _LIBCPP_HIDE_FROM_ABI void pop(error_code& __ec) { __pop(&__ec); } + + _LIBCPP_HIDE_FROM_ABI bool recursion_pending() const { return __rec_; } + + _LIBCPP_HIDE_FROM_ABI void disable_recursion_pending() { __rec_ = false; } + +# if _LIBCPP_STD_VER >= 20 + + _LIBCPP_HIDE_FROM_ABI bool operator==(default_sentinel_t) const noexcept { + return *this == recursive_directory_iterator(); } - _LIBCPP_FUNC_VIS directory_options options() const; - _LIBCPP_FUNC_VIS int depth() const; - - _LIBCPP_INLINE_VISIBILITY - void pop() { __pop(); } - - _LIBCPP_INLINE_VISIBILITY - void pop(error_code& __ec) { __pop(&__ec); } - - _LIBCPP_INLINE_VISIBILITY - bool recursion_pending() const { return __rec_; } - - _LIBCPP_INLINE_VISIBILITY - void disable_recursion_pending() { __rec_ = false; } +# endif private: - _LIBCPP_FUNC_VIS - recursive_directory_iterator(const path& __p, directory_options __opt, - error_code* __ec); + _LIBCPP_EXPORTED_FROM_ABI recursive_directory_iterator(const path& __p, directory_options __opt, error_code* __ec); + _LIBCPP_EXPORTED_FROM_ABI const directory_entry& __dereference() const; + _LIBCPP_EXPORTED_FROM_ABI bool __try_recursion(error_code* __ec); + _LIBCPP_EXPORTED_FROM_ABI void __advance(error_code* __ec = nullptr); + _LIBCPP_EXPORTED_FROM_ABI recursive_directory_iterator& __increment(error_code* __ec = nullptr); + _LIBCPP_EXPORTED_FROM_ABI void __pop(error_code* __ec = nullptr); - _LIBCPP_FUNC_VIS - const directory_entry& __dereference() const; - - _LIBCPP_FUNC_VIS - bool __try_recursion(error_code* __ec); - - _LIBCPP_FUNC_VIS - void __advance(error_code* __ec = nullptr); - - _LIBCPP_FUNC_VIS - recursive_directory_iterator& __increment(error_code* __ec = nullptr); - - _LIBCPP_FUNC_VIS - void __pop(error_code* __ec = nullptr); - - inline _LIBCPP_INLINE_VISIBILITY friend bool - operator==(const recursive_directory_iterator&, - const recursive_directory_iterator&) noexcept; + inline _LIBCPP_HIDE_FROM_ABI friend bool + operator==(const recursive_directory_iterator&, const recursive_directory_iterator&) noexcept; struct _LIBCPP_HIDDEN __shared_imp; shared_ptr<__shared_imp> __imp_; bool __rec_; }; // class recursive_directory_iterator -inline _LIBCPP_INLINE_VISIBILITY bool -operator==(const recursive_directory_iterator& __lhs, - const recursive_directory_iterator& __rhs) noexcept { +inline _LIBCPP_HIDE_FROM_ABI bool +operator==(const recursive_directory_iterator& __lhs, const recursive_directory_iterator& __rhs) noexcept { return __lhs.__imp_ == __rhs.__imp_; } -_LIBCPP_INLINE_VISIBILITY -inline bool operator!=(const recursive_directory_iterator& __lhs, - const recursive_directory_iterator& __rhs) noexcept { +_LIBCPP_HIDE_FROM_ABI inline bool +operator!=(const recursive_directory_iterator& __lhs, const recursive_directory_iterator& __rhs) noexcept { return !(__lhs == __rhs); } // enable recursive_directory_iterator range-based for statements -inline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator -begin(recursive_directory_iterator __iter) noexcept { +inline _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator begin(recursive_directory_iterator __iter) noexcept { return __iter; } -inline _LIBCPP_INLINE_VISIBILITY recursive_directory_iterator -end(recursive_directory_iterator) noexcept { +inline _LIBCPP_HIDE_FROM_ABI recursive_directory_iterator end(recursive_directory_iterator) noexcept { return recursive_directory_iterator(); } -_LIBCPP_AVAILABILITY_FILESYSTEM_POP +_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP _LIBCPP_END_NAMESPACE_FILESYSTEM -#if _LIBCPP_STD_VER >= 20 +# if _LIBCPP_STD_VER >= 20 template <> -_LIBCPP_AVAILABILITY_FILESYSTEM -inline constexpr bool _VSTD::ranges::enable_borrowed_range<_VSTD_FS::recursive_directory_iterator> = true; +_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY inline constexpr bool + std::ranges::enable_borrowed_range = true; template <> -_LIBCPP_AVAILABILITY_FILESYSTEM -inline constexpr bool _VSTD::ranges::enable_view<_VSTD_FS::recursive_directory_iterator> = true; +_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY inline constexpr bool + std::ranges::enable_view = true; -#endif // _LIBCPP_STD_VER >= 20 +# endif // _LIBCPP_STD_VER >= 20 -#endif // _LIBCPP_CXX03_LANG +#endif // _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM) + +_LIBCPP_POP_MACROS #endif // _LIBCPP___FILESYSTEM_RECURSIVE_DIRECTORY_ITERATOR_H diff --git a/third_party/libcxx/__filesystem/space_info.h b/third_party/libcxx/__filesystem/space_info.h index 25fcb9a77..3fa57d330 100644 --- a/third_party/libcxx/__filesystem/space_info.h +++ b/third_party/libcxx/__filesystem/space_info.h @@ -10,7 +10,6 @@ #ifndef _LIBCPP___FILESYSTEM_SPACE_INFO_H #define _LIBCPP___FILESYSTEM_SPACE_INFO_H -#include <__availability> #include <__config> #include @@ -18,13 +17,11 @@ # pragma GCC system_header #endif -#ifndef _LIBCPP_CXX03_LANG +#if _LIBCPP_STD_VER >= 17 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM -_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH - -struct _LIBCPP_TYPE_VIS space_info { +struct _LIBCPP_EXPORTED_FROM_ABI space_info { uintmax_t capacity; uintmax_t free; uintmax_t available; @@ -34,10 +31,8 @@ struct _LIBCPP_TYPE_VIS space_info { # endif }; -_LIBCPP_AVAILABILITY_FILESYSTEM_POP - _LIBCPP_END_NAMESPACE_FILESYSTEM -#endif // _LIBCPP_CXX03_LANG +#endif // _LIBCPP_STD_VER >= 17 #endif // _LIBCPP___FILESYSTEM_SPACE_INFO_H diff --git a/third_party/libcxx/__filesystem/u8path.h b/third_party/libcxx/__filesystem/u8path.h index ebc1159ee..dae582312 100644 --- a/third_party/libcxx/__filesystem/u8path.h +++ b/third_party/libcxx/__filesystem/u8path.h @@ -11,7 +11,6 @@ #define _LIBCPP___FILESYSTEM_U8PATH_H #include <__algorithm/unwrap_iter.h> -#include <__availability> #include <__config> #include <__filesystem/path.h> #include @@ -19,52 +18,48 @@ // Only required on Windows for __widen_from_utf8, and included conservatively // because it requires support for localization. #if defined(_LIBCPP_WIN32API) -# include +# include #endif #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif -#ifndef _LIBCPP_CXX03_LANG +#if _LIBCPP_STD_VER >= 17 _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM -_LIBCPP_AVAILABILITY_FILESYSTEM_PUSH +_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_PUSH -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T - typename enable_if<__is_pathable<_InputIt>::value, path>::type - u8path(_InputIt __f, _InputIt __l) { +template ::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(_InputIt __f, _InputIt __l) { static_assert( -#ifndef _LIBCPP_HAS_NO_CHAR8_T +# ifndef _LIBCPP_HAS_NO_CHAR8_T is_same::__char_type, char8_t>::value || -#endif - is_same::__char_type, char>::value, +# endif + is_same::__char_type, char>::value, "u8path(Iter, Iter) requires Iter have a value_type of type 'char'" " or 'char8_t'"); -#if defined(_LIBCPP_WIN32API) +# if defined(_LIBCPP_WIN32API) string __tmp(__f, __l); using _CVT = __widen_from_utf8; - _VSTD::wstring __w; + std::wstring __w; __w.reserve(__tmp.size()); _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size()); return path(__w); -#else +# else return path(__f, __l); -#endif /* !_LIBCPP_WIN32API */ +# endif /* !_LIBCPP_WIN32API */ } -#if defined(_LIBCPP_WIN32API) -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T - typename enable_if<__is_pathable<_InputIt>::value, path>::type - u8path(_InputIt __f, _NullSentinel) { +# if defined(_LIBCPP_WIN32API) +template ::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(_InputIt __f, _NullSentinel) { static_assert( -#ifndef _LIBCPP_HAS_NO_CHAR8_T +# ifndef _LIBCPP_HAS_NO_CHAR8_T is_same::__char_type, char8_t>::value || -#endif - is_same::__char_type, char>::value, +# endif + is_same::__char_type, char>::value, "u8path(Iter, Iter) requires Iter have a value_type of type 'char'" " or 'char8_t'"); string __tmp; @@ -72,36 +67,34 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T for (; *__f != __sentinel; ++__f) __tmp.push_back(*__f); using _CVT = __widen_from_utf8; - _VSTD::wstring __w; + std::wstring __w; __w.reserve(__tmp.size()); _CVT()(back_inserter(__w), __tmp.data(), __tmp.data() + __tmp.size()); return path(__w); } -#endif /* _LIBCPP_WIN32API */ +# endif /* _LIBCPP_WIN32API */ -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_WITH_CHAR8_T - typename enable_if<__is_pathable<_Source>::value, path>::type - u8path(const _Source& __s) { +template ::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_WITH_CHAR8_T path u8path(const _Source& __s) { static_assert( -#ifndef _LIBCPP_HAS_NO_CHAR8_T +# ifndef _LIBCPP_HAS_NO_CHAR8_T is_same::__char_type, char8_t>::value || -#endif - is_same::__char_type, char>::value, +# endif + is_same::__char_type, char>::value, "u8path(Source const&) requires Source have a character type of type " "'char' or 'char8_t'"); -#if defined(_LIBCPP_WIN32API) +# if defined(_LIBCPP_WIN32API) using _Traits = __is_pathable<_Source>; - return u8path(_VSTD::__unwrap_iter(_Traits::__range_begin(__s)), _VSTD::__unwrap_iter(_Traits::__range_end(__s))); -#else + return u8path(std::__unwrap_iter(_Traits::__range_begin(__s)), std::__unwrap_iter(_Traits::__range_end(__s))); +# else return path(__s); -#endif +# endif } -_LIBCPP_AVAILABILITY_FILESYSTEM_POP +_LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY_POP _LIBCPP_END_NAMESPACE_FILESYSTEM -#endif // _LIBCPP_CXX03_LANG +#endif // _LIBCPP_STD_VER >= 17 #endif // _LIBCPP___FILESYSTEM_U8PATH_H diff --git a/third_party/libcxx/__format/buffer.h b/third_party/libcxx/__format/buffer.h index e74ca8f57..8598f0a1c 100644 --- a/third_party/libcxx/__format/buffer.h +++ b/third_party/libcxx/__format/buffer.h @@ -71,7 +71,7 @@ public: __obj_(__obj) {} _LIBCPP_HIDE_FROM_ABI void __reset(_CharT* __ptr, size_t __capacity) { - __ptr_ = __ptr; + __ptr_ = __ptr; __capacity_ = __capacity; } @@ -95,7 +95,7 @@ public: _LIBCPP_HIDE_FROM_ABI void __copy(basic_string_view<_InCharT> __str) { // When the underlying iterator is a simple iterator the __capacity_ is // infinite. For a string or container back_inserter it isn't. This means - // adding a large string the the buffer can cause some overhead. In that + // that adding a large string to the buffer can cause some overhead. In that // case a better approach could be: // - flush the buffer // - container.append(__str.begin(), __str.end()); @@ -107,19 +107,19 @@ public: size_t __n = __str.size(); __flush_on_overflow(__n); - if (__n <= __capacity_) { - _VSTD::copy_n(__str.data(), __n, _VSTD::addressof(__ptr_[__size_])); + if (__n < __capacity_) { // push_back requires the buffer to have room for at least one character (so use <). + std::copy_n(__str.data(), __n, std::addressof(__ptr_[__size_])); __size_ += __n; return; } // The output doesn't fit in the internal buffer. // Copy the data in "__capacity_" sized chunks. - _LIBCPP_ASSERT(__size_ == 0, "the buffer should be flushed by __flush_on_overflow"); + _LIBCPP_ASSERT_INTERNAL(__size_ == 0, "the buffer should be flushed by __flush_on_overflow"); const _InCharT* __first = __str.data(); do { - size_t __chunk = _VSTD::min(__n, __capacity_); - _VSTD::copy_n(__first, __chunk, _VSTD::addressof(__ptr_[__size_])); + size_t __chunk = std::min(__n, __capacity_); + std::copy_n(__first, __chunk, std::addressof(__ptr_[__size_])); __size_ = __chunk; __first += __chunk; __n -= __chunk; @@ -130,24 +130,26 @@ public: /// A std::transform wrapper. /// /// Like @ref __copy it may need to do type conversion. - template <__fmt_char_type _InCharT, class _UnaryOperation> - _LIBCPP_HIDE_FROM_ABI void __transform(const _InCharT* __first, const _InCharT* __last, _UnaryOperation __operation) { - _LIBCPP_ASSERT(__first <= __last, "not a valid range"); + template ::value_type> + _LIBCPP_HIDE_FROM_ABI void __transform(_Iterator __first, _Iterator __last, _UnaryOperation __operation) { + _LIBCPP_ASSERT_INTERNAL(__first <= __last, "not a valid range"); size_t __n = static_cast(__last - __first); __flush_on_overflow(__n); - if (__n <= __capacity_) { - _VSTD::transform(__first, __last, _VSTD::addressof(__ptr_[__size_]), _VSTD::move(__operation)); + if (__n < __capacity_) { // push_back requires the buffer to have room for at least one character (so use <). + std::transform(__first, __last, std::addressof(__ptr_[__size_]), std::move(__operation)); __size_ += __n; return; } // The output doesn't fit in the internal buffer. // Transform the data in "__capacity_" sized chunks. - _LIBCPP_ASSERT(__size_ == 0, "the buffer should be flushed by __flush_on_overflow"); + _LIBCPP_ASSERT_INTERNAL(__size_ == 0, "the buffer should be flushed by __flush_on_overflow"); do { - size_t __chunk = _VSTD::min(__n, __capacity_); - _VSTD::transform(__first, __first + __chunk, _VSTD::addressof(__ptr_[__size_]), __operation); + size_t __chunk = std::min(__n, __capacity_); + std::transform(__first, __first + __chunk, std::addressof(__ptr_[__size_]), __operation); __size_ = __chunk; __first += __chunk; __n -= __chunk; @@ -158,18 +160,18 @@ public: /// A \c fill_n wrapper. _LIBCPP_HIDE_FROM_ABI void __fill(size_t __n, _CharT __value) { __flush_on_overflow(__n); - if (__n <= __capacity_) { - _VSTD::fill_n(_VSTD::addressof(__ptr_[__size_]), __n, __value); + if (__n < __capacity_) { // push_back requires the buffer to have room for at least one character (so use <). + std::fill_n(std::addressof(__ptr_[__size_]), __n, __value); __size_ += __n; return; } // The output doesn't fit in the internal buffer. // Fill the buffer in "__capacity_" sized chunks. - _LIBCPP_ASSERT(__size_ == 0, "the buffer should be flushed by __flush_on_overflow"); + _LIBCPP_ASSERT_INTERNAL(__size_ == 0, "the buffer should be flushed by __flush_on_overflow"); do { - size_t __chunk = _VSTD::min(__n, __capacity_); - _VSTD::fill_n(_VSTD::addressof(__ptr_[__size_]), __chunk, __value); + size_t __chunk = std::min(__n, __capacity_); + std::fill_n(std::addressof(__ptr_[__size_]), __chunk, __value); __size_ = __chunk; __n -= __chunk; __flush(); @@ -251,19 +253,18 @@ template <__fmt_char_type _CharT> class _LIBCPP_TEMPLATE_VIS __direct_storage {}; template -concept __enable_direct_output = __fmt_char_type<_CharT> && +concept __enable_direct_output = + __fmt_char_type<_CharT> && (same_as<_OutIt, _CharT*> -#ifndef _LIBCPP_ENABLE_DEBUG_MODE - || same_as<_OutIt, __wrap_iter<_CharT*>> -#endif - ); + // TODO(hardening): the following check might not apply to hardened iterators and might need to be wrapped in an + // `#ifdef`. + || same_as<_OutIt, __wrap_iter<_CharT*>>); /// Write policy for directly writing to the underlying output. template class _LIBCPP_TEMPLATE_VIS __writer_direct { public: - _LIBCPP_HIDE_FROM_ABI explicit __writer_direct(_OutIt __out_it) - : __out_it_(__out_it) {} + _LIBCPP_HIDE_FROM_ABI explicit __writer_direct(_OutIt __out_it) : __out_it_(__out_it) {} _LIBCPP_HIDE_FROM_ABI _OutIt __out_it() { return __out_it_; } @@ -281,8 +282,7 @@ private: template class _LIBCPP_TEMPLATE_VIS __writer_iterator { public: - _LIBCPP_HIDE_FROM_ABI explicit __writer_iterator(_OutIt __out_it) - : __out_it_{_VSTD::move(__out_it)} {} + _LIBCPP_HIDE_FROM_ABI explicit __writer_iterator(_OutIt __out_it) : __out_it_{std::move(__out_it)} {} _LIBCPP_HIDE_FROM_ABI _OutIt __out_it() && { return std::move(__out_it_); } @@ -304,7 +304,8 @@ private: template concept __insertable = __enable_insertable<_Container> && __fmt_char_type && - requires(_Container& __t, add_pointer_t __first, + requires(_Container& __t, + add_pointer_t __first, add_pointer_t __last) { __t.insert(__t.end(), __first, __last); }; /// Extract the container type of a \ref back_insert_iterator. @@ -343,28 +344,29 @@ class _LIBCPP_TEMPLATE_VIS __writer_selector { using _Container = typename __back_insert_iterator_container<_OutIt>::type; public: - using type = conditional_t, __writer_container<_Container>, - conditional_t<__enable_direct_output<_OutIt, _CharT>, __writer_direct<_OutIt, _CharT>, - __writer_iterator<_OutIt, _CharT>>>; + using type = + conditional_t, + __writer_container<_Container>, + conditional_t<__enable_direct_output<_OutIt, _CharT>, + __writer_direct<_OutIt, _CharT>, + __writer_iterator<_OutIt, _CharT>>>; }; /// The generic formatting buffer. template -requires(output_iterator<_OutIt, const _CharT&>) class _LIBCPP_TEMPLATE_VIS - __format_buffer { + requires(output_iterator<_OutIt, const _CharT&>) +class _LIBCPP_TEMPLATE_VIS __format_buffer { using _Storage = - conditional_t<__enable_direct_output<_OutIt, _CharT>, - __direct_storage<_CharT>, __internal_storage<_CharT>>; + conditional_t<__enable_direct_output<_OutIt, _CharT>, __direct_storage<_CharT>, __internal_storage<_CharT>>; public: _LIBCPP_HIDE_FROM_ABI explicit __format_buffer(_OutIt __out_it) requires(same_as<_Storage, __internal_storage<_CharT>>) - : __output_(__storage_.__begin(), __storage_.__buffer_size, this), __writer_(_VSTD::move(__out_it)) {} + : __output_(__storage_.__begin(), __storage_.__buffer_size, this), __writer_(std::move(__out_it)) {} - _LIBCPP_HIDE_FROM_ABI explicit __format_buffer(_OutIt __out_it) requires( - same_as<_Storage, __direct_storage<_CharT>>) - : __output_(_VSTD::__unwrap_iter(__out_it), size_t(-1), this), - __writer_(_VSTD::move(__out_it)) {} + _LIBCPP_HIDE_FROM_ABI explicit __format_buffer(_OutIt __out_it) + requires(same_as<_Storage, __direct_storage<_CharT>>) + : __output_(std::__unwrap_iter(__out_it), size_t(-1), this), __writer_(std::move(__out_it)) {} _LIBCPP_HIDE_FROM_ABI auto __make_output_iterator() { return __output_.__make_output_iterator(); } @@ -372,7 +374,7 @@ public: _LIBCPP_HIDE_FROM_ABI _OutIt __out_it() && { __output_.__flush(); - return _VSTD::move(__writer_).__out_it(); + return std::move(__writer_).__out_it(); } private: @@ -411,11 +413,11 @@ struct _LIBCPP_TEMPLATE_VIS __format_to_n_buffer_base { public: _LIBCPP_HIDE_FROM_ABI explicit __format_to_n_buffer_base(_OutIt __out_it, _Size __max_size) - : __writer_(_VSTD::move(__out_it)), __max_size_(_VSTD::max(_Size(0), __max_size)) {} + : __writer_(std::move(__out_it)), __max_size_(std::max(_Size(0), __max_size)) {} _LIBCPP_HIDE_FROM_ABI void __flush(_CharT* __ptr, size_t __n) { if (_Size(__size_) <= __max_size_) - __writer_.__flush(__ptr, _VSTD::min(_Size(__n), __max_size_ - __size_)); + __writer_.__flush(__ptr, std::min(_Size(__n), __max_size_ - __size_)); __size_ += __n; } @@ -441,8 +443,8 @@ class _LIBCPP_TEMPLATE_VIS __format_to_n_buffer_base<_OutIt, _CharT, true> { public: _LIBCPP_HIDE_FROM_ABI explicit __format_to_n_buffer_base(_OutIt __out_it, _Size __max_size) - : __output_(_VSTD::__unwrap_iter(__out_it), __max_size, this), - __writer_(_VSTD::move(__out_it)), + : __output_(std::__unwrap_iter(__out_it), __max_size, this), + __writer_(std::move(__out_it)), __max_size_(__max_size) { if (__max_size <= 0) [[unlikely]] __output_.__reset(__storage_.__begin(), __storage_.__buffer_size); @@ -466,7 +468,7 @@ public: } else if (__size_ < __max_size_) { // Copies a part of the internal buffer to the output up to n characters. // See __output_buffer<_CharT>::__flush_on_overflow for more information. - _Size __s = _VSTD::min(_Size(__n), __max_size_ - __size_); + _Size __s = std::min(_Size(__n), __max_size_ - __size_); std::copy_n(__ptr, __s, __writer_.__out_it()); __writer_.__flush(__ptr, __s); } @@ -493,12 +495,12 @@ struct _LIBCPP_TEMPLATE_VIS __format_to_n_buffer final public: _LIBCPP_HIDE_FROM_ABI explicit __format_to_n_buffer(_OutIt __out_it, _Size __max_size) - : _Base(_VSTD::move(__out_it), __max_size) {} + : _Base(std::move(__out_it), __max_size) {} _LIBCPP_HIDE_FROM_ABI auto __make_output_iterator() { return this->__output_.__make_output_iterator(); } _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __result() && { this->__output_.__flush(); - return {_VSTD::move(this->__writer_).__out_it(), this->__size_}; + return {std::move(this->__writer_).__out_it(), this->__size_}; } }; @@ -529,6 +531,7 @@ public: struct __iterator { using difference_type = ptrdiff_t; + using value_type = _CharT; _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(__retarget_buffer& __buffer) : __buffer_(std::addressof(__buffer)) {} @@ -551,7 +554,14 @@ public: __retarget_buffer& operator=(const __retarget_buffer&) = delete; _LIBCPP_HIDE_FROM_ABI explicit __retarget_buffer(size_t __size_hint) { - auto __result = std::__allocate_at_least(__alloc_, __size_hint ? __size_hint : 256 / sizeof(_CharT)); + // When the initial size is very small a lot of resizes happen + // when elements added. So use a hard-coded minimum size. + // + // Note a size < 2 will not work + // - 0 there is no buffer, while push_back requires 1 empty element. + // - 1 multiplied by the grow factor is 1 and thus the buffer never + // grows. + auto __result = std::__allocate_at_least(__alloc_, std::max(__size_hint, 256 / sizeof(_CharT))); __ptr_ = __result.ptr; __capacity_ = __result.count; } @@ -582,9 +592,11 @@ public: __size_ += __n; } - template <__fmt_char_type _InCharT, class _UnaryOperation> - _LIBCPP_HIDE_FROM_ABI void __transform(const _InCharT* __first, const _InCharT* __last, _UnaryOperation __operation) { - _LIBCPP_ASSERT(__first <= __last, "not a valid range"); + template ::value_type> + _LIBCPP_HIDE_FROM_ABI void __transform(_Iterator __first, _Iterator __last, _UnaryOperation __operation) { + _LIBCPP_ASSERT_INTERNAL(__first <= __last, "not a valid range"); size_t __n = static_cast(__last - __first); if (__size_ + __n >= __capacity_) @@ -611,12 +623,12 @@ private: _LIBCPP_HIDE_FROM_ABI void __grow_buffer() { __grow_buffer(__capacity_ * 1.6); } _LIBCPP_HIDE_FROM_ABI void __grow_buffer(size_t __capacity) { - _LIBCPP_ASSERT(__capacity > __capacity_, "the buffer must grow"); + _LIBCPP_ASSERT_INTERNAL(__capacity > __capacity_, "the buffer must grow"); auto __result = std::__allocate_at_least(__alloc_, __capacity); auto __guard = std::__make_exception_guard([&] { allocator_traits<_Alloc>::deallocate(__alloc_, __result.ptr, __result.count); }); - // This shouldn't throw, but just to be safe. Not that at -O1 this + // This shouldn't throw, but just to be safe. Note that at -O1 this // guard is optimized away so there is no runtime overhead. std::uninitialized_move_n(__ptr_, __size_, __result.ptr); __guard.__complete(); diff --git a/third_party/libcxx/__format/concepts.h b/third_party/libcxx/__format/concepts.h index 62552f827..13380e9b9 100644 --- a/third_party/libcxx/__format/concepts.h +++ b/third_party/libcxx/__format/concepts.h @@ -13,11 +13,14 @@ #include <__concepts/same_as.h> #include <__concepts/semiregular.h> #include <__config> -#include <__format/format_fwd.h> #include <__format/format_parse_context.h> +#include <__fwd/format.h> +#include <__fwd/tuple.h> +#include <__tuple/tuple_size.h> #include <__type_traits/is_specialization.h> +#include <__type_traits/remove_const.h> +#include <__type_traits/remove_reference.h> #include <__utility/pair.h> -#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -43,17 +46,21 @@ concept __fmt_char_type = template using __fmt_iter_for = _CharT*; +template >> +concept __formattable_with = + semiregular<_Formatter> && + requires(_Formatter& __f, + const _Formatter& __cf, + _Tp&& __t, + _Context __fc, + basic_format_parse_context __pc) { + { __f.parse(__pc) } -> same_as; + { __cf.format(__t, __fc) } -> same_as; + }; + template concept __formattable = - (semiregular, _CharT>>) && - requires(formatter, _CharT> __f, - const formatter, _CharT> __cf, - _Tp __t, - basic_format_context<__fmt_iter_for<_CharT>, _CharT> __fc, - basic_format_parse_context<_CharT> __pc) { - { __f.parse(__pc) } -> same_as::iterator>; - { __cf.format(__t, __fc) } -> same_as<__fmt_iter_for<_CharT>>; - }; + __formattable_with, basic_format_context<__fmt_iter_for<_CharT>, _CharT>>; # if _LIBCPP_STD_VER >= 23 template @@ -69,7 +76,7 @@ concept __fmt_pair_like = __is_specialization_v<_Tp, pair> || (__is_specialization_v<_Tp, tuple> && tuple_size_v<_Tp> == 2); # endif //_LIBCPP_STD_VER >= 23 -#endif //_LIBCPP_STD_VER >= 20 +#endif //_LIBCPP_STD_VER >= 20 _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__format/container_adaptor.h b/third_party/libcxx/__format/container_adaptor.h index 9b66f4b83..9f49ca03b 100644 --- a/third_party/libcxx/__format/container_adaptor.h +++ b/third_party/libcxx/__format/container_adaptor.h @@ -10,17 +10,19 @@ #ifndef _LIBCPP___FORMAT_CONTAINER_ADAPTOR_H #define _LIBCPP___FORMAT_CONTAINER_ADAPTOR_H -#include <__availability> +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + #include <__config> #include <__format/concepts.h> #include <__format/formatter.h> #include <__format/range_default_formatter.h> -#include <__ranges/all.h> +#include <__fwd/queue.h> +#include <__fwd/stack.h> #include <__ranges/ref_view.h> #include <__type_traits/is_const.h> #include <__type_traits/maybe_const.h> -#include -#include _LIBCPP_BEGIN_NAMESPACE_STD diff --git a/third_party/libcxx/__format/escaped_output_table.h b/third_party/libcxx/__format/escaped_output_table.h index 222847e6a..f7be2dc61 100644 --- a/third_party/libcxx/__format/escaped_output_table.h +++ b/third_party/libcxx/__format/escaped_output_table.h @@ -75,14 +75,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 23 namespace __escaped_output_table { +// clang-format off /// The entries of the characters to escape in format's debug string. /// /// Contains the entries for [format.string.escaped]/2.2.1.2.1 -/// CE is a Unicode encoding and C corresponds to either a UCS scalar value -/// whose Unicode property General_Category has a value in the groups -/// Separator (Z) or Other (C) or to a UCS scalar value which has the Unicode -/// property Grapheme_Extend=Yes, as described by table 12 of UAX #44 +/// CE is a Unicode encoding and C corresponds to a UCS scalar value whose +/// Unicode property General_Category has a value in the groups Separator (Z) +/// or Other (C), as described by table 12 of UAX #44 /// /// Separator (Z) consists of General_Category /// - Space_Separator, @@ -97,7 +97,6 @@ namespace __escaped_output_table { /// - Unassigned. /// /// The data is generated from -/// - https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt /// - https://www.unicode.org/Public/UCD/latest/ucd/extracted/DerivedGeneralCategory.txt /// /// The table is similar to the table @@ -106,929 +105,755 @@ namespace __escaped_output_table { /// table lacks a property, thus having more bits available for the size. /// /// The data has 2 values: -/// - bits [0, 10] The size of the range, allowing 2048 elements. -/// - bits [11, 31] The lower bound code point of the range. The upper bound of -/// the range is lower bound + size. -inline constexpr uint32_t __entries[893] = { - 0x00000020, - 0x0003f821, - 0x00056800, - 0x0018006f, - 0x001bc001, - 0x001c0003, - 0x001c5800, - 0x001c6800, - 0x001d1000, - 0x00241806, - 0x00298000, - 0x002ab801, - 0x002c5801, - 0x002c802d, - 0x002df800, - 0x002e0801, - 0x002e2001, - 0x002e3808, - 0x002f5803, - 0x002fa810, - 0x0030800a, - 0x0030e000, - 0x00325814, - 0x00338000, - 0x0036b007, - 0x0036f805, - 0x00373801, - 0x00375003, - 0x00387001, - 0x00388800, - 0x0039801c, - 0x003d300a, - 0x003d900d, - 0x003f5808, - 0x003fd802, - 0x0040b003, - 0x0040d808, - 0x00412802, - 0x00414806, - 0x0041f800, - 0x0042c804, - 0x0042f800, - 0x00435804, - 0x00447810, - 0x00465038, - 0x0049d000, - 0x0049e000, - 0x004a0807, - 0x004a6800, - 0x004a8806, - 0x004b1001, - 0x004c0800, - 0x004c2000, - 0x004c6801, - 0x004c8801, - 0x004d4800, - 0x004d8800, - 0x004d9802, - 0x004dd002, - 0x004df000, - 0x004e0805, - 0x004e4801, - 0x004e6800, - 0x004e780c, - 0x004ef000, - 0x004f1003, - 0x004ff004, - 0x00502000, - 0x00505803, - 0x00508801, - 0x00514800, - 0x00518800, - 0x0051a000, - 0x0051b800, - 0x0051d003, - 0x00520817, - 0x0052e800, - 0x0052f806, - 0x00538001, - 0x0053a800, - 0x0053b80b, - 0x00542000, - 0x00547000, - 0x00549000, - 0x00554800, - 0x00558800, - 0x0055a000, - 0x0055d002, - 0x00560807, - 0x00565000, - 0x00566802, - 0x0056880e, - 0x00571003, - 0x00579006, - 0x0057d007, - 0x00582000, - 0x00586801, - 0x00588801, - 0x00594800, - 0x00598800, - 0x0059a000, - 0x0059d002, - 0x0059f001, - 0x005a0805, - 0x005a4801, - 0x005a680e, - 0x005af000, - 0x005b1003, - 0x005bc00a, - 0x005c2000, - 0x005c5802, - 0x005c8800, - 0x005cb002, - 0x005cd800, - 0x005ce800, - 0x005d0002, - 0x005d2802, - 0x005d5802, - 0x005dd004, - 0x005e0000, - 0x005e1802, - 0x005e4800, - 0x005e6802, - 0x005e8814, - 0x005fd805, - 0x00602000, - 0x00606800, - 0x00608800, - 0x00614800, - 0x0061d002, - 0x0061f002, - 0x00622812, - 0x0062d801, - 0x0062f001, - 0x00631003, - 0x00638006, - 0x00640800, - 0x00646800, - 0x00648800, - 0x00654800, - 0x0065a000, - 0x0065d002, - 0x0065f800, - 0x00661000, - 0x00662801, - 0x00664800, - 0x00666010, - 0x0066f800, - 0x00671003, - 0x00678000, - 0x0067a00d, - 0x00686800, - 0x00688800, - 0x0069d801, - 0x0069f000, - 0x006a0804, - 0x006a4800, - 0x006a6800, - 0x006a8003, - 0x006ab800, - 0x006b1003, - 0x006c0001, - 0x006c2000, - 0x006cb802, - 0x006d9000, - 0x006de000, - 0x006df001, - 0x006e3808, - 0x006e9005, - 0x006ef806, - 0x006f8001, - 0x006fa80b, - 0x00718800, - 0x0071a00a, - 0x00723807, - 0x0072e024, - 0x00741800, - 0x00742800, - 0x00745800, - 0x00752000, - 0x00753000, - 0x00758800, - 0x0075a008, - 0x0075f001, - 0x00762800, - 0x00763808, - 0x0076d001, - 0x0077001f, - 0x0078c001, - 0x0079a800, - 0x0079b800, - 0x0079c800, - 0x007a4000, - 0x007b6811, - 0x007c0004, - 0x007c3001, - 0x007c6830, - 0x007e3000, - 0x007e6800, - 0x007ed824, - 0x00816803, - 0x00819005, - 0x0081c801, - 0x0081e801, - 0x0082c001, - 0x0082f002, - 0x00838803, - 0x00841000, - 0x00842801, - 0x00846800, - 0x0084e800, - 0x00863000, - 0x00864004, - 0x00867001, - 0x00924800, - 0x00927001, - 0x0092b800, - 0x0092c800, - 0x0092f001, - 0x00944800, - 0x00947001, - 0x00958800, - 0x0095b001, - 0x0095f800, - 0x00960800, - 0x00963001, - 0x0096b800, - 0x00988800, - 0x0098b001, - 0x009ad804, - 0x009be802, - 0x009cd005, - 0x009fb001, - 0x009ff001, - 0x00b40000, - 0x00b4e802, - 0x00b7c806, - 0x00b89002, - 0x00b8b008, - 0x00b99001, - 0x00b9b808, - 0x00ba900d, - 0x00bb6800, - 0x00bb880e, - 0x00bda001, - 0x00bdb806, - 0x00be3000, - 0x00be480a, - 0x00bee802, - 0x00bf5005, - 0x00bfd005, - 0x00c05804, - 0x00c0d005, - 0x00c3c806, - 0x00c42801, - 0x00c54800, - 0x00c55804, - 0x00c7b009, - 0x00c8f803, - 0x00c93801, - 0x00c96003, - 0x00c99000, - 0x00c9c806, - 0x00ca0802, - 0x00cb7001, - 0x00cba80a, - 0x00cd6003, - 0x00ce5005, - 0x00ced802, - 0x00d0b801, - 0x00d0d802, - 0x00d2b000, - 0x00d2c008, - 0x00d31000, - 0x00d32807, - 0x00d3980c, - 0x00d45005, - 0x00d4d005, - 0x00d57055, - 0x00d9a006, - 0x00d9e000, - 0x00da1000, - 0x00da6802, - 0x00db5808, - 0x00dbf802, - 0x00dd1003, - 0x00dd4001, - 0x00dd5802, - 0x00df3000, - 0x00df4001, - 0x00df6800, - 0x00df7802, - 0x00dfa007, - 0x00e16007, - 0x00e1b004, - 0x00e25002, - 0x00e44806, - 0x00e5d801, - 0x00e6400a, - 0x00e6a00c, - 0x00e71006, - 0x00e76800, - 0x00e7a000, - 0x00e7c001, - 0x00e7d804, - 0x00ee003f, - 0x00f8b001, - 0x00f8f001, - 0x00fa3001, - 0x00fa7001, - 0x00fac000, - 0x00fad000, - 0x00fae000, - 0x00faf000, - 0x00fbf001, - 0x00fda800, - 0x00fe2800, - 0x00fea001, - 0x00fee000, - 0x00ff8001, - 0x00ffa800, - 0x00fff810, - 0x01014007, - 0x0102f810, - 0x01039001, - 0x01047800, - 0x0104e802, - 0x0106083e, - 0x010c6003, - 0x01213818, - 0x01225814, - 0x015ba001, - 0x015cb000, - 0x01677802, - 0x0167a004, - 0x01693000, - 0x01694004, - 0x01697001, - 0x016b4006, - 0x016b880e, - 0x016cb808, - 0x016d3800, - 0x016d7800, - 0x016db800, - 0x016df800, - 0x016e3800, - 0x016e7800, - 0x016eb800, - 0x016ef820, - 0x0172f021, - 0x0174d000, - 0x0177a00b, - 0x017eb019, - 0x017fe004, - 0x01815005, - 0x01820000, - 0x0184b803, - 0x01880004, - 0x01898000, - 0x018c7800, - 0x018f200b, - 0x0190f800, - 0x05246802, - 0x05263808, - 0x05316013, - 0x05337803, - 0x0533a009, - 0x0534f001, - 0x05378001, - 0x0537c007, - 0x053e5804, - 0x053e9000, - 0x053ea000, - 0x053ed017, - 0x05401000, - 0x05403000, - 0x05405800, - 0x05412801, - 0x05416003, - 0x0541d005, - 0x0543c007, - 0x05462009, - 0x0546d017, - 0x0547f800, - 0x05493007, - 0x054a380a, - 0x054aa00a, - 0x054be805, - 0x054d9800, - 0x054db003, - 0x054de001, - 0x054e7000, - 0x054ed003, - 0x054f2800, - 0x054ff800, - 0x05514805, - 0x05518801, - 0x0551a80a, - 0x05521800, - 0x05526000, - 0x05527001, - 0x0552d001, - 0x0553e000, - 0x05558000, - 0x05559002, - 0x0555b801, - 0x0555f001, - 0x05560800, - 0x05561817, - 0x05576001, - 0x0557b00a, - 0x05583801, - 0x05587801, - 0x0558b808, - 0x05593800, - 0x05597800, - 0x055b6003, - 0x055f2800, - 0x055f4000, - 0x055f6802, - 0x055fd005, - 0x06bd200b, - 0x06be3803, - 0x06bfe7ff, - 0x06ffe7ff, - 0x073fe7ff, - 0x077fe7ff, - 0x07bfe103, - 0x07d37001, - 0x07d6d025, - 0x07d8380b, - 0x07d8c004, - 0x07d8f000, - 0x07d9b800, - 0x07d9e800, - 0x07d9f800, - 0x07da1000, - 0x07da2800, - 0x07de180f, - 0x07ec8001, - 0x07ee4006, - 0x07ee801f, - 0x07f0000f, - 0x07f0d015, - 0x07f29800, - 0x07f33800, - 0x07f36003, - 0x07f3a800, - 0x07f7e803, - 0x07fcf001, - 0x07fdf802, - 0x07fe4001, - 0x07fe8001, - 0x07fec001, - 0x07fee802, - 0x07ff3800, - 0x07ff780c, - 0x07fff001, - 0x08006000, - 0x08013800, - 0x0801d800, - 0x0801f000, - 0x08027001, - 0x0802f021, - 0x0807d804, - 0x08081803, - 0x0809a002, - 0x080c7800, - 0x080ce802, - 0x080d082e, - 0x080fe882, - 0x0814e802, - 0x0816880f, - 0x0817e003, - 0x08192008, - 0x081a5804, - 0x081bb009, - 0x081cf000, - 0x081e2003, - 0x081eb029, - 0x0824f001, - 0x08255005, - 0x0826a003, - 0x0827e003, - 0x08294007, - 0x082b200a, - 0x082bd800, - 0x082c5800, - 0x082c9800, - 0x082cb000, - 0x082d1000, - 0x082d9000, - 0x082dd000, - 0x082de842, - 0x0839b808, - 0x083ab009, - 0x083b4017, - 0x083c3000, - 0x083d8800, - 0x083dd844, - 0x08403001, - 0x08404800, - 0x0841b000, - 0x0841c802, - 0x0841e801, - 0x0842b000, - 0x0844f807, - 0x0845802f, - 0x08479800, - 0x0847b004, - 0x0848e002, - 0x0849d004, - 0x084a003f, - 0x084dc003, - 0x084e8001, - 0x0850080e, - 0x0850a000, - 0x0850c000, - 0x0851b009, - 0x08524806, - 0x0852c806, - 0x0855001f, - 0x08572805, - 0x0857b808, - 0x0859b002, - 0x085ab001, - 0x085b9804, - 0x085c9006, - 0x085ce80b, - 0x085d804f, - 0x08624836, - 0x0865980c, - 0x08679806, - 0x0869200b, - 0x0869d125, - 0x0873f800, - 0x08755002, - 0x08757001, - 0x0875904d, - 0x08794007, - 0x087a300a, - 0x087ad015, - 0x087c1003, - 0x087c5025, - 0x087e6013, - 0x087fb808, - 0x08800800, - 0x0881c00e, - 0x08827003, - 0x08838000, - 0x08839801, - 0x0883b00b, - 0x08859803, - 0x0885c801, - 0x0885e800, - 0x0886100d, - 0x08874806, - 0x0887d008, - 0x08893804, - 0x08896808, - 0x088a4007, - 0x088b9800, - 0x088bb80a, - 0x088db008, - 0x088e4803, - 0x088e7800, - 0x088f0000, - 0x088fa80a, - 0x08909000, - 0x08917802, - 0x0891a000, - 0x0891b001, - 0x0891f000, - 0x0892083e, - 0x08943800, - 0x08944800, - 0x08947000, - 0x0894f000, - 0x08955005, - 0x0896f800, - 0x0897180c, - 0x0897d007, - 0x08982000, - 0x08986801, - 0x08988801, - 0x08994800, - 0x08998800, - 0x0899a000, - 0x0899d002, - 0x0899f000, - 0x089a0000, - 0x089a2801, - 0x089a4801, - 0x089a7001, - 0x089a880b, - 0x089b209b, - 0x08a1c007, - 0x08a21002, - 0x08a23000, - 0x08a2e000, - 0x08a2f000, - 0x08a3101d, - 0x08a58000, - 0x08a59805, - 0x08a5d000, - 0x08a5e800, - 0x08a5f801, - 0x08a61001, - 0x08a64007, - 0x08a6d0a5, - 0x08ad7800, - 0x08ad9005, - 0x08ade001, - 0x08adf801, - 0x08aee023, - 0x08b19807, - 0x08b1e800, - 0x08b1f801, - 0x08b2280a, - 0x08b2d005, - 0x08b36812, - 0x08b55800, - 0x08b56800, - 0x08b58005, - 0x08b5b800, - 0x08b5d005, - 0x08b65035, - 0x08b8d804, - 0x08b91003, - 0x08b93808, - 0x08ba38b8, - 0x08c17808, - 0x08c1c801, - 0x08c1e063, - 0x08c7980b, - 0x08c83801, - 0x08c85001, - 0x08c8a000, - 0x08c8b800, - 0x08c98000, - 0x08c9b000, - 0x08c9c803, - 0x08c9f000, - 0x08ca1800, - 0x08ca3808, - 0x08cad045, - 0x08cd4001, - 0x08cea007, - 0x08cf0000, - 0x08cf281a, - 0x08d00809, - 0x08d19805, - 0x08d1d803, - 0x08d23808, - 0x08d28805, - 0x08d2c802, - 0x08d4500c, - 0x08d4c001, - 0x08d5180c, - 0x08d7c806, - 0x08d850f5, - 0x08e04800, - 0x08e1800d, - 0x08e1f800, - 0x08e23009, - 0x08e36802, - 0x08e48018, - 0x08e55006, - 0x08e59001, - 0x08e5a84a, - 0x08e83800, - 0x08e85000, - 0x08e98814, - 0x08ea3808, - 0x08ead005, - 0x08eb3000, - 0x08eb4800, - 0x08ec7803, - 0x08eca800, - 0x08ecb800, - 0x08ecc806, - 0x08ed5135, - 0x08f79801, - 0x08f7c808, - 0x08f88800, - 0x08f9b007, - 0x08fa0000, - 0x08fa1000, - 0x08fad055, - 0x08fd880e, - 0x08ff900c, - 0x091cd065, - 0x09237800, - 0x0923a80a, - 0x092a27ff, - 0x096a224b, - 0x097f980c, - 0x09a18010, - 0x09a23fff, - 0x09e23fb8, - 0x0a323fff, - 0x0a723fff, - 0x0ab23fff, - 0x0af23fff, - 0x0b3239b8, - 0x0b51c806, - 0x0b52f800, - 0x0b535003, - 0x0b55f800, - 0x0b565005, - 0x0b577006, - 0x0b57b009, - 0x0b598006, - 0x0b5a3009, - 0x0b5ad000, - 0x0b5b1000, - 0x0b5bc004, - 0x0b5c82af, - 0x0b74d864, - 0x0b7a5804, - 0x0b7c400a, - 0x0b7d003f, - 0x0b7f200b, - 0x0b7f900d, - 0x0c3fc007, - 0x0c66b029, - 0x0c684fff, - 0x0ca84fff, - 0x0ce84fff, - 0x0d284fff, - 0x0d684ae6, - 0x0d7fa000, - 0x0d7fe000, - 0x0d7ff800, - 0x0d89180e, - 0x0d89981c, - 0x0d8a9801, - 0x0d8ab00d, - 0x0d8b4007, - 0x0d97e7ff, - 0x0dd7e103, - 0x0de35804, - 0x0de3e802, - 0x0de44806, - 0x0de4d001, - 0x0de4e801, - 0x0de507ff, - 0x0e2507ff, - 0x0e6502af, - 0x0e7e203b, - 0x0e87b009, - 0x0e893801, - 0x0e8b2800, - 0x0e8b3802, - 0x0e8b7014, - 0x0e8c2806, - 0x0e8d5003, - 0x0e8f5814, - 0x0e921002, - 0x0e923079, - 0x0e96a00b, - 0x0e97a00b, - 0x0e9ab808, - 0x0e9bc886, - 0x0ea2a800, - 0x0ea4e800, - 0x0ea50001, - 0x0ea51801, - 0x0ea53801, - 0x0ea56800, - 0x0ea5d000, - 0x0ea5e000, - 0x0ea62000, - 0x0ea83000, - 0x0ea85801, - 0x0ea8a800, - 0x0ea8e800, - 0x0ea9d000, - 0x0ea9f800, - 0x0eaa2800, - 0x0eaa3802, - 0x0eaa8800, - 0x0eb53001, - 0x0ebe6001, - 0x0ed00036, - 0x0ed1d831, - 0x0ed3a800, - 0x0ed42000, - 0x0ed46473, - 0x0ef8f805, - 0x0ef95904, - 0x0f037091, - 0x0f096809, - 0x0f09f001, - 0x0f0a5003, - 0x0f0a813f, - 0x0f157011, - 0x0f176003, - 0x0f17d004, - 0x0f1801cf, - 0x0f276003, - 0x0f27d2e5, - 0x0f3f3800, - 0x0f3f6000, - 0x0f3f7800, - 0x0f3ff800, - 0x0f462801, - 0x0f46802f, - 0x0f4a2006, - 0x0f4a6003, - 0x0f4ad003, - 0x0f4b0310, - 0x0f65a84b, - 0x0f69f0c1, - 0x0f702000, - 0x0f710000, - 0x0f711800, - 0x0f712801, - 0x0f714000, - 0x0f719800, - 0x0f71c000, - 0x0f71d000, - 0x0f71e005, - 0x0f721803, - 0x0f724000, - 0x0f725000, - 0x0f726000, - 0x0f728000, - 0x0f729800, - 0x0f72a801, - 0x0f72c000, - 0x0f72d000, - 0x0f72e000, - 0x0f72f000, - 0x0f730000, - 0x0f731800, - 0x0f732801, - 0x0f735800, - 0x0f739800, - 0x0f73c000, - 0x0f73e800, - 0x0f73f800, - 0x0f745000, - 0x0f74e004, - 0x0f752000, - 0x0f755000, - 0x0f75e033, - 0x0f77910d, - 0x0f816003, - 0x0f84a00b, - 0x0f857801, - 0x0f860000, - 0x0f868000, - 0x0f87b009, - 0x0f8d7037, - 0x0f90180c, - 0x0f91e003, - 0x0f924806, - 0x0f92900d, - 0x0f933099, - 0x0fb6c003, - 0x0fb76802, - 0x0fb7e802, - 0x0fbbb803, - 0x0fbed005, - 0x0fbf6003, - 0x0fbf880e, - 0x0fc06003, - 0x0fc24007, - 0x0fc2d005, - 0x0fc44007, - 0x0fc57001, - 0x0fc5904d, - 0x0fd2a00b, - 0x0fd37001, - 0x0fd3e802, - 0x0fd44806, - 0x0fd5f000, - 0x0fd63007, - 0x0fd6e003, - 0x0fd74806, - 0x0fd7c806, - 0x0fdc9800, - 0x0fde5824, - 0x0fdfd405, - 0x1537001f, - 0x15b9d005, - 0x15c0f001, - 0x1675100d, - 0x175f0fff, - 0x179f0c1e, - 0x17d0f5e1, - 0x189a5804}; - -/// At the end of the valid Unicode code points space a lot of code points are -/// either reserved or a noncharacter. Adding all these entries to the -/// lookup table would add 446 entries to the table (in Unicode 14). -/// Instead the only the start of the region is stored, every code point in -/// this region needs to be escaped. -inline constexpr uint32_t __unallocated_region_lower_bound = 0x000323b0; +/// - bits [0, 13] The size of the range, allowing 16384 elements. +/// - bits [14, 31] The lower bound code point of the range. The upper bound of +/// the range is lower bound + size. Note the code expects code units the fit +/// into 18 bits, instead of the 21 bits needed for the full Unicode range. +_LIBCPP_HIDE_FROM_ABI inline constexpr uint32_t __entries[711] = { + 0x00000020 /* 00000000 - 00000020 [ 33] */, + 0x001fc021 /* 0000007f - 000000a0 [ 34] */, + 0x002b4000 /* 000000ad - 000000ad [ 1] */, + 0x00de0001 /* 00000378 - 00000379 [ 2] */, + 0x00e00003 /* 00000380 - 00000383 [ 4] */, + 0x00e2c000 /* 0000038b - 0000038b [ 1] */, + 0x00e34000 /* 0000038d - 0000038d [ 1] */, + 0x00e88000 /* 000003a2 - 000003a2 [ 1] */, + 0x014c0000 /* 00000530 - 00000530 [ 1] */, + 0x0155c001 /* 00000557 - 00000558 [ 2] */, + 0x0162c001 /* 0000058b - 0000058c [ 2] */, + 0x01640000 /* 00000590 - 00000590 [ 1] */, + 0x01720007 /* 000005c8 - 000005cf [ 8] */, + 0x017ac003 /* 000005eb - 000005ee [ 4] */, + 0x017d4010 /* 000005f5 - 00000605 [ 17] */, + 0x01870000 /* 0000061c - 0000061c [ 1] */, + 0x01b74000 /* 000006dd - 000006dd [ 1] */, + 0x01c38001 /* 0000070e - 0000070f [ 2] */, + 0x01d2c001 /* 0000074b - 0000074c [ 2] */, + 0x01ec800d /* 000007b2 - 000007bf [ 14] */, + 0x01fec001 /* 000007fb - 000007fc [ 2] */, + 0x020b8001 /* 0000082e - 0000082f [ 2] */, + 0x020fc000 /* 0000083f - 0000083f [ 1] */, + 0x02170001 /* 0000085c - 0000085d [ 2] */, + 0x0217c000 /* 0000085f - 0000085f [ 1] */, + 0x021ac004 /* 0000086b - 0000086f [ 5] */, + 0x0223c008 /* 0000088f - 00000897 [ 9] */, + 0x02388000 /* 000008e2 - 000008e2 [ 1] */, + 0x02610000 /* 00000984 - 00000984 [ 1] */, + 0x02634001 /* 0000098d - 0000098e [ 2] */, + 0x02644001 /* 00000991 - 00000992 [ 2] */, + 0x026a4000 /* 000009a9 - 000009a9 [ 1] */, + 0x026c4000 /* 000009b1 - 000009b1 [ 1] */, + 0x026cc002 /* 000009b3 - 000009b5 [ 3] */, + 0x026e8001 /* 000009ba - 000009bb [ 2] */, + 0x02714001 /* 000009c5 - 000009c6 [ 2] */, + 0x02724001 /* 000009c9 - 000009ca [ 2] */, + 0x0273c007 /* 000009cf - 000009d6 [ 8] */, + 0x02760003 /* 000009d8 - 000009db [ 4] */, + 0x02778000 /* 000009de - 000009de [ 1] */, + 0x02790001 /* 000009e4 - 000009e5 [ 2] */, + 0x027fc001 /* 000009ff - 00000a00 [ 2] */, + 0x02810000 /* 00000a04 - 00000a04 [ 1] */, + 0x0282c003 /* 00000a0b - 00000a0e [ 4] */, + 0x02844001 /* 00000a11 - 00000a12 [ 2] */, + 0x028a4000 /* 00000a29 - 00000a29 [ 1] */, + 0x028c4000 /* 00000a31 - 00000a31 [ 1] */, + 0x028d0000 /* 00000a34 - 00000a34 [ 1] */, + 0x028dc000 /* 00000a37 - 00000a37 [ 1] */, + 0x028e8001 /* 00000a3a - 00000a3b [ 2] */, + 0x028f4000 /* 00000a3d - 00000a3d [ 1] */, + 0x0290c003 /* 00000a43 - 00000a46 [ 4] */, + 0x02924001 /* 00000a49 - 00000a4a [ 2] */, + 0x02938002 /* 00000a4e - 00000a50 [ 3] */, + 0x02948006 /* 00000a52 - 00000a58 [ 7] */, + 0x02974000 /* 00000a5d - 00000a5d [ 1] */, + 0x0297c006 /* 00000a5f - 00000a65 [ 7] */, + 0x029dc009 /* 00000a77 - 00000a80 [ 10] */, + 0x02a10000 /* 00000a84 - 00000a84 [ 1] */, + 0x02a38000 /* 00000a8e - 00000a8e [ 1] */, + 0x02a48000 /* 00000a92 - 00000a92 [ 1] */, + 0x02aa4000 /* 00000aa9 - 00000aa9 [ 1] */, + 0x02ac4000 /* 00000ab1 - 00000ab1 [ 1] */, + 0x02ad0000 /* 00000ab4 - 00000ab4 [ 1] */, + 0x02ae8001 /* 00000aba - 00000abb [ 2] */, + 0x02b18000 /* 00000ac6 - 00000ac6 [ 1] */, + 0x02b28000 /* 00000aca - 00000aca [ 1] */, + 0x02b38001 /* 00000ace - 00000acf [ 2] */, + 0x02b4400e /* 00000ad1 - 00000adf [ 15] */, + 0x02b90001 /* 00000ae4 - 00000ae5 [ 2] */, + 0x02bc8006 /* 00000af2 - 00000af8 [ 7] */, + 0x02c00000 /* 00000b00 - 00000b00 [ 1] */, + 0x02c10000 /* 00000b04 - 00000b04 [ 1] */, + 0x02c34001 /* 00000b0d - 00000b0e [ 2] */, + 0x02c44001 /* 00000b11 - 00000b12 [ 2] */, + 0x02ca4000 /* 00000b29 - 00000b29 [ 1] */, + 0x02cc4000 /* 00000b31 - 00000b31 [ 1] */, + 0x02cd0000 /* 00000b34 - 00000b34 [ 1] */, + 0x02ce8001 /* 00000b3a - 00000b3b [ 2] */, + 0x02d14001 /* 00000b45 - 00000b46 [ 2] */, + 0x02d24001 /* 00000b49 - 00000b4a [ 2] */, + 0x02d38006 /* 00000b4e - 00000b54 [ 7] */, + 0x02d60003 /* 00000b58 - 00000b5b [ 4] */, + 0x02d78000 /* 00000b5e - 00000b5e [ 1] */, + 0x02d90001 /* 00000b64 - 00000b65 [ 2] */, + 0x02de0009 /* 00000b78 - 00000b81 [ 10] */, + 0x02e10000 /* 00000b84 - 00000b84 [ 1] */, + 0x02e2c002 /* 00000b8b - 00000b8d [ 3] */, + 0x02e44000 /* 00000b91 - 00000b91 [ 1] */, + 0x02e58002 /* 00000b96 - 00000b98 [ 3] */, + 0x02e6c000 /* 00000b9b - 00000b9b [ 1] */, + 0x02e74000 /* 00000b9d - 00000b9d [ 1] */, + 0x02e80002 /* 00000ba0 - 00000ba2 [ 3] */, + 0x02e94002 /* 00000ba5 - 00000ba7 [ 3] */, + 0x02eac002 /* 00000bab - 00000bad [ 3] */, + 0x02ee8003 /* 00000bba - 00000bbd [ 4] */, + 0x02f0c002 /* 00000bc3 - 00000bc5 [ 3] */, + 0x02f24000 /* 00000bc9 - 00000bc9 [ 1] */, + 0x02f38001 /* 00000bce - 00000bcf [ 2] */, + 0x02f44005 /* 00000bd1 - 00000bd6 [ 6] */, + 0x02f6000d /* 00000bd8 - 00000be5 [ 14] */, + 0x02fec004 /* 00000bfb - 00000bff [ 5] */, + 0x03034000 /* 00000c0d - 00000c0d [ 1] */, + 0x03044000 /* 00000c11 - 00000c11 [ 1] */, + 0x030a4000 /* 00000c29 - 00000c29 [ 1] */, + 0x030e8001 /* 00000c3a - 00000c3b [ 2] */, + 0x03114000 /* 00000c45 - 00000c45 [ 1] */, + 0x03124000 /* 00000c49 - 00000c49 [ 1] */, + 0x03138006 /* 00000c4e - 00000c54 [ 7] */, + 0x0315c000 /* 00000c57 - 00000c57 [ 1] */, + 0x0316c001 /* 00000c5b - 00000c5c [ 2] */, + 0x03178001 /* 00000c5e - 00000c5f [ 2] */, + 0x03190001 /* 00000c64 - 00000c65 [ 2] */, + 0x031c0006 /* 00000c70 - 00000c76 [ 7] */, + 0x03234000 /* 00000c8d - 00000c8d [ 1] */, + 0x03244000 /* 00000c91 - 00000c91 [ 1] */, + 0x032a4000 /* 00000ca9 - 00000ca9 [ 1] */, + 0x032d0000 /* 00000cb4 - 00000cb4 [ 1] */, + 0x032e8001 /* 00000cba - 00000cbb [ 2] */, + 0x03314000 /* 00000cc5 - 00000cc5 [ 1] */, + 0x03324000 /* 00000cc9 - 00000cc9 [ 1] */, + 0x03338006 /* 00000cce - 00000cd4 [ 7] */, + 0x0335c005 /* 00000cd7 - 00000cdc [ 6] */, + 0x0337c000 /* 00000cdf - 00000cdf [ 1] */, + 0x03390001 /* 00000ce4 - 00000ce5 [ 2] */, + 0x033c0000 /* 00000cf0 - 00000cf0 [ 1] */, + 0x033d000b /* 00000cf4 - 00000cff [ 12] */, + 0x03434000 /* 00000d0d - 00000d0d [ 1] */, + 0x03444000 /* 00000d11 - 00000d11 [ 1] */, + 0x03514000 /* 00000d45 - 00000d45 [ 1] */, + 0x03524000 /* 00000d49 - 00000d49 [ 1] */, + 0x03540003 /* 00000d50 - 00000d53 [ 4] */, + 0x03590001 /* 00000d64 - 00000d65 [ 2] */, + 0x03600000 /* 00000d80 - 00000d80 [ 1] */, + 0x03610000 /* 00000d84 - 00000d84 [ 1] */, + 0x0365c002 /* 00000d97 - 00000d99 [ 3] */, + 0x036c8000 /* 00000db2 - 00000db2 [ 1] */, + 0x036f0000 /* 00000dbc - 00000dbc [ 1] */, + 0x036f8001 /* 00000dbe - 00000dbf [ 2] */, + 0x0371c002 /* 00000dc7 - 00000dc9 [ 3] */, + 0x0372c003 /* 00000dcb - 00000dce [ 4] */, + 0x03754000 /* 00000dd5 - 00000dd5 [ 1] */, + 0x0375c000 /* 00000dd7 - 00000dd7 [ 1] */, + 0x03780005 /* 00000de0 - 00000de5 [ 6] */, + 0x037c0001 /* 00000df0 - 00000df1 [ 2] */, + 0x037d400b /* 00000df5 - 00000e00 [ 12] */, + 0x038ec003 /* 00000e3b - 00000e3e [ 4] */, + 0x03970024 /* 00000e5c - 00000e80 [ 37] */, + 0x03a0c000 /* 00000e83 - 00000e83 [ 1] */, + 0x03a14000 /* 00000e85 - 00000e85 [ 1] */, + 0x03a2c000 /* 00000e8b - 00000e8b [ 1] */, + 0x03a90000 /* 00000ea4 - 00000ea4 [ 1] */, + 0x03a98000 /* 00000ea6 - 00000ea6 [ 1] */, + 0x03af8001 /* 00000ebe - 00000ebf [ 2] */, + 0x03b14000 /* 00000ec5 - 00000ec5 [ 1] */, + 0x03b1c000 /* 00000ec7 - 00000ec7 [ 1] */, + 0x03b3c000 /* 00000ecf - 00000ecf [ 1] */, + 0x03b68001 /* 00000eda - 00000edb [ 2] */, + 0x03b8001f /* 00000ee0 - 00000eff [ 32] */, + 0x03d20000 /* 00000f48 - 00000f48 [ 1] */, + 0x03db4003 /* 00000f6d - 00000f70 [ 4] */, + 0x03e60000 /* 00000f98 - 00000f98 [ 1] */, + 0x03ef4000 /* 00000fbd - 00000fbd [ 1] */, + 0x03f34000 /* 00000fcd - 00000fcd [ 1] */, + 0x03f6c024 /* 00000fdb - 00000fff [ 37] */, + 0x04318000 /* 000010c6 - 000010c6 [ 1] */, + 0x04320004 /* 000010c8 - 000010cc [ 5] */, + 0x04338001 /* 000010ce - 000010cf [ 2] */, + 0x04924000 /* 00001249 - 00001249 [ 1] */, + 0x04938001 /* 0000124e - 0000124f [ 2] */, + 0x0495c000 /* 00001257 - 00001257 [ 1] */, + 0x04964000 /* 00001259 - 00001259 [ 1] */, + 0x04978001 /* 0000125e - 0000125f [ 2] */, + 0x04a24000 /* 00001289 - 00001289 [ 1] */, + 0x04a38001 /* 0000128e - 0000128f [ 2] */, + 0x04ac4000 /* 000012b1 - 000012b1 [ 1] */, + 0x04ad8001 /* 000012b6 - 000012b7 [ 2] */, + 0x04afc000 /* 000012bf - 000012bf [ 1] */, + 0x04b04000 /* 000012c1 - 000012c1 [ 1] */, + 0x04b18001 /* 000012c6 - 000012c7 [ 2] */, + 0x04b5c000 /* 000012d7 - 000012d7 [ 1] */, + 0x04c44000 /* 00001311 - 00001311 [ 1] */, + 0x04c58001 /* 00001316 - 00001317 [ 2] */, + 0x04d6c001 /* 0000135b - 0000135c [ 2] */, + 0x04df4002 /* 0000137d - 0000137f [ 3] */, + 0x04e68005 /* 0000139a - 0000139f [ 6] */, + 0x04fd8001 /* 000013f6 - 000013f7 [ 2] */, + 0x04ff8001 /* 000013fe - 000013ff [ 2] */, + 0x05a00000 /* 00001680 - 00001680 [ 1] */, + 0x05a74002 /* 0000169d - 0000169f [ 3] */, + 0x05be4006 /* 000016f9 - 000016ff [ 7] */, + 0x05c58008 /* 00001716 - 0000171e [ 9] */, + 0x05cdc008 /* 00001737 - 0000173f [ 9] */, + 0x05d5000b /* 00001754 - 0000175f [ 12] */, + 0x05db4000 /* 0000176d - 0000176d [ 1] */, + 0x05dc4000 /* 00001771 - 00001771 [ 1] */, + 0x05dd000b /* 00001774 - 0000177f [ 12] */, + 0x05f78001 /* 000017de - 000017df [ 2] */, + 0x05fa8005 /* 000017ea - 000017ef [ 6] */, + 0x05fe8005 /* 000017fa - 000017ff [ 6] */, + 0x06038000 /* 0000180e - 0000180e [ 1] */, + 0x06068005 /* 0000181a - 0000181f [ 6] */, + 0x061e4006 /* 00001879 - 0000187f [ 7] */, + 0x062ac004 /* 000018ab - 000018af [ 5] */, + 0x063d8009 /* 000018f6 - 000018ff [ 10] */, + 0x0647c000 /* 0000191f - 0000191f [ 1] */, + 0x064b0003 /* 0000192c - 0000192f [ 4] */, + 0x064f0003 /* 0000193c - 0000193f [ 4] */, + 0x06504002 /* 00001941 - 00001943 [ 3] */, + 0x065b8001 /* 0000196e - 0000196f [ 2] */, + 0x065d400a /* 00001975 - 0000197f [ 11] */, + 0x066b0003 /* 000019ac - 000019af [ 4] */, + 0x06728005 /* 000019ca - 000019cf [ 6] */, + 0x0676c002 /* 000019db - 000019dd [ 3] */, + 0x06870001 /* 00001a1c - 00001a1d [ 2] */, + 0x0697c000 /* 00001a5f - 00001a5f [ 1] */, + 0x069f4001 /* 00001a7d - 00001a7e [ 2] */, + 0x06a28005 /* 00001a8a - 00001a8f [ 6] */, + 0x06a68005 /* 00001a9a - 00001a9f [ 6] */, + 0x06ab8001 /* 00001aae - 00001aaf [ 2] */, + 0x06b3c030 /* 00001acf - 00001aff [ 49] */, + 0x06d34002 /* 00001b4d - 00001b4f [ 3] */, + 0x06dfc000 /* 00001b7f - 00001b7f [ 1] */, + 0x06fd0007 /* 00001bf4 - 00001bfb [ 8] */, + 0x070e0002 /* 00001c38 - 00001c3a [ 3] */, + 0x07128002 /* 00001c4a - 00001c4c [ 3] */, + 0x07224006 /* 00001c89 - 00001c8f [ 7] */, + 0x072ec001 /* 00001cbb - 00001cbc [ 2] */, + 0x07320007 /* 00001cc8 - 00001ccf [ 8] */, + 0x073ec004 /* 00001cfb - 00001cff [ 5] */, + 0x07c58001 /* 00001f16 - 00001f17 [ 2] */, + 0x07c78001 /* 00001f1e - 00001f1f [ 2] */, + 0x07d18001 /* 00001f46 - 00001f47 [ 2] */, + 0x07d38001 /* 00001f4e - 00001f4f [ 2] */, + 0x07d60000 /* 00001f58 - 00001f58 [ 1] */, + 0x07d68000 /* 00001f5a - 00001f5a [ 1] */, + 0x07d70000 /* 00001f5c - 00001f5c [ 1] */, + 0x07d78000 /* 00001f5e - 00001f5e [ 1] */, + 0x07df8001 /* 00001f7e - 00001f7f [ 2] */, + 0x07ed4000 /* 00001fb5 - 00001fb5 [ 1] */, + 0x07f14000 /* 00001fc5 - 00001fc5 [ 1] */, + 0x07f50001 /* 00001fd4 - 00001fd5 [ 2] */, + 0x07f70000 /* 00001fdc - 00001fdc [ 1] */, + 0x07fc0001 /* 00001ff0 - 00001ff1 [ 2] */, + 0x07fd4000 /* 00001ff5 - 00001ff5 [ 1] */, + 0x07ffc010 /* 00001fff - 0000200f [ 17] */, + 0x080a0007 /* 00002028 - 0000202f [ 8] */, + 0x0817c010 /* 0000205f - 0000206f [ 17] */, + 0x081c8001 /* 00002072 - 00002073 [ 2] */, + 0x0823c000 /* 0000208f - 0000208f [ 1] */, + 0x08274002 /* 0000209d - 0000209f [ 3] */, + 0x0830400e /* 000020c1 - 000020cf [ 15] */, + 0x083c400e /* 000020f1 - 000020ff [ 15] */, + 0x08630003 /* 0000218c - 0000218f [ 4] */, + 0x0909c018 /* 00002427 - 0000243f [ 25] */, + 0x0912c014 /* 0000244b - 0000245f [ 21] */, + 0x0add0001 /* 00002b74 - 00002b75 [ 2] */, + 0x0ae58000 /* 00002b96 - 00002b96 [ 1] */, + 0x0b3d0004 /* 00002cf4 - 00002cf8 [ 5] */, + 0x0b498000 /* 00002d26 - 00002d26 [ 1] */, + 0x0b4a0004 /* 00002d28 - 00002d2c [ 5] */, + 0x0b4b8001 /* 00002d2e - 00002d2f [ 2] */, + 0x0b5a0006 /* 00002d68 - 00002d6e [ 7] */, + 0x0b5c400d /* 00002d71 - 00002d7e [ 14] */, + 0x0b65c008 /* 00002d97 - 00002d9f [ 9] */, + 0x0b69c000 /* 00002da7 - 00002da7 [ 1] */, + 0x0b6bc000 /* 00002daf - 00002daf [ 1] */, + 0x0b6dc000 /* 00002db7 - 00002db7 [ 1] */, + 0x0b6fc000 /* 00002dbf - 00002dbf [ 1] */, + 0x0b71c000 /* 00002dc7 - 00002dc7 [ 1] */, + 0x0b73c000 /* 00002dcf - 00002dcf [ 1] */, + 0x0b75c000 /* 00002dd7 - 00002dd7 [ 1] */, + 0x0b77c000 /* 00002ddf - 00002ddf [ 1] */, + 0x0b978021 /* 00002e5e - 00002e7f [ 34] */, + 0x0ba68000 /* 00002e9a - 00002e9a [ 1] */, + 0x0bbd000b /* 00002ef4 - 00002eff [ 12] */, + 0x0bf58019 /* 00002fd6 - 00002fef [ 26] */, + 0x0c000000 /* 00003000 - 00003000 [ 1] */, + 0x0c100000 /* 00003040 - 00003040 [ 1] */, + 0x0c25c001 /* 00003097 - 00003098 [ 2] */, + 0x0c400004 /* 00003100 - 00003104 [ 5] */, + 0x0c4c0000 /* 00003130 - 00003130 [ 1] */, + 0x0c63c000 /* 0000318f - 0000318f [ 1] */, + 0x0c79000a /* 000031e4 - 000031ee [ 11] */, + 0x0c87c000 /* 0000321f - 0000321f [ 1] */, + 0x29234002 /* 0000a48d - 0000a48f [ 3] */, + 0x2931c008 /* 0000a4c7 - 0000a4cf [ 9] */, + 0x298b0013 /* 0000a62c - 0000a63f [ 20] */, + 0x29be0007 /* 0000a6f8 - 0000a6ff [ 8] */, + 0x29f2c004 /* 0000a7cb - 0000a7cf [ 5] */, + 0x29f48000 /* 0000a7d2 - 0000a7d2 [ 1] */, + 0x29f50000 /* 0000a7d4 - 0000a7d4 [ 1] */, + 0x29f68017 /* 0000a7da - 0000a7f1 [ 24] */, + 0x2a0b4002 /* 0000a82d - 0000a82f [ 3] */, + 0x2a0e8005 /* 0000a83a - 0000a83f [ 6] */, + 0x2a1e0007 /* 0000a878 - 0000a87f [ 8] */, + 0x2a318007 /* 0000a8c6 - 0000a8cd [ 8] */, + 0x2a368005 /* 0000a8da - 0000a8df [ 6] */, + 0x2a55000a /* 0000a954 - 0000a95e [ 11] */, + 0x2a5f4002 /* 0000a97d - 0000a97f [ 3] */, + 0x2a738000 /* 0000a9ce - 0000a9ce [ 1] */, + 0x2a768003 /* 0000a9da - 0000a9dd [ 4] */, + 0x2a7fc000 /* 0000a9ff - 0000a9ff [ 1] */, + 0x2a8dc008 /* 0000aa37 - 0000aa3f [ 9] */, + 0x2a938001 /* 0000aa4e - 0000aa4f [ 2] */, + 0x2a968001 /* 0000aa5a - 0000aa5b [ 2] */, + 0x2ab0c017 /* 0000aac3 - 0000aada [ 24] */, + 0x2abdc009 /* 0000aaf7 - 0000ab00 [ 10] */, + 0x2ac1c001 /* 0000ab07 - 0000ab08 [ 2] */, + 0x2ac3c001 /* 0000ab0f - 0000ab10 [ 2] */, + 0x2ac5c008 /* 0000ab17 - 0000ab1f [ 9] */, + 0x2ac9c000 /* 0000ab27 - 0000ab27 [ 1] */, + 0x2acbc000 /* 0000ab2f - 0000ab2f [ 1] */, + 0x2adb0003 /* 0000ab6c - 0000ab6f [ 4] */, + 0x2afb8001 /* 0000abee - 0000abef [ 2] */, + 0x2afe8005 /* 0000abfa - 0000abff [ 6] */, + 0x35e9000b /* 0000d7a4 - 0000d7af [ 12] */, + 0x35f1c003 /* 0000d7c7 - 0000d7ca [ 4] */, + 0x35ff2103 /* 0000d7fc - 0000f8ff [ 8452] */, + 0x3e9b8001 /* 0000fa6e - 0000fa6f [ 2] */, + 0x3eb68025 /* 0000fada - 0000faff [ 38] */, + 0x3ec1c00b /* 0000fb07 - 0000fb12 [ 12] */, + 0x3ec60004 /* 0000fb18 - 0000fb1c [ 5] */, + 0x3ecdc000 /* 0000fb37 - 0000fb37 [ 1] */, + 0x3ecf4000 /* 0000fb3d - 0000fb3d [ 1] */, + 0x3ecfc000 /* 0000fb3f - 0000fb3f [ 1] */, + 0x3ed08000 /* 0000fb42 - 0000fb42 [ 1] */, + 0x3ed14000 /* 0000fb45 - 0000fb45 [ 1] */, + 0x3ef0c00f /* 0000fbc3 - 0000fbd2 [ 16] */, + 0x3f640001 /* 0000fd90 - 0000fd91 [ 2] */, + 0x3f720006 /* 0000fdc8 - 0000fdce [ 7] */, + 0x3f74001f /* 0000fdd0 - 0000fdef [ 32] */, + 0x3f868005 /* 0000fe1a - 0000fe1f [ 6] */, + 0x3f94c000 /* 0000fe53 - 0000fe53 [ 1] */, + 0x3f99c000 /* 0000fe67 - 0000fe67 [ 1] */, + 0x3f9b0003 /* 0000fe6c - 0000fe6f [ 4] */, + 0x3f9d4000 /* 0000fe75 - 0000fe75 [ 1] */, + 0x3fbf4003 /* 0000fefd - 0000ff00 [ 4] */, + 0x3fefc002 /* 0000ffbf - 0000ffc1 [ 3] */, + 0x3ff20001 /* 0000ffc8 - 0000ffc9 [ 2] */, + 0x3ff40001 /* 0000ffd0 - 0000ffd1 [ 2] */, + 0x3ff60001 /* 0000ffd8 - 0000ffd9 [ 2] */, + 0x3ff74002 /* 0000ffdd - 0000ffdf [ 3] */, + 0x3ff9c000 /* 0000ffe7 - 0000ffe7 [ 1] */, + 0x3ffbc00c /* 0000ffef - 0000fffb [ 13] */, + 0x3fff8001 /* 0000fffe - 0000ffff [ 2] */, + 0x40030000 /* 0001000c - 0001000c [ 1] */, + 0x4009c000 /* 00010027 - 00010027 [ 1] */, + 0x400ec000 /* 0001003b - 0001003b [ 1] */, + 0x400f8000 /* 0001003e - 0001003e [ 1] */, + 0x40138001 /* 0001004e - 0001004f [ 2] */, + 0x40178021 /* 0001005e - 0001007f [ 34] */, + 0x403ec004 /* 000100fb - 000100ff [ 5] */, + 0x4040c003 /* 00010103 - 00010106 [ 4] */, + 0x404d0002 /* 00010134 - 00010136 [ 3] */, + 0x4063c000 /* 0001018f - 0001018f [ 1] */, + 0x40674002 /* 0001019d - 0001019f [ 3] */, + 0x4068402e /* 000101a1 - 000101cf [ 47] */, + 0x407f8081 /* 000101fe - 0001027f [ 130] */, + 0x40a74002 /* 0001029d - 0001029f [ 3] */, + 0x40b4400e /* 000102d1 - 000102df [ 15] */, + 0x40bf0003 /* 000102fc - 000102ff [ 4] */, + 0x40c90008 /* 00010324 - 0001032c [ 9] */, + 0x40d2c004 /* 0001034b - 0001034f [ 5] */, + 0x40dec004 /* 0001037b - 0001037f [ 5] */, + 0x40e78000 /* 0001039e - 0001039e [ 1] */, + 0x40f10003 /* 000103c4 - 000103c7 [ 4] */, + 0x40f58029 /* 000103d6 - 000103ff [ 42] */, + 0x41278001 /* 0001049e - 0001049f [ 2] */, + 0x412a8005 /* 000104aa - 000104af [ 6] */, + 0x41350003 /* 000104d4 - 000104d7 [ 4] */, + 0x413f0003 /* 000104fc - 000104ff [ 4] */, + 0x414a0007 /* 00010528 - 0001052f [ 8] */, + 0x4159000a /* 00010564 - 0001056e [ 11] */, + 0x415ec000 /* 0001057b - 0001057b [ 1] */, + 0x4162c000 /* 0001058b - 0001058b [ 1] */, + 0x4164c000 /* 00010593 - 00010593 [ 1] */, + 0x41658000 /* 00010596 - 00010596 [ 1] */, + 0x41688000 /* 000105a2 - 000105a2 [ 1] */, + 0x416c8000 /* 000105b2 - 000105b2 [ 1] */, + 0x416e8000 /* 000105ba - 000105ba [ 1] */, + 0x416f4042 /* 000105bd - 000105ff [ 67] */, + 0x41cdc008 /* 00010737 - 0001073f [ 9] */, + 0x41d58009 /* 00010756 - 0001075f [ 10] */, + 0x41da0017 /* 00010768 - 0001077f [ 24] */, + 0x41e18000 /* 00010786 - 00010786 [ 1] */, + 0x41ec4000 /* 000107b1 - 000107b1 [ 1] */, + 0x41eec044 /* 000107bb - 000107ff [ 69] */, + 0x42018001 /* 00010806 - 00010807 [ 2] */, + 0x42024000 /* 00010809 - 00010809 [ 1] */, + 0x420d8000 /* 00010836 - 00010836 [ 1] */, + 0x420e4002 /* 00010839 - 0001083b [ 3] */, + 0x420f4001 /* 0001083d - 0001083e [ 2] */, + 0x42158000 /* 00010856 - 00010856 [ 1] */, + 0x4227c007 /* 0001089f - 000108a6 [ 8] */, + 0x422c002f /* 000108b0 - 000108df [ 48] */, + 0x423cc000 /* 000108f3 - 000108f3 [ 1] */, + 0x423d8004 /* 000108f6 - 000108fa [ 5] */, + 0x42470002 /* 0001091c - 0001091e [ 3] */, + 0x424e8004 /* 0001093a - 0001093e [ 5] */, + 0x4250003f /* 00010940 - 0001097f [ 64] */, + 0x426e0003 /* 000109b8 - 000109bb [ 4] */, + 0x42740001 /* 000109d0 - 000109d1 [ 2] */, + 0x42810000 /* 00010a04 - 00010a04 [ 1] */, + 0x4281c004 /* 00010a07 - 00010a0b [ 5] */, + 0x42850000 /* 00010a14 - 00010a14 [ 1] */, + 0x42860000 /* 00010a18 - 00010a18 [ 1] */, + 0x428d8001 /* 00010a36 - 00010a37 [ 2] */, + 0x428ec003 /* 00010a3b - 00010a3e [ 4] */, + 0x42924006 /* 00010a49 - 00010a4f [ 7] */, + 0x42964006 /* 00010a59 - 00010a5f [ 7] */, + 0x42a8001f /* 00010aa0 - 00010abf [ 32] */, + 0x42b9c003 /* 00010ae7 - 00010aea [ 4] */, + 0x42bdc008 /* 00010af7 - 00010aff [ 9] */, + 0x42cd8002 /* 00010b36 - 00010b38 [ 3] */, + 0x42d58001 /* 00010b56 - 00010b57 [ 2] */, + 0x42dcc004 /* 00010b73 - 00010b77 [ 5] */, + 0x42e48006 /* 00010b92 - 00010b98 [ 7] */, + 0x42e7400b /* 00010b9d - 00010ba8 [ 12] */, + 0x42ec004f /* 00010bb0 - 00010bff [ 80] */, + 0x43124036 /* 00010c49 - 00010c7f [ 55] */, + 0x432cc00c /* 00010cb3 - 00010cbf [ 13] */, + 0x433cc006 /* 00010cf3 - 00010cf9 [ 7] */, + 0x434a0007 /* 00010d28 - 00010d2f [ 8] */, + 0x434e8125 /* 00010d3a - 00010e5f [ 294] */, + 0x439fc000 /* 00010e7f - 00010e7f [ 1] */, + 0x43aa8000 /* 00010eaa - 00010eaa [ 1] */, + 0x43ab8001 /* 00010eae - 00010eaf [ 2] */, + 0x43ac804a /* 00010eb2 - 00010efc [ 75] */, + 0x43ca0007 /* 00010f28 - 00010f2f [ 8] */, + 0x43d68015 /* 00010f5a - 00010f6f [ 22] */, + 0x43e28025 /* 00010f8a - 00010faf [ 38] */, + 0x43f30013 /* 00010fcc - 00010fdf [ 20] */, + 0x43fdc008 /* 00010ff7 - 00010fff [ 9] */, + 0x44138003 /* 0001104e - 00011051 [ 4] */, + 0x441d8008 /* 00011076 - 0001107e [ 9] */, + 0x442f4000 /* 000110bd - 000110bd [ 1] */, + 0x4430c00c /* 000110c3 - 000110cf [ 13] */, + 0x443a4006 /* 000110e9 - 000110ef [ 7] */, + 0x443e8005 /* 000110fa - 000110ff [ 6] */, + 0x444d4000 /* 00011135 - 00011135 [ 1] */, + 0x44520007 /* 00011148 - 0001114f [ 8] */, + 0x445dc008 /* 00011177 - 0001117f [ 9] */, + 0x44780000 /* 000111e0 - 000111e0 [ 1] */, + 0x447d400a /* 000111f5 - 000111ff [ 11] */, + 0x44848000 /* 00011212 - 00011212 [ 1] */, + 0x4490803d /* 00011242 - 0001127f [ 62] */, + 0x44a1c000 /* 00011287 - 00011287 [ 1] */, + 0x44a24000 /* 00011289 - 00011289 [ 1] */, + 0x44a38000 /* 0001128e - 0001128e [ 1] */, + 0x44a78000 /* 0001129e - 0001129e [ 1] */, + 0x44aa8005 /* 000112aa - 000112af [ 6] */, + 0x44bac004 /* 000112eb - 000112ef [ 5] */, + 0x44be8005 /* 000112fa - 000112ff [ 6] */, + 0x44c10000 /* 00011304 - 00011304 [ 1] */, + 0x44c34001 /* 0001130d - 0001130e [ 2] */, + 0x44c44001 /* 00011311 - 00011312 [ 2] */, + 0x44ca4000 /* 00011329 - 00011329 [ 1] */, + 0x44cc4000 /* 00011331 - 00011331 [ 1] */, + 0x44cd0000 /* 00011334 - 00011334 [ 1] */, + 0x44ce8000 /* 0001133a - 0001133a [ 1] */, + 0x44d14001 /* 00011345 - 00011346 [ 2] */, + 0x44d24001 /* 00011349 - 0001134a [ 2] */, + 0x44d38001 /* 0001134e - 0001134f [ 2] */, + 0x44d44005 /* 00011351 - 00011356 [ 6] */, + 0x44d60004 /* 00011358 - 0001135c [ 5] */, + 0x44d90001 /* 00011364 - 00011365 [ 2] */, + 0x44db4002 /* 0001136d - 0001136f [ 3] */, + 0x44dd408a /* 00011375 - 000113ff [ 139] */, + 0x45170000 /* 0001145c - 0001145c [ 1] */, + 0x4518801d /* 00011462 - 0001147f [ 30] */, + 0x45320007 /* 000114c8 - 000114cf [ 8] */, + 0x453680a5 /* 000114da - 0001157f [ 166] */, + 0x456d8001 /* 000115b6 - 000115b7 [ 2] */, + 0x45778021 /* 000115de - 000115ff [ 34] */, + 0x4591400a /* 00011645 - 0001164f [ 11] */, + 0x45968005 /* 0001165a - 0001165f [ 6] */, + 0x459b4012 /* 0001166d - 0001167f [ 19] */, + 0x45ae8005 /* 000116ba - 000116bf [ 6] */, + 0x45b28035 /* 000116ca - 000116ff [ 54] */, + 0x45c6c001 /* 0001171b - 0001171c [ 2] */, + 0x45cb0003 /* 0001172c - 0001172f [ 4] */, + 0x45d1c0b8 /* 00011747 - 000117ff [ 185] */, + 0x460f0063 /* 0001183c - 0001189f [ 100] */, + 0x463cc00b /* 000118f3 - 000118fe [ 12] */, + 0x4641c001 /* 00011907 - 00011908 [ 2] */, + 0x46428001 /* 0001190a - 0001190b [ 2] */, + 0x46450000 /* 00011914 - 00011914 [ 1] */, + 0x4645c000 /* 00011917 - 00011917 [ 1] */, + 0x464d8000 /* 00011936 - 00011936 [ 1] */, + 0x464e4001 /* 00011939 - 0001193a [ 2] */, + 0x4651c008 /* 00011947 - 0001194f [ 9] */, + 0x46568045 /* 0001195a - 0001199f [ 70] */, + 0x466a0001 /* 000119a8 - 000119a9 [ 2] */, + 0x46760001 /* 000119d8 - 000119d9 [ 2] */, + 0x4679401a /* 000119e5 - 000119ff [ 27] */, + 0x46920007 /* 00011a48 - 00011a4f [ 8] */, + 0x46a8c00c /* 00011aa3 - 00011aaf [ 13] */, + 0x46be4006 /* 00011af9 - 00011aff [ 7] */, + 0x46c280f5 /* 00011b0a - 00011bff [ 246] */, + 0x47024000 /* 00011c09 - 00011c09 [ 1] */, + 0x470dc000 /* 00011c37 - 00011c37 [ 1] */, + 0x47118009 /* 00011c46 - 00011c4f [ 10] */, + 0x471b4002 /* 00011c6d - 00011c6f [ 3] */, + 0x47240001 /* 00011c90 - 00011c91 [ 2] */, + 0x472a0000 /* 00011ca8 - 00011ca8 [ 1] */, + 0x472dc048 /* 00011cb7 - 00011cff [ 73] */, + 0x4741c000 /* 00011d07 - 00011d07 [ 1] */, + 0x47428000 /* 00011d0a - 00011d0a [ 1] */, + 0x474dc002 /* 00011d37 - 00011d39 [ 3] */, + 0x474ec000 /* 00011d3b - 00011d3b [ 1] */, + 0x474f8000 /* 00011d3e - 00011d3e [ 1] */, + 0x47520007 /* 00011d48 - 00011d4f [ 8] */, + 0x47568005 /* 00011d5a - 00011d5f [ 6] */, + 0x47598000 /* 00011d66 - 00011d66 [ 1] */, + 0x475a4000 /* 00011d69 - 00011d69 [ 1] */, + 0x4763c000 /* 00011d8f - 00011d8f [ 1] */, + 0x47648000 /* 00011d92 - 00011d92 [ 1] */, + 0x47664006 /* 00011d99 - 00011d9f [ 7] */, + 0x476a8135 /* 00011daa - 00011edf [ 310] */, + 0x47be4006 /* 00011ef9 - 00011eff [ 7] */, + 0x47c44000 /* 00011f11 - 00011f11 [ 1] */, + 0x47cec002 /* 00011f3b - 00011f3d [ 3] */, + 0x47d68055 /* 00011f5a - 00011faf [ 86] */, + 0x47ec400e /* 00011fb1 - 00011fbf [ 15] */, + 0x47fc800c /* 00011ff2 - 00011ffe [ 13] */, + 0x48e68065 /* 0001239a - 000123ff [ 102] */, + 0x491bc000 /* 0001246f - 0001246f [ 1] */, + 0x491d400a /* 00012475 - 0001247f [ 11] */, + 0x49510a4b /* 00012544 - 00012f8f [ 2636] */, + 0x4bfcc00c /* 00012ff3 - 00012fff [ 13] */, + 0x4d0c000f /* 00013430 - 0001343f [ 16] */, + 0x4d158fa9 /* 00013456 - 000143ff [ 4010] */, + 0x5191e1b8 /* 00014647 - 000167ff [ 8633] */, + 0x5a8e4006 /* 00016a39 - 00016a3f [ 7] */, + 0x5a97c000 /* 00016a5f - 00016a5f [ 1] */, + 0x5a9a8003 /* 00016a6a - 00016a6d [ 4] */, + 0x5aafc000 /* 00016abf - 00016abf [ 1] */, + 0x5ab28005 /* 00016aca - 00016acf [ 6] */, + 0x5abb8001 /* 00016aee - 00016aef [ 2] */, + 0x5abd8009 /* 00016af6 - 00016aff [ 10] */, + 0x5ad18009 /* 00016b46 - 00016b4f [ 10] */, + 0x5ad68000 /* 00016b5a - 00016b5a [ 1] */, + 0x5ad88000 /* 00016b62 - 00016b62 [ 1] */, + 0x5ade0004 /* 00016b78 - 00016b7c [ 5] */, + 0x5ae402af /* 00016b90 - 00016e3f [ 688] */, + 0x5ba6c064 /* 00016e9b - 00016eff [ 101] */, + 0x5bd2c003 /* 00016f4b - 00016f4e [ 4] */, + 0x5be20006 /* 00016f88 - 00016f8e [ 7] */, + 0x5be8003f /* 00016fa0 - 00016fdf [ 64] */, + 0x5bf9400a /* 00016fe5 - 00016fef [ 11] */, + 0x5bfc800d /* 00016ff2 - 00016fff [ 14] */, + 0x61fe0007 /* 000187f8 - 000187ff [ 8] */, + 0x63358029 /* 00018cd6 - 00018cff [ 42] */, + 0x634262e6 /* 00018d09 - 0001afef [ 8935] */, + 0x6bfd0000 /* 0001aff4 - 0001aff4 [ 1] */, + 0x6bff0000 /* 0001affc - 0001affc [ 1] */, + 0x6bffc000 /* 0001afff - 0001afff [ 1] */, + 0x6c48c00e /* 0001b123 - 0001b131 [ 15] */, + 0x6c4cc01c /* 0001b133 - 0001b14f [ 29] */, + 0x6c54c001 /* 0001b153 - 0001b154 [ 2] */, + 0x6c55800d /* 0001b156 - 0001b163 [ 14] */, + 0x6c5a0007 /* 0001b168 - 0001b16f [ 8] */, + 0x6cbf0903 /* 0001b2fc - 0001bbff [ 2308] */, + 0x6f1ac004 /* 0001bc6b - 0001bc6f [ 5] */, + 0x6f1f4002 /* 0001bc7d - 0001bc7f [ 3] */, + 0x6f224006 /* 0001bc89 - 0001bc8f [ 7] */, + 0x6f268001 /* 0001bc9a - 0001bc9b [ 2] */, + 0x6f28125f /* 0001bca0 - 0001ceff [ 4704] */, + 0x73cb8001 /* 0001cf2e - 0001cf2f [ 2] */, + 0x73d1c008 /* 0001cf47 - 0001cf4f [ 9] */, + 0x73f1003b /* 0001cfc4 - 0001cfff [ 60] */, + 0x743d8009 /* 0001d0f6 - 0001d0ff [ 10] */, + 0x7449c001 /* 0001d127 - 0001d128 [ 2] */, + 0x745cc007 /* 0001d173 - 0001d17a [ 8] */, + 0x747ac014 /* 0001d1eb - 0001d1ff [ 21] */, + 0x74918079 /* 0001d246 - 0001d2bf [ 122] */, + 0x74b5000b /* 0001d2d4 - 0001d2df [ 12] */, + 0x74bd000b /* 0001d2f4 - 0001d2ff [ 12] */, + 0x74d5c008 /* 0001d357 - 0001d35f [ 9] */, + 0x74de4086 /* 0001d379 - 0001d3ff [ 135] */, + 0x75154000 /* 0001d455 - 0001d455 [ 1] */, + 0x75274000 /* 0001d49d - 0001d49d [ 1] */, + 0x75280001 /* 0001d4a0 - 0001d4a1 [ 2] */, + 0x7528c001 /* 0001d4a3 - 0001d4a4 [ 2] */, + 0x7529c001 /* 0001d4a7 - 0001d4a8 [ 2] */, + 0x752b4000 /* 0001d4ad - 0001d4ad [ 1] */, + 0x752e8000 /* 0001d4ba - 0001d4ba [ 1] */, + 0x752f0000 /* 0001d4bc - 0001d4bc [ 1] */, + 0x75310000 /* 0001d4c4 - 0001d4c4 [ 1] */, + 0x75418000 /* 0001d506 - 0001d506 [ 1] */, + 0x7542c001 /* 0001d50b - 0001d50c [ 2] */, + 0x75454000 /* 0001d515 - 0001d515 [ 1] */, + 0x75474000 /* 0001d51d - 0001d51d [ 1] */, + 0x754e8000 /* 0001d53a - 0001d53a [ 1] */, + 0x754fc000 /* 0001d53f - 0001d53f [ 1] */, + 0x75514000 /* 0001d545 - 0001d545 [ 1] */, + 0x7551c002 /* 0001d547 - 0001d549 [ 3] */, + 0x75544000 /* 0001d551 - 0001d551 [ 1] */, + 0x75a98001 /* 0001d6a6 - 0001d6a7 [ 2] */, + 0x75f30001 /* 0001d7cc - 0001d7cd [ 2] */, + 0x76a3000e /* 0001da8c - 0001da9a [ 15] */, + 0x76a80000 /* 0001daa0 - 0001daa0 [ 1] */, + 0x76ac044f /* 0001dab0 - 0001deff [ 1104] */, + 0x77c7c005 /* 0001df1f - 0001df24 [ 6] */, + 0x77cac0d4 /* 0001df2b - 0001dfff [ 213] */, + 0x7801c000 /* 0001e007 - 0001e007 [ 1] */, + 0x78064001 /* 0001e019 - 0001e01a [ 2] */, + 0x78088000 /* 0001e022 - 0001e022 [ 1] */, + 0x78094000 /* 0001e025 - 0001e025 [ 1] */, + 0x780ac004 /* 0001e02b - 0001e02f [ 5] */, + 0x781b8020 /* 0001e06e - 0001e08e [ 33] */, + 0x7824006f /* 0001e090 - 0001e0ff [ 112] */, + 0x784b4002 /* 0001e12d - 0001e12f [ 3] */, + 0x784f8001 /* 0001e13e - 0001e13f [ 2] */, + 0x78528003 /* 0001e14a - 0001e14d [ 4] */, + 0x7854013f /* 0001e150 - 0001e28f [ 320] */, + 0x78abc010 /* 0001e2af - 0001e2bf [ 17] */, + 0x78be8004 /* 0001e2fa - 0001e2fe [ 5] */, + 0x78c001cf /* 0001e300 - 0001e4cf [ 464] */, + 0x793e82e5 /* 0001e4fa - 0001e7df [ 742] */, + 0x79f9c000 /* 0001e7e7 - 0001e7e7 [ 1] */, + 0x79fb0000 /* 0001e7ec - 0001e7ec [ 1] */, + 0x79fbc000 /* 0001e7ef - 0001e7ef [ 1] */, + 0x79ffc000 /* 0001e7ff - 0001e7ff [ 1] */, + 0x7a314001 /* 0001e8c5 - 0001e8c6 [ 2] */, + 0x7a35c028 /* 0001e8d7 - 0001e8ff [ 41] */, + 0x7a530003 /* 0001e94c - 0001e94f [ 4] */, + 0x7a568003 /* 0001e95a - 0001e95d [ 4] */, + 0x7a580310 /* 0001e960 - 0001ec70 [ 785] */, + 0x7b2d404b /* 0001ecb5 - 0001ed00 [ 76] */, + 0x7b4f80c1 /* 0001ed3e - 0001edff [ 194] */, + 0x7b810000 /* 0001ee04 - 0001ee04 [ 1] */, + 0x7b880000 /* 0001ee20 - 0001ee20 [ 1] */, + 0x7b88c000 /* 0001ee23 - 0001ee23 [ 1] */, + 0x7b894001 /* 0001ee25 - 0001ee26 [ 2] */, + 0x7b8a0000 /* 0001ee28 - 0001ee28 [ 1] */, + 0x7b8cc000 /* 0001ee33 - 0001ee33 [ 1] */, + 0x7b8e0000 /* 0001ee38 - 0001ee38 [ 1] */, + 0x7b8e8000 /* 0001ee3a - 0001ee3a [ 1] */, + 0x7b8f0005 /* 0001ee3c - 0001ee41 [ 6] */, + 0x7b90c003 /* 0001ee43 - 0001ee46 [ 4] */, + 0x7b920000 /* 0001ee48 - 0001ee48 [ 1] */, + 0x7b928000 /* 0001ee4a - 0001ee4a [ 1] */, + 0x7b930000 /* 0001ee4c - 0001ee4c [ 1] */, + 0x7b940000 /* 0001ee50 - 0001ee50 [ 1] */, + 0x7b94c000 /* 0001ee53 - 0001ee53 [ 1] */, + 0x7b954001 /* 0001ee55 - 0001ee56 [ 2] */, + 0x7b960000 /* 0001ee58 - 0001ee58 [ 1] */, + 0x7b968000 /* 0001ee5a - 0001ee5a [ 1] */, + 0x7b970000 /* 0001ee5c - 0001ee5c [ 1] */, + 0x7b978000 /* 0001ee5e - 0001ee5e [ 1] */, + 0x7b980000 /* 0001ee60 - 0001ee60 [ 1] */, + 0x7b98c000 /* 0001ee63 - 0001ee63 [ 1] */, + 0x7b994001 /* 0001ee65 - 0001ee66 [ 2] */, + 0x7b9ac000 /* 0001ee6b - 0001ee6b [ 1] */, + 0x7b9cc000 /* 0001ee73 - 0001ee73 [ 1] */, + 0x7b9e0000 /* 0001ee78 - 0001ee78 [ 1] */, + 0x7b9f4000 /* 0001ee7d - 0001ee7d [ 1] */, + 0x7b9fc000 /* 0001ee7f - 0001ee7f [ 1] */, + 0x7ba28000 /* 0001ee8a - 0001ee8a [ 1] */, + 0x7ba70004 /* 0001ee9c - 0001eea0 [ 5] */, + 0x7ba90000 /* 0001eea4 - 0001eea4 [ 1] */, + 0x7baa8000 /* 0001eeaa - 0001eeaa [ 1] */, + 0x7baf0033 /* 0001eebc - 0001eeef [ 52] */, + 0x7bbc810d /* 0001eef2 - 0001efff [ 270] */, + 0x7c0b0003 /* 0001f02c - 0001f02f [ 4] */, + 0x7c25000b /* 0001f094 - 0001f09f [ 12] */, + 0x7c2bc001 /* 0001f0af - 0001f0b0 [ 2] */, + 0x7c300000 /* 0001f0c0 - 0001f0c0 [ 1] */, + 0x7c340000 /* 0001f0d0 - 0001f0d0 [ 1] */, + 0x7c3d8009 /* 0001f0f6 - 0001f0ff [ 10] */, + 0x7c6b8037 /* 0001f1ae - 0001f1e5 [ 56] */, + 0x7c80c00c /* 0001f203 - 0001f20f [ 13] */, + 0x7c8f0003 /* 0001f23c - 0001f23f [ 4] */, + 0x7c924006 /* 0001f249 - 0001f24f [ 7] */, + 0x7c94800d /* 0001f252 - 0001f25f [ 14] */, + 0x7c998099 /* 0001f266 - 0001f2ff [ 154] */, + 0x7db60003 /* 0001f6d8 - 0001f6db [ 4] */, + 0x7dbb4002 /* 0001f6ed - 0001f6ef [ 3] */, + 0x7dbf4002 /* 0001f6fd - 0001f6ff [ 3] */, + 0x7dddc003 /* 0001f777 - 0001f77a [ 4] */, + 0x7df68005 /* 0001f7da - 0001f7df [ 6] */, + 0x7dfb0003 /* 0001f7ec - 0001f7ef [ 4] */, + 0x7dfc400e /* 0001f7f1 - 0001f7ff [ 15] */, + 0x7e030003 /* 0001f80c - 0001f80f [ 4] */, + 0x7e120007 /* 0001f848 - 0001f84f [ 8] */, + 0x7e168005 /* 0001f85a - 0001f85f [ 6] */, + 0x7e220007 /* 0001f888 - 0001f88f [ 8] */, + 0x7e2b8001 /* 0001f8ae - 0001f8af [ 2] */, + 0x7e2c804d /* 0001f8b2 - 0001f8ff [ 78] */, + 0x7e95000b /* 0001fa54 - 0001fa5f [ 12] */, + 0x7e9b8001 /* 0001fa6e - 0001fa6f [ 2] */, + 0x7e9f4002 /* 0001fa7d - 0001fa7f [ 3] */, + 0x7ea24006 /* 0001fa89 - 0001fa8f [ 7] */, + 0x7eaf8000 /* 0001fabe - 0001fabe [ 1] */, + 0x7eb18007 /* 0001fac6 - 0001facd [ 8] */, + 0x7eb70003 /* 0001fadc - 0001fadf [ 4] */, + 0x7eba4006 /* 0001fae9 - 0001faef [ 7] */, + 0x7ebe4006 /* 0001faf9 - 0001faff [ 7] */, + 0x7ee4c000 /* 0001fb93 - 0001fb93 [ 1] */, + 0x7ef2c024 /* 0001fbcb - 0001fbef [ 37] */, + 0x7efe8405 /* 0001fbfa - 0001ffff [ 1030] */, + 0xa9b8001f /* 0002a6e0 - 0002a6ff [ 32] */, + 0xadce8005 /* 0002b73a - 0002b73f [ 6] */, + 0xae078001 /* 0002b81e - 0002b81f [ 2] */, + 0xb3a8800d /* 0002cea2 - 0002ceaf [ 14] */, + 0xbaf8400e /* 0002ebe1 - 0002ebef [ 15] */, + 0xbb9789a1 /* 0002ee5e - 0002f7ff [ 2466] */, + 0xbe8785e1 /* 0002fa1e - 0002ffff [ 1506] */, + 0xc4d2c004 /* 0003134b - 0003134f [ 5] */}; /// Returns whether the code unit needs to be escaped. /// -/// \pre The code point is a valid Unicode code point. +/// At the end of the valid Unicode code points space a lot of code points are +/// either reserved or a noncharacter. Adding all these entries to the +/// lookup table would greatly increase the size of the table. Instead these +/// entries are manually processed. In this large area of reserved code points, +/// there is a small area of extended graphemes that should not be escaped +/// unconditionally. This is also manually coded. See the generation script for +/// more details. + +/// +/// \\pre The code point is a valid Unicode code point. [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool __needs_escape(const char32_t __code_point) noexcept { - // Since __unallocated_region_lower_bound contains the unshifted range do the - // comparison without shifting. - if (__code_point >= __unallocated_region_lower_bound) + + // The entries in the gap at the end. + if(__code_point >= 0x000e0100 && __code_point <= 0x000e01ef) + return false; + + // The entries at the end. + if (__code_point >= 0x000323b0) return true; - ptrdiff_t __i = std::ranges::upper_bound(__entries, (__code_point << 11) | 0x7ffu) - __entries; + ptrdiff_t __i = std::ranges::upper_bound(__entries, (__code_point << 14) | 0x3fffu) - __entries; if (__i == 0) return false; --__i; - uint32_t __upper_bound = (__entries[__i] >> 11) + (__entries[__i] & 0x7ffu); + uint32_t __upper_bound = (__entries[__i] >> 14) + (__entries[__i] & 0x3fffu); return __code_point <= __upper_bound; } +// clang-format on } // namespace __escaped_output_table #endif //_LIBCPP_STD_VER >= 23 diff --git a/third_party/libcxx/__format/extended_grapheme_cluster_table.h b/third_party/libcxx/__format/extended_grapheme_cluster_table.h index bd6d39fdc..48581d8a5 100644 --- a/third_party/libcxx/__format/extended_grapheme_cluster_table.h +++ b/third_party/libcxx/__format/extended_grapheme_cluster_table.h @@ -124,7 +124,8 @@ enum class __property : uint8_t { /// this approach uses less space for the data and is about 4% faster in the /// following benchmark. /// libcxx/benchmarks/std_format_spec_string_unicode.bench.cpp -inline constexpr uint32_t __entries[1496] = { +// clang-format off +_LIBCPP_HIDE_FROM_ABI inline constexpr uint32_t __entries[1496] = { 0x00000091, 0x00005005, 0x00005811, @@ -1621,6 +1622,7 @@ inline constexpr uint32_t __entries[1496] = { 0x707787f1, 0x707b87f1, 0x707f80f1}; +// clang-format on /// Returns the extended grapheme cluster bondary property of a code point. [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __property __get_property(const char32_t __code_point) noexcept { diff --git a/third_party/libcxx/__format/format_arg.h b/third_party/libcxx/__format/format_arg.h index a27da8d74..aa02f81dc 100644 --- a/third_party/libcxx/__format/format_arg.h +++ b/third_party/libcxx/__format/format_arg.h @@ -13,24 +13,27 @@ #include <__assert> #include <__concepts/arithmetic.h> #include <__config> -#include <__format/format_error.h> -#include <__format/format_fwd.h> +#include <__format/concepts.h> #include <__format/format_parse_context.h> #include <__functional/invoke.h> +#include <__fwd/format.h> #include <__memory/addressof.h> #include <__type_traits/conditional.h> -#include <__type_traits/is_const.h> -#include <__utility/declval.h> +#include <__type_traits/remove_const.h> #include <__utility/forward.h> +#include <__utility/move.h> #include <__utility/unreachable.h> #include <__variant/monostate.h> -#include +#include #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 @@ -54,7 +57,7 @@ namespace __format { /// handle to satisfy the user observable behaviour. The internal function /// __visit_format_arg doesn't do this wrapping. So in the format functions /// this function is used to avoid unneeded overhead. -enum class _LIBCPP_ENUM_VIS __arg_t : uint8_t { +enum class __arg_t : uint8_t { __none, __boolean, __char_type, @@ -74,17 +77,17 @@ enum class _LIBCPP_ENUM_VIS __arg_t : uint8_t { }; inline constexpr unsigned __packed_arg_t_bits = 5; -inline constexpr uint8_t __packed_arg_t_mask = 0x1f; +inline constexpr uint8_t __packed_arg_t_mask = 0x1f; inline constexpr unsigned __packed_types_storage_bits = 64; -inline constexpr unsigned __packed_types_max = __packed_types_storage_bits / __packed_arg_t_bits; +inline constexpr unsigned __packed_types_max = __packed_types_storage_bits / __packed_arg_t_bits; -_LIBCPP_HIDE_FROM_ABI -constexpr bool __use_packed_format_arg_store(size_t __size) { return __size <= __packed_types_max; } +_LIBCPP_HIDE_FROM_ABI constexpr bool __use_packed_format_arg_store(size_t __size) { + return __size <= __packed_types_max; +} -_LIBCPP_HIDE_FROM_ABI -constexpr __arg_t __get_packed_type(uint64_t __types, size_t __id) { - _LIBCPP_ASSERT(__id <= __packed_types_max, ""); +_LIBCPP_HIDE_FROM_ABI constexpr __arg_t __get_packed_type(uint64_t __types, size_t __id) { + _LIBCPP_ASSERT_INTERNAL(__id <= __packed_types_max, ""); if (__id > 0) __types >>= __id * __packed_arg_t_bits; @@ -94,58 +97,110 @@ constexpr __arg_t __get_packed_type(uint64_t __types, size_t __id) { } // namespace __format -// This function is not user obervable, so it can directly use the non-standard +// This function is not user observable, so it can directly use the non-standard // types of the "variant". See __arg_t for more details. template -_LIBCPP_HIDE_FROM_ABI decltype(auto) -__visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) { +_LIBCPP_HIDE_FROM_ABI decltype(auto) __visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) { switch (__arg.__type_) { case __format::__arg_t::__none: - return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__monostate_); + return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__monostate_); case __format::__arg_t::__boolean: - return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__boolean_); + return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__boolean_); case __format::__arg_t::__char_type: - return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__char_type_); + return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__char_type_); case __format::__arg_t::__int: - return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__int_); + return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__int_); case __format::__arg_t::__long_long: - return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__long_long_); + return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__long_long_); case __format::__arg_t::__i128: # ifndef _LIBCPP_HAS_NO_INT128 - return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__i128_); + return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__i128_); # else __libcpp_unreachable(); # endif case __format::__arg_t::__unsigned: - return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__unsigned_); + return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__unsigned_); case __format::__arg_t::__unsigned_long_long: - return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__unsigned_long_long_); + return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__unsigned_long_long_); case __format::__arg_t::__u128: # ifndef _LIBCPP_HAS_NO_INT128 - return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__u128_); + return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__u128_); # else __libcpp_unreachable(); # endif case __format::__arg_t::__float: - return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__float_); + return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__float_); case __format::__arg_t::__double: - return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__double_); + return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__double_); case __format::__arg_t::__long_double: - return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__long_double_); + return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__long_double_); case __format::__arg_t::__const_char_type_ptr: - return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__const_char_type_ptr_); + return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__const_char_type_ptr_); case __format::__arg_t::__string_view: - return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__string_view_); + return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__string_view_); case __format::__arg_t::__ptr: - return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__value_.__ptr_); + return std::invoke(std::forward<_Visitor>(__vis), __arg.__value_.__ptr_); case __format::__arg_t::__handle: - return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), - typename basic_format_arg<_Context>::handle{__arg.__value_.__handle_}); + return std::invoke( + std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__arg.__value_.__handle_}); } __libcpp_unreachable(); } +# if _LIBCPP_STD_VER >= 26 && defined(_LIBCPP_HAS_EXPLICIT_THIS_PARAMETER) + +template +_LIBCPP_HIDE_FROM_ABI _Rp __visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) { + switch (__arg.__type_) { + case __format::__arg_t::__none: + return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__monostate_); + case __format::__arg_t::__boolean: + return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__boolean_); + case __format::__arg_t::__char_type: + return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__char_type_); + case __format::__arg_t::__int: + return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__int_); + case __format::__arg_t::__long_long: + return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__long_long_); + case __format::__arg_t::__i128: +# ifndef _LIBCPP_HAS_NO_INT128 + return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__i128_); +# else + __libcpp_unreachable(); +# endif + case __format::__arg_t::__unsigned: + return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__unsigned_); + case __format::__arg_t::__unsigned_long_long: + return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__unsigned_long_long_); + case __format::__arg_t::__u128: +# ifndef _LIBCPP_HAS_NO_INT128 + return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__u128_); +# else + __libcpp_unreachable(); +# endif + case __format::__arg_t::__float: + return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__float_); + case __format::__arg_t::__double: + return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__double_); + case __format::__arg_t::__long_double: + return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__long_double_); + case __format::__arg_t::__const_char_type_ptr: + return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__const_char_type_ptr_); + case __format::__arg_t::__string_view: + return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__string_view_); + case __format::__arg_t::__ptr: + return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), __arg.__value_.__ptr_); + case __format::__arg_t::__handle: + return std::invoke_r<_Rp>( + std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__arg.__value_.__handle_}); + } + + __libcpp_unreachable(); +} + +# endif // _LIBCPP_STD_VER >= 26 && defined(_LIBCPP_HAS_EXPLICIT_THIS_PARAMETER) + /// Contains the values used in basic_format_arg. /// /// This is a separate type so it's possible to store the values and types in @@ -158,18 +213,14 @@ public: /// Contains the implementation for basic_format_arg::handle. struct __handle { template - _LIBCPP_HIDE_FROM_ABI explicit __handle(_Tp&& __v) noexcept - : __ptr_(_VSTD::addressof(__v)), + _LIBCPP_HIDE_FROM_ABI explicit __handle(_Tp& __v) noexcept + : __ptr_(std::addressof(__v)), __format_([](basic_format_parse_context<_CharT>& __parse_ctx, _Context& __ctx, const void* __ptr) { - using _Dp = remove_cvref_t<_Tp>; - using _Formatter = typename _Context::template formatter_type<_Dp>; - constexpr bool __const_formattable = - requires { _Formatter().format(std::declval(), std::declval<_Context&>()); }; - using _Qp = conditional_t<__const_formattable, const _Dp, _Dp>; + using _Dp = remove_const_t<_Tp>; + using _Qp = conditional_t<__formattable_with, const _Dp, _Dp>; + static_assert(__formattable_with<_Qp, _Context>, "Mandated by [format.arg]/10"); - static_assert(__const_formattable || !is_const_v>, "Mandated by [format.arg]/18"); - - _Formatter __f; + typename _Context::template formatter_type<_Dp> __f; __parse_ctx.advance_to(__f.parse(__parse_ctx)); __ctx.advance_to(__f.format(*const_cast<_Qp*>(static_cast(__ptr)), __ctx)); }) {} @@ -221,9 +272,7 @@ public: _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(basic_string_view<_CharT> __value) noexcept : __string_view_(__value) {} _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(const void* __value) noexcept : __ptr_(__value) {} - _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(__handle __value) noexcept - // TODO FMT Investigate why it doesn't work without the forward. - : __handle_(std::forward<__handle>(__value)) {} + _LIBCPP_HIDE_FROM_ABI __basic_format_arg_value(__handle&& __value) noexcept : __handle_(std::move(__value)) {} }; template @@ -231,13 +280,56 @@ class _LIBCPP_TEMPLATE_VIS basic_format_arg { public: class _LIBCPP_TEMPLATE_VIS handle; - _LIBCPP_HIDE_FROM_ABI basic_format_arg() noexcept - : __type_{__format::__arg_t::__none} {} + _LIBCPP_HIDE_FROM_ABI basic_format_arg() noexcept : __type_{__format::__arg_t::__none} {} - _LIBCPP_HIDE_FROM_ABI explicit operator bool() const noexcept { - return __type_ != __format::__arg_t::__none; + _LIBCPP_HIDE_FROM_ABI explicit operator bool() const noexcept { return __type_ != __format::__arg_t::__none; } + +# if _LIBCPP_STD_VER >= 26 && defined(_LIBCPP_HAS_EXPLICIT_THIS_PARAMETER) + + // This function is user facing, so it must wrap the non-standard types of + // the "variant" in a handle to stay conforming. See __arg_t for more details. + template + _LIBCPP_HIDE_FROM_ABI decltype(auto) visit(this basic_format_arg __arg, _Visitor&& __vis) { + switch (__arg.__type_) { +# ifndef _LIBCPP_HAS_NO_INT128 + case __format::__arg_t::__i128: { + typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_.__i128_}; + return std::invoke(std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h}); + } + + case __format::__arg_t::__u128: { + typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_.__u128_}; + return std::invoke(std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h}); + } +# endif + default: + return std::__visit_format_arg(std::forward<_Visitor>(__vis), __arg); + } } + // This function is user facing, so it must wrap the non-standard types of + // the "variant" in a handle to stay conforming. See __arg_t for more details. + template + _LIBCPP_HIDE_FROM_ABI _Rp visit(this basic_format_arg __arg, _Visitor&& __vis) { + switch (__arg.__type_) { +# ifndef _LIBCPP_HAS_NO_INT128 + case __format::__arg_t::__i128: { + typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_.__i128_}; + return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h}); + } + + case __format::__arg_t::__u128: { + typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_.__u128_}; + return std::invoke_r<_Rp>(std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h}); + } +# endif + default: + return std::__visit_format_arg<_Rp>(std::forward<_Visitor>(__vis), __arg); + } + } + +# endif // _LIBCPP_STD_VER >= 26 && defined(_LIBCPP_HAS_EXPLICIT_THIS_PARAMETER) + private: using char_type = typename _Context::char_type; @@ -264,8 +356,7 @@ public: template class _LIBCPP_TEMPLATE_VIS basic_format_arg<_Context>::handle { public: - _LIBCPP_HIDE_FROM_ABI - void format(basic_format_parse_context& __parse_ctx, _Context& __ctx) const { + _LIBCPP_HIDE_FROM_ABI void format(basic_format_parse_context& __parse_ctx, _Context& __ctx) const { __handle_.__format_(__parse_ctx, __ctx, __handle_.__ptr_); } @@ -279,22 +370,25 @@ private: // This function is user facing, so it must wrap the non-standard types of // the "variant" in a handle to stay conforming. See __arg_t for more details. template -_LIBCPP_HIDE_FROM_ABI decltype(auto) -visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) { +# if _LIBCPP_STD_VER >= 26 && defined(_LIBCPP_HAS_EXPLICIT_THIS_PARAMETER) +_LIBCPP_DEPRECATED_IN_CXX26 +# endif + _LIBCPP_HIDE_FROM_ABI decltype(auto) + visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) { switch (__arg.__type_) { # ifndef _LIBCPP_HAS_NO_INT128 case __format::__arg_t::__i128: { typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_.__i128_}; - return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h}); + return std::invoke(std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h}); } case __format::__arg_t::__u128: { typename __basic_format_arg_value<_Context>::__handle __h{__arg.__value_.__u128_}; - return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h}); + return std::invoke(std::forward<_Visitor>(__vis), typename basic_format_arg<_Context>::handle{__h}); } -# endif +# endif // _LIBCPP_STD_VER >= 26 && defined(_LIBCPP_HAS_EXPLICIT_THIS_PARAMETER) default: - return _VSTD::__visit_format_arg(_VSTD::forward<_Visitor>(__vis), __arg); + return std::__visit_format_arg(std::forward<_Visitor>(__vis), __arg); } } @@ -302,4 +396,6 @@ visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) { _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___FORMAT_FORMAT_ARG_H diff --git a/third_party/libcxx/__format/format_arg_store.h b/third_party/libcxx/__format/format_arg_store.h index 1dbbcf31b..23a599e99 100644 --- a/third_party/libcxx/__format/format_arg_store.h +++ b/third_party/libcxx/__format/format_arg_store.h @@ -10,6 +10,10 @@ #ifndef _LIBCPP___FORMAT_FORMAT_ARG_STORE_H #define _LIBCPP___FORMAT_FORMAT_ARG_STORE_H +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + #include <__concepts/arithmetic.h> #include <__concepts/same_as.h> #include <__config> @@ -17,8 +21,7 @@ #include <__format/format_arg.h> #include <__type_traits/conditional.h> #include <__type_traits/extent.h> -#include <__type_traits/is_same.h> -#include <__utility/forward.h> +#include <__type_traits/remove_const.h> #include #include @@ -148,23 +151,33 @@ consteval __arg_t __determine_arg_t() { // The overload for not formattable types allows triggering the static // assertion below. template - requires(!__formattable<_Tp, typename _Context::char_type>) + requires(!__formattable_with<_Tp, _Context>) consteval __arg_t __determine_arg_t() { return __arg_t::__none; } +// Pseudo constuctor for basic_format_arg +// +// Modeled after template explicit basic_format_arg(T& v) noexcept; +// [format.arg]/4-6 template -_LIBCPP_HIDE_FROM_ABI basic_format_arg<_Context> __create_format_arg(_Tp&& __value) noexcept { - constexpr __arg_t __arg = __determine_arg_t<_Context, remove_cvref_t<_Tp>>(); +_LIBCPP_HIDE_FROM_ABI basic_format_arg<_Context> __create_format_arg(_Tp& __value) noexcept { + using _Dp = remove_const_t<_Tp>; + constexpr __arg_t __arg = __determine_arg_t<_Context, _Dp>(); static_assert(__arg != __arg_t::__none, "the supplied type is not formattable"); + static_assert(__formattable_with<_Tp, _Context>); // Not all types can be used to directly initialize the // __basic_format_arg_value. First handle all types needing adjustment, the // final else requires no adjustment. if constexpr (__arg == __arg_t::__char_type) - // On some platforms initializing a wchar_t from a char is a narrowing - // conversion. - return basic_format_arg<_Context>{__arg, static_cast(__value)}; + +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS + if constexpr (same_as && same_as<_Dp, char>) + return basic_format_arg<_Context>{__arg, static_cast(static_cast(__value))}; + else +# endif + return basic_format_arg<_Context>{__arg, __value}; else if constexpr (__arg == __arg_t::__int) return basic_format_arg<_Context>{__arg, static_cast(__value)}; else if constexpr (__arg == __arg_t::__long_long) @@ -175,9 +188,9 @@ _LIBCPP_HIDE_FROM_ABI basic_format_arg<_Context> __create_format_arg(_Tp&& __val return basic_format_arg<_Context>{__arg, static_cast(__value)}; else if constexpr (__arg == __arg_t::__string_view) // Using std::size on a character array will add the NUL-terminator to the size. - if constexpr (is_array_v>) + if constexpr (is_array_v<_Dp>) return basic_format_arg<_Context>{ - __arg, basic_string_view{__value, extent_v> - 1}}; + __arg, basic_string_view{__value, extent_v<_Dp> - 1}}; else // When the _Traits or _Allocator are different an implicit conversion will // fail. @@ -186,15 +199,14 @@ _LIBCPP_HIDE_FROM_ABI basic_format_arg<_Context> __create_format_arg(_Tp&& __val else if constexpr (__arg == __arg_t::__ptr) return basic_format_arg<_Context>{__arg, static_cast(__value)}; else if constexpr (__arg == __arg_t::__handle) - return basic_format_arg<_Context>{ - __arg, typename __basic_format_arg_value<_Context>::__handle{_VSTD::forward<_Tp>(__value)}}; + return basic_format_arg<_Context>{__arg, typename __basic_format_arg_value<_Context>::__handle{__value}}; else return basic_format_arg<_Context>{__arg, __value}; } template -_LIBCPP_HIDE_FROM_ABI void __create_packed_storage(uint64_t& __types, __basic_format_arg_value<_Context>* __values, - _Args&&... __args) noexcept { +_LIBCPP_HIDE_FROM_ABI void +__create_packed_storage(uint64_t& __types, __basic_format_arg_value<_Context>* __values, _Args&... __args) noexcept { int __shift = 0; ( [&] { @@ -211,27 +223,26 @@ _LIBCPP_HIDE_FROM_ABI void __create_packed_storage(uint64_t& __types, __basic_fo } template -_LIBCPP_HIDE_FROM_ABI void __store_basic_format_arg(basic_format_arg<_Context>* __data, _Args&&... __args) noexcept { +_LIBCPP_HIDE_FROM_ABI void __store_basic_format_arg(basic_format_arg<_Context>* __data, _Args&... __args) noexcept { ([&] { *__data++ = __format::__create_format_arg<_Context>(__args); }(), ...); } -template +template struct __packed_format_arg_store { - __basic_format_arg_value<_Context> __values_[N]; - uint64_t __types_; + __basic_format_arg_value<_Context> __values_[_Np]; + uint64_t __types_ = 0; }; -template +template struct __unpacked_format_arg_store { - basic_format_arg<_Context> __args_[N]; + basic_format_arg<_Context> __args_[_Np]; }; } // namespace __format template struct _LIBCPP_TEMPLATE_VIS __format_arg_store { - _LIBCPP_HIDE_FROM_ABI - __format_arg_store(_Args&... __args) noexcept { + _LIBCPP_HIDE_FROM_ABI __format_arg_store(_Args&... __args) noexcept { if constexpr (sizeof...(_Args) != 0) { if constexpr (__format::__use_packed_format_arg_store(sizeof...(_Args))) __format::__create_packed_storage(__storage.__types_, __storage.__values_, __args...); @@ -240,9 +251,10 @@ struct _LIBCPP_TEMPLATE_VIS __format_arg_store { } } - using _Storage = conditional_t<__format::__use_packed_format_arg_store(sizeof...(_Args)), - __format::__packed_format_arg_store<_Context, sizeof...(_Args)>, - __format::__unpacked_format_arg_store<_Context, sizeof...(_Args)>>; + using _Storage = + conditional_t<__format::__use_packed_format_arg_store(sizeof...(_Args)), + __format::__packed_format_arg_store<_Context, sizeof...(_Args)>, + __format::__unpacked_format_arg_store<_Context, sizeof...(_Args)>>; _Storage __storage; }; diff --git a/third_party/libcxx/__format/format_args.h b/third_party/libcxx/__format/format_args.h index defb42a4a..07923570f 100644 --- a/third_party/libcxx/__format/format_args.h +++ b/third_party/libcxx/__format/format_args.h @@ -10,11 +10,10 @@ #ifndef _LIBCPP___FORMAT_FORMAT_ARGS_H #define _LIBCPP___FORMAT_FORMAT_ARGS_H -#include <__availability> #include <__config> #include <__format/format_arg.h> #include <__format/format_arg_store.h> -#include <__format/format_fwd.h> +#include <__fwd/format.h> #include #include @@ -29,22 +28,19 @@ _LIBCPP_BEGIN_NAMESPACE_STD template class _LIBCPP_TEMPLATE_VIS basic_format_args { public: - basic_format_args() noexcept = default; - template _LIBCPP_HIDE_FROM_ABI basic_format_args(const __format_arg_store<_Context, _Args...>& __store) noexcept : __size_(sizeof...(_Args)) { if constexpr (sizeof...(_Args) != 0) { if constexpr (__format::__use_packed_format_arg_store(sizeof...(_Args))) { __values_ = __store.__storage.__values_; - __types_ = __store.__storage.__types_; + __types_ = __store.__storage.__types_; } else __args_ = __store.__storage.__args_; } } - _LIBCPP_HIDE_FROM_ABI - basic_format_arg<_Context> get(size_t __id) const noexcept { + _LIBCPP_HIDE_FROM_ABI basic_format_arg<_Context> get(size_t __id) const noexcept { if (__id >= __size_) return basic_format_arg<_Context>{}; diff --git a/third_party/libcxx/__format/format_context.h b/third_party/libcxx/__format/format_context.h index 521131db8..20c07559e 100644 --- a/third_party/libcxx/__format/format_context.h +++ b/third_party/libcxx/__format/format_context.h @@ -10,7 +10,6 @@ #ifndef _LIBCPP___FORMAT_FORMAT_CONTEXT_H #define _LIBCPP___FORMAT_FORMAT_CONTEXT_H -#include <__availability> #include <__concepts/same_as.h> #include <__config> #include <__format/buffer.h> @@ -18,7 +17,7 @@ #include <__format/format_arg_store.h> #include <__format/format_args.h> #include <__format/format_error.h> -#include <__format/format_fwd.h> +#include <__fwd/format.h> #include <__iterator/back_insert_iterator.h> #include <__iterator/concepts.h> #include <__memory/addressof.h> @@ -27,23 +26,26 @@ #include #ifndef _LIBCPP_HAS_NO_LOCALIZATION -#include -#include +# include <__locale> +# include #endif #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 template -requires output_iterator<_OutIt, const _CharT&> + requires output_iterator<_OutIt, const _CharT&> class _LIBCPP_TEMPLATE_VIS basic_format_context; -#ifndef _LIBCPP_HAS_NO_LOCALIZATION +# ifndef _LIBCPP_HAS_NO_LOCALIZATION /** * Helper to create a basic_format_context. * @@ -51,32 +53,26 @@ class _LIBCPP_TEMPLATE_VIS basic_format_context; */ template _LIBCPP_HIDE_FROM_ABI basic_format_context<_OutIt, _CharT> -__format_context_create( - _OutIt __out_it, - basic_format_args> __args, - optional<_VSTD::locale>&& __loc = nullopt) { - return _VSTD::basic_format_context(_VSTD::move(__out_it), __args, _VSTD::move(__loc)); +__format_context_create(_OutIt __out_it, + basic_format_args> __args, + optional&& __loc = nullopt) { + return std::basic_format_context(std::move(__out_it), __args, std::move(__loc)); } -#else +# else template _LIBCPP_HIDE_FROM_ABI basic_format_context<_OutIt, _CharT> -__format_context_create( - _OutIt __out_it, - basic_format_args> __args) { - return _VSTD::basic_format_context(_VSTD::move(__out_it), __args); +__format_context_create(_OutIt __out_it, basic_format_args> __args) { + return std::basic_format_context(std::move(__out_it), __args); } -#endif +# endif -using format_context = - basic_format_context>, - char>; -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -using wformat_context = basic_format_context< - back_insert_iterator<__format::__output_buffer>, wchar_t>; -#endif +using format_context = basic_format_context>, char>; +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +using wformat_context = basic_format_context< back_insert_iterator<__format::__output_buffer>, wchar_t>; +# endif template -requires output_iterator<_OutIt, const _CharT&> + requires output_iterator<_OutIt, const _CharT&> class // clang-format off _LIBCPP_TEMPLATE_VIS @@ -85,29 +81,28 @@ class // clang-format on basic_format_context { public: - using iterator = _OutIt; + using iterator = _OutIt; using char_type = _CharT; template using formatter_type = formatter<_Tp, _CharT>; - _LIBCPP_HIDE_FROM_ABI basic_format_arg - arg(size_t __id) const noexcept { + _LIBCPP_HIDE_FROM_ABI basic_format_arg arg(size_t __id) const noexcept { return __args_.get(__id); } -#ifndef _LIBCPP_HAS_NO_LOCALIZATION - _LIBCPP_HIDE_FROM_ABI _VSTD::locale locale() { +# ifndef _LIBCPP_HAS_NO_LOCALIZATION + _LIBCPP_HIDE_FROM_ABI std::locale locale() { if (!__loc_) - __loc_ = _VSTD::locale{}; + __loc_ = std::locale{}; return *__loc_; } -#endif +# endif _LIBCPP_HIDE_FROM_ABI iterator out() { return std::move(__out_it_); } _LIBCPP_HIDE_FROM_ABI void advance_to(iterator __it) { __out_it_ = std::move(__it); } private: iterator __out_it_; basic_format_args __args_; -#ifndef _LIBCPP_HAS_NO_LOCALIZATION +# ifndef _LIBCPP_HAS_NO_LOCALIZATION // The Standard doesn't specify how the locale is stored. // [format.context]/6 @@ -118,30 +113,27 @@ private: // locale() is called and the optional has no value the value will be created. // This allows the implementation to lazily create the locale. // TODO FMT Validate whether lazy creation is the best solution. - optional<_VSTD::locale> __loc_; + optional __loc_; - template - friend _LIBCPP_HIDE_FROM_ABI basic_format_context<__OutIt, __CharT> - __format_context_create(__OutIt, basic_format_args>, - optional<_VSTD::locale>&&); + template + friend _LIBCPP_HIDE_FROM_ABI basic_format_context<_OtherOutIt, _OtherCharT> __format_context_create( + _OtherOutIt, basic_format_args>, optional&&); // Note: the Standard doesn't specify the required constructors. - _LIBCPP_HIDE_FROM_ABI - explicit basic_format_context(_OutIt __out_it, - basic_format_args __args, - optional<_VSTD::locale>&& __loc) - : __out_it_(_VSTD::move(__out_it)), __args_(__args), - __loc_(_VSTD::move(__loc)) {} -#else - template - friend _LIBCPP_HIDE_FROM_ABI basic_format_context<__OutIt, __CharT> - __format_context_create(__OutIt, basic_format_args>); + _LIBCPP_HIDE_FROM_ABI explicit basic_format_context( + _OutIt __out_it, basic_format_args __args, optional&& __loc) + : __out_it_(std::move(__out_it)), __args_(__args), __loc_(std::move(__loc)) {} +# else + template + friend _LIBCPP_HIDE_FROM_ABI basic_format_context<_OtherOutIt, _OtherCharT> + __format_context_create(_OtherOutIt, basic_format_args>); - _LIBCPP_HIDE_FROM_ABI - explicit basic_format_context(_OutIt __out_it, - basic_format_args __args) - : __out_it_(_VSTD::move(__out_it)), __args_(__args) {} -#endif + _LIBCPP_HIDE_FROM_ABI explicit basic_format_context(_OutIt __out_it, basic_format_args __args) + : __out_it_(std::move(__out_it)), __args_(__args) {} +# endif + + basic_format_context(const basic_format_context&) = delete; + basic_format_context& operator=(const basic_format_context&) = delete; }; // A specialization for __retarget_buffer @@ -161,8 +153,7 @@ private: // Here the width of an element in input is determined dynamically. // Note when the top-level element has no width the retargeting is not needed. template -class _LIBCPP_TEMPLATE_VIS - basic_format_context::__iterator, _CharT> { +class _LIBCPP_TEMPLATE_VIS basic_format_context::__iterator, _CharT> { public: using iterator = typename __format::__retarget_buffer<_CharT>::__iterator; using char_type = _CharT; @@ -177,20 +168,25 @@ public: # endif __ctx_(std::addressof(__ctx)), __arg_([](void* __c, size_t __id) { - return std::visit_format_arg( - [&](auto __arg) -> basic_format_arg { - if constexpr (same_as) - return {}; - else if constexpr (same_as::handle>) - // At the moment it's not possible for formatting to use a re-targeted handle. - // TODO FMT add this when support is needed. - std::__throw_format_error("Re-targeting handle not supported"); - else - return basic_format_arg{ - __format::__determine_arg_t(), - __basic_format_arg_value(__arg)}; - }, - static_cast<_Context*>(__c)->arg(__id)); + auto __visitor = [&](auto __arg) -> basic_format_arg { + if constexpr (same_as) + return {}; + else if constexpr (same_as::handle>) + // At the moment it's not possible for formatting to use a re-targeted handle. + // TODO FMT add this when support is needed. + std::__throw_format_error("Re-targeting handle not supported"); + else + return basic_format_arg{ + __format::__determine_arg_t(), + __basic_format_arg_value(__arg)}; + }; +# if _LIBCPP_STD_VER >= 26 && defined(_LIBCPP_HAS_EXPLICIT_THIS_PARAMETER) + return static_cast<_Context*>(__c)->arg(__id).visit(std::move(__visitor)); +# else + _LIBCPP_SUPPRESS_DEPRECATED_PUSH + return std::visit_format_arg(std::move(__visitor), static_cast<_Context*>(__c)->arg(__id)); + _LIBCPP_SUPPRESS_DEPRECATED_POP +# endif // _LIBCPP_STD_VER >= 26 && defined(_LIBCPP_HAS_EXPLICIT_THIS_PARAMETER) }) { } @@ -198,7 +194,7 @@ public: return __arg_(__ctx_, __id); } # ifndef _LIBCPP_HAS_NO_LOCALIZATION - _LIBCPP_HIDE_FROM_ABI _VSTD::locale locale() { return __loc_(__ctx_); } + _LIBCPP_HIDE_FROM_ABI std::locale locale() { return __loc_(__ctx_); } # endif _LIBCPP_HIDE_FROM_ABI iterator out() { return std::move(__out_it_); } _LIBCPP_HIDE_FROM_ABI void advance_to(iterator __it) { __out_it_ = std::move(__it); } @@ -219,4 +215,6 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_format_context); _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___FORMAT_FORMAT_CONTEXT_H diff --git a/third_party/libcxx/__format/format_error.h b/third_party/libcxx/__format/format_error.h index 7fb4dd0d7..ed40e395d 100644 --- a/third_party/libcxx/__format/format_error.h +++ b/third_party/libcxx/__format/format_error.h @@ -11,7 +11,7 @@ #define _LIBCPP___FORMAT_FORMAT_ERROR_H #include <__config> -#include +#include <__verbose_abort> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -24,25 +24,23 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_DIAGNOSTIC_PUSH _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables") -class _LIBCPP_EXCEPTION_ABI format_error : public runtime_error { +class _LIBCPP_EXPORTED_FROM_ABI format_error : public runtime_error { public: - _LIBCPP_HIDE_FROM_ABI explicit format_error(const string& __s) - : runtime_error(__s) {} - _LIBCPP_HIDE_FROM_ABI explicit format_error(const char* __s) - : runtime_error(__s) {} + _LIBCPP_HIDE_FROM_ABI explicit format_error(const string& __s) : runtime_error(__s) {} + _LIBCPP_HIDE_FROM_ABI explicit format_error(const char* __s) : runtime_error(__s) {} + _LIBCPP_HIDE_FROM_ABI format_error(const format_error&) = default; + _LIBCPP_HIDE_FROM_ABI format_error& operator=(const format_error&) = default; _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~format_error() noexcept override = default; }; _LIBCPP_DIAGNOSTIC_POP -_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void -__throw_format_error(const char* __s) { -#ifndef _LIBCPP_HAS_NO_EXCEPTIONS +_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void __throw_format_error(const char* __s) { +# ifndef _LIBCPP_HAS_NO_EXCEPTIONS throw format_error(__s); -#else - (void)__s; - _VSTD::abort(); -#endif +# else + _LIBCPP_VERBOSE_ABORT("format_error was thrown in -fno-exceptions mode with message \"%s\"", __s); +# endif } #endif //_LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__format/format_functions.h b/third_party/libcxx/__format/format_functions.h index 72a9f377d..d14b49aff 100644 --- a/third_party/libcxx/__format/format_functions.h +++ b/third_party/libcxx/__format/format_functions.h @@ -11,11 +11,9 @@ #define _LIBCPP___FORMAT_FORMAT_FUNCTIONS #include <__algorithm/clamp.h> -#include <__availability> #include <__concepts/convertible_to.h> #include <__concepts/same_as.h> #include <__config> -#include <__debug> #include <__format/buffer.h> #include <__format/format_arg.h> #include <__format/format_arg_store.h> @@ -36,20 +34,23 @@ #include <__iterator/back_insert_iterator.h> #include <__iterator/concepts.h> #include <__iterator/incrementable_traits.h> -#include <__iterator/readable_traits.h> // iter_value_t +#include <__iterator/iterator_traits.h> // iter_value_t #include <__variant/monostate.h> #include #include #include #ifndef _LIBCPP_HAS_NO_LOCALIZATION -#include +# include <__locale> #endif #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 @@ -60,21 +61,21 @@ _LIBCPP_BEGIN_NAMESPACE_STD // to do this optimization now. using format_args = basic_format_args; -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS using wformat_args = basic_format_args; -#endif +# endif template -_LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...> make_format_args(_Args&&... __args) { - return _VSTD::__format_arg_store<_Context, _Args...>(__args...); +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...> make_format_args(_Args&... __args) { + return std::__format_arg_store<_Context, _Args...>(__args...); } -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template -_LIBCPP_HIDE_FROM_ABI __format_arg_store make_wformat_args(_Args&&... __args) { - return _VSTD::__format_arg_store(__args...); +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI __format_arg_store make_wformat_args(_Args&... __args) { + return std::__format_arg_store(__args...); } -#endif +# endif namespace __format { @@ -128,13 +129,13 @@ public: _LIBCPP_HIDE_FROM_ABI constexpr __arg_t arg(size_t __id) const { if (__id >= __size_) - std::__throw_format_error("Argument index out of bounds"); + std::__throw_format_error("The argument index value is too large for the number of arguments supplied"); return __args_[__id]; } _LIBCPP_HIDE_FROM_ABI constexpr const __compile_time_handle<_CharT>& __handle(size_t __id) const { if (__id >= __size_) - std::__throw_format_error("Argument index out of bounds"); + std::__throw_format_error("The argument index value is too large for the number of arguments supplied"); return __handles_[__id]; } @@ -189,9 +190,10 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __compile_time_validate_argument( // This function is not user facing, so it can directly use the non-standard types of the "variant". template -_LIBCPP_HIDE_FROM_ABI constexpr void __compile_time_visit_format_arg(basic_format_parse_context<_CharT>& __parse_ctx, - __compile_time_basic_format_context<_CharT>& __ctx, - __arg_t __type) { +_LIBCPP_HIDE_FROM_ABI constexpr void __compile_time_visit_format_arg( + basic_format_parse_context<_CharT>& __parse_ctx, + __compile_time_basic_format_context<_CharT>& __ctx, + __arg_t __type) { switch (__type) { case __arg_t::__none: std::__throw_format_error("Invalid argument"); @@ -204,22 +206,22 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __compile_time_visit_format_arg(basic_forma case __arg_t::__long_long: return __format::__compile_time_validate_argument<_CharT, long long>(__parse_ctx, __ctx); case __arg_t::__i128: -# ifndef _LIBCPP_HAS_NO_INT128 +# ifndef _LIBCPP_HAS_NO_INT128 return __format::__compile_time_validate_argument<_CharT, __int128_t>(__parse_ctx, __ctx); -# else +# else std::__throw_format_error("Invalid argument"); -# endif +# endif return; case __arg_t::__unsigned: return __format::__compile_time_validate_argument<_CharT, unsigned>(__parse_ctx, __ctx); case __arg_t::__unsigned_long_long: return __format::__compile_time_validate_argument<_CharT, unsigned long long>(__parse_ctx, __ctx); case __arg_t::__u128: -# ifndef _LIBCPP_HAS_NO_INT128 +# ifndef _LIBCPP_HAS_NO_INT128 return __format::__compile_time_validate_argument<_CharT, __uint128_t>(__parse_ctx, __ctx); -# else +# else std::__throw_format_error("Invalid argument"); -# endif +# endif return; case __arg_t::__float: return __format::__compile_time_validate_argument<_CharT, float, true>(__parse_ctx, __ctx); @@ -241,11 +243,13 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __compile_time_visit_format_arg(basic_forma template _LIBCPP_HIDE_FROM_ABI constexpr _Iterator -__handle_replacement_field(_Iterator __begin, _Iterator __end, - _ParseCtx& __parse_ctx, _Ctx& __ctx) { - using _CharT = iter_value_t<_Iterator>; +__handle_replacement_field(_Iterator __begin, _Iterator __end, _ParseCtx& __parse_ctx, _Ctx& __ctx) { + using _CharT = iter_value_t<_Iterator>; __format::__parse_number_result __r = __format::__parse_arg_id(__begin, __end, __parse_ctx); + if (__r.__last == __end) + std::__throw_format_error("The argument index should end with a ':' or a '}'"); + bool __parse = *__r.__last == _CharT(':'); switch (*__r.__last) { case _CharT(':'): @@ -257,22 +261,22 @@ __handle_replacement_field(_Iterator __begin, _Iterator __end, __parse_ctx.advance_to(__r.__last); break; default: - std::__throw_format_error("The replacement field arg-id should terminate at a ':' or '}'"); + std::__throw_format_error("The argument index should end with a ':' or a '}'"); } if constexpr (same_as<_Ctx, __compile_time_basic_format_context<_CharT>>) { __arg_t __type = __ctx.arg(__r.__value); if (__type == __arg_t::__none) - std::__throw_format_error("Argument index out of bounds"); + std::__throw_format_error("The argument index value is too large for the number of arguments supplied"); else if (__type == __arg_t::__handle) __ctx.__handle(__r.__value).__parse(__parse_ctx); else if (__parse) __format::__compile_time_visit_format_arg(__parse_ctx, __ctx, __type); } else - _VSTD::__visit_format_arg( + std::__visit_format_arg( [&](auto __arg) { if constexpr (same_as) - std::__throw_format_error("Argument index out of bounds"); + std::__throw_format_error("The argument index value is too large for the number of arguments supplied"); else if constexpr (same_as::handle>) __arg.format(__parse_ctx, __ctx); else { @@ -292,13 +296,12 @@ __handle_replacement_field(_Iterator __begin, _Iterator __end, } template -_LIBCPP_HIDE_FROM_ABI constexpr typename _Ctx::iterator -__vformat_to(_ParseCtx&& __parse_ctx, _Ctx&& __ctx) { +_LIBCPP_HIDE_FROM_ABI constexpr typename _Ctx::iterator __vformat_to(_ParseCtx&& __parse_ctx, _Ctx&& __ctx) { using _CharT = typename _ParseCtx::char_type; static_assert(same_as); - auto __begin = __parse_ctx.begin(); - auto __end = __parse_ctx.end(); + auto __begin = __parse_ctx.begin(); + auto __end = __parse_ctx.end(); typename _Ctx::iterator __out_it = __ctx.out(); while (__begin != __end) { switch (*__begin) { @@ -308,9 +311,8 @@ __vformat_to(_ParseCtx&& __parse_ctx, _Ctx&& __ctx) { std::__throw_format_error("The format string terminates at a '{'"); if (*__begin != _CharT('{')) [[likely]] { - __ctx.advance_to(_VSTD::move(__out_it)); - __begin = - __format::__handle_replacement_field(__begin, __end, __parse_ctx, __ctx); + __ctx.advance_to(std::move(__out_it)); + __begin = __format::__handle_replacement_field(__begin, __end, __parse_ctx, __ctx); __out_it = __ctx.out(); // The output is written and __begin points to the next character. So @@ -336,6 +338,30 @@ __vformat_to(_ParseCtx&& __parse_ctx, _Ctx&& __ctx) { } // namespace __format +# if _LIBCPP_STD_VER >= 26 +template +struct _LIBCPP_TEMPLATE_VIS __runtime_format_string { +private: + basic_string_view<_CharT> __str_; + + template + friend struct _LIBCPP_TEMPLATE_VIS basic_format_string; + +public: + _LIBCPP_HIDE_FROM_ABI __runtime_format_string(basic_string_view<_CharT> __s) noexcept : __str_(__s) {} + + __runtime_format_string(const __runtime_format_string&) = delete; + __runtime_format_string& operator=(const __runtime_format_string&) = delete; +}; + +_LIBCPP_HIDE_FROM_ABI inline __runtime_format_string runtime_format(string_view __fmt) noexcept { return __fmt; } +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +_LIBCPP_HIDE_FROM_ABI inline __runtime_format_string runtime_format(wstring_view __fmt) noexcept { + return __fmt; +} +# endif +# endif //_LIBCPP_STD_VER >= 26 + template struct _LIBCPP_TEMPLATE_VIS basic_format_string { template @@ -345,9 +371,10 @@ struct _LIBCPP_TEMPLATE_VIS basic_format_string { _Context{__types_.data(), __handles_.data(), sizeof...(_Args)}); } - _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<_CharT> get() const noexcept { - return __str_; - } + _LIBCPP_HIDE_FROM_ABI constexpr basic_string_view<_CharT> get() const noexcept { return __str_; } +# if _LIBCPP_STD_VER >= 26 + _LIBCPP_HIDE_FROM_ABI basic_format_string(__runtime_format_string<_CharT> __s) noexcept : __str_(__s.__str_) {} +# endif private: basic_string_view<_CharT> __str_; @@ -357,20 +384,6 @@ private: static constexpr array<__format::__arg_t, sizeof...(_Args)> __types_{ __format::__determine_arg_t<_Context, remove_cvref_t<_Args>>()...}; - // TODO FMT remove this work-around when the AIX ICE has been resolved. -# if defined(_AIX) && defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER < 1400 - template - static constexpr __format::__compile_time_handle<_CharT> __get_handle() { - __format::__compile_time_handle<_CharT> __handle; - if (__format::__determine_arg_t<_Context, _Tp>() == __format::__arg_t::__handle) - __handle.template __enable<_Tp>(); - - return __handle; - } - - static constexpr array<__format::__compile_time_handle<_CharT>, sizeof...(_Args)> __handles_{ - __get_handle<_Args>()...}; -# else static constexpr array<__format::__compile_time_handle<_CharT>, sizeof...(_Args)> __handles_{[] { using _Tp = remove_cvref_t<_Args>; __format::__compile_time_handle<_CharT> __handle; @@ -379,30 +392,29 @@ private: return __handle; }()...}; -# endif }; template using format_string = basic_format_string...>; -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template using wformat_string = basic_format_string...>; -#endif +# endif template -requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt - __vformat_to( - _OutIt __out_it, basic_string_view<_CharT> __fmt, - basic_format_args> __args) { + requires(output_iterator<_OutIt, const _CharT&>) +_LIBCPP_HIDE_FROM_ABI _OutIt __vformat_to(_OutIt __out_it, + basic_string_view<_CharT> __fmt, + basic_format_args> __args) { if constexpr (same_as<_OutIt, _FormatOutIt>) - return _VSTD::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()}, - _VSTD::__format_context_create(_VSTD::move(__out_it), __args)); + return std::__format::__vformat_to( + basic_format_parse_context{__fmt, __args.__size()}, std::__format_context_create(std::move(__out_it), __args)); else { - __format::__format_buffer<_OutIt, _CharT> __buffer{_VSTD::move(__out_it)}; - _VSTD::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()}, - _VSTD::__format_context_create(__buffer.__make_output_iterator(), __args)); - return _VSTD::move(__buffer).__out_it(); + __format::__format_buffer<_OutIt, _CharT> __buffer{std::move(__out_it)}; + std::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()}, + std::__format_context_create(__buffer.__make_output_iterator(), __args)); + return std::move(__buffer).__out_it(); } } @@ -410,268 +422,259 @@ requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt // https://reviews.llvm.org/D110499#inline-1180704 // TODO FMT Evaluate whether we want to file a Clang bug report regarding this. template _OutIt> -_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt -vformat_to(_OutIt __out_it, string_view __fmt, format_args __args) { - return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args); +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt vformat_to(_OutIt __out_it, string_view __fmt, format_args __args) { + return std::__vformat_to(std::move(__out_it), __fmt, __args); } -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template _OutIt> _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt vformat_to(_OutIt __out_it, wstring_view __fmt, wformat_args __args) { - return _VSTD::__vformat_to(_VSTD::move(__out_it), __fmt, __args); + return std::__vformat_to(std::move(__out_it), __fmt, __args); } -#endif +# endif template _OutIt, class... _Args> _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt format_to(_OutIt __out_it, format_string<_Args...> __fmt, _Args&&... __args) { - return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt.get(), - _VSTD::make_format_args(__args...)); + return std::vformat_to(std::move(__out_it), __fmt.get(), std::make_format_args(__args...)); } -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template _OutIt, class... _Args> _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt format_to(_OutIt __out_it, wformat_string<_Args...> __fmt, _Args&&... __args) { - return _VSTD::vformat_to(_VSTD::move(__out_it), __fmt.get(), - _VSTD::make_wformat_args(__args...)); + return std::vformat_to(std::move(__out_it), __fmt.get(), std::make_wformat_args(__args...)); } -#endif +# endif // TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup // fires too eagerly, see http://llvm.org/PR61563. template -_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string -vformat(string_view __fmt, format_args __args) { +[[nodiscard]] _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string vformat(string_view __fmt, format_args __args) { string __res; - _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args); + std::vformat_to(std::back_inserter(__res), __fmt, __args); return __res; } -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS // TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup // fires too eagerly, see http://llvm.org/PR61563. template -_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring +[[nodiscard]] _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring vformat(wstring_view __fmt, wformat_args __args) { wstring __res; - _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args); + std::vformat_to(std::back_inserter(__res), __fmt, __args); return __res; } -#endif +# endif template -_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI string format(format_string<_Args...> __fmt, - _Args&&... __args) { - return _VSTD::vformat(__fmt.get(), _VSTD::make_format_args(__args...)); +[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI string +format(format_string<_Args...> __fmt, _Args&&... __args) { + return std::vformat(__fmt.get(), std::make_format_args(__args...)); } -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template -_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI wstring +[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI wstring format(wformat_string<_Args...> __fmt, _Args&&... __args) { - return _VSTD::vformat(__fmt.get(), _VSTD::make_wformat_args(__args...)); + return std::vformat(__fmt.get(), std::make_wformat_args(__args...)); } -#endif +# endif template -_LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, - basic_string_view<_CharT> __fmt, - basic_format_args<_Context> __args) { - __format::__format_to_n_buffer<_OutIt, _CharT> __buffer{_VSTD::move(__out_it), __n}; - _VSTD::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()}, - _VSTD::__format_context_create(__buffer.__make_output_iterator(), __args)); - return _VSTD::move(__buffer).__result(); +_LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> +__vformat_to_n(_OutIt __out_it, + iter_difference_t<_OutIt> __n, + basic_string_view<_CharT> __fmt, + basic_format_args<_Context> __args) { + __format::__format_to_n_buffer<_OutIt, _CharT> __buffer{std::move(__out_it), __n}; + std::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()}, + std::__format_context_create(__buffer.__make_output_iterator(), __args)); + return std::move(__buffer).__result(); } template _OutIt, class... _Args> _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, format_string<_Args...> __fmt, _Args&&... __args) { - return _VSTD::__vformat_to_n(_VSTD::move(__out_it), __n, __fmt.get(), _VSTD::make_format_args(__args...)); + return std::__vformat_to_n(std::move(__out_it), __n, __fmt.get(), std::make_format_args(__args...)); } -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template _OutIt, class... _Args> _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> -format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, wformat_string<_Args...> __fmt, - _Args&&... __args) { - return _VSTD::__vformat_to_n(_VSTD::move(__out_it), __n, __fmt.get(), _VSTD::make_wformat_args(__args...)); +format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, wformat_string<_Args...> __fmt, _Args&&... __args) { + return std::__vformat_to_n(std::move(__out_it), __n, __fmt.get(), std::make_wformat_args(__args...)); } -#endif +# endif template _LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(basic_string_view<_CharT> __fmt, auto __args) { __format::__formatted_size_buffer<_CharT> __buffer; - _VSTD::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()}, - _VSTD::__format_context_create(__buffer.__make_output_iterator(), __args)); - return _VSTD::move(__buffer).__result(); + std::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()}, + std::__format_context_create(__buffer.__make_output_iterator(), __args)); + return std::move(__buffer).__result(); } template -_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t +[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t formatted_size(format_string<_Args...> __fmt, _Args&&... __args) { - return _VSTD::__vformatted_size(__fmt.get(), basic_format_args{_VSTD::make_format_args(__args...)}); + return std::__vformatted_size(__fmt.get(), basic_format_args{std::make_format_args(__args...)}); } -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template -_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t +[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t formatted_size(wformat_string<_Args...> __fmt, _Args&&... __args) { - return _VSTD::__vformatted_size(__fmt.get(), basic_format_args{_VSTD::make_wformat_args(__args...)}); + return std::__vformatted_size(__fmt.get(), basic_format_args{std::make_wformat_args(__args...)}); } -#endif +# endif -#ifndef _LIBCPP_HAS_NO_LOCALIZATION +# ifndef _LIBCPP_HAS_NO_LOCALIZATION template -requires(output_iterator<_OutIt, const _CharT&>) _LIBCPP_HIDE_FROM_ABI _OutIt - __vformat_to( - _OutIt __out_it, locale __loc, basic_string_view<_CharT> __fmt, - basic_format_args> __args) { + requires(output_iterator<_OutIt, const _CharT&>) +_LIBCPP_HIDE_FROM_ABI _OutIt __vformat_to( + _OutIt __out_it, + locale __loc, + basic_string_view<_CharT> __fmt, + basic_format_args> __args) { if constexpr (same_as<_OutIt, _FormatOutIt>) - return _VSTD::__format::__vformat_to( - basic_format_parse_context{__fmt, __args.__size()}, - _VSTD::__format_context_create(_VSTD::move(__out_it), __args, _VSTD::move(__loc))); + return std::__format::__vformat_to(basic_format_parse_context{__fmt, __args.__size()}, + std::__format_context_create(std::move(__out_it), __args, std::move(__loc))); else { - __format::__format_buffer<_OutIt, _CharT> __buffer{_VSTD::move(__out_it)}; - _VSTD::__format::__vformat_to( + __format::__format_buffer<_OutIt, _CharT> __buffer{std::move(__out_it)}; + std::__format::__vformat_to( basic_format_parse_context{__fmt, __args.__size()}, - _VSTD::__format_context_create(__buffer.__make_output_iterator(), __args, _VSTD::move(__loc))); - return _VSTD::move(__buffer).__out_it(); + std::__format_context_create(__buffer.__make_output_iterator(), __args, std::move(__loc))); + return std::move(__buffer).__out_it(); } } template _OutIt> -_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt vformat_to( - _OutIt __out_it, locale __loc, string_view __fmt, format_args __args) { - return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, - __args); +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt +vformat_to(_OutIt __out_it, locale __loc, string_view __fmt, format_args __args) { + return std::__vformat_to(std::move(__out_it), std::move(__loc), __fmt, __args); } -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template _OutIt> -_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt vformat_to( - _OutIt __out_it, locale __loc, wstring_view __fmt, wformat_args __args) { - return _VSTD::__vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt, - __args); +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt +vformat_to(_OutIt __out_it, locale __loc, wstring_view __fmt, wformat_args __args) { + return std::__vformat_to(std::move(__out_it), std::move(__loc), __fmt, __args); } -#endif +# endif template _OutIt, class... _Args> _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt format_to(_OutIt __out_it, locale __loc, format_string<_Args...> __fmt, _Args&&... __args) { - return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt.get(), - _VSTD::make_format_args(__args...)); + return std::vformat_to(std::move(__out_it), std::move(__loc), __fmt.get(), std::make_format_args(__args...)); } -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template _OutIt, class... _Args> _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _OutIt format_to(_OutIt __out_it, locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) { - return _VSTD::vformat_to(_VSTD::move(__out_it), _VSTD::move(__loc), __fmt.get(), - _VSTD::make_wformat_args(__args...)); + return std::vformat_to(std::move(__out_it), std::move(__loc), __fmt.get(), std::make_wformat_args(__args...)); } -#endif +# endif // TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup // fires too eagerly, see http://llvm.org/PR61563. template -_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string +[[nodiscard]] _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string vformat(locale __loc, string_view __fmt, format_args __args) { string __res; - _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt, - __args); + std::vformat_to(std::back_inserter(__res), std::move(__loc), __fmt, __args); return __res; } -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS // TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup // fires too eagerly, see http://llvm.org/PR61563. template -_LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring +[[nodiscard]] _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring vformat(locale __loc, wstring_view __fmt, wformat_args __args) { wstring __res; - _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt, - __args); + std::vformat_to(std::back_inserter(__res), std::move(__loc), __fmt, __args); return __res; } -#endif +# endif template -_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI string format(locale __loc, - format_string<_Args...> __fmt, - _Args&&... __args) { - return _VSTD::vformat(_VSTD::move(__loc), __fmt.get(), - _VSTD::make_format_args(__args...)); +[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI string +format(locale __loc, format_string<_Args...> __fmt, _Args&&... __args) { + return std::vformat(std::move(__loc), __fmt.get(), std::make_format_args(__args...)); } -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template -_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI wstring +[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI wstring format(locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) { - return _VSTD::vformat(_VSTD::move(__loc), __fmt.get(), - _VSTD::make_wformat_args(__args...)); + return std::vformat(std::move(__loc), __fmt.get(), std::make_wformat_args(__args...)); } -#endif +# endif template -_LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, - locale __loc, basic_string_view<_CharT> __fmt, - basic_format_args<_Context> __args) { - __format::__format_to_n_buffer<_OutIt, _CharT> __buffer{_VSTD::move(__out_it), __n}; - _VSTD::__format::__vformat_to( +_LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> __vformat_to_n( + _OutIt __out_it, + iter_difference_t<_OutIt> __n, + locale __loc, + basic_string_view<_CharT> __fmt, + basic_format_args<_Context> __args) { + __format::__format_to_n_buffer<_OutIt, _CharT> __buffer{std::move(__out_it), __n}; + std::__format::__vformat_to( basic_format_parse_context{__fmt, __args.__size()}, - _VSTD::__format_context_create(__buffer.__make_output_iterator(), __args, _VSTD::move(__loc))); - return _VSTD::move(__buffer).__result(); + std::__format_context_create(__buffer.__make_output_iterator(), __args, std::move(__loc))); + return std::move(__buffer).__result(); } template _OutIt, class... _Args> -_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> -format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, format_string<_Args...> __fmt, - _Args&&... __args) { - return _VSTD::__vformat_to_n(_VSTD::move(__out_it), __n, _VSTD::move(__loc), __fmt.get(), - _VSTD::make_format_args(__args...)); +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> format_to_n( + _OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, format_string<_Args...> __fmt, _Args&&... __args) { + return std::__vformat_to_n( + std::move(__out_it), __n, std::move(__loc), __fmt.get(), std::make_format_args(__args...)); } -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template _OutIt, class... _Args> -_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> -format_to_n(_OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, wformat_string<_Args...> __fmt, - _Args&&... __args) { - return _VSTD::__vformat_to_n(_VSTD::move(__out_it), __n, _VSTD::move(__loc), __fmt.get(), - _VSTD::make_wformat_args(__args...)); +_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI format_to_n_result<_OutIt> format_to_n( + _OutIt __out_it, iter_difference_t<_OutIt> __n, locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) { + return std::__vformat_to_n( + std::move(__out_it), __n, std::move(__loc), __fmt.get(), std::make_wformat_args(__args...)); } -#endif +# endif template _LIBCPP_HIDE_FROM_ABI size_t __vformatted_size(locale __loc, basic_string_view<_CharT> __fmt, auto __args) { __format::__formatted_size_buffer<_CharT> __buffer; - _VSTD::__format::__vformat_to( + std::__format::__vformat_to( basic_format_parse_context{__fmt, __args.__size()}, - _VSTD::__format_context_create(__buffer.__make_output_iterator(), __args, _VSTD::move(__loc))); - return _VSTD::move(__buffer).__result(); + std::__format_context_create(__buffer.__make_output_iterator(), __args, std::move(__loc))); + return std::move(__buffer).__result(); } template -_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t +[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t formatted_size(locale __loc, format_string<_Args...> __fmt, _Args&&... __args) { - return _VSTD::__vformatted_size(_VSTD::move(__loc), __fmt.get(), basic_format_args{_VSTD::make_format_args(__args...)}); + return std::__vformatted_size(std::move(__loc), __fmt.get(), basic_format_args{std::make_format_args(__args...)}); } -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template -_LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t +[[nodiscard]] _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI size_t formatted_size(locale __loc, wformat_string<_Args...> __fmt, _Args&&... __args) { - return _VSTD::__vformatted_size(_VSTD::move(__loc), __fmt.get(), basic_format_args{_VSTD::make_wformat_args(__args...)}); + return std::__vformatted_size(std::move(__loc), __fmt.get(), basic_format_args{std::make_wformat_args(__args...)}); } -#endif - -#endif // _LIBCPP_HAS_NO_LOCALIZATION +# endif +# endif // _LIBCPP_HAS_NO_LOCALIZATION #endif //_LIBCPP_STD_VER >= 20 _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___FORMAT_FORMAT_FUNCTIONS diff --git a/third_party/libcxx/__format/format_parse_context.h b/third_party/libcxx/__format/format_parse_context.h index 79f53f77d..aefcd5497 100644 --- a/third_party/libcxx/__format/format_parse_context.h +++ b/third_party/libcxx/__format/format_parse_context.h @@ -26,32 +26,24 @@ _LIBCPP_BEGIN_NAMESPACE_STD template class _LIBCPP_TEMPLATE_VIS basic_format_parse_context { public: - using char_type = _CharT; + using char_type = _CharT; using const_iterator = typename basic_string_view<_CharT>::const_iterator; - using iterator = const_iterator; + using iterator = const_iterator; - _LIBCPP_HIDE_FROM_ABI - constexpr explicit basic_format_parse_context(basic_string_view<_CharT> __fmt, - size_t __num_args = 0) noexcept + _LIBCPP_HIDE_FROM_ABI constexpr explicit basic_format_parse_context( + basic_string_view<_CharT> __fmt, size_t __num_args = 0) noexcept : __begin_(__fmt.begin()), __end_(__fmt.end()), __indexing_(__unknown), __next_arg_id_(0), __num_args_(__num_args) {} - basic_format_parse_context(const basic_format_parse_context&) = delete; - basic_format_parse_context& - operator=(const basic_format_parse_context&) = delete; + basic_format_parse_context(const basic_format_parse_context&) = delete; + basic_format_parse_context& operator=(const basic_format_parse_context&) = delete; - _LIBCPP_HIDE_FROM_ABI constexpr const_iterator begin() const noexcept { - return __begin_; - } - _LIBCPP_HIDE_FROM_ABI constexpr const_iterator end() const noexcept { - return __end_; - } - _LIBCPP_HIDE_FROM_ABI constexpr void advance_to(const_iterator __it) { - __begin_ = __it; - } + _LIBCPP_HIDE_FROM_ABI constexpr const_iterator begin() const noexcept { return __begin_; } + _LIBCPP_HIDE_FROM_ABI constexpr const_iterator end() const noexcept { return __end_; } + _LIBCPP_HIDE_FROM_ABI constexpr void advance_to(const_iterator __it) { __begin_ = __it; } _LIBCPP_HIDE_FROM_ABI constexpr size_t next_arg_id() { if (__indexing_ == __manual) @@ -102,9 +94,9 @@ private: _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_format_parse_context); using format_parse_context = basic_format_parse_context; -#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS +# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS using wformat_parse_context = basic_format_parse_context; -#endif +# endif #endif //_LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__format/format_string.h b/third_party/libcxx/__format/format_string.h index bec3fe167..bdf3cff7f 100644 --- a/third_party/libcxx/__format/format_string.h +++ b/third_party/libcxx/__format/format_string.h @@ -14,7 +14,7 @@ #include <__config> #include <__format/format_error.h> #include <__iterator/concepts.h> -#include <__iterator/readable_traits.h> // iter_value_t +#include <__iterator/iterator_traits.h> // iter_value_t #include #include @@ -38,8 +38,7 @@ template __parse_number_result(_Iterator, uint32_t) -> __parse_number_result<_Iterator>; template -_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator> -__parse_number(_Iterator __begin, _Iterator __end); +_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator> __parse_number(_Iterator __begin, _Iterator __end); /** * The maximum value of a numeric argument. @@ -66,8 +65,7 @@ template _LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator> __parse_automatic(_Iterator __begin, _Iterator, auto& __parse_ctx) { size_t __value = __parse_ctx.next_arg_id(); - _LIBCPP_ASSERT(__value <= __number_max, - "Compilers don't support this number of arguments"); + _LIBCPP_ASSERT_UNCATEGORIZED(__value <= __number_max, "Compilers don't support this number of arguments"); return {__begin, uint32_t(__value)}; } @@ -92,8 +90,7 @@ template _LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator> __parse_number(_Iterator __begin, _Iterator __end_input) { using _CharT = iter_value_t<_Iterator>; - static_assert(__format::__number_max == INT32_MAX, - "The algorithm is implemented based on this value."); + static_assert(__format::__number_max == INT32_MAX, "The algorithm is implemented based on this value."); /* * Limit the input to 9 digits, otherwise we need two checks during every * iteration: @@ -101,7 +98,7 @@ __parse_number(_Iterator __begin, _Iterator __end_input) { * - Does the value exceed width of an uint32_t? (Switching to uint64_t would * have the same issue, but with a higher maximum.) */ - _Iterator __end = __end_input - __begin > 9 ? __begin + 9 : __end_input; + _Iterator __end = __end_input - __begin > 9 ? __begin + 9 : __end_input; uint32_t __value = *__begin - _CharT('0'); while (++__begin != __end) { if (*__begin < _CharT('0') || *__begin > _CharT('9')) @@ -110,9 +107,7 @@ __parse_number(_Iterator __begin, _Iterator __end_input) { __value = __value * 10 + *__begin - _CharT('0'); } - if (__begin != __end_input && *__begin >= _CharT('0') && - *__begin <= _CharT('9')) { - + if (__begin != __end_input && *__begin >= _CharT('0') && *__begin <= _CharT('9')) { /* * There are more than 9 digits, do additional validations: * - Does the 10th digit exceed the maximum allowed value? @@ -120,10 +115,8 @@ __parse_number(_Iterator __begin, _Iterator __end_input) { * (More than 10 digits always overflows the maximum.) */ uint64_t __v = uint64_t(__value) * 10 + *__begin++ - _CharT('0'); - if (__v > __number_max || - (__begin != __end_input && *__begin >= _CharT('0') && - *__begin <= _CharT('9'))) - std::__throw_format_error("The numeric value of the format-spec is too large"); + if (__v > __number_max || (__begin != __end_input && *__begin >= _CharT('0') && *__begin <= _CharT('9'))) + std::__throw_format_error("The numeric value of the format specifier is too large"); __value = __v; } @@ -153,7 +146,7 @@ __parse_arg_id(_Iterator __begin, _Iterator __end, auto& __parse_ctx) { return __detail::__parse_automatic(__begin, __end, __parse_ctx); } if (*__begin < _CharT('0') || *__begin > _CharT('9')) - std::__throw_format_error("The arg-id of the format-spec starts with an invalid character"); + std::__throw_format_error("The argument index starts with an invalid character"); return __detail::__parse_manual(__begin, __end, __parse_ctx); } diff --git a/third_party/libcxx/__format/formatter.h b/third_party/libcxx/__format/formatter.h index 172b2d5f7..e2f418f93 100644 --- a/third_party/libcxx/__format/formatter.h +++ b/third_party/libcxx/__format/formatter.h @@ -10,9 +10,8 @@ #ifndef _LIBCPP___FORMAT_FORMATTER_H #define _LIBCPP___FORMAT_FORMATTER_H -#include <__availability> #include <__config> -#include <__format/format_fwd.h> +#include <__fwd/format.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -33,8 +32,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD /// - is_move_assignable. template struct _LIBCPP_TEMPLATE_VIS formatter { - formatter() = delete; - formatter(const formatter&) = delete; + formatter() = delete; + formatter(const formatter&) = delete; formatter& operator=(const formatter&) = delete; }; diff --git a/third_party/libcxx/__format/formatter_bool.h b/third_party/libcxx/__format/formatter_bool.h index e95a216bb..17dc69541 100644 --- a/third_party/libcxx/__format/formatter_bool.h +++ b/third_party/libcxx/__format/formatter_bool.h @@ -11,20 +11,17 @@ #define _LIBCPP___FORMAT_FORMATTER_BOOL_H #include <__algorithm/copy.h> -#include <__availability> +#include <__assert> #include <__config> -#include <__debug> #include <__format/concepts.h> -#include <__format/format_error.h> #include <__format/format_parse_context.h> #include <__format/formatter.h> #include <__format/formatter_integral.h> #include <__format/parser_std_format_spec.h> #include <__utility/unreachable.h> -#include #ifndef _LIBCPP_HAS_NO_LOCALIZATION -# include +# include <__locale> #endif #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -41,7 +38,7 @@ public: template _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { typename _ParseContext::iterator __result = __parser_.__parse(__ctx, __format_spec::__fields_integral); - __format_spec::__process_parsed_bool(__parser_); + __format_spec::__process_parsed_bool(__parser_, "a bool"); return __result; } @@ -64,7 +61,7 @@ public: static_cast(__value), __ctx, __parser_.__get_parsed_std_specifications(__ctx)); default: - _LIBCPP_ASSERT(false, "The parse function should have validated the type"); + _LIBCPP_ASSERT_INTERNAL(false, "The parse function should have validated the type"); __libcpp_unreachable(); } } diff --git a/third_party/libcxx/__format/formatter_char.h b/third_party/libcxx/__format/formatter_char.h index 15a649807..d33e84368 100644 --- a/third_party/libcxx/__format/formatter_char.h +++ b/third_party/libcxx/__format/formatter_char.h @@ -10,7 +10,6 @@ #ifndef _LIBCPP___FORMAT_FORMATTER_CHAR_H #define _LIBCPP___FORMAT_FORMATTER_CHAR_H -#include <__availability> #include <__concepts/same_as.h> #include <__config> #include <__format/concepts.h> @@ -19,8 +18,9 @@ #include <__format/formatter_integral.h> #include <__format/formatter_output.h> #include <__format/parser_std_format_spec.h> +#include <__format/write_escaped.h> #include <__type_traits/conditional.h> -#include <__type_traits/is_signed.h> +#include <__type_traits/make_unsigned.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -36,7 +36,7 @@ public: template _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { typename _ParseContext::iterator __result = __parser_.__parse(__ctx, __format_spec::__fields_integral); - __format_spec::__process_parsed_char(__parser_); + __format_spec::__process_parsed_char(__parser_, "a character"); return __result; } @@ -50,22 +50,21 @@ public: return __formatter::__format_escaped_char(__value, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx)); # endif - if constexpr (sizeof(_CharT) <= sizeof(int)) - // Promotes _CharT to an integral type. This reduces the number of - // instantiations of __format_integer reducing code size. + if constexpr (sizeof(_CharT) <= sizeof(unsigned)) return __formatter::__format_integer( - static_cast, int, unsigned>>(__value), + static_cast(static_cast>(__value)), __ctx, __parser_.__get_parsed_std_specifications(__ctx)); else - return __formatter::__format_integer(__value, __ctx, __parser_.__get_parsed_std_specifications(__ctx)); + return __formatter::__format_integer( + static_cast>(__value), __ctx, __parser_.__get_parsed_std_specifications(__ctx)); } template _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(char __value, _FormatContext& __ctx) const requires(same_as<_CharT, wchar_t>) { - return format(static_cast(__value), __ctx); + return format(static_cast(static_cast(__value)), __ctx); } # if _LIBCPP_STD_VER >= 23 @@ -83,8 +82,7 @@ template <> struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_char {}; template <> -struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_char { -}; +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_char {}; # endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS diff --git a/third_party/libcxx/__format/formatter_floating_point.h b/third_party/libcxx/__format/formatter_floating_point.h index a699f403e..fa42ba203 100644 --- a/third_party/libcxx/__format/formatter_floating_point.h +++ b/third_party/libcxx/__format/formatter_floating_point.h @@ -16,6 +16,7 @@ #include <__algorithm/min.h> #include <__algorithm/rotate.h> #include <__algorithm/transform.h> +#include <__assert> #include <__charconv/chars_format.h> #include <__charconv/to_chars_floating_point.h> #include <__charconv/to_chars_result.h> @@ -28,6 +29,7 @@ #include <__format/formatter_integral.h> #include <__format/formatter_output.h> #include <__format/parser_std_format_spec.h> +#include <__iterator/concepts.h> #include <__memory/allocator.h> #include <__system_error/errc.h> #include <__type_traits/conditional.h> @@ -37,7 +39,7 @@ #include #ifndef _LIBCPP_HAS_NO_LOCALIZATION -# include +# include <__locale> #endif #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -55,22 +57,22 @@ namespace __formatter { template _LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value) { - to_chars_result __r = _VSTD::to_chars(__first, __last, __value); - _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small"); + to_chars_result __r = std::to_chars(__first, __last, __value); + _LIBCPP_ASSERT_INTERNAL(__r.ec == errc(0), "Internal buffer too small"); return __r.ptr; } template _LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value, chars_format __fmt) { - to_chars_result __r = _VSTD::to_chars(__first, __last, __value, __fmt); - _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small"); + to_chars_result __r = std::to_chars(__first, __last, __value, __fmt); + _LIBCPP_ASSERT_INTERNAL(__r.ec == errc(0), "Internal buffer too small"); return __r.ptr; } template _LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value, chars_format __fmt, int __precision) { - to_chars_result __r = _VSTD::to_chars(__first, __last, __value, __fmt, __precision); - _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small"); + to_chars_result __r = std::to_chars(__first, __last, __value, __fmt, __precision); + _LIBCPP_ASSERT_INTERNAL(__r.ec == errc(0), "Internal buffer too small"); return __r.ptr; } @@ -115,8 +117,8 @@ _LIBCPP_HIDE_FROM_ABI constexpr size_t __float_buffer_size(int __precision) { template <> struct __traits { - static constexpr int __max_integral = 38; - static constexpr int __max_fractional = 149; + static constexpr int __max_integral = 38; + static constexpr int __max_fractional = 149; static constexpr int __max_fractional_value = 3; static constexpr size_t __stack_buffer_size = 256; @@ -125,8 +127,8 @@ struct __traits { template <> struct __traits { - static constexpr int __max_integral = 308; - static constexpr int __max_fractional = 1074; + static constexpr int __max_integral = 308; + static constexpr int __max_fractional = 1074; static constexpr int __max_fractional_value = 4; static constexpr size_t __stack_buffer_size = 1024; @@ -135,7 +137,7 @@ struct __traits { /// Helper class to store the conversion buffer. /// -/// Depending on the maxium size required for a value, the buffer is allocated +/// Depending on the maximum size required for a value, the buffer is allocated /// on the stack or the heap. template class _LIBCPP_TEMPLATE_VIS __float_buffer { @@ -152,7 +154,6 @@ public: // required. explicit _LIBCPP_HIDE_FROM_ABI __float_buffer(int __precision) : __precision_(__precision != -1 ? __precision : _Traits::__max_fractional) { - // When the precision is larger than _Traits::__max_fractional the digits in // the range (_Traits::__max_fractional, precision] will contain the value // zero. There's no need to request to_chars to write these zeros: @@ -164,7 +165,7 @@ public: // to be converted from a char to a wchar_t. if (__precision_ > _Traits::__max_fractional) { __num_trailing_zeros_ = __precision_ - _Traits::__max_fractional; - __precision_ = _Traits::__max_fractional; + __precision_ = _Traits::__max_fractional; } __size_ = __formatter::__float_buffer_size<_Fp>(__precision_); @@ -179,7 +180,7 @@ public: if (__size_ > _Traits::__stack_buffer_size) allocator{}.deallocate(__begin_, __size_); } - _LIBCPP_HIDE_FROM_ABI __float_buffer(const __float_buffer&) = delete; + _LIBCPP_HIDE_FROM_ABI __float_buffer(const __float_buffer&) = delete; _LIBCPP_HIDE_FROM_ABI __float_buffer& operator=(const __float_buffer&) = delete; _LIBCPP_HIDE_FROM_ABI char* begin() const { return __begin_; } @@ -223,7 +224,7 @@ struct __float_result { constexpr inline _LIBCPP_HIDE_FROM_ABI char* __find_exponent(char* __first, char* __last) { ptrdiff_t __size = __last - __first; if (__size >= 4) { - __first = __last - _VSTD::min(__size, ptrdiff_t(6)); + __first = __last - std::min(__size, ptrdiff_t(6)); for (; __first != __last - 3; ++__first) { if (*__first == 'e') return __first; @@ -233,8 +234,8 @@ constexpr inline _LIBCPP_HIDE_FROM_ABI char* __find_exponent(char* __first, char } template -_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_default(const __float_buffer<_Fp>& __buffer, _Tp __value, - char* __integral) { +_LIBCPP_HIDE_FROM_ABI __float_result +__format_buffer_default(const __float_buffer<_Fp>& __buffer, _Tp __value, char* __integral) { __float_result __result; __result.__integral = __integral; __result.__last = __formatter::__to_buffer(__integral, __buffer.end(), __value); @@ -244,7 +245,7 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_default(const __float_buffe // Constrains: // - There's at least one decimal digit before the radix point. // - The radix point, when present, is placed before the exponent. - __result.__radix_point = _VSTD::find(__result.__integral + 1, __result.__exponent, '.'); + __result.__radix_point = std::find(__result.__integral + 1, __result.__exponent, '.'); // When the radix point isn't found its position is the exponent instead of // __result.__last. @@ -252,19 +253,18 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_default(const __float_buffe __result.__radix_point = __result.__last; // clang-format off - _LIBCPP_ASSERT((__result.__integral != __result.__last) && - (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && - (__result.__exponent == __result.__last || *__result.__exponent == 'e'), - "Post-condition failure."); + _LIBCPP_ASSERT_INTERNAL((__result.__integral != __result.__last) && + (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && + (__result.__exponent == __result.__last || *__result.__exponent == 'e'), + "Post-condition failure."); // clang-format on return __result; } template -_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_hexadecimal_lower_case(const __float_buffer<_Fp>& __buffer, - _Tp __value, int __precision, - char* __integral) { +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_hexadecimal_lower_case( + const __float_buffer<_Fp>& __buffer, _Tp __value, int __precision, char* __integral) { __float_result __result; __result.__integral = __integral; if (__precision == -1) @@ -296,67 +296,64 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_hexadecimal_lower_case(cons // 0123456789 static_assert(__traits<_Fp>::__hex_precision_digits <= 4, "Guard against possible underflow."); - char* __last = __result.__last - 2; - __first = __last - __traits<_Fp>::__hex_precision_digits; - __result.__exponent = _VSTD::find(__first, __last, 'p'); + char* __last = __result.__last - 2; + __first = __last - __traits<_Fp>::__hex_precision_digits; + __result.__exponent = std::find(__first, __last, 'p'); } else { __result.__radix_point = __result.__last; - __result.__exponent = __first; + __result.__exponent = __first; } // clang-format off - _LIBCPP_ASSERT((__result.__integral != __result.__last) && - (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && - (__result.__exponent != __result.__last && *__result.__exponent == 'p'), - "Post-condition failure."); + _LIBCPP_ASSERT_INTERNAL((__result.__integral != __result.__last) && + (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && + (__result.__exponent != __result.__last && *__result.__exponent == 'p'), + "Post-condition failure."); // clang-format on return __result; } template -_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_hexadecimal_upper_case(const __float_buffer<_Fp>& __buffer, - _Tp __value, int __precision, - char* __integral) { +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_hexadecimal_upper_case( + const __float_buffer<_Fp>& __buffer, _Tp __value, int __precision, char* __integral) { __float_result __result = __formatter::__format_buffer_hexadecimal_lower_case(__buffer, __value, __precision, __integral); - _VSTD::transform(__result.__integral, __result.__exponent, __result.__integral, __hex_to_upper); + std::transform(__result.__integral, __result.__exponent, __result.__integral, __hex_to_upper); *__result.__exponent = 'P'; return __result; } template -_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_scientific_lower_case(const __float_buffer<_Fp>& __buffer, - _Tp __value, int __precision, - char* __integral) { +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_scientific_lower_case( + const __float_buffer<_Fp>& __buffer, _Tp __value, int __precision, char* __integral) { __float_result __result; __result.__integral = __integral; __result.__last = __formatter::__to_buffer(__integral, __buffer.end(), __value, chars_format::scientific, __precision); char* __first = __integral + 1; - _LIBCPP_ASSERT(__first != __result.__last, "No exponent present"); + _LIBCPP_ASSERT_INTERNAL(__first != __result.__last, "No exponent present"); if (*__first == '.') { __result.__radix_point = __first; __result.__exponent = __formatter::__find_exponent(__first + 1, __result.__last); } else { __result.__radix_point = __result.__last; - __result.__exponent = __first; + __result.__exponent = __first; } // clang-format off - _LIBCPP_ASSERT((__result.__integral != __result.__last) && - (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && - (__result.__exponent != __result.__last && *__result.__exponent == 'e'), - "Post-condition failure."); + _LIBCPP_ASSERT_INTERNAL((__result.__integral != __result.__last) && + (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && + (__result.__exponent != __result.__last && *__result.__exponent == 'e'), + "Post-condition failure."); // clang-format on return __result; } template -_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_scientific_upper_case(const __float_buffer<_Fp>& __buffer, - _Tp __value, int __precision, - char* __integral) { +_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_scientific_upper_case( + const __float_buffer<_Fp>& __buffer, _Tp __value, int __precision, char* __integral) { __float_result __result = __formatter::__format_buffer_scientific_lower_case(__buffer, __value, __precision, __integral); *__result.__exponent = 'E'; @@ -364,8 +361,8 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_scientific_upper_case(const } template -_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_fixed(const __float_buffer<_Fp>& __buffer, _Tp __value, - int __precision, char* __integral) { +_LIBCPP_HIDE_FROM_ABI __float_result +__format_buffer_fixed(const __float_buffer<_Fp>& __buffer, _Tp __value, int __precision, char* __integral) { __float_result __result; __result.__integral = __integral; __result.__last = __formatter::__to_buffer(__integral, __buffer.end(), __value, chars_format::fixed, __precision); @@ -375,21 +372,20 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_fixed(const __float_buffer< // By converting __precision to a bool the subtraction can be done // unconditionally. __result.__radix_point = __result.__last - (__precision + bool(__precision)); - __result.__exponent = __result.__last; + __result.__exponent = __result.__last; // clang-format off - _LIBCPP_ASSERT((__result.__integral != __result.__last) && - (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && - (__result.__exponent == __result.__last), - "Post-condition failure."); + _LIBCPP_ASSERT_INTERNAL((__result.__integral != __result.__last) && + (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && + (__result.__exponent == __result.__last), + "Post-condition failure."); // clang-format on return __result; } template -_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_general_lower_case(__float_buffer<_Fp>& __buffer, _Tp __value, - int __precision, char* __integral) { - +_LIBCPP_HIDE_FROM_ABI __float_result +__format_buffer_general_lower_case(__float_buffer<_Fp>& __buffer, _Tp __value, int __precision, char* __integral) { __buffer.__remove_trailing_zeros(); __float_result __result; @@ -399,7 +395,7 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_general_lower_case(__float_ char* __first = __integral + 1; if (__first == __result.__last) { __result.__radix_point = __result.__last; - __result.__exponent = __result.__last; + __result.__exponent = __result.__last; } else { __result.__exponent = __formatter::__find_exponent(__first, __result.__last); if (__result.__exponent != __result.__last) @@ -410,23 +406,23 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_general_lower_case(__float_ // In fixed mode the algorithm truncates trailing spaces and possibly the // radix point. There's no good guess for the position of the radix point // therefore scan the output after the first digit. - __result.__radix_point = _VSTD::find(__first, __result.__last, '.'); + __result.__radix_point = std::find(__first, __result.__last, '.'); } } // clang-format off - _LIBCPP_ASSERT((__result.__integral != __result.__last) && - (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && - (__result.__exponent == __result.__last || *__result.__exponent == 'e'), - "Post-condition failure."); + _LIBCPP_ASSERT_INTERNAL((__result.__integral != __result.__last) && + (__result.__radix_point == __result.__last || *__result.__radix_point == '.') && + (__result.__exponent == __result.__last || *__result.__exponent == 'e'), + "Post-condition failure."); // clang-format on return __result; } template -_LIBCPP_HIDE_FROM_ABI __float_result __format_buffer_general_upper_case(__float_buffer<_Fp>& __buffer, _Tp __value, - int __precision, char* __integral) { +_LIBCPP_HIDE_FROM_ABI __float_result +__format_buffer_general_upper_case(__float_buffer<_Fp>& __buffer, _Tp __value, int __precision, char* __integral) { __float_result __result = __formatter::__format_buffer_general_lower_case(__buffer, __value, __precision, __integral); if (__result.__exponent != __result.__last) *__result.__exponent = 'E'; @@ -490,7 +486,7 @@ _LIBCPP_HIDE_FROM_ABI __float_result __format_buffer( return __formatter::__format_buffer_general_upper_case(__buffer, __value, __buffer.__precision(), __first); default: - _LIBCPP_ASSERT(false, "The parser should have validated the type"); + _LIBCPP_ASSERT_INTERNAL(false, "The parser should have validated the type"); __libcpp_unreachable(); } } @@ -501,13 +497,13 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __format_locale_specific_form( _OutIt __out_it, const __float_buffer<_Fp>& __buffer, const __float_result& __result, - _VSTD::locale __loc, + std::locale __loc, __format_spec::__parsed_specifications<_CharT> __specs) { - const auto& __np = std::use_facet>(__loc); + const auto& __np = std::use_facet>(__loc); string __grouping = __np.grouping(); - char* __first = __result.__integral; + char* __first = __result.__integral; // When no radix point or exponent are present __last will be __result.__last. - char* __last = _VSTD::min(__result.__radix_point, __result.__exponent); + char* __last = std::min(__result.__radix_point, __result.__exponent); ptrdiff_t __digits = __last - __first; if (!__grouping.empty()) { @@ -523,11 +519,11 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __format_locale_specific_form( __grouping.size() - // Grouping contains one !__grouping.empty(); // additional character - __formatter::__padding_size_result __padding = {0, 0}; - bool __zero_padding = __specs.__alignment_ == __format_spec::__alignment::__zero_padding; + __formatter::__padding_size_result __padding = {0, 0}; + bool __zero_padding = __specs.__alignment_ == __format_spec::__alignment::__zero_padding; if (__size < __specs.__width_) { if (__zero_padding) { - __specs.__alignment_ = __format_spec::__alignment::__right; + __specs.__alignment_ = __format_spec::__alignment::__right; __specs.__fill_.__data[0] = _CharT('0'); } @@ -537,16 +533,16 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __format_locale_specific_form( // sign and (zero padding or alignment) if (__zero_padding && __first != __buffer.begin()) *__out_it++ = *__buffer.begin(); - __out_it = __formatter::__fill(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_); + __out_it = __formatter::__fill(std::move(__out_it), __padding.__before_, __specs.__fill_); if (!__zero_padding && __first != __buffer.begin()) *__out_it++ = *__buffer.begin(); // integral part if (__grouping.empty()) { - __out_it = __formatter::__copy(__first, __digits, _VSTD::move(__out_it)); + __out_it = __formatter::__copy(__first, __digits, std::move(__out_it)); } else { - auto __r = __grouping.rbegin(); - auto __e = __grouping.rend() - 1; + auto __r = __grouping.rbegin(); + auto __e = __grouping.rend() - 1; _CharT __sep = __np.thousands_sep(); // The output is divided in small groups of numbers to write: // - A group before the first separator. @@ -555,7 +551,7 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __format_locale_specific_form( // This loop achieves that process by testing the termination condition // midway in the loop. while (true) { - __out_it = __formatter::__copy(__first, *__r, _VSTD::move(__out_it)); + __out_it = __formatter::__copy(__first, *__r, std::move(__out_it)); __first += *__r; if (__r == __e) @@ -569,16 +565,16 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __format_locale_specific_form( // fractional part if (__result.__radix_point != __result.__last) { *__out_it++ = __np.decimal_point(); - __out_it = __formatter::__copy(__result.__radix_point + 1, __result.__exponent, _VSTD::move(__out_it)); - __out_it = __formatter::__fill(_VSTD::move(__out_it), __buffer.__num_trailing_zeros(), _CharT('0')); + __out_it = __formatter::__copy(__result.__radix_point + 1, __result.__exponent, std::move(__out_it)); + __out_it = __formatter::__fill(std::move(__out_it), __buffer.__num_trailing_zeros(), _CharT('0')); } // exponent if (__result.__exponent != __result.__last) - __out_it = __formatter::__copy(__result.__exponent, __result.__last, _VSTD::move(__out_it)); + __out_it = __formatter::__copy(__result.__exponent, __result.__last, std::move(__out_it)); // alignment - return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_); + return __formatter::__fill(std::move(__out_it), __padding.__after_, __specs.__fill_); } # endif // _LIBCPP_HAS_NO_LOCALIZATION @@ -596,7 +592,7 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __format_floating_point_non_finite( __specs.__std_.__type_ == __format_spec::__type::__scientific_upper_case || __specs.__std_.__type_ == __format_spec::__type::__fixed_upper_case || __specs.__std_.__type_ == __format_spec::__type::__general_upper_case; - __last = _VSTD::copy_n(&("infnanINFNAN"[6 * __upper_case + 3 * __isnan]), 3, __last); + __last = std::copy_n(&("infnanINFNAN"[6 * __upper_case + 3 * __isnan]), 3, __last); // [format.string.std]/13 // A zero (0) character preceding the width field pads the field with @@ -605,16 +601,45 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __format_floating_point_non_finite( if (__specs.__alignment_ == __format_spec::__alignment::__zero_padding) __specs.__alignment_ = __format_spec::__alignment::__right; - return __formatter::__write(__buffer, __last, _VSTD::move(__out_it), __specs); + return __formatter::__write(__buffer, __last, std::move(__out_it), __specs); +} + +/// Writes additional zero's for the precision before the exponent. +/// This is used when the precision requested in the format string is larger +/// than the maximum precision of the floating-point type. These precision +/// digits are always 0. +/// +/// \param __exponent The location of the exponent character. +/// \param __num_trailing_zeros The number of 0's to write before the exponent +/// character. +template +_LIBCPP_HIDE_FROM_ABI auto __write_using_trailing_zeros( + const _CharT* __first, + const _CharT* __last, + output_iterator auto __out_it, + __format_spec::__parsed_specifications<_ParserCharT> __specs, + size_t __size, + const _CharT* __exponent, + size_t __num_trailing_zeros) -> decltype(__out_it) { + _LIBCPP_ASSERT_INTERNAL(__first <= __last, "Not a valid range"); + _LIBCPP_ASSERT_INTERNAL(__num_trailing_zeros > 0, "The overload not writing trailing zeros should have been used"); + + __padding_size_result __padding = + __formatter::__padding_size(__size + __num_trailing_zeros, __specs.__width_, __specs.__alignment_); + __out_it = __formatter::__fill(std::move(__out_it), __padding.__before_, __specs.__fill_); + __out_it = __formatter::__copy(__first, __exponent, std::move(__out_it)); + __out_it = __formatter::__fill(std::move(__out_it), __num_trailing_zeros, _CharT('0')); + __out_it = __formatter::__copy(__exponent, __last, std::move(__out_it)); + return __formatter::__fill(std::move(__out_it), __padding.__after_, __specs.__fill_); } template _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator __format_floating_point(_Tp __value, _FormatContext& __ctx, __format_spec::__parsed_specifications<_CharT> __specs) { - bool __negative = _VSTD::signbit(__value); + bool __negative = std::signbit(__value); - if (!_VSTD::isfinite(__value)) [[unlikely]] - return __formatter::__format_floating_point_non_finite(__ctx.out(), __specs, __negative, _VSTD::isnan(__value)); + if (!std::isfinite(__value)) [[unlikely]] + return __formatter::__format_floating_point_non_finite(__ctx.out(), __specs, __negative, std::isnan(__value)); // Depending on the std-format-spec string the sign and the value // might not be outputted together: @@ -640,7 +665,7 @@ __format_floating_point(_Tp __value, _FormatContext& __ctx, __format_spec::__par // When there is an exponent the point needs to be moved before the // exponent. When there's no exponent the rotate does nothing. Since // rotate tests whether the operation is a nop, call it unconditionally. - _VSTD::rotate(__result.__exponent, __result.__last - 1, __result.__last); + std::rotate(__result.__exponent, __result.__last - 1, __result.__last); __result.__radix_point = __result.__exponent; // The radix point is always placed before the exponent. @@ -665,7 +690,7 @@ __format_floating_point(_Tp __value, _FormatContext& __ctx, __format_spec::__par // Let P equal the precision if nonzero, 6 if the precision is not // specified, or 1 if the precision is 0. Then, if a conversion with // style E would have an exponent of X: - int __p = _VSTD::max(1, (__specs.__has_precision() ? __specs.__precision_ : 6)); + int __p = std::max(1, (__specs.__has_precision() ? __specs.__precision_ : 6)); if (__result.__exponent == __result.__last) // if P > X >= -4, the conversion is with style f or F and precision P - 1 - X. // By including the radix point it calculates P - (1 + X) @@ -711,15 +736,15 @@ __format_floating_point(_Tp __value, _FormatContext& __ctx, __format_spec::__par *__out_it++ = *__first++; // After the sign is written, zero padding is the same a right alignment // with '0'. - __specs.__alignment_ = __format_spec::__alignment::__right; + __specs.__alignment_ = __format_spec::__alignment::__right; __specs.__fill_.__data[0] = _CharT('0'); } if (__num_trailing_zeros) return __formatter::__write_using_trailing_zeros( - __first, __result.__last, _VSTD::move(__out_it), __specs, __size, __result.__exponent, __num_trailing_zeros); + __first, __result.__last, std::move(__out_it), __specs, __size, __result.__exponent, __num_trailing_zeros); - return __formatter::__write(__first, __result.__last, _VSTD::move(__out_it), __specs, __size); + return __formatter::__write(__first, __result.__last, std::move(__out_it), __specs, __size); } } // namespace __formatter @@ -730,7 +755,7 @@ public: template _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { typename _ParseContext::iterator __result = __parser_.__parse(__ctx, __format_spec::__fields_floating_point); - __format_spec::__process_parsed_floating_point(__parser_); + __format_spec::__process_parsed_floating_point(__parser_, "a floating-point"); return __result; } @@ -743,14 +768,11 @@ public: }; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_floating_point<_CharT> {}; +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_floating_point<_CharT> {}; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_floating_point<_CharT> {}; +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_floating_point<_CharT> {}; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_floating_point<_CharT> {}; +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_floating_point<_CharT> {}; #endif //_LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__format/formatter_integer.h b/third_party/libcxx/__format/formatter_integer.h index f7dac2885..41400f004 100644 --- a/third_party/libcxx/__format/formatter_integer.h +++ b/third_party/libcxx/__format/formatter_integer.h @@ -10,7 +10,6 @@ #ifndef _LIBCPP___FORMAT_FORMATTER_INTEGER_H #define _LIBCPP___FORMAT_FORMATTER_INTEGER_H -#include <__availability> #include <__concepts/arithmetic.h> #include <__config> #include <__format/concepts.h> @@ -19,25 +18,24 @@ #include <__format/formatter_integral.h> #include <__format/formatter_output.h> #include <__format/parser_std_format_spec.h> -#include <__type_traits/is_same.h> +#include <__type_traits/is_void.h> #include <__type_traits/make_32_64_or_128_bit.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif - _LIBCPP_BEGIN_NAMESPACE_STD +_LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 - template <__fmt_char_type _CharT> - struct _LIBCPP_TEMPLATE_VIS __formatter_integer { - +template <__fmt_char_type _CharT> +struct _LIBCPP_TEMPLATE_VIS __formatter_integer { public: template _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { typename _ParseContext::iterator __result = __parser_.__parse(__ctx, __format_spec::__fields_integral); - __format_spec::__process_parsed_integer(__parser_); + __format_spec::__process_parsed_integer(__parser_, "an integer"); return __result; } @@ -49,7 +47,7 @@ public: return __formatter::__format_char(__value, __ctx.out(), __specs); using _Type = __make_32_64_or_128_bit_t<_Tp>; - static_assert(!is_same<_Type, void>::value, "unsupported integral type used in __formatter_integer::__format"); + static_assert(!is_void<_Type>::value, "unsupported integral type used in __formatter_integer::__format"); // Reduce the number of instantiation of the integer formatter return __formatter::__format_integer(static_cast<_Type>(__value), __ctx, __specs); @@ -60,44 +58,34 @@ public: // Signed integral types. template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_integer<_CharT> {}; +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_integer<_CharT> {}; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_integer<_CharT> { -}; +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_integer<_CharT> {}; template <__fmt_char_type _CharT> struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_integer<_CharT> {}; template <__fmt_char_type _CharT> struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_integer<_CharT> {}; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_integer<_CharT> {}; +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_integer<_CharT> {}; # ifndef _LIBCPP_HAS_NO_INT128 template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter<__int128_t, _CharT> - : public __formatter_integer<_CharT> {}; +struct _LIBCPP_TEMPLATE_VIS formatter<__int128_t, _CharT> : public __formatter_integer<_CharT> {}; # endif // Unsigned integral types. template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_integer<_CharT> {}; +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_integer<_CharT> {}; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_integer<_CharT> {}; +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_integer<_CharT> {}; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_integer<_CharT> {}; +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_integer<_CharT> {}; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_integer<_CharT> {}; +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_integer<_CharT> {}; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_integer<_CharT> {}; +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_integer<_CharT> {}; # ifndef _LIBCPP_HAS_NO_INT128 template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter<__uint128_t, _CharT> - : public __formatter_integer<_CharT> {}; +struct _LIBCPP_TEMPLATE_VIS formatter<__uint128_t, _CharT> : public __formatter_integer<_CharT> {}; # endif #endif //_LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__format/formatter_integral.h b/third_party/libcxx/__format/formatter_integral.h index 657c9bd15..eca966f88 100644 --- a/third_party/libcxx/__format/formatter_integral.h +++ b/third_party/libcxx/__format/formatter_integral.h @@ -20,6 +20,9 @@ #include <__format/format_error.h> #include <__format/formatter_output.h> #include <__format/parser_std_format_spec.h> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__memory/pointer_traits.h> #include <__system_error/errc.h> #include <__type_traits/make_unsigned.h> #include <__utility/unreachable.h> @@ -29,7 +32,7 @@ #include #ifndef _LIBCPP_HAS_NO_LOCALIZATION -# include +# include <__locale> #endif #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -49,7 +52,9 @@ namespace __formatter { // Generic // -_LIBCPP_HIDE_FROM_ABI inline char* __insert_sign(char* __buf, bool __negative, __format_spec::__sign __sign) { +template + requires same_as> +_LIBCPP_HIDE_FROM_ABI inline _Iterator __insert_sign(_Iterator __buf, bool __negative, __format_spec::__sign __sign) { if (__negative) *__buf++ = '-'; else @@ -85,9 +90,8 @@ _LIBCPP_HIDE_FROM_ABI inline char* __insert_sign(char* __buf, bool __negative, _ * regardless whether the @c std::numpunct's type is @c char or @c wchar_t. */ _LIBCPP_HIDE_FROM_ABI inline string __determine_grouping(ptrdiff_t __size, const string& __grouping) { - _LIBCPP_ASSERT(!__grouping.empty() && __size > __grouping[0], - "The slow grouping formatting is used while there will be no " - "separators written"); + _LIBCPP_ASSERT_INTERNAL(!__grouping.empty() && __size > __grouping[0], + "The slow grouping formatting is used while there will be no separators written"); string __r; auto __end = __grouping.end() - 1; auto __ptr = __grouping.begin(); @@ -119,10 +123,10 @@ _LIBCPP_HIDE_FROM_ABI inline string __determine_grouping(ptrdiff_t __size, const // template <__fmt_char_type _CharT> -_LIBCPP_HIDE_FROM_ABI auto __format_char( - integral auto __value, - output_iterator auto __out_it, - __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) { +_LIBCPP_HIDE_FROM_ABI auto +__format_char(integral auto __value, + output_iterator auto __out_it, + __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) { using _Tp = decltype(__value); if constexpr (!same_as<_CharT, _Tp>) { // cmp_less and cmp_greater can't be used for character types. @@ -141,21 +145,23 @@ _LIBCPP_HIDE_FROM_ABI auto __format_char( } const auto __c = static_cast<_CharT>(__value); - return __formatter::__write(_VSTD::addressof(__c), _VSTD::addressof(__c) + 1, _VSTD::move(__out_it), __specs); + return __formatter::__write(std::addressof(__c), std::addressof(__c) + 1, std::move(__out_it), __specs); } // // Integer // -/** Wrapper around @ref to_chars, returning the output pointer. */ -template -_LIBCPP_HIDE_FROM_ABI char* __to_buffer(char* __first, char* __last, _Tp __value, int __base) { +/** Wrapper around @ref to_chars, returning the output iterator. */ +template + requires same_as> +_LIBCPP_HIDE_FROM_ABI _Iterator __to_buffer(_Iterator __first, _Iterator __last, _Tp __value, int __base) { // TODO FMT Evaluate code overhead due to not calling the internal function // directly. (Should be zero overhead.) - to_chars_result __r = _VSTD::to_chars(__first, __last, __value, __base); - _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small"); - return __r.ptr; + to_chars_result __r = std::to_chars(std::to_address(__first), std::to_address(__last), __value, __base); + _LIBCPP_ASSERT_INTERNAL(__r.ec == errc(0), "Internal buffer too small"); + auto __diff = __r.ptr - std::to_address(__first); + return __first + __diff; } /** @@ -203,22 +209,93 @@ consteval size_t __buffer_size() noexcept + 1; // Reserve space for the sign. } -template +template + requires same_as> +_LIBCPP_HIDE_FROM_ABI _OutIt __write_using_decimal_separators( + _OutIt __out_it, + _Iterator __begin, + _Iterator __first, + _Iterator __last, + string&& __grouping, + _CharT __sep, + __format_spec::__parsed_specifications<_CharT> __specs) { + int __size = (__first - __begin) + // [sign][prefix] + (__last - __first) + // data + (__grouping.size() - 1); // number of separator characters + + __padding_size_result __padding = {0, 0}; + if (__specs.__alignment_ == __format_spec::__alignment::__zero_padding) { + // Write [sign][prefix]. + __out_it = __formatter::__copy(__begin, __first, std::move(__out_it)); + + if (__specs.__width_ > __size) { + // Write zero padding. + __padding.__before_ = __specs.__width_ - __size; + __out_it = __formatter::__fill(std::move(__out_it), __specs.__width_ - __size, _CharT('0')); + } + } else { + if (__specs.__width_ > __size) { + // Determine padding and write padding. + __padding = __formatter::__padding_size(__size, __specs.__width_, __specs.__alignment_); + + __out_it = __formatter::__fill(std::move(__out_it), __padding.__before_, __specs.__fill_); + } + // Write [sign][prefix]. + __out_it = __formatter::__copy(__begin, __first, std::move(__out_it)); + } + + auto __r = __grouping.rbegin(); + auto __e = __grouping.rend() - 1; + _LIBCPP_ASSERT_INTERNAL( + __r != __e, "The slow grouping formatting is used while there will be no separators written."); + // The output is divided in small groups of numbers to write: + // - A group before the first separator. + // - A separator and a group, repeated for the number of separators. + // - A group after the last separator. + // This loop achieves that process by testing the termination condition + // midway in the loop. + // + // TODO FMT This loop evaluates the loop invariant `__parser.__type != + // _Flags::_Type::__hexadecimal_upper_case` for every iteration. (This test + // happens in the __write call.) Benchmark whether making two loops and + // hoisting the invariant is worth the effort. + while (true) { + if (__specs.__std_.__type_ == __format_spec::__type::__hexadecimal_upper_case) { + __last = __first + *__r; + __out_it = __formatter::__transform(__first, __last, std::move(__out_it), __hex_to_upper); + __first = __last; + } else { + __out_it = __formatter::__copy(__first, *__r, std::move(__out_it)); + __first += *__r; + } + + if (__r == __e) + break; + + ++__r; + *__out_it++ = __sep; + } + + return __formatter::__fill(std::move(__out_it), __padding.__after_, __specs.__fill_); +} + +template + requires same_as> _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator __format_integer( _Tp __value, _FormatContext& __ctx, __format_spec::__parsed_specifications<_CharT> __specs, bool __negative, - char* __begin, - char* __end, + _Iterator __begin, + _Iterator __end, const char* __prefix, int __base) { - char* __first = __formatter::__insert_sign(__begin, __negative, __specs.__std_.__sign_); + _Iterator __first = __formatter::__insert_sign(__begin, __negative, __specs.__std_.__sign_); if (__specs.__std_.__alternate_form_ && __prefix) while (*__prefix) *__first++ = *__prefix++; - char* __last = __formatter::__to_buffer(__first, __end, __value, __base); + _Iterator __last = __formatter::__to_buffer(__first, __end, __value, __base); # ifndef _LIBCPP_HAS_NO_LOCALIZATION if (__specs.__std_.__locale_specific_form_) { @@ -249,12 +326,12 @@ _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator __format_integer( // The zero padding is done like: // - Write [sign][prefix] // - Write data right aligned with '0' as fill character. - __out_it = __formatter::__copy(__begin, __first, _VSTD::move(__out_it)); - __specs.__alignment_ = __format_spec::__alignment::__right; + __out_it = __formatter::__copy(__begin, __first, std::move(__out_it)); + __specs.__alignment_ = __format_spec::__alignment::__right; __specs.__fill_.__data[0] = _CharT('0'); - int32_t __size = __first - __begin; + int32_t __size = __first - __begin; - __specs.__width_ -= _VSTD::min(__size, __specs.__width_); + __specs.__width_ -= std::min(__size, __specs.__width_); } if (__specs.__std_.__type_ != __format_spec::__type::__hexadecimal_upper_case) [[likely]] @@ -299,7 +376,7 @@ __format_integer(_Tp __value, return __formatter::__format_integer(__value, __ctx, __specs, __negative, __array.begin(), __array.end(), "0X", 16); } default: - _LIBCPP_ASSERT(false, "The parse function should have validated the type"); + _LIBCPP_ASSERT_INTERNAL(false, "The parse function should have validated the type"); __libcpp_unreachable(); } } diff --git a/third_party/libcxx/__format/formatter_output.h b/third_party/libcxx/__format/formatter_output.h index 6263dba09..1498f64c4 100644 --- a/third_party/libcxx/__format/formatter_output.h +++ b/third_party/libcxx/__format/formatter_output.h @@ -12,35 +12,32 @@ #include <__algorithm/ranges_copy.h> #include <__algorithm/ranges_fill_n.h> -#include <__algorithm/ranges_for_each.h> #include <__algorithm/ranges_transform.h> #include <__bit/countl.h> -#include <__charconv/to_chars_integral.h> -#include <__charconv/to_chars_result.h> -#include <__chrono/statically_widen.h> #include <__concepts/same_as.h> #include <__config> #include <__format/buffer.h> #include <__format/concepts.h> -#include <__format/escaped_output_table.h> #include <__format/formatter.h> #include <__format/parser_std_format_spec.h> #include <__format/unicode.h> #include <__iterator/back_insert_iterator.h> #include <__iterator/concepts.h> -#include <__iterator/readable_traits.h> // iter_value_t -#include <__system_error/errc.h> -#include <__type_traits/make_unsigned.h> +#include <__iterator/iterator_traits.h> +#include <__memory/addressof.h> +#include <__memory/pointer_traits.h> #include <__utility/move.h> #include <__utility/unreachable.h> #include -#include #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 @@ -65,15 +62,15 @@ _LIBCPP_HIDE_FROM_ABI constexpr char __hex_to_upper(char __c) { return __c; } -struct _LIBCPP_TYPE_VIS __padding_size_result { +struct _LIBCPP_EXPORTED_FROM_ABI __padding_size_result { size_t __before_; size_t __after_; }; _LIBCPP_HIDE_FROM_ABI constexpr __padding_size_result __padding_size(size_t __size, size_t __width, __format_spec::__alignment __align) { - _LIBCPP_ASSERT(__width > __size, "don't call this function when no padding is required"); - _LIBCPP_ASSERT( + _LIBCPP_ASSERT_INTERNAL(__width > __size, "don't call this function when no padding is required"); + _LIBCPP_ASSERT_INTERNAL( __align != __format_spec::__alignment::__zero_padding, "the caller should have handled the zero-padding"); size_t __fill = __width - __size; @@ -103,51 +100,55 @@ __padding_size(size_t __size, size_t __width, __format_spec::__alignment __align /// /// This uses a "mass output function" of __format::__output_buffer when possible. template <__fmt_char_type _CharT, __fmt_char_type _OutCharT = _CharT> -_LIBCPP_HIDE_FROM_ABI auto __copy(basic_string_view<_CharT> __str, output_iterator auto __out_it) - -> decltype(__out_it) { - if constexpr (_VSTD::same_as>>) { +_LIBCPP_HIDE_FROM_ABI auto +__copy(basic_string_view<_CharT> __str, output_iterator auto __out_it) -> decltype(__out_it) { + if constexpr (std::same_as>>) { __out_it.__get_container()->__copy(__str); return __out_it; - } else if constexpr (_VSTD::same_as::__iterator>) { + } else if constexpr (std::same_as::__iterator>) { __out_it.__buffer_->__copy(__str); return __out_it; } else { - return std::ranges::copy(__str, _VSTD::move(__out_it)).out; + return std::ranges::copy(__str, std::move(__out_it)).out; } } -template <__fmt_char_type _CharT, __fmt_char_type _OutCharT = _CharT> +template ::value_type, + __fmt_char_type _OutCharT = _CharT> _LIBCPP_HIDE_FROM_ABI auto -__copy(const _CharT* __first, const _CharT* __last, output_iterator auto __out_it) - -> decltype(__out_it) { - return __formatter::__copy(basic_string_view{__first, __last}, _VSTD::move(__out_it)); +__copy(_Iterator __first, _Iterator __last, output_iterator auto __out_it) -> decltype(__out_it) { + return __formatter::__copy(basic_string_view{__first, __last}, std::move(__out_it)); } -template <__fmt_char_type _CharT, __fmt_char_type _OutCharT = _CharT> -_LIBCPP_HIDE_FROM_ABI auto __copy(const _CharT* __first, size_t __n, output_iterator auto __out_it) - -> decltype(__out_it) { - return __formatter::__copy(basic_string_view{__first, __n}, _VSTD::move(__out_it)); +template ::value_type, + __fmt_char_type _OutCharT = _CharT> +_LIBCPP_HIDE_FROM_ABI auto +__copy(_Iterator __first, size_t __n, output_iterator auto __out_it) -> decltype(__out_it) { + return __formatter::__copy(basic_string_view{std::to_address(__first), __n}, std::move(__out_it)); } /// Transform wrapper. /// /// This uses a "mass output function" of __format::__output_buffer when possible. -template <__fmt_char_type _CharT, __fmt_char_type _OutCharT = _CharT, class _UnaryOperation> +template ::value_type, + __fmt_char_type _OutCharT = _CharT, + class _UnaryOperation> _LIBCPP_HIDE_FROM_ABI auto -__transform(const _CharT* __first, - const _CharT* __last, +__transform(_Iterator __first, + _Iterator __last, output_iterator auto __out_it, _UnaryOperation __operation) -> decltype(__out_it) { - if constexpr (_VSTD::same_as>>) { - __out_it.__get_container()->__transform(__first, __last, _VSTD::move(__operation)); + if constexpr (std::same_as>>) { + __out_it.__get_container()->__transform(__first, __last, std::move(__operation)); return __out_it; - } else if constexpr (_VSTD::same_as::__iterator>) { - __out_it.__buffer_->__transform(__first, __last, _VSTD::move(__operation)); + } else if constexpr (std::same_as::__iterator>) { + __out_it.__buffer_->__transform(__first, __last, std::move(__operation)); return __out_it; } else { - return std::ranges::transform(__first, __last, _VSTD::move(__out_it), __operation).out; + return std::ranges::transform(__first, __last, std::move(__out_it), __operation).out; } } @@ -156,14 +157,14 @@ __transform(const _CharT* __first, /// This uses a "mass output function" of __format::__output_buffer when possible. template <__fmt_char_type _CharT, output_iterator _OutIt> _LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, _CharT __value) { - if constexpr (_VSTD::same_as>>) { + if constexpr (std::same_as>>) { __out_it.__get_container()->__fill(__n, __value); return __out_it; - } else if constexpr (_VSTD::same_as::__iterator>) { + } else if constexpr (std::same_as::__iterator>) { __out_it.__buffer_->__fill(__n, __value); return __out_it; } else { - return std::ranges::fill_n(_VSTD::move(__out_it), __n, __value); + return std::ranges::fill_n(std::move(__out_it), __n, __value); } } @@ -207,70 +208,6 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __fill(_OutIt __out_it, size_t __n, __format_spec:: } # endif // _LIBCPP_HAS_NO_UNICODE -template -_LIBCPP_HIDE_FROM_ABI _OutIt __write_using_decimal_separators(_OutIt __out_it, const char* __begin, const char* __first, - const char* __last, string&& __grouping, _CharT __sep, - __format_spec::__parsed_specifications<_CharT> __specs) { - int __size = (__first - __begin) + // [sign][prefix] - (__last - __first) + // data - (__grouping.size() - 1); // number of separator characters - - __padding_size_result __padding = {0, 0}; - if (__specs.__alignment_ == __format_spec::__alignment::__zero_padding) { - // Write [sign][prefix]. - __out_it = __formatter::__copy(__begin, __first, _VSTD::move(__out_it)); - - if (__specs.__width_ > __size) { - // Write zero padding. - __padding.__before_ = __specs.__width_ - __size; - __out_it = __formatter::__fill(_VSTD::move(__out_it), __specs.__width_ - __size, _CharT('0')); - } - } else { - if (__specs.__width_ > __size) { - // Determine padding and write padding. - __padding = __formatter::__padding_size(__size, __specs.__width_, __specs.__alignment_); - - __out_it = __formatter::__fill(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_); - } - // Write [sign][prefix]. - __out_it = __formatter::__copy(__begin, __first, _VSTD::move(__out_it)); - } - - auto __r = __grouping.rbegin(); - auto __e = __grouping.rend() - 1; - _LIBCPP_ASSERT(__r != __e, "The slow grouping formatting is used while " - "there will be no separators written."); - // The output is divided in small groups of numbers to write: - // - A group before the first separator. - // - A separator and a group, repeated for the number of separators. - // - A group after the last separator. - // This loop achieves that process by testing the termination condition - // midway in the loop. - // - // TODO FMT This loop evaluates the loop invariant `__parser.__type != - // _Flags::_Type::__hexadecimal_upper_case` for every iteration. (This test - // happens in the __write call.) Benchmark whether making two loops and - // hoisting the invariant is worth the effort. - while (true) { - if (__specs.__std_.__type_ == __format_spec::__type::__hexadecimal_upper_case) { - __last = __first + *__r; - __out_it = __formatter::__transform(__first, __last, _VSTD::move(__out_it), __hex_to_upper); - __first = __last; - } else { - __out_it = __formatter::__copy(__first, *__r, _VSTD::move(__out_it)); - __first += *__r; - } - - if (__r == __e) - break; - - ++__r; - *__out_it++ = __sep; - } - - return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_); -} - /// Writes the input to the output with the required padding. /// /// Since the output column width is specified the function can be used for @@ -299,12 +236,12 @@ __write(basic_string_view<_CharT> __str, __format_spec::__parsed_specifications<_ParserCharT> __specs, ptrdiff_t __size) -> decltype(__out_it) { if (__size >= __specs.__width_) - return __formatter::__copy(__str, _VSTD::move(__out_it)); + return __formatter::__copy(__str, std::move(__out_it)); __padding_size_result __padding = __formatter::__padding_size(__size, __specs.__width_, __specs.__std_.__alignment_); - __out_it = __formatter::__fill(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_); - __out_it = __formatter::__copy(__str, _VSTD::move(__out_it)); - return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_); + __out_it = __formatter::__fill(std::move(__out_it), __padding.__before_, __specs.__fill_); + __out_it = __formatter::__copy(__str, std::move(__out_it)); + return __formatter::__fill(std::move(__out_it), __padding.__after_, __specs.__fill_); } template @@ -314,8 +251,8 @@ __write(_Iterator __first, output_iterator&> auto __out_it, __format_spec::__parsed_specifications<_ParserCharT> __specs, ptrdiff_t __size) -> decltype(__out_it) { - _LIBCPP_ASSERT(__first <= __last, "Not a valid range"); - return __formatter::__write(basic_string_view{__first, __last}, _VSTD::move(__out_it), __specs, __size); + _LIBCPP_ASSERT_VALID_INPUT_RANGE(__first <= __last, "Not a valid range"); + return __formatter::__write(basic_string_view{__first, __last}, std::move(__out_it), __specs, __size); } /// \overload @@ -327,54 +264,30 @@ __write(_Iterator __first, _Iterator __last, output_iterator&> auto __out_it, __format_spec::__parsed_specifications<_ParserCharT> __specs) -> decltype(__out_it) { - _LIBCPP_ASSERT(__first <= __last, "Not a valid range"); - return __formatter::__write(__first, __last, _VSTD::move(__out_it), __specs, __last - __first); + _LIBCPP_ASSERT_VALID_INPUT_RANGE(__first <= __last, "Not a valid range"); + return __formatter::__write(__first, __last, std::move(__out_it), __specs, __last - __first); } -template -_LIBCPP_HIDE_FROM_ABI auto __write_transformed(const _CharT* __first, const _CharT* __last, - output_iterator auto __out_it, - __format_spec::__parsed_specifications<_ParserCharT> __specs, - _UnaryOperation __op) -> decltype(__out_it) { - _LIBCPP_ASSERT(__first <= __last, "Not a valid range"); +template ::value_type, + class _ParserCharT, + class _UnaryOperation> +_LIBCPP_HIDE_FROM_ABI auto __write_transformed( + _Iterator __first, + _Iterator __last, + output_iterator auto __out_it, + __format_spec::__parsed_specifications<_ParserCharT> __specs, + _UnaryOperation __op) -> decltype(__out_it) { + _LIBCPP_ASSERT_VALID_INPUT_RANGE(__first <= __last, "Not a valid range"); ptrdiff_t __size = __last - __first; if (__size >= __specs.__width_) - return __formatter::__transform(__first, __last, _VSTD::move(__out_it), __op); + return __formatter::__transform(__first, __last, std::move(__out_it), __op); __padding_size_result __padding = __formatter::__padding_size(__size, __specs.__width_, __specs.__alignment_); - __out_it = __formatter::__fill(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_); - __out_it = __formatter::__transform(__first, __last, _VSTD::move(__out_it), __op); - return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_); -} - -/// Writes additional zero's for the precision before the exponent. -/// This is used when the precision requested in the format string is larger -/// than the maximum precision of the floating-point type. These precision -/// digits are always 0. -/// -/// \param __exponent The location of the exponent character. -/// \param __num_trailing_zeros The number of 0's to write before the exponent -/// character. -template -_LIBCPP_HIDE_FROM_ABI auto __write_using_trailing_zeros( - const _CharT* __first, - const _CharT* __last, - output_iterator auto __out_it, - __format_spec::__parsed_specifications<_ParserCharT> __specs, - size_t __size, - const _CharT* __exponent, - size_t __num_trailing_zeros) -> decltype(__out_it) { - _LIBCPP_ASSERT(__first <= __last, "Not a valid range"); - _LIBCPP_ASSERT(__num_trailing_zeros > 0, "The overload not writing trailing zeros should have been used"); - - __padding_size_result __padding = - __formatter::__padding_size(__size + __num_trailing_zeros, __specs.__width_, __specs.__alignment_); - __out_it = __formatter::__fill(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_); - __out_it = __formatter::__copy(__first, __exponent, _VSTD::move(__out_it)); - __out_it = __formatter::__fill(_VSTD::move(__out_it), __num_trailing_zeros, _CharT('0')); - __out_it = __formatter::__copy(__exponent, __last, _VSTD::move(__out_it)); - return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_); + __out_it = __formatter::__fill(std::move(__out_it), __padding.__before_, __specs.__fill_); + __out_it = __formatter::__transform(__first, __last, std::move(__out_it), __op); + return __formatter::__fill(std::move(__out_it), __padding.__after_, __specs.__fill_); } /// Writes a string using format's width estimation algorithm. @@ -388,11 +301,11 @@ _LIBCPP_HIDE_FROM_ABI auto __write_string_no_precision( basic_string_view<_CharT> __str, output_iterator auto __out_it, __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) { - _LIBCPP_ASSERT(!__specs.__has_precision(), "use __write_string"); + _LIBCPP_ASSERT_INTERNAL(!__specs.__has_precision(), "use __write_string"); // No padding -> copy the string if (!__specs.__has_width()) - return __formatter::__copy(__str, _VSTD::move(__out_it)); + return __formatter::__copy(__str, std::move(__out_it)); // Note when the estimated width is larger than size there's no padding. So // there's no reason to get the real size when the estimate is larger than or @@ -400,7 +313,7 @@ _LIBCPP_HIDE_FROM_ABI auto __write_string_no_precision( size_t __size = __format_spec::__estimate_column_width(__str, __specs.__width_, __format_spec::__column_width_rounding::__up) .__width_; - return __formatter::__write(__str, _VSTD::move(__out_it), __specs, __size); + return __formatter::__write(__str, std::move(__out_it), __specs, __size); } template @@ -411,187 +324,12 @@ _LIBCPP_HIDE_FROM_ABI int __truncate(basic_string_view<_CharT>& __str, int __pre return __result.__width_; } -/// Writes a string using format's width estimation algorithm. -/// -/// \note When \c _LIBCPP_HAS_NO_UNICODE is defined the function assumes the -/// input is ASCII. -template -_LIBCPP_HIDE_FROM_ABI auto __write_string( - basic_string_view<_CharT> __str, - output_iterator auto __out_it, - __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) { - if (!__specs.__has_precision()) - return __formatter::__write_string_no_precision(__str, _VSTD::move(__out_it), __specs); - - int __size = __formatter::__truncate(__str, __specs.__precision_); - - return __formatter::__write(__str.begin(), __str.end(), _VSTD::move(__out_it), __specs, __size); -} - -# if _LIBCPP_STD_VER >= 23 - -struct __nul_terminator {}; - -template -_LIBCPP_HIDE_FROM_ABI bool operator==(const _CharT* __cstr, __nul_terminator) { - return *__cstr == _CharT('\0'); -} - -template -_LIBCPP_HIDE_FROM_ABI void -__write_escaped_code_unit(basic_string<_CharT>& __str, char32_t __value, const _CharT* __prefix) { - back_insert_iterator __out_it{__str}; - std::ranges::copy(__prefix, __nul_terminator{}, __out_it); - - char __buffer[8]; - to_chars_result __r = std::to_chars(std::begin(__buffer), std::end(__buffer), __value, 16); - _LIBCPP_ASSERT(__r.ec == errc(0), "Internal buffer too small"); - std::ranges::copy(std::begin(__buffer), __r.ptr, __out_it); - - __str += _CharT('}'); -} - -// [format.string.escaped]/2.2.1.2 -// ... -// then the sequence \u{hex-digit-sequence} is appended to E, where -// hex-digit-sequence is the shortest hexadecimal representation of C using -// lower-case hexadecimal digits. -template -_LIBCPP_HIDE_FROM_ABI void __write_well_formed_escaped_code_unit(basic_string<_CharT>& __str, char32_t __value) { - __formatter::__write_escaped_code_unit(__str, __value, _LIBCPP_STATICALLY_WIDEN(_CharT, "\\u{")); -} - -// [format.string.escaped]/2.2.3 -// Otherwise (X is a sequence of ill-formed code units), each code unit U is -// appended to E in order as the sequence \x{hex-digit-sequence}, where -// hex-digit-sequence is the shortest hexadecimal representation of U using -// lower-case hexadecimal digits. -template -_LIBCPP_HIDE_FROM_ABI void __write_escape_ill_formed_code_unit(basic_string<_CharT>& __str, char32_t __value) { - __formatter::__write_escaped_code_unit(__str, __value, _LIBCPP_STATICALLY_WIDEN(_CharT, "\\x{")); -} - -template -[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool __is_escaped_sequence_written(basic_string<_CharT>& __str, char32_t __value) { -# ifdef _LIBCPP_HAS_NO_UNICODE - // For ASCII assume everything above 127 is printable. - if (__value > 127) - return false; -# endif - - if (!__escaped_output_table::__needs_escape(__value)) - return false; - - __formatter::__write_well_formed_escaped_code_unit(__str, __value); - return true; -} - -template -[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr char32_t __to_char32(_CharT __value) { - return static_cast>(__value); -} - -enum class _LIBCPP_ENUM_VIS __escape_quotation_mark { __apostrophe, __double_quote }; - -// [format.string.escaped]/2 -template -[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool -__is_escaped_sequence_written(basic_string<_CharT>& __str, char32_t __value, __escape_quotation_mark __mark) { - // 2.2.1.1 - Mapped character in [tab:format.escape.sequences] - switch (__value) { - case _CharT('\t'): - __str += _LIBCPP_STATICALLY_WIDEN(_CharT, "\\t"); - return true; - case _CharT('\n'): - __str += _LIBCPP_STATICALLY_WIDEN(_CharT, "\\n"); - return true; - case _CharT('\r'): - __str += _LIBCPP_STATICALLY_WIDEN(_CharT, "\\r"); - return true; - case _CharT('\''): - if (__mark == __escape_quotation_mark::__apostrophe) - __str += _LIBCPP_STATICALLY_WIDEN(_CharT, R"(\')"); - else - __str += __value; - return true; - case _CharT('"'): - if (__mark == __escape_quotation_mark::__double_quote) - __str += _LIBCPP_STATICALLY_WIDEN(_CharT, R"(\")"); - else - __str += __value; - return true; - case _CharT('\\'): - __str += _LIBCPP_STATICALLY_WIDEN(_CharT, R"(\\)"); - return true; - - // 2.2.1.2 - Space - case _CharT(' '): - __str += __value; - return true; - } - - // 2.2.2 - // Otherwise, if X is a shift sequence, the effect on E and further - // decoding of S is unspecified. - // For now shift sequences are ignored and treated as Unicode. Other parts - // of the format library do the same. It's unknown how ostream treats them. - // TODO FMT determine what to do with shift sequences. - - // 2.2.1.2.1 and 2.2.1.2.2 - Escape - return __formatter::__is_escaped_sequence_written(__str, __formatter::__to_char32(__value)); -} - -template -_LIBCPP_HIDE_FROM_ABI void -__escape(basic_string<_CharT>& __str, basic_string_view<_CharT> __values, __escape_quotation_mark __mark) { - __unicode::__code_point_view<_CharT> __view{__values.begin(), __values.end()}; - - while (!__view.__at_end()) { - auto __first = __view.__position(); - typename __unicode::__consume_result __result = __view.__consume(); - if (__result.__status == __unicode::__consume_result::__ok) { - if (!__formatter::__is_escaped_sequence_written(__str, __result.__code_point, __mark)) - // 2.2.1.3 - Add the character - ranges::copy(__first, __view.__position(), std::back_insert_iterator(__str)); - } else { - // 2.2.3 sequence of ill-formed code units - ranges::for_each(__first, __view.__position(), [&](_CharT __value) { - __formatter::__write_escape_ill_formed_code_unit(__str, __formatter::__to_char32(__value)); - }); - } - } -} - -template -_LIBCPP_HIDE_FROM_ABI auto -__format_escaped_char(_CharT __value, - output_iterator auto __out_it, - __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) { - basic_string<_CharT> __str; - __str += _CharT('\''); - __formatter::__escape(__str, basic_string_view{std::addressof(__value), 1}, __escape_quotation_mark::__apostrophe); - __str += _CharT('\''); - return __formatter::__write(__str.data(), __str.data() + __str.size(), _VSTD::move(__out_it), __specs, __str.size()); -} - -template -_LIBCPP_HIDE_FROM_ABI auto -__format_escaped_string(basic_string_view<_CharT> __values, - output_iterator auto __out_it, - __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) { - basic_string<_CharT> __str; - __str += _CharT('"'); - __formatter::__escape(__str, __values, __escape_quotation_mark::__double_quote); - __str += _CharT('"'); - return __formatter::__write_string(basic_string_view{__str}, _VSTD::move(__out_it), __specs); -} - -# endif // _LIBCPP_STD_VER >= 23 - } // namespace __formatter #endif //_LIBCPP_STD_VER >= 20 _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___FORMAT_FORMATTER_OUTPUT_H diff --git a/third_party/libcxx/__format/formatter_pointer.h b/third_party/libcxx/__format/formatter_pointer.h index ab699ba65..6941343ef 100644 --- a/third_party/libcxx/__format/formatter_pointer.h +++ b/third_party/libcxx/__format/formatter_pointer.h @@ -10,7 +10,6 @@ #ifndef _LIBCPP___FORMAT_FORMATTER_POINTER_H #define _LIBCPP___FORMAT_FORMATTER_POINTER_H -#include <__availability> #include <__config> #include <__format/concepts.h> #include <__format/format_parse_context.h> @@ -35,7 +34,7 @@ public: template _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { typename _ParseContext::iterator __result = __parser_.__parse(__ctx, __format_spec::__fields_pointer); - __format_spec::__process_display_type_pointer(__parser_.__type_); + __format_spec::__process_display_type_pointer(__parser_.__type_, "a pointer"); return __result; } @@ -43,11 +42,15 @@ public: _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(const void* __ptr, _FormatContext& __ctx) const { __format_spec::__parsed_specifications<_CharT> __specs = __parser_.__get_parsed_std_specifications(__ctx); __specs.__std_.__alternate_form_ = true; - __specs.__std_.__type_ = __format_spec::__type::__hexadecimal_lower_case; + __specs.__std_.__type_ = + __specs.__std_.__type_ == __format_spec::__type::__pointer_upper_case + ? __format_spec::__type::__hexadecimal_upper_case + : __format_spec::__type::__hexadecimal_lower_case; + return __formatter::__format_integer(reinterpret_cast(__ptr), __ctx, __specs); } - __format_spec::__parser<_CharT> __parser_{.__alignment_ = __format_spec::__alignment::__right}; + __format_spec::__parser<_CharT> __parser_; }; // [format.formatter.spec]/2.4 @@ -56,14 +59,11 @@ public: // - template<> struct formatter; // - template<> struct formatter; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_pointer<_CharT> {}; +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_pointer<_CharT> {}; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_pointer<_CharT> { -}; +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_pointer<_CharT> {}; template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_pointer<_CharT> {}; +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_pointer<_CharT> {}; #endif //_LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__format/formatter_string.h b/third_party/libcxx/__format/formatter_string.h index 25a9e8ee4..347439fc8 100644 --- a/third_party/libcxx/__format/formatter_string.h +++ b/third_party/libcxx/__format/formatter_string.h @@ -10,14 +10,13 @@ #ifndef _LIBCPP___FORMAT_FORMATTER_STRING_H #define _LIBCPP___FORMAT_FORMATTER_STRING_H -#include <__availability> #include <__config> #include <__format/concepts.h> #include <__format/format_parse_context.h> #include <__format/formatter.h> #include <__format/formatter_output.h> #include <__format/parser_std_format_spec.h> -#include <__utility/move.h> +#include <__format/write_escaped.h> #include #include @@ -59,14 +58,12 @@ public: // Formatter const char*. template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter - : public __formatter_string<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_string<_CharT> { using _Base = __formatter_string<_CharT>; template _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(const _CharT* __str, _FormatContext& __ctx) const { - _LIBCPP_ASSERT(__str, "The basic_format_arg constructor should have " - "prevented an invalid pointer."); + _LIBCPP_ASSERT_INTERNAL(__str, "The basic_format_arg constructor should have prevented an invalid pointer."); __format_spec::__parsed_specifications<_CharT> __specs = _Base::__parser_.__get_parsed_std_specifications(__ctx); # if _LIBCPP_STD_VER >= 23 @@ -98,8 +95,7 @@ struct _LIBCPP_TEMPLATE_VIS formatter // Formatter char*. template <__fmt_char_type _CharT> -struct _LIBCPP_TEMPLATE_VIS formatter<_CharT*, _CharT> - : public formatter { +struct _LIBCPP_TEMPLATE_VIS formatter<_CharT*, _CharT> : public formatter { using _Base = formatter; template @@ -110,12 +106,12 @@ struct _LIBCPP_TEMPLATE_VIS formatter<_CharT*, _CharT> // Formatter char[]. template <__fmt_char_type _CharT, size_t _Size> -struct _LIBCPP_TEMPLATE_VIS formatter<_CharT[_Size], _CharT> - : public __formatter_string<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter<_CharT[_Size], _CharT> : public __formatter_string<_CharT> { using _Base = __formatter_string<_CharT>; template - _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(_CharT __str[_Size], _FormatContext& __ctx) const { + _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator + format(const _CharT (&__str)[_Size], _FormatContext& __ctx) const { return _Base::format(basic_string_view<_CharT>(__str, _Size), __ctx); } }; @@ -136,8 +132,7 @@ struct _LIBCPP_TEMPLATE_VIS formatter, // Formatter std::string_view. template <__fmt_char_type _CharT, class _Traits> -struct _LIBCPP_TEMPLATE_VIS formatter, _CharT> - : public __formatter_string<_CharT> { +struct _LIBCPP_TEMPLATE_VIS formatter, _CharT> : public __formatter_string<_CharT> { using _Base = __formatter_string<_CharT>; template diff --git a/third_party/libcxx/__format/formatter_tuple.h b/third_party/libcxx/__format/formatter_tuple.h index 92380f858..030097a87 100644 --- a/third_party/libcxx/__format/formatter_tuple.h +++ b/third_party/libcxx/__format/formatter_tuple.h @@ -11,19 +11,16 @@ #define _LIBCPP___FORMAT_FORMATTER_TUPLE_H #include <__algorithm/ranges_copy.h> -#include <__availability> #include <__chrono/statically_widen.h> #include <__config> #include <__format/buffer.h> #include <__format/concepts.h> -#include <__format/format_args.h> #include <__format/format_context.h> #include <__format/format_error.h> #include <__format/format_parse_context.h> #include <__format/formatter.h> #include <__format/formatter_output.h> #include <__format/parser_std_format_spec.h> -#include <__iterator/back_insert_iterator.h> #include <__type_traits/remove_cvref.h> #include <__utility/integer_sequence.h> #include <__utility/pair.h> @@ -54,22 +51,20 @@ struct _LIBCPP_TEMPLATE_VIS __formatter_tuple { auto __begin = __parser_.__parse(__ctx, __format_spec::__fields_tuple); auto __end = __ctx.end(); - if (__begin != __end) { - if (*__begin == _CharT('m')) { - if constexpr (sizeof...(_Args) == 2) { - set_separator(_LIBCPP_STATICALLY_WIDEN(_CharT, ": ")); - set_brackets({}, {}); - ++__begin; - } else - std::__throw_format_error("The format specifier m requires a pair or a two-element tuple"); - } else if (*__begin == _CharT('n')) { + // Note 'n' is part of the type here + if (__parser_.__clear_brackets_) + set_brackets({}, {}); + else if (__begin != __end && *__begin == _CharT('m')) { + if constexpr (sizeof...(_Args) == 2) { + set_separator(_LIBCPP_STATICALLY_WIDEN(_CharT, ": ")); set_brackets({}, {}); ++__begin; - } + } else + std::__throw_format_error("Type m requires a pair or a tuple with two elements"); } if (__begin != __end && *__begin != _CharT('}')) - std::__throw_format_error("The format-spec should consume the input or end with a '}'"); + std::__throw_format_error("The format specifier should consume the input or end with a '}'"); __ctx.advance_to(__begin); diff --git a/third_party/libcxx/__format/indic_conjunct_break_table.h b/third_party/libcxx/__format/indic_conjunct_break_table.h new file mode 100644 index 000000000..44521d274 --- /dev/null +++ b/third_party/libcxx/__format/indic_conjunct_break_table.h @@ -0,0 +1,350 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// WARNING, this entire header is generated by +// utils/generate_indic_conjunct_break_table.py +// DO NOT MODIFY! + +// UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE +// +// See Terms of Use +// for definitions of Unicode Inc.'s Data Files and Software. +// +// NOTICE TO USER: Carefully read the following legal agreement. +// BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S +// DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), +// YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE +// TERMS AND CONDITIONS OF THIS AGREEMENT. +// IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE +// THE DATA FILES OR SOFTWARE. +// +// COPYRIGHT AND PERMISSION NOTICE +// +// Copyright (c) 1991-2022 Unicode, Inc. All rights reserved. +// Distributed under the Terms of Use in https://www.unicode.org/copyright.html. +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of the Unicode data files and any associated documentation +// (the "Data Files") or Unicode software and any associated documentation +// (the "Software") to deal in the Data Files or Software +// without restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, and/or sell copies of +// the Data Files or Software, and to permit persons to whom the Data Files +// or Software are furnished to do so, provided that either +// (a) this copyright and permission notice appear with all copies +// of the Data Files or Software, or +// (b) this copyright and permission notice appear in associated +// Documentation. +// +// THE DATA FILES AND SOFTWARE ARE 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 OF THIRD PARTY RIGHTS. +// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS +// NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL +// DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, +// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THE DATA FILES OR SOFTWARE. +// +// Except as contained in this notice, the name of a copyright holder +// shall not be used in advertising or otherwise to promote the sale, +// use or other dealings in these Data Files or Software without prior +// written authorization of the copyright holder. + +#ifndef _LIBCPP___FORMAT_INDIC_CONJUNCT_BREAK_TABLE_H +#define _LIBCPP___FORMAT_INDIC_CONJUNCT_BREAK_TABLE_H + +#include <__algorithm/ranges_upper_bound.h> +#include <__config> +#include <__iterator/access.h> +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER >= 20 + +namespace __indic_conjunct_break { + +enum class __property : uint8_t { + // Values generated from the data files. + __Consonant, + __Extend, + __Linker, + + // The code unit has none of above properties. + __none +}; + +/// The entries of the indic conjunct break property table. +/// +/// The data is generated from +/// - https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt +/// +/// The data has 3 values +/// - bits [0, 1] The property. One of the values generated from the datafiles +/// of \ref __property +/// - bits [2, 10] The size of the range. +/// - bits [11, 31] The lower bound code point of the range. The upper bound of +/// the range is lower bound + size. +/// +/// The 9 bits for the size allow a maximum range of 512 elements. Some ranges +/// in the Unicode tables are larger. They are stored in multiple consecutive +/// ranges in the data table. An alternative would be to store the sizes in a +/// separate 16-bit value. The original MSVC STL code had such an approach, but +/// this approach uses less space for the data and is about 4% faster in the +/// following benchmark. +/// libcxx/benchmarks/std_format_spec_string_unicode.bench.cpp +// clang-format off +_LIBCPP_HIDE_FROM_ABI inline constexpr uint32_t __entries[201] = { + 0x00180139, + 0x001a807d, + 0x00241811, + 0x002c88b1, + 0x002df801, + 0x002e0805, + 0x002e2005, + 0x002e3801, + 0x00308029, + 0x00325851, + 0x00338001, + 0x0036b019, + 0x0036f815, + 0x00373805, + 0x0037500d, + 0x00388801, + 0x00398069, + 0x003f5821, + 0x003fe801, + 0x0040b00d, + 0x0040d821, + 0x00412809, + 0x00414811, + 0x0042c809, + 0x0044c01d, + 0x0046505d, + 0x00471871, + 0x0048a890, + 0x0049e001, + 0x004a6802, + 0x004a880d, + 0x004ac01c, + 0x004bc01c, + 0x004ca84c, + 0x004d5018, + 0x004d9000, + 0x004db00c, + 0x004de001, + 0x004e6802, + 0x004ee004, + 0x004ef800, + 0x004f8004, + 0x004ff001, + 0x0051e001, + 0x0054a84c, + 0x00555018, + 0x00559004, + 0x0055a810, + 0x0055e001, + 0x00566802, + 0x0057c800, + 0x0058a84c, + 0x00595018, + 0x00599004, + 0x0059a810, + 0x0059e001, + 0x005a6802, + 0x005ae004, + 0x005af800, + 0x005b8800, + 0x0060a84c, + 0x0061503c, + 0x0061e001, + 0x00626802, + 0x0062a805, + 0x0062c008, + 0x0065e001, + 0x0068a894, + 0x0069d805, + 0x006a6802, + 0x0071c009, + 0x0072400d, + 0x0075c009, + 0x0076400d, + 0x0078c005, + 0x0079a801, + 0x0079b801, + 0x0079c801, + 0x007b8805, + 0x007ba001, + 0x007bd00d, + 0x007c0001, + 0x007c1009, + 0x007c3005, + 0x007e3001, + 0x0081b801, + 0x0081c805, + 0x00846801, + 0x009ae809, + 0x00b8a001, + 0x00be9001, + 0x00bee801, + 0x00c54801, + 0x00c9c809, + 0x00d0b805, + 0x00d30001, + 0x00d3a81d, + 0x00d3f801, + 0x00d58035, + 0x00d5f83d, + 0x00d9a001, + 0x00db5821, + 0x00dd5801, + 0x00df3001, + 0x00e1b801, + 0x00e68009, + 0x00e6a031, + 0x00e71019, + 0x00e76801, + 0x00e7a001, + 0x00e7c005, + 0x00ee00fd, + 0x01006801, + 0x01068031, + 0x01070801, + 0x0107282d, + 0x01677809, + 0x016bf801, + 0x016f007d, + 0x01815015, + 0x0184c805, + 0x05337801, + 0x0533a025, + 0x0534f005, + 0x05378005, + 0x05416001, + 0x05470045, + 0x05495809, + 0x054d9801, + 0x05558001, + 0x05559009, + 0x0555b805, + 0x0555f005, + 0x05560801, + 0x0557b001, + 0x055f6801, + 0x07d8f001, + 0x07f1003d, + 0x080fe801, + 0x08170001, + 0x081bb011, + 0x08506801, + 0x08507801, + 0x0851c009, + 0x0851f801, + 0x08572805, + 0x0869200d, + 0x08755805, + 0x0877e809, + 0x087a3029, + 0x087c100d, + 0x08838001, + 0x0883f801, + 0x0885d001, + 0x08880009, + 0x08899805, + 0x088b9801, + 0x088e5001, + 0x0891b001, + 0x08974805, + 0x0899d805, + 0x089b3019, + 0x089b8011, + 0x08a23001, + 0x08a2f001, + 0x08a61801, + 0x08ae0001, + 0x08b5b801, + 0x08b95801, + 0x08c1d001, + 0x08c9f001, + 0x08ca1801, + 0x08d1a001, + 0x08d23801, + 0x08d4c801, + 0x08ea1001, + 0x08ea2005, + 0x08ecb801, + 0x08fa1001, + 0x0b578011, + 0x0b598019, + 0x0de4f001, + 0x0e8b2801, + 0x0e8b3809, + 0x0e8b7011, + 0x0e8bd81d, + 0x0e8c2819, + 0x0e8d500d, + 0x0e921009, + 0x0f000019, + 0x0f004041, + 0x0f00d819, + 0x0f011805, + 0x0f013011, + 0x0f047801, + 0x0f098019, + 0x0f157001, + 0x0f17600d, + 0x0f27600d, + 0x0f468019, + 0x0f4a2019}; +// clang-format on + +/// Returns the indic conjuct break property of a code point. +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __property __get_property(const char32_t __code_point) noexcept { + // The algorithm searches for the upper bound of the range and, when found, + // steps back one entry. This algorithm is used since the code point can be + // anywhere in the range. After a lower bound is found the next step is to + // compare whether the code unit is indeed in the range. + // + // Since the entry contains a code unit, size, and property the code point + // being sought needs to be adjusted. Just shifting the code point to the + // proper position doesn't work; suppose an entry has property 0, size 1, + // and lower bound 3. This results in the entry 0x1810. + // When searching for code point 3 it will search for 0x1800, find 0x1810 + // and moves to the previous entry. Thus the lower bound value will never + // be found. + // The simple solution is to set the bits belonging to the property and + // size. Then the upper bound for code point 3 will return the entry after + // 0x1810. After moving to the previous entry the algorithm arrives at the + // correct entry. + ptrdiff_t __i = std::ranges::upper_bound(__entries, (__code_point << 11) | 0x7ffu) - __entries; + if (__i == 0) + return __property::__none; + + --__i; + uint32_t __upper_bound = (__entries[__i] >> 11) + ((__entries[__i] >> 2) & 0b1'1111'1111); + if (__code_point <= __upper_bound) + return static_cast<__property>(__entries[__i] & 0b11); + + return __property::__none; +} + +} // namespace __indic_conjunct_break + +#endif //_LIBCPP_STD_VER >= 20 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FORMAT_INDIC_CONJUNCT_BREAK_TABLE_H diff --git a/third_party/libcxx/__format/parser_std_format_spec.h b/third_party/libcxx/__format/parser_std_format_spec.h index f3f7bce81..150bdde89 100644 --- a/third_party/libcxx/__format/parser_std_format_spec.h +++ b/third_party/libcxx/__format/parser_std_format_spec.h @@ -17,13 +17,11 @@ /// affect the std-format-spec. #include <__algorithm/copy_n.h> -#include <__algorithm/find_if.h> #include <__algorithm/min.h> #include <__assert> #include <__concepts/arithmetic.h> #include <__concepts/same_as.h> #include <__config> -#include <__debug> #include <__format/format_arg.h> #include <__format/format_error.h> #include <__format/format_parse_context.h> @@ -31,12 +29,14 @@ #include <__format/unicode.h> #include <__format/width_estimation_table.h> #include <__iterator/concepts.h> -#include <__iterator/readable_traits.h> // iter_value_t +#include <__iterator/iterator_traits.h> // iter_value_t #include <__memory/addressof.h> #include <__type_traits/common_type.h> +#include <__type_traits/is_constant_evaluated.h> #include <__type_traits/is_trivially_copyable.h> #include <__variant/monostate.h> #include +#include #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -52,6 +52,17 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace __format_spec { +_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI inline void +__throw_invalid_option_format_error(const char* __id, const char* __option) { + std::__throw_format_error( + (string("The format specifier for ") + __id + " does not allow the " + __option + " option").c_str()); +} + +_LIBCPP_NORETURN _LIBCPP_HIDE_FROM_ABI inline void __throw_invalid_type_format_error(const char* __id) { + std::__throw_format_error( + (string("The type option contains an invalid value for ") + __id + " formatting argument").c_str()); +} + template _LIBCPP_HIDE_FROM_ABI constexpr __format::__parse_number_result<_Iterator> __parse_arg_id(_Iterator __begin, _Iterator __end, _ParseContext& __ctx) { @@ -59,20 +70,19 @@ __parse_arg_id(_Iterator __begin, _Iterator __end, _ParseContext& __ctx) { // This function is a wrapper to call the real parser. But it does the // validation for the pre-conditions and post-conditions. if (__begin == __end) - std::__throw_format_error("End of input while parsing format-spec arg-id"); + std::__throw_format_error("End of input while parsing an argument index"); __format::__parse_number_result __r = __format::__parse_arg_id(__begin, __end, __ctx); if (__r.__last == __end || *__r.__last != _CharT('}')) - std::__throw_format_error("Invalid arg-id"); + std::__throw_format_error("The argument index is invalid"); ++__r.__last; return __r; } template -_LIBCPP_HIDE_FROM_ABI constexpr uint32_t -__substitute_arg_id(basic_format_arg<_Context> __format_arg) { +_LIBCPP_HIDE_FROM_ABI constexpr uint32_t __substitute_arg_id(basic_format_arg<_Context> __format_arg) { // [format.string.std]/8 // If the corresponding formatting argument is not of integral type... // This wording allows char and bool too. LWG-3720 changes the wording to @@ -81,11 +91,11 @@ __substitute_arg_id(basic_format_arg<_Context> __format_arg) { // This means the 128-bit will not be valid anymore. // TODO FMT Verify this resolution is accepted and add a test to verify // 128-bit integrals fail and switch to visit_format_arg. - return _VSTD::__visit_format_arg( + return std::__visit_format_arg( [](auto __arg) -> uint32_t { using _Type = decltype(__arg); if constexpr (same_as<_Type, monostate>) - std::__throw_format_error("Argument index out of bounds"); + std::__throw_format_error("The argument index value is too large for the number of arguments supplied"); // [format.string.std]/8 // If { arg-idopt } is used in a width or precision, the value of the @@ -101,12 +111,12 @@ __substitute_arg_id(basic_format_arg<_Context> __format_arg) { same_as<_Type, long long> || same_as<_Type, unsigned long long>) { if constexpr (signed_integral<_Type>) { if (__arg < 0) - std::__throw_format_error("A format-spec arg-id replacement shouldn't have a negative value"); + std::__throw_format_error("An argument index may not have a negative value"); } using _CT = common_type_t<_Type, decltype(__format::__number_max)>; if (static_cast<_CT>(__arg) > static_cast<_CT>(__format::__number_max)) - std::__throw_format_error("A format-spec arg-id replacement exceeds the maximum supported value"); + std::__throw_format_error("The value of the argument index exceeds its maximum value"); return __arg; } else @@ -119,48 +129,52 @@ __substitute_arg_id(basic_format_arg<_Context> __format_arg) { /// /// They default to false so when a new field is added it needs to be opted in /// explicitly. -// TODO FMT Use an ABI tag for this struct. -struct __fields { - uint8_t __sign_ : 1 {false}; - uint8_t __alternate_form_ : 1 {false}; - uint8_t __zero_padding_ : 1 {false}; - uint8_t __precision_ : 1 {false}; - uint8_t __locale_specific_form_ : 1 {false}; - uint8_t __type_ : 1 {false}; +struct _LIBCPP_HIDE_FROM_ABI __fields { + uint16_t __sign_ : 1 {false}; + uint16_t __alternate_form_ : 1 {false}; + uint16_t __zero_padding_ : 1 {false}; + uint16_t __precision_ : 1 {false}; + uint16_t __locale_specific_form_ : 1 {false}; + uint16_t __type_ : 1 {false}; // Determines the valid values for fill. // // Originally the fill could be any character except { and }. Range-based // formatters use the colon to mark the beginning of the // underlying-format-spec. To avoid parsing ambiguities these formatter // specializations prohibit the use of the colon as a fill character. - uint8_t __use_range_fill_ : 1 {false}; + uint16_t __use_range_fill_ : 1 {false}; + uint16_t __clear_brackets_ : 1 {false}; + uint16_t __consume_all_ : 1 {false}; }; // By not placing this constant in the formatter class it's not duplicated for // char and wchar_t. +inline constexpr __fields __fields_bool{.__locale_specific_form_ = true, .__type_ = true, .__consume_all_ = true}; inline constexpr __fields __fields_integral{ .__sign_ = true, .__alternate_form_ = true, .__zero_padding_ = true, .__locale_specific_form_ = true, - .__type_ = true}; + .__type_ = true, + .__consume_all_ = true}; inline constexpr __fields __fields_floating_point{ .__sign_ = true, .__alternate_form_ = true, .__zero_padding_ = true, .__precision_ = true, .__locale_specific_form_ = true, - .__type_ = true}; -inline constexpr __fields __fields_string{.__precision_ = true, .__type_ = true}; -inline constexpr __fields __fields_pointer{.__type_ = true}; + .__type_ = true, + .__consume_all_ = true}; +inline constexpr __fields __fields_string{.__precision_ = true, .__type_ = true, .__consume_all_ = true}; +inline constexpr __fields __fields_pointer{.__zero_padding_ = true, .__type_ = true, .__consume_all_ = true}; # if _LIBCPP_STD_VER >= 23 -inline constexpr __fields __fields_tuple{.__use_range_fill_ = true}; -inline constexpr __fields __fields_range{.__use_range_fill_ = true}; +inline constexpr __fields __fields_tuple{.__use_range_fill_ = true, .__clear_brackets_ = true}; +inline constexpr __fields __fields_range{.__use_range_fill_ = true, .__clear_brackets_ = true}; inline constexpr __fields __fields_fill_align_width{}; # endif -enum class _LIBCPP_ENUM_VIS __alignment : uint8_t { +enum class __alignment : uint8_t { /// No alignment is set in the format string. __default, __left, @@ -169,7 +183,7 @@ enum class _LIBCPP_ENUM_VIS __alignment : uint8_t { __zero_padding }; -enum class _LIBCPP_ENUM_VIS __sign : uint8_t { +enum class __sign : uint8_t { /// No sign is set in the format string. /// /// The sign isn't allowed for certain format-types. By using this value @@ -181,8 +195,8 @@ enum class _LIBCPP_ENUM_VIS __sign : uint8_t { __space }; -enum class _LIBCPP_ENUM_VIS __type : uint8_t { - __default, +enum class __type : uint8_t { + __default = 0, __string, __binary_lower_case, __binary_upper_case, @@ -190,7 +204,8 @@ enum class _LIBCPP_ENUM_VIS __type : uint8_t { __decimal, __hexadecimal_lower_case, __hexadecimal_upper_case, - __pointer, + __pointer_lower_case, + __pointer_upper_case, __char, __hexfloat_lower_case, __hexfloat_upper_case, @@ -203,23 +218,42 @@ enum class _LIBCPP_ENUM_VIS __type : uint8_t { __debug }; +_LIBCPP_HIDE_FROM_ABI inline constexpr uint32_t __create_type_mask(__type __t) { + uint32_t __shift = static_cast(__t); + if (__shift == 0) + return 1; + + if (__shift > 31) + std::__throw_format_error("The type does not fit in the mask"); + + return 1 << __shift; +} + +inline constexpr uint32_t __type_mask_integer = + __create_type_mask(__type::__binary_lower_case) | // + __create_type_mask(__type::__binary_upper_case) | // + __create_type_mask(__type::__decimal) | // + __create_type_mask(__type::__octal) | // + __create_type_mask(__type::__hexadecimal_lower_case) | // + __create_type_mask(__type::__hexadecimal_upper_case); + struct __std { - __alignment __alignment_ : 3; - __sign __sign_ : 2; - bool __alternate_form_ : 1; + __alignment __alignment_ : 3; + __sign __sign_ : 2; + bool __alternate_form_ : 1; bool __locale_specific_form_ : 1; __type __type_; }; struct __chrono { - __alignment __alignment_ : 3; + __alignment __alignment_ : 3; bool __locale_specific_form_ : 1; bool __hour_ : 1; - bool __weekday_name_ : 1; + bool __weekday_name_ : 1; bool __weekday_ : 1; bool __day_of_year_ : 1; bool __week_of_year_ : 1; - bool __month_name_ : 1; + bool __month_name_ : 1; }; // The fill UCS scalar value. @@ -303,50 +337,163 @@ static_assert(is_trivially_copyable_v<__parsed_specifications>); template class _LIBCPP_TEMPLATE_VIS __parser { public: + // Parses the format specification. + // + // Depending on whether the parsing is done compile-time or run-time + // the method slightly differs. + // - Only parses a field when it is in the __fields. Accepting all + // fields and then validating the valid ones has a performance impact. + // This is faster but gives slighly worse error messages. + // - At compile-time when a field is not accepted the parser will still + // parse it and give an error when it's present. This gives a more + // accurate error. + // The idea is that most times the format instead of the vformat + // functions are used. In that case the error will be detected during + // compilation and there is no need to pay for the run-time overhead. template _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator __parse(_ParseContext& __ctx, __fields __fields) { auto __begin = __ctx.begin(); auto __end = __ctx.end(); - if (__begin == __end) + if (__begin == __end || *__begin == _CharT('}') || (__fields.__use_range_fill_ && *__begin == _CharT(':'))) return __begin; - if (__parse_fill_align(__begin, __end, __fields.__use_range_fill_) && __begin == __end) + if (__parse_fill_align(__begin, __end) && __begin == __end) return __begin; - if (__fields.__sign_ && __parse_sign(__begin) && __begin == __end) - return __begin; + if (__fields.__sign_) { + if (__parse_sign(__begin) && __begin == __end) + return __begin; + } else if (std::is_constant_evaluated() && __parse_sign(__begin)) { + std::__throw_format_error("The format specification does not allow the sign option"); + } - if (__fields.__alternate_form_ && __parse_alternate_form(__begin) && __begin == __end) - return __begin; + if (__fields.__alternate_form_) { + if (__parse_alternate_form(__begin) && __begin == __end) + return __begin; + } else if (std::is_constant_evaluated() && __parse_alternate_form(__begin)) { + std::__throw_format_error("The format specifier does not allow the alternate form option"); + } - if (__fields.__zero_padding_ && __parse_zero_padding(__begin) && __begin == __end) - return __begin; + if (__fields.__zero_padding_) { + if (__parse_zero_padding(__begin) && __begin == __end) + return __begin; + } else if (std::is_constant_evaluated() && __parse_zero_padding(__begin)) { + std::__throw_format_error("The format specifier does not allow the zero-padding option"); + } if (__parse_width(__begin, __end, __ctx) && __begin == __end) return __begin; - if (__fields.__precision_ && __parse_precision(__begin, __end, __ctx) && __begin == __end) - return __begin; + if (__fields.__precision_) { + if (__parse_precision(__begin, __end, __ctx) && __begin == __end) + return __begin; + } else if (std::is_constant_evaluated() && __parse_precision(__begin, __end, __ctx)) { + std::__throw_format_error("The format specifier does not allow the precision option"); + } - if (__fields.__locale_specific_form_ && __parse_locale_specific_form(__begin) && __begin == __end) - return __begin; + if (__fields.__locale_specific_form_) { + if (__parse_locale_specific_form(__begin) && __begin == __end) + return __begin; + } else if (std::is_constant_evaluated() && __parse_locale_specific_form(__begin)) { + std::__throw_format_error("The format specifier does not allow the locale-specific form option"); + } - if (__fields.__type_) { + if (__fields.__clear_brackets_) { + if (__parse_clear_brackets(__begin) && __begin == __end) + return __begin; + } else if (std::is_constant_evaluated() && __parse_clear_brackets(__begin)) { + std::__throw_format_error("The format specifier does not allow the n option"); + } + + if (__fields.__type_) __parse_type(__begin); - // When __type_ is false the calling parser is expected to do additional - // parsing. In that case that parser should do the end of format string - // validation. - if (__begin != __end && *__begin != _CharT('}')) - std::__throw_format_error("The format-spec should consume the input or end with a '}'"); - } + if (!__fields.__consume_all_) + return __begin; + + if (__begin != __end && *__begin != _CharT('}')) + std::__throw_format_error("The format specifier should consume the input or end with a '}'"); return __begin; } + // Validates the selected the parsed data. + // + // The valid fields in the parser may depend on the display type + // selected. But the type is the last optional field, so by the time + // it's known an option can't be used, it already has been parsed. + // This does the validation again. + // + // For example an integral may have a sign, zero-padding, or alternate + // form when the type option is not 'c'. So the generic approach is: + // + // typename _ParseContext::iterator __result = __parser_.__parse(__ctx, __format_spec::__fields_integral); + // if (__parser.__type_ == __format_spec::__type::__char) { + // __parser.__validate((__format_spec::__fields_bool, "an integer"); + // ... // more char adjustments + // } else { + // ... // validate an integral type. + // } + // + // For some types all valid options need a second validation run, like + // boolean types. + // + // Depending on whether the validation is done at compile-time or + // run-time the error differs + // - run-time the exception is thrown and contains the type of field + // being validated. + // - at compile-time the line with `std::__throw_format_error` is shown + // in the output. In that case it's important for the error to be on one + // line. + // Note future versions of C++ may allow better compile-time error + // reporting. + _LIBCPP_HIDE_FROM_ABI constexpr void + __validate(__fields __fields, const char* __id, uint32_t __type_mask = -1) const { + if (!__fields.__sign_ && __sign_ != __sign::__default) { + if (std::is_constant_evaluated()) + std::__throw_format_error("The format specifier does not allow the sign option"); + else + __format_spec::__throw_invalid_option_format_error(__id, "sign"); + } + + if (!__fields.__alternate_form_ && __alternate_form_) { + if (std::is_constant_evaluated()) + std::__throw_format_error("The format specifier does not allow the alternate form option"); + else + __format_spec::__throw_invalid_option_format_error(__id, "alternate form"); + } + + if (!__fields.__zero_padding_ && __alignment_ == __alignment::__zero_padding) { + if (std::is_constant_evaluated()) + std::__throw_format_error("The format specifier does not allow the zero-padding option"); + else + __format_spec::__throw_invalid_option_format_error(__id, "zero-padding"); + } + + if (!__fields.__precision_ && __precision_ != -1) { // Works both when the precision has a value or an arg-id. + if (std::is_constant_evaluated()) + std::__throw_format_error("The format specifier does not allow the precision option"); + else + __format_spec::__throw_invalid_option_format_error(__id, "precision"); + } + + if (!__fields.__locale_specific_form_ && __locale_specific_form_) { + if (std::is_constant_evaluated()) + std::__throw_format_error("The format specifier does not allow the locale-specific form option"); + else + __format_spec::__throw_invalid_option_format_error(__id, "locale-specific form"); + } + + if ((__create_type_mask(__type_) & __type_mask) == 0) { + if (std::is_constant_evaluated()) + std::__throw_format_error("The format specifier uses an invalid value for the type option"); + else + __format_spec::__throw_invalid_type_format_error(__id); + } + } + /// \returns the `__parsed_specifications` with the resolved dynamic sizes.. - _LIBCPP_HIDE_FROM_ABI - __parsed_specifications<_CharT> __get_parsed_std_specifications(auto& __ctx) const { + _LIBCPP_HIDE_FROM_ABI __parsed_specifications<_CharT> __get_parsed_std_specifications(auto& __ctx) const { return __parsed_specifications<_CharT>{ .__std_ = __std{.__alignment_ = __alignment_, .__sign_ = __sign_, @@ -374,11 +521,11 @@ public: .__fill_{__fill_}}; } - __alignment __alignment_ : 3 {__alignment::__default}; - __sign __sign_ : 2 {__sign::__default}; - bool __alternate_form_ : 1 {false}; + __alignment __alignment_ : 3 {__alignment::__default}; + __sign __sign_ : 2 {__sign::__default}; + bool __alternate_form_ : 1 {false}; bool __locale_specific_form_ : 1 {false}; - bool __reserved_0_ : 1 {false}; + bool __clear_brackets_ : 1 {false}; __type __type_{__type::__default}; // These flags are only used for formatting chrono. Since the struct has @@ -393,11 +540,11 @@ public: bool __month_name_ : 1 {false}; - uint8_t __reserved_1_ : 2 {0}; - uint8_t __reserved_2_ : 6 {0}; + uint8_t __reserved_0_ : 2 {0}; + uint8_t __reserved_1_ : 6 {0}; // These two flags are only used internally and not part of the // __parsed_specifications. Therefore put them at the end. - bool __width_as_arg_ : 1 {false}; + bool __width_as_arg_ : 1 {false}; bool __precision_as_arg_ : 1 {false}; /// The requested width, either the value or the arg-id. @@ -426,13 +573,11 @@ private: return false; } - _LIBCPP_HIDE_FROM_ABI constexpr void __validate_fill_character(_CharT __fill, bool __use_range_fill) { + _LIBCPP_HIDE_FROM_ABI constexpr void __validate_fill_character(_CharT __fill) { // The forbidden fill characters all code points formed from a single code unit, thus the // check can be omitted when more code units are used. - if (__use_range_fill && (__fill == _CharT('{') || __fill == _CharT('}') || __fill == _CharT(':'))) - std::__throw_format_error("The format-spec range-fill field contains an invalid character"); - else if (__fill == _CharT('{') || __fill == _CharT('}')) - std::__throw_format_error("The format-spec fill field contains an invalid character"); + if (__fill == _CharT('{')) + std::__throw_format_error("The fill option contains an invalid value"); } # ifndef _LIBCPP_HAS_NO_UNICODE @@ -442,14 +587,15 @@ private: # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS || (same_as<_CharT, wchar_t> && sizeof(wchar_t) == 2) # endif - _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_fill_align(_Iterator& __begin, _Iterator __end, bool __use_range_fill) { - _LIBCPP_ASSERT(__begin != __end, - "when called with an empty input the function will cause " - "undefined behavior by evaluating data not in the input"); + _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_fill_align(_Iterator& __begin, _Iterator __end) { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __begin != __end, + "when called with an empty input the function will cause " + "undefined behavior by evaluating data not in the input"); __unicode::__code_point_view<_CharT> __view{__begin, __end}; __unicode::__consume_result __consumed = __view.__consume(); if (__consumed.__status != __unicode::__consume_result::__ok) - std::__throw_format_error("The format-spec contains malformed Unicode characters"); + std::__throw_format_error("The format specifier contains malformed Unicode characters"); if (__view.__position() < __end && __parse_alignment(*__view.__position())) { ptrdiff_t __code_units = __view.__position() - __begin; @@ -457,7 +603,7 @@ private: // The forbidden fill characters all are code points encoded // in one code unit, thus the check can be omitted when more // code units are used. - __validate_fill_character(*__begin, __use_range_fill); + __validate_fill_character(*__begin); std::copy_n(__begin, __code_units, std::addressof(__fill_.__data[0])); __begin += __code_units + 1; @@ -474,15 +620,16 @@ private: # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template requires(same_as<_CharT, wchar_t> && sizeof(wchar_t) == 4) - _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_fill_align(_Iterator& __begin, _Iterator __end, bool __use_range_fill) { - _LIBCPP_ASSERT(__begin != __end, - "when called with an empty input the function will cause " - "undefined behavior by evaluating data not in the input"); + _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_fill_align(_Iterator& __begin, _Iterator __end) { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __begin != __end, + "when called with an empty input the function will cause " + "undefined behavior by evaluating data not in the input"); if (__begin + 1 != __end && __parse_alignment(*(__begin + 1))) { if (!__unicode::__is_scalar_value(*__begin)) - std::__throw_format_error("The fill character contains an invalid value"); + std::__throw_format_error("The fill option contains an invalid value"); - __validate_fill_character(*__begin, __use_range_fill); + __validate_fill_character(*__begin); __fill_.__data[0] = *__begin; __begin += 2; @@ -501,13 +648,14 @@ private: # else // _LIBCPP_HAS_NO_UNICODE // range-fill and tuple-fill are identical template - _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_fill_align(_Iterator& __begin, _Iterator __end, bool __use_range_fill) { - _LIBCPP_ASSERT(__begin != __end, - "when called with an empty input the function will cause " - "undefined behavior by evaluating data not in the input"); + _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_fill_align(_Iterator& __begin, _Iterator __end) { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __begin != __end, + "when called with an empty input the function will cause " + "undefined behavior by evaluating data not in the input"); if (__begin + 1 != __end) { if (__parse_alignment(*(__begin + 1))) { - __validate_fill_character(*__begin, __use_range_fill); + __validate_fill_character(*__begin); __fill_.__data[0] = *__begin; __begin += 2; @@ -567,13 +715,13 @@ private: template _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_width(_Iterator& __begin, _Iterator __end, auto& __ctx) { if (*__begin == _CharT('0')) - std::__throw_format_error("A format-spec width field shouldn't have a leading zero"); + std::__throw_format_error("The width option should not have a leading zero"); if (*__begin == _CharT('{')) { __format::__parse_number_result __r = __format_spec::__parse_arg_id(++__begin, __end, __ctx); - __width_as_arg_ = true; - __width_ = __r.__value; - __begin = __r.__last; + __width_as_arg_ = true; + __width_ = __r.__value; + __begin = __r.__last; return true; } @@ -581,9 +729,10 @@ private: return false; __format::__parse_number_result __r = __format::__parse_number(__begin, __end); - __width_ = __r.__value; - _LIBCPP_ASSERT(__width_ != 0, "A zero value isn't allowed and should be impossible, " - "due to validations in this function"); + __width_ = __r.__value; + _LIBCPP_ASSERT_INTERNAL(__width_ != 0, + "A zero value isn't allowed and should be impossible, " + "due to validations in this function"); __begin = __r.__last; return true; } @@ -595,23 +744,23 @@ private: ++__begin; if (__begin == __end) - std::__throw_format_error("End of input while parsing format-spec precision"); + std::__throw_format_error("End of input while parsing format specifier precision"); if (*__begin == _CharT('{')) { __format::__parse_number_result __arg_id = __format_spec::__parse_arg_id(++__begin, __end, __ctx); - __precision_as_arg_ = true; - __precision_ = __arg_id.__value; - __begin = __arg_id.__last; + __precision_as_arg_ = true; + __precision_ = __arg_id.__value; + __begin = __arg_id.__last; return true; } if (*__begin < _CharT('0') || *__begin > _CharT('9')) - std::__throw_format_error("The format-spec precision field doesn't contain a value or arg-id"); + std::__throw_format_error("The precision option does not contain a value or an argument index"); __format::__parse_number_result __r = __format::__parse_number(__begin, __end); - __precision_ = __r.__value; - __precision_as_arg_ = false; - __begin = __r.__last; + __precision_ = __r.__value; + __precision_as_arg_ = false; + __begin = __r.__last; return true; } @@ -625,6 +774,16 @@ private: return true; } + template + _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_clear_brackets(_Iterator& __begin) { + if (*__begin != _CharT('n')) + return false; + + __clear_brackets_ = true; + ++__begin; + return true; + } + template _LIBCPP_HIDE_FROM_ABI constexpr void __parse_type(_Iterator& __begin) { // Determines the type. It does not validate whether the selected type is @@ -676,7 +835,10 @@ private: __type_ = __type::__octal; break; case 'p': - __type_ = __type::__pointer; + __type_ = __type::__pointer_lower_case; + break; + case 'P': + __type_ = __type::__pointer_upper_case; break; case 's': __type_ = __type::__string; @@ -695,16 +857,14 @@ private: ++__begin; } - _LIBCPP_HIDE_FROM_ABI - int32_t __get_width(auto& __ctx) const { + _LIBCPP_HIDE_FROM_ABI int32_t __get_width(auto& __ctx) const { if (!__width_as_arg_) return __width_; return __format_spec::__substitute_arg_id(__ctx.arg(__width_)); } - _LIBCPP_HIDE_FROM_ABI - int32_t __get_precision(auto& __ctx) const { + _LIBCPP_HIDE_FROM_ABI int32_t __get_precision(auto& __ctx) const { if (!__precision_as_arg_) return __precision_; @@ -726,36 +886,28 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_string(__format_spec break; default: - std::__throw_format_error("The format-spec type has a type not supported for a string argument"); + std::__throw_format_error("The type option contains an invalid value for a string formatting argument"); } } template -_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_bool_string(__parser<_CharT>& __parser) { - if (__parser.__sign_ != __sign::__default) - std::__throw_format_error("A sign field isn't allowed in this format-spec"); - - if (__parser.__alternate_form_) - std::__throw_format_error("An alternate form field isn't allowed in this format-spec"); - - if (__parser.__alignment_ == __alignment::__zero_padding) - std::__throw_format_error("A zero-padding field isn't allowed in this format-spec"); - +_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_bool_string(__parser<_CharT>& __parser, const char* __id) { + __parser.__validate(__format_spec::__fields_bool, __id); if (__parser.__alignment_ == __alignment::__default) __parser.__alignment_ = __alignment::__left; } template -_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_char(__parser<_CharT>& __parser) { - __format_spec::__process_display_type_bool_string(__parser); +_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_char(__parser<_CharT>& __parser, const char* __id) { + __format_spec::__process_display_type_bool_string(__parser, __id); } template -_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_bool(__parser<_CharT>& __parser) { +_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_bool(__parser<_CharT>& __parser, const char* __id) { switch (__parser.__type_) { case __format_spec::__type::__default: case __format_spec::__type::__string: - __format_spec::__process_display_type_bool_string(__parser); + __format_spec::__process_display_type_bool_string(__parser, __id); break; case __format_spec::__type::__binary_lower_case: @@ -767,17 +919,17 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_bool(__parser<_CharT>& __p break; default: - std::__throw_format_error("The format-spec type has a type not supported for a bool argument"); + __format_spec::__throw_invalid_type_format_error(__id); } } template -_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_char(__parser<_CharT>& __parser) { +_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_char(__parser<_CharT>& __parser, const char* __id) { switch (__parser.__type_) { case __format_spec::__type::__default: case __format_spec::__type::__char: case __format_spec::__type::__debug: - __format_spec::__process_display_type_char(__parser); + __format_spec::__process_display_type_char(__parser, __id); break; case __format_spec::__type::__binary_lower_case: @@ -789,12 +941,12 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_char(__parser<_CharT>& __p break; default: - std::__throw_format_error("The format-spec type has a type not supported for a char argument"); + __format_spec::__throw_invalid_type_format_error(__id); } } template -_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_integer(__parser<_CharT>& __parser) { +_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_integer(__parser<_CharT>& __parser, const char* __id) { switch (__parser.__type_) { case __format_spec::__type::__default: case __format_spec::__type::__binary_lower_case: @@ -806,16 +958,16 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_integer(__parser<_CharT>& break; case __format_spec::__type::__char: - __format_spec::__process_display_type_char(__parser); + __format_spec::__process_display_type_char(__parser, __id); break; default: - std::__throw_format_error("The format-spec type has a type not supported for an integer argument"); + __format_spec::__throw_invalid_type_format_error(__id); } } template -_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_floating_point(__parser<_CharT>& __parser) { +_LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_floating_point(__parser<_CharT>& __parser, const char* __id) { switch (__parser.__type_) { case __format_spec::__type::__default: case __format_spec::__type::__hexfloat_lower_case: @@ -834,18 +986,19 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __process_parsed_floating_point(__parser<_C break; default: - std::__throw_format_error("The format-spec type has a type not supported for a floating-point argument"); + __format_spec::__throw_invalid_type_format_error(__id); } } -_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_pointer(__format_spec::__type __type) { +_LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type_pointer(__format_spec::__type __type, const char* __id) { switch (__type) { case __format_spec::__type::__default: - case __format_spec::__type::__pointer: + case __format_spec::__type::__pointer_lower_case: + case __format_spec::__type::__pointer_upper_case: break; default: - std::__throw_format_error("The format-spec type has a type not supported for a pointer argument"); + __format_spec::__throw_invalid_type_format_error(__id); } } @@ -1002,8 +1155,8 @@ __estimate_column_width(basic_string_view<_CharT> __str, size_t __maximum, __col // When Unicode isn't supported assume ASCII and every code unit is one code // point. In ASCII the estimated column width is always one. Thus there's no // need for rounding. - size_t __width_ = _VSTD::min(__str.size(), __maximum); - return {__width_, __str.begin() + __width_}; + size_t __width = std::min(__str.size(), __maximum); + return {__width, __str.begin() + __width}; } # endif // !defined(_LIBCPP_HAS_NO_UNICODE) diff --git a/third_party/libcxx/__format/range_default_formatter.h b/third_party/libcxx/__format/range_default_formatter.h index 7808d0b12..b35223ae9 100644 --- a/third_party/libcxx/__format/range_default_formatter.h +++ b/third_party/libcxx/__format/range_default_formatter.h @@ -10,8 +10,11 @@ #ifndef _LIBCPP___FORMAT_RANGE_DEFAULT_FORMATTER_H #define _LIBCPP___FORMAT_RANGE_DEFAULT_FORMATTER_H +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + #include <__algorithm/ranges_copy.h> -#include <__availability> #include <__chrono/statically_widen.h> #include <__concepts/same_as.h> #include <__config> @@ -21,11 +24,12 @@ #include <__iterator/back_insert_iterator.h> #include <__ranges/concepts.h> #include <__ranges/data.h> +#include <__ranges/from_range.h> #include <__ranges/size.h> +#include <__type_traits/conditional.h> #include <__type_traits/remove_cvref.h> #include <__utility/pair.h> #include -#include _LIBCPP_BEGIN_NAMESPACE_STD @@ -108,8 +112,9 @@ public: return __underlying_.parse(__ctx); } - template - _LIBCPP_HIDE_FROM_ABI typename FormatContext::iterator format(__maybe_const_r& __range, FormatContext& __ctx) const { + template + _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator + format(__maybe_const_r& __range, _FormatContext& __ctx) const { return __underlying_.format(__range, __ctx); } }; @@ -193,15 +198,8 @@ public: // specialization is the "basic" string formatter in libc++. if constexpr (ranges::contiguous_range<_Rp> && std::ranges::sized_range<_Rp>) return __underlying_.format(basic_string_view<_CharT>{ranges::data(__range), ranges::size(__range)}, __ctx); - else { - // P2106's from_range has not been implemented yet. Instead use a simple - // copy operation. - // TODO FMT use basic_string's "from_range" constructor. - // return __underlying_.format(basic_string<_CharT>{from_range, __range}, __ctx); - basic_string<_CharT> __str; - std::ranges::copy(__range, back_insert_iterator{__str}); - return __underlying_.format(static_cast>(__str), __ctx); - } + else + return __underlying_.format(basic_string<_CharT>{from_range, __range}, __ctx); } }; diff --git a/third_party/libcxx/__format/range_formatter.h b/third_party/libcxx/__format/range_formatter.h index c0d238a55..691563074 100644 --- a/third_party/libcxx/__format/range_formatter.h +++ b/third_party/libcxx/__format/range_formatter.h @@ -10,14 +10,16 @@ #ifndef _LIBCPP___FORMAT_RANGE_FORMATTER_H #define _LIBCPP___FORMAT_RANGE_FORMATTER_H +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + #include <__algorithm/ranges_copy.h> -#include <__availability> #include <__chrono/statically_widen.h> #include <__concepts/same_as.h> #include <__config> #include <__format/buffer.h> #include <__format/concepts.h> -#include <__format/format_args.h> #include <__format/format_context.h> #include <__format/format_error.h> #include <__format/formatter.h> @@ -26,6 +28,7 @@ #include <__iterator/back_insert_iterator.h> #include <__ranges/concepts.h> #include <__ranges/data.h> +#include <__ranges/from_range.h> #include <__ranges/size.h> #include <__type_traits/remove_cvref.h> #include @@ -62,18 +65,8 @@ struct _LIBCPP_TEMPLATE_VIS range_formatter { // The n field overrides a possible m type, therefore delay applying the // effect of n until the type has been procesed. - bool __clear_brackets = (*__begin == _CharT('n')); - if (__clear_brackets) { - ++__begin; - if (__begin == __end) [[unlikely]] { - // Since there is no more data, clear the brackets before returning. - set_brackets({}, {}); - return __parse_empty_range_underlying_spec(__ctx, __begin); - } - } - __parse_type(__begin, __end); - if (__clear_brackets) + if (__parser_.__clear_brackets_) set_brackets({}, {}); if (__begin == __end) [[unlikely]] return __parse_empty_range_underlying_spec(__ctx, __begin); @@ -89,7 +82,7 @@ struct _LIBCPP_TEMPLATE_VIS range_formatter { // processed by the underlying. For example {:-} for a range in invalid, // the sign field is not present. Without this check the underlying_ will // get -} as input which my be valid. - std::__throw_format_error("The format-spec should consume the input or end with a '}'"); + std::__throw_format_error("The format specifier should consume the input or end with a '}'"); __ctx.advance_to(__begin); __begin = __underlying_.parse(__ctx); @@ -102,13 +95,13 @@ struct _LIBCPP_TEMPLATE_VIS range_formatter { // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ // could consume more than it should. if (__begin != __end && *__begin != _CharT('}')) - std::__throw_format_error("The format-spec should consume the input or end with a '}'"); + std::__throw_format_error("The format specifier should consume the input or end with a '}'"); if (__parser_.__type_ != __format_spec::__type::__default) { // [format.range.formatter]/6 // If the range-type is s or ?s, then there shall be no n option and no // range-underlying-spec. - if (__clear_brackets) { + if (__parser_.__clear_brackets_) { if (__parser_.__type_ == __format_spec::__type::__string) std::__throw_format_error("The n option and type s can't be used together"); std::__throw_format_error("The n option and type ?s can't be used together"); @@ -192,13 +185,7 @@ struct _LIBCPP_TEMPLATE_VIS range_formatter { std::formatter, _CharT> __formatter; if (__debug_format) __formatter.set_debug_format(); - // P2106's from_range has not been implemented yet. Instead use a simple - // copy operation. - // TODO FMT use basic_string's "from_range" constructor. - // return std::formatter, _CharT>{}.format(basic_string<_CharT>{from_range, __range}, __ctx); - basic_string<_CharT> __str; - ranges::copy(__range, back_insert_iterator{__str}); - return __formatter.format(__str, __ctx); + return __formatter.format(basic_string<_CharT>{from_range, __range}, __ctx); } } @@ -231,7 +218,7 @@ private: set_separator(_LIBCPP_STATICALLY_WIDEN(_CharT, ", ")); ++__begin; } else - std::__throw_format_error("The range-format-spec type m requires two elements for a pair or tuple"); + std::__throw_format_error("Type m requires a pair or a tuple with two elements"); break; case _CharT('s'): @@ -239,18 +226,18 @@ private: __parser_.__type_ = __format_spec::__type::__string; ++__begin; } else - std::__throw_format_error("The range-format-spec type s requires formatting a character type"); + std::__throw_format_error("Type s requires character type as formatting argument"); break; case _CharT('?'): ++__begin; if (__begin == __end || *__begin != _CharT('s')) - std::__throw_format_error("The format-spec should consume the input or end with a '}'"); + std::__throw_format_error("The format specifier should consume the input or end with a '}'"); if constexpr (same_as<_Tp, _CharT>) { __parser_.__type_ = __format_spec::__type::__debug; ++__begin; } else - std::__throw_format_error("The range-format-spec type ?s requires formatting a character type"); + std::__throw_format_error("Type ?s requires character type as formatting argument"); } } @@ -259,8 +246,8 @@ private: __parse_empty_range_underlying_spec(_ParseContext& __ctx, typename _ParseContext::iterator __begin) { __ctx.advance_to(__begin); [[maybe_unused]] typename _ParseContext::iterator __result = __underlying_.parse(__ctx); - _LIBCPP_ASSERT(__result == __begin, - "the underlying's parse function should not advance the input beyond the end of the input"); + _LIBCPP_ASSERT_INTERNAL(__result == __begin, + "the underlying's parse function should not advance the input beyond the end of the input"); return __begin; } diff --git a/third_party/libcxx/__format/unicode.h b/third_party/libcxx/__format/unicode.h index 12aed5079..de7d0fea1 100644 --- a/third_party/libcxx/__format/unicode.h +++ b/third_party/libcxx/__format/unicode.h @@ -15,9 +15,9 @@ #include <__concepts/same_as.h> #include <__config> #include <__format/extended_grapheme_cluster_table.h> +#include <__format/indic_conjunct_break_table.h> #include <__iterator/concepts.h> #include <__iterator/readable_traits.h> // iter_value_t -#include <__type_traits/make_unsigned.h> #include <__utility/unreachable.h> #include @@ -105,7 +105,7 @@ template requires same_as, char> _LIBCPP_HIDE_FROM_ABI constexpr bool __is_continuation(_Iterator __char, int __count) { do { - if ((*__char & 0b1000'0000) != 0b1000'0000) + if ((*__char & 0b1100'0000) != 0b1000'0000) return false; --__count; ++__char; @@ -155,7 +155,7 @@ public: // - The parser always needs to consume these code units // - The code is optimized for well-formed UTF-8 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __consume_result __consume() noexcept { - _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input"); + _LIBCPP_ASSERT_INTERNAL(__first_ != __last_, "can't move beyond the end of input"); // Based on the number of leading 1 bits the number of code units in the // code point can be determined. See @@ -261,7 +261,7 @@ public: _LIBCPP_HIDE_FROM_ABI constexpr bool __at_end() const noexcept { return __first_ == __last_; } [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __consume_result __consume() noexcept { - _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input"); + _LIBCPP_ASSERT_INTERNAL(__first_ != __last_, "can't move beyond the end of input"); char32_t __value = static_cast(*__first_++); if constexpr (sizeof(wchar_t) == 2) { @@ -294,85 +294,231 @@ private: }; # endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS -_LIBCPP_HIDE_FROM_ABI constexpr bool __at_extended_grapheme_cluster_break( - bool& __ri_break_allowed, - bool __has_extened_pictographic, - __extended_grapheme_custer_property_boundary::__property __prev, - __extended_grapheme_custer_property_boundary::__property __next) { - using __extended_grapheme_custer_property_boundary::__property; +// State machine to implement the Extended Grapheme Cluster Boundary +// +// The exact rules may change between Unicode versions. +// This implements the extended rules see +// https://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries +class __extended_grapheme_cluster_break { + using __EGC_property = __extended_grapheme_custer_property_boundary::__property; + using __inCB_property = __indic_conjunct_break::__property; - __has_extened_pictographic |= __prev == __property::__Extended_Pictographic; - - // https://www.unicode.org/reports/tr29/tr29-39.html#Grapheme_Cluster_Boundary_Rules - - // *** Break at the start and end of text, unless the text is empty. *** - - _LIBCPP_ASSERT(__prev != __property::__sot, "should be handled in the constructor"); // GB1 - _LIBCPP_ASSERT(__prev != __property::__eot, "should be handled by our caller"); // GB2 - - // *** Do not break between a CR and LF. Otherwise, break before and after controls. *** - if (__prev == __property::__CR && __next == __property::__LF) // GB3 - return false; - - if (__prev == __property::__Control || __prev == __property::__CR || __prev == __property::__LF) // GB4 - return true; - - if (__next == __property::__Control || __next == __property::__CR || __next == __property::__LF) // GB5 - return true; - - // *** Do not break Hangul syllable sequences. *** - if (__prev == __property::__L && - (__next == __property::__L || __next == __property::__V || __next == __property::__LV || - __next == __property::__LVT)) // GB6 - return false; - - if ((__prev == __property::__LV || __prev == __property::__V) && - (__next == __property::__V || __next == __property::__T)) // GB7 - return false; - - if ((__prev == __property::__LVT || __prev == __property::__T) && __next == __property::__T) // GB8 - return false; - - // *** Do not break before extending characters or ZWJ. *** - if (__next == __property::__Extend || __next == __property::__ZWJ) - return false; // GB9 - - // *** Do not break before SpacingMarks, or after Prepend characters. *** - if (__next == __property::__SpacingMark) // GB9a - return false; - - if (__prev == __property::__Prepend) // GB9b - return false; - - // *** Do not break within emoji modifier sequences or emoji zwj sequences. *** - - // GB11 \p{Extended_Pictographic} Extend* ZWJ x \p{Extended_Pictographic} - // - // Note that several parts of this rule are matched by GB9: Any x (Extend | ZWJ) - // - \p{Extended_Pictographic} x Extend - // - Extend x Extend - // - \p{Extended_Pictographic} x ZWJ - // - Extend x ZWJ - // - // So the only case left to test is - // - \p{Extended_Pictographic}' x ZWJ x \p{Extended_Pictographic} - // where \p{Extended_Pictographic}' is stored in __has_extened_pictographic - if (__has_extened_pictographic && __prev == __property::__ZWJ && __next == __property::__Extended_Pictographic) - return false; - - // *** Do not break within emoji flag sequences *** - - // That is, do not break between regional indicator (RI) symbols if there - // is an odd number of RI characters before the break point. - - if (__prev == __property::__Regional_Indicator && __next == __property::__Regional_Indicator) { // GB12 + GB13 - __ri_break_allowed = !__ri_break_allowed; - return __ri_break_allowed; +public: + _LIBCPP_HIDE_FROM_ABI constexpr explicit __extended_grapheme_cluster_break(char32_t __first_code_point) + : __prev_code_point_(__first_code_point), + __prev_property_(__extended_grapheme_custer_property_boundary::__get_property(__first_code_point)) { + // Initializes the active rule. + if (__prev_property_ == __EGC_property::__Extended_Pictographic) + __active_rule_ = __rule::__GB11_emoji; + else if (__prev_property_ == __EGC_property::__Regional_Indicator) + __active_rule_ = __rule::__GB12_GB13_regional_indicator; + else if (__indic_conjunct_break::__get_property(__first_code_point) == __inCB_property::__Consonant) + __active_rule_ = __rule::__GB9c_indic_conjunct_break; } - // *** Otherwise, break everywhere. *** - return true; // GB999 -} + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(char32_t __next_code_point) { + __EGC_property __next_property = __extended_grapheme_custer_property_boundary::__get_property(__next_code_point); + bool __result = __evaluate(__next_code_point, __next_property); + __prev_code_point_ = __next_code_point; + __prev_property_ = __next_property; + return __result; + } + + // The code point whose break propery are considered during the next + // evaluation cyle. + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr char32_t __current_code_point() const { return __prev_code_point_; } + +private: + // The naming of the identifiers matches the Unicode standard. + // NOLINTBEGIN(readability-identifier-naming) + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool + __evaluate(char32_t __next_code_point, __EGC_property __next_property) { + switch (__active_rule_) { + case __rule::__none: + return __evaluate_none(__next_code_point, __next_property); + case __rule::__GB9c_indic_conjunct_break: + return __evaluate_GB9c_indic_conjunct_break(__next_code_point, __next_property); + case __rule::__GB11_emoji: + return __evaluate_GB11_emoji(__next_code_point, __next_property); + case __rule::__GB12_GB13_regional_indicator: + return __evaluate_GB12_GB13_regional_indicator(__next_code_point, __next_property); + } + __libcpp_unreachable(); + } + + _LIBCPP_HIDE_FROM_ABI constexpr bool __evaluate_none(char32_t __next_code_point, __EGC_property __next_property) { + // *** Break at the start and end of text, unless the text is empty. *** + + _LIBCPP_ASSERT_INTERNAL(__prev_property_ != __EGC_property::__sot, "should be handled in the constructor"); // GB1 + _LIBCPP_ASSERT_INTERNAL(__prev_property_ != __EGC_property::__eot, "should be handled by our caller"); // GB2 + + // *** Do not break between a CR and LF. Otherwise, break before and after controls. *** + if (__prev_property_ == __EGC_property::__CR && __next_property == __EGC_property::__LF) // GB3 + return false; + + if (__prev_property_ == __EGC_property::__Control || __prev_property_ == __EGC_property::__CR || + __prev_property_ == __EGC_property::__LF) // GB4 + return true; + + if (__next_property == __EGC_property::__Control || __next_property == __EGC_property::__CR || + __next_property == __EGC_property::__LF) // GB5 + return true; + + // *** Do not break Hangul syllable sequences. *** + if (__prev_property_ == __EGC_property::__L && + (__next_property == __EGC_property::__L || __next_property == __EGC_property::__V || + __next_property == __EGC_property::__LV || __next_property == __EGC_property::__LVT)) // GB6 + return false; + + if ((__prev_property_ == __EGC_property::__LV || __prev_property_ == __EGC_property::__V) && + (__next_property == __EGC_property::__V || __next_property == __EGC_property::__T)) // GB7 + return false; + + if ((__prev_property_ == __EGC_property::__LVT || __prev_property_ == __EGC_property::__T) && + __next_property == __EGC_property::__T) // GB8 + return false; + + // *** Do not break before extending characters or ZWJ. *** + if (__next_property == __EGC_property::__Extend || __next_property == __EGC_property::__ZWJ) + return false; // GB9 + + // *** Do not break before SpacingMarks, or after Prepend characters. *** + if (__next_property == __EGC_property::__SpacingMark) // GB9a + return false; + + if (__prev_property_ == __EGC_property::__Prepend) // GB9b + return false; + + // *** Do not break within certain combinations with Indic_Conjunct_Break (InCB)=Linker. *** + if (__indic_conjunct_break::__get_property(__next_code_point) == __inCB_property::__Consonant) { + __active_rule_ = __rule::__GB9c_indic_conjunct_break; + __GB9c_indic_conjunct_break_state_ = __GB9c_indic_conjunct_break_state::__Consonant; + return true; + } + + // *** Do not break within emoji modifier sequences or emoji zwj sequences. *** + if (__next_property == __EGC_property::__Extended_Pictographic) { + __active_rule_ = __rule::__GB11_emoji; + __GB11_emoji_state_ = __GB11_emoji_state::__Extended_Pictographic; + return true; + } + + // *** Do not break within emoji flag sequences *** + + // That is, do not break between regional indicator (RI) symbols if there + // is an odd number of RI characters before the break point. + if (__next_property == __EGC_property::__Regional_Indicator) { // GB12 + GB13 + __active_rule_ = __rule::__GB12_GB13_regional_indicator; + return true; + } + + // *** Otherwise, break everywhere. *** + return true; // GB999 + } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool + __evaluate_GB9c_indic_conjunct_break(char32_t __next_code_point, __EGC_property __next_property) { + __inCB_property __break = __indic_conjunct_break::__get_property(__next_code_point); + if (__break == __inCB_property::__none) { + __active_rule_ = __rule::__none; + return __evaluate_none(__next_code_point, __next_property); + } + + switch (__GB9c_indic_conjunct_break_state_) { + case __GB9c_indic_conjunct_break_state::__Consonant: + if (__break == __inCB_property::__Extend) { + return false; + } + if (__break == __inCB_property::__Linker) { + __GB9c_indic_conjunct_break_state_ = __GB9c_indic_conjunct_break_state::__Linker; + return false; + } + __active_rule_ = __rule::__none; + return __evaluate_none(__next_code_point, __next_property); + + case __GB9c_indic_conjunct_break_state::__Linker: + if (__break == __inCB_property::__Extend) { + return false; + } + if (__break == __inCB_property::__Linker) { + return false; + } + if (__break == __inCB_property::__Consonant) { + __GB9c_indic_conjunct_break_state_ = __GB9c_indic_conjunct_break_state::__Consonant; + return false; + } + __active_rule_ = __rule::__none; + return __evaluate_none(__next_code_point, __next_property); + } + __libcpp_unreachable(); + } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool + __evaluate_GB11_emoji(char32_t __next_code_point, __EGC_property __next_property) { + switch (__GB11_emoji_state_) { + case __GB11_emoji_state::__Extended_Pictographic: + if (__next_property == __EGC_property::__Extend) { + __GB11_emoji_state_ = __GB11_emoji_state::__Extend; + return false; + } + [[fallthrough]]; + case __GB11_emoji_state::__Extend: + if (__next_property == __EGC_property::__ZWJ) { + __GB11_emoji_state_ = __GB11_emoji_state::__ZWJ; + return false; + } + if (__next_property == __EGC_property::__Extend) + return false; + __active_rule_ = __rule::__none; + return __evaluate_none(__next_code_point, __next_property); + + case __GB11_emoji_state::__ZWJ: + if (__next_property == __EGC_property::__Extended_Pictographic) { + __GB11_emoji_state_ = __GB11_emoji_state::__Extended_Pictographic; + return false; + } + __active_rule_ = __rule::__none; + return __evaluate_none(__next_code_point, __next_property); + } + __libcpp_unreachable(); + } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool + __evaluate_GB12_GB13_regional_indicator(char32_t __next_code_point, __EGC_property __next_property) { + __active_rule_ = __rule::__none; + if (__next_property == __EGC_property::__Regional_Indicator) + return false; + return __evaluate_none(__next_code_point, __next_property); + } + + char32_t __prev_code_point_; + __EGC_property __prev_property_; + + enum class __rule { + __none, + __GB9c_indic_conjunct_break, + __GB11_emoji, + __GB12_GB13_regional_indicator, + }; + __rule __active_rule_ = __rule::__none; + + enum class __GB11_emoji_state { + __Extended_Pictographic, + __Extend, + __ZWJ, + }; + __GB11_emoji_state __GB11_emoji_state_ = __GB11_emoji_state::__Extended_Pictographic; + + enum class __GB9c_indic_conjunct_break_state { + __Consonant, + __Linker, + }; + + __GB9c_indic_conjunct_break_state __GB9c_indic_conjunct_break_state_ = __GB9c_indic_conjunct_break_state::__Consonant; + + // NOLINTEND(readability-identifier-naming) +}; /// Helper class to extract an extended grapheme cluster from a Unicode character range. /// @@ -385,9 +531,7 @@ class __extended_grapheme_cluster_view { public: _LIBCPP_HIDE_FROM_ABI constexpr explicit __extended_grapheme_cluster_view(_Iterator __first, _Iterator __last) - : __code_point_view_(__first, __last), - __next_code_point_(__code_point_view_.__consume().__code_point), - __next_prop_(__extended_grapheme_custer_property_boundary::__get_property(__next_code_point_)) {} + : __code_point_view_(__first, __last), __at_break_(__code_point_view_.__consume().__code_point) {} struct __cluster { /// The first code point of the extended grapheme cluster. @@ -403,45 +547,20 @@ public: _Iterator __last_; }; - _LIBCPP_HIDE_FROM_ABI constexpr __cluster __consume() { - _LIBCPP_ASSERT( - __next_prop_ != __extended_grapheme_custer_property_boundary::__property::__eot, - "can't move beyond the end of input"); - - char32_t __code_point = __next_code_point_; - if (!__code_point_view_.__at_end()) - return {__code_point, __get_break()}; - - __next_prop_ = __extended_grapheme_custer_property_boundary::__property::__eot; - return {__code_point, __code_point_view_.__position()}; + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __cluster __consume() { + char32_t __code_point = __at_break_.__current_code_point(); + _Iterator __position = __code_point_view_.__position(); + while (!__code_point_view_.__at_end()) { + if (__at_break_(__code_point_view_.__consume().__code_point)) + break; + __position = __code_point_view_.__position(); + } + return {__code_point, __position}; } private: __code_point_view<_CharT> __code_point_view_; - - char32_t __next_code_point_; - __extended_grapheme_custer_property_boundary::__property __next_prop_; - - _LIBCPP_HIDE_FROM_ABI constexpr _Iterator __get_break() { - bool __ri_break_allowed = true; - bool __has_extened_pictographic = false; - while (true) { - _Iterator __result = __code_point_view_.__position(); - __extended_grapheme_custer_property_boundary::__property __prev = __next_prop_; - if (__code_point_view_.__at_end()) { - __next_prop_ = __extended_grapheme_custer_property_boundary::__property::__eot; - return __result; - } - __next_code_point_ = __code_point_view_.__consume().__code_point; - __next_prop_ = __extended_grapheme_custer_property_boundary::__get_property(__next_code_point_); - - __has_extened_pictographic |= - __prev == __extended_grapheme_custer_property_boundary::__property::__Extended_Pictographic; - - if (__at_extended_grapheme_cluster_break(__ri_break_allowed, __has_extened_pictographic, __prev, __next_prop_)) - return __result; - } - } + __extended_grapheme_cluster_break __at_break_; }; template @@ -463,7 +582,7 @@ public: _LIBCPP_HIDE_FROM_ABI constexpr _Iterator __position() const noexcept { return __first_; } [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __consume_result __consume() noexcept { - _LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input"); + _LIBCPP_ASSERT_INTERNAL(__first_ != __last_, "can't move beyond the end of input"); return {static_cast(*__first_++)}; } diff --git a/third_party/libcxx/__format/width_estimation_table.h b/third_party/libcxx/__format/width_estimation_table.h index cfb488975..11f61dea1 100644 --- a/third_party/libcxx/__format/width_estimation_table.h +++ b/third_party/libcxx/__format/width_estimation_table.h @@ -119,7 +119,7 @@ namespace __width_estimation_table { /// - bits [0, 13] The size of the range, allowing 16384 elements. /// - bits [14, 31] The lower bound code point of the range. The upper bound of /// the range is lower bound + size. -inline constexpr uint32_t __entries[108] = { +_LIBCPP_HIDE_FROM_ABI inline constexpr uint32_t __entries[107] = { 0x0440005f /* 00001100 - 0000115f [ 96] */, // 0x08c68001 /* 0000231a - 0000231b [ 2] */, // 0x08ca4001 /* 00002329 - 0000232a [ 2] */, // @@ -158,14 +158,13 @@ inline constexpr uint32_t __entries[108] = { 0x0ba00019 /* 00002e80 - 00002e99 [ 26] */, // 0x0ba6c058 /* 00002e9b - 00002ef3 [ 89] */, // 0x0bc000d5 /* 00002f00 - 00002fd5 [ 214] */, // - 0x0bfc000b /* 00002ff0 - 00002ffb [ 12] */, // - 0x0c00003e /* 00003000 - 0000303e [ 63] */, // + 0x0bfc004e /* 00002ff0 - 0000303e [ 79] */, // 0x0c104055 /* 00003041 - 00003096 [ 86] */, // 0x0c264066 /* 00003099 - 000030ff [ 103] */, // 0x0c41402a /* 00003105 - 0000312f [ 43] */, // 0x0c4c405d /* 00003131 - 0000318e [ 94] */, // 0x0c640053 /* 00003190 - 000031e3 [ 84] */, // - 0x0c7c002e /* 000031f0 - 0000321e [ 47] */, // + 0x0c7bc02f /* 000031ef - 0000321e [ 48] */, // 0x0c880027 /* 00003220 - 00003247 [ 40] */, // 0x0c943fff /* 00003250 - 0000724f [16384] */, // 0x1c94323c /* 00007250 - 0000a48c [12861] */, // @@ -238,7 +237,7 @@ inline constexpr uint32_t __table_upper_bound = 0x0003fffd; /// Returns the estimated width of a Unicode code point. /// -/// \pre The code point is a valid Unicode code point. +/// \\pre The code point is a valid Unicode code point. [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int __estimated_width(const char32_t __code_point) noexcept { // Since __table_upper_bound contains the unshifted range do the // comparison without shifting. diff --git a/third_party/libcxx/__format/write_escaped.h b/third_party/libcxx/__format/write_escaped.h new file mode 100644 index 000000000..052ea98c3 --- /dev/null +++ b/third_party/libcxx/__format/write_escaped.h @@ -0,0 +1,242 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___FORMAT_WRITE_ESCAPED_H +#define _LIBCPP___FORMAT_WRITE_ESCAPED_H + +#include <__algorithm/ranges_copy.h> +#include <__algorithm/ranges_for_each.h> +#include <__charconv/to_chars_integral.h> +#include <__charconv/to_chars_result.h> +#include <__chrono/statically_widen.h> +#include <__format/escaped_output_table.h> +#include <__format/formatter_output.h> +#include <__format/parser_std_format_spec.h> +#include <__format/unicode.h> +#include <__iterator/back_insert_iterator.h> +#include <__memory/addressof.h> +#include <__system_error/errc.h> +#include <__type_traits/make_unsigned.h> +#include <__utility/move.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace __formatter { + +#if _LIBCPP_STD_VER >= 20 + +/// Writes a string using format's width estimation algorithm. +/// +/// \note When \c _LIBCPP_HAS_NO_UNICODE is defined the function assumes the +/// input is ASCII. +template +_LIBCPP_HIDE_FROM_ABI auto +__write_string(basic_string_view<_CharT> __str, + output_iterator auto __out_it, + __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) { + if (!__specs.__has_precision()) + return __formatter::__write_string_no_precision(__str, std::move(__out_it), __specs); + + int __size = __formatter::__truncate(__str, __specs.__precision_); + + return __formatter::__write(__str.begin(), __str.end(), std::move(__out_it), __specs, __size); +} + +#endif // _LIBCPP_STD_VER >= 20 +#if _LIBCPP_STD_VER >= 23 + +struct __nul_terminator {}; + +template +_LIBCPP_HIDE_FROM_ABI bool operator==(const _CharT* __cstr, __nul_terminator) { + return *__cstr == _CharT('\0'); +} + +template +_LIBCPP_HIDE_FROM_ABI void +__write_escaped_code_unit(basic_string<_CharT>& __str, char32_t __value, const _CharT* __prefix) { + back_insert_iterator __out_it{__str}; + std::ranges::copy(__prefix, __nul_terminator{}, __out_it); + + char __buffer[8]; + to_chars_result __r = std::to_chars(std::begin(__buffer), std::end(__buffer), __value, 16); + _LIBCPP_ASSERT_INTERNAL(__r.ec == errc(0), "Internal buffer too small"); + std::ranges::copy(std::begin(__buffer), __r.ptr, __out_it); + + __str += _CharT('}'); +} + +// [format.string.escaped]/2.2.1.2 +// ... +// then the sequence \u{hex-digit-sequence} is appended to E, where +// hex-digit-sequence is the shortest hexadecimal representation of C using +// lower-case hexadecimal digits. +template +_LIBCPP_HIDE_FROM_ABI void __write_well_formed_escaped_code_unit(basic_string<_CharT>& __str, char32_t __value) { + __formatter::__write_escaped_code_unit(__str, __value, _LIBCPP_STATICALLY_WIDEN(_CharT, "\\u{")); +} + +// [format.string.escaped]/2.2.3 +// Otherwise (X is a sequence of ill-formed code units), each code unit U is +// appended to E in order as the sequence \x{hex-digit-sequence}, where +// hex-digit-sequence is the shortest hexadecimal representation of U using +// lower-case hexadecimal digits. +template +_LIBCPP_HIDE_FROM_ABI void __write_escape_ill_formed_code_unit(basic_string<_CharT>& __str, char32_t __value) { + __formatter::__write_escaped_code_unit(__str, __value, _LIBCPP_STATICALLY_WIDEN(_CharT, "\\x{")); +} + +template +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool +__is_escaped_sequence_written(basic_string<_CharT>& __str, bool __last_escaped, char32_t __value) { +# ifdef _LIBCPP_HAS_NO_UNICODE + // For ASCII assume everything above 127 is printable. + if (__value > 127) + return false; +# endif + + // [format.string.escaped]/2.2.1.2.1 + // CE is UTF-8, UTF-16, or UTF-32 and C corresponds to a Unicode scalar + // value whose Unicode property General_Category has a value in the groups + // Separator (Z) or Other (C), as described by UAX #44 of the Unicode Standard, + if (!__escaped_output_table::__needs_escape(__value)) + // [format.string.escaped]/2.2.1.2.2 + // CE is UTF-8, UTF-16, or UTF-32 and C corresponds to a Unicode scalar + // value with the Unicode property Grapheme_Extend=Yes as described by UAX + // #44 of the Unicode Standard and C is not immediately preceded in S by a + // character P appended to E without translation to an escape sequence, + if (!__last_escaped || __extended_grapheme_custer_property_boundary::__get_property(__value) != + __extended_grapheme_custer_property_boundary::__property::__Extend) + return false; + + __formatter::__write_well_formed_escaped_code_unit(__str, __value); + return true; +} + +template +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr char32_t __to_char32(_CharT __value) { + return static_cast>(__value); +} + +enum class __escape_quotation_mark { __apostrophe, __double_quote }; + +// [format.string.escaped]/2 +template +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool __is_escaped_sequence_written( + basic_string<_CharT>& __str, char32_t __value, bool __last_escaped, __escape_quotation_mark __mark) { + // 2.2.1.1 - Mapped character in [tab:format.escape.sequences] + switch (__value) { + case _CharT('\t'): + __str += _LIBCPP_STATICALLY_WIDEN(_CharT, "\\t"); + return true; + case _CharT('\n'): + __str += _LIBCPP_STATICALLY_WIDEN(_CharT, "\\n"); + return true; + case _CharT('\r'): + __str += _LIBCPP_STATICALLY_WIDEN(_CharT, "\\r"); + return true; + case _CharT('\''): + if (__mark == __escape_quotation_mark::__apostrophe) + __str += _LIBCPP_STATICALLY_WIDEN(_CharT, R"(\')"); + else + __str += __value; + return true; + case _CharT('"'): + if (__mark == __escape_quotation_mark::__double_quote) + __str += _LIBCPP_STATICALLY_WIDEN(_CharT, R"(\")"); + else + __str += __value; + return true; + case _CharT('\\'): + __str += _LIBCPP_STATICALLY_WIDEN(_CharT, R"(\\)"); + return true; + + // 2.2.1.2 - Space + case _CharT(' '): + __str += __value; + return true; + } + + // 2.2.2 + // Otherwise, if X is a shift sequence, the effect on E and further + // decoding of S is unspecified. + // For now shift sequences are ignored and treated as Unicode. Other parts + // of the format library do the same. It's unknown how ostream treats them. + // TODO FMT determine what to do with shift sequences. + + // 2.2.1.2.1 and 2.2.1.2.2 - Escape + return __formatter::__is_escaped_sequence_written(__str, __last_escaped, __formatter::__to_char32(__value)); +} + +template +_LIBCPP_HIDE_FROM_ABI void +__escape(basic_string<_CharT>& __str, basic_string_view<_CharT> __values, __escape_quotation_mark __mark) { + __unicode::__code_point_view<_CharT> __view{__values.begin(), __values.end()}; + + // When the first code unit has the property Grapheme_Extend=Yes it needs to + // be escaped. This happens when the previous code unit was also escaped. + bool __escape = true; + while (!__view.__at_end()) { + auto __first = __view.__position(); + typename __unicode::__consume_result __result = __view.__consume(); + if (__result.__status == __unicode::__consume_result::__ok) { + __escape = __formatter::__is_escaped_sequence_written(__str, __result.__code_point, __escape, __mark); + if (!__escape) + // 2.2.1.3 - Add the character + ranges::copy(__first, __view.__position(), std::back_insert_iterator(__str)); + } else { + // 2.2.3 sequence of ill-formed code units + ranges::for_each(__first, __view.__position(), [&](_CharT __value) { + __formatter::__write_escape_ill_formed_code_unit(__str, __formatter::__to_char32(__value)); + }); + } + } +} + +template +_LIBCPP_HIDE_FROM_ABI auto +__format_escaped_char(_CharT __value, + output_iterator auto __out_it, + __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) { + basic_string<_CharT> __str; + __str += _CharT('\''); + __formatter::__escape(__str, basic_string_view{std::addressof(__value), 1}, __escape_quotation_mark::__apostrophe); + __str += _CharT('\''); + return __formatter::__write(__str.data(), __str.data() + __str.size(), std::move(__out_it), __specs, __str.size()); +} + +template +_LIBCPP_HIDE_FROM_ABI auto +__format_escaped_string(basic_string_view<_CharT> __values, + output_iterator auto __out_it, + __format_spec::__parsed_specifications<_CharT> __specs) -> decltype(__out_it) { + basic_string<_CharT> __str; + __str += _CharT('"'); + __formatter::__escape(__str, __values, __escape_quotation_mark::__double_quote); + __str += _CharT('"'); + return __formatter::__write_string(basic_string_view{__str}, std::move(__out_it), __specs); +} + +#endif // _LIBCPP_STD_VER >= 23 + +} // namespace __formatter + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___FORMAT_WRITE_ESCAPED_H diff --git a/third_party/libcxx/__functional/binary_function.h b/third_party/libcxx/__functional/binary_function.h index fdedb8b17..ddee3b170 100644 --- a/third_party/libcxx/__functional/binary_function.h +++ b/third_party/libcxx/__functional/binary_function.h @@ -21,20 +21,20 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION) template -struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binary_function -{ - typedef _Arg1 first_argument_type; - typedef _Arg2 second_argument_type; - typedef _Result result_type; +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binary_function { + typedef _Arg1 first_argument_type; + typedef _Arg2 second_argument_type; + typedef _Result result_type; }; #endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION) -template struct __binary_function_keep_layout_base { +template +struct __binary_function_keep_layout_base { #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - using first_argument_type _LIBCPP_DEPRECATED_IN_CXX17 = _Arg1; + using first_argument_type _LIBCPP_DEPRECATED_IN_CXX17 = _Arg1; using second_argument_type _LIBCPP_DEPRECATED_IN_CXX17 = _Arg2; - using result_type _LIBCPP_DEPRECATED_IN_CXX17 = _Result; + using result_type _LIBCPP_DEPRECATED_IN_CXX17 = _Result; #endif }; diff --git a/third_party/libcxx/__functional/binary_negate.h b/third_party/libcxx/__functional/binary_negate.h index 73ecea997..ce52b5ae9 100644 --- a/third_party/libcxx/__functional/binary_negate.h +++ b/third_party/libcxx/__functional/binary_negate.h @@ -25,23 +25,24 @@ template class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 binary_negate : public __binary_function -{ - _Predicate __pred_; -public: - _LIBCPP_INLINE_VISIBILITY explicit _LIBCPP_CONSTEXPR_SINCE_CXX14 - binary_negate(const _Predicate& __pred) : __pred_(__pred) {} + bool> { + _Predicate __pred_; - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - bool operator()(const typename _Predicate::first_argument_type& __x, - const typename _Predicate::second_argument_type& __y) const - {return !__pred_(__x, __y);} +public: + _LIBCPP_HIDE_FROM_ABI explicit _LIBCPP_CONSTEXPR_SINCE_CXX14 binary_negate(const _Predicate& __pred) + : __pred_(__pred) {} + + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()( + const typename _Predicate::first_argument_type& __x, const typename _Predicate::second_argument_type& __y) const { + return !__pred_(__x, __y); + } }; template -_LIBCPP_DEPRECATED_IN_CXX17 inline _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY -binary_negate<_Predicate> -not2(const _Predicate& __pred) {return binary_negate<_Predicate>(__pred);} +_LIBCPP_DEPRECATED_IN_CXX17 inline _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI binary_negate<_Predicate> +not2(const _Predicate& __pred) { + return binary_negate<_Predicate>(__pred); +} #endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS) diff --git a/third_party/libcxx/__functional/bind.h b/third_party/libcxx/__functional/bind.h index b0c9bfe78..b4f46441d 100644 --- a/third_party/libcxx/__functional/bind.h +++ b/third_party/libcxx/__functional/bind.h @@ -13,6 +13,7 @@ #include <__config> #include <__functional/invoke.h> #include <__functional/weak_result_type.h> +#include <__fwd/functional.h> #include <__type_traits/decay.h> #include <__type_traits/is_reference_wrapper.h> #include <__type_traits/is_void.h> @@ -25,34 +26,30 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template -struct is_bind_expression : _If< - _IsSame<_Tp, __remove_cvref_t<_Tp> >::value, - false_type, - is_bind_expression<__remove_cvref_t<_Tp> > -> {}; +template +struct is_bind_expression + : _If< _IsSame<_Tp, __remove_cvref_t<_Tp> >::value, false_type, is_bind_expression<__remove_cvref_t<_Tp> > > {}; #if _LIBCPP_STD_VER >= 17 template inline constexpr bool is_bind_expression_v = is_bind_expression<_Tp>::value; #endif -template -struct is_placeholder : _If< - _IsSame<_Tp, __remove_cvref_t<_Tp> >::value, - integral_constant, - is_placeholder<__remove_cvref_t<_Tp> > -> {}; +template +struct is_placeholder + : _If< _IsSame<_Tp, __remove_cvref_t<_Tp> >::value, + integral_constant, + is_placeholder<__remove_cvref_t<_Tp> > > {}; #if _LIBCPP_STD_VER >= 17 template inline constexpr int is_placeholder_v = is_placeholder<_Tp>::value; #endif -namespace placeholders -{ +namespace placeholders { -template struct __ph {}; +template +struct __ph {}; // C++17 recommends that we implement placeholders as `inline constexpr`, but allows // implementing them as `extern `. Libc++ implements them as @@ -62,321 +59,234 @@ template struct __ph {}; // // In practice, since placeholders are empty, `extern const` is almost impossible // to distinguish from `inline constexpr` from a usage stand point. -_LIBCPP_FUNC_VIS extern const __ph<1> _1; -_LIBCPP_FUNC_VIS extern const __ph<2> _2; -_LIBCPP_FUNC_VIS extern const __ph<3> _3; -_LIBCPP_FUNC_VIS extern const __ph<4> _4; -_LIBCPP_FUNC_VIS extern const __ph<5> _5; -_LIBCPP_FUNC_VIS extern const __ph<6> _6; -_LIBCPP_FUNC_VIS extern const __ph<7> _7; -_LIBCPP_FUNC_VIS extern const __ph<8> _8; -_LIBCPP_FUNC_VIS extern const __ph<9> _9; -_LIBCPP_FUNC_VIS extern const __ph<10> _10; +_LIBCPP_EXPORTED_FROM_ABI extern const __ph<1> _1; +_LIBCPP_EXPORTED_FROM_ABI extern const __ph<2> _2; +_LIBCPP_EXPORTED_FROM_ABI extern const __ph<3> _3; +_LIBCPP_EXPORTED_FROM_ABI extern const __ph<4> _4; +_LIBCPP_EXPORTED_FROM_ABI extern const __ph<5> _5; +_LIBCPP_EXPORTED_FROM_ABI extern const __ph<6> _6; +_LIBCPP_EXPORTED_FROM_ABI extern const __ph<7> _7; +_LIBCPP_EXPORTED_FROM_ABI extern const __ph<8> _8; +_LIBCPP_EXPORTED_FROM_ABI extern const __ph<9> _9; +_LIBCPP_EXPORTED_FROM_ABI extern const __ph<10> _10; } // namespace placeholders -template -struct is_placeholder > - : public integral_constant {}; - +template +struct is_placeholder > : public integral_constant {}; #ifndef _LIBCPP_CXX03_LANG template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -_Tp& -__mu(reference_wrapper<_Tp> __t, _Uj&) -{ - return __t.get(); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& __mu(reference_wrapper<_Tp> __t, _Uj&) { + return __t.get(); } -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -typename __invoke_of<_Ti&, _Uj...>::type -__mu_expand(_Ti& __ti, tuple<_Uj...>& __uj, __tuple_indices<_Indx...>) -{ - return __ti(_VSTD::forward<_Uj>(_VSTD::get<_Indx>(__uj))...); +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __invoke_of<_Ti&, _Uj...>::type +__mu_expand(_Ti& __ti, tuple<_Uj...>& __uj, __tuple_indices<_Indx...>) { + return __ti(std::forward<_Uj>(std::get<_Indx>(__uj))...); } -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -typename __enable_if_t -< - is_bind_expression<_Ti>::value, - __invoke_of<_Ti&, _Uj...> ->::type -__mu(_Ti& __ti, tuple<_Uj...>& __uj) -{ - typedef typename __make_tuple_indices::type __indices; - return _VSTD::__mu_expand(__ti, __uj, __indices()); +template ::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __invoke_of<_Ti&, _Uj...>::type +__mu(_Ti& __ti, tuple<_Uj...>& __uj) { + typedef typename __make_tuple_indices::type __indices; + return std::__mu_expand(__ti, __uj, __indices()); } -template +template struct __mu_return2 {}; template -struct __mu_return2 -{ - typedef typename tuple_element::value - 1, _Uj>::type type; +struct __mu_return2 { + typedef typename tuple_element::value - 1, _Uj>::type type; }; -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -typename enable_if -< - 0 < is_placeholder<_Ti>::value, - typename __mu_return2<0 < is_placeholder<_Ti>::value, _Ti, _Uj>::type ->::type -__mu(_Ti&, _Uj& __uj) -{ - const size_t __indx = is_placeholder<_Ti>::value - 1; - return _VSTD::forward::type>(_VSTD::get<__indx>(__uj)); +template ::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 +typename __mu_return2<0 < is_placeholder<_Ti>::value, _Ti, _Uj>::type +__mu(_Ti&, _Uj& __uj) { + const size_t __indx = is_placeholder<_Ti>::value - 1; + return std::forward::type>(std::get<__indx>(__uj)); } -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -typename enable_if -< - !is_bind_expression<_Ti>::value && - is_placeholder<_Ti>::value == 0 && - !__is_reference_wrapper<_Ti>::value, - _Ti& ->::type -__mu(_Ti& __ti, _Uj&) -{ - return __ti; +template ::value && is_placeholder<_Ti>::value == 0 && + !__is_reference_wrapper<_Ti>::value, + int> = 0> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Ti& __mu(_Ti& __ti, _Uj&) { + return __ti; } -template +template struct __mu_return_impl; -template -struct __mu_return_invokable // false +template +struct __mu_return_invokable // false { - typedef __nat type; + typedef __nat type; }; -template -struct __mu_return_invokable -{ - typedef typename __invoke_of<_Ti&, _Uj...>::type type; +template +struct __mu_return_invokable { + typedef typename __invoke_of<_Ti&, _Uj...>::type type; }; -template +template struct __mu_return_impl<_Ti, false, true, false, tuple<_Uj...> > - : public __mu_return_invokable<__invokable<_Ti&, _Uj...>::value, _Ti, _Uj...> -{ + : public __mu_return_invokable<__invokable<_Ti&, _Uj...>::value, _Ti, _Uj...> {}; + +template +struct __mu_return_impl<_Ti, false, false, true, _TupleUj> { + typedef typename tuple_element::value - 1, _TupleUj>::type&& type; }; template -struct __mu_return_impl<_Ti, false, false, true, _TupleUj> -{ - typedef typename tuple_element::value - 1, - _TupleUj>::type&& type; +struct __mu_return_impl<_Ti, true, false, false, _TupleUj> { + typedef typename _Ti::type& type; }; template -struct __mu_return_impl<_Ti, true, false, false, _TupleUj> -{ - typedef typename _Ti::type& type; -}; - -template -struct __mu_return_impl<_Ti, false, false, false, _TupleUj> -{ - typedef _Ti& type; +struct __mu_return_impl<_Ti, false, false, false, _TupleUj> { + typedef _Ti& type; }; template struct __mu_return - : public __mu_return_impl<_Ti, - __is_reference_wrapper<_Ti>::value, - is_bind_expression<_Ti>::value, - 0 < is_placeholder<_Ti>::value && - is_placeholder<_Ti>::value <= tuple_size<_TupleUj>::value, - _TupleUj> -{ -}; + : public __mu_return_impl< + _Ti, + __is_reference_wrapper<_Ti>::value, + is_bind_expression<_Ti>::value, + 0 < is_placeholder<_Ti>::value && is_placeholder<_Ti>::value <= tuple_size<_TupleUj>::value, + _TupleUj> {}; template -struct __is_valid_bind_return -{ - static const bool value = false; +struct __is_valid_bind_return { + static const bool value = false; }; -template -struct __is_valid_bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj> -{ - static const bool value = __invokable<_Fp, - typename __mu_return<_BoundArgs, _TupleUj>::type...>::value; +template +struct __is_valid_bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj> { + static const bool value = __invokable<_Fp, typename __mu_return<_BoundArgs, _TupleUj>::type...>::value; }; -template -struct __is_valid_bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj> -{ - static const bool value = __invokable<_Fp, - typename __mu_return::type...>::value; +template +struct __is_valid_bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj> { + static const bool value = __invokable<_Fp, typename __mu_return::type...>::value; }; -template ::value> +template ::value> struct __bind_return; -template -struct __bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj, true> -{ - typedef typename __invoke_of - < - _Fp&, - typename __mu_return - < - _BoundArgs, - _TupleUj - >::type... - >::type type; +template +struct __bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj, true> { + typedef typename __invoke_of< _Fp&, typename __mu_return< _BoundArgs, _TupleUj >::type... >::type type; }; -template -struct __bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj, true> -{ - typedef typename __invoke_of - < - _Fp&, - typename __mu_return - < - const _BoundArgs, - _TupleUj - >::type... - >::type type; +template +struct __bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj, true> { + typedef typename __invoke_of< _Fp&, typename __mu_return< const _BoundArgs, _TupleUj >::type... >::type type; }; -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -typename __bind_return<_Fp, _BoundArgs, _Args>::type -__apply_functor(_Fp& __f, _BoundArgs& __bound_args, __tuple_indices<_Indx...>, - _Args&& __args) -{ - return _VSTD::__invoke(__f, _VSTD::__mu(_VSTD::get<_Indx>(__bound_args), __args)...); +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __bind_return<_Fp, _BoundArgs, _Args>::type +__apply_functor(_Fp& __f, _BoundArgs& __bound_args, __tuple_indices<_Indx...>, _Args&& __args) { + return std::__invoke(__f, std::__mu(std::get<_Indx>(__bound_args), __args)...); } -template -class __bind : public __weak_result_type<__decay_t<_Fp> > -{ +template +class __bind : public __weak_result_type<__decay_t<_Fp> > { protected: - using _Fd = __decay_t<_Fp>; - typedef tuple<__decay_t<_BoundArgs>...> _Td; + using _Fd = __decay_t<_Fp>; + typedef tuple<__decay_t<_BoundArgs>...> _Td; + private: - _Fd __f_; - _Td __bound_args_; + _Fd __f_; + _Td __bound_args_; + + typedef typename __make_tuple_indices::type __indices; - typedef typename __make_tuple_indices::type __indices; public: - template ::value && - !is_same<__libcpp_remove_reference_t<_Gp>, - __bind>::value - >::type> - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 - explicit __bind(_Gp&& __f, _BA&& ...__bound_args) - : __f_(_VSTD::forward<_Gp>(__f)), - __bound_args_(_VSTD::forward<_BA>(__bound_args)...) {} + template < + class _Gp, + class... _BA, + __enable_if_t::value && !is_same<__libcpp_remove_reference_t<_Gp>, __bind>::value, + int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __bind(_Gp&& __f, _BA&&... __bound_args) + : __f_(std::forward<_Gp>(__f)), __bound_args_(std::forward<_BA>(__bound_args)...) {} - template - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 - typename __bind_return<_Fd, _Td, tuple<_Args&&...> >::type - operator()(_Args&& ...__args) - { - return _VSTD::__apply_functor(__f_, __bound_args_, __indices(), - tuple<_Args&&...>(_VSTD::forward<_Args>(__args)...)); - } + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __bind_return<_Fd, _Td, tuple<_Args&&...> >::type + operator()(_Args&&... __args) { + return std::__apply_functor(__f_, __bound_args_, __indices(), tuple<_Args&&...>(std::forward<_Args>(__args)...)); + } - template - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 - typename __bind_return >::type - operator()(_Args&& ...__args) const - { - return _VSTD::__apply_functor(__f_, __bound_args_, __indices(), - tuple<_Args&&...>(_VSTD::forward<_Args>(__args)...)); - } + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 + typename __bind_return >::type + operator()(_Args&&... __args) const { + return std::__apply_functor(__f_, __bound_args_, __indices(), tuple<_Args&&...>(std::forward<_Args>(__args)...)); + } }; -template +template struct is_bind_expression<__bind<_Fp, _BoundArgs...> > : public true_type {}; -template -class __bind_r - : public __bind<_Fp, _BoundArgs...> -{ - typedef __bind<_Fp, _BoundArgs...> base; - typedef typename base::_Fd _Fd; - typedef typename base::_Td _Td; +template +class __bind_r : public __bind<_Fp, _BoundArgs...> { + typedef __bind<_Fp, _BoundArgs...> base; + typedef typename base::_Fd _Fd; + typedef typename base::_Td _Td; + public: - typedef _Rp result_type; + typedef _Rp result_type; + template < + class _Gp, + class... _BA, + __enable_if_t::value && !is_same<__libcpp_remove_reference_t<_Gp>, __bind_r>::value, + int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit __bind_r(_Gp&& __f, _BA&&... __bound_args) + : base(std::forward<_Gp>(__f), std::forward<_BA>(__bound_args)...) {} - template ::value && - !is_same<__libcpp_remove_reference_t<_Gp>, - __bind_r>::value - >::type> - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 - explicit __bind_r(_Gp&& __f, _BA&& ...__bound_args) - : base(_VSTD::forward<_Gp>(__f), - _VSTD::forward<_BA>(__bound_args)...) {} + template < + class... _Args, + __enable_if_t >::type, result_type>::value || + is_void<_Rp>::value, + int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 result_type operator()(_Args&&... __args) { + typedef __invoke_void_return_wrapper<_Rp> _Invoker; + return _Invoker::__call(static_cast(*this), std::forward<_Args>(__args)...); + } - template - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 - typename enable_if - < - is_convertible >::type, - result_type>::value || is_void<_Rp>::value, - result_type - >::type - operator()(_Args&& ...__args) - { - typedef __invoke_void_return_wrapper<_Rp> _Invoker; - return _Invoker::__call(static_cast(*this), _VSTD::forward<_Args>(__args)...); - } - - template - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 - typename enable_if - < - is_convertible >::type, - result_type>::value || is_void<_Rp>::value, - result_type - >::type - operator()(_Args&& ...__args) const - { - typedef __invoke_void_return_wrapper<_Rp> _Invoker; - return _Invoker::__call(static_cast(*this), _VSTD::forward<_Args>(__args)...); - } + template >::type, + result_type>::value || + is_void<_Rp>::value, + int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 result_type operator()(_Args&&... __args) const { + typedef __invoke_void_return_wrapper<_Rp> _Invoker; + return _Invoker::__call(static_cast(*this), std::forward<_Args>(__args)...); + } }; -template +template struct is_bind_expression<__bind_r<_Rp, _Fp, _BoundArgs...> > : public true_type {}; -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -__bind<_Fp, _BoundArgs...> -bind(_Fp&& __f, _BoundArgs&&... __bound_args) -{ - typedef __bind<_Fp, _BoundArgs...> type; - return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...); +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bind<_Fp, _BoundArgs...> +bind(_Fp&& __f, _BoundArgs&&... __bound_args) { + typedef __bind<_Fp, _BoundArgs...> type; + return type(std::forward<_Fp>(__f), std::forward<_BoundArgs>(__bound_args)...); } -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -__bind_r<_Rp, _Fp, _BoundArgs...> -bind(_Fp&& __f, _BoundArgs&&... __bound_args) -{ - typedef __bind_r<_Rp, _Fp, _BoundArgs...> type; - return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...); +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __bind_r<_Rp, _Fp, _BoundArgs...> +bind(_Fp&& __f, _BoundArgs&&... __bound_args) { + typedef __bind_r<_Rp, _Fp, _BoundArgs...> type; + return type(std::forward<_Fp>(__f), std::forward<_BoundArgs>(__bound_args)...); } #endif // _LIBCPP_CXX03_LANG diff --git a/third_party/libcxx/__functional/bind_back.h b/third_party/libcxx/__functional/bind_back.h index 71dc63c86..e44768d22 100644 --- a/third_party/libcxx/__functional/bind_back.h +++ b/third_party/libcxx/__functional/bind_back.h @@ -29,33 +29,52 @@ _LIBCPP_BEGIN_NAMESPACE_STD template > struct __bind_back_op; -template +template struct __bind_back_op<_NBound, index_sequence<_Ip...>> { - template - _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Fn&& __f, _BoundArgs&& __bound_args, _Args&&... __args) const - noexcept(noexcept(_VSTD::invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)..., _VSTD::get<_Ip>(_VSTD::forward<_BoundArgs>(__bound_args))...))) - -> decltype( _VSTD::invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)..., _VSTD::get<_Ip>(_VSTD::forward<_BoundArgs>(__bound_args))...)) - { return _VSTD::invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)..., _VSTD::get<_Ip>(_VSTD::forward<_BoundArgs>(__bound_args))...); } + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Fn&& __f, _BoundArgs&& __bound_args, _Args&&... __args) const + noexcept(noexcept(std::invoke(std::forward<_Fn>(__f), + std::forward<_Args>(__args)..., + std::get<_Ip>(std::forward<_BoundArgs>(__bound_args))...))) + -> decltype(std::invoke(std::forward<_Fn>(__f), + std::forward<_Args>(__args)..., + std::get<_Ip>(std::forward<_BoundArgs>(__bound_args))...)) { + return std::invoke(std::forward<_Fn>(__f), + std::forward<_Args>(__args)..., + std::get<_Ip>(std::forward<_BoundArgs>(__bound_args))...); + } }; template struct __bind_back_t : __perfect_forward<__bind_back_op>, _Fn, _BoundArgs> { - using __perfect_forward<__bind_back_op>, _Fn, _BoundArgs>::__perfect_forward; + using __perfect_forward<__bind_back_op>, _Fn, _BoundArgs>::__perfect_forward; }; -template , _Fn>, - is_move_constructible>, - is_constructible, _Args>..., - is_move_constructible>... - >::value ->> -_LIBCPP_HIDE_FROM_ABI -constexpr auto __bind_back(_Fn&& __f, _Args&&... __args) - noexcept(noexcept(__bind_back_t, tuple...>>(_VSTD::forward<_Fn>(__f), _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)))) - -> decltype( __bind_back_t, tuple...>>(_VSTD::forward<_Fn>(__f), _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...))) - { return __bind_back_t, tuple...>>(_VSTD::forward<_Fn>(__f), _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); } +template + requires is_constructible_v, _Fn> && is_move_constructible_v> && + (is_constructible_v, _Args> && ...) && (is_move_constructible_v> && ...) +_LIBCPP_HIDE_FROM_ABI constexpr auto __bind_back(_Fn&& __f, _Args&&... __args) noexcept( + noexcept(__bind_back_t, tuple...>>( + std::forward<_Fn>(__f), std::forward_as_tuple(std::forward<_Args>(__args)...)))) + -> decltype(__bind_back_t, tuple...>>( + std::forward<_Fn>(__f), std::forward_as_tuple(std::forward<_Args>(__args)...))) { + return __bind_back_t, tuple...>>( + std::forward<_Fn>(__f), std::forward_as_tuple(std::forward<_Args>(__args)...)); +} + +# if _LIBCPP_STD_VER >= 23 +template +_LIBCPP_HIDE_FROM_ABI constexpr auto bind_back(_Fn&& __f, _Args&&... __args) { + static_assert(is_constructible_v, _Fn>, "bind_back requires decay_t to be constructible from F"); + static_assert(is_move_constructible_v>, "bind_back requires decay_t to be move constructible"); + static_assert((is_constructible_v, _Args> && ...), + "bind_back requires all decay_t to be constructible from respective Args"); + static_assert((is_move_constructible_v> && ...), + "bind_back requires all decay_t to be move constructible"); + return __bind_back_t, tuple...>>( + std::forward<_Fn>(__f), std::forward_as_tuple(std::forward<_Args>(__args)...)); +} +# endif // _LIBCPP_STD_VER >= 23 #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__functional/bind_front.h b/third_party/libcxx/__functional/bind_front.h index 72bb66480..87ef3affe 100644 --- a/third_party/libcxx/__functional/bind_front.h +++ b/third_party/libcxx/__functional/bind_front.h @@ -17,7 +17,6 @@ #include <__type_traits/decay.h> #include <__type_traits/enable_if.h> #include <__type_traits/is_constructible.h> -#include <__type_traits/is_move_constructible.h> #include <__utility/forward.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -29,30 +28,23 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 struct __bind_front_op { - template - _LIBCPP_HIDE_FROM_ABI - constexpr auto operator()(_Args&& ...__args) const - noexcept(noexcept(_VSTD::invoke(_VSTD::forward<_Args>(__args)...))) - -> decltype( _VSTD::invoke(_VSTD::forward<_Args>(__args)...)) - { return _VSTD::invoke(_VSTD::forward<_Args>(__args)...); } + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) const noexcept( + noexcept(std::invoke(std::forward<_Args>(__args)...))) -> decltype(std::invoke(std::forward<_Args>(__args)...)) { + return std::invoke(std::forward<_Args>(__args)...); + } }; -template +template struct __bind_front_t : __perfect_forward<__bind_front_op, _Fn, _BoundArgs...> { - using __perfect_forward<__bind_front_op, _Fn, _BoundArgs...>::__perfect_forward; + using __perfect_forward<__bind_front_op, _Fn, _BoundArgs...>::__perfect_forward; }; -template , _Fn>, - is_move_constructible>, - is_constructible, _Args>..., - is_move_constructible>... - >::value ->> -_LIBCPP_HIDE_FROM_ABI -constexpr auto bind_front(_Fn&& __f, _Args&&... __args) { - return __bind_front_t, decay_t<_Args>...>(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...); +template + requires is_constructible_v, _Fn> && is_move_constructible_v> && + (is_constructible_v, _Args> && ...) && (is_move_constructible_v> && ...) +_LIBCPP_HIDE_FROM_ABI constexpr auto bind_front(_Fn&& __f, _Args&&... __args) { + return __bind_front_t, decay_t<_Args>...>(std::forward<_Fn>(__f), std::forward<_Args>(__args)...); } #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__functional/binder1st.h b/third_party/libcxx/__functional/binder1st.h index dea22c70e..04b51fefa 100644 --- a/third_party/libcxx/__functional/binder1st.h +++ b/third_party/libcxx/__functional/binder1st.h @@ -21,30 +21,31 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) -template +template class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder1st - : public __unary_function -{ + : public __unary_function { protected: - __Operation op; - typename __Operation::first_argument_type value; + _Operation op; + typename _Operation::first_argument_type value; + public: - _LIBCPP_INLINE_VISIBILITY binder1st(const __Operation& __x, - const typename __Operation::first_argument_type __y) - : op(__x), value(__y) {} - _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator() - (typename __Operation::second_argument_type& __x) const - {return op(value, __x);} - _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator() - (const typename __Operation::second_argument_type& __x) const - {return op(value, __x);} + _LIBCPP_HIDE_FROM_ABI binder1st(const _Operation& __x, const typename _Operation::first_argument_type __y) + : op(__x), value(__y) {} + _LIBCPP_HIDE_FROM_ABI typename _Operation::result_type + operator()(typename _Operation::second_argument_type& __x) const { + return op(value, __x); + } + _LIBCPP_HIDE_FROM_ABI typename _Operation::result_type + operator()(const typename _Operation::second_argument_type& __x) const { + return op(value, __x); + } }; -template -_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY -binder1st<__Operation> -bind1st(const __Operation& __op, const _Tp& __x) - {return binder1st<__Operation>(__op, __x);} +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI binder1st<_Operation> +bind1st(const _Operation& __op, const _Tp& __x) { + return binder1st<_Operation>(__op, __x); +} #endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) diff --git a/third_party/libcxx/__functional/binder2nd.h b/third_party/libcxx/__functional/binder2nd.h index c98a146b6..9d22e4430 100644 --- a/third_party/libcxx/__functional/binder2nd.h +++ b/third_party/libcxx/__functional/binder2nd.h @@ -21,30 +21,31 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) -template +template class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 binder2nd - : public __unary_function -{ + : public __unary_function { protected: - __Operation op; - typename __Operation::second_argument_type value; + _Operation op; + typename _Operation::second_argument_type value; + public: - _LIBCPP_INLINE_VISIBILITY - binder2nd(const __Operation& __x, const typename __Operation::second_argument_type __y) - : op(__x), value(__y) {} - _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator() - ( typename __Operation::first_argument_type& __x) const - {return op(__x, value);} - _LIBCPP_INLINE_VISIBILITY typename __Operation::result_type operator() - (const typename __Operation::first_argument_type& __x) const - {return op(__x, value);} + _LIBCPP_HIDE_FROM_ABI binder2nd(const _Operation& __x, const typename _Operation::second_argument_type __y) + : op(__x), value(__y) {} + _LIBCPP_HIDE_FROM_ABI typename _Operation::result_type + operator()(typename _Operation::first_argument_type& __x) const { + return op(__x, value); + } + _LIBCPP_HIDE_FROM_ABI typename _Operation::result_type + operator()(const typename _Operation::first_argument_type& __x) const { + return op(__x, value); + } }; -template -_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY -binder2nd<__Operation> -bind2nd(const __Operation& __op, const _Tp& __x) - {return binder2nd<__Operation>(__op, __x);} +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI binder2nd<_Operation> +bind2nd(const _Operation& __op, const _Tp& __x) { + return binder2nd<_Operation>(__op, __x); +} #endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) diff --git a/third_party/libcxx/__functional/boyer_moore_searcher.h b/third_party/libcxx/__functional/boyer_moore_searcher.h index d9d662714..648b60c50 100644 --- a/third_party/libcxx/__functional/boyer_moore_searcher.h +++ b/third_party/libcxx/__functional/boyer_moore_searcher.h @@ -9,6 +9,10 @@ #ifndef _LIBCPP___FUNCTIONAL_BOYER_MOORE_SEARCHER_H #define _LIBCPP___FUNCTIONAL_BOYER_MOORE_SEARCHER_H +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + #include <__algorithm/fill_n.h> #include <__config> #include <__functional/hash.h> @@ -25,39 +29,29 @@ #if _LIBCPP_STD_VER >= 17 _LIBCPP_PUSH_MACROS -#include <__undef_macros> +# include <__undef_macros> _LIBCPP_BEGIN_NAMESPACE_STD -template +template class _BMSkipTable; // General case for BM data searching; use a map -template +template class _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, false> { private: using value_type = _Value; - using key_type = _Key; + using key_type = _Key; const value_type __default_value_; unordered_map<_Key, _Value, _Hash, _BinaryPredicate> __table_; public: - _LIBCPP_HIDE_FROM_ABI - explicit _BMSkipTable(size_t __sz, value_type __default_value, _Hash __hash, _BinaryPredicate __pred) - : __default_value_(__default_value), - __table_(__sz, __hash, __pred) {} + _LIBCPP_HIDE_FROM_ABI explicit _BMSkipTable( + size_t __sz, value_type __default_value, _Hash __hash, _BinaryPredicate __pred) + : __default_value_(__default_value), __table_(__sz, __hash, __pred) {} - _LIBCPP_HIDE_FROM_ABI void insert(const key_type& __key, value_type __val) { - __table_[__key] = __val; - } + _LIBCPP_HIDE_FROM_ABI void insert(const key_type& __key, value_type __val) { __table_[__key] = __val; } _LIBCPP_HIDE_FROM_ABI value_type operator[](const key_type& __key) const { auto __it = __table_.find(__key); @@ -66,14 +60,11 @@ public: }; // Special case small numeric values; use an array -template +template class _BMSkipTable<_Key, _Value, _Hash, _BinaryPredicate, true> { private: using value_type = _Value; - using key_type = _Key; + using key_type = _Key; using unsigned_key_type = make_unsigned_t; std::array __table_; @@ -94,34 +85,33 @@ public: }; template ::value_type>, + class _Hash = hash::value_type>, class _BinaryPredicate = equal_to<>> class _LIBCPP_TEMPLATE_VIS boyer_moore_searcher { private: using difference_type = typename std::iterator_traits<_RandomAccessIterator1>::difference_type; - using value_type = typename std::iterator_traits<_RandomAccessIterator1>::value_type; - using __skip_table_type = _BMSkipTable - && sizeof(value_type) == 1 - && is_same_v<_Hash, hash> - && is_same_v<_BinaryPredicate, equal_to<>>>; + using value_type = typename std::iterator_traits<_RandomAccessIterator1>::value_type; + using __skip_table_type = + _BMSkipTable && sizeof(value_type) == 1 && is_same_v<_Hash, hash> && + is_same_v<_BinaryPredicate, equal_to<>>>; public: - _LIBCPP_HIDE_FROM_ABI - boyer_moore_searcher(_RandomAccessIterator1 __first, - _RandomAccessIterator1 __last, - _Hash __hash = _Hash(), - _BinaryPredicate __pred = _BinaryPredicate()) - : __first_(__first), - __last_(__last), - __pred_(__pred), - __pattern_length_(__last - __first), - __skip_table_(std::make_shared<__skip_table_type>(__pattern_length_, -1, __hash, __pred_)), - __suffix_(std::__allocate_shared_unbounded_array( - allocator(), __pattern_length_ + 1)) { + _LIBCPP_HIDE_FROM_ABI boyer_moore_searcher( + _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _Hash __hash = _Hash(), + _BinaryPredicate __pred = _BinaryPredicate()) + : __first_(__first), + __last_(__last), + __pred_(__pred), + __pattern_length_(__last - __first), + __skip_table_(std::make_shared<__skip_table_type>(__pattern_length_, -1, __hash, __pred_)), + __suffix_(std::__allocate_shared_unbounded_array( + allocator(), __pattern_length_ + 1)) { difference_type __i = 0; while (__first != __last) { __skip_table_->insert(*__first, __i); @@ -158,8 +148,8 @@ private: template _LIBCPP_HIDE_FROM_ABI pair<_RandomAccessIterator2, _RandomAccessIterator2> __search(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const { - _RandomAccessIterator2 __current = __f; - const _RandomAccessIterator2 __last = __l - __pattern_length_; + _RandomAccessIterator2 __current = __f; + const _RandomAccessIterator2 __last = __l - __pattern_length_; const __skip_table_type& __skip_table = *__skip_table_; while (__current <= __last) { @@ -186,7 +176,7 @@ private: const size_t __count = __last - __first; __prefix[0] = 0; - size_t __k = 0; + size_t __k = 0; for (size_t __i = 1; __i != __count; ++__i) { while (__k > 0 && !__pred(__first[__k], __first[__i])) @@ -215,7 +205,7 @@ private: __compute_bm_prefix(_ReverseIter(__last), _ReverseIter(__first), __pred, __scratch); for (size_t __i = 0; __i != __count; ++__i) { - const size_t __j = __count - __scratch[__i]; + const size_t __j = __count - __scratch[__i]; const difference_type __k = __i - __scratch[__i] + 1; if (__suffix_[__j] > __k) @@ -226,31 +216,31 @@ private: _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(boyer_moore_searcher); template ::value_type>, + class _Hash = hash::value_type>, class _BinaryPredicate = equal_to<>> class _LIBCPP_TEMPLATE_VIS boyer_moore_horspool_searcher { private: using difference_type = typename iterator_traits<_RandomAccessIterator1>::difference_type; - using value_type = typename iterator_traits<_RandomAccessIterator1>::value_type; - using __skip_table_type = _BMSkipTable - && sizeof(value_type) == 1 - && is_same_v<_Hash, hash> - && is_same_v<_BinaryPredicate, equal_to<>>>; + using value_type = typename iterator_traits<_RandomAccessIterator1>::value_type; + using __skip_table_type = + _BMSkipTable && sizeof(value_type) == 1 && is_same_v<_Hash, hash> && + is_same_v<_BinaryPredicate, equal_to<>>>; + public: - _LIBCPP_HIDE_FROM_ABI - boyer_moore_horspool_searcher(_RandomAccessIterator1 __first, - _RandomAccessIterator1 __last, - _Hash __hash = _Hash(), - _BinaryPredicate __pred = _BinaryPredicate()) - : __first_(__first), - __last_(__last), - __pred_(__pred), - __pattern_length_(__last - __first), - __skip_table_(std::make_shared<__skip_table_type>(__pattern_length_, __pattern_length_, __hash, __pred_)) { + _LIBCPP_HIDE_FROM_ABI boyer_moore_horspool_searcher( + _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _Hash __hash = _Hash(), + _BinaryPredicate __pred = _BinaryPredicate()) + : __first_(__first), + __last_(__last), + __pred_(__pred), + __pattern_length_(__last - __first), + __skip_table_(std::make_shared<__skip_table_type>(__pattern_length_, __pattern_length_, __hash, __pred_)) { if (__first == __last) return; --__last; @@ -289,8 +279,8 @@ private: template _LIBCPP_HIDE_FROM_ABI pair<_RandomAccessIterator2, _RandomAccessIterator2> __search(_RandomAccessIterator2 __f, _RandomAccessIterator2 __l) const { - _RandomAccessIterator2 __current = __f; - const _RandomAccessIterator2 __last = __l - __pattern_length_; + _RandomAccessIterator2 __current = __f; + const _RandomAccessIterator2 __last = __l - __pattern_length_; const __skip_table_type& __skip_table = *__skip_table_; while (__current <= __last) { diff --git a/third_party/libcxx/__functional/compose.h b/third_party/libcxx/__functional/compose.h index 80fcd7076..4b86dd37c 100644 --- a/third_party/libcxx/__functional/compose.h +++ b/third_party/libcxx/__functional/compose.h @@ -25,25 +25,26 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 struct __compose_op { - template - _LIBCPP_HIDE_FROM_ABI - constexpr auto operator()(_Fn1&& __f1, _Fn2&& __f2, _Args&&... __args) const - noexcept(noexcept(_VSTD::invoke(_VSTD::forward<_Fn1>(__f1), _VSTD::invoke(_VSTD::forward<_Fn2>(__f2), _VSTD::forward<_Args>(__args)...)))) - -> decltype( _VSTD::invoke(_VSTD::forward<_Fn1>(__f1), _VSTD::invoke(_VSTD::forward<_Fn2>(__f2), _VSTD::forward<_Args>(__args)...))) - { return _VSTD::invoke(_VSTD::forward<_Fn1>(__f1), _VSTD::invoke(_VSTD::forward<_Fn2>(__f2), _VSTD::forward<_Args>(__args)...)); } + template + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Fn1&& __f1, _Fn2&& __f2, _Args&&... __args) const noexcept(noexcept( + std::invoke(std::forward<_Fn1>(__f1), std::invoke(std::forward<_Fn2>(__f2), std::forward<_Args>(__args)...)))) + -> decltype(std::invoke(std::forward<_Fn1>(__f1), + std::invoke(std::forward<_Fn2>(__f2), std::forward<_Args>(__args)...))) { + return std::invoke(std::forward<_Fn1>(__f1), std::invoke(std::forward<_Fn2>(__f2), std::forward<_Args>(__args)...)); + } }; template struct __compose_t : __perfect_forward<__compose_op, _Fn1, _Fn2> { - using __perfect_forward<__compose_op, _Fn1, _Fn2>::__perfect_forward; + using __perfect_forward<__compose_op, _Fn1, _Fn2>::__perfect_forward; }; template -_LIBCPP_HIDE_FROM_ABI -constexpr auto __compose(_Fn1&& __f1, _Fn2&& __f2) - noexcept(noexcept(__compose_t, decay_t<_Fn2>>(_VSTD::forward<_Fn1>(__f1), _VSTD::forward<_Fn2>(__f2)))) - -> decltype( __compose_t, decay_t<_Fn2>>(_VSTD::forward<_Fn1>(__f1), _VSTD::forward<_Fn2>(__f2))) - { return __compose_t, decay_t<_Fn2>>(_VSTD::forward<_Fn1>(__f1), _VSTD::forward<_Fn2>(__f2)); } +_LIBCPP_HIDE_FROM_ABI constexpr auto __compose(_Fn1&& __f1, _Fn2&& __f2) noexcept( + noexcept(__compose_t, decay_t<_Fn2>>(std::forward<_Fn1>(__f1), std::forward<_Fn2>(__f2)))) + -> decltype(__compose_t, decay_t<_Fn2>>(std::forward<_Fn1>(__f1), std::forward<_Fn2>(__f2))) { + return __compose_t, decay_t<_Fn2>>(std::forward<_Fn1>(__f1), std::forward<_Fn2>(__f2)); +} #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__functional/default_searcher.h b/third_party/libcxx/__functional/default_searcher.h index 222b4c66e..db89d1075 100644 --- a/third_party/libcxx/__functional/default_searcher.h +++ b/third_party/libcxx/__functional/default_searcher.h @@ -26,27 +26,24 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 17 // default searcher -template> +template > class _LIBCPP_TEMPLATE_VIS default_searcher { public: - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 - default_searcher(_ForwardIterator __f, _ForwardIterator __l, - _BinaryPredicate __p = _BinaryPredicate()) - : __first_(__f), __last_(__l), __pred_(__p) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 + default_searcher(_ForwardIterator __f, _ForwardIterator __l, _BinaryPredicate __p = _BinaryPredicate()) + : __first_(__f), __last_(__l), __pred_(__p) {} - template - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 - pair<_ForwardIterator2, _ForwardIterator2> - operator () (_ForwardIterator2 __f, _ForwardIterator2 __l) const - { - auto __proj = __identity(); - return std::__search_impl(__f, __l, __first_, __last_, __pred_, __proj, __proj); - } + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator2, _ForwardIterator2> + operator()(_ForwardIterator2 __f, _ForwardIterator2 __l) const { + auto __proj = __identity(); + return std::__search_impl(__f, __l, __first_, __last_, __pred_, __proj, __proj); + } private: - _ForwardIterator __first_; - _ForwardIterator __last_; - _BinaryPredicate __pred_; + _ForwardIterator __first_; + _ForwardIterator __last_; + _BinaryPredicate __pred_; }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(default_searcher); diff --git a/third_party/libcxx/__functional/function.h b/third_party/libcxx/__functional/function.h index f3abba453..c7b98035e 100644 --- a/third_party/libcxx/__functional/function.h +++ b/third_party/libcxx/__functional/function.h @@ -28,7 +28,7 @@ #include <__type_traits/decay.h> #include <__type_traits/is_core_convertible.h> #include <__type_traits/is_scalar.h> -#include <__type_traits/is_trivially_copy_constructible.h> +#include <__type_traits/is_trivially_constructible.h> #include <__type_traits/is_trivially_destructible.h> #include <__type_traits/is_void.h> #include <__type_traits/strip_signature.h> @@ -45,6 +45,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #ifndef _LIBCPP_CXX03_LANG _LIBCPP_BEGIN_NAMESPACE_STD @@ -52,84 +55,80 @@ _LIBCPP_BEGIN_NAMESPACE_STD // bad_function_call _LIBCPP_DIAGNOSTIC_PUSH +# if !_LIBCPP_AVAILABILITY_HAS_BAD_FUNCTION_CALL_KEY_FUNCTION _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables") -class _LIBCPP_EXCEPTION_ABI bad_function_call - : public exception -{ +# endif +class _LIBCPP_EXPORTED_FROM_ABI bad_function_call : public exception { public: + _LIBCPP_HIDE_FROM_ABI bad_function_call() _NOEXCEPT = default; + _LIBCPP_HIDE_FROM_ABI bad_function_call(const bad_function_call&) _NOEXCEPT = default; + _LIBCPP_HIDE_FROM_ABI bad_function_call& operator=(const bad_function_call&) _NOEXCEPT = default; // Note that when a key function is not used, every translation unit that uses // bad_function_call will end up containing a weak definition of the vtable and // typeinfo. -#ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION - ~bad_function_call() _NOEXCEPT override; -#else - _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~bad_function_call() _NOEXCEPT override {} -#endif +# if _LIBCPP_AVAILABILITY_HAS_BAD_FUNCTION_CALL_KEY_FUNCTION + ~bad_function_call() _NOEXCEPT override; +# else + _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~bad_function_call() _NOEXCEPT override {} +# endif -#ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE - const char* what() const _NOEXCEPT override; -#endif +# ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE + const char* what() const _NOEXCEPT override; +# endif }; _LIBCPP_DIAGNOSTIC_POP -_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY -void __throw_bad_function_call() -{ -#ifndef _LIBCPP_HAS_NO_EXCEPTIONS - throw bad_function_call(); -#else - _LIBCPP_VERBOSE_ABORT("bad_function_call was thrown in -fno-exceptions mode"); -#endif +_LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void __throw_bad_function_call() { +# ifndef _LIBCPP_HAS_NO_EXCEPTIONS + throw bad_function_call(); +# else + _LIBCPP_VERBOSE_ABORT("bad_function_call was thrown in -fno-exceptions mode"); +# endif } -template class _LIBCPP_TEMPLATE_VIS function; // undefined +template +class _LIBCPP_TEMPLATE_VIS function; // undefined -namespace __function -{ +namespace __function { -template -struct __maybe_derive_from_unary_function -{ -}; +template +struct __maybe_derive_from_unary_function {}; -template -struct __maybe_derive_from_unary_function<_Rp(_A1)> - : public __unary_function<_A1, _Rp> -{ -}; +template +struct __maybe_derive_from_unary_function<_Rp(_A1)> : public __unary_function<_A1, _Rp> {}; -template -struct __maybe_derive_from_binary_function -{ -}; +template +struct __maybe_derive_from_binary_function {}; -template -struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)> - : public __binary_function<_A1, _A2, _Rp> -{ -}; +template +struct __maybe_derive_from_binary_function<_Rp(_A1, _A2)> : public __binary_function<_A1, _A2, _Rp> {}; template -_LIBCPP_INLINE_VISIBILITY -bool __not_null(_Fp const&) { return true; } +_LIBCPP_HIDE_FROM_ABI bool __not_null(_Fp const&) { + return true; +} template -_LIBCPP_INLINE_VISIBILITY -bool __not_null(_Fp* __ptr) { return __ptr; } +_LIBCPP_HIDE_FROM_ABI bool __not_null(_Fp* __ptr) { + return __ptr; +} template -_LIBCPP_INLINE_VISIBILITY -bool __not_null(_Ret _Class::*__ptr) { return __ptr; } +_LIBCPP_HIDE_FROM_ABI bool __not_null(_Ret _Class::*__ptr) { + return __ptr; +} template -_LIBCPP_INLINE_VISIBILITY -bool __not_null(function<_Fp> const& __f) { return !!__f; } +_LIBCPP_HIDE_FROM_ABI bool __not_null(function<_Fp> const& __f) { + return !!__f; +} -#ifdef _LIBCPP_HAS_EXTENSION_BLOCKS -template -_LIBCPP_INLINE_VISIBILITY -bool __not_null(_Rp (^__p)(_Args...)) { return __p; } -#endif +# ifdef _LIBCPP_HAS_EXTENSION_BLOCKS +template +_LIBCPP_HIDE_FROM_ABI bool __not_null(_Rp (^__p)(_Args...)) { + return __p; +} +# endif } // namespace __function @@ -137,84 +136,60 @@ namespace __function { // __alloc_func holds a functor and an allocator. -template class __alloc_func; +template +class __alloc_func; template class __default_alloc_func; template -class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)> -{ - __compressed_pair<_Fp, _Ap> __f_; +class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)> { + __compressed_pair<_Fp, _Ap> __f_; - public: - typedef _LIBCPP_NODEBUG _Fp _Target; - typedef _LIBCPP_NODEBUG _Ap _Alloc; +public: + typedef _LIBCPP_NODEBUG _Fp _Target; + typedef _LIBCPP_NODEBUG _Ap _Alloc; - _LIBCPP_INLINE_VISIBILITY - const _Target& __target() const { return __f_.first(); } + _LIBCPP_HIDE_FROM_ABI const _Target& __target() const { return __f_.first(); } - // WIN32 APIs may define __allocator, so use __get_allocator instead. - _LIBCPP_INLINE_VISIBILITY - const _Alloc& __get_allocator() const { return __f_.second(); } + // WIN32 APIs may define __allocator, so use __get_allocator instead. + _LIBCPP_HIDE_FROM_ABI const _Alloc& __get_allocator() const { return __f_.second(); } - _LIBCPP_INLINE_VISIBILITY - explicit __alloc_func(_Target&& __f) - : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)), - _VSTD::forward_as_tuple()) - { - } + _LIBCPP_HIDE_FROM_ABI explicit __alloc_func(_Target&& __f) + : __f_(piecewise_construct, std::forward_as_tuple(std::move(__f)), std::forward_as_tuple()) {} - _LIBCPP_INLINE_VISIBILITY - explicit __alloc_func(const _Target& __f, const _Alloc& __a) - : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f), - _VSTD::forward_as_tuple(__a)) - { - } + _LIBCPP_HIDE_FROM_ABI explicit __alloc_func(const _Target& __f, const _Alloc& __a) + : __f_(piecewise_construct, std::forward_as_tuple(__f), std::forward_as_tuple(__a)) {} - _LIBCPP_INLINE_VISIBILITY - explicit __alloc_func(const _Target& __f, _Alloc&& __a) - : __f_(piecewise_construct, _VSTD::forward_as_tuple(__f), - _VSTD::forward_as_tuple(_VSTD::move(__a))) - { - } + _LIBCPP_HIDE_FROM_ABI explicit __alloc_func(const _Target& __f, _Alloc&& __a) + : __f_(piecewise_construct, std::forward_as_tuple(__f), std::forward_as_tuple(std::move(__a))) {} - _LIBCPP_INLINE_VISIBILITY - explicit __alloc_func(_Target&& __f, _Alloc&& __a) - : __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)), - _VSTD::forward_as_tuple(_VSTD::move(__a))) - { - } + _LIBCPP_HIDE_FROM_ABI explicit __alloc_func(_Target&& __f, _Alloc&& __a) + : __f_(piecewise_construct, std::forward_as_tuple(std::move(__f)), std::forward_as_tuple(std::move(__a))) {} - _LIBCPP_INLINE_VISIBILITY - _Rp operator()(_ArgTypes&&... __arg) - { - typedef __invoke_void_return_wrapper<_Rp> _Invoker; - return _Invoker::__call(__f_.first(), - _VSTD::forward<_ArgTypes>(__arg)...); - } + _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __arg) { + typedef __invoke_void_return_wrapper<_Rp> _Invoker; + return _Invoker::__call(__f_.first(), std::forward<_ArgTypes>(__arg)...); + } - _LIBCPP_INLINE_VISIBILITY - __alloc_func* __clone() const - { - typedef allocator_traits<_Alloc> __alloc_traits; - typedef __rebind_alloc<__alloc_traits, __alloc_func> _AA; - _AA __a(__f_.second()); - typedef __allocator_destructor<_AA> _Dp; - unique_ptr<__alloc_func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new ((void*)__hold.get()) __alloc_func(__f_.first(), _Alloc(__a)); - return __hold.release(); - } + _LIBCPP_HIDE_FROM_ABI __alloc_func* __clone() const { + typedef allocator_traits<_Alloc> __alloc_traits; + typedef __rebind_alloc<__alloc_traits, __alloc_func> _AA; + _AA __a(__f_.second()); + typedef __allocator_destructor<_AA> _Dp; + unique_ptr<__alloc_func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new ((void*)__hold.get()) __alloc_func(__f_.first(), _Alloc(__a)); + return __hold.release(); + } - _LIBCPP_INLINE_VISIBILITY - void destroy() _NOEXCEPT { __f_.~__compressed_pair<_Target, _Alloc>(); } + _LIBCPP_HIDE_FROM_ABI void destroy() _NOEXCEPT { __f_.~__compressed_pair<_Target, _Alloc>(); } - _LIBCPP_HIDE_FROM_ABI static void __destroy_and_delete(__alloc_func* __f) { - typedef allocator_traits<_Alloc> __alloc_traits; - typedef __rebind_alloc<__alloc_traits, __alloc_func> _FunAlloc; - _FunAlloc __a(__f->__get_allocator()); - __f->destroy(); - __a.deallocate(__f, 1); - } + _LIBCPP_HIDE_FROM_ABI static void __destroy_and_delete(__alloc_func* __f) { + typedef allocator_traits<_Alloc> __alloc_traits; + typedef __rebind_alloc<__alloc_traits, __alloc_func> _FunAlloc; + _FunAlloc __a(__f->__get_allocator()); + __f->destroy(); + __a.deallocate(__f, 1); + } }; template @@ -224,455 +199,377 @@ class __default_alloc_func<_Fp, _Rp(_ArgTypes...)> { public: typedef _LIBCPP_NODEBUG _Fp _Target; - _LIBCPP_INLINE_VISIBILITY - const _Target& __target() const { return __f_; } + _LIBCPP_HIDE_FROM_ABI const _Target& __target() const { return __f_; } - _LIBCPP_INLINE_VISIBILITY - explicit __default_alloc_func(_Target&& __f) : __f_(_VSTD::move(__f)) {} + _LIBCPP_HIDE_FROM_ABI explicit __default_alloc_func(_Target&& __f) : __f_(std::move(__f)) {} - _LIBCPP_INLINE_VISIBILITY - explicit __default_alloc_func(const _Target& __f) : __f_(__f) {} + _LIBCPP_HIDE_FROM_ABI explicit __default_alloc_func(const _Target& __f) : __f_(__f) {} - _LIBCPP_INLINE_VISIBILITY - _Rp operator()(_ArgTypes&&... __arg) { + _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __arg) { typedef __invoke_void_return_wrapper<_Rp> _Invoker; - return _Invoker::__call(__f_, _VSTD::forward<_ArgTypes>(__arg)...); + return _Invoker::__call(__f_, std::forward<_ArgTypes>(__arg)...); } - _LIBCPP_INLINE_VISIBILITY - __default_alloc_func* __clone() const { - __builtin_new_allocator::__holder_t __hold = - __builtin_new_allocator::__allocate_type<__default_alloc_func>(1); - __default_alloc_func* __res = - ::new ((void*)__hold.get()) __default_alloc_func(__f_); + _LIBCPP_HIDE_FROM_ABI __default_alloc_func* __clone() const { + __builtin_new_allocator::__holder_t __hold = __builtin_new_allocator::__allocate_type<__default_alloc_func>(1); + __default_alloc_func* __res = ::new ((void*)__hold.get()) __default_alloc_func(__f_); (void)__hold.release(); return __res; } - _LIBCPP_INLINE_VISIBILITY - void destroy() _NOEXCEPT { __f_.~_Target(); } + _LIBCPP_HIDE_FROM_ABI void destroy() _NOEXCEPT { __f_.~_Target(); } _LIBCPP_HIDE_FROM_ABI static void __destroy_and_delete(__default_alloc_func* __f) { __f->destroy(); - __builtin_new_allocator::__deallocate_type<__default_alloc_func>(__f, 1); + __builtin_new_allocator::__deallocate_type<__default_alloc_func>(__f, 1); } }; // __base provides an abstract interface for copyable functors. -template class _LIBCPP_TEMPLATE_VIS __base; +template +class _LIBCPP_TEMPLATE_VIS __base; -template -class __base<_Rp(_ArgTypes...)> -{ - __base(const __base&); - __base& operator=(const __base&); +template +class __base<_Rp(_ArgTypes...)> { public: - _LIBCPP_INLINE_VISIBILITY __base() {} - _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual ~__base() {} - virtual __base* __clone() const = 0; - virtual void __clone(__base*) const = 0; - virtual void destroy() _NOEXCEPT = 0; - virtual void destroy_deallocate() _NOEXCEPT = 0; - virtual _Rp operator()(_ArgTypes&& ...) = 0; -#ifndef _LIBCPP_HAS_NO_RTTI - virtual const void* target(const type_info&) const _NOEXCEPT = 0; - virtual const std::type_info& target_type() const _NOEXCEPT = 0; -#endif // _LIBCPP_HAS_NO_RTTI + __base(const __base&) = delete; + __base& operator=(const __base&) = delete; + + _LIBCPP_HIDE_FROM_ABI __base() {} + _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual ~__base() {} + virtual __base* __clone() const = 0; + virtual void __clone(__base*) const = 0; + virtual void destroy() _NOEXCEPT = 0; + virtual void destroy_deallocate() _NOEXCEPT = 0; + virtual _Rp operator()(_ArgTypes&&...) = 0; +# ifndef _LIBCPP_HAS_NO_RTTI + virtual const void* target(const type_info&) const _NOEXCEPT = 0; + virtual const std::type_info& target_type() const _NOEXCEPT = 0; +# endif // _LIBCPP_HAS_NO_RTTI }; // __func implements __base for a given functor type. -template class __func; +template +class __func; + +template +class __func<_Fp, _Alloc, _Rp(_ArgTypes...)> : public __base<_Rp(_ArgTypes...)> { + __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> __f_; -template -class __func<_Fp, _Alloc, _Rp(_ArgTypes...)> - : public __base<_Rp(_ArgTypes...)> -{ - __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> __f_; public: - _LIBCPP_INLINE_VISIBILITY - explicit __func(_Fp&& __f) - : __f_(_VSTD::move(__f)) {} + _LIBCPP_HIDE_FROM_ABI explicit __func(_Fp&& __f) : __f_(std::move(__f)) {} - _LIBCPP_INLINE_VISIBILITY - explicit __func(const _Fp& __f, const _Alloc& __a) - : __f_(__f, __a) {} + _LIBCPP_HIDE_FROM_ABI explicit __func(const _Fp& __f, const _Alloc& __a) : __f_(__f, __a) {} - _LIBCPP_INLINE_VISIBILITY - explicit __func(const _Fp& __f, _Alloc&& __a) - : __f_(__f, _VSTD::move(__a)) {} + _LIBCPP_HIDE_FROM_ABI explicit __func(const _Fp& __f, _Alloc&& __a) : __f_(__f, std::move(__a)) {} - _LIBCPP_INLINE_VISIBILITY - explicit __func(_Fp&& __f, _Alloc&& __a) - : __f_(_VSTD::move(__f), _VSTD::move(__a)) {} + _LIBCPP_HIDE_FROM_ABI explicit __func(_Fp&& __f, _Alloc&& __a) : __f_(std::move(__f), std::move(__a)) {} - _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual __base<_Rp(_ArgTypes...)>* __clone() const; - _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __clone(__base<_Rp(_ArgTypes...)>*) const; - _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy() _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate() _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&&... __arg); -#ifndef _LIBCPP_HAS_NO_RTTI - _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const void* target(const type_info&) const _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const std::type_info& target_type() const _NOEXCEPT; -#endif // _LIBCPP_HAS_NO_RTTI + _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual __base<_Rp(_ArgTypes...)>* __clone() const; + _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __clone(__base<_Rp(_ArgTypes...)>*) const; + _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy() _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate() _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&&... __arg); +# ifndef _LIBCPP_HAS_NO_RTTI + _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const void* target(const type_info&) const _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const std::type_info& target_type() const _NOEXCEPT; +# endif // _LIBCPP_HAS_NO_RTTI }; -template -__base<_Rp(_ArgTypes...)>* -__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const -{ - typedef allocator_traits<_Alloc> __alloc_traits; - typedef __rebind_alloc<__alloc_traits, __func> _Ap; - _Ap __a(__f_.__get_allocator()); - typedef __allocator_destructor<_Ap> _Dp; - unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); - ::new ((void*)__hold.get()) __func(__f_.__target(), _Alloc(__a)); - return __hold.release(); +template +__base<_Rp(_ArgTypes...)>* __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone() const { + typedef allocator_traits<_Alloc> __alloc_traits; + typedef __rebind_alloc<__alloc_traits, __func> _Ap; + _Ap __a(__f_.__get_allocator()); + typedef __allocator_destructor<_Ap> _Dp; + unique_ptr<__func, _Dp> __hold(__a.allocate(1), _Dp(__a, 1)); + ::new ((void*)__hold.get()) __func(__f_.__target(), _Alloc(__a)); + return __hold.release(); } -template -void -__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const -{ - ::new ((void*)__p) __func(__f_.__target(), __f_.__get_allocator()); +template +void __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::__clone(__base<_Rp(_ArgTypes...)>* __p) const { + ::new ((void*)__p) __func(__f_.__target(), __f_.__get_allocator()); } -template -void -__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() _NOEXCEPT -{ - __f_.destroy(); +template +void __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy() _NOEXCEPT { + __f_.destroy(); } -template -void -__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT -{ - typedef allocator_traits<_Alloc> __alloc_traits; - typedef __rebind_alloc<__alloc_traits, __func> _Ap; - _Ap __a(__f_.__get_allocator()); - __f_.destroy(); - __a.deallocate(this, 1); +template +void __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::destroy_deallocate() _NOEXCEPT { + typedef allocator_traits<_Alloc> __alloc_traits; + typedef __rebind_alloc<__alloc_traits, __func> _Ap; + _Ap __a(__f_.__get_allocator()); + __f_.destroy(); + __a.deallocate(this, 1); } -template -_Rp -__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ... __arg) -{ - return __f_(_VSTD::forward<_ArgTypes>(__arg)...); +template +_Rp __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&&... __arg) { + return __f_(std::forward<_ArgTypes>(__arg)...); } -#ifndef _LIBCPP_HAS_NO_RTTI +# ifndef _LIBCPP_HAS_NO_RTTI -template -const void* -__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT -{ - if (__ti == typeid(_Fp)) - return _VSTD::addressof(__f_.__target()); - return nullptr; +template +const void* __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target(const type_info& __ti) const _NOEXCEPT { + if (__ti == typeid(_Fp)) + return std::addressof(__f_.__target()); + return nullptr; } -template -const std::type_info& -__func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT -{ - return typeid(_Fp); +template +const std::type_info& __func<_Fp, _Alloc, _Rp(_ArgTypes...)>::target_type() const _NOEXCEPT { + return typeid(_Fp); } -#endif // _LIBCPP_HAS_NO_RTTI +# endif // _LIBCPP_HAS_NO_RTTI // __value_func creates a value-type from a __func. -template class __value_func; +template +class __value_func; -template class __value_func<_Rp(_ArgTypes...)> -{ - _LIBCPP_SUPPRESS_DEPRECATED_PUSH - typename aligned_storage<3 * sizeof(void*)>::type __buf_; - _LIBCPP_SUPPRESS_DEPRECATED_POP +template +class __value_func<_Rp(_ArgTypes...)> { + _LIBCPP_SUPPRESS_DEPRECATED_PUSH + typename aligned_storage<3 * sizeof(void*)>::type __buf_; + _LIBCPP_SUPPRESS_DEPRECATED_POP - typedef __base<_Rp(_ArgTypes...)> __func; - __func* __f_; + typedef __base<_Rp(_ArgTypes...)> __func; + __func* __f_; - _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI static __func* __as_base(void* __p) - { - return reinterpret_cast<__func*>(__p); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI static __func* __as_base(void* __p) { return reinterpret_cast<__func*>(__p); } + +public: + _LIBCPP_HIDE_FROM_ABI __value_func() _NOEXCEPT : __f_(nullptr) {} + + template + _LIBCPP_HIDE_FROM_ABI __value_func(_Fp&& __f, const _Alloc& __a) : __f_(nullptr) { + typedef allocator_traits<_Alloc> __alloc_traits; + typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun; + typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc; + + if (__function::__not_null(__f)) { + _FunAlloc __af(__a); + if (sizeof(_Fun) <= sizeof(__buf_) && is_nothrow_copy_constructible<_Fp>::value && + is_nothrow_copy_constructible<_FunAlloc>::value) { + __f_ = ::new ((void*)&__buf_) _Fun(std::move(__f), _Alloc(__af)); + } else { + typedef __allocator_destructor<_FunAlloc> _Dp; + unique_ptr<__func, _Dp> __hold(__af.allocate(1), _Dp(__af, 1)); + ::new ((void*)__hold.get()) _Fun(std::move(__f), _Alloc(__a)); + __f_ = __hold.release(); + } } + } - public: - _LIBCPP_INLINE_VISIBILITY - __value_func() _NOEXCEPT : __f_(nullptr) {} + template , __value_func>::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI explicit __value_func(_Fp&& __f) : __value_func(std::forward<_Fp>(__f), allocator<_Fp>()) {} - template - _LIBCPP_INLINE_VISIBILITY __value_func(_Fp&& __f, const _Alloc& __a) - : __f_(nullptr) - { - typedef allocator_traits<_Alloc> __alloc_traits; - typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun; - typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc; + _LIBCPP_HIDE_FROM_ABI __value_func(const __value_func& __f) { + if (__f.__f_ == nullptr) + __f_ = nullptr; + else if ((void*)__f.__f_ == &__f.__buf_) { + __f_ = __as_base(&__buf_); + __f.__f_->__clone(__f_); + } else + __f_ = __f.__f_->__clone(); + } - if (__function::__not_null(__f)) - { - _FunAlloc __af(__a); - if (sizeof(_Fun) <= sizeof(__buf_) && - is_nothrow_copy_constructible<_Fp>::value && - is_nothrow_copy_constructible<_FunAlloc>::value) - { - __f_ = - ::new ((void*)&__buf_) _Fun(_VSTD::move(__f), _Alloc(__af)); - } - else - { - typedef __allocator_destructor<_FunAlloc> _Dp; - unique_ptr<__func, _Dp> __hold(__af.allocate(1), _Dp(__af, 1)); - ::new ((void*)__hold.get()) _Fun(_VSTD::move(__f), _Alloc(__a)); - __f_ = __hold.release(); - } - } + _LIBCPP_HIDE_FROM_ABI __value_func(__value_func&& __f) _NOEXCEPT { + if (__f.__f_ == nullptr) + __f_ = nullptr; + else if ((void*)__f.__f_ == &__f.__buf_) { + __f_ = __as_base(&__buf_); + __f.__f_->__clone(__f_); + } else { + __f_ = __f.__f_; + __f.__f_ = nullptr; } + } - template , __value_func>::value>::type> - _LIBCPP_INLINE_VISIBILITY explicit __value_func(_Fp&& __f) - : __value_func(_VSTD::forward<_Fp>(__f), allocator<_Fp>()) {} + _LIBCPP_HIDE_FROM_ABI ~__value_func() { + if ((void*)__f_ == &__buf_) + __f_->destroy(); + else if (__f_) + __f_->destroy_deallocate(); + } - _LIBCPP_INLINE_VISIBILITY - __value_func(const __value_func& __f) - { - if (__f.__f_ == nullptr) - __f_ = nullptr; - else if ((void*)__f.__f_ == &__f.__buf_) - { - __f_ = __as_base(&__buf_); - __f.__f_->__clone(__f_); - } - else - __f_ = __f.__f_->__clone(); + _LIBCPP_HIDE_FROM_ABI __value_func& operator=(__value_func&& __f) { + *this = nullptr; + if (__f.__f_ == nullptr) + __f_ = nullptr; + else if ((void*)__f.__f_ == &__f.__buf_) { + __f_ = __as_base(&__buf_); + __f.__f_->__clone(__f_); + } else { + __f_ = __f.__f_; + __f.__f_ = nullptr; } + return *this; + } - _LIBCPP_INLINE_VISIBILITY - __value_func(__value_func&& __f) _NOEXCEPT - { - if (__f.__f_ == nullptr) - __f_ = nullptr; - else if ((void*)__f.__f_ == &__f.__buf_) - { - __f_ = __as_base(&__buf_); - __f.__f_->__clone(__f_); - } - else - { - __f_ = __f.__f_; - __f.__f_ = nullptr; - } - } + _LIBCPP_HIDE_FROM_ABI __value_func& operator=(nullptr_t) { + __func* __f = __f_; + __f_ = nullptr; + if ((void*)__f == &__buf_) + __f->destroy(); + else if (__f) + __f->destroy_deallocate(); + return *this; + } - _LIBCPP_INLINE_VISIBILITY - ~__value_func() - { - if ((void*)__f_ == &__buf_) - __f_->destroy(); - else if (__f_) - __f_->destroy_deallocate(); - } + _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __args) const { + if (__f_ == nullptr) + __throw_bad_function_call(); + return (*__f_)(std::forward<_ArgTypes>(__args)...); + } - _LIBCPP_INLINE_VISIBILITY - __value_func& operator=(__value_func&& __f) - { - *this = nullptr; - if (__f.__f_ == nullptr) - __f_ = nullptr; - else if ((void*)__f.__f_ == &__f.__buf_) - { - __f_ = __as_base(&__buf_); - __f.__f_->__clone(__f_); - } - else - { - __f_ = __f.__f_; - __f.__f_ = nullptr; - } - return *this; - } + _LIBCPP_HIDE_FROM_ABI void swap(__value_func& __f) _NOEXCEPT { + if (&__f == this) + return; + if ((void*)__f_ == &__buf_ && (void*)__f.__f_ == &__f.__buf_) { + _LIBCPP_SUPPRESS_DEPRECATED_PUSH + typename aligned_storage::type __tempbuf; + _LIBCPP_SUPPRESS_DEPRECATED_POP + __func* __t = __as_base(&__tempbuf); + __f_->__clone(__t); + __f_->destroy(); + __f_ = nullptr; + __f.__f_->__clone(__as_base(&__buf_)); + __f.__f_->destroy(); + __f.__f_ = nullptr; + __f_ = __as_base(&__buf_); + __t->__clone(__as_base(&__f.__buf_)); + __t->destroy(); + __f.__f_ = __as_base(&__f.__buf_); + } else if ((void*)__f_ == &__buf_) { + __f_->__clone(__as_base(&__f.__buf_)); + __f_->destroy(); + __f_ = __f.__f_; + __f.__f_ = __as_base(&__f.__buf_); + } else if ((void*)__f.__f_ == &__f.__buf_) { + __f.__f_->__clone(__as_base(&__buf_)); + __f.__f_->destroy(); + __f.__f_ = __f_; + __f_ = __as_base(&__buf_); + } else + std::swap(__f_, __f.__f_); + } - _LIBCPP_INLINE_VISIBILITY - __value_func& operator=(nullptr_t) - { - __func* __f = __f_; - __f_ = nullptr; - if ((void*)__f == &__buf_) - __f->destroy(); - else if (__f) - __f->destroy_deallocate(); - return *this; - } + _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return __f_ != nullptr; } - _LIBCPP_INLINE_VISIBILITY - _Rp operator()(_ArgTypes&&... __args) const - { - if (__f_ == nullptr) - __throw_bad_function_call(); - return (*__f_)(_VSTD::forward<_ArgTypes>(__args)...); - } +# ifndef _LIBCPP_HAS_NO_RTTI + _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT { + if (__f_ == nullptr) + return typeid(void); + return __f_->target_type(); + } - _LIBCPP_INLINE_VISIBILITY - void swap(__value_func& __f) _NOEXCEPT - { - if (&__f == this) - return; - if ((void*)__f_ == &__buf_ && (void*)__f.__f_ == &__f.__buf_) - { - _LIBCPP_SUPPRESS_DEPRECATED_PUSH - typename aligned_storage::type __tempbuf; - _LIBCPP_SUPPRESS_DEPRECATED_POP - __func* __t = __as_base(&__tempbuf); - __f_->__clone(__t); - __f_->destroy(); - __f_ = nullptr; - __f.__f_->__clone(__as_base(&__buf_)); - __f.__f_->destroy(); - __f.__f_ = nullptr; - __f_ = __as_base(&__buf_); - __t->__clone(__as_base(&__f.__buf_)); - __t->destroy(); - __f.__f_ = __as_base(&__f.__buf_); - } - else if ((void*)__f_ == &__buf_) - { - __f_->__clone(__as_base(&__f.__buf_)); - __f_->destroy(); - __f_ = __f.__f_; - __f.__f_ = __as_base(&__f.__buf_); - } - else if ((void*)__f.__f_ == &__f.__buf_) - { - __f.__f_->__clone(__as_base(&__buf_)); - __f.__f_->destroy(); - __f.__f_ = __f_; - __f_ = __as_base(&__buf_); - } - else - _VSTD::swap(__f_, __f.__f_); - } - - _LIBCPP_INLINE_VISIBILITY - explicit operator bool() const _NOEXCEPT { return __f_ != nullptr; } - -#ifndef _LIBCPP_HAS_NO_RTTI - _LIBCPP_INLINE_VISIBILITY - const std::type_info& target_type() const _NOEXCEPT - { - if (__f_ == nullptr) - return typeid(void); - return __f_->target_type(); - } - - template - _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT - { - if (__f_ == nullptr) - return nullptr; - return (const _Tp*)__f_->target(typeid(_Tp)); - } -#endif // _LIBCPP_HAS_NO_RTTI + template + _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT { + if (__f_ == nullptr) + return nullptr; + return (const _Tp*)__f_->target(typeid(_Tp)); + } +# endif // _LIBCPP_HAS_NO_RTTI }; // Storage for a functor object, to be used with __policy to manage copy and // destruction. -union __policy_storage -{ - mutable char __small[sizeof(void*) * 2]; - void* __large; +union __policy_storage { + mutable char __small[sizeof(void*) * 2]; + void* __large; }; // True if _Fun can safely be held in __policy_storage.__small. template struct __use_small_storage : public integral_constant< - bool, sizeof(_Fun) <= sizeof(__policy_storage) && - _LIBCPP_ALIGNOF(_Fun) <= _LIBCPP_ALIGNOF(__policy_storage) && - is_trivially_copy_constructible<_Fun>::value && - is_trivially_destructible<_Fun>::value> {}; + bool, + sizeof(_Fun) <= sizeof(__policy_storage)&& _LIBCPP_ALIGNOF(_Fun) <= _LIBCPP_ALIGNOF(__policy_storage) && + is_trivially_copy_constructible<_Fun>::value && is_trivially_destructible<_Fun>::value> {}; // Policy contains information about how to copy, destroy, and move the // underlying functor. You can think of it as a vtable of sorts. -struct __policy -{ - // Used to copy or destroy __large values. null for trivial objects. - void* (*const __clone)(const void*); - void (*const __destroy)(void*); +struct __policy { + // Used to copy or destroy __large values. null for trivial objects. + void* (*const __clone)(const void*); + void (*const __destroy)(void*); - // True if this is the null policy (no value). - const bool __is_null; + // True if this is the null policy (no value). + const bool __is_null; - // The target type. May be null if RTTI is disabled. - const std::type_info* const __type_info; + // The target type. May be null if RTTI is disabled. + const std::type_info* const __type_info; - // Returns a pointer to a static policy object suitable for the functor - // type. - template - _LIBCPP_INLINE_VISIBILITY static const __policy* __create() - { - return __choose_policy<_Fun>(__use_small_storage<_Fun>()); - } + // Returns a pointer to a static policy object suitable for the functor + // type. + template + _LIBCPP_HIDE_FROM_ABI static const __policy* __create() { + return __choose_policy<_Fun>(__use_small_storage<_Fun>()); + } - _LIBCPP_INLINE_VISIBILITY - static const __policy* __create_empty() - { - static const _LIBCPP_CONSTEXPR __policy __policy = {nullptr, nullptr, - true, -#ifndef _LIBCPP_HAS_NO_RTTI - &typeid(void) -#else - nullptr -#endif - }; - return &__policy; - } + _LIBCPP_HIDE_FROM_ABI static const __policy* __create_empty() { + static constexpr __policy __policy = { + nullptr, + nullptr, + true, +# ifndef _LIBCPP_HAS_NO_RTTI + &typeid(void) +# else + nullptr +# endif + }; + return &__policy; + } - private: - template - _LIBCPP_HIDE_FROM_ABI static void* __large_clone(const void* __s) - { - const _Fun* __f = static_cast(__s); - return __f->__clone(); - } +private: + template + _LIBCPP_HIDE_FROM_ABI static void* __large_clone(const void* __s) { + const _Fun* __f = static_cast(__s); + return __f->__clone(); + } - template - _LIBCPP_HIDE_FROM_ABI static void __large_destroy(void* __s) { - _Fun::__destroy_and_delete(static_cast<_Fun*>(__s)); - } + template + _LIBCPP_HIDE_FROM_ABI static void __large_destroy(void* __s) { + _Fun::__destroy_and_delete(static_cast<_Fun*>(__s)); + } - template - _LIBCPP_INLINE_VISIBILITY static const __policy* - __choose_policy(/* is_small = */ false_type) { - static const _LIBCPP_CONSTEXPR __policy __policy = { - &__large_clone<_Fun>, &__large_destroy<_Fun>, false, -#ifndef _LIBCPP_HAS_NO_RTTI - &typeid(typename _Fun::_Target) -#else - nullptr -#endif - }; - return &__policy; - } + template + _LIBCPP_HIDE_FROM_ABI static const __policy* __choose_policy(/* is_small = */ false_type) { + static constexpr __policy __policy = { + &__large_clone<_Fun>, + &__large_destroy<_Fun>, + false, +# ifndef _LIBCPP_HAS_NO_RTTI + &typeid(typename _Fun::_Target) +# else + nullptr +# endif + }; + return &__policy; + } - template - _LIBCPP_INLINE_VISIBILITY static const __policy* - __choose_policy(/* is_small = */ true_type) - { - static const _LIBCPP_CONSTEXPR __policy __policy = { - nullptr, nullptr, false, -#ifndef _LIBCPP_HAS_NO_RTTI - &typeid(typename _Fun::_Target) -#else - nullptr -#endif - }; - return &__policy; - } + template + _LIBCPP_HIDE_FROM_ABI static const __policy* __choose_policy(/* is_small = */ true_type) { + static constexpr __policy __policy = { + nullptr, + nullptr, + false, +# ifndef _LIBCPP_HAS_NO_RTTI + &typeid(typename _Fun::_Target) +# else + nullptr +# endif + }; + return &__policy; + } }; // Used to choose between perfect forwarding or pass-by-value. Pass-by-value is @@ -682,545 +579,470 @@ using __fast_forward = __conditional_t::value, _Tp, _Tp&&>; // __policy_invoker calls an instance of __alloc_func held in __policy_storage. -template struct __policy_invoker; +template +struct __policy_invoker; template -struct __policy_invoker<_Rp(_ArgTypes...)> -{ - typedef _Rp (*__Call)(const __policy_storage*, - __fast_forward<_ArgTypes>...); +struct __policy_invoker<_Rp(_ArgTypes...)> { + typedef _Rp (*__Call)(const __policy_storage*, __fast_forward<_ArgTypes>...); - __Call __call_; + __Call __call_; - // Creates an invoker that throws bad_function_call. - _LIBCPP_INLINE_VISIBILITY - __policy_invoker() : __call_(&__call_empty) {} + // Creates an invoker that throws bad_function_call. + _LIBCPP_HIDE_FROM_ABI __policy_invoker() : __call_(&__call_empty) {} - // Creates an invoker that calls the given instance of __func. - template - _LIBCPP_INLINE_VISIBILITY static __policy_invoker __create() - { - return __policy_invoker(&__call_impl<_Fun>); - } + // Creates an invoker that calls the given instance of __func. + template + _LIBCPP_HIDE_FROM_ABI static __policy_invoker __create() { + return __policy_invoker(&__call_impl<_Fun>); + } - private: - _LIBCPP_INLINE_VISIBILITY - explicit __policy_invoker(__Call __c) : __call_(__c) {} +private: + _LIBCPP_HIDE_FROM_ABI explicit __policy_invoker(__Call __c) : __call_(__c) {} - _LIBCPP_HIDE_FROM_ABI static _Rp __call_empty(const __policy_storage*, - __fast_forward<_ArgTypes>...) - { - __throw_bad_function_call(); - } + _LIBCPP_HIDE_FROM_ABI static _Rp __call_empty(const __policy_storage*, __fast_forward<_ArgTypes>...) { + __throw_bad_function_call(); + } - template - _LIBCPP_HIDE_FROM_ABI static _Rp __call_impl(const __policy_storage* __buf, - __fast_forward<_ArgTypes>... __args) - { - _Fun* __f = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value - ? &__buf->__small - : __buf->__large); - return (*__f)(_VSTD::forward<_ArgTypes>(__args)...); - } + template + _LIBCPP_HIDE_FROM_ABI static _Rp __call_impl(const __policy_storage* __buf, __fast_forward<_ArgTypes>... __args) { + _Fun* __f = reinterpret_cast<_Fun*>(__use_small_storage<_Fun>::value ? &__buf->__small : __buf->__large); + return (*__f)(std::forward<_ArgTypes>(__args)...); + } }; // __policy_func uses a __policy and __policy_invoker to create a type-erased, // copyable functor. -template class __policy_func; +template +class __policy_func; -template class __policy_func<_Rp(_ArgTypes...)> -{ - // Inline storage for small objects. - __policy_storage __buf_; +template +class __policy_func<_Rp(_ArgTypes...)> { + // Inline storage for small objects. + __policy_storage __buf_; - // Calls the value stored in __buf_. This could technically be part of - // policy, but storing it here eliminates a level of indirection inside - // operator(). - typedef __function::__policy_invoker<_Rp(_ArgTypes...)> __invoker; - __invoker __invoker_; + // Calls the value stored in __buf_. This could technically be part of + // policy, but storing it here eliminates a level of indirection inside + // operator(). + typedef __function::__policy_invoker<_Rp(_ArgTypes...)> __invoker; + __invoker __invoker_; - // The policy that describes how to move / copy / destroy __buf_. Never - // null, even if the function is empty. - const __policy* __policy_; - - public: - _LIBCPP_INLINE_VISIBILITY - __policy_func() : __policy_(__policy::__create_empty()) {} - - template - _LIBCPP_INLINE_VISIBILITY __policy_func(_Fp&& __f, const _Alloc& __a) - : __policy_(__policy::__create_empty()) - { - typedef __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun; - typedef allocator_traits<_Alloc> __alloc_traits; - typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc; - - if (__function::__not_null(__f)) - { - __invoker_ = __invoker::template __create<_Fun>(); - __policy_ = __policy::__create<_Fun>(); - - _FunAlloc __af(__a); - if (__use_small_storage<_Fun>()) - { - ::new ((void*)&__buf_.__small) - _Fun(_VSTD::move(__f), _Alloc(__af)); - } - else - { - typedef __allocator_destructor<_FunAlloc> _Dp; - unique_ptr<_Fun, _Dp> __hold(__af.allocate(1), _Dp(__af, 1)); - ::new ((void*)__hold.get()) - _Fun(_VSTD::move(__f), _Alloc(__af)); - __buf_.__large = __hold.release(); - } - } - } - - template , __policy_func>::value>::type> - _LIBCPP_INLINE_VISIBILITY explicit __policy_func(_Fp&& __f) - : __policy_(__policy::__create_empty()) { - typedef __default_alloc_func<_Fp, _Rp(_ArgTypes...)> _Fun; - - if (__function::__not_null(__f)) { - __invoker_ = __invoker::template __create<_Fun>(); - __policy_ = __policy::__create<_Fun>(); - if (__use_small_storage<_Fun>()) { - ::new ((void*)&__buf_.__small) _Fun(_VSTD::move(__f)); - } else { - __builtin_new_allocator::__holder_t __hold = - __builtin_new_allocator::__allocate_type<_Fun>(1); - __buf_.__large = ::new ((void*)__hold.get()) _Fun(_VSTD::move(__f)); - (void)__hold.release(); - } - } - } - - _LIBCPP_INLINE_VISIBILITY - __policy_func(const __policy_func& __f) - : __buf_(__f.__buf_), __invoker_(__f.__invoker_), - __policy_(__f.__policy_) - { - if (__policy_->__clone) - __buf_.__large = __policy_->__clone(__f.__buf_.__large); - } - - _LIBCPP_INLINE_VISIBILITY - __policy_func(__policy_func&& __f) - : __buf_(__f.__buf_), __invoker_(__f.__invoker_), - __policy_(__f.__policy_) - { - if (__policy_->__destroy) - { - __f.__policy_ = __policy::__create_empty(); - __f.__invoker_ = __invoker(); - } - } - - _LIBCPP_INLINE_VISIBILITY - ~__policy_func() - { - if (__policy_->__destroy) - __policy_->__destroy(__buf_.__large); - } - - _LIBCPP_INLINE_VISIBILITY - __policy_func& operator=(__policy_func&& __f) - { - *this = nullptr; - __buf_ = __f.__buf_; - __invoker_ = __f.__invoker_; - __policy_ = __f.__policy_; - __f.__policy_ = __policy::__create_empty(); - __f.__invoker_ = __invoker(); - return *this; - } - - _LIBCPP_INLINE_VISIBILITY - __policy_func& operator=(nullptr_t) - { - const __policy* __p = __policy_; - __policy_ = __policy::__create_empty(); - __invoker_ = __invoker(); - if (__p->__destroy) - __p->__destroy(__buf_.__large); - return *this; - } - - _LIBCPP_INLINE_VISIBILITY - _Rp operator()(_ArgTypes&&... __args) const - { - return __invoker_.__call_(_VSTD::addressof(__buf_), - _VSTD::forward<_ArgTypes>(__args)...); - } - - _LIBCPP_INLINE_VISIBILITY - void swap(__policy_func& __f) - { - _VSTD::swap(__invoker_, __f.__invoker_); - _VSTD::swap(__policy_, __f.__policy_); - _VSTD::swap(__buf_, __f.__buf_); - } - - _LIBCPP_INLINE_VISIBILITY - explicit operator bool() const _NOEXCEPT - { - return !__policy_->__is_null; - } - -#ifndef _LIBCPP_HAS_NO_RTTI - _LIBCPP_INLINE_VISIBILITY - const std::type_info& target_type() const _NOEXCEPT - { - return *__policy_->__type_info; - } - - template - _LIBCPP_INLINE_VISIBILITY const _Tp* target() const _NOEXCEPT - { - if (__policy_->__is_null || typeid(_Tp) != *__policy_->__type_info) - return nullptr; - if (__policy_->__clone) // Out of line storage. - return reinterpret_cast(__buf_.__large); - else - return reinterpret_cast(&__buf_.__small); - } -#endif // _LIBCPP_HAS_NO_RTTI -}; - -#if defined(_LIBCPP_HAS_BLOCKS_RUNTIME) - -extern "C" void *_Block_copy(const void *); -extern "C" void _Block_release(const void *); - -template -class __func<_Rp1(^)(_ArgTypes1...), _Alloc, _Rp(_ArgTypes...)> - : public __base<_Rp(_ArgTypes...)> -{ - typedef _Rp1(^__block_type)(_ArgTypes1...); - __block_type __f_; + // The policy that describes how to move / copy / destroy __buf_. Never + // null, even if the function is empty. + const __policy* __policy_; public: - _LIBCPP_INLINE_VISIBILITY - explicit __func(__block_type const& __f) -#ifdef _LIBCPP_HAS_OBJC_ARC - : __f_(__f) -#else - : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr)) -#endif - { } + _LIBCPP_HIDE_FROM_ABI __policy_func() : __policy_(__policy::__create_empty()) {} - // [TODO] add && to save on a retain + template + _LIBCPP_HIDE_FROM_ABI __policy_func(_Fp&& __f, const _Alloc& __a) : __policy_(__policy::__create_empty()) { + typedef __alloc_func<_Fp, _Alloc, _Rp(_ArgTypes...)> _Fun; + typedef allocator_traits<_Alloc> __alloc_traits; + typedef __rebind_alloc<__alloc_traits, _Fun> _FunAlloc; - _LIBCPP_INLINE_VISIBILITY - explicit __func(__block_type __f, const _Alloc& /* unused */) -#ifdef _LIBCPP_HAS_OBJC_ARC - : __f_(__f) -#else - : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr)) -#endif - { } + if (__function::__not_null(__f)) { + __invoker_ = __invoker::template __create<_Fun>(); + __policy_ = __policy::__create<_Fun>(); - virtual __base<_Rp(_ArgTypes...)>* __clone() const { - _LIBCPP_ASSERT(false, - "Block pointers are just pointers, so they should always fit into " - "std::function's small buffer optimization. This function should " - "never be invoked."); - return nullptr; + _FunAlloc __af(__a); + if (__use_small_storage<_Fun>()) { + ::new ((void*)&__buf_.__small) _Fun(std::move(__f), _Alloc(__af)); + } else { + typedef __allocator_destructor<_FunAlloc> _Dp; + unique_ptr<_Fun, _Dp> __hold(__af.allocate(1), _Dp(__af, 1)); + ::new ((void*)__hold.get()) _Fun(std::move(__f), _Alloc(__af)); + __buf_.__large = __hold.release(); + } } + } - virtual void __clone(__base<_Rp(_ArgTypes...)>* __p) const { - ::new ((void*)__p) __func(__f_); - } + template , __policy_func>::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI explicit __policy_func(_Fp&& __f) : __policy_(__policy::__create_empty()) { + typedef __default_alloc_func<_Fp, _Rp(_ArgTypes...)> _Fun; - virtual void destroy() _NOEXCEPT { -#ifndef _LIBCPP_HAS_OBJC_ARC - if (__f_) - _Block_release(__f_); -#endif - __f_ = 0; + if (__function::__not_null(__f)) { + __invoker_ = __invoker::template __create<_Fun>(); + __policy_ = __policy::__create<_Fun>(); + if (__use_small_storage<_Fun>()) { + ::new ((void*)&__buf_.__small) _Fun(std::move(__f)); + } else { + __builtin_new_allocator::__holder_t __hold = __builtin_new_allocator::__allocate_type<_Fun>(1); + __buf_.__large = ::new ((void*)__hold.get()) _Fun(std::move(__f)); + (void)__hold.release(); + } } + } - virtual void destroy_deallocate() _NOEXCEPT { - _LIBCPP_ASSERT(false, - "Block pointers are just pointers, so they should always fit into " - "std::function's small buffer optimization. This function should " - "never be invoked."); - } + _LIBCPP_HIDE_FROM_ABI __policy_func(const __policy_func& __f) + : __buf_(__f.__buf_), __invoker_(__f.__invoker_), __policy_(__f.__policy_) { + if (__policy_->__clone) + __buf_.__large = __policy_->__clone(__f.__buf_.__large); + } - virtual _Rp operator()(_ArgTypes&& ... __arg) { - return _VSTD::__invoke(__f_, _VSTD::forward<_ArgTypes>(__arg)...); + _LIBCPP_HIDE_FROM_ABI __policy_func(__policy_func&& __f) + : __buf_(__f.__buf_), __invoker_(__f.__invoker_), __policy_(__f.__policy_) { + if (__policy_->__destroy) { + __f.__policy_ = __policy::__create_empty(); + __f.__invoker_ = __invoker(); } + } -#ifndef _LIBCPP_HAS_NO_RTTI - virtual const void* target(type_info const& __ti) const _NOEXCEPT { - if (__ti == typeid(__func::__block_type)) - return &__f_; - return (const void*)nullptr; - } + _LIBCPP_HIDE_FROM_ABI ~__policy_func() { + if (__policy_->__destroy) + __policy_->__destroy(__buf_.__large); + } - virtual const std::type_info& target_type() const _NOEXCEPT { - return typeid(__func::__block_type); - } -#endif // _LIBCPP_HAS_NO_RTTI + _LIBCPP_HIDE_FROM_ABI __policy_func& operator=(__policy_func&& __f) { + *this = nullptr; + __buf_ = __f.__buf_; + __invoker_ = __f.__invoker_; + __policy_ = __f.__policy_; + __f.__policy_ = __policy::__create_empty(); + __f.__invoker_ = __invoker(); + return *this; + } + + _LIBCPP_HIDE_FROM_ABI __policy_func& operator=(nullptr_t) { + const __policy* __p = __policy_; + __policy_ = __policy::__create_empty(); + __invoker_ = __invoker(); + if (__p->__destroy) + __p->__destroy(__buf_.__large); + return *this; + } + + _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __args) const { + return __invoker_.__call_(std::addressof(__buf_), std::forward<_ArgTypes>(__args)...); + } + + _LIBCPP_HIDE_FROM_ABI void swap(__policy_func& __f) { + std::swap(__invoker_, __f.__invoker_); + std::swap(__policy_, __f.__policy_); + std::swap(__buf_, __f.__buf_); + } + + _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return !__policy_->__is_null; } + +# ifndef _LIBCPP_HAS_NO_RTTI + _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT { return *__policy_->__type_info; } + + template + _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT { + if (__policy_->__is_null || typeid(_Tp) != *__policy_->__type_info) + return nullptr; + if (__policy_->__clone) // Out of line storage. + return reinterpret_cast(__buf_.__large); + else + return reinterpret_cast(&__buf_.__small); + } +# endif // _LIBCPP_HAS_NO_RTTI }; -#endif // _LIBCPP_HAS_EXTENSION_BLOCKS +# if defined(_LIBCPP_HAS_BLOCKS_RUNTIME) + +extern "C" void* _Block_copy(const void*); +extern "C" void _Block_release(const void*); + +template +class __func<_Rp1 (^)(_ArgTypes1...), _Alloc, _Rp(_ArgTypes...)> : public __base<_Rp(_ArgTypes...)> { + typedef _Rp1 (^__block_type)(_ArgTypes1...); + __block_type __f_; + +public: + _LIBCPP_HIDE_FROM_ABI explicit __func(__block_type const& __f) +# ifdef _LIBCPP_HAS_OBJC_ARC + : __f_(__f) +# else + : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr)) +# endif + { + } + + // [TODO] add && to save on a retain + + _LIBCPP_HIDE_FROM_ABI explicit __func(__block_type __f, const _Alloc& /* unused */) +# ifdef _LIBCPP_HAS_OBJC_ARC + : __f_(__f) +# else + : __f_(reinterpret_cast<__block_type>(__f ? _Block_copy(__f) : nullptr)) +# endif + { + } + + _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual __base<_Rp(_ArgTypes...)>* __clone() const { + _LIBCPP_ASSERT_INTERNAL( + false, + "Block pointers are just pointers, so they should always fit into " + "std::function's small buffer optimization. This function should " + "never be invoked."); + return nullptr; + } + + _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void __clone(__base<_Rp(_ArgTypes...)>* __p) const { + ::new ((void*)__p) __func(__f_); + } + + _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy() _NOEXCEPT { +# ifndef _LIBCPP_HAS_OBJC_ARC + if (__f_) + _Block_release(__f_); +# endif + __f_ = 0; + } + + _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual void destroy_deallocate() _NOEXCEPT { + _LIBCPP_ASSERT_INTERNAL( + false, + "Block pointers are just pointers, so they should always fit into " + "std::function's small buffer optimization. This function should " + "never be invoked."); + } + + _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual _Rp operator()(_ArgTypes&&... __arg) { + return std::__invoke(__f_, std::forward<_ArgTypes>(__arg)...); + } + +# ifndef _LIBCPP_HAS_NO_RTTI + _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const void* target(type_info const& __ti) const _NOEXCEPT { + if (__ti == typeid(__func::__block_type)) + return &__f_; + return (const void*)nullptr; + } + + _LIBCPP_HIDE_FROM_ABI_VIRTUAL virtual const std::type_info& target_type() const _NOEXCEPT { + return typeid(__func::__block_type); + } +# endif // _LIBCPP_HAS_NO_RTTI +}; + +# endif // _LIBCPP_HAS_EXTENSION_BLOCKS } // namespace __function -template +template class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)> : public __function::__maybe_derive_from_unary_function<_Rp(_ArgTypes...)>, - public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)> -{ -#ifndef _LIBCPP_ABI_OPTIMIZED_FUNCTION - typedef __function::__value_func<_Rp(_ArgTypes...)> __func; -#else - typedef __function::__policy_func<_Rp(_ArgTypes...)> __func; -#endif + public __function::__maybe_derive_from_binary_function<_Rp(_ArgTypes...)> { +# ifndef _LIBCPP_ABI_OPTIMIZED_FUNCTION + typedef __function::__value_func<_Rp(_ArgTypes...)> __func; +# else + typedef __function::__policy_func<_Rp(_ArgTypes...)> __func; +# endif - __func __f_; + __func __f_; - template , function>, - __invokable<_Fp, _ArgTypes...> - >::value> - struct __callable; - template - struct __callable<_Fp, true> - { - static const bool value = is_void<_Rp>::value || - __is_core_convertible::type, - _Rp>::value; - }; - template - struct __callable<_Fp, false> - { - static const bool value = false; - }; + template , function>, __invokable<_Fp, _ArgTypes...> >::value> + struct __callable; + template + struct __callable<_Fp, true> { + static const bool value = + is_void<_Rp>::value || __is_core_convertible::type, _Rp>::value; + }; + template + struct __callable<_Fp, false> { + static const bool value = false; + }; template - using _EnableIfLValueCallable = typename enable_if<__callable<_Fp&>::value>::type; + using _EnableIfLValueCallable = __enable_if_t<__callable<_Fp&>::value>; + public: - typedef _Rp result_type; + typedef _Rp result_type; - // construct/copy/destroy: - _LIBCPP_INLINE_VISIBILITY - function() _NOEXCEPT { } - _LIBCPP_INLINE_VISIBILITY - _LIBCPP_HIDE_FROM_ABI function(nullptr_t) _NOEXCEPT {} - _LIBCPP_HIDE_FROM_ABI function(const function&); - _LIBCPP_HIDE_FROM_ABI function(function&&) _NOEXCEPT; - template> - _LIBCPP_HIDE_FROM_ABI function(_Fp); + // construct/copy/destroy: + _LIBCPP_HIDE_FROM_ABI function() _NOEXCEPT {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDE_FROM_ABI function(nullptr_t) _NOEXCEPT {} + _LIBCPP_HIDE_FROM_ABI function(const function&); + _LIBCPP_HIDE_FROM_ABI function(function&&) _NOEXCEPT; + template > + _LIBCPP_HIDE_FROM_ABI function(_Fp); -#if _LIBCPP_STD_VER <= 14 - template - _LIBCPP_INLINE_VISIBILITY - function(allocator_arg_t, const _Alloc&) _NOEXCEPT {} - template - _LIBCPP_INLINE_VISIBILITY - function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {} - template - _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, const function&); - template - _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, function&&); - template> - _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc& __a, _Fp __f); -#endif +# if _LIBCPP_STD_VER <= 14 + template + _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&) _NOEXCEPT {} + template + _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, nullptr_t) _NOEXCEPT {} + template + _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, const function&); + template + _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc&, function&&); + template > + _LIBCPP_HIDE_FROM_ABI function(allocator_arg_t, const _Alloc& __a, _Fp __f); +# endif - _LIBCPP_HIDE_FROM_ABI function& operator=(const function&); - _LIBCPP_HIDE_FROM_ABI function& operator=(function&&) _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI function& operator=(nullptr_t) _NOEXCEPT; - template>> - _LIBCPP_HIDE_FROM_ABI function& operator=(_Fp&&); + _LIBCPP_HIDE_FROM_ABI function& operator=(const function&); + _LIBCPP_HIDE_FROM_ABI function& operator=(function&&) _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI function& operator=(nullptr_t) _NOEXCEPT; + template >> + _LIBCPP_HIDE_FROM_ABI function& operator=(_Fp&&); - _LIBCPP_HIDE_FROM_ABI ~function(); + _LIBCPP_HIDE_FROM_ABI ~function(); - // function modifiers: - _LIBCPP_HIDE_FROM_ABI void swap(function&) _NOEXCEPT; + // function modifiers: + _LIBCPP_HIDE_FROM_ABI void swap(function&) _NOEXCEPT; -#if _LIBCPP_STD_VER <= 14 - template - _LIBCPP_INLINE_VISIBILITY - void assign(_Fp&& __f, const _Alloc& __a) - {function(allocator_arg, __a, _VSTD::forward<_Fp>(__f)).swap(*this);} -#endif +# if _LIBCPP_STD_VER <= 14 + template + _LIBCPP_HIDE_FROM_ABI void assign(_Fp&& __f, const _Alloc& __a) { + function(allocator_arg, __a, std::forward<_Fp>(__f)).swap(*this); + } +# endif - // function capacity: - _LIBCPP_INLINE_VISIBILITY - explicit operator bool() const _NOEXCEPT { - return static_cast(__f_); - } + // function capacity: + _LIBCPP_HIDE_FROM_ABI explicit operator bool() const _NOEXCEPT { return static_cast(__f_); } + + // deleted overloads close possible hole in the type system + template + bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete; +# if _LIBCPP_STD_VER <= 17 + template + bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete; +# endif - // deleted overloads close possible hole in the type system - template - bool operator==(const function<_R2(_ArgTypes2...)>&) const = delete; - template - bool operator!=(const function<_R2(_ArgTypes2...)>&) const = delete; public: - // function invocation: - _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes...) const; + // function invocation: + _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes...) const; -#ifndef _LIBCPP_HAS_NO_RTTI - // function target access: - _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT; - template - _LIBCPP_HIDE_FROM_ABI _Tp* target() _NOEXCEPT; - template - _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT; -#endif // _LIBCPP_HAS_NO_RTTI +# ifndef _LIBCPP_HAS_NO_RTTI + // function target access: + _LIBCPP_HIDE_FROM_ABI const std::type_info& target_type() const _NOEXCEPT; + template + _LIBCPP_HIDE_FROM_ABI _Tp* target() _NOEXCEPT; + template + _LIBCPP_HIDE_FROM_ABI const _Tp* target() const _NOEXCEPT; +# endif // _LIBCPP_HAS_NO_RTTI }; -#if _LIBCPP_STD_VER >= 17 -template -function(_Rp(*)(_Ap...)) -> function<_Rp(_Ap...)>; +# if _LIBCPP_STD_VER >= 17 +template +function(_Rp (*)(_Ap...)) -> function<_Rp(_Ap...)>; -template::type> +template ::type> function(_Fp) -> function<_Stripped>; -#endif // _LIBCPP_STD_VER >= 17 +# endif // _LIBCPP_STD_VER >= 17 -template +template function<_Rp(_ArgTypes...)>::function(const function& __f) : __f_(__f.__f_) {} -#if _LIBCPP_STD_VER <= 14 -template +# if _LIBCPP_STD_VER <= 14 +template template -function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, - const function& __f) : __f_(__f.__f_) {} -#endif +function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, const function& __f) : __f_(__f.__f_) {} +# endif template -function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT - : __f_(_VSTD::move(__f.__f_)) {} +function<_Rp(_ArgTypes...)>::function(function&& __f) _NOEXCEPT : __f_(std::move(__f.__f_)) {} -#if _LIBCPP_STD_VER <= 14 -template +# if _LIBCPP_STD_VER <= 14 +template template -function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, - function&& __f) - : __f_(_VSTD::move(__f.__f_)) {} -#endif +function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc&, function&& __f) : __f_(std::move(__f.__f_)) {} +# endif template template -function<_Rp(_ArgTypes...)>::function(_Fp __f) : __f_(_VSTD::move(__f)) {} +function<_Rp(_ArgTypes...)>::function(_Fp __f) : __f_(std::move(__f)) {} -#if _LIBCPP_STD_VER <= 14 +# if _LIBCPP_STD_VER <= 14 template template -function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a, - _Fp __f) - : __f_(_VSTD::move(__f), __a) {} -#endif +function<_Rp(_ArgTypes...)>::function(allocator_arg_t, const _Alloc& __a, _Fp __f) : __f_(std::move(__f), __a) {} +# endif -template -function<_Rp(_ArgTypes...)>& -function<_Rp(_ArgTypes...)>::operator=(const function& __f) -{ - function(__f).swap(*this); - return *this; +template +function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(const function& __f) { + function(__f).swap(*this); + return *this; } -template -function<_Rp(_ArgTypes...)>& -function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT -{ - __f_ = _VSTD::move(__f.__f_); - return *this; +template +function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(function&& __f) _NOEXCEPT { + __f_ = std::move(__f.__f_); + return *this; } -template -function<_Rp(_ArgTypes...)>& -function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT -{ - __f_ = nullptr; - return *this; +template +function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(nullptr_t) _NOEXCEPT { + __f_ = nullptr; + return *this; } -template +template template -function<_Rp(_ArgTypes...)>& -function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f) -{ - function(_VSTD::forward<_Fp>(__f)).swap(*this); - return *this; +function<_Rp(_ArgTypes...)>& function<_Rp(_ArgTypes...)>::operator=(_Fp&& __f) { + function(std::forward<_Fp>(__f)).swap(*this); + return *this; } -template +template function<_Rp(_ArgTypes...)>::~function() {} -template -void -function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT -{ - __f_.swap(__f.__f_); +template +void function<_Rp(_ArgTypes...)>::swap(function& __f) _NOEXCEPT { + __f_.swap(__f.__f_); } -template -_Rp -function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const -{ - return __f_(_VSTD::forward<_ArgTypes>(__arg)...); +template +_Rp function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) const { + return __f_(std::forward<_ArgTypes>(__arg)...); } -#ifndef _LIBCPP_HAS_NO_RTTI +# ifndef _LIBCPP_HAS_NO_RTTI -template -const std::type_info& -function<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT -{ - return __f_.target_type(); +template +const std::type_info& function<_Rp(_ArgTypes...)>::target_type() const _NOEXCEPT { + return __f_.target_type(); } -template +template template -_Tp* -function<_Rp(_ArgTypes...)>::target() _NOEXCEPT -{ - return (_Tp*)(__f_.template target<_Tp>()); +_Tp* function<_Rp(_ArgTypes...)>::target() _NOEXCEPT { + return (_Tp*)(__f_.template target<_Tp>()); } -template +template template -const _Tp* -function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT -{ - return __f_.template target<_Tp>(); +const _Tp* function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT { + return __f_.template target<_Tp>(); } -#endif // _LIBCPP_HAS_NO_RTTI +# endif // _LIBCPP_HAS_NO_RTTI template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return !__f;} +inline _LIBCPP_HIDE_FROM_ABI bool operator==(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT { + return !__f; +} + +# if _LIBCPP_STD_VER <= 17 template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator==(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return !__f;} +inline _LIBCPP_HIDE_FROM_ABI bool operator==(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT { + return !__f; +} template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator!=(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT {return (bool)__f;} +inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const function<_Rp(_ArgTypes...)>& __f, nullptr_t) _NOEXCEPT { + return (bool)__f; +} template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT {return (bool)__f;} +inline _LIBCPP_HIDE_FROM_ABI bool operator!=(nullptr_t, const function<_Rp(_ArgTypes...)>& __f) _NOEXCEPT { + return (bool)__f; +} + +# endif // _LIBCPP_STD_VER <= 17 template -inline _LIBCPP_INLINE_VISIBILITY -void -swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCEPT -{return __x.swap(__y);} +inline _LIBCPP_HIDE_FROM_ABI void swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCEPT { + return __x.swap(__y); +} _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_CXX03_LANG +_LIBCPP_POP_MACROS + #endif // _LIBCPP___FUNCTIONAL_FUNCTION_H diff --git a/third_party/libcxx/__functional/hash.h b/third_party/libcxx/__functional/hash.h index fa09748b1..a9e450edd 100644 --- a/third_party/libcxx/__functional/hash.h +++ b/third_party/libcxx/__functional/hash.h @@ -10,23 +10,18 @@ #define _LIBCPP___FUNCTIONAL_HASH_H #include <__config> -#include <__functional/invoke.h> #include <__functional/unary_function.h> -#include <__fwd/hash.h> -#include <__tuple/sfinae_helpers.h> -#include <__type_traits/is_copy_constructible.h> -#include <__type_traits/is_default_constructible.h> +#include <__fwd/functional.h> +#include <__type_traits/conjunction.h> +#include <__type_traits/invoke.h> +#include <__type_traits/is_constructible.h> #include <__type_traits/is_enum.h> -#include <__type_traits/is_move_constructible.h> #include <__type_traits/underlying_type.h> -#include <__utility/forward.h> -#include <__utility/move.h> #include <__utility/pair.h> #include <__utility/swap.h> #include #include #include -#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -35,133 +30,117 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_HIDE_FROM_ABI -_Size -__loadword(const void* __p) -{ - _Size __r; - _VSTD::memcpy(&__r, __p, sizeof(__r)); - return __r; +inline _LIBCPP_HIDE_FROM_ABI _Size __loadword(const void* __p) { + _Size __r; + std::memcpy(&__r, __p, sizeof(__r)); + return __r; } // We use murmur2 when size_t is 32 bits, and cityhash64 when size_t // is 64 bits. This is because cityhash64 uses 64bit x 64bit // multiplication, which can be very slow on 32-bit systems. -template +template struct __murmur2_or_cityhash; template -struct __murmur2_or_cityhash<_Size, 32> -{ - _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK - _Size operator()(const void* __key, _Size __len) const { - // murmur2 - const _Size __m = 0x5bd1e995; - const _Size __r = 24; - _Size __h = __len; - const unsigned char* __data = static_cast(__key); - for (; __len >= 4; __data += 4, __len -= 4) - { - _Size __k = std::__loadword<_Size>(__data); - __k *= __m; - __k ^= __k >> __r; - __k *= __m; - __h *= __m; - __h ^= __k; - } - switch (__len) - { - case 3: - __h ^= static_cast<_Size>(__data[2] << 16); - _LIBCPP_FALLTHROUGH(); - case 2: - __h ^= static_cast<_Size>(__data[1] << 8); - _LIBCPP_FALLTHROUGH(); - case 1: - __h ^= __data[0]; - __h *= __m; - } - __h ^= __h >> 13; +struct __murmur2_or_cityhash<_Size, 32> { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK _Size + operator()(const void* __key, _Size __len) const { + // murmur2 + const _Size __m = 0x5bd1e995; + const _Size __r = 24; + _Size __h = __len; + const unsigned char* __data = static_cast(__key); + for (; __len >= 4; __data += 4, __len -= 4) { + _Size __k = std::__loadword<_Size>(__data); + __k *= __m; + __k ^= __k >> __r; + __k *= __m; __h *= __m; - __h ^= __h >> 15; - return __h; + __h ^= __k; } + switch (__len) { + case 3: + __h ^= static_cast<_Size>(__data[2] << 16); + _LIBCPP_FALLTHROUGH(); + case 2: + __h ^= static_cast<_Size>(__data[1] << 8); + _LIBCPP_FALLTHROUGH(); + case 1: + __h ^= __data[0]; + __h *= __m; + } + __h ^= __h >> 13; + __h *= __m; + __h ^= __h >> 15; + return __h; + } }; template -struct __murmur2_or_cityhash<_Size, 64> -{ +struct __murmur2_or_cityhash<_Size, 64> { // cityhash64 - _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK - _Size operator()(const void* __key, _Size __len) const { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK _Size + operator()(const void* __key, _Size __len) const { const char* __s = static_cast(__key); if (__len <= 32) { - if (__len <= 16) { + if (__len <= 16) { return __hash_len_0_to_16(__s, __len); - } else { + } else { return __hash_len_17_to_32(__s, __len); - } + } } else if (__len <= 64) { - return __hash_len_33_to_64(__s, __len); + return __hash_len_33_to_64(__s, __len); } // For strings over 64 bytes we hash the end first, and then as we // loop we keep 56 bytes of state: v, w, x, y, and z. _Size __x = std::__loadword<_Size>(__s + __len - 40); - _Size __y = std::__loadword<_Size>(__s + __len - 16) + - std::__loadword<_Size>(__s + __len - 56); - _Size __z = __hash_len_16(std::__loadword<_Size>(__s + __len - 48) + __len, - std::__loadword<_Size>(__s + __len - 24)); + _Size __y = std::__loadword<_Size>(__s + __len - 16) + std::__loadword<_Size>(__s + __len - 56); + _Size __z = + __hash_len_16(std::__loadword<_Size>(__s + __len - 48) + __len, std::__loadword<_Size>(__s + __len - 24)); pair<_Size, _Size> __v = __weak_hash_len_32_with_seeds(__s + __len - 64, __len, __z); pair<_Size, _Size> __w = __weak_hash_len_32_with_seeds(__s + __len - 32, __y + __k1, __x); - __x = __x * __k1 + std::__loadword<_Size>(__s); + __x = __x * __k1 + std::__loadword<_Size>(__s); // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks. __len = (__len - 1) & ~static_cast<_Size>(63); do { - __x = __rotate(__x + __y + __v.first + std::__loadword<_Size>(__s + 8), 37) * __k1; - __y = __rotate(__y + __v.second + std::__loadword<_Size>(__s + 48), 42) * __k1; - __x ^= __w.second; - __y += __v.first + std::__loadword<_Size>(__s + 40); - __z = __rotate(__z + __w.first, 33) * __k1; - __v = __weak_hash_len_32_with_seeds(__s, __v.second * __k1, __x + __w.first); - __w = __weak_hash_len_32_with_seeds(__s + 32, __z + __w.second, - __y + std::__loadword<_Size>(__s + 16)); - _VSTD::swap(__z, __x); - __s += 64; - __len -= 64; + __x = __rotate(__x + __y + __v.first + std::__loadword<_Size>(__s + 8), 37) * __k1; + __y = __rotate(__y + __v.second + std::__loadword<_Size>(__s + 48), 42) * __k1; + __x ^= __w.second; + __y += __v.first + std::__loadword<_Size>(__s + 40); + __z = __rotate(__z + __w.first, 33) * __k1; + __v = __weak_hash_len_32_with_seeds(__s, __v.second * __k1, __x + __w.first); + __w = __weak_hash_len_32_with_seeds(__s + 32, __z + __w.second, __y + std::__loadword<_Size>(__s + 16)); + std::swap(__z, __x); + __s += 64; + __len -= 64; } while (__len != 0); - return __hash_len_16( - __hash_len_16(__v.first, __w.first) + __shift_mix(__y) * __k1 + __z, - __hash_len_16(__v.second, __w.second) + __x); + return __hash_len_16(__hash_len_16(__v.first, __w.first) + __shift_mix(__y) * __k1 + __z, + __hash_len_16(__v.second, __w.second) + __x); } - private: - // Some primes between 2^63 and 2^64. - static const _Size __k0 = 0xc3a5c85c97cb3127ULL; - static const _Size __k1 = 0xb492b66fbe98f273ULL; - static const _Size __k2 = 0x9ae16a3b2f90404fULL; - static const _Size __k3 = 0xc949d7c7509e6557ULL; +private: + // Some primes between 2^63 and 2^64. + static const _Size __k0 = 0xc3a5c85c97cb3127ULL; + static const _Size __k1 = 0xb492b66fbe98f273ULL; + static const _Size __k2 = 0x9ae16a3b2f90404fULL; + static const _Size __k3 = 0xc949d7c7509e6557ULL; - _LIBCPP_HIDE_FROM_ABI - static _Size __rotate(_Size __val, int __shift) { + _LIBCPP_HIDE_FROM_ABI static _Size __rotate(_Size __val, int __shift) { return __shift == 0 ? __val : ((__val >> __shift) | (__val << (64 - __shift))); } - _LIBCPP_HIDE_FROM_ABI - static _Size __rotate_by_at_least_1(_Size __val, int __shift) { + _LIBCPP_HIDE_FROM_ABI static _Size __rotate_by_at_least_1(_Size __val, int __shift) { return (__val >> __shift) | (__val << (64 - __shift)); } - _LIBCPP_HIDE_FROM_ABI - static _Size __shift_mix(_Size __val) { - return __val ^ (__val >> 47); - } + _LIBCPP_HIDE_FROM_ABI static _Size __shift_mix(_Size __val) { return __val ^ (__val >> 47); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK - static _Size __hash_len_16(_Size __u, _Size __v) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK static _Size __hash_len_16(_Size __u, _Size __v) { const _Size __mul = 0x9ddfea08eb382d69ULL; - _Size __a = (__u ^ __v) * __mul; + _Size __a = (__u ^ __v) * __mul; __a ^= (__a >> 47); _Size __b = (__v ^ __a) * __mul; __b ^= (__b >> 47); @@ -169,8 +148,8 @@ struct __murmur2_or_cityhash<_Size, 64> return __b; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK - static _Size __hash_len_0_to_16(const char* __s, _Size __len) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK static _Size + __hash_len_0_to_16(const char* __s, _Size __len) { if (__len > 8) { const _Size __a = std::__loadword<_Size>(__s); const _Size __b = std::__loadword<_Size>(__s + __len - 8); @@ -189,32 +168,29 @@ struct __murmur2_or_cityhash<_Size, 64> const unsigned char __a = static_cast(__s[0]); const unsigned char __b = static_cast(__s[__len >> 1]); const unsigned char __c = static_cast(__s[__len - 1]); - const uint32_t __y = static_cast(__a) + - (static_cast(__b) << 8); - const uint32_t __z = __len + (static_cast(__c) << 2); + const uint32_t __y = static_cast(__a) + (static_cast(__b) << 8); + const uint32_t __z = __len + (static_cast(__c) << 2); return __shift_mix(__y * __k2 ^ __z * __k3) * __k2; } return __k2; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK - static _Size __hash_len_17_to_32(const char *__s, _Size __len) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK static _Size + __hash_len_17_to_32(const char* __s, _Size __len) { const _Size __a = std::__loadword<_Size>(__s) * __k1; const _Size __b = std::__loadword<_Size>(__s + 8); const _Size __c = std::__loadword<_Size>(__s + __len - 8) * __k2; const _Size __d = std::__loadword<_Size>(__s + __len - 16) * __k0; - return __hash_len_16(__rotate(__a - __b, 43) + __rotate(__c, 30) + __d, - __a + __rotate(__b ^ __k3, 20) - __c + __len); + return __hash_len_16( + __rotate(__a - __b, 43) + __rotate(__c, 30) + __d, __a + __rotate(__b ^ __k3, 20) - __c + __len); } // Return a 16-byte hash for 48 bytes. Quick and dirty. // Callers do best to use "random-looking" values for a and b. - _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK - static pair<_Size, _Size> __weak_hash_len_32_with_seeds( - _Size __w, _Size __x, _Size __y, _Size __z, _Size __a, _Size __b) - { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK static pair<_Size, _Size> + __weak_hash_len_32_with_seeds(_Size __w, _Size __x, _Size __y, _Size __z, _Size __a, _Size __b) { __a += __w; - __b = __rotate(__b + __a + __z, 21); + __b = __rotate(__b + __a + __z, 21); const _Size __c = __a; __a += __x; __a += __y; @@ -223,24 +199,22 @@ struct __murmur2_or_cityhash<_Size, 64> } // Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty. - _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK - static pair<_Size, _Size> __weak_hash_len_32_with_seeds( - const char* __s, _Size __a, _Size __b) - { - return __weak_hash_len_32_with_seeds(std::__loadword<_Size>(__s), - std::__loadword<_Size>(__s + 8), - std::__loadword<_Size>(__s + 16), - std::__loadword<_Size>(__s + 24), - __a, - __b); + _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK static pair<_Size, _Size> + __weak_hash_len_32_with_seeds(const char* __s, _Size __a, _Size __b) { + return __weak_hash_len_32_with_seeds( + std::__loadword<_Size>(__s), + std::__loadword<_Size>(__s + 8), + std::__loadword<_Size>(__s + 16), + std::__loadword<_Size>(__s + 24), + __a, + __b); } // Return an 8-byte hash for 33 to 64 bytes. - _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK - static _Size __hash_len_33_to_64(const char *__s, size_t __len) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK static _Size + __hash_len_33_to_64(const char* __s, size_t __len) { _Size __z = std::__loadword<_Size>(__s + 24); - _Size __a = std::__loadword<_Size>(__s) + - (__len + std::__loadword<_Size>(__s + __len - 16)) * __k0; + _Size __a = std::__loadword<_Size>(__s) + (__len + std::__loadword<_Size>(__s + __len - 16)) * __k0; _Size __b = __rotate(__a + __z, 52); _Size __c = __rotate(__a, 37); __a += std::__loadword<_Size>(__s + 8); @@ -248,7 +222,7 @@ struct __murmur2_or_cityhash<_Size, 64> __a += std::__loadword<_Size>(__s + 16); _Size __vf = __a + __z; _Size __vs = __b + __rotate(__a, 31) + __c; - __a = std::__loadword<_Size>(__s + 16) + std::__loadword<_Size>(__s + __len - 32); + __a = std::__loadword<_Size>(__s + 16) + std::__loadword<_Size>(__s + __len - 32); __z += std::__loadword<_Size>(__s + __len - 8); __b = __rotate(__a + __z, 52); __c = __rotate(__a, 37); @@ -257,7 +231,7 @@ struct __murmur2_or_cityhash<_Size, 64> __a += std::__loadword<_Size>(__s + __len - 16); _Size __wf = __a + __z; _Size __ws = __b + __rotate(__a, 31) + __c; - _Size __r = __shift_mix((__vf + __ws) * __k2 + (__wf + __vs) * __k0); + _Size __r = __shift_mix((__vf + __ws) * __k2 + (__wf + __vs) * __k0); return __shift_mix(__r * __k0 + __vs) * __k2; } }; @@ -266,104 +240,76 @@ template struct __scalar_hash; template -struct __scalar_hash<_Tp, 0> - : public __unary_function<_Tp, size_t> -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(_Tp __v) const _NOEXCEPT - { - union - { - _Tp __t; - size_t __a; - } __u; - __u.__a = 0; - __u.__t = __v; - return __u.__a; - } +struct __scalar_hash<_Tp, 0> : public __unary_function<_Tp, size_t> { + _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT { + union { + _Tp __t; + size_t __a; + } __u; + __u.__a = 0; + __u.__t = __v; + return __u.__a; + } }; template -struct __scalar_hash<_Tp, 1> - : public __unary_function<_Tp, size_t> -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(_Tp __v) const _NOEXCEPT - { - union - { - _Tp __t; - size_t __a; - } __u; - __u.__t = __v; - return __u.__a; - } +struct __scalar_hash<_Tp, 1> : public __unary_function<_Tp, size_t> { + _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT { + union { + _Tp __t; + size_t __a; + } __u; + __u.__t = __v; + return __u.__a; + } }; template -struct __scalar_hash<_Tp, 2> - : public __unary_function<_Tp, size_t> -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(_Tp __v) const _NOEXCEPT - { - union - { - _Tp __t; - struct - { - size_t __a; - size_t __b; - } __s; - } __u; - __u.__t = __v; - return __murmur2_or_cityhash()(&__u, sizeof(__u)); - } +struct __scalar_hash<_Tp, 2> : public __unary_function<_Tp, size_t> { + _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT { + union { + _Tp __t; + struct { + size_t __a; + size_t __b; + } __s; + } __u; + __u.__t = __v; + return __murmur2_or_cityhash()(&__u, sizeof(__u)); + } }; template -struct __scalar_hash<_Tp, 3> - : public __unary_function<_Tp, size_t> -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(_Tp __v) const _NOEXCEPT - { - union - { - _Tp __t; - struct - { - size_t __a; - size_t __b; - size_t __c; - } __s; - } __u; - __u.__t = __v; - return __murmur2_or_cityhash()(&__u, sizeof(__u)); - } +struct __scalar_hash<_Tp, 3> : public __unary_function<_Tp, size_t> { + _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT { + union { + _Tp __t; + struct { + size_t __a; + size_t __b; + size_t __c; + } __s; + } __u; + __u.__t = __v; + return __murmur2_or_cityhash()(&__u, sizeof(__u)); + } }; template -struct __scalar_hash<_Tp, 4> - : public __unary_function<_Tp, size_t> -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(_Tp __v) const _NOEXCEPT - { - union - { - _Tp __t; - struct - { - size_t __a; - size_t __b; - size_t __c; - size_t __d; - } __s; - } __u; - __u.__t = __v; - return __murmur2_or_cityhash()(&__u, sizeof(__u)); - } +struct __scalar_hash<_Tp, 4> : public __unary_function<_Tp, size_t> { + _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT { + union { + _Tp __t; + struct { + size_t __a; + size_t __b; + size_t __c; + size_t __d; + } __s; + } __u; + __u.__t = __v; + return __murmur2_or_cityhash()(&__u, sizeof(__u)); + } }; struct _PairT { @@ -371,314 +317,223 @@ struct _PairT { size_t second; }; -_LIBCPP_HIDE_FROM_ABI -inline size_t __hash_combine(size_t __lhs, size_t __rhs) _NOEXCEPT { - typedef __scalar_hash<_PairT> _HashT; - const _PairT __p = {__lhs, __rhs}; - return _HashT()(__p); +_LIBCPP_HIDE_FROM_ABI inline size_t __hash_combine(size_t __lhs, size_t __rhs) _NOEXCEPT { + typedef __scalar_hash<_PairT> _HashT; + const _PairT __p = {__lhs, __rhs}; + return _HashT()(__p); } -template -struct _LIBCPP_TEMPLATE_VIS hash<_Tp*> - : public __unary_function<_Tp*, size_t> -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(_Tp* __v) const _NOEXCEPT - { - union - { - _Tp* __t; - size_t __a; - } __u; - __u.__t = __v; - return __murmur2_or_cityhash()(&__u, sizeof(__u)); - } +template +struct _LIBCPP_TEMPLATE_VIS hash<_Tp*> : public __unary_function<_Tp*, size_t> { + _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp* __v) const _NOEXCEPT { + union { + _Tp* __t; + size_t __a; + } __u; + __u.__t = __v; + return __murmur2_or_cityhash()(&__u, sizeof(__u)); + } }; template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __unary_function -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(bool __v) const _NOEXCEPT {return static_cast(__v);} +struct _LIBCPP_TEMPLATE_VIS hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(bool __v) const _NOEXCEPT { return static_cast(__v); } }; template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __unary_function -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(char __v) const _NOEXCEPT {return static_cast(__v);} +struct _LIBCPP_TEMPLATE_VIS hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(char __v) const _NOEXCEPT { return static_cast(__v); } }; template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __unary_function -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(signed char __v) const _NOEXCEPT {return static_cast(__v);} +struct _LIBCPP_TEMPLATE_VIS hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(signed char __v) const _NOEXCEPT { return static_cast(__v); } }; template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __unary_function -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(unsigned char __v) const _NOEXCEPT {return static_cast(__v);} +struct _LIBCPP_TEMPLATE_VIS hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(unsigned char __v) const _NOEXCEPT { return static_cast(__v); } }; #ifndef _LIBCPP_HAS_NO_CHAR8_T template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __unary_function -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(char8_t __v) const _NOEXCEPT {return static_cast(__v);} +struct _LIBCPP_TEMPLATE_VIS hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(char8_t __v) const _NOEXCEPT { return static_cast(__v); } }; #endif // !_LIBCPP_HAS_NO_CHAR8_T template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __unary_function -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(char16_t __v) const _NOEXCEPT {return static_cast(__v);} +struct _LIBCPP_TEMPLATE_VIS hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(char16_t __v) const _NOEXCEPT { return static_cast(__v); } }; template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __unary_function -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(char32_t __v) const _NOEXCEPT {return static_cast(__v);} +struct _LIBCPP_TEMPLATE_VIS hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(char32_t __v) const _NOEXCEPT { return static_cast(__v); } }; #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __unary_function -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(wchar_t __v) const _NOEXCEPT {return static_cast(__v);} +struct _LIBCPP_TEMPLATE_VIS hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(wchar_t __v) const _NOEXCEPT { return static_cast(__v); } }; #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __unary_function -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(short __v) const _NOEXCEPT {return static_cast(__v);} +struct _LIBCPP_TEMPLATE_VIS hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(short __v) const _NOEXCEPT { return static_cast(__v); } }; template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __unary_function -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(unsigned short __v) const _NOEXCEPT {return static_cast(__v);} +struct _LIBCPP_TEMPLATE_VIS hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(unsigned short __v) const _NOEXCEPT { return static_cast(__v); } }; template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __unary_function -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(int __v) const _NOEXCEPT {return static_cast(__v);} +struct _LIBCPP_TEMPLATE_VIS hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(int __v) const _NOEXCEPT { return static_cast(__v); } }; template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __unary_function -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(unsigned int __v) const _NOEXCEPT {return static_cast(__v);} +struct _LIBCPP_TEMPLATE_VIS hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(unsigned int __v) const _NOEXCEPT { return static_cast(__v); } }; template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __unary_function -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(long __v) const _NOEXCEPT {return static_cast(__v);} +struct _LIBCPP_TEMPLATE_VIS hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(long __v) const _NOEXCEPT { return static_cast(__v); } }; template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __unary_function -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(unsigned long __v) const _NOEXCEPT {return static_cast(__v);} +struct _LIBCPP_TEMPLATE_VIS hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(unsigned long __v) const _NOEXCEPT { return static_cast(__v); } }; template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __scalar_hash -{ -}; +struct _LIBCPP_TEMPLATE_VIS hash : public __scalar_hash {}; template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __scalar_hash -{ -}; +struct _LIBCPP_TEMPLATE_VIS hash : public __scalar_hash {}; #ifndef _LIBCPP_HAS_NO_INT128 template <> -struct _LIBCPP_TEMPLATE_VIS hash<__int128_t> - : public __scalar_hash<__int128_t> -{ -}; +struct _LIBCPP_TEMPLATE_VIS hash<__int128_t> : public __scalar_hash<__int128_t> {}; template <> -struct _LIBCPP_TEMPLATE_VIS hash<__uint128_t> - : public __scalar_hash<__uint128_t> -{ -}; +struct _LIBCPP_TEMPLATE_VIS hash<__uint128_t> : public __scalar_hash<__uint128_t> {}; #endif template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __scalar_hash -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(float __v) const _NOEXCEPT - { - // -0.0 and 0.0 should return same hash - if (__v == 0.0f) - return 0; - return __scalar_hash::operator()(__v); - } +struct _LIBCPP_TEMPLATE_VIS hash : public __scalar_hash { + _LIBCPP_HIDE_FROM_ABI size_t operator()(float __v) const _NOEXCEPT { + // -0.0 and 0.0 should return same hash + if (__v == 0.0f) + return 0; + return __scalar_hash::operator()(__v); + } }; template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __scalar_hash -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(double __v) const _NOEXCEPT - { - // -0.0 and 0.0 should return same hash - if (__v == 0.0) - return 0; - return __scalar_hash::operator()(__v); - } +struct _LIBCPP_TEMPLATE_VIS hash : public __scalar_hash { + _LIBCPP_HIDE_FROM_ABI size_t operator()(double __v) const _NOEXCEPT { + // -0.0 and 0.0 should return same hash + if (__v == 0.0) + return 0; + return __scalar_hash::operator()(__v); + } }; template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __scalar_hash -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(long double __v) const _NOEXCEPT - { - // -0.0 and 0.0 should return same hash - if (__v == 0.0L) - return 0; +struct _LIBCPP_TEMPLATE_VIS hash : public __scalar_hash { + _LIBCPP_HIDE_FROM_ABI size_t operator()(long double __v) const _NOEXCEPT { + // -0.0 and 0.0 should return same hash + if (__v == 0.0L) + return 0; #if defined(__i386__) || (defined(__x86_64__) && defined(__ILP32__)) - // Zero out padding bits - union - { - long double __t; - struct - { - size_t __a; - size_t __b; - size_t __c; - size_t __d; - } __s; - } __u; - __u.__s.__a = 0; - __u.__s.__b = 0; - __u.__s.__c = 0; - __u.__s.__d = 0; - __u.__t = __v; - return __u.__s.__a ^ __u.__s.__b ^ __u.__s.__c ^ __u.__s.__d; + // Zero out padding bits + union { + long double __t; + struct { + size_t __a; + size_t __b; + size_t __c; + size_t __d; + } __s; + } __u; + __u.__s.__a = 0; + __u.__s.__b = 0; + __u.__s.__c = 0; + __u.__s.__d = 0; + __u.__t = __v; + return __u.__s.__a ^ __u.__s.__b ^ __u.__s.__c ^ __u.__s.__d; #elif defined(__x86_64__) - // Zero out padding bits - union - { - long double __t; - struct - { - size_t __a; - size_t __b; - } __s; - } __u; - __u.__s.__a = 0; - __u.__s.__b = 0; - __u.__t = __v; - return __u.__s.__a ^ __u.__s.__b; + // Zero out padding bits + union { + long double __t; + struct { + size_t __a; + size_t __b; + } __s; + } __u; + __u.__s.__a = 0; + __u.__s.__b = 0; + __u.__t = __v; + return __u.__s.__a ^ __u.__s.__b; #else - return __scalar_hash::operator()(__v); + return __scalar_hash::operator()(__v); #endif - } + } }; template ::value> -struct _LIBCPP_TEMPLATE_VIS __enum_hash - : public __unary_function<_Tp, size_t> -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(_Tp __v) const _NOEXCEPT - { - typedef typename underlying_type<_Tp>::type type; - return hash()(static_cast(__v)); - } +struct _LIBCPP_TEMPLATE_VIS __enum_hash : public __unary_function<_Tp, size_t> { + _LIBCPP_HIDE_FROM_ABI size_t operator()(_Tp __v) const _NOEXCEPT { + typedef typename underlying_type<_Tp>::type type; + return hash()(static_cast(__v)); + } }; template struct _LIBCPP_TEMPLATE_VIS __enum_hash<_Tp, false> { - __enum_hash() = delete; - __enum_hash(__enum_hash const&) = delete; - __enum_hash& operator=(__enum_hash const&) = delete; + __enum_hash() = delete; + __enum_hash(__enum_hash const&) = delete; + __enum_hash& operator=(__enum_hash const&) = delete; }; template -struct _LIBCPP_TEMPLATE_VIS hash : public __enum_hash<_Tp> -{ -}; +struct _LIBCPP_TEMPLATE_VIS hash : public __enum_hash<_Tp> {}; #if _LIBCPP_STD_VER >= 17 template <> -struct _LIBCPP_TEMPLATE_VIS hash - : public __unary_function -{ - _LIBCPP_HIDE_FROM_ABI - size_t operator()(nullptr_t) const _NOEXCEPT { - return 662607004ull; - } +struct _LIBCPP_TEMPLATE_VIS hash : public __unary_function { + _LIBCPP_HIDE_FROM_ABI size_t operator()(nullptr_t) const _NOEXCEPT { return 662607004ull; } }; #endif #ifndef _LIBCPP_CXX03_LANG template -using __check_hash_requirements _LIBCPP_NODEBUG = integral_constant::value && - is_move_constructible<_Hash>::value && - __invokable_r::value ->; +using __check_hash_requirements _LIBCPP_NODEBUG = + integral_constant::value && is_move_constructible<_Hash>::value && + __invokable_r::value >; template > -using __has_enabled_hash _LIBCPP_NODEBUG = integral_constant::value && - is_default_constructible<_Hash>::value ->; +using __has_enabled_hash _LIBCPP_NODEBUG = + integral_constant::value && is_default_constructible<_Hash>::value >; -#if _LIBCPP_STD_VER >= 17 +# if _LIBCPP_STD_VER >= 17 template using __enable_hash_helper_imp _LIBCPP_NODEBUG = _Type; -template -using __enable_hash_helper _LIBCPP_NODEBUG = __enable_hash_helper_imp<_Type, - typename enable_if<__all<__has_enabled_hash<_Keys>::value...>::value>::type ->; -#else -template +template +using __enable_hash_helper _LIBCPP_NODEBUG = + __enable_hash_helper_imp<_Type, __enable_if_t<__all<__has_enabled_hash<_Keys>::value...>::value> >; +# else +template using __enable_hash_helper _LIBCPP_NODEBUG = _Type; -#endif +# endif #endif // !_LIBCPP_CXX03_LANG diff --git a/third_party/libcxx/__functional/identity.h b/third_party/libcxx/__functional/identity.h index 5dffedf67..8468de3da 100644 --- a/third_party/libcxx/__functional/identity.h +++ b/third_party/libcxx/__functional/identity.h @@ -11,6 +11,7 @@ #define _LIBCPP___FUNCTIONAL_IDENTITY_H #include <__config> +#include <__fwd/functional.h> #include <__type_traits/integral_constant.h> #include <__utility/forward.h> @@ -34,21 +35,28 @@ struct __identity { template <> struct __is_identity<__identity> : true_type {}; +template <> +struct __is_identity > : true_type {}; +template <> +struct __is_identity > : true_type {}; #if _LIBCPP_STD_VER >= 20 struct identity { - template - _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator()(_Tp&& __t) const noexcept - { - return _VSTD::forward<_Tp>(__t); - } + template + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator()(_Tp&& __t) const noexcept { + return std::forward<_Tp>(__t); + } - using is_transparent = void; + using is_transparent = void; }; template <> struct __is_identity : true_type {}; +template <> +struct __is_identity > : true_type {}; +template <> +struct __is_identity > : true_type {}; #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__functional/invoke.h b/third_party/libcxx/__functional/invoke.h index a7dd31107..ef4bf25f0 100644 --- a/third_party/libcxx/__functional/invoke.h +++ b/third_party/libcxx/__functional/invoke.h @@ -22,12 +22,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 17 -template +template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 invoke_result_t<_Fn, _Args...> -invoke(_Fn&& __f, _Args&&... __args) - noexcept(is_nothrow_invocable_v<_Fn, _Args...>) -{ - return _VSTD::__invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...); +invoke(_Fn&& __f, _Args&&... __args) noexcept(is_nothrow_invocable_v<_Fn, _Args...>) { + return std::__invoke(std::forward<_Fn>(__f), std::forward<_Args>(__args)...); } #endif // _LIBCPP_STD_VER >= 17 @@ -37,17 +35,17 @@ template requires is_invocable_r_v<_Result, _Fn, _Args...> _LIBCPP_HIDE_FROM_ABI constexpr _Result invoke_r(_Fn&& __f, _Args&&... __args) noexcept(is_nothrow_invocable_r_v<_Result, _Fn, _Args...>) { - if constexpr (is_void_v<_Result>) { - static_cast(std::invoke(std::forward<_Fn>(__f), std::forward<_Args>(__args)...)); - } else { - // TODO: Use reference_converts_from_temporary_v once implemented - // using _ImplicitInvokeResult = invoke_result_t<_Fn, _Args...>; - // static_assert(!reference_converts_from_temporary_v<_Result, _ImplicitInvokeResult>, - static_assert(true, - "Returning from invoke_r would bind a temporary object to the reference return type, " - "which would result in a dangling reference."); - return std::invoke(std::forward<_Fn>(__f), std::forward<_Args>(__args)...); - } + if constexpr (is_void_v<_Result>) { + static_cast(std::invoke(std::forward<_Fn>(__f), std::forward<_Args>(__args)...)); + } else { + // TODO: Use reference_converts_from_temporary_v once implemented + // using _ImplicitInvokeResult = invoke_result_t<_Fn, _Args...>; + // static_assert(!reference_converts_from_temporary_v<_Result, _ImplicitInvokeResult>, + static_assert(true, + "Returning from invoke_r would bind a temporary object to the reference return type, " + "which would result in a dangling reference."); + return std::invoke(std::forward<_Fn>(__f), std::forward<_Args>(__args)...); + } } #endif diff --git a/third_party/libcxx/__functional/is_transparent.h b/third_party/libcxx/__functional/is_transparent.h index c539a07d6..b2d62f2e3 100644 --- a/third_party/libcxx/__functional/is_transparent.h +++ b/third_party/libcxx/__functional/is_transparent.h @@ -11,7 +11,6 @@ #define _LIBCPP___FUNCTIONAL_IS_TRANSPARENT #include <__config> -#include <__type_traits/integral_constant.h> #include <__type_traits/void_t.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -23,11 +22,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 14 template -struct __is_transparent : false_type {}; +inline const bool __is_transparent_v = false; template -struct __is_transparent<_Tp, _Up, __void_t > - : true_type {}; +inline const bool __is_transparent_v<_Tp, _Up, __void_t > = true; #endif diff --git a/third_party/libcxx/__functional/mem_fn.h b/third_party/libcxx/__functional/mem_fn.h index fe221dd12..ee07a7177 100644 --- a/third_party/libcxx/__functional/mem_fn.h +++ b/third_party/libcxx/__functional/mem_fn.h @@ -23,34 +23,30 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -class __mem_fn : public __weak_result_type<_Tp> -{ +class __mem_fn : public __weak_result_type<_Tp> { public: - // types - typedef _Tp type; + // types + typedef _Tp type; + private: - type __f_; + type __f_; public: - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 - __mem_fn(type __f) _NOEXCEPT : __f_(__f) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __mem_fn(type __f) _NOEXCEPT : __f_(__f) {} - // invoke - template - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 + // invoke + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 - typename __invoke_return::type - operator() (_ArgTypes&&... __args) const { - return std::__invoke(__f_, std::forward<_ArgTypes>(__args)...); - } + typename __invoke_return::type + operator()(_ArgTypes&&... __args) const { + return std::__invoke(__f_, std::forward<_ArgTypes>(__args)...); + } }; -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -__mem_fn<_Rp _Tp::*> -mem_fn(_Rp _Tp::* __pm) _NOEXCEPT -{ - return __mem_fn<_Rp _Tp::*>(__pm); +template +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __mem_fn<_Rp _Tp::*> mem_fn(_Rp _Tp::*__pm) _NOEXCEPT { + return __mem_fn<_Rp _Tp::*>(__pm); } _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__functional/mem_fun_ref.h b/third_party/libcxx/__functional/mem_fun_ref.h index 65aab0696..c344420b0 100644 --- a/third_party/libcxx/__functional/mem_fun_ref.h +++ b/third_party/libcxx/__functional/mem_fun_ref.h @@ -22,149 +22,122 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) -template -class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun_t - : public __unary_function<_Tp*, _Sp> -{ - _Sp (_Tp::*__p_)(); -public: - _LIBCPP_INLINE_VISIBILITY explicit mem_fun_t(_Sp (_Tp::*__p)()) - : __p_(__p) {} - _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp* __p) const - {return (__p->*__p_)();} -}; - -template -class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun1_t - : public __binary_function<_Tp*, _Ap, _Sp> -{ - _Sp (_Tp::*__p_)(_Ap); -public: - _LIBCPP_INLINE_VISIBILITY explicit mem_fun1_t(_Sp (_Tp::*__p)(_Ap)) - : __p_(__p) {} - _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp* __p, _Ap __x) const - {return (__p->*__p_)(__x);} -}; - -template -_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY -mem_fun_t<_Sp,_Tp> -mem_fun(_Sp (_Tp::*__f)()) - {return mem_fun_t<_Sp,_Tp>(__f);} - -template -_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY -mem_fun1_t<_Sp,_Tp,_Ap> -mem_fun(_Sp (_Tp::*__f)(_Ap)) - {return mem_fun1_t<_Sp,_Tp,_Ap>(__f);} - -template -class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun_ref_t - : public __unary_function<_Tp, _Sp> -{ - _Sp (_Tp::*__p_)(); -public: - _LIBCPP_INLINE_VISIBILITY explicit mem_fun_ref_t(_Sp (_Tp::*__p)()) - : __p_(__p) {} - _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp& __p) const - {return (__p.*__p_)();} -}; - -template -class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun1_ref_t - : public __binary_function<_Tp, _Ap, _Sp> -{ - _Sp (_Tp::*__p_)(_Ap); -public: - _LIBCPP_INLINE_VISIBILITY explicit mem_fun1_ref_t(_Sp (_Tp::*__p)(_Ap)) - : __p_(__p) {} - _LIBCPP_INLINE_VISIBILITY _Sp operator()(_Tp& __p, _Ap __x) const - {return (__p.*__p_)(__x);} -}; - -template -_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY -mem_fun_ref_t<_Sp,_Tp> -mem_fun_ref(_Sp (_Tp::*__f)()) - {return mem_fun_ref_t<_Sp,_Tp>(__f);} - -template -_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY -mem_fun1_ref_t<_Sp,_Tp,_Ap> -mem_fun_ref(_Sp (_Tp::*__f)(_Ap)) - {return mem_fun1_ref_t<_Sp,_Tp,_Ap>(__f);} - template -class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun_t - : public __unary_function -{ - _Sp (_Tp::*__p_)() const; +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun_t : public __unary_function<_Tp*, _Sp> { + _Sp (_Tp::*__p_)(); + public: - _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun_t(_Sp (_Tp::*__p)() const) - : __p_(__p) {} - _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp* __p) const - {return (__p->*__p_)();} + _LIBCPP_HIDE_FROM_ABI explicit mem_fun_t(_Sp (_Tp::*__p)()) : __p_(__p) {} + _LIBCPP_HIDE_FROM_ABI _Sp operator()(_Tp* __p) const { return (__p->*__p_)(); } }; template -class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun1_t - : public __binary_function -{ - _Sp (_Tp::*__p_)(_Ap) const; +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun1_t : public __binary_function<_Tp*, _Ap, _Sp> { + _Sp (_Tp::*__p_)(_Ap); + public: - _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun1_t(_Sp (_Tp::*__p)(_Ap) const) - : __p_(__p) {} - _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp* __p, _Ap __x) const - {return (__p->*__p_)(__x);} + _LIBCPP_HIDE_FROM_ABI explicit mem_fun1_t(_Sp (_Tp::*__p)(_Ap)) : __p_(__p) {} + _LIBCPP_HIDE_FROM_ABI _Sp operator()(_Tp* __p, _Ap __x) const { return (__p->*__p_)(__x); } }; template -_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY -const_mem_fun_t<_Sp,_Tp> -mem_fun(_Sp (_Tp::*__f)() const) - {return const_mem_fun_t<_Sp,_Tp>(__f);} +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI mem_fun_t<_Sp, _Tp> mem_fun(_Sp (_Tp::*__f)()) { + return mem_fun_t<_Sp, _Tp>(__f); +} template -_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY -const_mem_fun1_t<_Sp,_Tp,_Ap> -mem_fun(_Sp (_Tp::*__f)(_Ap) const) - {return const_mem_fun1_t<_Sp,_Tp,_Ap>(__f);} +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI mem_fun1_t<_Sp, _Tp, _Ap> mem_fun(_Sp (_Tp::*__f)(_Ap)) { + return mem_fun1_t<_Sp, _Tp, _Ap>(__f); +} template -class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun_ref_t - : public __unary_function<_Tp, _Sp> -{ - _Sp (_Tp::*__p_)() const; +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun_ref_t : public __unary_function<_Tp, _Sp> { + _Sp (_Tp::*__p_)(); + public: - _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun_ref_t(_Sp (_Tp::*__p)() const) - : __p_(__p) {} - _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp& __p) const - {return (__p.*__p_)();} + _LIBCPP_HIDE_FROM_ABI explicit mem_fun_ref_t(_Sp (_Tp::*__p)()) : __p_(__p) {} + _LIBCPP_HIDE_FROM_ABI _Sp operator()(_Tp& __p) const { return (__p.*__p_)(); } }; template -class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun1_ref_t - : public __binary_function<_Tp, _Ap, _Sp> -{ - _Sp (_Tp::*__p_)(_Ap) const; +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 mem_fun1_ref_t : public __binary_function<_Tp, _Ap, _Sp> { + _Sp (_Tp::*__p_)(_Ap); + public: - _LIBCPP_INLINE_VISIBILITY explicit const_mem_fun1_ref_t(_Sp (_Tp::*__p)(_Ap) const) - : __p_(__p) {} - _LIBCPP_INLINE_VISIBILITY _Sp operator()(const _Tp& __p, _Ap __x) const - {return (__p.*__p_)(__x);} + _LIBCPP_HIDE_FROM_ABI explicit mem_fun1_ref_t(_Sp (_Tp::*__p)(_Ap)) : __p_(__p) {} + _LIBCPP_HIDE_FROM_ABI _Sp operator()(_Tp& __p, _Ap __x) const { return (__p.*__p_)(__x); } }; template -_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY -const_mem_fun_ref_t<_Sp,_Tp> -mem_fun_ref(_Sp (_Tp::*__f)() const) - {return const_mem_fun_ref_t<_Sp,_Tp>(__f);} +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI mem_fun_ref_t<_Sp, _Tp> mem_fun_ref(_Sp (_Tp::*__f)()) { + return mem_fun_ref_t<_Sp, _Tp>(__f); +} template -_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY -const_mem_fun1_ref_t<_Sp,_Tp,_Ap> -mem_fun_ref(_Sp (_Tp::*__f)(_Ap) const) - {return const_mem_fun1_ref_t<_Sp,_Tp,_Ap>(__f);} +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI mem_fun1_ref_t<_Sp, _Tp, _Ap> +mem_fun_ref(_Sp (_Tp::*__f)(_Ap)) { + return mem_fun1_ref_t<_Sp, _Tp, _Ap>(__f); +} + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun_t : public __unary_function { + _Sp (_Tp::*__p_)() const; + +public: + _LIBCPP_HIDE_FROM_ABI explicit const_mem_fun_t(_Sp (_Tp::*__p)() const) : __p_(__p) {} + _LIBCPP_HIDE_FROM_ABI _Sp operator()(const _Tp* __p) const { return (__p->*__p_)(); } +}; + +template +class _LIBCPP_TEMPLATE_VIS +_LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun1_t : public __binary_function { + _Sp (_Tp::*__p_)(_Ap) const; + +public: + _LIBCPP_HIDE_FROM_ABI explicit const_mem_fun1_t(_Sp (_Tp::*__p)(_Ap) const) : __p_(__p) {} + _LIBCPP_HIDE_FROM_ABI _Sp operator()(const _Tp* __p, _Ap __x) const { return (__p->*__p_)(__x); } +}; + +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI const_mem_fun_t<_Sp, _Tp> mem_fun(_Sp (_Tp::*__f)() const) { + return const_mem_fun_t<_Sp, _Tp>(__f); +} + +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI const_mem_fun1_t<_Sp, _Tp, _Ap> +mem_fun(_Sp (_Tp::*__f)(_Ap) const) { + return const_mem_fun1_t<_Sp, _Tp, _Ap>(__f); +} + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun_ref_t : public __unary_function<_Tp, _Sp> { + _Sp (_Tp::*__p_)() const; + +public: + _LIBCPP_HIDE_FROM_ABI explicit const_mem_fun_ref_t(_Sp (_Tp::*__p)() const) : __p_(__p) {} + _LIBCPP_HIDE_FROM_ABI _Sp operator()(const _Tp& __p) const { return (__p.*__p_)(); } +}; + +template +class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 const_mem_fun1_ref_t : public __binary_function<_Tp, _Ap, _Sp> { + _Sp (_Tp::*__p_)(_Ap) const; + +public: + _LIBCPP_HIDE_FROM_ABI explicit const_mem_fun1_ref_t(_Sp (_Tp::*__p)(_Ap) const) : __p_(__p) {} + _LIBCPP_HIDE_FROM_ABI _Sp operator()(const _Tp& __p, _Ap __x) const { return (__p.*__p_)(__x); } +}; + +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI const_mem_fun_ref_t<_Sp, _Tp> +mem_fun_ref(_Sp (_Tp::*__f)() const) { + return const_mem_fun_ref_t<_Sp, _Tp>(__f); +} + +template +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI const_mem_fun1_ref_t<_Sp, _Tp, _Ap> +mem_fun_ref(_Sp (_Tp::*__f)(_Ap) const) { + return const_mem_fun1_ref_t<_Sp, _Tp, _Ap>(__f); +} #endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) diff --git a/third_party/libcxx/__functional/not_fn.h b/third_party/libcxx/__functional/not_fn.h index 0cdb1b7e2..4b3ce5524 100644 --- a/third_party/libcxx/__functional/not_fn.h +++ b/third_party/libcxx/__functional/not_fn.h @@ -16,7 +16,6 @@ #include <__type_traits/decay.h> #include <__type_traits/enable_if.h> #include <__type_traits/is_constructible.h> -#include <__type_traits/is_move_constructible.h> #include <__utility/forward.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -28,26 +27,23 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 17 struct __not_fn_op { - template - _LIBCPP_HIDE_FROM_ABI - _LIBCPP_CONSTEXPR_SINCE_CXX20 auto operator()(_Args&&... __args) const - noexcept(noexcept(!_VSTD::invoke(_VSTD::forward<_Args>(__args)...))) - -> decltype( !_VSTD::invoke(_VSTD::forward<_Args>(__args)...)) - { return !_VSTD::invoke(_VSTD::forward<_Args>(__args)...); } + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 auto operator()(_Args&&... __args) const + noexcept(noexcept(!std::invoke(std::forward<_Args>(__args)...))) + -> decltype(!std::invoke(std::forward<_Args>(__args)...)) { + return !std::invoke(std::forward<_Args>(__args)...); + } }; template struct __not_fn_t : __perfect_forward<__not_fn_op, _Fn> { - using __perfect_forward<__not_fn_op, _Fn>::__perfect_forward; + using __perfect_forward<__not_fn_op, _Fn>::__perfect_forward; }; -template , _Fn> && - is_move_constructible_v> ->> -_LIBCPP_HIDE_FROM_ABI -_LIBCPP_CONSTEXPR_SINCE_CXX20 auto not_fn(_Fn&& __f) { - return __not_fn_t>(_VSTD::forward<_Fn>(__f)); +template , _Fn> && is_move_constructible_v> >> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 auto not_fn(_Fn&& __f) { + return __not_fn_t>(std::forward<_Fn>(__f)); } #endif // _LIBCPP_STD_VER >= 17 diff --git a/third_party/libcxx/__functional/operations.h b/third_party/libcxx/__functional/operations.h index 3d0c3641b..0a6320f19 100644 --- a/third_party/libcxx/__functional/operations.h +++ b/third_party/libcxx/__functional/operations.h @@ -13,8 +13,7 @@ #include <__config> #include <__functional/binary_function.h> #include <__functional/unary_function.h> -#include <__type_traits/integral_constant.h> -#include <__type_traits/predicate_traits.h> +#include <__type_traits/desugars_to.h> #include <__utility/forward.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -30,27 +29,32 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS plus - : __binary_function<_Tp, _Tp, _Tp> -{ - typedef _Tp __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - _Tp operator()(const _Tp& __x, const _Tp& __y) const - {return __x + __y;} +struct _LIBCPP_TEMPLATE_VIS plus : __binary_function<_Tp, _Tp, _Tp> { + typedef _Tp __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { + return __x + __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(plus); +// The non-transparent std::plus specialization is only equivalent to a raw plus +// operator when we don't perform an implicit conversion when calling it. +template +inline const bool __desugars_to_v<__plus_tag, plus<_Tp>, _Tp, _Tp> = true; + +template +inline const bool __desugars_to_v<__plus_tag, plus, _Tp, _Up> = true; + #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS plus -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(_VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u))) - -> decltype( _VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) + _VSTD::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS plus { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) + std::forward<_T2>(__u))) // + -> decltype(std::forward<_T1>(__t) + std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) + std::forward<_T2>(__u); + } + typedef void is_transparent; }; #endif @@ -59,27 +63,24 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS minus - : __binary_function<_Tp, _Tp, _Tp> -{ - typedef _Tp __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - _Tp operator()(const _Tp& __x, const _Tp& __y) const - {return __x - __y;} +struct _LIBCPP_TEMPLATE_VIS minus : __binary_function<_Tp, _Tp, _Tp> { + typedef _Tp __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { + return __x - __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(minus); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS minus -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(_VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u))) - -> decltype( _VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) - _VSTD::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS minus { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) - std::forward<_T2>(__u))) // + -> decltype(std::forward<_T1>(__t) - std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) - std::forward<_T2>(__u); + } + typedef void is_transparent; }; #endif @@ -88,27 +89,24 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS multiplies - : __binary_function<_Tp, _Tp, _Tp> -{ - typedef _Tp __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - _Tp operator()(const _Tp& __x, const _Tp& __y) const - {return __x * __y;} +struct _LIBCPP_TEMPLATE_VIS multiplies : __binary_function<_Tp, _Tp, _Tp> { + typedef _Tp __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { + return __x * __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(multiplies); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS multiplies -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(_VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u))) - -> decltype( _VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) * _VSTD::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS multiplies { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) * std::forward<_T2>(__u))) // + -> decltype(std::forward<_T1>(__t) * std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) * std::forward<_T2>(__u); + } + typedef void is_transparent; }; #endif @@ -117,27 +115,24 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS divides - : __binary_function<_Tp, _Tp, _Tp> -{ - typedef _Tp __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - _Tp operator()(const _Tp& __x, const _Tp& __y) const - {return __x / __y;} +struct _LIBCPP_TEMPLATE_VIS divides : __binary_function<_Tp, _Tp, _Tp> { + typedef _Tp __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { + return __x / __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(divides); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS divides -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(_VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u))) - -> decltype( _VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) / _VSTD::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS divides { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) / std::forward<_T2>(__u))) // + -> decltype(std::forward<_T1>(__t) / std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) / std::forward<_T2>(__u); + } + typedef void is_transparent; }; #endif @@ -146,27 +141,24 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS modulus - : __binary_function<_Tp, _Tp, _Tp> -{ - typedef _Tp __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - _Tp operator()(const _Tp& __x, const _Tp& __y) const - {return __x % __y;} +struct _LIBCPP_TEMPLATE_VIS modulus : __binary_function<_Tp, _Tp, _Tp> { + typedef _Tp __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { + return __x % __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(modulus); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS modulus -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(_VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u))) - -> decltype( _VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) % _VSTD::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS modulus { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) % std::forward<_T2>(__u))) // + -> decltype(std::forward<_T1>(__t) % std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) % std::forward<_T2>(__u); + } + typedef void is_transparent; }; #endif @@ -175,27 +167,22 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS negate - : __unary_function<_Tp, _Tp> -{ - typedef _Tp __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - _Tp operator()(const _Tp& __x) const - {return -__x;} +struct _LIBCPP_TEMPLATE_VIS negate : __unary_function<_Tp, _Tp> { + typedef _Tp __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x) const { return -__x; } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(negate); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS negate -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - auto operator()(_Tp&& __x) const - noexcept(noexcept(- _VSTD::forward<_Tp>(__x))) - -> decltype( - _VSTD::forward<_Tp>(__x)) - { return - _VSTD::forward<_Tp>(__x); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS negate { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const + noexcept(noexcept(-std::forward<_Tp>(__x))) // + -> decltype(-std::forward<_Tp>(__x)) { + return -std::forward<_Tp>(__x); + } + typedef void is_transparent; }; #endif @@ -206,51 +193,43 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS bit_and - : __binary_function<_Tp, _Tp, _Tp> -{ - typedef _Tp __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - _Tp operator()(const _Tp& __x, const _Tp& __y) const - {return __x & __y;} +struct _LIBCPP_TEMPLATE_VIS bit_and : __binary_function<_Tp, _Tp, _Tp> { + typedef _Tp __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { + return __x & __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_and); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS bit_and -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(_VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u))) - -> decltype( _VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) & _VSTD::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS bit_and { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) & + std::forward<_T2>(__u))) -> decltype(std::forward<_T1>(__t) & std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) & std::forward<_T2>(__u); + } + typedef void is_transparent; }; #endif #if _LIBCPP_STD_VER >= 14 template -struct _LIBCPP_TEMPLATE_VIS bit_not - : __unary_function<_Tp, _Tp> -{ - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - _Tp operator()(const _Tp& __x) const - {return ~__x;} +struct _LIBCPP_TEMPLATE_VIS bit_not : __unary_function<_Tp, _Tp> { + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x) const { return ~__x; } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_not); template <> -struct _LIBCPP_TEMPLATE_VIS bit_not -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - auto operator()(_Tp&& __x) const - noexcept(noexcept(~_VSTD::forward<_Tp>(__x))) - -> decltype( ~_VSTD::forward<_Tp>(__x)) - { return ~_VSTD::forward<_Tp>(__x); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS bit_not { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const + noexcept(noexcept(~std::forward<_Tp>(__x))) // + -> decltype(~std::forward<_Tp>(__x)) { + return ~std::forward<_Tp>(__x); + } + typedef void is_transparent; }; #endif @@ -259,27 +238,24 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS bit_or - : __binary_function<_Tp, _Tp, _Tp> -{ - typedef _Tp __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - _Tp operator()(const _Tp& __x, const _Tp& __y) const - {return __x | __y;} +struct _LIBCPP_TEMPLATE_VIS bit_or : __binary_function<_Tp, _Tp, _Tp> { + typedef _Tp __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { + return __x | __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_or); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS bit_or -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(_VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u))) - -> decltype( _VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) | _VSTD::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS bit_or { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) | std::forward<_T2>(__u))) // + -> decltype(std::forward<_T1>(__t) | std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) | std::forward<_T2>(__u); + } + typedef void is_transparent; }; #endif @@ -288,27 +264,24 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS bit_xor - : __binary_function<_Tp, _Tp, _Tp> -{ - typedef _Tp __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - _Tp operator()(const _Tp& __x, const _Tp& __y) const - {return __x ^ __y;} +struct _LIBCPP_TEMPLATE_VIS bit_xor : __binary_function<_Tp, _Tp, _Tp> { + typedef _Tp __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp operator()(const _Tp& __x, const _Tp& __y) const { + return __x ^ __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(bit_xor); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS bit_xor -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(_VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u))) - -> decltype( _VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) ^ _VSTD::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS bit_xor { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) ^ std::forward<_T2>(__u))) // + -> decltype(std::forward<_T1>(__t) ^ std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) ^ std::forward<_T2>(__u); + } + typedef void is_transparent; }; #endif @@ -319,64 +292,59 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS equal_to - : __binary_function<_Tp, _Tp, bool> -{ - typedef bool __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - bool operator()(const _Tp& __x, const _Tp& __y) const - {return __x == __y;} +struct _LIBCPP_TEMPLATE_VIS equal_to : __binary_function<_Tp, _Tp, bool> { + typedef bool __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { + return __x == __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(equal_to); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS equal_to -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(_VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u))) - -> decltype( _VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) == _VSTD::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS equal_to { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) == std::forward<_T2>(__u))) // + -> decltype(std::forward<_T1>(__t) == std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) == std::forward<_T2>(__u); + } + typedef void is_transparent; }; #endif +// The non-transparent std::equal_to specialization is only equivalent to a raw equality +// comparison when we don't perform an implicit conversion when calling it. template -struct __is_trivial_equality_predicate, _Tp, _Tp> : true_type {}; +inline const bool __desugars_to_v<__equal_tag, equal_to<_Tp>, _Tp, _Tp> = true; -#if _LIBCPP_STD_VER >= 14 -template -struct __is_trivial_equality_predicate, _Tp, _Tp> : true_type {}; -#endif +// In the transparent case, we do not enforce that +template +inline const bool __desugars_to_v<__equal_tag, equal_to, _Tp, _Up> = true; #if _LIBCPP_STD_VER >= 14 template #else template #endif -struct _LIBCPP_TEMPLATE_VIS not_equal_to - : __binary_function<_Tp, _Tp, bool> -{ - typedef bool __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - bool operator()(const _Tp& __x, const _Tp& __y) const - {return __x != __y;} +struct _LIBCPP_TEMPLATE_VIS not_equal_to : __binary_function<_Tp, _Tp, bool> { + typedef bool __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { + return __x != __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(not_equal_to); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS not_equal_to -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(_VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u))) - -> decltype( _VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) != _VSTD::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS not_equal_to { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) != std::forward<_T2>(__u))) // + -> decltype(std::forward<_T1>(__t) != std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) != std::forward<_T2>(__u); + } + typedef void is_transparent; }; #endif @@ -385,28 +353,31 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS less - : __binary_function<_Tp, _Tp, bool> -{ - typedef bool __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - bool operator()(const _Tp& __x, const _Tp& __y) const - {return __x < __y;} +struct _LIBCPP_TEMPLATE_VIS less : __binary_function<_Tp, _Tp, bool> { + typedef bool __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { + return __x < __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(less); +template +inline const bool __desugars_to_v<__less_tag, less<_Tp>, _Tp, _Tp> = true; + #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS less -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(_VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u))) - -> decltype( _VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) < _VSTD::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS less { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) < std::forward<_T2>(__u))) // + -> decltype(std::forward<_T1>(__t) < std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) < std::forward<_T2>(__u); + } + typedef void is_transparent; }; + +template +inline const bool __desugars_to_v<__less_tag, less<>, _Tp, _Tp> = true; #endif #if _LIBCPP_STD_VER >= 14 @@ -414,27 +385,24 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS less_equal - : __binary_function<_Tp, _Tp, bool> -{ - typedef bool __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - bool operator()(const _Tp& __x, const _Tp& __y) const - {return __x <= __y;} +struct _LIBCPP_TEMPLATE_VIS less_equal : __binary_function<_Tp, _Tp, bool> { + typedef bool __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { + return __x <= __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(less_equal); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS less_equal -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(_VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u))) - -> decltype( _VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) <= _VSTD::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS less_equal { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) <= std::forward<_T2>(__u))) // + -> decltype(std::forward<_T1>(__t) <= std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) <= std::forward<_T2>(__u); + } + typedef void is_transparent; }; #endif @@ -443,27 +411,24 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS greater_equal - : __binary_function<_Tp, _Tp, bool> -{ - typedef bool __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - bool operator()(const _Tp& __x, const _Tp& __y) const - {return __x >= __y;} +struct _LIBCPP_TEMPLATE_VIS greater_equal : __binary_function<_Tp, _Tp, bool> { + typedef bool __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { + return __x >= __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(greater_equal); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS greater_equal -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(_VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u))) - -> decltype( _VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) >= _VSTD::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS greater_equal { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) >= + std::forward<_T2>(__u))) -> decltype(std::forward<_T1>(__t) >= std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) >= std::forward<_T2>(__u); + } + typedef void is_transparent; }; #endif @@ -472,27 +437,24 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS greater - : __binary_function<_Tp, _Tp, bool> -{ - typedef bool __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - bool operator()(const _Tp& __x, const _Tp& __y) const - {return __x > __y;} +struct _LIBCPP_TEMPLATE_VIS greater : __binary_function<_Tp, _Tp, bool> { + typedef bool __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { + return __x > __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(greater); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS greater -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(_VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u))) - -> decltype( _VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) > _VSTD::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS greater { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) > std::forward<_T2>(__u))) // + -> decltype(std::forward<_T1>(__t) > std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) > std::forward<_T2>(__u); + } + typedef void is_transparent; }; #endif @@ -503,27 +465,24 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS logical_and - : __binary_function<_Tp, _Tp, bool> -{ - typedef bool __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - bool operator()(const _Tp& __x, const _Tp& __y) const - {return __x && __y;} +struct _LIBCPP_TEMPLATE_VIS logical_and : __binary_function<_Tp, _Tp, bool> { + typedef bool __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { + return __x && __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_and); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS logical_and -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(_VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u))) - -> decltype( _VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) && _VSTD::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS logical_and { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) && std::forward<_T2>(__u))) // + -> decltype(std::forward<_T1>(__t) && std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) && std::forward<_T2>(__u); + } + typedef void is_transparent; }; #endif @@ -532,27 +491,22 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS logical_not - : __unary_function<_Tp, bool> -{ - typedef bool __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - bool operator()(const _Tp& __x) const - {return !__x;} +struct _LIBCPP_TEMPLATE_VIS logical_not : __unary_function<_Tp, bool> { + typedef bool __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x) const { return !__x; } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_not); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS logical_not -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - auto operator()(_Tp&& __x) const - noexcept(noexcept(!_VSTD::forward<_Tp>(__x))) - -> decltype( !_VSTD::forward<_Tp>(__x)) - { return !_VSTD::forward<_Tp>(__x); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS logical_not { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_Tp&& __x) const + noexcept(noexcept(!std::forward<_Tp>(__x))) // + -> decltype(!std::forward<_Tp>(__x)) { + return !std::forward<_Tp>(__x); + } + typedef void is_transparent; }; #endif @@ -561,27 +515,24 @@ template #else template #endif -struct _LIBCPP_TEMPLATE_VIS logical_or - : __binary_function<_Tp, _Tp, bool> -{ - typedef bool __result_type; // used by valarray - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - bool operator()(const _Tp& __x, const _Tp& __y) const - {return __x || __y;} +struct _LIBCPP_TEMPLATE_VIS logical_or : __binary_function<_Tp, _Tp, bool> { + typedef bool __result_type; // used by valarray + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Tp& __x, const _Tp& __y) const { + return __x || __y; + } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(logical_or); #if _LIBCPP_STD_VER >= 14 template <> -struct _LIBCPP_TEMPLATE_VIS logical_or -{ - template - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - auto operator()(_T1&& __t, _T2&& __u) const - noexcept(noexcept(_VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u))) - -> decltype( _VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u)) - { return _VSTD::forward<_T1>(__t) || _VSTD::forward<_T2>(__u); } - typedef void is_transparent; +struct _LIBCPP_TEMPLATE_VIS logical_or { + template + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const + noexcept(noexcept(std::forward<_T1>(__t) || std::forward<_T2>(__u))) // + -> decltype(std::forward<_T1>(__t) || std::forward<_T2>(__u)) { + return std::forward<_T1>(__t) || std::forward<_T2>(__u); + } + typedef void is_transparent; }; #endif diff --git a/third_party/libcxx/__functional/perfect_forward.h b/third_party/libcxx/__functional/perfect_forward.h index e12654c48..74177c789 100644 --- a/third_party/libcxx/__functional/perfect_forward.h +++ b/third_party/libcxx/__functional/perfect_forward.h @@ -11,8 +11,12 @@ #define _LIBCPP___FUNCTIONAL_PERFECT_FORWARD_H #include <__config> +#include <__type_traits/enable_if.h> +#include <__type_traits/invoke.h> +#include <__type_traits/is_constructible.h> #include <__utility/declval.h> #include <__utility/forward.h> +#include <__utility/integer_sequence.h> #include <__utility/move.h> #include @@ -20,6 +24,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 17 @@ -33,61 +40,65 @@ private: tuple<_BoundArgs...> __bound_args_; public: - template , _Args&&...> - >> + template , _Args&&...> >> _LIBCPP_HIDE_FROM_ABI explicit constexpr __perfect_forward_impl(_Args&&... __bound_args) - : __bound_args_(_VSTD::forward<_Args>(__bound_args)...) {} + : __bound_args_(std::forward<_Args>(__bound_args)...) {} _LIBCPP_HIDE_FROM_ABI __perfect_forward_impl(__perfect_forward_impl const&) = default; - _LIBCPP_HIDE_FROM_ABI __perfect_forward_impl(__perfect_forward_impl&&) = default; + _LIBCPP_HIDE_FROM_ABI __perfect_forward_impl(__perfect_forward_impl&&) = default; _LIBCPP_HIDE_FROM_ABI __perfect_forward_impl& operator=(__perfect_forward_impl const&) = default; - _LIBCPP_HIDE_FROM_ABI __perfect_forward_impl& operator=(__perfect_forward_impl&&) = default; + _LIBCPP_HIDE_FROM_ABI __perfect_forward_impl& operator=(__perfect_forward_impl&&) = default; template >> - _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) & - noexcept(noexcept(_Op()(_VSTD::get<_Idx>(__bound_args_)..., _VSTD::forward<_Args>(__args)...))) - -> decltype( _Op()(_VSTD::get<_Idx>(__bound_args_)..., _VSTD::forward<_Args>(__args)...)) - { return _Op()(_VSTD::get<_Idx>(__bound_args_)..., _VSTD::forward<_Args>(__args)...); } + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) & noexcept( + noexcept(_Op()(std::get<_Idx>(__bound_args_)..., std::forward<_Args>(__args)...))) + -> decltype(_Op()(std::get<_Idx>(__bound_args_)..., std::forward<_Args>(__args)...)) { + return _Op()(std::get<_Idx>(__bound_args_)..., std::forward<_Args>(__args)...); + } template >> auto operator()(_Args&&...) & = delete; template >> - _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) const& - noexcept(noexcept(_Op()(_VSTD::get<_Idx>(__bound_args_)..., _VSTD::forward<_Args>(__args)...))) - -> decltype( _Op()(_VSTD::get<_Idx>(__bound_args_)..., _VSTD::forward<_Args>(__args)...)) - { return _Op()(_VSTD::get<_Idx>(__bound_args_)..., _VSTD::forward<_Args>(__args)...); } + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) const& noexcept( + noexcept(_Op()(std::get<_Idx>(__bound_args_)..., std::forward<_Args>(__args)...))) + -> decltype(_Op()(std::get<_Idx>(__bound_args_)..., std::forward<_Args>(__args)...)) { + return _Op()(std::get<_Idx>(__bound_args_)..., std::forward<_Args>(__args)...); + } template >> auto operator()(_Args&&...) const& = delete; template >> - _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) && - noexcept(noexcept(_Op()(_VSTD::get<_Idx>(_VSTD::move(__bound_args_))..., _VSTD::forward<_Args>(__args)...))) - -> decltype( _Op()(_VSTD::get<_Idx>(_VSTD::move(__bound_args_))..., _VSTD::forward<_Args>(__args)...)) - { return _Op()(_VSTD::get<_Idx>(_VSTD::move(__bound_args_))..., _VSTD::forward<_Args>(__args)...); } + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) && noexcept( + noexcept(_Op()(std::get<_Idx>(std::move(__bound_args_))..., std::forward<_Args>(__args)...))) + -> decltype(_Op()(std::get<_Idx>(std::move(__bound_args_))..., std::forward<_Args>(__args)...)) { + return _Op()(std::get<_Idx>(std::move(__bound_args_))..., std::forward<_Args>(__args)...); + } template >> auto operator()(_Args&&...) && = delete; template >> - _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) const&& - noexcept(noexcept(_Op()(_VSTD::get<_Idx>(_VSTD::move(__bound_args_))..., _VSTD::forward<_Args>(__args)...))) - -> decltype( _Op()(_VSTD::get<_Idx>(_VSTD::move(__bound_args_))..., _VSTD::forward<_Args>(__args)...)) - { return _Op()(_VSTD::get<_Idx>(_VSTD::move(__bound_args_))..., _VSTD::forward<_Args>(__args)...); } + _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) const&& noexcept( + noexcept(_Op()(std::get<_Idx>(std::move(__bound_args_))..., std::forward<_Args>(__args)...))) + -> decltype(_Op()(std::get<_Idx>(std::move(__bound_args_))..., std::forward<_Args>(__args)...)) { + return _Op()(std::get<_Idx>(std::move(__bound_args_))..., std::forward<_Args>(__args)...); + } template >> auto operator()(_Args&&...) const&& = delete; }; // __perfect_forward implements a perfect-forwarding call wrapper as explained in [func.require]. -template +template using __perfect_forward = __perfect_forward_impl<_Op, index_sequence_for<_Args...>, _Args...>; #endif // _LIBCPP_STD_VER >= 17 _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___FUNCTIONAL_PERFECT_FORWARD_H diff --git a/third_party/libcxx/__functional/pointer_to_binary_function.h b/third_party/libcxx/__functional/pointer_to_binary_function.h index b2676c58f..e345250dc 100644 --- a/third_party/libcxx/__functional/pointer_to_binary_function.h +++ b/third_party/libcxx/__functional/pointer_to_binary_function.h @@ -22,22 +22,20 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) template -class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 pointer_to_binary_function - : public __binary_function<_Arg1, _Arg2, _Result> -{ - _Result (*__f_)(_Arg1, _Arg2); +class _LIBCPP_TEMPLATE_VIS +_LIBCPP_DEPRECATED_IN_CXX11 pointer_to_binary_function : public __binary_function<_Arg1, _Arg2, _Result> { + _Result (*__f_)(_Arg1, _Arg2); + public: - _LIBCPP_INLINE_VISIBILITY explicit pointer_to_binary_function(_Result (*__f)(_Arg1, _Arg2)) - : __f_(__f) {} - _LIBCPP_INLINE_VISIBILITY _Result operator()(_Arg1 __x, _Arg2 __y) const - {return __f_(__x, __y);} + _LIBCPP_HIDE_FROM_ABI explicit pointer_to_binary_function(_Result (*__f)(_Arg1, _Arg2)) : __f_(__f) {} + _LIBCPP_HIDE_FROM_ABI _Result operator()(_Arg1 __x, _Arg2 __y) const { return __f_(__x, __y); } }; template -_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY -pointer_to_binary_function<_Arg1,_Arg2,_Result> -ptr_fun(_Result (*__f)(_Arg1,_Arg2)) - {return pointer_to_binary_function<_Arg1,_Arg2,_Result>(__f);} +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI pointer_to_binary_function<_Arg1, _Arg2, _Result> +ptr_fun(_Result (*__f)(_Arg1, _Arg2)) { + return pointer_to_binary_function<_Arg1, _Arg2, _Result>(__f); +} #endif diff --git a/third_party/libcxx/__functional/pointer_to_unary_function.h b/third_party/libcxx/__functional/pointer_to_unary_function.h index 77d07adf2..3a5d153d3 100644 --- a/third_party/libcxx/__functional/pointer_to_unary_function.h +++ b/third_party/libcxx/__functional/pointer_to_unary_function.h @@ -22,22 +22,20 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) template -class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 pointer_to_unary_function - : public __unary_function<_Arg, _Result> -{ - _Result (*__f_)(_Arg); +class _LIBCPP_TEMPLATE_VIS +_LIBCPP_DEPRECATED_IN_CXX11 pointer_to_unary_function : public __unary_function<_Arg, _Result> { + _Result (*__f_)(_Arg); + public: - _LIBCPP_INLINE_VISIBILITY explicit pointer_to_unary_function(_Result (*__f)(_Arg)) - : __f_(__f) {} - _LIBCPP_INLINE_VISIBILITY _Result operator()(_Arg __x) const - {return __f_(__x);} + _LIBCPP_HIDE_FROM_ABI explicit pointer_to_unary_function(_Result (*__f)(_Arg)) : __f_(__f) {} + _LIBCPP_HIDE_FROM_ABI _Result operator()(_Arg __x) const { return __f_(__x); } }; template -_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_INLINE_VISIBILITY -pointer_to_unary_function<_Arg,_Result> -ptr_fun(_Result (*__f)(_Arg)) - {return pointer_to_unary_function<_Arg,_Result>(__f);} +_LIBCPP_DEPRECATED_IN_CXX11 inline _LIBCPP_HIDE_FROM_ABI pointer_to_unary_function<_Arg, _Result> +ptr_fun(_Result (*__f)(_Arg)) { + return pointer_to_unary_function<_Arg, _Result>(__f); +} #endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_BINDERS) diff --git a/third_party/libcxx/__functional/ranges_operations.h b/third_party/libcxx/__functional/ranges_operations.h index c344fc38f..27f06eadd 100644 --- a/third_party/libcxx/__functional/ranges_operations.h +++ b/third_party/libcxx/__functional/ranges_operations.h @@ -13,8 +13,7 @@ #include <__concepts/equality_comparable.h> #include <__concepts/totally_ordered.h> #include <__config> -#include <__type_traits/integral_constant.h> -#include <__type_traits/predicate_traits.h> +#include <__type_traits/desugars_to.h> #include <__utility/forward.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -29,10 +28,10 @@ namespace ranges { struct equal_to { template - requires equality_comparable_with<_Tp, _Up> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp &&__t, _Up &&__u) const - noexcept(noexcept(bool(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u)))) { - return _VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u); + requires equality_comparable_with<_Tp, _Up> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(bool(std::forward<_Tp>(__t) == std::forward<_Up>(__u)))) { + return std::forward<_Tp>(__t) == std::forward<_Up>(__u); } using is_transparent = void; @@ -40,10 +39,10 @@ struct equal_to { struct not_equal_to { template - requires equality_comparable_with<_Tp, _Up> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp &&__t, _Up &&__u) const - noexcept(noexcept(bool(!(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u))))) { - return !(_VSTD::forward<_Tp>(__t) == _VSTD::forward<_Up>(__u)); + requires equality_comparable_with<_Tp, _Up> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(bool(!(std::forward<_Tp>(__t) == std::forward<_Up>(__u))))) { + return !(std::forward<_Tp>(__t) == std::forward<_Up>(__u)); } using is_transparent = void; @@ -51,10 +50,10 @@ struct not_equal_to { struct less { template - requires totally_ordered_with<_Tp, _Up> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp &&__t, _Up &&__u) const - noexcept(noexcept(bool(_VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u)))) { - return _VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u); + requires totally_ordered_with<_Tp, _Up> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(bool(std::forward<_Tp>(__t) < std::forward<_Up>(__u)))) { + return std::forward<_Tp>(__t) < std::forward<_Up>(__u); } using is_transparent = void; @@ -62,10 +61,10 @@ struct less { struct less_equal { template - requires totally_ordered_with<_Tp, _Up> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp &&__t, _Up &&__u) const - noexcept(noexcept(bool(!(_VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t))))) { - return !(_VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t)); + requires totally_ordered_with<_Tp, _Up> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(bool(!(std::forward<_Up>(__u) < std::forward<_Tp>(__t))))) { + return !(std::forward<_Up>(__u) < std::forward<_Tp>(__t)); } using is_transparent = void; @@ -73,10 +72,10 @@ struct less_equal { struct greater { template - requires totally_ordered_with<_Tp, _Up> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp &&__t, _Up &&__u) const - noexcept(noexcept(bool(_VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t)))) { - return _VSTD::forward<_Up>(__u) < _VSTD::forward<_Tp>(__t); + requires totally_ordered_with<_Tp, _Up> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(bool(std::forward<_Up>(__u) < std::forward<_Tp>(__t)))) { + return std::forward<_Up>(__u) < std::forward<_Tp>(__t); } using is_transparent = void; @@ -84,10 +83,10 @@ struct greater { struct greater_equal { template - requires totally_ordered_with<_Tp, _Up> - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp &&__t, _Up &&__u) const - noexcept(noexcept(bool(!(_VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u))))) { - return !(_VSTD::forward<_Tp>(__t) < _VSTD::forward<_Up>(__u)); + requires totally_ordered_with<_Tp, _Up> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t, _Up&& __u) const + noexcept(noexcept(bool(!(std::forward<_Tp>(__t) < std::forward<_Up>(__u))))) { + return !(std::forward<_Tp>(__t) < std::forward<_Up>(__u)); } using is_transparent = void; @@ -95,8 +94,13 @@ struct greater_equal { } // namespace ranges -template -struct __is_trivial_equality_predicate : true_type {}; +// For ranges we do not require that the types on each side of the equality +// operator are of the same type +template +inline const bool __desugars_to_v<__equal_tag, ranges::equal_to, _Tp, _Up> = true; + +template +inline const bool __desugars_to_v<__less_tag, ranges::less, _Tp, _Up> = true; #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__functional/reference_wrapper.h b/third_party/libcxx/__functional/reference_wrapper.h index 2d382a34f..3570e2673 100644 --- a/third_party/libcxx/__functional/reference_wrapper.h +++ b/third_party/libcxx/__functional/reference_wrapper.h @@ -10,12 +10,16 @@ #ifndef _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H #define _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H +#include <__compare/synth_three_way.h> +#include <__concepts/boolean_testable.h> #include <__config> #include <__functional/invoke.h> #include <__functional/weak_result_type.h> #include <__memory/addressof.h> #include <__type_traits/enable_if.h> +#include <__type_traits/is_const.h> #include <__type_traits/remove_cvref.h> +#include <__type_traits/void_t.h> #include <__utility/declval.h> #include <__utility/forward.h> @@ -26,44 +30,91 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -class _LIBCPP_TEMPLATE_VIS reference_wrapper : public __weak_result_type<_Tp> -{ +class _LIBCPP_TEMPLATE_VIS reference_wrapper : public __weak_result_type<_Tp> { public: - // types - typedef _Tp type; + // types + typedef _Tp type; + private: - type* __f_; + type* __f_; - static void __fun(_Tp&) _NOEXCEPT; - static void __fun(_Tp&&) = delete; + static void __fun(_Tp&) _NOEXCEPT; + static void __fun(_Tp&&) = delete; // NOLINT(modernize-use-equals-delete) ; This is llvm.org/PR54276 public: - template ::value, decltype(__fun(std::declval<_Up>())) > > - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 - reference_wrapper(_Up&& __u) _NOEXCEPT_(noexcept(__fun(std::declval<_Up>()))) { - type& __f = static_cast<_Up&&>(__u); - __f_ = _VSTD::addressof(__f); - } + template ()))>, + __enable_if_t::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper(_Up&& __u) + _NOEXCEPT_(noexcept(__fun(std::declval<_Up>()))) { + type& __f = static_cast<_Up&&>(__u); + __f_ = std::addressof(__f); + } - // access - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 - operator type&() const _NOEXCEPT {return *__f_;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 - type& get() const _NOEXCEPT {return *__f_;} + // access + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 operator type&() const _NOEXCEPT { return *__f_; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 type& get() const _NOEXCEPT { return *__f_; } - // invoke - template - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 - typename __invoke_of::type - operator() (_ArgTypes&&... __args) const + // invoke + template + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __invoke_of::type + operator()(_ArgTypes&&... __args) const #if _LIBCPP_STD_VER >= 17 - // Since is_nothrow_invocable requires C++17 LWG3764 is not backported - // to earlier versions. - noexcept(is_nothrow_invocable_v<_Tp&, _ArgTypes...>) + // Since is_nothrow_invocable requires C++17 LWG3764 is not backported + // to earlier versions. + noexcept(is_nothrow_invocable_v<_Tp&, _ArgTypes...>) #endif - { - return std::__invoke(get(), std::forward<_ArgTypes>(__args)...); + { + return std::__invoke(get(), std::forward<_ArgTypes>(__args)...); + } + +#if _LIBCPP_STD_VER >= 26 + + // [refwrap.comparisons], comparisons + + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(reference_wrapper __x, reference_wrapper __y) + requires requires { + { __x.get() == __y.get() } -> __boolean_testable; } + { + return __x.get() == __y.get(); + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(reference_wrapper __x, const _Tp& __y) + requires requires { + { __x.get() == __y } -> __boolean_testable; + } + { + return __x.get() == __y; + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(reference_wrapper __x, reference_wrapper __y) + requires(!is_const_v<_Tp>) && requires { + { __x.get() == __y.get() } -> __boolean_testable; + } + { + return __x.get() == __y.get(); + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(reference_wrapper __x, reference_wrapper __y) + requires requires { std::__synth_three_way(__x.get(), __y.get()); } + { + return std::__synth_three_way(__x.get(), __y.get()); + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(reference_wrapper __x, const _Tp& __y) + requires requires { std::__synth_three_way(__x.get(), __y); } + { + return std::__synth_three_way(__x.get(), __y); + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(reference_wrapper __x, reference_wrapper __y) + requires(!is_const_v<_Tp>) && requires { std::__synth_three_way(__x.get(), __y.get()); } + { + return std::__synth_three_way(__x.get(), __y.get()); + } + +#endif // _LIBCPP_STD_VER >= 26 }; #if _LIBCPP_STD_VER >= 17 @@ -72,39 +123,31 @@ reference_wrapper(_Tp&) -> reference_wrapper<_Tp>; #endif template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -reference_wrapper<_Tp> -ref(_Tp& __t) _NOEXCEPT -{ - return reference_wrapper<_Tp>(__t); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp> ref(_Tp& __t) _NOEXCEPT { + return reference_wrapper<_Tp>(__t); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -reference_wrapper<_Tp> -ref(reference_wrapper<_Tp> __t) _NOEXCEPT -{ - return __t; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper<_Tp> +ref(reference_wrapper<_Tp> __t) _NOEXCEPT { + return __t; } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -reference_wrapper -cref(const _Tp& __t) _NOEXCEPT -{ - return reference_wrapper(__t); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper cref(const _Tp& __t) _NOEXCEPT { + return reference_wrapper(__t); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -reference_wrapper -cref(reference_wrapper<_Tp> __t) _NOEXCEPT -{ - return __t; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 reference_wrapper +cref(reference_wrapper<_Tp> __t) _NOEXCEPT { + return __t; } -template void ref(const _Tp&&) = delete; -template void cref(const _Tp&&) = delete; +template +void ref(const _Tp&&) = delete; +template +void cref(const _Tp&&) = delete; _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__functional/unary_function.h b/third_party/libcxx/__functional/unary_function.h index f07cac175..69b1bc942 100644 --- a/third_party/libcxx/__functional/unary_function.h +++ b/third_party/libcxx/__functional/unary_function.h @@ -20,18 +20,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION) template -struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 unary_function -{ - typedef _Arg argument_type; - typedef _Result result_type; +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 unary_function { + typedef _Arg argument_type; + typedef _Result result_type; }; #endif // _LIBCPP_STD_VER <= 14 -template struct __unary_function_keep_layout_base { +template +struct __unary_function_keep_layout_base { #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) using argument_type _LIBCPP_DEPRECATED_IN_CXX17 = _Arg; - using result_type _LIBCPP_DEPRECATED_IN_CXX17 = _Result; + using result_type _LIBCPP_DEPRECATED_IN_CXX17 = _Result; #endif }; diff --git a/third_party/libcxx/__functional/unary_negate.h b/third_party/libcxx/__functional/unary_negate.h index ab87e86d1..5bd487a97 100644 --- a/third_party/libcxx/__functional/unary_negate.h +++ b/third_party/libcxx/__functional/unary_negate.h @@ -22,23 +22,24 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS) template -class _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 unary_negate - : public __unary_function -{ - _Predicate __pred_; +class _LIBCPP_TEMPLATE_VIS +_LIBCPP_DEPRECATED_IN_CXX17 unary_negate : public __unary_function { + _Predicate __pred_; + public: - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - explicit unary_negate(const _Predicate& __pred) - : __pred_(__pred) {} - _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY - bool operator()(const typename _Predicate::argument_type& __x) const - {return !__pred_(__x);} + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI explicit unary_negate(const _Predicate& __pred) + : __pred_(__pred) {} + _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI bool + operator()(const typename _Predicate::argument_type& __x) const { + return !__pred_(__x); + } }; template -_LIBCPP_DEPRECATED_IN_CXX17 inline _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_INLINE_VISIBILITY -unary_negate<_Predicate> -not1(const _Predicate& __pred) {return unary_negate<_Predicate>(__pred);} +_LIBCPP_DEPRECATED_IN_CXX17 inline _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI unary_negate<_Predicate> +not1(const _Predicate& __pred) { + return unary_negate<_Predicate>(__pred); +} #endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS) diff --git a/third_party/libcxx/__functional/weak_result_type.h b/third_party/libcxx/__functional/weak_result_type.h index 18d1bf718..ad7a83951 100644 --- a/third_party/libcxx/__functional/weak_result_type.h +++ b/third_party/libcxx/__functional/weak_result_type.h @@ -25,268 +25,205 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -struct __has_result_type -{ +struct __has_result_type { private: - template static false_type __test(...); - template static true_type __test(typename _Up::result_type* = 0); + template + static false_type __test(...); + template + static true_type __test(typename _Up::result_type* = 0); + public: - static const bool value = decltype(__test<_Tp>(0))::value; + static const bool value = decltype(__test<_Tp>(0))::value; }; // __weak_result_type template -struct __derives_from_unary_function -{ +struct __derives_from_unary_function { private: - struct __two {char __lx; char __lxx;}; - static __two __test(...); - template - static __unary_function<_Ap, _Rp> - __test(const volatile __unary_function<_Ap, _Rp>*); + struct __two { + char __lx; + char __lxx; + }; + static __two __test(...); + template + static __unary_function<_Ap, _Rp> __test(const volatile __unary_function<_Ap, _Rp>*); public: - static const bool value = !is_same::value; - typedef decltype(__test((_Tp*)0)) type; + static const bool value = !is_same::value; + typedef decltype(__test((_Tp*)0)) type; }; template -struct __derives_from_binary_function -{ +struct __derives_from_binary_function { private: - struct __two {char __lx; char __lxx;}; - static __two __test(...); - template - static __binary_function<_A1, _A2, _Rp> - __test(const volatile __binary_function<_A1, _A2, _Rp>*); + struct __two { + char __lx; + char __lxx; + }; + static __two __test(...); + template + static __binary_function<_A1, _A2, _Rp> __test(const volatile __binary_function<_A1, _A2, _Rp>*); public: - static const bool value = !is_same::value; - typedef decltype(__test((_Tp*)0)) type; + static const bool value = !is_same::value; + typedef decltype(__test((_Tp*)0)) type; }; template ::value> -struct __maybe_derive_from_unary_function // bool is true - : public __derives_from_unary_function<_Tp>::type -{ -}; +struct __maybe_derive_from_unary_function // bool is true + : public __derives_from_unary_function<_Tp>::type {}; template -struct __maybe_derive_from_unary_function<_Tp, false> -{ -}; +struct __maybe_derive_from_unary_function<_Tp, false> {}; template ::value> -struct __maybe_derive_from_binary_function // bool is true - : public __derives_from_binary_function<_Tp>::type -{ -}; +struct __maybe_derive_from_binary_function // bool is true + : public __derives_from_binary_function<_Tp>::type {}; template -struct __maybe_derive_from_binary_function<_Tp, false> -{ -}; +struct __maybe_derive_from_binary_function<_Tp, false> {}; template ::value> struct __weak_result_type_imp // bool is true : public __maybe_derive_from_unary_function<_Tp>, - public __maybe_derive_from_binary_function<_Tp> -{ + public __maybe_derive_from_binary_function<_Tp> { #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = typename _Tp::result_type; + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = typename _Tp::result_type; #endif }; template struct __weak_result_type_imp<_Tp, false> - : public __maybe_derive_from_unary_function<_Tp>, - public __maybe_derive_from_binary_function<_Tp> -{ -}; + : public __maybe_derive_from_unary_function<_Tp>, public __maybe_derive_from_binary_function<_Tp> {}; template -struct __weak_result_type - : public __weak_result_type_imp<_Tp> -{ -}; +struct __weak_result_type : public __weak_result_type_imp<_Tp> {}; // 0 argument case template -struct __weak_result_type<_Rp ()> -{ +struct __weak_result_type<_Rp()> { #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; #endif }; template -struct __weak_result_type<_Rp (&)()> -{ +struct __weak_result_type<_Rp (&)()> { #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; #endif }; template -struct __weak_result_type<_Rp (*)()> -{ +struct __weak_result_type<_Rp (*)()> { #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; #endif }; // 1 argument case template -struct __weak_result_type<_Rp (_A1)> - : public __unary_function<_A1, _Rp> -{ -}; +struct __weak_result_type<_Rp(_A1)> : public __unary_function<_A1, _Rp> {}; template -struct __weak_result_type<_Rp (&)(_A1)> - : public __unary_function<_A1, _Rp> -{ -}; +struct __weak_result_type<_Rp (&)(_A1)> : public __unary_function<_A1, _Rp> {}; template -struct __weak_result_type<_Rp (*)(_A1)> - : public __unary_function<_A1, _Rp> -{ -}; +struct __weak_result_type<_Rp (*)(_A1)> : public __unary_function<_A1, _Rp> {}; template -struct __weak_result_type<_Rp (_Cp::*)()> - : public __unary_function<_Cp*, _Rp> -{ -}; +struct __weak_result_type<_Rp (_Cp::*)()> : public __unary_function<_Cp*, _Rp> {}; template -struct __weak_result_type<_Rp (_Cp::*)() const> - : public __unary_function -{ -}; +struct __weak_result_type<_Rp (_Cp::*)() const> : public __unary_function {}; template -struct __weak_result_type<_Rp (_Cp::*)() volatile> - : public __unary_function -{ -}; +struct __weak_result_type<_Rp (_Cp::*)() volatile> : public __unary_function {}; template -struct __weak_result_type<_Rp (_Cp::*)() const volatile> - : public __unary_function -{ -}; +struct __weak_result_type<_Rp (_Cp::*)() const volatile> : public __unary_function {}; // 2 argument case template -struct __weak_result_type<_Rp (_A1, _A2)> - : public __binary_function<_A1, _A2, _Rp> -{ -}; +struct __weak_result_type<_Rp(_A1, _A2)> : public __binary_function<_A1, _A2, _Rp> {}; template -struct __weak_result_type<_Rp (*)(_A1, _A2)> - : public __binary_function<_A1, _A2, _Rp> -{ -}; +struct __weak_result_type<_Rp (*)(_A1, _A2)> : public __binary_function<_A1, _A2, _Rp> {}; template -struct __weak_result_type<_Rp (&)(_A1, _A2)> - : public __binary_function<_A1, _A2, _Rp> -{ -}; +struct __weak_result_type<_Rp (&)(_A1, _A2)> : public __binary_function<_A1, _A2, _Rp> {}; template -struct __weak_result_type<_Rp (_Cp::*)(_A1)> - : public __binary_function<_Cp*, _A1, _Rp> -{ -}; +struct __weak_result_type<_Rp (_Cp::*)(_A1)> : public __binary_function<_Cp*, _A1, _Rp> {}; template -struct __weak_result_type<_Rp (_Cp::*)(_A1) const> - : public __binary_function -{ -}; +struct __weak_result_type<_Rp (_Cp::*)(_A1) const> : public __binary_function {}; template -struct __weak_result_type<_Rp (_Cp::*)(_A1) volatile> - : public __binary_function -{ -}; +struct __weak_result_type<_Rp (_Cp::*)(_A1) volatile> : public __binary_function {}; template -struct __weak_result_type<_Rp (_Cp::*)(_A1) const volatile> - : public __binary_function -{ +struct __weak_result_type<_Rp (_Cp::*)(_A1) const volatile> : public __binary_function { }; // 3 or more arguments -template -struct __weak_result_type<_Rp (_A1, _A2, _A3, _A4...)> -{ +template +struct __weak_result_type<_Rp(_A1, _A2, _A3, _A4...)> { #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; #endif }; -template -struct __weak_result_type<_Rp (&)(_A1, _A2, _A3, _A4...)> -{ +template +struct __weak_result_type<_Rp (&)(_A1, _A2, _A3, _A4...)> { #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; #endif }; -template -struct __weak_result_type<_Rp (*)(_A1, _A2, _A3, _A4...)> -{ +template +struct __weak_result_type<_Rp (*)(_A1, _A2, _A3, _A4...)> { #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; #endif }; -template -struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...)> -{ +template +struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...)> { #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; #endif }; -template -struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const> -{ +template +struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const> { #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; #endif }; -template -struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) volatile> -{ +template +struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) volatile> { #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; #endif }; -template -struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile> -{ +template +struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile> { #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS) - using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; + using result_type _LIBCPP_NODEBUG _LIBCPP_DEPRECATED_IN_CXX17 = _Rp; #endif }; -template -struct __invoke_return -{ - typedef decltype(_VSTD::__invoke(std::declval<_Tp>(), std::declval<_Args>()...)) type; +template +struct __invoke_return { + typedef decltype(std::__invoke(std::declval<_Tp>(), std::declval<_Args>()...)) type; }; _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__fwd/array.h b/third_party/libcxx/__fwd/array.h index 9a79effb6..b429d0c5a 100644 --- a/third_party/libcxx/__fwd/array.h +++ b/third_party/libcxx/__fwd/array.h @@ -21,6 +21,26 @@ _LIBCPP_BEGIN_NAMESPACE_STD template struct _LIBCPP_TEMPLATE_VIS array; +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp& get(array<_Tp, _Size>&) _NOEXCEPT; + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& get(const array<_Tp, _Size>&) _NOEXCEPT; + +#ifndef _LIBCPP_CXX03_LANG +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp&& get(array<_Tp, _Size>&&) _NOEXCEPT; + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp&& get(const array<_Tp, _Size>&&) _NOEXCEPT; +#endif + +template +struct __is_std_array : false_type {}; + +template +struct __is_std_array > : true_type {}; + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP___FWD_ARRAY_H diff --git a/third_party/libcxx/__type_traits/predicate_traits.h b/third_party/libcxx/__fwd/bit_reference.h similarity index 64% rename from third_party/libcxx/__type_traits/predicate_traits.h rename to third_party/libcxx/__fwd/bit_reference.h index 872608e6a..237efb6db 100644 --- a/third_party/libcxx/__type_traits/predicate_traits.h +++ b/third_party/libcxx/__fwd/bit_reference.h @@ -6,11 +6,10 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___TYPE_TRAITS_PREDICATE_TRAITS -#define _LIBCPP___TYPE_TRAITS_PREDICATE_TRAITS +#ifndef _LIBCPP___FWD_BIT_REFERENCE_H +#define _LIBCPP___FWD_BIT_REFERENCE_H #include <__config> -#include <__type_traits/integral_constant.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -18,9 +17,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template -struct __is_trivial_equality_predicate : false_type {}; +template +class __bit_iterator; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___TYPE_TRAITS_PREDICATE_TRAITS +#endif // _LIBCPP___FWD_BIT_REFERENCE_H diff --git a/third_party/libcxx/__fwd/complex.h b/third_party/libcxx/__fwd/complex.h new file mode 100644 index 000000000..22c78c5cc --- /dev/null +++ b/third_party/libcxx/__fwd/complex.h @@ -0,0 +1,42 @@ +//===---------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===---------------------------------------------------------------------===// + +#ifndef _LIBCPP___FWD_COMPLEX_H +#define _LIBCPP___FWD_COMPLEX_H + +#include <__config> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +class _LIBCPP_TEMPLATE_VIS complex; + +#if _LIBCPP_STD_VER >= 26 + +template +_LIBCPP_HIDE_FROM_ABI constexpr _Tp& get(complex<_Tp>&) noexcept; + +template +_LIBCPP_HIDE_FROM_ABI constexpr _Tp&& get(complex<_Tp>&&) noexcept; + +template +_LIBCPP_HIDE_FROM_ABI constexpr const _Tp& get(const complex<_Tp>&) noexcept; + +template +_LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& get(const complex<_Tp>&&) noexcept; + +#endif // _LIBCPP_STD_VER >= 26 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FWD_COMPLEX_H diff --git a/third_party/libcxx/__fwd/deque.h b/third_party/libcxx/__fwd/deque.h new file mode 100644 index 000000000..fd2fb5bb4 --- /dev/null +++ b/third_party/libcxx/__fwd/deque.h @@ -0,0 +1,26 @@ +//===---------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===---------------------------------------------------------------------===// + +#ifndef _LIBCPP___FWD_DEQUE_H +#define _LIBCPP___FWD_DEQUE_H + +#include <__config> +#include <__fwd/memory.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template > +class _LIBCPP_TEMPLATE_VIS deque; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FWD_DEQUE_H diff --git a/third_party/libcxx/__format/format_fwd.h b/third_party/libcxx/__fwd/format.h similarity index 86% rename from third_party/libcxx/__format/format_fwd.h rename to third_party/libcxx/__fwd/format.h index 120b2fc8d..b30c220f8 100644 --- a/third_party/libcxx/__format/format_fwd.h +++ b/third_party/libcxx/__fwd/format.h @@ -7,10 +7,9 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FORMAT_FORMAT_FWD_H -#define _LIBCPP___FORMAT_FORMAT_FWD_H +#ifndef _LIBCPP___FWD_FORMAT_H +#define _LIBCPP___FWD_FORMAT_H -#include <__availability> #include <__config> #include <__iterator/concepts.h> @@ -36,4 +35,4 @@ struct _LIBCPP_TEMPLATE_VIS formatter; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FORMAT_FORMAT_FWD_H +#endif // _LIBCPP___FWD_FORMAT_H diff --git a/third_party/libcxx/__fwd/functional.h b/third_party/libcxx/__fwd/functional.h new file mode 100644 index 000000000..32c9ef33e --- /dev/null +++ b/third_party/libcxx/__fwd/functional.h @@ -0,0 +1,28 @@ +//===---------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===---------------------------------------------------------------------===// + +#ifndef _LIBCPP___FWD_FUNCTIONAL_H +#define _LIBCPP___FWD_FUNCTIONAL_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct _LIBCPP_TEMPLATE_VIS hash; + +template +class _LIBCPP_TEMPLATE_VIS reference_wrapper; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FWD_FUNCTIONAL_H diff --git a/third_party/libcxx/__fwd/get.h b/third_party/libcxx/__fwd/get.h deleted file mode 100644 index d04341496..000000000 --- a/third_party/libcxx/__fwd/get.h +++ /dev/null @@ -1,115 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP___FWD_GET_H -#define _LIBCPP___FWD_GET_H - -#include <__concepts/copyable.h> -#include <__config> -#include <__fwd/array.h> -#include <__fwd/pair.h> -#include <__fwd/subrange.h> -#include <__fwd/tuple.h> -#include <__tuple/tuple_element.h> -#include - -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header -#endif - -_LIBCPP_BEGIN_NAMESPACE_STD - -#ifndef _LIBCPP_CXX03_LANG - -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -typename tuple_element<_Ip, tuple<_Tp...> >::type& -get(tuple<_Tp...>&) _NOEXCEPT; - -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -const typename tuple_element<_Ip, tuple<_Tp...> >::type& -get(const tuple<_Tp...>&) _NOEXCEPT; - -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -typename tuple_element<_Ip, tuple<_Tp...> >::type&& -get(tuple<_Tp...>&&) _NOEXCEPT; - -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -const typename tuple_element<_Ip, tuple<_Tp...> >::type&& -get(const tuple<_Tp...>&&) _NOEXCEPT; - -#endif //_LIBCPP_CXX03_LANG - -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -typename tuple_element<_Ip, pair<_T1, _T2> >::type& -get(pair<_T1, _T2>&) _NOEXCEPT; - -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -const typename tuple_element<_Ip, pair<_T1, _T2> >::type& -get(const pair<_T1, _T2>&) _NOEXCEPT; - -#ifndef _LIBCPP_CXX03_LANG -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -typename tuple_element<_Ip, pair<_T1, _T2> >::type&& -get(pair<_T1, _T2>&&) _NOEXCEPT; - -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -const typename tuple_element<_Ip, pair<_T1, _T2> >::type&& -get(const pair<_T1, _T2>&&) _NOEXCEPT; -#endif - -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -_Tp& -get(array<_Tp, _Size>&) _NOEXCEPT; - -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -const _Tp& -get(const array<_Tp, _Size>&) _NOEXCEPT; - -#ifndef _LIBCPP_CXX03_LANG -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -_Tp&& -get(array<_Tp, _Size>&&) _NOEXCEPT; - -template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -const _Tp&& -get(const array<_Tp, _Size>&&) _NOEXCEPT; -#endif - -#if _LIBCPP_STD_VER >= 20 - -namespace ranges { - -template - requires((_Index == 0 && copyable<_Iter>) || _Index == 1) -_LIBCPP_HIDE_FROM_ABI constexpr auto get(const subrange<_Iter, _Sent, _Kind>& __subrange); - -template - requires(_Index < 2) -_LIBCPP_HIDE_FROM_ABI constexpr auto get(subrange<_Iter, _Sent, _Kind>&& __subrange); - -} // namespace ranges - -using ranges::get; - -#endif // _LIBCPP_STD_VER >= 20 - -_LIBCPP_END_NAMESPACE_STD - -#endif // _LIBCPP___FWD_GET_H diff --git a/third_party/libcxx/__fwd/ios.h b/third_party/libcxx/__fwd/ios.h index 82c865d58..48350709d 100644 --- a/third_party/libcxx/__fwd/ios.h +++ b/third_party/libcxx/__fwd/ios.h @@ -18,6 +18,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD +class _LIBCPP_EXPORTED_FROM_ABI ios_base; + template > class _LIBCPP_TEMPLATE_VIS basic_ios; diff --git a/third_party/libcxx/__fwd/mdspan.h b/third_party/libcxx/__fwd/mdspan.h new file mode 100644 index 000000000..8889567a0 --- /dev/null +++ b/third_party/libcxx/__fwd/mdspan.h @@ -0,0 +1,57 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// Kokkos v. 4.0 +// Copyright (2022) National Technology & Engineering +// Solutions of Sandia, LLC (NTESS). +// +// Under the terms of Contract DE-NA0003525 with NTESS, +// the U.S. Government retains certain rights in this software. +// +//===---------------------------------------------------------------------===// + +#ifndef _LIBCPP___MDSPAN_LAYOUTS_H +#define _LIBCPP___MDSPAN_LAYOUTS_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER >= 23 + +// Layout policy with a mapping which corresponds to FORTRAN-style array layouts +struct layout_left { + template + class mapping; +}; + +// Layout policy with a mapping which corresponds to C-style array layouts +struct layout_right { + template + class mapping; +}; + +// Layout policy with a unique mapping where strides are arbitrary +struct layout_stride { + template + class mapping; +}; + +#endif // _LIBCPP_STD_VER >= 23 + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___MDSPAN_LAYOUTS_H diff --git a/third_party/libcxx/__fwd/hash.h b/third_party/libcxx/__fwd/memory.h similarity index 77% rename from third_party/libcxx/__fwd/hash.h rename to third_party/libcxx/__fwd/memory.h index af9eca876..b9e151855 100644 --- a/third_party/libcxx/__fwd/hash.h +++ b/third_party/libcxx/__fwd/memory.h @@ -6,8 +6,8 @@ // //===---------------------------------------------------------------------===// -#ifndef _LIBCPP___FWD_HASH_H -#define _LIBCPP___FWD_HASH_H +#ifndef _LIBCPP___FWD_MEMORY_H +#define _LIBCPP___FWD_MEMORY_H #include <__config> @@ -17,9 +17,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template -struct _LIBCPP_TEMPLATE_VIS hash; +template +class _LIBCPP_TEMPLATE_VIS allocator; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FWD_HASH_H +#endif // _LIBCPP___FWD_MEMORY_H diff --git a/third_party/libcxx/__fwd/memory_resource.h b/third_party/libcxx/__fwd/memory_resource.h index 718a9078d..d68b2c2b6 100644 --- a/third_party/libcxx/__fwd/memory_resource.h +++ b/third_party/libcxx/__fwd/memory_resource.h @@ -19,7 +19,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace pmr { template -class _LIBCPP_TEMPLATE_VIS polymorphic_allocator; +class _LIBCPP_AVAILABILITY_PMR _LIBCPP_TEMPLATE_VIS polymorphic_allocator; } // namespace pmr _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__fwd/pair.h b/third_party/libcxx/__fwd/pair.h index 3844014de..af32628fe 100644 --- a/third_party/libcxx/__fwd/pair.h +++ b/third_party/libcxx/__fwd/pair.h @@ -10,6 +10,8 @@ #define _LIBCPP___FWD_PAIR_H #include <__config> +#include <__fwd/tuple.h> +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -20,6 +22,24 @@ _LIBCPP_BEGIN_NAMESPACE_STD template struct _LIBCPP_TEMPLATE_VIS pair; +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Ip, pair<_T1, _T2> >::type& +get(pair<_T1, _T2>&) _NOEXCEPT; + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, pair<_T1, _T2> >::type& +get(const pair<_T1, _T2>&) _NOEXCEPT; + +#ifndef _LIBCPP_CXX03_LANG +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Ip, pair<_T1, _T2> >::type&& +get(pair<_T1, _T2>&&) _NOEXCEPT; + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, pair<_T1, _T2> >::type&& +get(const pair<_T1, _T2>&&) _NOEXCEPT; +#endif + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP___FWD_PAIR_H diff --git a/third_party/libcxx/__fwd/queue.h b/third_party/libcxx/__fwd/queue.h new file mode 100644 index 000000000..50d99ad9c --- /dev/null +++ b/third_party/libcxx/__fwd/queue.h @@ -0,0 +1,31 @@ +//===---------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===---------------------------------------------------------------------===// + +#ifndef _LIBCPP___FWD_QUEUE_H +#define _LIBCPP___FWD_QUEUE_H + +#include <__config> +#include <__functional/operations.h> +#include <__fwd/deque.h> +#include <__fwd/vector.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template > +class _LIBCPP_TEMPLATE_VIS queue; + +template , class _Compare = less > +class _LIBCPP_TEMPLATE_VIS priority_queue; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FWD_QUEUE_H diff --git a/third_party/libcxx/__fwd/span.h b/third_party/libcxx/__fwd/span.h index e9fa70382..8dafa742c 100644 --- a/third_party/libcxx/__fwd/span.h +++ b/third_party/libcxx/__fwd/span.h @@ -26,7 +26,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 inline constexpr size_t dynamic_extent = numeric_limits::max(); -template class span; +template +class span; #endif diff --git a/third_party/libcxx/__fwd/sstream.h b/third_party/libcxx/__fwd/sstream.h index e2d46fbe1..39a9c3faf 100644 --- a/third_party/libcxx/__fwd/sstream.h +++ b/third_party/libcxx/__fwd/sstream.h @@ -10,6 +10,7 @@ #define _LIBCPP___FWD_SSTREAM_H #include <__config> +#include <__fwd/memory.h> #include <__fwd/string.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/third_party/libcxx/__fwd/stack.h b/third_party/libcxx/__fwd/stack.h new file mode 100644 index 000000000..7dab6c1a4 --- /dev/null +++ b/third_party/libcxx/__fwd/stack.h @@ -0,0 +1,26 @@ +//===---------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===---------------------------------------------------------------------===// + +#ifndef _LIBCPP___FWD_STACK_H +#define _LIBCPP___FWD_STACK_H + +#include <__config> +#include <__fwd/deque.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template > +class _LIBCPP_TEMPLATE_VIS stack; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FWD_STACK_H diff --git a/third_party/libcxx/__fwd/string.h b/third_party/libcxx/__fwd/string.h index 7ab5561b7..2418e1f9b 100644 --- a/third_party/libcxx/__fwd/string.h +++ b/third_party/libcxx/__fwd/string.h @@ -10,6 +10,7 @@ #define _LIBCPP___FWD_STRING_H #include <__config> +#include <__fwd/memory.h> #include <__fwd/memory_resource.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -38,9 +39,6 @@ template <> struct char_traits; #endif -template -class _LIBCPP_TEMPLATE_VIS allocator; - template , class _Allocator = allocator<_CharT> > class _LIBCPP_TEMPLATE_VIS basic_string; @@ -61,21 +59,20 @@ using u32string = basic_string; namespace pmr { template > -using basic_string = std::basic_string<_CharT, _Traits, polymorphic_allocator<_CharT>>; +using basic_string _LIBCPP_AVAILABILITY_PMR = std::basic_string<_CharT, _Traits, polymorphic_allocator<_CharT>>; -using string = basic_string; +using string _LIBCPP_AVAILABILITY_PMR = basic_string; # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -using wstring = basic_string; +using wstring _LIBCPP_AVAILABILITY_PMR = basic_string; # endif # ifndef _LIBCPP_HAS_NO_CHAR8_T -using u8string = basic_string; +using u8string _LIBCPP_AVAILABILITY_PMR = basic_string; # endif -using u16string = basic_string; -using u32string = basic_string; - +using u16string _LIBCPP_AVAILABILITY_PMR = basic_string; +using u32string _LIBCPP_AVAILABILITY_PMR = basic_string; } // namespace pmr #endif // _LIBCPP_STD_VER >= 17 diff --git a/third_party/libcxx/__fwd/string_view.h b/third_party/libcxx/__fwd/string_view.h index 481899024..72a64be5b 100644 --- a/third_party/libcxx/__fwd/string_view.h +++ b/third_party/libcxx/__fwd/string_view.h @@ -11,7 +11,7 @@ #define _LIBCPP___FWD_STRING_VIEW_H #include <__config> -#include // char_traits +#include <__fwd/string.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -19,17 +19,17 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template > +template > class _LIBCPP_TEMPLATE_VIS basic_string_view; -typedef basic_string_view string_view; +typedef basic_string_view string_view; #ifndef _LIBCPP_HAS_NO_CHAR8_T -typedef basic_string_view u8string_view; +typedef basic_string_view u8string_view; #endif typedef basic_string_view u16string_view; typedef basic_string_view u32string_view; #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS -typedef basic_string_view wstring_view; +typedef basic_string_view wstring_view; #endif // clang-format off diff --git a/third_party/libcxx/__fwd/subrange.h b/third_party/libcxx/__fwd/subrange.h index 8f7239247..60a41da23 100644 --- a/third_party/libcxx/__fwd/subrange.h +++ b/third_party/libcxx/__fwd/subrange.h @@ -9,7 +9,10 @@ #ifndef _LIBCPP___FWD_SUBRANGE_H #define _LIBCPP___FWD_SUBRANGE_H +#include <__concepts/copyable.h> #include <__config> +#include <__iterator/concepts.h> +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -17,20 +20,28 @@ #if _LIBCPP_STD_VER >= 20 -#include <__iterator/concepts.h> - _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { -enum class _LIBCPP_ENUM_VIS subrange_kind : bool { unsized, sized }; +enum class subrange_kind : bool { unsized, sized }; template _Sent, subrange_kind _Kind> requires(_Kind == subrange_kind::sized || !sized_sentinel_for<_Sent, _Iter>) class _LIBCPP_TEMPLATE_VIS subrange; +template + requires((_Index == 0 && copyable<_Iter>) || _Index == 1) +_LIBCPP_HIDE_FROM_ABI constexpr auto get(const subrange<_Iter, _Sent, _Kind>&); + +template + requires(_Index < 2) +_LIBCPP_HIDE_FROM_ABI constexpr auto get(subrange<_Iter, _Sent, _Kind>&&); + } // namespace ranges +using ranges::get; + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__fwd/tuple.h b/third_party/libcxx/__fwd/tuple.h index 16b3fabbb..902770c29 100644 --- a/third_party/libcxx/__fwd/tuple.h +++ b/third_party/libcxx/__fwd/tuple.h @@ -10,6 +10,7 @@ #define _LIBCPP___FWD_TUPLE_H #include <__config> +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -17,11 +18,33 @@ _LIBCPP_BEGIN_NAMESPACE_STD +template +struct _LIBCPP_TEMPLATE_VIS tuple_element; + #ifndef _LIBCPP_CXX03_LANG template class _LIBCPP_TEMPLATE_VIS tuple; +template +struct _LIBCPP_TEMPLATE_VIS tuple_size; + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Ip, tuple<_Tp...> >::type& +get(tuple<_Tp...>&) _NOEXCEPT; + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, tuple<_Tp...> >::type& +get(const tuple<_Tp...>&) _NOEXCEPT; + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename tuple_element<_Ip, tuple<_Tp...> >::type&& +get(tuple<_Tp...>&&) _NOEXCEPT; + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const typename tuple_element<_Ip, tuple<_Tp...> >::type&& +get(const tuple<_Tp...>&&) _NOEXCEPT; + #endif // _LIBCPP_CXX03_LANG _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__fwd/vector.h b/third_party/libcxx/__fwd/vector.h new file mode 100644 index 000000000..c9cc96137 --- /dev/null +++ b/third_party/libcxx/__fwd/vector.h @@ -0,0 +1,26 @@ +//===---------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===---------------------------------------------------------------------===// + +#ifndef _LIBCPP___FWD_VECTOR_H +#define _LIBCPP___FWD_VECTOR_H + +#include <__config> +#include <__fwd/memory.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template > +class _LIBCPP_TEMPLATE_VIS vector; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FWD_VECTOR_H diff --git a/third_party/libcxx/__hash_table b/third_party/libcxx/__hash_table index 570e8209c..025758528 100644 --- a/third_party/libcxx/__hash_table +++ b/third_party/libcxx/__hash_table @@ -15,25 +15,22 @@ #include <__assert> #include <__bit/countl.h> #include <__config> -#include <__debug> #include <__functional/hash.h> #include <__functional/invoke.h> #include <__iterator/iterator_traits.h> #include <__memory/addressof.h> #include <__memory/allocator_traits.h> #include <__memory/compressed_pair.h> +#include <__memory/construct_at.h> #include <__memory/pointer_traits.h> #include <__memory/swap_allocator.h> #include <__memory/unique_ptr.h> #include <__type_traits/can_extract_key.h> #include <__type_traits/conditional.h> #include <__type_traits/is_const.h> -#include <__type_traits/is_copy_constructible.h> +#include <__type_traits/is_constructible.h> +#include <__type_traits/is_nothrow_assignable.h> #include <__type_traits/is_nothrow_constructible.h> -#include <__type_traits/is_nothrow_copy_constructible.h> -#include <__type_traits/is_nothrow_default_constructible.h> -#include <__type_traits/is_nothrow_move_assignable.h> -#include <__type_traits/is_nothrow_move_constructible.h> #include <__type_traits/is_pointer.h> #include <__type_traits/is_reference.h> #include <__type_traits/is_swappable.h> @@ -46,6 +43,7 @@ #include #include #include +#include // __launder #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -54,7 +52,6 @@ _LIBCPP_PUSH_MACROS #include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD template @@ -66,95 +63,100 @@ struct __is_hash_value_type_imp : false_type {}; template struct __is_hash_value_type_imp<__hash_value_type<_Key, _Value> > : true_type {}; -template +template struct __is_hash_value_type : false_type {}; template struct __is_hash_value_type<_One> : __is_hash_value_type_imp<__remove_cvref_t<_One> > {}; -_LIBCPP_FUNC_VIS -size_t __next_prime(size_t __n); +_LIBCPP_EXPORTED_FROM_ABI size_t __next_prime(size_t __n); template -struct __hash_node_base -{ - typedef typename pointer_traits<_NodePtr>::element_type __node_type; - typedef __hash_node_base __first_node; - typedef __rebind_pointer_t<_NodePtr, __first_node> __node_base_pointer; - typedef _NodePtr __node_pointer; +struct __hash_node_base { + typedef typename pointer_traits<_NodePtr>::element_type __node_type; + typedef __hash_node_base __first_node; + typedef __rebind_pointer_t<_NodePtr, __first_node> __node_base_pointer; + typedef _NodePtr __node_pointer; #if defined(_LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB) typedef __node_base_pointer __next_pointer; #else - typedef __conditional_t::value, __node_base_pointer, __node_pointer> __next_pointer; + typedef __conditional_t::value, __node_base_pointer, __node_pointer> __next_pointer; #endif - __next_pointer __next_; + __next_pointer __next_; - _LIBCPP_INLINE_VISIBILITY - __next_pointer __ptr() _NOEXCEPT { - return static_cast<__next_pointer>( - pointer_traits<__node_base_pointer>::pointer_to(*this)); - } + _LIBCPP_HIDE_FROM_ABI __next_pointer __ptr() _NOEXCEPT { + return static_cast<__next_pointer>(pointer_traits<__node_base_pointer>::pointer_to(*this)); + } - _LIBCPP_INLINE_VISIBILITY - __node_pointer __upcast() _NOEXCEPT { - return static_cast<__node_pointer>( - pointer_traits<__node_base_pointer>::pointer_to(*this)); - } + _LIBCPP_HIDE_FROM_ABI __node_pointer __upcast() _NOEXCEPT { + return static_cast<__node_pointer>(pointer_traits<__node_base_pointer>::pointer_to(*this)); + } - _LIBCPP_INLINE_VISIBILITY - size_t __hash() const _NOEXCEPT { - return static_cast<__node_type const&>(*this).__hash_; - } + _LIBCPP_HIDE_FROM_ABI size_t __hash() const _NOEXCEPT { return static_cast<__node_type const&>(*this).__hash_; } - _LIBCPP_INLINE_VISIBILITY __hash_node_base() _NOEXCEPT : __next_(nullptr) {} + _LIBCPP_HIDE_FROM_ABI __hash_node_base() _NOEXCEPT : __next_(nullptr) {} + _LIBCPP_HIDE_FROM_ABI explicit __hash_node_base(__next_pointer __next) _NOEXCEPT : __next_(__next) {} }; template -struct _LIBCPP_STANDALONE_DEBUG __hash_node - : public __hash_node_base - < - __rebind_pointer_t<_VoidPtr, __hash_node<_Tp, _VoidPtr> > - > -{ - typedef _Tp __node_value_type; +struct __hash_node : public __hash_node_base< __rebind_pointer_t<_VoidPtr, __hash_node<_Tp, _VoidPtr> > > { + typedef _Tp __node_value_type; + using _Base = __hash_node_base<__rebind_pointer_t<_VoidPtr, __hash_node<_Tp, _VoidPtr> > >; + using __next_pointer = typename _Base::__next_pointer; - size_t __hash_; - __node_value_type __value_; + size_t __hash_; + + // We allow starting the lifetime of nodes without initializing the value held by the node, + // since that is handled by the hash table itself in order to be allocator-aware. +#ifndef _LIBCPP_CXX03_LANG + +private: + union { + _Tp __value_; + }; + +public: + _LIBCPP_HIDE_FROM_ABI _Tp& __get_value() { return __value_; } +#else + +private: + _ALIGNAS_TYPE(_Tp) char __buffer_[sizeof(_Tp)]; + +public: + _LIBCPP_HIDE_FROM_ABI _Tp& __get_value() { return *std::__launder(reinterpret_cast<_Tp*>(&__buffer_)); } +#endif + + _LIBCPP_HIDE_FROM_ABI explicit __hash_node(__next_pointer __next, size_t __hash) : _Base(__next), __hash_(__hash) {} + _LIBCPP_HIDE_FROM_ABI ~__hash_node() {} }; -inline _LIBCPP_INLINE_VISIBILITY -bool -__is_hash_power2(size_t __bc) -{ - return __bc > 2 && !(__bc & (__bc - 1)); +inline _LIBCPP_HIDE_FROM_ABI bool __is_hash_power2(size_t __bc) { return __bc > 2 && !(__bc & (__bc - 1)); } + +inline _LIBCPP_HIDE_FROM_ABI size_t __constrain_hash(size_t __h, size_t __bc) { + return !(__bc & (__bc - 1)) ? __h & (__bc - 1) : (__h < __bc ? __h : __h % __bc); } -inline _LIBCPP_INLINE_VISIBILITY -size_t -__constrain_hash(size_t __h, size_t __bc) -{ - return !(__bc & (__bc - 1)) ? __h & (__bc - 1) : - (__h < __bc ? __h : __h % __bc); +inline _LIBCPP_HIDE_FROM_ABI size_t __next_hash_pow2(size_t __n) { + return __n < 2 ? __n : (size_t(1) << (numeric_limits::digits - __libcpp_clz(__n - 1))); } -inline _LIBCPP_INLINE_VISIBILITY -size_t -__next_hash_pow2(size_t __n) -{ - return __n < 2 ? __n : (size_t(1) << (numeric_limits::digits - __libcpp_clz(__n-1))); -} +template +class __hash_table; - -template class __hash_table; - -template class _LIBCPP_TEMPLATE_VIS __hash_iterator; -template class _LIBCPP_TEMPLATE_VIS __hash_const_iterator; -template class _LIBCPP_TEMPLATE_VIS __hash_local_iterator; -template class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator; -template class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; -template class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; +template +class _LIBCPP_TEMPLATE_VIS __hash_iterator; +template +class _LIBCPP_TEMPLATE_VIS __hash_const_iterator; +template +class _LIBCPP_TEMPLATE_VIS __hash_local_iterator; +template +class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator; +template +class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; +template +class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; template struct __hash_key_value_types { @@ -164,73 +166,47 @@ struct __hash_key_value_types { typedef _Tp __container_value_type; static const bool __is_map = false; - _LIBCPP_INLINE_VISIBILITY - static key_type const& __get_key(_Tp const& __v) { - return __v; - } - _LIBCPP_INLINE_VISIBILITY - static __container_value_type const& __get_value(__node_value_type const& __v) { - return __v; - } - _LIBCPP_INLINE_VISIBILITY - static __container_value_type* __get_ptr(__node_value_type& __n) { - return _VSTD::addressof(__n); - } - _LIBCPP_INLINE_VISIBILITY - static __container_value_type&& __move(__node_value_type& __v) { - return _VSTD::move(__v); - } + _LIBCPP_HIDE_FROM_ABI static key_type const& __get_key(_Tp const& __v) { return __v; } + _LIBCPP_HIDE_FROM_ABI static __container_value_type const& __get_value(__node_value_type const& __v) { return __v; } + _LIBCPP_HIDE_FROM_ABI static __container_value_type* __get_ptr(__node_value_type& __n) { return std::addressof(__n); } + _LIBCPP_HIDE_FROM_ABI static __container_value_type&& __move(__node_value_type& __v) { return std::move(__v); } }; template struct __hash_key_value_types<__hash_value_type<_Key, _Tp> > { - typedef _Key key_type; - typedef _Tp mapped_type; - typedef __hash_value_type<_Key, _Tp> __node_value_type; - typedef pair __container_value_type; - typedef __container_value_type __map_value_type; + typedef _Key key_type; + typedef _Tp mapped_type; + typedef __hash_value_type<_Key, _Tp> __node_value_type; + typedef pair __container_value_type; + typedef __container_value_type __map_value_type; static const bool __is_map = true; - _LIBCPP_INLINE_VISIBILITY - static key_type const& __get_key(__container_value_type const& __v) { - return __v.first; - } + _LIBCPP_HIDE_FROM_ABI static key_type const& __get_key(__container_value_type const& __v) { return __v.first; } - template - _LIBCPP_INLINE_VISIBILITY - static __enable_if_t<__is_same_uncvref<_Up, __node_value_type>::value, __container_value_type const&> - __get_value(_Up& __t) { + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI static __container_value_type const& __get_value(_Up& __t) { return __t.__get_value(); } - template - _LIBCPP_INLINE_VISIBILITY - static __enable_if_t<__is_same_uncvref<_Up, __container_value_type>::value, __container_value_type const&> - __get_value(_Up& __t) { + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI static __container_value_type const& __get_value(_Up& __t) { return __t; } - _LIBCPP_INLINE_VISIBILITY - static __container_value_type* __get_ptr(__node_value_type& __n) { - return _VSTD::addressof(__n.__get_value()); - } - _LIBCPP_INLINE_VISIBILITY - static pair __move(__node_value_type& __v) { - return __v.__move(); + _LIBCPP_HIDE_FROM_ABI static __container_value_type* __get_ptr(__node_value_type& __n) { + return std::addressof(__n.__get_value()); } + _LIBCPP_HIDE_FROM_ABI static pair __move(__node_value_type& __v) { return __v.__move(); } }; -template , - bool = _KVTypes::__is_map> +template , bool = _KVTypes::__is_map> struct __hash_map_pointer_types {}; template struct __hash_map_pointer_types<_Tp, _AllocPtr, _KVTypes, true> { - typedef typename _KVTypes::__map_value_type _Mv; - typedef __rebind_pointer_t<_AllocPtr, _Mv> - __map_value_type_pointer; - typedef __rebind_pointer_t<_AllocPtr, const _Mv> - __const_map_value_type_pointer; + typedef typename _KVTypes::__map_value_type _Mv; + typedef __rebind_pointer_t<_AllocPtr, _Mv> __map_value_type_pointer; + typedef __rebind_pointer_t<_AllocPtr, const _Mv> __const_map_value_type_pointer; }; template ::element_type> @@ -238,39 +214,36 @@ struct __hash_node_types; template struct __hash_node_types<_NodePtr, __hash_node<_Tp, _VoidPtr> > - : public __hash_key_value_types<_Tp>, __hash_map_pointer_types<_Tp, _VoidPtr> + : public __hash_key_value_types<_Tp>, + __hash_map_pointer_types<_Tp, _VoidPtr> { - typedef __hash_key_value_types<_Tp> __base; + typedef __hash_key_value_types<_Tp> __base; public: typedef ptrdiff_t difference_type; typedef size_t size_type; - typedef __rebind_pointer_t<_NodePtr, void> __void_pointer; + typedef __rebind_pointer_t<_NodePtr, void> __void_pointer; - typedef typename pointer_traits<_NodePtr>::element_type __node_type; - typedef _NodePtr __node_pointer; + typedef typename pointer_traits<_NodePtr>::element_type __node_type; + typedef _NodePtr __node_pointer; - typedef __hash_node_base<__node_pointer> __node_base_type; - typedef __rebind_pointer_t<_NodePtr, __node_base_type> - __node_base_pointer; + typedef __hash_node_base<__node_pointer> __node_base_type; + typedef __rebind_pointer_t<_NodePtr, __node_base_type> __node_base_pointer; - typedef typename __node_base_type::__next_pointer __next_pointer; + typedef typename __node_base_type::__next_pointer __next_pointer; - typedef _Tp __node_value_type; - typedef __rebind_pointer_t<_VoidPtr, __node_value_type> - __node_value_type_pointer; - typedef __rebind_pointer_t<_VoidPtr, const __node_value_type> - __const_node_value_type_pointer; + typedef _Tp __node_value_type; + typedef __rebind_pointer_t<_VoidPtr, __node_value_type> __node_value_type_pointer; + typedef __rebind_pointer_t<_VoidPtr, const __node_value_type> __const_node_value_type_pointer; private: - static_assert(!is_const<__node_type>::value, - "_NodePtr should never be a pointer to const"); - static_assert((is_same::element_type, void>::value), - "_VoidPtr does not point to unqualified void type"); - static_assert((is_same<__rebind_pointer_t<_VoidPtr, __node_type>, - _NodePtr>::value), "_VoidPtr does not rebind to _NodePtr."); + static_assert(!is_const<__node_type>::value, "_NodePtr should never be a pointer to const"); + static_assert(is_same::element_type, void>::value, + "_VoidPtr does not point to unqualified void type"); + static_assert(is_same<__rebind_pointer_t<_VoidPtr, __node_type>, _NodePtr>::value, + "_VoidPtr does not rebind to _NodePtr."); }; template @@ -284,7 +257,6 @@ struct __hash_node_types_from_iterator<__hash_local_iterator<_NodePtr> > : __has template struct __hash_node_types_from_iterator<__hash_const_local_iterator<_NodePtr> > : __hash_node_types<_NodePtr> {}; - template struct __make_hash_node_types { typedef __hash_node<_NodeValueTp, _VoidPtr> _NodeTp; @@ -293,550 +265,359 @@ struct __make_hash_node_types { }; template -class _LIBCPP_TEMPLATE_VIS __hash_iterator -{ - typedef __hash_node_types<_NodePtr> _NodeTypes; - typedef _NodePtr __node_pointer; - typedef typename _NodeTypes::__next_pointer __next_pointer; +class _LIBCPP_TEMPLATE_VIS __hash_iterator { + typedef __hash_node_types<_NodePtr> _NodeTypes; + typedef _NodePtr __node_pointer; + typedef typename _NodeTypes::__next_pointer __next_pointer; - __next_pointer __node_; + __next_pointer __node_; public: - typedef forward_iterator_tag iterator_category; - typedef typename _NodeTypes::__node_value_type value_type; - typedef typename _NodeTypes::difference_type difference_type; - typedef value_type& reference; - typedef typename _NodeTypes::__node_value_type_pointer pointer; + typedef forward_iterator_tag iterator_category; + typedef typename _NodeTypes::__node_value_type value_type; + typedef typename _NodeTypes::difference_type difference_type; + typedef value_type& reference; + typedef typename _NodeTypes::__node_value_type_pointer pointer; - _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT : __node_(nullptr) { - _VSTD::__debug_db_insert_i(this); - } + _LIBCPP_HIDE_FROM_ABI __hash_iterator() _NOEXCEPT : __node_(nullptr) {} -#ifdef _LIBCPP_ENABLE_DEBUG_MODE - _LIBCPP_INLINE_VISIBILITY - __hash_iterator(const __hash_iterator& __i) - : __node_(__i.__node_) - { - __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); - } + _LIBCPP_HIDE_FROM_ABI reference operator*() const { + _LIBCPP_ASSERT_NON_NULL( + __node_ != nullptr, "Attempted to dereference a non-dereferenceable unordered container iterator"); + return __node_->__upcast()->__get_value(); + } - _LIBCPP_INLINE_VISIBILITY - ~__hash_iterator() - { - __get_db()->__erase_i(this); - } + _LIBCPP_HIDE_FROM_ABI pointer operator->() const { + _LIBCPP_ASSERT_NON_NULL( + __node_ != nullptr, "Attempted to dereference a non-dereferenceable unordered container iterator"); + return pointer_traits::pointer_to(__node_->__upcast()->__get_value()); + } - _LIBCPP_INLINE_VISIBILITY - __hash_iterator& operator=(const __hash_iterator& __i) - { - if (this != _VSTD::addressof(__i)) - { - __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); - __node_ = __i.__node_; - } - return *this; - } -#endif // _LIBCPP_ENABLE_DEBUG_MODE + _LIBCPP_HIDE_FROM_ABI __hash_iterator& operator++() { + _LIBCPP_ASSERT_NON_NULL( + __node_ != nullptr, "Attempted to increment a non-incrementable unordered container iterator"); + __node_ = __node_->__next_; + return *this; + } - _LIBCPP_INLINE_VISIBILITY - reference operator*() const { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable unordered container iterator"); - return __node_->__upcast()->__value_; - } + _LIBCPP_HIDE_FROM_ABI __hash_iterator operator++(int) { + __hash_iterator __t(*this); + ++(*this); + return __t; + } - _LIBCPP_INLINE_VISIBILITY - pointer operator->() const { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable unordered container iterator"); - return pointer_traits::pointer_to(__node_->__upcast()->__value_); - } - - _LIBCPP_INLINE_VISIBILITY - __hash_iterator& operator++() { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to increment a non-incrementable unordered container iterator"); - __node_ = __node_->__next_; - return *this; - } - - _LIBCPP_INLINE_VISIBILITY - __hash_iterator operator++(int) - { - __hash_iterator __t(*this); - ++(*this); - return __t; - } - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const __hash_iterator& __x, const __hash_iterator& __y) - { - return __x.__node_ == __y.__node_; - } - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const __hash_iterator& __x, const __hash_iterator& __y) - {return !(__x == __y);} + friend _LIBCPP_HIDE_FROM_ABI bool operator==(const __hash_iterator& __x, const __hash_iterator& __y) { + return __x.__node_ == __y.__node_; + } + friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const __hash_iterator& __x, const __hash_iterator& __y) { + return !(__x == __y); + } private: - _LIBCPP_INLINE_VISIBILITY - explicit __hash_iterator(__next_pointer __node, const void* __c) _NOEXCEPT - : __node_(__node) - { - (void)__c; -#ifdef _LIBCPP_ENABLE_DEBUG_MODE - __get_db()->__insert_ic(this, __c); -#endif - } - template friend class __hash_table; - template friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator; - template friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; - template friend class _LIBCPP_TEMPLATE_VIS unordered_map; - template friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; + _LIBCPP_HIDE_FROM_ABI explicit __hash_iterator(__next_pointer __node) _NOEXCEPT : __node_(__node) {} + + template + friend class __hash_table; + template + friend class _LIBCPP_TEMPLATE_VIS __hash_const_iterator; + template + friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; + template + friend class _LIBCPP_TEMPLATE_VIS unordered_map; + template + friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; }; template -class _LIBCPP_TEMPLATE_VIS __hash_const_iterator -{ - static_assert(!is_const::element_type>::value, ""); - typedef __hash_node_types<_NodePtr> _NodeTypes; - typedef _NodePtr __node_pointer; - typedef typename _NodeTypes::__next_pointer __next_pointer; +class _LIBCPP_TEMPLATE_VIS __hash_const_iterator { + static_assert(!is_const::element_type>::value, ""); + typedef __hash_node_types<_NodePtr> _NodeTypes; + typedef _NodePtr __node_pointer; + typedef typename _NodeTypes::__next_pointer __next_pointer; - __next_pointer __node_; + __next_pointer __node_; public: - typedef __hash_iterator<_NodePtr> __non_const_iterator; + typedef __hash_iterator<_NodePtr> __non_const_iterator; - typedef forward_iterator_tag iterator_category; - typedef typename _NodeTypes::__node_value_type value_type; - typedef typename _NodeTypes::difference_type difference_type; - typedef const value_type& reference; - typedef typename _NodeTypes::__const_node_value_type_pointer pointer; + typedef forward_iterator_tag iterator_category; + typedef typename _NodeTypes::__node_value_type value_type; + typedef typename _NodeTypes::difference_type difference_type; + typedef const value_type& reference; + typedef typename _NodeTypes::__const_node_value_type_pointer pointer; + _LIBCPP_HIDE_FROM_ABI __hash_const_iterator() _NOEXCEPT : __node_(nullptr) {} - _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT : __node_(nullptr) { - _VSTD::__debug_db_insert_i(this); - } + _LIBCPP_HIDE_FROM_ABI __hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT : __node_(__x.__node_) {} - _LIBCPP_INLINE_VISIBILITY - __hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT - : __node_(__x.__node_) - { -#ifdef _LIBCPP_ENABLE_DEBUG_MODE - __get_db()->__iterator_copy(this, _VSTD::addressof(__x)); -#endif - } + _LIBCPP_HIDE_FROM_ABI reference operator*() const { + _LIBCPP_ASSERT_NON_NULL( + __node_ != nullptr, "Attempted to dereference a non-dereferenceable unordered container const_iterator"); + return __node_->__upcast()->__get_value(); + } + _LIBCPP_HIDE_FROM_ABI pointer operator->() const { + _LIBCPP_ASSERT_NON_NULL( + __node_ != nullptr, "Attempted to dereference a non-dereferenceable unordered container const_iterator"); + return pointer_traits::pointer_to(__node_->__upcast()->__get_value()); + } -#ifdef _LIBCPP_ENABLE_DEBUG_MODE - _LIBCPP_INLINE_VISIBILITY - __hash_const_iterator(const __hash_const_iterator& __i) - : __node_(__i.__node_) - { - __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); - } + _LIBCPP_HIDE_FROM_ABI __hash_const_iterator& operator++() { + _LIBCPP_ASSERT_NON_NULL( + __node_ != nullptr, "Attempted to increment a non-incrementable unordered container const_iterator"); + __node_ = __node_->__next_; + return *this; + } - _LIBCPP_INLINE_VISIBILITY - ~__hash_const_iterator() - { - __get_db()->__erase_i(this); - } + _LIBCPP_HIDE_FROM_ABI __hash_const_iterator operator++(int) { + __hash_const_iterator __t(*this); + ++(*this); + return __t; + } - _LIBCPP_INLINE_VISIBILITY - __hash_const_iterator& operator=(const __hash_const_iterator& __i) - { - if (this != _VSTD::addressof(__i)) - { - __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); - __node_ = __i.__node_; - } - return *this; - } -#endif // _LIBCPP_ENABLE_DEBUG_MODE - - _LIBCPP_INLINE_VISIBILITY - reference operator*() const { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable unordered container const_iterator"); - return __node_->__upcast()->__value_; - } - _LIBCPP_INLINE_VISIBILITY - pointer operator->() const { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable unordered container const_iterator"); - return pointer_traits::pointer_to(__node_->__upcast()->__value_); - } - - _LIBCPP_INLINE_VISIBILITY - __hash_const_iterator& operator++() { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to increment a non-incrementable unordered container const_iterator"); - __node_ = __node_->__next_; - return *this; - } - - _LIBCPP_INLINE_VISIBILITY - __hash_const_iterator operator++(int) - { - __hash_const_iterator __t(*this); - ++(*this); - return __t; - } - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const __hash_const_iterator& __x, const __hash_const_iterator& __y) - { - return __x.__node_ == __y.__node_; - } - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const __hash_const_iterator& __x, const __hash_const_iterator& __y) - {return !(__x == __y);} + friend _LIBCPP_HIDE_FROM_ABI bool operator==(const __hash_const_iterator& __x, const __hash_const_iterator& __y) { + return __x.__node_ == __y.__node_; + } + friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const __hash_const_iterator& __x, const __hash_const_iterator& __y) { + return !(__x == __y); + } private: - _LIBCPP_INLINE_VISIBILITY - explicit __hash_const_iterator(__next_pointer __node, const void* __c) _NOEXCEPT - : __node_(__node) - { - (void)__c; -#ifdef _LIBCPP_ENABLE_DEBUG_MODE - __get_db()->__insert_ic(this, __c); -#endif - } - template friend class __hash_table; - template friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; - template friend class _LIBCPP_TEMPLATE_VIS unordered_map; - template friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; + _LIBCPP_HIDE_FROM_ABI explicit __hash_const_iterator(__next_pointer __node) _NOEXCEPT : __node_(__node) {} + + template + friend class __hash_table; + template + friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; + template + friend class _LIBCPP_TEMPLATE_VIS unordered_map; + template + friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; }; template -class _LIBCPP_TEMPLATE_VIS __hash_local_iterator -{ - typedef __hash_node_types<_NodePtr> _NodeTypes; - typedef _NodePtr __node_pointer; - typedef typename _NodeTypes::__next_pointer __next_pointer; +class _LIBCPP_TEMPLATE_VIS __hash_local_iterator { + typedef __hash_node_types<_NodePtr> _NodeTypes; + typedef _NodePtr __node_pointer; + typedef typename _NodeTypes::__next_pointer __next_pointer; - __next_pointer __node_; - size_t __bucket_; - size_t __bucket_count_; + __next_pointer __node_; + size_t __bucket_; + size_t __bucket_count_; public: - typedef forward_iterator_tag iterator_category; - typedef typename _NodeTypes::__node_value_type value_type; - typedef typename _NodeTypes::difference_type difference_type; - typedef value_type& reference; - typedef typename _NodeTypes::__node_value_type_pointer pointer; + typedef forward_iterator_tag iterator_category; + typedef typename _NodeTypes::__node_value_type value_type; + typedef typename _NodeTypes::difference_type difference_type; + typedef value_type& reference; + typedef typename _NodeTypes::__node_value_type_pointer pointer; - _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT : __node_(nullptr) { - _VSTD::__debug_db_insert_i(this); - } + _LIBCPP_HIDE_FROM_ABI __hash_local_iterator() _NOEXCEPT : __node_(nullptr) {} -#ifdef _LIBCPP_ENABLE_DEBUG_MODE - _LIBCPP_INLINE_VISIBILITY - __hash_local_iterator(const __hash_local_iterator& __i) - : __node_(__i.__node_), - __bucket_(__i.__bucket_), - __bucket_count_(__i.__bucket_count_) - { - __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); - } + _LIBCPP_HIDE_FROM_ABI reference operator*() const { + _LIBCPP_ASSERT_NON_NULL( + __node_ != nullptr, "Attempted to dereference a non-dereferenceable unordered container local_iterator"); + return __node_->__upcast()->__get_value(); + } - _LIBCPP_INLINE_VISIBILITY - ~__hash_local_iterator() - { - __get_db()->__erase_i(this); - } + _LIBCPP_HIDE_FROM_ABI pointer operator->() const { + _LIBCPP_ASSERT_NON_NULL( + __node_ != nullptr, "Attempted to dereference a non-dereferenceable unordered container local_iterator"); + return pointer_traits::pointer_to(__node_->__upcast()->__get_value()); + } - _LIBCPP_INLINE_VISIBILITY - __hash_local_iterator& operator=(const __hash_local_iterator& __i) - { - if (this != _VSTD::addressof(__i)) - { - __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); - __node_ = __i.__node_; - __bucket_ = __i.__bucket_; - __bucket_count_ = __i.__bucket_count_; - } - return *this; - } -#endif // _LIBCPP_ENABLE_DEBUG_MODE + _LIBCPP_HIDE_FROM_ABI __hash_local_iterator& operator++() { + _LIBCPP_ASSERT_NON_NULL( + __node_ != nullptr, "Attempted to increment a non-incrementable unordered container local_iterator"); + __node_ = __node_->__next_; + if (__node_ != nullptr && std::__constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_) + __node_ = nullptr; + return *this; + } - _LIBCPP_INLINE_VISIBILITY - reference operator*() const { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable unordered container local_iterator"); - return __node_->__upcast()->__value_; - } + _LIBCPP_HIDE_FROM_ABI __hash_local_iterator operator++(int) { + __hash_local_iterator __t(*this); + ++(*this); + return __t; + } - _LIBCPP_INLINE_VISIBILITY - pointer operator->() const { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable unordered container local_iterator"); - return pointer_traits::pointer_to(__node_->__upcast()->__value_); - } - - _LIBCPP_INLINE_VISIBILITY - __hash_local_iterator& operator++() { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to increment a non-incrementable unordered container local_iterator"); - __node_ = __node_->__next_; - if (__node_ != nullptr && std::__constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_) - __node_ = nullptr; - return *this; - } - - _LIBCPP_INLINE_VISIBILITY - __hash_local_iterator operator++(int) - { - __hash_local_iterator __t(*this); - ++(*this); - return __t; - } - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const __hash_local_iterator& __x, const __hash_local_iterator& __y) - { - return __x.__node_ == __y.__node_; - } - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const __hash_local_iterator& __x, const __hash_local_iterator& __y) - {return !(__x == __y);} + friend _LIBCPP_HIDE_FROM_ABI bool operator==(const __hash_local_iterator& __x, const __hash_local_iterator& __y) { + return __x.__node_ == __y.__node_; + } + friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const __hash_local_iterator& __x, const __hash_local_iterator& __y) { + return !(__x == __y); + } private: - _LIBCPP_INLINE_VISIBILITY - explicit __hash_local_iterator(__next_pointer __node, size_t __bucket, - size_t __bucket_count, const void* __c) _NOEXCEPT - : __node_(__node), - __bucket_(__bucket), - __bucket_count_(__bucket_count) - { - (void)__c; -#ifdef _LIBCPP_ENABLE_DEBUG_MODE - __get_db()->__insert_ic(this, __c); -#endif - if (__node_ != nullptr) - __node_ = __node_->__next_; - } - template friend class __hash_table; - template friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator; - template friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; + _LIBCPP_HIDE_FROM_ABI explicit __hash_local_iterator( + __next_pointer __node, size_t __bucket, size_t __bucket_count) _NOEXCEPT + : __node_(__node), + __bucket_(__bucket), + __bucket_count_(__bucket_count) { + if (__node_ != nullptr) + __node_ = __node_->__next_; + } + + template + friend class __hash_table; + template + friend class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator; + template + friend class _LIBCPP_TEMPLATE_VIS __hash_map_iterator; }; template -class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator -{ - typedef __hash_node_types<_ConstNodePtr> _NodeTypes; - typedef _ConstNodePtr __node_pointer; - typedef typename _NodeTypes::__next_pointer __next_pointer; +class _LIBCPP_TEMPLATE_VIS __hash_const_local_iterator { + typedef __hash_node_types<_ConstNodePtr> _NodeTypes; + typedef _ConstNodePtr __node_pointer; + typedef typename _NodeTypes::__next_pointer __next_pointer; - __next_pointer __node_; - size_t __bucket_; - size_t __bucket_count_; + __next_pointer __node_; + size_t __bucket_; + size_t __bucket_count_; + + typedef pointer_traits<__node_pointer> __pointer_traits; + typedef typename __pointer_traits::element_type __node; + typedef __remove_const_t<__node> __non_const_node; + typedef __rebind_pointer_t<__node_pointer, __non_const_node> __non_const_node_pointer; - typedef pointer_traits<__node_pointer> __pointer_traits; - typedef typename __pointer_traits::element_type __node; - typedef __remove_const_t<__node> __non_const_node; - typedef __rebind_pointer_t<__node_pointer, __non_const_node> - __non_const_node_pointer; public: - typedef __hash_local_iterator<__non_const_node_pointer> - __non_const_iterator; + typedef __hash_local_iterator<__non_const_node_pointer> __non_const_iterator; - typedef forward_iterator_tag iterator_category; - typedef typename _NodeTypes::__node_value_type value_type; - typedef typename _NodeTypes::difference_type difference_type; - typedef const value_type& reference; - typedef typename _NodeTypes::__const_node_value_type_pointer pointer; + typedef forward_iterator_tag iterator_category; + typedef typename _NodeTypes::__node_value_type value_type; + typedef typename _NodeTypes::difference_type difference_type; + typedef const value_type& reference; + typedef typename _NodeTypes::__const_node_value_type_pointer pointer; + _LIBCPP_HIDE_FROM_ABI __hash_const_local_iterator() _NOEXCEPT : __node_(nullptr) {} - _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT : __node_(nullptr) { - _VSTD::__debug_db_insert_i(this); - } + _LIBCPP_HIDE_FROM_ABI __hash_const_local_iterator(const __non_const_iterator& __x) _NOEXCEPT + : __node_(__x.__node_), + __bucket_(__x.__bucket_), + __bucket_count_(__x.__bucket_count_) {} - _LIBCPP_INLINE_VISIBILITY - __hash_const_local_iterator(const __non_const_iterator& __x) _NOEXCEPT - : __node_(__x.__node_), - __bucket_(__x.__bucket_), - __bucket_count_(__x.__bucket_count_) - { -#ifdef _LIBCPP_ENABLE_DEBUG_MODE - __get_db()->__iterator_copy(this, _VSTD::addressof(__x)); -#endif - } + _LIBCPP_HIDE_FROM_ABI reference operator*() const { + _LIBCPP_ASSERT_NON_NULL( + __node_ != nullptr, "Attempted to dereference a non-dereferenceable unordered container const_local_iterator"); + return __node_->__upcast()->__get_value(); + } -#ifdef _LIBCPP_ENABLE_DEBUG_MODE - _LIBCPP_INLINE_VISIBILITY - __hash_const_local_iterator(const __hash_const_local_iterator& __i) - : __node_(__i.__node_), - __bucket_(__i.__bucket_), - __bucket_count_(__i.__bucket_count_) - { - __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); - } + _LIBCPP_HIDE_FROM_ABI pointer operator->() const { + _LIBCPP_ASSERT_NON_NULL( + __node_ != nullptr, "Attempted to dereference a non-dereferenceable unordered container const_local_iterator"); + return pointer_traits::pointer_to(__node_->__upcast()->__get_value()); + } - _LIBCPP_INLINE_VISIBILITY - ~__hash_const_local_iterator() - { - __get_db()->__erase_i(this); - } + _LIBCPP_HIDE_FROM_ABI __hash_const_local_iterator& operator++() { + _LIBCPP_ASSERT_NON_NULL( + __node_ != nullptr, "Attempted to increment a non-incrementable unordered container const_local_iterator"); + __node_ = __node_->__next_; + if (__node_ != nullptr && std::__constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_) + __node_ = nullptr; + return *this; + } - _LIBCPP_INLINE_VISIBILITY - __hash_const_local_iterator& operator=(const __hash_const_local_iterator& __i) - { - if (this != _VSTD::addressof(__i)) - { - __get_db()->__iterator_copy(this, _VSTD::addressof(__i)); - __node_ = __i.__node_; - __bucket_ = __i.__bucket_; - __bucket_count_ = __i.__bucket_count_; - } - return *this; - } -#endif // _LIBCPP_ENABLE_DEBUG_MODE + _LIBCPP_HIDE_FROM_ABI __hash_const_local_iterator operator++(int) { + __hash_const_local_iterator __t(*this); + ++(*this); + return __t; + } - _LIBCPP_INLINE_VISIBILITY - reference operator*() const { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable unordered container const_local_iterator"); - return __node_->__upcast()->__value_; - } - - _LIBCPP_INLINE_VISIBILITY - pointer operator->() const { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to dereference a non-dereferenceable unordered container const_local_iterator"); - return pointer_traits::pointer_to(__node_->__upcast()->__value_); - } - - _LIBCPP_INLINE_VISIBILITY - __hash_const_local_iterator& operator++() { - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__dereferenceable(this), - "Attempted to increment a non-incrementable unordered container const_local_iterator"); - __node_ = __node_->__next_; - if (__node_ != nullptr && std::__constrain_hash(__node_->__hash(), __bucket_count_) != __bucket_) - __node_ = nullptr; - return *this; - } - - _LIBCPP_INLINE_VISIBILITY - __hash_const_local_iterator operator++(int) - { - __hash_const_local_iterator __t(*this); - ++(*this); - return __t; - } - - friend _LIBCPP_INLINE_VISIBILITY - bool operator==(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y) - { - return __x.__node_ == __y.__node_; - } - friend _LIBCPP_INLINE_VISIBILITY - bool operator!=(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y) - {return !(__x == __y);} + friend _LIBCPP_HIDE_FROM_ABI bool + operator==(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y) { + return __x.__node_ == __y.__node_; + } + friend _LIBCPP_HIDE_FROM_ABI bool + operator!=(const __hash_const_local_iterator& __x, const __hash_const_local_iterator& __y) { + return !(__x == __y); + } private: - _LIBCPP_INLINE_VISIBILITY - explicit __hash_const_local_iterator(__next_pointer __node_ptr, size_t __bucket, - size_t __bucket_count, const void* __c) _NOEXCEPT - : __node_(__node_ptr), - __bucket_(__bucket), - __bucket_count_(__bucket_count) - { - (void)__c; -#ifdef _LIBCPP_ENABLE_DEBUG_MODE - __get_db()->__insert_ic(this, __c); -#endif - if (__node_ != nullptr) - __node_ = __node_->__next_; - } - template friend class __hash_table; - template friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; + _LIBCPP_HIDE_FROM_ABI explicit __hash_const_local_iterator( + __next_pointer __node_ptr, size_t __bucket, size_t __bucket_count) _NOEXCEPT + : __node_(__node_ptr), + __bucket_(__bucket), + __bucket_count_(__bucket_count) { + if (__node_ != nullptr) + __node_ = __node_->__next_; + } + + template + friend class __hash_table; + template + friend class _LIBCPP_TEMPLATE_VIS __hash_map_const_iterator; }; template -class __bucket_list_deallocator -{ - typedef _Alloc allocator_type; - typedef allocator_traits __alloc_traits; - typedef typename __alloc_traits::size_type size_type; +class __bucket_list_deallocator { + typedef _Alloc allocator_type; + typedef allocator_traits __alloc_traits; + typedef typename __alloc_traits::size_type size_type; + + __compressed_pair __data_; - __compressed_pair __data_; public: - typedef typename __alloc_traits::pointer pointer; + typedef typename __alloc_traits::pointer pointer; - _LIBCPP_INLINE_VISIBILITY - __bucket_list_deallocator() - _NOEXCEPT_(is_nothrow_default_constructible::value) - : __data_(0, __default_init_tag()) {} + _LIBCPP_HIDE_FROM_ABI __bucket_list_deallocator() _NOEXCEPT_(is_nothrow_default_constructible::value) + : __data_(0, __default_init_tag()) {} - _LIBCPP_INLINE_VISIBILITY - __bucket_list_deallocator(const allocator_type& __a, size_type __size) - _NOEXCEPT_(is_nothrow_copy_constructible::value) - : __data_(__size, __a) {} + _LIBCPP_HIDE_FROM_ABI __bucket_list_deallocator(const allocator_type& __a, size_type __size) + _NOEXCEPT_(is_nothrow_copy_constructible::value) + : __data_(__size, __a) {} - _LIBCPP_INLINE_VISIBILITY - __bucket_list_deallocator(__bucket_list_deallocator&& __x) - _NOEXCEPT_(is_nothrow_move_constructible::value) - : __data_(_VSTD::move(__x.__data_)) - { - __x.size() = 0; - } + _LIBCPP_HIDE_FROM_ABI __bucket_list_deallocator(__bucket_list_deallocator&& __x) + _NOEXCEPT_(is_nothrow_move_constructible::value) + : __data_(std::move(__x.__data_)) { + __x.size() = 0; + } - _LIBCPP_INLINE_VISIBILITY - size_type& size() _NOEXCEPT {return __data_.first();} - _LIBCPP_INLINE_VISIBILITY - size_type size() const _NOEXCEPT {return __data_.first();} + _LIBCPP_HIDE_FROM_ABI size_type& size() _NOEXCEPT { return __data_.first(); } + _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __data_.first(); } - _LIBCPP_INLINE_VISIBILITY - allocator_type& __alloc() _NOEXCEPT {return __data_.second();} - _LIBCPP_INLINE_VISIBILITY - const allocator_type& __alloc() const _NOEXCEPT {return __data_.second();} + _LIBCPP_HIDE_FROM_ABI allocator_type& __alloc() _NOEXCEPT { return __data_.second(); } + _LIBCPP_HIDE_FROM_ABI const allocator_type& __alloc() const _NOEXCEPT { return __data_.second(); } - _LIBCPP_INLINE_VISIBILITY - void operator()(pointer __p) _NOEXCEPT - { - __alloc_traits::deallocate(__alloc(), __p, size()); - } + _LIBCPP_HIDE_FROM_ABI void operator()(pointer __p) _NOEXCEPT { __alloc_traits::deallocate(__alloc(), __p, size()); } }; -template class __hash_map_node_destructor; +template +class __hash_map_node_destructor; template -class __hash_node_destructor -{ - typedef _Alloc allocator_type; - typedef allocator_traits __alloc_traits; +class __hash_node_destructor { + typedef _Alloc allocator_type; + typedef allocator_traits __alloc_traits; public: - typedef typename __alloc_traits::pointer pointer; + typedef typename __alloc_traits::pointer pointer; + private: - typedef __hash_node_types _NodeTypes; + typedef __hash_node_types _NodeTypes; - allocator_type& __na_; + allocator_type& __na_; public: - bool __value_constructed; + bool __value_constructed; - _LIBCPP_HIDE_FROM_ABI __hash_node_destructor(__hash_node_destructor const&) = default; - _LIBCPP_HIDE_FROM_ABI __hash_node_destructor& operator=(const __hash_node_destructor&) = delete; + _LIBCPP_HIDE_FROM_ABI __hash_node_destructor(__hash_node_destructor const&) = default; + _LIBCPP_HIDE_FROM_ABI __hash_node_destructor& operator=(const __hash_node_destructor&) = delete; + _LIBCPP_HIDE_FROM_ABI explicit __hash_node_destructor(allocator_type& __na, bool __constructed = false) _NOEXCEPT + : __na_(__na), + __value_constructed(__constructed) {} - _LIBCPP_INLINE_VISIBILITY - explicit __hash_node_destructor(allocator_type& __na, - bool __constructed = false) _NOEXCEPT - : __na_(__na), - __value_constructed(__constructed) - {} - - _LIBCPP_INLINE_VISIBILITY - void operator()(pointer __p) _NOEXCEPT - { - if (__value_constructed) - __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__value_)); - if (__p) - __alloc_traits::deallocate(__na_, __p, 1); + _LIBCPP_HIDE_FROM_ABI void operator()(pointer __p) _NOEXCEPT { + if (__value_constructed) { + __alloc_traits::destroy(__na_, _NodeTypes::__get_ptr(__p->__get_value())); + std::__destroy_at(std::addressof(*__p)); } + if (__p) + __alloc_traits::deallocate(__na_, __p, 1); + } - template friend class __hash_map_node_destructor; + template + friend class __hash_map_node_destructor; }; #if _LIBCPP_STD_VER >= 17 @@ -844,33 +625,30 @@ template struct __generic_container_node_destructor; template -struct __generic_container_node_destructor<__hash_node<_Tp, _VoidPtr>, _Alloc> - : __hash_node_destructor<_Alloc> -{ - using __hash_node_destructor<_Alloc>::__hash_node_destructor; +struct __generic_container_node_destructor<__hash_node<_Tp, _VoidPtr>, _Alloc> : __hash_node_destructor<_Alloc> { + using __hash_node_destructor<_Alloc>::__hash_node_destructor; }; #endif template struct __enforce_unordered_container_requirements { #ifndef _LIBCPP_CXX03_LANG - static_assert(__check_hash_requirements<_Key, _Hash>::value, - "the specified hash does not meet the Hash requirements"); - static_assert(is_copy_constructible<_Equal>::value, - "the specified comparator is required to be copy constructible"); + static_assert(__check_hash_requirements<_Key, _Hash>::value, + "the specified hash does not meet the Hash requirements"); + static_assert(is_copy_constructible<_Equal>::value, "the specified comparator is required to be copy constructible"); #endif - typedef int type; + typedef int type; }; template #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Equal const&, _Key const&, _Key const&>::value, - "the specified comparator type does not provide a viable const call operator") - _LIBCPP_DIAGNOSE_WARNING(!__invokable<_Hash const&, _Key const&>::value, - "the specified hash functor does not provide a viable const call operator") +_LIBCPP_DIAGNOSE_WARNING(!__invokable<_Equal const&, _Key const&, _Key const&>::value, + "the specified comparator type does not provide a viable const call operator") +_LIBCPP_DIAGNOSE_WARNING(!__invokable<_Hash const&, _Key const&>::value, + "the specified hash functor does not provide a viable const call operator") #endif -typename __enforce_unordered_container_requirements<_Key, _Hash, _Equal>::type -__diagnose_unordered_container_requirements(int); + typename __enforce_unordered_container_requirements<_Key, _Hash, _Equal>::type + __diagnose_unordered_container_requirements(int); // This dummy overload is used so that the compiler won't emit a spurious // "no matching function for call to __diagnose_unordered_xxx" diagnostic @@ -879,914 +657,670 @@ template int __diagnose_unordered_container_requirements(void*); template -class __hash_table -{ +class __hash_table { public: - typedef _Tp value_type; - typedef _Hash hasher; - typedef _Equal key_equal; - typedef _Alloc allocator_type; + typedef _Tp value_type; + typedef _Hash hasher; + typedef _Equal key_equal; + typedef _Alloc allocator_type; private: - typedef allocator_traits __alloc_traits; - typedef typename - __make_hash_node_types::type - _NodeTypes; -public: + typedef allocator_traits __alloc_traits; + typedef typename __make_hash_node_types::type _NodeTypes; - typedef typename _NodeTypes::__node_value_type __node_value_type; - typedef typename _NodeTypes::__container_value_type __container_value_type; - typedef typename _NodeTypes::key_type key_type; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef typename __alloc_traits::pointer pointer; - typedef typename __alloc_traits::const_pointer const_pointer; +public: + typedef typename _NodeTypes::__node_value_type __node_value_type; + typedef typename _NodeTypes::__container_value_type __container_value_type; + typedef typename _NodeTypes::key_type key_type; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef typename __alloc_traits::pointer pointer; + typedef typename __alloc_traits::const_pointer const_pointer; #ifndef _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE - typedef typename __alloc_traits::size_type size_type; + typedef typename __alloc_traits::size_type size_type; #else - typedef typename _NodeTypes::size_type size_type; + typedef typename _NodeTypes::size_type size_type; #endif - typedef typename _NodeTypes::difference_type difference_type; -public: - // Create __node + typedef typename _NodeTypes::difference_type difference_type; - typedef typename _NodeTypes::__node_type __node; - typedef __rebind_alloc<__alloc_traits, __node> __node_allocator; - typedef allocator_traits<__node_allocator> __node_traits; - typedef typename _NodeTypes::__void_pointer __void_pointer; - typedef typename _NodeTypes::__node_pointer __node_pointer; - typedef typename _NodeTypes::__node_pointer __node_const_pointer; - typedef typename _NodeTypes::__node_base_type __first_node; - typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; - typedef typename _NodeTypes::__next_pointer __next_pointer; +public: + // Create __node + + typedef typename _NodeTypes::__node_type __node; + typedef __rebind_alloc<__alloc_traits, __node> __node_allocator; + typedef allocator_traits<__node_allocator> __node_traits; + typedef typename _NodeTypes::__void_pointer __void_pointer; + typedef typename _NodeTypes::__node_pointer __node_pointer; + typedef typename _NodeTypes::__node_pointer __node_const_pointer; + typedef typename _NodeTypes::__node_base_type __first_node; + typedef typename _NodeTypes::__node_base_pointer __node_base_pointer; + typedef typename _NodeTypes::__next_pointer __next_pointer; private: - // check for sane allocator pointer rebinding semantics. Rebinding the - // allocator for a new pointer type should be exactly the same as rebinding - // the pointer using 'pointer_traits'. - static_assert((is_same<__node_pointer, typename __node_traits::pointer>::value), - "Allocator does not rebind pointers in a sane manner."); - typedef __rebind_alloc<__node_traits, __first_node> __node_base_allocator; - typedef allocator_traits<__node_base_allocator> __node_base_traits; - static_assert((is_same<__node_base_pointer, typename __node_base_traits::pointer>::value), - "Allocator does not rebind pointers in a sane manner."); + // check for sane allocator pointer rebinding semantics. Rebinding the + // allocator for a new pointer type should be exactly the same as rebinding + // the pointer using 'pointer_traits'. + static_assert(is_same<__node_pointer, typename __node_traits::pointer>::value, + "Allocator does not rebind pointers in a sane manner."); + typedef __rebind_alloc<__node_traits, __first_node> __node_base_allocator; + typedef allocator_traits<__node_base_allocator> __node_base_traits; + static_assert(is_same<__node_base_pointer, typename __node_base_traits::pointer>::value, + "Allocator does not rebind pointers in a sane manner."); private: + typedef __rebind_alloc<__node_traits, __next_pointer> __pointer_allocator; + typedef __bucket_list_deallocator<__pointer_allocator> __bucket_list_deleter; + typedef unique_ptr<__next_pointer[], __bucket_list_deleter> __bucket_list; + typedef allocator_traits<__pointer_allocator> __pointer_alloc_traits; + typedef typename __bucket_list_deleter::pointer __node_pointer_pointer; - typedef __rebind_alloc<__node_traits, __next_pointer> __pointer_allocator; - typedef __bucket_list_deallocator<__pointer_allocator> __bucket_list_deleter; - typedef unique_ptr<__next_pointer[], __bucket_list_deleter> __bucket_list; - typedef allocator_traits<__pointer_allocator> __pointer_alloc_traits; - typedef typename __bucket_list_deleter::pointer __node_pointer_pointer; + // --- Member data begin --- + __bucket_list __bucket_list_; + __compressed_pair<__first_node, __node_allocator> __p1_; + __compressed_pair __p2_; + __compressed_pair __p3_; + // --- Member data end --- - // --- Member data begin --- - __bucket_list __bucket_list_; - __compressed_pair<__first_node, __node_allocator> __p1_; - __compressed_pair __p2_; - __compressed_pair __p3_; - // --- Member data end --- - - _LIBCPP_INLINE_VISIBILITY - size_type& size() _NOEXCEPT {return __p2_.first();} -public: - _LIBCPP_INLINE_VISIBILITY - size_type size() const _NOEXCEPT {return __p2_.first();} - - _LIBCPP_INLINE_VISIBILITY - hasher& hash_function() _NOEXCEPT {return __p2_.second();} - _LIBCPP_INLINE_VISIBILITY - const hasher& hash_function() const _NOEXCEPT {return __p2_.second();} - - _LIBCPP_INLINE_VISIBILITY - float& max_load_factor() _NOEXCEPT {return __p3_.first();} - _LIBCPP_INLINE_VISIBILITY - float max_load_factor() const _NOEXCEPT {return __p3_.first();} - - _LIBCPP_INLINE_VISIBILITY - key_equal& key_eq() _NOEXCEPT {return __p3_.second();} - _LIBCPP_INLINE_VISIBILITY - const key_equal& key_eq() const _NOEXCEPT {return __p3_.second();} - - _LIBCPP_INLINE_VISIBILITY - __node_allocator& __node_alloc() _NOEXCEPT {return __p1_.second();} - _LIBCPP_INLINE_VISIBILITY - const __node_allocator& __node_alloc() const _NOEXCEPT - {return __p1_.second();} + _LIBCPP_HIDE_FROM_ABI size_type& size() _NOEXCEPT { return __p2_.first(); } public: - typedef __hash_iterator<__node_pointer> iterator; - typedef __hash_const_iterator<__node_pointer> const_iterator; - typedef __hash_local_iterator<__node_pointer> local_iterator; - typedef __hash_const_local_iterator<__node_pointer> const_local_iterator; + _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __p2_.first(); } - _LIBCPP_INLINE_VISIBILITY - __hash_table() - _NOEXCEPT_( - is_nothrow_default_constructible<__bucket_list>::value && - is_nothrow_default_constructible<__first_node>::value && - is_nothrow_default_constructible<__node_allocator>::value && - is_nothrow_default_constructible::value && - is_nothrow_default_constructible::value); - _LIBCPP_INLINE_VISIBILITY - __hash_table(const hasher& __hf, const key_equal& __eql); - _LIBCPP_HIDE_FROM_ABI __hash_table(const hasher& __hf, const key_equal& __eql, - const allocator_type& __a); - _LIBCPP_HIDE_FROM_ABI explicit __hash_table(const allocator_type& __a); - _LIBCPP_HIDE_FROM_ABI __hash_table(const __hash_table& __u); - _LIBCPP_HIDE_FROM_ABI __hash_table(const __hash_table& __u, const allocator_type& __a); - _LIBCPP_HIDE_FROM_ABI __hash_table(__hash_table&& __u) - _NOEXCEPT_( - is_nothrow_move_constructible<__bucket_list>::value && - is_nothrow_move_constructible<__first_node>::value && - is_nothrow_move_constructible<__node_allocator>::value && - is_nothrow_move_constructible::value && - is_nothrow_move_constructible::value); - _LIBCPP_HIDE_FROM_ABI __hash_table(__hash_table&& __u, const allocator_type& __a); - _LIBCPP_HIDE_FROM_ABI ~__hash_table(); + _LIBCPP_HIDE_FROM_ABI hasher& hash_function() _NOEXCEPT { return __p2_.second(); } + _LIBCPP_HIDE_FROM_ABI const hasher& hash_function() const _NOEXCEPT { return __p2_.second(); } - _LIBCPP_HIDE_FROM_ABI __hash_table& operator=(const __hash_table& __u); - _LIBCPP_INLINE_VISIBILITY - __hash_table& operator=(__hash_table&& __u) - _NOEXCEPT_( - __node_traits::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable<__node_allocator>::value && - is_nothrow_move_assignable::value && - is_nothrow_move_assignable::value); - template - _LIBCPP_HIDE_FROM_ABI void __assign_unique(_InputIterator __first, _InputIterator __last); - template - _LIBCPP_HIDE_FROM_ABI void __assign_multi(_InputIterator __first, _InputIterator __last); + _LIBCPP_HIDE_FROM_ABI float& max_load_factor() _NOEXCEPT { return __p3_.first(); } + _LIBCPP_HIDE_FROM_ABI float max_load_factor() const _NOEXCEPT { return __p3_.first(); } - _LIBCPP_INLINE_VISIBILITY - size_type max_size() const _NOEXCEPT - { - return _VSTD::min( - __node_traits::max_size(__node_alloc()), - numeric_limits::max() - ); - } + _LIBCPP_HIDE_FROM_ABI key_equal& key_eq() _NOEXCEPT { return __p3_.second(); } + _LIBCPP_HIDE_FROM_ABI const key_equal& key_eq() const _NOEXCEPT { return __p3_.second(); } + + _LIBCPP_HIDE_FROM_ABI __node_allocator& __node_alloc() _NOEXCEPT { return __p1_.second(); } + _LIBCPP_HIDE_FROM_ABI const __node_allocator& __node_alloc() const _NOEXCEPT { return __p1_.second(); } + +public: + typedef __hash_iterator<__node_pointer> iterator; + typedef __hash_const_iterator<__node_pointer> const_iterator; + typedef __hash_local_iterator<__node_pointer> local_iterator; + typedef __hash_const_local_iterator<__node_pointer> const_local_iterator; + + _LIBCPP_HIDE_FROM_ABI __hash_table() _NOEXCEPT_( + is_nothrow_default_constructible<__bucket_list>::value&& is_nothrow_default_constructible<__first_node>::value&& + is_nothrow_default_constructible<__node_allocator>::value&& is_nothrow_default_constructible::value&& + is_nothrow_default_constructible::value); + _LIBCPP_HIDE_FROM_ABI __hash_table(const hasher& __hf, const key_equal& __eql); + _LIBCPP_HIDE_FROM_ABI __hash_table(const hasher& __hf, const key_equal& __eql, const allocator_type& __a); + _LIBCPP_HIDE_FROM_ABI explicit __hash_table(const allocator_type& __a); + _LIBCPP_HIDE_FROM_ABI __hash_table(const __hash_table& __u); + _LIBCPP_HIDE_FROM_ABI __hash_table(const __hash_table& __u, const allocator_type& __a); + _LIBCPP_HIDE_FROM_ABI __hash_table(__hash_table&& __u) _NOEXCEPT_( + is_nothrow_move_constructible<__bucket_list>::value&& is_nothrow_move_constructible<__first_node>::value&& + is_nothrow_move_constructible<__node_allocator>::value&& is_nothrow_move_constructible::value&& + is_nothrow_move_constructible::value); + _LIBCPP_HIDE_FROM_ABI __hash_table(__hash_table&& __u, const allocator_type& __a); + _LIBCPP_HIDE_FROM_ABI ~__hash_table(); + + _LIBCPP_HIDE_FROM_ABI __hash_table& operator=(const __hash_table& __u); + _LIBCPP_HIDE_FROM_ABI __hash_table& operator=(__hash_table&& __u) + _NOEXCEPT_(__node_traits::propagate_on_container_move_assignment::value&& + is_nothrow_move_assignable<__node_allocator>::value&& is_nothrow_move_assignable::value&& + is_nothrow_move_assignable::value); + template + _LIBCPP_HIDE_FROM_ABI void __assign_unique(_InputIterator __first, _InputIterator __last); + template + _LIBCPP_HIDE_FROM_ABI void __assign_multi(_InputIterator __first, _InputIterator __last); + + _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { + return std::min(__node_traits::max_size(__node_alloc()), numeric_limits::max()); + } private: - _LIBCPP_INLINE_VISIBILITY - __next_pointer __node_insert_multi_prepare(size_t __cp_hash, - value_type& __cp_val); - _LIBCPP_INLINE_VISIBILITY - void __node_insert_multi_perform(__node_pointer __cp, - __next_pointer __pn) _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI __next_pointer __node_insert_multi_prepare(size_t __cp_hash, value_type& __cp_val); + _LIBCPP_HIDE_FROM_ABI void __node_insert_multi_perform(__node_pointer __cp, __next_pointer __pn) _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY - __next_pointer __node_insert_unique_prepare(size_t __nd_hash, - value_type& __nd_val); - _LIBCPP_INLINE_VISIBILITY - void __node_insert_unique_perform(__node_pointer __ptr) _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI __next_pointer __node_insert_unique_prepare(size_t __nd_hash, value_type& __nd_val); + _LIBCPP_HIDE_FROM_ABI void __node_insert_unique_perform(__node_pointer __ptr) _NOEXCEPT; public: - _LIBCPP_INLINE_VISIBILITY - pair __node_insert_unique(__node_pointer __nd); - _LIBCPP_INLINE_VISIBILITY - iterator __node_insert_multi(__node_pointer __nd); - _LIBCPP_INLINE_VISIBILITY - iterator __node_insert_multi(const_iterator __p, - __node_pointer __nd); + _LIBCPP_HIDE_FROM_ABI pair __node_insert_unique(__node_pointer __nd); + _LIBCPP_HIDE_FROM_ABI iterator __node_insert_multi(__node_pointer __nd); + _LIBCPP_HIDE_FROM_ABI iterator __node_insert_multi(const_iterator __p, __node_pointer __nd); - template - _LIBCPP_INLINE_VISIBILITY - pair __emplace_unique_key_args(_Key const& __k, _Args&&... __args); + template + _LIBCPP_HIDE_FROM_ABI pair __emplace_unique_key_args(_Key const& __k, _Args&&... __args); - template - _LIBCPP_INLINE_VISIBILITY - pair __emplace_unique_impl(_Args&&... __args); + template + _LIBCPP_HIDE_FROM_ABI pair __emplace_unique_impl(_Args&&... __args); - template - _LIBCPP_INLINE_VISIBILITY - pair __emplace_unique(_Pp&& __x) { - return __emplace_unique_extract_key(_VSTD::forward<_Pp>(__x), - __can_extract_key<_Pp, key_type>()); - } + template + _LIBCPP_HIDE_FROM_ABI pair __emplace_unique(_Pp&& __x) { + return __emplace_unique_extract_key(std::forward<_Pp>(__x), __can_extract_key<_Pp, key_type>()); + } - template - _LIBCPP_INLINE_VISIBILITY - __enable_if_t<__can_extract_map_key<_First, key_type, __container_value_type>::value, pair > - __emplace_unique(_First&& __f, _Second&& __s) { - return __emplace_unique_key_args(__f, _VSTD::forward<_First>(__f), - _VSTD::forward<_Second>(__s)); - } + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI pair __emplace_unique(_First&& __f, _Second&& __s) { + return __emplace_unique_key_args(__f, std::forward<_First>(__f), std::forward<_Second>(__s)); + } - template - _LIBCPP_INLINE_VISIBILITY - pair __emplace_unique(_Args&&... __args) { - return __emplace_unique_impl(_VSTD::forward<_Args>(__args)...); - } + template + _LIBCPP_HIDE_FROM_ABI pair __emplace_unique(_Args&&... __args) { + return __emplace_unique_impl(std::forward<_Args>(__args)...); + } - template - _LIBCPP_INLINE_VISIBILITY - pair - __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) { - return __emplace_unique_impl(_VSTD::forward<_Pp>(__x)); - } - template - _LIBCPP_INLINE_VISIBILITY - pair - __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) { - return __emplace_unique_key_args(__x, _VSTD::forward<_Pp>(__x)); - } - template - _LIBCPP_INLINE_VISIBILITY - pair - __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) { - return __emplace_unique_key_args(__x.first, _VSTD::forward<_Pp>(__x)); - } + template + _LIBCPP_HIDE_FROM_ABI pair __emplace_unique_extract_key(_Pp&& __x, __extract_key_fail_tag) { + return __emplace_unique_impl(std::forward<_Pp>(__x)); + } + template + _LIBCPP_HIDE_FROM_ABI pair __emplace_unique_extract_key(_Pp&& __x, __extract_key_self_tag) { + return __emplace_unique_key_args(__x, std::forward<_Pp>(__x)); + } + template + _LIBCPP_HIDE_FROM_ABI pair __emplace_unique_extract_key(_Pp&& __x, __extract_key_first_tag) { + return __emplace_unique_key_args(__x.first, std::forward<_Pp>(__x)); + } - template - _LIBCPP_INLINE_VISIBILITY - iterator __emplace_multi(_Args&&... __args); - template - _LIBCPP_INLINE_VISIBILITY - iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args); + template + _LIBCPP_HIDE_FROM_ABI iterator __emplace_multi(_Args&&... __args); + template + _LIBCPP_HIDE_FROM_ABI iterator __emplace_hint_multi(const_iterator __p, _Args&&... __args); + _LIBCPP_HIDE_FROM_ABI pair __insert_unique(__container_value_type&& __x) { + return __emplace_unique_key_args(_NodeTypes::__get_key(__x), std::move(__x)); + } - _LIBCPP_INLINE_VISIBILITY - pair - __insert_unique(__container_value_type&& __x) { - return __emplace_unique_key_args(_NodeTypes::__get_key(__x), _VSTD::move(__x)); - } + template ::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI pair __insert_unique(_Pp&& __x) { + return __emplace_unique(std::forward<_Pp>(__x)); + } - template ::value> > - _LIBCPP_INLINE_VISIBILITY - pair __insert_unique(_Pp&& __x) { - return __emplace_unique(_VSTD::forward<_Pp>(__x)); - } + template + _LIBCPP_HIDE_FROM_ABI iterator __insert_multi(_Pp&& __x) { + return __emplace_multi(std::forward<_Pp>(__x)); + } - template - _LIBCPP_INLINE_VISIBILITY - iterator __insert_multi(_Pp&& __x) { - return __emplace_multi(_VSTD::forward<_Pp>(__x)); - } + template + _LIBCPP_HIDE_FROM_ABI iterator __insert_multi(const_iterator __p, _Pp&& __x) { + return __emplace_hint_multi(__p, std::forward<_Pp>(__x)); + } - template - _LIBCPP_INLINE_VISIBILITY - iterator __insert_multi(const_iterator __p, _Pp&& __x) { - return __emplace_hint_multi(__p, _VSTD::forward<_Pp>(__x)); - } - - _LIBCPP_INLINE_VISIBILITY - pair __insert_unique(const __container_value_type& __x) { - return __emplace_unique_key_args(_NodeTypes::__get_key(__x), __x); - } + _LIBCPP_HIDE_FROM_ABI pair __insert_unique(const __container_value_type& __x) { + return __emplace_unique_key_args(_NodeTypes::__get_key(__x), __x); + } #if _LIBCPP_STD_VER >= 17 - template - _LIBCPP_INLINE_VISIBILITY - _InsertReturnType __node_handle_insert_unique(_NodeHandle&& __nh); - template - _LIBCPP_INLINE_VISIBILITY - iterator __node_handle_insert_unique(const_iterator __hint, - _NodeHandle&& __nh); - template - _LIBCPP_INLINE_VISIBILITY - void __node_handle_merge_unique(_Table& __source); + template + _LIBCPP_HIDE_FROM_ABI _InsertReturnType __node_handle_insert_unique(_NodeHandle&& __nh); + template + _LIBCPP_HIDE_FROM_ABI iterator __node_handle_insert_unique(const_iterator __hint, _NodeHandle&& __nh); + template + _LIBCPP_HIDE_FROM_ABI void __node_handle_merge_unique(_Table& __source); - template - _LIBCPP_INLINE_VISIBILITY - iterator __node_handle_insert_multi(_NodeHandle&& __nh); - template - _LIBCPP_INLINE_VISIBILITY - iterator __node_handle_insert_multi(const_iterator __hint, _NodeHandle&& __nh); - template - _LIBCPP_INLINE_VISIBILITY - void __node_handle_merge_multi(_Table& __source); + template + _LIBCPP_HIDE_FROM_ABI iterator __node_handle_insert_multi(_NodeHandle&& __nh); + template + _LIBCPP_HIDE_FROM_ABI iterator __node_handle_insert_multi(const_iterator __hint, _NodeHandle&& __nh); + template + _LIBCPP_HIDE_FROM_ABI void __node_handle_merge_multi(_Table& __source); - template - _LIBCPP_INLINE_VISIBILITY - _NodeHandle __node_handle_extract(key_type const& __key); - template - _LIBCPP_INLINE_VISIBILITY - _NodeHandle __node_handle_extract(const_iterator __it); + template + _LIBCPP_HIDE_FROM_ABI _NodeHandle __node_handle_extract(key_type const& __key); + template + _LIBCPP_HIDE_FROM_ABI _NodeHandle __node_handle_extract(const_iterator __it); #endif - _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY void __rehash_unique(size_type __n) { __rehash(__n); } - _LIBCPP_INLINE_VISIBILITY void __rehash_multi(size_type __n) { __rehash(__n); } - _LIBCPP_INLINE_VISIBILITY void __reserve_unique(size_type __n) - { - __rehash_unique(static_cast(std::ceil(__n / max_load_factor()))); - } - _LIBCPP_INLINE_VISIBILITY void __reserve_multi(size_type __n) - { - __rehash_multi(static_cast(std::ceil(__n / max_load_factor()))); - } + _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI void __rehash_unique(size_type __n) { __rehash(__n); } + _LIBCPP_HIDE_FROM_ABI void __rehash_multi(size_type __n) { __rehash(__n); } + _LIBCPP_HIDE_FROM_ABI void __reserve_unique(size_type __n) { + __rehash_unique(static_cast(std::ceil(__n / max_load_factor()))); + } + _LIBCPP_HIDE_FROM_ABI void __reserve_multi(size_type __n) { + __rehash_multi(static_cast(std::ceil(__n / max_load_factor()))); + } - _LIBCPP_INLINE_VISIBILITY - size_type bucket_count() const _NOEXCEPT - { - return __bucket_list_.get_deleter().size(); - } + _LIBCPP_HIDE_FROM_ABI size_type bucket_count() const _NOEXCEPT { return __bucket_list_.get_deleter().size(); } - _LIBCPP_INLINE_VISIBILITY - iterator begin() _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY - iterator end() _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY - const_iterator begin() const _NOEXCEPT; - _LIBCPP_INLINE_VISIBILITY - const_iterator end() const _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT; - template - _LIBCPP_INLINE_VISIBILITY - size_type bucket(const _Key& __k) const - { - _LIBCPP_ASSERT(bucket_count() > 0, - "unordered container::bucket(key) called when bucket_count() == 0"); - return std::__constrain_hash(hash_function()(__k), bucket_count()); - } + template + _LIBCPP_HIDE_FROM_ABI size_type bucket(const _Key& __k) const { + _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN( + bucket_count() > 0, "unordered container::bucket(key) called when bucket_count() == 0"); + return std::__constrain_hash(hash_function()(__k), bucket_count()); + } - template - _LIBCPP_HIDE_FROM_ABI iterator find(const _Key& __x); - template - _LIBCPP_HIDE_FROM_ABI const_iterator find(const _Key& __x) const; + template + _LIBCPP_HIDE_FROM_ABI iterator find(const _Key& __x); + template + _LIBCPP_HIDE_FROM_ABI const_iterator find(const _Key& __x) const; - typedef __hash_node_destructor<__node_allocator> _Dp; - typedef unique_ptr<__node, _Dp> __node_holder; + typedef __hash_node_destructor<__node_allocator> _Dp; + typedef unique_ptr<__node, _Dp> __node_holder; - _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p); - _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __first, const_iterator __last); - template - _LIBCPP_HIDE_FROM_ABI size_type __erase_unique(const _Key& __k); - template - _LIBCPP_HIDE_FROM_ABI size_type __erase_multi(const _Key& __k); - _LIBCPP_HIDE_FROM_ABI __node_holder remove(const_iterator __p) _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p); + _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __first, const_iterator __last); + template + _LIBCPP_HIDE_FROM_ABI size_type __erase_unique(const _Key& __k); + template + _LIBCPP_HIDE_FROM_ABI size_type __erase_multi(const _Key& __k); + _LIBCPP_HIDE_FROM_ABI __node_holder remove(const_iterator __p) _NOEXCEPT; - template - _LIBCPP_INLINE_VISIBILITY - size_type __count_unique(const _Key& __k) const; - template - _LIBCPP_HIDE_FROM_ABI size_type __count_multi(const _Key& __k) const; + template + _LIBCPP_HIDE_FROM_ABI size_type __count_unique(const _Key& __k) const; + template + _LIBCPP_HIDE_FROM_ABI size_type __count_multi(const _Key& __k) const; - template - _LIBCPP_HIDE_FROM_ABI pair - __equal_range_unique(const _Key& __k); - template - _LIBCPP_HIDE_FROM_ABI pair - __equal_range_unique(const _Key& __k) const; + template + _LIBCPP_HIDE_FROM_ABI pair __equal_range_unique(const _Key& __k); + template + _LIBCPP_HIDE_FROM_ABI pair __equal_range_unique(const _Key& __k) const; - template - _LIBCPP_HIDE_FROM_ABI pair - __equal_range_multi(const _Key& __k); - template - _LIBCPP_HIDE_FROM_ABI pair - __equal_range_multi(const _Key& __k) const; + template + _LIBCPP_HIDE_FROM_ABI pair __equal_range_multi(const _Key& __k); + template + _LIBCPP_HIDE_FROM_ABI pair __equal_range_multi(const _Key& __k) const; - _LIBCPP_HIDE_FROM_ABI void swap(__hash_table& __u) + _LIBCPP_HIDE_FROM_ABI void swap(__hash_table& __u) #if _LIBCPP_STD_VER <= 11 - _NOEXCEPT_( - __is_nothrow_swappable::value && __is_nothrow_swappable::value - && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value - || __is_nothrow_swappable<__pointer_allocator>::value) - && (!__node_traits::propagate_on_container_swap::value - || __is_nothrow_swappable<__node_allocator>::value) - ); + _NOEXCEPT_(__is_nothrow_swappable_v&& __is_nothrow_swappable_v && + (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value || + __is_nothrow_swappable_v<__pointer_allocator>) && + (!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__node_allocator>)); #else - _NOEXCEPT_(__is_nothrow_swappable::value && __is_nothrow_swappable::value); + _NOEXCEPT_(__is_nothrow_swappable_v&& __is_nothrow_swappable_v); #endif - _LIBCPP_INLINE_VISIBILITY - size_type max_bucket_count() const _NOEXCEPT - {return max_size(); } - _LIBCPP_HIDE_FROM_ABI size_type bucket_size(size_type __n) const; - _LIBCPP_INLINE_VISIBILITY float load_factor() const _NOEXCEPT - { - size_type __bc = bucket_count(); - return __bc != 0 ? (float)size() / __bc : 0.f; - } - _LIBCPP_INLINE_VISIBILITY void max_load_factor(float __mlf) _NOEXCEPT - { - _LIBCPP_ASSERT(__mlf > 0, - "unordered container::max_load_factor(lf) called with lf <= 0"); - max_load_factor() = _VSTD::max(__mlf, load_factor()); - } + _LIBCPP_HIDE_FROM_ABI size_type max_bucket_count() const _NOEXCEPT { return max_size(); } + _LIBCPP_HIDE_FROM_ABI size_type bucket_size(size_type __n) const; + _LIBCPP_HIDE_FROM_ABI float load_factor() const _NOEXCEPT { + size_type __bc = bucket_count(); + return __bc != 0 ? (float)size() / __bc : 0.f; + } + _LIBCPP_HIDE_FROM_ABI void max_load_factor(float __mlf) _NOEXCEPT { + // While passing a non-positive load factor is undefined behavior, in practice the result will be benign (the + // call will be equivalent to `max_load_factor(load_factor())`, which is also the case for passing a valid value + // less than the current `load_factor`). + _LIBCPP_ASSERT_PEDANTIC(__mlf > 0, "unordered container::max_load_factor(lf) called with lf <= 0"); + max_load_factor() = std::max(__mlf, load_factor()); + } - _LIBCPP_INLINE_VISIBILITY - local_iterator - begin(size_type __n) - { - _LIBCPP_ASSERT(__n < bucket_count(), - "unordered container::begin(n) called with n >= bucket_count()"); - return local_iterator(__bucket_list_[__n], __n, bucket_count(), this); - } + _LIBCPP_HIDE_FROM_ABI local_iterator begin(size_type __n) { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __n < bucket_count(), "unordered container::begin(n) called with n >= bucket_count()"); + return local_iterator(__bucket_list_[__n], __n, bucket_count()); + } - _LIBCPP_INLINE_VISIBILITY - local_iterator - end(size_type __n) - { - _LIBCPP_ASSERT(__n < bucket_count(), - "unordered container::end(n) called with n >= bucket_count()"); - return local_iterator(nullptr, __n, bucket_count(), this); - } + _LIBCPP_HIDE_FROM_ABI local_iterator end(size_type __n) { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __n < bucket_count(), "unordered container::end(n) called with n >= bucket_count()"); + return local_iterator(nullptr, __n, bucket_count()); + } - _LIBCPP_INLINE_VISIBILITY - const_local_iterator - cbegin(size_type __n) const - { - _LIBCPP_ASSERT(__n < bucket_count(), - "unordered container::cbegin(n) called with n >= bucket_count()"); - return const_local_iterator(__bucket_list_[__n], __n, bucket_count(), this); - } + _LIBCPP_HIDE_FROM_ABI const_local_iterator cbegin(size_type __n) const { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __n < bucket_count(), "unordered container::cbegin(n) called with n >= bucket_count()"); + return const_local_iterator(__bucket_list_[__n], __n, bucket_count()); + } - _LIBCPP_INLINE_VISIBILITY - const_local_iterator - cend(size_type __n) const - { - _LIBCPP_ASSERT(__n < bucket_count(), - "unordered container::cend(n) called with n >= bucket_count()"); - return const_local_iterator(nullptr, __n, bucket_count(), this); - } - -#ifdef _LIBCPP_ENABLE_DEBUG_MODE - - _LIBCPP_HIDE_FROM_ABI bool __dereferenceable(const const_iterator* __i) const; - _LIBCPP_HIDE_FROM_ABI bool __decrementable(const const_iterator* __i) const; - _LIBCPP_HIDE_FROM_ABI bool __addable(const const_iterator* __i, ptrdiff_t __n) const; - _LIBCPP_HIDE_FROM_ABI bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const; - -#endif // _LIBCPP_ENABLE_DEBUG_MODE + _LIBCPP_HIDE_FROM_ABI const_local_iterator cend(size_type __n) const { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __n < bucket_count(), "unordered container::cend(n) called with n >= bucket_count()"); + return const_local_iterator(nullptr, __n, bucket_count()); + } private: - template - _LIBCPP_HIDE_FROM_ABI void __rehash(size_type __n); - template - _LIBCPP_HIDE_FROM_ABI void __do_rehash(size_type __n); + template + _LIBCPP_HIDE_FROM_ABI void __rehash(size_type __n); + template + _LIBCPP_HIDE_FROM_ABI void __do_rehash(size_type __n); - template - _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node(_Args&& ...__args); + template + _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node(_Args&&... __args); - template - _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node_hash(size_t __hash, _First&& __f, _Rest&&... __rest); + template + _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node_hash(size_t __hash, _First&& __f, _Rest&&... __rest); + _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __hash_table& __u) { + __copy_assign_alloc(__u, integral_constant()); + } + _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __hash_table& __u, true_type); + _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __hash_table&, false_type) {} - _LIBCPP_INLINE_VISIBILITY - void __copy_assign_alloc(const __hash_table& __u) - {__copy_assign_alloc(__u, integral_constant());} - _LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc(const __hash_table& __u, true_type); - _LIBCPP_INLINE_VISIBILITY - void __copy_assign_alloc(const __hash_table&, false_type) {} + _LIBCPP_HIDE_FROM_ABI void __move_assign(__hash_table& __u, false_type); + _LIBCPP_HIDE_FROM_ABI void __move_assign(__hash_table& __u, true_type) + _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value&& is_nothrow_move_assignable::value&& + is_nothrow_move_assignable::value); + _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__hash_table& __u) _NOEXCEPT_( + !__node_traits::propagate_on_container_move_assignment::value || + (is_nothrow_move_assignable<__pointer_allocator>::value && is_nothrow_move_assignable<__node_allocator>::value)) { + __move_assign_alloc(__u, integral_constant()); + } + _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__hash_table& __u, true_type) _NOEXCEPT_( + is_nothrow_move_assignable<__pointer_allocator>::value&& is_nothrow_move_assignable<__node_allocator>::value) { + __bucket_list_.get_deleter().__alloc() = std::move(__u.__bucket_list_.get_deleter().__alloc()); + __node_alloc() = std::move(__u.__node_alloc()); + } + _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__hash_table&, false_type) _NOEXCEPT {} - _LIBCPP_HIDE_FROM_ABI void __move_assign(__hash_table& __u, false_type); - _LIBCPP_HIDE_FROM_ABI void __move_assign(__hash_table& __u, true_type) - _NOEXCEPT_( - is_nothrow_move_assignable<__node_allocator>::value && - is_nothrow_move_assignable::value && - is_nothrow_move_assignable::value); - _LIBCPP_INLINE_VISIBILITY - void __move_assign_alloc(__hash_table& __u) - _NOEXCEPT_( - !__node_traits::propagate_on_container_move_assignment::value || - (is_nothrow_move_assignable<__pointer_allocator>::value && - is_nothrow_move_assignable<__node_allocator>::value)) - {__move_assign_alloc(__u, integral_constant());} - _LIBCPP_INLINE_VISIBILITY - void __move_assign_alloc(__hash_table& __u, true_type) - _NOEXCEPT_( - is_nothrow_move_assignable<__pointer_allocator>::value && - is_nothrow_move_assignable<__node_allocator>::value) - { - __bucket_list_.get_deleter().__alloc() = - _VSTD::move(__u.__bucket_list_.get_deleter().__alloc()); - __node_alloc() = _VSTD::move(__u.__node_alloc()); - } - _LIBCPP_INLINE_VISIBILITY - void __move_assign_alloc(__hash_table&, false_type) _NOEXCEPT {} + _LIBCPP_HIDE_FROM_ABI void __deallocate_node(__next_pointer __np) _NOEXCEPT; + _LIBCPP_HIDE_FROM_ABI __next_pointer __detach() _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI void __deallocate_node(__next_pointer __np) _NOEXCEPT; - _LIBCPP_HIDE_FROM_ABI __next_pointer __detach() _NOEXCEPT; - - template friend class _LIBCPP_TEMPLATE_VIS unordered_map; - template friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; + template + friend class _LIBCPP_TEMPLATE_VIS unordered_map; + template + friend class _LIBCPP_TEMPLATE_VIS unordered_multimap; }; template -inline -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table() - _NOEXCEPT_( - is_nothrow_default_constructible<__bucket_list>::value && - is_nothrow_default_constructible<__first_node>::value && - is_nothrow_default_constructible<__node_allocator>::value && - is_nothrow_default_constructible::value && - is_nothrow_default_constructible::value) - : __p2_(0, __default_init_tag()), - __p3_(1.0f, __default_init_tag()) -{ -} +inline __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table() _NOEXCEPT_( + is_nothrow_default_constructible<__bucket_list>::value&& is_nothrow_default_constructible<__first_node>::value&& + is_nothrow_default_constructible<__node_allocator>::value&& is_nothrow_default_constructible::value&& + is_nothrow_default_constructible::value) + : __p2_(0, __default_init_tag()), __p3_(1.0f, __default_init_tag()) {} template -inline -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf, - const key_equal& __eql) - : __bucket_list_(nullptr, __bucket_list_deleter()), - __p1_(), - __p2_(0, __hf), - __p3_(1.0f, __eql) -{ -} +inline __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf, const key_equal& __eql) + : __bucket_list_(nullptr, __bucket_list_deleter()), __p1_(), __p2_(0, __hf), __p3_(1.0f, __eql) {} template -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const hasher& __hf, - const key_equal& __eql, - const allocator_type& __a) +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table( + const hasher& __hf, const key_equal& __eql, const allocator_type& __a) : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), __p1_(__default_init_tag(), __node_allocator(__a)), __p2_(0, __hf), - __p3_(1.0f, __eql) -{ -} + __p3_(1.0f, __eql) {} template __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const allocator_type& __a) : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), __p1_(__default_init_tag(), __node_allocator(__a)), __p2_(0, __default_init_tag()), - __p3_(1.0f, __default_init_tag()) -{ -} + __p3_(1.0f, __default_init_tag()) {} template __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u) : __bucket_list_(nullptr, - __bucket_list_deleter(allocator_traits<__pointer_allocator>:: - select_on_container_copy_construction( - __u.__bucket_list_.get_deleter().__alloc()), 0)), - __p1_(__default_init_tag(), allocator_traits<__node_allocator>:: - select_on_container_copy_construction(__u.__node_alloc())), + __bucket_list_deleter(allocator_traits<__pointer_allocator>::select_on_container_copy_construction( + __u.__bucket_list_.get_deleter().__alloc()), + 0)), + __p1_(__default_init_tag(), + allocator_traits<__node_allocator>::select_on_container_copy_construction(__u.__node_alloc())), __p2_(0, __u.hash_function()), - __p3_(__u.__p3_) -{ -} + __p3_(__u.__p3_) {} template -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u, - const allocator_type& __a) +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u, const allocator_type& __a) : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), __p1_(__default_init_tag(), __node_allocator(__a)), __p2_(0, __u.hash_function()), - __p3_(__u.__p3_) -{ -} + __p3_(__u.__p3_) {} template -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u) - _NOEXCEPT_( - is_nothrow_move_constructible<__bucket_list>::value && - is_nothrow_move_constructible<__first_node>::value && - is_nothrow_move_constructible<__node_allocator>::value && - is_nothrow_move_constructible::value && +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u) _NOEXCEPT_( + is_nothrow_move_constructible<__bucket_list>::value&& is_nothrow_move_constructible<__first_node>::value&& + is_nothrow_move_constructible<__node_allocator>::value&& is_nothrow_move_constructible::value&& is_nothrow_move_constructible::value) - : __bucket_list_(_VSTD::move(__u.__bucket_list_)), - __p1_(_VSTD::move(__u.__p1_)), - __p2_(_VSTD::move(__u.__p2_)), - __p3_(_VSTD::move(__u.__p3_)) -{ - if (size() > 0) - { - __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = - __p1_.first().__ptr(); - __u.__p1_.first().__next_ = nullptr; - __u.size() = 0; - } + : __bucket_list_(std::move(__u.__bucket_list_)), + __p1_(std::move(__u.__p1_)), + __p2_(std::move(__u.__p2_)), + __p3_(std::move(__u.__p3_)) { + if (size() > 0) { + __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = __p1_.first().__ptr(); + __u.__p1_.first().__next_ = nullptr; + __u.size() = 0; + } } template -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u, - const allocator_type& __a) +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u, const allocator_type& __a) : __bucket_list_(nullptr, __bucket_list_deleter(__pointer_allocator(__a), 0)), __p1_(__default_init_tag(), __node_allocator(__a)), - __p2_(0, _VSTD::move(__u.hash_function())), - __p3_(_VSTD::move(__u.__p3_)) -{ - if (__a == allocator_type(__u.__node_alloc())) - { - __bucket_list_.reset(__u.__bucket_list_.release()); - __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size(); - __u.__bucket_list_.get_deleter().size() = 0; - if (__u.size() > 0) - { - __p1_.first().__next_ = __u.__p1_.first().__next_; - __u.__p1_.first().__next_ = nullptr; - __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = - __p1_.first().__ptr(); - size() = __u.size(); - __u.size() = 0; - } + __p2_(0, std::move(__u.hash_function())), + __p3_(std::move(__u.__p3_)) { + if (__a == allocator_type(__u.__node_alloc())) { + __bucket_list_.reset(__u.__bucket_list_.release()); + __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size(); + __u.__bucket_list_.get_deleter().size() = 0; + if (__u.size() > 0) { + __p1_.first().__next_ = __u.__p1_.first().__next_; + __u.__p1_.first().__next_ = nullptr; + __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = __p1_.first().__ptr(); + size() = __u.size(); + __u.size() = 0; } + } } template -__hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table() -{ +__hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table() { #if defined(_LIBCPP_CXX03_LANG) - static_assert((is_copy_constructible::value), - "Predicate must be copy-constructible."); - static_assert((is_copy_constructible::value), - "Hasher must be copy-constructible."); + static_assert(is_copy_constructible::value, "Predicate must be copy-constructible."); + static_assert(is_copy_constructible::value, "Hasher must be copy-constructible."); #endif - __deallocate_node(__p1_.first().__next_); - std::__debug_db_erase_c(this); + __deallocate_node(__p1_.first().__next_); } template -void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__copy_assign_alloc( - const __hash_table& __u, true_type) -{ - if (__node_alloc() != __u.__node_alloc()) - { - clear(); - __bucket_list_.reset(); - __bucket_list_.get_deleter().size() = 0; - } - __bucket_list_.get_deleter().__alloc() = __u.__bucket_list_.get_deleter().__alloc(); - __node_alloc() = __u.__node_alloc(); +void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__copy_assign_alloc(const __hash_table& __u, true_type) { + if (__node_alloc() != __u.__node_alloc()) { + clear(); + __bucket_list_.reset(); + __bucket_list_.get_deleter().size() = 0; + } + __bucket_list_.get_deleter().__alloc() = __u.__bucket_list_.get_deleter().__alloc(); + __node_alloc() = __u.__node_alloc(); } template -__hash_table<_Tp, _Hash, _Equal, _Alloc>& -__hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(const __hash_table& __u) -{ - if (this != _VSTD::addressof(__u)) - { - __copy_assign_alloc(__u); - hash_function() = __u.hash_function(); - key_eq() = __u.key_eq(); - max_load_factor() = __u.max_load_factor(); - __assign_multi(__u.begin(), __u.end()); - } - return *this; +__hash_table<_Tp, _Hash, _Equal, _Alloc>& __hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(const __hash_table& __u) { + if (this != std::addressof(__u)) { + __copy_assign_alloc(__u); + hash_function() = __u.hash_function(); + key_eq() = __u.key_eq(); + max_load_factor() = __u.max_load_factor(); + __assign_multi(__u.begin(), __u.end()); + } + return *this; } template -void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate_node(__next_pointer __np) - _NOEXCEPT -{ - __node_allocator& __na = __node_alloc(); - while (__np != nullptr) - { - __next_pointer __next = __np->__next_; -#ifdef _LIBCPP_ENABLE_DEBUG_MODE - __c_node* __c = __get_db()->__find_c_and_lock(this); - for (__i_node** __p = __c->end_; __p != __c->beg_; ) - { - --__p; - iterator* __i = static_cast((*__p)->__i_); - if (__i->__node_ == __np) - { - (*__p)->__c_ = nullptr; - if (--__c->end_ != __p) - _VSTD::memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); - } - } - __get_db()->unlock(); -#endif - __node_pointer __real_np = __np->__upcast(); - __node_traits::destroy(__na, _NodeTypes::__get_ptr(__real_np->__value_)); - __node_traits::deallocate(__na, __real_np, 1); - __np = __next; - } +void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate_node(__next_pointer __np) _NOEXCEPT { + __node_allocator& __na = __node_alloc(); + while (__np != nullptr) { + __next_pointer __next = __np->__next_; + __node_pointer __real_np = __np->__upcast(); + __node_traits::destroy(__na, _NodeTypes::__get_ptr(__real_np->__get_value())); + std::__destroy_at(std::addressof(*__real_np)); + __node_traits::deallocate(__na, __real_np, 1); + __np = __next; + } } template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__detach() _NOEXCEPT -{ - size_type __bc = bucket_count(); - for (size_type __i = 0; __i < __bc; ++__i) - __bucket_list_[__i] = nullptr; - size() = 0; - __next_pointer __cache = __p1_.first().__next_; - __p1_.first().__next_ = nullptr; - return __cache; +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__detach() _NOEXCEPT { + size_type __bc = bucket_count(); + for (size_type __i = 0; __i < __bc; ++__i) + __bucket_list_[__i] = nullptr; + size() = 0; + __next_pointer __cache = __p1_.first().__next_; + __p1_.first().__next_ = nullptr; + return __cache; } template -void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( - __hash_table& __u, true_type) - _NOEXCEPT_( - is_nothrow_move_assignable<__node_allocator>::value && - is_nothrow_move_assignable::value && - is_nothrow_move_assignable::value) -{ - clear(); - __bucket_list_.reset(__u.__bucket_list_.release()); - __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size(); - __u.__bucket_list_.get_deleter().size() = 0; - __move_assign_alloc(__u); - size() = __u.size(); - hash_function() = _VSTD::move(__u.hash_function()); +void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(__hash_table& __u, true_type) + _NOEXCEPT_(is_nothrow_move_assignable<__node_allocator>::value&& is_nothrow_move_assignable::value&& + is_nothrow_move_assignable::value) { + clear(); + __bucket_list_.reset(__u.__bucket_list_.release()); + __bucket_list_.get_deleter().size() = __u.__bucket_list_.get_deleter().size(); + __u.__bucket_list_.get_deleter().size() = 0; + __move_assign_alloc(__u); + size() = __u.size(); + hash_function() = std::move(__u.hash_function()); + max_load_factor() = __u.max_load_factor(); + key_eq() = std::move(__u.key_eq()); + __p1_.first().__next_ = __u.__p1_.first().__next_; + if (size() > 0) { + __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = __p1_.first().__ptr(); + __u.__p1_.first().__next_ = nullptr; + __u.size() = 0; + } +} + +template +void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign(__hash_table& __u, false_type) { + if (__node_alloc() == __u.__node_alloc()) + __move_assign(__u, true_type()); + else { + hash_function() = std::move(__u.hash_function()); + key_eq() = std::move(__u.key_eq()); max_load_factor() = __u.max_load_factor(); - key_eq() = _VSTD::move(__u.key_eq()); - __p1_.first().__next_ = __u.__p1_.first().__next_; - if (size() > 0) - { - __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = - __p1_.first().__ptr(); - __u.__p1_.first().__next_ = nullptr; - __u.size() = 0; - } - std::__debug_db_swap(this, std::addressof(__u)); -} - -template -void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( - __hash_table& __u, false_type) -{ - if (__node_alloc() == __u.__node_alloc()) - __move_assign(__u, true_type()); - else - { - hash_function() = _VSTD::move(__u.hash_function()); - key_eq() = _VSTD::move(__u.key_eq()); - max_load_factor() = __u.max_load_factor(); - if (bucket_count() != 0) - { - __next_pointer __cache = __detach(); + if (bucket_count() != 0) { + __next_pointer __cache = __detach(); #ifndef _LIBCPP_HAS_NO_EXCEPTIONS - try - { + try { #endif // _LIBCPP_HAS_NO_EXCEPTIONS - const_iterator __i = __u.begin(); - while (__cache != nullptr && __u.size() != 0) - { - __cache->__upcast()->__value_ = - _VSTD::move(__u.remove(__i++)->__value_); - __next_pointer __next = __cache->__next_; - __node_insert_multi(__cache->__upcast()); - __cache = __next; - } -#ifndef _LIBCPP_HAS_NO_EXCEPTIONS - } - catch (...) - { - __deallocate_node(__cache); - throw; - } -#endif // _LIBCPP_HAS_NO_EXCEPTIONS - __deallocate_node(__cache); - } const_iterator __i = __u.begin(); - while (__u.size() != 0) - { - __node_holder __h = __construct_node(_NodeTypes::__move(__u.remove(__i++)->__value_)); - __node_insert_multi(__h.get()); - __h.release(); + while (__cache != nullptr && __u.size() != 0) { + __cache->__upcast()->__get_value() = std::move(__u.remove(__i++)->__get_value()); + __next_pointer __next = __cache->__next_; + __node_insert_multi(__cache->__upcast()); + __cache = __next; } +#ifndef _LIBCPP_HAS_NO_EXCEPTIONS + } catch (...) { + __deallocate_node(__cache); + throw; + } +#endif // _LIBCPP_HAS_NO_EXCEPTIONS + __deallocate_node(__cache); } + const_iterator __i = __u.begin(); + while (__u.size() != 0) { + __node_holder __h = __construct_node(_NodeTypes::__move(__u.remove(__i++)->__get_value())); + __node_insert_multi(__h.get()); + __h.release(); + } + } } template -inline -__hash_table<_Tp, _Hash, _Equal, _Alloc>& -__hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(__hash_table&& __u) - _NOEXCEPT_( - __node_traits::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable<__node_allocator>::value && - is_nothrow_move_assignable::value && - is_nothrow_move_assignable::value) -{ - __move_assign(__u, integral_constant()); - return *this; +inline __hash_table<_Tp, _Hash, _Equal, _Alloc>& +__hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(__hash_table&& __u) _NOEXCEPT_( + __node_traits::propagate_on_container_move_assignment::value&& is_nothrow_move_assignable<__node_allocator>::value&& + is_nothrow_move_assignable::value&& is_nothrow_move_assignable::value) { + __move_assign(__u, integral_constant()); + return *this; } template template -void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first, - _InputIterator __last) -{ - typedef iterator_traits<_InputIterator> _ITraits; - typedef typename _ITraits::value_type _ItValueType; - static_assert((is_same<_ItValueType, __container_value_type>::value), - "__assign_unique may only be called with the containers value type"); +void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_unique(_InputIterator __first, _InputIterator __last) { + typedef iterator_traits<_InputIterator> _ITraits; + typedef typename _ITraits::value_type _ItValueType; + static_assert(is_same<_ItValueType, __container_value_type>::value, + "__assign_unique may only be called with the containers value type"); - if (bucket_count() != 0) - { - __next_pointer __cache = __detach(); + if (bucket_count() != 0) { + __next_pointer __cache = __detach(); #ifndef _LIBCPP_HAS_NO_EXCEPTIONS - try - { + try { #endif // _LIBCPP_HAS_NO_EXCEPTIONS - for (; __cache != nullptr && __first != __last; ++__first) - { - __cache->__upcast()->__value_ = *__first; - __next_pointer __next = __cache->__next_; - __node_insert_unique(__cache->__upcast()); - __cache = __next; - } + for (; __cache != nullptr && __first != __last; ++__first) { + __cache->__upcast()->__get_value() = *__first; + __next_pointer __next = __cache->__next_; + __node_insert_unique(__cache->__upcast()); + __cache = __next; + } #ifndef _LIBCPP_HAS_NO_EXCEPTIONS - } - catch (...) - { - __deallocate_node(__cache); - throw; - } -#endif // _LIBCPP_HAS_NO_EXCEPTIONS - __deallocate_node(__cache); + } catch (...) { + __deallocate_node(__cache); + throw; } - for (; __first != __last; ++__first) - __insert_unique(*__first); +#endif // _LIBCPP_HAS_NO_EXCEPTIONS + __deallocate_node(__cache); + } + for (; __first != __last; ++__first) + __insert_unique(*__first); } template template -void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first, - _InputIterator __last) -{ - typedef iterator_traits<_InputIterator> _ITraits; - typedef typename _ITraits::value_type _ItValueType; - static_assert((is_same<_ItValueType, __container_value_type>::value || - is_same<_ItValueType, __node_value_type>::value), - "__assign_multi may only be called with the containers value type" - " or the nodes value type"); - if (bucket_count() != 0) - { - __next_pointer __cache = __detach(); +void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first, _InputIterator __last) { + typedef iterator_traits<_InputIterator> _ITraits; + typedef typename _ITraits::value_type _ItValueType; + static_assert( + (is_same<_ItValueType, __container_value_type>::value || is_same<_ItValueType, __node_value_type>::value), + "__assign_multi may only be called with the containers value type" + " or the nodes value type"); + if (bucket_count() != 0) { + __next_pointer __cache = __detach(); #ifndef _LIBCPP_HAS_NO_EXCEPTIONS - try - { + try { #endif // _LIBCPP_HAS_NO_EXCEPTIONS - for (; __cache != nullptr && __first != __last; ++__first) - { - __cache->__upcast()->__value_ = *__first; - __next_pointer __next = __cache->__next_; - __node_insert_multi(__cache->__upcast()); - __cache = __next; - } + for (; __cache != nullptr && __first != __last; ++__first) { + __cache->__upcast()->__get_value() = *__first; + __next_pointer __next = __cache->__next_; + __node_insert_multi(__cache->__upcast()); + __cache = __next; + } #ifndef _LIBCPP_HAS_NO_EXCEPTIONS - } - catch (...) - { - __deallocate_node(__cache); - throw; - } + } catch (...) { + __deallocate_node(__cache); + throw; + } #endif // _LIBCPP_HAS_NO_EXCEPTIONS - __deallocate_node(__cache); - } - for (; __first != __last; ++__first) - __insert_multi(_NodeTypes::__get_value(*__first)); + __deallocate_node(__cache); + } + for (; __first != __last; ++__first) + __insert_multi(_NodeTypes::__get_value(*__first)); } template -inline -typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() _NOEXCEPT -{ - return iterator(__p1_.first().__next_, this); +inline typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() _NOEXCEPT { + return iterator(__p1_.first().__next_); } template -inline -typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() _NOEXCEPT -{ - return iterator(nullptr, this); +inline typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() _NOEXCEPT { + return iterator(nullptr); } template -inline -typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() const _NOEXCEPT -{ - return const_iterator(__p1_.first().__next_, this); +inline typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() const _NOEXCEPT { + return const_iterator(__p1_.first().__next_); } template -inline -typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() const _NOEXCEPT -{ - return const_iterator(nullptr, this); +inline typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() const _NOEXCEPT { + return const_iterator(nullptr); } template -void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::clear() _NOEXCEPT -{ - if (size() > 0) - { - __deallocate_node(__p1_.first().__next_); - __p1_.first().__next_ = nullptr; - size_type __bc = bucket_count(); - for (size_type __i = 0; __i < __bc; ++__i) - __bucket_list_[__i] = nullptr; - size() = 0; - } +void __hash_table<_Tp, _Hash, _Equal, _Alloc>::clear() _NOEXCEPT { + if (size() > 0) { + __deallocate_node(__p1_.first().__next_); + __p1_.first().__next_ = nullptr; + size_type __bc = bucket_count(); + for (size_type __i = 0; __i < __bc; ++__i) + __bucket_list_[__i] = nullptr; + size() = 0; + } } - // Prepare the container for an insertion of the value __value with the hash // __hash. This does a lookup into the container to see if __value is already // present, and performs a rehash if necessary. Returns a pointer to the @@ -1795,34 +1329,28 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::clear() _NOEXCEPT // Note that this function does forward exceptions if key_eq() throws, and never // mutates __value or actually inserts into the map. template -_LIBCPP_INLINE_VISIBILITY -typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_prepare( - size_t __hash, value_type& __value) -{ - size_type __bc = bucket_count(); +_LIBCPP_HIDE_FROM_ABI typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_prepare(size_t __hash, value_type& __value) { + size_type __bc = bucket_count(); - if (__bc != 0) - { - size_t __chash = std::__constrain_hash(__hash, __bc); - __next_pointer __ndptr = __bucket_list_[__chash]; - if (__ndptr != nullptr) - { - for (__ndptr = __ndptr->__next_; __ndptr != nullptr && - std::__constrain_hash(__ndptr->__hash(), __bc) == __chash; - __ndptr = __ndptr->__next_) - { - if (key_eq()(__ndptr->__upcast()->__value_, __value)) - return __ndptr; - } - } + if (__bc != 0) { + size_t __chash = std::__constrain_hash(__hash, __bc); + __next_pointer __ndptr = __bucket_list_[__chash]; + if (__ndptr != nullptr) { + for (__ndptr = __ndptr->__next_; + __ndptr != nullptr && + (__ndptr->__hash() == __hash || std::__constrain_hash(__ndptr->__hash(), __bc) == __chash); + __ndptr = __ndptr->__next_) { + if ((__ndptr->__hash() == __hash) && key_eq()(__ndptr->__upcast()->__get_value(), __value)) + return __ndptr; + } } - if (size()+1 > __bc * max_load_factor() || __bc == 0) - { - __rehash_unique(_VSTD::max(2 * __bc + !std::__is_hash_power2(__bc), - size_type(std::ceil(float(size() + 1) / max_load_factor())))); - } - return nullptr; + } + if (size() + 1 > __bc * max_load_factor() || __bc == 0) { + __rehash_unique(std::max( + 2 * __bc + !std::__is_hash_power2(__bc), size_type(std::ceil(float(size() + 1) / max_load_factor())))); + } + return nullptr; } // Insert the node __nd into the container by pushing it into the right bucket, @@ -1830,50 +1358,41 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_prepare( // rehashing has already occurred and that no element with the same key exists // in the map. template -_LIBCPP_INLINE_VISIBILITY -void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_perform( - __node_pointer __nd) _NOEXCEPT -{ - size_type __bc = bucket_count(); - size_t __chash = std::__constrain_hash(__nd->__hash(), __bc); - // insert_after __bucket_list_[__chash], or __first_node if bucket is null - __next_pointer __pn = __bucket_list_[__chash]; - if (__pn == nullptr) - { - __pn =__p1_.first().__ptr(); - __nd->__next_ = __pn->__next_; - __pn->__next_ = __nd->__ptr(); - // fix up __bucket_list_ - __bucket_list_[__chash] = __pn; - if (__nd->__next_ != nullptr) - __bucket_list_[std::__constrain_hash(__nd->__next_->__hash(), __bc)] = __nd->__ptr(); - } - else - { - __nd->__next_ = __pn->__next_; - __pn->__next_ = __nd->__ptr(); - } - ++size(); +_LIBCPP_HIDE_FROM_ABI void +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique_perform(__node_pointer __nd) _NOEXCEPT { + size_type __bc = bucket_count(); + size_t __chash = std::__constrain_hash(__nd->__hash(), __bc); + // insert_after __bucket_list_[__chash], or __first_node if bucket is null + __next_pointer __pn = __bucket_list_[__chash]; + if (__pn == nullptr) { + __pn = __p1_.first().__ptr(); + __nd->__next_ = __pn->__next_; + __pn->__next_ = __nd->__ptr(); + // fix up __bucket_list_ + __bucket_list_[__chash] = __pn; + if (__nd->__next_ != nullptr) + __bucket_list_[std::__constrain_hash(__nd->__next_->__hash(), __bc)] = __nd->__ptr(); + } else { + __nd->__next_ = __pn->__next_; + __pn->__next_ = __nd->__ptr(); + } + ++size(); } template pair::iterator, bool> -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __nd) -{ - __nd->__hash_ = hash_function()(__nd->__value_); - __next_pointer __existing_node = - __node_insert_unique_prepare(__nd->__hash(), __nd->__value_); +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __nd) { + __nd->__hash_ = hash_function()(__nd->__get_value()); + __next_pointer __existing_node = __node_insert_unique_prepare(__nd->__hash(), __nd->__get_value()); - // Insert the node, unless it already exists in the container. - bool __inserted = false; - if (__existing_node == nullptr) - { - __node_insert_unique_perform(__nd); - __existing_node = __nd->__ptr(); - __inserted = true; - } - return pair(iterator(__existing_node, this), __inserted); + // Insert the node, unless it already exists in the container. + bool __inserted = false; + if (__existing_node == nullptr) { + __node_insert_unique_perform(__nd); + __existing_node = __nd->__ptr(); + __inserted = true; + } + return pair(iterator(__existing_node), __inserted); } // Prepare the container for an insertion of the value __cp_val with the hash @@ -1885,40 +1404,34 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_unique(__node_pointer __ // mutates __value or actually inserts into the map. template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__next_pointer -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_prepare( - size_t __cp_hash, value_type& __cp_val) -{ - size_type __bc = bucket_count(); - if (size()+1 > __bc * max_load_factor() || __bc == 0) - { - __rehash_multi(_VSTD::max(2 * __bc + !std::__is_hash_power2(__bc), - size_type(std::ceil(float(size() + 1) / max_load_factor())))); - __bc = bucket_count(); +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_prepare(size_t __cp_hash, value_type& __cp_val) { + size_type __bc = bucket_count(); + if (size() + 1 > __bc * max_load_factor() || __bc == 0) { + __rehash_multi(std::max( + 2 * __bc + !std::__is_hash_power2(__bc), size_type(std::ceil(float(size() + 1) / max_load_factor())))); + __bc = bucket_count(); + } + size_t __chash = std::__constrain_hash(__cp_hash, __bc); + __next_pointer __pn = __bucket_list_[__chash]; + if (__pn != nullptr) { + for (bool __found = false; + __pn->__next_ != nullptr && std::__constrain_hash(__pn->__next_->__hash(), __bc) == __chash; + __pn = __pn->__next_) { + // __found key_eq() action + // false false loop + // true true loop + // false true set __found to true + // true false break + if (__found != + (__pn->__next_->__hash() == __cp_hash && key_eq()(__pn->__next_->__upcast()->__get_value(), __cp_val))) { + if (!__found) + __found = true; + else + break; + } } - size_t __chash = std::__constrain_hash(__cp_hash, __bc); - __next_pointer __pn = __bucket_list_[__chash]; - if (__pn != nullptr) - { - for (bool __found = false; __pn->__next_ != nullptr && - std::__constrain_hash(__pn->__next_->__hash(), __bc) == __chash; - __pn = __pn->__next_) - { - // __found key_eq() action - // false false loop - // true true loop - // false true set __found to true - // true false break - if (__found != (__pn->__next_->__hash() == __cp_hash && - key_eq()(__pn->__next_->__upcast()->__value_, __cp_val))) - { - if (!__found) - __found = true; - else - break; - } - } - } - return __pn; + } + return __pn; } // Insert the node __cp into the container after __pn (which is the last node in @@ -1927,802 +1440,603 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_prepare( // all we need to do is update the bucket and size(). Assumes that __cp->__hash // is up-to-date. template -void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_perform( - __node_pointer __cp, __next_pointer __pn) _NOEXCEPT -{ - size_type __bc = bucket_count(); - size_t __chash = std::__constrain_hash(__cp->__hash_, __bc); - if (__pn == nullptr) - { - __pn =__p1_.first().__ptr(); - __cp->__next_ = __pn->__next_; - __pn->__next_ = __cp->__ptr(); - // fix up __bucket_list_ - __bucket_list_[__chash] = __pn; - if (__cp->__next_ != nullptr) - __bucket_list_[std::__constrain_hash(__cp->__next_->__hash(), __bc)] - = __cp->__ptr(); +void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi_perform( + __node_pointer __cp, __next_pointer __pn) _NOEXCEPT { + size_type __bc = bucket_count(); + size_t __chash = std::__constrain_hash(__cp->__hash_, __bc); + if (__pn == nullptr) { + __pn = __p1_.first().__ptr(); + __cp->__next_ = __pn->__next_; + __pn->__next_ = __cp->__ptr(); + // fix up __bucket_list_ + __bucket_list_[__chash] = __pn; + if (__cp->__next_ != nullptr) + __bucket_list_[std::__constrain_hash(__cp->__next_->__hash(), __bc)] = __cp->__ptr(); + } else { + __cp->__next_ = __pn->__next_; + __pn->__next_ = __cp->__ptr(); + if (__cp->__next_ != nullptr) { + size_t __nhash = std::__constrain_hash(__cp->__next_->__hash(), __bc); + if (__nhash != __chash) + __bucket_list_[__nhash] = __cp->__ptr(); } - else - { - __cp->__next_ = __pn->__next_; - __pn->__next_ = __cp->__ptr(); - if (__cp->__next_ != nullptr) - { - size_t __nhash = std::__constrain_hash(__cp->__next_->__hash(), __bc); - if (__nhash != __chash) - __bucket_list_[__nhash] = __cp->__ptr(); - } + } + ++size(); +} + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __cp) { + __cp->__hash_ = hash_function()(__cp->__get_value()); + __next_pointer __pn = __node_insert_multi_prepare(__cp->__hash(), __cp->__get_value()); + __node_insert_multi_perform(__cp, __pn); + + return iterator(__cp->__ptr()); +} + +template +typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(const_iterator __p, __node_pointer __cp) { + if (__p != end() && key_eq()(*__p, __cp->__get_value())) { + __next_pointer __np = __p.__node_; + __cp->__hash_ = __np->__hash(); + size_type __bc = bucket_count(); + if (size() + 1 > __bc * max_load_factor() || __bc == 0) { + __rehash_multi(std::max( + 2 * __bc + !std::__is_hash_power2(__bc), size_type(std::ceil(float(size() + 1) / max_load_factor())))); + __bc = bucket_count(); } + size_t __chash = std::__constrain_hash(__cp->__hash_, __bc); + __next_pointer __pp = __bucket_list_[__chash]; + while (__pp->__next_ != __np) + __pp = __pp->__next_; + __cp->__next_ = __np; + __pp->__next_ = static_cast<__next_pointer>(__cp); ++size(); -} - - -template -typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi(__node_pointer __cp) -{ - __cp->__hash_ = hash_function()(__cp->__value_); - __next_pointer __pn = __node_insert_multi_prepare(__cp->__hash(), __cp->__value_); - __node_insert_multi_perform(__cp, __pn); - - return iterator(__cp->__ptr(), this); + return iterator(static_cast<__next_pointer>(__cp)); + } + return __node_insert_multi(__cp); } template -typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_insert_multi( - const_iterator __p, __node_pointer __cp) -{ - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" - " referring to this unordered container"); - if (__p != end() && key_eq()(*__p, __cp->__value_)) - { - __next_pointer __np = __p.__node_; - __cp->__hash_ = __np->__hash(); - size_type __bc = bucket_count(); - if (size()+1 > __bc * max_load_factor() || __bc == 0) - { - __rehash_multi(_VSTD::max(2 * __bc + !std::__is_hash_power2(__bc), - size_type(std::ceil(float(size() + 1) / max_load_factor())))); - __bc = bucket_count(); - } - size_t __chash = std::__constrain_hash(__cp->__hash_, __bc); - __next_pointer __pp = __bucket_list_[__chash]; - while (__pp->__next_ != __np) - __pp = __pp->__next_; - __cp->__next_ = __np; - __pp->__next_ = static_cast<__next_pointer>(__cp); - ++size(); - return iterator(static_cast<__next_pointer>(__cp), this); - } - return __node_insert_multi(__cp); -} - - - -template -template +template pair::iterator, bool> -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args) -{ - - size_t __hash = hash_function()(__k); - size_type __bc = bucket_count(); - bool __inserted = false; - __next_pointer __nd; - size_t __chash; - if (__bc != 0) - { - __chash = std::__constrain_hash(__hash, __bc); - __nd = __bucket_list_[__chash]; - if (__nd != nullptr) - { - for (__nd = __nd->__next_; __nd != nullptr && - (__nd->__hash() == __hash || std::__constrain_hash(__nd->__hash(), __bc) == __chash); - __nd = __nd->__next_) - { - if (key_eq()(__nd->__upcast()->__value_, __k)) - goto __done; - } - } +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_key_args(_Key const& __k, _Args&&... __args) { + size_t __hash = hash_function()(__k); + size_type __bc = bucket_count(); + bool __inserted = false; + __next_pointer __nd; + size_t __chash; + if (__bc != 0) { + __chash = std::__constrain_hash(__hash, __bc); + __nd = __bucket_list_[__chash]; + if (__nd != nullptr) { + for (__nd = __nd->__next_; + __nd != nullptr && (__nd->__hash() == __hash || std::__constrain_hash(__nd->__hash(), __bc) == __chash); + __nd = __nd->__next_) { + if ((__nd->__hash() == __hash) && key_eq()(__nd->__upcast()->__get_value(), __k)) + goto __done; + } } - { - __node_holder __h = __construct_node_hash(__hash, _VSTD::forward<_Args>(__args)...); - if (size()+1 > __bc * max_load_factor() || __bc == 0) - { - __rehash_unique(_VSTD::max(2 * __bc + !std::__is_hash_power2(__bc), - size_type(std::ceil(float(size() + 1) / max_load_factor())))); - __bc = bucket_count(); - __chash = std::__constrain_hash(__hash, __bc); - } - // insert_after __bucket_list_[__chash], or __first_node if bucket is null - __next_pointer __pn = __bucket_list_[__chash]; - if (__pn == nullptr) - { - __pn = __p1_.first().__ptr(); - __h->__next_ = __pn->__next_; - __pn->__next_ = __h.get()->__ptr(); - // fix up __bucket_list_ - __bucket_list_[__chash] = __pn; - if (__h->__next_ != nullptr) - __bucket_list_[std::__constrain_hash(__h->__next_->__hash(), __bc)] - = __h.get()->__ptr(); - } - else - { - __h->__next_ = __pn->__next_; - __pn->__next_ = static_cast<__next_pointer>(__h.get()); - } - __nd = static_cast<__next_pointer>(__h.release()); - // increment size - ++size(); - __inserted = true; + } + { + __node_holder __h = __construct_node_hash(__hash, std::forward<_Args>(__args)...); + if (size() + 1 > __bc * max_load_factor() || __bc == 0) { + __rehash_unique(std::max( + 2 * __bc + !std::__is_hash_power2(__bc), size_type(std::ceil(float(size() + 1) / max_load_factor())))); + __bc = bucket_count(); + __chash = std::__constrain_hash(__hash, __bc); } + // insert_after __bucket_list_[__chash], or __first_node if bucket is null + __next_pointer __pn = __bucket_list_[__chash]; + if (__pn == nullptr) { + __pn = __p1_.first().__ptr(); + __h->__next_ = __pn->__next_; + __pn->__next_ = __h.get()->__ptr(); + // fix up __bucket_list_ + __bucket_list_[__chash] = __pn; + if (__h->__next_ != nullptr) + __bucket_list_[std::__constrain_hash(__h->__next_->__hash(), __bc)] = __h.get()->__ptr(); + } else { + __h->__next_ = __pn->__next_; + __pn->__next_ = static_cast<__next_pointer>(__h.get()); + } + __nd = static_cast<__next_pointer>(__h.release()); + // increment size + ++size(); + __inserted = true; + } __done: - return pair(iterator(__nd, this), __inserted); + return pair(iterator(__nd), __inserted); } template template pair::iterator, bool> -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_impl(_Args&&... __args) -{ - __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); - pair __r = __node_insert_unique(__h.get()); - if (__r.second) - __h.release(); - return __r; +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_unique_impl(_Args&&... __args) { + __node_holder __h = __construct_node(std::forward<_Args>(__args)...); + pair __r = __node_insert_unique(__h.get()); + if (__r.second) + __h.release(); + return __r; } template template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_multi(_Args&&... __args) -{ - __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); - iterator __r = __node_insert_multi(__h.get()); - __h.release(); - return __r; +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_multi(_Args&&... __args) { + __node_holder __h = __construct_node(std::forward<_Args>(__args)...); + iterator __r = __node_insert_multi(__h.get()); + __h.release(); + return __r; } template template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_hint_multi( - const_iterator __p, _Args&&... __args) -{ - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "unordered container::emplace_hint(const_iterator, args...) called with an iterator not" - " referring to this unordered container"); - __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...); - iterator __r = __node_insert_multi(__p, __h.get()); - __h.release(); - return __r; +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__emplace_hint_multi(const_iterator __p, _Args&&... __args) { + __node_holder __h = __construct_node(std::forward<_Args>(__args)...); + iterator __r = __node_insert_multi(__p, __h.get()); + __h.release(); + return __r; } #if _LIBCPP_STD_VER >= 17 template template -_LIBCPP_INLINE_VISIBILITY -_InsertReturnType -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique( - _NodeHandle&& __nh) -{ - if (__nh.empty()) - return _InsertReturnType{end(), false, _NodeHandle()}; - pair __result = __node_insert_unique(__nh.__ptr_); - if (__result.second) - __nh.__release_ptr(); - return _InsertReturnType{__result.first, __result.second, _VSTD::move(__nh)}; +_LIBCPP_HIDE_FROM_ABI _InsertReturnType +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique(_NodeHandle&& __nh) { + if (__nh.empty()) + return _InsertReturnType{end(), false, _NodeHandle()}; + pair __result = __node_insert_unique(__nh.__ptr_); + if (__result.second) + __nh.__release_ptr(); + return _InsertReturnType{__result.first, __result.second, std::move(__nh)}; } template template -_LIBCPP_INLINE_VISIBILITY -typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique( - const_iterator, _NodeHandle&& __nh) -{ - if (__nh.empty()) - return end(); - pair __result = __node_insert_unique(__nh.__ptr_); - if (__result.second) - __nh.__release_ptr(); - return __result.first; +_LIBCPP_HIDE_FROM_ABI typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique(const_iterator, _NodeHandle&& __nh) { + if (__nh.empty()) + return end(); + pair __result = __node_insert_unique(__nh.__ptr_); + if (__result.second) + __nh.__release_ptr(); + return __result.first; } template template -_LIBCPP_INLINE_VISIBILITY -_NodeHandle -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract( - key_type const& __key) -{ - iterator __i = find(__key); - if (__i == end()) - return _NodeHandle(); - return __node_handle_extract<_NodeHandle>(__i); +_LIBCPP_HIDE_FROM_ABI _NodeHandle +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract(key_type const& __key) { + iterator __i = find(__key); + if (__i == end()) + return _NodeHandle(); + return __node_handle_extract<_NodeHandle>(__i); } template template -_LIBCPP_INLINE_VISIBILITY -_NodeHandle -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract( - const_iterator __p) -{ - allocator_type __alloc(__node_alloc()); - return _NodeHandle(remove(__p).release(), __alloc); +_LIBCPP_HIDE_FROM_ABI _NodeHandle __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract(const_iterator __p) { + allocator_type __alloc(__node_alloc()); + return _NodeHandle(remove(__p).release(), __alloc); } template template -_LIBCPP_INLINE_VISIBILITY -void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_unique( - _Table& __source) -{ - static_assert(is_same<__node, typename _Table::__node>::value, ""); +_LIBCPP_HIDE_FROM_ABI void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_unique(_Table& __source) { + static_assert(is_same<__node, typename _Table::__node>::value, ""); - for (typename _Table::iterator __it = __source.begin(); - __it != __source.end();) - { - __node_pointer __src_ptr = __it.__node_->__upcast(); - size_t __hash = hash_function()(__src_ptr->__value_); - __next_pointer __existing_node = - __node_insert_unique_prepare(__hash, __src_ptr->__value_); - auto __prev_iter = __it++; - if (__existing_node == nullptr) - { - (void)__source.remove(__prev_iter).release(); - __src_ptr->__hash_ = __hash; - __node_insert_unique_perform(__src_ptr); - } + for (typename _Table::iterator __it = __source.begin(); __it != __source.end();) { + __node_pointer __src_ptr = __it.__node_->__upcast(); + size_t __hash = hash_function()(__src_ptr->__get_value()); + __next_pointer __existing_node = __node_insert_unique_prepare(__hash, __src_ptr->__get_value()); + auto __prev_iter = __it++; + if (__existing_node == nullptr) { + (void)__source.remove(__prev_iter).release(); + __src_ptr->__hash_ = __hash; + __node_insert_unique_perform(__src_ptr); } + } } template template -_LIBCPP_INLINE_VISIBILITY -typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi( - _NodeHandle&& __nh) -{ - if (__nh.empty()) - return end(); - iterator __result = __node_insert_multi(__nh.__ptr_); - __nh.__release_ptr(); - return __result; +_LIBCPP_HIDE_FROM_ABI typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi(_NodeHandle&& __nh) { + if (__nh.empty()) + return end(); + iterator __result = __node_insert_multi(__nh.__ptr_); + __nh.__release_ptr(); + return __result; } template template -_LIBCPP_INLINE_VISIBILITY -typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi( - const_iterator __hint, _NodeHandle&& __nh) -{ - if (__nh.empty()) - return end(); - iterator __result = __node_insert_multi(__hint, __nh.__ptr_); - __nh.__release_ptr(); - return __result; +_LIBCPP_HIDE_FROM_ABI typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi(const_iterator __hint, _NodeHandle&& __nh) { + if (__nh.empty()) + return end(); + iterator __result = __node_insert_multi(__hint, __nh.__ptr_); + __nh.__release_ptr(); + return __result; } template template -_LIBCPP_INLINE_VISIBILITY -void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_multi( - _Table& __source) -{ - static_assert(is_same::value, ""); +_LIBCPP_HIDE_FROM_ABI void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_merge_multi(_Table& __source) { + static_assert(is_same::value, ""); - for (typename _Table::iterator __it = __source.begin(); - __it != __source.end();) - { - __node_pointer __src_ptr = __it.__node_->__upcast(); - size_t __src_hash = hash_function()(__src_ptr->__value_); - __next_pointer __pn = - __node_insert_multi_prepare(__src_hash, __src_ptr->__value_); - (void)__source.remove(__it++).release(); - __src_ptr->__hash_ = __src_hash; - __node_insert_multi_perform(__src_ptr, __pn); - } + for (typename _Table::iterator __it = __source.begin(); __it != __source.end();) { + __node_pointer __src_ptr = __it.__node_->__upcast(); + size_t __src_hash = hash_function()(__src_ptr->__get_value()); + __next_pointer __pn = __node_insert_multi_prepare(__src_hash, __src_ptr->__get_value()); + (void)__source.remove(__it++).release(); + __src_ptr->__hash_ = __src_hash; + __node_insert_multi_perform(__src_ptr, __pn); + } } #endif // _LIBCPP_STD_VER >= 17 template template -void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __n) -_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK -{ - if (__n == 1) - __n = 2; - else if (__n & (__n - 1)) - __n = std::__next_prime(__n); - size_type __bc = bucket_count(); - if (__n > __bc) - __do_rehash<_UniqueKeys>(__n); - else if (__n < __bc) - { - __n = _VSTD::max - ( - __n, - std::__is_hash_power2(__bc) ? std::__next_hash_pow2(size_t(std::ceil(float(size()) / max_load_factor()))) : - std::__next_prime(size_t(std::ceil(float(size()) / max_load_factor()))) - ); - if (__n < __bc) - __do_rehash<_UniqueKeys>(__n); - } +void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__rehash(size_type __n) _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK { + if (__n == 1) + __n = 2; + else if (__n & (__n - 1)) + __n = std::__next_prime(__n); + size_type __bc = bucket_count(); + if (__n > __bc) + __do_rehash<_UniqueKeys>(__n); + else if (__n < __bc) { + __n = std::max( + __n, + std::__is_hash_power2(__bc) ? std::__next_hash_pow2(size_t(std::ceil(float(size()) / max_load_factor()))) + : std::__next_prime(size_t(std::ceil(float(size()) / max_load_factor())))); + if (__n < __bc) + __do_rehash<_UniqueKeys>(__n); + } } template template -void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__do_rehash(size_type __nbc) -{ - std::__debug_db_invalidate_all(this); - __pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc(); - __bucket_list_.reset(__nbc > 0 ? - __pointer_alloc_traits::allocate(__npa, __nbc) : nullptr); - __bucket_list_.get_deleter().size() = __nbc; - if (__nbc > 0) - { - for (size_type __i = 0; __i < __nbc; ++__i) - __bucket_list_[__i] = nullptr; - __next_pointer __pp = __p1_.first().__ptr(); - __next_pointer __cp = __pp->__next_; - if (__cp != nullptr) - { - size_type __chash = std::__constrain_hash(__cp->__hash(), __nbc); +void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__do_rehash(size_type __nbc) { + __pointer_allocator& __npa = __bucket_list_.get_deleter().__alloc(); + __bucket_list_.reset(__nbc > 0 ? __pointer_alloc_traits::allocate(__npa, __nbc) : nullptr); + __bucket_list_.get_deleter().size() = __nbc; + if (__nbc > 0) { + for (size_type __i = 0; __i < __nbc; ++__i) + __bucket_list_[__i] = nullptr; + __next_pointer __pp = __p1_.first().__ptr(); + __next_pointer __cp = __pp->__next_; + if (__cp != nullptr) { + size_type __chash = std::__constrain_hash(__cp->__hash(), __nbc); + __bucket_list_[__chash] = __pp; + size_type __phash = __chash; + for (__pp = __cp, void(), __cp = __cp->__next_; __cp != nullptr; __cp = __pp->__next_) { + __chash = std::__constrain_hash(__cp->__hash(), __nbc); + if (__chash == __phash) + __pp = __cp; + else { + if (__bucket_list_[__chash] == nullptr) { __bucket_list_[__chash] = __pp; - size_type __phash = __chash; - for (__pp = __cp, void(), __cp = __cp->__next_; __cp != nullptr; - __cp = __pp->__next_) - { - __chash = std::__constrain_hash(__cp->__hash(), __nbc); - if (__chash == __phash) - __pp = __cp; - else - { - if (__bucket_list_[__chash] == nullptr) - { - __bucket_list_[__chash] = __pp; - __pp = __cp; - __phash = __chash; - } - else - { - __next_pointer __np = __cp; - if _LIBCPP_CONSTEXPR_SINCE_CXX17 (!_UniqueKeys) - { - for (; __np->__next_ != nullptr && - key_eq()(__cp->__upcast()->__value_, - __np->__next_->__upcast()->__value_); - __np = __np->__next_) - ; - } - __pp->__next_ = __np->__next_; - __np->__next_ = __bucket_list_[__chash]->__next_; - __bucket_list_[__chash]->__next_ = __cp; - - } - } + __pp = __cp; + __phash = __chash; + } else { + __next_pointer __np = __cp; + if _LIBCPP_CONSTEXPR_SINCE_CXX17 (!_UniqueKeys) { + for (; __np->__next_ != nullptr && + key_eq()(__cp->__upcast()->__get_value(), __np->__next_->__upcast()->__get_value()); + __np = __np->__next_) + ; } + __pp->__next_ = __np->__next_; + __np->__next_ = __bucket_list_[__chash]->__next_; + __bucket_list_[__chash]->__next_ = __cp; + } } + } } + } } template template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) -{ - size_t __hash = hash_function()(__k); - size_type __bc = bucket_count(); - if (__bc != 0) - { - size_t __chash = std::__constrain_hash(__hash, __bc); - __next_pointer __nd = __bucket_list_[__chash]; - if (__nd != nullptr) - { - for (__nd = __nd->__next_; __nd != nullptr && - (__nd->__hash() == __hash - || std::__constrain_hash(__nd->__hash(), __bc) == __chash); - __nd = __nd->__next_) - { - if ((__nd->__hash() == __hash) - && key_eq()(__nd->__upcast()->__value_, __k)) - return iterator(__nd, this); - } - } +__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) { + size_t __hash = hash_function()(__k); + size_type __bc = bucket_count(); + if (__bc != 0) { + size_t __chash = std::__constrain_hash(__hash, __bc); + __next_pointer __nd = __bucket_list_[__chash]; + if (__nd != nullptr) { + for (__nd = __nd->__next_; + __nd != nullptr && (__nd->__hash() == __hash || std::__constrain_hash(__nd->__hash(), __bc) == __chash); + __nd = __nd->__next_) { + if ((__nd->__hash() == __hash) && key_eq()(__nd->__upcast()->__get_value(), __k)) + return iterator(__nd); + } } - return end(); + } + return end(); } template template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const -{ - size_t __hash = hash_function()(__k); - size_type __bc = bucket_count(); - if (__bc != 0) - { - size_t __chash = std::__constrain_hash(__hash, __bc); - __next_pointer __nd = __bucket_list_[__chash]; - if (__nd != nullptr) - { - for (__nd = __nd->__next_; __nd != nullptr && - (__hash == __nd->__hash() - || std::__constrain_hash(__nd->__hash(), __bc) == __chash); - __nd = __nd->__next_) - { - if ((__nd->__hash() == __hash) - && key_eq()(__nd->__upcast()->__value_, __k)) - return const_iterator(__nd, this); - } - } - +__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const { + size_t __hash = hash_function()(__k); + size_type __bc = bucket_count(); + if (__bc != 0) { + size_t __chash = std::__constrain_hash(__hash, __bc); + __next_pointer __nd = __bucket_list_[__chash]; + if (__nd != nullptr) { + for (__nd = __nd->__next_; + __nd != nullptr && (__hash == __nd->__hash() || std::__constrain_hash(__nd->__hash(), __bc) == __chash); + __nd = __nd->__next_) { + if ((__nd->__hash() == __hash) && key_eq()(__nd->__upcast()->__get_value(), __k)) + return const_iterator(__nd); + } } - return end(); + } + return end(); } template -template +template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(_Args&& ...__args) -{ - static_assert(!__is_hash_value_type<_Args...>::value, - "Construct cannot be called with a hash value type"); - __node_allocator& __na = __node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), _VSTD::forward<_Args>(__args)...); - __h.get_deleter().__value_constructed = true; - __h->__hash_ = hash_function()(__h->__value_); - __h->__next_ = nullptr; - return __h; +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node(_Args&&... __args) { + static_assert(!__is_hash_value_type<_Args...>::value, "Construct cannot be called with a hash value type"); + __node_allocator& __na = __node_alloc(); + __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); + + // Begin the lifetime of the node itself. Note that this doesn't begin the lifetime of the value + // held inside the node, since we need to use the allocator's construct() method for that. + // + // We don't use the allocator's construct() method to construct the node itself since the + // Cpp17FooInsertable named requirements don't require the allocator's construct() method + // to work on anything other than the value_type. + std::__construct_at(std::addressof(*__h), /* next = */ nullptr, /* hash = */ 0); + + // Now construct the value_type using the allocator's construct() method. + __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__get_value()), std::forward<_Args>(__args)...); + __h.get_deleter().__value_constructed = true; + + __h->__hash_ = hash_function()(__h->__get_value()); + return __h; } template -template +template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node_hash( - size_t __hash, _First&& __f, _Rest&& ...__rest) -{ - static_assert(!__is_hash_value_type<_First, _Rest...>::value, - "Construct cannot be called with a hash value type"); - __node_allocator& __na = __node_alloc(); - __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); - __node_traits::construct(__na, _NodeTypes::__get_ptr(__h->__value_), - _VSTD::forward<_First>(__f), - _VSTD::forward<_Rest>(__rest)...); - __h.get_deleter().__value_constructed = true; - __h->__hash_ = __hash; - __h->__next_ = nullptr; - return __h; +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__construct_node_hash(size_t __hash, _First&& __f, _Rest&&... __rest) { + static_assert(!__is_hash_value_type<_First, _Rest...>::value, "Construct cannot be called with a hash value type"); + __node_allocator& __na = __node_alloc(); + __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); + std::__construct_at(std::addressof(*__h), /* next = */ nullptr, /* hash = */ __hash); + __node_traits::construct( + __na, _NodeTypes::__get_ptr(__h->__get_value()), std::forward<_First>(__f), std::forward<_Rest>(__rest)...); + __h.get_deleter().__value_constructed = true; + return __h; } template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p) -{ - __next_pointer __np = __p.__node_; - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this, - "unordered container erase(iterator) called with an iterator not" - " referring to this container"); - _LIBCPP_ASSERT(__p != end(), - "unordered container erase(iterator) called with a non-dereferenceable iterator"); - iterator __r(__np, this); - ++__r; - remove(__p); - return __r; +__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p) { + __next_pointer __np = __p.__node_; + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __p != end(), "unordered container::erase(iterator) called with a non-dereferenceable iterator"); + iterator __r(__np); + ++__r; + remove(__p); + return __r; } template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first, - const_iterator __last) -{ - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__first)) == this, - "unordered container::erase(iterator, iterator) called with an iterator not" - " referring to this container"); - _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__last)) == this, - "unordered container::erase(iterator, iterator) called with an iterator not" - " referring to this container"); - for (const_iterator __p = __first; __first != __last; __p = __first) - { - ++__first; - erase(__p); - } - __next_pointer __np = __last.__node_; - return iterator (__np, this); +__hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __first, const_iterator __last) { + for (const_iterator __p = __first; __first != __last; __p = __first) { + ++__first; + erase(__p); + } + __next_pointer __np = __last.__node_; + return iterator(__np); } template template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_unique(const _Key& __k) -{ - iterator __i = find(__k); - if (__i == end()) - return 0; - erase(__i); - return 1; +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_unique(const _Key& __k) { + iterator __i = find(__k); + if (__i == end()) + return 0; + erase(__i); + return 1; } template template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_multi(const _Key& __k) -{ - size_type __r = 0; - iterator __i = find(__k); - if (__i != end()) - { - iterator __e = end(); - do - { - erase(__i++); - ++__r; - } while (__i != __e && key_eq()(*__i, __k)); - } - return __r; +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_multi(const _Key& __k) { + size_type __r = 0; + iterator __i = find(__k); + if (__i != end()) { + iterator __e = end(); + do { + erase(__i++); + ++__r; + } while (__i != __e && key_eq()(*__i, __k)); + } + return __r; } template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder -__hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT -{ - // current node - __next_pointer __cn = __p.__node_; - size_type __bc = bucket_count(); - size_t __chash = std::__constrain_hash(__cn->__hash(), __bc); - // find previous node - __next_pointer __pn = __bucket_list_[__chash]; - for (; __pn->__next_ != __cn; __pn = __pn->__next_) - ; - // Fix up __bucket_list_ - // if __pn is not in same bucket (before begin is not in same bucket) && - // if __cn->__next_ is not in same bucket (nullptr is not in same bucket) - if (__pn == __p1_.first().__ptr() - || std::__constrain_hash(__pn->__hash(), __bc) != __chash) - { - if (__cn->__next_ == nullptr - || std::__constrain_hash(__cn->__next_->__hash(), __bc) != __chash) - __bucket_list_[__chash] = nullptr; - } - // if __cn->__next_ is not in same bucket (nullptr is in same bucket) - if (__cn->__next_ != nullptr) - { - size_t __nhash = std::__constrain_hash(__cn->__next_->__hash(), __bc); - if (__nhash != __chash) - __bucket_list_[__nhash] = __pn; - } - // remove __cn - __pn->__next_ = __cn->__next_; - __cn->__next_ = nullptr; - --size(); -#ifdef _LIBCPP_ENABLE_DEBUG_MODE - __c_node* __c = __get_db()->__find_c_and_lock(this); - for (__i_node** __dp = __c->end_; __dp != __c->beg_; ) - { - --__dp; - iterator* __i = static_cast((*__dp)->__i_); - if (__i->__node_ == __cn) - { - (*__dp)->__c_ = nullptr; - if (--__c->end_ != __dp) - _VSTD::memmove(__dp, __dp+1, (__c->end_ - __dp)*sizeof(__i_node*)); - } - } - __get_db()->unlock(); -#endif - return __node_holder(__cn->__upcast(), _Dp(__node_alloc(), true)); +__hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT { + // current node + __next_pointer __cn = __p.__node_; + size_type __bc = bucket_count(); + size_t __chash = std::__constrain_hash(__cn->__hash(), __bc); + // find previous node + __next_pointer __pn = __bucket_list_[__chash]; + for (; __pn->__next_ != __cn; __pn = __pn->__next_) + ; + // Fix up __bucket_list_ + // if __pn is not in same bucket (before begin is not in same bucket) && + // if __cn->__next_ is not in same bucket (nullptr is not in same bucket) + if (__pn == __p1_.first().__ptr() || std::__constrain_hash(__pn->__hash(), __bc) != __chash) { + if (__cn->__next_ == nullptr || std::__constrain_hash(__cn->__next_->__hash(), __bc) != __chash) + __bucket_list_[__chash] = nullptr; + } + // if __cn->__next_ is not in same bucket (nullptr is in same bucket) + if (__cn->__next_ != nullptr) { + size_t __nhash = std::__constrain_hash(__cn->__next_->__hash(), __bc); + if (__nhash != __chash) + __bucket_list_[__nhash] = __pn; + } + // remove __cn + __pn->__next_ = __cn->__next_; + __cn->__next_ = nullptr; + --size(); + return __node_holder(__cn->__upcast(), _Dp(__node_alloc(), true)); } template template -inline -typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_unique(const _Key& __k) const -{ - return static_cast(find(__k) != end()); +inline typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_unique(const _Key& __k) const { + return static_cast(find(__k) != end()); } template template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_multi(const _Key& __k) const -{ - size_type __r = 0; - const_iterator __i = find(__k); - if (__i != end()) - { - const_iterator __e = end(); - do - { - ++__i; - ++__r; - } while (__i != __e && key_eq()(*__i, __k)); - } - return __r; +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__count_multi(const _Key& __k) const { + size_type __r = 0; + const_iterator __i = find(__k); + if (__i != end()) { + const_iterator __e = end(); + do { + ++__i; + ++__r; + } while (__i != __e && key_eq()(*__i, __k)); + } + return __r; } template template pair::iterator, typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator> -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique( - const _Key& __k) -{ - iterator __i = find(__k); - iterator __j = __i; - if (__i != end()) - ++__j; - return pair(__i, __j); +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique(const _Key& __k) { + iterator __i = find(__k); + iterator __j = __i; + if (__i != end()) + ++__j; + return pair(__i, __j); } template template pair::const_iterator, typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator> -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique( - const _Key& __k) const -{ - const_iterator __i = find(__k); - const_iterator __j = __i; - if (__i != end()) - ++__j; - return pair(__i, __j); +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_unique(const _Key& __k) const { + const_iterator __i = find(__k); + const_iterator __j = __i; + if (__i != end()) + ++__j; + return pair(__i, __j); } template template pair::iterator, typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator> -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi( - const _Key& __k) -{ - iterator __i = find(__k); - iterator __j = __i; - if (__i != end()) - { - iterator __e = end(); - do - { - ++__j; - } while (__j != __e && key_eq()(*__j, __k)); - } - return pair(__i, __j); +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi(const _Key& __k) { + iterator __i = find(__k); + iterator __j = __i; + if (__i != end()) { + iterator __e = end(); + do { + ++__j; + } while (__j != __e && key_eq()(*__j, __k)); + } + return pair(__i, __j); } template template pair::const_iterator, typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator> -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi( - const _Key& __k) const -{ - const_iterator __i = find(__k); - const_iterator __j = __i; - if (__i != end()) - { - const_iterator __e = end(); - do - { - ++__j; - } while (__j != __e && key_eq()(*__j, __k)); - } - return pair(__i, __j); +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi(const _Key& __k) const { + const_iterator __i = find(__k); + const_iterator __j = __i; + if (__i != end()) { + const_iterator __e = end(); + do { + ++__j; + } while (__j != __e && key_eq()(*__j, __k)); + } + return pair(__i, __j); } template -void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u) +void __hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u) #if _LIBCPP_STD_VER <= 11 - _NOEXCEPT_( - __is_nothrow_swappable::value && __is_nothrow_swappable::value - && (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value - || __is_nothrow_swappable<__pointer_allocator>::value) - && (!__node_traits::propagate_on_container_swap::value - || __is_nothrow_swappable<__node_allocator>::value) - ) + _NOEXCEPT_(__is_nothrow_swappable_v&& __is_nothrow_swappable_v && + (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value || + __is_nothrow_swappable_v<__pointer_allocator>) && + (!__node_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__node_allocator>)) #else - _NOEXCEPT_(__is_nothrow_swappable::value && __is_nothrow_swappable::value) + _NOEXCEPT_(__is_nothrow_swappable_v&& __is_nothrow_swappable_v) #endif { - _LIBCPP_ASSERT(__node_traits::propagate_on_container_swap::value || - this->__node_alloc() == __u.__node_alloc(), - "list::swap: Either propagate_on_container_swap must be true" - " or the allocators must compare equal"); - { + _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR( + __node_traits::propagate_on_container_swap::value || this->__node_alloc() == __u.__node_alloc(), + "unordered container::swap: Either propagate_on_container_swap " + "must be true or the allocators must compare equal"); + { __node_pointer_pointer __npp = __bucket_list_.release(); __bucket_list_.reset(__u.__bucket_list_.release()); __u.__bucket_list_.reset(__npp); - } - _VSTD::swap(__bucket_list_.get_deleter().size(), __u.__bucket_list_.get_deleter().size()); - _VSTD::__swap_allocator(__bucket_list_.get_deleter().__alloc(), - __u.__bucket_list_.get_deleter().__alloc()); - _VSTD::__swap_allocator(__node_alloc(), __u.__node_alloc()); - _VSTD::swap(__p1_.first().__next_, __u.__p1_.first().__next_); - __p2_.swap(__u.__p2_); - __p3_.swap(__u.__p3_); - if (size() > 0) - __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = - __p1_.first().__ptr(); - if (__u.size() > 0) - __u.__bucket_list_[std::__constrain_hash(__u.__p1_.first().__next_->__hash(), __u.bucket_count())] = - __u.__p1_.first().__ptr(); - std::__debug_db_swap(this, std::addressof(__u)); + } + std::swap(__bucket_list_.get_deleter().size(), __u.__bucket_list_.get_deleter().size()); + std::__swap_allocator(__bucket_list_.get_deleter().__alloc(), __u.__bucket_list_.get_deleter().__alloc()); + std::__swap_allocator(__node_alloc(), __u.__node_alloc()); + std::swap(__p1_.first().__next_, __u.__p1_.first().__next_); + __p2_.swap(__u.__p2_); + __p3_.swap(__u.__p3_); + if (size() > 0) + __bucket_list_[std::__constrain_hash(__p1_.first().__next_->__hash(), bucket_count())] = __p1_.first().__ptr(); + if (__u.size() > 0) + __u.__bucket_list_[std::__constrain_hash(__u.__p1_.first().__next_->__hash(), __u.bucket_count())] = + __u.__p1_.first().__ptr(); } template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::size_type -__hash_table<_Tp, _Hash, _Equal, _Alloc>::bucket_size(size_type __n) const -{ - _LIBCPP_ASSERT(__n < bucket_count(), - "unordered container::bucket_size(n) called with n >= bucket_count()"); - __next_pointer __np = __bucket_list_[__n]; - size_type __bc = bucket_count(); - size_type __r = 0; - if (__np != nullptr) - { - for (__np = __np->__next_; __np != nullptr && - std::__constrain_hash(__np->__hash(), __bc) == __n; - __np = __np->__next_, (void) ++__r) - ; - } - return __r; +__hash_table<_Tp, _Hash, _Equal, _Alloc>::bucket_size(size_type __n) const { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __n < bucket_count(), "unordered container::bucket_size(n) called with n >= bucket_count()"); + __next_pointer __np = __bucket_list_[__n]; + size_type __bc = bucket_count(); + size_type __r = 0; + if (__np != nullptr) { + for (__np = __np->__next_; __np != nullptr && std::__constrain_hash(__np->__hash(), __bc) == __n; + __np = __np->__next_, (void)++__r) + ; + } + return __r; } template -inline _LIBCPP_INLINE_VISIBILITY -void -swap(__hash_table<_Tp, _Hash, _Equal, _Alloc>& __x, - __hash_table<_Tp, _Hash, _Equal, _Alloc>& __y) - _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) -{ - __x.swap(__y); +inline _LIBCPP_HIDE_FROM_ABI void +swap(__hash_table<_Tp, _Hash, _Equal, _Alloc>& __x, __hash_table<_Tp, _Hash, _Equal, _Alloc>& __y) + _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) { + __x.swap(__y); } -#ifdef _LIBCPP_ENABLE_DEBUG_MODE - -template -bool -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__dereferenceable(const const_iterator* __i) const -{ - return __i->__node_ != nullptr; -} - -template -bool -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__decrementable(const const_iterator*) const -{ - return false; -} - -template -bool -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__addable(const const_iterator*, ptrdiff_t) const -{ - return false; -} - -template -bool -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__subscriptable(const const_iterator*, ptrdiff_t) const -{ - return false; -} - -#endif // _LIBCPP_ENABLE_DEBUG_MODE - _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS diff --git a/third_party/libcxx/__ios/fpos.h b/third_party/libcxx/__ios/fpos.h index 87f0135fc..1af1e23ee 100644 --- a/third_party/libcxx/__ios/fpos.h +++ b/third_party/libcxx/__ios/fpos.h @@ -11,7 +11,7 @@ #define _LIBCPP___IOS_FPOS_H #include <__config> -#include +#include <__fwd/ios.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -57,20 +57,17 @@ public: }; template -inline _LIBCPP_HIDE_FROM_ABI -streamoff operator-(const fpos<_StateT>& __x, const fpos<_StateT>& __y) { +inline _LIBCPP_HIDE_FROM_ABI streamoff operator-(const fpos<_StateT>& __x, const fpos<_StateT>& __y) { return streamoff(__x) - streamoff(__y); } template -inline _LIBCPP_HIDE_FROM_ABI -bool operator==(const fpos<_StateT>& __x, const fpos<_StateT>& __y) { +inline _LIBCPP_HIDE_FROM_ABI bool operator==(const fpos<_StateT>& __x, const fpos<_StateT>& __y) { return streamoff(__x) == streamoff(__y); } template -inline _LIBCPP_HIDE_FROM_ABI -bool operator!=(const fpos<_StateT>& __x, const fpos<_StateT>& __y) { +inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const fpos<_StateT>& __x, const fpos<_StateT>& __y) { return streamoff(__x) != streamoff(__y); } diff --git a/third_party/libcxx/__iterator/access.h b/third_party/libcxx/__iterator/access.h index d7bcb3378..acc4f60bf 100644 --- a/third_party/libcxx/__iterator/access.h +++ b/third_party/libcxx/__iterator/access.h @@ -20,106 +20,72 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -_Tp* -begin(_Tp (&__array)[_Np]) -{ - return __array; +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp* begin(_Tp (&__array)[_Np]) _NOEXCEPT { + return __array; } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -_Tp* -end(_Tp (&__array)[_Np]) -{ - return __array + _Np; +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp* end(_Tp (&__array)[_Np]) _NOEXCEPT { + return __array + _Np; } #if !defined(_LIBCPP_CXX03_LANG) template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 -auto -begin(_Cp& __c) -> decltype(__c.begin()) -{ - return __c.begin(); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto begin(_Cp& __c) -> decltype(__c.begin()) { + return __c.begin(); } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 -auto -begin(const _Cp& __c) -> decltype(__c.begin()) -{ - return __c.begin(); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto begin(const _Cp& __c) -> decltype(__c.begin()) { + return __c.begin(); } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 -auto -end(_Cp& __c) -> decltype(__c.end()) -{ - return __c.end(); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto end(_Cp& __c) -> decltype(__c.end()) { + return __c.end(); } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 -auto -end(const _Cp& __c) -> decltype(__c.end()) -{ - return __c.end(); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto end(const _Cp& __c) -> decltype(__c.end()) { + return __c.end(); } -#if _LIBCPP_STD_VER >= 14 +# if _LIBCPP_STD_VER >= 14 template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -auto cbegin(const _Cp& __c) -> decltype(_VSTD::begin(__c)) -{ - return _VSTD::begin(__c); +_LIBCPP_HIDE_FROM_ABI constexpr auto +cbegin(const _Cp& __c) noexcept(noexcept(std::begin(__c))) -> decltype(std::begin(__c)) { + return std::begin(__c); } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 -auto cend(const _Cp& __c) -> decltype(_VSTD::end(__c)) -{ - return _VSTD::end(__c); +_LIBCPP_HIDE_FROM_ABI constexpr auto cend(const _Cp& __c) noexcept(noexcept(std::end(__c))) -> decltype(std::end(__c)) { + return std::end(__c); } -#endif +# endif - -#else // defined(_LIBCPP_CXX03_LANG) +#else // defined(_LIBCPP_CXX03_LANG) template -_LIBCPP_INLINE_VISIBILITY -typename _Cp::iterator -begin(_Cp& __c) -{ - return __c.begin(); +_LIBCPP_HIDE_FROM_ABI typename _Cp::iterator begin(_Cp& __c) { + return __c.begin(); } template -_LIBCPP_INLINE_VISIBILITY -typename _Cp::const_iterator -begin(const _Cp& __c) -{ - return __c.begin(); +_LIBCPP_HIDE_FROM_ABI typename _Cp::const_iterator begin(const _Cp& __c) { + return __c.begin(); } template -_LIBCPP_INLINE_VISIBILITY -typename _Cp::iterator -end(_Cp& __c) -{ - return __c.end(); +_LIBCPP_HIDE_FROM_ABI typename _Cp::iterator end(_Cp& __c) { + return __c.end(); } template -_LIBCPP_INLINE_VISIBILITY -typename _Cp::const_iterator -end(const _Cp& __c) -{ - return __c.end(); +_LIBCPP_HIDE_FROM_ABI typename _Cp::const_iterator end(const _Cp& __c) { + return __c.end(); } #endif // !defined(_LIBCPP_CXX03_LANG) diff --git a/third_party/libcxx/__iterator/advance.h b/third_party/libcxx/__iterator/advance.h index c5f3c500d..296db1aaa 100644 --- a/third_party/libcxx/__iterator/advance.h +++ b/third_party/libcxx/__iterator/advance.h @@ -29,18 +29,21 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -void __advance(_InputIter& __i, typename iterator_traits<_InputIter>::difference_type __n, input_iterator_tag) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 void +__advance(_InputIter& __i, typename iterator_traits<_InputIter>::difference_type __n, input_iterator_tag) { for (; __n > 0; --__n) ++__i; } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -void __advance(_BiDirIter& __i, typename iterator_traits<_BiDirIter>::difference_type __n, bidirectional_iterator_tag) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 void +__advance(_BiDirIter& __i, typename iterator_traits<_BiDirIter>::difference_type __n, bidirectional_iterator_tag) { if (__n >= 0) for (; __n > 0; --__n) ++__i; @@ -50,22 +53,22 @@ void __advance(_BiDirIter& __i, typename iterator_traits<_BiDirIter>::difference } template -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -void __advance(_RandIter& __i, typename iterator_traits<_RandIter>::difference_type __n, random_access_iterator_tag) { +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 void +__advance(_RandIter& __i, typename iterator_traits<_RandIter>::difference_type __n, random_access_iterator_tag) { __i += __n; } -template < - class _InputIter, class _Distance, - class _IntegralDistance = decltype(_VSTD::__convert_to_integral(std::declval<_Distance>())), - class = __enable_if_t::value> > -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -void advance(_InputIter& __i, _Distance __orig_n) { +template < class _InputIter, + class _Distance, + class _IntegralDistance = decltype(std::__convert_to_integral(std::declval<_Distance>())), + __enable_if_t::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 void advance(_InputIter& __i, _Distance __orig_n) { typedef typename iterator_traits<_InputIter>::difference_type _Difference; - _Difference __n = static_cast<_Difference>(_VSTD::__convert_to_integral(__orig_n)); - _LIBCPP_ASSERT(__n >= 0 || __has_bidirectional_iterator_category<_InputIter>::value, - "Attempt to advance(it, n) with negative n on a non-bidirectional iterator"); - _VSTD::__advance(__i, __n, typename iterator_traits<_InputIter>::iterator_category()); + _Difference __n = static_cast<_Difference>(std::__convert_to_integral(__orig_n)); + // Calling `advance` with a negative value on a non-bidirectional iterator is a no-op in the current implementation. + _LIBCPP_ASSERT_PEDANTIC(__n >= 0 || __has_bidirectional_iterator_category<_InputIter>::value, + "Attempt to advance(it, n) with negative n on a non-bidirectional iterator"); + std::__advance(__i, __n, typename iterator_traits<_InputIter>::iterator_category()); } #if _LIBCPP_STD_VER >= 20 @@ -78,8 +81,7 @@ namespace __advance { struct __fn { private: template - _LIBCPP_HIDE_FROM_ABI - static constexpr void __advance_forward(_Ip& __i, iter_difference_t<_Ip> __n) { + _LIBCPP_HIDE_FROM_ABI static constexpr void __advance_forward(_Ip& __i, iter_difference_t<_Ip> __n) { while (__n > 0) { --__n; ++__i; @@ -87,8 +89,7 @@ private: } template - _LIBCPP_HIDE_FROM_ABI - static constexpr void __advance_backward(_Ip& __i, iter_difference_t<_Ip> __n) { + _LIBCPP_HIDE_FROM_ABI static constexpr void __advance_backward(_Ip& __i, iter_difference_t<_Ip> __n) { while (__n < 0) { ++__n; --__i; @@ -98,10 +99,10 @@ private: public: // Preconditions: If `I` does not model `bidirectional_iterator`, `n` is not negative. template - _LIBCPP_HIDE_FROM_ABI - constexpr void operator()(_Ip& __i, iter_difference_t<_Ip> __n) const { - _LIBCPP_ASSERT(__n >= 0 || bidirectional_iterator<_Ip>, - "If `n < 0`, then `bidirectional_iterator` must be true."); + _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_Ip& __i, iter_difference_t<_Ip> __n) const { + // Calling `advance` with a negative value on a non-bidirectional iterator is a no-op in the current implementation. + _LIBCPP_ASSERT_PEDANTIC( + __n >= 0 || bidirectional_iterator<_Ip>, "If `n < 0`, then `bidirectional_iterator` must be true."); // If `I` models `random_access_iterator`, equivalent to `i += n`. if constexpr (random_access_iterator<_Ip>) { @@ -120,14 +121,16 @@ public: } } - // Preconditions: Either `assignable_from || sized_sentinel_for` is modeled, or [i, bound_sentinel) denotes a range. + // Preconditions: Either `assignable_from || sized_sentinel_for` is modeled, or [i, bound_sentinel) + // denotes a range. template _Sp> _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_Ip& __i, _Sp __bound_sentinel) const { // If `I` and `S` model `assignable_from`, equivalent to `i = std::move(bound_sentinel)`. if constexpr (assignable_from<_Ip&, _Sp>) { - __i = _VSTD::move(__bound_sentinel); + __i = std::move(__bound_sentinel); } - // Otherwise, if `S` and `I` model `sized_sentinel_for`, equivalent to `ranges::advance(i, bound_sentinel - i)`. + // Otherwise, if `S` and `I` model `sized_sentinel_for`, equivalent to `ranges::advance(i, bound_sentinel - + // i)`. else if constexpr (sized_sentinel_for<_Sp, _Ip>) { (*this)(__i, __bound_sentinel - __i); } @@ -142,22 +145,20 @@ public: // Preconditions: // * If `n > 0`, [i, bound_sentinel) denotes a range. // * If `n == 0`, [i, bound_sentinel) or [bound_sentinel, i) denotes a range. - // * If `n < 0`, [bound_sentinel, i) denotes a range, `I` models `bidirectional_iterator`, and `I` and `S` model `same_as`. + // * If `n < 0`, [bound_sentinel, i) denotes a range, `I` models `bidirectional_iterator`, and `I` and `S` model + // `same_as`. // Returns: `n - M`, where `M` is the difference between the ending and starting position. template _Sp> - _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Ip> operator()(_Ip& __i, iter_difference_t<_Ip> __n, - _Sp __bound_sentinel) const { - _LIBCPP_ASSERT((__n >= 0) || (bidirectional_iterator<_Ip> && same_as<_Ip, _Sp>), - "If `n < 0`, then `bidirectional_iterator && same_as` must be true."); + _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Ip> + operator()(_Ip& __i, iter_difference_t<_Ip> __n, _Sp __bound_sentinel) const { + // Calling `advance` with a negative value on a non-bidirectional iterator is a no-op in the current implementation. + _LIBCPP_ASSERT_PEDANTIC((__n >= 0) || (bidirectional_iterator<_Ip> && same_as<_Ip, _Sp>), + "If `n < 0`, then `bidirectional_iterator && same_as` must be true."); // If `S` and `I` model `sized_sentinel_for`: if constexpr (sized_sentinel_for<_Sp, _Ip>) { // If |n| >= |bound_sentinel - i|, equivalent to `ranges::advance(i, bound_sentinel)`. // __magnitude_geq(a, b) returns |a| >= |b|, assuming they have the same sign. - auto __magnitude_geq = [](auto __a, auto __b) { - return __a == 0 ? __b == 0 : - __a > 0 ? __a >= __b : - __a <= __b; - }; + auto __magnitude_geq = [](auto __a, auto __b) { return __a == 0 ? __b == 0 : __a > 0 ? __a >= __b : __a <= __b; }; if (const auto __m = __bound_sentinel - __i; __magnitude_geq(__n, __m)) { (*this)(__i, __bound_sentinel); return __n - __m; @@ -169,14 +170,14 @@ public: } else { // Otherwise, if `n` is non-negative, while `bool(i != bound_sentinel)` is true, increments `i` but at // most `n` times. - while (__i != __bound_sentinel && __n > 0) { + while (__n > 0 && __i != __bound_sentinel) { ++__i; --__n; } // Otherwise, while `bool(i != bound_sentinel)` is true, decrements `i` but at most `-n` times. if constexpr (bidirectional_iterator<_Ip> && same_as<_Ip, _Sp>) { - while (__i != __bound_sentinel && __n < 0) { + while (__n < 0 && __i != __bound_sentinel) { --__i; ++__n; } @@ -191,7 +192,7 @@ public: } // namespace __advance inline namespace __cpo { - inline constexpr auto advance = __advance::__fn{}; +inline constexpr auto advance = __advance::__fn{}; } // namespace __cpo } // namespace ranges @@ -199,4 +200,6 @@ inline namespace __cpo { _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ITERATOR_ADVANCE_H diff --git a/third_party/libcxx/__iterator/aliasing_iterator.h b/third_party/libcxx/__iterator/aliasing_iterator.h new file mode 100644 index 000000000..94ba57707 --- /dev/null +++ b/third_party/libcxx/__iterator/aliasing_iterator.h @@ -0,0 +1,127 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ITERATOR_ALIASING_ITERATOR_H +#define _LIBCPP___ITERATOR_ALIASING_ITERATOR_H + +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__memory/pointer_traits.h> +#include <__type_traits/is_trivial.h> +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +// This iterator wrapper is used to type-pun an iterator to return a different type. This is done without UB by not +// actually punning the type, but instead inspecting the object representation of the base type and copying that into +// an instance of the alias type. For that reason the alias type has to be trivial. The alias is returned as a prvalue +// when derferencing the iterator, since it is temporary storage. This wrapper is used to vectorize some algorithms. + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct __aliasing_iterator_wrapper { + class __iterator { + _BaseIter __base_ = nullptr; + + using __iter_traits = iterator_traits<_BaseIter>; + using __base_value_type = typename __iter_traits::value_type; + + static_assert(__has_random_access_iterator_category<_BaseIter>::value, + "The base iterator has to be a random access iterator!"); + + public: + using iterator_category = random_access_iterator_tag; + using value_type = _Alias; + using difference_type = ptrdiff_t; + using reference = value_type&; + using pointer = value_type*; + + static_assert(is_trivial::value); + static_assert(sizeof(__base_value_type) == sizeof(value_type)); + + _LIBCPP_HIDE_FROM_ABI __iterator() = default; + _LIBCPP_HIDE_FROM_ABI __iterator(_BaseIter __base) _NOEXCEPT : __base_(__base) {} + + _LIBCPP_HIDE_FROM_ABI __iterator& operator++() _NOEXCEPT { + ++__base_; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI __iterator operator++(int) _NOEXCEPT { + __iterator __tmp(*this); + ++__base_; + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI __iterator& operator--() _NOEXCEPT { + --__base_; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI __iterator operator--(int) _NOEXCEPT { + __iterator __tmp(*this); + --__base_; + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI friend __iterator operator+(__iterator __iter, difference_type __n) _NOEXCEPT { + return __iterator(__iter.__base_ + __n); + } + + _LIBCPP_HIDE_FROM_ABI friend __iterator operator+(difference_type __n, __iterator __iter) _NOEXCEPT { + return __iterator(__n + __iter.__base_); + } + + _LIBCPP_HIDE_FROM_ABI __iterator& operator+=(difference_type __n) _NOEXCEPT { + __base_ += __n; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI friend __iterator operator-(__iterator __iter, difference_type __n) _NOEXCEPT { + return __iterator(__iter.__base_ - __n); + } + + _LIBCPP_HIDE_FROM_ABI friend difference_type operator-(__iterator __lhs, __iterator __rhs) _NOEXCEPT { + return __lhs.__base_ - __rhs.__base_; + } + + _LIBCPP_HIDE_FROM_ABI __iterator& operator-=(difference_type __n) _NOEXCEPT { + __base_ -= __n; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI _BaseIter __base() const _NOEXCEPT { return __base_; } + + _LIBCPP_HIDE_FROM_ABI _Alias operator*() const _NOEXCEPT { + _Alias __val; + __builtin_memcpy(&__val, std::__to_address(__base_), sizeof(value_type)); + return __val; + } + + _LIBCPP_HIDE_FROM_ABI value_type operator[](difference_type __n) const _NOEXCEPT { return *(*this + __n); } + + _LIBCPP_HIDE_FROM_ABI friend bool operator==(const __iterator& __lhs, const __iterator& __rhs) _NOEXCEPT { + return __lhs.__base_ == __rhs.__base_; + } + + _LIBCPP_HIDE_FROM_ABI friend bool operator!=(const __iterator& __lhs, const __iterator& __rhs) _NOEXCEPT { + return __lhs.__base_ != __rhs.__base_; + } + }; +}; + +// This is required to avoid ADL instantiations on _BaseT +template +using __aliasing_iterator = typename __aliasing_iterator_wrapper<_BaseT, _Alias>::__iterator; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_ALIASING_ITERATOR_H diff --git a/third_party/libcxx/__iterator/back_insert_iterator.h b/third_party/libcxx/__iterator/back_insert_iterator.h index dc656e381..6d3dd4b12 100644 --- a/third_party/libcxx/__iterator/back_insert_iterator.h +++ b/third_party/libcxx/__iterator/back_insert_iterator.h @@ -21,6 +21,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_SUPPRESS_DEPRECATED_PUSH @@ -30,44 +33,53 @@ class _LIBCPP_TEMPLATE_VIS back_insert_iterator : public iterator #endif { -_LIBCPP_SUPPRESS_DEPRECATED_POP + _LIBCPP_SUPPRESS_DEPRECATED_POP + protected: - _Container* container; + _Container* container; + public: - typedef output_iterator_tag iterator_category; - typedef void value_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; #if _LIBCPP_STD_VER >= 20 - typedef ptrdiff_t difference_type; + typedef ptrdiff_t difference_type; #else - typedef void difference_type; + typedef void difference_type; #endif - typedef void pointer; - typedef void reference; - typedef _Container container_type; + typedef void pointer; + typedef void reference; + typedef _Container container_type; - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit back_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator& operator=(const typename _Container::value_type& __value) - {container->push_back(__value); return *this;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit back_insert_iterator(_Container& __x) + : container(std::addressof(__x)) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator& + operator=(const typename _Container::value_type& __value) { + container->push_back(__value); + return *this; + } #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator& operator=(typename _Container::value_type&& __value) - {container->push_back(_VSTD::move(__value)); return *this;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator& + operator=(typename _Container::value_type&& __value) { + container->push_back(std::move(__value)); + return *this; + } #endif // _LIBCPP_CXX03_LANG - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator& operator*() {return *this;} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator& operator++() {return *this;} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator operator++(int) {return *this;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator& operator*() { return *this; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator& operator++() { return *this; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator operator++(int) { return *this; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Container* __get_container() const { return container; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Container* __get_container() const { return container; } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(back_insert_iterator); template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 -back_insert_iterator<_Container> -back_inserter(_Container& __x) -{ - return back_insert_iterator<_Container>(__x); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 back_insert_iterator<_Container> +back_inserter(_Container& __x) { + return back_insert_iterator<_Container>(__x); } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ITERATOR_BACK_INSERT_ITERATOR_H diff --git a/third_party/libcxx/__iterator/bounded_iter.h b/third_party/libcxx/__iterator/bounded_iter.h index 329fd924d..a8f66f4a0 100644 --- a/third_party/libcxx/__iterator/bounded_iter.h +++ b/third_party/libcxx/__iterator/bounded_iter.h @@ -23,18 +23,28 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD // Iterator wrapper that carries the valid range it is allowed to access. // // This is a simple iterator wrapper for contiguous iterators that points -// within a [begin, end) range and carries these bounds with it. The iterator -// ensures that it is pointing within that [begin, end) range when it is -// dereferenced. +// within a [begin, end] range and carries these bounds with it. The iterator +// ensures that it is pointing within [begin, end) range when it is +// dereferenced. It also ensures that it is never iterated outside of +// [begin, end]. This is important for two reasons: // -// Arithmetic operations are allowed and the bounds of the resulting iterator -// are not checked. Hence, it is possible to create an iterator pointing outside -// its range, but it is not possible to dereference it. +// 1. It allows `operator*` and `operator++` bounds checks to be `iter != end`. +// This is both less for the optimizer to prove, and aligns with how callers +// typically use iterators. +// +// 2. Advancing an iterator out of bounds is undefined behavior (see the table +// in [input.iterators]). In particular, when the underlying iterator is a +// pointer, it is undefined at the language level (see [expr.add]). If +// bounded iterators exhibited this undefined behavior, we risk compiler +// optimizations deleting non-redundant bounds checks. template ::value > > struct __bounded_iter { using value_type = typename iterator_traits<_Iterator>::value_type; @@ -48,14 +58,14 @@ struct __bounded_iter { // Create a singular iterator. // - // Such an iterator does not point to any object and is conceptually out of bounds, so it is - // not dereferenceable. Observing operations like comparison and assignment are valid. + // Such an iterator points past the end of an empty span, so it is not dereferenceable. + // Observing operations like comparison and assignment are valid. _LIBCPP_HIDE_FROM_ABI __bounded_iter() = default; _LIBCPP_HIDE_FROM_ABI __bounded_iter(__bounded_iter const&) = default; _LIBCPP_HIDE_FROM_ABI __bounded_iter(__bounded_iter&&) = default; - template ::value > > + template ::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __bounded_iter(__bounded_iter<_OtherIterator> const& __other) _NOEXCEPT : __current_(__other.__current_), __begin_(__other.__begin_), @@ -67,18 +77,20 @@ struct __bounded_iter { private: // Create an iterator wrapping the given iterator, and whose bounds are described - // by the provided [begin, end) range. + // by the provided [begin, end] range. // - // This constructor does not check whether the resulting iterator is within its bounds. - // However, it does check that the provided [begin, end) range is a valid range (that - // is, begin <= end). + // The constructor does not check whether the resulting iterator is within its bounds. It is a + // responsibility of the container to ensure that the given bounds are valid. // // Since it is non-standard for iterators to have this constructor, __bounded_iter must // be created via `std::__make_bounded_iter`. - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __bounded_iter( - _Iterator __current, _Iterator __begin, _Iterator __end) + _LIBCPP_HIDE_FROM_ABI + _LIBCPP_CONSTEXPR_SINCE_CXX14 explicit __bounded_iter(_Iterator __current, _Iterator __begin, _Iterator __end) : __current_(__current), __begin_(__begin), __end_(__end) { - _LIBCPP_ASSERT(__begin <= __end, "__bounded_iter(current, begin, end): [begin, end) is not a valid range"); + _LIBCPP_ASSERT_INTERNAL( + __begin <= __current, "__bounded_iter(current, begin, end): current and begin are inconsistent"); + _LIBCPP_ASSERT_INTERNAL( + __current <= __end, "__bounded_iter(current, begin, end): current and end are inconsistent"); } template @@ -87,30 +99,37 @@ private: public: // Dereference and indexing operations. // - // These operations check that the iterator is dereferenceable, that is within [begin, end). + // These operations check that the iterator is dereferenceable. Since the class invariant is + // that the iterator is always within `[begin, end]`, we only need to check it's not pointing to + // `end`. This is easier for the optimizer because it aligns with the `iter != container.end()` + // checks that typical callers already use (see + // https://github.com/llvm/llvm-project/issues/78829). _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator*() const _NOEXCEPT { - _LIBCPP_ASSERT( - __in_bounds(__current_), "__bounded_iter::operator*: Attempt to dereference an out-of-range iterator"); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __current_ != __end_, "__bounded_iter::operator*: Attempt to dereference an iterator at the end"); return *__current_; } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pointer operator->() const _NOEXCEPT { - _LIBCPP_ASSERT( - __in_bounds(__current_), "__bounded_iter::operator->: Attempt to dereference an out-of-range iterator"); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __current_ != __end_, "__bounded_iter::operator->: Attempt to dereference an iterator at the end"); return std::__to_address(__current_); } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 reference operator[](difference_type __n) const _NOEXCEPT { - _LIBCPP_ASSERT( - __in_bounds(__current_ + __n), "__bounded_iter::operator[]: Attempt to index an iterator out-of-range"); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __n >= __begin_ - __current_, "__bounded_iter::operator[]: Attempt to index an iterator past the start"); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __n < __end_ - __current_, "__bounded_iter::operator[]: Attempt to index an iterator at or past the end"); return __current_[__n]; } // Arithmetic operations. // - // These operations do not check that the resulting iterator is within the bounds, since that - // would make it impossible to create a past-the-end iterator. + // These operations check that the iterator remains within `[begin, end]`. _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __bounded_iter& operator++() _NOEXCEPT { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __current_ != __end_, "__bounded_iter::operator++: Attempt to advance an iterator past the end"); ++__current_; return *this; } @@ -121,6 +140,8 @@ public: } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __bounded_iter& operator--() _NOEXCEPT { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __current_ != __begin_, "__bounded_iter::operator--: Attempt to rewind an iterator past the start"); --__current_; return *this; } @@ -131,6 +152,10 @@ public: } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __bounded_iter& operator+=(difference_type __n) _NOEXCEPT { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __n >= __begin_ - __current_, "__bounded_iter::operator+=: Attempt to rewind an iterator past the start"); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __n <= __end_ - __current_, "__bounded_iter::operator+=: Attempt to advance an iterator past the end"); __current_ += __n; return *this; } @@ -148,6 +173,10 @@ public: } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __bounded_iter& operator-=(difference_type __n) _NOEXCEPT { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __n <= __current_ - __begin_, "__bounded_iter::operator-=: Attempt to rewind an iterator past the start"); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __n >= __current_ - __end_, "__bounded_iter::operator-=: Attempt to advance an iterator past the end"); __current_ -= __n; return *this; } @@ -194,15 +223,10 @@ public: } private: - // Return whether the given iterator is in the bounds of this __bounded_iter. - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool __in_bounds(_Iterator const& __iter) const { - return __iter >= __begin_ && __iter < __end_; - } - template friend struct pointer_traits; _Iterator __current_; // current iterator - _Iterator __begin_, __end_; // valid range represented as [begin, end) + _Iterator __begin_, __end_; // valid range represented as [begin, end] }; template @@ -228,4 +252,6 @@ struct pointer_traits<__bounded_iter<_Iterator> > { _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ITERATOR_BOUNDED_ITER_H diff --git a/third_party/libcxx/__iterator/common_iterator.h b/third_party/libcxx/__iterator/common_iterator.h index e1d114ab9..199de2cc7 100644 --- a/third_party/libcxx/__iterator/common_iterator.h +++ b/third_party/libcxx/__iterator/common_iterator.h @@ -34,119 +34,131 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 -template +template concept __can_use_postfix_proxy = - constructible_from, iter_reference_t<_Iter>> && - move_constructible>; + constructible_from, iter_reference_t<_Iter>> && move_constructible>; -template _Sent> - requires (!same_as<_Iter, _Sent> && copyable<_Iter>) +template _Sent> + requires(!same_as<_Iter, _Sent> && copyable<_Iter>) class common_iterator { struct __proxy { _LIBCPP_HIDE_FROM_ABI constexpr const iter_value_t<_Iter>* operator->() const noexcept { - return _VSTD::addressof(__value_); + return std::addressof(__value_); } iter_value_t<_Iter> __value_; }; struct __postfix_proxy { - _LIBCPP_HIDE_FROM_ABI constexpr const iter_value_t<_Iter>& operator*() const noexcept { - return __value_; - } + _LIBCPP_HIDE_FROM_ABI constexpr const iter_value_t<_Iter>& operator*() const noexcept { return __value_; } iter_value_t<_Iter> __value_; }; -public: variant<_Iter, _Sent> __hold_; + template _OtherSent> + requires(!same_as<_OtherIter, _OtherSent> && copyable<_OtherIter>) + friend class common_iterator; - _LIBCPP_HIDE_FROM_ABI common_iterator() requires default_initializable<_Iter> = default; +public: + _LIBCPP_HIDE_FROM_ABI common_iterator() + requires default_initializable<_Iter> + = default; - _LIBCPP_HIDE_FROM_ABI constexpr common_iterator(_Iter __i) : __hold_(in_place_type<_Iter>, _VSTD::move(__i)) {} - _LIBCPP_HIDE_FROM_ABI constexpr common_iterator(_Sent __s) : __hold_(in_place_type<_Sent>, _VSTD::move(__s)) {} + _LIBCPP_HIDE_FROM_ABI constexpr common_iterator(_Iter __i) : __hold_(in_place_type<_Iter>, std::move(__i)) {} + _LIBCPP_HIDE_FROM_ABI constexpr common_iterator(_Sent __s) : __hold_(in_place_type<_Sent>, std::move(__s)) {} - template + template requires convertible_to && convertible_to _LIBCPP_HIDE_FROM_ABI constexpr common_iterator(const common_iterator<_I2, _S2>& __other) - : __hold_([&]() -> variant<_Iter, _Sent> { - _LIBCPP_ASSERT(!__other.__hold_.valueless_by_exception(), "Attempted to construct from a valueless common_iterator"); - if (__other.__hold_.index() == 0) - return variant<_Iter, _Sent>{in_place_index<0>, _VSTD::__unchecked_get<0>(__other.__hold_)}; - return variant<_Iter, _Sent>{in_place_index<1>, _VSTD::__unchecked_get<1>(__other.__hold_)}; - }()) {} + : __hold_([&]() -> variant<_Iter, _Sent> { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + !__other.__hold_.valueless_by_exception(), "Attempted to construct from a valueless common_iterator"); + if (__other.__hold_.index() == 0) + return variant<_Iter, _Sent>{in_place_index<0>, std::__unchecked_get<0>(__other.__hold_)}; + return variant<_Iter, _Sent>{in_place_index<1>, std::__unchecked_get<1>(__other.__hold_)}; + }()) {} - template + template requires convertible_to && convertible_to && assignable_from<_Iter&, const _I2&> && assignable_from<_Sent&, const _S2&> _LIBCPP_HIDE_FROM_ABI common_iterator& operator=(const common_iterator<_I2, _S2>& __other) { - _LIBCPP_ASSERT(!__other.__hold_.valueless_by_exception(), "Attempted to assign from a valueless common_iterator"); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + !__other.__hold_.valueless_by_exception(), "Attempted to assign from a valueless common_iterator"); - auto __idx = __hold_.index(); + auto __idx = __hold_.index(); auto __other_idx = __other.__hold_.index(); // If they're the same index, just assign. if (__idx == 0 && __other_idx == 0) - _VSTD::__unchecked_get<0>(__hold_) = _VSTD::__unchecked_get<0>(__other.__hold_); + std::__unchecked_get<0>(__hold_) = std::__unchecked_get<0>(__other.__hold_); else if (__idx == 1 && __other_idx == 1) - _VSTD::__unchecked_get<1>(__hold_) = _VSTD::__unchecked_get<1>(__other.__hold_); + std::__unchecked_get<1>(__hold_) = std::__unchecked_get<1>(__other.__hold_); // Otherwise replace with the oposite element. else if (__other_idx == 1) - __hold_.template emplace<1>(_VSTD::__unchecked_get<1>(__other.__hold_)); + __hold_.template emplace<1>(std::__unchecked_get<1>(__other.__hold_)); else if (__other_idx == 0) - __hold_.template emplace<0>(_VSTD::__unchecked_get<0>(__other.__hold_)); + __hold_.template emplace<0>(std::__unchecked_get<0>(__other.__hold_)); return *this; } - _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() - { - _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator"); - return *_VSTD::__unchecked_get<_Iter>(__hold_); + _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator"); + return *std::__unchecked_get<_Iter>(__hold_); } _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const requires __dereferenceable { - _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator"); - return *_VSTD::__unchecked_get<_Iter>(__hold_); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator"); + return *std::__unchecked_get<_Iter>(__hold_); } - template - _LIBCPP_HIDE_FROM_ABI decltype(auto) operator->() const - requires indirectly_readable && - (requires(const _I2& __i) { __i.operator->(); } || - is_reference_v> || - constructible_from, iter_reference_t<_I2>>) + template + _LIBCPP_HIDE_FROM_ABI auto operator->() const + requires indirectly_readable && (requires(const _I2& __i) { + __i.operator->(); + } || is_reference_v> || constructible_from, iter_reference_t<_I2>>) { - _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator"); - if constexpr (is_pointer_v<_Iter> || requires(const _Iter& __i) { __i.operator->(); }) { - return _VSTD::__unchecked_get<_Iter>(__hold_); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + std::holds_alternative<_Iter>(__hold_), "Attempted to dereference a non-dereferenceable common_iterator"); + if constexpr (is_pointer_v<_Iter> || requires(const _Iter& __i) { __i.operator->(); }) { + return std::__unchecked_get<_Iter>(__hold_); } else if constexpr (is_reference_v>) { - auto&& __tmp = *_VSTD::__unchecked_get<_Iter>(__hold_); - return _VSTD::addressof(__tmp); + auto&& __tmp = *std::__unchecked_get<_Iter>(__hold_); + return std::addressof(__tmp); } else { - return __proxy{*_VSTD::__unchecked_get<_Iter>(__hold_)}; + return __proxy{*std::__unchecked_get<_Iter>(__hold_)}; } } _LIBCPP_HIDE_FROM_ABI common_iterator& operator++() { - _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to increment a non-dereferenceable common_iterator"); - ++_VSTD::__unchecked_get<_Iter>(__hold_); return *this; + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + std::holds_alternative<_Iter>(__hold_), "Attempted to increment a non-dereferenceable common_iterator"); + ++std::__unchecked_get<_Iter>(__hold_); + return *this; } _LIBCPP_HIDE_FROM_ABI decltype(auto) operator++(int) { - _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__hold_), "Attempted to increment a non-dereferenceable common_iterator"); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + std::holds_alternative<_Iter>(__hold_), "Attempted to increment a non-dereferenceable common_iterator"); if constexpr (forward_iterator<_Iter>) { auto __tmp = *this; ++*this; return __tmp; - } else if constexpr (requires (_Iter& __i) { { *__i++ } -> __can_reference; } || - !__can_use_postfix_proxy<_Iter>) { - return _VSTD::__unchecked_get<_Iter>(__hold_)++; + } else if constexpr (requires(_Iter& __i) { + { *__i++ } -> __can_reference; + } || !__can_use_postfix_proxy<_Iter>) { + return std::__unchecked_get<_Iter>(__hold_)++; } else { auto __p = __postfix_proxy{**this}; ++*this; @@ -154,12 +166,14 @@ public: } } - template _S2> + template _S2> requires sentinel_for<_Sent, _I2> - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { - _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); - _LIBCPP_ASSERT(!__y.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); + _LIBCPP_HIDE_FROM_ABI friend constexpr bool + operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + !__x.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + !__y.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); auto __x_index = __x.__hold_.index(); auto __y_index = __y.__hold_.index(); @@ -168,17 +182,19 @@ public: return true; if (__x_index == 0) - return _VSTD::__unchecked_get<_Iter>(__x.__hold_) == _VSTD::__unchecked_get<_S2>(__y.__hold_); + return std::__unchecked_get<_Iter>(__x.__hold_) == std::__unchecked_get<_S2>(__y.__hold_); - return _VSTD::__unchecked_get<_Sent>(__x.__hold_) == _VSTD::__unchecked_get<_I2>(__y.__hold_); + return std::__unchecked_get<_Sent>(__x.__hold_) == std::__unchecked_get<_I2>(__y.__hold_); } - template _S2> + template _S2> requires sentinel_for<_Sent, _I2> && equality_comparable_with<_Iter, _I2> - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { - _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); - _LIBCPP_ASSERT(!__y.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); + _LIBCPP_HIDE_FROM_ABI friend constexpr bool + operator==(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + !__x.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + !__y.__hold_.valueless_by_exception(), "Attempted to compare a valueless common_iterator"); auto __x_index = __x.__hold_.index(); auto __y_index = __y.__hold_.index(); @@ -187,20 +203,22 @@ public: return true; if (__x_index == 0 && __y_index == 0) - return _VSTD::__unchecked_get<_Iter>(__x.__hold_) == _VSTD::__unchecked_get<_I2>(__y.__hold_); + return std::__unchecked_get<_Iter>(__x.__hold_) == std::__unchecked_get<_I2>(__y.__hold_); if (__x_index == 0) - return _VSTD::__unchecked_get<_Iter>(__x.__hold_) == _VSTD::__unchecked_get<_S2>(__y.__hold_); + return std::__unchecked_get<_Iter>(__x.__hold_) == std::__unchecked_get<_S2>(__y.__hold_); - return _VSTD::__unchecked_get<_Sent>(__x.__hold_) == _VSTD::__unchecked_get<_I2>(__y.__hold_); + return std::__unchecked_get<_Sent>(__x.__hold_) == std::__unchecked_get<_I2>(__y.__hold_); } - template _I2, sized_sentinel_for<_Iter> _S2> + template _I2, sized_sentinel_for<_Iter> _S2> requires sized_sentinel_for<_Sent, _I2> - _LIBCPP_HIDE_FROM_ABI - friend constexpr iter_difference_t<_I2> operator-(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { - _LIBCPP_ASSERT(!__x.__hold_.valueless_by_exception(), "Attempted to subtract from a valueless common_iterator"); - _LIBCPP_ASSERT(!__y.__hold_.valueless_by_exception(), "Attempted to subtract a valueless common_iterator"); + _LIBCPP_HIDE_FROM_ABI friend constexpr iter_difference_t<_I2> + operator-(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + !__x.__hold_.valueless_by_exception(), "Attempted to subtract from a valueless common_iterator"); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + !__y.__hold_.valueless_by_exception(), "Attempted to subtract a valueless common_iterator"); auto __x_index = __x.__hold_.index(); auto __y_index = __y.__hold_.index(); @@ -209,74 +227,73 @@ public: return 0; if (__x_index == 0 && __y_index == 0) - return _VSTD::__unchecked_get<_Iter>(__x.__hold_) - _VSTD::__unchecked_get<_I2>(__y.__hold_); + return std::__unchecked_get<_Iter>(__x.__hold_) - std::__unchecked_get<_I2>(__y.__hold_); if (__x_index == 0) - return _VSTD::__unchecked_get<_Iter>(__x.__hold_) - _VSTD::__unchecked_get<_S2>(__y.__hold_); + return std::__unchecked_get<_Iter>(__x.__hold_) - std::__unchecked_get<_S2>(__y.__hold_); - return _VSTD::__unchecked_get<_Sent>(__x.__hold_) - _VSTD::__unchecked_get<_I2>(__y.__hold_); + return std::__unchecked_get<_Sent>(__x.__hold_) - std::__unchecked_get<_I2>(__y.__hold_); } - _LIBCPP_HIDE_FROM_ABI friend constexpr iter_rvalue_reference_t<_Iter> iter_move(const common_iterator& __i) - noexcept(noexcept(ranges::iter_move(std::declval()))) - requires input_iterator<_Iter> + _LIBCPP_HIDE_FROM_ABI friend constexpr iter_rvalue_reference_t<_Iter> + iter_move(const common_iterator& __i) noexcept(noexcept(ranges::iter_move(std::declval()))) + requires input_iterator<_Iter> { - _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__i.__hold_), "Attempted to iter_move a non-dereferenceable common_iterator"); - return ranges::iter_move( _VSTD::__unchecked_get<_Iter>(__i.__hold_)); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + std::holds_alternative<_Iter>(__i.__hold_), "Attempted to iter_move a non-dereferenceable common_iterator"); + return ranges::iter_move(std::__unchecked_get<_Iter>(__i.__hold_)); } - template _I2, class _S2> - _LIBCPP_HIDE_FROM_ABI friend constexpr void iter_swap(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) - noexcept(noexcept(ranges::iter_swap(std::declval(), std::declval()))) - { - _LIBCPP_ASSERT(std::holds_alternative<_Iter>(__x.__hold_), "Attempted to iter_swap a non-dereferenceable common_iterator"); - _LIBCPP_ASSERT(std::holds_alternative<_I2>(__y.__hold_), "Attempted to iter_swap a non-dereferenceable common_iterator"); - return ranges::iter_swap(_VSTD::__unchecked_get<_Iter>(__x.__hold_), _VSTD::__unchecked_get<_I2>(__y.__hold_)); + template _I2, class _S2> + _LIBCPP_HIDE_FROM_ABI friend constexpr void + iter_swap(const common_iterator& __x, const common_iterator<_I2, _S2>& __y) noexcept( + noexcept(ranges::iter_swap(std::declval(), std::declval()))) { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + std::holds_alternative<_Iter>(__x.__hold_), "Attempted to iter_swap a non-dereferenceable common_iterator"); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + std::holds_alternative<_I2>(__y.__hold_), "Attempted to iter_swap a non-dereferenceable common_iterator"); + return ranges::iter_swap(std::__unchecked_get<_Iter>(__x.__hold_), std::__unchecked_get<_I2>(__y.__hold_)); } }; -template +template struct incrementable_traits> { using difference_type = iter_difference_t<_Iter>; }; -template -concept __denotes_forward_iter = - requires { typename iterator_traits<_Iter>::iterator_category; } && - derived_from::iterator_category, forward_iterator_tag>; +template +concept __denotes_forward_iter = requires { + typename iterator_traits<_Iter>::iterator_category; +} && derived_from::iterator_category, forward_iterator_tag>; -template -concept __common_iter_has_ptr_op = requires(const common_iterator<_Iter, _Sent>& __a) { - __a.operator->(); -}; +template +concept __common_iter_has_ptr_op = requires(const common_iterator<_Iter, _Sent>& __a) { __a.operator->(); }; -template +template struct __arrow_type_or_void { - using type = void; + using type = void; }; -template +template requires __common_iter_has_ptr_op<_Iter, _Sent> struct __arrow_type_or_void<_Iter, _Sent> { - using type = decltype(std::declval&>().operator->()); + using type = decltype(std::declval&>().operator->()); }; -template +template struct iterator_traits> { - using iterator_concept = _If, - forward_iterator_tag, - input_iterator_tag>; - using iterator_category = _If<__denotes_forward_iter<_Iter>, - forward_iterator_tag, - input_iterator_tag>; - using pointer = typename __arrow_type_or_void<_Iter, _Sent>::type; - using value_type = iter_value_t<_Iter>; - using difference_type = iter_difference_t<_Iter>; - using reference = iter_reference_t<_Iter>; + using iterator_concept = _If, forward_iterator_tag, input_iterator_tag>; + using iterator_category = _If<__denotes_forward_iter<_Iter>, forward_iterator_tag, input_iterator_tag>; + using pointer = typename __arrow_type_or_void<_Iter, _Sent>::type; + using value_type = iter_value_t<_Iter>; + using difference_type = iter_difference_t<_Iter>; + using reference = iter_reference_t<_Iter>; }; #endif // _LIBCPP_STD_VER >= 20 _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ITERATOR_COMMON_ITERATOR_H diff --git a/third_party/libcxx/__iterator/concepts.h b/third_party/libcxx/__iterator/concepts.h index dd9e8d6ac..0a4878308 100644 --- a/third_party/libcxx/__iterator/concepts.h +++ b/third_party/libcxx/__iterator/concepts.h @@ -49,252 +49,209 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 // [iterator.concept.readable] -template +template concept __indirectly_readable_impl = - requires(const _In __i) { - typename iter_value_t<_In>; - typename iter_reference_t<_In>; - typename iter_rvalue_reference_t<_In>; - { *__i } -> same_as>; - { ranges::iter_move(__i) } -> same_as>; - } && - common_reference_with&&, iter_value_t<_In>&> && - common_reference_with&&, iter_rvalue_reference_t<_In>&&> && - common_reference_with&&, const iter_value_t<_In>&>; + requires(const _In __i) { + typename iter_value_t<_In>; + typename iter_reference_t<_In>; + typename iter_rvalue_reference_t<_In>; + { *__i } -> same_as>; + { ranges::iter_move(__i) } -> same_as>; + } && common_reference_with&&, iter_value_t<_In>&> && + common_reference_with&&, iter_rvalue_reference_t<_In>&&> && + common_reference_with&&, const iter_value_t<_In>&>; -template +template concept indirectly_readable = __indirectly_readable_impl>; -template +template using iter_common_reference_t = common_reference_t, iter_value_t<_Tp>&>; // [iterator.concept.writable] -template -concept indirectly_writable = - requires(_Out&& __o, _Tp&& __t) { - *__o = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving - *_VSTD::forward<_Out>(__o) = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving - const_cast&&>(*__o) = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving - const_cast&&>(*_VSTD::forward<_Out>(__o)) = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving - }; +template +concept indirectly_writable = requires(_Out&& __o, _Tp&& __t) { + *__o = std::forward<_Tp>(__t); // not required to be equality-preserving + *std::forward<_Out>(__o) = std::forward<_Tp>(__t); // not required to be equality-preserving + const_cast&&>(*__o) = std::forward<_Tp>(__t); // not required to be equality-preserving + const_cast&&>(*std::forward<_Out>(__o)) = + std::forward<_Tp>(__t); // not required to be equality-preserving +}; // [iterator.concept.winc] -template +template concept __integer_like = integral<_Tp> && !same_as<_Tp, bool>; -template +template concept __signed_integer_like = signed_integral<_Tp>; -template +template concept weakly_incrementable = - // TODO: remove this once the clang bug is fixed (bugs.llvm.org/PR48173). - !same_as<_Ip, bool> && // Currently, clang does not handle bool correctly. - movable<_Ip> && - requires(_Ip __i) { - typename iter_difference_t<_Ip>; - requires __signed_integer_like>; - { ++__i } -> same_as<_Ip&>; // not required to be equality-preserving - __i++; // not required to be equality-preserving - }; + // TODO: remove this once the clang bug is fixed (bugs.llvm.org/PR48173). + !same_as<_Ip, bool> && // Currently, clang does not handle bool correctly. + movable<_Ip> && requires(_Ip __i) { + typename iter_difference_t<_Ip>; + requires __signed_integer_like>; + { ++__i } -> same_as<_Ip&>; // not required to be equality-preserving + __i++; // not required to be equality-preserving + }; // [iterator.concept.inc] -template -concept incrementable = - regular<_Ip> && - weakly_incrementable<_Ip> && - requires(_Ip __i) { - { __i++ } -> same_as<_Ip>; - }; +template +concept incrementable = regular<_Ip> && weakly_incrementable<_Ip> && requires(_Ip __i) { + { __i++ } -> same_as<_Ip>; +}; // [iterator.concept.iterator] -template -concept input_or_output_iterator = - requires(_Ip __i) { - { *__i } -> __can_reference; - } && - weakly_incrementable<_Ip>; +template +concept input_or_output_iterator = requires(_Ip __i) { + { *__i } -> __can_reference; +} && weakly_incrementable<_Ip>; // [iterator.concept.sentinel] -template -concept sentinel_for = - semiregular<_Sp> && - input_or_output_iterator<_Ip> && - __weakly_equality_comparable_with<_Sp, _Ip>; +template +concept sentinel_for = semiregular<_Sp> && input_or_output_iterator<_Ip> && __weakly_equality_comparable_with<_Sp, _Ip>; -template +template inline constexpr bool disable_sized_sentinel_for = false; -template +template concept sized_sentinel_for = - sentinel_for<_Sp, _Ip> && - !disable_sized_sentinel_for, remove_cv_t<_Ip>> && - requires(const _Ip& __i, const _Sp& __s) { - { __s - __i } -> same_as>; - { __i - __s } -> same_as>; - }; + sentinel_for<_Sp, _Ip> && !disable_sized_sentinel_for, remove_cv_t<_Ip>> && + requires(const _Ip& __i, const _Sp& __s) { + { __s - __i } -> same_as>; + { __i - __s } -> same_as>; + }; // [iterator.concept.input] -template -concept input_iterator = - input_or_output_iterator<_Ip> && - indirectly_readable<_Ip> && - requires { typename _ITER_CONCEPT<_Ip>; } && - derived_from<_ITER_CONCEPT<_Ip>, input_iterator_tag>; +template +concept input_iterator = input_or_output_iterator<_Ip> && indirectly_readable<_Ip> && requires { + typename _ITER_CONCEPT<_Ip>; +} && derived_from<_ITER_CONCEPT<_Ip>, input_iterator_tag>; // [iterator.concept.output] -template +template concept output_iterator = - input_or_output_iterator<_Ip> && - indirectly_writable<_Ip, _Tp> && - requires (_Ip __it, _Tp&& __t) { - *__it++ = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving - }; + input_or_output_iterator<_Ip> && indirectly_writable<_Ip, _Tp> && requires(_Ip __it, _Tp&& __t) { + *__it++ = std::forward<_Tp>(__t); // not required to be equality-preserving + }; // [iterator.concept.forward] -template +template concept forward_iterator = - input_iterator<_Ip> && - derived_from<_ITER_CONCEPT<_Ip>, forward_iterator_tag> && - incrementable<_Ip> && - sentinel_for<_Ip, _Ip>; + input_iterator<_Ip> && derived_from<_ITER_CONCEPT<_Ip>, forward_iterator_tag> && incrementable<_Ip> && + sentinel_for<_Ip, _Ip>; // [iterator.concept.bidir] -template +template concept bidirectional_iterator = - forward_iterator<_Ip> && - derived_from<_ITER_CONCEPT<_Ip>, bidirectional_iterator_tag> && - requires(_Ip __i) { - { --__i } -> same_as<_Ip&>; - { __i-- } -> same_as<_Ip>; - }; + forward_iterator<_Ip> && derived_from<_ITER_CONCEPT<_Ip>, bidirectional_iterator_tag> && requires(_Ip __i) { + { --__i } -> same_as<_Ip&>; + { __i-- } -> same_as<_Ip>; + }; -template +template concept random_access_iterator = - bidirectional_iterator<_Ip> && - derived_from<_ITER_CONCEPT<_Ip>, random_access_iterator_tag> && - totally_ordered<_Ip> && - sized_sentinel_for<_Ip, _Ip> && - requires(_Ip __i, const _Ip __j, const iter_difference_t<_Ip> __n) { - { __i += __n } -> same_as<_Ip&>; - { __j + __n } -> same_as<_Ip>; - { __n + __j } -> same_as<_Ip>; - { __i -= __n } -> same_as<_Ip&>; - { __j - __n } -> same_as<_Ip>; - { __j[__n] } -> same_as>; - }; + bidirectional_iterator<_Ip> && derived_from<_ITER_CONCEPT<_Ip>, random_access_iterator_tag> && + totally_ordered<_Ip> && sized_sentinel_for<_Ip, _Ip> && + requires(_Ip __i, const _Ip __j, const iter_difference_t<_Ip> __n) { + { __i += __n } -> same_as<_Ip&>; + { __j + __n } -> same_as<_Ip>; + { __n + __j } -> same_as<_Ip>; + { __i -= __n } -> same_as<_Ip&>; + { __j - __n } -> same_as<_Ip>; + { __j[__n] } -> same_as>; + }; -template +template concept contiguous_iterator = - random_access_iterator<_Ip> && - derived_from<_ITER_CONCEPT<_Ip>, contiguous_iterator_tag> && - is_lvalue_reference_v> && - same_as, remove_cvref_t>> && - requires(const _Ip& __i) { - { _VSTD::to_address(__i) } -> same_as>>; - }; + random_access_iterator<_Ip> && derived_from<_ITER_CONCEPT<_Ip>, contiguous_iterator_tag> && + is_lvalue_reference_v> && same_as, remove_cvref_t>> && + requires(const _Ip& __i) { + { std::to_address(__i) } -> same_as>>; + }; -template +template concept __has_arrow = input_iterator<_Ip> && (is_pointer_v<_Ip> || requires(_Ip __i) { __i.operator->(); }); // [indirectcallable.indirectinvocable] -template +template concept indirectly_unary_invocable = - indirectly_readable<_It> && - copy_constructible<_Fp> && - invocable<_Fp&, iter_value_t<_It>&> && - invocable<_Fp&, iter_reference_t<_It>> && - invocable<_Fp&, iter_common_reference_t<_It>> && - common_reference_with< - invoke_result_t<_Fp&, iter_value_t<_It>&>, - invoke_result_t<_Fp&, iter_reference_t<_It>>>; + indirectly_readable<_It> && copy_constructible<_Fp> && invocable<_Fp&, iter_value_t<_It>&> && + invocable<_Fp&, iter_reference_t<_It>> && + common_reference_with< invoke_result_t<_Fp&, iter_value_t<_It>&>, invoke_result_t<_Fp&, iter_reference_t<_It>>>; -template +template concept indirectly_regular_unary_invocable = - indirectly_readable<_It> && - copy_constructible<_Fp> && - regular_invocable<_Fp&, iter_value_t<_It>&> && - regular_invocable<_Fp&, iter_reference_t<_It>> && - regular_invocable<_Fp&, iter_common_reference_t<_It>> && - common_reference_with< - invoke_result_t<_Fp&, iter_value_t<_It>&>, - invoke_result_t<_Fp&, iter_reference_t<_It>>>; + indirectly_readable<_It> && copy_constructible<_Fp> && regular_invocable<_Fp&, iter_value_t<_It>&> && + regular_invocable<_Fp&, iter_reference_t<_It>> && + common_reference_with< invoke_result_t<_Fp&, iter_value_t<_It>&>, invoke_result_t<_Fp&, iter_reference_t<_It>>>; -template +template concept indirect_unary_predicate = - indirectly_readable<_It> && - copy_constructible<_Fp> && - predicate<_Fp&, iter_value_t<_It>&> && - predicate<_Fp&, iter_reference_t<_It>> && - predicate<_Fp&, iter_common_reference_t<_It>>; + indirectly_readable<_It> && copy_constructible<_Fp> && predicate<_Fp&, iter_value_t<_It>&> && + predicate<_Fp&, iter_reference_t<_It>>; -template +template concept indirect_binary_predicate = - indirectly_readable<_It1> && indirectly_readable<_It2> && - copy_constructible<_Fp> && - predicate<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> && - predicate<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> && - predicate<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> && - predicate<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>> && - predicate<_Fp&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>; + indirectly_readable<_It1> && indirectly_readable<_It2> && copy_constructible<_Fp> && + predicate<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> && + predicate<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> && + predicate<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> && + predicate<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>>; -template +template concept indirect_equivalence_relation = - indirectly_readable<_It1> && indirectly_readable<_It2> && - copy_constructible<_Fp> && - equivalence_relation<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> && - equivalence_relation<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> && - equivalence_relation<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> && - equivalence_relation<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>> && - equivalence_relation<_Fp&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>; + indirectly_readable<_It1> && indirectly_readable<_It2> && copy_constructible<_Fp> && + equivalence_relation<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> && + equivalence_relation<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> && + equivalence_relation<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> && + equivalence_relation<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>>; -template +template concept indirect_strict_weak_order = - indirectly_readable<_It1> && indirectly_readable<_It2> && - copy_constructible<_Fp> && - strict_weak_order<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> && - strict_weak_order<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> && - strict_weak_order<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> && - strict_weak_order<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>> && - strict_weak_order<_Fp&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>; + indirectly_readable<_It1> && indirectly_readable<_It2> && copy_constructible<_Fp> && + strict_weak_order<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> && + strict_weak_order<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> && + strict_weak_order<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> && + strict_weak_order<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>>; -template - requires (indirectly_readable<_Its> && ...) && invocable<_Fp, iter_reference_t<_Its>...> +template + requires(indirectly_readable<_Its> && ...) && invocable<_Fp, iter_reference_t<_Its>...> using indirect_result_t = invoke_result_t<_Fp, iter_reference_t<_Its>...>; -template -concept indirectly_movable = - indirectly_readable<_In> && - indirectly_writable<_Out, iter_rvalue_reference_t<_In>>; +template +concept indirectly_movable = indirectly_readable<_In> && indirectly_writable<_Out, iter_rvalue_reference_t<_In>>; -template +template concept indirectly_movable_storable = - indirectly_movable<_In, _Out> && - indirectly_writable<_Out, iter_value_t<_In>> && - movable> && - constructible_from, iter_rvalue_reference_t<_In>> && - assignable_from&, iter_rvalue_reference_t<_In>>; + indirectly_movable<_In, _Out> && indirectly_writable<_Out, iter_value_t<_In>> && movable> && + constructible_from, iter_rvalue_reference_t<_In>> && + assignable_from&, iter_rvalue_reference_t<_In>>; -template -concept indirectly_copyable = - indirectly_readable<_In> && - indirectly_writable<_Out, iter_reference_t<_In>>; +template +concept indirectly_copyable = indirectly_readable<_In> && indirectly_writable<_Out, iter_reference_t<_In>>; -template +template concept indirectly_copyable_storable = - indirectly_copyable<_In, _Out> && - indirectly_writable<_Out, iter_value_t<_In>&> && - indirectly_writable<_Out, const iter_value_t<_In>&> && - indirectly_writable<_Out, iter_value_t<_In>&&> && - indirectly_writable<_Out, const iter_value_t<_In>&&> && - copyable> && - constructible_from, iter_reference_t<_In>> && - assignable_from&, iter_reference_t<_In>>; + indirectly_copyable<_In, _Out> && indirectly_writable<_Out, iter_value_t<_In>&> && + indirectly_writable<_Out, const iter_value_t<_In>&> && indirectly_writable<_Out, iter_value_t<_In>&&> && + indirectly_writable<_Out, const iter_value_t<_In>&&> && copyable> && + constructible_from, iter_reference_t<_In>> && + assignable_from&, iter_reference_t<_In>>; // Note: indirectly_swappable is located in iter_swap.h to prevent a dependency cycle // (both iter_swap and indirectly_swappable require indirectly_readable). #endif // _LIBCPP_STD_VER >= 20 +template +using __has_random_access_iterator_category_or_concept +#if _LIBCPP_STD_VER >= 20 + = integral_constant>; +#else // _LIBCPP_STD_VER < 20 + = __has_random_access_iterator_category<_Tp>; +#endif // _LIBCPP_STD_VER + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP___ITERATOR_CONCEPTS_H diff --git a/third_party/libcxx/__iterator/counted_iterator.h b/third_party/libcxx/__iterator/counted_iterator.h index ad69a5c90..ea2832e3b 100644 --- a/third_party/libcxx/__iterator/counted_iterator.h +++ b/third_party/libcxx/__iterator/counted_iterator.h @@ -34,135 +34,126 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 -template +template struct __counted_iterator_concept {}; -template +template requires requires { typename _Iter::iterator_concept; } struct __counted_iterator_concept<_Iter> { using iterator_concept = typename _Iter::iterator_concept; }; -template +template struct __counted_iterator_category {}; -template +template requires requires { typename _Iter::iterator_category; } struct __counted_iterator_category<_Iter> { using iterator_category = typename _Iter::iterator_category; }; -template +template struct __counted_iterator_value_type {}; -template +template struct __counted_iterator_value_type<_Iter> { using value_type = iter_value_t<_Iter>; }; -template +template class counted_iterator - : public __counted_iterator_concept<_Iter> - , public __counted_iterator_category<_Iter> - , public __counted_iterator_value_type<_Iter> -{ + : public __counted_iterator_concept<_Iter>, + public __counted_iterator_category<_Iter>, + public __counted_iterator_value_type<_Iter> { public: - _LIBCPP_NO_UNIQUE_ADDRESS _Iter __current_ = _Iter(); - iter_difference_t<_Iter> __count_ = 0; - - using iterator_type = _Iter; + using iterator_type = _Iter; using difference_type = iter_difference_t<_Iter>; - _LIBCPP_HIDE_FROM_ABI - constexpr counted_iterator() requires default_initializable<_Iter> = default; + _LIBCPP_HIDE_FROM_ABI constexpr counted_iterator() + requires default_initializable<_Iter> + = default; - _LIBCPP_HIDE_FROM_ABI - constexpr counted_iterator(_Iter __iter, iter_difference_t<_Iter> __n) - : __current_(_VSTD::move(__iter)), __count_(__n) { - _LIBCPP_ASSERT(__n >= 0, "__n must not be negative."); + _LIBCPP_HIDE_FROM_ABI constexpr counted_iterator(_Iter __iter, iter_difference_t<_Iter> __n) + : __current_(std::move(__iter)), __count_(__n) { + _LIBCPP_ASSERT_UNCATEGORIZED(__n >= 0, "__n must not be negative."); } - template + template requires convertible_to - _LIBCPP_HIDE_FROM_ABI - constexpr counted_iterator(const counted_iterator<_I2>& __other) - : __current_(__other.__current_), __count_(__other.__count_) {} + _LIBCPP_HIDE_FROM_ABI constexpr counted_iterator(const counted_iterator<_I2>& __other) + : __current_(__other.__current_), __count_(__other.__count_) {} - template + template requires assignable_from<_Iter&, const _I2&> - _LIBCPP_HIDE_FROM_ABI - constexpr counted_iterator& operator=(const counted_iterator<_I2>& __other) { + _LIBCPP_HIDE_FROM_ABI constexpr counted_iterator& operator=(const counted_iterator<_I2>& __other) { __current_ = __other.__current_; - __count_ = __other.__count_; + __count_ = __other.__count_; return *this; } - _LIBCPP_HIDE_FROM_ABI - constexpr const _Iter& base() const& noexcept { return __current_; } + _LIBCPP_HIDE_FROM_ABI constexpr const _Iter& base() const& noexcept { return __current_; } - _LIBCPP_HIDE_FROM_ABI - constexpr _Iter base() && { return _VSTD::move(__current_); } + _LIBCPP_HIDE_FROM_ABI constexpr _Iter base() && { return std::move(__current_); } - _LIBCPP_HIDE_FROM_ABI - constexpr iter_difference_t<_Iter> count() const noexcept { return __count_; } + _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter> count() const noexcept { return __count_; } - _LIBCPP_HIDE_FROM_ABI - constexpr decltype(auto) operator*() { - _LIBCPP_ASSERT(__count_ > 0, "Iterator is equal to or past end."); + _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count_ > 0, "Iterator is equal to or past end."); return *__current_; } - _LIBCPP_HIDE_FROM_ABI - constexpr decltype(auto) operator*() const + _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const requires __dereferenceable { - _LIBCPP_ASSERT(__count_ > 0, "Iterator is equal to or past end."); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count_ > 0, "Iterator is equal to or past end."); return *__current_; } - _LIBCPP_HIDE_FROM_ABI - constexpr auto operator->() const noexcept + _LIBCPP_HIDE_FROM_ABI constexpr auto operator->() const noexcept requires contiguous_iterator<_Iter> { - return _VSTD::to_address(__current_); + return std::to_address(__current_); } - _LIBCPP_HIDE_FROM_ABI - constexpr counted_iterator& operator++() { - _LIBCPP_ASSERT(__count_ > 0, "Iterator already at or past end."); + _LIBCPP_HIDE_FROM_ABI constexpr counted_iterator& operator++() { + _LIBCPP_ASSERT_UNCATEGORIZED(__count_ > 0, "Iterator already at or past end."); ++__current_; --__count_; return *this; } - _LIBCPP_HIDE_FROM_ABI - decltype(auto) operator++(int) { - _LIBCPP_ASSERT(__count_ > 0, "Iterator already at or past end."); + _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator++(int) { + _LIBCPP_ASSERT_UNCATEGORIZED(__count_ > 0, "Iterator already at or past end."); --__count_; -#ifndef _LIBCPP_HAS_NO_EXCEPTIONS - try { return __current_++; } - catch(...) { ++__count_; throw; } -#else +# ifndef _LIBCPP_HAS_NO_EXCEPTIONS + try { + return __current_++; + } catch (...) { + ++__count_; + throw; + } +# else return __current_++; -#endif // _LIBCPP_HAS_NO_EXCEPTIONS +# endif // _LIBCPP_HAS_NO_EXCEPTIONS } - _LIBCPP_HIDE_FROM_ABI - constexpr counted_iterator operator++(int) + _LIBCPP_HIDE_FROM_ABI constexpr counted_iterator operator++(int) requires forward_iterator<_Iter> { - _LIBCPP_ASSERT(__count_ > 0, "Iterator already at or past end."); + _LIBCPP_ASSERT_UNCATEGORIZED(__count_ > 0, "Iterator already at or past end."); counted_iterator __tmp = *this; ++*this; return __tmp; } - _LIBCPP_HIDE_FROM_ABI - constexpr counted_iterator& operator--() + _LIBCPP_HIDE_FROM_ABI constexpr counted_iterator& operator--() requires bidirectional_iterator<_Iter> { --__current_; @@ -170,8 +161,7 @@ public: return *this; } - _LIBCPP_HIDE_FROM_ABI - constexpr counted_iterator operator--(int) + _LIBCPP_HIDE_FROM_ABI constexpr counted_iterator operator--(int) requires bidirectional_iterator<_Iter> { counted_iterator __tmp = *this; @@ -179,132 +169,121 @@ public: return __tmp; } - _LIBCPP_HIDE_FROM_ABI - constexpr counted_iterator operator+(iter_difference_t<_Iter> __n) const + _LIBCPP_HIDE_FROM_ABI constexpr counted_iterator operator+(iter_difference_t<_Iter> __n) const requires random_access_iterator<_Iter> { return counted_iterator(__current_ + __n, __count_ - __n); } - _LIBCPP_HIDE_FROM_ABI - friend constexpr counted_iterator operator+( - iter_difference_t<_Iter> __n, const counted_iterator& __x) + _LIBCPP_HIDE_FROM_ABI friend constexpr counted_iterator + operator+(iter_difference_t<_Iter> __n, const counted_iterator& __x) requires random_access_iterator<_Iter> { return __x + __n; } - _LIBCPP_HIDE_FROM_ABI - constexpr counted_iterator& operator+=(iter_difference_t<_Iter> __n) + _LIBCPP_HIDE_FROM_ABI constexpr counted_iterator& operator+=(iter_difference_t<_Iter> __n) requires random_access_iterator<_Iter> { - _LIBCPP_ASSERT(__n <= __count_, "Cannot advance iterator past end."); + _LIBCPP_ASSERT_UNCATEGORIZED(__n <= __count_, "Cannot advance iterator past end."); __current_ += __n; __count_ -= __n; return *this; } - _LIBCPP_HIDE_FROM_ABI - constexpr counted_iterator operator-(iter_difference_t<_Iter> __n) const + _LIBCPP_HIDE_FROM_ABI constexpr counted_iterator operator-(iter_difference_t<_Iter> __n) const requires random_access_iterator<_Iter> { return counted_iterator(__current_ - __n, __count_ + __n); } - template _I2> - _LIBCPP_HIDE_FROM_ABI - friend constexpr iter_difference_t<_I2> operator-( - const counted_iterator& __lhs, const counted_iterator<_I2>& __rhs) - { + template _I2> + _LIBCPP_HIDE_FROM_ABI friend constexpr iter_difference_t<_I2> + operator-(const counted_iterator& __lhs, const counted_iterator<_I2>& __rhs) { return __rhs.__count_ - __lhs.__count_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr iter_difference_t<_Iter> operator-( - const counted_iterator& __lhs, default_sentinel_t) - { + _LIBCPP_HIDE_FROM_ABI friend constexpr iter_difference_t<_Iter> + operator-(const counted_iterator& __lhs, default_sentinel_t) { return -__lhs.__count_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr iter_difference_t<_Iter> operator-( - default_sentinel_t, const counted_iterator& __rhs) - { + _LIBCPP_HIDE_FROM_ABI friend constexpr iter_difference_t<_Iter> + operator-(default_sentinel_t, const counted_iterator& __rhs) { return __rhs.__count_; } - _LIBCPP_HIDE_FROM_ABI - constexpr counted_iterator& operator-=(iter_difference_t<_Iter> __n) + _LIBCPP_HIDE_FROM_ABI constexpr counted_iterator& operator-=(iter_difference_t<_Iter> __n) requires random_access_iterator<_Iter> { - _LIBCPP_ASSERT(-__n <= __count_, "Attempt to subtract too large of a size: " - "counted_iterator would be decremented before the " - "first element of its range."); + _LIBCPP_ASSERT_UNCATEGORIZED( + -__n <= __count_, + "Attempt to subtract too large of a size: " + "counted_iterator would be decremented before the " + "first element of its range."); __current_ -= __n; __count_ += __n; return *this; } - _LIBCPP_HIDE_FROM_ABI - constexpr decltype(auto) operator[](iter_difference_t<_Iter> __n) const + _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](iter_difference_t<_Iter> __n) const requires random_access_iterator<_Iter> { - _LIBCPP_ASSERT(__n < __count_, "Subscript argument must be less than size."); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < __count_, "Subscript argument must be less than size."); return __current_[__n]; } - template _I2> - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==( - const counted_iterator& __lhs, const counted_iterator<_I2>& __rhs) - { + template _I2> + _LIBCPP_HIDE_FROM_ABI friend constexpr bool + operator==(const counted_iterator& __lhs, const counted_iterator<_I2>& __rhs) { return __lhs.__count_ == __rhs.__count_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr bool operator==( - const counted_iterator& __lhs, default_sentinel_t) - { + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const counted_iterator& __lhs, default_sentinel_t) { return __lhs.__count_ == 0; } - template _I2> - _LIBCPP_HIDE_FROM_ABI friend constexpr strong_ordering operator<=>( - const counted_iterator& __lhs, const counted_iterator<_I2>& __rhs) - { + template _I2> + _LIBCPP_HIDE_FROM_ABI friend constexpr strong_ordering + operator<=>(const counted_iterator& __lhs, const counted_iterator<_I2>& __rhs) { return __rhs.__count_ <=> __lhs.__count_; } - _LIBCPP_HIDE_FROM_ABI - friend constexpr iter_rvalue_reference_t<_Iter> iter_move(const counted_iterator& __i) - noexcept(noexcept(ranges::iter_move(__i.__current_))) - requires input_iterator<_Iter> + _LIBCPP_HIDE_FROM_ABI friend constexpr iter_rvalue_reference_t<_Iter> + iter_move(const counted_iterator& __i) noexcept(noexcept(ranges::iter_move(__i.__current_))) + requires input_iterator<_Iter> { - _LIBCPP_ASSERT(__i.__count_ > 0, "Iterator must not be past end of range."); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__i.__count_ > 0, "Iterator must not be past end of range."); return ranges::iter_move(__i.__current_); } - template _I2> - _LIBCPP_HIDE_FROM_ABI - friend constexpr void iter_swap(const counted_iterator& __x, const counted_iterator<_I2>& __y) - noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_))) - { - _LIBCPP_ASSERT(__x.__count_ > 0 && __y.__count_ > 0, - "Iterators must not be past end of range."); + template _I2> + _LIBCPP_HIDE_FROM_ABI friend constexpr void + iter_swap(const counted_iterator& __x, + const counted_iterator<_I2>& __y) noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_))) { + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( + __x.__count_ > 0 && __y.__count_ > 0, "Iterators must not be past end of range."); return ranges::iter_swap(__x.__current_, __y.__current_); } + +private: + _LIBCPP_NO_UNIQUE_ADDRESS _Iter __current_ = _Iter(); + iter_difference_t<_Iter> __count_ = 0; + template + friend class counted_iterator; }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(counted_iterator); -template +template requires same_as<_ITER_TRAITS<_Iter>, iterator_traits<_Iter>> struct iterator_traits> : iterator_traits<_Iter> { - using pointer = conditional_t, - add_pointer_t>, void>; + using pointer = conditional_t, add_pointer_t>, void>; }; #endif // _LIBCPP_STD_VER >= 20 _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ITERATOR_COUNTED_ITERATOR_H diff --git a/third_party/libcxx/__iterator/cpp17_iterator_concepts.h b/third_party/libcxx/__iterator/cpp17_iterator_concepts.h new file mode 100644 index 000000000..ba3536b68 --- /dev/null +++ b/third_party/libcxx/__iterator/cpp17_iterator_concepts.h @@ -0,0 +1,190 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ITERATOR_CPP17_ITERATOR_CONCEPTS_H +#define _LIBCPP___ITERATOR_CPP17_ITERATOR_CONCEPTS_H + +#include <__concepts/boolean_testable.h> +#include <__concepts/convertible_to.h> +#include <__concepts/same_as.h> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__type_traits/is_constructible.h> +#include <__type_traits/is_convertible.h> +#include <__type_traits/is_signed.h> +#include <__type_traits/is_void.h> +#include <__utility/as_const.h> +#include <__utility/forward.h> +#include <__utility/move.h> +#include <__utility/swap.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +#if _LIBCPP_STD_VER >= 20 + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +concept __cpp17_move_constructible = is_move_constructible_v<_Tp>; + +template +concept __cpp17_copy_constructible = __cpp17_move_constructible<_Tp> && is_copy_constructible_v<_Tp>; + +template +concept __cpp17_move_assignable = requires(_Tp __lhs, _Tp __rhs) { + { __lhs = std::move(__rhs) } -> same_as<_Tp&>; +}; + +template +concept __cpp17_copy_assignable = __cpp17_move_assignable<_Tp> && requires(_Tp __lhs, _Tp __rhs) { + { __lhs = __rhs } -> same_as<_Tp&>; + { __lhs = std::as_const(__rhs) } -> same_as<_Tp&>; +}; + +template +concept __cpp17_destructible = requires(_Tp __v) { __v.~_Tp(); }; + +template +concept __cpp17_equality_comparable = requires(_Tp __lhs, _Tp __rhs) { + { __lhs == __rhs } -> __boolean_testable; + { std::as_const(__lhs) == __rhs } -> __boolean_testable; + { __lhs == std::as_const(__rhs) } -> __boolean_testable; + { std::as_const(__lhs) == std::as_const(__rhs) } -> __boolean_testable; +}; + +template +concept __cpp17_default_constructible = is_default_constructible_v<_Tp>; + +template +concept __cpp17_iterator = + __cpp17_copy_constructible<_Iter> && __cpp17_copy_assignable<_Iter> && __cpp17_destructible<_Iter> && + (is_signed_v<__iter_diff_t<_Iter>> || is_void_v<__iter_diff_t<_Iter>>) && requires(_Iter __iter) { + { *__iter }; + { ++__iter } -> same_as<_Iter&>; + }; + +template +concept __cpp17_input_iterator = + __cpp17_iterator<_Iter> && __cpp17_equality_comparable<_Iter> && requires(_Iter __lhs, _Iter __rhs) { + { __lhs != __rhs } -> __boolean_testable; + { std::as_const(__lhs) != __rhs } -> __boolean_testable; + { __lhs != std::as_const(__rhs) } -> __boolean_testable; + { std::as_const(__lhs) != std::as_const(__rhs) } -> __boolean_testable; + + { *__lhs } -> same_as<__iter_reference<_Iter>>; + { *std::as_const(__lhs) } -> same_as<__iter_reference<_Iter>>; + + { ++__lhs } -> same_as<_Iter&>; + { (void)__lhs++ }; + { *__lhs++ }; + }; + +template +concept __cpp17_output_iterator = __cpp17_iterator<_Iter> && requires(_Iter __iter, _WriteTo __write) { + { *__iter = std::forward<_WriteTo>(__write) }; + { ++__iter } -> same_as<_Iter&>; + { __iter++ } -> convertible_to; + { *__iter++ = std::forward<_WriteTo>(__write) }; +}; + +template +concept __cpp17_forward_iterator = + __cpp17_input_iterator<_Iter> && __cpp17_default_constructible<_Iter> && requires(_Iter __iter) { + { __iter++ } -> convertible_to; + { *__iter++ } -> same_as<__iter_reference<_Iter>>; + }; + +template +concept __cpp17_bidirectional_iterator = __cpp17_forward_iterator<_Iter> && requires(_Iter __iter) { + { --__iter } -> same_as<_Iter&>; + { __iter-- } -> convertible_to; + { *__iter-- } -> same_as<__iter_reference<_Iter>>; +}; + +template +concept __cpp17_random_access_iterator = + __cpp17_bidirectional_iterator<_Iter> && requires(_Iter __iter, __iter_diff_t<_Iter> __n) { + { __iter += __n } -> same_as<_Iter&>; + + { __iter + __n } -> same_as<_Iter>; + { __n + __iter } -> same_as<_Iter>; + { std::as_const(__iter) + __n } -> same_as<_Iter>; + { __n + std::as_const(__iter) } -> same_as<_Iter>; + + { __iter -= __n } -> same_as<_Iter&>; + { __iter - __n } -> same_as<_Iter>; + { std::as_const(__iter) - __n } -> same_as<_Iter>; + + { __iter - __iter } -> same_as<__iter_diff_t<_Iter>>; + { std::as_const(__iter) - __iter } -> same_as<__iter_diff_t<_Iter>>; + { __iter - std::as_const(__iter) } -> same_as<__iter_diff_t<_Iter>>; + { std::as_const(__iter) - std::as_const(__iter) } -> same_as<__iter_diff_t<_Iter>>; + + { __iter[__n] } -> convertible_to<__iter_reference<_Iter>>; + { std::as_const(__iter)[__n] } -> convertible_to<__iter_reference<_Iter>>; + + { __iter < __iter } -> __boolean_testable; + { std::as_const(__iter) < __iter } -> __boolean_testable; + { __iter < std::as_const(__iter) } -> __boolean_testable; + { std::as_const(__iter) < std::as_const(__iter) } -> __boolean_testable; + + { __iter > __iter } -> __boolean_testable; + { std::as_const(__iter) > __iter } -> __boolean_testable; + { __iter > std::as_const(__iter) } -> __boolean_testable; + { std::as_const(__iter) > std::as_const(__iter) } -> __boolean_testable; + + { __iter >= __iter } -> __boolean_testable; + { std::as_const(__iter) >= __iter } -> __boolean_testable; + { __iter >= std::as_const(__iter) } -> __boolean_testable; + { std::as_const(__iter) >= std::as_const(__iter) } -> __boolean_testable; + + { __iter <= __iter } -> __boolean_testable; + { std::as_const(__iter) <= __iter } -> __boolean_testable; + { __iter <= std::as_const(__iter) } -> __boolean_testable; + { std::as_const(__iter) <= std::as_const(__iter) } -> __boolean_testable; + }; + +_LIBCPP_END_NAMESPACE_STD + +# ifndef _LIBCPP_DISABLE_ITERATOR_CHECKS +# define _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(iter_t, message) \ + static_assert(::std::__cpp17_input_iterator, message) +# define _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(iter_t, write_t, message) \ + static_assert(::std::__cpp17_output_iterator, message) +# define _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(iter_t, message) \ + static_assert(::std::__cpp17_forward_iterator, message) +# define _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(iter_t, message) \ + static_assert(::std::__cpp17_bidirectional_iterator, message) +# define _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(iter_t, message) \ + static_assert(::std::__cpp17_random_access_iterator, message) +# else +# define _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(iter_t, message) static_assert(true) +# define _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(iter_t, write_t, message) static_assert(true) +# define _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(iter_t, message) static_assert(true) +# define _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(iter_t, message) static_assert(true) +# define _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(iter_t, message) static_assert(true) +# endif + +#else // _LIBCPP_STD_VER >= 20 + +# define _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(iter_t, message) static_assert(true) +# define _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(iter_t, write_t, message) static_assert(true) +# define _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(iter_t, message) static_assert(true) +# define _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(iter_t, message) static_assert(true) +# define _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(iter_t, message) static_assert(true) + +#endif // _LIBCPP_STD_VER >= 20 + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___ITERATOR_CPP17_ITERATOR_CONCEPTS_H diff --git a/third_party/libcxx/__iterator/data.h b/third_party/libcxx/__iterator/data.h index f10680744..b7c160365 100644 --- a/third_party/libcxx/__iterator/data.h +++ b/third_party/libcxx/__iterator/data.h @@ -22,27 +22,25 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 17 -template constexpr -_LIBCPP_INLINE_VISIBILITY -auto data(_Cont& __c) -_NOEXCEPT_(noexcept(__c.data())) --> decltype (__c.data()) -{ return __c.data(); } +template +constexpr _LIBCPP_HIDE_FROM_ABI auto data(_Cont& __c) noexcept(noexcept(__c.data())) -> decltype(__c.data()) { + return __c.data(); +} -template constexpr -_LIBCPP_INLINE_VISIBILITY -auto data(const _Cont& __c) -_NOEXCEPT_(noexcept(__c.data())) --> decltype (__c.data()) -{ return __c.data(); } +template +constexpr _LIBCPP_HIDE_FROM_ABI auto data(const _Cont& __c) noexcept(noexcept(__c.data())) -> decltype(__c.data()) { + return __c.data(); +} template -_LIBCPP_INLINE_VISIBILITY -constexpr _Tp* data(_Tp (&__array)[_Sz]) noexcept { return __array; } +_LIBCPP_HIDE_FROM_ABI constexpr _Tp* data(_Tp (&__array)[_Sz]) noexcept { + return __array; +} template -_LIBCPP_INLINE_VISIBILITY -constexpr const _Ep* data(initializer_list<_Ep> __il) noexcept { return __il.begin(); } +_LIBCPP_HIDE_FROM_ABI constexpr const _Ep* data(initializer_list<_Ep> __il) noexcept { + return __il.begin(); +} #endif diff --git a/third_party/libcxx/__iterator/default_sentinel.h b/third_party/libcxx/__iterator/default_sentinel.h index d5fb2b699..3b65f442f 100644 --- a/third_party/libcxx/__iterator/default_sentinel.h +++ b/third_party/libcxx/__iterator/default_sentinel.h @@ -20,7 +20,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 -struct default_sentinel_t { }; +struct default_sentinel_t {}; inline constexpr default_sentinel_t default_sentinel{}; #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__iterator/distance.h b/third_party/libcxx/__iterator/distance.h index ebe547337..75bd49c9a 100644 --- a/third_party/libcxx/__iterator/distance.h +++ b/third_party/libcxx/__iterator/distance.h @@ -27,30 +27,24 @@ _LIBCPP_BEGIN_NAMESPACE_STD template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 -typename iterator_traits<_InputIter>::difference_type -__distance(_InputIter __first, _InputIter __last, input_iterator_tag) -{ - typename iterator_traits<_InputIter>::difference_type __r(0); - for (; __first != __last; ++__first) - ++__r; - return __r; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 typename iterator_traits<_InputIter>::difference_type +__distance(_InputIter __first, _InputIter __last, input_iterator_tag) { + typename iterator_traits<_InputIter>::difference_type __r(0); + for (; __first != __last; ++__first) + ++__r; + return __r; } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 -typename iterator_traits<_RandIter>::difference_type -__distance(_RandIter __first, _RandIter __last, random_access_iterator_tag) -{ - return __last - __first; +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 typename iterator_traits<_RandIter>::difference_type +__distance(_RandIter __first, _RandIter __last, random_access_iterator_tag) { + return __last - __first; } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 -typename iterator_traits<_InputIter>::difference_type -distance(_InputIter __first, _InputIter __last) -{ - return _VSTD::__distance(__first, __last, typename iterator_traits<_InputIter>::iterator_category()); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 typename iterator_traits<_InputIter>::difference_type +distance(_InputIter __first, _InputIter __last) { + return std::__distance(__first, __last, typename iterator_traits<_InputIter>::iterator_category()); } #if _LIBCPP_STD_VER >= 20 @@ -61,10 +55,9 @@ namespace ranges { namespace __distance { struct __fn { - template _Sp> - requires (!sized_sentinel_for<_Sp, _Ip>) - _LIBCPP_HIDE_FROM_ABI - constexpr iter_difference_t<_Ip> operator()(_Ip __first, _Sp __last) const { + template _Sp> + requires(!sized_sentinel_for<_Sp, _Ip>) + _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Ip> operator()(_Ip __first, _Sp __last) const { iter_difference_t<_Ip> __n = 0; while (__first != __last) { ++__first; @@ -73,9 +66,8 @@ struct __fn { return __n; } - template> _Sp> - _LIBCPP_HIDE_FROM_ABI - constexpr iter_difference_t<_Ip> operator()(_Ip&& __first, _Sp __last) const { + template > _Sp> + _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Ip> operator()(_Ip&& __first, _Sp __last) const { if constexpr (sized_sentinel_for<_Sp, __remove_cvref_t<_Ip>>) { return __last - __first; } else { @@ -83,9 +75,8 @@ struct __fn { } } - template - _LIBCPP_HIDE_FROM_ABI - constexpr range_difference_t<_Rp> operator()(_Rp&& __r) const { + template + _LIBCPP_HIDE_FROM_ABI constexpr range_difference_t<_Rp> operator()(_Rp&& __r) const { if constexpr (sized_range<_Rp>) { return static_cast>(ranges::size(__r)); } else { @@ -97,7 +88,7 @@ struct __fn { } // namespace __distance inline namespace __cpo { - inline constexpr auto distance = __distance::__fn{}; +inline constexpr auto distance = __distance::__fn{}; } // namespace __cpo } // namespace ranges diff --git a/third_party/libcxx/__iterator/empty.h b/third_party/libcxx/__iterator/empty.h index 2cd4c7abf..773f27769 100644 --- a/third_party/libcxx/__iterator/empty.h +++ b/third_party/libcxx/__iterator/empty.h @@ -23,19 +23,20 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 17 template -_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY -constexpr auto empty(const _Cont& __c) -_NOEXCEPT_(noexcept(__c.empty())) --> decltype (__c.empty()) -{ return __c.empty(); } +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto +empty(const _Cont& __c) noexcept(noexcept(__c.empty())) -> decltype(__c.empty()) { + return __c.empty(); +} template -_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY -constexpr bool empty(const _Tp (&)[_Sz]) noexcept { return false; } +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty(const _Tp (&)[_Sz]) noexcept { + return false; +} template -_LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY -constexpr bool empty(initializer_list<_Ep> __il) noexcept { return __il.size() == 0; } +[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty(initializer_list<_Ep> __il) noexcept { + return __il.size() == 0; +} #endif // _LIBCPP_STD_VER >= 17 diff --git a/third_party/libcxx/__iterator/erase_if_container.h b/third_party/libcxx/__iterator/erase_if_container.h index d7c71a947..0f87f50cd 100644 --- a/third_party/libcxx/__iterator/erase_if_container.h +++ b/third_party/libcxx/__iterator/erase_if_container.h @@ -16,12 +16,13 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template -_LIBCPP_HIDE_FROM_ABI -typename _Container::size_type -__libcpp_erase_if_container(_Container& __c, _Predicate& __pred) { +_LIBCPP_HIDE_FROM_ABI typename _Container::size_type __libcpp_erase_if_container(_Container& __c, _Predicate& __pred) { typename _Container::size_type __old_size = __c.size(); const typename _Container::iterator __last = __c.end(); @@ -37,4 +38,6 @@ __libcpp_erase_if_container(_Container& __c, _Predicate& __pred) { _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ITERATOR_ERASE_IF_CONTAINER_H diff --git a/third_party/libcxx/__iterator/front_insert_iterator.h b/third_party/libcxx/__iterator/front_insert_iterator.h index 1ad5348b2..7f2c54ec8 100644 --- a/third_party/libcxx/__iterator/front_insert_iterator.h +++ b/third_party/libcxx/__iterator/front_insert_iterator.h @@ -21,6 +21,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_SUPPRESS_DEPRECATED_PUSH @@ -30,42 +33,51 @@ class _LIBCPP_TEMPLATE_VIS front_insert_iterator : public iterator #endif { -_LIBCPP_SUPPRESS_DEPRECATED_POP -protected: - _Container* container; -public: - typedef output_iterator_tag iterator_category; - typedef void value_type; -#if _LIBCPP_STD_VER >= 20 - typedef ptrdiff_t difference_type; -#else - typedef void difference_type; -#endif - typedef void pointer; - typedef void reference; - typedef _Container container_type; + _LIBCPP_SUPPRESS_DEPRECATED_POP - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit front_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator& operator=(const typename _Container::value_type& __value) - {container->push_front(__value); return *this;} +protected: + _Container* container; + +public: + typedef output_iterator_tag iterator_category; + typedef void value_type; +#if _LIBCPP_STD_VER >= 20 + typedef ptrdiff_t difference_type; +#else + typedef void difference_type; +#endif + typedef void pointer; + typedef void reference; + typedef _Container container_type; + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit front_insert_iterator(_Container& __x) + : container(std::addressof(__x)) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator& + operator=(const typename _Container::value_type& __value) { + container->push_front(__value); + return *this; + } #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator& operator=(typename _Container::value_type&& __value) - {container->push_front(_VSTD::move(__value)); return *this;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator& + operator=(typename _Container::value_type&& __value) { + container->push_front(std::move(__value)); + return *this; + } #endif // _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator& operator*() {return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator& operator++() {return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator operator++(int) {return *this;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator& operator*() { return *this; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator& operator++() { return *this; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator operator++(int) { return *this; } }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(front_insert_iterator); template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -front_insert_iterator<_Container> -front_inserter(_Container& __x) -{ - return front_insert_iterator<_Container>(__x); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 front_insert_iterator<_Container> +front_inserter(_Container& __x) { + return front_insert_iterator<_Container>(__x); } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ITERATOR_FRONT_INSERT_ITERATOR_H diff --git a/third_party/libcxx/__iterator/incrementable_traits.h b/third_party/libcxx/__iterator/incrementable_traits.h index 604e9580e..a228b228f 100644 --- a/third_party/libcxx/__iterator/incrementable_traits.h +++ b/third_party/libcxx/__iterator/incrementable_traits.h @@ -29,33 +29,33 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 // [incrementable.traits] -template struct incrementable_traits {}; +template +struct incrementable_traits {}; -template -requires is_object_v<_Tp> +template + requires is_object_v<_Tp> struct incrementable_traits<_Tp*> { using difference_type = ptrdiff_t; }; -template +template struct incrementable_traits : incrementable_traits<_Ip> {}; -template +template concept __has_member_difference_type = requires { typename _Tp::difference_type; }; -template<__has_member_difference_type _Tp> +template <__has_member_difference_type _Tp> struct incrementable_traits<_Tp> { using difference_type = typename _Tp::difference_type; }; -template -concept __has_integral_minus = - requires(const _Tp& __x, const _Tp& __y) { - { __x - __y } -> integral; - }; +template +concept __has_integral_minus = requires(const _Tp& __x, const _Tp& __y) { + { __x - __y } -> integral; +}; -template<__has_integral_minus _Tp> -requires (!__has_member_difference_type<_Tp>) +template <__has_integral_minus _Tp> + requires(!__has_member_difference_type<_Tp>) struct incrementable_traits<_Tp> { using difference_type = make_signed_t() - std::declval<_Tp>())>; }; @@ -67,9 +67,10 @@ struct iterator_traits; // `incrementable_traits::difference_type` if `iterator_traits` names a specialization // generated from the primary template, and `iterator_traits::difference_type` otherwise. template -using iter_difference_t = typename conditional_t<__is_primary_template > >::value, - incrementable_traits >, - iterator_traits > >::difference_type; +using iter_difference_t = + typename conditional_t<__is_primary_template > >::value, + incrementable_traits >, + iterator_traits > >::difference_type; #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__iterator/indirectly_comparable.h b/third_party/libcxx/__iterator/indirectly_comparable.h index e60ba25ca..e8a7398ba 100644 --- a/third_party/libcxx/__iterator/indirectly_comparable.h +++ b/third_party/libcxx/__iterator/indirectly_comparable.h @@ -24,8 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 template -concept indirectly_comparable = - indirect_binary_predicate<_Rp, projected<_I1, _P1>, projected<_I2, _P2>>; +concept indirectly_comparable = indirect_binary_predicate<_Rp, projected<_I1, _P1>, projected<_I2, _P2>>; #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__iterator/insert_iterator.h b/third_party/libcxx/__iterator/insert_iterator.h index 55348545e..8b7574dc9 100644 --- a/third_party/libcxx/__iterator/insert_iterator.h +++ b/third_party/libcxx/__iterator/insert_iterator.h @@ -22,6 +22,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 @@ -39,43 +42,54 @@ class _LIBCPP_TEMPLATE_VIS insert_iterator : public iterator #endif { -_LIBCPP_SUPPRESS_DEPRECATED_POP -protected: - _Container* container; - __insert_iterator_iter_t<_Container> iter; -public: - typedef output_iterator_tag iterator_category; - typedef void value_type; -#if _LIBCPP_STD_VER >= 20 - typedef ptrdiff_t difference_type; -#else - typedef void difference_type; -#endif - typedef void pointer; - typedef void reference; - typedef _Container container_type; + _LIBCPP_SUPPRESS_DEPRECATED_POP - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator(_Container& __x, __insert_iterator_iter_t<_Container> __i) - : container(_VSTD::addressof(__x)), iter(__i) {} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator=(const typename _Container::value_type& __value) - {iter = container->insert(iter, __value); ++iter; return *this;} +protected: + _Container* container; + __insert_iterator_iter_t<_Container> iter; + +public: + typedef output_iterator_tag iterator_category; + typedef void value_type; +#if _LIBCPP_STD_VER >= 20 + typedef ptrdiff_t difference_type; +#else + typedef void difference_type; +#endif + typedef void pointer; + typedef void reference; + typedef _Container container_type; + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 + insert_iterator(_Container& __x, __insert_iterator_iter_t<_Container> __i) + : container(std::addressof(__x)), iter(__i) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& + operator=(const typename _Container::value_type& __value) { + iter = container->insert(iter, __value); + ++iter; + return *this; + } #ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator=(typename _Container::value_type&& __value) - {iter = container->insert(iter, _VSTD::move(__value)); ++iter; return *this;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& + operator=(typename _Container::value_type&& __value) { + iter = container->insert(iter, std::move(__value)); + ++iter; + return *this; + } #endif // _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator*() {return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator++() {return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator++(int) {return *this;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator*() { return *this; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator++() { return *this; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator& operator++(int) { return *this; } }; template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 -insert_iterator<_Container> -inserter(_Container& __x, __insert_iterator_iter_t<_Container> __i) -{ - return insert_iterator<_Container>(__x, __i); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 insert_iterator<_Container> +inserter(_Container& __x, __insert_iterator_iter_t<_Container> __i) { + return insert_iterator<_Container>(__x, __i); } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ITERATOR_INSERT_ITERATOR_H diff --git a/third_party/libcxx/__iterator/istream_iterator.h b/third_party/libcxx/__iterator/istream_iterator.h index 989902f21..58c9ac6d4 100644 --- a/third_party/libcxx/__iterator/istream_iterator.h +++ b/third_party/libcxx/__iterator/istream_iterator.h @@ -11,12 +11,13 @@ #define _LIBCPP___ITERATOR_ISTREAM_ITERATOR_H #include <__config> +#include <__fwd/istream.h> +#include <__fwd/string.h> #include <__iterator/default_sentinel.h> #include <__iterator/iterator.h> #include <__iterator/iterator_traits.h> #include <__memory/addressof.h> #include -#include // for forward declarations of char_traits and basic_istream #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -25,78 +26,73 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_SUPPRESS_DEPRECATED_PUSH -template , class _Distance = ptrdiff_t> +template , class _Distance = ptrdiff_t> class _LIBCPP_TEMPLATE_VIS istream_iterator #if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES) : public iterator #endif { -_LIBCPP_SUPPRESS_DEPRECATED_POP + _LIBCPP_SUPPRESS_DEPRECATED_POP + public: - typedef input_iterator_tag iterator_category; - typedef _Tp value_type; - typedef _Distance difference_type; - typedef const _Tp* pointer; - typedef const _Tp& reference; - typedef _CharT char_type; - typedef _Traits traits_type; - typedef basic_istream<_CharT,_Traits> istream_type; + typedef input_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Distance difference_type; + typedef const _Tp* pointer; + typedef const _Tp& reference; + typedef _CharT char_type; + typedef _Traits traits_type; + typedef basic_istream<_CharT, _Traits> istream_type; + private: - istream_type* __in_stream_; - _Tp __value_; + istream_type* __in_stream_; + _Tp __value_; + public: - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istream_iterator() : __in_stream_(nullptr), __value_() {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR istream_iterator() : __in_stream_(nullptr), __value_() {} #if _LIBCPP_STD_VER >= 20 - _LIBCPP_HIDE_FROM_ABI constexpr istream_iterator(default_sentinel_t) : istream_iterator() {} + _LIBCPP_HIDE_FROM_ABI constexpr istream_iterator(default_sentinel_t) : istream_iterator() {} #endif // _LIBCPP_STD_VER >= 20 - _LIBCPP_INLINE_VISIBILITY istream_iterator(istream_type& __s) : __in_stream_(_VSTD::addressof(__s)) - { - if (!(*__in_stream_ >> __value_)) - __in_stream_ = nullptr; - } + _LIBCPP_HIDE_FROM_ABI istream_iterator(istream_type& __s) : __in_stream_(std::addressof(__s)) { + if (!(*__in_stream_ >> __value_)) + __in_stream_ = nullptr; + } - _LIBCPP_INLINE_VISIBILITY const _Tp& operator*() const {return __value_;} - _LIBCPP_INLINE_VISIBILITY const _Tp* operator->() const {return _VSTD::addressof((operator*()));} - _LIBCPP_INLINE_VISIBILITY istream_iterator& operator++() - { - if (!(*__in_stream_ >> __value_)) - __in_stream_ = nullptr; - return *this; - } - _LIBCPP_INLINE_VISIBILITY istream_iterator operator++(int) - {istream_iterator __t(*this); ++(*this); return __t;} + _LIBCPP_HIDE_FROM_ABI const _Tp& operator*() const { return __value_; } + _LIBCPP_HIDE_FROM_ABI const _Tp* operator->() const { return std::addressof((operator*())); } + _LIBCPP_HIDE_FROM_ABI istream_iterator& operator++() { + if (!(*__in_stream_ >> __value_)) + __in_stream_ = nullptr; + return *this; + } + _LIBCPP_HIDE_FROM_ABI istream_iterator operator++(int) { + istream_iterator __t(*this); + ++(*this); + return __t; + } - template - friend _LIBCPP_INLINE_VISIBILITY - bool - operator==(const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __x, - const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __y); + template + friend _LIBCPP_HIDE_FROM_ABI bool operator==(const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __x, + const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __y); #if _LIBCPP_STD_VER >= 20 - friend _LIBCPP_HIDE_FROM_ABI bool operator==(const istream_iterator& __i, default_sentinel_t) { - return __i.__in_stream_ == nullptr; - } + friend _LIBCPP_HIDE_FROM_ABI bool operator==(const istream_iterator& __i, default_sentinel_t) { + return __i.__in_stream_ == nullptr; + } #endif // _LIBCPP_STD_VER >= 20 }; template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator==(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x, - const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __y) -{ - return __x.__in_stream_ == __y.__in_stream_; +inline _LIBCPP_HIDE_FROM_ABI bool operator==(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x, + const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __y) { + return __x.__in_stream_ == __y.__in_stream_; } #if _LIBCPP_STD_VER <= 17 template -inline _LIBCPP_INLINE_VISIBILITY -bool -operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x, - const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __y) -{ - return !(__x == __y); +inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x, + const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __y) { + return !(__x == __y); } #endif // _LIBCPP_STD_VER <= 17 diff --git a/third_party/libcxx/__iterator/istreambuf_iterator.h b/third_party/libcxx/__iterator/istreambuf_iterator.h index e39fec6d7..51c4ecff3 100644 --- a/third_party/libcxx/__iterator/istreambuf_iterator.h +++ b/third_party/libcxx/__iterator/istreambuf_iterator.h @@ -11,10 +11,11 @@ #define _LIBCPP___ITERATOR_ISTREAMBUF_ITERATOR_H #include <__config> +#include <__fwd/istream.h> +#include <__fwd/streambuf.h> #include <__iterator/default_sentinel.h> #include <__iterator/iterator.h> #include <__iterator/iterator_traits.h> -#include // for forward declaration of basic_streambuf #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -23,95 +24,84 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_SUPPRESS_DEPRECATED_PUSH -template +template class _LIBCPP_TEMPLATE_VIS istreambuf_iterator #if _LIBCPP_STD_VER <= 14 || !defined(_LIBCPP_ABI_NO_ITERATOR_BASES) - : public iterator + : public iterator #endif { -_LIBCPP_SUPPRESS_DEPRECATED_POP + _LIBCPP_SUPPRESS_DEPRECATED_POP + public: - typedef input_iterator_tag iterator_category; - typedef _CharT value_type; - typedef typename _Traits::off_type difference_type; - typedef _CharT* pointer; - typedef _CharT reference; - typedef _CharT char_type; - typedef _Traits traits_type; - typedef typename _Traits::int_type int_type; - typedef basic_streambuf<_CharT,_Traits> streambuf_type; - typedef basic_istream<_CharT,_Traits> istream_type; + typedef input_iterator_tag iterator_category; + typedef _CharT value_type; + typedef typename _Traits::off_type difference_type; + typedef _CharT* pointer; + typedef _CharT reference; + typedef _CharT char_type; + typedef _Traits traits_type; + typedef typename _Traits::int_type int_type; + typedef basic_streambuf<_CharT, _Traits> streambuf_type; + typedef basic_istream<_CharT, _Traits> istream_type; + private: - mutable streambuf_type* __sbuf_; + mutable streambuf_type* __sbuf_; - class __proxy - { - char_type __keep_; - streambuf_type* __sbuf_; - _LIBCPP_INLINE_VISIBILITY - explicit __proxy(char_type __c, streambuf_type* __s) - : __keep_(__c), __sbuf_(__s) {} - friend class istreambuf_iterator; - public: - _LIBCPP_INLINE_VISIBILITY char_type operator*() const {return __keep_;} - }; + class __proxy { + char_type __keep_; + streambuf_type* __sbuf_; + _LIBCPP_HIDE_FROM_ABI explicit __proxy(char_type __c, streambuf_type* __s) : __keep_(__c), __sbuf_(__s) {} + friend class istreambuf_iterator; + + public: + _LIBCPP_HIDE_FROM_ABI char_type operator*() const { return __keep_; } + }; + + _LIBCPP_HIDE_FROM_ABI bool __test_for_eof() const { + if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sgetc(), traits_type::eof())) + __sbuf_ = nullptr; + return __sbuf_ == nullptr; + } - _LIBCPP_INLINE_VISIBILITY - bool __test_for_eof() const - { - if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sgetc(), traits_type::eof())) - __sbuf_ = nullptr; - return __sbuf_ == nullptr; - } public: - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istreambuf_iterator() _NOEXCEPT : __sbuf_(nullptr) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR istreambuf_iterator() _NOEXCEPT : __sbuf_(nullptr) {} #if _LIBCPP_STD_VER >= 20 - _LIBCPP_INLINE_VISIBILITY constexpr istreambuf_iterator(default_sentinel_t) noexcept - : istreambuf_iterator() {} + _LIBCPP_HIDE_FROM_ABI constexpr istreambuf_iterator(default_sentinel_t) noexcept : istreambuf_iterator() {} #endif // _LIBCPP_STD_VER >= 20 - _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(istream_type& __s) _NOEXCEPT - : __sbuf_(__s.rdbuf()) {} - _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(streambuf_type* __s) _NOEXCEPT - : __sbuf_(__s) {} - _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(const __proxy& __p) _NOEXCEPT - : __sbuf_(__p.__sbuf_) {} + _LIBCPP_HIDE_FROM_ABI istreambuf_iterator(istream_type& __s) _NOEXCEPT : __sbuf_(__s.rdbuf()) {} + _LIBCPP_HIDE_FROM_ABI istreambuf_iterator(streambuf_type* __s) _NOEXCEPT : __sbuf_(__s) {} + _LIBCPP_HIDE_FROM_ABI istreambuf_iterator(const __proxy& __p) _NOEXCEPT : __sbuf_(__p.__sbuf_) {} - _LIBCPP_INLINE_VISIBILITY char_type operator*() const - {return static_cast(__sbuf_->sgetc());} - _LIBCPP_INLINE_VISIBILITY istreambuf_iterator& operator++() - { - __sbuf_->sbumpc(); - return *this; - } - _LIBCPP_INLINE_VISIBILITY __proxy operator++(int) - { - return __proxy(__sbuf_->sbumpc(), __sbuf_); - } + _LIBCPP_HIDE_FROM_ABI char_type operator*() const { return static_cast(__sbuf_->sgetc()); } + _LIBCPP_HIDE_FROM_ABI istreambuf_iterator& operator++() { + __sbuf_->sbumpc(); + return *this; + } + _LIBCPP_HIDE_FROM_ABI __proxy operator++(int) { return __proxy(__sbuf_->sbumpc(), __sbuf_); } - _LIBCPP_INLINE_VISIBILITY bool equal(const istreambuf_iterator& __b) const - {return __test_for_eof() == __b.__test_for_eof();} + _LIBCPP_HIDE_FROM_ABI bool equal(const istreambuf_iterator& __b) const { + return __test_for_eof() == __b.__test_for_eof(); + } #if _LIBCPP_STD_VER >= 20 - friend _LIBCPP_HIDE_FROM_ABI bool operator==(const istreambuf_iterator& __i, default_sentinel_t) { - return __i.__test_for_eof(); - } + friend _LIBCPP_HIDE_FROM_ABI bool operator==(const istreambuf_iterator& __i, default_sentinel_t) { + return __i.__test_for_eof(); + } #endif // _LIBCPP_STD_VER >= 20 }; template -inline _LIBCPP_INLINE_VISIBILITY -bool operator==(const istreambuf_iterator<_CharT,_Traits>& __a, - const istreambuf_iterator<_CharT,_Traits>& __b) - {return __a.equal(__b);} +inline _LIBCPP_HIDE_FROM_ABI bool +operator==(const istreambuf_iterator<_CharT, _Traits>& __a, const istreambuf_iterator<_CharT, _Traits>& __b) { + return __a.equal(__b); +} #if _LIBCPP_STD_VER <= 17 template -inline _LIBCPP_INLINE_VISIBILITY -bool operator!=(const istreambuf_iterator<_CharT,_Traits>& __a, - const istreambuf_iterator<_CharT,_Traits>& __b) - {return !__a.equal(__b);} +inline _LIBCPP_HIDE_FROM_ABI bool +operator!=(const istreambuf_iterator<_CharT, _Traits>& __a, const istreambuf_iterator<_CharT, _Traits>& __b) { + return !__a.equal(__b); +} #endif // _LIBCPP_STD_VER <= 17 _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__iterator/iter_move.h b/third_party/libcxx/__iterator/iter_move.h index 78b1448d0..ba8aed3c0 100644 --- a/third_party/libcxx/__iterator/iter_move.h +++ b/third_party/libcxx/__iterator/iter_move.h @@ -23,6 +23,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 @@ -32,73 +35,69 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __iter_move { -void iter_move(); +void iter_move() = delete; template -concept __unqualified_iter_move = - __class_or_enum> && - requires (_Tp&& __t) { - // NOLINTNEXTLINE(libcpp-robust-against-adl) iter_swap ADL calls should only be made through ranges::iter_swap - iter_move(std::forward<_Tp>(__t)); - }; +concept __unqualified_iter_move = __class_or_enum> && requires(_Tp&& __t) { + // NOLINTNEXTLINE(libcpp-robust-against-adl) iter_swap ADL calls should only be made through ranges::iter_swap + iter_move(std::forward<_Tp>(__t)); +}; -template -concept __move_deref = - !__unqualified_iter_move<_Tp> && - requires (_Tp&& __t) { - *__t; - requires is_lvalue_reference_v; - }; +template +concept __move_deref = !__unqualified_iter_move<_Tp> && requires(_Tp&& __t) { + *__t; + requires is_lvalue_reference_v; +}; -template -concept __just_deref = - !__unqualified_iter_move<_Tp> && - !__move_deref<_Tp> && - requires (_Tp&& __t) { - *__t; - requires (!is_lvalue_reference_v); - }; +template +concept __just_deref = !__unqualified_iter_move<_Tp> && !__move_deref<_Tp> && requires(_Tp&& __t) { + *__t; + requires(!is_lvalue_reference_v); +}; // [iterator.cust.move] struct __fn { // NOLINTBEGIN(libcpp-robust-against-adl) iter_move ADL calls should only be made through ranges::iter_move - template + template requires __unqualified_iter_move<_Ip> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator()(_Ip&& __i) const - noexcept(noexcept(iter_move(std::forward<_Ip>(__i)))) - { + noexcept(noexcept(iter_move(std::forward<_Ip>(__i)))) { return iter_move(std::forward<_Ip>(__i)); } // NOLINTEND(libcpp-robust-against-adl) - template + template requires __move_deref<_Ip> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Ip&& __i) const - noexcept(noexcept(std::move(*std::forward<_Ip>(__i)))) - -> decltype( std::move(*std::forward<_Ip>(__i))) - { return std::move(*std::forward<_Ip>(__i)); } + noexcept(noexcept(std::move(*std::forward<_Ip>(__i)))) -> decltype(std::move(*std::forward<_Ip>(__i))) { + return std::move(*std::forward<_Ip>(__i)); + } - template + template requires __just_deref<_Ip> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Ip&& __i) const - noexcept(noexcept(*std::forward<_Ip>(__i))) - -> decltype( *std::forward<_Ip>(__i)) - { return *std::forward<_Ip>(__i); } + noexcept(noexcept(*std::forward<_Ip>(__i))) -> decltype(*std::forward<_Ip>(__i)) { + return *std::forward<_Ip>(__i); + } }; } // namespace __iter_move inline namespace __cpo { - inline constexpr auto iter_move = __iter_move::__fn{}; +inline constexpr auto iter_move = __iter_move::__fn{}; } // namespace __cpo } // namespace ranges -template<__dereferenceable _Tp> - requires requires(_Tp& __t) { { ranges::iter_move(__t) } -> __can_reference; } +template <__dereferenceable _Tp> + requires requires(_Tp& __t) { + { ranges::iter_move(__t) } -> __can_reference; + } using iter_rvalue_reference_t = decltype(ranges::iter_move(std::declval<_Tp&>())); #endif // _LIBCPP_STD_VER >= 20 _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ITERATOR_ITER_MOVE_H diff --git a/third_party/libcxx/__iterator/iter_swap.h b/third_party/libcxx/__iterator/iter_swap.h index c78efafb9..01ab1b97d 100644 --- a/third_party/libcxx/__iterator/iter_swap.h +++ b/third_party/libcxx/__iterator/iter_swap.h @@ -26,6 +26,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 @@ -34,80 +37,72 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { namespace __iter_swap { - template - void iter_swap(_I1, _I2) = delete; +template +void iter_swap(_I1, _I2) = delete; - template - concept __unqualified_iter_swap = - (__class_or_enum> || __class_or_enum>) && - requires (_T1&& __x, _T2&& __y) { +template +concept __unqualified_iter_swap = + (__class_or_enum> || __class_or_enum>) && requires(_T1&& __x, _T2&& __y) { // NOLINTNEXTLINE(libcpp-robust-against-adl) iter_swap ADL calls should only be made through ranges::iter_swap - iter_swap(_VSTD::forward<_T1>(__x), _VSTD::forward<_T2>(__y)); + iter_swap(std::forward<_T1>(__x), std::forward<_T2>(__y)); }; - template - concept __readable_swappable = +template +concept __readable_swappable = indirectly_readable<_T1> && indirectly_readable<_T2> && swappable_with, iter_reference_t<_T2>>; +struct __fn { + // NOLINTBEGIN(libcpp-robust-against-adl) iter_swap ADL calls should only be made through ranges::iter_swap + template + requires __unqualified_iter_swap<_T1, _T2> + _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_T1&& __x, _T2&& __y) const + noexcept(noexcept(iter_swap(std::forward<_T1>(__x), std::forward<_T2>(__y)))) { + (void)iter_swap(std::forward<_T1>(__x), std::forward<_T2>(__y)); + } + // NOLINTEND(libcpp-robust-against-adl) - struct __fn { - // NOLINTBEGIN(libcpp-robust-against-adl) iter_swap ADL calls should only be made through ranges::iter_swap - template - requires __unqualified_iter_swap<_T1, _T2> - _LIBCPP_HIDE_FROM_ABI - constexpr void operator()(_T1&& __x, _T2&& __y) const - noexcept(noexcept(iter_swap(_VSTD::forward<_T1>(__x), _VSTD::forward<_T2>(__y)))) - { - (void)iter_swap(_VSTD::forward<_T1>(__x), _VSTD::forward<_T2>(__y)); - } - // NOLINTEND(libcpp-robust-against-adl) + template + requires(!__unqualified_iter_swap<_T1, _T2>) && __readable_swappable<_T1, _T2> + _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_T1&& __x, _T2&& __y) const + noexcept(noexcept(ranges::swap(*std::forward<_T1>(__x), *std::forward<_T2>(__y)))) { + ranges::swap(*std::forward<_T1>(__x), *std::forward<_T2>(__y)); + } - template - requires (!__unqualified_iter_swap<_T1, _T2>) && - __readable_swappable<_T1, _T2> - _LIBCPP_HIDE_FROM_ABI - constexpr void operator()(_T1&& __x, _T2&& __y) const - noexcept(noexcept(ranges::swap(*_VSTD::forward<_T1>(__x), *_VSTD::forward<_T2>(__y)))) - { - ranges::swap(*_VSTD::forward<_T1>(__x), *_VSTD::forward<_T2>(__y)); - } - - template - requires (!__unqualified_iter_swap<_T1, _T2> && - !__readable_swappable<_T1, _T2>) && - indirectly_movable_storable<_T1, _T2> && - indirectly_movable_storable<_T2, _T1> - _LIBCPP_HIDE_FROM_ABI - constexpr void operator()(_T1&& __x, _T2&& __y) const - noexcept(noexcept(iter_value_t<_T2>(ranges::iter_move(__y))) && - noexcept(*__y = ranges::iter_move(__x)) && - noexcept(*_VSTD::forward<_T1>(__x) = std::declval>())) - { - iter_value_t<_T2> __old(ranges::iter_move(__y)); - *__y = ranges::iter_move(__x); - *_VSTD::forward<_T1>(__x) = _VSTD::move(__old); - } - }; + template + requires(!__unqualified_iter_swap<_T1, _T2> && // + !__readable_swappable<_T1, _T2>) && // + indirectly_movable_storable<_T1, _T2> && // + indirectly_movable_storable<_T2, _T1> + _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_T1&& __x, _T2&& __y) const + noexcept(noexcept(iter_value_t<_T2>(ranges::iter_move(__y))) && // + noexcept(*__y = ranges::iter_move(__x)) && // + noexcept(*std::forward<_T1>(__x) = std::declval>())) { + iter_value_t<_T2> __old(ranges::iter_move(__y)); + *__y = ranges::iter_move(__x); + *std::forward<_T1>(__x) = std::move(__old); + } +}; } // namespace __iter_swap inline namespace __cpo { - inline constexpr auto iter_swap = __iter_swap::__fn{}; +inline constexpr auto iter_swap = __iter_swap::__fn{}; } // namespace __cpo } // namespace ranges -template +template concept indirectly_swappable = - indirectly_readable<_I1> && indirectly_readable<_I2> && - requires(const _I1 __i1, const _I2 __i2) { - ranges::iter_swap(__i1, __i1); - ranges::iter_swap(__i2, __i2); - ranges::iter_swap(__i1, __i2); - ranges::iter_swap(__i2, __i1); - }; + indirectly_readable<_I1> && indirectly_readable<_I2> && requires(const _I1 __i1, const _I2 __i2) { + ranges::iter_swap(__i1, __i1); + ranges::iter_swap(__i2, __i2); + ranges::iter_swap(__i1, __i2); + ranges::iter_swap(__i2, __i1); + }; #endif // _LIBCPP_STD_VER >= 20 _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ITERATOR_ITER_SWAP_H diff --git a/third_party/libcxx/__iterator/iterator.h b/third_party/libcxx/__iterator/iterator.h index b417eeab7..ba9308f3c 100644 --- a/third_party/libcxx/__iterator/iterator.h +++ b/third_party/libcxx/__iterator/iterator.h @@ -19,15 +19,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template -struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 iterator -{ - typedef _Tp value_type; - typedef _Distance difference_type; - typedef _Pointer pointer; - typedef _Reference reference; - typedef _Category iterator_category; +template +struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 iterator { + typedef _Tp value_type; + typedef _Distance difference_type; + typedef _Pointer pointer; + typedef _Reference reference; + typedef _Category iterator_category; }; _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__iterator/iterator_traits.h b/third_party/libcxx/__iterator/iterator_traits.h index a81f0b577..11af9e301 100644 --- a/third_party/libcxx/__iterator/iterator_traits.h +++ b/third_party/libcxx/__iterator/iterator_traits.h @@ -21,7 +21,6 @@ #include <__fwd/pair.h> #include <__iterator/incrementable_traits.h> #include <__iterator/readable_traits.h> -#include <__type_traits/add_const.h> #include <__type_traits/common_reference.h> #include <__type_traits/conditional.h> #include <__type_traits/disjunction.h> @@ -49,9 +48,7 @@ template using __with_reference = _Tp&; template -concept __can_reference = requires { - typename __with_reference<_Tp>; -}; +concept __can_reference = requires { typename __with_reference<_Tp>; }; template concept __dereferenceable = requires(_Tp& __t) { @@ -59,7 +56,7 @@ concept __dereferenceable = requires(_Tp& __t) { }; // [iterator.traits] -template<__dereferenceable _Tp> +template <__dereferenceable _Tp> using iter_reference_t = decltype(*std::declval<_Tp&>()); #endif // _LIBCPP_STD_VER >= 20 @@ -69,20 +66,16 @@ struct _LIBCPP_TEMPLATE_VIS iterator_traits; struct _LIBCPP_TEMPLATE_VIS input_iterator_tag {}; struct _LIBCPP_TEMPLATE_VIS output_iterator_tag {}; -struct _LIBCPP_TEMPLATE_VIS forward_iterator_tag : public input_iterator_tag {}; +struct _LIBCPP_TEMPLATE_VIS forward_iterator_tag : public input_iterator_tag {}; struct _LIBCPP_TEMPLATE_VIS bidirectional_iterator_tag : public forward_iterator_tag {}; struct _LIBCPP_TEMPLATE_VIS random_access_iterator_tag : public bidirectional_iterator_tag {}; #if _LIBCPP_STD_VER >= 20 -struct _LIBCPP_TEMPLATE_VIS contiguous_iterator_tag : public random_access_iterator_tag {}; +struct _LIBCPP_TEMPLATE_VIS contiguous_iterator_tag : public random_access_iterator_tag {}; #endif template struct __iter_traits_cache { - using type = _If< - __is_primary_template >::value, - _Iter, - iterator_traits<_Iter> - >; + using type = _If< __is_primary_template >::value, _Iter, iterator_traits<_Iter> >; }; template using _ITER_TRAITS = typename __iter_traits_cache<_Iter>::type; @@ -97,64 +90,61 @@ struct __iter_concept_category_test { }; struct __iter_concept_random_fallback { template - using _Apply = __enable_if_t< - __is_primary_template >::value, - random_access_iterator_tag - >; + using _Apply = __enable_if_t< __is_primary_template >::value, random_access_iterator_tag >; }; -template struct __test_iter_concept - : _IsValidExpansion<_Tester::template _Apply, _Iter>, - _Tester -{ -}; +template +struct __test_iter_concept : _IsValidExpansion<_Tester::template _Apply, _Iter>, _Tester {}; template struct __iter_concept_cache { - using type = _Or< - __test_iter_concept<_Iter, __iter_concept_concept_test>, - __test_iter_concept<_Iter, __iter_concept_category_test>, - __test_iter_concept<_Iter, __iter_concept_random_fallback> - >; + using type = _Or< __test_iter_concept<_Iter, __iter_concept_concept_test>, + __test_iter_concept<_Iter, __iter_concept_category_test>, + __test_iter_concept<_Iter, __iter_concept_random_fallback> >; }; template using _ITER_CONCEPT = typename __iter_concept_cache<_Iter>::type::template _Apply<_Iter>; - template -struct __has_iterator_typedefs -{ +struct __has_iterator_typedefs { private: - template static false_type __test(...); - template static true_type __test(__void_t* = nullptr, - __void_t* = nullptr, - __void_t* = nullptr, - __void_t* = nullptr, - __void_t* = nullptr); -public: - static const bool value = decltype(__test<_Tp>(0,0,0,0,0))::value; -}; + template + static false_type __test(...); + template + static true_type + __test(__void_t* = nullptr, + __void_t* = nullptr, + __void_t* = nullptr, + __void_t* = nullptr, + __void_t* = nullptr); - -template -struct __has_iterator_category -{ -private: - template static false_type __test(...); - template static true_type __test(typename _Up::iterator_category* = nullptr); public: - static const bool value = decltype(__test<_Tp>(nullptr))::value; + static const bool value = decltype(__test<_Tp>(nullptr, nullptr, nullptr, nullptr, nullptr))::value; }; template -struct __has_iterator_concept -{ +struct __has_iterator_category { private: - template static false_type __test(...); - template static true_type __test(typename _Up::iterator_concept* = nullptr); + template + static false_type __test(...); + template + static true_type __test(typename _Up::iterator_category* = nullptr); + public: - static const bool value = decltype(__test<_Tp>(nullptr))::value; + static const bool value = decltype(__test<_Tp>(nullptr))::value; +}; + +template +struct __has_iterator_concept { +private: + template + static false_type __test(...); + template + static true_type __test(typename _Up::iterator_concept* = nullptr); + +public: + static const bool value = decltype(__test<_Tp>(nullptr))::value; }; #if _LIBCPP_STD_VER >= 20 @@ -163,200 +153,194 @@ public: // from `[iterator.cpp17]`. To avoid confusion between the two, the exposition-only concepts have been banished to // a "detail" namespace indicating they have a niche use-case. namespace __iterator_traits_detail { -template -concept __cpp17_iterator = - requires(_Ip __i) { - { *__i } -> __can_reference; - { ++__i } -> same_as<_Ip&>; - { *__i++ } -> __can_reference; - } && - copyable<_Ip>; +template +concept __cpp17_iterator = requires(_Ip __i) { + { *__i } -> __can_reference; + { ++__i } -> same_as<_Ip&>; + { *__i++ } -> __can_reference; +} && copyable<_Ip>; -template -concept __cpp17_input_iterator = - __cpp17_iterator<_Ip> && - equality_comparable<_Ip> && - requires(_Ip __i) { - typename incrementable_traits<_Ip>::difference_type; - typename indirectly_readable_traits<_Ip>::value_type; - typename common_reference_t&&, - typename indirectly_readable_traits<_Ip>::value_type&>; - typename common_reference_t::value_type&>; - requires signed_integral::difference_type>; - }; +template +concept __cpp17_input_iterator = __cpp17_iterator<_Ip> && equality_comparable<_Ip> && requires(_Ip __i) { + typename incrementable_traits<_Ip>::difference_type; + typename indirectly_readable_traits<_Ip>::value_type; + typename common_reference_t&&, typename indirectly_readable_traits<_Ip>::value_type&>; + typename common_reference_t::value_type&>; + requires signed_integral::difference_type>; +}; -template +template concept __cpp17_forward_iterator = - __cpp17_input_iterator<_Ip> && - constructible_from<_Ip> && - is_reference_v> && - same_as>, - typename indirectly_readable_traits<_Ip>::value_type> && - requires(_Ip __i) { - { __i++ } -> convertible_to<_Ip const&>; - { *__i++ } -> same_as>; - }; + __cpp17_input_iterator<_Ip> && constructible_from<_Ip> && is_reference_v> && + same_as>, typename indirectly_readable_traits<_Ip>::value_type> && + requires(_Ip __i) { + { __i++ } -> convertible_to<_Ip const&>; + { *__i++ } -> same_as>; + }; -template -concept __cpp17_bidirectional_iterator = - __cpp17_forward_iterator<_Ip> && - requires(_Ip __i) { - { --__i } -> same_as<_Ip&>; - { __i-- } -> convertible_to<_Ip const&>; - { *__i-- } -> same_as>; - }; +template +concept __cpp17_bidirectional_iterator = __cpp17_forward_iterator<_Ip> && requires(_Ip __i) { + { --__i } -> same_as<_Ip&>; + { __i-- } -> convertible_to<_Ip const&>; + { *__i-- } -> same_as>; +}; -template +template concept __cpp17_random_access_iterator = - __cpp17_bidirectional_iterator<_Ip> && - totally_ordered<_Ip> && - requires(_Ip __i, typename incrementable_traits<_Ip>::difference_type __n) { - { __i += __n } -> same_as<_Ip&>; - { __i -= __n } -> same_as<_Ip&>; - { __i + __n } -> same_as<_Ip>; - { __n + __i } -> same_as<_Ip>; - { __i - __n } -> same_as<_Ip>; - { __i - __i } -> same_as; // NOLINT(misc-redundant-expression) ; This is llvm.org/PR54114 - { __i[__n] } -> convertible_to>; - }; + __cpp17_bidirectional_iterator<_Ip> && totally_ordered<_Ip> && + requires(_Ip __i, typename incrementable_traits<_Ip>::difference_type __n) { + { __i += __n } -> same_as<_Ip&>; + { __i -= __n } -> same_as<_Ip&>; + { __i + __n } -> same_as<_Ip>; + { __n + __i } -> same_as<_Ip>; + { __i - __n } -> same_as<_Ip>; + { __i - __i } -> same_as; // NOLINT(misc-redundant-expression) ; This is llvm.org/PR54114 + { __i[__n] } -> convertible_to>; + }; } // namespace __iterator_traits_detail -template +template concept __has_member_reference = requires { typename _Ip::reference; }; -template +template concept __has_member_pointer = requires { typename _Ip::pointer; }; -template +template concept __has_member_iterator_category = requires { typename _Ip::iterator_category; }; -template +template concept __specifies_members = requires { - typename _Ip::value_type; - typename _Ip::difference_type; - requires __has_member_reference<_Ip>; - requires __has_member_iterator_category<_Ip>; - }; + typename _Ip::value_type; + typename _Ip::difference_type; + requires __has_member_reference<_Ip>; + requires __has_member_iterator_category<_Ip>; +}; -template +template struct __iterator_traits_member_pointer_or_void { using type = void; }; -template<__has_member_pointer _Tp> +template <__has_member_pointer _Tp> struct __iterator_traits_member_pointer_or_void<_Tp> { using type = typename _Tp::pointer; }; -template -concept __cpp17_iterator_missing_members = - !__specifies_members<_Tp> && - __iterator_traits_detail::__cpp17_iterator<_Tp>; +template +concept __cpp17_iterator_missing_members = !__specifies_members<_Tp> && __iterator_traits_detail::__cpp17_iterator<_Tp>; -template +template concept __cpp17_input_iterator_missing_members = - __cpp17_iterator_missing_members<_Tp> && - __iterator_traits_detail::__cpp17_input_iterator<_Tp>; + __cpp17_iterator_missing_members<_Tp> && __iterator_traits_detail::__cpp17_input_iterator<_Tp>; // Otherwise, `pointer` names `void`. -template -struct __iterator_traits_member_pointer_or_arrow_or_void { using type = void; }; +template +struct __iterator_traits_member_pointer_or_arrow_or_void { + using type = void; +}; // [iterator.traits]/3.2.1 // If the qualified-id `I::pointer` is valid and denotes a type, `pointer` names that type. -template<__has_member_pointer _Ip> -struct __iterator_traits_member_pointer_or_arrow_or_void<_Ip> { using type = typename _Ip::pointer; }; +template <__has_member_pointer _Ip> +struct __iterator_traits_member_pointer_or_arrow_or_void<_Ip> { + using type = typename _Ip::pointer; +}; // Otherwise, if `decltype(declval().operator->())` is well-formed, then `pointer` names that // type. -template +template requires requires(_Ip& __i) { __i.operator->(); } && (!__has_member_pointer<_Ip>) struct __iterator_traits_member_pointer_or_arrow_or_void<_Ip> { using type = decltype(std::declval<_Ip&>().operator->()); }; // Otherwise, `reference` names `iter-reference-t`. -template -struct __iterator_traits_member_reference { using type = iter_reference_t<_Ip>; }; +template +struct __iterator_traits_member_reference { + using type = iter_reference_t<_Ip>; +}; // [iterator.traits]/3.2.2 // If the qualified-id `I::reference` is valid and denotes a type, `reference` names that type. -template<__has_member_reference _Ip> -struct __iterator_traits_member_reference<_Ip> { using type = typename _Ip::reference; }; +template <__has_member_reference _Ip> +struct __iterator_traits_member_reference<_Ip> { + using type = typename _Ip::reference; +}; // [iterator.traits]/3.2.3.4 // input_iterator_tag -template +template struct __deduce_iterator_category { using type = input_iterator_tag; }; // [iterator.traits]/3.2.3.1 // `random_access_iterator_tag` if `I` satisfies `cpp17-random-access-iterator`, or otherwise -template<__iterator_traits_detail::__cpp17_random_access_iterator _Ip> +template <__iterator_traits_detail::__cpp17_random_access_iterator _Ip> struct __deduce_iterator_category<_Ip> { using type = random_access_iterator_tag; }; // [iterator.traits]/3.2.3.2 // `bidirectional_iterator_tag` if `I` satisfies `cpp17-bidirectional-iterator`, or otherwise -template<__iterator_traits_detail::__cpp17_bidirectional_iterator _Ip> +template <__iterator_traits_detail::__cpp17_bidirectional_iterator _Ip> struct __deduce_iterator_category<_Ip> { using type = bidirectional_iterator_tag; }; // [iterator.traits]/3.2.3.3 // `forward_iterator_tag` if `I` satisfies `cpp17-forward-iterator`, or otherwise -template<__iterator_traits_detail::__cpp17_forward_iterator _Ip> +template <__iterator_traits_detail::__cpp17_forward_iterator _Ip> struct __deduce_iterator_category<_Ip> { using type = forward_iterator_tag; }; -template +template struct __iterator_traits_iterator_category : __deduce_iterator_category<_Ip> {}; // [iterator.traits]/3.2.3 // If the qualified-id `I::iterator-category` is valid and denotes a type, `iterator-category` names // that type. -template<__has_member_iterator_category _Ip> +template <__has_member_iterator_category _Ip> struct __iterator_traits_iterator_category<_Ip> { using type = typename _Ip::iterator_category; }; // otherwise, it names void. -template -struct __iterator_traits_difference_type { using type = void; }; +template +struct __iterator_traits_difference_type { + using type = void; +}; // If the qualified-id `incrementable_traits::difference_type` is valid and denotes a type, then // `difference_type` names that type; -template -requires requires { typename incrementable_traits<_Ip>::difference_type; } +template + requires requires { typename incrementable_traits<_Ip>::difference_type; } struct __iterator_traits_difference_type<_Ip> { using type = typename incrementable_traits<_Ip>::difference_type; }; // [iterator.traits]/3.4 // Otherwise, `iterator_traits` has no members by any of the above names. -template +template struct __iterator_traits {}; // [iterator.traits]/3.1 // If `I` has valid ([temp.deduct]) member types `difference-type`, `value-type`, `reference`, and // `iterator-category`, then `iterator-traits` has the following publicly accessible members: -template<__specifies_members _Ip> +template <__specifies_members _Ip> struct __iterator_traits<_Ip> { - using iterator_category = typename _Ip::iterator_category; - using value_type = typename _Ip::value_type; - using difference_type = typename _Ip::difference_type; - using pointer = typename __iterator_traits_member_pointer_or_void<_Ip>::type; - using reference = typename _Ip::reference; + using iterator_category = typename _Ip::iterator_category; + using value_type = typename _Ip::value_type; + using difference_type = typename _Ip::difference_type; + using pointer = typename __iterator_traits_member_pointer_or_void<_Ip>::type; + using reference = typename _Ip::reference; }; // [iterator.traits]/3.2 // Otherwise, if `I` satisfies the exposition-only concept `cpp17-input-iterator`, // `iterator-traits` has the following publicly accessible members: -template<__cpp17_input_iterator_missing_members _Ip> +template <__cpp17_input_iterator_missing_members _Ip> struct __iterator_traits<_Ip> { using iterator_category = typename __iterator_traits_iterator_category<_Ip>::type; using value_type = typename indirectly_readable_traits<_Ip>::value_type; @@ -367,7 +351,7 @@ struct __iterator_traits<_Ip> { // Otherwise, if `I` satisfies the exposition-only concept `cpp17-iterator`, then // `iterator_traits` has the following publicly accessible members: -template<__cpp17_iterator_missing_members _Ip> +template <__cpp17_iterator_missing_members _Ip> struct __iterator_traits<_Ip> { using iterator_category = output_iterator_tag; using value_type = void; @@ -376,36 +360,33 @@ struct __iterator_traits<_Ip> { using reference = void; }; -template +template struct iterator_traits : __iterator_traits<_Ip> { using __primary_template = iterator_traits; }; -#else // _LIBCPP_STD_VER >= 20 +#else // _LIBCPP_STD_VER >= 20 -template struct __iterator_traits {}; +template +struct __iterator_traits {}; -template struct __iterator_traits_impl {}; +template +struct __iterator_traits_impl {}; template -struct __iterator_traits_impl<_Iter, true> -{ - typedef typename _Iter::difference_type difference_type; - typedef typename _Iter::value_type value_type; - typedef typename _Iter::pointer pointer; - typedef typename _Iter::reference reference; - typedef typename _Iter::iterator_category iterator_category; +struct __iterator_traits_impl<_Iter, true> { + typedef typename _Iter::difference_type difference_type; + typedef typename _Iter::value_type value_type; + typedef typename _Iter::pointer pointer; + typedef typename _Iter::reference reference; + typedef typename _Iter::iterator_category iterator_category; }; template struct __iterator_traits<_Iter, true> - : __iterator_traits_impl - < - _Iter, - is_convertible::value || - is_convertible::value - > -{}; + : __iterator_traits_impl< _Iter, + is_convertible::value || + is_convertible::value > {}; // iterator_traits will only have the nested types if Iterator::iterator_category // exists. Else iterator_traits will be an empty class. This is a @@ -413,41 +394,35 @@ struct __iterator_traits<_Iter, true> // the client expects instead of failing at compile time. template -struct _LIBCPP_TEMPLATE_VIS iterator_traits - : __iterator_traits<_Iter, __has_iterator_typedefs<_Iter>::value> { - +struct _LIBCPP_TEMPLATE_VIS iterator_traits : __iterator_traits<_Iter, __has_iterator_typedefs<_Iter>::value> { using __primary_template = iterator_traits; }; #endif // _LIBCPP_STD_VER >= 20 -template +template #if _LIBCPP_STD_VER >= 20 -requires is_object_v<_Tp> + requires is_object_v<_Tp> #endif -struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*> -{ - typedef ptrdiff_t difference_type; - typedef __remove_cv_t<_Tp> value_type; - typedef _Tp* pointer; - typedef _Tp& reference; - typedef random_access_iterator_tag iterator_category; +struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*> { + typedef ptrdiff_t difference_type; + typedef __remove_cv_t<_Tp> value_type; + typedef _Tp* pointer; + typedef _Tp& reference; + typedef random_access_iterator_tag iterator_category; #if _LIBCPP_STD_VER >= 20 - typedef contiguous_iterator_tag iterator_concept; + typedef contiguous_iterator_tag iterator_concept; #endif }; template >::value> -struct __has_iterator_category_convertible_to - : is_convertible::iterator_category, _Up> -{}; +struct __has_iterator_category_convertible_to : is_convertible::iterator_category, _Up> { +}; template struct __has_iterator_category_convertible_to<_Tp, _Up, false> : false_type {}; template ::value> -struct __has_iterator_concept_convertible_to - : is_convertible -{}; +struct __has_iterator_concept_convertible_to : is_convertible {}; template struct __has_iterator_concept_convertible_to<_Tp, _Up, false> : false_type {}; @@ -473,10 +448,9 @@ using __has_random_access_iterator_category = __has_iterator_category_convertibl // #if _LIBCPP_STD_VER >= 20 template -struct __libcpp_is_contiguous_iterator : _Or< - __has_iterator_category_convertible_to<_Tp, contiguous_iterator_tag>, - __has_iterator_concept_convertible_to<_Tp, contiguous_iterator_tag> -> {}; +struct __libcpp_is_contiguous_iterator + : _Or< __has_iterator_category_convertible_to<_Tp, contiguous_iterator_tag>, + __has_iterator_concept_convertible_to<_Tp, contiguous_iterator_tag> > {}; #else template struct __libcpp_is_contiguous_iterator : false_type {}; @@ -486,41 +460,40 @@ struct __libcpp_is_contiguous_iterator : false_type {}; template struct __libcpp_is_contiguous_iterator<_Up*> : true_type {}; - template class __wrap_iter; template -using __has_exactly_input_iterator_category - = integral_constant::value && - !__has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value>; +using __has_exactly_input_iterator_category = + integral_constant::value && + !__has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value>; template -using __has_exactly_forward_iterator_category - = integral_constant::value && - !__has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>::value>; +using __has_exactly_forward_iterator_category = + integral_constant::value && + !__has_iterator_category_convertible_to<_Tp, bidirectional_iterator_tag>::value>; template -using __has_exactly_bidirectional_iterator_category - = integral_constant::value && - !__has_iterator_category_convertible_to<_Tp, random_access_iterator_tag>::value>; +using __has_exactly_bidirectional_iterator_category = + integral_constant::value && + !__has_iterator_category_convertible_to<_Tp, random_access_iterator_tag>::value>; -template +template using __iter_value_type = typename iterator_traits<_InputIterator>::value_type; -template +template using __iter_key_type = __remove_const_t::value_type::first_type>; -template +template using __iter_mapped_type = typename iterator_traits<_InputIterator>::value_type::second_type; -template -using __iter_to_alloc_type = pair< - typename add_const::value_type::first_type>::type, - typename iterator_traits<_InputIterator>::value_type::second_type>; +template +using __iter_to_alloc_type = + pair::value_type::first_type, + typename iterator_traits<_InputIterator>::value_type::second_type>; template using __iterator_category_type = typename iterator_traits<_Iter>::iterator_category; @@ -534,6 +507,22 @@ using __iter_diff_t = typename iterator_traits<_Iter>::difference_type; template using __iter_reference = typename iterator_traits<_Iter>::reference; +#if _LIBCPP_STD_VER >= 20 + +// [readable.traits] + +// Let `RI` be `remove_cvref_t`. The type `iter_value_t` denotes +// `indirectly_readable_traits::value_type` if `iterator_traits` names a specialization +// generated from the primary template, and `iterator_traits::value_type` otherwise. +// This has to be in this file and not readable_traits.h to break the include cycle between the two. +template +using iter_value_t = + typename conditional_t<__is_primary_template > >::value, + indirectly_readable_traits >, + iterator_traits > >::value_type; + +#endif // _LIBCPP_STD_VER >= 20 + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP___ITERATOR_ITERATOR_TRAITS_H diff --git a/third_party/libcxx/__iterator/iterator_with_data.h b/third_party/libcxx/__iterator/iterator_with_data.h index 06c2fa699..afdc0a4e1 100644 --- a/third_party/libcxx/__iterator/iterator_with_data.h +++ b/third_party/libcxx/__iterator/iterator_with_data.h @@ -24,6 +24,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + #if _LIBCPP_STD_VER >= 20 _LIBCPP_BEGIN_NAMESPACE_STD @@ -97,4 +100,6 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ITERATOR_ITERATOR_WITH_DATA_H diff --git a/third_party/libcxx/__iterator/mergeable.h b/third_party/libcxx/__iterator/mergeable.h index 494fda956..7976d7510 100644 --- a/third_party/libcxx/__iterator/mergeable.h +++ b/third_party/libcxx/__iterator/mergeable.h @@ -24,14 +24,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 -template +template concept mergeable = - input_iterator<_Input1> && - input_iterator<_Input2> && - weakly_incrementable<_Output> && - indirectly_copyable<_Input1, _Output> && - indirectly_copyable<_Input2, _Output> && + input_iterator<_Input1> && input_iterator<_Input2> && weakly_incrementable<_Output> && + indirectly_copyable<_Input1, _Output> && indirectly_copyable<_Input2, _Output> && indirect_strict_weak_order<_Comp, projected<_Input1, _Proj1>, projected<_Input2, _Proj2>>; #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__iterator/move_iterator.h b/third_party/libcxx/__iterator/move_iterator.h index 6028a0e84..a1c53e9bd 100644 --- a/third_party/libcxx/__iterator/move_iterator.h +++ b/third_party/libcxx/__iterator/move_iterator.h @@ -39,25 +39,27 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 -template +template struct __move_iter_category_base {}; -template +template requires requires { typename iterator_traits<_Iter>::iterator_category; } struct __move_iter_category_base<_Iter> { - using iterator_category = _If< - derived_from::iterator_category, random_access_iterator_tag>, - random_access_iterator_tag, - typename iterator_traits<_Iter>::iterator_category - >; + using iterator_category = + _If< derived_from::iterator_category, random_access_iterator_tag>, + random_access_iterator_tag, + typename iterator_traits<_Iter>::iterator_category >; }; -template +template concept __move_iter_comparable = requires { - { std::declval() == std::declval<_Sent>() } -> convertible_to; + { std::declval() == std::declval<_Sent>() } -> convertible_to; }; #endif // _LIBCPP_STD_VER >= 20 @@ -67,284 +69,279 @@ class _LIBCPP_TEMPLATE_VIS move_iterator : public __move_iter_category_base<_Iter> #endif { - #if _LIBCPP_STD_VER >= 20 +#if _LIBCPP_STD_VER >= 20 + private: - _LIBCPP_HIDE_FROM_ABI - static constexpr auto __get_iter_concept() { - if constexpr (random_access_iterator<_Iter>) { - return random_access_iterator_tag{}; - } else if constexpr (bidirectional_iterator<_Iter>) { - return bidirectional_iterator_tag{}; - } else if constexpr (forward_iterator<_Iter>) { - return forward_iterator_tag{}; - } else { - return input_iterator_tag{}; - } + _LIBCPP_HIDE_FROM_ABI static constexpr auto __get_iter_concept() { + if constexpr (random_access_iterator<_Iter>) { + return random_access_iterator_tag{}; + } else if constexpr (bidirectional_iterator<_Iter>) { + return bidirectional_iterator_tag{}; + } else if constexpr (forward_iterator<_Iter>) { + return forward_iterator_tag{}; + } else { + return input_iterator_tag{}; } + } #endif // _LIBCPP_STD_VER >= 20 + public: #if _LIBCPP_STD_VER >= 20 - using iterator_type = _Iter; - using iterator_concept = decltype(__get_iter_concept()); - // iterator_category is inherited and not always present - using value_type = iter_value_t<_Iter>; - using difference_type = iter_difference_t<_Iter>; - using pointer = _Iter; - using reference = iter_rvalue_reference_t<_Iter>; + using iterator_type = _Iter; + using iterator_concept = decltype(__get_iter_concept()); + // iterator_category is inherited and not always present + using value_type = iter_value_t<_Iter>; + using difference_type = iter_difference_t<_Iter>; + using pointer = _Iter; + using reference = iter_rvalue_reference_t<_Iter>; #else - typedef _Iter iterator_type; - typedef _If< - __has_random_access_iterator_category<_Iter>::value, - random_access_iterator_tag, - typename iterator_traits<_Iter>::iterator_category - > iterator_category; - typedef typename iterator_traits::value_type value_type; - typedef typename iterator_traits::difference_type difference_type; - typedef iterator_type pointer; + typedef _Iter iterator_type; + typedef _If< __has_random_access_iterator_category<_Iter>::value, + random_access_iterator_tag, + typename iterator_traits<_Iter>::iterator_category > + iterator_category; + typedef typename iterator_traits::value_type value_type; + typedef typename iterator_traits::difference_type difference_type; + typedef iterator_type pointer; - typedef typename iterator_traits::reference __reference; - typedef typename conditional< - is_reference<__reference>::value, - __libcpp_remove_reference_t<__reference>&&, - __reference - >::type reference; + typedef typename iterator_traits::reference __reference; + typedef __conditional_t::value, __libcpp_remove_reference_t<__reference>&&, __reference> + reference; #endif // _LIBCPP_STD_VER >= 20 - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - explicit move_iterator(_Iter __i) : __current_(std::move(__i)) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 explicit move_iterator(_Iter __i) : __current_(std::move(__i)) {} - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - move_iterator& operator++() { ++__current_; return *this; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator& operator++() { + ++__current_; + return *this; + } - _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - pointer operator->() const { return __current_; } + _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pointer operator->() const { + return __current_; + } #if _LIBCPP_STD_VER >= 20 - _LIBCPP_HIDE_FROM_ABI constexpr - move_iterator() requires is_constructible_v<_Iter> : __current_() {} + _LIBCPP_HIDE_FROM_ABI constexpr move_iterator() + requires is_constructible_v<_Iter> + : __current_() {} - template - requires (!_IsSame<_Up, _Iter>::value) && convertible_to - _LIBCPP_HIDE_FROM_ABI constexpr - move_iterator(const move_iterator<_Up>& __u) : __current_(__u.base()) {} + template + requires(!_IsSame<_Up, _Iter>::value) && convertible_to + _LIBCPP_HIDE_FROM_ABI constexpr move_iterator(const move_iterator<_Up>& __u) : __current_(__u.base()) {} - template - requires (!_IsSame<_Up, _Iter>::value) && - convertible_to && - assignable_from<_Iter&, const _Up&> - _LIBCPP_HIDE_FROM_ABI constexpr - move_iterator& operator=(const move_iterator<_Up>& __u) { - __current_ = __u.base(); - return *this; - } + template + requires(!_IsSame<_Up, _Iter>::value) && convertible_to && assignable_from<_Iter&, const _Up&> + _LIBCPP_HIDE_FROM_ABI constexpr move_iterator& operator=(const move_iterator<_Up>& __u) { + __current_ = __u.base(); + return *this; + } - _LIBCPP_HIDE_FROM_ABI constexpr const _Iter& base() const & noexcept { return __current_; } - _LIBCPP_HIDE_FROM_ABI constexpr _Iter base() && { return std::move(__current_); } + _LIBCPP_HIDE_FROM_ABI constexpr const _Iter& base() const& noexcept { return __current_; } + _LIBCPP_HIDE_FROM_ABI constexpr _Iter base() && { return std::move(__current_); } - _LIBCPP_HIDE_FROM_ABI constexpr - reference operator*() const { return ranges::iter_move(__current_); } - _LIBCPP_HIDE_FROM_ABI constexpr - reference operator[](difference_type __n) const { return ranges::iter_move(__current_ + __n); } + _LIBCPP_HIDE_FROM_ABI constexpr reference operator*() const { return ranges::iter_move(__current_); } + _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](difference_type __n) const { + return ranges::iter_move(__current_ + __n); + } - _LIBCPP_HIDE_FROM_ABI constexpr - auto operator++(int) - requires forward_iterator<_Iter> - { - move_iterator __tmp(*this); ++__current_; return __tmp; - } + _LIBCPP_HIDE_FROM_ABI constexpr auto operator++(int) + requires forward_iterator<_Iter> + { + move_iterator __tmp(*this); + ++__current_; + return __tmp; + } - _LIBCPP_HIDE_FROM_ABI constexpr - void operator++(int) { ++__current_; } + _LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++__current_; } #else - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - move_iterator() : __current_() {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator() : __current_() {} - template ::value && is_convertible::value - > > - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - move_iterator(const move_iterator<_Up>& __u) : __current_(__u.base()) {} + template ::value && is_convertible::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator(const move_iterator<_Up>& __u) + : __current_(__u.base()) {} - template ::value && - is_convertible::value && - is_assignable<_Iter&, const _Up&>::value - > > - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - move_iterator& operator=(const move_iterator<_Up>& __u) { - __current_ = __u.base(); - return *this; - } + template ::value && is_convertible::value && + is_assignable<_Iter&, const _Up&>::value, + int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator& operator=(const move_iterator<_Up>& __u) { + __current_ = __u.base(); + return *this; + } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - _Iter base() const { return __current_; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _Iter base() const { return __current_; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - reference operator*() const { return static_cast(*__current_); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - reference operator[](difference_type __n) const { return static_cast(__current_[__n]); } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator*() const { + return static_cast(*__current_); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](difference_type __n) const { + return static_cast(__current_[__n]); + } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - move_iterator operator++(int) { move_iterator __tmp(*this); ++__current_; return __tmp; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator operator++(int) { + move_iterator __tmp(*this); + ++__current_; + return __tmp; + } #endif // _LIBCPP_STD_VER >= 20 - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - move_iterator& operator--() { --__current_; return *this; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - move_iterator operator--(int) { move_iterator __tmp(*this); --__current_; return __tmp; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - move_iterator operator+(difference_type __n) const { return move_iterator(__current_ + __n); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - move_iterator& operator+=(difference_type __n) { __current_ += __n; return *this; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - move_iterator operator-(difference_type __n) const { return move_iterator(__current_ - __n); } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 - move_iterator& operator-=(difference_type __n) { __current_ -= __n; return *this; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator& operator--() { + --__current_; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator operator--(int) { + move_iterator __tmp(*this); + --__current_; + return __tmp; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator operator+(difference_type __n) const { + return move_iterator(__current_ + __n); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator& operator+=(difference_type __n) { + __current_ += __n; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator operator-(difference_type __n) const { + return move_iterator(__current_ - __n); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator& operator-=(difference_type __n) { + __current_ -= __n; + return *this; + } #if _LIBCPP_STD_VER >= 20 - template _Sent> - friend _LIBCPP_HIDE_FROM_ABI constexpr - bool operator==(const move_iterator& __x, const move_sentinel<_Sent>& __y) - requires __move_iter_comparable<_Iter, _Sent> - { - return __x.base() == __y.base(); - } + template _Sent> + friend _LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const move_iterator& __x, const move_sentinel<_Sent>& __y) + requires __move_iter_comparable<_Iter, _Sent> + { + return __x.base() == __y.base(); + } - template _Sent> - friend _LIBCPP_HIDE_FROM_ABI constexpr - iter_difference_t<_Iter> operator-(const move_sentinel<_Sent>& __x, const move_iterator& __y) - { - return __x.base() - __y.base(); - } + template _Sent> + friend _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter> + operator-(const move_sentinel<_Sent>& __x, const move_iterator& __y) { + return __x.base() - __y.base(); + } - template _Sent> - friend _LIBCPP_HIDE_FROM_ABI constexpr - iter_difference_t<_Iter> operator-(const move_iterator& __x, const move_sentinel<_Sent>& __y) - { - return __x.base() - __y.base(); - } + template _Sent> + friend _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Iter> + operator-(const move_iterator& __x, const move_sentinel<_Sent>& __y) { + return __x.base() - __y.base(); + } - friend _LIBCPP_HIDE_FROM_ABI constexpr - iter_rvalue_reference_t<_Iter> iter_move(const move_iterator& __i) - noexcept(noexcept(ranges::iter_move(__i.__current_))) - { - return ranges::iter_move(__i.__current_); - } + friend _LIBCPP_HIDE_FROM_ABI constexpr iter_rvalue_reference_t<_Iter> + iter_move(const move_iterator& __i) noexcept(noexcept(ranges::iter_move(__i.__current_))) { + return ranges::iter_move(__i.__current_); + } - template _It2> - friend _LIBCPP_HIDE_FROM_ABI constexpr - void iter_swap(const move_iterator& __x, const move_iterator<_It2>& __y) - noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_))) - { - return ranges::iter_swap(__x.__current_, __y.__current_); - } + template _It2> + friend _LIBCPP_HIDE_FROM_ABI constexpr void + iter_swap(const move_iterator& __x, + const move_iterator<_It2>& __y) noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_))) { + return ranges::iter_swap(__x.__current_, __y.__current_); + } #endif // _LIBCPP_STD_VER >= 20 private: - template friend class move_iterator; + template + friend class move_iterator; - _Iter __current_; + _Iter __current_; }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(move_iterator); template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -bool operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) -{ - return __x.base() == __y.base(); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool +operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { + return __x.base() == __y.base(); } #if _LIBCPP_STD_VER <= 17 template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -bool operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) -{ - return __x.base() != __y.base(); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool +operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { + return __x.base() != __y.base(); } #endif // _LIBCPP_STD_VER <= 17 template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -bool operator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) -{ - return __x.base() < __y.base(); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool +operator<(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { + return __x.base() < __y.base(); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -bool operator>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) -{ - return __x.base() > __y.base(); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool +operator>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { + return __x.base() > __y.base(); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -bool operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) -{ - return __x.base() <= __y.base(); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool +operator<=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { + return __x.base() <= __y.base(); } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -bool operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) -{ - return __x.base() >= __y.base(); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool +operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { + return __x.base() >= __y.base(); } #if _LIBCPP_STD_VER >= 20 template _Iter2> -inline _LIBCPP_HIDE_FROM_ABI constexpr -auto operator<=>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) - -> compare_three_way_result_t<_Iter1, _Iter2> -{ - return __x.base() <=> __y.base(); +inline _LIBCPP_HIDE_FROM_ABI constexpr auto +operator<=>(const move_iterator<_Iter1>& __x, + const move_iterator<_Iter2>& __y) -> compare_three_way_result_t<_Iter1, _Iter2> { + return __x.base() <=> __y.base(); } #endif // _LIBCPP_STD_VER >= 20 #ifndef _LIBCPP_CXX03_LANG template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -auto operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) - -> decltype(__x.base() - __y.base()) -{ - return __x.base() - __y.base(); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto +operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) -> decltype(__x.base() - __y.base()) { + return __x.base() - __y.base(); } #else template -inline _LIBCPP_HIDE_FROM_ABI -typename move_iterator<_Iter1>::difference_type -operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) -{ - return __x.base() - __y.base(); +inline _LIBCPP_HIDE_FROM_ABI typename move_iterator<_Iter1>::difference_type +operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { + return __x.base() - __y.base(); } #endif // !_LIBCPP_CXX03_LANG #if _LIBCPP_STD_VER >= 20 template -inline _LIBCPP_HIDE_FROM_ABI constexpr -move_iterator<_Iter> operator+(iter_difference_t<_Iter> __n, const move_iterator<_Iter>& __x) - requires requires { { __x.base() + __n } -> same_as<_Iter>; } +inline _LIBCPP_HIDE_FROM_ABI constexpr move_iterator<_Iter> +operator+(iter_difference_t<_Iter> __n, const move_iterator<_Iter>& __x) + requires requires { + { __x.base() + __n } -> same_as<_Iter>; + } { - return __x + __n; + return __x + __n; } #else template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -move_iterator<_Iter> -operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterator<_Iter>& __x) -{ - return move_iterator<_Iter>(__x.base() + __n); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator<_Iter> +operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterator<_Iter>& __x) { + return move_iterator<_Iter>(__x.base() + __n); } #endif // _LIBCPP_STD_VER >= 20 +#if _LIBCPP_STD_VER >= 20 +template + requires(!sized_sentinel_for<_Iter1, _Iter2>) +inline constexpr bool disable_sized_sentinel_for, move_iterator<_Iter2>> = true; +#endif // _LIBCPP_STD_VER >= 20 + template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 -move_iterator<_Iter> -make_move_iterator(_Iter __i) -{ - return move_iterator<_Iter>(std::move(__i)); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 move_iterator<_Iter> make_move_iterator(_Iter __i) { + return move_iterator<_Iter>(std::move(__i)); } _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ITERATOR_MOVE_ITERATOR_H diff --git a/third_party/libcxx/__iterator/move_sentinel.h b/third_party/libcxx/__iterator/move_sentinel.h index 2fd0af889..4a2a09ef0 100644 --- a/third_party/libcxx/__iterator/move_sentinel.h +++ b/third_party/libcxx/__iterator/move_sentinel.h @@ -19,35 +19,35 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 template -class _LIBCPP_TEMPLATE_VIS move_sentinel -{ +class _LIBCPP_TEMPLATE_VIS move_sentinel { public: - _LIBCPP_HIDE_FROM_ABI - move_sentinel() = default; + _LIBCPP_HIDE_FROM_ABI move_sentinel() = default; - _LIBCPP_HIDE_FROM_ABI constexpr - explicit move_sentinel(_Sent __s) : __last_(std::move(__s)) {} + _LIBCPP_HIDE_FROM_ABI constexpr explicit move_sentinel(_Sent __s) : __last_(std::move(__s)) {} template requires convertible_to - _LIBCPP_HIDE_FROM_ABI constexpr - move_sentinel(const move_sentinel<_S2>& __s) : __last_(__s.base()) {} + _LIBCPP_HIDE_FROM_ABI constexpr move_sentinel(const move_sentinel<_S2>& __s) : __last_(__s.base()) {} template requires assignable_from<_Sent&, const _S2&> - _LIBCPP_HIDE_FROM_ABI constexpr - move_sentinel& operator=(const move_sentinel<_S2>& __s) - { __last_ = __s.base(); return *this; } + _LIBCPP_HIDE_FROM_ABI constexpr move_sentinel& operator=(const move_sentinel<_S2>& __s) { + __last_ = __s.base(); + return *this; + } _LIBCPP_HIDE_FROM_ABI constexpr _Sent base() const { return __last_; } private: - _Sent __last_ = _Sent(); + _Sent __last_ = _Sent(); }; _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(move_sentinel); @@ -56,4 +56,6 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(move_sentinel); _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___ITERATOR_MOVE_SENTINEL_H diff --git a/third_party/libcxx/__iterator/next.h b/third_party/libcxx/__iterator/next.h index 6cb63ecc8..21d3688ad 100644 --- a/third_party/libcxx/__iterator/next.h +++ b/third_party/libcxx/__iterator/next.h @@ -24,14 +24,15 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 - typename enable_if<__has_input_iterator_category<_InputIter>::value, _InputIter>::type - next(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) { - _LIBCPP_ASSERT(__n >= 0 || __has_bidirectional_iterator_category<_InputIter>::value, - "Attempt to next(it, n) with negative n on a non-bidirectional iterator"); +template ::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _InputIter +next(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) { + // Calling `advance` with a negative value on a non-bidirectional iterator is a no-op in the current implementation. + // Note that this check duplicates the similar check in `std::advance`. + _LIBCPP_ASSERT_PEDANTIC(__n >= 0 || __has_bidirectional_iterator_category<_InputIter>::value, + "Attempt to next(it, n) with negative n on a non-bidirectional iterator"); - _VSTD::advance(__x, __n); + std::advance(__x, __n); return __x; } @@ -44,15 +45,13 @@ namespace __next { struct __fn { template - _LIBCPP_HIDE_FROM_ABI - constexpr _Ip operator()(_Ip __x) const { + _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x) const { ++__x; return __x; } template - _LIBCPP_HIDE_FROM_ABI - constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n) const { + _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n) const { ranges::advance(__x, __n); return __x; } @@ -73,7 +72,7 @@ struct __fn { } // namespace __next inline namespace __cpo { - inline constexpr auto next = __next::__fn{}; +inline constexpr auto next = __next::__fn{}; } // namespace __cpo } // namespace ranges diff --git a/third_party/libcxx/__iterator/ostream_iterator.h b/third_party/libcxx/__iterator/ostream_iterator.h index 025712bb1..05697e62d 100644 --- a/third_party/libcxx/__iterator/ostream_iterator.h +++ b/third_party/libcxx/__iterator/ostream_iterator.h @@ -11,11 +11,12 @@ #define _LIBCPP___ITERATOR_OSTREAM_ITERATOR_H #include <__config> +#include <__fwd/ostream.h> +#include <__fwd/string.h> #include <__iterator/iterator.h> #include <__iterator/iterator_traits.h> #include <__memory/addressof.h> #include -#include // for forward declarations of char_traits and basic_ostream #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -30,40 +31,43 @@ class _LIBCPP_TEMPLATE_VIS ostream_iterator : public iterator #endif { -_LIBCPP_SUPPRESS_DEPRECATED_POP + _LIBCPP_SUPPRESS_DEPRECATED_POP + public: - typedef output_iterator_tag iterator_category; - typedef void value_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; #if _LIBCPP_STD_VER >= 20 - typedef ptrdiff_t difference_type; + typedef ptrdiff_t difference_type; #else - typedef void difference_type; + typedef void difference_type; #endif - typedef void pointer; - typedef void reference; - typedef _CharT char_type; - typedef _Traits traits_type; - typedef basic_ostream<_CharT, _Traits> ostream_type; + typedef void pointer; + typedef void reference; + typedef _CharT char_type; + typedef _Traits traits_type; + typedef basic_ostream<_CharT, _Traits> ostream_type; private: - ostream_type* __out_stream_; - const char_type* __delim_; -public: - _LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s) _NOEXCEPT - : __out_stream_(_VSTD::addressof(__s)), __delim_(nullptr) {} - _LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s, const _CharT* __delimiter) _NOEXCEPT - : __out_stream_(_VSTD::addressof(__s)), __delim_(__delimiter) {} - _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator=(const _Tp& __value) - { - *__out_stream_ << __value; - if (__delim_) - *__out_stream_ << __delim_; - return *this; - } + ostream_type* __out_stream_; + const char_type* __delim_; - _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator*() {return *this;} - _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator++() {return *this;} - _LIBCPP_INLINE_VISIBILITY ostream_iterator& operator++(int) {return *this;} +public: + _LIBCPP_HIDE_FROM_ABI ostream_iterator(ostream_type& __s) _NOEXCEPT + : __out_stream_(std::addressof(__s)), + __delim_(nullptr) {} + _LIBCPP_HIDE_FROM_ABI ostream_iterator(ostream_type& __s, const _CharT* __delimiter) _NOEXCEPT + : __out_stream_(std::addressof(__s)), + __delim_(__delimiter) {} + _LIBCPP_HIDE_FROM_ABI ostream_iterator& operator=(const _Tp& __value) { + *__out_stream_ << __value; + if (__delim_) + *__out_stream_ << __delim_; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI ostream_iterator& operator*() { return *this; } + _LIBCPP_HIDE_FROM_ABI ostream_iterator& operator++() { return *this; } + _LIBCPP_HIDE_FROM_ABI ostream_iterator& operator++(int) { return *this; } }; _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__iterator/ostreambuf_iterator.h b/third_party/libcxx/__iterator/ostreambuf_iterator.h index 898ef90e7..dda0094dc 100644 --- a/third_party/libcxx/__iterator/ostreambuf_iterator.h +++ b/third_party/libcxx/__iterator/ostreambuf_iterator.h @@ -29,47 +29,42 @@ class _LIBCPP_TEMPLATE_VIS ostreambuf_iterator : public iterator #endif { -_LIBCPP_SUPPRESS_DEPRECATED_POP + _LIBCPP_SUPPRESS_DEPRECATED_POP + public: - typedef output_iterator_tag iterator_category; - typedef void value_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; #if _LIBCPP_STD_VER >= 20 - typedef ptrdiff_t difference_type; + typedef ptrdiff_t difference_type; #else - typedef void difference_type; + typedef void difference_type; #endif - typedef void pointer; - typedef void reference; - typedef _CharT char_type; - typedef _Traits traits_type; - typedef basic_streambuf<_CharT, _Traits> streambuf_type; - typedef basic_ostream<_CharT, _Traits> ostream_type; + typedef void pointer; + typedef void reference; + typedef _CharT char_type; + typedef _Traits traits_type; + typedef basic_streambuf<_CharT, _Traits> streambuf_type; + typedef basic_ostream<_CharT, _Traits> ostream_type; private: - streambuf_type* __sbuf_; -public: - _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(ostream_type& __s) _NOEXCEPT - : __sbuf_(__s.rdbuf()) {} - _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(streambuf_type* __s) _NOEXCEPT - : __sbuf_(__s) {} - _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator=(_CharT __c) - { - if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sputc(__c), traits_type::eof())) - __sbuf_ = nullptr; - return *this; - } - _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator*() {return *this;} - _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator++() {return *this;} - _LIBCPP_INLINE_VISIBILITY ostreambuf_iterator& operator++(int) {return *this;} - _LIBCPP_INLINE_VISIBILITY bool failed() const _NOEXCEPT {return __sbuf_ == nullptr;} + streambuf_type* __sbuf_; - template - friend - _LIBCPP_HIDE_FROM_ABI - ostreambuf_iterator<_Ch, _Tr> - __pad_and_output(ostreambuf_iterator<_Ch, _Tr> __s, - const _Ch* __ob, const _Ch* __op, const _Ch* __oe, - ios_base& __iob, _Ch __fl); +public: + _LIBCPP_HIDE_FROM_ABI ostreambuf_iterator(ostream_type& __s) _NOEXCEPT : __sbuf_(__s.rdbuf()) {} + _LIBCPP_HIDE_FROM_ABI ostreambuf_iterator(streambuf_type* __s) _NOEXCEPT : __sbuf_(__s) {} + _LIBCPP_HIDE_FROM_ABI ostreambuf_iterator& operator=(_CharT __c) { + if (__sbuf_ && traits_type::eq_int_type(__sbuf_->sputc(__c), traits_type::eof())) + __sbuf_ = nullptr; + return *this; + } + _LIBCPP_HIDE_FROM_ABI ostreambuf_iterator& operator*() { return *this; } + _LIBCPP_HIDE_FROM_ABI ostreambuf_iterator& operator++() { return *this; } + _LIBCPP_HIDE_FROM_ABI ostreambuf_iterator& operator++(int) { return *this; } + _LIBCPP_HIDE_FROM_ABI bool failed() const _NOEXCEPT { return __sbuf_ == nullptr; } + + template + friend _LIBCPP_HIDE_FROM_ABI ostreambuf_iterator<_Ch, _Tr> __pad_and_output( + ostreambuf_iterator<_Ch, _Tr> __s, const _Ch* __ob, const _Ch* __op, const _Ch* __oe, ios_base& __iob, _Ch __fl); }; _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__iterator/permutable.h b/third_party/libcxx/__iterator/permutable.h index adf88f506..f65ba3bfb 100644 --- a/third_party/libcxx/__iterator/permutable.h +++ b/third_party/libcxx/__iterator/permutable.h @@ -24,8 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template concept permutable = - forward_iterator<_Iterator> && - indirectly_movable_storable<_Iterator, _Iterator> && + forward_iterator<_Iterator> && indirectly_movable_storable<_Iterator, _Iterator> && indirectly_swappable<_Iterator, _Iterator>; #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__iterator/prev.h b/third_party/libcxx/__iterator/prev.h index d3f1071d5..2f0e6a088 100644 --- a/third_party/libcxx/__iterator/prev.h +++ b/third_party/libcxx/__iterator/prev.h @@ -24,13 +24,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD -template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 - typename enable_if<__has_input_iterator_category<_InputIter>::value, _InputIter>::type - prev(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) { - _LIBCPP_ASSERT(__n <= 0 || __has_bidirectional_iterator_category<_InputIter>::value, - "Attempt to prev(it, n) with a positive n on a non-bidirectional iterator"); - _VSTD::advance(__x, -__n); +template ::value, int> = 0> +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _InputIter +prev(_InputIter __x, typename iterator_traits<_InputIter>::difference_type __n = 1) { + // Calling `advance` with a negative value on a non-bidirectional iterator is a no-op in the current implementation. + // Note that this check duplicates the similar check in `std::advance`. + _LIBCPP_ASSERT_PEDANTIC(__n <= 0 || __has_bidirectional_iterator_category<_InputIter>::value, + "Attempt to prev(it, n) with a positive n on a non-bidirectional iterator"); + std::advance(__x, -__n); return __x; } @@ -43,15 +44,13 @@ namespace __prev { struct __fn { template - _LIBCPP_HIDE_FROM_ABI - constexpr _Ip operator()(_Ip __x) const { + _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x) const { --__x; return __x; } template - _LIBCPP_HIDE_FROM_ABI - constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n) const { + _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n) const { ranges::advance(__x, -__n); return __x; } @@ -66,7 +65,7 @@ struct __fn { } // namespace __prev inline namespace __cpo { - inline constexpr auto prev = __prev::__fn{}; +inline constexpr auto prev = __prev::__fn{}; } // namespace __cpo } // namespace ranges diff --git a/third_party/libcxx/__iterator/projected.h b/third_party/libcxx/__iterator/projected.h index e74e56d6f..463d07b0d 100644 --- a/third_party/libcxx/__iterator/projected.h +++ b/third_party/libcxx/__iterator/projected.h @@ -12,7 +12,7 @@ #include <__config> #include <__iterator/concepts.h> -#include <__iterator/incrementable_traits.h> +#include <__iterator/incrementable_traits.h> // iter_difference_t #include <__type_traits/remove_cvref.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -23,17 +23,29 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 -template _Proj> -struct projected { - using value_type = remove_cvref_t>; - indirect_result_t<_Proj&, _It> operator*() const; // not defined +template +struct __projected_impl { + struct __type { + using value_type = remove_cvref_t>; + indirect_result_t<_Proj&, _It> operator*() const; // not defined + }; }; -template -struct incrementable_traits> { - using difference_type = iter_difference_t<_It>; +template +struct __projected_impl<_It, _Proj> { + struct __type { + using value_type = remove_cvref_t>; + using difference_type = iter_difference_t<_It>; + indirect_result_t<_Proj&, _It> operator*() const; // not defined + }; }; +// Note that we implement std::projected in a way that satisfies P2538R1 even in standard +// modes before C++26 to avoid breaking the ABI between standard modes (even though ABI +// breaks with std::projected are expected to have essentially no impact). +template _Proj> +using projected = typename __projected_impl<_It, _Proj>::__type; + #endif // _LIBCPP_STD_VER >= 20 _LIBCPP_END_NAMESPACE_STD diff --git a/third_party/libcxx/__iterator/ranges_iterator_traits.h b/third_party/libcxx/__iterator/ranges_iterator_traits.h new file mode 100644 index 000000000..859e70820 --- /dev/null +++ b/third_party/libcxx/__iterator/ranges_iterator_traits.h @@ -0,0 +1,40 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ITERATOR_RANGES_ITERATOR_TRAITS_H +#define _LIBCPP___ITERATOR_RANGES_ITERATOR_TRAITS_H + +#include <__config> +#include <__fwd/pair.h> +#include <__ranges/concepts.h> +#include <__type_traits/remove_const.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER >= 23 + +template +using __range_key_type = __remove_const_t::first_type>; + +template +using __range_mapped_type = typename ranges::range_value_t<_Range>::second_type; + +template +using __range_to_alloc_type = + pair::first_type, typename ranges::range_value_t<_Range>::second_type>; + +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_RANGES_ITERATOR_TRAITS_H diff --git a/third_party/libcxx/__iterator/readable_traits.h b/third_party/libcxx/__iterator/readable_traits.h index fe4f0cd13..25e74567f 100644 --- a/third_party/libcxx/__iterator/readable_traits.h +++ b/third_party/libcxx/__iterator/readable_traits.h @@ -29,61 +29,50 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 20 // [readable.traits] -template struct __cond_value_type {}; +template +struct __cond_value_type {}; -template -requires is_object_v<_Tp> -struct __cond_value_type<_Tp> { using value_type = remove_cv_t<_Tp>; }; +template + requires is_object_v<_Tp> +struct __cond_value_type<_Tp> { + using value_type = remove_cv_t<_Tp>; +}; -template +template concept __has_member_value_type = requires { typename _Tp::value_type; }; -template +template concept __has_member_element_type = requires { typename _Tp::element_type; }; -template struct indirectly_readable_traits {}; +template +struct indirectly_readable_traits {}; -template -requires is_array_v<_Ip> +template + requires is_array_v<_Ip> struct indirectly_readable_traits<_Ip> { using value_type = remove_cv_t>; }; -template +template struct indirectly_readable_traits : indirectly_readable_traits<_Ip> {}; -template +template struct indirectly_readable_traits<_Tp*> : __cond_value_type<_Tp> {}; -template<__has_member_value_type _Tp> -struct indirectly_readable_traits<_Tp> - : __cond_value_type {}; +template <__has_member_value_type _Tp> +struct indirectly_readable_traits<_Tp> : __cond_value_type {}; -template<__has_member_element_type _Tp> -struct indirectly_readable_traits<_Tp> - : __cond_value_type {}; +template <__has_member_element_type _Tp> +struct indirectly_readable_traits<_Tp> : __cond_value_type {}; -template<__has_member_value_type _Tp> +template <__has_member_value_type _Tp> requires __has_member_element_type<_Tp> struct indirectly_readable_traits<_Tp> {}; -template<__has_member_value_type _Tp> +template <__has_member_value_type _Tp> requires __has_member_element_type<_Tp> && - same_as, - remove_cv_t> -struct indirectly_readable_traits<_Tp> - : __cond_value_type {}; - -template -struct iterator_traits; - -// Let `RI` be `remove_cvref_t`. The type `iter_value_t` denotes -// `indirectly_readable_traits::value_type` if `iterator_traits` names a specialization -// generated from the primary template, and `iterator_traits::value_type` otherwise. -template -using iter_value_t = typename conditional_t<__is_primary_template > >::value, - indirectly_readable_traits >, - iterator_traits > >::value_type; + same_as, remove_cv_t> +struct indirectly_readable_traits<_Tp> : __cond_value_type {}; #endif // _LIBCPP_STD_VER >= 20 diff --git a/third_party/libcxx/__iterator/reverse_access.h b/third_party/libcxx/__iterator/reverse_access.h index b8c5a071c..54d7270b0 100644 --- a/third_party/libcxx/__iterator/reverse_access.h +++ b/third_party/libcxx/__iterator/reverse_access.h @@ -24,73 +24,53 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 14 template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 -reverse_iterator<_Tp*> rbegin(_Tp (&__array)[_Np]) -{ - return reverse_iterator<_Tp*>(__array + _Np); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator<_Tp*> rbegin(_Tp (&__array)[_Np]) { + return reverse_iterator<_Tp*>(__array + _Np); } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 -reverse_iterator<_Tp*> rend(_Tp (&__array)[_Np]) -{ - return reverse_iterator<_Tp*>(__array); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator<_Tp*> rend(_Tp (&__array)[_Np]) { + return reverse_iterator<_Tp*>(__array); } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 -reverse_iterator rbegin(initializer_list<_Ep> __il) -{ - return reverse_iterator(__il.end()); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rbegin(initializer_list<_Ep> __il) { + return reverse_iterator(__il.end()); } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 -reverse_iterator rend(initializer_list<_Ep> __il) -{ - return reverse_iterator(__il.begin()); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rend(initializer_list<_Ep> __il) { + return reverse_iterator(__il.begin()); } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 -auto rbegin(_Cp& __c) -> decltype(__c.rbegin()) -{ - return __c.rbegin(); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto rbegin(_Cp& __c) -> decltype(__c.rbegin()) { + return __c.rbegin(); } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 -auto rbegin(const _Cp& __c) -> decltype(__c.rbegin()) -{ - return __c.rbegin(); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto rbegin(const _Cp& __c) -> decltype(__c.rbegin()) { + return __c.rbegin(); } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 -auto rend(_Cp& __c) -> decltype(__c.rend()) -{ - return __c.rend(); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto rend(_Cp& __c) -> decltype(__c.rend()) { + return __c.rend(); } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 -auto rend(const _Cp& __c) -> decltype(__c.rend()) -{ - return __c.rend(); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto rend(const _Cp& __c) -> decltype(__c.rend()) { + return __c.rend(); } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 -auto crbegin(const _Cp& __c) -> decltype(_VSTD::rbegin(__c)) -{ - return _VSTD::rbegin(__c); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto crbegin(const _Cp& __c) -> decltype(std::rbegin(__c)) { + return std::rbegin(__c); } template -_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 -auto crend(const _Cp& __c) -> decltype(_VSTD::rend(__c)) -{ - return _VSTD::rend(__c); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto crend(const _Cp& __c) -> decltype(std::rend(__c)) { + return std::rend(__c); } #endif // _LIBCPP_STD_VER >= 14 diff --git a/third_party/libcxx/__iterator/reverse_iterator.h b/third_party/libcxx/__iterator/reverse_iterator.h index beb10f7f4..50c0f21ea 100644 --- a/third_party/libcxx/__iterator/reverse_iterator.h +++ b/third_party/libcxx/__iterator/reverse_iterator.h @@ -34,7 +34,7 @@ #include <__type_traits/enable_if.h> #include <__type_traits/is_assignable.h> #include <__type_traits/is_convertible.h> -#include <__type_traits/is_nothrow_copy_constructible.h> +#include <__type_traits/is_nothrow_constructible.h> #include <__type_traits/is_pointer.h> #include <__type_traits/is_same.h> #include <__utility/declval.h> @@ -57,440 +57,283 @@ class _LIBCPP_TEMPLATE_VIS reverse_iterator typename iterator_traits<_Iter>::reference> #endif { -_LIBCPP_SUPPRESS_DEPRECATED_POP + _LIBCPP_SUPPRESS_DEPRECATED_POP + private: #ifndef _LIBCPP_ABI_NO_ITERATOR_BASES - _Iter __t_; // no longer used as of LWG #2360, not removed due to ABI break + _Iter __t_; // no longer used as of LWG #2360, not removed due to ABI break #endif #if _LIBCPP_STD_VER >= 20 - static_assert(__has_bidirectional_iterator_category<_Iter>::value || bidirectional_iterator<_Iter>, - "reverse_iterator requires It to be a bidirectional iterator."); + static_assert(__has_bidirectional_iterator_category<_Iter>::value || bidirectional_iterator<_Iter>, + "reverse_iterator requires It to be a bidirectional iterator."); #endif // _LIBCPP_STD_VER >= 20 protected: - _Iter current; -public: - using iterator_type = _Iter; + _Iter current; - using iterator_category = _If<__has_random_access_iterator_category<_Iter>::value, - random_access_iterator_tag, - typename iterator_traits<_Iter>::iterator_category>; - using pointer = typename iterator_traits<_Iter>::pointer; +public: + using iterator_type = _Iter; + + using iterator_category = + _If<__has_random_access_iterator_category<_Iter>::value, + random_access_iterator_tag, + typename iterator_traits<_Iter>::iterator_category>; + using pointer = typename iterator_traits<_Iter>::pointer; #if _LIBCPP_STD_VER >= 20 - using iterator_concept = _If, random_access_iterator_tag, bidirectional_iterator_tag>; - using value_type = iter_value_t<_Iter>; - using difference_type = iter_difference_t<_Iter>; - using reference = iter_reference_t<_Iter>; + using iterator_concept = _If, random_access_iterator_tag, bidirectional_iterator_tag>; + using value_type = iter_value_t<_Iter>; + using difference_type = iter_difference_t<_Iter>; + using reference = iter_reference_t<_Iter>; #else - using value_type = typename iterator_traits<_Iter>::value_type; - using difference_type = typename iterator_traits<_Iter>::difference_type; - using reference = typename iterator_traits<_Iter>::reference; + using value_type = typename iterator_traits<_Iter>::value_type; + using difference_type = typename iterator_traits<_Iter>::difference_type; + using reference = typename iterator_traits<_Iter>::reference; #endif #ifndef _LIBCPP_ABI_NO_ITERATOR_BASES - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 - reverse_iterator() : __t_(), current() {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator() : __t_(), current() {} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 - explicit reverse_iterator(_Iter __x) : __t_(__x), current(__x) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 explicit reverse_iterator(_Iter __x) : __t_(__x), current(__x) {} - template ::value && is_convertible<_Up const&, _Iter>::value - > > - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 - reverse_iterator(const reverse_iterator<_Up>& __u) - : __t_(__u.base()), current(__u.base()) - { } + template ::value && is_convertible<_Up const&, _Iter>::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator(const reverse_iterator<_Up>& __u) + : __t_(__u.base()), current(__u.base()) {} - template ::value && - is_convertible<_Up const&, _Iter>::value && - is_assignable<_Iter&, _Up const&>::value - > > - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 - reverse_iterator& operator=(const reverse_iterator<_Up>& __u) { - __t_ = current = __u.base(); - return *this; - } + template ::value && is_convertible<_Up const&, _Iter>::value && + is_assignable<_Iter&, _Up const&>::value, + int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator& operator=(const reverse_iterator<_Up>& __u) { + __t_ = current = __u.base(); + return *this; + } #else - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 - reverse_iterator() : current() {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator() : current() {} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 - explicit reverse_iterator(_Iter __x) : current(__x) {} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 explicit reverse_iterator(_Iter __x) : current(__x) {} - template ::value && is_convertible<_Up const&, _Iter>::value - > > - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 - reverse_iterator(const reverse_iterator<_Up>& __u) - : current(__u.base()) - { } + template ::value && is_convertible<_Up const&, _Iter>::value, int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator(const reverse_iterator<_Up>& __u) + : current(__u.base()) {} - template ::value && - is_convertible<_Up const&, _Iter>::value && - is_assignable<_Iter&, _Up const&>::value - > > - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 - reverse_iterator& operator=(const reverse_iterator<_Up>& __u) { - current = __u.base(); - return *this; - } + template ::value && is_convertible<_Up const&, _Iter>::value && + is_assignable<_Iter&, _Up const&>::value, + int> = 0> + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator& operator=(const reverse_iterator<_Up>& __u) { + current = __u.base(); + return *this; + } #endif - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 - _Iter base() const {return current;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 - reference operator*() const {_Iter __tmp = current; return *--__tmp;} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _Iter base() const { return current; } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator*() const { + _Iter __tmp = current; + return *--__tmp; + } #if _LIBCPP_STD_VER >= 20 - _LIBCPP_INLINE_VISIBILITY - constexpr pointer operator->() const - requires is_pointer_v<_Iter> || requires(const _Iter __i) { __i.operator->(); } - { - if constexpr (is_pointer_v<_Iter>) { - return std::prev(current); - } else { - return std::prev(current).operator->(); - } + _LIBCPP_HIDE_FROM_ABI constexpr pointer operator->() const + requires is_pointer_v<_Iter> || requires(const _Iter __i) { __i.operator->(); } + { + if constexpr (is_pointer_v<_Iter>) { + return std::prev(current); + } else { + return std::prev(current).operator->(); } + } #else - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 - pointer operator->() const { - return std::addressof(operator*()); - } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 pointer operator->() const { return std::addressof(operator*()); } #endif // _LIBCPP_STD_VER >= 20 - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 - reverse_iterator& operator++() {--current; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 - reverse_iterator operator++(int) {reverse_iterator __tmp(*this); --current; return __tmp;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 - reverse_iterator& operator--() {++current; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 - reverse_iterator operator--(int) {reverse_iterator __tmp(*this); ++current; return __tmp;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 - reverse_iterator operator+(difference_type __n) const {return reverse_iterator(current - __n);} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 - reverse_iterator& operator+=(difference_type __n) {current -= __n; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 - reverse_iterator operator-(difference_type __n) const {return reverse_iterator(current + __n);} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 - reverse_iterator& operator-=(difference_type __n) {current += __n; return *this;} - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 - reference operator[](difference_type __n) const {return *(*this + __n);} + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator& operator++() { + --current; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator operator++(int) { + reverse_iterator __tmp(*this); + --current; + return __tmp; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator& operator--() { + ++current; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator operator--(int) { + reverse_iterator __tmp(*this); + ++current; + return __tmp; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator operator+(difference_type __n) const { + return reverse_iterator(current - __n); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator& operator+=(difference_type __n) { + current -= __n; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator operator-(difference_type __n) const { + return reverse_iterator(current + __n); + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator& operator-=(difference_type __n) { + current += __n; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](difference_type __n) const { + return *(*this + __n); + } #if _LIBCPP_STD_VER >= 20 - _LIBCPP_HIDE_FROM_ABI friend constexpr - iter_rvalue_reference_t<_Iter> iter_move(const reverse_iterator& __i) - noexcept(is_nothrow_copy_constructible_v<_Iter> && - noexcept(ranges::iter_move(--std::declval<_Iter&>()))) { - auto __tmp = __i.base(); - return ranges::iter_move(--__tmp); - } + _LIBCPP_HIDE_FROM_ABI friend constexpr iter_rvalue_reference_t<_Iter> iter_move(const reverse_iterator& __i) noexcept( + is_nothrow_copy_constructible_v<_Iter> && noexcept(ranges::iter_move(--std::declval<_Iter&>()))) { + auto __tmp = __i.base(); + return ranges::iter_move(--__tmp); + } - template _Iter2> - _LIBCPP_HIDE_FROM_ABI friend constexpr - void iter_swap(const reverse_iterator& __x, const reverse_iterator<_Iter2>& __y) - noexcept(is_nothrow_copy_constructible_v<_Iter> && - is_nothrow_copy_constructible_v<_Iter2> && - noexcept(ranges::iter_swap(--std::declval<_Iter&>(), --std::declval<_Iter2&>()))) { - auto __xtmp = __x.base(); - auto __ytmp = __y.base(); - ranges::iter_swap(--__xtmp, --__ytmp); - } + template _Iter2> + _LIBCPP_HIDE_FROM_ABI friend constexpr void + iter_swap(const reverse_iterator& __x, const reverse_iterator<_Iter2>& __y) noexcept( + is_nothrow_copy_constructible_v<_Iter> && is_nothrow_copy_constructible_v<_Iter2> && + noexcept(ranges::iter_swap(--std::declval<_Iter&>(), --std::declval<_Iter2&>()))) { + auto __xtmp = __x.base(); + auto __ytmp = __y.base(); + ranges::iter_swap(--__xtmp, --__ytmp); + } #endif // _LIBCPP_STD_VER >= 20 }; template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 -bool +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) #if _LIBCPP_STD_VER >= 20 - requires requires { - { __x.base() == __y.base() } -> convertible_to; - } + requires requires { + { __x.base() == __y.base() } -> convertible_to; + } #endif // _LIBCPP_STD_VER >= 20 { - return __x.base() == __y.base(); + return __x.base() == __y.base(); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 -bool +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) #if _LIBCPP_STD_VER >= 20 - requires requires { - { __x.base() > __y.base() } -> convertible_to; - } + requires requires { + { __x.base() > __y.base() } -> convertible_to; + } #endif // _LIBCPP_STD_VER >= 20 { - return __x.base() > __y.base(); + return __x.base() > __y.base(); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 -bool +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) #if _LIBCPP_STD_VER >= 20 - requires requires { - { __x.base() != __y.base() } -> convertible_to; - } + requires requires { + { __x.base() != __y.base() } -> convertible_to; + } #endif // _LIBCPP_STD_VER >= 20 { - return __x.base() != __y.base(); + return __x.base() != __y.base(); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 -bool +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) #if _LIBCPP_STD_VER >= 20 - requires requires { - { __x.base() < __y.base() } -> convertible_to; - } + requires requires { + { __x.base() < __y.base() } -> convertible_to; + } #endif // _LIBCPP_STD_VER >= 20 { - return __x.base() < __y.base(); + return __x.base() < __y.base(); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 -bool +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) #if _LIBCPP_STD_VER >= 20 - requires requires { - { __x.base() <= __y.base() } -> convertible_to; - } + requires requires { + { __x.base() <= __y.base() } -> convertible_to; + } #endif // _LIBCPP_STD_VER >= 20 { - return __x.base() <= __y.base(); + return __x.base() <= __y.base(); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 -bool +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 bool operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) #if _LIBCPP_STD_VER >= 20 - requires requires { - { __x.base() >= __y.base() } -> convertible_to; - } + requires requires { + { __x.base() >= __y.base() } -> convertible_to; + } #endif // _LIBCPP_STD_VER >= 20 { - return __x.base() >= __y.base(); + return __x.base() >= __y.base(); } #if _LIBCPP_STD_VER >= 20 template _Iter2> -_LIBCPP_HIDE_FROM_ABI constexpr -compare_three_way_result_t<_Iter1, _Iter2> -operator<=>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) -{ - return __y.base() <=> __x.base(); +_LIBCPP_HIDE_FROM_ABI constexpr compare_three_way_result_t<_Iter1, _Iter2> +operator<=>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) { + return __y.base() <=> __x.base(); } #endif // _LIBCPP_STD_VER >= 20 #ifndef _LIBCPP_CXX03_LANG template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 -auto -operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) --> decltype(__y.base() - __x.base()) -{ - return __y.base() - __x.base(); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto +operator-(const reverse_iterator<_Iter1>& __x, + const reverse_iterator<_Iter2>& __y) -> decltype(__y.base() - __x.base()) { + return __y.base() - __x.base(); } #else template -inline _LIBCPP_INLINE_VISIBILITY -typename reverse_iterator<_Iter1>::difference_type -operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) -{ - return __y.base() - __x.base(); +inline _LIBCPP_HIDE_FROM_ABI typename reverse_iterator<_Iter1>::difference_type +operator-(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) { + return __y.base() - __x.base(); } #endif template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 -reverse_iterator<_Iter> -operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_iterator<_Iter>& __x) -{ - return reverse_iterator<_Iter>(__x.base() - __n); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator<_Iter> +operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_iterator<_Iter>& __x) { + return reverse_iterator<_Iter>(__x.base() - __n); } #if _LIBCPP_STD_VER >= 20 template - requires (!sized_sentinel_for<_Iter1, _Iter2>) + requires(!sized_sentinel_for<_Iter1, _Iter2>) inline constexpr bool disable_sized_sentinel_for, reverse_iterator<_Iter2>> = true; #endif // _LIBCPP_STD_VER >= 20 #if _LIBCPP_STD_VER >= 14 template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 -reverse_iterator<_Iter> make_reverse_iterator(_Iter __i) -{ - return reverse_iterator<_Iter>(__i); +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator<_Iter> make_reverse_iterator(_Iter __i) { + return reverse_iterator<_Iter>(__i); } #endif -#if _LIBCPP_STD_VER <= 17 -template -using __unconstrained_reverse_iterator = reverse_iterator<_Iter>; -#else +#if _LIBCPP_STD_VER >= 20 +template +_LIBCPP_HIDE_FROM_ABI constexpr ranges::subrange>, + reverse_iterator>> +__reverse_range(_Range&& __range) { + auto __first = ranges::begin(__range); + return {std::make_reverse_iterator(ranges::next(__first, ranges::end(__range))), std::make_reverse_iterator(__first)}; +} +#endif -// __unconstrained_reverse_iterator allows us to use reverse iterators in the implementation of algorithms by working -// around a language issue in C++20. -// In C++20, when a reverse iterator wraps certain C++20-hostile iterators, calling comparison operators on it will -// result in a compilation error. However, calling comparison operators on the pristine hostile iterator is not -// an error. Thus, we cannot use reverse_iterators in the implementation of an algorithm that accepts a -// C++20-hostile iterator. This class is an internal workaround -- it is a copy of reverse_iterator with -// tweaks to make it support hostile iterators. -// -// A C++20-hostile iterator is one that defines a comparison operator where one of the arguments is an exact match -// and the other requires an implicit conversion, for example: -// friend bool operator==(const BaseIter&, const DerivedIter&); -// -// C++20 rules for rewriting equality operators create another overload of this function with parameters reversed: -// friend bool operator==(const DerivedIter&, const BaseIter&); -// -// This creates an ambiguity in overload resolution. -// -// Clang treats this ambiguity differently in different contexts. When operator== is actually called in the function -// body, the code is accepted with a warning. When a concept requires operator== to be a valid expression, however, -// it evaluates to false. Thus, the implementation of reverse_iterator::operator== can actually call operator== on its -// base iterators, but the constraints on reverse_iterator::operator== prevent it from being considered during overload -// resolution. This class simply removes the problematic constraints from comparison functions. -template -class __unconstrained_reverse_iterator { - _Iter __iter_; - -public: - static_assert(__has_bidirectional_iterator_category<_Iter>::value || bidirectional_iterator<_Iter>); - - using iterator_type = _Iter; - using iterator_category = - _If<__has_random_access_iterator_category<_Iter>::value, random_access_iterator_tag, __iterator_category_type<_Iter>>; - using pointer = __iterator_pointer_type<_Iter>; - using value_type = iter_value_t<_Iter>; - using difference_type = iter_difference_t<_Iter>; - using reference = iter_reference_t<_Iter>; - - _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator() = default; - _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator(const __unconstrained_reverse_iterator&) = default; - _LIBCPP_HIDE_FROM_ABI constexpr explicit __unconstrained_reverse_iterator(_Iter __iter) : __iter_(__iter) {} - - _LIBCPP_HIDE_FROM_ABI constexpr _Iter base() const { return __iter_; } - _LIBCPP_HIDE_FROM_ABI constexpr reference operator*() const { - auto __tmp = __iter_; - return *--__tmp; - } - - _LIBCPP_HIDE_FROM_ABI constexpr pointer operator->() const { - if constexpr (is_pointer_v<_Iter>) { - return std::prev(__iter_); - } else { - return std::prev(__iter_).operator->(); - } - } - - _LIBCPP_HIDE_FROM_ABI friend constexpr - iter_rvalue_reference_t<_Iter> iter_move(const __unconstrained_reverse_iterator& __i) - noexcept(is_nothrow_copy_constructible_v<_Iter> && - noexcept(ranges::iter_move(--std::declval<_Iter&>()))) { - auto __tmp = __i.base(); - return ranges::iter_move(--__tmp); - } - - _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator++() { - --__iter_; - return *this; - } - - _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator++(int) { - auto __tmp = *this; - --__iter_; - return __tmp; - } - - _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator--() { - ++__iter_; - return *this; - } - - _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator--(int) { - auto __tmp = *this; - ++__iter_; - return __tmp; - } - - _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator+=(difference_type __n) { - __iter_ -= __n; - return *this; - } - - _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator& operator-=(difference_type __n) { - __iter_ += __n; - return *this; - } - - _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator+(difference_type __n) const { - return __unconstrained_reverse_iterator(__iter_ - __n); - } - - _LIBCPP_HIDE_FROM_ABI constexpr __unconstrained_reverse_iterator operator-(difference_type __n) const { - return __unconstrained_reverse_iterator(__iter_ + __n); - } - - _LIBCPP_HIDE_FROM_ABI constexpr difference_type operator-(const __unconstrained_reverse_iterator& __other) const { - return __other.__iter_ - __iter_; - } - - _LIBCPP_HIDE_FROM_ABI constexpr auto operator[](difference_type __n) const { return *(*this + __n); } - - // Deliberately unconstrained unlike the comparison functions in `reverse_iterator` -- see the class comment for the - // rationale. - _LIBCPP_HIDE_FROM_ABI friend constexpr bool - operator==(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) { - return __lhs.base() == __rhs.base(); - } - - _LIBCPP_HIDE_FROM_ABI friend constexpr bool - operator!=(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) { - return __lhs.base() != __rhs.base(); - } - - _LIBCPP_HIDE_FROM_ABI friend constexpr bool - operator<(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) { - return __lhs.base() > __rhs.base(); - } - - _LIBCPP_HIDE_FROM_ABI friend constexpr bool - operator>(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) { - return __lhs.base() < __rhs.base(); - } - - _LIBCPP_HIDE_FROM_ABI friend constexpr bool - operator<=(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) { - return __lhs.base() >= __rhs.base(); - } - - _LIBCPP_HIDE_FROM_ABI friend constexpr bool - operator>=(const __unconstrained_reverse_iterator& __lhs, const __unconstrained_reverse_iterator& __rhs) { - return __lhs.base() <= __rhs.base(); - } -}; - -#endif // _LIBCPP_STD_VER <= 17 - -template